--------------------------------------------------------------------------------------------------------------- Flakgun Tutorial-By BadShot -Edited by Drumstix42 This is for all the people that could not get his tutorial working. All that's done is one step from Projectiles.cs is taken out, and it's updated to the new patch. I have to say, it works great. Remember that all credit goes to him. More of his tuts at: http://www.mage-tower.com/BadShot --------------------------------------------------------------------------------------------------------------- This tutorial makes an effective non-heat seeking anti air weapon called a flakgun. It works like a chaingun, except its bullets explode throwing flak into the air, it has a wider spread then a chaingun and varrying distance before it explodes. It's particulary usefull against flare happy flag cappers and shrikes as a bomber tailgunner. This tut uses the chaingun damageType, you may want to add a flakgun damageType for it instead. Step #1 // ------------------------------------------ // inventoryHud.cs // ------------------------------------------ Add these to the top of the file. $InvWeapon[12] = "Flakgun"; $NameToInv["Flakgun"] = "Flakgun"; Step #2 // ------------------------------------------ // weapons.cs // ------------------------------------------ $WeaponsHudData[12, bitmapName] = "gui/hud_chaingun"; $WeaponsHudData[12, itemDataName] = "Flakgun"; $WeaponsHudData[12, ammoDataName] = "FlakgunAmmo"; $WeaponsHudData[12, reticle] = "gui/ret_chaingun"; $WeaponsHudData[12, visible] = "true"; $WeaponsHudCount = 13; $AmmoIncrement[FlakgunAmmo] = 25; exec("scripts/weapons/Flakgun.cs"); Step #3 // ------------------------------------------ // inventory.cs // ------------------------------------------ 3a) Add this with all the other cleared items function ShapeBase::clearInventory(%this) { %this.setInventory(Flakgun, 0); %this.setInventory(FlakgunAmmo, 0); } 3b) function serverCmdGiveAll(%client) { if($TestCheats) { %player.setInventory(Flakgun, 1); %player.setInventory(FlakgunAmmo, 999); } } Step #4 // ------------------------------------------ // player.cs // ------------------------------------------ 4a) Add to player armor datablocks. Probably only want to give it to mediums and heavies. Recommend 50 ammo for mediums and 100 for heavies. max [Flakgun] = 1; max [FlakgunAmmo] = 50; 4b) Add these to function armor::applyConcussion if( %weaps[12] = %player.getInventory("Flakgun") > 0 ) %numWeapons++; and case 12: %player.use("Flakgun"); Step #5 // ------------------------------------------ // Ammopack.cs // ------------------------------------------ Add ammo to ammopack, to increase with it. $ammoItem[8] = FlakgunAmmo; $numAmmoItems = 9; datablock ItemData(AmmoPack) { max[FlakgunAmmo] = 50; } Step #6 // ------------------------------------------ // OptionsDlg.cs // ------------------------------------------ $RemapName[$RemapCount] = "Flakgun"; $RemapCmd[$RemapCount] = "useFlakgun"; $RemapCount++; Step #7 // ------------------------------------------ // Projectiles.cs // ------------------------------------------ The parts of this step handle the weapon's basing damage on heat. This handles the heat multiple of damaging of players (people standing around take little damage, people flying take lots): function RadiusExplosion(%explosionSource, %position, %radius, %damage, %impulse, %sourceObject, %damageType) { if(%amount > 0) %data.damageObject(%targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %explosionSource.theClient, %explosionSource); should become: if( %explosionSource.getDataBlock().getName() $= "FlakgunBullet" && %data.getClassName() $= "PlayerData" ) { %amount = %amount * ((%targetObject.getHeat() * 4.0) + 0.1); } if(%amount > 0) %data.damageObject(%targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %explosionSource.theClient, %explosionSource); } Step #8 // ------------------------------------------ // Flakgun.cs // ------------------------------------------ Create a file called Flakgun.cs in your weapon's directory. Add all this into it. //-------------------------------------- // Flakgun //-------------------------------------- //-------------------------------------------------------------------------- // Force-Feedback Effects //-------------------------------------- datablock EffectProfile(FlakgunSwitchEffect) { effectname = "weapons/chaingun_activate"; minDistance = 2.5; }; datablock EffectProfile(FlakgunFireEffect) { effectname = "weapons/chaingun_fire"; minDistance = 4.0; }; datablock EffectProfile(FlakgunSpinUpEffect) { effectname = "weapons/chaingun_spinup"; minDistance = 2.5; }; datablock EffectProfile(FlakgunSpinDownEffect) { effectname = "weapons/chaingun_spindown"; minDistance = 2.5; }; datablock EffectProfile(FlakgunDryFire) { effectname = "weapons/chaingun_dryfire"; minDistance = 2.5; }; //-------------------------------------------------------------------------- // Sounds //-------------------------------------- datablock AudioProfile(FlakgunSwitchSound) { filename = "fx/weapons/chaingun_activate.wav"; description = AudioClosest3d; preload = true; effect = FlakgunSwitchEffect; }; datablock AudioProfile(FlakgunFireSound) { filename = "fx/weapons/chaingun_fire.wav"; description = AudioDefaultLooping3d; preload = true; effect = FlakgunFireEffect; }; datablock AudioProfile(FlakgunProjectile) { filename = "fx/weapons/chaingun_projectile.wav"; description = ProjectileLooping3d; preload = true; }; datablock AudioProfile(FlakgunImpact) { filename = "fx/weapons/chaingun_impact.WAV"; description = AudioClosest3d; preload = true; }; datablock AudioProfile(FlakgunSpinDownSound) { filename = "fx/weapons/chaingun_spindown.wav"; description = AudioClosest3d; preload = true; effect = FlakgunSpinDownEffect; }; datablock AudioProfile(FlakgunSpinUpSound) { filename = "fx/weapons/chaingun_spinup.wav"; description = AudioClosest3d; preload = true; effect = FlakgunSpinUpEffect; }; datablock AudioProfile(FlakgunDryFireSound) { filename = "fx/weapons/chaingun_dryfire.wav"; description = AudioClose3d; preload = true; effect = FlakgunDryFire; }; datablock AudioProfile(ShrikeBlasterProjectileSound) { filename = "fx/vehicles/shrike_blaster_projectile.wav"; description = ProjectileLooping3d; preload = true; }; //-------------------------------------------------------------------------- // Splash //-------------------------------------------------------------------------- datablock ParticleData( FlakgunSplashParticle ) { dragCoefficient = 1; gravityCoefficient = 0.0; inheritedVelFactor = 0.2; constantAcceleration = -1.4; lifetimeMS = 300; 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.05; sizes[1] = 0.2; sizes[2] = 0.2; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0; }; datablock ParticleEmitterData( FlakgunSplashEmitter ) { ejectionPeriodMS = 4; periodVarianceMS = 0; ejectionVelocity = 3; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 50; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; orientParticles = true; lifetimeMS = 100; particles = "FlakgunSplashParticle"; }; datablock SplashData(FlakgunSplash) { numSegments = 10; ejectionFreq = 10; ejectionAngle = 20; ringLifetime = 0.4; lifetimeMS = 400; velocity = 3.0; startRadius = 0.0; acceleration = -3.0; texWrap = 5.0; texture = "special/water2"; emitter[0] = FlakgunSplashEmitter; 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(FlakgunFireParticle) { dragCoefficient = 2.75; gravityCoefficient = 0.1; inheritedVelFactor = 0.0; constantAcceleration = 0.0; lifetimeMS = 550; lifetimeVarianceMS = 0; textureName = "particleTest"; colors[0] = "0.46 0.36 0.26 1.0"; colors[1] = "0.46 0.36 0.26 0.0"; sizes[0] = 0.25; sizes[1] = 0.20; }; datablock ParticleEmitterData(FlakgunFireEmitter) { ejectionPeriodMS = 6; periodVarianceMS = 0; ejectionVelocity = 10; velocityVariance = 1.0; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 12; phiReferenceVel = 0; phiVariance = 360; overrideAdvance = true; particles = "FlakgunFireParticle"; }; //-------------------------------------------------------------------------- // Explosions //-------------------------------------- datablock ParticleData(FlakgunExplosionParticle1) { dragCoefficient = 0.65; gravityCoefficient = 0.3; inheritedVelFactor = 0.0; constantAcceleration = 0.0; lifetimeMS = 500; lifetimeVarianceMS = 150; textureName = "particleTest"; colors[0] = "0.56 0.36 0.26 1.0"; colors[1] = "0.56 0.36 0.26 0.0"; sizes[0] = 0.0625; sizes[1] = 0.2; }; datablock ParticleEmitterData(FlakgunExplosionEmitter) { ejectionPeriodMS = 10; periodVarianceMS = 0; ejectionVelocity = 0.75; velocityVariance = 0.25; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 60; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; particles = "FlakgunExplosionParticle1"; }; datablock ParticleData(FlakgunImpactSmokeParticle) { dragCoefficient = 0.0; gravityCoefficient = -0.2; inheritedVelFactor = 0.0; constantAcceleration = 0.0; lifetimeMS = 1000; lifetimeVarianceMS = 200; useInvAlpha = true; spinRandomMin = -90.0; spinRandomMax = 90.0; textureName = "particleTest"; colors[0] = "0.7 0.7 0.7 0.0"; colors[1] = "0.7 0.7 0.7 0.4"; colors[2] = "0.7 0.7 0.7 0.0"; sizes[0] = 0.5; sizes[1] = 0.5; sizes[2] = 1.0; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0; }; datablock ParticleEmitterData(FlakgunImpactSmoke) { ejectionPeriodMS = 8; periodVarianceMS = 1; ejectionVelocity = 1.0; velocityVariance = 0.5; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 35; overrideAdvances = false; particles = "FlakgunImpactSmokeParticle"; lifetimeMS = 50; }; datablock ParticleData(FlakgunSparks) { dragCoefficient = 1; gravityCoefficient = 0.0; inheritedVelFactor = 0.2; constantAcceleration = 0.0; lifetimeMS = 300; lifetimeVarianceMS = 0; textureName = "special/spark00"; colors[0] = "0.56 0.36 0.26 1.0"; colors[1] = "0.56 0.36 0.26 1.0"; colors[2] = "1.0 0.36 0.26 0.0"; sizes[0] = 0.6; sizes[1] = 0.2; sizes[2] = 0.05; times[0] = 0.0; times[1] = 0.2; times[2] = 1.0; }; datablock ParticleEmitterData(FlakgunSparkEmitter) { ejectionPeriodMS = 4; periodVarianceMS = 0; ejectionVelocity = 4; velocityVariance = 2.0; ejectionOffset = 0.0; thetaMin = 0; thetaMax = 50; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; orientParticles = true; lifetimeMS = 100; particles = "FlakgunSparks"; }; datablock ShockwaveData(ScoutFlakgunHit) { width = 0.5; numSegments = 13; numVertSegments = 1; velocity = 0.5; acceleration = 2.0; lifetimeMS = 900; height = 0.1; verticalCurve = 0.5; mapToTerrain = false; renderBottom = false; orientToNormal = true; texture[0] = "special/shockwave5"; texture[1] = "special/gradient"; texWrap = 3.0; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0; colors[0] = "0.6 0.6 1.0 1.0"; colors[1] = "0.6 0.3 1.0 0.5"; colors[2] = "0.0 0.0 1.0 0.0"; }; datablock ParticleData(ScoutFlakgunExplosionParticle1) { dragCoefficient = 2; gravityCoefficient = 0.0; inheritedVelFactor = 0.2; constantAcceleration = -0.0; lifetimeMS = 600; lifetimeVarianceMS = 000; textureName = "special/crescent4"; colors[0] = "0.6 0.6 1.0 1.0"; colors[1] = "0.6 0.3 1.0 1.0"; colors[2] = "0.0 0.0 1.0 0.0"; sizes[0] = 0.25; sizes[1] = 0.5; sizes[2] = 1.0; times[0] = 0.0; times[1] = 0.5; times[2] = 1.0; }; datablock ParticleEmitterData(ScoutFlakgunExplosionEmitter) { ejectionPeriodMS = 10; periodVarianceMS = 0; ejectionVelocity = 2; velocityVariance = 1.5; ejectionOffset = 0.0; thetaMin = 80; thetaMax = 90; phiReferenceVel = 0; phiVariance = 360; overrideAdvances = false; orientParticles = true; lifetimeMS = 200; particles = "ScoutFlakgunExplosionParticle1"; }; datablock ExplosionData(ScoutFlakgunExplosion) { soundProfile = blasterExpSound; shockwave = ScoutFlakgunHit; emitter[0] = ScoutFlakgunExplosionEmitter; }; //-------------------------------------------------------------------------- // Particle effects //-------------------------------------- datablock DebrisData( ShellDebris ) { shapeName = "weapon_Chaingun_ammocasing.dts"; lifetime = 3.0; minSpinSpeed = 300.0; maxSpinSpeed = 400.0; elasticity = 0.5; friction = 0.2; numBounces = 3; fade = true; staticOnMaxBounce = true; snapOnMaxBounce = true; }; //-------------------------------------------------------------------------- // Projectile //-------------------------------------- datablock DecalData(FlakgunDecal1) { sizeX = 0.05; sizeY = 0.05; textureName = "special/bullethole1"; }; datablock DecalData(FlakgunDecal2) : FlakgunDecal1 { textureName = "special/bullethole2"; }; datablock DecalData(FlakgunDecal3) : FlakgunDecal1 { textureName = "special/bullethole3"; }; datablock DecalData(FlakgunDecal4) : FlakgunDecal1 { textureName = "special/bullethole4"; }; datablock DecalData(FlakgunDecal5) : FlakgunDecal1 { textureName = "special/bullethole5"; }; datablock DecalData(FlakgunDecal6) : FlakgunDecal1 { textureName = "special/bullethole6"; }; datablock ParticleData(FlakSmokeParticle) { dragCoeffiecient = 0.0; gravityCoefficient = -0.2; // rises slowly inheritedVelFactor = 0.00; lifetimeMS = 700; // lasts 2 second lifetimeVarianceMS = 150; // ...more or less textureName = "particleTest"; useInvAlpha = true; spinRandomMin = -30.0; spinRandomMax = 30.0; colors[0] = "0.9 0.9 0.9 1.0"; colors[1] = "0.6 0.6 0.6 1.0"; colors[2] = "0.4 0.4 0.4 0.0"; sizes[0] = 10; sizes[1] = 23.5; sizes[2] = 45.0; times[0] = 0.0; times[1] = 0.2; times[2] = 1.0; }; datablock ParticleEmitterData(FlakSmokeEmitter) { ejectionPeriodMS = 15; periodVarianceMS = 5; ejectionVelocity = 1.25; velocityVariance = 0.50; thetaMin = 0.0; thetaMax = 90.0; particles = "FlakSmokeParticle"; }; datablock ExplosionData(FlakgunExplosion) { soundProfile = GrenadeExplosionSound; faceViewer = true; explosionScale = "0.8 0.8 0.8"; debris = GrenadeDebris; debrisThetaMin = 10; debrisThetaMax = 50; debrisNum = 8; debrisVelocity = 26.0; debrisVelocityVariance = 7.0; emitter[0] = GrenadeDustEmitter; emitter[1] = FlakSmokeEmitter; emitter[2] = GrenadeSparksEmitter; shakeCamera = true; camShakeFreq = "10.0 6.0 9.0"; camShakeAmp = "20.0 20.0 20.0"; camShakeDuration = 0.25; camShakeRadius = 10.0; }; datablock TracerProjectileData(FlakgunBullet) { doDynamicClientHits = true; directDamageType = $DamageType::Chaingun; splash = FlakgunSplash; kickBackStrength = 0.0; sound = FlakgunProjectile; dryVelocity = 425.0; wetVelocity = 100.0; velInheritFactor = 1.0; fizzleTimeMS = 3000; lifetimeMS = 100; explodeOnDeath = true; explosion = FlakgunExplosion; radiusDamageType = $DamageType::Chaingun; directDamage = 0.0; hasDamageRadius = true; indirectDamage = 0.45; damageRadius = 45; reflectOnWaterImpactAngle = 0.0; explodeOnWaterImpact = false; deflectionOnWaterImpact = 0.0; fizzleUnderwaterMS = 3000; tracerLength = 15.0; tracerAlpha = false; tracerMinPixels = 6; tracerColor = 211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75"; tracerTex[0] = "special/tracer00"; tracerTex[1] = "special/tracercross"; tracerWidth = 0.30; crossSize = 0.007; crossViewAng = 0.990; renderCross = true; decalData[0] = FlakgunDecal1; decalData[1] = FlakgunDecal2; decalData[2] = FlakgunDecal3; decalData[3] = FlakgunDecal4; decalData[4] = FlakgunDecal5; decalData[5] = FlakgunDecal6; }; //-------------------------------------------------------------------------- // Ammo //-------------------------------------- datablock ItemData(FlakgunAmmo) { className = Ammo; catagory = "Ammo"; shapeFile = "ammo_chaingun.dts"; mass = 1; elasticity = 0.2; friction = 0.6; pickupRadius = 2; pickUpName = "some flakgun ammo"; computeCRC = true; }; //-------------------------------------------------------------------------- // Weapon //-------------------------------------- datablock ShapeBaseImageData(FlakgunImage) { className = WeaponImage; shapeFile = "weapon_chaingun.dts"; item = Flakgun; showname = "Flakgun"; ammo = flakgunAmmo; projectile = flakgunBullet; projectileType = TracerProjectile; emap = true; casing = ShellDebris; shellExitDir = "1.0 0.3 1.0"; shellExitOffset = "0.15 -0.56 -0.1"; shellExitVariance = 15.0; shellVelocity = 3.0; projectileSpread = 70.0 / 1000.0; //-------------------------------------- stateName[0] = "Activate"; stateSequence[0] = "Activate"; stateSound[0] = FlakgunSwitchSound; stateAllowImageChange[0] = false; // stateTimeoutValue[0] = 0.5; stateTransitionOnTimeout[0] = "Ready"; stateTransitionOnNoAmmo[0] = "NoAmmo"; //-------------------------------------- stateName[1] = "Ready"; stateSpinThread[1] = Stop; // stateTransitionOnTriggerDown[1] = "Spinup"; stateTransitionOnNoAmmo[1] = "NoAmmo"; //-------------------------------------- stateName[2] = "NoAmmo"; stateTransitionOnAmmo[2] = "Ready"; stateSpinThread[2] = Stop; stateTransitionOnTriggerDown[2] = "DryFire"; //-------------------------------------- stateName[3] = "Spinup"; stateSpinThread[3] = SpinUp; stateSound[3] = FlakgunSpinupSound; // stateTimeoutValue[3] = 0.5; stateWaitForTimeout[3] = false; stateTransitionOnTimeout[3] = "Fire"; stateTransitionOnTriggerUp[3] = "Spindown"; //-------------------------------------- stateName[4] = "Fire"; stateSequence[4] = "Fire"; stateSequenceRandomFlash[4] = true; stateSpinThread[4] = FullSpeed; stateSound[4] = FlakgunFireSound; //stateRecoil[4] = LightRecoil; stateAllowImageChange[4] = false; stateScript[4] = "onFire"; stateFire[4] = true; stateEjectShell[4] = true; // stateTimeoutValue[4] = 0.375; stateTransitionOnTimeout[4] = "Fire"; stateTransitionOnTriggerUp[4] = "Spindown"; stateTransitionOnNoAmmo[4] = "EmptySpindown"; //-------------------------------------- stateName[5] = "Spindown"; stateSound[5] = FlakgunSpinDownSound; stateSpinThread[5] = SpinDown; // stateTimeoutValue[5] = 1.0; stateWaitForTimeout[5] = true; stateTransitionOnTimeout[5] = "Ready"; stateTransitionOnTriggerDown[5] = "Spinup"; //-------------------------------------- stateName[6] = "EmptySpindown"; stateSound[6] = FlakgunSpinDownSound; stateSpinThread[6] = SpinDown; // stateTimeoutValue[6] = 0.5; stateTransitionOnTimeout[6] = "NoAmmo"; //-------------------------------------- stateName[7] = "DryFire"; stateSound[7] = FlakgunDryFireSound; stateTimeoutValue[7] = 0.5; stateTransitionOnTimeout[7] = "NoAmmo"; }; datablock ItemData(Flakgun) { className = Weapon; catagory = "Spawn Items"; shapeFile = "weapon_chaingun.dts"; image = FlakgunImage; mass = 1; elasticity = 0.2; friction = 0.6; pickupRadius = 2; pickUpName = "a flakgun"; computeCRC = true; emap = true; };