Certain Weapon Zoom with Individual Scope HUDs
by Chris Byars · 08/07/2005 (1:05 am) · 46 comments
Today you get to learn how to make only certain weapons be able to zoom, and to cause a unique scope HUD to be visible for each. This resource was made possible by the contributions of Matt Sanders, Harold "LabRat" Brown, and hours of banging heads on desks getting the code to function exactly as we wished.
To begin, create a new script file called zoom.cs and place it in yourgame/server/scripts/. Put the following code in it:
Open up /server/scripts/game.cs and add this in with the rest of the execute script commands:
We're done with the server side part of things. Now open up /client/scripts/default.bind.cs and under "Zoom and FOV functions", replace everything there with the following.
Be sure to change "XM8" and "sniperrifle" to the weapon names you want to zoom. What the above script does, is when you press the right-mouse button (mouse2, which you can change to whatever you wish in your options GUI), it calls the zoom function, which then makes sure you are in 1st person, checks what the client's current weapon is, and performs the zoom function and set's the scope HUD group visible that is specified for the current weapon. If you only want to have one weapon be able to zoom, simply remove this part of the script:
Likewise, if you want more than two weapons to zoom, add another of the above code block, and change the %curWeapon $= "" to the weapon of addition. If you want it to use another HUD, change the ScopeGuiGroup1 to your new GUI group's name. Where are all these GUI groups, you say? We'll get to that in a few moments.
You will want to now go into /client/prefs.cs and change the CurrentFOV preference to the zoom distance you want, it is the zoom in power. I happen to like 8x, so mine is set to 11.25.
2x = 45
3x = 30
4x = 22.5
5x = 18
6x = 15
7x = 12.86
8x = 11.25
Now on to the GUI groups, the Scope HUDs. First, download the Sniper Scope image and place it in /client/ui/.
To get this to appear when you zoom in, we will be opening /client/ui/playGui.gui for modification. Add the following scripts somewhere under the new GameTSCtrl(PlayGui) { block of code, and be sure they are indented correctly, to reflect the GUI tree.
Those two GuiBitmapCtrls control the bitmap that will be displayed for each GUI Group. Both are set to the sniperscope.png image currently, but if you will probably want to change one of them; after all, you're supposed to be able to have each weapon have unique scoping HUDs, with this resource. After doing the above additions/changes, the weapons you set to zoom, should now zoom correctly.
Now you don't want a player to be able to switch to 3rd person while zooming, so open up /client/scripts/default.bind.cs again and look for the toggleFirstPerson(%val) function, and replace it with the following.
For some more exploit protection, you don't want a player to be able to switch weapons while they are zooming, otherwise they'll be able to use the zoom and scope for weapons unspecified. So if you are using the Weapon Cycling resource and/or have weapons set to be used when you hit a number on the keyboard, you'll want to do the following.
Open up /server/scripts/inventory.cs and replace the function ShapeBase::use(%this,%data) with the code below:
And now, if you are using the Weapon Cycling resource (which I highly suggest using), you will want to also want to find your serverCmdCycleWeapon function in inventory.cs, and replace it with the following:
There. So now you have a way to make certain weapons able to use a zoom function, and each weapon can have its own HUD plastered on the screen while you zoom. And it cannot be exploited by using items/weapons or cycling weapons while the zoom is on. If you have any problems (hope not), go ahead and post a comment.
Enjoy the power of zoom.
To begin, create a new script file called zoom.cs and place it in yourgame/server/scripts/. Put the following code in it:
function serverCmdCallZoomFunction( %client, %val )
{
%zoomer = %client.getControlObject();
%curWeapon = %zoomer.getMountedImage($WeaponSlot).item.getName();
commandToClient(%client,'ZoomInDaBiatch',%val,%curWeapon);
}Open up /server/scripts/game.cs and add this in with the rest of the execute script commands:
exec("./zoom.cs");We're done with the server side part of things. Now open up /client/scripts/default.bind.cs and under "Zoom and FOV functions", replace everything there with the following.
if($Pref::player::CurrentFOV $= "")
$Pref::player::CurrentFOV = 45;
function clientCmdZoomInDaBiatch( %val, %curWeapon )
{
if ( %val && %curWeapon $= "XM8" )
{
$ZoomOn = true;
setFov( $Pref::player::CurrentFOV );
ScopeGuiGroup1.Visible = 1; // Show XM8 Scope HUD
Crosshair.Visible = 0; // Hide Crosshair
}
else if ( %val && %curWeapon $= "sniperrifle" )
{
$ZoomOn = true;
setFov( $Pref::player::CurrentFOV );
ScopeGuiGroup2.Visible = 1; // Show Sniper Rifle Scope HUD
Crosshair.Visible = 0; // Hide Crosshair
}
else
{
$ZoomOn = false;
setFov( $Pref::player::DefaultFov );
ScopeGuiGroup1.Visible = 0; // Make XM8 Scope HUD Invisible
ScopeGuiGroup2.Visible = 0; //Make Sniper Rifle Scope HUD Invisible
Crosshair.Visible = 1; // Show crosshair
}
}
function toggleZoom(%val)
{
if ($firstPerson == 1) // No Zoom When in 3rd Person View
{
commandToServer( 'CallZoomFunction', %val );
}
}
moveMap.bind(mouse, mouse2, toggleZoom);Be sure to change "XM8" and "sniperrifle" to the weapon names you want to zoom. What the above script does, is when you press the right-mouse button (mouse2, which you can change to whatever you wish in your options GUI), it calls the zoom function, which then makes sure you are in 1st person, checks what the client's current weapon is, and performs the zoom function and set's the scope HUD group visible that is specified for the current weapon. If you only want to have one weapon be able to zoom, simply remove this part of the script:
else if ( %val && %curWeapon $= "sniperrifle" )
{
$ZoomOn = true;
setFov( $Pref::player::CurrentFOV );
ScopeGuiGroup2.Visible = 1; // Show Sniper Rifle Scope HUD
Crosshair.Visible = 0; // Hide Crosshair
}Likewise, if you want more than two weapons to zoom, add another of the above code block, and change the %curWeapon $= "" to the weapon of addition. If you want it to use another HUD, change the ScopeGuiGroup1 to your new GUI group's name. Where are all these GUI groups, you say? We'll get to that in a few moments.
You will want to now go into /client/prefs.cs and change the CurrentFOV preference to the zoom distance you want, it is the zoom in power. I happen to like 8x, so mine is set to 11.25.
$Pref::player::CurrentFOV = 11.25;
2x = 45
3x = 30
4x = 22.5
5x = 18
6x = 15
7x = 12.86
8x = 11.25
Now on to the GUI groups, the Scope HUDs. First, download the Sniper Scope image and place it in /client/ui/.
To get this to appear when you zoom in, we will be opening /client/ui/playGui.gui for modification. Add the following scripts somewhere under the new GameTSCtrl(PlayGui) { block of code, and be sure they are indented correctly, to reflect the GUI tree.
new GuiControl(ScopeGuiGroup1) {
profile = "GuiDefaultProfile";
horizSizing = "width";
vertSizing = "height";
position = "0 0";
extent = "1024 768";
minExtent = "8 8";
visible = "0";
new GuiBitmapCtrl() {
profile = "GuiDefaultProfile";
horizSizing = "relative";
vertSizing = "relative";
position = "0 0";
extent = "1024 768";
minExtent = "8 8";
visible = "1";
bitmap = "./sniperscope";
wrap = "0";
helpTag = "0";
};
};
new GuiControl(ScopeGuiGroup2) {
profile = "GuiDefaultProfile";
horizSizing = "width";
vertSizing = "height";
position = "0 0";
extent = "1024 768";
minExtent = "8 8";
visible = "0";
new GuiBitmapCtrl() {
profile = "GuiDefaultProfile";
horizSizing = "relative";
vertSizing = "relative";
position = "0 0";
extent = "1024 768";
minExtent = "8 8";
visible = "1";
bitmap = "./sniperscope";
wrap = "0";
helpTag = "0";
};
};Those two GuiBitmapCtrls control the bitmap that will be displayed for each GUI Group. Both are set to the sniperscope.png image currently, but if you will probably want to change one of them; after all, you're supposed to be able to have each weapon have unique scoping HUDs, with this resource. After doing the above additions/changes, the weapons you set to zoom, should now zoom correctly.
Now you don't want a player to be able to switch to 3rd person while zooming, so open up /client/scripts/default.bind.cs again and look for the toggleFirstPerson(%val) function, and replace it with the following.
function toggleFirstPerson(%val)
{
if (%val && $ZoomOn != true)
{
$firstPerson = !$firstPerson;
}
}For some more exploit protection, you don't want a player to be able to switch weapons while they are zooming, otherwise they'll be able to use the zoom and scope for weapons unspecified. So if you are using the Weapon Cycling resource and/or have weapons set to be used when you hit a number on the keyboard, you'll want to do the following.
Open up /server/scripts/inventory.cs and replace the function ShapeBase::use(%this,%data) with the code below:
function ShapeBase::use(%this,%data)
{
if ( $ZoomOn $= false )
{
// Use an object in the inventory.
if (%this.getInventory(%data) > 0)
return %data.onUse(%this);
return false;
}
}And now, if you are using the Weapon Cycling resource (which I highly suggest using), you will want to also want to find your serverCmdCycleWeapon function in inventory.cs, and replace it with the following:
function serverCmdCycleWeapon( %client, %data )
{
if ( $ZoomOn $= false )
{
%client.getControlObject().cycleWeapon( %data );
}
}There. So now you have a way to make certain weapons able to use a zoom function, and each weapon can have its own HUD plastered on the screen while you zoom. And it cannot be exploited by using items/weapons or cycling weapons while the zoom is on. If you have any problems (hope not), go ahead and post a comment.
Enjoy the power of zoom.
#2
For my game, I have one scope bitmap GUI control for all my scopes. I have the zoom levels, zoom amount for each level, scope image name, and recoil effects in the ShapeBaseImageDatablock. The image name and zoom settings are sent to the client via clientCmds, and it works great on multiplayer.
08/07/2005 (2:33 pm)
Just so everyone knows, this code will not work correctly on a multiplayer game. The $ZoomOn variable looks to be set on the client, yet it's accessed on the server.For my game, I have one scope bitmap GUI control for all my scopes. I have the zoom levels, zoom amount for each level, scope image name, and recoil effects in the ShapeBaseImageDatablock. The image name and zoom settings are sent to the client via clientCmds, and it works great on multiplayer.
#3
08/07/2005 (3:36 pm)
Thanks, Josh, for clarifying. I wondered if this was network compatable; our project had some zoom scopes on only a few weapons, and I never really saw it work across a connection...kept suggesting about the difference. Also there was animated crosshair, which did similar goofiness.
#4
08/07/2005 (5:20 pm)
This will work networked just fine. The only server side command is serverCmdCallZoomFunction which checks what weapon the client is holding and then calls the client side Zoom function. The $ZoomOn variable is on the client side.
#5
Those are both server-side methods referencing the $ZoomOn variable.
08/07/2005 (6:16 pm)
LabRat: I guess you missed this stuff?function ShapeBase::use(%this,%data)
{
if ( $ZoomOn $= false )
{
// Use an object in the inventory.
if (%this.getInventory(%data) > 0)
return %data.onUse(%this);
return false;
}
}
and
function serverCmdCycleWeapon( %client, %data )
{
if ( $ZoomOn $= false )
{
%client.getControlObject().cycleWeapon( %data );
}
}Those are both server-side methods referencing the $ZoomOn variable.
#6
08/07/2005 (7:55 pm)
Ah, I quickly added those to stop exploiting for people to be switching weapons while zooming, which would allow them to use zoom for non-zoomable weapons. It seems I did it wrong. :P
#7
08/09/2005 (2:12 pm)
Would a simpler solution be to have the server send a client command to turn off the zoom whenever a new weapon is mounted? Then they can still switch weapons when zoomed but it will take off the scope. Just a quick thought.
#8
09/18/2005 (8:30 am)
I would greatly appreciate such a solution. Think you could post it?
#9
function serverCmdweaponzoomout(%client){
$ZoomOn = false;
setFov( $Pref::player::DefaultFov );
ScopeGuiGroup1.Visible = 0; // Make XM8 Scope HUD Invisible
ScopeGuiGroup2.Visible = 0; //Make Sniper Rifle Scope HUD Invisible
Crosshair.Visible = 1; // Show crosshair
}
now whenever you want to zoomout you just say
commandToServer('weaponzoomout');
so when you want to switch weapons just put commandToServer('weaponzoomout');
at the base of the code so it will zoomout when people switch.
09/18/2005 (8:38 am)
heres the solutionfunction serverCmdweaponzoomout(%client){
$ZoomOn = false;
setFov( $Pref::player::DefaultFov );
ScopeGuiGroup1.Visible = 0; // Make XM8 Scope HUD Invisible
ScopeGuiGroup2.Visible = 0; //Make Sniper Rifle Scope HUD Invisible
Crosshair.Visible = 1; // Show crosshair
}
now whenever you want to zoomout you just say
commandToServer('weaponzoomout');
so when you want to switch weapons just put commandToServer('weaponzoomout');
at the base of the code so it will zoomout when people switch.
#10
09/18/2005 (10:19 am)
Wouldn't that be just for the server player? It's sending a command to the server, not the individual client who's switching weapons and calling the commandToServer('weaponzoomout');. Unless I'm confused. :P
#11
09/22/2005 (8:07 pm)
ooh you're right missed a (%client)I just fixed it
#12
It seems to work great, will try it over a network tonight.
09/23/2005 (3:25 am)
And that "$ZoomOn = false;" will only affect the client who called that function right?It seems to work great, will try it over a network tonight.
#13
09/24/2005 (2:52 pm)
I believe so if it does I have alternate code that I created before this came out that I know would work over multiplayer but it would take a lot of changes.
#14
09/26/2005 (2:41 pm)
Works perfect over network.
#15
Anywho, it works great after I made that little change.
Thanks
09/28/2005 (7:28 am)
shouldn't this :if ( %val && %curWeapon $= "XM8" )
{
$ZoomOn = true;
setFov( $Pref::player::CurrentFOV );
ScopeGuiGroup.Visible = 1; // Show XM8 Scope HUD
Crosshair.Visible = 0; // Hide Crosshair
}be:if ( %val && %curWeapon $= "XM8" )
{
$ZoomOn = true;
setFov( $Pref::player::CurrentFOV );
ScopeGuiGroup1.Visible = 1; // Show XM8 Scope HUD <--- ScopeGuiGroup1 or 2?
Crosshair.Visible = 0; // Hide Crosshair
}Anywho, it works great after I made that little change.
Thanks
#16
09/28/2005 (1:00 pm)
Whoops. Yeah, my original code was named different. I'll fix that.
#17
10/29/2005 (2:51 pm)
...
#18
The only thing i changed was assigning the mouse wheel to zoom in at increments rather than having only one fov setting. Each to their own i suppose.
Good work C2.
12/20/2005 (11:58 am)
Not a bad little resource. The only thing i changed was assigning the mouse wheel to zoom in at increments rather than having only one fov setting. Each to their own i suppose.
Good work C2.
#19
(AKA: Toggling, instead of having to hold down the zoom button to have the zoom active.)
12/21/2005 (5:44 pm)
Tim, do you have yours set up to, once you hit the zoom button, the zoom stays on until you press the zoom button again? If so, I'd like to know how you did this. :)(AKA: Toggling, instead of having to hold down the zoom button to have the zoom active.)
#20
There is a way to do what you want, you just have to make a statement like $mvTriggerCount1++; in your toggle zoom function and $mvTriggerCount1--; in your 'zoom off' function.
I'll work it out for you and post the results here...
01/18/2006 (11:46 pm)
C2, mine is set up so when you hit right mouse button once it zooms in a little bit, then (whilst right button is still held down) if you scroll up with the mouse wheel it zooms in further and if you scroll down with the mouse wheel it zooms back in. You may keep zooming in and out in this fashion as long as the right mouse button is held down.There is a way to do what you want, you just have to make a statement like $mvTriggerCount1++; in your toggle zoom function and $mvTriggerCount1--; in your 'zoom off' function.
I'll work it out for you and post the results here...

Torque Owner Dracola