//---------------------------------------------- // zombie.cs // Zombie AI Code //============================================== function ZcreateLoop(%obj) { if(isObject(%obj)) { if(%obj.timedout == 0){ if((%obj.numZ <= 2 || %obj.numZ $= "") && (ZombieGroup.getCount() < $Host::MaxZombies || $Host::MaxZombies == -1)){ ZPCreateZombie(%obj); if(%obj.numZ $= "") %obj.numZ = 0; %obj.numZ++; %obj.timedout = 1; schedule(10000, %obj, "TimedInF", %obj); } } %obj.ZCLoop = schedule(2000, 0, "ZcreateLoop", %obj); } } function TimedInF(%obj){ %obj.timedout = 0; } //this is for when a ZSpawn spawns a zombie function ZPCreateZombie(%obj){ %Cpos = vectorAdd(%obj.getposition() ,%obj.getUpvector()); if(%obj.Ztype $= ""){ %obj.ZType = 1; } if(%obj.ZType == 1){ %Zombie = new player(){ Datablock = "ZombieArmor"; }; applyskin(%zombie,'Zombie',"Zombie"); %Cpos = vectoradd(vectoradd(vectorscale(%obj.getUpvector(),1.15),"0 0 -1.15"),%obj.getposition()); } else if(%obj.ZType == 2){ %Zombie = new player(){ Datablock = "FZombieArmor"; }; applyskin(%zombie,'Zombie',"Ravenger Zombie"); %Cpos = vectoradd(vectoradd(vectorscale(%obj.getUpvector(),1.15),"0 0 -1.15"),%obj.getposition()); } else if(%obj.ZType == 3){ %Zombie = new player(){ Datablock = "LordZombieArmor"; }; applyskin(%zombie,'ZLord',"Zombie Lord"); %Cpos = vectoradd(vectoradd(vectorscale(%obj.getUpvector(),2.4),"0 0 -2.4"),%obj.getposition()); %Zombie.mountImage(ZHead, 3); %Zombie.mountImage(ZBack, 4); %Zombie.mountImage(ZDummyslotImg, 5); %Zombie.mountImage(ZDummyslotImg2, 6); %zombie.firstFired = 0; %zombie.canmove = 1; } else if(%obj.ZType == 4){ %Zombie = new player(){ Datablock = "DemonZombieArmor"; }; applyskin(%zombie,'Zombie',"Demon Zombie"); %zombie.mountImage(ZdummyslotImg, 4); %Cpos = vectoradd(vectoradd(vectorscale(%obj.getUpvector(),1.3),"0 0 -1.3"),%obj.getposition()); } else if(%obj.ZType == 5){ %Zombie = new player(){ Datablock = "RapierZombieArmor"; }; applyskin(%zombie,'Zombie',"Rapier Zombie"); %Zombie.mountImage(ZWingImage, 3); %Zombie.mountImage(ZWingImage2, 4); %zombie.setActionThread("scoutRoot",true); %Cpos = vectoradd(vectoradd(vectorscale(%obj.getUpvector(),1),"0 0 -0.6"),%obj.getposition()); } else if(%obj.ZType == 6){ %Cpos = vectoradd(vectoradd(vectorscale(%obj.getUpvector(),1.15),"0 0 -1.15"),%obj.getposition()); %Zombie = DemonMotherCreate(%Cpos); } %zombie.type = %obj.Ztype; %Zombie.setTransform(%Cpos); %Zombie.team = 0; %zombie.HasCP = 1; if(%obj.spawnTypeset == 1) %obj.numZ = 3; else %zombie.CP = %obj; AddToZombieGroup(%Zombie); if(%obj.ZType != 6) { %zombie.canjump = 1; %zombie.hastarget = 1; schedule(1000, %zombie, "ZombieLookforTarget", %zombie); } } //This is for creation of a zombie at a location using the console function StartAZombie(%pos, %type){ if(ZombieGroup.getCount >= $Host::MaxZombies && $Host::MaxZombies != -1) { error("StartAZombie: Cannot spawn. There are too many zombies on the server."); return; } if(%Type == 1){ %Zombie = new player(){ Datablock = "ZombieArmor"; }; applyskin(%zombie,'Zombie',"Zombie"); } if(%Type == 2){ %Zombie = new player(){ Datablock = "FZombieArmor"; }; applyskin(%zombie,'Zombie',"Ravenger Zombie"); } if(%Type == 3){ %Zombie = new player(){ Datablock = "LordZombieArmor"; }; applyskin(%zombie,'ZLord',"Zombie Lord"); %zombie.client = $zombie::Lclient; %Zombie.mountImage(ZHead, 3); %Zombie.mountImage(ZBack, 4); %Zombie.mountImage(ZDummyslotImg, 5); %Zombie.mountImage(ZDummyslotImg2, 6); %zombie.firstFired = 0; %zombie.canmove = 1; } if(%type == 4){ %Zombie = new player(){ Datablock = "DemonZombieArmor"; }; applyskin(%zombie,'Zombie',"Demon Zombie"); %zombie.mountImage(ZdummyslotImg, 4); } %zombie.type = %type; %Zombie.setTransform(%pos); %Zombie.team = 0; %zombie.canjump = 1; %zombie.hastarget = 1; AddToZombieGroup(%Zombie); schedule(1000, %zombie, "ZombieLookforTarget", %zombie); } //This is for when someone is killed by a zombie and spawns a new one function CreateZombie(%obj){ if(ZombieGroup.getCount() >= $Host::MaxZombies && $Host::MaxZombies != -1) return; %Cpos = %obj.getposition(); %Zombie = new player(){ Datablock = "ZombieArmor"; }; applyskin(%zombie,'Zombie',"Zombie"); %Zombie.setTransform(%Cpos); %zombie.type = 1; %Zombie.team = 0; %zombie.canjump = 1; %zombie.hastarget = 1; AddToZombieGroup(%Zombie); schedule(1000, %zombie, "ZombieLookforTarget", %zombie); } function ZombieLookforTarget(%zombie) { if(!isObject(%zombie)) { return; } if(%Zombie.getState() $= "dead") { freeClientTarget(%zombie); return; } %pos = %zombie.getposition(); %wbpos = %zombie.getworldboxcenter(); %count = ClientGroup.getCount(); %closestClient = -1; %closestDistance = 32767; for(%i = 0; %i < %count; %i++) { %cl = ClientGroup.getObject(%i); if(isObject(%cl.player)){ %testPos = %cl.player.getWorldBoxCenter(); %distance = vectorDist(%wbpos, %testPos); if (%distance > 0 && %distance < %closestDistance && %cl.player.isFTD != 1 && %cl.player.iszombie != 1) { %closestClient = %cl; %closestDistance = %distance; } } } if(%closestClient){ if (%zombie.type == 1) Zombiemovetotarget(%zombie,%closestClient,%closestDistance); else if (%zombie.type == 2) FZombiemovetotarget(%zombie,%closestClient,%closestDistance); else if (%zombie.type == 3) LZombiemovetotarget(%zombie,%closestClient,%closestDistance); else if (%zombie.type == 4) DZombiemovetotarget(%zombie,%closestClient,%closestDistance); else if (%zombie.type == 5) RZombiemovetotarget(%zombie,%closestClient,%closestDistance); } %zombie.ZombieTargeting = schedule(500, %zombie, "ZombieLookForTarget", %zombie); } function Zombiemovetotarget(%zombie,%closestClient,%closestDistance){ %pos = %zombie.getworldboxcenter(); %closestClient = %closestClient.Player; if(%closestDistance <= $zombie::detectDist){ if(%zombie.hastarget != 1){ %zombie.hastarget = 1; } %chance = (getrandom() * 20); if(%chance >= 19) ZDoMoan(%zombie); %clpos = %closestClient.getPosition(); %vector = vectorNormalize(vectorSub(%clpos, %pos)); %v1 = getword(%vector, 0); %v2 = getword(%vector, 1); %nv1 = %v2; %nv2 = (%v1 * -1); %none = 0; %vector2 = %nv1@" "@%nv2@" "@%none; %zombie.setRotation(fullrot("0 0 0",%vector2)); %fmultiplier = $Zombie::ForwardSpeed; if(%closestDistance <= $zombie::lungDist && %zombie.canjump == 1) %fmultiplier = (%fmultiplier * 4); %vector = vectorscale(%vector, %Fmultiplier); %upvec = "150"; if(%closestDistance <= $zombie::lungDist && %zombie.canjump == 1){ %upvec = %upvec * 2; %zombie.canjump = 0; schedule(1500, %zombie, "Zsetjump", %zombie); } %x = Getword(%vector,0); %y = Getword(%vector,1); %z = Getword(%vector,2); if(%z >= 600) %upvec = (%upvec * 5); %vector = %x@" "@%y@" "@%upvec; %zombie.applyImpulse(%pos, %vector); } else if(%zombie.hastarget == 1){ %zombie.hastarget = 0; %zombie.zombieRmove = schedule(100, %zombie, "ZSetRandomMove", %zombie); } } function FZombiemovetotarget(%zombie,%closestClient,%closestDistance){ %pos = %zombie.getworldboxcenter(); %closestClient = %closestClient.Player; if(%closestDistance <= $zombie::detectDist){ if(%zombie.hastarget != 1){ %zombie.hastarget = 1; } %zombie.setActionThread("scoutRoot",true); %upvec = "250"; %fmultiplier = $Zombie::FForwardSpeed; //moanStuff %chance = (getrandom() * 50); if(%chance >= 49) ZDoMoan(%zombie); //Rotation stuff %clpos = %closestClient.getPosition(); %vector = vectorNormalize(vectorSub(%clpos, %pos)); %v1 = getword(%vector, 0); %v2 = getword(%vector, 1); %nv1 = %v2; %nv2 = (%v1 * -1); %none = 0; %vector2 = %nv1@" "@%nv2@" "@%none; %zombie.setRotation(fullrot("0 0 0",%vector2)); //Move Stuff if(%closestDistance <= $zombie::lungDist && %zombie.canjump == 1 && getword(%vector, 2) <= "0.8" ){ %zombie.setvelocity("0 0 0"); %fmultiplier = (%fmultiplier * 2); %upvec = (%upvec * 3.5); %zombie.canjump = 0; schedule(2000, %zombie, "Zsetjump", %zombie); } %vector = vectorscale(%vector, %Fmultiplier); %x = Getword(%vector,0); %y = Getword(%vector,1); %z = Getword(%vector,2); if(%z >= "1200" && %zombie.canjump == 1){ %zombie.setvelocity("0 0 0"); %upvec = (%upvec * 8); %x = (%x * 0.5); %y = (%y * 0.5); %zombie.canjump = 0; schedule(2500, %zombie, "Zsetjump", %zombie); } %vector = %x@" "@%y@" "@%upvec; %zombie.applyImpulse(%pos, %vector); } else if(%zombie.hastarget == 1){ %zombie.hastarget = 0; %zombie.zombieRmove = schedule(100, %zombie, "ZSetRandomMove", %zombie); %zombie.setActionThread("ski",true); } } function LZombiemovetotarget(%zombie,%closestClient,%closestDistance){ %pos = %zombie.getworldboxcenter(); %closestClient = %closestClient.Player; if(%closestDistance <= $zombie::detectDist && %zombie.canmove != 0){ if(%zombie.hastarget != 1){ LZDoYell(%zombie); %zombie.hastarget = 1; } %chance = (getrandom() * 20); if(%chance >= 19) LZDoMoan(%zombie); %clpos = %closestClient.getPosition(); %vector = vectorNormalize(vectorSub(%clpos, %pos)); %nv2 = (getword(%vector, 0) * -1); %nv1 = getword(%vector, 1); %none = 0; %vector2 = %nv1@" "@%nv2@" "@%none; %zombie.setRotation(fullrot("0 0 0",%vector2)); if(%zombie.ATCount >= 20){ %zombie.ATCount = 0; %zombie.nomove = 1; %zombie.Fire = schedule(1250, %zombie, "ZFire", %zombie, %closestClient); %zombie.Charge = schedule(500, %zombie, "ChargeEmitter", %zombie); %zombie.chargecount = 0; } if(%zombie.nomove != 1) { %fmultiplier = $Zombie::LForwardSpeed; %upvec = "150"; if(%closestDistance <= $zombie::LKillDist && %zombie.canjump == 1){ %vec = vectoradd(%pos,vectorScale(%vector,($zombie::LkillDist - 1.6))); %mask = $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::PlayerObjectType; %searchResult = containerRayCast(vectoradd(%pos,vectorScale(%vector,1.6)), %vec, %mask, %zombie); if(%searchResult){ %searchObj = getWord(%searchResult,0); if(%searchObj $= %closestClient){ %chance = getrandom(1,5); if(%chance == 1){ %dir = %zombie.getEyeVector(); %dir = vectornormalize(getword(%dir,0)@" "@getword(%dir,1)@" 0"); %dir = vectoradd(vectorscale(%dir,7500),"0 0 1000"); %closestclient.applyimpulse(%clpos,%dir); %closestclient.damage(0, %clpos, 0.8, $DamageType::ZombieL); } else{ %zombie.setvelocity("0 0 0"); %zombie.canjump = 0; schedule(1000, %zombie, "Zsetjump", %zombie); Llifttarget(%zombie,%closestclient,0); return; } } } } else if(%closestDistance <= ($zombie::LKillDist + $zombie::lungDist)){ %zombie.setvelocity("0 0 0"); %fmultiplier = (%fmultiplier * 2.5); } %vector = vectorscale(%vector, %Fmultiplier); %x = Getword(%vector,0); %y = Getword(%vector,1); %z = Getword(%vector,2); if(%z >= 4000) %upvec = (%upvec * 5); %vector = %x@" "@%y@" "@%upvec; %zombie.applyImpulse(%pos, %vector); %zombie.ATCount++; } } else if(%zombie.hastarget == 1 && %zombie.canmove != 0){ %zombie.hastarget = 0; %zombie.zombieRmove = schedule(100, %zombie, "ZSetRandomMove", %zombie); } } function DZombiemovetotarget(%zombie,%closestClient,%closestDistance){ %pos = %zombie.getworldboxcenter(); %closestClient = %closestClient.Player; if(%closestDistance <= $zombie::detectDist){ if(%zombie.hastarget != 1 && %closestdistance >= 10 && %closestdistance <= 150){ DzombieFire(%zombie,%closestclient); %zombie.canjump = 0; schedule(4000, %zombie, "Zsetjump", %zombie); } if(%zombie.hastarget != 1){ LZDoYell(%zombie); %zombie.hastarget = 1; } %chance = (getrandom() * 20); if(%chance >= 19) LZDoMoan(%zombie); %clpos = %closestClient.getPosition(); %vector = vectorNormalize(vectorSub(%clpos, %pos)); %v1 = getword(%vector, 0); %v2 = getword(%vector, 1); %nv1 = %v2; %nv2 = (%v1 * -1); %none = 0; %vector2 = %nv1@" "@%nv2@" "@%none; %zombie.setRotation(fullrot("0 0 0",%vector2)); if (%closestdistance >= 10 && %closestdistance <= 150 && %zombie.canjump == 1){ DzombieFire(%zombie,%closestclient); %zombie.canjump = 0; schedule(4000, %zombie, "Zsetjump", %zombie); return; } %vector = vectorscale(%vector, $Zombie::DForwardSpeed); %upvec = "150"; %x = Getword(%vector,0); %y = Getword(%vector,1); %z = Getword(%vector,2); if(%z >= ($Zombie::DForwardSpeed / 3 * 2)) %upvec = (%upvec * 5); %vector = %x@" "@%y@" "@%upvec; %zombie.applyImpulse(%pos, %vector); } else if(%zombie.hastarget == 1){ %zombie.hastarget = 0; %zombie.zombieRmove = schedule(100, %zombie, "ZSetRandomMove", %zombie); } } function RZombiemovetotarget(%zombie,%closestClient,%closestDistance){ %pos = %zombie.getworldboxcenter(); %zombie.setActionThread("scoutRoot",true); %closestClient = %closestClient.Player; if(%closestDistance <= $zombie::detectDist){ if(%zombie.wingset == 1){ %zombie.wingset = 0; %Zombie.mountImage(ZWingImage, 3); %Zombie.mountImage(ZWingImage2, 4); } else{ %zombie.wingset = 1; %Zombie.mountImage(ZWingaltImage, 3); %Zombie.mountImage(ZWingaltImage2, 4); } %chance = (getrandom() * 20); if(%chance >= 19) ZDoMoan(%zombie); if(%zombie.iscarrying == 1){ %vector = vectorscale(%zombie.getForwardVector(),($Zombie::RForwardSpeed / 2)); %vector = getword(%vector, 0)@" "@getword(%vector, 1)@" "@($zombie::Rupvec * 1.5); %zombie.applyImpulse(%zombie.getposition(), %vector); return; } %clpos = %closestClient.getWorldBoxCenter(); %vector = vectorNormalize(vectorSub(%clpos, %pos)); %v1 = getword(%vector, 0); %v2 = getword(%vector, 1); %nv1 = %v2; %nv2 = (%v1 * -1); %none = 0; %vector2 = %nv1@" "@%nv2@" "@%none; %zombie.setRotation(fullrot("0 0 0",%vector2)); %z = Getword(%vector,2); %spd = vectorLen(%zombie.getVelocity()); %fallpoint = 0.05 - (%spd / 630); if(%closestdistance <= 15 || %z > (0.25 + %fallpoint) || %z < (-1 * (0.25 + %fallpoint))){ if(%z < 0) %upvec = ($zombie::Rupvec * (%z - (%spd / 130))); if(%z >= 0) %upvec = ($zombie::Rupvec * (%z + 1)); if(%spd <= 5) %vector = vectorScale(%vector,3); } else{ %upvec = $zombie::Rupvec * (%z + 1.2); %spdmod = 1; } if(%z < 0) %z = %z * -1; %Zz = getWord(%zombie.getVelocity(),2); if(%Zz <= -40){ %result = containerRayCast(%pos, vectoradd(%pos,vectorScale("0 0 1",%Zz * 2)), $TypeMasks::StaticShapeObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::TerrainObjectType, %zombie); if(%result) %upvec = $zombie::Rupvec * 5; } %vector = vectorscale(%vector, ($Zombie::RForwardSpeed * (1 - %z))); %x = Getword(%vector,0); %y = Getword(%vector,1); %vector = %x@" "@%y@" "@%upvec; %zombie.applyImpulse(%pos, %vector); } } function ZDoMoan(%zombie){ %chance = (getRandom() * 12); if(%chance <= 11) serverPlay3d("ZombieMoan",%zombie.getWorldBoxCenter()); else serverPlay3d("ZombieHOWL",%zombie.getWorldBoxCenter()); } function LZDoMoan(%zombie){ serverPlay3d("ZombieMoan",%zombie.getWorldBoxCenter()); } function LZDoYell(%zombie){ serverPlay3d("ZombieHOWL",%zombie.getWorldBoxCenter()); } function Zsetjump(%zombie){ %zombie.canjump = 1; } function ChargeEmitter(%zombie){ if(!isobject(%zombie)) return; if(%zombie.chargecount >= 2){ %charge2 = new ParticleEmissionDummy() { position = %zombie.getMuzzlePoint(6); dataBlock = "defaultEmissionDummy"; emitter = "FlameEmitter"; }; MissionCleanup.add(%charge2); %charge2.schedule(100, "delete"); } if(%zombie.chargecount <= 7){ %charge = new ParticleEmissionDummy() { position = %zombie.getMuzzlePoint(5); dataBlock = "defaultEmissionDummy"; emitter = "FlameEmitter"; }; MissionCleanup.add(%charge); %charge.schedule(100, "delete"); } if(%zombie.chargecount <= 9){ %zombie.Fire = schedule(100, %zombie, "ChargeEmitter", %zombie); %zombie.chargecount++; } else %zombie.chargecount = 0; } function ZFire(%zombie, %target){ if(isobject(%zombie) && isobject(%target)){ if(%Zombie.firstFired == 1){ %vec = vectorsub(%target.getworldboxcenter(),%zombie.getMuzzlePoint(6)); %vec = vectoradd(%vec, vectorscale(%target.getvelocity(),vectorlen(%vec)/100)); %zombie.firstFired = 0; %zombie.nomove = 0; %p = new TracerProjectile() { dataBlock = LZombieAcidBall; initialDirection = %vec; initialPosition = %zombie.getMuzzlePoint(6); sourceObject = %zombie; sourceSlot = 6; }; } else{ %vec = vectorsub(%target.getworldboxcenter(),%zombie.getMuzzlePoint(5)); %vec = vectoradd(%vec, vectorscale(%target.getvelocity(),vectorlen(%vec)/100)); %p = new TracerProjectile() { dataBlock = LZombieAcidBall; initialDirection = %vec; initialPosition = %zombie.getMuzzlePoint(5); sourceObject = %zombie; sourceSlot = 5; }; %zombie.firstFired = 1; %zombie.Fire = schedule(250, %zombie, "ZFire", %zombie, %target); } } else{ %zombie.firstFired = 0; %zombie.nomove = 0; } } function Llifttarget(%zombie,%closestclient,%count){ if(%count == 0) %zombie.canmove = 0; if(%closestclient.getState() $= "dead" || %Zombie.getState() $= "dead"){ %zombie.canmove = 1; return; } %target = %closestclient; if(!isobject(%target)){ %zombie.canmove = 1; return; } %pos = %zombie.getworldboxcenter(); %Tpos = %target.getworldboxcenter(); %ZtoT = vectorsub(%tpos,%pos); if (%count <= 12){ %newpos = vectoradd(%ZtoT,vectoradd(%pos,"0 0 -0.6")); %target.setTransform(%newpos); %target.setvelocity("0 0 0"); } else { %killtype = getrandom(1,2); if(%killtype == 1){ %closestwall = 20; %nv2 = (getword(%ZtoT, 0) * -1); %nv1 = getword(%ZtoT, 1); %vector1 = vectorscale(vectornormalize(%nv1@" "@%nv2@" 0"),20); %nvector1 = vectoradd(%tpos,%vector1); %nv2 = getword(%ZtoT, 0); %nv1 = (getword(%ZtoT, 1) * -1); %vector2 = vectorscale(vectornormalize(%nv1@" "@%nv2@" 0"),20); %nvector2 = vectoradd(%tpos,%vector2); %searchresultR = containerRayCast(%tpos, %nvector1, $TypeMasks::StaticShapeObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::VehicleObjectType); %searchresultL = containerRayCast(%tpos, %nvector2, $TypeMasks::StaticShapeObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::VehicleObjectType); if(%searchresultR){ %Hpos = getword(%searchresultR,1)@" "@getword(%searchresultR,2)@" "@getword(%searchresultR,3); %distance = vectordist(%Tpos, %Hpos); if(%distance <= %closestwall){ %closestwall = %distance; %vector = vectoradd(vectorscale(%vector1,1500),"0 0 100"); } } if(%searchresultL){ %Hpos = getword(%searchresultL,1)@" "@getword(%searchresultL,2)@" "@getword(%searchresultL,3); %distance = vectordist(%Tpos, %Hpos); if(%distance <= %closestwall){ %closestwall = %distance; %vector = vectoradd(vectorscale(%vector2,1500),"0 0 100"); } } if(%closestwall == 20){ %x = getword(%ZtoT, 0); %y = getword(%ZtoT, 1); %outvec = vectorscale(vectornormalize(%x@" "@%y@" 0"),50); %vector = vectoradd("0 0 -15000",%outvec); } %target.applyimpulse(%target.getposition(),%vector); } else if(%killtype == 2){ %target.infected = 1; %target.damage(0, %target.getposition(), 10.0, $DamageType::ZombieL); } %count = 0; %zombie.canmove = 1; return; } %count++; %zombie.killingplayer = schedule(150, %zombie, "Llifttarget", %zombie, %closestclient, %count); } function DZombieFire(%zombie,%closestclient){ %pos = %zombie.getMuzzlePoint(4); %tpos = %closestclient.getWorldBoxCenter(); %tvel = %closestclient.getvelocity(); %vec = vectorsub(%tpos,%pos); %dist = vectorlen(%vec); %velpredict = vectorscale(%tvel,(%dist / 50)); %vector = vectoradd(%vec,%velpredict); %ndist = vectorlen(%vector); %upvec = "0 0 "@((%ndist / 50) * (%ndist / 50) * 2); %vector = vectornormalize(vectoradd(%vector,%upvec)); %p = new GrenadeProjectile() { dataBlock = DemonFireball; initialDirection = %vector; initialPosition = %pos; sourceObject = %zombie; sourceSlot = 4; }; } function RkillLoop(%zombie,%target,%count){ if(!isObject(%zombie)){ %zombie.iscarrying = 0; %target.grabbed = 0; return; } if(!isObject(%target)){ %zombie.iscarrying = 0; %target.grabbed = 0; return; } if (%Zombie.getState() $= "dead"){ %zombie.iscarrying = 0; %target.grabbed = 0; return; } if (%target.getState() $= "dead"){ %zombie.iscarrying = 0; %target.grabbed = 0; return; } if(%count == 50){ %chance = getRandom(1,3); if(%chance == 3) %target.damage(0, %tpos, 10.0, $DamageType::Zombie); else{ %target.isFTD = 1; if(%target.getMountedImage($Backpackslot) !$= "") %target.throwPack(); %target.finishingfall = schedule(5000, 0, "stopFTD", %target); } %zombie.iscarrying = 0; return; } %target.setPosition(vectoradd(%zombie.getPosition(),"0 0 -4")); %target.setVelocity(%zombie.getVelocity()); %count++; %zombie.killingplayer = schedule(100, 0, "RkillLoop", %zombie, %target, %count); } function stopFTD(%target){ %target.isFTD = 0; %target.grabbed = 0; } function ZSetRandomMove(%zombie){ if (!isobject(%zombie)) return; %RX = getrandom(-10, 10); %RY = getrandom(-10, 10); %RZ = getrandom(); %vector = %RX@" "@%RY@" "@%RZ; %zombie.direction = vectornormalize(%vector); %zombie.Mnum = getrandom(1, 20); %zombie.zombieRmove = schedule(500, %zombie, "ZrandommoveLoop", %zombie); } function ZrandommoveLoop(%zombie){ if (!isobject(%zombie)) { return; } if (%Zombie.getState() $= "dead") { return; } if (%zombie.hastarget == 1){ %zombie.direction = ""; return; } if (%zombie.Mnum >= 1){ %X = getword(%zombie.direction, 1); %Y = (getword(%zombie.direction, 0) * -1); %none = 0; %vector = %X@" "@%Y@" "@%none; %zombie.setRotation(fullrot("0 0 0",%vector)); if(%zombie.type == 1) %speed = ($zombie::forwardspeed); else if(%zombie.type == 2) %speed = ($zombie::Fforwardspeed * 0.6); else if(%zombie.type == 4) %speed = ($zombie::Dforwardspeed * 0.75); else if(%zombie.type == 3) %speed = ($zombie::Lforwardspeed * 0.8); %vector = vectorscale(%zombie.direction, %speed); %zombie.applyimpulse(%zombie.getposition(), %vector); %zombie.Mnum = (%zombie.Mnum - 1); %zombie.zombieRmove = schedule(500, %zombie, "ZrandommoveLoop", %zombie); } else if(%zombie.Mnum == 0) %zombie.zombieRmove = schedule(100, %zombie, "ZSetRandomMove", %zombie); } function InfectLoop(%obj){ if(%obj.isSentinel) return; if((%obj.armor $= "Pure") || (%obj.armor $= "Light")) { return; } if ($Host::NoInfection) { %obj.Infected = 0; cancel(%obj.infectedDamage); %obj.infectedDamage = ""; %obj.beats = 0; %obj.canZKill = 0; cancel(%player.zombieAttackImpulse); return; } if (%obj.getState() $= "dead") return; if(isObject(%obj)){ if(%obj.beats $= "") zombieAttackImpulse(%obj,0); if(%obj.beats < 15) %obj.setWhiteOut(%obj.beats * 0.05); else %obj.setDamageFlash(1); if(%obj.beats == 15){ %obj.canZkill = 1; } if(%obj.beats >=15) serverPlay3d("ZombieMoan",%obj.getWorldBoxCenter()); else if (%obj.beats >= 10) playDeathCry(%obj); else playPain(%obj); if(%obj.beats == 20){ if($host::canZombie $= "") $host::canZombie = 0; if($host::canZombie == 1) makePersonZombie(%obj.getTransform(), %obj.client, ZombieGetRandom()); else %obj.damage(0, %obj.getposition(), 10.0, $DamageType::Zombie); return; } %obj.beats++; %obj.infectedDamage = schedule(2000, %obj, "InfectLoop", %obj); } } function ZkillUpdateScore(%game, %client,%implement){ if( %implement.getClassName() $= "Turret") %client = %implement.getControllingClient(); else if(%implement.getDataBlock().catagory $= "Vehicles") %client = %implement.getControllingClient(); %client.Zkills++; %game.recalcScore(%client); } function zombieSpawnLoop(%pos, %radius, %freq){ if(ZombieGroup.getCount() >= $Host::MaxZombies && $Host::MaxZombies != -1) return; if(%freq > 10) %freq = 10; if(%freq < 1) %freq = 1; %chance = getRandom(1,50); if(%chance <= %freq && $numspawnedzombies < (%freq * 5)){ %spawnPos = vectorAdd(%pos,(getRandom(0,%radius) - (%radius / 2))@" "@(getRandom(0,%radius) - (%radius / 2))@" getRandom(0,15)"); %search = containerRayCast(%spawnPos, vectorAdd(%spawnPos,"0 0 -1000"), $TypeMasks::StaticShapeObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::TerrainObjectType); if(%search) %spawnPos = getWord(%search,1)@" "@getWord(%search,2)@" "@getWord(%search,3); %chance = getRandom(1,65); if(%chance <= 25){ %Zombie = new player(){ Datablock = "ZombieArmor"; }; applyskin(%zombie,'Zombie',"Zombie"); %Ztype = 1; } else if(%chance <= 35){ %Zombie = new player(){ Datablock = "FZombieArmor"; }; applyskin(%zombie,'Zombie',"Ravenger Zombie"); %Ztype = 2; } else if(%chance <= 40){ %Zombie = new player(){ Datablock = "LordZombieArmor"; }; applyskin(%zombie,'ZLord',"Zombie Lord"); %Zombie.mountImage(ZHead, 3); %Zombie.mountImage(ZBack, 4); %Zombie.mountImage(ZDummyslotImg, 5); %Zombie.mountImage(ZDummyslotImg2, 6); %zombie.firstFired = 0; %zombie.canmove = 1; %Ztype = 3; } else if(%chance <= 55){ %Zombie = new player(){ Datablock = "DemonZombieArmor"; }; applyskin(%zombie,'Zombie',"Demon Zombie"); %zombie.mountImage(ZdummyslotImg, 4); %Ztype = 4; } else if(%chance <= 65){ %Zombie = new player(){ Datablock = "RapierZombieArmor"; }; applyskin(%zombie,'Zombie',"Rapier Zombie"); %Zombie.mountImage(ZWingImage, 3); %Zombie.mountImage(ZWingImage2, 4); %zombie.setActionThread("scoutRoot",true); %Ztype = 5; } %zombie.type = %Ztype; %Zombie.setTransform(%spawnPos); %Zombie.team = 0; %zombie.canjump = 1; %zombie.hastarget = 1; %zombie.randspawnerstarted = 1; AddToZombieGroup(%Zombie); schedule(1000, %zombie, "ZombieLookforTarget", %zombie); $numspawnedzombies++; } $zombieloop = schedule(500, 0, "zombieSpawnLoop", %pos, %radius, %freq); } function StopZombieSpawnLoop(){ cancel($zombieloop); } function ZombieBloodLust(%obj, %count){ if(!isObject(%obj)) return; if (%obj.getState() $= "dead") return; %obj.setDamageFlash(0.5); if(%count == 10){ serverPlay3d("ZombieMoan",%obj.getWorldBoxCenter()); %count = 0; } %count++; schedule(200, %obj, "ZombieBloodLust", %obj, %count); } function makePersonZombie(%trans, %client, %special) { %client.player.delete(); %client.setWeaponsHudClearAll(); if(%special == 1) %data = "ControlLordZombieArmor"; else if(%special == 2) %data = "ControlRapierZombieArmor"; else if(%special == 3) %data = "ControlDemonZombieArmor"; else %data = "ZombieArmor"; %player = new Player() { dataBlock = %data; }; if(%special == 1) { // %player.mountImage(ZHead, 3); %player.mountImage(ZBack, 4); %player.mountImage(ZDummyslotImg, 5); %player.mountImage(ZDummyslotImg2, 6); } else if(%special == 2) { %player.mountImage(ZWingImage, 3); %player.mountImage(ZWingImage2, 4); } %player.setTransform( %trans ); AddToZombieGroup(%player); // setup some info %player.setOwnerClient(%client); %player.team = 0; %client.outOfBounds = false; %player.setEnergyLevel(0); %client.player = %player; // updates client's target info for this player %player.setTarget(%client.target); setTargetDataBlock(%client.target, %player.getDatablock()); setTargetSensorData(%client.target, PlayerSensor); setTargetSensorGroup(%client.target, 1); %client.setSensorGroup(1); %client.setControlObject(%player); %player.client.clearBackpackIcon(); %player.iszombie = 1; if(%special == 1) { %player.setInventory(LordAcidGun, 1, true); %player.use("LordAcidGun"); // Eolk - attempt to fix this problem. } else if(%special == 2) RapierCarryCheck(%player); else if(%special == 3) { %player.setInventory(DZShot, 1, true); %player.use("DZShot"); // Eolk - attempt to fix this problem. } ZombieBloodLust(%player,0); if(!%special) zombieAttackImpulse(%player,80); } // This keeps the rapier-human squatting and acting like a real rapier when carrying someone to die. function RapierCarryCheck(%obj) { if(!isObject(%obj) || %obj.getState() $= "Dead") return; if(%obj.isCarrying == 1) { %vector = VectorScale(%obj.getEyeVector(), $Zombie::RForwardSpeed + %obj.getDatablock().mass); %vector = getword(%vector, 0) SPC getword(%vector, 1) SPC ($Zombie::rupvec * 1.5); %obj.applyImpulse(%obj.position, %vector); } %obj.setActionThread("scoutroot", 1); %obj.RImpulse = schedule(500, 0, "RapierCarryCheck", %obj); } function zombieAttackImpulse(%obj, %count){ if(!isObject(%obj)) { return; } if (%obj.getState() $= "Dead") { return; } %pos = %obj.getposition(); InitContainerRadiusSearch(%pos, %count, $TypeMasks::PlayerObjectType || $TypeMasks::VehicleObjectType); while ((%objtarget = containerSearchNext()) != 0){ if(isObject(%objtarget) && %objtarget !$= %obj){ %objarmortype = %objtarget.getdatablock().getname(); if(%objarmortype $= "ZombieArmor" || %objarmortype $= "FZombieArmor" || %objarmortype $= "LordZombieArmor" || %objarmortype $= "DemonZombieArmor" || %objarmortype $= "ControlDemonZombieArmor" || %objarmortype $= "RapierZombieArmor" || %objarmortype $= "ControlRapierZombieArmor" || %objarmortype $= "ControlLordZombieArmor") %objiszomb = 1; if(!(%objiszomb) && %objtarget.iszombie != 1) { %vec = vectorNormalize(vectorSub(%objtarget.getWorldBoxCenter(),%obj.getWorldBoxCenter())); if(vectorDist(%vec,%obj.getForwardVector()) <= 0.5){ if(%count <= 200){ %impulse = (%count / 20) * 90; %up = (%count / 100) * 90; } else{ %impulse = 900; %up = 180; } %vec = vectorScale(%vec,%impulse); %vec = vectorAdd(%vec,"0 0 "@%up); %obj.applyimpulse(%obj.getPosition(),%vec); %count++; %obj.zombieAttackImpulse = schedule(500, 0, "zombieAttackImpulse", %obj, %count); return; } } } %objiszomb = 0; } %count++; %obj.zombieAttackImpulse = schedule(500, 0, "zombieAttackImpulse", %obj, %count); } function AddToZombieGroup(%player) { if(isObject(%player)) { %group = nameToID("MissionCleanup/ZombieGroup"); if(!isObject(%group)) { %group = new SimGroup("ZombieGroup"); MissionCleanup.add(%group); } %group.add(%player); } } function RemoveFromZombieGroup(%player) { if(isObject(%player)) { %group = nameToID("MissionCleanup/ZombieGroup"); if(!isObject(%group)) { %group = new SimGroup("ZombieGroup"); MissionCleanup.add(%group); } %group.remove(%player); } } //--------------------------------------------------------------------- //------------------------DEMON MOTHER STUFF--------------------------- //--------------------------------------------------------------------- datablock SeekerProjectileData(DMMissile) { casingShapeName = "weapon_missile_casement.dts"; projectileShapeName = "weapon_missile_projectile.dts"; hasDamageRadius = true; indirectDamage = 0.5; damageRadius = 5.0; radiusDamageType = $DamageType::Zombie; kickBackStrength = 2000; explosion = "MissileExplosion"; splash = MissileSplash; velInheritFactor = 1.0; // to compensate for slow starting velocity, this value // is cranked up to full so the missile doesn't start // out behind the player when the player is moving // very quickly - bramage baseEmitter = MortarSmokeEmitter; delayEmitter = MissileFireEmitter; puffEmitter = MissilePuffEmitter; bubbleEmitter = GrenadeBubbleEmitter; bubbleEmitTime = 1.0; exhaustEmitter = MissileLauncherExhaustEmitter; exhaustTimeMs = 300; exhaustNodeName = "muzzlePoint1"; lifetimeMS = 10000; // z0dd - ZOD, 4/14/02. Was 6000 muzzleVelocity = 10.0; maxVelocity = 35.0; // z0dd - ZOD, 4/14/02. Was 80.0 turningSpeed = 23.0; acceleration = 15.0; proximityRadius = 2.5; terrainAvoidanceSpeed = 10; terrainScanAhead = 7; terrainHeightFail = 1; terrainAvoidanceRadius = 3; flareDistance = 40; flareAngle = 20; minSeekHeat = 0.0; sound = MissileProjectileSound; hasLight = true; lightRadius = 5.0; lightColor = "0.2 0.05 0"; useFlechette = true; flechetteDelayMs = 250; casingDeb = FlechetteDebris; explodeOnWaterImpact = false; }; datablock LinearFlareProjectileData(DMPlasma) { doDynamicClientHits = true; directDamage = 0; directDamageType = $DamageType::Zombie; hasDamageRadius = true; indirectDamage = 0.8; // z0dd - ZOD, 4/25/02. Was 0.5 damageRadius = 15.0; kickBackStrength = 1500; radiusDamageType = $DamageType::Zombie; explosion = MortarExplosion; splash = PlasmaSplash; dryVelocity = 85.0; // z0dd - ZOD, 4/25/02. Was 50. Velocity of projectile out of water wetVelocity = -1; velInheritFactor = 1.0; fizzleTimeMS = 4000; lifetimeMS = 2500; // z0dd - ZOD, 4/25/02. Was 6000 explodeOnDeath = true; reflectOnWaterImpactAngle = 0.0; explodeOnWaterImpact = true; deflectionOnWaterImpact = 0.0; fizzleUnderwaterMS = -1; activateDelayMS = 100; scale = "3.0 3.0 3.0"; numFlares = 30; flareColor = "0.1 0.3 1.0"; flareModTexture = "flaremod"; flareBaseTexture = "flarebase"; }; function DemonMotherCreate(%pos){ if(ZombieGroup.getCount() >= $Host::MaxZombies && $Host::MaxZombies != -1) { error("Too many zombies. Cannot create demon mother"); return; } %obj = new player(){ Datablock = "DemonMotherZombieArmor"; }; %obj.setTransform(%pos); %obj.team = 0; MissionCleanup.add(%obj); AddToZombieGroup(%obj); schedule(1000, 0, "DemonMotherInitiate", %obj); // Eolk - Needs to return %obj now return %obj; } function DemonMotherInitiate(%obj){ if(!isObject(%obj)) return; DemonMotherDefense(%obj); DemonMotherThink(%obj); %obj.mountImage(ZdummyslotImg, 4); %obj.justshot = 0; %obj.justmelee = 0; } function DemonMotherThink(%obj){ if(!isObject(%obj)) return; if(%obj.getState() $= "dead") return; %pos = %obj.getposition(); %count = ClientGroup.getCount(); %closestClient = -1; %closestDistance = 32767; for(%i = 0; %i < %count; %i++) { %cl = ClientGroup.getObject(%i); if(isObject(%cl.player)){ %testPos = %cl.player.getWorldBoxCenter(); %distance = vectorDist(%pos, %testPos); if (%distance > 0 && %distance < %closestDistance && %cl.player.isFTD != 1 && %cl.player.iszombie != 1) { %closestClient = %cl; %closestDistance = %distance; } } } if(%closestClient != -1){ %searchobject = %closestclient.player; %dist = vectorDist(%pos,%searchobject.getPosition()); if(%dist <= 100){ if(%dist <= 50){ //ok were now in combat mode, lets decide on what we should do, move attack, or shoot. if(%obj.justmelee == 1){ //if we just used a melee attack, maybe we should follow it up with a shot attack. if(%dist >= 10){ //good were far enough away, lets shoot em. %rand = getrandom(1,3); if(%rand <= 2) DemonMotherSpermAttack(%obj,%searchobject); else DemonMotherFireRainAttack(%obj,%searchobject); } else //damn, to close, ok lung at him DemonMotherLungAttack(%obj,%searchobject); } else{ %rand = getRandom(1,5); //ok so theres 3 good possible attacks here, so lets get a random variable and decide what to do. if(%rand == 1) DemonMotherPlasmaAttack(%obj,%searchobject); else if(%rand <= 3) DemonMotherStrafeAttack(%obj,%searchobject); else DemonMotherFlyAttack(%obj,%searchobject); } } else{ //ok, were to far away, maybe we should shoot at them. if(%obj.justshot == 1) //humm we just attacked, ok, let charge him, get in close DemonMotherChargeIn(%obj,%searchobject); else{ //were good to fire, FIRE AWAY! %rand = getRandom(1,5); //ok so theres 3 good possible attacks here, so lets get a random variable and decide what to do. if(%rand == 1) DemonMotherFireRainAttack(%obj,%searchobject); else if(%rand <= 3) DemonMotherMissileAttack(%obj,%searchobject); else DemonMotherSpermAttack(%obj,%searchobject); } } } else if(%dist > 200){ %rand = getrandom(1,120); if(%rand == 94) //please, dont ask why i choose this number, it just poped in my head DemonMotherDemonSpawn(%obj); else DemonMotherMoveToTarget(%obj,%searchobject); } else DemonMotherMoveToTarget(%obj,%searchobject); %obj.justshot = 0; %obj.justmelee = 0; } else{ schedule(500, 0, "DemonMotherThink", %obj); } } function DemonMotherDefense(%obj){ if(!isObject(%obj)) return; if(%obj.getState() $= "dead") return; %pos = %obj.getposition(); InitContainerRadiusSearch(%pos, 250, $TypeMasks::ProjectileObjectType); while ((%searchObject = containerSearchNext()) != 0){ %projpos = %searchobject.getPosition(); %dist = vectorDist(%pos,%projpos); if(%dist <= 100){ if(%searchobject.lastpos) %searchobject.delete(); } else %searchobject.lastpos = %projpos; } schedule(50, "DemonMotherDefense", %obj); } function DemonMotherSpermAttack(%obj,%target){ if(!isObject(%obj)) return; if(%obj.getState() $= "dead") return; if(!isObject(%target)){ DemonMotherThink(%obj); return; } FaceTarget(%obj,%target); if(%obj.chargecount $= "") %obj.chargecount = 0; %charge = new ParticleEmissionDummy() { position = %obj.getMuzzlePoint(4); dataBlock = "defaultEmissionDummy"; emitter = "FlameEmitter"; }; MissionCleanup.add(%charge); %charge.schedule(100, "delete"); if(%obj.chargecount == 7){ %vec = vectorsub(%target.getworldboxcenter(),%obj.getMuzzlePoint(4)); %vec = vectoradd(%vec, vectorscale(%target.getvelocity(),vectorlen(%vec)/100)); %p = new TracerProjectile() { dataBlock = LZombieAcidBall; initialDirection = %vec; initialPosition = %obj.getMuzzlePoint(4); sourceObject = %obj; sourceSlot = 6; }; } if(%obj.chargecount == 9){ %vec = vectorsub(%target.getworldboxcenter(),%obj.getMuzzlePoint(4)); %vec = vectoradd(%vec, vectorscale(%target.getvelocity(),vectorlen(%vec)/100)); %p = new TracerProjectile() { dataBlock = LZombieAcidBall; initialDirection = %vec; initialPosition = %obj.getMuzzlePoint(4); sourceObject = %obj; sourceSlot = 6; }; } if(%obj.chargecount <= 9){ schedule(100, 0, "DemonMotherSpermAttack", %obj, %target); %obj.chargecount++; } else{ %obj.chargecount = 0; %obj.justshot = 1; DemonMotherThink(%obj); } } function DemonMotherLungAttack(%obj,%target){ FaceTarget(%obj,%target); %vector = vectorNormalize(vectorSub(%target.getPosition(), %obj.getPosition())); %vector = vectorscale(%vector, 4000); %x = Getword(%vector,0); %y = Getword(%vector,1); %z = Getword(%vector,2); %vector = %x@" "@%y@" 400"; %obj.applyImpulse(%obj.getPosition(), %vector); %obj.justmelee = 1; schedule(750, 0, "DemonMotherThink", %obj); } function DemonMotherStrafeAttack(%obj,%target){ if(!isObject(%obj)) return; if(%obj.getState() $= "dead") return; if(%obj.chargecount $= "") %obj.chargecount = 0; if(%obj.chargecount <= 8){ %obj.setVelocity("0 0 0"); FaceTarget(%obj,%target); %vector = vectorNormalize(vectorSub(%target.getPosition(), %obj.getPosition())); %vector = vectorscale(%vector, 3250); %x = Getword(%vector,0); %y = Getword(%vector,1); %nv1 = %y; %nv2 = (%x * -1); %vector = %nv1@" "@%nv2@" 0"; %obj.applyImpulse(%obj.getPosition(), %vector); } else if(%obj.chargecount <= 11){ %obj.setvelocity("0 0 0"); FaceTarget(%obj,%target); %vector = vectorNormalize(vectorSub(%target.getPosition(), %obj.getPosition())); %vector = vectorscale(%vector, 4500); %x = Getword(%vector,0); %y = Getword(%vector,1); %z = Getword(%vector,2); %vector = %x@" "@%y@" 150"; %obj.applyImpulse(%obj.getPosition(), %vector); } else{ %obj.chargecount = 0; %obj.justmelee = 1; schedule(250, 0, "DemonMotherThink", %obj); return; } schedule(250, 0, "DemonMotherStrafeAttack", %obj, %target); %obj.chargecount++; } function DemonMotherFlyAttack(%obj,%target){ if(!isObject(%obj)) return; if(%obj.getState() $= "dead") return; if(%obj.chargecount $= "") %obj.chargecount = 0; if(%obj.chargecount <= 9){ FaceTarget(%obj,%target); %obj.setvelocity("0 0 10"); %obj.chargecount++; schedule(100, 0, "DemonMotherFlyAttack",%obj,%target); } else if(%obj.chargecount == 10){ FaceTarget(%obj,%target); %obj.setvelocity("0 0 5"); %vector = vectorSub(%target.getPosition(),%obj.getPosition()); %nVec = vectorNormalize(%vector); %vector = vectorAdd(%vector,vectorscale(%nvec,-4)); %obj.attackpos = vectorAdd(%obj.getPosition(),%vector); %obj.attackdir = %nVec; // echo(%obj.getPosition() SPC %target.getPosition() SPC %obj.attackpos SPC %obj.attackdir); %obj.startFade(400, 0, true); %obj.chargecount++; schedule(400, 0, "DemonMotherFlyAttack",%obj,%target); } else if(%obj.chargecount >= 11){ %obj.startFade(500, 0, false); %obj.setPosition(%obj.attackpos); %obj.setvelocity(vectorscale(%obj.attackdir,25)); %obj.justmelee = 1; %obj.chargecount = 0; // echo(%obj.getPosition() SPC %target.getPosition() SPC %obj.attackpos SPC %obj.attackdir); %obj.attackpos = ""; %obj.attackdir = ""; schedule(1000, 0, "DemonMotherThink",%obj); } } function DemonMotherFireRainAttack(%obj,%target){ if(!isObject(%obj)) return; if(%obj.getState() $= "dead") return; if(%obj.chargecount $= "") %obj.chargecount = 0; if(%obj.chargecount == 0){ FaceTarget(%obj, %target); for(%i = 0; %i < 10; %i++){ %pos = %obj.getPosition(); %x = getRandom(0,10) - 5; %y = getRandom(0,10) - 5; %vec = vectorAdd(%pos,%x SPC %y SPC "5"); %searchResult = containerRayCast(%vec, vectorAdd(%vec,"0 0 -10"), $TypeMasks::TerrainObjectType, %obj); %charge = new ParticleEmissionDummy() { position = posFromRaycast(%searchresult); dataBlock = "defaultEmissionDummy"; emitter = "FlameEmitter"; }; MissionCleanup.add(%charge); %charge.schedule(1500, "delete"); } %obj.chargecount++; schedule(1000, 0, "DemonMotherFireRainAttack",%obj,%target); } else{ %x = (getRandom() * 2) - 1; %y = (getRandom() * 2) - 1; %z = getRandom(); %vec = vectorNormalize(%x SPC %y SPC %z); %pos = vectorAdd(%target.getPosition(),vectorScale(%vec, 20)); for(%i = 0;%i < 10;%i++){ %x = getRandom(0,14) - 7; %y = getRandom(0,14) - 7; %spwpos = vectorAdd(%pos,%x SPC %y SPC "2"); %p = new GrenadeProjectile() { dataBlock = DemonFireball; initialDirection = vectorScale(%vec,-1); initialPosition = %spwpos; sourceObject = %obj; sourceSlot = 4; }; } %obj.justshot = 1; %obj.chargecount = 0; schedule(1000, 0, "DemonMotherThink",%obj); } } function DemonMotherMissileAttack(%obj,%target){ if(!isObject(%obj)) return; if(%obj.getState() $= "dead") return; if(%obj.chargecount $= "") %obj.chargecount = 0; if(%obj.chargecount == 0){ %obj.chargecount++; schedule(1000, 0, "DemonMotherMissileAttack", %obj, %target); } else{ %vec = vectorNormalize(vectorSub(%target.getPosition(),%obj.getPosition())); %p = new SeekerProjectile() { dataBlock = DMMissile; initialDirection = %vec; initialPosition = %obj.getMuzzlePoint(4); sourceObject = %obj; sourceSlot = 4; }; %beacon = new BeaconObject() { dataBlock = "SubBeacon"; beaconType = "vehicle"; position = %target.getWorldBoxCenter(); }; %beacon.team = 0; %beacon.setTarget(0); MissionCleanup.add(%beacon); %p.setObjectTarget(%beacon); DemonMotherMissileFollow(%target,%beacon,%p); %obj.justshot = 1; %obj.chargecount = 0; schedule(1000, 0, "DemonMotherThink", %obj); } } function DemonMotherMissileFollow(%target,%beacon,%missile){ if(!isObject(%target)){ %beacon.delete(); return; } if(!isObject(%missile)){ %beacon.delete(); return; } %beacon.setPosition(%target.getWorldBoxCenter()); schedule(100, 0, "DemonMotherMissileFollow", %target, %beacon, %missile); } function DemonMotherPlasmaAttack(%obj,%target){ if(!isObject(%obj)) return; if(%obj.getState() $= "dead") return; if(%obj.chargecount $= "") %obj.chargecount = 0; if(%obj.chargecount <= 9){ %obj.setVelocity("0 0 10"); %obj.chargecount++; schedule(100, 0, "DemonMotherPlasmaAttack", %obj, %target); } else{ %obj.setVelocity("0 0 3"); %vec = vectorNormalize(vectorSub(%target.getPosition(),%obj.getPosition())); %p = new LinearFlareProjectile() { dataBlock = DMPlasma; initialDirection = %vec; initialPosition = %obj.getMuzzlePoint(4); sourceObject = %obj; sourceSlot = 4; }; %obj.chargecount = 0; %obj.justshot = 1; schedule(1000, 0, "DemonMotherThink", %obj); } } function DemonMotherChargeIn(%obj,%target){ if(!isObject(%obj)) return; if(%obj.getState() $= "dead") return; if(%obj.chargecount $= "") %obj.chargecount = 0; if(%obj.chargecount <= 4){ FaceTarget(%obj, %target); %vec = vectorNormalize(vectorSub(%target.getPosition(),%obj.getPosition())); %obj.setvelocity(vectorScale(%vec,50)); %obj.chargecount++; schedule(500, 0, "DemonMotherChargeIn", %obj, %target); } else{ %obj.justmelee = 1; %obj.chargecount = 0; DemonMotherThink(%obj); } } function DemonMotherMoveToTarget(%obj,%target){ FaceTarget(%obj,%target); %vector = vectorNormalize(vectorSub(%target.getPosition(), %obj.getPosition())); %vector = vectorscale(%vector, 1200); %x = Getword(%vector,0); %y = Getword(%vector,1); %z = Getword(%vector,2); %vector = %x@" "@%y@" 150"; %obj.applyImpulse(%obj.getPosition(), %vector); schedule(500, 0, "DemonMotherThink", %obj); } function DemonMotherDemonSpawn(%obj){ for(%i = 0; %i < 5; %i++){ %pos = %obj.getPosition(); %x = getRandom(0,200) - 100; %y = getRandom(0,200) - 100; %vec = vectorAdd(%pos,%x SPC %y SPC "40"); %searchResult = containerRayCast(%vec, vectorAdd(%vec,"0 0 -80"), $TypeMasks::TerrainObjectType, %obj); %charge = new ParticleEmissionDummy() { position = posFromRaycast(%searchresult); dataBlock = "defaultEmissionDummy"; emitter = "FlameEmitter"; }; MissionCleanup.add(%charge); %charge.schedule(1100, "delete"); schedule(1000, 0, "startAzombie", posFromRaycast(%searchresult), 4); } schedule(1500, 0, "DemonMotherThink", %obj); } function FaceTarget(%obj,%target){ %vector = vectorNormalize(vectorSub(%target.getPosition(), %obj.getPosition())); %v1 = getword(%vector, 0); %v2 = getword(%vector, 1); %nv1 = %v2; %nv2 = (%v1 * -1); %vector2 = %nv1@" "@%nv2@" 0"; %obj.setRotation(fullrot("0 0 0",%vector2)); }