Weapon Cycling in Torque
by Julian Ridley · 06/23/2004 (7:45 am) · 41 comments
Ok, for some reason, this isnt in torque to begin with, and there are no resources on it. After some struggling I figured it out, using some tweaked code from the forums. To start:
open Default.Binds.cs in client/scripts. Add this after the bind for fire:
next:
open optionsDLG.cs in client/scripts. Put this where all the others like it are:
The rest of this is done in inventory.cs in server/scripts. Open it up and at the top put:
open Default.Binds.cs in client/scripts. Add this after the bind for fire:
function prevWeapon( %val )
{
if ( %val )
commandToServer( 'cycleWeapon', "prev" );
}
function nextWeapon( %val )
{
if ( %val )
commandToServer( 'cycleWeapon', "next" );
}
moveMap.bind(keyboard, "ctrl q", prevWeapon);
moveMap.bind(keyboard, q, nextWeapon);The above simply sets up the default binds and tells them what to do. q and ctrl q can be whatever you want.next:
open optionsDLG.cs in client/scripts. Put this where all the others like it are:
$RemapName[$RemapCount] = "Previous Weapon"; $RemapCmd[$RemapCount] = "prevWeapon"; $RemapCount++; $RemapName[$RemapCount] = "Next Weapon"; $RemapCmd[$RemapCount] = "nextWeapon"; $RemapCount++;That allows the user to bind the weapon cycling to whatever they want.
The rest of this is done in inventory.cs in server/scripts. Open it up and at the top put:
$weaponInSlot[0] = "Crossbow"; $weaponInSlot[1] = "UberCrossbow"; $weaponInSlot[2] = "RocketLauncher"; $weaponInSlot[3] = "FragMine"; $maxWeaponSlot = 3;However, fill those in with your weapon names instead, and maxWeaponSlot should equal the highest number in your list, NOT the actual number of weapons. Next add this at the bottom of the file:
function ShapeBase::hasInventory(%this, %data)
{
return (%this.inv[%data] > 0);
}
function serverCmdCycleWeapon( %client, %data )
{
%client.getControlObject().cycleWeapon( %data );
}
function ShapeBase::cycleWeapon( %this, %data )
{
%slot = -1;
if ( %this.getMountedImage($WeaponSlot) != 0 ) {
%curWeapon = %this.getMountedImage($WeaponSlot).item.getName();
if(%curWeapon $= "Crossbow")
%slot = 0;
else if(%curWeapon $= "UberCrossbow")
%slot = 1;
else if(%curWeapon $= "RocketLauncher")
%slot = 2;
else if(%curWeapon $= "FragMine")
%slot = 3;
}
if ( %data $= "prev" ) {
// Previous weapon...
if ( %slot == 0 || %slot == -1 ) {
%i = $maxWeaponSlot;
%slot = 0;
}
else
%i = %slot - 1;
}
else {
// Next weapon...
if ( %slot == $maxWeaponSlot || %slot == -1 ) {
%i = 0;
%slot = $maxWeaponSlot;
}
else
%i = %slot + 1;
}
%newSlot = -1;
while ( %i != %slot ) {
if ( $weaponInSlot[%i] !$= ""
&& %this.hasInventory( $weaponInSlot[%i] )) {
// player has this weapon and it has ammo or doesn't need ammo
%newSlot = %i;
break;
}
if ( %data $= "prev" ) {
if ( %i == 0 )
%i = $maxWeaponSlot;
else
%i--;
}
else {
if ( %i == $maxWeaponSlot )
%i = 0;
else
%i++;
}
}
if ( %newSlot != -1 )
%this.use( $weaponInSlot[%newSlot] );
}Replace the series of if statements(with the weapons), with your weapons and the slots they occupy. The rest is pretty straight forward.
#22
08/30/2006 (11:27 am)
nvm, solved it, turns out to be a misspeled weapon in the array:S such simple mistakes, lol
#23
I have a question though. how can I make it cycle to "no weapon" instead of always having an equiped weapon.
I want to be able to cycle through all weapons and have one of the slots be without a weapon equiped.
03/27/2007 (8:32 pm)
I know this is an old resource but it still does the job in 1.5I have a question though. how can I make it cycle to "no weapon" instead of always having an equiped weapon.
I want to be able to cycle through all weapons and have one of the slots be without a weapon equiped.
#24
05/13/2007 (8:48 pm)
Why not just mount another weapon that isn't able to fire? Essentially the same thing. Otherwise you could probably dismount the weapon images if you wanted no weapons up, but I imagine the other is easier.
#25
I have implemented this resource, but I'm having a problem. I can cycle my 2 weapons ok, 1 being the crossbow, 2 being the m16 from the soldier pack nothing special here. But no matter which weapon is selected the crossbow shows on top as always mounted. I can see the m16 appear and disappear when switching. But when I switch back to the crossbow it plays the arming animation over the top of the crossbow image that is always there like there's 2 crossbows at once. I don't know what the hell to try next. Getting ready to find replace all m16 in the script with crossbow and save over the crossbow script. Any suggestions? Or anyone else experience this. I'm using 1.5.
Thanks in Advance,
Trey
07/03/2007 (6:14 pm)
Could use some help here...I have implemented this resource, but I'm having a problem. I can cycle my 2 weapons ok, 1 being the crossbow, 2 being the m16 from the soldier pack nothing special here. But no matter which weapon is selected the crossbow shows on top as always mounted. I can see the m16 appear and disappear when switching. But when I switch back to the crossbow it plays the arming animation over the top of the crossbow image that is always there like there's 2 crossbows at once. I don't know what the hell to try next. Getting ready to find replace all m16 in the script with crossbow and save over the crossbow script. Any suggestions? Or anyone else experience this. I'm using 1.5.
Thanks in Advance,
Trey
#26
In my game.cs I had this:
%player.setInventory(M16,1);
%player.setInventory(M16Ammo,30);
%player.setInventory(M16AmmoClip,50);
%player.mountImage(M16Image,0);
%player.setInventory(Crossbow,1);
%player.setInventory(CrossbowAmmo,75);
%player.mountImage(CrossbowImage,1);
My thought was the mountImage needed to be the same as in this part:
$weaponInSlot[0] = "M16";
$weaponInSlot[1] = "Crossbow";
And the described problems above where occurring. So I changed this:
%player.mountImage(CrossbowImage,1);
To this:
%player.mountImage(CrossbowImage,0);
From this point no more crossbow sitting on top all the time. Yes both m16 and crossbow are both on 0 in the game.cs.
Ok next thing. With the above change the crossbow was always set as the default weapon don't know why maybe someone can enlighten me (actually I'm thinking this must be because its the last mount image loaded so it becomes the default?) but the fix for this, to choose the default weapon you spawn with, I just totally commented out like this.
//%player.mountImage(CrossbowImage,0);
Now the m16 is the default weapon or vise versa.
take it for what it is, just in case any other noobs get stuck here's another lead you can sniff down.
07/03/2007 (7:09 pm)
Ok, sorry to bump, I got it working and thought I'd share on some assumptions that got me in trouble. Here it is.In my game.cs I had this:
%player.setInventory(M16,1);
%player.setInventory(M16Ammo,30);
%player.setInventory(M16AmmoClip,50);
%player.mountImage(M16Image,0);
%player.setInventory(Crossbow,1);
%player.setInventory(CrossbowAmmo,75);
%player.mountImage(CrossbowImage,1);
My thought was the mountImage needed to be the same as in this part:
$weaponInSlot[0] = "M16";
$weaponInSlot[1] = "Crossbow";
And the described problems above where occurring. So I changed this:
%player.mountImage(CrossbowImage,1);
To this:
%player.mountImage(CrossbowImage,0);
From this point no more crossbow sitting on top all the time. Yes both m16 and crossbow are both on 0 in the game.cs.
Ok next thing. With the above change the crossbow was always set as the default weapon don't know why maybe someone can enlighten me (actually I'm thinking this must be because its the last mount image loaded so it becomes the default?) but the fix for this, to choose the default weapon you spawn with, I just totally commented out like this.
//%player.mountImage(CrossbowImage,0);
Now the m16 is the default weapon or vise versa.
take it for what it is, just in case any other noobs get stuck here's another lead you can sniff down.
#27
08/29/2007 (12:57 pm)
Great tutorial. Worked great.
#28
Loading compiled script my.game/server/scripts/laser.cs.
Error: cannot change namespace parent linkage for Laser from Projectile to Weapon.
For some reason its thinking the laser is a projectile rather then a weapon.
datablock ItemData(Laser)
{
category = "Weapon";
className = "Weapon";
shapeFile = "~/data/shapes/weapons/PX213/assaultrifle.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
emap = true;
pickUpName = "a Laser Rifle";
image = LaserImage;
};
datablock ShapeBaseImageData(LaserImage)
{
shapeFile = "~/data/shapes/weapons/PX213/assaultrifle.dts";
emap = true;
mountPoint = 0;
eyeOffset = "0.1 0.4 -0.6";
maxRange = 500;
correctMuzzleVector = false;
className = "WeaponImage";
item = Laser;
ammo = LaserAmmo;
projectile = laserProjectile;
projectileType = Laser;
... continues on to fire sequence....
any ideas why this error might be conflicting with the weapon cycling code? or is it a error that can be corrected from the laser code?
12/11/2007 (6:02 pm)
Hello, i successfully have got this weapon working and added the fixes above, however, i am still recieving this error. Would this be causing a conflict. i also am not able to cycle through example 0,1,2,3,0,1,2,3, as i should, it seems to stop at the laser 0,1,2, then it stops on the last weapon, the laser. btw if i start the cycling onthe laser it does show up, and works fine as long as i dont cycle away then it wont come backLoading compiled script my.game/server/scripts/laser.cs.
Error: cannot change namespace parent linkage for Laser from Projectile to Weapon.
For some reason its thinking the laser is a projectile rather then a weapon.
datablock ItemData(Laser)
{
category = "Weapon";
className = "Weapon";
shapeFile = "~/data/shapes/weapons/PX213/assaultrifle.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
emap = true;
pickUpName = "a Laser Rifle";
image = LaserImage;
};
datablock ShapeBaseImageData(LaserImage)
{
shapeFile = "~/data/shapes/weapons/PX213/assaultrifle.dts";
emap = true;
mountPoint = 0;
eyeOffset = "0.1 0.4 -0.6";
maxRange = 500;
correctMuzzleVector = false;
className = "WeaponImage";
item = Laser;
ammo = LaserAmmo;
projectile = laserProjectile;
projectileType = Laser;
... continues on to fire sequence....
any ideas why this error might be conflicting with the weapon cycling code? or is it a error that can be corrected from the laser code?
#29
01/06/2008 (7:09 am)
Cool stuff, I'll try this. :-)
#30
Error: cannot change namespace parent linkage for Laser from Projectile to Weapon.
The laser works fine btw, as does the inventory and doing damage. So its curious why using it a laser isnt being recognized.
01/06/2008 (10:16 am)
Any ideas regarding why my laser code is conflicting with the weapon cycling code? Is there a code that i can use that tells the computer that the laser class is equal to the weapon code. i do get the error Error: cannot change namespace parent linkage for Laser from Projectile to Weapon.
The laser works fine btw, as does the inventory and doing damage. So its curious why using it a laser isnt being recognized.
#31
Great resource! Very easy to integrate, thanks a ton!
@Tim: Thanks for the mouse scroll code, too !)
I had one problem: the scrolling was much to sensitive, i.e. that weapons changed so fast it was hard to pick the one I wanted--so I made a few modifications for anyone who has the same problem (and hasn't already figured it out !)
At the top of "Client/config.cs" add:
//////////////////
$SCROLL_ACTIVE = 1
$PAUSETIME_MS = 50
//////////////////
Just above the "handleMouseWheel" function in the same file add:
///////////////////////
function activateScrollWheel()
{
$SCROLL_ACTIVE = 1;
}
///////////////////////
Then change the "handleMouseWheel" function to this:
/////////////////////////
function handleMouseWheel(%val)
{
if($SCROLL_ACTIVE)
{
if ( %val < 0 )
commandToServer('cycleWeapon', "next");
else if ( %val > 0 )
commandToServer('cycleWeapon', "prev");
schedule($PAUSETIME_MS,0,"activateScrollWheel");
}
}
//////////////////////////
You can adjust the time interval between weapon changing by adjusting the "$PAUSETIME_MS" variable.
Hope that helps!
01/11/2008 (12:05 pm)
Hey guys :)Great resource! Very easy to integrate, thanks a ton!
@Tim: Thanks for the mouse scroll code, too !)
I had one problem: the scrolling was much to sensitive, i.e. that weapons changed so fast it was hard to pick the one I wanted--so I made a few modifications for anyone who has the same problem (and hasn't already figured it out !)
At the top of "Client/config.cs" add:
//////////////////
$SCROLL_ACTIVE = 1
$PAUSETIME_MS = 50
//////////////////
Just above the "handleMouseWheel" function in the same file add:
///////////////////////
function activateScrollWheel()
{
$SCROLL_ACTIVE = 1;
}
///////////////////////
Then change the "handleMouseWheel" function to this:
/////////////////////////
function handleMouseWheel(%val)
{
if($SCROLL_ACTIVE)
{
if ( %val < 0 )
commandToServer('cycleWeapon', "next");
else if ( %val > 0 )
commandToServer('cycleWeapon', "prev");
schedule($PAUSETIME_MS,0,"activateScrollWheel");
}
}
//////////////////////////
You can adjust the time interval between weapon changing by adjusting the "$PAUSETIME_MS" variable.
Hope that helps!
#32
Try changing
projectileType = Laser;
to
projectileType = LaserType;
or
projectileType = Projectile;
The error you are getting is probably from your projectile type having the same name as your Laser datablock
datablock ItemData(Laser)
04/10/2008 (10:42 pm)
EdwardTry changing
projectileType = Laser;
to
projectileType = LaserType;
or
projectileType = Projectile;
The error you are getting is probably from your projectile type having the same name as your Laser datablock
datablock ItemData(Laser)
#33
in inventory.cs
and
It helps if you are lazy(me) or have a lot of weapons.
04/20/2008 (4:36 pm)
Great resource, but instead of those bulky ifs couldn't you just do this:in inventory.cs
$weaponInSlot[0] = "Crossbow";//which weapon is __ slot $weaponInSlot[1] = "Crossbow2"; $weaponInSlot[2] = "Crossbow3"; $weaponInSlot[3] = "Crossbow4"; $maxWeaponSlot = 3; $weaponForSlot["Crossbow"] = 0;//which slot is __ weapon $weaponForSlot["Crossbow2"] = 1; $weaponForSlot["Crossbow3"] = 2; $weaponForSlot["Crossbow4"] = 3;
and
function ShapeBase::cycleWeapon( %this, %data )
{
%slot = -1;
if ( %this.getMountedImage($WeaponSlot) != 0 ) {
%curWeapon = %this.getMountedImage($WeaponSlot).item.getName();
%slot = $WeaponForSlot[%curWeapon];// this one line instead of those ifs
}It helps if you are lazy(me) or have a lot of weapons.
#35
I've been trying to add this mod to the T3D project for TGEA 1.7.1. I've actully used this resource b4 & me and the rest of my team had no problems just droping it in to the TGEA 1.7 Stronghold kit & works just fine. I thought it would be just as easy this time, but its not. I have no clue whats wrong, no errors show up, the console says "Mapping string: cycleWeapon to index: 3" when i press the Q or CTRL Q keys so I think its working but it dosent switch the SwarmGun with the Crossbow n vis versa at all as if the cycleweapon function dosent exist. it just stays at the swarmgun... any ideas?
NM silly mistake on my part. turns out swarmgun is not what the engine calls it, it still calls it rocketLauncher even tho the .cs file with its info is called swarmgun. so when i called it swarmgun torque didnt know what that was. lol
its working fine now.
& I still love this resource :)
12/19/2008 (11:11 am)
Hi every1!I've been trying to add this mod to the T3D project for TGEA 1.7.1. I've actully used this resource b4 & me and the rest of my team had no problems just droping it in to the TGEA 1.7 Stronghold kit & works just fine. I thought it would be just as easy this time, but its not. I have no clue whats wrong, no errors show up, the console says "Mapping string: cycleWeapon to index: 3" when i press the Q or CTRL Q keys so I think its working but it dosent switch the SwarmGun with the Crossbow n vis versa at all as if the cycleweapon function dosent exist. it just stays at the swarmgun... any ideas?
NM silly mistake on my part. turns out swarmgun is not what the engine calls it, it still calls it rocketLauncher even tho the .cs file with its info is called swarmgun. so when i called it swarmgun torque didnt know what that was. lol
its working fine now.
& I still love this resource :)
#36
I implemented this, and have two weapons ingame now, the standard crossbow, and my very own banana grenade.
Now, I can pick up the banana-nade, and one item that is ammo (Same DTS), and can switch inbetween them.
Until I fire the banana grenade.
Then it get's "stuck" on the banana, won't switch back to the crossbow, I can't fire again and can't pick up more ammo.
I've been trying to figure out what's wrong but can't.
I'm using a modified version of crossbow.cs for this, as it's just a test.
Changed everything mentioning Crossbow over to Banana, It's pointed at the right DTS etc.
It seems to be that there's something that gets "stuck" at the reloading, as it won't fire again and I can't pick up more ammo (Which is strange to begin with as I've been having trouble picking up more then one, when it's got a maxInv[] of 5..)
Ideas? Anyone?
--Edit--
I can now pick up extra ammo, but still can't switch weapons around after firing the banana-grenade
03/09/2009 (3:26 pm)
I'm having a problem I simply can't figure out.. Maybe someone else can shed some light on this?I implemented this, and have two weapons ingame now, the standard crossbow, and my very own banana grenade.
Now, I can pick up the banana-nade, and one item that is ammo (Same DTS), and can switch inbetween them.
Until I fire the banana grenade.
Then it get's "stuck" on the banana, won't switch back to the crossbow, I can't fire again and can't pick up more ammo.
I've been trying to figure out what's wrong but can't.
I'm using a modified version of crossbow.cs for this, as it's just a test.
Changed everything mentioning Crossbow over to Banana, It's pointed at the right DTS etc.
It seems to be that there's something that gets "stuck" at the reloading, as it won't fire again and I can't pick up more ammo (Which is strange to begin with as I've been having trouble picking up more then one, when it's got a maxInv[] of 5..)
Ideas? Anyone?
--Edit--
I can now pick up extra ammo, but still can't switch weapons around after firing the banana-grenade
#37
Go ahead and add his suggested piece of code to replace all those if/else if (or possible switch/case/case/..) lines:
Add this helper function in the same file you added the cycleWeapon() in -- this will build the order/name index for you:
Now when you want to build the array(s) just call the function with a name and order# for each weapon, like so:
I find this simpler to manage when adding/removing many weapons, and it also cuts down on mispelling/misnaming errors. There is also a means of doing this dynamically without the global variables but the cycle order changes depending on what order the weapons are given to or picked up by the player. If someone would like that method just request and I'll show it here, it involves a minor change to the setInventory method.
03/24/2009 (10:39 am)
Another simplification for what Steve DeChiara suggested, especially if you're as lazy as me and don't want to add the two different arrays individually and still be able to avoid the if/else situation.Go ahead and add his suggested piece of code to replace all those if/else if (or possible switch/case/case/..) lines:
function ShapeBase::cycleWeapon(%this, %data)
{
%slot = -1;
if (%this.getMountedImage($WeaponSlot) != 0)
{
%curWeapon = %this.getMountedImage($WeaponSlot).item.getName();
%slot = $WeaponForSlot[%curWeapon];// this one line instead of those ifs
}
// rest of functionAdd this helper function in the same file you added the cycleWeapon() in -- this will build the order/name index for you:
function WeaponOrderIndex(%weapon, %slot)
{
if ($maxWeaponSlot $= "")
$maxWeaponSlot = -1;
$weaponInSlot[%slot] = %weapon;
$weaponForSlot[%weapon] = %slot;
$maxWeaponSlot++;
}Now when you want to build the array(s) just call the function with a name and order# for each weapon, like so:
WeaponOrderIndex(Pistol, 0); WeaponOrderIndex(Shotgun, 1); WeaponOrderIndex(Rifle, 2); WeaponOrderIndex(Machinegun, 3); WeaponOrderIndex(RocketLauncher, 4);You could add these lines anywhere, but I tend to keep them together for organizational purposes (makes it easier to change the order when you have the list in one place). Just remember that your first weapon still needs to go into orderslot #0.
I find this simpler to manage when adding/removing many weapons, and it also cuts down on mispelling/misnaming errors. There is also a means of doing this dynamically without the global variables but the cycle order changes depending on what order the weapons are given to or picked up by the player. If someone would like that method just request and I'll show it here, it involves a minor change to the setInventory method.
#38
In order to "fix" this, simply change this if statement
and add the following wherever you added the ShapeBase::hasInventory method (I actually placed both in inventory.cs for organizational purposes)
03/24/2009 (10:55 am)
Oh, and has anyone noticed that this comment is lying?Quote:// player has this weapon and it has ammo or doesn't need ammoIt implies that it only switches to a weapon that has ammo or doesn't need ammo, but it will cycle to a weapon that requires it yet has no ammo.
In order to "fix" this, simply change this if statement
if ($weaponInSlot[%i] !$= ""
&& %this.hasInventory($weaponInSlot[%i]))
{
// player has this weapon and it has ammo or doesn't need ammo
%newSlot = %i;
break;
}to read like thisif ($weaponInSlot[%i] !$= ""
&& %this.hasInventory($weaponInSlot[%i])
&& %this.hasAmmo($weaponInSlot[%i]))
{
// player has this weapon and it has ammo or doesn't need ammo
%newSlot = %i;
break;
} and add the following wherever you added the ShapeBase::hasInventory method (I actually placed both in inventory.cs for organizational purposes)
function ShapeBase::hasAmmo(%this, %weapon)
{
if (%weapon.image.ammo $= "")
return(true);
else
return(%this.getInventory(%weapon.image.ammo) > 0);
}Now you will not cycle to a weapon that doesn't have ammo, but you can still cycle to energy based (no-ammo usage) weapons.
#39
07/24/2009 (10:56 am)
Thanks Everyone this helped out a lot. I learn a great deal from you guys. Thanks again
#40
I would love to see your modification of setInventory!
01/30/2011 (11:03 pm)
@Michael:Quote:
There is also a means of doing this dynamically without the global variables but the cycle order changes depending on what order the weapons are given to or picked up by the player.
I would love to see your modification of setInventory!

Torque Owner Tom
however, i dont knwo how to solve it, im at it now for 3 days!
here is what i found:
the first time that cycle weapons is called, the function enteres this portion:
if ( $weaponInSlot[%i] !$= "" && %this.hasInventory( $weaponInSlot[%i] )) { // player has this weapon and it has ammo or doesn't need ammo %newSlot = %i; break; }however, any other time, it just skips over it!, y does it do that? like it whould enter since the $weaponInSlot[%i] !$= "" is true and %this.hasInventory( $weaponInSlot[%i] ) is true as well!
so does anyone know how to fix this? or experienenced a similar problem?
im literally at the end of ideas after 3 days of trying to get it to work