------------------------------------------------------------------------------------------------------------ Warp Gun Tutorial ------------------------------------------------------------------------------------------------------------ This tutorial shows you how to make a teleportation gun, that I call a Warp Gun. Only lights can use it, works just like a laser rifle, except it warps you right above whatever it hits. For balancing purposes, it uses both energy and ammo, and can't be used around the enemy flag. Step #1 // ------------------------------------------ // inventoryHud.cs // ------------------------------------------ $InvWeapon[6] = "Warp Gun"; //I prefer to put it right after laser rifle and bump the others down. $NameToInv["Warp Gun"] = "WarpGun"; Step #2 // ------------------------------------------ // weapons.cs // ------------------------------------------ $WeaponsHudData[11, bitmapName] = "gui/hud_targetlaser"; $WeaponsHudData[11, itemDataName] = "WarpGun"; $WeaponsHudData[11, ammoDataName] = "WarpGunAmmo"; $WeaponsHudData[11, reticle] = "gui/hud_ret_targlaser"; $WeaponsHudData[11, visible] = "false"; $WeaponsHudCount = 12; exec("scripts/weapons/WarpGun.cs"); {DrumStix}:Remember to set numbers correctly Step #3 // ------------------------------------------ // inventory.cs // ------------------------------------------ 3a) Add this with all the other cleared items function ShapeBase::clearInventory(%this) { %this.setInventory(WarpGun, 0); %this.setInventory(WarpGunAmmo, 0); } 3b) function serverCmdGiveAll(%client) { if($TestCheats) { %player.setInventory(WarpGun, 1); %player.setInventory(WarpGunAmmo, 999); } } Step #4 // ------------------------------------------ // player.cs // ------------------------------------------ 4a) Add to player armor datablocks. Probably only want to give it to lights. max [WarpGun] = 1; max [WarpGunAmmo] = 5; 4b) Add these to function armor::applyConcussion if( %weaps[11] = %player.getInventory("WarpGun") > 0 ) %numWeapons++; and case 12: %player.use("WarpGun"); Step #5 // ------------------------------------------ // Ammopack.cs // ------------------------------------------ Add ammo to ammopack, to increase with it. $ammoItem[7] = WarpGunAmmo; $numAmmoItems = 8; datablock ItemData(AmmoPack) { max[WarpGunAmmo] = 5; } Step #6 // ------------------------------------------ // WarpGun.cs // ------------------------------------------ Make a new file called WarpGun.cs in weapons directory. Add all this into it. //-------------------------------------------------------------------------- // Warp Gun // // //-------------------------------------------------------------------------- datablock EffectProfile(WarpGunSwitchEffect) { effectname = "weapons/sniper_activate"; minDistance = 2.5; }; datablock EffectProfile(WarpGunFireEffect) { effectname = "weapons/sniper_fire"; minDistance = 4.0; }; datablock EffectProfile(WarpGunFireWetEffect) { effectname = "weapons/sniper_underwater"; minDistance = 4.0; }; datablock AudioProfile(WarpGunSwitchSound) { filename = "fx/weapons/sniper_activate.wav"; description = AudioClosest3d; preload = true; effect = WarpGunSwitchEffect; }; datablock AudioProfile(WarpGunFireSound) { filename = "fx/weapons/sniper_fire.wav"; description = AudioClose3d; preload = true; effect = WarpGunFireEffect; }; datablock AudioProfile(WarpGunFireWetSound) { filename = "fx/weapons/sniper_underwater.wav"; description = AudioClose3d; preload = true; effect = WarpGunFireWetEffect; }; datablock AudioProfile(WarpGunDryFireSound) { filename = "fx/weapons/chaingun_dryfire.wav"; description = AudioClose3d; preload = true; }; datablock AudioProfile(WarpGunProjectileSound) { filename = "fx/weapons/sniper_miss.wav"; description = AudioClose3d; preload = true; }; datablock ItemData(WarpGunAmmo) { className = Ammo; catagory = "Ammo"; shapeFile = "ammo_chaingun.dts"; mass = 1; elasticity = 0.2; friction = 0.6; pickupRadius = 2; pickUpName = "some warp gun ammo"; computeCRC = true; }; //-------------------------------------- // Rifle and item... //-------------------------------------- datablock ItemData(WarpGun) { className = Weapon; catagory = "Spawn Items"; shapeFile = "weapon_sniper.dts"; image = WarpGunImage; mass = 1; elasticity = 0.2; friction = 0.6; pickupRadius = 2; pickUpName = "a warp gun"; computeCRC = true; }; datablock ShapeBaseImageData(WarpGunImage) { className = WeaponImage; shapeFile = "weapon_sniper.dts"; item = WarpGun; ammo = WarpGunAmmo; showname = "Warp Gun"; armThread = looksn; usesEnergy = true; minEnergy = 59; stateName[0] = "Activate"; stateTransitionOnTimeout[0] = "ActivateReady"; stateSound[0] = WarpGunSwitchSound; stateTimeoutValue[0] = 0.5; stateSequence[0] = "Activate"; 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.5; stateFire[3] = true; stateAllowImageChange[3] = false; stateSequence[3] = "Fire"; stateScript[3] = "onFire"; stateName[4] = "Reload"; stateTransitionOnTimeout[4] = "Ready"; stateTimeoutValue[4] = 3.0; stateAllowImageChange[4] = false; stateName[5] = "CheckWet"; stateTransitionOnWet[5] = "DryFire"; stateTransitionOnNotWet[5] = "Fire"; stateName[6] = "NoAmmo"; stateTransitionOnAmmo[6] = "Reload"; stateTransitionOnTriggerDown[6] = "DryFire"; stateSequence[6] = "NoAmmo"; stateName[7] = "DryFire"; stateSound[7] = WarpGunDryFireSound; stateTimeoutValue[7] = 0.5; stateTransitionOnTimeout[7] = "Ready"; }; function WarpGunImage::onFire(%data,%obj,%slot) { %range = 600; //Max range someone can warp to. %rangeFromFlag = 150; //Meters from enemy Flag must be to work. Prevents Flag Capping with WarpGun %radius = 0.5; %rot = getWords(%obj.getTransform(), 3, 6); %muzzlePos = %obj.getMuzzlePoint(%slot); %muzzleVec = %obj.getMuzzleVector(%slot); %endPos = VectorAdd(%muzzlePos, VectorScale(%muzzleVec, %range)); %damageMasks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StationObjectType | $TypeMasks::GeneratorObjectType | $TypeMasks::SensorObjectType | $TypeMasks::TurretObjectType | $TypeMasks::InteriorObjectType; %hit = ContainerRayCast(%muzzlePos, %endPos, %damageMasks | $TypeMasks::TerrainObjectType, %obj); %x2 = getWord(%hit, 1); %y2 = getWord(%hit, 2); %z2 = getWord(%hit, 3); if ((%hit) && (%z2 > 15)) { %count = 0; %endpos = getWords(%hit.getWorldBoxCenter(), 0, 2); while (%count < 5) { %z2 += 2; %check1 = %x2 SPC %y2 SPC %z2; InitContainerRadiusSearch(%check1, %radius, %damageMasks); %checkok = 1; %targetObject = containerSearchNext(); if (%targetObject) %count++; else { %checkok = 0; %count = 5; } } if (%checkok == 0) { if (%obj.team == 1) %team1 = 2; else %team1 = 1; %enemyFlag = $TeamFlag[%team1]; if (isObject(%enemyFlag)) { %dist = VectorDist(posfromTransform(%enemyFlag.getTransform()), %check1); %dist2 = VectorDist(posfromTransform(%enemyFlag.getTransform()), %obj.getMuzzlePoint(%slot)); if ((%dist < %rangeFromFlag) || (%dist2 < %rangeFromFlag) || (%enemyFlag.carrier == %obj)) { %checkok = 1; %checkok2 = 1; messageClient(%obj.client, 'msgBlocked', '\c1Interference from Flag.'); } } } if (%checkok == 0) { if (%obj.getInventory( %data.ammo ) > 0) { %obj.setEnergyLevel(0); %newtrans = %check1 SPC %rot; %obj.setWhiteout(0.3); %obj.setVelocity("0 0 0"); %obj.setTransform(%newtrans); %obj.decInventory(%data.ammo,1); %obj.playAudio(0, StationInventoryActivateSound); } } else if(%checkok2 != 1) messageClient(%obj.client, 'msgBlocked', '\c1The Target is Blocked.'); } else messageClient(%obj.client, 'msgNothing', '\c1Nothing to lock onto.'); }