Code copied from code.nut ->
https://tf2maps.net/downloads/vscrip..._weapon.14897/
Code:
//-----------------------------------------------------------------------------
// Purpose: Used to update viewmodel arms.
// -> See top of script for more info
//-----------------------------------------------------------------------------
::CTFPlayer.UpdateArms <- function()
{
if ( !CVAR_GTFW_USE_VIEWMODEL_FIX ) {
GTFW_DevPrint("give_tf_weapon: CVAR_GTFW_USE_VIEWMODEL_FIX = false. UpdateArms cancelled.")
return
}
/* Purpose: This is the special VM fix.
it creates class arms that bonemerge with VM
*/
// Table for bonemerged class arms, per player.
// Adds a class arms model if nothing has parented to the main_viewmodel
if ( !( this in PlayerLoadoutGlobal_BonemergedArms ) ) {
local main_viewmodel = NetProps.GetPropEntity(this, "m_hViewModel")
local wearable_handle = this.GTFW_CreateCustomWeaponModel(false, main_viewmodel, GTFW_MODEL_ARMS[this.GetPlayerClass()] ) // creates player class' arms, parents and does all that stuff
/* Purpose: Initialize tables if they aren't already made
So we don't create more arms than necessary
Puts into a table "player = arms model" for easy tracking
*/
::PlayerLoadoutGlobal_BonemergedArms[this] <- wearable_handle
}
// Purpose: Writes to the tables above, which keep the class arms the weapon needs to update to when switched to.
for (local i = 0; i < GLOBAL_WEAPON_COUNT; i++)
{
local wep = NetProps.GetPropEntityArray(this, "m_hMyWeapons", i)
if ( wep )
{
local baseitem = this.ReturnWeaponTable(GetItemID(wep))
if ( baseitem ) {
if ( baseitem.className == "tf_weapon_pda_spy" ) {
wep.SetModelSimple( "models/weapons/v_models/v_pda_spy.mdl" )
wep.SetCustomViewModel( "models/weapons/v_models/v_pda_spy.mdl" )
}
else if ( baseitem.className == "tf_weapon_invis" && baseitem.itemID == 30 ) {
wep.SetModelSimple( "models/weapons/v_models/v_watch_spy.mdl" )
wep.SetCustomViewModel( "models/weapons/v_models/v_watch_spy.mdl" )
}
else if ( baseitem.className == "tf_weapon_invis" && baseitem.itemID == 59 ) {
wep.SetModelSimple( "models/weapons/v_models/v_watch_pocket_spy.mdl" )
wep.SetCustomViewModel( "models/weapons/v_models/v_watch_pocket_spy.mdl" )
}
else if ( baseitem.className == "tf_weapon_invis" && baseitem.itemID == 60 ) {
wep.SetModelSimple( "models/weapons/v_models/v_watch_leather_spy.mdl" )
wep.SetCustomViewModel( "models/weapons/v_models/v_watch_leather_spy.mdl" )
}
else if ( baseitem.className == "tf_weapon_invis" && baseitem.itemID == 297 ) {
wep.SetModelSimple( "models/weapons/v_models/v_ttg_watch_spy.mdl" )
wep.SetCustomViewModel( "models/weapons/v_models/v_ttg_watch_spy.mdl" )
}
else if ( baseitem.className == "tf_weapon_invis" && baseitem.itemID == 947 ) {
wep.SetModelSimple( "models/workshop_partner/weapons/v_models/v_hm_watch/v_hm_watch.mdl" )
wep.SetCustomViewModel( "models/workshop_partner/weapons/v_models/v_hm_watch/v_hm_watch.mdl" )
}
else if ( this.HasGunslinger() ) {
wep.SetModelSimple( GTFW_MODEL_ARMS[10] )
wep.SetCustomViewModel( GTFW_MODEL_ARMS[10] )
}
else if ( baseitem.class_arms ) {
wep.SetModelSimple( baseitem.class_arms )
wep.SetCustomViewModel( baseitem.class_arms )
}
else if ( baseitem.tf_class == 0 || this.GetPlayerClass() == baseitem.tf_class ) {
wep.SetModelSimple( GTFW_MODEL_ARMS[this.GetPlayerClass()] )
wep.SetCustomViewModel( GTFW_MODEL_ARMS[this.GetPlayerClass()] )
}
else {
wep.SetModelSimple( GTFW_MODEL_ARMS[baseitem.tf_class] )
wep.SetCustomViewModel( GTFW_MODEL_ARMS[baseitem.tf_class] )
}
}
}
}
}
Code:
//-----------------------------------------------------------------------------
// Purpose: Updates viewmodel think script.
// Clears and updates the viewmodel think script for weapon switching, enabling/disabling visibility of custom weapons.
//-----------------------------------------------------------------------------
::CTFPlayer.AddThinkToViewModel <- function()
{
if ( !CVAR_GTFW_USE_VIEWMODEL_FIX ) {
return
}
local main_viewmodel = NetProps.GetPropEntity(this, "m_hViewModel")
local wearable_handle = null
// Think script itself.
// Reads from several tables to find weapon's class arms.
if( main_viewmodel.ValidateScriptScope() )
{
local wep = null
local player = this
local entscriptname = "THINK_VM_FIX_"+this.tostring()
local main_viewmodel = NetProps.GetPropEntity(this, "m_hViewModel")
local DisableDrawQueue = null
local asdf = null
local WEP_TAUNT_FIX = false
const THINK_VMFIX_DELAY = 0
local entityscript = main_viewmodel.GetScriptScope()
entityscript[entscriptname] <- function()
{
// Fixes taunts
// It clears the parent of the original weapon, and makes it invisible.
// It is reparented inside the DisableDrawQueue section (a few lines down)
if ( player.InCond(7) && WEP_TAUNT_FIX ) {
WEP_TAUNT_FIX = false
wep = player.GetActiveWeapon()
NetProps.SetPropEntity(DisableDrawQueue, "m_hWeaponAssociatedWith", wep)
NetProps.SetPropInt(wep, "m_fEffects", 161)
DoEntFire("!self", "Clearparent", "", 0, null, wep)
DoEntFire("!self", "DisableShadow", "", 0, null, wep)
wep.EnableDraw()
NetProps.SetPropInt(wep, "m_iState", 0)
wep = null
}
// updates weapons' visibility based on which one is being used
else if ( player.GetActiveWeapon() && !player.InCond(7) && player.GetActiveWeapon() != wep )
{
wep = player.GetActiveWeapon()
local wepC = wep.GetClassname()
// This fixes taunts and switching away from custom weapons.
// It reparents and sets owner back to the player
if ( DisableDrawQueue )
{
NetProps.SetPropInt(wep, "m_iState", 0)
DoEntFire("!self", "RunScriptCode", "self.DisableDraw()", 0, null, DisableDrawQueue) //using delay here purposely. Won't update b/c thinks too fast!!
NetProps.SetPropEntity(DisableDrawQueue, "m_hWeaponAssociatedWith", null)
DoEntFire("!self", "SetParent", "!activator", 0, player, wep)
wep.SetOwner(player)
DisableDrawQueue = null
}
// These are vars are for the next part
asdf = null
DisableDrawQueue = null
//Checks for custom weapon and/or weapon unintended for the class.
//Passing as a custom weapon means it updates the weapon visibility, disables the base weapon,
// then adds it to the queue to be disabled when switched away
if ( IS_CUSTOM(wep, false) )
{
main_viewmodel.DisableDraw() //makes firstperson weapon invisible (as well as other's class arms from the other class)
WEP_TAUNT_FIX = true
NetProps.SetPropInt(wep, "m_iState", 0)
wep.EnableDraw() //Have to send EnableDraw() first before DisableDraw(). Thanks Sorse(tm)!
DoEntFire("!self", "RunScriptCode", "self.DisableDraw()", 0.01, null, wep) //using delay here purposely. Won't update b/c thinks too fast!!
asdf = PlayerLoadoutGlobal_CustomWeaponModels_TP[player][wepC] //reads from table
asdf.EnableDraw()
DoEntFire("!self", "RunScriptCode", "self.EnableDraw()", 0.01, null, asdf) //using delay here purposely. Won't update b/c thinks too fast!!
DisableDrawQueue = asdf //custom weapon disables visibility at beginning of think script.
}
else if ( IS_UNINTENDED(wep, false) ) {
WEP_TAUNT_FIX = true
main_viewmodel.DisableDraw() //makes firstperson weapon invisible (as well as other's class arms from the other class)
}
// this part reads from the bonemerged arms table
// who ever the class is, and which ever arms they are using, this will put it as a value...
if ( player in PlayerLoadoutGlobal_BonemergedArms ) {
local bonemerged = PlayerLoadoutGlobal_BonemergedArms[player]
// if ShortCircuit, disable the class arms' visibility
if ( wep.GetClassname() == "tf_weapon_mechanical_arm" ) { // Short Circuit
bonemerged.DisableDraw()
}
else if ( IS_CUSTOM(wep, false) || IS_UNINTENDED(wep, false) ) {
bonemerged.EnableDraw()
}
}
}
return THINK_VMFIX_DELAY
}
AddThinkToEnt(main_viewmodel, entscriptname) //adds think script
}
}
Table from tables.nut
Code:
::GTFW_MODEL_ARMS <-
[
"models/weapons/c_models/c_medic_arms.mdl", //dummy
"models/weapons/c_models/c_scout_arms.mdl",
"models/weapons/c_models/c_sniper_arms.mdl",
"models/weapons/c_models/c_soldier_arms.mdl",
"models/weapons/c_models/c_demo_arms.mdl",
"models/weapons/c_models/c_medic_arms.mdl",
"models/weapons/c_models/c_heavy_arms.mdl",
"models/weapons/c_models/c_pyro_arms.mdl",
"models/weapons/c_models/c_spy_arms.mdl",
"models/weapons/c_models/c_engineer_arms.mdl",
"models/weapons/c_models/c_engineer_gunslinger.mdl", //CIVILIAN/Gunslinger
]
The code above seems to be the fix for viewmodels.
One function updates arms viewmodels, the other adds weapon think in case user switches to/from another weapon.
Code:
CTFPlayer.UpdateArms()
Updates all arm models for all equipped weapons. Branches from `GiveWeapon`.
CTFPlayer.AddThinkToViewModel()
Updates the think script on tf_viewmodel. Branches from `GiveWeapon`.
__________________