Garry's Mod

Garry's Mod

Not enough ratings
How to make custom TTT VR weapons
By Beverly
This guide will show you how to port an SWEP for my TTT VR addon.
   
Award
Favorite
Favorited
Unfavorite
Summary
In my TTT VR addon, I've set up a system that gives VR users a different VR SWEP version of each weapon in TTT to allow for changes to how the weapons look for VR clients. This could be used to give custom view models (for instance fixing view models that don't have a back side), custom scopes, animations, etc. for people who are playing in VR. I've already made versions of all of the default TTT weapons, but if you wanted to make a VR variant of a custom weapon, then this guide will teach you how to make it compatible with TTT VR.

For this guide, I'll go through making a TTT VR version of the Silenced AWP from this addon. You can find the finished product here if you want to use it in game or look at the LUA as an example. In this guide, I'm only going to set up the SWEP so that it works with the weapon swapping system in TTT VR and has a fixed muzzle offset, but if you knew what you were doing, you could also make it use a custom view model for VR players or add other functions like a working scope or manual reloading like what is seen with Arctic's VR weapons.
Step 1: Addon Structure
This section is just a quick summary of how to set up a GMod addon and start an SWEP lua file, so if you have already done this, feel free to skip to Step 2.

Firstly, we will make a new folder in our addons folder for this addon. Your addons folder can be found in your [Steam games directory]/steamapps/common/GarrysMod/garrysmod/addons and in here we will make a new folder for our addon. I'm calling mine "tttvr_awp":



Next, inside this folder we create a file called "addon.json" which defines the addon for the community workshop. You can find more information about this file on the official wiki page[wiki.facepunch.com], but mine below should be a pretty good outline.

{ "title" : "TTT VR AWP", "type" : "weapon", "tags" : [ "fun", "realism" ], "ignore" : [ "*.psd", "*.vcproj", "*.svn*", "*.git*" ] }

Next, make a folder called "lua" inside of the addon folder so the contents of the "tttvr_awp" folder should look like this now:



Next, make a folder called "weapons" inside of the "lua" folder, and make a new lua file inside of it for your SWEP titled with your desired weapon class name. I'm calling mine "tttvr_awp.lua", so it should look something like this:



That's all for the addon structure! You could put several SWEP files in this folder if you wanted to make a collection of weapons all with one addon, and you could also add this in along with an existing addon that does other stuff if you wanted.
Step 2: SWEP Configuration
Now that we have a file the game will recognize, we need to actually set it up to be an SWEP and add the functions so that TTT VR recognizes it. This file will be different depending on whether or not the weapon you are adding has already been defined as a TTT weapon or not, or if you are making it from scratch.

If your weapon isn't already added into TTT, then you need to make a version for regular TTT first so that non-VR players can also use it by following the official guide[www.troubleinterroristtown.com], then follow the steps below to make a separate VR variant based off of that class.

Once you have your weapon working in normal TTT, you can move on to adding a VR variant, as I am doing with this AWP. For this case, first, find out the class name that the existing TTT weapon already has. If you don't already know this, you can figure it out by running the following command in the game console while you are holding the weapon:
lua_run_cl print(LocalPlayer():GetActiveWeapon():GetClass())


As you can see, the class that the creator chose for this weapon is "weapon_ttt_awp". Using this, we can start writing the SWEP file for the VR variant of our weapon.

Start by making sure that clients get the lua file by adding the line:
AddCSLuaFile()
This is standard for all SWEPs.

Then, we inherit all of the properties of the original weapon by making it the base for the VR variant with this line using the class name we found earlier:
SWEP.Base = "weapon_ttt_awp"
Next, we add include all of the changes that must apply to all VR weapons by including the base weapon script from TTT VR (note: use "tttvr_basegrenade.lua" if you are adding a grenade):
include("tttvr_base.lua")
Next, we add the function that handles the VR muzzle offset, making sure that it looks exactly like this:
function SWEP:SetMuzzleOffset() TTTVRCurrentMuzzleOffset = Vector(0, 0, 0) end
Leave the offset values at 0,0,0 for now, we will figure them out later.

Lastly, we add the weapon replacement to the master list so that TTT VR knows what weapon this VR weapon is a variant of:
if SERVER then hook.Add("TTTVR:Initialize", "Benny:TTTVRAWP", function() TTTVRWeaponReplacements["weapon_ttt_awp"] = "tttvr_awp" end) end
You must change the hook identifier to something unique for the hook to work. I recommend you combine your name/tag and the weapon name as I have done with "Benny:TTTVRAWP".

Then, replace the strings in the table entry so that the key is the original weapon class we found earlier, "weapon_ttt_awp" in this case, and so that the value is the class name for the VR variant (should be what you named the lua file). I called my lua file "tttvr_awp.lua" so I set the value to "tttvr_awp".

I know that was probably a little confusing, so basically just make our finished file should look like this and change the important bits that correspond to the weapon you are adding:



Now that we have a functional SWEP, TTT VR will automatically give VR users this variant of the weapon, and it will turn back into the normal version when other people use it.

As such, we can change anything we want about its properties in this file. For example, you could change the view model so that people in and out of VR use different view models for the same weapon. Find out more about all of the things you can change with SWEPs on their wiki page[wiki.facepunch.com].
Step 3: Testing
Now, we can go in-game to make sure that it is all working properly. You can enter the following commands to quickly get into a testing world:
maxplayers 2 gamemode terrortown map gm_construct bot

Now, give yourself the normal variant of the weapon with the give command using the class name from earlier
give weapon_ttt_awp

Then, try going into VR with the command:
vrmod_start

Use your controllers to switch to the weapon and then use the command from earlier to make sure that TTT VR automatically switched it your new VR version of the gun:



As you can see, the console prints out the VR variant's class name "tttvr_awp", not the original weapon class "weapon_ttt_awp", so we know it is all set up right.

Next, make sure to test everything while looking out for errors in the console, including but not limited to:
  • Primary fire
  • Secondary fire (if there is one)
  • Dropping on the ground
  • Picking up ammo

If your game freezes/crashes while doing any of these, don't worry! That just means that one of the functions in the original SWEP file is getting stuck in an infinite loop because it wasn't intended to be inherited into a different SWEP. It would be impossible to cover every scenario, but this is usually fixable by finding the culprit function and making slight tweaks so that the references point to the right base class.

The most common crash is with dropping the weapon, which you should be able to fix by copying the PreDrop() function from below into your SWEP class.
function SWEP:PreDrop() self:SetZoom(false) self:SetIronsights(false) local ply = self:GetOwner() if SERVER and IsValid(ply) and self.Primary.Ammo != "none" then local ammo = self:Ammo1() -- Do not drop ammo if we have another gun that uses this type for _, w in ipairs(ply:GetWeapons()) do if IsValid(w) and w != self and w:GetPrimaryAmmoType() == self:GetPrimaryAmmoType() then ammo = 0 end end self.StoredAmmo = ammo if ammo > 0 then ply:RemoveAmmo(ammo, self.Primary.Ammo) end end local newgun = convertTTTVRWeaponToNormal(self) newgun.StoredAmmo = self.StoredAmmo ply:DropWeapon(newgun) end

Another common issue is that the VR variant loses some of the original SWEP's properties like the AmmoEnt, Icon, or PrintName. If you notice that the name in the weapon selector or icon for weapon used on a dead body aren't working properly, or that you can't pick up ammo for the weapon, just find those properties in the original SWEP and paste them into the VR variant as well. That would look like this for the Deagle:
SWEP.AmmoEnt = "item_ammo_revolver_ttt" SWEP.Icon = "vgui/ttt/icon_deagle" SWEP.PrintName = "Deagle"

Also, if your weapon usually has a scope, you should get rid of the secondary zoom ability with this line, as it will only work on the screen and not in the VR headset:
function SWEP:SecondaryAttack() return end

If you are having trouble with these types of problems, feel free to look at the default TTT weapons I have already done in the TTT VR addon, or leave a comment and I will try my best to help.
Step 4: Touchups
Now that we have our weapon working, we have the liberty to change the view model or anything else about it as needed. Only once everything else is configured the way you want it and working properly, you should align the muzzle offset so that it is actually on the end of the gun.

To do this, get a hold of the weapon in VR and use the following commands to show the laser pointer and muzzle position:
sv_cheats 1 tttvr_laser 1

The box shows where the muzzle is and the laser shows the direction that the bullet will go. You will probably see that it is completely wrong, like this:



You can tweak the offset in the file and then switch to another weapon and back again in game to see it update without having to close and reopen the world every time. It is much easier to see how close it is in VR, so I recommend checking using the headset rather than the screen view.

The first value corresponds to how far forward or back it is offset, so for this AWP, I had to use a value of 45 to move it forwards to the end of the barrel.

The second value corresponds to how left or right it is offset, so for this AWP, I had to use a value of 7.1 to move it just enough to the right to be centered along the gun.

The third value corresponds to how up or down is is offset, so for this AWP, I had to use a value of -4.3 to move it down so that it was just right on the barrel.

So, the line of code ends up as seen below and gives us the following result:
TTTVRCurrentMuzzleOffset = Vector(45, 7.1, -4.3)
Conclusion
And that's all there is to it! Again, you can find the finished product here if you want to use it in game or look at the LUA as an example, and if you need any help, please feel free to add me or leave a comment.

If you don't know how to compile and upload a GMod addon, follow this guide[wiki.facepunch.com] on the GMod wiki.

Also, it would mean a lot to me if you could rate with a thumbs up and favorite my TTT VR addon if you do like it and use it. I put a lot of effort into getting all of this to work and it makes me really happy to know that there are people who enjoy it! Thanks so much!!