#include "GameModes.h"

#include "Utils/TimeUtils.h"

auto Hooks::GameModes::callback_startDestroyBlock(GameMode* _this, const glm::vec3& pos, unsigned char a2, bool& a3) -> bool {
	for (Mod* mod : Client::modlist) {
		if (!mod->enabled && mod->onlyenabled) continue;

		mod->onStartDestroyBlock();
	}

	return gamemode_startdestroyblock(_this, pos, a2, a3);
}

auto Hooks::GameModes::callback_stopDestroyBlock(GameMode* _this, const glm::vec3& pos) -> void {
	for (Mod* mod : Client::modlist) {
		if (!mod->enabled && mod->onlyenabled) continue;

		mod->onStopDestroyBlock();
	}

	return gamemode_stopdestroyblock(_this, pos);
}

auto Hooks::GameModes::callback_getPickRange(GameMode* _this, InputMode const& currentInputMode, bool isVR) -> float {
	float value = gamemode_getpickrange(_this, currentInputMode, isVR);

	for (Mod* mod : Client::modlist) {
		if (!mod->enabled && mod->onlyenabled) continue;

		mod->onGetPickRange(&value);
	}

	return value;
}

auto Hooks::GameModes::callback_attack(GameMode* _this, Actor& target) -> bool {
	for (Mod* mod : Client::modlist) {
		if (!mod->enabled && mod->onlyenabled) continue;

		mod->onAttack(target);
	}

	{
		Player* player = (Player*)&target;
		uint64_t runtimeId = player->getRuntimeIDComponent()->mRuntimeID.rawID;

		auto it = std::find_if(Client::attackdatas.rbegin(), Client::attackdatas.rend(), [runtimeId](const Client::AttackData& data) {
			return data.runtimeId == runtimeId;
			});

		if (it != Client::attackdatas.rend()) {
			Client::AttackData last = *it;
			Client::attackdatas.clear();
			Client::attackdatas.push_back(std::move(last));
		}
		else {
			Client::attackdatas.clear();
		}

		Client::attackdatas.push_back({ runtimeId, target, Utils::Time::getMs() });
	}

	return gamemode_attack(_this, target);
}
