#pragma once
#include "Structures.h"
#include "DB_Cost.h"

struct VampirePlayer
{
	static const unsigned short MAX_TINI = 20;
	static const unsigned short MAX_INFERNAL = 20;
	ParamPlayer vParamPlayer;
	ActionStackForUnits vActionStackForUnits;
	HITEM vGoldCoin;

	unsigned short vStage;
	unsigned short vX,vY;
	Coordinates vCoordinatesRC;

	sVampire vVampire;
	sTini vMassTini[MAX_TINI];
	sInfernal vMassInfernal[MAX_INFERNAL];
	VampirePlayer *pPartner;

	unsigned short vFarmBase;
	HGROUP hGroupFarm;
	bool vFarsight;
	unsigned short vShop;
	DataUnit *pDataUnit;
	DataUnit *pDataUnit2;
	DataUnit *pDataUnit3;
	DataUnit *vRC;
	int vvi;
	//integer vQNewUnit;
	bool vFlag;
	HITEM vItem;
	real vTimeItemGold;
	real vG;
	real vX_1,vY_1;
	real vX_2,vY_2;
	integer vId;
	unit u;
	unit u2;
	bool vTransmitInvulnerability;
	bool vHealingwave;
	bool vStealth;
	bool vFlagHealingwave;
	bool vStealthON;
	bool vSync;
	unsigned short vFlagFarsight;
	bool vFlagStage11;
	integer vIdResearch;

	real vTimeInvulnerability;

	real vTimeAction;

	unsigned short vQUnits;

	bool vInvulnerability;
	bool vFlagIPassedInvulnerability;

	integer vQNewUnit;
	bool vComeToMe;
	real vTimeBeastScroll;
	DataUnit * vHealMe;
	unit vFireInfernalUnit;
	DataUnit * vFireInfernal;
	bool vStepBack;
	real vTimeStepBack;

	real vDiffX;
	real vDiffY;
	real vX_3,vY_3;

	integer vQItems;
	integer vIdOrder;

	HTIMER vTimerBreeze;
	unsigned short vCountForTimerBreeze;
	
	bool vComeToMeTini;
	real vTime;
	real vTime2;

	int vInt3;
	unsigned short vBaseHumanTemp;
	bool vFlagInfernal;
	bool vFlagPullYourselfUp;
	unsigned short vTactic;
	bool vFlagTini;
	bool vComeToMeInfernal;
	unsigned short vQ;
	real vProcHPWall;
	real vTimeGoldCoin;
	real vTimeDelGoldCoin;
	real vTimeAttack;
	
	real vTimeTestGoTo;
	real vTimePermissionMove;
	real vTimeMove;
	real vTimeBuildRC;
	real vTimeMoveOver;
	//int vvi;

	bool fInit()
	{
		vGoldCoin = 0;
		vStage = 0;
		vRC = NULL;
		vTransmitInvulnerability = FALSE;
		vStealthON = FALSE;
		vSync = FALSE;
		vTimeAction = 0;
		vTimeInvulnerability = 0;
		vFlagFarsight = 0;
		vFlagStage11 = 0;
		vInvulnerability = FALSE;
		vFlagIPassedInvulnerability = FALSE;
		vQNewUnit = 0;
		vComeToMe = FALSE;
		vTimeBeastScroll = 0;
		vIdResearch = 0;
		vFireInfernalUnit = NULL;
		vHealMe = NULL;
		vFireInfernal = NULL;
		vStepBack = FALSE;
		vTimeStepBack = 0;
		vTimerBreeze = 0;
		vComeToMeTini = FALSE;
		vFlagInfernal = FALSE;
		vFlagPullYourselfUp = FALSE;
		vTactic = 0;
		vComeToMeInfernal = FALSE;
		vProcHPWall = 0;
		vTimeGoldCoin = 0;
		vTimeDelGoldCoin = 0;
		vTimeAttack = 0;
		vTimeTestGoTo = 0;
		vTimePermissionMove = 0;
		vTimeMove = 0;
		pDataUnit3 = NULL;
		vTimeBuildRC = 0;
		vTimeMoveOver = 0;
		return TRUE;
	}

	bool fStealthOff()
	{
		if (GetUnitState(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit, UNIT_STATE_LIFE) >
			(GetUnitState(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit, UNIT_STATE_MAX_LIFE) * 0.5))
		{
			vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = TRUE;
			//IssueImmediateOrderById(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,0);
			if (IssueImmediateOrderById(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,
				                        ID_ORDER_STEALS_OFF) == TRUE)
			{
				vStealthON = FALSE;
				return TRUE;
			}
			vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = FALSE;
		}
		return FALSE;
	}

	bool fStealth()
	{
		if (vVampire.vUnitParam.pDataUnits->pDataUnit == NULL) return FALSE;
		if (GetUnitState(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit, UNIT_STATE_LIFE) <
			(GetUnitState(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit, UNIT_STATE_MAX_LIFE) * 0.3))
		{
			vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = TRUE;
			//IssueImmediateOrderById(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,0);
			if (IssueImmediateOrderById(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,
				                        vVampire.vStealth.vId) == TRUE)
			{
				vStealthON = TRUE;
				return TRUE;
			}
			vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = FALSE;
		}
		return FALSE;
	}

	bool fStealthON()
	{
		if (1)
		{
			vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = TRUE;
			//IssueImmediateOrderById(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,0);
			if (IssueImmediateOrderById(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,
				                        vVampire.vStealth.vId) == TRUE)
			{
				vStealthON = TRUE;
				return TRUE;
			}
			vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = FALSE;
		}
		return FALSE;
	}

	bool fHealingwaveOnYourself()
	{
		if ((GetUnitState(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit, UNIT_STATE_MAX_LIFE) -
			GetUnitState(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit, UNIT_STATE_LIFE)) >=
			vVampire.vHealingwave.Damage)
		{
			real vMana;
			real vManaSpell;
			vMana = GetUnitState(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit, UNIT_STATE_MANA);
			if (fGetManaSpell(vVampire.vHealingwave.vId,vVampire.vHealingwave.lvl,&vManaSpell) == FALSE) return FALSE;
			if (vMana >= vManaSpell)
			{
				if (IsUnitVisible(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,Player(0)) == TRUE)
				//if (vStealthON == FALSE || (vStealthON == TRUE && fStealthOff() == TRUE))
				{
					vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = TRUE;
					//IssueImmediateOrderById(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,0);
					if (IssueTargetOrderById(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,
											 vVampire.vHealingwave.vId,
											 vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit) == TRUE)
					{
						return TRUE;
					}
					vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = FALSE;
				}
			}
		}
		return FALSE;
	}

	bool fHealingwave(DataUnit * pDataUnit)
	{
		if (pDataUnit == NULL && (unsigned int)pDataUnit == 0xcdcdcdcd) return FALSE;
		pDataUnit2 = fGetDataUnit(pDataUnit->WhichUnit);
		if (pDataUnit2 == NULL) return FALSE;
		vId = GetUnitTypeId(pDataUnit->WhichUnit);
		if (IsUnitVisible(pDataUnit->WhichUnit,Player(0)) == TRUE)
		if (fIsVampire(vId) == FALSE ||
			(fIsVampire(vId) == TRUE &&
			((GetUnitState(pDataUnit->WhichUnit, UNIT_STATE_MAX_LIFE) -
			GetUnitState(pDataUnit->WhichUnit, UNIT_STATE_LIFE)) >=
			vVampire.vHealingwave.Damage) ||
			(GetUnitState(pDataUnit->WhichUnit, UNIT_STATE_LIFE) <
			(GetUnitState(pDataUnit->WhichUnit, UNIT_STATE_MAX_LIFE) * 0.5))))
		{
			vG = fG(vVampire.vUnitParam.pDataUnits->pDataUnit->LastCoordinates.X,
					vVampire.vUnitParam.pDataUnits->pDataUnit->LastCoordinates.Y,
					pDataUnit->LastCoordinates.X,
					pDataUnit->LastCoordinates.Y);
			if (vG <= vVampire.vHealingwave.vRadius)
			{
				vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = TRUE;
				//IssueImmediateOrderById(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,0);
				if (IssueTargetOrderById(vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit,
										 vVampire.vHealingwave.vId,
										 pDataUnit->WhichUnit) == TRUE)
				{
					return TRUE;
				}
				vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = FALSE;
			}
		}
		return FALSE;
	}

	bool fIlluminationOfGlobalStaсkFarsight(sDataVampires *pDataVampires)
	{
		if (pDataVampires->vQFarsight > 0 &&
			fIlluminationByCoordinates(pDataVampires->vMassCoordinatesForFarsight[pDataVampires->vQFarsight-1].X,
									   pDataVampires->vMassCoordinatesForFarsight[pDataVampires->vQFarsight-1].Y) == TRUE)
		{
			pDataVampires->vQFarsight--;
			return TRUE;
		}
		return FALSE;
	}

	bool fIlluminationByCoordinates(real vX, real vY)
	{
		unit vUnit = vVampire.vUnitParam.pDataUnits->pDataUnit->WhichUnit;
		if (vUnit == NULL) return FALSE;
		real vMana;
		real vManaSpell;
		vMana = GetUnitState(vUnit, UNIT_STATE_MANA);
		if (fGetManaSpell(vVampire.vEnlightenment.vId,vVampire.vEnlightenment.lvl,&vManaSpell) == FALSE) return FALSE;
		if (vMana >= vManaSpell)
		{
			vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = TRUE;
			//IssueImmediateOrderById(vUnit,0);
			if (IssuePointOrderById(vUnit,vVampire.vEnlightenment.vId,vX,vY) == TRUE)
			{
				return TRUE;
			}
			else
			{
				vVampire.vUnitParam.pDataUnits->pDataUnit->Permission = FALSE;
			}
		}
		return FALSE;
	}

};

struct HumanPlayer
{
	ParamPlayer vParamPlayer;
	sStackActions vPreviousStackActions;
	sStackActions vStackActions;
	// Работы с лесом
	sStackWorks vStackWorks;
	//integer vIdBase;
	ActionStackForUnits vActionStackForUnits;
	ActionStackForUnits vActionStackForUnitsGoTo;
	ActionStackForUnits vActionStackForUnitsResearch;
	ActionStackForUnits vActionStackForUnitsWorkers;
	ActionStackForUnits vActionStackForUnitsSlayer;
	ActionStackForUnits vActionStackForUnitsMainHuman;
	ActionStackForUnits vActionStackForUnitsTower;
	ActionStackForUnits vActionStackForUnitsFurbolgs;
	ActionStackForUnits vActionStackForUnitsTracker;
	ActionStackForUnits vActionStackForUnitsHeal;
	ActionStackForUnits vActionStackForUnitsOrc;
	ActionStackForUnits vActionStackForUnitsSvens;
	ActionStackForUnits vActionStackForUnitsOgonek;
	ActionStackForUnits vActionStackForUnitsSatyrs;
	ActionStackForUnits vActionStackForUnitsGoblins;

	unsigned short vStage;
	unsigned short vCountTowerWhite;
	integer vIdWall;
	bool vFlagBuildWhiteTower;
	bool vFlagGreadeGoldTower;

	sSlayer vSlayer;

	sMainHuman *pMainHuman;
	sBase vBase;
	unsigned int vInt3;
	bool vFlagPos;

	bool vFlagRepair;
	bool vBlockRepair;
	real vTimeAttackWall;
	bool vFlagEscapeFromTheBase;
	unsigned short vStageEscapeFromTheBase;
	real vTimeLastAttack;
	unit u;
	group hGroupFarm;
	integer vIdOrder;
	
	HITEM vItem;
	real vTimeItemGold;

	real vG;
	real vX_1, vX_2;
	real vY_1, vY_2;
	real vG2;
	real vRadius;
	unsigned short vX;
	unsigned short vY;
	unsigned short vNBase;

	int vvi, vvj, vvz, vvr;
	unsigned short vvi2;
	unsigned short vvi3;

	bool vFlagDearBase;
	unsigned short vCount;
	bool vHelp;
	bool vFlagHelp;
	unsigned short vStageHelp;
	bool vHelping;
	sBase *vHelpBase;
	bool vFlagImba;
	real vTimeImba;

	real vManaUnit;
	DataUnit *pDataUnit;
	DataUnit *pDataUnit2;
	real vTimeCoolDown;
	bool vBuyGold;
	real vTimeForOneSecond;
	real vTimeAttackWorker;
	integer vAllWood;
	unsigned short vQ;
	real vTimeBuild;
	integer vId;
	bool vBlockCreateWorkers;
	bool vFlagEscapeFromTheBaseTemp;
	bool vFlagAttackTowers;
	bool vGoldYes;
	real vTimeCreateTower;
	unsigned short vStageBuildHeal;
	bool vFlagBuildHeal;
	bool vWallCreated;
	integer vCheck;
	real vMana;
	bool vFlagRicochet;
	bool vOneGoldImba;

	sStackActions *vLastAction;
	sStackActions *vCurrentAction;
	unsigned short vCurrentEra;
	unsigned short vNextEra;
	unsigned short vForerunnerStage;
	sStackChains *vLastChain;
	sStackChains *vCurrentChain;
	unsigned short vNFree;

	unsigned short vQHeal;

	StackForUnits *current;
	StackForUnits *next;
	bool vFlagSafeZone;

	integer vAllGold;

	sStackChains *vTempChain;

	real vTimeBuildHeal;
	bool vNoVamp;
	bool vFlagAttackTemp;
	bool vFlagGoldTower;

	Integer vFlag2;
	bool vFlagForResultChain;
	bool vFlagForMassResultChain;
	bool vTowerHouse;
	sRect2 vRect7;
	sRect2 vRect8;
	real vMaxLife;
	real vLife;
	sBase * vBaseAnAlly;
	unsigned short vQWorkers;
	bool vShaman;
	// переменные для апгрейда
	bool vFlag3;
	real vMax;
	StackForUnits *vUnitRadiusMax;
	StackForUnits *vUnitDel;
	bool vDelWorkers;
	unsigned short vQWorkersCurrent;
	//
	unsigned short vResult;
	//от 0 до 65535 (unsigned short)
	static const unsigned short MAX_Q_FOR_MASS_CHAINS = 5000;
	bool vMassChains[MAX_Q_FOR_MASS_CHAINS];//Массив цепочек
	static const unsigned short MAX_Q_NUM_FOR_MASS_CHAINS = 100;
	unsigned short vMassNumForChains[MAX_Q_NUM_FOR_MASS_CHAINS];//Массив чисел для цепочек
	unsigned short vQNumForChains;//Количество чисел для цепочек
	real vTimeJumpMainHuman;
	bool vBuildHram;
	
	sStackChains *vForerunnerChainTemp;	// Предидущая цепочка

	int vCountBuilding;

	unsigned short vIdForComments;
	
	static const unsigned short MAX_Q_FOR_MASS_COMMENT = 199;
	bool vMassComment[MAX_Q_FOR_MASS_COMMENT];
	unsigned short vQNumForComment;//Количество чисел для комментариев

	unsigned short vDevelopmentPriority;
	unsigned short vN;

	bool vEndGame;

	real vTimeExplorationOfTheAreaTracker;

	
	sStackChains *vDevelopmentCurrentChain;
	sStackChains *vDefanseCurrentChain;
	sStackChains *vAttackCurrentChain;
	sStackChains *vDevelopmentLastChain;
	sStackChains *vDefanseLastChain;
	sStackChains *vAttackLastChain;

	bool vFlagFirstTowerBegin;

	bool vFlagDefanse;
	bool vFlagAttack;
	bool vFlagDevelopment;
	unsigned short vDirection;

	DataUnit * vAttackSlayerVampirLol;

	real vTimeGrive;

	unsigned short vCurrentN;

	int vTypeHarvestUnit;
	int vTypeWoodUnit;

	bool vCheckOccupiedPositions;

	unsigned short vMaxIdStackChain;

	sUnitParam *pUnitParam;

	unsigned short vIdDataUnit;

	unsigned short vCommentUnit;

	real vTimeMinute;

	bool vFlagImbaMana;
	
	bool fInit()
	{
		vStage = 0;
		vCountTowerWhite = 0;
		vIdWall = 0;
		vFlagGreadeGoldTower = FALSE;
		vFlagBuildWhiteTower = FALSE;

		vBase.vNBase = DO_NOT_FIND_BASE;
		vInt3 = vSizeMap;
		vFlagPos = FALSE;
		vFlagRepair = FALSE;
		vBlockRepair = FALSE;
		vTimeAttackWall = 0;
		vTimeLastAttack = 0;
		vFlagDearBase = FALSE;
		vHelp = FALSE;
		vFlagHelp = FALSE;
		vStageHelp = 0;
		vHelping = FALSE;
		vHelpBase = NULL;
		vFlagImba = FALSE;
		pDataUnit = NULL;
		vBuyGold = FALSE;
		vTimeForOneSecond = 0;
		vTimeAttackWorker = 0;
		vTimeBuild = 0;
		vFlagEscapeFromTheBase = FALSE;
		vBlockCreateWorkers = FALSE;
		vFlagEscapeFromTheBaseTemp = FALSE;
		vFlagAttackTowers = FALSE;
		vGoldYes = FALSE;
		vTimeCreateTower = 0;
		vStageBuildHeal = 0;
		vFlagBuildHeal = FALSE;
		vWallCreated = FALSE;
		vFlagRicochet = FALSE;
		vLastAction = NULL;
		vCurrentAction = NULL;
		vCurrentEra = 0;
		vNextEra = 0;
		vForerunnerStage = 0;
		vLastChain = NULL;
		vCurrentChain = NULL;
		vNFree = MAX_Q_FOR_MASS_CHAINS;
		vQHeal = 0;
		vFlagSafeZone = FALSE;
		vOneGoldImba = FALSE;
		vAllGold = 0;
		vTempChain = NULL;
		vTimeBuildHeal = 0;
		vNoVamp = FALSE;
		vFlagAttack = FALSE;
		vFlagGoldTower = FALSE;
		vTowerHouse = FALSE;
		vBaseAnAlly = NULL;
		vQWorkers = 0;
		vShaman = FALSE;
		vFlag3 = FALSE;
		vMax = 0;
		vUnitRadiusMax = NULL;
		vUnitDel = NULL;
		vDelWorkers = FALSE;
		vQNumForChains = 0;
		for (vvi = 0; vvi < MAX_Q_FOR_MASS_CHAINS; vvi++)
		{
			vMassChains[vvi] = FALSE;
		}
		vFlag2 = 0;
		vTimeJumpMainHuman = 0.0;
		vForerunnerChainTemp = NULL;
		vBuildHram = FALSE;
		vCountBuilding = 0;
		vIdForComments = 0;
		vQNumForComment = 0;
		for (vvi = 0; vvi < MAX_Q_FOR_MASS_COMMENT; vvi++)
		{
			vMassComment[vvi] = FALSE;
		}
		vDevelopmentPriority = 0;
		vN = 0;
		vEndGame = FALSE;
		vDevelopmentCurrentChain = NULL;
		vDefanseCurrentChain = NULL;
		vAttackCurrentChain = NULL;
		vDevelopmentLastChain = NULL;
		vDefanseLastChain = NULL;
		vAttackLastChain = NULL;
		vFlagFirstTowerBegin = FALSE;
		vFlagDefanse = FALSE;
		vFlagAttack = FALSE;
		vFlagDevelopment = FALSE;
		vDirection = 0;
		vAttackSlayerVampirLol = NULL;
		vTimeGrive = 0;
		vCurrentN = 0;
		vTypeHarvestUnit = 0;
		vTypeWoodUnit = 0;
		pUnitParam = NULL;
		vIdDataUnit = NO_UNIT;
		vCommentUnit = COMMENT_NO_UNIT;
		vTimeMinute = 0;
		vFlagImbaMana = FALSE;
		return TRUE;
	}
};