mirror of
https://github.com/PhantomGamesDevelopment/TWM2.git
synced 2026-07-14 16:04:39 +00:00
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:
parent
923eb2ce37
commit
5106a3fbff
4 changed files with 160 additions and 169 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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){
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue