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
* 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

View file

@ -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:

View file

@ -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);
}

View file

@ -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){