Game Development Community

Weapon mounting

by Luke Griffin · in Torque 3D Professional · 03/07/2011 (4:38 am) · 15 replies

Hi

I've just spent the past day trying to figure this one out with no success. I would like to change the key bindings for the weapon mounting process so insted of having a command to server that specifies the weapon itself:

[ moveMap.bindCmd(keyboard, "1", "commandToServer(\'use\',\"RocketLauncher\");", ""); ]

it runs a function called something like "equipPrimaryWeapon":

[ moveMap.bind(keyboard, "1", equipPrimaryWeapon); ]

I am planning on putting together an inventory which will allow you to equip 1 primary and 1 secondary weapon, and as these will be changing I need a function that I can call up that will mount a weapon defined as primary or secondry. I've made a function in multiple places and done the whole

%player.mountimage

approach just to see if I can get it to switch weapons, but it simply doesnt want to work.

Does anyone have any ideas?

thanks in advance.

#1
03/07/2011 (5:55 am)
Keybinds need copying to config.cs, either manually, or the proper way is to clean your prefs with deletePrefs.bat and let the project rebuild itself on restart.

Quote:
I've made a function in multiple places and done the whole

%player.mountimage

approach just to see if I can get it to switch weapons, but it simply doesnt want to work.

Congratulations on being telepathic but the rest of us are wearing tinfoil hats to guard against mindprobes so you're not coming through. Might be more useful if you included your script.

Also check out the Simple FPS Tutorial in TDN which tells you all the changes you need to add new weapons and keybinds.
#2
03/07/2011 (6:08 am)
You would need to setup an array of weapon slots with slot number equaling it's location in the array, and a string for each location denoting the weapon Image name. When the player chooses his primary and secondary (or more) weapons each would get plugged into the appropriate array location. From your keybind you would call your "need to equip function" and pass in the appropriate array location: first, second, third, etc. Your "need to equip function" (which would have universal use to avoid needless duplication) would then be able to read the parameter passed into it, look at the array and know what weapon this is (the string name), it would then proceed to call mountImage as normal.
#3
03/07/2011 (8:50 am)
@Steve

Sorry, guess I could have been a lot clearer. I know how to set key binds for weapons at the moment but they are all based on the method:
moveMap.bindCmd(keyboard, "1", "commandToServer(\'use\',\"RocketLauncher\");", "");

What I would like to do is rather then specifying the weapon in the key bind, run it through a function instead. A function that I could later use to determine what is the current primary weapon that the player has selected.

I tried the following:

scripts/client/config.cs
------------------------------------------------
moveMap.bind(keyboard, "1", equipPrimaryWeapon);
------------------------------------------------

scripts/client/customweapons.cs (which has been exec in init.cs)
------------------------------------------------
function equipPrimaryWeapon()
{
%player.mountImage(WEAPONNAMEHERE,0);
)
------------------------------------------------

I was hoping to just replicate the switching of weapons in this function that I could then use later on to work out which weapon is primary.

hope that helps.
#4
03/07/2011 (9:25 am)
I have (had) the kind of system you want, but it's kinda hard to keep tack of what weapon is assigned to what slot with this method. You can try for your self:

scripts/client/config.cs and scripts/client/default.map.cs:
moveMap.bindCmd(keyboard, "1", "commandToServer('UseSlot', 1);", "");
This is similar to your equipPrimaryWeapon, but i have added more dynamicness so i wont need a equipSecondary, equipThird, etc. Instead just define what slot to mount and then keep the primary weapon in the first slot.

scripts/server/commands.cs:
function serverCmdUseSlot(%client, %slot)
{
   %player = %client.player;
   if(isObject(%player.weaponSlot[%slot].image))
   {
      // Weapon has image, mount it!
      %player.mountImage(%player.weaponSlot[%slot].image, $WeaponSlot);
   }
}
This code will simply check if there is any weapon in the slot you specified, and mount if there is.

Now to specify weapons for the slots, you'll just need the player, and do like:
%player.weaponSlot[%slot] = %weaponItem;
Where %slot would be the slot to mount to, and %weaponItem would be the ItemData of the weapon. The only thing is to find out where you want to assign your weapons, maybe in pickup or onAdd. Anyways this how i'd do it, hope you'll figure it out.
#5
03/07/2011 (10:26 am)
looks good I will give it a try. reason mine i was looking at a equipPrimaryWeapon function was because I will have closer to two inventorys. one represents what the player is carrying and is a 4X4 slot setup "total of 16 slots". Items can take up multiple slots, for example a pistol may take up two, a rifle three and a health pack 1. You will then have an equip screen which will allow you to equip only two weapons and 4 usable items "non weapons" plus two other items which include a flashlight "which will just need a boolean of true or false". The primary weapon will be bound to 1 as default, secondary weapon 2 as default, and the items will be scrolled through using the <> keys or mouse wheel.

All of this information will need to be saved to two files containing the inventory status and equiped status, and they will eventually have to be saved with all of the levels "as I will want the player to traverse between levels and save their status so when they return its how they left it" quest book information and loads of other stuff.

I thought I would post that as I will no doubt be finding some more problems along the way.
#6
03/07/2011 (10:39 am)
@Marcus

You script worked a dream, its pulling out the weapon now. I would still welcome any tips or suggestions as to how I can build on this process to accomplish what I am after.
#7
03/07/2011 (11:15 am)
That which Marcus showed is about what I described. The reason why your code wasn't working was that you were trying to mount from the client when what you needed to do is have the server tell the client/player what to mount. Client processes keybind, tells the server. The server then tells the player object to do something.
#8
03/07/2011 (11:25 am)
ahh i see, i also tried putting that same file in the server side scripts and it had the same effect, but i see the logic. could be because it wasnt precise enough lol
#9
03/07/2011 (11:31 am)
It's a bit of a learning process but you'll get there, just keep asking questions - most people around are helpful.
#10
03/07/2011 (11:36 am)
Sorry Michael, forgot to mention that my setup was basically what you said :)

@ Luke
Nice to see you got it to work =)
#11
03/07/2011 (11:44 am)
If people can't see your scripts then they won't know if you're doing it wrong. ;)
#12
03/07/2011 (12:58 pm)
Thanks everyone for your help its much appreciated. I have a question on the same subject, well kind of. Using the method suggested by Marcus I have tested a new concept. Instead of using the scroll wheel or <> keys to cycle through my 4 equiped items I was thinking of having a gui element do it instead. I have 4 buttons that I can now press on my gui and it switches items correctly. I was thinking of doing a radial gui for item selection, so when you hold down a key the gui is displayed "which shows a circle split into 4 buttons" then you move your mouse over the 4 GuiBitmapButtonCtrl's and when it is highlighted, release the key and the gui disappears and the item is mounted. My questions are, can you have a gui display only while a key is down, and also do the GuiBitmapButtonCtrl's have a mouse over function that will trigger an effect?
#13
03/07/2011 (2:00 pm)
Your idea is good, not so easy to achieve. Therefore i took the liberty to do it for you =)

scripts/client/default.map.cs:
function showWeaponSelector(%val)
{
   commandToServer('ShowWeaponSelector', %val);
}

// Add to config.cs or delete config.cs
// to re-generate it (like Steve said above)
moveMap.bind(keyboard, m, showWeaponSelector);
I just called the functions something and put a random button, :P

scripts/client/client.cs:
function clientCmdSetVisible(%control, %val)
{
   %control.setVisible(%val);
}
For hiding GUI elements throught networking.

scripts/server/commands.cs:
function serverCmdShowWeaponSelector(%client, %val)
{
   commandToClient(%client, 'SetVisible', "weaponSelector", %val);
   if(%client.player.selectedSlot)
      %player.mountImage(%client.player.weaponSlot[%client.player.selectedSlot].image, $WeaponSlot);
   else
      %client.player.selectedSlot = 0;
}

function serverCmdShowWeaponSelector(%client, %val)
{
   %client.player.selectedSlot = %val;
}
Note that you have to replace the "weaponSelector" with what ever your radial gui thingy is named.

your_place_where_you_store_gui_functions:
function weaponButton1::onMouseEnter()
{
   commandToServer("SetSelectedSlot", 1);
}

function weaponButton1::onMouseLeave()
{
   commandToServer("SetSelectedSlot", 0);
}
Assuming your primary weapon button is named weaponButton1, this will set the selected slot to 1, make this for the 3 other buttons as well. The onMouseLeave will make sure no slot is selected if you're not hovering any button.

Just note that i haven't tested these functions at all, so please report any problems. I did also not manage to get a onMouseEnter callback from a button, but i didn't really try that much.

This will have to be enough generosity for this week :P just kidding!
#14
03/08/2011 (6:06 am)
OK just tried the code "and thanks for all your help btw!", and it doesnt seem to be working. I determined that it is running the function "function serverCmdShowWeaponSelector(%client, %val)" but it doesnt actually seem to do anything. I have the weaponSelector gui element in playgui.gui as a guibitmapborderctrl, with the buttons inside, hidden as default, but it wont get the buttons to appear. Also I tried a basic gui bound to appear and tried the:
function weaponButton1::onMouseEnter()
{
commandToServer("SetSelectedSlot", 1);
}

but that doesnt seem to do anything either. Now I probubly dont know what im talking about but is it ok to have two functions named:

function serverCmdShowWeaponSelector

as you have above? Or would that confuse the program having two?

#15
03/08/2011 (9:05 am)
Quote:as you have above? Or would that confuse the program having two?
That would indeed confuse the program.

Quote:I determined that it is running the function "function serverCmdShowWeaponSelector(%client, %val)" but it doesn't actually seem to do anything.
Hmm, that's interesting. Just tested myself, and i am able to hide GUI elements with it, you can test for yourself by calling it in the console:
commandToClient(LocalClientConnection, 'SetVisible', "any_gui_here", %hide); // %hide = false or true
Note that in the code i posted (serverCmdShowWeaponSelector) assumed that all of your buttons where visible, but their parent "weaponSelector" was hidden. If you want to unhide/hide the buttons themselves, you'll have to call the code i posted above (commandToClient) for each button.

Quote:
function weaponButton1::onMouseEnter()
{
commandToServer("SetSelectedSlot", 1);
}

but that doesn't seem to do anything either.
Yeah, I have actually never used onMouseEnter myself, so what i wrote is just what i assumed should work. And as i stated in my previous post, i didn't manage to get a callback either. Might be a sort of bug or just me using it wrong. Probably someone who has successfully managed to use onMouseEnter could tell how to do so. And i dont think there is any other solution which would do what you want :/

Good luck figuring it out :P