--------------------------------------------------------------------------------------------
Greande Fountain Tutorial
--------------------------------------------------------------------------------------------
This tutorial makes a weapon that fires a non-heat seaking missile, when the fire button is pressed a second time, it detonates the missile and drops a bunch of grenades over the area the missile detonates. To make depth perception easier, I added a tracking effect with a flattened out nexus effect that follows under the missile along the ground so you can easily see where to detonate it over. This is recommended for heavies only.
Step #1
// ------------------------------------------
// inventoryHud.cs
// ------------------------------------------
1a) Add these to the top of the file.
$InvWeapon[13] = "Grenade Fountain";
$NameToInv["Grenade Fountain"] = "GrenadeFountain";
1b) Add this to function buyFavorites and function buyDeployableFavorites
case GrenadeFountain:
%client.player.setInventory( GrenadeFountainAmmo, 400 );
Step #2
// ------------------------------------------
// weapons.cs
// ------------------------------------------
$WeaponsHudData[13, bitmapName] = "gui/hud_grenlaunch";
$WeaponsHudData[13, itemDataName] = "GrenadeFountain";
$WeaponsHudData[13, ammoDataName] = "GrenadeFountainAmmo";
$WeaponsHudCount = 14;
$AmmoIncrement[GrenadeFountainAmmo] = 5;
exec("scripts/weapons/GrenadeFountain.cs");
Step #3
// ------------------------------------------
// inventory.cs
// ------------------------------------------
3a) Add this with all the other 'case' in the function
function ShapeBase::hasAmmo( %this, %weapon )
{
switch$ ( %weapon )
{
case GrenadeFountain:
return( %this.getInventory( GrenadeFountainAmmo ) > 0 );
}
}
3b) Add this with all the other cleared items
function ShapeBase::clearInventory(%this)
{
%this.setInventory(GrenadeFountain, 0);
%this.setInventory(GrenadeFountainAmmo, 0);
}
3c)
function serverCmdGiveAll(%client)
{
if($TestCheats)
{
%player.setInventory(GrenadeFountain, 1);
%player.setInventory(GrenadeFountainAmmo, 999);
}
}
Step #4
// ------------------------------------------
// player.cs
// ------------------------------------------
4a) Add to player armor datablocks. Probably only want to give it to heavies.
max [GrenadeFountain] = 1;
max [GrenadeFountainAmmo] = 10;
4b) Add these to function armor::applyConcussion
if( %weaps[13] = %player.getInventory("GrenadeFountain") > 0 ) %numWeapons++;
and
case 13:
%player.use("GrenadeFountain");
Step #5
// ------------------------------------------
// hud.cs
// ------------------------------------------
Ignore this step if you use any server side reticle workarounds.
function clientCmdSetWeaponsHudActive(%slot)
{
weaponsHud.setActiveWeapon(%slot);
switch$($WeaponNames[%slot])
{
case "GrenadeFountain":
reticleHud.setBitmap("gui/ret_missile");
reticleFrameHud.setVisible(true);
}
}
Step #6
// ------------------------------------------
// Ammopack.cs
// ------------------------------------------
Add ammo to ammopack, to increase with it.
$ammoItem[9] = GrenadeFountainAmmo;
$numAmmoItems = 10;
datablock ItemData(AmmoPack)
{
max[GrenadeFountainAmmo] = 10;
}
Step #7
// ------------------------------------------
// OptionsDlg.cs
// ------------------------------------------
$RemapName[$RemapCount] = "GrenadeFountain";
$RemapCmd[$RemapCount] = "useGrenadeFountain";
$RemapCount++;
Step #8
// ------------------------------------------
// ControlDefaults.cs
// ------------------------------------------
function useGrenadeFountain( %val )
{
if ( %val )
use( GrenadeFountain );
}
Step #9
// ------------------------------------------
// GrenadeFountain.cs
// ------------------------------------------
Create a file called GrenadeFountain.cs in your weapon's directory. Add all this into it.
//--------------------------------------
// GrenadeFountain launcher
//--------------------------------------
//--------------------------------------------------------------------------
// Force-Feedback Effects
//--------------------------------------
datablock EffectProfile(GrenadeFountainSwitchEffect)
{
effectname = "weapons/missile_launcher_activate";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(GrenadeFountainFireEffect)
{
effectname = "weapons/missile_fire";
minDistance = 2.5;
maxDistance = 5.0;
};
datablock EffectProfile(GrenadeFountainDryFireEffect)
{
effectname = "weapons/missile_launcher_dryfire";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(GrenadeFountainExplosionEffect)
{
effectname = "explosions/explosion.xpl23";
minDistance = 10;
maxDistance = 30;
};
//--------------------------------------------------------------------------
// Sounds
//--------------------------------------
datablock AudioProfile(GrenadeFountainSwitchSound)
{
filename = "fx/weapons/missile_launcher_activate.wav";
description = AudioClosest3d;
preload = true;
effect = GrenadeFountainSwitchEffect;
};
datablock AudioProfile(GrenadeFountainFireSound)
{
filename = "fx/weapons/missile_fire.WAV";
description = AudioDefault3d;
preload = true;
effect = GrenadeFountainFireEffect;
};
datablock AudioProfile(GrenadeFountainProjectileSound)
{
filename = "fx/weapons/missile_projectile.wav";
description = ProjectileLooping3d;
preload = true;
};
datablock AudioProfile(GrenadeFountainReloadSound)
{
filename = "fx/weapons/weapon.missilereload.wav";
description = AudioClosest3d;
preload = true;
};
datablock AudioProfile(GrenadeFountainLockSound)
{
filename = "fx/weapons/missile_launcher_searching.WAV";
description = AudioClosest3d;
preload = true;
};
datablock AudioProfile(GrenadeFountainExplosionSound)
{
filename = "fx/explosions/explosion.xpl23.wav";
description = AudioBIGExplosion3d;
preload = true;
effect = GrenadeFountainExplosionEffect;
};
datablock AudioProfile(GrenadeFountainDryFireSound)
{
filename = "fx/weapons/missile_launcher_dryfire.wav";
description = AudioClose3d;
preload = true;
effect = GrenadeFountainDryFireEffect;
};
//----------------------------------------------------------------------------
// Splash Debris
//----------------------------------------------------------------------------
datablock ParticleData( MDebrisSmokeParticle )
{
dragCoeffiecient = 1.0;
gravityCoefficient = 0.10;
inheritedVelFactor = 0.1;
lifetimeMS = 1000;
lifetimeVarianceMS = 100;
textureName = "particleTest";
// useInvAlpha = true;
spinRandomMin = -60.0;
spinRandomMax = 60.0;
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.5";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.0;
sizes[1] = 0.8;
sizes[2] = 0.8;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( MDebrisSmokeEmitter )
{
ejectionPeriodMS = 10;
periodVarianceMS = 1;
ejectionVelocity = 1.0; // A little oomph at the back end
velocityVariance = 0.2;
thetaMin = 0.0;
thetaMax = 40.0;
particles = "MDebrisSmokeParticle";
};
datablock DebrisData( GrenadeFountainSplashDebris )
{
emitters[0] = MDebrisSmokeEmitter;
explodeOnMaxBounce = true;
elasticity = 0.4;
friction = 0.2;
lifetime = 0.3;
lifetimeVariance = 0.1;
numBounces = 1;
};
//----------------------------------------------------------------------------
// GrenadeFountain smoke spike (for debris)
//----------------------------------------------------------------------------
datablock ParticleData( GrenadeFountainSmokeSpike )
{
dragCoeffiecient = 1.0;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
lifetimeMS = 1000;
lifetimeVarianceMS = 100;
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -60.0;
spinRandomMax = 60.0;
colors[0] = "0.6 0.6 0.6 1.0";
colors[1] = "0.4 0.4 0.4 0.5";
colors[2] = "0.4 0.4 0.4 0.0";
sizes[0] = 0.0;
sizes[1] = 1.0;
sizes[2] = 0.5;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( GrenadeFountainSmokeSpikeEmitter )
{
ejectionPeriodMS = 7;
periodVarianceMS = 1;
ejectionVelocity = 1.0; // A little oomph at the back end
velocityVariance = 0.2;
thetaMin = 0.0;
thetaMax = 40.0;
particles = "GrenadeFountainSmokeSpike";
};
//----------------------------------------------------------------------------
// Explosion smoke particles
//----------------------------------------------------------------------------
datablock ParticleData(GrenadeFountainExplosionSmoke)
{
dragCoeffiecient = 0.3;
gravityCoefficient = -0.2;
inheritedVelFactor = 0.025;
lifetimeMS = 1250;
lifetimeVarianceMS = 0;
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -100.0;
spinRandomMax = 100.0;
textureName = "special/Smoke/bigSmoke";
colors[0] = "1.0 0.7 0.0 1.0";
colors[1] = "0.4 0.4 0.4 0.5";
colors[2] = "0.4 0.4 0.4 0.0";
sizes[0] = 1.0;
sizes[1] = 3.0;
sizes[2] = 1.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(GrenadeFountainExplosionSmokeEMitter)
{
ejectionOffset = 0.0;
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 3.25;
velocityVariance = 0.25;
thetaMin = 0.0;
thetaMax = 180.0;
lifetimeMS = 250;
particles = "GrenadeFountainExplosionSmoke";
};
datablock DebrisData( GrenadeFountainSpikeDebris )
{
emitters[0] = GrenadeFountainSmokeSpikeEmitter;
explodeOnMaxBounce = true;
elasticity = 0.4;
friction = 0.2;
lifetime = 0.3;
lifetimeVariance = 0.02;
};
//---------------------------------------------------------------------------
// Explosions
//---------------------------------------------------------------------------
datablock ExplosionData(GrenadeFountainExplosion)
{
explosionShape = "effect_plasma_explosion.dts";
playSpeed = 1.5;
soundProfile = GrenadeFountainExplosionSound;
faceViewer = true;
sizes[0] = "0.5 0.5 0.5";
sizes[1] = "0.5 0.5 0.5";
sizes[2] = "0.5 0.5 0.5";
emitter[0] = GrenadeFountainExplosionSmokeEmitter;
debris = GrenadeFountainSpikeDebris;
debrisThetaMin = 10;
debrisThetaMax = 170;
debrisNum = 8;
debrisNumVariance = 6;
debrisVelocity = 15.0;
debrisVelocityVariance = 2.0;
shakeCamera = true;
camShakeFreq = "6.0 7.0 7.0";
camShakeAmp = "70.0 70.0 70.0";
camShakeDuration = 1.0;
camShakeRadius = 7.0;
};
datablock ExplosionData(GrenadeFountainSplashExplosion)
{
explosionShape = "disc_explosion.dts";
faceViewer = true;
explosionScale = "1.0 1.0 1.0";
debris = GrenadeFountainSplashDebris;
debrisThetaMin = 10;
debrisThetaMax = 80;
debrisNum = 10;
debrisVelocity = 10.0;
debrisVelocityVariance = 4.0;
sizes[0] = "0.35 0.35 0.35";
sizes[1] = "0.15 0.15 0.15";
sizes[2] = "0.15 0.15 0.15";
sizes[3] = "0.15 0.15 0.15";
times[0] = 0.0;
times[1] = 0.333;
times[2] = 0.666;
times[3] = 1.0;
};
//--------------------------------------------------------------------------
// Splash
//--------------------------------------------------------------------------
datablock ParticleData(GrenadeFountainMist)
{
dragCoefficient = 2.0;
gravityCoefficient = -0.05;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 400;
lifetimeVarianceMS = 100;
useInvAlpha = false;
spinRandomMin = -90.0;
spinRandomMax = 500.0;
textureName = "particleTest";
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.5";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.5;
sizes[1] = 0.5;
sizes[2] = 0.8;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(GrenadeFountainMistEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 6.0;
velocityVariance = 4.0;
ejectionOffset = 0.0;
thetaMin = 85;
thetaMax = 85;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
lifetimeMS = 250;
particles = "GrenadeFountainMist";
};
datablock ParticleData( GrenadeFountainSplashParticle )
{
dragCoefficient = 1;
gravityCoefficient = 0.2;
inheritedVelFactor = 0.2;
constantAcceleration = -0.0;
lifetimeMS = 600;
lifetimeVarianceMS = 0;
textureName = "special/droplet";
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.5";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.5;
sizes[1] = 0.5;
sizes[2] = 0.5;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( GrenadeFountainSplashEmitter )
{
ejectionPeriodMS = 1;
periodVarianceMS = 0;
ejectionVelocity = 6;
velocityVariance = 3.0;
ejectionOffset = 0.0;
thetaMin = 60;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "GrenadeFountainSplashParticle";
};
datablock SplashData(GrenadeFountainSplash)
{
numSegments = 15;
ejectionFreq = 0.0001;
ejectionAngle = 45;
ringLifetime = 0.5;
lifetimeMS = 400;
velocity = 5.0;
startRadius = 0.0;
acceleration = -3.0;
texWrap = 5.0;
explosion = GrenadeFountainSplashExplosion;
texture = "special/water2";
emitter[0] = GrenadeFountainSplashEmitter;
emitter[1] = GrenadeFountainMistEmitter;
colors[0] = "0.7 0.8 1.0 0.0";
colors[1] = "0.7 0.8 1.0 1.0";
colors[2] = "0.7 0.8 1.0 0.0";
colors[3] = "0.7 0.8 1.0 0.0";
times[0] = 0.0;
times[1] = 0.4;
times[2] = 0.8;
times[3] = 1.0;
};
//--------------------------------------------------------------------------
// Particle effects
//--------------------------------------
datablock ParticleData(GrenadeFountainSmokeParticle)
{
dragCoeffiecient = 0.0;
gravityCoefficient = -0.02;
inheritedVelFactor = 0.1;
lifetimeMS = 1200;
lifetimeVarianceMS = 100;
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -90.0;
spinRandomMax = 90.0;
colors[0] = "1.0 0.75 0.0 0.0";
colors[1] = "0.5 0.5 0.5 1.0";
colors[2] = "0.3 0.3 0.3 0.0";
sizes[0] = 1;
sizes[1] = 2;
sizes[2] = 3;
times[0] = 0.0;
times[1] = 0.1;
times[2] = 1.0;
};
datablock ParticleEmitterData(GrenadeFountainSmokeEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 1.5;
velocityVariance = 0.3;
thetaMin = 0.0;
thetaMax = 50.0;
particles = "GrenadeFountainSmokeParticle";
};
datablock ParticleData(GrenadeFountainFireParticle)
{
dragCoeffiecient = 0.0;
gravityCoefficient = 0.0;
inheritedVelFactor = 1.0;
lifetimeMS = 300;
lifetimeVarianceMS = 000;
textureName = "particleTest";
spinRandomMin = -135;
spinRandomMax = 135;
colors[0] = "1.0 0.75 0.2 1.0";
colors[1] = "1.0 0.5 0.0 1.0";
colors[2] = "1.0 0.40 0.0 0.0";
sizes[0] = 0;
sizes[1] = 1;
sizes[2] = 1.5;
times[0] = 0.0;
times[1] = 0.3;
times[2] = 1.0;
};
datablock ParticleEmitterData(GrenadeFountainFireEmitter)
{
ejectionPeriodMS = 15;
periodVarianceMS = 0;
ejectionVelocity = 15.0;
velocityVariance = 0.0;
thetaMin = 0.0;
thetaMax = 0.0;
particles = "GrenadeFountainFireParticle";
};
datablock ParticleData(GrenadeFountainPuffParticle)
{
dragCoeffiecient = 0.0;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 300;
textureName = "particleTest";
spinRandomMin = -135;
spinRandomMax = 135;
colors[0] = "1.0 1.0 1.0 0.5";
colors[1] = "0.7 0.7 0.7 0.0";
sizes[0] = 0.25;
sizes[1] = 1.0;
times[0] = 0.0;
times[1] = 1.0;
};
datablock ParticleEmitterData(GrenadeFountainPuffEmitter)
{
ejectionPeriodMS = 50;
periodVarianceMS = 3;
ejectionVelocity = 0.5;
velocityVariance = 0.0;
thetaMin = 0.0;
thetaMax = 90.0;
particles = "GrenadeFountainPuffParticle";
};
datablock ParticleData(GrenadeFountainLauncherExhaustParticle)
{
dragCoeffiecient = 0.0;
gravityCoefficient = 0.01;
inheritedVelFactor = 1.0;
lifetimeMS = 500;
lifetimeVarianceMS = 300;
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -135;
spinRandomMax = 135;
colors[0] = "1.0 1.0 1.0 0.5";
colors[1] = "0.7 0.7 0.7 0.0";
sizes[0] = 0.25;
sizes[1] = 1.0;
times[0] = 0.0;
times[1] = 1.0;
};
datablock ParticleEmitterData(GrenadeFountainLauncherExhaustEmitter)
{
ejectionPeriodMS = 15;
periodVarianceMS = 0;
ejectionVelocity = 3.0;
velocityVariance = 0.0;
thetaMin = 0.0;
thetaMax = 20.0;
particles = "GrenadeFountainLauncherExhaustParticle";
};
//--------------------------------------------------------------------------
// Debris
//--------------------------------------
datablock DebrisData( FlechetteDebris )
{
shapeName = "weapon_missile_fleschette.dts";
lifetime = 5.0;
minSpinSpeed = -320.0;
maxSpinSpeed = 320.0;
elasticity = 0.2;
friction = 0.3;
numBounces = 3;
gravModifier = 0.40;
staticOnMaxBounce = true;
};
//--------------------------------------------------------------------------
// Projectile
//--------------------------------------
datablock SeekerProjectileData(ShoulderGrenadeFountain)
{
casingShapeName = "weapon_missile_casement.dts";
projectileShapeName = "weapon_missile_projectile.dts";
hasDamageRadius = true;
indirectDamage = 0.8;
damageRadius = 8.0;
radiusDamageType = $DamageType::Missile;
kickBackStrength = 2000;
explosion = "GrenadeFountainExplosion";
splash = GrenadeFountainSplash;
velInheritFactor = 1.0;
baseEmitter = GrenadeFountainSmokeEmitter;
delayEmitter = GrenadeFountainFireEmitter;
// puffEmitter = GrenadeFountainPuffEmitter;
bubbleEmitter = GrenadeBubbleEmitter;
bubbleEmitTime = 1.0;
// exhaustEmitter = GrenadeFountainLauncherExhaustEmitter;
exhaustTimeMs = 300;
exhaustNodeName = "muzzlePoint1";
lifetimeMS = 20000;
muzzleVelocity = 10.0;
maxVelocity = 30.0;
turningSpeed = 0.0;
acceleration = 200.0;
proximityRadius = 3;
terrainAvoidanceSpeed = 180;
terrainScanAhead = 25;
terrainHeightFail = 12;
terrainAvoidanceRadius = 100;
flareDistance = 200;
flareAngle = 30;
sound = GrenadeFountainProjectileSound;
hasLight = true;
lightRadius = 5.0;
lightColor = "0.2 0.05 0";
useFlechette = true;
flechetteDelayMs = 550;
casingDeb = FlechetteDebris;
explodeOnWaterImpact = false;
};
//--------------------------------------------------------------------------
// Ammo
//--------------------------------------
datablock ItemData(GrenadeFountainAmmo)
{
className = Ammo;
catagory = "Ammo";
shapeFile = "ammo_missile.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "some grendade fountain ammo";
computeCRC = true;
};
//--------------------------------------------------------------------------
// Weapon
//--------------------------------------
datablock ItemData(GrenadeFountain)
{
className = Weapon;
catagory = "Spawn Items";
shapeFile = "weapon_missile.dts";
image = GrenadeFountainImage;
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "a grenade fountain";
computeCRC = true;
emap = true;
};
datablock ShapeBaseImageData(GrenadeFountainImage)
{
className = WeaponImage;
shapeFile = "weapon_missile.dts";
item = GrenadeFountain;
ammo = GrenadeFountainAmmo;
offset = "0 0 0";
armThread = lookms;
emap = true;
projectile = ShoulderGrenadeFountain;
projectileType = SeekerProjectile;
isSeeker = false;
// only target objects outside this range
minTargetingDistance = 40;
stateName[0] = "Activate";
stateTransitionOnTimeout[0] = "ActivateReady";
stateTimeoutValue[0] = 0.5;
stateSequence[0] = "Activate";
stateSound[0] = GrenadeFountainSwitchSound;
stateName[1] = "ActivateReady";
stateTransitionOnLoaded[1] = "Ready";
stateTransitionOnNoAmmo[1] = "NoAmmo";
stateName[2] = "Ready";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "CheckWet";
stateName[3] = "Fire";
stateTransitionOnTimeout[3] = "Reload";
stateTimeoutValue[3] = 0.4;
stateFire[3] = true;
stateRecoil[3] = LightRecoil;
stateAllowImageChange[3] = false;
stateSequence[3] = "Fire";
stateScript[3] = "onFire";
stateSound[3] = GrenadeFountainFireSound;
stateName[4] = "Reload";
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateTransitionOnTimeout[4] = "Ready";
stateTimeoutValue[4] = 1.0;
stateAllowImageChange[4] = false;
stateSequence[4] = "Reload";
stateSound[4] = GrenadeFountainReloadSound;
stateName[5] = "NoAmmo";
stateTransitionOnAmmo[5] = "Reload";
stateSequence[5] = "NoAmmo";
stateTransitionOnTriggerDown[5] = "DryFire";
stateName[6] = "DryFire";
stateScript[6] = "onDryFire";
stateSound[6] = GrenadeFountainDryFireSound;
stateTimeoutValue[6] = 1.0;
stateTransitionOnTimeout[6] = "ActivateReady";
stateName[7] = "CheckTarget";
stateTransitionOnNoTarget[7] = "Fire";
stateTransitionOnTarget[7] = "Fire";
stateName[8] = "CheckWet";
stateTransitionOnWet[8] = "WetFire";
stateTransitionOnNotWet[8] = "CheckTarget";
stateName[9] = "WetFire";
stateTransitionOnNoAmmo[9] = "NoAmmo";
stateTransitionOnTimeout[9] = "Reload";
stateSound[9] = GrenadeFountainFireSound;
stateRecoil[9] = LightRecoil;
stateTimeoutValue[9] = 0.4;
stateSequence[9] = "Fire";
stateScript[9] = "onFire";
stateAllowImageChange[9] = false;
};
datablock StaticShapeData(RPCNexus)
{
shapefile = "nexus_effect.dts";
isInvincible = true;
dynamicType = $TypeMasks::BeaconObjectType;
};
function GrenadeFountainImage::onFire(%data,%obj,%slot)
{
if (isObject(%obj.GrenadeFountainProj))
detGrenadeFountainProj(%obj);
else
{
%obj.GrenadeFountainProj = Parent::onFire(%data,%obj,%slot);
BeaconIt(%obj.GrenadeFountainProj);
}
}
function GrenadeFountainImage::onDryFire(%data,%obj,%slot)
{
if (isObject(%obj.GrenadeFountainProj))
detGrenadeFountainProj(%obj);
}
function ShoulderGrenadeFountain::onExplode(%data, %proj, %pos, %mod)
{
if (isObject(%proj.beac))
%proj.beac.delete();
if (isObject(%proj.sourceObject))
%proj.sourceObject.grenadeFountainProj = "";
if (%data.hasDamageRadius)
RadiusExplosion(%proj, %pos, %data.damageRadius, %data.indirectDamage, %data.kickBackStrength, %proj.sourceObject, %data.radiusDamageType);
}
function detGrenadeFountainProj(%obj)
{
%proj = %obj.GrenadeFountainProj;
if (!isObject(%proj))
return;
%pos = posFromTransform(%proj.getTransform());
%endpos = VectorAdd(%pos, "0 0 -3000");
%hit = ContainerRayCast(%pos, %endpos, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType, %proj);
if (%hit)
%height = getWord(%pos, 2) - getWord(%hit, 3);
if ((%height > 150) || (!%height))
%height = 150;
if (%height < 10)
%height = 10;
%spread = 2.25 / ((%height / 20) * (%height / 20));
%vec = "0 0 -1";
for (%i=0;%i<20;%i++)
{
%x = (getRandom() - 0.5) * 2 * 3.1415926 * %spread;
%y = (getRandom() - 0.5) * 2 * 3.1415926 * %spread;
%z = (getRandom() - 0.5) * 2 * 3.1415926 * %spread;
%mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z);
%vector = MatrixMulVector(%mat, %vec);
%p = new (GrenadeProjectile)() {
dataBlock = BasicGrenade;
initialDirection = %vector;
initialPosition = %pos;
sourceObject = %proj.sourceObject;
sourceSlot = %proj.sourceSlot;
vehicleObject = %proj.vehicleObject;
};
MissionCleanup.add(%p);
}
if (isObject(%obj.grenadeFountainProj.beac))
%obj.grenadeFountainProj.beac.delete();
%obj.grenadeFountainProj.delete();
%obj.grenadeFountainProj = "";
}
function BeaconIt(%p)
{
if (!isObject(%p))
return;
%pos = posFromTransform(%p.getTransform());
%endpos = VectorAdd(%pos, "0 0 -3000");
%hit = ContainerRayCast(%pos, %endpos, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType, %proj);
%pos = getWords(%hit, 1, 3);
%p.beac = new StaticShape() {
dataBlock = RPCNexus;
scale = "3 3 0.1";
};
MissionCleanup.add(%p.beac);
%p.beac.setTransform(%pos SPC "0 0 0 1");
schedule(100, 0, "BeaconItTwo", %p);
}
function BeaconItTwo(%p)
{
if (!isObject(%p))
return;
%pos = posFromTransform(%p.getTransform());
%endpos = VectorAdd(%pos, "0 0 -3000");
%hit = ContainerRayCast(%pos, %endpos, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType, %proj);
%pos = getWords(%hit, 1, 3);
if (!isObject(%p.beac))
return;
%p.beac.setTransform(%pos SPC "0 0 0 1");
schedule(100, 0, "BeaconItTwo", %p);
}