Class Ext_T_ZEDHelper extends Info
	transient
	DependsOn(Ext_TraitZED_Summon)
	config(ServerExt);

var config array<FZEDTypes> ZedTypes; // Dummy hack, not really config but merely just for being able to set class on defaults.

var() float FriendlyScalar;
var Pawn PawnOwner;
var byte CurLevel,RespawnHelperTime,NoLiveCounter;
var KFPawn_Monster LiveHelper;
var class<KFPawn_Monster> PrevMonster;
var float PrevMonsterHP;

var float HPScale,DamageScale;
var int OldKillsValue;
var bool bNeedsKillZed,bIsExtra;

function PostBeginPlay()
{
	PawnOwner = Pawn(Owner);
	bNeedsKillZed = true;
	if (PawnOwner==None)
		Destroy();
	else
	{
		OldKillsValue = PawnOwner.PlayerReplicationInfo.Kills;
		SetTimer(1+(FRand()*0.1),true);
	}
}

function Timer()
{
	if (PawnOwner==None || PawnOwner.Health<=0 || PawnOwner.PlayerReplicationInfo==None)
		Destroy();
	else if (bNeedsKillZed)
	{
		if (RespawnHelperTime>1)
			--RespawnHelperTime;
		if (OldKillsValue==PawnOwner.PlayerReplicationInfo.Kills)
			return;
		bNeedsKillZed = false;
	}
	else if (RespawnHelperTime>0)
	{
		if (--RespawnHelperTime==0)
			SpawnHelper();
	}
	else if (LiveHelper==None || LiveHelper.Health<=0)
	{
		OldKillsValue = PawnOwner.PlayerReplicationInfo.Kills;
		bNeedsKillZed = true;
		RespawnHelperTime = 60;
	}
	else if (!HasLiveZeds())
	{
		if (NoLiveCounter==0)
		{
			PrevMonster = LiveHelper.Class;
			PrevMonsterHP = (float(LiveHelper.Health) / LiveHelper.HealthMax);
			LiveHelper.Died(None,class'KFDT_Healing',vect(0,0,0));
			RespawnHelperTime = 5;
		}
		else --NoLiveCounter;
	}
	else NoLiveCounter = 5;
}

function Destroyed()
{
	if (LiveHelper!=None && LiveHelper.Health>0)
		LiveHelper.Died(None,class'DmgType_Suicided',vect(0,0,0));
}

final function bool HasLiveZeds()
{
	local KFPawn_Monster M;

	if (KFGameReplicationInfo(WorldInfo.GRI).WaveNum>=KFGameReplicationInfo(WorldInfo.GRI).WaveMax) // No pets on possible bonus waves.
		return false;

	foreach WorldInfo.AllPawns(Class'KFPawn_Monster',M)
		if (M.Health>0 && M.GetTeamNum()!=0)
			return true;
	return false;
}

final function SpawnHelper()
{
	local class<KFPawn_Monster> MC;
	local byte i;
	local vector V;
	local rotator R;
	local Controller C;
	local Ext_T_MonsterPRI PRI;
	local AkBaseSoundObject TempSound;
	local bool bFinalWave;

	if (PawnOwner.PlayerReplicationInfo==None || !HasLiveZeds())
	{
		RespawnHelperTime = 3;
		return;
	}
	NoLiveCounter = 5;
	bFinalWave = KFGameReplicationInfo(WorldInfo.GRI).IsFinalWave();
	if (bFinalWave && Class<KFPawn_MonsterBoss>(PrevMonster)!=None)
		PrevMonster = None;
	MC = (PrevMonster!=None ? PrevMonster : PickRandomMonster(CurLevel,bFinalWave));

	if (MC!=None)
	{
		R.Yaw = Rand(65536);
		if (MC.Default.SoundGroupArch!=None)
		{
			// Make no entrance roam (for FP's and Scrakes).
			TempSound = MC.Default.SoundGroupArch.EntranceSound;
			MC.Default.SoundGroupArch.EntranceSound = None;
		}
		for (i=0; i<40; ++i)
		{
			V = PawnOwner.Location;
			V.X += (FRand()*300.f-150.f);
			V.Y += (FRand()*300.f-150.f);
			if (!PawnOwner.FastTrace(V,PawnOwner.Location))
				continue;
			LiveHelper = Spawn(MC,,,V,R);
			if (LiveHelper!=None)
				break;
		}
		if (MC.Default.SoundGroupArch!=None)
			MC.Default.SoundGroupArch.EntranceSound = TempSound;
	}
	if (LiveHelper==None)
		RespawnHelperTime = 2;
	else
	{
		// Downscale.
		LiveHelper.SetDrawScale(LiveHelper.DrawScale*FriendlyScalar);
		LiveHelper.SetCollisionSize(LiveHelper.GetCollisionRadius()*FriendlyScalar,LiveHelper.GetCollisionHeight()*FriendlyScalar);

		// Setup AI
		C = Spawn(LiveHelper.ControllerClass);
		if (KFAIController(C)!=None)
		{
			KFAIController(C).bCanTeleportCloser = false;
			KFAIController(C).DefaultCommandClass = class'Ext_AICommandBasePet';
			KFAIController(C).StuckCheckInterval = 100000.f; // ~27 hours
			KFAIController(C).LastStuckCheckTime = WorldInfo.TimeSeconds;
		}
		LiveHelper.SpecialMoveHandler.SpecialMoveClasses[SM_Taunt] = class'Ext_AINoTaunt';
		C.Possess(LiveHelper,false);

		// Set HP.
		LiveHelper.HealthMax = Clamp(LiveHelper.Default.Health,180,900)*HPScale;
		LiveHelper.Health = LiveHelper.HealthMax;
		LiveHelper.DamageScaling = DamageScale;
		LiveHelper.SetWeakGrabCoolDown(28800.f); // Never get grabbed (for 80 hours).
		LiveHelper.bWeakZedGrab = true;
		LiveHelper.bCanGrabAttack = false;

		// Scale by previous zed HP.
		if (PrevMonster!=None)
		{
			LiveHelper.Health *= PrevMonsterHP;
			PrevMonster = None;
		}

		// Setup PRI.
		if (C.PlayerReplicationInfo!=None)
			C.PlayerReplicationInfo.Destroy();
		PRI = Spawn(class'Ext_T_MonsterPRI',LiveHelper);
		LiveHelper.PlayerReplicationInfo = PRI;
		C.PlayerReplicationInfo = PRI;
		PRI.PawnOwner = LiveHelper;
		PRI.HealthMax = LiveHelper.HealthMax;
		PRI.MonsterName = Class'KFExtendedHUD'.Static.GetNameOf(MC);
		PRI.OwnerPRI = PawnOwner.PlayerReplicationInfo;
		PRI.MonsterType = MC;
		PRI.PlayerName = PawnOwner.PlayerReplicationInfo.PlayerName$"'s "$PRI.MonsterName;
		PRI.OwnerController = PawnOwner.Controller;
		if (PawnOwner.PlayerReplicationInfo.Team!=None)
			PawnOwner.PlayerReplicationInfo.Team.AddToTeam(C);
		PRI.Timer();
		if (WorldInfo.NetMode!=NM_DedicatedServer)
			PRI.NotifyOwner();
	}
}

final function SetDamageScale(float Sc)
{
	DamageScale = Default.DamageScale*Sc;
	if (LiveHelper!=None)
		LiveHelper.DamageScaling = DamageScale;
}

final function SetHealthScale(float Sc)
{
	HPScale = Default.HPScale*Sc;
}

static final function LoadMonsterList()
{
	local int i,j;
	local array<string> SA;
	local class<KFPawn_Monster> C;

	Default.ZedTypes.Length = class'Ext_TraitZED_Summon'.Default.ZedTypes.Length;

	for (i=0; i<Default.ZedTypes.Length; ++i)
	{
		SA.Length = 0;
		ParseStringIntoArray(class'Ext_TraitZED_Summon'.Default.ZedTypes[i],SA,",",true);

		for (j=0; j<SA.Length; ++j)
		{
			C = class<KFPawn_Monster>(DynamicLoadObject(SA[j],Class'Class'));
			if (C==None)
				continue;
			Default.ZedTypes[i].Zeds[Default.ZedTypes[i].Zeds.Length] = C;
		}
		if (Default.ZedTypes[i].Zeds.Length==0)
			Default.ZedTypes[i].Zeds[Default.ZedTypes[i].Zeds.Length] = Class'KFPawn_ZedClot_Alpha';
	}
}

static final function class<KFPawn_Monster> PickRandomMonster(byte Level, bool bNotBoss)
{
	local byte i;
	local class<KFPawn_Monster> Res;

	Level = Min(Default.ZedTypes.Length-1,Level);
	for (i=0; i<5; ++i)
	{
		Res = Default.ZedTypes[Level].Zeds[Rand(Default.ZedTypes[Level].Zeds.Length)];
		if (!bNotBoss || class<KFPawn_MonsterBoss>(Res)==None)
			break;
	}
	if (bNotBoss && class<KFPawn_MonsterBoss>(Res)!=None)
		Res = Class'KFPawn_ZedFleshpound';
	return Res;
}

defaultproperties
{
	RespawnHelperTime=1
	HPScale=0.5
	DamageScale=2
	FriendlyScalar=0.65
}
