Difference between revisions of "Hand Viewmodels"

From Valve Developer Community
Jump to: navigation, search
m (Removed div style from code blocks, minor cleanup/formatting)
(added fix for mp games with rounds)
Line 86: Line 86:
  
 
{{note|This might not work perfectly on the {{As}} Alien Swarm branch since it does weird stuff sometimes with bone merging.}}
 
{{note|This might not work perfectly on the {{As}} Alien Swarm branch since it does weird stuff sometimes with bone merging.}}
 +
 +
 +
 +
=== Fix for MP games with round system ===
 +
If you are using this method for multiplayer and your game (mod) has rounds system, you will have to add your new viewmodel's entity name (in this tutorial it's "hand_viewmodel") into <code>s_PreserveEnts[]</code> array which is located in the gamerules file (hl2mp_gamerules.cpp for example) so it will look something like this:
 +
 +
<source lang=cpp>
 +
static const char *s_PreserveEnts[] =
 +
{
 +
"ai_network",
 +
"ai_hint",
 +
"hl2mp_gamerules",
 +
"team_manager",
 +
"player_manager",
 +
"env_soundscape",
 +
"env_soundscape_proxy",
 +
"env_soundscape_triggerable",
 +
"env_sun",
 +
"env_wind",
 +
"env_fog_controller",
 +
"func_brush",
 +
"func_wall",
 +
"func_buyzone",
 +
"func_illusionary",
 +
"infodecal",
 +
"info_projecteddecal",
 +
"info_node",
 +
"info_target",
 +
"info_node_hint",
 +
"info_player_deathmatch",
 +
"info_player_combine",
 +
"info_player_rebel",
 +
"info_map_parameters",
 +
"keyframe_rope",
 +
"move_rope",
 +
"info_ladder",
 +
"player",
 +
"point_viewcontrol",
 +
"scene_manager",
 +
"shadow_control",
 +
"sky_camera",
 +
"soundent",
 +
"trigger_soundscape",
 +
"viewmodel",
 +
"predicted_viewmodel",
 +
"hand_viewmodel", // our new viewmodel entity
 +
"worldspawn",
 +
"point_devshot_camera",
 +
"", // END Marker
 +
};
 +
</source>
 +
 +
If you don't do it, your hands viewmodel '''will be removed every time new round has started'''.
  
 
[[Category: Programming]][[Category: Tutorials]]
 
[[Category: Programming]][[Category: Tutorials]]

Revision as of 18:09, 15 June 2020

Have you ever wanted fancy c_ models like all those cool games? Well now you can!

Put this file in your shared folder or shared game folder.

handviewmodel_shared.cpp

#include "cbase.h"
#include "baseviewmodel_shared.h"

#if defined( CLIENT_DLL )
#define CHandViewModel C_HandViewModel
#endif

class CHandViewModel : public CBaseViewModel
{
	DECLARE_CLASS( CHandViewModel, CBaseViewModel );
public:
	DECLARE_NETWORKCLASS();
private:
};

LINK_ENTITY_TO_CLASS(hand_viewmodel, CHandViewModel);
IMPLEMENT_NETWORKCLASS_ALIASED(HandViewModel, DT_HandViewModel)

// for whatever reason the parent doesn't get sent 
// I don't really want to mess with the baseviewmodel
// so now it does
BEGIN_NETWORK_TABLE(CHandViewModel, DT_HandViewModel)
#ifndef CLIENT_DLL
SendPropEHandle(SENDINFO_NAME(m_hMoveParent, moveparent)),
#else
RecvPropInt(RECVINFO_NAME(m_hNetworkMoveParent, moveparent), 0, RecvProxy_IntToMoveParent),
#endif
END_NETWORK_TABLE()

I'd put something like this in your server/player.cpp or in your mod's server player.cpp below CreateViewModel.

server/player.cpp

void CBasePlayer::CreateHandModel(int index, int iOtherVm)
{
	Assert(index >= 0 && index < MAX_VIEWMODELS && iOtherVm >= 0 && iOtherVm < MAX_VIEWMODELS );

	if (GetViewModel(index))
		return;

	CBaseViewModel *vm = (CBaseViewModel *)CreateEntityByName("hand_viewmodel");
	if (vm)
	{
		vm->SetAbsOrigin(GetAbsOrigin());
		vm->SetOwner(this);
		vm->SetIndex(index);
		DispatchSpawn(vm);
		vm->FollowEntity(GetViewModel(iOtherVm), true);
		m_hViewModel.Set(index, vm);
	}
}

You should also add this to your server or mod's player.h below CreateViewModel.

server/player.h

virtual void	        CreateHandModel( int viewmodelindex = 1, int iOtherVm = 0 );

Now if you want this to actually work you're gonna need to call it. Call it sometime after CreateViewModel in either CBasePlayer or your mod's player spawn.

server/player.cpp

	CreateHandModel();

So now that the HandViewModel has been created we need to set its model. Put this in your mod's server's player's spawn sometime after the hand model has been created.

server/your_mod/your_player.cpp

	GetViewModel(1)->SetModel("models/coolhandsfolder/cool_arms.mdl");

Make sure your model has been precached first!

Note.png Note: This might not work perfectly on the Alien Swarm Alien Swarm branch since it does weird stuff sometimes with bone merging.


Fix for MP games with round system

If you are using this method for multiplayer and your game (mod) has rounds system, you will have to add your new viewmodel's entity name (in this tutorial it's "hand_viewmodel") into s_PreserveEnts[] array which is located in the gamerules file (hl2mp_gamerules.cpp for example) so it will look something like this:

static const char *s_PreserveEnts[] =
{
	"ai_network",
	"ai_hint",
	"hl2mp_gamerules",
	"team_manager",
	"player_manager",
	"env_soundscape",
	"env_soundscape_proxy",
	"env_soundscape_triggerable",
	"env_sun",
	"env_wind",
	"env_fog_controller",
	"func_brush",
	"func_wall",
	"func_buyzone",
	"func_illusionary",
	"infodecal",
	"info_projecteddecal",
	"info_node",
	"info_target",
	"info_node_hint",
	"info_player_deathmatch",
	"info_player_combine",
	"info_player_rebel",
	"info_map_parameters",
	"keyframe_rope",
	"move_rope",
	"info_ladder",
	"player",
	"point_viewcontrol",
	"scene_manager",
	"shadow_control",
	"sky_camera",
	"soundent",
	"trigger_soundscape",
	"viewmodel",
	"predicted_viewmodel",
	"hand_viewmodel", // our new viewmodel entity
	"worldspawn",
	"point_devshot_camera",
	"", // END Marker
};

If you don't do it, your hands viewmodel will be removed every time new round has started.