TWM2/scripts/TWM2/Bosses/LordVardison.cs
Robert Fritzen f25a53d74b 3.9.1 Update
Current work here...
2017-06-20 13:44:29 -05:00

1782 lines
62 KiB
C#

//Lord Vardison
//Version 2.0
//Revised And Reimagined... The Pure Evil of TWM2 Has Been Reborn, Now With Less Crashing xD
// Now with difficulty levels :P
// 1, Easy: Standard Vardison Battle
// - Limited Mobs
// - Attacks On Normal
// - Has Timed Grab Kills
// 2, Normal: Tougher Vardison Battle
// - Enhanced Mob Spawns
// - Slightly Faster Attacks
// - Phase 3 Insta-Kills
// - Shadow Orb Mechanic: Deaths to phase 3 initiate Shadow Orb, which is a 20 second to kill all mechanic.
// 3, Hard: The True Experience
// - Minions A Plenty
// - Quick Attacks
// - Phases 2 & 3 Insta-Kill
// - Shadow Orb at Phase 2 & 3
// 4, WTF!?!?! Why God... Why....
// - The Army Comith...
// - Attacks Are So Rapid....
// - All Phases Insta-Kill, Phase 3 does the spawn camp thingy :D
// - Shadow Orb at all Phases
// - Shadow Orb regenerates Vardison's HP
$TWM2::VardisonDifficulty = 1;
$TWM2::Vardison_DMsg[1] = "Lord Vardison Fight [EASY]: The Standard Battle... Work Togther and Be Victorious.";
$TWM2::Vardison_DMsg[2] = "Lord Vardison Fight [NORMAL]: Vardison Has Enhanced His Skills, Will you prove stronger?";
$TWM2::Vardison_DMsg[3] = "Lord Vardison Fight [HARD]: The True Vardison Experience... Only The True Will Be Victorious...";
$TWM2::Vardison_DMsg[4] = "Lord Vardison Fight [WTF]: All Prayers Will Be Accepted Before You Painfully Die... Over And Over And Over....";
//Difficulty Variables, Don't Touch
$TWM2::Vardison_OrbKillTime = 12500;
$TWM2::Vardison1_AttSpeed[1] = 20000;
$TWM2::Vardison1_AttSpeed[2] = 17500;
$TWM2::Vardison1_AttSpeed[3] = 13500;
$TWM2::Vardison1_AttSpeed[4] = 7500;
$TWM2::Vardison2_AttSpeed[1] = 20000;
$TWM2::Vardison2_AttSpeed[2] = 17500;
$TWM2::Vardison2_AttSpeed[3] = 12500;
$TWM2::Vardison2_AttSpeed[4] = 7000;
$TWM2::Vardison3_AttSpeed[1] = 17500;
$TWM2::Vardison3_AttSpeed[2] = 15000;
$TWM2::Vardison3_AttSpeed[3] = 11500;
$TWM2::Vardison3_AttSpeed[4] = 6500;
$TWM2::Vardison1_CanOrb[1] = false;
$TWM2::Vardison1_CanOrb[2] = false;
$TWM2::Vardison1_CanOrb[3] = false;
$TWM2::Vardison1_CanOrb[4] = true;
$TWM2::Vardison2_CanOrb[1] = false;
$TWM2::Vardison2_CanOrb[2] = false;
$TWM2::Vardison2_CanOrb[3] = true;
$TWM2::Vardison2_CanOrb[4] = true;
$TWM2::Vardison3_CanOrb[1] = false;
$TWM2::Vardison3_CanOrb[2] = true;
$TWM2::Vardison3_CanOrb[3] = true;
$TWM2::Vardison3_CanOrb[4] = true;
$TWM2::Vardison_OrbRegenHP[1] = false;
$TWM2::Vardison_OrbRegenHP[2] = false;
$TWM2::Vardison_OrbRegenHP[3] = false;
$TWM2::Vardison_OrbRegenHP[4] = true;
$TWM2::Vardison1_MaxMinions[1] = 5;
$TWM2::Vardison1_MaxMinions[2] = 10;
$TWM2::Vardison1_MaxMinions[3] = 12;
$TWM2::Vardison1_MaxMinions[4] = 15;
$TWM2::Vardison2_MaxMinions[1] = 7;
$TWM2::Vardison2_MaxMinions[2] = 9;
$TWM2::Vardison2_MaxMinions[3] = 12;
$TWM2::Vardison2_MaxMinions[4] = 15;
$TWM2::Vardison3_MaxMinions[1] = 10;
$TWM2::Vardison3_MaxMinions[2] = 13;
$TWM2::Vardison3_MaxMinions[3] = 17;
$TWM2::Vardison3_MaxMinions[4] = 25;
$TWM2::Vardison_MinionCooldown[1] = 20;
$TWM2::Vardison_MinionCooldown[2] = 17;
$TWM2::Vardison_MinionCooldown[3] = 15;
$TWM2::Vardison_MinionCooldown[4] = 10;
//Particles & Emitters
datablock ParticleData(SummoningPierParticle) {
dragCoeffiecient = 0.0;
gravityCoefficient = -0.1;
inheritedVelFactor = 0.1;
lifetimeMS = 1500;
lifetimeVarianceMS = 50;
textureName = "special/cloudflash";
spinRandomMin = -10.0;
spinRandomMax = 10.0;
colors[0] = "1 0.18 0.03 0.4";
colors[1] = "0 134 139 0.3";
colors[2] = "1 0.18 0.03 0.0";
sizes[0] = 10.0;
sizes[1] = 7.5;
sizes[2] = 5.0;
times[0] = 0.0;
times[1] = 0.6;
times[2] = 1.0;
};
datablock ParticleEmitterData(SummoningPierEmitter) {
ejectionPeriodMS = 3;
periodVarianceMS = 0;
ejectionOffset = 0.2;
ejectionVelocity = 10.0;
velocityVariance = 0.0;
thetaMin = 0.0;
thetaMax = 10.0;
particles = "SummoningPierParticle";
};
datablock ParticleData(ShadowOrbParticle) {
dragCoefficient = 5;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.0;
constantAcceleration = -1.3;
lifetimeMS = 1000;
lifetimeVarianceMS = 150;
textureName = "special/cloudflash";
useInvAlpha = false;
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] = 20.501;
sizes[1] = 25.001;
sizes[2] = 30.001;
times[0] = 0.0;
times[1] = 0.2;
times[2] = 1.0;
};
datablock ParticleEmitterData(ShadowOrbEmitter) {
ejectionPeriodMS = 15;
periodVarianceMS = 5;
ejectionVelocity = 42.7; // A little oomph at the back end
velocityVariance = 0.0;
ejectionoffset = 0;
thetaMin = 0.0;
thetaMax = 180.0;
phiReferenceVel = 0;
phiVariance = "360";
particles = "ShadowOrbParticle";
overrideAdvances = true;
orientParticles = true;
};
datablock ParticleData(ShadowOrbDetonationParticle) {
dragCoefficient = 1.0;
gravityCoefficient = 0.00;
windcoefficient = 0.0;
inheritedVelFactor = 0.0;
constantAcceleration = 10.0;
lifetimeMS = 1000;
lifetimeVarianceMS = 100;
useInvAlpha = true;
spinRandomMin = -90.0;
spinRandomMax = 90.0;
textureName = "special/cloudFlash";
colors[0] = "0.5 0.1 0.9 1.0";
colors[1] = "156 0 0 0.5";
colors[2] = "0.5 0.1 0.9 1.0";
sizes[0] = 500;
sizes[1] = 500;
sizes[2] = 2;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(ShadowOrbDetonationEmitter) {
ejectionPeriodMS = 1;
periodVarianceMS = 0;
ejectionVelocity = 400.0;
velocityVariance = 150.0;
ejectionOffset = 0.0;
thetaMin = 85;
thetaMax = 85;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
particles = "ShadowOrbDetonationParticle";
};
datablock ParticleData(ShadowBaseParticle) {
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(ShadowBaseEmitter) {
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 1.5;
velocityVariance = 0.3;
thetaMin = 0.0;
thetaMax = 30.0;
particles = "ShadowBaseParticle";
};
//Projectile Datablocks:
//Ultimate Laser Projectile
datablock LinearFlareProjectileData(SuperlaserProjectile) {
scale = "15.0 15.0 15.0";
faceViewer = false;
directDamage = 1.0;
hasDamageRadius = true;
indirectDamage = 0.9;
damageRadius = 30.0;
kickBackStrength = 1000.0;
radiusDamageType = $DamageType::Explosion;
explosion[0] = "HyperDevCannonExplosion2";
explosion[1] = "SatchelMainExplosion";
splash = PlasmaSplash;
baseEmitter = HyperDevCannonBaseEmitter;
dryVelocity = 200.0;
wetVelocity = 200;
velInheritFactor = 0.5;
fizzleTimeMS = 10000;
lifetimeMS = 10000;
explodeOnDeath = false;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = true;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = -1;
//activateDelayMS = 100;
activateDelayMS = -1;
size[0] = 9;
size[1] = 10;
size[2] = 11;
numFlares = 400;
flareColor = "0.0 1.0 0";
flareModTexture = "flaremod";
flareBaseTexture = "flarebase";
sound = MissileProjectileSound;
fireSound = PlasmaFireSound;
wetFireSound = PlasmaFireWetSound;
hasLight = true;
lightRadius = 3.0;
lightColor = "0 0.75 0.25";
};
datablock LinearFlareProjectileData(ShadowBladeSlam) {
scale = "0.1 0.1 0.1";
faceViewer = false;
directDamage = 1.0;
hasDamageRadius = true;
indirectDamage = 5.0;
damageRadius = 15.0;
kickBackStrength = 1000.0;
radiusDamageType = $DamageType::BladeOfVengance;
explosion[0] = "SatchelMainExplosion";
splash = PlasmaSplash;
dryVelocity = 200.0;
wetVelocity = 200;
velInheritFactor = 0.5;
fizzleTimeMS = 10000;
lifetimeMS = 10000;
explodeOnDeath = false;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = true;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = -1;
//activateDelayMS = 100;
activateDelayMS = -1;
size[0] = "0.1";
size[1] = "0.1";
size[2] = "0.1";
numFlares = 1;
flareColor = "0.0 1.0 0";
flareModTexture = "flaremod";
flareBaseTexture = "flarebase";
sound = MissileProjectileSound;
fireSound = PlasmaFireSound;
wetFireSound = PlasmaFireWetSound;
hasLight = true;
lightRadius = 3.0;
lightColor = "0 0.75 0.25";
};
datablock LinearFlareProjectileData(ShadowBlastBolt) {
projectileShapeName = "turret_muzzlepoint.dts";
scale = "1.0 1.0 1.0";
faceViewer = true;
directDamage = 0.9;
hasDamageRadius = true;
indirectDamage = 0.9;
damageRadius = 15.0;
kickBackStrength = 0.0;
radiusDamageType = $DamageType::Vardison;
explosion = "MortarExplosion";
splash = PlasmaSplash;
baseEmitter = ShadowBaseEmitter;
dryVelocity = 50.0; // z0dd - ZOD, 7/20/02. Faster plasma projectile. was 55
wetVelocity = -1;
velInheritFactor = 0.3;
fizzleTimeMS = 29500;
lifetimeMS = 30000;
explodeOnDeath = false;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = true;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = -1;
//activateDelayMS = 100;
activateDelayMS = -1;
size[0] = 0.2;
size[1] = 0.5;
size[2] = 0.1;
numFlares = 35;
flareColor = "1 0.18 0.03";
flareModTexture = "flaremod";
flareBaseTexture = "flarebase";
sound = PlasmaProjectileSound;
fireSound = FlamethrowerFireSound;
wetFireSound = PlasmaFireWetSound;
hasLight = true;
lightRadius = 10.0;
lightColor = "0.94 0.03 0.12";
};
//Armor Datablocks
datablock StaticShapeData(InitialVaridionHoloArmor) : StaticShapeDamageProfile {
className = "player";
shapeFile = "TR2Heavy_male.dts"; // dmiscf.dts, alternate
mass = 1;
elasticity = 0.1;
friction = 0.9;
collideable = 0;
isInvincible = true;
};
function InitialVaridionHoloArmor::shouldApplyImpulse(%targetObject) {
return false;
}
datablock PlayerData(VardisonStageOneArmor) : LightMaleHumanArmor {
boundingBox = "1.63 1.63 2.6";
maxDamage = 300.0;
minImpactSpeed = 35;
shapeFile = "medium_male.dts";
debrisShapeName = "bio_player_debris.dts";
//Foot Prints
decalData = HeavyBiodermFootprint;
decalOffset = 0.4;
waterBreathSound = WaterBreathBiodermSound;
damageScale[$DamageType::W1700] = 3.0;
damageScale[$DamageType::Bullet] = 0.10; //I deny you shrike n0bs
damageScale[$DamageType::BladeOfVengance] = 0.001;
};
datablock PlayerData(VardisonStageTwoArmor) : LightMaleHumanArmor {
shapefile = "TR2medium_male.dts";
mass = 500;
maxDamage = 350.0;
minImpactSpeed = 50;
speedDamageScale = 0.015;
boundingBox = "2.9 2.9 4.8";
underwaterJetForce = 10;
LFootSoftSound = ZLordFootSound;
RFootSoftSound = ZLordFootSound;
LFootHardSound = HZLordFootSound;
RFootHardSound = HZLordFootSound;
LFootMetalSound = ZLordFootSound;
RFootMetalSound = ZLordFootSound;
LFootSnowSound = ZLordFootSound;
RFootSnowSound = ZLordFootSound;
damageScale[$DamageType::M1700] = 1.5;
damageScale[$DamageType::BladeOfVengance] = 0.001;
max[RepairKit] = 0;
max[Mine] = 0;
max[Grenade] = 0;
};
datablock PlayerData(VardisonStageThreeArmor) : LightMaleHumanArmor {
shapefile = "TR2Heavy_male.dts";
mass = 500;
maxDamage = 500.0;
minImpactSpeed = 50;
speedDamageScale = 0.015;
boundingBox = "2.9 2.9 4.8";
underwaterJetForce = 10;
LFootSoftSound = ZLordFootSound;
RFootSoftSound = ZLordFootSound;
LFootHardSound = HZLordFootSound;
RFootHardSound = HZLordFootSound;
LFootMetalSound = ZLordFootSound;
RFootMetalSound = ZLordFootSound;
LFootSnowSound = ZLordFootSound;
RFootSnowSound = ZLordFootSound;
damageScale[$DamageType::M1700] = 1.5;
damageScale[$DamageType::BladeOfVengance] = 0.001;
max[RepairKit] = 0;
max[Mine] = 0;
max[Grenade] = 0;
};
datablock StaticShapeData(ShadowOrb) : StaticShapeDamageProfile {
className = "Generator";
shapeFile = "station_generator_large.dts";
maxDamage = 2.0;
destroyedLevel = 2.0;
disabledLevel = 0.3;
isShielded = false;
energyPerDamagePoint = 240;
maxEnergy = 50;
rechargeRate = 0.25;
explosion = HandGrenadeExplosion;
expDmgRadius = 1.0;
expDamage = 0.05;
expImpulse = 200;
boundingBox = "5.0 5.0 5.0";
dynamicType = $TypeMasks::StaticShapeObjectType;
deployedObject = true;
cmdCategory = "DSupport";
cmdIcon = CMDSensorIcon;
cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor";
targetNameTag = 'Shadow Rift';
deployAmbientThread = true;
debrisShapeName = "debris_generic_small.dts";
debris = DeployableDebris;
heatSignature = 0;
needsPower = true;
};
function ShadowOrb::onDestroyed(%this, %obj, %prevState) {
if (%obj.isRemoved) {
return;
}
if(isObject(%obj.waypoint)) {
%obj.waypoint.schedule(500, "delete");
}
if(isObject($TWM2::VardisonManager.OrbSFX)) {
$TWM2::VardisonManager.OrbSFX.schedule(500, "delete");
}
%obj.isRemoved = true;
Parent::onDestroyed(%this, %obj, %prevState);
%obj.schedule(500, "delete");
$TWM2::VardisonManager.orbDestroyed();
}
//Boss Functions
function CheckVardisonManager() {
if($TWM2::VardisonDifficulty < 1 || $TWM2::VardisonDifficulty > 4) {
//Are the odds in your favor now, or will Vardison rek you endlessly?
$TWM2::VardisonDifficulty = getRandom(1, 4);
}
if(!isObject($TWM2::VardisonManager)) {
$TWM2::VardisonManager = new ScriptObject() {
class = "VardisonManager";
};
}
//Setup default params
$TWM2::VardisonManager.lastAttackTime = getRealTime();
$TWM2::VardisonManager.minionCount = 0;
$TWM2::VardisonManager.orbObject = -1;
}
function StartVardison1(%position) {
CheckVardisonManager();
//Trip the boss manager so nothing else fires up in the initial 10 seconds.
$TWM2::BossGoing = 1;
//Erupt a firestorm in his coming....
// They shall know fear xD
MessageAll('msgAdminForce', "\c5"@$TWM2::Vardison_DMsg[$TWM2::VardisonDifficulty]);
//Adjust Position
%spawnPos = getWord(%position, 0) SPC getWord(%position, 1) SPC getTerrainHeight(%position);
//First Spawn The Firestorm & Sound FX
MessageAll('msgSound', "~wfx/environment/wind_sandstorm.wav");
MessageAll('msgSound', "~wfx/environment/snowstorm1.wav");
schedule(1500, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(2500, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(3500, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(5000, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(5500, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(7500, 0, MessageAll, 'msgSound', "~wfx/armor/breath_bio_uw.wav");
schedule(10000, 0, MessageAll, 'msgSound', "~wfx/explosions/explosion.xpl03.wav");
schedule(10000, 0, MessageAll, 'msgSound', "~wfx/explosions/explosion.xpl03.wav");
schedule(10000, 0, MessageAll, 'msgSound', "~wfx/explosions/explosion.xpl03.wav");
%fire = new ParticleEmissionDummy(){
position = vectoradd(%spawnPos, "0 0 0.5");
dataBlock = "defaultEmissionDummy";
emitter = "SummoningPierEmitter";
};
MissionCleanup.add(%fire);
%fire.schedule(10000, "delete");
//Spawn the fake hologram vardison.
%fakeHolo = new StaticShape(){
Datablock = "InitialVaridionHoloArmor";
};
%fakeHolo.setTransform(vectorAdd(%spawnPos, "0 0 0.25"));
%fakeHolo.startfade(0, 0, true);
%fakeHolo.schedule(1000, startfade, 2500, 0, false);
%fakeHolo.schedule(7500, startfade, 2500, 0, true);
%fakeHolo.schedule(10000, "Delete");
//And then start the real one...
schedule(10000, 0, SpawnVardison, %spawnPos);
}
function SpawnVardison(%position) {
%Boss = new player(){
Datablock = "VardisonStageOneArmor";
};
%Cpos = vectorAdd(%position, "0 0 5");
%Boss.isMultiPhaseBoss = true;
%Boss.isFirstPhase = true;
%Boss.isFinalPhase = false;
InitiateBoss(%Boss, "Vardison1");
%Boss.team = 30;
%Boss.target = createTarget(%Boss, "\c7Lord Vardison", "", "Derm3", '', %Boss.team, PlayerSensor);
setTargetSensorData(%Boss.target, PlayerSensor);
setTargetSensorGroup(%Boss.target, 30);
setTargetName(%Boss.target, addtaggedstring("\c7Lord Vardison"));
setTargetSkin(%Boss.target, 'Horde');
%Boss.setTransform(%Cpos);
%Boss.phase = 1;
MissionCleanup.add(%Boss);
%Boss.lastKillCount = $TWM2::BossManager.bossKills;
%Boss.canSummonMinions = true;
$TWM2::VardisonManager.Vardison = %Boss;
%Boss.thinkSched = schedule(2500, 0, VardisonThink, %Boss);
}
function SpawnVardison2(%position) {
schedule(250, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(500, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(750, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(1000, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(1100, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
%Boss = new player(){
Datablock = "VardisonStageTwoArmor";
};
%Cpos = vectorAdd(%position, "0 0 5");
%Boss.isMultiPhaseBoss = true;
%Boss.isFirstPhase = false;
%Boss.isFinalPhase = false;
InitiateBoss(%Boss, "Vardison2");
%Boss.team = 30;
%Boss.target = createTarget(%Boss, "\c7Lord Vardison", "", "Derm3", '', %Boss.team, PlayerSensor);
setTargetSensorData(%Boss.target, PlayerSensor);
setTargetSensorGroup(%Boss.target, 30);
setTargetName(%Boss.target, addtaggedstring("\c7Lord Vardison"));
setTargetSkin(%Boss.target, 'Horde');
%Boss.setTransform(%Cpos);
%Boss.phase = 2;
MissionCleanup.add(%Boss);
%Boss.lastKillCount = $TWM2::BossManager.bossKills;
%Boss.canSummonMinions = true;
$TWM2::VardisonManager.Vardison = %Boss;
//If we're on difficulty level 4, summon an orb :P
if($TWM2::VardisonDifficulty >= 4) {
VardisonSummonOrb(%Boss);
}
%Boss.thinkSched = schedule(1000, 0, VardisonThink, %Boss);
}
function SpawnVardison3(%position) {
schedule(250, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(500, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(750, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(1000, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(1100, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(1250, 0, MessageAll, 'msgSound', "~wfx/armor/breath_bio_uw.wav");
schedule(1250, 0, MessageAll, 'msgSound', "~wfx/explosions/explosion.xpl03.wav");
schedule(1250, 0, MessageAll, 'msgSound', "~wfx/explosions/explosion.xpl03.wav");
schedule(1250, 0, MessageAll, 'msgSound', "~wfx/explosions/explosion.xpl03.wav");
%Boss = new player(){
Datablock = "VardisonStageThreeArmor";
};
%Cpos = vectorAdd(%position, "0 0 5");
%Boss.isMultiPhaseBoss = true;
%Boss.isFirstPhase = false;
%Boss.isFinalPhase = true;
InitiateBoss(%Boss, "Vardison3");
%Boss.team = 30;
%Boss.target = createTarget(%Boss, "\c7Lord Vardison", "", "Derm3", '', %Boss.team, PlayerSensor);
setTargetSensorData(%Boss.target, PlayerSensor);
setTargetSensorGroup(%Boss.target, 30);
setTargetName(%Boss.target, addtaggedstring("\c7Lord Vardison"));
setTargetSkin(%Boss.target, 'Horde');
%Boss.setTransform(%Cpos);
%Boss.phase = 3;
MissionCleanup.add(%Boss);
%Boss.lastKillCount = $TWM2::BossManager.bossKills;
%Boss.canSummonMinions = true;
$TWM2::VardisonManager.Vardison = %Boss;
//If we're on level 3 or 4, instantly summon the Shadow Orb to kick things off
if($TWM2::VardisonDifficulty >= 3) {
VardisonSummonOrb(%Boss);
}
%Boss.thinkSched = schedule(1000, 0, VardisonThink, %Boss);
}
function VardisonThink(%Boss) {
if(!isObject(%Boss) || %Boss.getState() $= "Dead") {
//Kill this think instance, let the next one take over.
return;
}
if(%Boss.busy) {
//I'm currently doing something, check back soon.
%Boss.thinkSched = schedule(200, 0, VardisonThink, %Boss);
return;
}
%dLevel = $TWM2::VardisonDifficulty;
%lastAtt = $TWM2::VardisonManager.lastAttackTime; //<--- Note: This value is from the time the last attack ENDED
%cTime = getRealTime();
%lastKC = %Boss.lastKillCount;
%nowKC = $TWM2::BossManager.bossKills;
%Boss.lastKillCount = $TWM2::BossManager.bossKills;
//Possible Outcomes...
%needAttack = false;
%needMinions = false;
%needOrbSummon = false;
%needMove = false;
//Check for anti-fall....
if(getWord(%Boss.getPosition(), 2) < (getTerrainHeight(%Boss.getPosition()) - 250)) {
if(getWord(%Boss.getVelocity(), 2) < -1) {
//Block the fall... bring us back up...
echo("VardisonThink(): Anti-Fall Countermeasures activated.");
%Boss.setPosition(getWord(%Boss.getPosition(), 0) SPC getWord(%Boss.getPosition(), 1) SPC getTerrainHeight(%Boss.getPosition()) + 15);
%Boss.setVelocity("0 0 1");
%Boss.startfade(0, 0, true);
%Boss.schedule(250, startfade, 1000, 0, false);
}
}
//Determine the correct action.
switch(%Boss.phase) {
case 1:
//Did I just get a kill?
if(%nowKC > %lastKC) {
//Do I need to summon a shadow orb?
if($TWM2::Vardison1_CanOrb[%dLevel]) {
//Is there already an active orb?
if(!isObject($TWM2::VardisonManager.orbObject)) {
//Yep, I need to summon it.
%needOrbSummon = true;
}
}
}
if((%cTime - %lastAtt) >= $TWM2::Vardison1_AttSpeed[%dLevel]) {
//Time for an attack
%needAttack = true;
}
else {
//If we're not ready to dish out an attack, let's check what else we need to do...
// Are we low on minions?
if($TWM2::VardisonManager.minionCount < $TWM2::Vardison1_MaxMinions[%dLevel]) {
if(%Boss.canSummonMinions) {
//How many players am I up against?
%pCount = $HostGamePlayerCount;
//How low is my health?
%percentage = mCeil((mFloor(%boss.getDamageLeft()*100) / mFloor(%boss.getMaxDamage()*100)) * 100);
%BackwardsHP = 100 - %percentage;
%chance = %BackwardsHP * %pCount;
//Using our test factor, determine if I need minions.
if(%chance <= getRandom(1, 100)) {
%needMinions = true;
}
}
}
//Do I need to be moving towards the enemy?
%needMove = true; //Phase 1 is always doing this...
}
case 2:
//Did I just get a kill?
if(%nowKC > %lastKC) {
//Do I need to summon a shadow orb?
if($TWM2::Vardison2_CanOrb[%dLevel]) {
//Is there already an active orb?
if(!isObject($TWM2::VardisonManager.orbObject)) {
//Yep, I need to summon it.
%needOrbSummon = true;
}
}
}
if((%cTime - %lastAtt) >= $TWM2::Vardison2_AttSpeed[%dLevel]) {
//Time for an attack
%needAttack = true;
}
else {
//If we're not ready to dish out an attack, let's check what else we need to do...
// Are we low on minions?
if($TWM2::VardisonManager.minionCount < $TWM2::Vardison2_MaxMinions[%dLevel]) {
if(%Boss.canSummonMinions) {
//How many players am I up against?
%pCount = $HostGamePlayerCount;
//How low is my health?
%percentage = mCeil((mFloor(%boss.getDamageLeft()*100) / mFloor(%boss.getMaxDamage()*100)) * 100);
%BackwardsHP = 100 - %percentage;
%chance = %BackwardsHP * %pCount;
//Using our test factor, determine if I need minions.
if(%chance <= getRandom(1, 100)) {
%needMinions = true;
}
}
}
%needMove = true;
}
case 3:
//Did I just get a kill?
if(%nowKC > %lastKC) {
//Do I need to summon a shadow orb?
if($TWM2::Vardison3_CanOrb[%dLevel]) {
//Is there already an active orb?
if(!isObject($TWM2::VardisonManager.orbObject)) {
//Yep, I need to summon it.
%needOrbSummon = true;
}
}
}
if((%cTime - %lastAtt) >= $TWM2::Vardison3_AttSpeed[%dLevel]) {
//Time for an attack
%needAttack = true;
}
else {
//If we're not ready to dish out an attack, let's check what else we need to do...
// Are we low on minions?
if($TWM2::VardisonManager.minionCount < $TWM2::Vardison3_MaxMinions[%dLevel] && %boss.canSummonMinions) {
if(%Boss.canSummonMinions) {
//How many players am I up against?
%pCount = $HostGamePlayerCount;
//How low is my health?
%percentage = mCeil((mFloor(%boss.getDamageLeft()*100) / mFloor(%boss.getMaxDamage()*100)) * 100);
%BackwardsHP = 100 - %percentage;
%chance = %BackwardsHP * %pCount;
//Using our test factor, determine if I need minions.
if(%chance <= getRandom(1, 100)) {
%needMinions = true;
}
}
}
//Do I need to be moving towards the enemy?
%needMove = true; //Phase 3 is always doing this...
}
}
//Call the correct function...
if(%needOrbSummon) {
VardisonSummonOrb(%Boss);
}
else if(%needAttack) {
VardisonPerformAttack(%Boss);
}
else {
if(%needMinions) {
VardisonSummonMinions(%Boss);
}
if(%needMove) {
VardisonDoMove(%Boss);
}
}
%Boss.thinkSched = schedule(500, 0, VardisonThink, %Boss);
}
function VardisonDoMove(%Boss) {
if(!isObject(%Boss) || %Boss.getState() $= "Dead") {
return;
}
%pos = %Boss.getworldboxcenter();
switch(%Boss.phase) {
case 1:
%closest = VardisonGetClosest(%Boss);
%clDst = getWord(%closest, 1);
%clPlayer = getWord(%closest, 0).Player;
if(%clDst < 12) {
//Perform a sword slam
VardisonDoSlam(%Boss, %clPlayer);
return;
}
if(%Boss.hastarget != 1){
%Boss.hastarget = 1;
}
%vector = ZgetFacingDirection(%Boss, %clPlayer, %pos);
%vector = vectorscale(%vector, $Zombie::DForwardSpeed);
%upvec = "150";
%x = Getword(%vector,0);
%y = Getword(%vector,1);
%z = Getword(%vector,2);
if(%z >= ($Zombie::DForwardSpeed)) {
%upvec = (%upvec * 5);
}
%vector = %x@" "@%y@" "@%upvec;
%Boss.applyImpulse(%pos, %vector);
case 2:
%closest = VardisonGetClosest(%Boss);
%clDst = getWord(%closest, 1);
%clPlayer = getWord(%closest, 0).Player;
if(%clDst < 15) {
//Perform a sword slam
VardisonDoSlam(%Boss, %clPlayer);
return;
}
if(%Boss.hastarget != 1){
%Boss.hastarget = 1;
}
%vector = ZgetFacingDirection(%Boss, %clPlayer, %pos);
%vector = vectorscale(%vector, $Zombie::DForwardSpeed*2);
%upvec = "150";
%x = Getword(%vector,0);
%y = Getword(%vector,1);
%z = Getword(%vector,2);
if(%z >= ($Zombie::DForwardSpeed)) {
%upvec = (%upvec * 5);
}
%vector = %x@" "@%y@" "@%upvec;
%Boss.applyImpulse(%pos, %vector);
case 3:
%closest = VardisonGetClosest(%Boss);
%clDst = getWord(%closest, 1);
%clPlayer = getWord(%closest, 0).Player;
if(%clDst < 6) {
//Insta-Kill xD
%clPlayer.setInvincible(false);
MessageAll('msgDie', "\c4Lord Vardision: DIE "@getWord(%closest, 0).namebase@"!!!");
%clPlayer.damage(%boss, %clPlayer.getPosition(), 10000, $DamageType::Idiocy);
return;
}
if(%Boss.hastarget != 1){
%Boss.hastarget = 1;
}
%vector = ZgetFacingDirection(%Boss, %clPlayer, %pos);
%vector = vectorscale(%vector, $Zombie::DForwardSpeed*5);
%upvec = "150";
%x = Getword(%vector,0);
%y = Getword(%vector,1);
%z = Getword(%vector,2);
if(%z >= ($Zombie::DForwardSpeed)) {
%upvec = (%upvec * 5);
}
%vector = %x@" "@%y@" "@%upvec;
%Boss.applyImpulse(%pos, %vector);
}
}
function VardisonDoSlam(%Boss, %ToDie) {
%Boss.busy = true;
%vector = ZgetFacingDirection(%Boss, %ToDie, %Boss.getWorldBoxCenter());
%vector = vectorscale(%vector, $Zombie::DForwardSpeed * 7.5);
%upvec = "150";
%x = Getword(%vector,0);
%y = Getword(%vector,1);
%z = Getword(%vector,2);
if(%z >= ($Zombie::DForwardSpeed)) {
%upvec = (%upvec * 5);
}
%vector = %x@" "@%y@" "@%upvec;
%Boss.applyImpulse(%pos, %vector);
schedule(750, 0, "VardisonFinishSlam", %Boss, %ToDie);
}
function VardisonFinishSlam(%Boss, %ToDie) {
//Summon the invis-projectile
%Boss.setMoveState(true);
%p = new LinearFlareProjectile() {
dataBlock = ShadowBladeSlam;
initialDirection = "0 0 -10";
initialPosition = vectorAdd(%ToDie.getPosition(), "0 0 1");
sourceSlot = 0;
};
%p.sourceObject = %Boss;
MissionCleanup.add(%p);
%Boss.schedule(1000, "setMoveState", false);
ServerPlay3d(BOVHitSound, %ToDie.getPosition());
ServerPlay3d(BOVHitSound, %ToDie.getPosition());
ServerPlay3d(BOVHitSound, %ToDie.getPosition());
$TWM2::VardisonManager.schedule(1000, cooldownOff, %Boss, "busy");
}
function VardisonSummonOrb(%Boss) {
if(isObject($TWM2::VardisonManager.orbObject)) {
//Stop, we already have an orb.
return;
}
//Shadow Orb Time...
MessageAll('msgAttack', "\c5Alert: Lord Vardison Opens The Shadow Rift...");
schedule(250, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(700, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(1250, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(1350, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(1500, 0, MessageAll, 'msgSound', "~wfx/environment/ctmelody4.wav");
schedule(2000, 0, MessageAll, 'msgSound', "~wfx/explosions/explosion.xpl03.wav");
schedule(2000, 0, MessageAll, 'msgSound', "~wfx/explosions/explosion.xpl03.wav");
schedule(2000, 0, MessageAll, 'msgSound', "~wfx/explosions/explosion.xpl03.wav");
%Boss.busy = true;
%Boss.rapierShield = true;
%Boss.setMoveState(true);
//Fire SFX
$TWM2::VardisonManager.orbFire = new ParticleEmissionDummy(){
position = vectoradd(%Boss.getPosition(), "0 0 0.5");
dataBlock = "defaultEmissionDummy";
emitter = "SummoningPierEmitter";
};
MissionCleanup.add($TWM2::VardisonManager.orbFire);
//Create the Orb Object
$TWM2::VardisonManager.schedule(2000, summonOrb, %Boss);
}
function VardisonSummonMinions(%Boss) {
if(%Boss.canSummonMinions) {
%currentCount = $TWM2::VardisonManager.minionCount;
%dLevel = $TWM2::VardisonDifficulty;
%max = 0;
switch(%Boss.phase) {
case 1:
%max = $TWM2::Vardison1_MaxMinions[%dLevel];
case 2:
%max = $TWM2::Vardison2_MaxMinions[%dLevel];
case 3:
%max = $TWM2::Vardison3_MaxMinions[%dLevel];
}
%factor = %dLevel / 4;
%Low = 1;
%High = mCeil((%max - %currentCount) * %factor);
for(%i = 0; %i < getRandom(%Low, %High); %i++) {
VardisonDoMinionSummon(%Boss);
}
%Boss.canSummonMinions = false;
$TWM2::VardisonManager.schedule($TWM2::Vardison_MinionCooldown[%dLevel] * 1000, cooldownOff, %Boss, "minions");
}
}
function VardisonDoMinionSummon(%Boss) {
%posSpawn = vectorAdd(%Boss.getPosition(), TWM2Lib_MainControl("getRandomPosition", 50 TAB 1));
%spawnFire = new ParticleEmissionDummy(){
position = vectoradd(%posSpawn, "0 0 0.5");
dataBlock = "defaultEmissionDummy";
emitter = "SummoningPierEmitter";
};
MissionCleanup.add(%spawnFire);
%spawnFire.schedule(500, "delete");
schedule(650, 0, SpawnVMinion, %posSpawn);
}
function SpawnVMinion(%position) {
%minion = StartAZombie(%position, 17);
if(isObject(%minion)) {
//Apply minion settings & increase count
$TWM2::VardisonManager.minionCount++;
%minion.isBossMinion = true;
%minion.isVardisonMinion = true;
}
}
function VardisonGetClosest(%Boss) {
%wbpos = %Boss.getworldboxcenter();
%count = ClientGroup.getCount();
%closestClient = -1;
%closestDistance = 32767;
for(%i = 0; %i < %count; %i++) {
%cl = ClientGroup.getObject(%i);
if(isObject(%cl.player)){
%testPos = %cl.player.getWorldBoxCenter();
%distance = vectorDist(%wbpos, %testPos);
if (%distance > 0 && %distance < %closestDistance) {
%closestClient = %cl;
%closestDistance = %distance;
}
}
}
return %closestClient SPC %closestDistance;
}
function VardisonPerformAttack(%Boss) {
//The do-all opening function for Vardison's attacks
//Start by halting the think() method
%Boss.busy = true;
switch(%Boss.phase) {
case 1:
%attackSelect = getRandom(1, 5);
switch(%attackSelect) {
case 1:
//Shadow Bomb Strike
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
VardisonNamedAttack(%Boss, "ShadowBombStrike", %tPl);
$TWM2::VardisonManager.schedule(4000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 2:
//Nightmare Missile
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
VardisonNamedAttack(%Boss, "NightmareMissile", %tPl);
$TWM2::VardisonManager.schedule(4500, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 3:
//Shadow Fissure
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
%tPos = %tPl.getPosition();
%bPos = %Boss.getPosition();
%fVec = vectorNormalize(vectorSub(%tPos, %bPos));
//Phase Vardison Out To Safety
%fire = new ParticleEmissionDummy(){
position = vectoradd(%spawnPos, "0 0 0.5");
dataBlock = "defaultEmissionDummy";
emitter = "SummoningPierEmitter";
};
MissionCleanup.add(%fire);
%fire.schedule(6500, "delete");
//Fades & Teleports
%Boss.startfade(1500, 0, true);
%Boss.schedule(2000, setPosition, vectorAdd(%bPos, "9999 9999 10"));
schedule(3000, 0, "VardisonNamedAttack", %Boss, "ShadowFissure", %bPos TAB %fVec);
%Boss.schedule(6000, setPosition, %bPos);
%Boss.schedule(6000, startFade, 1000, 0, false);
//
$TWM2::VardisonManager.schedule(7000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 4:
//4x Seeker Photon
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
schedule(1000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
schedule(2000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
schedule(3000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
schedule(4000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
$TWM2::VardisonManager.schedule(5000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 5:
//Fire Missile
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
VardisonNamedAttack(%Boss, "FireSeeker", %tPl);
$TWM2::VardisonManager.schedule(4500, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
}
case 2:
%attackSelect = getRandom(1, 8);
switch(%attackSelect) {
case 1:
//Shadow Bomb Strike
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
VardisonNamedAttack(%Boss, "ShadowBombStrike", %tPl);
$TWM2::VardisonManager.schedule(4000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 2:
//Nightmare Missile
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
VardisonNamedAttack(%Boss, "NightmareMissile", %tPl);
$TWM2::VardisonManager.schedule(4500, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 3:
//Shadow Fissure
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
%tPos = %tPl.getPosition();
%bPos = %Boss.getPosition();
%fVec = vectorNormalize(vectorSub(%tPos, %bPos));
//Phase Vardison Out To Safety
%fire = new ParticleEmissionDummy(){
position = vectoradd(%spawnPos, "0 0 0.5");
dataBlock = "defaultEmissionDummy";
emitter = "SummoningPierEmitter";
};
MissionCleanup.add(%fire);
%fire.schedule(6500, "delete");
//Fades & Teleports
%Boss.startfade(1500, 0, true);
%Boss.schedule(2000, setPosition, vectorAdd(%bPos, "9999 9999 10"));
schedule(3000, 0, "VardisonNamedAttack", %Boss, "ShadowFissure", %bPos TAB %fVec);
%Boss.schedule(6000, setPosition, %bPos);
%Boss.schedule(6000, startFade, 1000, 0, false);
//
$TWM2::VardisonManager.schedule(7000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 4:
//4x Seeker Photon
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
schedule(1000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
schedule(2000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
schedule(3000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
schedule(4000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
$TWM2::VardisonManager.schedule(5000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 5:
//Minion Army
VardisonNamedAttack(%Boss, "MinionFlood", "");
case 6:
//Stasis Gate
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player.getPosition();
VardisonNamedAttack(%Boss, "StasisGate", %tPl);
$TWM2::VardisonManager.schedule(10000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 7:
//Rift Gate
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player.getPosition();
VardisonNamedAttack(%Boss, "RiftGate", %tPl);
$TWM2::VardisonManager.schedule(10000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 8:
//SGF
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
VardisonNamedAttack(%Boss, "SolomentaryGravityFlux", %tPl TAB 0);
$TWM2::VardisonManager.schedule(5000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
}
case 3:
%attackSelect = getRandom(1, 7);
switch(%attackSelect) {
case 1:
//Shadow Bomb Strike
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
VardisonNamedAttack(%Boss, "ShadowBombStrike", %tPl);
$TWM2::VardisonManager.schedule(4000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 2:
//Nightmare Missile
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
VardisonNamedAttack(%Boss, "NightmareMissile", %tPl);
$TWM2::VardisonManager.schedule(4500, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 3:
//Shadow Fissure
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
%tPos = %tPl.getPosition();
%bPos = %Boss.getPosition();
%fVec = vectorNormalize(vectorSub(%tPos, %bPos));
//Phase Vardison Out To Safety
%fire = new ParticleEmissionDummy(){
position = vectoradd(%spawnPos, "0 0 0.5");
dataBlock = "defaultEmissionDummy";
emitter = "SummoningPierEmitter";
};
MissionCleanup.add(%fire);
%fire.schedule(6500, "delete");
//Fades & Teleports
%Boss.startfade(1500, 0, true);
%Boss.schedule(2000, setPosition, vectorAdd(%bPos, "9999 9999 10"));
schedule(3000, 0, "VardisonNamedAttack", %Boss, "ShadowFissure", %bPos TAB %fVec);
%Boss.schedule(6000, setPosition, %bPos);
%Boss.schedule(6000, startFade, 1000, 0, false);
//
$TWM2::VardisonManager.schedule(7000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 4:
//4x Seeker Photon
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
schedule(1000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
schedule(2000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
schedule(3000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
schedule(4000, 0, "VardisonNamedAttack", %Boss, "SeekerPhoton", %tPl);
$TWM2::VardisonManager.schedule(5000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 5:
//Laser Drop
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
VardisonNamedAttack(%Boss, "LaserDrop", %tPl);
$TWM2::VardisonManager.schedule(5000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 6:
//Laser Wall
%Boss.setMoveState(true);
%target = FindValidTarget(%Boss);
if(isObject(%target)) {
%tPl = %target.player;
for(%i = 0; %i < 25; %i++) {
schedule(50+(%i*150), 0, VardisonNamedAttack, %Boss, "LaserWall", %tPl);
}
$TWM2::VardisonManager.schedule(10000, cooldownOff, %Boss, "attackFinished");
}
else {
%Boss.setMoveState(false);
%Boss.busy = false;
}
case 7:
//Gravity Well
%Boss.setMoveState(true);
VardisonNamedAttack(%Boss, "GravityWell", 0);
$TWM2::VardisonManager.schedule(5000, cooldownOff, %Boss, "attackFinished");
}
}
}
function VardisonNamedAttack(%Boss, %attack, %args) {
if(!isObject(%Boss) || %Boss.getState() $= "Dead") {
return;
}
%bPos = %Boss.getPosition();
switch$(%attack) {
case "ShadowBombStrike":
//Spawn 4 Pulses Above Vardison Fired at a guy
%target = getField(%args, 0);
%sPos = vectorAdd(%bPos, "0 0 25");
%vec = vectorNormalize(vectorSub(%target.getPosition(), %sPos));
for(%i = 0; %i < 4; %i++) {
%p = new LinearFlareProjectile() {
dataBlock = ShadowBlastBolt;
initialDirection = vectorScale(%vec, 10);
initialPosition = %sPos;
sourceSlot = 4;
};
%p.sourceObject = %Boss;
MissionCleanup.add(%p);
}
case "NightmareMissile":
%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);
case "ShadowFissure":
%sPos = getField(%args, 0);
%fVec = getField(%args, 1);
for(%i = 1; %i < 20; %i++) {
%sPos = vectorAdd(%sPos, "0 0 0.5");
%sPos = vectorAdd(%sPos, vectorScale(%fVec, %i*3));
%p = new LinearFlareProjectile() {
dataBlock = ShadowBlastBolt;
initialDirection = "0 0 -15";
initialPosition = %sPos;
sourceSlot = 4;
};
%p.sourceObject = %Boss;
MissionCleanup.add(%p);
}
case "SeekerPhoton":
%target = getField(%args, 0);
FireSeekerPhotons(%Boss, %target);
case "FireSeeker":
%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);
case "MinionFlood":
//Summon Maximum Minions & then Phase out until the team drops them
%max = $TWM2::Vardison2_MaxMinions[$TWM2::VardisonDifficulty];
%lowEnd = mFloor(%max * 0.25);
%retPos = %bPos;
%current = $TWM2::VardisonManager.minionCount;
%need = %max - %current;
for(%i = 0; %i < %need; %i++) {
VardisonDoMinionSummon(%Boss);
}
//Meanwhile, I take my leave :)
%Boss.startfade(1500, 0, true);
%Boss.rapierShield = true;
%Boss.schedule(2000, setPosition, vectorAdd(%bPos, "9999 9999 10"));
%Boss.vmcountLoop = schedule(1000, 0, VardisonMinionCountCheckup, %Boss, %retPos, %lowEnd);
case "StasisGate":
%pos = getField(%args, 0);
%TargetSearchMask = $TypeMasks::PlayerObjectType;
%c = createEmitter(%pos, FlashLEmitter, "1 0 0"); //Rotate it
%c.schedule(1000, delete);
InitContainerRadiusSearch(%pos, 25, %TargetSearchMask);
while ((%potentialTarget = ContainerSearchNext()) != 0){
if (!%potentialTarget.isZombie && !%potentialTarget.isBoss && !%potentialTarget.isVardisonMinion) {
VardisonNamedAttack(%Boss, "StasisLoop", %potentialTarget TAB 0);
}
}
case "StasisLoop":
%pl = getField(%args, 0);
if(!isObject(%pl) || %pl.getState() $= "dead") {
return;
}
%counter = getField(%args, 1);
%counter++;
if(%counter > 10) {
%pl.setMoveState(false);
return;
}
%c = createEmitter(%pl.getPosition(), PBCExpEmitter, "1 0 0"); //Rotate it
%c.schedule(1000, delete);
%pl.setMoveState(true);
schedule(1000, 0, VardisonNamedAttack, %Boss, %attack, %pl TAB %counter);
case "RiftGate":
%pos = getField(%args, 0);
%goPos = TWM2Lib_MainControl("RMPG");
%TargetSearchMask = $TypeMasks::PlayerObjectType;
%c = createEmitter(%pos, FlashLEmitter, "1 0 0"); //Rotate it
%c.schedule(1000, delete);
%c2 = createEmitter(%goPos, FlashLEmitter, "1 0 0"); //Rotate it
%c2.schedule(1000, delete);
InitContainerRadiusSearch(%pos, 25, %TargetSearchMask);
while ((%potentialTarget = ContainerSearchNext()) != 0){
if (!%potentialTarget.isZombie && !%potentialTarget.isBoss && !%potentialTarget.isVardisonMinion) {
%PosAdd = vectorNormalize(vectorSub(%pos, %potentialTarget.getPosition()));
%PosDst = vectorDist(%pos, %potentialTarget.getPosition());
%newPos = vectorAdd(%goPos, vectorScale(%PosAdd, %PosDst));
%potentialTarget.setPosition(%newPos);
}
}
case "LaserDrop":
%toDie = getField(%args, 0);
if(!isObject(%toDie) || %toDie.getState() $= "dead") {
return;
}
%p = new LinearFlareProjectile() {
dataBlock = HyperDevestatorBeam;
initialDirection = "0 0 -10";
initialPosition = vectoradd(%toDie.getPosition(), "0 0 500");
sourceSlot = 4;
};
%p.sourceObject = %boss;
MissionCleanup.add(%p);
case "LaserWall":
%toDie = getField(%args, 0);
if(!isObject(%toDie) || %toDie.getState() $= "dead") {
return;
}
%vec = vectorNormalize(vectorSub(%toDie.getPosition(), %bPos));
%p = new LinearFlareProjectile() {
dataBlock = SuperlaserProjectile;
initialDirection = %vec;
initialPosition = %bPos;
sourceObject = %boss;
sourceSlot = 4;
};
MissionCleanup.add(%p);
case "SolomentaryGravityFlux":
%target = getField(%args, 0);
if(!isObject(%target) || %target.getState() $= "dead") {
return;
}
%counter = getField(%args, 1);
%counter++;
if(%counter < 15) {
%target.setVelocity("0 0 300");
}
else if(%counter > 25) {
//Stop...
return;
}
else {
%target.setVelocity("0 0 -300");
}
schedule(150, 0, VardisonNamedAttack, %Boss, %attack, %target TAB %counter);
case "GravityWell":
%counter = getField(%args, 0);
%counter++;
if(%counter < 15) {
for(%i = 0; %i < ClientGroup.getCount(); %i++) {
%cl = ClientGroup.getObject(%i);
if(isObject(%cl.player) || %cl.player.getState() !$= "dead") {
%cl.player.setVelocity("0 0 300");
}
}
}
else if(%counter > 25) {
//Stop...
return;
}
else {
for(%i = 0; %i < ClientGroup.getCount(); %i++) {
%cl = ClientGroup.getObject(%i);
if(isObject(%cl.player) || %cl.player.getState() !$= "dead") {
%cl.player.setVelocity("0 0 -300");
}
}
}
schedule(150, 0, VardisonNamedAttack, %Boss, %attack, %counter);
default:
error("Invalid vardison attack...");
}
}
function VardisonMinionCountCheckup(%boss, %retPos, %lowEnd) {
if($TWM2::VardisonManager.minionCount < %lowEnd) {
//Return to the arena
%Boss.schedule(1500, setPosition, %retPos);
%Boss.schedule(1500, startFade, 1000, 0, false);
%Boss.rapierShield = false;
$TWM2::VardisonManager.schedule(7000, cooldownOff, %Boss, "attackFinished");
return;
}
%boss.vmcountLoop = schedule(1000, 0, VardisonMinionCountCheckup, %boss, %retPos, %lowEnd);
}
//Vardison Manager Functions
//SummonOrb()
function VardisonManager::summonOrb(%this, %boss) {
%summonPos = vectorAdd(%boss.getPosition(), "0 0 35");
%orb = new (StaticShape)() {
dataBlock = ShadowOrb;
};
%orb.setTransform(%summonPos SPC "0 0 0 1");
%orb.team = %boss.Team;
%orb.setOwner(%boss);
%orb.team = 30;
%orb.target = createTarget(%orb, "\c7Shadow Rift", "", "Derm3", '', %orb.team, PlayerSensor);
setTargetSensorData(%orb.target, PlayerSensor);
setTargetSensorGroup(%orb.target, 30);
setTargetName(%orb.target, addtaggedstring("\c7Shadow Rift"));
%orb.waypoint = new WayPoint() {
position = %orb.getPosition();
dataBlock = "WayPointMarker";
team = %boss.Team;
name = "Shadow Rift";
};
%orb.startfade(1, 0, true);
//SFX
$TWM2::VardisonManager.OrbSFX = new ParticleEmissionDummy(){
position = %orb.getPosition();
dataBlock = "defaultEmissionDummy";
emitter = "ShadowOrbEmitter";
};
MissionCleanup.add($TWM2::VardisonManager.OrbSFX);
//
%this.orbKillSched = %this.schedule($TWM2::Vardison_OrbKillTime, orbKill, %boss, %orb);
}
function VardisonManager::orbKill(%this, %boss, %orb) {
%restoreCount = 0;
for(%i = 0; %i < ClientGroup.getCount(); %i++) {
%cl = ClientGroup.getObject(%i);
if(isObject(%cl.player) && %cl.player.getState() !$= "dead") {
//Bye Bye :)
%cl.player.rapierShield = false;
%cl.player.setInvincible(false);
%cl.player.damage(%boss, %cl.player.getPosition(), 10000, $DamageType::ShadowOrb);
%cl.player.blowup();
MessageAll('msgDeath', "\c2"@%cl.namebase@" has been annihilated by the Shadow Rift.");
//If Vardison Restores HP from rift kills, do that now :P
if($TWM2::Vardison_OrbRegenHP[$TWM2::VardisonDifficulty]) {
%boss.setDamageLevel(%boss.getDamageLevel() - 0.35);
%restoreCount++;
}
}
}
MessageAll('msgRestore', "\c5Lord Vardison has absorbed the life energy of "@%restoreCount@" combatants.");
%wipeEmit = new ParticleEmissionDummy(){
position = %orb.getPosition();
dataBlock = "defaultEmissionDummy";
emitter = "ShadowOrbDetonationEmitter";
};
%wipeEmit.schedule(500, "delete");
//Delete the orb & it's effects
if(isObject(%obj.waypoint)) {
%obj.waypoint.schedule(500, "delete");
}
if(isObject($TWM2::VardisonManager.OrbSFX)) {
$TWM2::VardisonManager.OrbSFX.schedule(500, "delete");
}
%orb.schedule(500, "delete");
if(isObject(%this.orbFire)) {
%this.orbFire.schedule(500, "delete");
}
%this.orbObject = -1;
%boss.rapierShield = false;
%boss.busy = false; //<-- let think() resume...
}
function VardisonManager::orbDestroyed(%this) {
if(isObject(%this.orbFire)) {
%this.orbFire.schedule(500, "delete");
}
cancel(%this.orbKillSched);
%this.orbObject = -1;
%boss = %this.Vardison;
%boss.rapierShield = false;
%boss.busy = false; //<-- let think() resume...
MessageAll('msgDeath', "\c2The Shadow Rift has been Shattered...");
}
function VardisonManager::cooldownOff(%this, %Boss, %type) {
if(!isObject(%this)) {
error("VardisonManager::cooldownOff(): Missing instance of VM.");
return;
}
if(!isObject(%Boss) || %Boss.getState() $= "dead") {
error("VardisonManager::cooldownOff(): Vardison Dead.");
return;
}
switch$(%type) {
case "minions":
%Boss.canSummonMinions = true;
case "busy":
%Boss.busy = false;
case "attackFinished":
//Unlock the boss & update LAT
%Boss.setMoveState(false);
%this.lastAttackTime = getRealTime();
%Boss.busy = false;
}
}
function ShadowOrb::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) {
if(%sourceObject && %targetObject.isEnabled()) {
if(%sourceObject.client) {
%targetObject.lastDamagedBy = %sourceObject.client;
%targetObject.lastDamagedByTeam = %sourceObject.client.team;
%targetObject.damageTimeMS = GetSimTime();
}
else {
%targetObject.lastDamagedBy = %sourceObject;
%targetObject.lastDamagedByTeam = %sourceObject.team;
%targetObject.damageTimeMS = GetSimTime();
}
}
if (%data.isShielded) {
%amount = %data.checkShields(%targetObject, %position, %amount, %damageType);
}
%damageScale = %data.damageScale[%damageType];
if(%damageScale !$= "") {
%amount *= %damageScale;
}
if (%amount > 0) {
%targetObject.applyDamage(%amount);
}
}