KF2-Server-Extension/ServerExt/Classes/Ext_T_ZEDHelper.uc

250 lines
6.5 KiB
Ucode

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
}