mirror of
https://github.com/PhantomGamesDevelopment/TWM2.git
synced 2026-01-19 19:44:47 +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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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){
|
||||
|
|
|
|||
Loading…
Reference in a new issue