Shifter Zombies, Other Misc Changes

Upgraded the shifter zombie type to the new AI script style, added in
additional flags to zombieCore.cs and moved the zombie moan functioning
to the zombieCore file for easier modification across all types.
This commit is contained in:
Robert Fritzen 2017-12-20 11:39:43 -06:00
parent f7095e8823
commit f4c2eeabc6
8 changed files with 153 additions and 120 deletions

View file

@ -22,6 +22,24 @@ datablock AudioProfile(ZombieHOWL) {
preload = true;
};
datablock AudioProfile(ZombieDeathSound1) {
filename = "voice/Derm3/avo.deathcry_01.wav";
description = AudioClose3d;
preload = true;
};
datablock AudioProfile(ZombieDeathSound2) {
filename = "voice/Derm2/avo.deathcry_01.wav";
description = AudioClose3d;
preload = true;
};
datablock AudioProfile(ZombieDeathSound3) {
filename = "voice/Derm1/avo.deathcry_01.wav";
description = AudioClose3d;
preload = true;
};
//**********************************************
// PARTICLE DATABLOCKS
//**********************************************

View file

@ -85,8 +85,21 @@ $Zombie::DemonZombieFireBombMaxRange = 250;
//$Zombie::RapierUpwardScaling: How fast a rapier zombie will ascend when holding a player
$Zombie::RapierUpwardScaling = 750;
//$Zombie::DemonLord_FireLunge_Thrust: The velocity scalar of the thrust associated with the fire lunge attack
$Zombie::DemonLord_FireLunge_Thrust = 4000;
//$Zombie::DemonLord_FireLunge_MinimumRange: The minimum range following the burst of speed to trigger the fire explosion
$Zombie::DemonLord_FireLunge_MinimumRange = 10;
//$Zombie::DemonLord_FirestormTrigger: How long in miliseconds between the firestorm charge up and the attack itself
$Zombie::DemonLord_FirestormTrigger = 1000;
//$Zombie::DemonLord_MinionSpawnChance: The chance scalar associated with the minion summon attack (The larger this number, the less likely)
$Zombie::DemonLord_MinionSpawnChance = 120;
//$Zombie::Shifter_Teleport_MaximumRange: The maximum range at which a shifter is allowed to teleport from
$Zombie::Shifter_Teleport_MaximumRange = 400;
//$Zombie::Shifter_Teleport_PrepTime: The amount of time (in ms) that it takes for the shifter to lock down before teleporting
$Zombie::Shifter_Teleport_PrepTime = 1500;
//$Zombie::Shifter_Teleport_Cooldown: The cooldown between each teleport
$Zombie::Shifter_Teleport_Cooldown = 12500;
//MISC Globals, Do not edit.
$Zombie::killpoints = 5;
@ -124,9 +137,31 @@ function TWM2Lib_Zombie_Core(%functionName, %arg1, %arg2, %arg3, %arg4) {
%final = %speed * %multiplier;
return %final;
//playzaudio(%zombie, %chanceToPlay, %chanceHowl): Plays the moaning sounds associated with zombies
case "playzaudio":
if(!isObject(%arg1) || %arg1.getState() $= "dead") {
return;
}
if(!isSet(%arg2)) {
%arg2 = 50;
}
if(!isSet(%arg3)) {
%arg3 = 35;
}
%chance = (getrandom() * %arg2);
if(%chance >= (%arg2 - 1)) {
%chance = (getRandom() * %arg3);
if(%chance <= (%arg3 - 1)) {
serverPlay3d("ZombieMoan", %arg1.getWorldBoxCenter());
}
else {
serverPlay3d("ZombieHOWL", %arg1.getWorldBoxCenter());
}
}
//zsetrandommove(%zombie): Activated when the zombie needs to begin random movement
case "zsetrandommove":
if(!isObject(%arg1)) {
if(!isObject(%arg1) || arg1.getState() $= "dead") {
return;
}
%rx = getRandom(-10, 10);
@ -649,27 +684,4 @@ function TWM2Lib_Zombie_Core(%functionName, %arg1, %arg2, %arg3, %arg4) {
%zombie.getDatablock().AI(%zombie);
return %zombie;
}
}
//-----------------------------------------------------------
//DEATH
datablock AudioProfile(ZombieDeathSound1)
{
filename = "voice/Derm3/avo.deathcry_01.wav";
description = AudioClose3d;
preload = true;
};
datablock AudioProfile(ZombieDeathSound2)
{
filename = "voice/Derm2/avo.deathcry_01.wav";
description = AudioClose3d;
preload = true;
};
datablock AudioProfile(ZombieDeathSound3)
{
filename = "voice/Derm1/avo.deathcry_01.wav";
description = AudioClose3d;
preload = true;
};
}

View file

@ -161,9 +161,8 @@ function DemonMotherZombieArmor::AIRoutine(%datablock, %zombie) {
}
}
else if(%dist > 100) {
%rand = getrandom(1,120);
//please, dont ask why i choose this number, it just popped in my head
if(%rand == 94) {
%rand = getRandom(1, $Zombie::DemonLord_MinionSpawnChance);
if(%rand == (($Zombie::DemonLord_MinionSpawnChance / 2) + 1)) {
%datablock.AttackFunction(%zombie, "SpawnZombies");
}
else {
@ -253,7 +252,7 @@ function DemonMotherZombieArmor::AttackFunction(%datablock, %zombie, %attackFunc
if(%zombie.chargeCount == 0) {
TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %target.getPosition());
%vector = vectorNormalize(vectorSub(%target.getPosition(), %zombie.getPosition()));
%vector = vectorscale(%vector, 4000);
%vector = vectorscale(%vector, $Zombie::DemonLord_FireLunge_Thrust);
%x = Getword(%vector, 0);
%y = Getword(%vector, 1);
%z = Getword(%vector, 2);
@ -272,7 +271,7 @@ function DemonMotherZombieArmor::AttackFunction(%datablock, %zombie, %attackFunc
%zombie.attackFunction = %datablock.schedule(300, 0, "AttackFunction", %zombie, %attackFunction, %target);
}
else {
if(vectorDist(%zombie.getPosition(), %target.getPosition()) < 10) {
if(vectorDist(%zombie.getPosition(), %target.getPosition()) < $Zombie::DemonLord_FireLunge_MinimumRange) {
%p = new TracerProjectile() {
dataBlock = napalmSubExplosion;
initialDirection = "0 0 -10";
@ -328,7 +327,7 @@ function DemonMotherZombieArmor::AttackFunction(%datablock, %zombie, %attackFunc
if(%zombie.chargecount $= "") {
%zombie.chargecount = 0;
}
if(%zombie.chargecount <= 9){
if(%zombie.chargecount <= 9) {
TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %target.getPosition());
%zombie.setvelocity("0 0 10");
%zombie.chargecount++;
@ -346,7 +345,7 @@ function DemonMotherZombieArmor::AttackFunction(%datablock, %zombie, %attackFunc
%zombie.chargecount++;
%zombie.attackFunction = %datablock.schedule(400, 0, "AttackFunction", %zombie, %attackFunction, %target);
}
else if(%zombie.chargecount >= 11){
else if(%zombie.chargecount >= 11) {
%zombie.startFade(500, 0, false);
%zombie.setPosition(%zombie.attackpos);
%zombie.setvelocity(vectorscale(%zombie.attackdir, 25));

View file

@ -65,7 +65,7 @@ function ZombieArmor::armorCollisionFunction(%datablock, %zombie, %colPlayer) {
function ZombieArmor::AI(%datablock, %zombie) {
//Normal zombies do not employ any "AI" other than target and move, fork off to main move function
%datablock.Move(%zombie);
%zombie.moveloop = %datablock.Move(%zombie);
}
function ZombieArmor::Move(%datablock, %zombie) {
@ -80,16 +80,7 @@ function ZombieArmor::Move(%datablock, %zombie) {
if(%zombie.hastarget != 1) {
%zombie.hastarget = 1;
}
%chance = (getrandom() * 20);
if(%chance >= 19) {
%chance = (getRandom() * 12);
if(%chance <= 11) {
serverPlay3d("ZombieMoan", %zombie.getWorldBoxCenter());
}
else {
serverPlay3d("ZombieHOWL", %zombie.getWorldBoxCenter());
}
}
TWM2Lib_Zombie_Core("playZAudio", %zombie, 100, 40);
%vector = TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %closestClient.getPosition());
if(Game.CheckModifier("SuperLunge") == 1) {

View file

@ -128,16 +128,7 @@ function RapierZombieArmor::move(%datablock, %zombie) {
%Zombie.mountImage(ZWingaltImage, 3);
%Zombie.mountImage(ZWingaltImage2, 4);
}
%chance = (getrandom() * 20);
if(%chance >= 19) {
%chance = (getRandom() * 12);
if(%chance <= 11) {
serverPlay3d("ZombieMoan", %zombie.getWorldBoxCenter());
}
else {
serverPlay3d("ZombieHOWL", %zombie.getWorldBoxCenter());
}
}
TWM2Lib_Zombie_Core("playZAudio", %zombie, 20, 12);
if(%zombie.iscarrying == 1) {
%vector = vectorscale(%zombie.getForwardVector(), (%zombie.speed / 2));
%vector = getword(%vector, 0)@" "@getword(%vector, 1)@" "@($Zombie::RapierUpwardScaling * 1.5);

View file

@ -132,16 +132,7 @@ function RavagerZombieArmor::Move(%datablock, %zombie) {
%pos = %zombie.getWorldBoxCenter();
%upVec = "250";
//moanStuff
%chance = (getrandom() * 50);
if(%chance >= 49) {
%chance = (getRandom() * 12);
if(%chance <= 11) {
serverPlay3d("ZombieMoan", %zombie.getWorldBoxCenter());
}
else {
serverPlay3d("ZombieHOWL", %zombie.getWorldBoxCenter());
}
}
TWM2Lib_Zombie_Core("playZAudio", %zombie, 250, 40);
//Determine target location
if(%zombie.ambushing) {
%vector = TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %zombie.ambushPosition);

View file

@ -1,3 +1,5 @@
$TWM2::ArmorHasCollisionFunction[ShifterZombieArmor] = true;
datablock PlayerData(ShifterZombieArmor) : LightMaleHumanArmor {
runForce = 60.20 * 90;
runEnergyDrain = 0.0;
@ -34,63 +36,87 @@ datablock PlayerData(ShifterZombieArmor) : LightMaleHumanArmor {
max[Grenade] = 0;
};
function ShifterZombiemovetotarget(%zombie){
if(!isobject(%Zombie))
return;
if(%Zombie.getState() $= "dead")
return;
%pos = %zombie.getworldboxcenter();
%closestClient = ZombieLookForTarget(%zombie);
%closestDistance = getWord(%closestClient,1);
%closestClient = getWord(%closestClient,0).Player;
if(%closestDistance <= $zombie::detectDist){
if(%zombie.hastarget != 1){
%zombie.hastarget = 1;
function ShifterZombieArmor::armorCollisionFunction(%datablock, %zombie, %colPlayer) {
if(!isObject(%zombie) || %zombie.getState() $= "dead") {
return;
}
%chance = (getrandom() * 20);
if(%chance >= 19) {
%chance = (getRandom() * 12);
if(%chance <= 11)
serverPlay3d("ZombieMoan",%zombie.getWorldBoxCenter());
else
serverPlay3d("ZombieHOWL",%zombie.getWorldBoxCenter());
}
%vector = ZgetFacingDirection(%zombie,%closestClient,%pos);
%fmultiplier = $Zombie::ForwardSpeed;
if(%closestDistance <= $zombie::lungDist && %zombie.canjump == 1)
%fmultiplier = (%fmultiplier * 4);
%vector = vectorscale(%vector, %Fmultiplier);
%upvec = "150";
//tis shift timez :)
if(%closestDistance > 200 || (%zombie.getVelocity() == 0 && !%zombie.RecentShift)) {
%zombie.setMoveState(true);
%zombie.startFade(1500, 0, true);
%zombie.schedule(1600, "SetPosition", VectorAdd(%closestClient.getPosition(), vectorAdd("0 0 3", TWM2Lib_MainControl("getRandomPosition", "5\t1"))));
%zombie.startFade(1750, 0, false);
%zombie.schedule(2000, setMoveState, false);
%zombie.RecentShift = 1;
Schedule(10500, 0, "eval", ""@%zombie@".RecentShift=0;");
}
if(%closestDistance <= $zombie::lungDist && %zombie.canjump == 1){
%upvec = %upvec * 2;
%zombie.canjump = 0;
schedule(1500, %zombie, "Zsetjump", %zombie);
if(!isObject(%colPlayer) || %colPlayer.getState() $= "dead") {
return;
}
%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);
}
%zombie.moveloop = schedule(500, %zombie, "ShifterZombiemovetotarget", %zombie);
//Check to make sure we're not hitting another zombie / boss
if(%colPlayer.isBoss || %colPlayer.isZombie || %colPlayer.rapierShield) {
return;
}
//Damage.
%causeInfect = %zombie.damage_infectOnTouch;
%baseDamage = %zombie.damage_amountOnTouch;
%multiplier = %zombie.damage_alreadyInfectedMultiplier;
%total = %colPlayer.infected ? (%baseDamage * %multiplier) : %baseDamage;
%pushVector = vectorscale(%colPlayer.getvelocity(), 100);
%colPlayer.applyimpulse(%colPlayer.getposition(), %pushVector);
if(%causeInfect) {
%colPlayer.Infected = 1;
%colPlayer.InfectedLoop = schedule(10, %colPlayer, "TWM2Lib_Zombie_Core", "InfectLoop", %colPlayer, "impact");
}
%colPlayer.damage(0, %colPlayer.getPosition(), %total, $DamageType::Zombie);
}
function ShifterZombieArmor::AI(%datablock, %zombie) {
//Shifter zombies do not employ any "AI" other than target and move, fork off to main move function
%zombie.moveloop = %datablock.Move(%zombie);
}
function ShifterZombieArmor::Move(%datablock, %zombie) {
if(!isObject(%zombie) || %zombie.getState() $= "dead") {
return;
}
%pos = %zombie.getWorldBoxCenter();
%closestClient = TWM2Lib_Zombie_Core("lookForTarget", %zombie);
%closestDistance = getWord(%closestClient, 1);
%closestClient = getWord(%closestClient, 0).Player;
if(%closestDistance <= $zombie::detectDist) {
if(%zombie.hastarget != 1) {
%zombie.hastarget = 1;
}
TWM2Lib_Zombie_Core("playZAudio", %zombie, 100, 40);
%vector = TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %closestClient.getPosition());
if(%closestDistance <= $Zombie::LungeDistance && %zombie.canjump == 1) {
%vector = vectorScale(%vector, 4);
}
%vector = vectorScale(%vector, %zombie.speed);
%upvec = "150";
//tis shift timez :)
if(%closestDistance > $Zombie::Shifter_Teleport_MaximumRange || (%zombie.getVelocity() == 0 && !%zombie.RecentShift)) {
%zombie.setMoveState(true);
%zombie.startFade($Zombie::Shifter_Teleport_PrepTime, 0, true);
%zombie.schedule($Zombie::Shifter_Teleport_PrepTime + 100, "SetPosition", VectorAdd(%closestClient.getPosition(), vectorAdd("0 0 3", TWM2Lib_MainControl("getRandomPosition", "5\t1"))));
%zombie.startFade($Zombie::Shifter_Teleport_PrepTime + 250, 0, false);
%zombie.schedule($Zombie::Shifter_Teleport_PrepTime + 350, setMoveState, false);
TWM2Lib_Zombie_Core("setZFlag", %zombie, "recentShift", 1);
schedule($Zombie::Shifter_Teleport_Cooldown, 0, TWM2Lib_Zombie_Core, "setZFlag", %zombie, "recentShift", 0);
}
if(%closestDistance <= $Zombie::LungeDistance && %zombie.canjump == 1) {
%upvec *= 2;
TWM2Lib_Zombie_Core("setZFlag", %zombie, "canJump", 0);
schedule($Zombie::BaseJumpCooldown, 0, TWM2Lib_Zombie_Core, "setZFlag", %zombie, "canJump", 1);
}
%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(%zombie.updateTimeFrequency, %zombie, "TWM2Lib_Zombie_Core", "zRandomMoveLoop", %zombie);
}
%zombie.moveloop = %datablock.schedule(%zombie.updateTimeFrequency, %datablock, "Move", %zombie);
}