//bot specific functions 
local scope = self.GetScriptScope()

scope.thinkFunctions <- {}
scope.divineSealCurrentlyParticling <- false
scope.divineSealCurrentlyHealing <- false
scope.divineSealParticleTimer <- -1
scope.divineSealHealTimer <- -1
scope.protectTheCarrierInRadius <- false
scope.protectTheCarrierIsBombCarrier <- false
scope.purifyingEmblemParticlePlaying <- false
scope.purifyingEmblemParticleTimer <- 1

function think() {
	foreach(key, func in thinkFunctions) {
		func()
	}
}

function purifyingEmblem() {
	//Particle names:
	//purifyingEmblem_bigStatusDenied
	//purifyingEmblem_constantStatusDenied
	foreach(i, cond in mutators.mutatorParams.purifyingEmblem_noParticlesConds) {
		if(self.InCond(cond)) self.RemoveCondEx(cond, true)
	}
	foreach(i, cond in mutators.mutatorParams.purifyingEmblem_constantConds) {
		if(self.InCond(cond)) {
			self.ExtinguishPlayerBurning() //Mfw hardcode because removecond doesnt work
			self.RemoveCondEx(cond, true)
			scope.purifyingEmblemParticleTimer = Time() + 2
			if(scope.purifyingEmblemParticlePlaying == false) {
				DoEntFire("purifyingEmblem_constantParticles", "StartTouch", "!activator", -1, self, self)
				scope.purifyingEmblemParticlePlaying = true
			}
		}
	}
	foreach(i, cond in mutators.mutatorParams.purifyingEmblem_bigConds) {
		if(self.InCond(cond)) {
			self.RemoveCondEx(cond, true)
			DoEntFire("purifyingEmblem_bigParticles", "StartTouch", "!activator", -1, self, self)
		}
	}
	if(Time() > scope.purifyingEmblemParticleTimer && scope.purifyingEmblemParticlePlaying) {
		EntFireByHandle(self, "DispatchEffect", "ParticleEffectStop", -1, self, self)
		scope.purifyingEmblemParticlePlaying = false
	}
	return -1
}

function divineSeal() {
	if(Time() >= divineSealParticleTimer && divineSealCurrentlyParticling) {
		divineSealCurrentlyParticling = false
		DoEntFire("divineSeal_healWarningParticles", "StartTouch", "!activator", -1, self, self)
	}
	if(Time() >= divineSealHealTimer && divineSealCurrentlyHealing) {
		divineSealCurrentlyHealing = false
		self.SetHealth(self.GetMaxHealth())
		DoEntFire("divineSeal_healBoomParticles", "StartTouch", "!activator", -1, self, self)
		EntFireByHandle(self, "DispatchEffect", "ParticleEffectStop", 0.2, self, self)
	}
}

function applyHeavyBombDebuff() {
	if(mutators.activeMutators.find("energySaving") != null) {
		self.AddCustomAttribute("CARD: move speed bonus", mutators.mutatorParams.heavyBomb_speedMultiplier * mutators.mutatorParams.energySaving_speedMultiplier, -1)
	}
	else {
		self.AddCustomAttribute("CARD: move speed bonus", mutators.mutatorParams.heavyBomb_speedMultiplier, -1)
	}
}

function protectTheCarrierBombPickup() {
	scope.protectTheCarrierIsBombCarrier = true
	local carrierOrigin = self.GetOrigin()
	carrierOrigin = carrierOrigin + (self.HasBotAttribute(MINIBOSS) ? Vector(0,0,72) : Vector(0,0,40))
	//NetProps.SetPropString(self, "m_iName", self.GetEntityIndex().tostring())

	local bomb_shield_prop = SpawnEntityFromTable("prop_dynamic", {
		targetname = "bomb_shield_prop"
		origin = carrierOrigin
		disableshadows = 1
		model = "models/mutators/bomb_shield.mdl"
		modelscale = mutators.mutatorParams.protectTheCarrier_modelScale
		lightingorigin = "bright_lighting_info"
	})

    //EntFireByHandle(bomb_shield_prop, "SetParent", self.GetEntityIndex().tostring(), -1, bomb_shield_prop, null)
	//bomb_shield_prop.SetModelScale(mutators.mutatorParams.protectTheCarrier_modelScale, 0.0)
	//EntFireByHandle(bomb_shield_prop, "DisableShadows", 0, -1, bomb_shield_prop, null)
	//EntFireByHandle(bomb_shield_prop, "SetParentAttachment", "flag", 0.03, bomb_shield_prop, null)

	thinkFunctions["protectTheCarrierThink"] <- protectTheCarrierThink
}

function protectTheCarrierThink() {
	//Particle names:
	//mutator_bomb_shield_glow
	//mutator_bomb_shield_giant_glow

	// if(self.GetScriptScope().protectTheCarrierIsBombCarrier) {
	// 	ClientPrint(null,3,"Is carrier: "+self.entindex().tostring())
	// }

	if(NetProps.GetPropInt(self, "m_lifeState") != 0) {
		delete thinkFunctions["protectTheCarrierThink"]
		//bomb_shield_prop.Kill()
		return
	}

	local carrierOrigin = self.GetOrigin()

	local bomb_shield_prop = Entities.FindByName(null, "bomb_shield_prop")

	if(bomb_shield_prop != null) {
		local propGoalOrigin = carrierOrigin + (self.HasBotAttribute(MINIBOSS) ? Vector(0,0,72) : Vector(0,0,40))
		bomb_shield_prop.SetAbsOrigin(propGoalOrigin)
	}

	for(local i = 1; i <= mutators.maxPlayers; i++) {
		local nearbyBot = PlayerInstanceFromIndex(i)
		if(nearbyBot == null) continue
		if(!IsPlayerABot(nearbyBot)) continue
		if(nearbyBot.GetTeam() != 3) continue
		if(NetProps.GetPropInt(nearbyBot, "m_lifeState") != 0) continue

		local nearbyBotOrigin = nearbyBot.GetOrigin()
		local distanceX = pow(nearbyBotOrigin.x - carrierOrigin.x, 2)
		local distanceY = pow(nearbyBotOrigin.y - carrierOrigin.y, 2)
		local distanceZ = pow(nearbyBotOrigin.z - carrierOrigin.z, 2)
		local rootedDistanceSum = pow(distanceX + distanceY + distanceZ, 0.5)

		local nearbyBotScope = nearbyBot.GetScriptScope()

		if(nearbyBotScope.protectTheCarrierInRadius == false && rootedDistanceSum <= mutators.mutatorParams.protectTheCarrier_radius) {
			if(mutators.activeMutators.find("selfRepair") != null) {
				nearbyBot.AddCustomAttribute("health drain", mutators.mutatorParams.protectTheCarrier_healthRegen + mutators.mutatorParams.selfRepair_healthRegen, -1)
			}
			else {
				nearbyBot.AddCustomAttribute("health drain", mutators.mutatorParams.protectTheCarrier_healthRegen, -1)
			}
			
			if(nearbyBot.GetPlayerClass() == TF_CLASS_SPY && mutators.activeMutators.find("chateauBackstab") != null) {
				nearbyBot.AddCustomAttribute("dmg taken increased", mutators.mutatorParams.protectTheCarrier_dmgReduction * mutators.mutatorParams.chateauBackstab_dmgTakenMultiplier, -1)
			}
			else {
				nearbyBot.AddCustomAttribute("dmg taken increased", mutators.mutatorParams.protectTheCarrier_dmgReduction, -1)
			}

			local particleName = null
			NetProps.SetPropString(nearbyBot, "m_iName", nearbyBot.entindex().tostring())
			particleName = nearbyBot.IsMiniBoss() ? "mutator_bomb_shield_giant_glow" : "mutator_bomb_shield_glow"
			
			local particle = SpawnEntityGroupFromTable({ //apparently need to use this for parentname
				a = {
					info_particle_system = {
						targetname = "protectTheCarrier_particle_" + nearbyBot.entindex()
						effect_name = particleName
						start_active = true
						origin = nearbyBot.GetOrigin()
						parentname = nearbyBot.GetName()
					}
				}
			})
			nearbyBotScope.protectTheCarrierInRadius = true
		}

		if(nearbyBotScope.protectTheCarrierInRadius == true && rootedDistanceSum > mutators.mutatorParams.protectTheCarrier_radius) {
			if(mutators.activeMutators.find("selfRepair") != null) {
				nearbyBot.AddCustomAttribute("health drain", mutators.mutatorParams.selfRepair_healthRegen, -1)
			}
			else {
				nearbyBot.RemoveCustomAttribute("health drain")
			}
			if(nearbyBot.GetPlayerClass() == TF_CLASS_SPY && mutators.activeMutators.find("chateauBackstab") != null) {
				nearbyBot.AddCustomAttribute("dmg taken increased", mutators.mutatorParams.chateauBackstab_dmgTakenMultiplier, -1)
			}
			else {
				nearbyBot.RemoveCustomAttribute("dmg taken increased")
			}
			nearbyBotScope.protectTheCarrierInRadius = false

			local nearbyBotEntIndex = nearbyBot.entindex().tostring()
			nearbyBotEntIndex = "protectTheCarrier_particle_" + nearbyBotEntIndex
			local bomb_shield_particle = Entities.FindByName(null, nearbyBotEntIndex)
			if(bomb_shield_particle) {
				bomb_shield_particle.Kill()
			}
		}
	}

	return -1
}

//does setup for the main think
function acceleratedDevelopmentHasBomb() {
	if(!self.HasBotAttribute(MINIBOSS)) {
		return
	}
	
	NetProps.SetPropString(self, "m_iName", self.GetEntityIndex().tostring())
	
	local targetName = UniqueString()
	local particleAttachment = SpawnEntityFromTable("info_target", {targetname = targetName})
	EntFire(targetName, "SetParent", self.GetEntityIndex().tostring(), -1)
	EntFire(targetName, "SetParentAttachment", "head", -1)
	
	particleTarget <- particleAttachment
	buffTimer <- null
	
	NetProps.SetPropInt(mutators.objResource, "m_nFlagCarrierUpgradeLevel", 0)
	NetProps.SetPropFloat(mutators.objResource, "m_flMvMBaseBombUpgradeTime", Time())
	NetProps.SetPropFloat(mutators.objResource, "m_flMvMNextBombUpgradeTime", Time() 
		+ Convars.GetFloat("tf_mvm_bot_flag_carrier_interval_to_1st_upgrade"))
	
	upgradeTime <- NetProps.GetPropFloat(mutators.objResource, "m_flMvMNextBombUpgradeTime")
	
	thinkFunctions["acceleratedDevelopmentThink"] <- acceleratedDevelopmentThink
}

//name so it doesn't automatically get added to think
function acceleratedDevelopmentThink() {
	local navTile = self.GetLastKnownArea()
	
	if(navTile != null && navTile.HasAttributeTF(TF_NAV_SPAWN_ROOM_BLUE)) {
		//procrastinate ticking the timer
		//this may need reworked considering how this normally works
		//printl("in spawnroom, haven't started timer")
		NetProps.SetPropFloat(mutators.objResource, "m_flMvMBaseBombUpgradeTime", Time())
		NetProps.SetPropFloat(mutators.objResource, "m_flMvMNextBombUpgradeTime", Time() 
			+ Convars.GetFloat("tf_mvm_bot_flag_carrier_interval_to_1st_upgrade"))
		upgradeTime = NetProps.GetPropFloat(mutators.objResource, "m_flMvMNextBombUpgradeTime")
		return;
	}
	
	//printl(Time())
	//printl(NetProps.GetPropFloat(mutators.objResource, "m_flMvMBaseBombUpgradeTime"))
	//printl(NetProps.GetPropFloat(mutators.objResource, "m_flMvMNextBombUpgradeTime"))
	//printl(NetProps.GetPropInt(mutators.objResource, "m_nFlagCarrierUpgradeLevel"))
	
	//if dead, stop this func
	if(NetProps.GetPropInt(self, "m_lifeState") != 0) {
		delete thinkFunctions["acceleratedDevelopmentThink"]
		delete buffTimer
		particleTarget.Kill()
		return;
	}
	
	//ent_fire player runscriptcode "AddThinkToEnt(self, `think`)"
	
	if(Time() >= upgradeTime) { //enough time has passed, time to upgrade
		local upgradeLevel = NetProps.GetPropInt(mutators.objResource, "m_nFlagCarrierUpgradeLevel")
		if(upgradeLevel < 3) {
			EntFire("tf_gamerules", "PlayVO", "MVM.Warning", -1)
		
			switch(upgradeLevel) {
				case 0:				
					self.Taunt(TAUNT_BASE_WEAPON, 11)
					
					NetProps.SetPropInt(mutators.objResource, "m_nFlagCarrierUpgradeLevel", 1)
					NetProps.SetPropFloat(mutators.objResource, "m_flMvMBaseBombUpgradeTime", Time())
					NetProps.SetPropFloat(mutators.objResource, "m_flMvMNextBombUpgradeTime", Time() 
						+ Convars.GetFloat("tf_mvm_bot_flag_carrier_interval_to_2nd_upgrade"))
					
					upgradeTime = NetProps.GetPropFloat(mutators.objResource, "m_flMvMNextBombUpgradeTime")
					
					foreach(i, player in mutators.players) {
						EntFireByHandle(player, "AddContext", "ConceptMvMBombCarrierUpgrade1:1", -1, null, null)
						//the concept rules handle the chance
						EntFireByHandle(player, "SpeakResponseConcept", "TLK_MVM_BOMB_CARRIER_UPGRADE1", -1, null, null)
					}
					DispatchParticleEffect("mvm_levelup1", particleTarget.GetOrigin(), Vector(0, 0, 0))
					buffTimer = Time()
					break;
				case 1:
					self.Taunt(TAUNT_BASE_WEAPON, 11)
					
					NetProps.SetPropInt(mutators.objResource, "m_nFlagCarrierUpgradeLevel", 2)
					NetProps.SetPropFloat(mutators.objResource, "m_flMvMBaseBombUpgradeTime", Time())
					NetProps.SetPropFloat(mutators.objResource, "m_flMvMNextBombUpgradeTime", Time() 
						+ Convars.GetFloat("tf_mvm_bot_flag_carrier_interval_to_3rd_upgrade"))
					
					upgradeTime = NetProps.GetPropFloat(mutators.objResource, "m_flMvMNextBombUpgradeTime")
					
					foreach(i, player in mutators.players) {
						EntFireByHandle(player, "AddContext", "ConceptMvMBombCarrierUpgrade2:1", -1, null, null)
						EntFireByHandle(player, "SpeakResponseConcept", "TLK_MVM_BOMB_CARRIER_UPGRADE2", -1, null, null)
					}
					DispatchParticleEffect("mvm_levelup2", particleTarget.GetOrigin(), Vector(0, 0, 0))
					self.AddCustomAttribute("CARD: health regen", Convars.GetFloat("tf_mvm_bot_flag_carrier_health_regen"), -1)
					break;
				case 2:
					self.Taunt(TAUNT_BASE_WEAPON, 11)
				
					NetProps.SetPropInt(mutators.objResource, "m_nFlagCarrierUpgradeLevel", 3)
					NetProps.SetPropFloat(mutators.objResource, "m_flMvMBaseBombUpgradeTime", -1)
					NetProps.SetPropFloat(mutators.objResource, "m_flMvMNextBombUpgradeTime", -1)
					foreach(i, player in mutators.players) {
						EntFireByHandle(player, "AddContext", "ConceptMvMBombCarrierUpgrade3:1", -1, null, null)
						EntFireByHandle(player, "SpeakResponseConcept", "TLK_MVM_BOMB_CARRIER_UPGRADE3", -1, null, null)
					}
					DispatchParticleEffect("mvm_levelup3", particleTarget.GetOrigin(), Vector(0, 0, 0))
					self.AddCond(TF_COND_CRITBOOSTED)
					break;
				default:
					break;
			}
		}
	}
	
	if(buffTimer != null) {
		if(Time() >= buffTimer) {
			local player = null
			while(player = Entities.FindByClassnameWithin(player, "player", self.GetOrigin(), 450)) {
				if(player.GetTeam() == TF_TEAM_BLUE) {
					player.AddCondEx(TF_COND_DEFENSEBUFF_NO_CRIT_BLOCK, 1.1, null)
				}
			}
			buffTimer = Time() + 1.1
		}
	}
}