From 5106a3fbffff3f13a0757c242d7df8417dd8be8e Mon Sep 17 00:00:00 2001 From: Robert Fritzen Date: Tue, 17 Oct 2017 16:12:59 -0500 Subject: [PATCH] Air Rapier Zombies Added the new AI capabilities to air rapiers. They will still function just like before. Missile damage has been increased. --- README.md | 2 + scripts/TWM2/Zombie/ZombieCore.cs | 9 +- scripts/TWM2/Zombie/ZombieTypes/Rapier.cs | 316 +++++++++++----------- scripts/player.cs | 2 +- 4 files changed, 160 insertions(+), 169 deletions(-) diff --git a/README.md b/README.md index 64cfa30..2b9de9f 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,8 @@ PLEASE NOTE: I've moved all old changelogs into the version_history folder. This * Replaced the acid cannon with an anti-tank photon cannon * Zombie lords will now preferential target enemy ground armor before infantry, and engage their photon cannon on targets * Zombie lords can now activate a defensive barrier to protect themselves and allies from damage temporarily... enjoy this new rage inducing mechanic :) + * Air Rapier + * Modified the damage scalar of missiles to be a OHK on rapier zombies * Added Boss Proficiency * Hidden challenges embedded in boss fights that award additional experience for completing tough feats * For example: Defeat the shade lord without dying by the elemental shades diff --git a/scripts/TWM2/Zombie/ZombieCore.cs b/scripts/TWM2/Zombie/ZombieCore.cs index afa69d4..9efa106 100644 --- a/scripts/TWM2/Zombie/ZombieCore.cs +++ b/scripts/TWM2/Zombie/ZombieCore.cs @@ -23,7 +23,7 @@ $Zombie::BaseSpeed = 150; $Zombie::TypeSpeed[2] = 300; $Zombie::TypeSpeed[3] = 4000; $Zombie::TypeSpeed[4] = 240; -$Zombie::TypeSpeed[5] = 300; +$Zombie::TypeSpeed[5] = 1500; //$Zombie::BaseJumpCooldown: The time zombies must elapse before jumping / lunging $Zombie::BaseJumpCooldown = 1500; @@ -37,6 +37,7 @@ $Zombie::SpeedMultiplier[4] = 0.75; $Zombie::BaseSpeedUpdateTime = 100; //$Zombie::SpeedUpdateTime[#]: An override to the base update type, use for specific types that need slower or faster processing between AI steps $Zombie::SpeedUpdateTime[3] = 500; +$Zombie::SpeedUpdateTime[5] = 500; //$Zombie::LungeDistance: How far (m) a zombie must be to lunge at a target $Zombie::LungeDistance = 10; @@ -436,15 +437,15 @@ function TWM2Lib_Zombie_Core(%functionName, %arg1, %arg2, %arg3, %arg4) { %zombie.mountImage(ZDummyslotImg2, 6); %zombie.mountImage(zLordPhotonCannonImg, 7); %zombie.canFireWeapon = 1; - %zombie.canShield = 1; - %zombie.canmove = 1; + %zombie.canShield = 1; //Demon Zombie case 4: %zombie = new player() { Datablock = "DemonZombieArmor"; }; - %zombie.mountImage(ZdummyslotImg, 4); + %zombie.mountImage(ZdummyslotImg, 4); + %zombie.canFireWeapon = 1; //Air-Rapier Zombie case 5: diff --git a/scripts/TWM2/Zombie/ZombieTypes/Rapier.cs b/scripts/TWM2/Zombie/ZombieTypes/Rapier.cs index 0371ebc..03d2260 100644 --- a/scripts/TWM2/Zombie/ZombieTypes/Rapier.cs +++ b/scripts/TWM2/Zombie/ZombieTypes/Rapier.cs @@ -1,188 +1,176 @@ -datablock PlayerData(RapierZombieArmor) : LightMaleBiodermArmor -{ - maxDamage = 1.0; - minImpactSpeed = 50; - speedDamageScale = 0.015; - maxEnergy = 80; - repairRate = 0.0033; - energyPerDamagePoint = 75.0; // shield energy required to block one point of damage +datablock PlayerData(RapierZombieArmor) : LightMaleBiodermArmor { + maxDamage = 1.0; + minImpactSpeed = 50; + speedDamageScale = 0.015; + maxEnergy = 80; + repairRate = 0.0033; + energyPerDamagePoint = 75.0; // shield energy required to block one point of damage - rechargeRate = 0.256; - jetForce = 25.22 * 130 * 1.5; - underwaterJetForce = 25.22 * 130 * 1.5; - underwaterVertJetFactor = 1.5; - jetEnergyDrain = 1.0; - underwaterJetEnergyDrain = 0.6; - minJetEnergy = 1; - maxJetHorizontalPercentage = 0.8; + rechargeRate = 0.256; + jetForce = 25.22 * 130 * 1.5; + underwaterJetForce = 25.22 * 130 * 1.5; + underwaterVertJetFactor = 1.5; + jetEnergyDrain = 1.0; + underwaterJetEnergyDrain = 0.6; + minJetEnergy = 1; + maxJetHorizontalPercentage = 0.8; - boundingBox = "2.0 2.0 1.2"; - - damageScale[$DamageType::M1700] = 2.0; + boundingBox = "2.0 2.0 1.2"; + + damageScale[$DamageType::M1700] = 2.0; + damageScale[$DamageType::Missile] = 100.0; max[RepairKit] = 0; max[Mine] = 0; max[Grenade] = 0; }; -datablock StaticShapeData(fakeRapierZombie) : StaticShapeDamageProfile { - className = "player"; - shapeFile = "bioderm_light.dts"; // dmiscf.dts, alternate - mass = 1; - elasticity = 0.1; - friction = 0.9; - collideable = 0; - isInvincible = true; +datablock ShapeBaseImageData(ZWingImage) { + shapeFile = "flag.dts"; + mountPoint = 1; + + offset = "0 0 0"; // L/R - F/B - T/B + rotation = "0 1 0 90"; // L/R - F/B - T/B }; -datablock ShapeBaseImageData(ZWingImage) -{ - shapeFile = "flag.dts"; - mountPoint = 1; +datablock ShapeBaseImageData(ZWingImage2) { + shapeFile = "flag.dts"; + mountPoint = 1; - offset = "0 0 0"; // L/R - F/B - T/B - rotation = "0 1 0 90"; // L/R - F/B - T/B + offset = "0 0 0"; // L/R - F/B - T/B + rotation = "0 -1 0 90"; // L/R - F/B - T/B }; -datablock ShapeBaseImageData(ZWingImage2) -{ - shapeFile = "flag.dts"; - mountPoint = 1; +datablock ShapeBaseImageData(ZWingAltImage) { + shapeFile = "flag.dts"; + mountPoint = 1; - offset = "0 0 0"; // L/R - F/B - T/B - rotation = "0 -1 0 90"; // L/R - F/B - T/B + offset = "0 0 0"; // L/R - F/B - T/B + rotation = "-0.5 2 0 35"; // L/R - F/B - T/B }; -datablock ShapeBaseImageData(ZWingAltImage) -{ - shapeFile = "flag.dts"; - mountPoint = 1; +datablock ShapeBaseImageData(ZWingAltImage2) { + shapeFile = "flag.dts"; + mountPoint = 1; - offset = "0 0 0"; // L/R - F/B - T/B - rotation = "-0.5 2 0 35"; // L/R - F/B - T/B + offset = "0 0 0"; // L/R - F/B - T/B + rotation = "-0.5 -2 0 35"; // L/R - F/B - T/B }; -datablock ShapeBaseImageData(ZWingAltImage2) -{ - shapeFile = "flag.dts"; - mountPoint = 1; - - offset = "0 0 0"; // L/R - F/B - T/B - rotation = "-0.5 -2 0 35"; // L/R - F/B - T/B -}; - -function RZombiemovetotarget(%zombie){ - if(!isobject(%Zombie)) - return; - if(%Zombie.getState() $= "dead") - return; - - %zombie.setHeat(999); - - %pos = %zombie.getworldboxcenter(); - %zombie.setActionThread("scoutRoot",true); - %closestClient = ZombieLookForTarget(%zombie); - %closestDistance = getWord(%closestClient,1); - %closestClient = getWord(%closestClient,0).Player; - if(%closestDistance <= $zombie::detectDist){ - if(%zombie.wingset == 1){ - %zombie.wingset = 0; - %Zombie.mountImage(ZWingImage, 3); - %Zombie.mountImage(ZWingImage2, 4); +function RapierZombieArmor::AI(%datablock, %zombie) { + //No special AI here, we'll let %block.move() handle it... + if(!isObject(%zombie) || %zombie.getState() $= "dead") { + return; } - else{ - %zombie.wingset = 1; - %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()); - } - 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); - } - else { - - %vector = ZgetFacingDirection(%zombie, %closestClient, %pos); - - %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); - } - } - %zombie.moveloop = schedule(500, %zombie, "RZombiemovetotarget", %zombie); + %zombie.setHeat(999); + %zombie.setActionThread("scoutRoot",true); + %datablock.move(%zombie); + %datablock.schedule(%zombie.updateTimeFrequency, "AI", %zombie); } -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, "eval", ""@%target@".isFTD = 0; "@%target@".grabbed = 0;"); +function RapierZombieArmor::move(%datablock, %zombie) { + %pos = %zombie.getworldboxcenter(); + + %targetParams = TWM2Lib_Zombie_Core("lookForTarget", %zombie); + %targetClient = getWord(targetParams, 0); + %distance = getWord(%targetParams, 1); + %target = %targetClient.player; + if(%distance <= $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) { + %chance = (getRandom() * 12); + if(%chance <= 11) { + serverPlay3d("ZombieMoan", %zombie.getWorldBoxCenter()); + } + else { + serverPlay3d("ZombieHOWL", %zombie.getWorldBoxCenter()); + } + } + if(%zombie.iscarrying == 1) { + %vector = vectorscale(%zombie.getForwardVector(), (%zombie.speed / 2)); + %vector = getword(%vector, 0)@" "@getword(%vector, 1)@" "@($Zombie::RapierUpwardScaling * 1.5); + %zombie.applyImpulse(%zombie.getposition(), %vector); + } + else { + %vector = TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %target.getPosition()); + + %z = Getword(%vector,2); + %spd = vectorLen(%zombie.getVelocity()); + %fallpoint = 0.05 - (%spd / 630); + if(%distance <= 15 || %z > (0.25 + %fallpoint) || %z < (-1 * (0.25 + %fallpoint))) { + if(%z < 0) { + %upvec = ($Zombie::RapierUpwardScaling * (%z - (%spd / 130))); + } + if(%z >= 0) { + %upvec = ($Zombie::RapierUpwardScaling * (%z + 1)); + } + if(%spd <= 5) { + %vector = vectorScale(%vector,3); + } + } + else { + %upvec = $Zombie::RapierUpwardScaling * (%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::RapierUpwardScaling * 5; + } + } + + %vector = vectorscale(%vector, (%zombie.speed * (1 - %z))); + %x = Getword(%vector,0); + %y = Getword(%vector,1); + %vector = %x@" "@%y@" "@%upvec; + %zombie.applyImpulse(%pos, %vector); + } } - %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 RapierZombieArmor::zCarryLoop(%datablock, %zombie, %target, %count) { + if(!isObject(%zombie) || %zombie.getState() $= "dead") { + %zombie.iscarrying = 0; + %target.grabbed = 0; + return; + } + if(!isObject(%target) || %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, "eval", ""@%target@".isFTD = 0; "@%target@".grabbed = 0;"); + } + %zombie.iscarrying = 0; + return; + } + %target.setPosition(vectoradd(%zombie.getPosition(),"0 0 -4")); + %target.setVelocity(%zombie.getVelocity()); + %count++; + %zombie.killingplayer = %datablock.schedule(100, "zCarryLoop", %zombie, %target, %count); +} \ No newline at end of file diff --git a/scripts/player.cs b/scripts/player.cs index 1ae229d..714165a 100644 --- a/scripts/player.cs +++ b/scripts/player.cs @@ -3017,7 +3017,7 @@ function Armor::onCollision(%this,%obj,%col,%forceVehicleNode) %col.iscarrying = 1; %obj.grabbed = 1; %obj.damage(0, %obj.position, 0.2, $DamageType::Zombie); - %col.killingPlayer = schedule(10, 0, "RkillLoop", %col, %obj, 0); + %col.killingPlayer = %col.getDatablock().zCarryLoop(%col, %obj, 0); // schedule(10, 0, "RkillLoop", %col, %obj, 0); } } else if(%colarmortype $= "ShifterZombieArmor" && %obj.Infected != 1 && %objiszomb != 1 && !%obj.rapierShield){