------------------------------------------------------------------------------------------------------------
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
// ------------------------------------------
1a)
$InvWeapon[6] = "Warp Gun"; //I prefer to put it right after laser rifle and bump the others down.
$NameToInv["Warp Gun"] = "WarpGun";
1b) Add this to buyFavorites and buyDeployableFavorites
case WarpGun:
%client.player.setInventory( WarpGunAmmo, 400 );
Step #2
// ------------------------------------------
// weapons.cs
// ------------------------------------------
$WeaponsHudData[11, bitmapName] = "gui/hud_targetlaser";
$WeaponsHudData[11, itemDataName] = "WarpGun";
$WeaponsHudData[11, ammoDataName] = "WarpGunAmmo";
$WeaponsHudCount = 12;
exec("scripts/weapons/WarpGun.cs");
Step #3
// ------------------------------------------
// inventory.cs
// ------------------------------------------
3a) Add this with all the other 'case' in the function
function ShapeBase::hasAmmo( %this, %weapon )
{
switch$ ( %weapon )
{
case WarpGun:
return( %this.getInventory( WarpGunAmmo ) > 0 );
}
}
3b) Add this with all the other cleared items
function ShapeBase::clearInventory(%this)
{
%this.setInventory(WarpGun, 0);
%this.setInventory(WarpGunAmmo, 0);
}
3c)
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
// ------------------------------------------
// hud.cs
// ------------------------------------------
Ignore this step if you use any server side reticle workarounds.
function clientCmdSetWeaponsHudActive(%slot)
{
weaponsHud.setActiveWeapon(%slot);
switch$($WeaponNames[%slot])
{
case "WarpGun":
reticleHud.setBitmap("gui/hud_ret_targlaser");
reticleFrameHud.setVisible(false);
}
}
Step #6
// ------------------------------------------
// Ammopack.cs
// ------------------------------------------
Add ammo to ammopack, to increase with it.
$ammoItem[7] = WarpGunAmmo;
$numAmmoItems = 8;
datablock ItemData(AmmoPack)
{
max[WarpGunAmmo] = 5;
}
Step #7
// ------------------------------------------
// OptionsDlg.cs
// ------------------------------------------
$RemapName[$RemapCount] = "Warp Gun";
$RemapCmd[$RemapCount] = "useWarpGun";
$RemapCount++;
Step #8
// ------------------------------------------
// ControlDefaults.cs
// ------------------------------------------
function useWarpGun( %val )
{
if ( %val )
use( WarpGun );
}
Step #9
// ------------------------------------------
// 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.');
}