Air Rapier Zombies

Added the new AI capabilities to air rapiers. They will still function
just like before. Missile damage has been increased.
This commit is contained in:
Robert Fritzen 2017-10-17 16:12:59 -05:00
parent 923eb2ce37
commit 5106a3fbff
4 changed files with 160 additions and 169 deletions

View file

@ -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 * 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 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 :) * 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 * Added Boss Proficiency
* Hidden challenges embedded in boss fights that award additional experience for completing tough feats * 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 * For example: Defeat the shade lord without dying by the elemental shades

View file

@ -23,7 +23,7 @@ $Zombie::BaseSpeed = 150;
$Zombie::TypeSpeed[2] = 300; $Zombie::TypeSpeed[2] = 300;
$Zombie::TypeSpeed[3] = 4000; $Zombie::TypeSpeed[3] = 4000;
$Zombie::TypeSpeed[4] = 240; $Zombie::TypeSpeed[4] = 240;
$Zombie::TypeSpeed[5] = 300; $Zombie::TypeSpeed[5] = 1500;
//$Zombie::BaseJumpCooldown: The time zombies must elapse before jumping / lunging //$Zombie::BaseJumpCooldown: The time zombies must elapse before jumping / lunging
$Zombie::BaseJumpCooldown = 1500; $Zombie::BaseJumpCooldown = 1500;
@ -37,6 +37,7 @@ $Zombie::SpeedMultiplier[4] = 0.75;
$Zombie::BaseSpeedUpdateTime = 100; $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[#]: 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[3] = 500;
$Zombie::SpeedUpdateTime[5] = 500;
//$Zombie::LungeDistance: How far (m) a zombie must be to lunge at a target //$Zombie::LungeDistance: How far (m) a zombie must be to lunge at a target
$Zombie::LungeDistance = 10; $Zombie::LungeDistance = 10;
@ -436,15 +437,15 @@ function TWM2Lib_Zombie_Core(%functionName, %arg1, %arg2, %arg3, %arg4) {
%zombie.mountImage(ZDummyslotImg2, 6); %zombie.mountImage(ZDummyslotImg2, 6);
%zombie.mountImage(zLordPhotonCannonImg, 7); %zombie.mountImage(zLordPhotonCannonImg, 7);
%zombie.canFireWeapon = 1; %zombie.canFireWeapon = 1;
%zombie.canShield = 1; %zombie.canShield = 1;
%zombie.canmove = 1;
//Demon Zombie //Demon Zombie
case 4: case 4:
%zombie = new player() { %zombie = new player() {
Datablock = "DemonZombieArmor"; Datablock = "DemonZombieArmor";
}; };
%zombie.mountImage(ZdummyslotImg, 4); %zombie.mountImage(ZdummyslotImg, 4);
%zombie.canFireWeapon = 1;
//Air-Rapier Zombie //Air-Rapier Zombie
case 5: case 5:

View file

@ -1,188 +1,176 @@
datablock PlayerData(RapierZombieArmor) : LightMaleBiodermArmor datablock PlayerData(RapierZombieArmor) : LightMaleBiodermArmor {
{ maxDamage = 1.0;
maxDamage = 1.0; minImpactSpeed = 50;
minImpactSpeed = 50; speedDamageScale = 0.015;
speedDamageScale = 0.015; maxEnergy = 80;
maxEnergy = 80; repairRate = 0.0033;
repairRate = 0.0033; energyPerDamagePoint = 75.0; // shield energy required to block one point of damage
energyPerDamagePoint = 75.0; // shield energy required to block one point of damage
rechargeRate = 0.256; rechargeRate = 0.256;
jetForce = 25.22 * 130 * 1.5; jetForce = 25.22 * 130 * 1.5;
underwaterJetForce = 25.22 * 130 * 1.5; underwaterJetForce = 25.22 * 130 * 1.5;
underwaterVertJetFactor = 1.5; underwaterVertJetFactor = 1.5;
jetEnergyDrain = 1.0; jetEnergyDrain = 1.0;
underwaterJetEnergyDrain = 0.6; underwaterJetEnergyDrain = 0.6;
minJetEnergy = 1; minJetEnergy = 1;
maxJetHorizontalPercentage = 0.8; maxJetHorizontalPercentage = 0.8;
boundingBox = "2.0 2.0 1.2"; boundingBox = "2.0 2.0 1.2";
damageScale[$DamageType::M1700] = 2.0; damageScale[$DamageType::M1700] = 2.0;
damageScale[$DamageType::Missile] = 100.0;
max[RepairKit] = 0; max[RepairKit] = 0;
max[Mine] = 0; max[Mine] = 0;
max[Grenade] = 0; max[Grenade] = 0;
}; };
datablock StaticShapeData(fakeRapierZombie) : StaticShapeDamageProfile { datablock ShapeBaseImageData(ZWingImage) {
className = "player"; shapeFile = "flag.dts";
shapeFile = "bioderm_light.dts"; // dmiscf.dts, alternate mountPoint = 1;
mass = 1;
elasticity = 0.1; offset = "0 0 0"; // L/R - F/B - T/B
friction = 0.9; rotation = "0 1 0 90"; // L/R - F/B - T/B
collideable = 0;
isInvincible = true;
}; };
datablock ShapeBaseImageData(ZWingImage) datablock ShapeBaseImageData(ZWingImage2) {
{ shapeFile = "flag.dts";
shapeFile = "flag.dts"; mountPoint = 1;
mountPoint = 1;
offset = "0 0 0"; // 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 rotation = "0 -1 0 90"; // L/R - F/B - T/B
}; };
datablock ShapeBaseImageData(ZWingImage2) datablock ShapeBaseImageData(ZWingAltImage) {
{ shapeFile = "flag.dts";
shapeFile = "flag.dts"; mountPoint = 1;
mountPoint = 1;
offset = "0 0 0"; // 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 rotation = "-0.5 2 0 35"; // L/R - F/B - T/B
}; };
datablock ShapeBaseImageData(ZWingAltImage) datablock ShapeBaseImageData(ZWingAltImage2) {
{ shapeFile = "flag.dts";
shapeFile = "flag.dts"; mountPoint = 1;
mountPoint = 1;
offset = "0 0 0"; // 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 rotation = "-0.5 -2 0 35"; // L/R - F/B - T/B
}; };
datablock ShapeBaseImageData(ZWingAltImage2) function RapierZombieArmor::AI(%datablock, %zombie) {
{ //No special AI here, we'll let %block.move() handle it...
shapeFile = "flag.dts"; if(!isObject(%zombie) || %zombie.getState() $= "dead") {
mountPoint = 1; return;
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);
} }
else{ %zombie.setHeat(999);
%zombie.wingset = 1; %zombie.setActionThread("scoutRoot",true);
%Zombie.mountImage(ZWingaltImage, 3); %datablock.move(%zombie);
%Zombie.mountImage(ZWingaltImage2, 4); %datablock.schedule(%zombie.updateTimeFrequency, "AI", %zombie);
}
%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);
} }
function RkillLoop(%zombie,%target,%count){ function RapierZombieArmor::move(%datablock, %zombie) {
if(!isObject(%zombie)){ %pos = %zombie.getworldboxcenter();
%zombie.iscarrying = 0;
%target.grabbed = 0; %targetParams = TWM2Lib_Zombie_Core("lookForTarget", %zombie);
return; %targetClient = getWord(targetParams, 0);
} %distance = getWord(%targetParams, 1);
if(!isObject(%target)){ %target = %targetClient.player;
%zombie.iscarrying = 0; if(%distance <= $zombie::detectDist) {
%target.grabbed = 0; if(%zombie.wingset == 1){
return; %zombie.wingset = 0;
} %Zombie.mountImage(ZWingImage, 3);
if (%Zombie.getState() $= "dead"){ %Zombie.mountImage(ZWingImage2, 4);
%zombie.iscarrying = 0; }
%target.grabbed = 0; else{
return; %zombie.wingset = 1;
} %Zombie.mountImage(ZWingaltImage, 3);
if (%target.getState() $= "dead"){ %Zombie.mountImage(ZWingaltImage2, 4);
%zombie.iscarrying = 0; }
%target.grabbed = 0; %chance = (getrandom() * 20);
return; if(%chance >= 19) {
} %chance = (getRandom() * 12);
if(%count == 50){ if(%chance <= 11) {
%chance = getRandom(1,3); serverPlay3d("ZombieMoan", %zombie.getWorldBoxCenter());
if(%chance == 3) }
%target.damage(0, %tpos, 10.0, $DamageType::Zombie); else {
else{ serverPlay3d("ZombieHOWL", %zombie.getWorldBoxCenter());
%target.isFTD = 1; }
if(%target.getMountedImage($Backpackslot) !$= "") }
%target.throwPack(); if(%zombie.iscarrying == 1) {
%target.finishingfall = schedule(5000, 0, "eval", ""@%target@".isFTD = 0; "@%target@".grabbed = 0;"); %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);
}

View file

@ -3017,7 +3017,7 @@ function Armor::onCollision(%this,%obj,%col,%forceVehicleNode)
%col.iscarrying = 1; %col.iscarrying = 1;
%obj.grabbed = 1; %obj.grabbed = 1;
%obj.damage(0, %obj.position, 0.2, $DamageType::Zombie); %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){ else if(%colarmortype $= "ShifterZombieArmor" && %obj.Infected != 1 && %objiszomb != 1 && !%obj.rapierShield){