Raised This Month: $ Target: $400
 0% 

[TUT] 1 Player Model For All - The best anti-crash way


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Author Message
Jhob94
AMX Mod X Donor
Join Date: Jul 2012
Old 10-06-2023 , 09:25   [TUT] 1 Player Model For All - The best anti-crash way
Reply With Quote #1

The best anti-crash is using 1 player model for all player models. This will save you resources precached and avoid crashes on multiple model changes.

Here i will teach you how to use 1 Model and than play with Sub-Models. On plugin you will play with pev_body.

First on Model.
1. Create a Folder to gather all the player models.
2. Decompile all your models into that folder
3. Edit QC file of your main model
Code:
//reference mesh(es)
$bodygroup "studio"
{
studio "model1"
studio "model2"
studio "model3"
studio "model4"
}
4. Compile the model & it's done

Crucial Information:

- The model1/2/etc that we use on bodygroup can be named whatever you want but it must be the name of the main SMD file of the sub-model.
- Your models must be 1 Part only (unless the second part is the bomb/defuse). If your model is divided into several parts it won't work (at least i don't know how to make it work)



After everything is done properly you will have one player model with several sub-models. Now we can go to the plugin part.

Code:
#include <amxmodx>
#include <hamsandwich>
#include <fakemeta>
#include <cstrike>
#include <cl_buy>

#define TASKID 4256
#define MODEL_TASK 8425

new g_szModelName[] = "my_multimodel"

new g_iBody[33]

public plugin_init()
{
	RegisterHam(Ham_AddPlayerItem, "player", "Player__AddPlayerItem", true)
	RegisterHam(Ham_Spawn, "player", "Player__Spawn", true)
	
	register_forward(FM_SetClientKeyValue, "Fw__SetClientKeyValue")
	register_forward(FM_ClientUserInfoChanged, "Fw__ClientUserInfoChanged")
}

public plugin_precache()
{
	new szPlayerModel[64]
	formatex(szPlayerModel, charsmax(szPlayerModel), "models/player/%s/%s.mdl", g_szModelName, g_szModelName)
	
	if(file_exists(szPlayerModel))
		engfunc(EngFunc_PrecacheModel, szPlayerModel)
}

public client_putinserver(id)
	g_iBody[id] = 0

public Player__AddPlayerItem(id , iWeapon)
{
	if(cs_get_weapon_id(iWeapon) == CSW_C4)
		set_pev(id, pev_body, g_iBody[id])
}

// You can remove this if players can't buy on your server, including Task__FixBody function
public client_buy(id, iItem)
{
	if(iItem == CSW_DEFUSER && !cs_get_user_defuse(id))
		set_task(0.5, "Task__FixBody", id + TASKID)
}

public Task__FixBody(id)
{
	id -= TASKID
	
	if(is_user_alive(id))
		set_pev(id, pev_body, g_iBody[id])
}

public Player__Spawn(id)
{
	if(is_user_alive(id))
	{
		static currentmodel[32]
		engfunc(EngFunc_InfoKeyValue, engfunc(EngFunc_GetInfoKeyBuffer, id), "model", currentmodel, charsmax(currentmodel))
		
		if(!equal(currentmodel, g_szModelName))
			set_task(random_float(0.1, 2.9), "Task__SetModel", id + MODEL_TASK)
			
	/* Example:
		g_iBody[id] = cs_get_user_team(id) == CS_TEAM_CT ? 0 : 1
		
		You should set body on spawn & on events where you would change the player model. Like Zombie Plague infection
		After changing g_iBody you must change pev_body.
		The reason we are using g_iBody is because we need to store the information for when a player buys defuse kit or gets a bomb
		because that will mess with pev_body. So we either do this or a looping task to check the pev_body value. This way is better.
	*/
	}
}

public Task__SetModel(id)
{
	id -= MODEL_TASK
	
	if(is_user_alive(id))
	{
		engfunc(EngFunc_SetClientKeyValue, id, engfunc(EngFunc_GetInfoKeyBuffer, id), "model", g_szModelName)
		set_pev(id, pev_body, g_iBody[id])
	}
}

public Fw__SetClientKeyValue(id, const infobuffer[], const key[])
{   
	if(equal(key, "model") && !equal(infobuffer, g_szModelName))
		return FMRES_SUPERCEDE
		
	return FMRES_IGNORED
}

public Fw__ClientUserInfoChanged(id)
{
	static currentmodel[32]
	engfunc(EngFunc_InfoKeyValue, engfunc(EngFunc_GetInfoKeyBuffer, id), "model", currentmodel, charsmax(currentmodel))
	
	if(!equal(currentmodel, g_szModelName))
		engfunc(EngFunc_SetClientKeyValue, id, engfunc(EngFunc_GetInfoKeyBuffer, id), "model", g_szModelName)
		
	return FMRES_IGNORED
}
In that code you already change the player model, all you need to do is manipulate the g_iBody[index] and set the pev_body when you need to. You can also create a models menu.

The client_buy forward can be found here. You don't need to use it if your server doesn't allow the player to buy a defuse kit.
The bomb part should remain for safety since if a player gets the bomb it will change his pev_body.

Also you must NOT use plugins that use the cs_set_user_defuse native.
__________________

Last edited by Jhob94; 10-06-2023 at 09:28.
Jhob94 is offline
 



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 09:46.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode