Raised This Month: $ Target: $400
 0% 

[L4D/L4D2] Character Select Menu (2.5a/b)


Post New Thread Reply   
 
Thread Tools Display Modes
NeoTM
AlliedModders Donor
Join Date: Feb 2013
Location: Britain
Old 11-05-2021 , 03:43   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #851

HI!
I also used this plugin long time ago and didn't have problems with it (i think it was version b).
But today i'm using l4d_CreateSurvivorBot, l4d_survivor_identity_fix and [L4D2]The passing CSM fix.
I played the passing 2 times and didn't see anything wrong (or didn't noticed it).
__________________
82.66.75.218:27015 - Walk In Dead Nightmare
82.66.75.218:27016 - Walk In Dead Rampage
82.66.75.218:27017 - Walk In Dead Vanilla
NeoTM is offline
Darkness93
New Member
Join Date: Nov 2021
Old 11-06-2021 , 11:57   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #852

Quote:
Originally Posted by Gonzofred View Post
My Linux "CSM" (2.5b)
I have only changed the cvars and compiled that I must not write in the server.cfg. I have "nothing changed in the script.
Toggles access to L4D1 Survivors in L4D2 campaigns (8 Survivors available)
change L4D1 Characters in L4D1 Campaigns.
no announcement.
no infected access.
for coop and survival.
Maybe it could use somebody!?
Hey mate!

I'm quite a fan of your "l4dcsm_b" version Wondering if you've updated this since to add support for infected characters?

When I try them, I'm left in a T-Pose and the animations just play briefly after jumping.

In the meantime I'll use the latest standard csm plugin though from

https://forums.alliedmods.net/showpo...&postcount=831

Cheers!
Darkness93 is offline
TiTz
Member
Join Date: Jan 2020
Old 12-17-2021 , 11:32   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #853

Hi, I'm running a L4D1 server - I'm using Merudo's Survivor Chat Select 1.6.1 (Forked) https://forums.alliedmods.net/showth...63#post2399163
It was crashing my server so I removed all the L4D2 stuff and the fake zoey. This seems to have cured the problem.
although I still get the following error:

Code:
L 12/17/2021 - 16:10:31: [SM] Exception reported: Invalid convar handle 0 (error 4)
L 12/17/2021 - 16:10:31: [SM] Blaming: L4D_Mv_CSM.smx
L 12/17/2021 - 16:10:31: [SM] Call stack trace:
L 12/17/2021 - 16:10:31: [SM]   [0] SetConVarInt
L 12/17/2021 - 16:10:31: [SM]   [1] Line 142, plugin.sp::OnMapStart
Here's the edited source code:
HTML Code:
/*=======================================================================================
	Plugin Info:

*	Name	:	Survivor Chat Select
*	Author	:	mi123645
*	Descrp	:	This plugin allows players to change their character or model
*	Link	:	https://forums.alliedmods.net/showthread.php?t=107121

*   Edits by:   DeathChaos25
*	Descrp	:	Compatibility with fakezoey plugin added
*   Link    :   https://forums.alliedmods.net/showthread.php?t=258189

*   Edits by:   Cookie
*	Descrp	:	Support for cookies added

*   Edits by:   Merudo
*	Descrp	:	Fixed bugs with misplaced weapon models after selecting a survivor & added admin menu support (!sm_admin)
*   Link    :   "https://forums.alliedmods.net/showthread.php?p=2399150#post2399150"

========================================================================================*/
#pragma semicolon 1
#define PLUGIN_VERSION "1.6.1"  
#define PLUGIN_NAME "Survivor Chat Select"
#define PLUGIN_PREFIX 	"\x01[\x04SCS\x01]"

#include <sourcemod>  
#include <sdktools>  
#include <clientprefs>
#include <adminmenu>

#pragma newdecls required

TopMenu hTopMenu;

ConVar convarSpawn;
ConVar convarAdminsOnly;
ConVar convarCookies;

#define MODEL_BILL "models/survivors/survivor_namvet.mdl"
#define MODEL_ZOEY "models/survivors/survivor_teenangst.mdl" 
#define MODEL_FRANCIS "models/survivors/survivor_biker.mdl" 
#define MODEL_LOUIS "models/survivors/survivor_manager.mdl"

#define     BILL     	0
#define     ZOEY     	1
#define     FRANCIS     2
#define     LOUIS     	3

int    g_iSelectedClient[MAXPLAYERS+1];
Handle g_hClientID;
Handle g_hClientModel;

public Plugin myinfo =  
{  
	name = PLUGIN_NAME,  
	author = "DeatChaos25, Mi123456 & Merudo",  
	description = "Select a survivor character by typing their name into the chat.",  
	version = PLUGIN_VERSION,
	url = "https://forums.alliedmods.net/showthread.php?p=2399163#post2399163"
}  

public void OnPluginStart()  
{  
	g_hClientID 	= RegClientCookie("Player_Character", "Player's default character ID.", CookieAccess_Protected);
	g_hClientModel  = RegClientCookie("Player_Model", "Player's default character model.", CookieAccess_Protected);

	RegConsoleCmd("sm_zoey", ZoeyUse, "Changes your survivor character into Zoey");  
	RegConsoleCmd("sm_bill", BillUse, "Changes your survivor character into Bill");  
	RegConsoleCmd("sm_francis", BikerUse, "Changes your survivor character into Francis");  
	RegConsoleCmd("sm_louis", LouisUse, "Changes your survivor character into Louis");  
	
	RegConsoleCmd("sm_z", ZoeyUse, "Changes your survivor character into Zoey");  
	RegConsoleCmd("sm_b", BillUse, "Changes your survivor character into Bill");  
	RegConsoleCmd("sm_f", BikerUse, "Changes your survivor character into Francis");  
	RegConsoleCmd("sm_l", LouisUse, "Changes your survivor character into Louis");  
	
	RegAdminCmd("sm_csc", InitiateMenuAdmin, ADMFLAG_GENERIC, "Brings up a menu to select a client's character"); 
	RegConsoleCmd("sm_csm", ShowMenu, "Brings up a menu to select a client's character"); 
	
	HookEvent("player_spawn", Event_PlayerSpawn, EventHookMode_Post);
	HookEvent("player_bot_replace", Event_PlayerToBot, EventHookMode_Post);

	convarAdminsOnly = CreateConVar("l4d_csm_admins_only", "1","Changes access to the sm_csm command. 1 = Admin access only.",FCVAR_NOTIFY,true, 0.0, true, 1.0);	
	convarSpawn		 = CreateConVar("l4d_scs_botschange", "1","Change new bots to least prevalent survivor? 1:Enable, 0:Disable",FCVAR_NOTIFY,true, 0.0, true, 1.0);
	convarCookies	 = CreateConVar("l4d_scs_cookies", "1","Store player's survivor? 1:Enable, 0:Disable",FCVAR_NOTIFY,true, 0.0, true, 1.0);
	
	AutoExecConfig(true, "l4dscs");
	
	/* Account for late loading */
	TopMenu topmenu;
	if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != null))
	{
		OnAdminMenuReady(topmenu);
	}
}  
// *********************************************************************************
// Character Select functions
// *********************************************************************************	
public Action ZoeyUse(int client, int args)  
{  
	SurvivorChange(client, ZOEY, MODEL_ZOEY, "Zoey"); 
}  
public Action BillUse(int client, int args)  
{  
	SurvivorChange(client, BILL, MODEL_BILL, "Bill");
}  
public Action BikerUse(int client, int args)  
{  
	SurvivorChange(client, FRANCIS, MODEL_FRANCIS, "Francis");
}  
public Action LouisUse(int client, int args)  
{  
	SurvivorChange(client, LOUIS, MODEL_LOUIS, "Louis");
}

// Function changes the survivor
void SurvivorChange(int client, int prop, char[] model,  char[] name, bool save = true)
{
	if( client == 0		)  { PrintToServer("You must be in the survivor team to use this command!"); return;}
	if(!IsSurvivor(client)){ PrintToChat(client, "You must be in the survivor team to use this command!"); 	return; }

	if (IsFakeClient(client))  // if bot, change name
	{
		SetClientInfo(client, "name", name);
	}
	
	SetEntProp(client, Prop_Send, "m_survivorCharacter", prop);  
	SetEntityModel(client, model);
	ReEquipWeapons(client);
	
	if (convarCookies.BoolValue && save)
	{
		char sprop[2]; IntToString(prop, sprop, 2);
		SetClientCookie(client, g_hClientID, sprop);
		SetClientCookie(client, g_hClientModel, model);
		PrintToChat(client, "%s Your \x05default \x01character is now set to \x03%s\x01.", PLUGIN_PREFIX, name); 
	}
}	
public void OnMapStart()
{     
	SetConVarInt(FindConVar("precache_all_survivors"), 1); 
	
	if (!IsModelPrecached("models/survivors/survivor_teenangst.mdl"))    PrecacheModel("models/survivors/survivor_teenangst.mdl", false); 
	if (!IsModelPrecached("models/survivors/survivor_biker.mdl"))     PrecacheModel("models/survivors/survivor_biker.mdl", false); 
	if (!IsModelPrecached("models/survivors/survivor_manager.mdl"))    PrecacheModel("models/survivors/survivor_manager.mdl", false); 
	if (!IsModelPrecached("models/survivors/survivor_namvet.mdl"))     PrecacheModel("models/survivors/survivor_namvet.mdl", false); 
} 

bool IsSurvivor(int client)
{
	if(client > 0 && client <= MaxClients && IsClientInGame(client) && GetClientTeam(client) == 2)
	{
		return true;
	}
	return false;
}

// *********************************************************************************
// Character Select menu
// *********************************************************************************	

/* This Admin Menu was taken from csm, all credits go to Mi123645 */ 
public Action InitiateMenuAdmin(int client, int args)  
{ 
	if (client == 0)  
	{ 
		ReplyToCommand(client, "Menu is in-game only."); 
		return; 
	} 
	
	char name[MAX_NAME_LENGTH]; char number[10]; 
	
	Handle menu = CreateMenu(ShowMenu2);
	SetMenuTitle(menu, "Select a client:"); 
	
	for (int i = 1; i <= MaxClients; i++) 
	{ 
		if (!IsClientInGame(i)) continue; 
		if (GetClientTeam(i) != 2) continue; 
		//if (i == client) continue; 
		
		Format(name, sizeof(name), "%N", i); 
		Format(number, sizeof(number), "%i", i); 
		AddMenuItem(menu, number, name); 
	} 
	
	
	SetMenuExitButton(menu, true); 
	DisplayMenu(menu, client, MENU_TIME_FOREVER); 
} 

public int ShowMenu2(Handle menu, MenuAction action, int client, int param2)  
{ 
	switch (action)  
	{ 
		case MenuAction_Select:  
		{ 
			char number[4]; 
			GetMenuItem(menu, param2, number, sizeof(number)); 
			
			g_iSelectedClient[client] = StringToInt(number); 

			ShowMenuAdmin(client, 0); 
		} 
		case MenuAction_Cancel: 
		{ 
			if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
			{
				DisplayTopMenu(hTopMenu, client, TopMenuPosition_LastCategory);
			}			
		} 
		case MenuAction_End:  
		{ 
			CloseHandle(menu); 
		} 
	} 
} 

public Action ShowMenuAdmin(int client, int args)  
{ 
	char sMenuEntry[4]; 
	
	Handle menu = CreateMenu(CharMenuAdmin); 
	SetMenuTitle(menu, "Choose a character:"); 
	
	IntToString(BILL, sMenuEntry, sizeof(sMenuEntry)); 
	AddMenuItem(menu, sMenuEntry, "Bill");     
	IntToString(ZOEY, sMenuEntry, sizeof(sMenuEntry)); 
	AddMenuItem(menu, sMenuEntry, "Zoey"); 
	IntToString(FRANCIS, sMenuEntry, sizeof(sMenuEntry)); 
	AddMenuItem(menu, sMenuEntry, "Francis"); 
	IntToString(LOUIS, sMenuEntry, sizeof(sMenuEntry)); 
	AddMenuItem(menu, sMenuEntry, "Louis"); 
	
	SetMenuExitButton(menu, true); 
	DisplayMenu(menu, client, MENU_TIME_FOREVER); 
} 

public int CharMenuAdmin(Handle menu, MenuAction action, int client, int param2)  
{ 
	switch (action)  
	{ 
		case MenuAction_Select:  
		{ 
			char item[4]; 
			GetMenuItem(menu, param2, item, sizeof(item)); 
			
			switch(StringToInt(item))  
			{

				case BILL:        {    SurvivorChange(g_iSelectedClient[client],        BILL, MODEL_BILL,    "Bill",false);    }
				case ZOEY:        {    SurvivorChange(g_iSelectedClient[client],        ZOEY, MODEL_ZOEY,    "Zoey",false);    }  
				case FRANCIS:     {    SurvivorChange(g_iSelectedClient[client],        FRANCIS, MODEL_FRANCIS, "Francis",false); }  
				case LOUIS:       {    SurvivorChange(g_iSelectedClient[client],        LOUIS, MODEL_LOUIS,   "Louis", false);   }
			} 
		} 
		case MenuAction_Cancel: { } 
		case MenuAction_End:    {CloseHandle(menu); } 
	} 
} 

public Action ShowMenu(int client, int args) 
{
	if (client == 0) 
	{
		ReplyToCommand(client, "[SCS] Character Select Menu is in-game only.");
		return;
	}
	if (GetClientTeam(client) != 2)
	{
		ReplyToCommand(client, "[SCS] Character Select Menu is only available to survivors.");
		return;
	}
	if (!IsPlayerAlive(client)) 
	{
		ReplyToCommand(client, "[SCS] You must be alive to use the Character Select Menu!");
		return;
	}
	if (GetUserFlagBits(client) == 0 && convarAdminsOnly.BoolValue)
	{
		ReplyToCommand(client, "[SCS] Character Select Menu is only available to admins.");
		return;
	}
	char sMenuEntry[4];
	
	Handle menu = CreateMenu(CharMenu);
	SetMenuTitle(menu, "Choose a character:");
	
	IntToString(BILL, sMenuEntry, sizeof(sMenuEntry));
	AddMenuItem(menu, sMenuEntry, "Bill");    
	IntToString(ZOEY, sMenuEntry, sizeof(sMenuEntry));
	AddMenuItem(menu, sMenuEntry, "Zoey");
	IntToString(FRANCIS, sMenuEntry, sizeof(sMenuEntry));
	AddMenuItem(menu, sMenuEntry, "Francis");
	IntToString(LOUIS, sMenuEntry, sizeof(sMenuEntry));
	AddMenuItem(menu, sMenuEntry, "Louis");
	
	SetMenuExitButton(menu, true);
	DisplayMenu(menu, client, MENU_TIME_FOREVER);
}

public int CharMenu(Handle menu, MenuAction action, int param1, int param2) 
{
	switch (action) 
	{
		case MenuAction_Select: 
		{
			char item[4];
			GetMenuItem(menu, param2, item, sizeof(item));
			
			switch(StringToInt(item)) 
			{
				case BILL:        {    BillUse(param1, BILL);        }
				case ZOEY:        {    ZoeyUse(param1, ZOEY);        }
				case FRANCIS:    {    BikerUse(param1, FRANCIS);    }
				case LOUIS:        {    LouisUse(param1, LOUIS);        }
				
			}
		}
		case MenuAction_Cancel:
		{
			
		}
		case MenuAction_End: 
		{
			CloseHandle(menu);
		}
	}
}

// *********************************************************************************
// Admin Menu entry
// *********************************************************************************

//// Added for admin menu
public void OnAdminMenuReady(Handle aTopMenu)
{
	TopMenu topmenu = TopMenu.FromHandle(aTopMenu);

	/* Block us from being called twice */
	if (topmenu == hTopMenu)
	{
		return;
	}
	
	/* Save the Handle */
	hTopMenu = topmenu;
	
	// Find player's menu ...
	TopMenuObject player_commands = hTopMenu.FindCategory(ADMINMENU_PLAYERCOMMANDS);

	if (player_commands != INVALID_TOPMENUOBJECT)
	{
		AddToTopMenu (hTopMenu, "Select player's survivor", TopMenuObject_Item, InitiateMenuAdmin2, player_commands, "Select player's survivor", ADMFLAG_GENERIC);
	}
}

public void InitiateMenuAdmin2(Handle topmenu, TopMenuAction action, TopMenuObject object_id, int client, char[] buffer, int maxlength)
{
	if (action == TopMenuAction_DisplayOption)
	{
		Format(buffer, maxlength, "Select player's survivor", "", client);
	}
	else if (action == TopMenuAction_SelectOption)
	{
		InitiateMenuAdmin(client, 0);
	}
}
// *********************************************************************************
// Cookie loading
// *********************************************************************************

public void Event_PlayerSpawn(Handle event, const char[] name, bool dontBroadcast)
{
	int client = GetClientOfUserId(GetEventInt(event, "userid"));
	if(client && IsClientInGame(client) && !IsFakeClient(client) && GetClientTeam(client) == 2 && convarCookies.BoolValue)
	{
		CreateTimer(0.3, Timer_LoadCookie, GetClientUserId(client));
	}
}

public Action Timer_LoadCookie(Handle timer, int userid)
{
	int client = GetClientOfUserId(userid);
	char sID[2]; char sModel[64];

	if(client && IsClientInGame(client) && !IsFakeClient(client) && GetClientTeam(client) == 2 && convarCookies.BoolValue && AreClientCookiesCached(client))
	{
		GetClientCookie(client, g_hClientID, sID, sizeof(sID));
		GetClientCookie(client, g_hClientModel, sModel, sizeof(sModel));
	
		if(strlen(sID) && strlen(sModel))
		{
			SetEntProp(client, Prop_Send, "m_survivorCharacter", StringToInt(sID)); 
			SetEntityModel(client, sModel); 
		}
	}
	else if (client) { PrintToChat(client, "%s Couldn't load your default character. Type \x05!csm \x01to choose your \x03default \x01character.", PLUGIN_PREFIX);}
}

// *********************************************************************************
// Bots spawn as survivor with fewest clones
// *********************************************************************************

char survivor_models[4][] = { MODEL_BILL,  MODEL_ZOEY,	MODEL_FRANCIS, MODEL_LOUIS };
char survivor_commands[4][] = { "sm_bill", "sm_zoey", "sm_francis", "sm_louis"};

public Action Event_PlayerToBot(Handle event, char[] name, bool dontBroadcast)
{
	int player = GetClientOfUserId(GetEventInt(event, "player"));
	int bot    = GetClientOfUserId(GetEventInt(event, "bot")); 

	// If bot replace bot (due to bot creation)
	if(player > 0 && GetClientTeam(player)== 2  &&  IsFakeClient(player) && convarSpawn.BoolValue) 
	{
		FakeClientCommand(bot, survivor_commands[GetFewestSurvivor(bot)]);
	}
}

int GetFewestSurvivor(int clientignore = -1) 
{
	char Model[128];
	int Survivors[4];

	for (int client=1; client <= MaxClients; client++)
	{
		if (IsClientInGame(client) && GetClientTeam(client) == 2 && client != clientignore)
		{
			GetClientModel(client, Model, 128);
			for (int s = 0; s < 4; s++)
			{
				if (StrEqual(Model, survivor_models[s])) Survivors[s] = Survivors[s] + 1;
			}		
		}
	}
	
	int minS = 1;
	int min  = 9999;
	
	for (int s = 0; s < 4; s++)
	{
		if (Survivors[s] < min) 
		{
			minS = s;
			min  = Survivors[s];
		}
	}
	return minS;
}



// *********************************************************************************
// Reequip weapons functions
// *********************************************************************************

enum()
{
	iClip = 0,
	iAmmo,
	iUpgrade,
	iUpAmmo,
};

// ------------------------------------------------------------------
// Save weapon details, remove weapon, create new weapons with exact same properties
// Needed otherwise there will be animation bugs after switching characters due to different weapon mount points
// ------------------------------------------------------------------
void ReEquipWeapons(int client)
{
	int i_Weapon = GetEntDataEnt2(client, FindSendPropInfo("CBasePlayer", "m_hActiveWeapon"));
	
	// Don't bother with the weapon fix if dead or unarmed
	if (!IsPlayerAlive(client) || !IsValidEdict(i_Weapon) || !IsValidEntity(i_Weapon))  return;

	int iSlot0 = GetPlayerWeaponSlot(client, 0);  	int iSlot1 = GetPlayerWeaponSlot(client, 1);	
	int iSlot2 = GetPlayerWeaponSlot(client, 2);  	int iSlot3 = GetPlayerWeaponSlot(client, 3);
	int iSlot4 = GetPlayerWeaponSlot(client, 4);  	

	
	char sWeapon[64];
	GetClientWeapon(client, sWeapon, sizeof(sWeapon));
	
	//  Protection against grenade duplication exploit (throwing grenade then quickly changing character)
	if (iSlot2 > 0 && strcmp(sWeapon, "weapon_vomitjar", true) && strcmp(sWeapon, "weapon_pipe_bomb", true) && strcmp(sWeapon, "weapon_molotov", true ))
	{
		GetEdictClassname(iSlot2, sWeapon, 64);
		DeletePlayerSlot(client, iSlot2);
		CheatCommand(client, "give", sWeapon, "");
	}
	if (iSlot3 > 0)
	{
		GetEdictClassname(iSlot3, sWeapon, 64);
		DeletePlayerSlot(client, iSlot3);
		CheatCommand(client, "give", sWeapon, "");
	}
	if (iSlot4 > 0)
	{
		GetEdictClassname(iSlot4, sWeapon, 64);
		DeletePlayerSlot(client, iSlot4);
		CheatCommand(client, "give", sWeapon, "");
	}
	if (iSlot1 > 0) ReEquipSlot1(client, iSlot1);
	if (iSlot0 > 0) ReEquipSlot0(client, iSlot0);
}

// --------------------------------------
// Extra work to save/load ammo details
// --------------------------------------	
void ReEquipSlot0(int client, int iSlot0)
{
	int iWeapon0[4];
	char sWeapon[64];
	
	GetEdictClassname(iSlot0, sWeapon, 64);
		
	iWeapon0[iClip] = GetEntProp(iSlot0, Prop_Send, "m_iClip1", 4);
	iWeapon0[iAmmo] = GetClientAmmo(client, sWeapon);
//	iWeapon0[iUpgrade] = GetEntProp(iSlot0, Prop_Send, "m_upgradeBitVec", 4);
	iWeapon0[iUpAmmo]  = GetEntProp(iSlot0, Prop_Send, "m_nUpgradedPrimaryAmmoLoaded", 4);
		
	DeletePlayerSlot(client, iSlot0);
	CheatCommand(client, "give", sWeapon, "");
		
	iSlot0 = GetPlayerWeaponSlot(client, 0);
	if (iSlot0 > 0)
	{
		SetEntProp(iSlot0, Prop_Send, "m_iClip1", iWeapon0[iClip], 4);
		SetClientAmmo(client, sWeapon, iWeapon0[iAmmo]);
//		SetEntProp(iSlot0, Prop_Send, "m_upgradeBitVec", iWeapon0[iUpgrade], 4);
		SetEntProp(iSlot0, Prop_Send, "m_nUpgradedPrimaryAmmoLoaded", iWeapon0[iUpAmmo], 4);
	}			
}

// --------------------------------------
// Extra work to identify melee weapon, & save/load ammo details
// --------------------------------------
void ReEquipSlot1(int client, int iSlot1)
{
	char className[64];
	char modelName[64];
	
	char sWeapon[64]; 	sWeapon[0] = '\0'  ;
	int Ammo = -1;
	int iSlot = -1;
	
	GetEdictClassname(iSlot1, className, sizeof(className));
	
	// Try to find weapon name without models
	if 		(!strcmp(className, "weapon_melee", true))   GetEntPropString(iSlot1, Prop_Data, "m_strMapSetScriptName", sWeapon, 64);
	else if (strcmp(className, "weapon_pistol", true))   GetEdictClassname(iSlot1, sWeapon, 64);
	
	// IF model checking is required
	if (sWeapon[0] == '\0')
	{
		GetEntPropString(iSlot1, Prop_Data, "m_ModelName", modelName, sizeof(modelName));

		if 		(StrContains(modelName, "v_pistolA.mdl",         true) != -1)	sWeapon = "weapon_pistol";
		else if (StrContains(modelName, "v_dual_pistolA.mdl",    true) != -1)	sWeapon = "dual_pistol";
		else if (StrContains(modelName, "v_desert_eagle.mdl",    true) != -1)	sWeapon = "weapon_pistol_magnum";
		else if (StrContains(modelName, "v_bat.mdl",             true) != -1)	sWeapon = "baseball_bat";
		else if (StrContains(modelName, "v_cricket_bat.mdl",     true) != -1)	sWeapon = "cricket_bat";
		else if (StrContains(modelName, "v_crowbar.mdl",         true) != -1)	sWeapon = "crowbar";
		else if (StrContains(modelName, "v_fireaxe.mdl",         true) != -1)	sWeapon = "fireaxe";
		else if (StrContains(modelName, "v_katana.mdl",          true) != -1)	sWeapon = "katana";
		else if (StrContains(modelName, "v_golfclub.mdl",        true) != -1)	sWeapon = "golfclub";
		else if (StrContains(modelName, "v_machete.mdl",         true) != -1)	sWeapon = "machete";
		else if (StrContains(modelName, "v_tonfa.mdl",           true) != -1)	sWeapon = "tonfa";
		else if (StrContains(modelName, "v_electric_guitar.mdl", true) != -1)	sWeapon = "electric_guitar";
		else if (StrContains(modelName, "v_frying_pan.mdl",      true) != -1)	sWeapon = "frying_pan";
		else if (StrContains(modelName, "v_knife_t.mdl",         true) != -1)	sWeapon = "knife";
		else if (StrContains(modelName, "v_chainsaw.mdl",        true) != -1)	sWeapon = "weapon_chainsaw";
		else if (StrContains(modelName, "v_riotshield.mdl",      true) != -1)	sWeapon = "alliance_shield";
		else if (StrContains(modelName, "v_fubar.mdl",           true) != -1)	sWeapon = "fubar";
		else if (StrContains(modelName, "v_paintrain.mdl",       true) != -1)	sWeapon = "nail_board";
		else if (StrContains(modelName, "v_sledgehammer.mdl",    true) != -1)	sWeapon = "sledgehammer";
	}

	// IF Weapon properly identified, save then delete then reequip
	if (sWeapon[0] != '\0')
	{
		// IF Weapon uses ammo, save it
		if (!strcmp(sWeapon, "dual_pistol", true)   || !strcmp(sWeapon, "weapon_pistol", true)
		|| !strcmp(sWeapon, "weapon_pistol_magnum", true) || !strcmp(sWeapon, "weapon_chainsaw", true))
		{
			Ammo = GetEntProp(iSlot1, Prop_Send, "m_iClip1", 4);
		}	
	
		DeletePlayerSlot(client, iSlot1);
		
		// Reequip weapon (special code for dual pistols)
		if (!strcmp(sWeapon, "dual_pistol", true))
		{
			 CheatCommand(client, "give", "weapon_pistol", "");
			 CheatCommand(client, "give", "weapon_pistol", "");
		}
		else CheatCommand(client, "give", sWeapon, "");
		
		// Restore ammo
		if (Ammo >= 0)
		{
			iSlot = GetPlayerWeaponSlot(client, 1);
			if (iSlot > 0) SetEntProp(iSlot, Prop_Send, "m_iClip1", Ammo, 4);
		}
	}
}

void DeletePlayerSlot(int client, int weapon)
{		
	if(RemovePlayerItem(client, weapon)) AcceptEntityInput(weapon, "Kill");
}

void CheatCommand(int client, const char[] command, const char[] argument1, const char[] argument2)
{
	int userFlags = GetUserFlagBits(client);
	SetUserFlagBits(client, ADMFLAG_ROOT);
	int flags = GetCommandFlags(command);
	SetCommandFlags(command, flags & ~FCVAR_CHEAT);
	FakeClientCommand(client, "%s %s %s", command, argument1, argument2);
	SetCommandFlags(command, flags);
	SetUserFlagBits(client, userFlags);
}

// *********************************************************************************
// Get/Set ammo
// *********************************************************************************

int GetClientAmmo(int client, char[] weapon)
{
	int weapon_offset = GetWeaponOffset(weapon);
	int iAmmoOffset = FindSendPropInfo("CTerrorPlayer", "m_iAmmo");
	
	return weapon_offset > 0 ? GetEntData(client, iAmmoOffset+weapon_offset) : 0;
}

void SetClientAmmo(int client, char[] weapon, int count)
{
	int weapon_offset = GetWeaponOffset(weapon);
	int iAmmoOffset = FindSendPropInfo("CTerrorPlayer", "m_iAmmo");
	
	if (weapon_offset > 0) SetEntData(client, iAmmoOffset+weapon_offset, count);
}

int GetWeaponOffset(char[] weapon)
{
	int weapon_offset;

	if (StrEqual(weapon, "weapon_rifle") || StrEqual(weapon, "weapon_rifle_sg552") || StrEqual(weapon, "weapon_rifle_desert") || StrEqual(weapon, "weapon_rifle_ak47"))
	{
		weapon_offset = 12;
	}
	else if (StrEqual(weapon, "weapon_rifle_m60"))
	{
		weapon_offset = 24;
	}
	else if (StrEqual(weapon, "weapon_smg") || StrEqual(weapon, "weapon_smg_silenced") || StrEqual(weapon, "weapon_smg_mp5"))
	{
		weapon_offset = 20;
	}
	else if (StrEqual(weapon, "weapon_pumpshotgun") || StrEqual(weapon, "weapon_shotgun_chrome"))
	{
		weapon_offset = 28;
	}
	else if (StrEqual(weapon, "weapon_autoshotgun") || StrEqual(weapon, "weapon_shotgun_spas"))
	{
		weapon_offset = 32;
	}
	else if (StrEqual(weapon, "weapon_hunting_rifle"))
	{
		weapon_offset = 36;
	}
	else if (StrEqual(weapon, "weapon_sniper_scout") || StrEqual(weapon, "weapon_sniper_military") || StrEqual(weapon, "weapon_sniper_awp"))
	{
		weapon_offset = 40;
	}
	else if (StrEqual(weapon, "weapon_grenade_launcher"))
	{
		weapon_offset = 68;
	}

	return weapon_offset;
}
I have limited knowledge and writing code - so would very much appreciate someone having a look to see what the issue is.

Many thanks

TiTz
Attached Files
File Type: sp Get Plugin or Get Source (L4D_Mv_CSM.sp - 161 views - 23.4 KB)

Last edited by TiTz; 12-17-2021 at 11:34. Reason: added a link
TiTz is offline
Marttt
Veteran Member
Join Date: Jan 2019
Location: Brazil
Old 12-17-2021 , 11:57   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #854

For L4D1 you can simply remove the "OnMapStart" part

This cvar don't exist in L4D1
__________________

Last edited by Marttt; 12-17-2021 at 16:12.
Marttt is offline
TiTz
Member
Join Date: Jan 2020
Old 12-17-2021 , 13:29   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #855

Quote:
Originally Posted by Marttt View Post
For L4D1 you can simply remove the "OnMapStart" part

or change the line to

PHP Code:
if (GetEngineVersion() == Engine_Left4DeadFindConVar("precache_all_survivors"), 1); 
This cvar don't exist in L4D1
Thanks for helping Marttt really appreciate it

I tried omitting the start map "OnMapStart" part like so
Code:
}	
public void 
{     
SetConVarInt(FindConVar("precache_all_survivors"), 1); 

	if (!IsModelPrecached("models/survivors/survivor_teenangst.mdl"))    PrecacheModel("models/survivors/survivor_teenangst.mdl", false); 
	if (!IsModelPrecached("models/survivors/survivor_biker.mdl"))     PrecacheModel("models/survivors/survivor_biker.mdl", false); 
	if (!IsModelPrecached("models/survivors/survivor_manager.mdl"))    PrecacheModel("models/survivors/survivor_manager.mdl", false); 
	if (!IsModelPrecached("models/survivors/survivor_namvet.mdl"))     PrecacheModel("models/survivors/survivor_namvet.mdl", false); 
}
but when compiling i got

Code:
SourcePawn Compiler 1.10
Copyright (c) 1997-2006 ITB CompuPhase
Copyright (c) 2004-2018 AlliedModders LLC

plugin.sp(140) : error 001: expected token: "-identifier-", but found "{"
plugin.sp(145) : error 010: invalid function or declaration
plugin.sp(146) : error 010: invalid function or declaration
plugin.sp(147) : error 010: invalid function or declaration
plugin.sp(148) : error 010: invalid function or declaration

5 Errors.
so then I tried:
Code:
}	
public void OnMapStart()
{     
if (GetEngineVersion() == Engine_Left4Dead) FindConVar("precache_all_survivors"), 1);
	
	if (!IsModelPrecached("models/survivors/survivor_teenangst.mdl"))    PrecacheModel("models/survivors/survivor_teenangst.mdl", false); 
	if (!IsModelPrecached("models/survivors/survivor_biker.mdl"))     PrecacheModel("models/survivors/survivor_biker.mdl", false); 
	if (!IsModelPrecached("models/survivors/survivor_manager.mdl"))    PrecacheModel("models/survivors/survivor_manager.mdl", false); 
	if (!IsModelPrecached("models/survivors/survivor_namvet.mdl"))     PrecacheModel("models/survivors/survivor_namvet.mdl", false); 
}
but got these compiling errors:
Code:
SourcePawn Compiler 1.10
Copyright (c) 1997-2006 ITB CompuPhase
Copyright (c) 2004-2018 AlliedModders LLC

plugin.sp(141) : warning 215: expression has no effect
plugin.sp(141) : error 001: expected token: ";", but found ")"
plugin.sp(141) : error 029: invalid expression, assumed zero
plugin.sp(141) : warning 215: expression has no effect
plugin.sp(143) : warning 217: loose indentation

2 Errors.
More than likely i've just pasted it to the wrong place ...
TiTz is offline
Marttt
Veteran Member
Join Date: Jan 2019
Location: Brazil
Old 12-17-2021 , 16:13   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #856

Sorry mistyped cause I was on hurry

change OnMapStart to:

PHP Code:
public void OnMapStart()
{
    if (
GetEngineVersion() == Engine_Left4Dead2SetConVarInt(FindConVar("precache_all_survivors"), 1);

    if (!
IsModelPrecached("models/survivors/survivor_teenangst.mdl"))    PrecacheModel("models/survivors/survivor_teenangst.mdl"false);
    if (!
IsModelPrecached("models/survivors/survivor_biker.mdl"))     PrecacheModel("models/survivors/survivor_biker.mdl"false);
    if (!
IsModelPrecached("models/survivors/survivor_manager.mdl"))    PrecacheModel("models/survivors/survivor_manager.mdl"false);
    if (!
IsModelPrecached("models/survivors/survivor_namvet.mdl"))     PrecacheModel("models/survivors/survivor_namvet.mdl"false);

__________________

Last edited by Marttt; 12-18-2021 at 09:54.
Marttt is offline
TiTz
Member
Join Date: Jan 2020
Old 12-17-2021 , 17:05   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #857

No worries!
Great Thank-you Marttt - all seems to be working fine now - no errors and so far no server crash.
I edited the selection menu for just Bill, Zoey, Francis and Louis. So if anyone needs a L4D1 only version - this is it.

All the best

TiTz
TiTz is offline
TiTz
Member
Join Date: Jan 2020
Old 12-17-2021 , 17:40   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #858

Hi Marttt, Bit premature --- more errors have come up

When I swap models - i get errors

Also some info - i'm using [L4D1] Multiple Equipments https://forums.alliedmods.net/showthread.php?p=2639385



Code:
L 12/17/2021 - 22:08:10: SourceMod error session started
L 12/17/2021 - 22:08:10: Info (map "l4d_airport01_greenhouse") (file "D:\servl4dt1\left4dead\addons\sourcemod\logs\errors_20211217.log")
L 12/17/2021 - 22:08:10: [SM] Exception reported: Property "m_nUpgradedPrimaryAmmoLoaded" not found (entity 488/weapon_hunting_rifle)
L 12/17/2021 - 22:08:10: [SM] Blaming: L4D_Mv_CSM.smx
L 12/17/2021 - 22:08:10: [SM] Call stack trace:
L 12/17/2021 - 22:08:10: [SM]   [0] GetEntProp
L 12/17/2021 - 22:08:10: [SM]   [1] Line 520, /home/forums/content/files/2/9/0/3/2/7/192700.attach::ReEquipSlot0
L 12/17/2021 - 22:08:10: [SM]   [2] Line 504, /home/forums/content/files/2/9/0/3/2/7/192700.attach::ReEquipWeapons
L 12/17/2021 - 22:08:10: [SM]   [3] Line 129, /home/forums/content/files/2/9/0/3/2/7/192700.attach::SurvivorChange
L 12/17/2021 - 22:08:10: [SM]   [4] Line 101, /home/forums/content/files/2/9/0/3/2/7/192700.attach::ZoeyUse
L 12/17/2021 - 22:08:16: [SM] Exception reported: Property "m_nUpgradedPrimaryAmmoLoaded" not found (entity 488/weapon_hunting_rifle)
L 12/17/2021 - 22:08:16: [SM] Blaming: L4D_Mv_CSM.smx
L 12/17/2021 - 22:08:16: [SM] Call stack trace:
L 12/17/2021 - 22:08:16: [SM]   [0] GetEntProp
L 12/17/2021 - 22:08:16: [SM]   [1] Line 520, /home/forums/content/files/2/9/0/3/2/7/192700.attach::ReEquipSlot0
L 12/17/2021 - 22:08:16: [SM]   [2] Line 504, /home/forums/content/files/2/9/0/3/2/7/192700.attach::ReEquipWeapons
L 12/17/2021 - 22:08:16: [SM]   [3] Line 129, /home/forums/content/files/2/9/0/3/2/7/192700.attach::SurvivorChange
L 12/17/2021 - 22:08:16: [SM]   [4] Line 109, /home/forums/content/files/2/9/0/3/2/7/192700.attach::BikerUse
L 12/17/2021 - 22:08:25: [SM] Exception reported: Property "m_nUpgradedPrimaryAmmoLoaded" not found (entity 488/weapon_hunting_rifle)
L 12/17/2021 - 22:08:25: [SM] Blaming: L4D_Mv_CSM.smx
L 12/17/2021 - 22:08:25: [SM] Call stack trace:
L 12/17/2021 - 22:08:25: [SM]   [0] GetEntProp
L 12/17/2021 - 22:08:25: [SM]   [1] Line 520, /home/forums/content/files/2/9/0/3/2/7/192700.attach::ReEquipSlot0
L 12/17/2021 - 22:08:25: [SM]   [2] Line 504, /home/forums/content/files/2/9/0/3/2/7/192700.attach::ReEquipWeapons
L 12/17/2021 - 22:08:25: [SM]   [3] Line 129, /home/forums/content/files/2/9/0/3/2/7/192700.attach::SurvivorChange
L 12/17/2021 - 22:08:25: [SM]   [4] Line 113, /home/forums/content/files/2/9/0/3/2/7/192700.attach::LouisUse
L 12/17/2021 - 22:08:32: [SM] Exception reported: Property "m_nUpgradedPrimaryAmmoLoaded" not found (entity 488/weapon_hunting_rifle)
L 12/17/2021 - 22:08:32: [SM] Blaming: L4D_Mv_CSM.smx
L 12/17/2021 - 22:08:32: [SM] Call stack trace:
L 12/17/2021 - 22:08:32: [SM]   [0] GetEntProp
L 12/17/2021 - 22:08:32: [SM]   [1] Line 520, /home/forums/content/files/2/9/0/3/2/7/192700.attach::ReEquipSlot0
L 12/17/2021 - 22:08:32: [SM]   [2] Line 504, /home/forums/content/files/2/9/0/3/2/7/192700.attach::ReEquipWeapons
L 12/17/2021 - 22:08:32: [SM]   [3] Line 129, /home/forums/content/files/2/9/0/3/2/7/192700.attach::SurvivorChange
L 12/17/2021 - 22:08:32: [SM]   [4] Line 105, /home/forums/content/files/2/9/0/3/2/7/192700.attach::BillUse
L 12/17/2021 - 22:18:19: Error log file session closed.
TiTz is offline
Marttt
Veteran Member
Join Date: Jan 2019
Location: Brazil
Old 12-18-2021 , 09:54   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #859

Try this version:
Attached Files
File Type: sp Get Plugin or Get Source (L4D_Mv_CSM.sp - 378 views - 26.1 KB)
__________________
Marttt is offline
TiTz
Member
Join Date: Jan 2020
Old 12-18-2021 , 11:08   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #860

Great Marttt - Many thanks! - perfect - no errors messages -

but a further anomaly I've noticed is when i join the server it loads the last player I was using. This was happening before your correction.

Example: if the last character i was using was bill - when i next join the server there will be two bills and either francis, zoey or louis will be missing.
is there some sort of pre-cashing going on ?

Also will I run into a problem (as I've not tested this) with the witch going after the wrong player... if say there are two bill's or three zoeys etc... I assume the witch would attack the original bot and ignore the imposter?
TiTz is offline
Reply



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 00:10.


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