Raised This Month: $51 Target: $400
 12% 

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


Post New Thread Reply   
 
Thread Tools Display Modes
Mr. Zero
Veteran Member
Join Date: Jun 2009
Location: Denmark
Old 08-18-2014 , 03:21   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #641

Quote:
Originally Posted by DeathChaos25 View Post
To be perfectly honest, I have ABSOLUTELY no clue at all, as this was actually an accidental find.

I tried using tEntDev, but I didn't really find anything that might be this unknown netprop, it won't stop me from further testing to find it though.

My experimentation worked like this,
by using Cheat Engine on a Vanilla Listen Server (aka Single Player), I would use sb_takecontrol to switch around my m_survivorCharacter netprop to find it's address with Cheat Engine, and set it to 5, and instead of finding only m_survivorCharacter, I found this unknown netprop that seems to be a clone.

It works the same way, and the values would load up the corresponding icons and hands, it's also a 4 byte value too, everything bar the functionality seems to be alike, and in an actual dedicated server, cheat engine doesn't pick up m_survivorCharacter's address, but rather, this unknow netprop.

I'll test in No Mercy and see if I can indeed load L4D2 icons and hands and I'll let you guys know.

Edit : Well, sadly, no L4D2 Icons/arms in L4D campaigns, and I have yet to find out the name of this mysterious netprop.

On a side note, m_survivorCharacter 5 crashes EVEN on L4D campaigns, unsurprisingly.
Arms and icons are client predicted. Using Cheat Engine, you changed the m_survivorCharacter netprop on your client, meanwhile the server still knew you were Ellis hence model and voice. There is no dupe of m_survivorCharacter however the client does use this netprop to predict arms and icons (including scoreboard).
Another easy way to debunk it would be to get yourself incapped or another action that requires a teammate and see what name the bot yells out. E.g. get incapped as Ellis but with the m_survivorCharacter netprop changed to Zoey (5). The Survivor bots will still yell out "Ellis!" since the bot reads character from the server, not from client.

L4D2 icons and arms do not exist in Survivor Set 1 (L4D1 Survivors) since L4D2 survivors are not loaded at all into memory on the clients and L4D1 Survivors uses up the same character indexes as L4D2 crew while in Survivor Set 1.

Sadly SendProxy Manager does not support L4D2, otherwise you could fool clients to believe they are playing as another character.

However while the problem lies in how Windows handle m_survivorCharacter, this was the same issue before with Bill. The fixing of Zoey will be up to Valve. The best you could do is make a replacement fake Zoey. However Linux does not suffer this bug and would be a much better alternative if it is an option.

Last edited by Mr. Zero; 08-18-2014 at 03:33.
Mr. Zero is offline
DeathChaos25
Senior Member
Join Date: Jan 2014
Location: Puerto Rico
Old 08-18-2014 , 13:54   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #642

Quote:
Originally Posted by Mr. Zero View Post
Arms and icons are client predicted. Using Cheat Engine, you changed the m_survivorCharacter netprop on your client, meanwhile the server still knew you were Ellis hence model and voice. There is no dupe of m_survivorCharacter however the client does use this netprop to predict arms and icons (including scoreboard).
Another easy way to debunk it would be to get yourself incapped or another action that requires a teammate and see what name the bot yells out. E.g. get incapped as Ellis but with the m_survivorCharacter netprop changed to Zoey (5). The Survivor bots will still yell out "Ellis!" since the bot reads character from the server, not from client.
I think I understand what you mean, but that would mean the value exists twice?

And with Cheat Engine, I can change the actual m_survivorCharacter Netprop, but the search also returns the address I was messing around with, I'm guessing the search yields both the client side value and the server side value then?

For demonstration's sake, let's called the real one the server side netprop, and the one I found the client side one.

You can edit both of them with Cheat Engine, but in the video, I only pay attention to the client side one because of how weird it was...

Cheat Engine is obviously not a choice on real Dedicated Servers, so we really DO need a way to send client sided props to the clients...

Last edited by DeathChaos25; 08-18-2014 at 17:15.
DeathChaos25 is offline
Mr. Zero
Veteran Member
Join Date: Jun 2009
Location: Denmark
Old 08-19-2014 , 04:33   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #643

Quote:
Originally Posted by DeathChaos25 View Post
I think I understand what you mean, but that would mean the value exists twice?
I think you are getting server and client mixed up here.

m_survivorCharacter exists only once on CTerrorPlayer (Survivor player) entity. The way netprop works is that both server and each client have a copy of these properties. That means the value you were changing was your own client copy of m_survivorCharacter which only affects you. Hence you changed arms and icon upon changing your copy of m_survivorCharacter since arms and icon are client predicted.

The value does not exist twice, but each client has their own copies that replicates the server value.

Quote:
Originally Posted by DeathChaos25 View Post
And with Cheat Engine, I can change the actual m_survivorCharacter Netprop, but the search also returns the address I was messing around with, I'm guessing the search yields both the client side value and the server side value then?
I must admit I am not entirely sure if a local listen server is created within the game executable it self or hosted in another instance. However the value you were changing was client sided.

Quote:
Originally Posted by DeathChaos25 View Post
Cheat Engine is obviously not a choice on real Dedicated Servers, so we really DO need a way to send client sided props to the clients...
That depends. If you need to change the client predicted arms and icon, then yes you would need to send a different value for m_survivorCharacter from the servers real value. Which is what the SendProxy Manager extension does.

Otherwise if you do not need to change the client predicted arms and icon, then no.

Last edited by Mr. Zero; 08-19-2014 at 04:33.
Mr. Zero is offline
spidera2
Junior Member
Join Date: Aug 2014
Old 08-22-2014 , 01:22   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #644

So why does selecting the charecter Zoey make the game crash?
spidera2 is offline
DeathChaos25
Senior Member
Join Date: Jan 2014
Location: Puerto Rico
Old 08-23-2014 , 20:43   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #645

I'm just gunna leave this here...
DeathChaos25 is offline
SEGA EMPRESS ERIS
Senior Member
Join Date: Sep 2010
Location: THE-MILKY-WAY-GALAXY
Old 08-24-2014 , 02:22   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #646

You should probably all type bug in console to send in a bug report about Zoey's crash issue because before she would work and Bill wouldnt work. Now Bill works but Zoey doesnt work. Here is another fine example

l4d2csm00 | Administrator

Bill works but now Zoey character crashes the game Zoey model still works.
probably have to wait for VALVe to fix Zoey like they did with Bill.
dont change character if infected team.
can change targets character.
sm_targetb | yourself
sm_targetd | other players

Copy and paste entire plugin code into a blank text/SP file named l4d2csm00 then compile the file with spcomp located in sourcemod > scripting.

Change the name of AutoExecConfig(true, "l4d2csm00"); within the code to something else if you would like to make the file exec a config with a different name for example AutoExecConfig(true, "csm"); and have the file name csm so it creates the config file in sourcemod cfg folder. (both names must be the same, file, and autoexeconfig name, for it to work)

PHP Code:
/********************************************************************************************
* Plugin    : L4D2 Character Select Menu
* Version    : 1.7
* Game        : Left 4 Dead 2
* Author    : Sourcemod Community
* Testers    : Sourcemod Community
* Website    : N/A

* Purpose    : Allows players to change their in game character or model!

* Version 1.7
*         - Fixed a crash with the infected menu
*         - Precached boomer and witch so that it doesn't crash when you select them
*         - Fixed bug where survivors couldn't access the menu when they had 1 point of health left
*         - Changed the description of the Infected Menu cvar
*         - Added cvar: l4d_csm_models_only

* Version 1.6
*         - L4D1 Survivors can now be played on any campaign

* Version 1.5
*         - Original Survivors are now playable in L4D2 (except for Bill for obvious reasons)

* Version 1.4
*         - Optimized the plugin
*         - Merged L4D version of plugin with L4D2 version
*         - Survivors can now become fully Infected (admins only to prevent abuse)
*         - Fixed server crashes with uncommon infected
*
* Version 1.3
*         - Added a timer to the Gamemode ConVarHook to ensure compatitbilty with other gamemode changing plugins
*         - Survivors can now become Infected and vice versa (Character or model) (L4D2 only)
*         - Added Boomette (L4D2 only)
*         - Added Uncommon infected (model only) (L4D2 only)
*         - Fixed bug where the survivor menu would appear even if its turned off

* Version 1.2
*         - Redone tank health fix
*         - Few optimizations here and there

* Version 1.1
*         - Added cvars: l4d_csm_infected_menu, l4d_csm_survivor_menu and l4d_csm_change_limit
*         - Fixed bug where clients can access restricted parts of the menu

* Version 1.0
*         - Initial release.


**********************************************************************************************/

// define
#define PLUGIN_VERSION "1.7"
#define PLUGIN_NAME "L4D2 Character Select Menu"
#define DEBUG 0
#pragma semicolon 1
#define TEAM_SPECTATOR        1
#define TEAM_SURVIVORS         2
#define TEAM_INFECTED         3
#define MODEL_BILL "models/survivors/survivor_namvet.mdl"
#define MODEL_FRANCIS "models/survivors/survivor_biker.mdl"
#define MODEL_LOUIS "models/survivors/survivor_manager.mdl"
#define MODEL_ZOEY "models/survivors/survivor_teenangst.mdl"
#define MODEL_NICK "models/survivors/survivor_gambler.mdl"
#define MODEL_COACH "models/survivors/survivor_coach.mdl"
#define MODEL_ROCHELLE "models/survivors/survivor_producer.mdl"
#define MODEL_ELLIS "models/survivors/survivor_mechanic.mdl"
new String:currentmap[64];

// includes
#include <sourcemod>
#include <sdktools>

// Cvar Handles
new Handle:g_hActivate;
new 
Handle:g_hFun;
new 
Handle:g_hInfectedMenu;
new 
Handle:g_hSurvivorMenu;
new 
Handle:g_hChangeLimit;
new 
Handle:g_hModelsOnly;

// variables
static g_iSelectedClient// used to save the client number that was selected by an admin to change their character

// Bools
new bool:g_bL4DVersion;
new 
bool:g_bRoundStarted;

// Arrays
new bool:g_b_aOneToSpawn[MAXPLAYERS+1]; // Used to tell the plugin that this client will be the one to spawn and not place any spawn restrictions on that client
new g_i_aChangeLimitPlayer[MAXPLAYERS+1];


public 
Plugin:myinfo 
{
    
name "Character Select00",
    
author "Sourcemod Community",
    
description "Change character",
    
version PLUGIN_VERSION,
    
url "N/A"
}

public 
APLRes:AskPluginLoad2(Handle:myselfbool:lateString:error[], err_max)
{
    
// Checks to see if the game is a L4D game. If it is, check if its the sequel. L4DVersion is L4D if false, L4D2 if true.
    
decl String:GameName[64];
    
GetGameFolderName(GameNamesizeof(GameName));
    if (
StrContains("left4dead""left4dead"false) == -1)
        return 
APLRes_Failure;
    else if (
StrEqual(GameName"left4dead2"false))
        
g_bL4DVersion true;
    
    return 
APLRes_Success;
}

public 
OnPluginStart()
{    
    
// Register the version cvar
    
CreateConVar("l4d_csm_version"PLUGIN_VERSION"Version of L4D Character Select Menu"FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
    
    
// convars
    
    // Fun Cvar
    
g_hFun CreateConVar("l4d_csm_fun_mode""0""If 1, players will be able to change their models on the csm"FCVAR_PLUGIN|FCVAR_SPONLYtrue0.0true1.0);
    
    
// Activate Cvar
    
g_hActivate CreateConVar("l4d_csm_enable""1""If 1, character select menu is activated"FCVAR_PLUGIN|FCVAR_SPONLYtrue0.0true1.0);
    
    
// Infected Menu cvar
    
g_hInfectedMenu CreateConVar("l4d_csm_infected_menu""1""If 1, Infected Menu will be shown to admins only, will only show models to players if fun mode is on"FCVAR_PLUGIN|FCVAR_SPONLYtrue0.0true1.0);
    
    
// Survivor Menu cvar
    
g_hSurvivorMenu CreateConVar("l4d_csm_survivor_menu""1""If 1, Survivor Menu will be shown to players and admins"FCVAR_PLUGIN|FCVAR_SPONLYtrue0.0true1.0);
    
    
// Models only cvar
    
g_hModelsOnly CreateConVar("l4d_csm_models_only""1""If 1, only models can be selected, admins can bypass this"FCVAR_PLUGIN|FCVAR_SPONLYtrue0.0true1.0);
    
    
// Change Limit cvar
    
g_hChangeLimit CreateConVar("l4d_csm_change_limit""9999""Sets the amount of times a client can change their character"FCVAR_PLUGIN|FCVAR_SPONLY);
    
HookConVarChange(g_hChangeLimitConVarChangeLimit);
    
    
// Hook Events
    
HookEvent("item_pickup"Event_RoundStart);
    
HookEvent("player_spawn"Event_PlayerSpawn);
    
HookEvent("round_end"Event_RoundEnd);
    
    
// config file
    
AutoExecConfig(true"l4d2csm00");
    
    
// sourcemod command
    
RegConsoleCmd("sm_targetb"PlayerMenuActivator);
    
RegAdminCmd("sm_targetd"InitiateMenuAdminADMFLAG_GENERIC"Brings up a menu to select a client's character");
}

public 
ConVarChangeLimit(Handle:convar, const String:oldValue[], const String:newValue[])
{
    
#if DEBUG
    
LogMessage("L4D CSM:Round Started");
    
#endif
    
for (new 1<= MaxClientsi++) 
    {
        
g_i_aChangeLimitPlayer[i] = GetConVarInt(g_hChangeLimit);
    }
}

public 
Action:Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
    
// If round has started ...
    
if (g_bRoundStarted)
        return;
    
    
g_bRoundStarted true;
    
    for (new 
1<= MaxClientsi++) 
    {
        
g_i_aChangeLimitPlayer[i] = GetConVarInt(g_hChangeLimit);
    }
}

public 
OnMapStart()
{
    
//Precache models here so that the server doesn't crash
    
if (g_bL4DVersion)
    {
        
GetCurrentMap(currentmap64);
        
PrecacheModel(MODEL_BILLtrue);
        
PrecacheModel(MODEL_FRANCIStrue);
        
PrecacheModel(MODEL_LOUIStrue);
        
PrecacheModel(MODEL_ZOEYtrue);
        
PrecacheModel(MODEL_NICKtrue);
        
PrecacheModel(MODEL_COACHtrue);
        
PrecacheModel(MODEL_ROCHELLEtrue);
        
PrecacheModel(MODEL_ELLIStrue);
        
SetConVarInt(FindConVar("precache_l4d1_survivors"), 1truetrue);
        
PrecacheModel("models/infected/common_male_ceda.mdl"true);
        
PrecacheModel("models/infected/common_male_clown.mdl"true);
        
PrecacheModel("models/infected/common_male_mud.mdl"true);
        
PrecacheModel("models/infected/common_male_roadcrew.mdl"true);
        
PrecacheModel("models/infected/common_male_riot.mdl"true);
        
PrecacheModel("models/infected/common_male_fallen_survivor.mdl"true);
        
PrecacheModel("models/infected/common_male_jimmy.mdl.mdl"true);
        
PrecacheModel("models/infected/boomette.mdl"true);
        
PrecacheModel("models/infected/witch.mdl"true);
        
PrecacheModel("models/survivors/survivor_teenangst.mdl"true);
        
PrecacheModel("models/survivors/survivor_biker.mdl"true);
        
PrecacheModel("models/survivors/survivor_manager.mdl"true);
        
PrecacheModel("models/survivors/survivor_namvet.mdl"true);
    }
}

public 
Action:Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
    
g_bRoundStarted false;
}

public 
OnMapEnd()
{
    
g_bRoundStarted false;
}

public 
Action:Event_PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
{
    
// We get the client id
    
new client GetClientOfUserId(GetEventInt(event"userid"));
    
    
// If client is valid
    
if (client == 0) return Plugin_Continue;
    if (!
IsClientConnected(client)) return Plugin_Continue;
    if (!
IsClientInGame(client)) return Plugin_Continue;
    
    
g_i_aChangeLimitPlayer[client] = GetConVarInt(g_hChangeLimit);
    
    return 
Plugin_Continue;
}

public 
OnClientDisconnect(client)
{
    
// If is a bot, skip this function
    
if (IsFakeClient(client))
        return;
    
    
g_i_aChangeLimitPlayer[client] = GetConVarInt(g_hChangeLimit);
}

public 
Action:PlayerMenuActivator(clientargs)
{
    if ((
client) && (GetConVarBool(g_hActivate)))
    {
        
CreateTimer(0.1PlayerMenuclient);
    }
}

public 
Action:PlayerMenu(Handle:timerany:client)
{
    
    new 
Handle:menu CreateMenu(CharMenu);
    
SetMenuTitle(menu"Choose a character:");
    
    
// if the player is alive
    
if (PlayerIsAlive(client))
    {
        if (
GetClientTeam(client) == TEAM_SURVIVORS && GetConVarBool(g_hSurvivorMenu) && g_i_aChangeLimitPlayer[client] >= 1)
        {
            if (!
GetConVarBool(g_hModelsOnly) || GetUserFlagBits(client) != 0)
            {
                
AddMenuItem(menu"0""Zoey");
                
AddMenuItem(menu"1""Francis");
                
AddMenuItem(menu"2""Louis");
                
AddMenuItem(menu"3""Bill");
                if (!
g_bL4DVersion)
                    
AddMenuItem(menu"8""Gargantua");
                else
                {
                    
AddMenuItem(menu"4""Nick");
                    
AddMenuItem(menu"5""Rochelle");
                    
AddMenuItem(menu"6""Coach");
                    
AddMenuItem(menu"7""Ellis");
                }
            }
            
        }
        
        if (
GetConVarBool(g_hFun) && GetConVarBool(g_hSurvivorMenu) && g_i_aChangeLimitPlayer[client] >= || GetUserFlagBits(client) != && GetConVarBool(g_hSurvivorMenu) && g_i_aChangeLimitPlayer[client] >= 1)
        {
            
AddMenuItem(menu"8""Zoey(Model)");
            
AddMenuItem(menu"9""Francis(Model)");
            
AddMenuItem(menu"10""Louis(Model)");
            
AddMenuItem(menu"11""Bill(Model)");
            if (!
g_bL4DVersion)
                
AddMenuItem(menu"16""Gargantua(Model)");
            else
            {
                
AddMenuItem(menu"12""Nick(Model)");
                
AddMenuItem(menu"13""Rochelle(Model)");
                
AddMenuItem(menu"14""Coach(Model)");
                
AddMenuItem(menu"15""Ellis(Model)");
            }
        }
        
        if (
GetUserFlagBits(client) != && GetConVarBool(g_hInfectedMenu) && g_i_aChangeLimitPlayer[client] >= 1)
        {
            if (!
GetConVarBool(g_hModelsOnly) || GetUserFlagBits(client) != 0)
            {
                
AddMenuItem(menu"16""Smoker");
                
AddMenuItem(menu"17""Boomer");
                
AddMenuItem(menu"18""Hunter");
                
AddMenuItem(menu"19""Tank");
                if (
g_bL4DVersion)
                {
                    
AddMenuItem(menu"20""Boomette");
                    
AddMenuItem(menu"21""Charger");
                    
AddMenuItem(menu"22""Jockey");
                    
AddMenuItem(menu"23""Spitter");
                }
            }
        }
        
        if (
GetConVarBool(g_hFun) && GetConVarBool(g_hInfectedMenu) && g_i_aChangeLimitPlayer[client] >= || GetUserFlagBits(client) != && GetConVarBool(g_hInfectedMenu) && g_i_aChangeLimitPlayer[client] >= 1)
        {
            if (!
g_bL4DVersion && GetClientTeam(client) == TEAM_INFECTED || g_bL4DVersion)
            {
                
AddMenuItem(menu"24""Smoker(Model)");
                
AddMenuItem(menu"25""Boomer(Model)");
                
AddMenuItem(menu"26""Hunter(Model)");
            }
            
AddMenuItem(menu"27""Tank(Model)");
            if (
g_bL4DVersion)
            {
                
AddMenuItem(menu"28""Boomette(Model)");
                
AddMenuItem(menu"29""Charger(Model)");
                
AddMenuItem(menu"30""Jockey(Model)");
                
AddMenuItem(menu"31""Spitter(Model)");
                
AddMenuItem(menu"32""CEDA Hazmat(Model)");
                
AddMenuItem(menu"33""Clown(Model)");
                
AddMenuItem(menu"34""Mud Man(Model)");
                
AddMenuItem(menu"35""Construction Worker(Model)");
                
AddMenuItem(menu"36""Riot Officer(Model)");
                
AddMenuItem(menu"37""Fallen Survivor(Model)");
                
AddMenuItem(menu"38""Jimmy Gibbs Jr.(Model)");
            }
            
AddMenuItem(menu"39""Witch(Model)");
        }
        if (
g_i_aChangeLimitPlayer[client] < 1)
        {
            
PrintHintText(client"Sorry, you cannot change your character until you respawn.");
            return;
        }
        if (
GetMenuItemCount(menu) == 0)
        {
            
PrintHintText(client"Sorry, there are no selections you can make at this time.");
            return;
        }
    }
    else
    {
        
PrintHintText(client"Sorry, you must be alive to use the Character Select Menu!");
        return;
    }
    
SetMenuExitButton(menutrue);
    
DisplayMenu(menuclient9999);
}

public 
CharMenu(Handle:menuMenuAction:actionparam1param2)
{
    if (
action == MenuAction_Select)
    {
        
decl String:item[256], String:display[256];
        
        
GetMenuItem(menuparam2itemsizeof(item), _displaysizeof(display));
        
        new 
Menu_Number StringToInt(item);
        
        switch(
Menu_Number)
        {
            case 
0// Zoey
            
SetUpSurvivor(param10);
            case 
1// Francis
            
SetUpSurvivor(param11);
            case 
2// Louis
            
SetUpSurvivor(param12);
            case 
3// Bill
            
SetUpSurvivor(param13);
            case 
4// Nick
            
SetUpSurvivor(param14);
            case 
5// Rochelle
            
SetUpSurvivor(param15);
            case 
6// Coach
            
SetUpSurvivor(param16);
            case 
7// Ellis
            
SetUpSurvivor(param17);
            case 
8// Zoey (Model)
            
SetUpSurvivorModel(param10);
            case 
9// Francis (Model)
            
SetUpSurvivorModel(param11);
            case 
10// Louis (Model)
            
SetUpSurvivorModel(param12);
            case 
11// Bill (Model)
            
SetUpSurvivorModel(param13);
            case 
12// Nick (Model)
            
SetUpSurvivorModel(param14);
            case 
13// Rochelle (Model)
            
SetUpSurvivorModel(param15);
            case 
14// Coach (Model)
            
SetUpSurvivorModel(param16);
            case 
15// Ellis (Model)
            
SetUpSurvivorModel(param17);
            case 
16// Smoker
            
SetUpInfected(param12);
            case 
17// Boomer
            
SetUpInfected(param13);
            case 
18// Hunter
            
SetUpInfected(param11);
            case 
19// Tank
            
SetUpInfected(param14);
            case 
20// Boomette
            
SetUpInfected(param18);
            case 
21// Charger
            
SetUpInfected(param15);
            case 
22// Jockey
            
SetUpInfected(param16);
            case 
23// Spitter
            
SetUpInfected(param17);
            case 
24// Smoker (Model)
            
SetUpInfectedModel(param12);
            case 
25// Boomer (Model)
            
SetUpInfectedModel(param13);
            case 
26// Hunter (Model)
            
SetUpInfectedModel(param11);
            case 
27// Tank (Model)
            
SetUpInfectedModel(param14);
            case 
28// Boomette (Model)
            
SetUpInfectedModel(param18);
            case 
29// Charger (Model)
            
SetUpInfectedModel(param15);
            case 
30// Jockey (Model)
            
SetUpInfectedModel(param16);
            case 
31// Spitter (Model)
            
SetUpInfectedModel(param17);
            case 
32// CEDA (Model)
            
SetUpInfectedModel(param19);
            case 
33// Clown (Model)
            
SetUpInfectedModel(param110);
            case 
34// Mudman (Model)
            
SetUpInfectedModel(param111);
            case 
35// Roadcrew (Model)
            
SetUpInfectedModel(param112);
            case 
36// Riot (Model)
            
SetUpInfectedModel(param113);
            case 
37// Fallen Survivor (Model)
            
SetUpInfectedModel(param114);
            case 
38// Jimmy Gibbs Jr.
            
SetUpInfectedModel(param115);
            case 
39// Witch
            
SetUpInfectedModel(param116);
        }
    } 
    else if (
action == MenuAction_Cancel)
    {
        
    }
    else if (
action == MenuAction_End)
    {
        
CloseHandle(menu);
    }
}

SetUpSurvivor(param1Survivor)
{
    if (
GetClientTeam(param1) == TEAM_INFECTED)
        return;
    
    
// Set the character and model
    
switch(Survivor)
    {
        case 
0// Zoey
        
{
            if (!
g_bL4DVersion)
                
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 11true);
            else
            
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 51true);
            
            
SetEntityModel(param1"models/survivors/survivor_teenangst.mdl");
            
PrintToChat(param1"\x05[ \x01You're now playing as \x03Zoey \x05]");
        }
        case 
1// Francis
        
{
            if (!
g_bL4DVersion)
                
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 21true);
            else
            
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 61true);
            
            
SetEntityModel(param1"models/survivors/survivor_biker.mdl");
            
PrintToChat(param1"\x05[ \x01You're now playing as \x03Francis \x05]");
        }
        case 
2// Louis
        
{
            if (!
g_bL4DVersion)
                
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 31true);
            else
            
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 71true);
            
            
SetEntityModel(param1"models/survivors/survivor_manager.mdl");
            
PrintToChat(param1"\x05[ \x01You're now playing as \x03Louis \x05]");
        }
        case 
3// Bill
        
{
            if (!
g_bL4DVersion)
                
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 01true);
            else
            
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 41true);

            
SetEntityModel(param1"models/survivors/survivor_namvet.mdl");
            
PrintToChat(param1"\x05[ \x01You're now playing as \x03Bill \x05]");
        }
        case 
4// Nick
        
{
            
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 01true);
            
SetEntityModel(param1"models/survivors/survivor_gambler.mdl");
            
PrintToChat(param1"\x05[ \x01You're now playing as \x03Nick \x05]");
        }
        case 
5// Rochelle
        
{
            
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 11true);
            
SetEntityModel(param1"models/survivors/survivor_producer.mdl");
            
PrintToChat(param1"\x05[ \x01You're now playing as \x03Rochelle \x05]");
        }
        case 
6// Coach
        
{
            
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 21true);
            
SetEntityModel(param1"models/survivors/survivor_coach.mdl");
            
PrintToChat(param1"\x05[ \x01You're now playing as \x03Coach \x05]");
        }
        case 
7// Ellis
        
{
            
SetEntData(param1FindSendPropInfo("CTerrorPlayer""m_survivorCharacter"), 31true);
            
SetEntityModel(param1"models/survivors/survivor_mechanic.mdl");
            
PrintToChat(param1"\x05[ \x01You're now playing as \x03Ellis \x05]");
        }
    }
    
    
g_i_aChangeLimitPlayer[param1]--;
}

SetUpSurvivorModel(param1Survivor)
{
    switch(
Survivor)
    {
        case 
0// Zoey
        
{
            
SetEntityModel(param1"models/survivors/survivor_teenangst.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now \x03Zoey \x05]");
        }
        case 
1// Francis
        
{
            
SetEntityModel(param1"models/survivors/survivor_biker.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now \x03Francis \x05]");
        }
        case 
2// Louis
        
{
            
SetEntityModel(param1"models/survivors/survivor_manager.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now \x03Louis \x05]");
        }
        case 
3// Bill
        
{
            
SetEntityModel(param1"models/survivors/survivor_namvet.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now \x03Bill \x05]");
        }
        case 
4// Nick
        
{
            
SetEntityModel(param1"models/survivors/survivor_gambler.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now \x03Nick \x05]");
        }
        case 
5// Rochelle
        
{
            
SetEntityModel(param1"models/survivors/survivor_producer.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now \x03Rochelle \x05]");
        }
        case 
6// Coach
        
{
            
SetEntityModel(param1"models/survivors/survivor_coach.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now \x03Coach \x05]");
        }
        case 
7// Ellis
        
{
            
SetEntityModel(param1"models/survivors/survivor_mechanic.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now \x03Ellis \x05]");
        }
    }
    
    
g_i_aChangeLimitPlayer[param1]--;
}

SetUpInfected(param1Infected)
{
    if ((
GetClientTeam(param1)) == TEAM_SURVIVORS)
        
ChangeClientTeam(param1TEAM_INFECTED);
    
    
// Set the player as a ghost so that it can take the spawned infected
    
SetGhostStatus(param1true);
    
    
// Set the player as the one to spawn so no spawn restrictions apply to that client
    
g_b_aOneToSpawn[param1] = true;
    
    
// If it's a boomette, spawn a boomer, else just pass the infected number to the Spawn_Infected function
    
if (Infected == 8)
        
Spawn_Infected(3);
    else
    
Spawn_Infected(Infected);
    
    
// The client is no longer the one to spawn as the client has already spawned
    
g_b_aOneToSpawn[param1] = false;
    
    
// Set the client back to life
    
SetGhostStatus(param1false);
    
    
// Change the model for the boomer or boomette
    
if (Infected == 3)
        
SetEntityModel(param1"models/infected/boomer.mdl");
    else if (
Infected == 8)
        
SetEntityModel(param1"models/infected/boomette.mdl");
    
    
// Print to the player they changed into
    
switch(Infected)
    {
        case 
1// Hunter
        
PrintToChat(param1"\x05[ \x01You're now playing as a \x03Hunter \x05]");
        case 
2// Smoker
        
PrintToChat(param1"\x05[ \x01You're now playing as a \x03Smoker \x05]");
        case 
3// Boomer
        
PrintToChat(param1"\x05[ \x01You're now playing as a \x03Boomer \x05]");
        case 
4// Tank
        
PrintToChat(param1"\x05[ \x01You're now playing as a \x03Tank! \x05]");
        case 
5// Charger
        
PrintToChat(param1"\x05[ \x01You're now playing as a \x03Charger \x05]");
        case 
6// Jockey
        
PrintToChat(param1"\x05[ \x01You're now playing as a \x03Jockey \x05]");
        case 
7// Spitter
        
PrintToChat(param1"\x05[ \x01You're now playing as a \x03Spitter \x05]");
        case 
8// Boomette
        
PrintToChat(param1"\x05[ \x01You're now playing as a \x03Boomette \x05]");
    }
    
    
g_i_aChangeLimitPlayer[param1]--;
}

SetUpInfectedModel(param1Infected)
{
    switch(
Infected)
    {
        case 
1// Hunter
        
{
            
// Prevents players from changing teams and accessing the models while the menu is running
            
if (!g_bL4DVersion && GetClientTeam(param1) != TEAM_INFECTED)
                return;
            
SetEntityModel(param1"models/infected/hunter.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Hunter \x05]");
        }
        case 
2// Smoker
        
{
            
// Prevents players from changing teams and accessing the models while the menu is running
            
if (!g_bL4DVersion && GetClientTeam(param1) != TEAM_INFECTED)
                return;
            
SetEntityModel(param1"models/infected/smoker.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Smoker \x05]");
        }
        case 
3// Boomer
        
{
            
// Prevents players from changing teams and accessing the models while the menu is running
            
if (!g_bL4DVersion && GetClientTeam(param1) != TEAM_INFECTED)
                return;
            
SetEntityModel(param1"models/infected/boomer.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Boomer \x05]");
        }
        case 
4// Tank
        
{
            
SetEntityModel(param1"models/infected/hulk.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Tank! \x05]");
        }
        case 
5// Charger
        
{
            
SetEntityModel(param1"models/infected/charger.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Charger \x05]");
        }
        case 
6// Jockey
        
{
            
SetEntityModel(param1"models/infected/jockey.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Jockey \x05]");
        }
        case 
7// Spitter
        
{
            
SetEntityModel(param1"models/infected/spitter.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Spitter \x05]");
        }
        case 
8// Boomette
        
{
            
SetEntityModel(param1"models/infected/boomette.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Boomette \x05]");
        }
        case 
9// CEDA
        
{
            
SetEntityModel(param1"models/infected/common_male_ceda.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Ceda Hazmat Operative! \x05]");
        }
        case 
10// Clown
        
{
            
SetEntityModel(param1"models/infected/common_male_clown.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Clown Infected! \x05]");
        }
        case 
11// Mud
        
{
            
SetEntityModel(param1"models/infected/common_male_mud.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Mud Man Infected! \x05]");
        }
        case 
12// Roadcrew
        
{
            
SetEntityModel(param1"models/infected/common_male_roadcrew.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Construction worker! \x05]");
        }
        case 
13// Riot
        
{
            
SetEntityModel(param1"models/infected/common_male_riot.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Riot Infected! \x05]");
        }
        case 
14// Fallen Survivor
        
{
            
SetEntityModel(param1"models/infected/common_male_fallen_survivor.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Fallen Survivor! \x05]");
        }
        case 
15// Jimmy Gibbs Jr.
        
{
            
SetEntityModel(param1"models/infected/common_male_jimmy.mdl.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Jimmy Gibbs Jr.! \x05]");
        }
        case 
16// Witch
        
{
            
SetEntityModel(param1"models/infected/witch.mdl");
            
PrintToChat(param1"\x05[ \x01Your model is now a \x03Witch! \x05]");
        }
    }
    
    
g_i_aChangeLimitPlayer[param1]--;
}

Spawn_Infected(InfectedTicket)
{
    
// Before spawning the bot, we determine if an real infected player is dead, since the new infected bot will be controlled by this player
    
new bool:resetGhost[MAXPLAYERS+1];
    new 
bool:resetLife[MAXPLAYERS+1];
    
    for (new 
i=1;i<=MaxClients;i++)
    {
        if (
IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i)) // player is connected and is not fake and it's in game ...
        
{
            
// If player is on infected's team and is dead ..
            
if (GetClientTeam(i)==TEAM_INFECTED)
            {
                if (
g_b_aOneToSpawn[i] == false)
                {
                    
// If player is a ghost ....
                    
if (IsPlayerGhost(i))
                    {
                        
resetGhost[i] = true;
                        
SetGhostStatus(ifalse);
                        
#if DEBUG
                        
LogMessage("Player is a ghost, taking preventive measures for spawning an infected bot");
                        
#endif
                    
}
                    else if (!
PlayerIsAlive(i))
                    {
                        
resetLife[i] = true;
                        
SetLifeState(ifalse);
                        
#if DEBUG
                        
LogMessage("Found a dead player, spawn time has not reached zero, delaying player to Spawn an infected bot");
                        
#endif
                    
}
                }
            }
        }
    }
    
    
// We get any client ....
    
new anyclient GetAnyClient();
    new 
bool:temp false;
    if (!
anyclient)
    {
        
#if DEBUG
        
LogMessage("[CSM] Creating temp client to fake command");
        
#endif
        // we create a fake client
        
anyclient CreateFakeClient("Bot");
        if (!
anyclient)
        {
            
LogError("[L4D] Character Select Menu: CreateFakeClient returned 0 -- Infected bot was not spawned");
            return;
        }
        
temp true;
    }
    
    
// We spawn the bot ...
    
switch (InfectedTicket)
    {
        case 
1// Hunter
        
{
            
#if DEBUG
            
LogMessage("Spawning Hunter");
            
#endif
            
CheatCommand(anyclient"z_spawn""hunter auto");
        }
        case 
2// Smoker
        
{    
            
#if DEBUG
            
LogMessage("Spawning Smoker");
            
#endif
            
CheatCommand(anyclient"z_spawn""smoker auto");
        }
        case 
3// Boomer
        
{
            
#if DEBUG
            
LogMessage("Spawning Boomer");
            
#endif
            
CheatCommand(anyclient"z_spawn""boomer auto");
        }
        case 
4// Tank
        
{
            
#if DEBUG
            
LogMessage("Spawning Tank");
            
#endif
            
CheatCommand(anyclient"z_spawn""tank auto");
        }
        case 
5// Charger
        
{
            
#if DEBUG
            
LogMessage("Spawning Charger");
            
#endif
            
CheatCommand(anyclient"z_spawn""charger auto");
        }
        case 
6// Jockey
        
{
            
#if DEBUG
            
LogMessage("Spawning Jockey");
            
#endif
            
CheatCommand(anyclient"z_spawn""jockey auto");
        }
        case 
7// Spitter
        
{
            
#if DEBUG
            
LogMessage("Spawning Spitter");
            
#endif
            
CheatCommand(anyclient"z_spawn""spitter auto");
        }
    }
    
    
// If client was temp, we setup a timer to kick the fake player
    
if (tempCreateTimer(0.1kickbottemp);
    
    
// We restore the player's status
    
for (new i=1;i<=MaxClients;i++)
    {
        if (
resetGhost[i] == true)
            
SetGhostStatus(itrue);
        if (
resetLife[i] == true)
            
SetLifeState(itrue);
    }
    
}

bool:IsPlayerGhost (client)
{
    if (
GetEntProp(clientProp_Send"m_isGhost"))
        return 
true;
    return 
false;
}

bool:PlayerIsAlive (client)
{
    if (!
GetEntProp(client,Prop_Send"m_lifeState"))
        return 
true;
    return 
false;
}

stock GetAnyClient()
{
    
#if DEBUG
    
LogMessage("[Infected bots] Looking for any real client to fake command");
    
#endif
    
for (new i=1;i<=MaxClients;i++)
    {
        if (
IsClientInGame(i) && (!IsFakeClient(i)))
        {
            return 
i;
        }
    }
    return 
0;
}

SetGhostStatus (clientbool:ghost)
{
    if (
ghost)
        
SetEntProp(clientProp_Send"m_isGhost"1);
    else
    
SetEntProp(clientProp_Send"m_isGhost"0);
}

SetLifeState (clientbool:ready)
{
    if (
ready)
        
SetEntProp(clientProp_Send"m_lifeState"1);
    else
    
SetEntProp(clientProp_Send"m_lifeState"0);
}

public 
Action:kickbot(Handle:timerany:value)
{
    
KickThis(value);
}

KickThis (client)
{
    
    if (
IsClientConnected(client) && (!IsClientInKickQueue(client)))
    {
        if (
IsFakeClient(client)) KickClient(client,"Kick");
    }
}

stock CheatCommand(clientString:command[], String:arguments[] = "")
{
    if (!
client || !IsClientInGame(client))
    {
        for (new 
target 1target <= MaxClientstarget++)
        {
            
client target;
            break;
        }
        
        return; 
// case no valid Client found
    
}
    
    new 
userFlags GetUserFlagBits(client);
    
SetUserFlagBits(clientADMFLAG_ROOT);
    new 
flags GetCommandFlags(command);
    
SetCommandFlags(commandflags & ~FCVAR_CHEAT);
    
FakeClientCommand(client"%s %s"commandarguments);
    
SetCommandFlags(commandflags);
    
SetUserFlagBits(clientuserFlags);
}

public 
Action:InitiateMenuAdmin(clientargs
{
    
decl String:name[MAX_NAME_LENGTH], String:number[10];
    
    new 
Handle:menu CreateMenu(ShowMenu2);
    
SetMenuTitle(menu"Select a client:");
    
    for (new 
1<= MaxClientsi++)
    {
        if (!
IsClientInGame(i)) continue;
        if (
GetClientTeam(i) != TEAM_SURVIVORS) continue;
        if (
== client) continue;
        
        
Format(namesizeof(name), "%N"i);
        
Format(numbersizeof(number), "%i"i);
        
AddMenuItem(menunumbername);
    }
    
    
    
SetMenuExitButton(menutrue);
    
DisplayMenu(menuclientMENU_TIME_FOREVER);
}

public 
ShowMenu2(Handle:menuMenuAction:actionparam1param2
{
    switch (
action
    {
        case 
MenuAction_Select
        {
            
decl String:number[4];
            
GetMenuItem(menuparam2numbersizeof(number));
            
            
g_iSelectedClient StringToInt(number);
            
            new 
args;
            
ShowMenuAdmin(param1args);
        }
        case 
MenuAction_Cancel:
        {
            
        }
        case 
MenuAction_End
        {
            
CloseHandle(menu);
        }
    }
}

public 
Action:ShowMenuAdmin(clientargs
{
    
decl String:sMenuEntry[8];
    
    new 
Handle:menu CreateMenu(CharMenuAdmin);
    
SetMenuTitle(menu"Choose a character:");
    {
        {
        
AddMenuItem(menu"0""Zoey");
        
AddMenuItem(menu"1""Francis");
        
AddMenuItem(menu"2""Louis");
        
AddMenuItem(menu"3""Bill");
        
AddMenuItem(menu"4""Nick");
        
AddMenuItem(menu"5""Rochelle");
        
AddMenuItem(menu"6""Coach");
        
AddMenuItem(menu"7""Ellis");
        }        
    }
    
SetMenuExitButton(menutrue);
    
DisplayMenu(menuclientMENU_TIME_FOREVER);
}

public 
CharMenuAdmin(Handle:menuMenuAction:actionparam1param2
{
    switch (
action
    {
        case 
MenuAction_Select
        {
            
decl String:item[8];
            
GetMenuItem(menuparam2itemsizeof(item));
            
            switch(
StringToInt(item)) 
            {
                case 
0:    {    SetUpSurvivor(g_iSelectedClient0);    }
                case 
1:    {    SetUpSurvivor(g_iSelectedClient1);    }
                case 
2:    {    SetUpSurvivor(g_iSelectedClient2);    }
                case 
3:    {    SetUpSurvivor(g_iSelectedClient3);    }
                case 
4:    {    SetUpSurvivor(g_iSelectedClient4);    }
                case 
5:    {    SetUpSurvivor(g_iSelectedClient5);    }
                case 
6:    {    SetUpSurvivor(g_iSelectedClient6);    }
                case 
7:    {    SetUpSurvivor(g_iSelectedClient7);    }

            }
        }
        case 
MenuAction_Cancel:
        {
            
        }
        case 
MenuAction_End
        {
            
CloseHandle(menu);
        }
    }
}

//////// 
__________________
SEGA EMPRESS ERIS is offline
Ellie
Senior Member
Join Date: Apr 2013
Old 08-24-2014 , 13:52   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #647

Quote:
Originally Posted by Emcitement View Post
Is there anyway to change config files in game through the console?
The description says you need to change l4d_csm_l4d1_survivors to 2 when playing on L4D1 campaigns and its a bit of a pain to restart everything everytime you change levels.
Yes, go to the CFG folder on the server and you should have a folder names sourcemod. Open it and look for a file named something along the lines of l4d2csm. Open that file with notepad and look for the cvar that says l4d_csm_l4d1_survivors and change the value to what you need, then save the changes to the file.


Quote:
Originally Posted by HilbertPL View Post
How to change Timer? What file i need to edit?
Bill works just fine on Windows and Linux. There is no need to change any timers.



Quote:
Originally Posted by Mr. Zero View Post
I must admit I am not entirely sure if a local listen server is created within the game executable it self or hosted in another instance. However the value you were changing was client sided.
In the L4D games, when you run single player or a LAN game as the host or start a lobby with the local server option, you are BOTH the server and the client. In these instances, the server and client binaries are loaded when you're playing. Otherwise, when you join a game, only the client binaries are loaded on your end.


Quote:
Originally Posted by spidera2 View Post
So why does selecting the charecter Zoey make the game crash?
Originally Bill is the one that had this similar issue. However, after some time that was fixed and in the process, the data in the binaries shifted and broke Francis and Zoey. Then that was patched up to fix Francis and the data in he binaries shifted again, but Zoey remains broken.

Zoey crashes on Windows because the binaries point to garbage data dealing with her model when that specific netprop has a value of 5. The server will attempt to load it, but fails, and crashes.

In L4D1 (and L4D2 with survivor set 1), the values have always been like this:
0=Bill
1=Zoey
2=Francis
3=Louis

In L4D2 with survivor set 2, the values are like this:
0=Nick
1=Rochelle
2=Coach
3=Ellis
4=Bill
5=Zoey
6=Francis
7=Louis

So basically in L4D2, if you try to use a value that doesn't exist within each specific survivor set, the game will either load garbage data or crash. This is why a value higher than 3 on survivor set 1 is useless. The same applies to values higher than 7 on survivor set 2. There is no data for Nick, Rochelle, Coach, and Ellis in survivor set 1. That's just the way the game is programmed.

If you want Zoey fixed, get a ton of people to file a bug report within the game as XJR15 mentioned.
Ellie is offline
spidera2
Junior Member
Join Date: Aug 2014
Old 08-27-2014 , 01:45   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #648

Im kind of a noob but how do i do a bug report? Im using a local server becuse setting up dedicated is very hard for me also im not the owner of my router so i cant port forward or install the hlds always gives me error in the cmd commands i have to type but all i need to know is how can i bug report?
spidera2 is offline
SEGA EMPRESS ERIS
Senior Member
Join Date: Sep 2010
Location: THE-MILKY-WAY-GALAXY
Old 08-28-2014 , 04:05   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #649

Enable the developer console it should be in the game options make sure its enabled in the game options. To bring up developer console, Press the "~" key above tab to open up the console then type in the console bug then hit enter then you can begin submitting your bug report.

Zoey has been broke for over a year now so I hope they get around to fixing her like they did with Bill.
We probably just need more people to submit bugs about it then maybe she will get fixed sometime like how they did with Bill.
__________________
SEGA EMPRESS ERIS is offline
id5473
Member
Join Date: Mar 2012
Old 08-28-2014 , 16:00   Re: [L4D/L4D2] Character Select Menu (2.5a/b)
Reply With Quote #650

Hey,
would someone kindly give me some brief instructions what exactly needs to be done to get all 8 survivors being selectable via the csm menu? I don't want to run 8 survivors at once.. i just want 4 but these 4 should have the option to be any of the 8...
At the moment I have only 4 selectable and these are always the l4d2 ones even in the l4d1 campaigns.. and in the l4d1 campaigns they only take the models.. hands/voices are l4d1.

- does that mean i need "left 4 downtown?" From what I understand I don't need it unless I use any plugins which require the natives it provides (which i don't) or if i want to run with more then 4 survivors. correct?

- do I need to set any cvars? (Do you really need to flip l4d_csm_l4d1_survivors back and forth depending on the campaign?)

I'm using a linux dedicated server.

thanks for clearing this up for me.

Last edited by id5473; 08-28-2014 at 16:01.
id5473 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:32.


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