Mid-December Updates

Next batch of updates, including the demon lord zombies, some function
centralization, and datablock cleanup.
This commit is contained in:
Robert Fritzen 2017-12-19 17:25:48 -06:00
parent 0954efcdc4
commit f7095e8823
20 changed files with 1850 additions and 2045 deletions

View file

@ -89,6 +89,11 @@ PLEASE NOTE: I've moved all old changelogs into the version_history folder. This
* Players will be knocked back with a higher force when hit by demon zombies
* Air Rapier
* Modified the damage scalar of missiles to be a OHK on rapier zombies
* Demon Lord
* Cleaned up this script file substantially
* Replaced the standard lunge with a fire lunge which creates a firey explosion on impact
* Reduced the hit damage of the demon lord from 0.8 to 0.5
* Demon Lords, like the regular demons will no longer infect on collision, but set the player on fire instead
* 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
@ -117,6 +122,8 @@ PLEASE NOTE: I've moved all old changelogs into the version_history folder. This
* Lord Vardison
* Fixed an erraneous text prompt that would appear when the shadow rift detonated outside of WTF difficulty stating vardison had healed when in fact he did not
* General Enhancements
* Centralized some of the datablocks that were shared across the mod to allow for easier access / modification
* Centralized the demon lord's missile seeking logic that was used across multiple zombies & bosses to allow for easier access and editing
* Modified the vote logic in admin.cs to clean up a ton of redundant if/else paths
* Re-did the player collision logic in player.cs to make things a whole lot easier to modify in the future
* Did a pass through all of the weapon files, cleaning the code up and making each unique weapon have its own damage type.
@ -141,10 +148,13 @@ PLEASE NOTE: I've moved all old changelogs into the version_history folder. This
* Added a 100.0 damage modifier to all zombie types for Blade of Vengeance
* This includes player zombies.
* Removed the clause that bosses could not be damaged by the Blade of Vengeance
* Bosses now take 65HP damage from the blade.
* Bosses now take 6.5 (650 HP) damage from the blade.
* Plasmasaber
* Removed the damage flag on player type
* Now deals a flat damage of 5.0 to all targets (OHK to all players, low tier zombies), 500HP damage to bosses.
* Now deals a flat damage of 5.0 to all targets (OHK to all players, low tier zombies), 500 HP damage to bosses.
* Reduced the melee attack cooldown from 1.5 seconds to 0.8 seconds.
* Holding the Plasmasaber will grant you a protective buff preventing zombie infection from impact damage.
* You can still be infected by taking zombie based projectile damage.
* Sidearms
* At the moment, the two statistical outliers in the pool (Crimson Hawk and Pulse Phaser) feel close to being perfect, some minor tuning will help get them there.
* Crimson Hawk Pistol

File diff suppressed because it is too large Load diff

View file

@ -127,50 +127,6 @@ function DroneFindNearestPilot(%radius, %drone) {
return %closestClient;
}
datablock SeekerProjectileData(BossMissiles)
{
casingShapeName = "weapon_missile_casement.dts";
projectileShapeName = "weapon_missile_projectile.dts";
hasDamageRadius = true;
indirectDamage = 0.1;
damageRadius = 6.0;
radiusDamageType = $DamageType::MissileTurret;
kickBackStrength = 500;
flareDistance = 200;
flareAngle = 30;
minSeekHeat = 0.0;
explosion = "MissileExplosion";
velInheritFactor = 1.0;
splash = MissileSplash;
baseEmitter = MortarSmokeEmitter;
delayEmitter = MissileFireEmitter;
puffEmitter = MissilePuffEmitter;
lifetimeMS = 15000; // z0dd - ZOD, 4/14/02. Was 6000
muzzleVelocity = 12.0;
maxVelocity = 225.0; // z0dd - ZOD, 4/14/02. Was 80.0
turningSpeed = 50.0;
acceleration = 100.0;
proximityRadius = 4;
terrainAvoidanceSpeed = 100;
terrainScanAhead = 50;
terrainHeightFail = 50;
terrainAvoidanceRadius = 150;
useFlechette = true;
flechetteDelayMs = 225;
casingDeb = FlechetteDebris;
};
function WindshearAttacks(%drone) {
if(!isObject(%drone)) {
return;

View file

@ -292,23 +292,7 @@ function VegenorAttack_FUNC(%att, %args) {
case "FlameMissileSingle":
%Tobj = getWord(%args, 0);
%vec = vectorNormalize(vectorSub(%Tobj.getPosition(), %z.getPosition()));
%p = new SeekerProjectile() {
dataBlock = VegenorFireMissile;
initialDirection = %vec;
initialPosition = %z.getMuzzlePoint(4);
sourceObject = %z;
sourceSlot = 4;
};
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %Tobj.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%p.setObjectTarget(%beacon);
DemonMotherMissileFollow(%Tobj, %beacon,%p);
createMissileSeekingProjectile("VegenorFireMissile", %Tobj, %z, %z.getMuzzlePoint(4), %vec, 4, 100);
case "MeteorDrop":
%t = getWord(%args, 0);
%fpos = vectoradd(%t.getposition(), TWM2Lib_MainControl("getRandomPosition", 50 TAB 0));

View file

@ -260,23 +260,7 @@ function DoGoLAttacks(%ghost) {
}
MessageAll('msgBossAlertAttack', "\c4"@$TWM2::BossName["GoL"]@": Watch Electricity Chase You!!!");
%vec = vectorNormalize(vectorSub(%target.player.getPosition(),%ghost.getPosition()));
%p = new SeekerProjectile() {
dataBlock = IonMissile;
initialDirection = %vec;
initialPosition = %ghost.getMuzzlePoint(0);
sourceObject = %ghost;
sourceSlot = 4;
};
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %target.player.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%p.setObjectTarget(%beacon);
DemonMotherMissileFollow(%target.player,%beacon,%p);
createMissileSeekingProjectile("IonMissile", %target, %ghost, %ghost.getMuzzlePoint(0), %vec, 4, 100);
case 3:
%target = FindValidTarget(%ghost);
if(!isObject(%target.player)) {
@ -307,23 +291,7 @@ function DoGoLAttacks(%ghost) {
%cl = ClientGroup.getObject(%i);
if(isObject(%cl.player) && %cl.player.getState() !$= "dead") {
%vec = vectorNormalize(vectorSub(%cl.player.getPosition(),%ghost.getPosition()));
%p = new SeekerProjectile() {
dataBlock = IonMissile;
initialDirection = %vec;
initialPosition = %ghost.getMuzzlePoint(0);
sourceObject = %ghost;
sourceSlot = 4;
};
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %cl.player.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%p.setObjectTarget(%beacon);
DemonMotherMissileFollow(%cl.player,%beacon,%p);
createMissileSeekingProjectile("IonMissile", %cl.player, %ghost, %ghost.getMuzzlePoint(4), %vec, 4, 100);
}
}
}

View file

@ -1443,23 +1443,7 @@ function VardisonNamedAttack(%Boss, %attack, %args) {
%target = getField(%args, 0);
%sPos = vectorAdd(%bPos, "0 0 25");
%vec = vectorNormalize(vectorSub(%target.getPosition(), %sPos));
%p = new SeekerProjectile() {
dataBlock = YvexNightmareMissile;
initialDirection = %vec;
initialPosition = %sPos;
sourceSlot = 4;
};
%p.sourceObject = %Boss;
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %target.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%p.setObjectTarget(%beacon);
DemonMotherMissileFollow(%target, %beacon, %p);
createMissileSeekingProjectile("YvexNightmareMissile", %target, %Boss, %Boss.getMuzzlePoint(4), %vec, 4, 100);
case "ShadowFissure":
%sPos = getField(%args, 0);
@ -1485,23 +1469,7 @@ function VardisonNamedAttack(%Boss, %attack, %args) {
%target = getField(%args, 0);
%sPos = vectorAdd(%bPos, "0 0 25");
%vec = vectorNormalize(vectorSub(%target.getPosition(), %sPos));
%p = new SeekerProjectile() {
dataBlock = VegenorFireMissile;
initialDirection = %vec;
initialPosition = %sPos;
sourceSlot = 4;
};
%p.sourceObject = %Boss;
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %target.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%p.setObjectTarget(%beacon);
DemonMotherMissileFollow(%target, %beacon, %p);
createMissileSeekingProjectile("VegenorFireMissile", %target, %Boss, %Boss.getMuzzlePoint(4), %vec, 4, 100);
case "MinionFlood":
//Summon Maximum Minions & then Phase out until the team drops them

View file

@ -22,629 +22,211 @@ $Boss::DamageScaling["Yvex"] = 5.0;
$Boss::ScaleReduction["Yvex"] = 0.15;
//DATABLOCKS
datablock ParticleData(InflictionNightmareGlobeSmoke) {
dragCoefficient = 50;/////////-----------------------
gravityCoefficient = 0.0;
inheritedVelFactor = 1.0;
constantAcceleration = 0.0;
lifetimeMS = 5050;
lifetimeVarianceMS = 0;
useInvAlpha = true;
spinRandomMin = -360.0;
spinRandomMax = 360.0;
textureName = "particleTest";
colors[0] = "0.5 0.1 0.9 1.0";
colors[1] = "0.5 0.1 0.9 1.0";
colors[2] = "0.5 0.1 0.9 1.0";
colors[3] = "0.5 0.1 0.9";
sizes[0] = 1.0;
sizes[1] = 1.0;
sizes[2] = 1.0;
sizes[3] = 1.0;
times[0] = 0.0;
times[1] = 0.33;
times[2] = 0.66;
times[3] = 1.0;
mass = 0.7;
elasticity = 0.2;
friction = 1;
computeCRC = true;
haslight = true;
lightType = "PulsingLight";
lightColor = "0.2 0.0 0.5 1.0";
lightTime = "200";
lightRadius = "2.0";
};
datablock ParticleEmitterData(InfNightmareGlobeEmitter) {
ejectionPeriodMS = 0.1;
periodVarianceMS = 0;
ejectionVelocity = 0.0;
velocityVariance = 0.0;
ejectionOffset = 5;
thetaMin = 0;
thetaMax = 180;
overrideAdvances = false;
particles = "InflictionNightmareGlobeSmoke";
};
datablock ParticleData(NightmareGlobeSmoke) {
dragCoefficient = 50;/////////-----------------------
gravityCoefficient = 0.0;
inheritedVelFactor = 1.0;
constantAcceleration = 0.0;
lifetimeMS = 5050;
lifetimeVarianceMS = 0;
useInvAlpha = true;
spinRandomMin = -360.0;
spinRandomMax = 360.0;
textureName = "particleTest";
colors[0] = "0.1 0.1 0.1 1.0";// ////////////////////
colors[1] = "0.1 0.1 0.1 1.0";// ////////////////////
colors[2] = "0.1 0.1 0.1 1.0";// \\\\\\\\\\\\\\\\\\\\
colors[3] = "0.1 0.1 0.1 1.0";// \\\\\\\\\\\\\\\\\\\\
sizes[0] = 1.0;
sizes[1] = 1.0;
sizes[2] = 1.0;
sizes[3] = 1.0;
times[0] = 0.0;
times[1] = 0.33;
times[2] = 0.66;
times[3] = 1.0;
mass = 0.7;
elasticity = 0.2;
friction = 1;
computeCRC = true;
haslight = true;
lightType = "PulsingLight";
lightColor = "0.2 0.0 0.5 1.0";
lightTime = "200";
lightRadius = "2.0";
};
datablock ParticleEmitterData(NightmareGlobeEmitter) {
ejectionPeriodMS = 0.1;
periodVarianceMS = 0;
ejectionVelocity = 0.0;
velocityVariance = 0.0;
ejectionOffset = 5;
thetaMin = 0;
thetaMax = 180;
overrideAdvances = false;
particles = "NightmareGlobeSmoke";
};
//Yvex STUFF.. MORE
datablock ParticleData(GreenEmitParticle) {
dragCoeffiecient = 1;
gravityCoefficient = -0.3; // rises slowly
inheritedVelFactor = 0;
lifetimeMS = 300;
lifetimeVarianceMS = 0;
useInvAlpha = false;
spinRandomMin = 0.0;
spinRandomMax = 0.0;
animateTexture = false;
textureName = "flareBase"; // "special/Smoke/bigSmoke"
colors[0] = "0 1 0";
colors[1] = "0 1 0";
colors[2] = "0 1 0";
sizes[0] = 0.8;
sizes[1] = 0.8;
sizes[2] = 0.8;
times[0] = 0.0;
times[1] = 1.0;
times[2] = 5.0;
};
datablock ParticleEmitterData(PulseGreenEmitter) {
ejectionPeriodMS = 2;
periodVarianceMS = 1;
ejectionVelocity = 10;
velocityVariance = 0;
thetaMin = 89.0;
thetaMax = 90.0;
orientParticles = false;
particles = "GreenEmitParticle";
};
datablock SeekerProjectileData(YvexNightmareMissile){
casingShapeName = "weapon_missile_casement.dts";
projectileShapeName = "weapon_missile_projectile.dts";
hasDamageRadius = true;
indirectDamage = 0.8;
damageRadius = 8.0;
radiusDamageType = $DamageType::Missile;
kickBackStrength = 2000;
explosion = "MissileExplosion";
splash = MissileSplash;
velInheritFactor = 1.0; // to compensate for slow starting velocity, this value
// is cranked up to full so the missile doesn't start
// out behind the player when the player is moving
// very quickly - bramage
delayEmitter = MissileFireEmitter;
puffEmitter = MissilePuffEmitter;
bubbleEmitter = GrenadeBubbleEmitter;
bubbleEmitTime = 1.0;
exhaustEmitter = MissileLauncherExhaustEmitter;
exhaustTimeMs = 300;
exhaustNodeName = "muzzlePoint1";
lifetimeMS = 30000;
muzzleVelocity = 10.0;
maxVelocity = 150.0;
turningSpeed = 110.0;
acceleration = 350.0;
proximityRadius = 3;
terrainAvoidanceSpeed = 180;
terrainScanAhead = 25;
terrainHeightFail = 12;
terrainAvoidanceRadius = 100;
flareDistance = 200;
flareAngle = 30;
sound = MissileProjectileSound;
hasLight = true;
lightRadius = 5.0;
lightColor = "0.2 0.05 0";
useFlechette = true;
flechetteDelayMs = 550;
casingDeb = FlechetteDebris;
explodeOnWaterImpact = false;
baseEmitter = NMMissileBaseEmitter;
};
function YvexNightmareMissile::OnExplode(%data, %proj, %pos, %mod) {
%source = %proj.SourceObject;
InitContainerRadiusSearch(%proj.getPosition(), 6, $TypeMasks::PlayerObjectType);
while ((%potentialTarget = ContainerSearchNext()) != 0) {
%cl = %potentialTarget.client;
if(%cl !$= "")
Yvexnightmareloop(%source, %cl);
}
%source = %proj.SourceObject;
InitContainerRadiusSearch(%proj.getPosition(), 6, $TypeMasks::PlayerObjectType);
while ((%potentialTarget = ContainerSearchNext()) != 0) {
%cl = %potentialTarget.client;
if(%cl !$= "") {
Yvexnightmareloop(%source, %cl);
}
}
}
datablock LinearFlareProjectileData(KillerPulse) {
scale = "1.0 1.0 1.0";
faceViewer = false;
directDamage = 0.00001;
hasDamageRadius = false;
indirectDamage = 0.6;
damageRadius = 10.0;
kickBackStrength = 100.0;
directDamageType = $DamageType::Admin;
indirectDamageType = $DamageType::Admin;
scale = "1.0 1.0 1.0";
faceViewer = false;
directDamage = 0.00001;
hasDamageRadius = false;
indirectDamage = 0.6;
damageRadius = 10.0;
kickBackStrength = 100.0;
directDamageType = $DamageType::Admin;
indirectDamageType = $DamageType::Admin;
explosion = "BlasterExplosion";
splash = PlasmaSplash;
explosion = "BlasterExplosion";
splash = PlasmaSplash;
dryVelocity = 200.0;
wetVelocity = 10;
velInheritFactor = 0.5;
fizzleTimeMS = 30000;
lifetimeMS = 30000;
explodeOnDeath = false;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = true;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = -1;
dryVelocity = 200.0;
wetVelocity = 10;
velInheritFactor = 0.5;
fizzleTimeMS = 30000;
lifetimeMS = 30000;
explodeOnDeath = false;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = true;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = -1;
baseEmitter = PulseGreenEmitter;
delayEmitter = PulseGreenEmitter;
bubbleEmitter = PulseGreenEmitter;
baseEmitter = PulseGreenEmitter;
delayEmitter = PulseGreenEmitter;
bubbleEmitter = PulseGreenEmitter;
//activateDelayMS = 100;
activateDelayMS = -1;
//activateDelayMS = 100;
activateDelayMS = -1;
size[0] = 0.2;
size[1] = 0.2;
size[2] = 0.2;
size[0] = 0.2;
size[1] = 0.2;
size[2] = 0.2;
numFlares = 15;
flareColor = "0 1 0";
flareModTexture = "flaremod";
flareBaseTexture = "flarebase";
numFlares = 15;
flareColor = "0 1 0";
flareModTexture = "flaremod";
flareBaseTexture = "flarebase";
sound = MissileProjectileSound;
fireSound = PlasmaFireSound;
wetFireSound = PlasmaFireWetSound;
sound = MissileProjectileSound;
fireSound = PlasmaFireSound;
wetFireSound = PlasmaFireWetSound;
hasLight = true;
lightRadius = 3.0;
lightColor = "0 1 0";
};
datablock ParticleData(PurpleNightmareEmitParticle) {
dragCoeffiecient = 1;
gravityCoefficient = -0.3; // rises slowly
inheritedVelFactor = 0;
lifetimeMS = 300;
lifetimeVarianceMS = 0;
useInvAlpha = false;
spinRandomMin = 0.0;
spinRandomMax = 0.0;
animateTexture = false;
textureName = "flareBase"; // "special/Smoke/bigSmoke"
colors[0] = "0.5 0.1 0.9 1.0";
colors[1] = "0.5 0.1 0.9 1.0";
colors[2] = "0.5 0.1 0.9";
sizes[0] = 0.4;
sizes[1] = 0.4;
sizes[2] = 0.4;
times[0] = 0.0;
times[1] = 1.0;
times[2] = 5.0;
};
datablock ParticleEmitterData(YvexSniperEmitter) {
ejectionPeriodMS = 2;
periodVarianceMS = 1;
ejectionVelocity = 10;
velocityVariance = 0;
thetaMin = 89.0;
thetaMax = 90.0;
orientParticles = false;
particles = "PurpleNightmareEmitParticle";
hasLight = true;
lightRadius = 3.0;
lightColor = "0 1 0";
};
datablock LinearFlareProjectileData(YvexSniperShot) {
projectileShapeName = "weapon_missile_projectile.dts";
scale = "3.0 5.0 3.0";
faceViewer = true;
directDamage = 0.01;
kickBackStrength = 4000.0;
DirectDamageType = $DamageType::Zombie;
projectileShapeName = "weapon_missile_projectile.dts";
scale = "3.0 5.0 3.0";
faceViewer = true;
directDamage = 0.01;
kickBackStrength = 4000.0;
DirectDamageType = $DamageType::Zombie;
explosion = "BlasterExplosion";
explosion = "BlasterExplosion";
dryVelocity = 150.0;
wetVelocity = -1;
velInheritFactor = 0.3;
fizzleTimeMS = 10000;
lifetimeMS = 10000;
explodeOnDeath = true;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = true;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = -1;
dryVelocity = 150.0;
wetVelocity = -1;
velInheritFactor = 0.3;
fizzleTimeMS = 10000;
lifetimeMS = 10000;
explodeOnDeath = true;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = true;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = -1;
activateDelayMS = 100;
activateDelayMS = -1;
activateDelayMS = 100;
activateDelayMS = -1;
baseEmitter = YvexSniperEmitter;
baseEmitter = YvexSniperEmitter;
size[0] = 0.0;
size[1] = 0.0;
size[2] = 0.0;
size[0] = 0.0;
size[1] = 0.0;
size[2] = 0.0;
numFlares = 0;
flareColor = "0.0 0.0 0.0";
flareModTexture = "flaremod";
flareBaseTexture = "flarebase";
numFlares = 0;
flareColor = "0.0 0.0 0.0";
flareModTexture = "flaremod";
flareBaseTexture = "flarebase";
sound = PlasmaProjectileSound;
fireSound = PlasmaFireSound;
wetFireSound = PlasmaFireWetSound;
fireSound = PlasmaFireSound;
wetFireSound = PlasmaFireWetSound;
hasLight = true;
lightRadius = 3.0;
lightColor = "1 0.75 0.25";
};
datablock SeekerProjectileData(YvexZombieMakerMissile) {
casingShapeName = "weapon_missile_casement.dts";
projectileShapeName = "weapon_missile_projectile.dts";
hasDamageRadius = true;
indirectDamage = 0.5;
damageRadius = 5.0;
radiusDamageType = $DamageType::Zombie;
kickBackStrength = 2000;
explosion = "MissileExplosion";
splash = MissileSplash;
velInheritFactor = 1.0; // to compensate for slow starting velocity, this value
// is cranked up to full so the missile doesn't start
// out behind the player when the player is moving
// very quickly - bramage
baseEmitter = MortarSmokeEmitter;
delayEmitter = MissileFireEmitter;
puffEmitter = MissilePuffEmitter;
bubbleEmitter = GrenadeBubbleEmitter;
bubbleEmitTime = 1.0;
exhaustEmitter = MissileLauncherExhaustEmitter;
exhaustTimeMs = 300;
exhaustNodeName = "muzzlePoint1";
lifetimeMS = 30000; // z0dd - ZOD, 4/14/02. Was 6000
muzzleVelocity = 30.0;
maxVelocity = 35.0; // z0dd - ZOD, 4/14/02. Was 80.0
turningSpeed = 23.0;
acceleration = 15.0;
proximityRadius = 2.5;
terrainAvoidanceSpeed = 10;
terrainScanAhead = 7;
terrainHeightFail = 1;
terrainAvoidanceRadius = 3;
flareDistance = 40;
flareAngle = 20;
minSeekHeat = 0.0;
sound = MissileProjectileSound;
hasLight = true;
lightRadius = 5.0;
lightColor = "0.2 0.05 0";
useFlechette = true;
flechetteDelayMs = 250;
casingDeb = FlechetteDebris;
explodeOnWaterImpact = false;
hasLight = true;
lightRadius = 3.0;
lightColor = "1 0.75 0.25";
};
datablock PlayerData(YvexZombieArmor) : LightMaleHumanArmor {
boundingBox = "1.63 1.63 2.6";
maxDamage = 400.0;
minImpactSpeed = 35;
shapeFile = "medium_male.dts";
boundingBox = "1.63 1.63 2.6";
maxDamage = 400.0;
minImpactSpeed = 35;
shapeFile = "medium_male.dts";
debrisShapeName = "bio_player_debris.dts";
debrisShapeName = "bio_player_debris.dts";
//Foot Prints
decalData = HeavyBiodermFootprint;
decalOffset = 0.4;
//Foot Prints
decalData = HeavyBiodermFootprint;
decalOffset = 0.4;
waterBreathSound = WaterBreathBiodermSound;
waterBreathSound = WaterBreathBiodermSound;
damageScale[$DamageType::W1700] = 3.0;
damageScale[$DamageType::Bullet] = 0.10; //I deny you shrike n0bs
max[RepairKit] = 0;
max[Mine] = 0;
max[Grenade] = 0;
max[SmokeGrenade] = 0;
max[BeaconSmokeGrenade] = 0;
max[Blaster] = 0;
max[Plasma] = 0;
max[PlasmaAmmo] = 0;
max[Disc] = 0;
max[DiscAmmo] = 0;
max[SniperRifle] = 0;
max[GrenadeLauncher] = 0;
max[GrenadeLauncherAmmo] = 0;
max[Mortar] = 0;
max[MortarAmmo] = 0;
max[MissileLauncher] = 0;
max[MissileLauncherAmmo] = 0;
max[Chaingun] = 0;
max[ChaingunAmmo] = 0;
max[RepairGun] = 0;
max[CloakingPack] = 0;
max[SensorJammerPack] = 0;
max[EnergyPack] = 0;
max[RepairPack] = 0;
max[ShieldPack] = 0;
max[AmmoPack] = 0;
max[SatchelCharge] = 0;
max[MortarBarrelPack] = 0;
max[MissileBarrelPack] = 0;
max[AABarrelPack] = 0;
max[PlasmaBarrelPack] = 0;
max[ELFBarrelPack] = 0;
max[artillerybarrelpack] = 0;
max[MedPack] = 0;
max[InventoryDeployable] = 0;
max[MotionSensorDeployable] = 0;
max[PulseSensorDeployable] = 0;
max[TurretOutdoorDeployable] = 0;
max[TurretIndoorDeployable] = 0;
max[FlashGrenade] = 0;
max[ConcussionGrenade] = 0;
max[FlareGrenade] = 0;
max[TargetingLaser] = 0;
max[ELFGun] = 0;
max[ShockLance] = 0;
max[CameraGrenade] = 0;
max[Beacon] = 0;
max[flamerAmmoPack] = 0;
max[ParachutePack] = 0;
max[ConstructionTool] = 0;
max[MergeTool] = 0;
max[NerfGun] = 0;
max[NerfBallLauncher] = 0;
max[NerfBallLauncherAmmo] = 0;
max[SuperChaingun] = 0;
max[SuperChaingunAmmo] = 0;
max[RPChaingun] = 0;
max[RPChaingunAmmo] = 0;
max[MGClip] = 0;
max[LSMG] = 0;
max[LSMGAmmo] = 0;
max[LSMGClip] = 0;
max[snipergun] = 0;
max[snipergunAmmo] = 0;
max[Bazooka] = 0;
max[BazookaAmmo] = 0;
max[BunkerBuster] = 0;
max[MG42] = 0;
max[MG42Ammo] = 0;
max[SPistol] = 0;
max[Pistol] = 0;
max[PistolAmmo] = 0;
max[Pistolclip] = 0;
max[flamer] = 0;
max[flamerAmmo] = 0;
max[AALauncher] = 0;
max[AALauncherAmmo] = 0;
max[melee] = 0;
max[SOmelee] = 0;
max[KriegRifle] = 0;
max[KriegAmmo] = 0;
max[Rifleclip] = 0;
max[Shotgun] = 0;
max[ShotgunAmmo] = 0;
max[ShotgunClip] = 0;
max[RShotgun] = 0;
max[RShotgunAmmo] = 0;
max[RShotgunClip] = 0;
max[LMissileLauncher] = 0;
max[LMissileLauncherAmmo] = 0;
max[HRPChaingun] = 0;
max[RPGAmmo] = 0;
max[RPGItem] = 0;
max[spineDeployable] = 0;
max[mspineDeployable] = 0;
max[wWallDeployable] = 0;
max[floorDeployable] = 0;
max[WallDeployable] = 0;
max[DoorDeployable] = 0;
max[TurretLaserDeployable] = 0;
max[TurretMissileRackDeployable]= 0;
max[DiscTurretDeployable] = 0;
max[EnergizerDeployable] = 0;
max[TreeDeployable] = 0;
max[CrateDeployable] = 0;
max[DecorationDeployable] = 0;
max[LogoProjectorDeployable] = 0;
max[LightDeployable] = 0;
max[TripwireDeployable] = 0;
max[TelePadPack] = 0;
max[TurretBasePack] = 0;
max[LargeInventoryDeployable] = 0;
max[GeneratorDeployable] = 0;
max[SolarPanelDeployable] = 0;
max[SwitchDeployable] = 0;
max[MediumSensorDeployable] = 0;
max[LargeSensorDeployable] = 0;
max[SpySatelliteDeployable] = 0;
max[JumpadDeployable] = 0;
max[EscapePodDeployable] = 0;
max[ForceFieldDeployable] = 0;
max[GravityFieldDeployable] = 0;
max[VehiclePadPack] = 0;
damageScale[$DamageType::M1700] = 3.0;
damageScale[$DamageType::Bullet] = 0.10; //I deny you shrike n0bs
};
//CREATION
function SpawnYvex(%position) {
%Zombie = new player(){
Datablock = "YvexZombieArmor";
};
%Cpos = vectorAdd(%position, "0 0 5");
MessageAll('MsgYvexreturn', "\c4"@$TWM2::ZombieName[7]@": Did you miss me? Because... I WANT MY REVENGE!!!");
%Zombie = new player(){
Datablock = "YvexZombieArmor";
};
%Cpos = vectorAdd(%position, "0 0 5");
MessageAll('MsgYvexreturn', "\c4"@$TWM2::ZombieName[7]@": Did you miss me? Because... I WANT MY REVENGE!!!");
%command = "Yvexmovetotarget";
%zombie.ticks = 0;
InitiateBoss(%zombie, "Yvex");
YvexAttack_FUNC("ZombieSummon", %zombie);
YvexAttacks(%zombie);
%Zombie.team = 30;
%zname = $TWM2::ZombieName[7]; // <- To Hosts, Enjoy, You can
//Change the Zombie Names now!!!
%zombie.target = createTarget(%zombie, %zname, "", "Derm3", '', %zombie.team, PlayerSensor);
setTargetSensorData(%zombie.target, PlayerSensor);
setTargetSensorGroup(%zombie.target, 30);
setTargetName(%zombie.target, addtaggedstring(%zname));
setTargetSkin(%zombie.target, 'Horde');
//
%zombie.type = %type;
%Zombie.setTransform(%cpos);
%zombie.canjump = 1;
%zombie.hastarget = 1;
%zombie.isZombie = 1;
MissionCleanup.add(%Zombie);
schedule(1000, %zombie, %command, %zombie);
%command = "Yvexmovetotarget";
%zombie.ticks = 0;
InitiateBoss(%zombie, "Yvex");
YvexAttack_FUNC("ZombieSummon", %zombie);
YvexAttacks(%zombie);
%Zombie.team = 30;
%zname = $TWM2::ZombieName[7]; // <- To Hosts, Enjoy, You can
//Change the Zombie Names now!!!
%zombie.target = createTarget(%zombie, %zname, "", "Derm3", '', %zombie.team, PlayerSensor);
setTargetSensorData(%zombie.target, PlayerSensor);
setTargetSensorGroup(%zombie.target, 30);
setTargetName(%zombie.target, addtaggedstring(%zname));
setTargetSkin(%zombie.target, 'Horde');
//
%zombie.type = %type;
%Zombie.setTransform(%cpos);
%zombie.canjump = 1;
%zombie.hastarget = 1;
%zombie.isZombie = 1;
MissionCleanup.add(%Zombie);
schedule(1000, %zombie, %command, %zombie);
}
//AI
function Yvexmovetotarget(%zombie){
if(!isobject(%zombie))
return;
if(%zombie.getState() $= "dead")
return;
%pos = %zombie.getworldboxcenter();
%z = getWord(%pos, 2);
if(%z < -300) {
%zombie.startFade(400, 0, true);
%zombie.startFade(1000, 0, false);
%zombie.setPosition(vectorAdd(vectoradd(%closestclient.player.getPosition(), "0 0 20"), TWM2Lib_MainControl("getRandomPosition", 25 TAB 1)));
%zombie.setVelocity("0 0 0");
MessageAll('msgYvexAttack', "\c4"@$TWM2::ZombieName[7]@": I shall not fall to my end!");
}
%closestClient = ZombieLookForTarget(%zombie);
%closestDistance = getWord(%closestClient,1);
%closestClient = getWord(%closestClient,0).Player;
if(%closestDistance <= $zombie::detectDist){
if(%zombie.hastarget != 1){
serverPlay3d("ZombieHOWL",%zombie.getWorldBoxCenter());
%zombie.hastarget = 1;
if(!isobject(%zombie))
return;
if(%zombie.getState() $= "dead")
return;
%pos = %zombie.getworldboxcenter();
%z = getWord(%pos, 2);
if(%z < -300) {
%zombie.startFade(400, 0, true);
%zombie.startFade(1000, 0, false);
%zombie.setPosition(vectorAdd(vectoradd(%closestclient.player.getPosition(), "0 0 20"), TWM2Lib_MainControl("getRandomPosition", 25 TAB 1)));
%zombie.setVelocity("0 0 0");
MessageAll('msgYvexAttack', "\c4"@$TWM2::ZombieName[7]@": I shall not fall to my end!");
}
%chance = (getrandom() * 20);
if(%chance >= 19)
serverPlay3d("ZombieMoan",%zombie.getWorldBoxCenter());
%closestClient = ZombieLookForTarget(%zombie);
%closestDistance = getWord(%closestClient,1);
%closestClient = getWord(%closestClient,0).Player;
if(%closestDistance <= $zombie::detectDist){
if(%zombie.hastarget != 1){
serverPlay3d("ZombieHOWL",%zombie.getWorldBoxCenter());
%zombie.hastarget = 1;
}
%chance = (getrandom() * 20);
if(%chance >= 19)
serverPlay3d("ZombieMoan",%zombie.getWorldBoxCenter());
%vector = ZgetFacingDirection(%zombie,%closestClient,%pos);
%vector = ZgetFacingDirection(%zombie,%closestClient,%pos);
%zombie.ticks++;
%vector = vectorscale(%vector, $Zombie::DForwardSpeed / 2);
%upvec = "150";
%x = Getword(%vector,0);
%y = Getword(%vector,1);
%z = Getword(%vector,2);
if(%z >= ($Zombie::DForwardSpeed / 3 * 2))
%upvec = (%upvec * 5);
%vector = %x@" "@%y@" "@%upvec;
%zombie.applyImpulse(%pos, %vector);
}
else if(%zombie.hastarget == 1){
%zombie.hastarget = 0;
%zombie.zombieRmove = schedule(100, %zombie, "ZSetRandomMove", %zombie);
}
%zombie.moveloop = schedule(500, %zombie, "Yvexmovetotarget", %zombie);
%zombie.ticks++;
%vector = vectorscale(%vector, $Zombie::DForwardSpeed / 2);
%upvec = "150";
%x = Getword(%vector,0);
%y = Getword(%vector,1);
%z = Getword(%vector,2);
if(%z >= ($Zombie::DForwardSpeed / 3 * 2))
%upvec = (%upvec * 5);
%vector = %x@" "@%y@" "@%upvec;
%zombie.applyImpulse(%pos, %vector);
}
else if(%zombie.hastarget == 1) {
%zombie.hastarget = 0;
%zombie.zombieRmove = schedule(100, %zombie, "ZSetRandomMove", %zombie);
}
%zombie.moveloop = schedule(500, %zombie, "Yvexmovetotarget", %zombie);
}
//ATTACKS
@ -747,23 +329,7 @@ function YvexAttack_FUNC(%att, %args) {
%z = getWord(%args, 0);
%t = getWord(%args, 1);
%vec = vectorNormalize(vectorSub(%t.getPosition(),%z.getPosition()));
%p = new SeekerProjectile() {
dataBlock = YvexZombieMakerMissile;
initialDirection = %vec;
initialPosition = %z.getMuzzlePoint(4);
sourceObject = %z;
sourceSlot = 4;
};
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %t.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%p.setObjectTarget(%beacon);
DemonMotherMissileFollow(%t, %beacon, %p);
createMissileSeekingProjectile("YvexZombieMakerMissile", %t, %z, %z.getMuzzlePoint(4), %vec, 4, 100);
case "RiftPulse":
%t = getWord(%args, 0);
@ -783,23 +349,7 @@ function YvexAttack_FUNC(%att, %args) {
%z = getWord(%args, 0);
%t = getWord(%args, 1);
%vec = vectorNormalize(vectorSub(%t.getPosition(),%z.getPosition()));
%p = new SeekerProjectile() {
dataBlock = YvexNightmareMissile;
initialDirection = %vec;
initialPosition = %z.getMuzzlePoint(4);
sourceObject = %z;
sourceSlot = 4;
};
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %t.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%p.setObjectTarget(%beacon);
DemonMotherMissileFollow(%t, %beacon, %p);
createMissileSeekingProjectile("YvexNightmareMissile", %t, %z, %z.getMuzzlePoint(4), %vec, 4, 100);
case "KillLoop":
%player = getWord(%args, 0);

View file

@ -464,23 +464,7 @@ function ShadeLordFunction(%boss, %function, %args) {
%neg = %i % 2 == 0 ? 1 : -1;
%start = vectorAdd(%start1, %neg*%interval*%i@" 0 0");
%vec = vectorNormalize(vectorSub(%go,%start));
%p = new SeekerProjectile() {
dataBlock = ShadeLordSword;
initialDirection = %vec;
initialPosition = %start;
};
%p.sourceObject = %boss;
%p.targetedPlayer = %target;
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %target.player.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%p.setObjectTarget(%beacon);
DemonMotherMissileFollow(%target,%beacon,%p);
createMissileSeekingProjectile("ShadeLordSword", %target, %boss, %start, %vec, 4, 100);
}
case "Att_HealSequence":
@ -883,23 +867,7 @@ function ShadeLordFunction(%boss, %function, %args) {
%target = getWord(%args, 0);
%incoming = vectorAdd(%target.getPosition(), vectorAdd(TWM2Lib_MainControl("getRandomPosition", 70 TAB 1), "0 0 250"));
%vec = vectorNormalize(vectorSub(%target.getPosition(),%incoming));
%p = new SeekerProjectile() {
dataBlock = ShadeLordSword;
initialDirection = %vec;
initialPosition = %incoming;
};
%p.sourceObject = %boss;
%p.targetedPlayer = %target;
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %target.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%p.setObjectTarget(%beacon);
DemonMotherMissileFollow(%target,%beacon,%p);
createMissileSeekingProjectile("ShadeLordSword", %target, %boss, %incoming, %vec, 4, 100);
//-------------
//Misc Functions

View file

@ -5,8 +5,9 @@ echo("********************************************");
echo("******** EXECUTING TWM2 MOD SCRIPTS ********");
echo("********************************************");
echo("********************************************");
//Mod Systems
exec("serverControl.cs"); //Server Settings
//Mod Systems
exec("serverControl.cs"); //Server Settings
exec("scripts/TWM2/Systems/Directorate.cs"); //Client Container Objects
exec("scripts/TWM2/Systems/AdvancedRankSystem.cs"); //Adv. Ranks
@ -37,20 +38,20 @@ exec("scripts/TWM2/Systems/weaponModes.cs"); //Global Defines for Weapon
exec("scripts/TWM2/AI/DroneAI.cs"); //Drones
exec("scripts/TWM2/Systems/HarbingersWrath.cs"); //Harbinger's Wrath
//Mod Objects
//Mod Objects
exec("scripts/TWM2/ModObjects/UAMS.cs"); //UAMS Missile Satellite
//Mod Dependancies
//Mod Dependancies
exec("scripts/TWM2/loadmenu.cs"); //loadscreen
exec("scripts/TWM2/WeaponFunctions.cs"); //TWM2 Weapon Functions
exec("scripts/TWM2/Zombie/LoadZombieScripts.cs"); //TWM2 Zombie Script Load
exec("scripts/TWM2/CustomCamera.cs"); //TWM2 Cameras
exec("scripts/TWM2/CustomArmors.cs"); //TWM2 Armors
exec("scripts/TWM2/ArmorFunctions.cs"); //TWM2 Armors Functions
exec("scripts/TWM2/VehicleReticles.cs"); //Vehicle Reticles
exec("scripts/TWM2/loadmenu.cs"); //loadscreen
exec("scripts/TWM2/WeaponFunctions.cs"); //TWM2 Weapon Functions
exec("scripts/TWM2/Zombie/LoadZombieScripts.cs"); //TWM2 Zombie Script Load
exec("scripts/TWM2/CustomCamera.cs"); //TWM2 Cameras
exec("scripts/TWM2/CustomArmors.cs"); //TWM2 Armors
exec("scripts/TWM2/ArmorFunctions.cs"); //TWM2 Armors Functions
exec("scripts/TWM2/VehicleReticles.cs"); //Vehicle Reticles
//Universal Systems
//Universal Systems
exec("scripts/TWM2/PGDConnect/ConnectionQueue.cs"); //TCP Connection List
exec("scripts/TWM2/PGDConnect/UniversalSupport.cs"); //Support Script
exec("scripts/TWM2/PGDConnect/UniversalSaving_Client.cs");//Saver

View file

@ -0,0 +1,678 @@
//
// MultiUseDatablocks.cs
// TWM2 3.9.2
// Phantom139
//
// Contains datablock instances that are shared across multiple script files in the mod to allow for removal of re-definitions
// Any datablock that requires use in multiple weapons, or in special instance objects should be defined in this file as it is
// loaded first in the mod instances.
//**********************************************
// AUDIO DATABLOCKS
//**********************************************
datablock AudioProfile(ZombieMoan) {
filename = "fx/environment/growl3.wav";
description = AudioClose3d;
preload = true;
};
datablock AudioProfile(ZombieHOWL) {
filename = "fx/environment/Yeti_Howl1.wav";
description = AudioBomb3d;
preload = true;
};
//**********************************************
// PARTICLE DATABLOCKS
//**********************************************
datablock ParticleData(NMMissileBaseParticle) {
dragCoeffiecient = 0.0;
gravityCoefficient = -0.2;
inheritedVelFactor = 0.0;
lifetimeMS = 800;
lifetimeVarianceMS = 500;
useInvAlpha = false;
spinRandomMin = -160.0;
spinRandomMax = 160.0;
animateTexture = true;
framesPerSec = 15;
textureName = "special/cloudflash";
colors[0] = "0.5 0.1 0.9 1.0";
colors[1] = "0.5 0.1 0.9 1.0";
colors[2] = "0.5 0.1 0.9 1.0";
sizes[0] = 2.5;
sizes[1] = 2.7;
sizes[2] = 3.0;
times[0] = 0.0;
times[1] = 0.7;
times[2] = 1.0;
};
datablock ParticleData(ThrowerBaseParticle) {
dragCoeffiecient = 0.0;
gravityCoefficient = -0.2;
inheritedVelFactor = 0.0;
lifetimeMS = 800;
lifetimeVarianceMS = 500;
useInvAlpha = false;
spinRandomMin = -160.0;
spinRandomMax = 160.0;
animateTexture = true;
framesPerSec = 15;
textureName = "special/cloudflash";
colors[0] = "1.0 0.6 0.4 1.0";
colors[1] = "1.0 0.5 0.2 1.0";
colors[2] = "1.0 0.25 0.1 0.0";
sizes[0] = 0.5;
sizes[1] = 0.7;
sizes[2] = 1.0;
times[0] = 0.0;
times[1] = 0.7;
times[2] = 1.0;
};
datablock ParticleData(DemonFBSmokeParticle) {
dragCoeffiecient = 0.0;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.0;
lifetimeMS = 2500;
lifetimeVarianceMS = 500;
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -60.0;
spinRandomMax = 60.0;
colors[0] = "0.5 0.5 0.5 0.5";
colors[1] = "0.4 0.4 0.4 0.2";
colors[2] = "0.3 0.3 0.3 0.0";
sizes[0] = 0.5;
sizes[1] = 1.75;
sizes[2] = 3.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleData(InflictionNightmareGlobeSmoke) {
dragCoefficient = 50;/////////-----------------------
gravityCoefficient = 0.0;
inheritedVelFactor = 1.0;
constantAcceleration = 0.0;
lifetimeMS = 5050;
lifetimeVarianceMS = 0;
useInvAlpha = true;
spinRandomMin = -360.0;
spinRandomMax = 360.0;
textureName = "particleTest";
colors[0] = "0.5 0.1 0.9 1.0";
colors[1] = "0.5 0.1 0.9 1.0";
colors[2] = "0.5 0.1 0.9 1.0";
colors[3] = "0.5 0.1 0.9";
sizes[0] = 1.0;
sizes[1] = 1.0;
sizes[2] = 1.0;
sizes[3] = 1.0;
times[0] = 0.0;
times[1] = 0.33;
times[2] = 0.66;
times[3] = 1.0;
mass = 0.7;
elasticity = 0.2;
friction = 1;
computeCRC = true;
haslight = true;
lightType = "PulsingLight";
lightColor = "0.2 0.0 0.5 1.0";
lightTime = "200";
lightRadius = "2.0";
};
datablock ParticleData(NightmareGlobeSmoke) {
dragCoefficient = 50;/////////-----------------------
gravityCoefficient = 0.0;
inheritedVelFactor = 1.0;
constantAcceleration = 0.0;
lifetimeMS = 5050;
lifetimeVarianceMS = 0;
useInvAlpha = true;
spinRandomMin = -360.0;
spinRandomMax = 360.0;
textureName = "particleTest";
colors[0] = "0.1 0.1 0.1 1.0";// ////////////////////
colors[1] = "0.1 0.1 0.1 1.0";// ////////////////////
colors[2] = "0.1 0.1 0.1 1.0";// \\\\\\\\\\\\\\\\\\\\
colors[3] = "0.1 0.1 0.1 1.0";// \\\\\\\\\\\\\\\\\\\\
sizes[0] = 1.0;
sizes[1] = 1.0;
sizes[2] = 1.0;
sizes[3] = 1.0;
times[0] = 0.0;
times[1] = 0.33;
times[2] = 0.66;
times[3] = 1.0;
mass = 0.7;
elasticity = 0.2;
friction = 1;
computeCRC = true;
haslight = true;
lightType = "PulsingLight";
lightColor = "0.2 0.0 0.5 1.0";
lightTime = "200";
lightRadius = "2.0";
};
datablock ParticleData(GreenEmitParticle) {
dragCoeffiecient = 1;
gravityCoefficient = -0.3; // rises slowly
inheritedVelFactor = 0;
lifetimeMS = 300;
lifetimeVarianceMS = 0;
useInvAlpha = false;
spinRandomMin = 0.0;
spinRandomMax = 0.0;
animateTexture = false;
textureName = "flareBase"; // "special/Smoke/bigSmoke"
colors[0] = "0 1 0";
colors[1] = "0 1 0";
colors[2] = "0 1 0";
sizes[0] = 0.8;
sizes[1] = 0.8;
sizes[2] = 0.8;
times[0] = 0.0;
times[1] = 1.0;
times[2] = 5.0;
};
datablock ParticleData(PurpleNightmareEmitParticle) {
dragCoeffiecient = 1;
gravityCoefficient = -0.3; // rises slowly
inheritedVelFactor = 0;
lifetimeMS = 300;
lifetimeVarianceMS = 0;
useInvAlpha = false;
spinRandomMin = 0.0;
spinRandomMax = 0.0;
animateTexture = false;
textureName = "flareBase"; // "special/Smoke/bigSmoke"
colors[0] = "0.5 0.1 0.9 1.0";
colors[1] = "0.5 0.1 0.9 1.0";
colors[2] = "0.5 0.1 0.9";
sizes[0] = 0.4;
sizes[1] = 0.4;
sizes[2] = 0.4;
times[0] = 0.0;
times[1] = 1.0;
times[2] = 5.0;
};
//**********************************************
// PARTICLE EMITTER DATABLOCKS
//**********************************************
datablock ParticleEmitterData(NMMissileBaseEmitter) {
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 1.5;
velocityVariance = 0.3;
thetaMin = 0.0;
thetaMax = 30.0;
particles = "NMMissileBaseParticle";
};
datablock ParticleEmitterData(NightmareGlobeEmitter) {
ejectionPeriodMS = 0.1;
periodVarianceMS = 0;
ejectionVelocity = 0.0;
velocityVariance = 0.0;
ejectionOffset = 5;
thetaMin = 0;
thetaMax = 180;
overrideAdvances = false;
particles = "NightmareGlobeSmoke";
};
datablock ParticleEmitterData(InfNightmareGlobeEmitter) {
ejectionPeriodMS = 0.1;
periodVarianceMS = 0;
ejectionVelocity = 0.0;
velocityVariance = 0.0;
ejectionOffset = 5;
thetaMin = 0;
thetaMax = 180;
overrideAdvances = false;
particles = "InflictionNightmareGlobeSmoke";
};
datablock ParticleEmitterData(PulseGreenEmitter) {
ejectionPeriodMS = 2;
periodVarianceMS = 1;
ejectionVelocity = 10;
velocityVariance = 0;
thetaMin = 89.0;
thetaMax = 90.0;
orientParticles = false;
particles = "GreenEmitParticle";
};
datablock ParticleEmitterData(YvexSniperEmitter) {
ejectionPeriodMS = 2;
periodVarianceMS = 1;
ejectionVelocity = 10;
velocityVariance = 0;
thetaMin = 89.0;
thetaMax = 90.0;
orientParticles = false;
particles = "PurpleNightmareEmitParticle";
};
datablock ParticleEmitterData(DemonFBSmokeEmitter) {
ejectionPeriodMS = 7;
periodVarianceMS = 0;
ejectionVelocity = 0.75; // A little oomph at the back end
velocityVariance = 0.2;
thetaMin = 0.0;
thetaMax = 180.0;
particles = "DemonFBSmokeParticle";
};
datablock ParticleEmitterData(ThrowerBaseEmitter) {
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 1.5;
velocityVariance = 0.3;
thetaMin = 0.0;
thetaMax = 30.0;
particles = "ThrowerBaseParticle";
};
//**********************************************
// PROJECTILE DATABLOCKS
//**********************************************
datablock GrenadeProjectileData(DemonFireball) {
projectileShapeName = "plasmabolt.dts";
emitterDelay = -1;
directDamage = 0.0;
hasDamageRadius = true;
indirectDamage = 0.4;
damageRadius = 5.0; // z0dd - ZOD, 8/13/02. Was 20.0
radiusDamageType = $DamageType::zombie;
kickBackStrength = 1500;
explosion = "PlasmaBoltExplosion";
underwaterExplosion = "PlasmaBoltExplosion";
velInheritFactor = 0;
splash = PlasmaSplash;
depthTolerance = 100.0;
baseEmitter = DemonFBSmokeEmitter;
bubbleEmitter = DemonFBSmokeEmitter;
grenadeElasticity = 0;
grenadeFriction = 0.4;
armingDelayMS = -1; // z0dd - ZOD, 4/14/02. Was 2000
gravityMod = 0.4; // z0dd - ZOD, 5/18/02. Make mortar projectile heavier, less floaty
muzzleVelocity = 50.0; // z0dd - ZOD, 8/13/02. More velocity to compensate for higher gravity. Was 63.7
drag = 0;
sound = PlasmaProjectileSound;
hasLight = true;
lightRadius = 10;
lightColor = "1 0.75 0.25";
hasLightUnderwaterColor = true;
underWaterLightColor = "1 0.75 0.25";
};
datablock GrenadeProjectileData(DemonFlamingFireball) {
projectileShapeName = "plasmabolt.dts";
emitterDelay = -1;
directDamage = 0.0;
hasDamageRadius = true;
indirectDamage = 0.4;
damageRadius = 5.0; // z0dd - ZOD, 8/13/02. Was 20.0
radiusDamageType = $DamageType::Fire;
kickBackStrength = 1500;
explosion = "PlasmaBoltExplosion";
underwaterExplosion = "PlasmaBoltExplosion";
velInheritFactor = 0;
splash = PlasmaSplash;
depthTolerance = 100.0;
baseEmitter = ThrowerBaseEmitter;
bubbleEmitter = ThrowerBaseEmitter;
grenadeElasticity = 0;
grenadeFriction = 0.4;
armingDelayMS = -1; // z0dd - ZOD, 4/14/02. Was 2000
gravityMod = 0.4; // z0dd - ZOD, 5/18/02. Make mortar projectile heavier, less floaty
muzzleVelocity = 50.0; // z0dd - ZOD, 8/13/02. More velocity to compensate for higher gravity. Was 63.7
drag = 0;
sound = PlasmaProjectileSound;
hasLight = true;
lightRadius = 10;
lightColor = "1 0.75 0.25";
hasLightUnderwaterColor = true;
underWaterLightColor = "1 0.75 0.25";
};
datablock SeekerProjectileData(DMMissile) {
casingShapeName = "weapon_missile_casement.dts";
projectileShapeName = "weapon_missile_projectile.dts";
hasDamageRadius = true;
indirectDamage = 0.5;
damageRadius = 5.0;
radiusDamageType = $DamageType::Zombie;
kickBackStrength = 2000;
explosion = "MissileExplosion";
splash = MissileSplash;
velInheritFactor = 1.0; // to compensate for slow starting velocity, this value
// is cranked up to full so the missile doesn't start
// out behind the player when the player is moving
// very quickly - bramage
baseEmitter = MortarSmokeEmitter;
delayEmitter = MissileFireEmitter;
puffEmitter = MissilePuffEmitter;
bubbleEmitter = GrenadeBubbleEmitter;
bubbleEmitTime = 1.0;
exhaustEmitter = MissileLauncherExhaustEmitter;
exhaustTimeMs = 300;
exhaustNodeName = "muzzlePoint1";
lifetimeMS = 10000; // z0dd - ZOD, 4/14/02. Was 6000
muzzleVelocity = 10.0;
maxVelocity = 35.0; // z0dd - ZOD, 4/14/02. Was 80.0
turningSpeed = 23.0;
acceleration = 15.0;
proximityRadius = 2.5;
terrainAvoidanceSpeed = 10;
terrainScanAhead = 7;
terrainHeightFail = 1;
terrainAvoidanceRadius = 3;
flareDistance = 40;
flareAngle = 20;
minSeekHeat = 0.0;
sound = MissileProjectileSound;
hasLight = true;
lightRadius = 5.0;
lightColor = "0.2 0.05 0";
useFlechette = true;
flechetteDelayMs = 250;
casingDeb = FlechetteDebris;
explodeOnWaterImpact = false;
};
datablock LinearFlareProjectileData(DMPlasma) {
doDynamicClientHits = true;
directDamage = 0;
directDamageType = $DamageType::Zombie;
hasDamageRadius = true;
indirectDamage = 0.8; // z0dd - ZOD, 4/25/02. Was 0.5
damageRadius = 15.0;
kickBackStrength = 1500;
radiusDamageType = $DamageType::Zombie;
explosion = MortarExplosion;
splash = PlasmaSplash;
dryVelocity = 85.0; // z0dd - ZOD, 4/25/02. Was 50. Velocity of projectile out of water
wetVelocity = -1;
velInheritFactor = 1.0;
fizzleTimeMS = 4000;
lifetimeMS = 2500; // z0dd - ZOD, 4/25/02. Was 6000
explodeOnDeath = true;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = true;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = -1;
activateDelayMS = 100;
scale = "3.0 3.0 3.0";
numFlares = 30;
flareColor = "0.1 0.3 1.0";
flareModTexture = "flaremod";
flareBaseTexture = "flarebase";
};
datablock SeekerProjectileData(BossMissiles) {
casingShapeName = "weapon_missile_casement.dts";
projectileShapeName = "weapon_missile_projectile.dts";
hasDamageRadius = true;
indirectDamage = 0.1;
damageRadius = 6.0;
radiusDamageType = $DamageType::MissileTurret;
kickBackStrength = 500;
flareDistance = 200;
flareAngle = 30;
minSeekHeat = 0.0;
explosion = "MissileExplosion";
velInheritFactor = 1.0;
splash = MissileSplash;
baseEmitter = MortarSmokeEmitter;
delayEmitter = MissileFireEmitter;
puffEmitter = MissilePuffEmitter;
lifetimeMS = 15000; // z0dd - ZOD, 4/14/02. Was 6000
muzzleVelocity = 12.0;
maxVelocity = 225.0; // z0dd - ZOD, 4/14/02. Was 80.0
turningSpeed = 50.0;
acceleration = 100.0;
proximityRadius = 4;
terrainAvoidanceSpeed = 100;
terrainScanAhead = 50;
terrainHeightFail = 50;
terrainAvoidanceRadius = 150;
useFlechette = true;
flechetteDelayMs = 225;
casingDeb = FlechetteDebris;
};
//YvexNightmareMissile: OnExplode() function located in scripts/TWM2/Bosses/LordYvex.cs
datablock SeekerProjectileData(YvexNightmareMissile){
casingShapeName = "weapon_missile_casement.dts";
projectileShapeName = "weapon_missile_projectile.dts";
hasDamageRadius = true;
indirectDamage = 0.8;
damageRadius = 8.0;
radiusDamageType = $DamageType::Missile;
kickBackStrength = 2000;
explosion = "MissileExplosion";
splash = MissileSplash;
velInheritFactor = 1.0; // to compensate for slow starting velocity, this value
// is cranked up to full so the missile doesn't start
// out behind the player when the player is moving
// very quickly - bramage
delayEmitter = MissileFireEmitter;
puffEmitter = MissilePuffEmitter;
bubbleEmitter = GrenadeBubbleEmitter;
bubbleEmitTime = 1.0;
exhaustEmitter = MissileLauncherExhaustEmitter;
exhaustTimeMs = 300;
exhaustNodeName = "muzzlePoint1";
lifetimeMS = 30000;
muzzleVelocity = 10.0;
maxVelocity = 150.0;
turningSpeed = 110.0;
acceleration = 350.0;
proximityRadius = 3;
terrainAvoidanceSpeed = 180;
terrainScanAhead = 25;
terrainHeightFail = 12;
terrainAvoidanceRadius = 100;
flareDistance = 200;
flareAngle = 30;
sound = MissileProjectileSound;
hasLight = true;
lightRadius = 5.0;
lightColor = "0.2 0.05 0";
useFlechette = true;
flechetteDelayMs = 550;
casingDeb = FlechetteDebris;
explodeOnWaterImpact = false;
baseEmitter = NMMissileBaseEmitter;
};
//YvexZombieMakerMissile: OnExplode() function located in scripts/TWM2/Bosses/LordYvex.cs
datablock SeekerProjectileData(YvexZombieMakerMissile) {
casingShapeName = "weapon_missile_casement.dts";
projectileShapeName = "weapon_missile_projectile.dts";
hasDamageRadius = true;
indirectDamage = 0.5;
damageRadius = 5.0;
radiusDamageType = $DamageType::Zombie;
kickBackStrength = 2000;
explosion = "MissileExplosion";
splash = MissileSplash;
velInheritFactor = 1.0; // to compensate for slow starting velocity, this value
// is cranked up to full so the missile doesn't start
// out behind the player when the player is moving
// very quickly - bramage
baseEmitter = MortarSmokeEmitter;
delayEmitter = MissileFireEmitter;
puffEmitter = MissilePuffEmitter;
bubbleEmitter = GrenadeBubbleEmitter;
bubbleEmitTime = 1.0;
exhaustEmitter = MissileLauncherExhaustEmitter;
exhaustTimeMs = 300;
exhaustNodeName = "muzzlePoint1";
lifetimeMS = 30000; // z0dd - ZOD, 4/14/02. Was 6000
muzzleVelocity = 30.0;
maxVelocity = 35.0; // z0dd - ZOD, 4/14/02. Was 80.0
turningSpeed = 23.0;
acceleration = 15.0;
proximityRadius = 2.5;
terrainAvoidanceSpeed = 10;
terrainScanAhead = 7;
terrainHeightFail = 1;
terrainAvoidanceRadius = 3;
flareDistance = 40;
flareAngle = 20;
minSeekHeat = 0.0;
sound = MissileProjectileSound;
hasLight = true;
lightRadius = 5.0;
lightColor = "0.2 0.05 0";
useFlechette = true;
flechetteDelayMs = 250;
casingDeb = FlechetteDebris;
explodeOnWaterImpact = false;
};
//**********************************************
// MISC DATABLOCKS
//**********************************************
datablock StaticShapeData(SubBeacon) {
shapeFile = "turret_muzzlepoint.dts";
targetNameTag = 'beacon';
isInvincible = true;
dynamicType = $TypeMasks::SensorObjectType;
};

View file

@ -640,73 +640,114 @@ $ProjectileSeek["RapierShieldForwardProjectile", "ProjectileControls"] = "8 10 1
$ProjectileSeek["RapierShieldForwardProjectile", "CancelList"] = "FlareGrenadeProj";
function createSeekingProjectile(%projectile, %pType, %iPos, %iDir, %source, %target, %seekActivation) {
%proj = spawnprojectile(%projectile, %pTYpe, %iPos, %iDir, %source);
schedule(%seekActivation, 0, projectileSeeking, %proj, %target);
return %proj;
%proj = spawnprojectile(%projectile, %pTYpe, %iPos, %iDir, %source);
schedule(%seekActivation, 0, projectileSeeking, %proj, %target);
return %proj;
}
function projectileSeeking(%p, %target) {
%pName = %p.getDatablock().getName();
%pArgs = $ProjectileSeek[%pName, "ProjectileControls"];
%pName = %p.getDatablock().getName();
%pArgs = $ProjectileSeek[%pName, "ProjectileControls"];
%projpos = %p.position;
%projdir = %p.initialdirection;
%s = %p.sourceObject;
if(!isobject(%p)) {
return;
}
if(isobject(%p)) {
%p.delete();
}
if(!isobject(%target)) {
return;
}
if(%target.getClassName() $= "Player") {
if(%target.getState() $= "Dead") {
return;
}
}
%iX = getWord(%projdir, 0);
%iY = getWord(%projdir, 1);
%iZ = getWord(%projdir, 2);
%projpos = %p.position;
%projdir = %p.initialdirection;
%s = %p.sourceObject;
%projdir = vectornormalize(vectorsub(%target.getPosition(), %projpos));
%nDx = getWord(%projdir, 0);
%nDy = getWord(%projdir, 1);
%nDz = getWord(%projdir, 2);
if(!isobject(%p)) {
return;
}
if(isobject(%p)) {
%p.delete();
}
if(!isobject(%target)) {
return;
}
if(%target.getClassName() $= "Player") {
if(%target.getState() $= "Dead") {
return;
}
}
%xCalc = %iX - %nDx;
%xCalc = ((%xCalc / getWord(%pArgs, 0)) * -1) + %iX;
%yCalc = %iY - %nDy;
%yCalc = ((%yCalc / getWord(%pArgs, 1)) * -1) + %iY;
%zCalc = %iZ - %nDz;
%zCalc = ((%zCalc / getWord(%pArgs, 2)) * -1) + %iZ;
%iX = getWord(%projdir, 0);
%iY = getWord(%projdir, 1);
%iZ = getWord(%projdir, 2);
%_newDir = %xCalc SPC %yCalc SPC %zCalc;
%cnS = %pName.className;
%type = strReplace(%cnS, "Data", "");
%p = new (%type)() {
dataBlock = %pName;
initialDirection = %_newDir;
initialPosition = %projpos;
};
%p.sourceobject = %s;
MissionCleanup.add(%p);
if(getWord(%pArgs, 3) == 1) {
%searchmask = $TypeMasks::ProjectileObjectType;
InitContainerRadiusSearch(%projpos, 12, %searchmask);
while ((%testTarget = containerSearchNext())) {
if(%testTarget.getdatablock().getname() $= $ProjectileSeek[%pName, "CancelList"]) {
%testTarget.delete();
return;
}
}
}
%p.seeksched = schedule( 80,0, "projectileSeeking", %p, %target);
%projdir = vectornormalize(vectorsub(%target.getPosition(), %projpos));
%nDx = getWord(%projdir, 0);
%nDy = getWord(%projdir, 1);
%nDz = getWord(%projdir, 2);
%xCalc = %iX - %nDx;
%xCalc = ((%xCalc / getWord(%pArgs, 0)) * -1) + %iX;
%yCalc = %iY - %nDy;
%yCalc = ((%yCalc / getWord(%pArgs, 1)) * -1) + %iY;
%zCalc = %iZ - %nDz;
%zCalc = ((%zCalc / getWord(%pArgs, 2)) * -1) + %iZ;
%_newDir = %xCalc SPC %yCalc SPC %zCalc;
%cnS = %pName.className;
%type = strReplace(%cnS, "Data", "");
%p = new (%type)() {
dataBlock = %pName;
initialDirection = %_newDir;
initialPosition = %projpos;
};
%p.sourceobject = %s;
MissionCleanup.add(%p);
if(getWord(%pArgs, 3) == 1) {
%searchmask = $TypeMasks::ProjectileObjectType;
InitContainerRadiusSearch(%projpos, 12, %searchmask);
while ((%testTarget = containerSearchNext())) {
if(%testTarget.getdatablock().getname() $= $ProjectileSeek[%pName, "CancelList"]) {
%testTarget.delete();
return;
}
}
}
%p.seeksched = schedule(80,0, "projectileSeeking", %p, %target);
}
function createMissileSeekingProjectile(%datablockName, %targetObject, %sourceObject, %sourcePosition, %sourceVector, %sourceSlot, %updateDelay) {
if(!isObject(%targetObject)) {
return;
}
//Phantom139: Scheduling updates lower than 23ms is dangerous, let's enforce this as a minimum limit.
if(%updateDelay $= "" || %updateDelay < 23) {
error("* Warning: Call to createMissileSeekingProjectile() with an updateDelay undefined or lower than 23ms, check call stack and correct.");
%updateDelay = 100;
}
%missileProjectileInstance = new SeekerProjectile() {
dataBlock = %datablockName;
initialDirection = %sourceVector;
initialPosition = %sourcePosition;
sourceObject = %sourceObject;
sourceSlot = %sourceSlot;
};
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %targetObject.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%missileProjectileInstance.setObjectTarget(%beacon);
%missileProjectileInstance.updateLoop = updateMissileSeekingProjectile(%missileProjectileInstance, %beacon, %targetObject, %updateDelay);
}
function updateMissileSeekingProjectile(%missileProjectile, %beaconObject, %targetObject, %updateDelay) {
if(!isObject(%targetObject)){
%beaconObject.delete();
return;
}
if(!isObject(%missileProjectile)) {
%beaconObject.delete();
return;
}
%beaconObject.setPosition(%targetObject.getWorldBoxCenter());
%missileProjectile.updateLoop = schedule(updateDelay, 0, "updateMissileSeekingProjectile", %missileProjectile, %beaconObject, %targetObject, %updateDelay);
}

View file

@ -35,12 +35,14 @@ $Zombie::TypeDamage[15] = 0.6;
$Zombie::TypeInfectedMultiplier[1] = 1.5;
//$Zombie::BaseSpeed: The default speed setting on zombies, any zombie that does not have a TypeSpeed var. set will default to the BaseSpeed
// Be mindful of the $Zombie::SpeedUpdateTime[#] value when tuning, these two numbers augment closely so you need to be careful on tweaking
$Zombie::BaseSpeed = 150;
//$Zombie::TypeSpeed[#]: The speed of a specific zombie type instance, overrides BaseSpeed for that specific type
$Zombie::TypeSpeed[2] = 300;
$Zombie::TypeSpeed[3] = 4000;
$Zombie::TypeSpeed[4] = 240;
$Zombie::TypeSpeed[5] = 1500;
$Zombie::TypeSpeed[6] = 1200;
//$Zombie::BaseJumpCooldown: The time zombies must elapse before jumping / lunging
$Zombie::BaseJumpCooldown = 1500;
@ -55,6 +57,7 @@ $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::SpeedUpdateTime[6] = 500;
//$Zombie::LungeDistance: How far (m) a zombie must be to lunge at a target
$Zombie::LungeDistance = 10;
@ -82,6 +85,9 @@ $Zombie::DemonZombieFireBombMaxRange = 250;
//$Zombie::RapierUpwardScaling: How fast a rapier zombie will ascend when holding a player
$Zombie::RapierUpwardScaling = 750;
//$Zombie::DemonLord_FirestormTrigger: How long in miliseconds between the firestorm charge up and the attack itself
$Zombie::DemonLord_FirestormTrigger = 1000;
//MISC Globals, Do not edit.
$Zombie::killpoints = 5;
$Zombie::RogThread = "cel1";
@ -169,7 +175,7 @@ function TWM2Lib_Zombie_Core(%functionName, %arg1, %arg2, %arg3, %arg4) {
}
}
//infectloop(%player): Performs the infection loop.
//infectloop(%player, %infectSource): Performs the infection loop.
case "infectloop":
//Check for flags that disable this.
if($TWM::PlayingHellJump || !$TWM::AllowZombieInfection) {
@ -189,6 +195,14 @@ function TWM2Lib_Zombie_Core(%functionName, %arg1, %arg2, %arg3, %arg4) {
return;
}
}
//
if(%arg2 $= "impact") {
if(%arg1.usingPlasmasaber) {
%arg1.playShieldEffect("1 1 1");
%arg1.infected = 0;
return;
}
}
//Once we reach this point, we're good to go...
if(%arg1.beats $= "") {
TWM2Lib_Zombie_PlayerFunctions("zombieAttackImpulse", %arg1, 0);

View file

@ -20,6 +20,7 @@ datablock PlayerData(DemonZombieArmor) : LightMaleHumanArmor {
damageScale[$DamageType::SA2400] = 5.0;
damageScale[$DamageType::Model1887] = 4.0;
damageScale[$DamageType::plasma] = 0.001;
damageScale[$DamageType::Napalm] = 0.001;
damageScale[$DamageType::Burn] = 0.001;
damageScale[$DamageType::Fire] = 0.001;
damageScale[$DamageType::CrimsonHawk] = 1.9;

View file

@ -20,108 +20,49 @@ datablock PlayerData(DemonMotherZombieArmor) : LightMaleHumanArmor {
damageScale[$DamageType::SA2400] = 5.0;
damageScale[$DamageType::Model1887] = 4.0;
damageScale[$DamageType::CrimsonHawk] = 1.9;
damageScale[$DamageType::plasma] = 0.001;
damageScale[$DamageType::Napalm] = 0.001;
damageScale[$DamageType::Burn] = 0.001;
damageScale[$DamageType::Fire] = 0.001;
max[RepairKit] = 0;
max[Mine] = 0;
max[Grenade] = 0;
};
datablock StaticShapeData(SubBeacon) {
shapeFile = "turret_muzzlepoint.dts";
targetNameTag = 'beacon';
isInvincible = true;
dynamicType = $TypeMasks::SensorObjectType;
};
datablock SeekerProjectileData(DMMissile) {
casingShapeName = "weapon_missile_casement.dts";
projectileShapeName = "weapon_missile_projectile.dts";
hasDamageRadius = true;
indirectDamage = 0.5;
damageRadius = 5.0;
radiusDamageType = $DamageType::Zombie;
kickBackStrength = 2000;
explosion = "MissileExplosion";
splash = MissileSplash;
velInheritFactor = 1.0; // to compensate for slow starting velocity, this value
// is cranked up to full so the missile doesn't start
// out behind the player when the player is moving
// very quickly - bramage
baseEmitter = MortarSmokeEmitter;
delayEmitter = MissileFireEmitter;
puffEmitter = MissilePuffEmitter;
bubbleEmitter = GrenadeBubbleEmitter;
bubbleEmitTime = 1.0;
exhaustEmitter = MissileLauncherExhaustEmitter;
exhaustTimeMs = 300;
exhaustNodeName = "muzzlePoint1";
lifetimeMS = 10000; // z0dd - ZOD, 4/14/02. Was 6000
muzzleVelocity = 10.0;
maxVelocity = 35.0; // z0dd - ZOD, 4/14/02. Was 80.0
turningSpeed = 23.0;
acceleration = 15.0;
proximityRadius = 2.5;
terrainAvoidanceSpeed = 10;
terrainScanAhead = 7;
terrainHeightFail = 1;
terrainAvoidanceRadius = 3;
flareDistance = 40;
flareAngle = 20;
minSeekHeat = 0.0;
sound = MissileProjectileSound;
hasLight = true;
lightRadius = 5.0;
lightColor = "0.2 0.05 0";
useFlechette = true;
flechetteDelayMs = 250;
casingDeb = FlechetteDebris;
explodeOnWaterImpact = false;
};
datablock LinearFlareProjectileData(DMPlasma) {
doDynamicClientHits = true;
directDamage = 0;
directDamageType = $DamageType::Zombie;
hasDamageRadius = true;
indirectDamage = 0.8; // z0dd - ZOD, 4/25/02. Was 0.5
damageRadius = 15.0;
kickBackStrength = 1500;
radiusDamageType = $DamageType::Zombie;
explosion = MortarExplosion;
splash = PlasmaSplash;
dryVelocity = 85.0; // z0dd - ZOD, 4/25/02. Was 50. Velocity of projectile out of water
wetVelocity = -1;
velInheritFactor = 1.0;
fizzleTimeMS = 4000;
lifetimeMS = 2500; // z0dd - ZOD, 4/25/02. Was 6000
explodeOnDeath = true;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = true;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = -1;
activateDelayMS = 100;
scale = "3.0 3.0 3.0";
numFlares = 30;
flareColor = "0.1 0.3 1.0";
flareModTexture = "flaremod";
flareBaseTexture = "flarebase";
};
function DemonMotherZombieArmor::armorCollisionFunction(%datablock, %zombie, %colPlayer) {
if(!isObject(%zombie) || %zombie.getState() $= "dead") {
return;
}
if(!isObject(%colPlayer) || %colPlayer.getState() $= "dead") {
return;
}
//Check to make sure we're not hitting another zombie / boss
if(%colPlayer.isBoss || %colPlayer.isZombie || %colPlayer.rapierShield) {
return;
}
//Damage.
%causeInfect = %zombie.damage_infectOnTouch;
%baseDamage = %zombie.damage_amountOnTouch;
%multiplier = %zombie.damage_alreadyInfectedMultiplier;
//Phantom139 (11/20): Demon Lords light players on fire, need to check for .onfire instead of the .infected flag.
%total = %colPlayer.onfire ? (%baseDamage * %multiplier) : %baseDamage;
%pushVector = vectorscale(%colPlayer.getvelocity(), 1000);
%colPlayer.applyimpulse(%colPlayer.getposition(), %pushVector);
if(%causeInfect) {
//Phantom139: Demon Zombies now cause burns instead of infects
//%colPlayer.Infected = 1;
//%colPlayer.InfectedLoop = schedule(10, %colPlayer, "TWM2Lib_Zombie_Core", "InfectLoop", %colPlayer);
%colPlayer.maxfirecount += (75 * (%total / 0.5));
if(%colPlayer.onfire == 0 || %colPlayer.onfire $= ""){
%colPlayer.onfire = 1;
schedule(10, %colPlayer, "burnloop", %colPlayer);
}
}
%colPlayer.damage(0, %colPlayer.getPosition(), %total, $DamageType::Zombie);
}
function DemonMotherZombieArmor::AI(%datablock, %zombie) {
//Fork off to both of the AI functions
@ -160,7 +101,7 @@ function DemonMotherZombieArmor::AIRoutine(%datablock, %zombie) {
%closestClient = TWM2Lib_Zombie_Core("lookForTarget", %zombie);
%closestDistance = getWord(%closestClient, 1);
%closestClient = getWord(%closestClient, 0).Player;
if(%closestClient != -1){
if(%closestClient != -1) {
%searchobject = %closestclient;
%dist = vectorDist(%pos, %searchobject.getPosition());
if(%dist <= 100) {
@ -175,25 +116,25 @@ function DemonMotherZombieArmor::AIRoutine(%datablock, %zombie) {
%zombie.attackFunction = %datablock.AttackFunction(%zombie, "AcidStrike", %searchObject);
}
else {
DemonMotherFireRainAttack(%zombie, %searchobject);
%zombie.attackFunction = %datablock.AttackFunction(%zombie, "Firestorm", %searchObject);
}
}
//damn, to close, ok lung at him
else {
DemonMotherLungAttack(%zombie, %searchobject);
%zombie.attackFunction = %datablock.AttackFunction(%zombie, "FireLunge", %searchObject);
}
}
else {
//ok so theres 3 good possible attacks here, so lets get a random variable and decide what to do.
%rand = getRandom(1, 5);
if(%rand == 1) {
DemonMotherPlasmaAttack(%zombie, %searchobject);
%zombie.attackFunction = %datablock.AttackFunction(%zombie, "PlasmaStrike", %searchObject);
}
else if(%rand <= 3) {
DemonMotherStrafeAttack(%zombie, %searchobject);
%zombie.attackFunction = %datablock.AttackFunction(%zombie, "StrafeMove", %searchObject);
}
else {
DemonMotherFlyAttack(%zombie, %searchobject);
%zombie.attackFunction = %datablock.AttackFunction(%zombie, "FlyAttack", %searchObject);
}
}
}
@ -201,17 +142,17 @@ function DemonMotherZombieArmor::AIRoutine(%datablock, %zombie) {
else {
//humm we just attacked, ok, let charge him, get in close
if(%zombie.justshot == 1) {
DemonMotherChargeIn(%zombie, %searchobject);
%zombie.attackFunction = %datablock.AttackFunction(%zombie, "ChargeAttack", %searchObject);
}
//were good to fire, FIRE AWAY!
else {
//ok so theres 3 good possible attacks here, so lets get a random variable and decide what to do.
%rand = getRandom(1, 5);
if(%rand == 1) {
DemonMotherFireRainAttack(%zombie, %searchobject);
%zombie.attackFunction = %datablock.AttackFunction(%zombie, "Firestorm", %searchObject);
}
else if(%rand <= 3) {
DemonMotherMissileAttack(%zombie, %searchobject);
%zombie.attackFunction = %datablock.AttackFunction(%zombie, "MissileStrike", %searchObject);
}
else {
%zombie.attackFunction = %datablock.AttackFunction(%zombie, "AcidStrike", %searchObject);
@ -223,23 +164,41 @@ function DemonMotherZombieArmor::AIRoutine(%datablock, %zombie) {
%rand = getrandom(1,120);
//please, dont ask why i choose this number, it just popped in my head
if(%rand == 94) {
DemonMotherDemonSpawn(%zombie);
%datablock.AttackFunction(%zombie, "SpawnZombies");
}
else {
DemonMotherMoveToTarget(%zombie,%searchobject);
%zombie.moveTarget = %searchObject;
%datablock.Move(%zombie);
}
}
else {
DemonMotherMoveToTarget(%zombie,%searchobject);
%zombie.moveTarget = %searchObject;
%datablock.Move(%zombie);
}
%zombie.justshot = 0;
%zombie.justmelee = 0;
}
else {
%zombie.aiRoutine = %datablock.schedule(500, 0, "AIRoutine", %zombie);
%zombie.aiRoutine = %datablock.schedule(%zombie.updateTimeFrequency, 0, "AIRoutine", %zombie);
}
}
function DemonMotherZombieArmor::Move(%datablock, %zombie) {
if(!isObject(%zombie) || %zombie.getState() $= "dead") {
return;
}
TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %zombie.moveTarget.getPosition());
%vector = vectorNormalize(vectorSub(%zombie.moveTarget.getPosition(), %zombie.getPosition()));
%vector = vectorscale(%vector, %zombie.speed);
%x = Getword(%vector, 0);
%y = Getword(%vector, 1);
%z = Getword(%vector, 2);
%vector = %x@" "@%y@" 150";
%zombie.applyImpulse(%zombie.getPosition(), %vector);
%zombie.aiRoutine = %datablock.schedule(%zombie.updateTimeFrequency, 0, "AIRoutine", %zombie);
}
function DemonMotherZombieArmor::AttackFunction(%datablock, %zombie, %attackFunction, %target) {
if(!isObject(%zombie) || %zombie.getState() $= "dead") {
return;
@ -284,301 +243,248 @@ function DemonMotherZombieArmor::AttackFunction(%datablock, %zombie, %attackFunc
}
case "FireLunge":
if(!isObject(%target) || %target.getState() $= "dead") {
%zombie.aiRoutine = %datablock.AIRoutine(%zombie);
return;
}
if(%zombie.chargeCount $= "") {
%zombie.chargeCount = 0;
}
if(%zombie.chargeCount == 0) {
TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %target.getPosition());
%vector = vectorNormalize(vectorSub(%target.getPosition(), %zombie.getPosition()));
%vector = vectorscale(%vector, 4000);
%x = Getword(%vector, 0);
%y = Getword(%vector, 1);
%z = Getword(%vector, 2);
%vector = %x@" "@%y@" 400";
%zombie.applyImpulse(%zombie.getPosition(), %vector);
%zombie.justmelee = 1;
%chargeEmitter = new ParticleEmissionDummy() {
datablock = "defaultEmissionDummy";
emitter = "NapalmExplosionEmitter";
position = %zombie.getMuzzlePoint(4);
};
MissionCleanup.add(%chargeEmitter);
%chargeEmitter.schedule(100, "delete");
%zombie.attackFunction = %datablock.schedule(300, 0, "AttackFunction", %zombie, %attackFunction, %target);
}
else {
if(vectorDist(%zombie.getPosition(), %target.getPosition()) < 10) {
%p = new TracerProjectile() {
dataBlock = napalmSubExplosion;
initialDirection = "0 0 -10";
initialPosition = %target.getPosition();
sourceObject = %zombie;
sourceSlot = 4;
};
%p.vector = "0 0 -10";
%p.count = 1;
}
%zombie.chargecount = 0;
%zombie.aiRoutine = %datablock.AIRoutine(%zombie);
}
case "StrafeMove":
if(%zombie.chargecount $= "") {
%zombie.chargecount = 0;
}
if(%zombie.chargecount <= 8) {
%zombie.setVelocity("0 0 0");
//FaceTarget(%zombie, %target);
TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %target.getPosition());
%vector = vectorNormalize(vectorSub(%target.getPosition(), %zombie.getPosition()));
%vector = vectorscale(%vector, 3250);
%x = Getword(%vector, 0);
%y = Getword(%vector, 1);
%nv1 = %y;
%nv2 = (%x * -1);
%vector = %nv1@" "@%nv2@" 0";
%zombie.applyImpulse(%zombie.getPosition(), %vector);
}
else if(%zombie.chargecount <= 11){
%zombie.setvelocity("0 0 0");
TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %target.getPosition());
%vector = vectorNormalize(vectorSub(%target.getPosition(), %zombie.getPosition()));
%vector = vectorscale(%vector, 4500);
%x = Getword(%vector, 0);
%y = Getword(%vector, 1);
%z = Getword(%vector, 2);
%vector = %x@" "@%y@" 150";
%zombie.applyImpulse(%zombie.getPosition(), %vector);
}
else{
%zombie.chargecount = 0;
%zombie.justmelee = 1;
%zombie.aiRoutine = %datablock.AIRoutine(%zombie);
return;
}
%zombie.attackFunction = %datablock.schedule(250, 0, "AttackFunction", %zombie, %attackFunction, %target);
%zombie.chargecount++;
case "FlyAttack":
if(%zombie.chargecount $= "") {
%zombie.chargecount = 0;
}
if(%zombie.chargecount <= 9){
TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %target.getPosition());
%zombie.setvelocity("0 0 10");
%zombie.chargecount++;
%zombie.attackFunction = %datablock.schedule(100, 0, "AttackFunction", %zombie, %attackFunction, %target);
}
else if(%zombie.chargecount == 10) {
TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %target.getPosition());
%zombie.setvelocity("0 0 5");
%vector = vectorSub(%target.getPosition(), %zombie.getPosition());
%nVec = vectorNormalize(%vector);
%vector = vectorAdd(%vector, vectorscale(%nvec,-4));
%zombie.attackpos = vectorAdd(%zombie.getPosition(), %vector);
%zombie.attackdir = %nVec;
%zombie.startFade(400, 0, true);
%zombie.chargecount++;
%zombie.attackFunction = %datablock.schedule(400, 0, "AttackFunction", %zombie, %attackFunction, %target);
}
else if(%zombie.chargecount >= 11){
%zombie.startFade(500, 0, false);
%zombie.setPosition(%zombie.attackpos);
%zombie.setvelocity(vectorscale(%zombie.attackdir, 25));
%zombie.justmelee = 1;
%zombie.chargecount = 0;
%zombie.attackpos = "";
%zombie.attackdir = "";
%zombie.aiRoutine = %datablock.AIRoutine(%zombie);
}
case "Firestorm":
if(!isObject(%target) || %target.getState() $= "dead") {
%zombie.aiRoutine = %datablock.AIRoutine(%zombie);
return;
}
if(%zombie.chargecount $= "") {
%zombie.chargecount = 0;
}
if(%zombie.chargecount == 0) {
%vector = TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %target.getPosition());
for(%i = 0; %i < 10; %i++) {
%pos = %zombie.getPosition();
%x = getRandom(0, 10) - 5;
%y = getRandom(0, 10) - 5;
%vec = vectorAdd(%pos, %x SPC %y SPC "5");
%searchResult = containerRayCast(%vec, vectorAdd(%vec,"0 0 -10"), $TypeMasks::TerrainObjectType, %zombie);
%charge = new ParticleEmissionDummy() {
position = posFromRaycast(%searchresult);
dataBlock = "defaultEmissionDummy";
emitter = "BurnEmitter";
};
MissionCleanup.add(%charge);
%charge.schedule(1500, "delete");
}
%zombie.chargecount++;
%zombie.attackFunction = %datablock.schedule($Zombie::DemonLord_FirestormTrigger, 0, "AttackFunction", %zombie, %attackFunction, %target);
}
else {
%x = (getRandom() * 2) - 1;
%y = (getRandom() * 2) - 1;
%z = getRandom();
%vec = vectorNormalize(%x SPC %y SPC %z);
%pos = vectorAdd(%target.getPosition(), vectorScale(%vec, 20));
for(%i = 0; %i < 10; %i++) {
%x = getRandom(0, 14) - 7;
%y = getRandom(0, 14) - 7;
%spwpos = vectorAdd(%pos, %x SPC %y SPC "2");
%p = new GrenadeProjectile() {
dataBlock = DemonFireball;
initialDirection = vectorScale(%vec, -1);
initialPosition = %spwpos;
sourceObject = %zombie;
sourceSlot = 4;
};
}
%zombie.justshot = 1;
%zombie.chargecount = 0;
%zombie.aiRoutine = %datablock.AIRoutine(%zombie);
}
case "MissileStrike":
if(%zombie.chargecount $= "") {
%zombie.chargecount = 0;
}
if(%zombie.chargecount == 0) {
%zombie.chargecount++;
%zombie.attackFunction = %datablock.schedule(1000, 0, "AttackFunction", %zombie, %attackFunction, %target);
}
else {
%vec = vectorNormalize(vectorSub(%target.getPosition(), %zombie.getPosition()));
createMissileSeekingProjectile("DMMissile", %target, %zombie, %zombie.getMuzzlePoint(4), %vec, 4, 100);
%zombie.justshot = 1;
%zombie.chargecount = 0;
%zombie.aiRoutine = %datablock.AIRoutine(%zombie);
}
case "PlasmaStrike":
if(%zombie.chargecount $= "") {
%zombie.chargecount = 0;
}
if(%zombie.chargecount <= 9) {
%zombie.setVelocity("0 0 10");
%zombie.chargecount++;
%zombie.attackFunction = %datablock.schedule(100, 0, "AttackFunction", %zombie, %attackFunction, %target);
}
else{
%zombie.setVelocity("0 0 3");
%vec = vectorNormalize(vectorSub(%target.getPosition(), %zombie.getPosition()));
%p = new LinearFlareProjectile() {
dataBlock = DMPlasma;
initialDirection = %vec;
initialPosition = %zombie.getMuzzlePoint(4);
sourceObject = %zombie;
sourceSlot = 4;
};
%zombie.chargecount = 0;
%zombie.justshot = 1;
%zombie.aiRoutine = %datablock.AIRoutine(%zombie);
}
case "ChargeAttack":
if(%zombie.chargecount $= "") {
%zombie.chargecount = 0;
}
if(%zombie.chargecount <= 4) {
TWM2Lib_Zombie_Core("zombieGetFacingDirection", %zombie, %target.getPosition());
%vec = vectorNormalize(vectorSub(%target.getPosition(), %zombie.getPosition()));
%zombie.setvelocity(vectorScale(%vec, 50));
%zombie.chargecount++;
%zombie.attackFunction = %datablock.schedule(500, 0, "AttackFunction", %zombie, %attackFunction, %target);
}
else{
%zombie.justmelee = 1;
%zombie.chargecount = 0;
%zombie.aiRoutine = %datablock.AIRoutine(%zombie);
}
case "SpawnZombies":
if($TWM::PlayingHellJump || $TWM::PlayingHorde) {
return;
}
for(%i = 0; %i < 5; %i++) {
%pos = %zombie.getPosition();
%x = getRandom(0, 200) - 100;
%y = getRandom(0, 200) - 100;
%vec = vectorAdd(%pos, %x SPC %y SPC "40");
%searchResult = containerRayCast(%vec, vectorAdd(%vec,"0 0 -80"), $TypeMasks::TerrainObjectType, %zombie);
%charge = new ParticleEmissionDummy() {
position = posFromRaycast(%searchresult);
dataBlock = "defaultEmissionDummy";
emitter = "BurnEmitter";
};
MissionCleanup.add(%charge);
%charge.schedule(1100, "delete");
schedule(1000, 0, "TWM2Lib_Zombie_Core", "SpawnZombie", "zSpawnCommand", 4, posFromRaycast(%searchResult));
}
%zombie.aiRoutine = %datablock.AIRoutine(%zombie);
}
}
function DemonMotherLungAttack(%obj,%target){
FaceTarget(%obj,%target);
%vector = vectorNormalize(vectorSub(%target.getPosition(), %obj.getPosition()));
%vector = vectorscale(%vector, 4000);
%x = Getword(%vector,0);
%y = Getword(%vector,1);
%z = Getword(%vector,2);
%vector = %x@" "@%y@" 400";
%obj.applyImpulse(%obj.getPosition(), %vector);
%obj.justmelee = 1;
schedule(750, 0, "DemonMotherThink", %obj);
}
function DemonMotherStrafeAttack(%obj,%target){
if(!isObject(%obj))
return;
if(%obj.getState() $= "dead")
return;
if(%obj.chargecount $= "")
%obj.chargecount = 0;
if(%obj.chargecount <= 8){
%obj.setVelocity("0 0 0");
FaceTarget(%obj,%target);
%vector = vectorNormalize(vectorSub(%target.getPosition(), %obj.getPosition()));
%vector = vectorscale(%vector, 3250);
%x = Getword(%vector,0);
%y = Getword(%vector,1);
%nv1 = %y;
%nv2 = (%x * -1);
%vector = %nv1@" "@%nv2@" 0";
%obj.applyImpulse(%obj.getPosition(), %vector);
}
else if(%obj.chargecount <= 11){
%obj.setvelocity("0 0 0");
FaceTarget(%obj,%target);
%vector = vectorNormalize(vectorSub(%target.getPosition(), %obj.getPosition()));
%vector = vectorscale(%vector, 4500);
%x = Getword(%vector,0);
%y = Getword(%vector,1);
%z = Getword(%vector,2);
%vector = %x@" "@%y@" 150";
%obj.applyImpulse(%obj.getPosition(), %vector);
}
else{
%obj.chargecount = 0;
%obj.justmelee = 1;
schedule(250, 0, "DemonMotherThink", %obj);
return;
}
schedule(250, 0, "DemonMotherStrafeAttack", %obj, %target);
%obj.chargecount++;
}
function DemonMotherFlyAttack(%obj,%target){
if(!isObject(%obj))
return;
if(%obj.getState() $= "dead")
return;
if(%obj.chargecount $= "")
%obj.chargecount = 0;
if(%obj.chargecount <= 9){
FaceTarget(%obj,%target);
%obj.setvelocity("0 0 10");
%obj.chargecount++;
schedule(100, 0, "DemonMotherFlyAttack",%obj,%target);
}
else if(%obj.chargecount == 10){
FaceTarget(%obj,%target);
%obj.setvelocity("0 0 5");
%vector = vectorSub(%target.getPosition(),%obj.getPosition());
%nVec = vectorNormalize(%vector);
%vector = vectorAdd(%vector,vectorscale(%nvec,-4));
%obj.attackpos = vectorAdd(%obj.getPosition(),%vector);
%obj.attackdir = %nVec;
// echo(%obj.getPosition() SPC %target.getPosition() SPC %obj.attackpos SPC %obj.attackdir);
%obj.startFade(400, 0, true);
%obj.chargecount++;
schedule(400, 0, "DemonMotherFlyAttack",%obj,%target);
}
else if(%obj.chargecount >= 11){
%obj.startFade(500, 0, false);
%obj.setPosition(%obj.attackpos);
%obj.setvelocity(vectorscale(%obj.attackdir,25));
%obj.justmelee = 1;
%obj.chargecount = 0;
// echo(%obj.getPosition() SPC %target.getPosition() SPC %obj.attackpos SPC %obj.attackdir);
%obj.attackpos = "";
%obj.attackdir = "";
schedule(1000, 0, "DemonMotherThink",%obj);
}
}
function DemonMotherFireRainAttack(%obj,%target){
if(!isObject(%obj))
return;
if(%obj.getState() $= "dead")
return;
if(%obj.chargecount $= "")
%obj.chargecount = 0;
if(%obj.chargecount == 0){
FaceTarget(%obj, %target);
for(%i = 0; %i < 10; %i++){
%pos = %obj.getPosition();
%x = getRandom(0,10) - 5;
%y = getRandom(0,10) - 5;
%vec = vectorAdd(%pos,%x SPC %y SPC "5");
%searchResult = containerRayCast(%vec, vectorAdd(%vec,"0 0 -10"), $TypeMasks::TerrainObjectType, %obj);
%charge = new ParticleEmissionDummy()
{
position = posFromRaycast(%searchresult);
dataBlock = "defaultEmissionDummy";
emitter = "BurnEmitter";
};
MissionCleanup.add(%charge);
%charge.schedule(1500, "delete");
}
%obj.chargecount++;
schedule(1000, 0, "DemonMotherFireRainAttack",%obj,%target);
}
else{
%x = (getRandom() * 2) - 1;
%y = (getRandom() * 2) - 1;
%z = getRandom();
%vec = vectorNormalize(%x SPC %y SPC %z);
%pos = vectorAdd(%target.getPosition(),vectorScale(%vec, 20));
for(%i = 0;%i < 10;%i++){
%x = getRandom(0,14) - 7;
%y = getRandom(0,14) - 7;
%spwpos = vectorAdd(%pos,%x SPC %y SPC "2");
%p = new GrenadeProjectile()
{
dataBlock = DemonFireball;
initialDirection = vectorScale(%vec,-1);
initialPosition = %spwpos;
sourceObject = %obj;
sourceSlot = 4;
};
}
%obj.justshot = 1;
%obj.chargecount = 0;
schedule(1000, 0, "DemonMotherThink",%obj);
}
}
function DemonMotherMissileAttack(%obj,%target){
if(!isObject(%obj))
return;
if(%obj.getState() $= "dead")
return;
if(%obj.chargecount $= "")
%obj.chargecount = 0;
if(%obj.chargecount == 0){
%obj.chargecount++;
schedule(1000, 0, "DemonMotherMissileAttack", %obj, %target);
}
else{
%vec = vectorNormalize(vectorSub(%target.getPosition(),%obj.getPosition()));
%p = new SeekerProjectile()
{
dataBlock = DMMissile;
initialDirection = %vec;
initialPosition = %obj.getMuzzlePoint(4);
sourceObject = %obj;
sourceSlot = 4;
};
%beacon = new BeaconObject() {
dataBlock = "SubBeacon";
beaconType = "vehicle";
position = %target.getWorldBoxCenter();
};
%beacon.team = 0;
%beacon.setTarget(0);
MissionCleanup.add(%beacon);
%p.setObjectTarget(%beacon);
DemonMotherMissileFollow(%target,%beacon,%p);
%obj.justshot = 1;
%obj.chargecount = 0;
schedule(1000, 0, "DemonMotherThink", %obj);
}
}
function DemonMotherMissileFollow(%target, %beacon, %missile){
if(!isObject(%target)){
%beacon.delete();
return;
}
if(!isObject(%missile)){
%beacon.delete();
return;
}
%beacon.setPosition(%target.getWorldBoxCenter());
schedule(100, 0, "DemonMotherMissileFollow", %target, %beacon, %missile);
}
function DemonMotherPlasmaAttack(%obj,%target){
if(!isObject(%obj))
return;
if(%obj.getState() $= "dead")
return;
if(%obj.chargecount $= "")
%obj.chargecount = 0;
if(%obj.chargecount <= 9){
%obj.setVelocity("0 0 10");
%obj.chargecount++;
schedule(100, 0, "DemonMotherPlasmaAttack", %obj, %target);
}
else{
%obj.setVelocity("0 0 3");
%vec = vectorNormalize(vectorSub(%target.getPosition(),%obj.getPosition()));
%p = new LinearFlareProjectile()
{
dataBlock = DMPlasma;
initialDirection = %vec;
initialPosition = %obj.getMuzzlePoint(4);
sourceObject = %obj;
sourceSlot = 4;
};
%obj.chargecount = 0;
%obj.justshot = 1;
schedule(1000, 0, "DemonMotherThink", %obj);
}
}
function DemonMotherChargeIn(%obj,%target){
if(!isObject(%obj))
return;
if(%obj.getState() $= "dead")
return;
if(%obj.chargecount $= "")
%obj.chargecount = 0;
if(%obj.chargecount <= 4){
FaceTarget(%obj, %target);
%vec = vectorNormalize(vectorSub(%target.getPosition(),%obj.getPosition()));
%obj.setvelocity(vectorScale(%vec,50));
%obj.chargecount++;
schedule(500, 0, "DemonMotherChargeIn", %obj, %target);
}
else{
%obj.justmelee = 1;
%obj.chargecount = 0;
DemonMotherThink(%obj);
}
}
function DemonMotherMoveToTarget(%obj,%target){
FaceTarget(%obj,%target);
%vector = vectorNormalize(vectorSub(%target.getPosition(), %obj.getPosition()));
%vector = vectorscale(%vector, 1200);
%x = Getword(%vector,0);
%y = Getword(%vector,1);
%z = Getword(%vector,2);
%vector = %x@" "@%y@" 150";
%obj.applyImpulse(%obj.getPosition(), %vector);
schedule(500, 0, "DemonMotherThink", %obj);
}
function DemonMotherDemonSpawn(%obj){
if($TWM::PlayingHellJump || $TWM::PlayingHorde) {
return;
}
for(%i = 0; %i < 5; %i++){
%pos = %obj.getPosition();
%x = getRandom(0,200) - 100;
%y = getRandom(0,200) - 100;
%vec = vectorAdd(%pos,%x SPC %y SPC "40");
%searchResult = containerRayCast(%vec, vectorAdd(%vec,"0 0 -80"), $TypeMasks::TerrainObjectType, %obj);
%charge = new ParticleEmissionDummy()
{
position = posFromRaycast(%searchresult);
dataBlock = "defaultEmissionDummy";
emitter = "BurnEmitter";
};
MissionCleanup.add(%charge);
%charge.schedule(1100, "delete");
schedule(1000, 0, "TWM2Lib_Zombie_Core", "SpawnZombie", "zSpawnCommand", 4, posFromRaycast(%searchResult));
}
schedule(1500, 0, "DemonMotherThink", %obj);
}
}

View file

@ -58,7 +58,7 @@ function ZombieArmor::armorCollisionFunction(%datablock, %zombie, %colPlayer) {
%colPlayer.applyimpulse(%colPlayer.getposition(), %pushVector);
if(%causeInfect) {
%colPlayer.Infected = 1;
%colPlayer.InfectedLoop = schedule(10, %colPlayer, "TWM2Lib_Zombie_Core", "InfectLoop", %colPlayer);
%colPlayer.InfectedLoop = schedule(10, %colPlayer, "TWM2Lib_Zombie_Core", "InfectLoop", %colPlayer, "impact");
}
%colPlayer.damage(0, %colPlayer.getPosition(), %total, $DamageType::Zombie);
}

View file

@ -94,7 +94,7 @@ function RapierZombieArmor::armorCollisionFunction(%datablock, %zombie, %colPlay
%colPlayer.damage(0, %colPlayer.getPosition(), %total, $DamageType::Zombie);
if(%causeInfect) {
%colPlayer.Infected = 1;
%colPlayer.InfectedLoop = schedule(10, %colPlayer, "TWM2Lib_Zombie_Core", "InfectLoop", %colPlayer);
%colPlayer.InfectedLoop = schedule(10, %colPlayer, "TWM2Lib_Zombie_Core", "InfectLoop", %colPlayer, "impact");
}
}
}

View file

@ -39,7 +39,7 @@ function RavagerZombieArmor::armorCollisionFunction(%datablock, %zombie, %colPla
%colPlayer.applyimpulse(%colPlayer.getposition(), %pushVector);
if(%causeInfect) {
%colPlayer.Infected = 1;
%colPlayer.InfectedLoop = schedule(10, %colPlayer, "TWM2Lib_Zombie_Core", "InfectLoop", %colPlayer);
%colPlayer.InfectedLoop = schedule(10, %colPlayer, "TWM2Lib_Zombie_Core", "InfectLoop", %colPlayer, "impact");
}
%colPlayer.damage(0, %colPlayer.getPosition(), %total, $DamageType::Zombie);
}

View file

@ -3,223 +3,6 @@ $TeamDeployableMax[ZSpawnDeployable] = 9999;
// Zombie Spawn Point
//---------------------------------------------------------
datablock AudioProfile(ZombieMoan)
{
filename = "fx/environment/growl3.wav";
description = AudioClose3d;
preload = true;
};
datablock AudioProfile(ZombieHOWL)
{
filename = "fx/environment/Yeti_Howl1.wav";
description = AudioBomb3d;
preload = true;
};
//USED IN FLAMETHROWER / NMM
//DO NOT REMOVE: NEEDED HERE
datablock ParticleData(NMMissileBaseParticle) {
dragCoeffiecient = 0.0;
gravityCoefficient = -0.2;
inheritedVelFactor = 0.0;
lifetimeMS = 800;
lifetimeVarianceMS = 500;
useInvAlpha = false;
spinRandomMin = -160.0;
spinRandomMax = 160.0;
animateTexture = true;
framesPerSec = 15;
textureName = "special/cloudflash";
colors[0] = "0.5 0.1 0.9 1.0";
colors[1] = "0.5 0.1 0.9 1.0";
colors[2] = "0.5 0.1 0.9 1.0";
sizes[0] = 2.5;
sizes[1] = 2.7;
sizes[2] = 3.0;
times[0] = 0.0;
times[1] = 0.7;
times[2] = 1.0;
};
datablock ParticleEmitterData(NMMissileBaseEmitter) {
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 1.5;
velocityVariance = 0.3;
thetaMin = 0.0;
thetaMax = 30.0;
particles = "NMMissileBaseParticle";
};
datablock ParticleData(ThrowerBaseParticle) {
dragCoeffiecient = 0.0;
gravityCoefficient = -0.2;
inheritedVelFactor = 0.0;
lifetimeMS = 800;
lifetimeVarianceMS = 500;
useInvAlpha = false;
spinRandomMin = -160.0;
spinRandomMax = 160.0;
animateTexture = true;
framesPerSec = 15;
textureName = "special/cloudflash";
colors[0] = "1.0 0.6 0.4 1.0";
colors[1] = "1.0 0.5 0.2 1.0";
colors[2] = "1.0 0.25 0.1 0.0";
sizes[0] = 0.5;
sizes[1] = 0.7;
sizes[2] = 1.0;
times[0] = 0.0;
times[1] = 0.7;
times[2] = 1.0;
};
datablock ParticleEmitterData(ThrowerBaseEmitter) {
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 1.5;
velocityVariance = 0.3;
thetaMin = 0.0;
thetaMax = 30.0;
particles = "ThrowerBaseParticle";
};
//
datablock ParticleData(DemonFBSmokeParticle)
{
dragCoeffiecient = 0.0;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.0;
lifetimeMS = 2500;
lifetimeVarianceMS = 500;
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -60.0;
spinRandomMax = 60.0;
colors[0] = "0.5 0.5 0.5 0.5";
colors[1] = "0.4 0.4 0.4 0.2";
colors[2] = "0.3 0.3 0.3 0.0";
sizes[0] = 0.5;
sizes[1] = 1.75;
sizes[2] = 3.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(DemonFBSmokeEmitter)
{
ejectionPeriodMS = 7;
periodVarianceMS = 0;
ejectionVelocity = 0.75; // A little oomph at the back end
velocityVariance = 0.2;
thetaMin = 0.0;
thetaMax = 180.0;
particles = "DemonFBSmokeParticle";
};
datablock GrenadeProjectileData(DemonFireball)
{
projectileShapeName = "plasmabolt.dts";
emitterDelay = -1;
directDamage = 0.0;
hasDamageRadius = true;
indirectDamage = 0.4;
damageRadius = 5.0; // z0dd - ZOD, 8/13/02. Was 20.0
radiusDamageType = $DamageType::zombie;
kickBackStrength = 1500;
explosion = "PlasmaBoltExplosion";
underwaterExplosion = "PlasmaBoltExplosion";
velInheritFactor = 0;
splash = PlasmaSplash;
depthTolerance = 100.0;
baseEmitter = DemonFBSmokeEmitter;
bubbleEmitter = DemonFBSmokeEmitter;
grenadeElasticity = 0;
grenadeFriction = 0.4;
armingDelayMS = -1; // z0dd - ZOD, 4/14/02. Was 2000
gravityMod = 0.4; // z0dd - ZOD, 5/18/02. Make mortar projectile heavier, less floaty
muzzleVelocity = 50.0; // z0dd - ZOD, 8/13/02. More velocity to compensate for higher gravity. Was 63.7
drag = 0;
sound = PlasmaProjectileSound;
hasLight = true;
lightRadius = 10;
lightColor = "1 0.75 0.25";
hasLightUnderwaterColor = true;
underWaterLightColor = "1 0.75 0.25";
};
datablock GrenadeProjectileData(DemonFlamingFireball) {
projectileShapeName = "plasmabolt.dts";
emitterDelay = -1;
directDamage = 0.0;
hasDamageRadius = true;
indirectDamage = 0.4;
damageRadius = 5.0; // z0dd - ZOD, 8/13/02. Was 20.0
radiusDamageType = $DamageType::Fire;
kickBackStrength = 1500;
explosion = "PlasmaBoltExplosion";
underwaterExplosion = "PlasmaBoltExplosion";
velInheritFactor = 0;
splash = PlasmaSplash;
depthTolerance = 100.0;
baseEmitter = ThrowerBaseEmitter;
bubbleEmitter = ThrowerBaseEmitter;
grenadeElasticity = 0;
grenadeFriction = 0.4;
armingDelayMS = -1; // z0dd - ZOD, 4/14/02. Was 2000
gravityMod = 0.4; // z0dd - ZOD, 5/18/02. Make mortar projectile heavier, less floaty
muzzleVelocity = 50.0; // z0dd - ZOD, 8/13/02. More velocity to compensate for higher gravity. Was 63.7
drag = 0;
sound = PlasmaProjectileSound;
hasLight = true;
lightRadius = 10;
lightColor = "1 0.75 0.25";
hasLightUnderwaterColor = true;
underWaterLightColor = "1 0.75 0.25";
};
datablock StaticShapeData(DeployedZSpawnBase) : StaticShapeDamageProfile {
className = "lightbase";
shapeFile = "pack_deploy_sensor_motion.dts";
@ -292,7 +75,9 @@ datablock ItemData(ZSpawnDeployable) {
function ZSpawnDeployableImage::testObjectTooClose(%item) {
return "";
}
function ZSpawnDeployableImage::testNoTerrainFound(%item) {}
function ZSpawnDeployable::onPickup(%this, %obj, %shape, %amount) {}
function ZSpawnDeployableImage::onDeploy(%item, %plyr, %slot) {
@ -300,10 +85,12 @@ function ZSpawnDeployableImage::onDeploy(%item, %plyr, %slot) {
%playerVector = vectorNormalize(-1 * getWord(%plyr.getEyeVector(),1) SPC getWord(%plyr.getEyeVector(),0) SPC "0");
if (vAbs(floorVec(%item.surfaceNrm,100)) $= "0 0 1")
if (vAbs(floorVec(%item.surfaceNrm,100)) $= "0 0 1") {
%item.surfaceNrm2 = %playerVector;
else
}
else {
%item.surfaceNrm2 = vectorNormalize(vectorCross(%item.surfaceNrm,"0 0 -1"));
}
%rot = fullRot(%item.surfaceNrm,%item.surfaceNrm2);
@ -315,8 +102,9 @@ function ZSpawnDeployableImage::onDeploy(%item, %plyr, %slot) {
%deplObj.setTransform(%item.surfacePt SPC %rot);
// set the recharge rate right away
if (%deplObj.getDatablock().rechargeRate)
if (%deplObj.getDatablock().rechargeRate) {
%deplObj.setRechargeRate(%deplObj.getDatablock().rechargeRate);
}
// set team, owner, and handle
%deplObj.team = %plyr.client.Team;
@ -324,8 +112,9 @@ function ZSpawnDeployableImage::onDeploy(%item, %plyr, %slot) {
%deplObj.light.lightBase = %deplObj;
// set the sensor group if it needs one
if (%deplObj.getTarget() != -1)
if (%deplObj.getTarget() != -1) {
setTargetSensorGroup(%deplObj.getTarget(), %plyr.client.team);
}
// place the deployable in the MissionCleanup/Deployables group (AI reasons)
addToDeployGroup(%deplObj);
@ -345,10 +134,10 @@ function ZSpawnDeployableImage::onDeploy(%item, %plyr, %slot) {
%deplObj.playThread($AmbientThread,"ambient");
// take the deployable off the player's back and out of inventory
if(!%plyr.client.isSuperAdmin) {
%plyr.unmountImage(%slot);
%plyr.decInventory(%item.item, 1);
}
if(!%plyr.client.isSuperAdmin) {
%plyr.unmountImage(%slot);
%plyr.decInventory(%item.item, 1);
}
// set power frequency
%deplObj.powerFreq = %plyr.powerFreq;
@ -356,84 +145,92 @@ function ZSpawnDeployableImage::onDeploy(%item, %plyr, %slot) {
// Power object
checkPowerObject(%deplObj);
switch(%plyr.packset) {
case 0:
%deplobj.ZType = 1;
case 1:
%deplobj.ZType = 2;
case 2:
%deplobj.ZType = 3;
%deplobj.numZ = 2;
case 3:
%deplobj.ZType = 4;
case 4:
%deplobj.ZType = 5;
case 5:
%deplobj.ZType = 6;
case 6:
%deplobj.ZType = 9;
case 7:
%deplobj.ZType = 11;
case 8:
%deplobj.ZType = 12;
case 9:
%deplobj.ZType = 13;
case 10:
%deplobj.ZType = 14;
case 11:
%deplobj.ZType = 15;
case 12:
%deplobj.ZType = 16;
case 13:
%deplobj.ZType = 17;
}
switch(%plyr.packset) {
case 0:
%deplobj.ZType = 1;
case 1:
%deplobj.ZType = 2;
case 2:
%deplobj.ZType = 3;
%deplobj.numZ = 2;
case 3:
%deplobj.ZType = 4;
case 4:
%deplobj.ZType = 5;
case 5:
%deplobj.ZType = 6;
case 6:
%deplobj.ZType = 9;
case 7:
%deplobj.ZType = 11;
case 8:
%deplobj.ZType = 12;
case 9:
%deplobj.ZType = 13;
case 10:
%deplobj.ZType = 14;
case 11:
%deplobj.ZType = 15;
case 12:
%deplobj.ZType = 16;
case 13:
%deplobj.ZType = 17;
}
%deplobj.spawnTypeSet = %plyr.expertset;
return %deplObj;
}
function DeployedZSpawnBase::onDestroyed(%this,%obj,%prevState) {
if (%obj.isRemoved)
if (%obj.isRemoved) {
return;
}
%obj.isRemoved = true;
Parent::onDestroyed(%this,%obj,%prevState);
$TeamDeployedCount[%obj.team, ZSpawnDeployable]--;
remDSurface(%obj);
%obj.schedule(500, "delete");
if (%obj.ZCloop !$= "")
Cancel(%obj.ZCLoop);
if (%obj.ZCloop !$= "") {
Cancel(%obj.ZCLoop);
}
}
function DeployedZSpawnBase::disassemble(%data,%plyr,%obj) {
if (%obj.ZCloop !$= "")
Cancel(%obj.ZCLoop);
if (%obj.ZCloop !$= "") {
Cancel(%obj.ZCLoop);
}
disassemble(%data,%plyr,%obj);
}
function ZSpawnDeployableImage::onMount(%data, %obj, %node) {
%obj.hasZSpawn = true;
%obj.expertset = 0;
%obj.hasZSpawn = true;
%obj.expertset = 0;
}
function ZSpawnDeployableImage::onUnmount(%data, %obj, %node) {
%obj.hasZSpawn = "";
%obj.hasZSpawn = "";
}
function DeployedZSpawnBase::onGainPowerEnabled(%data,%obj) {
if(%obj.spawnTypeSet == 1)
%obj.numz = 0;
if (%obj.ZCloop !$= "")
Cancel(%obj.ZCLoop);
%obj.ZCLoop = schedule(1000, 0, "ZcreateLoop", %obj);
Parent::onGainPowerEnabled(%data,%obj);
if(%obj.spawnTypeSet == 1) {
%obj.numz = 0;
}
if (%obj.ZCloop !$= "") {
Cancel(%obj.ZCLoop);
}
%obj.ZCLoop = schedule(1000, 0, "ZcreateLoop", %obj);
Parent::onGainPowerEnabled(%data,%obj);
}
function DeployedZSpawnBase::onLosePowerDisabled(%data,%obj) {
if (%obj.ZCloop !$= "")
Cancel(%obj.ZCLoop);
Parent::onLosePowerDisabled(%data,%obj);
if (%obj.ZCloop !$= "") {
Cancel(%obj.ZCLoop);
}
Parent::onLosePowerDisabled(%data,%obj);
}
//Phantom139: Personal note, rework this at some point using a built in datablock function and
// a simtimer such that we can remove that eval statement.
function ZcreateLoop(%obj) {
if(isObject(%obj)) {
if(%obj.timedout == 0){

View file

@ -58,6 +58,10 @@ function CreateServer(%mission, %missionType)
exec("scripts/particleEmitter.cs"); // Must exist before item.cs and explosion.cs
exec("scripts/particleDummies.cs");
exec("scripts/projectiles.cs"); // Must exits before item.cs
echo("*********************");
echo("* LOADING TWM2 DATABLOCKS");
exec("scripts/TWM2/MultiUseDatablocks.cs");
echo("*********************");
exec("scripts/player.cs");
exec("scripts/gameBase.cs");
exec("scripts/staticShape.cs");

View file

@ -110,7 +110,7 @@ datablock ShapeBaseImageData(PlasmasaberImage) {
stateName[4] = "Reload";
stateTransitionOnTimeout[4] = "Ready";
stateTimeoutValue[4] = 1.5;
stateTimeoutValue[4] = 0.8;
stateAllowImageChange[4] = false;
};