forked from jeremyvillanuevar/scripting
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbalancer_hp.sp
More file actions
282 lines (234 loc) · 8.67 KB
/
balancer_hp.sp
File metadata and controls
282 lines (234 loc) · 8.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
//#define DEBUG
#define PLUGIN_NAME "[L4D/L4D2] Balancer HP Special Infected"
#define PLUGIN_AUTHOR "z☣; Slightly edited by mac"
#define PLUGIN_DESCRIPTION "Balances the HP of the Special Infecteds, depending on the number of Survivor players in game"
#define PLUGIN_VERSION "1.1"
#define PLUGIN_URL ""
#include <sourcemod>
#include <sdktools>
#pragma semicolon 1
#define IS_VALID_CLIENT(%1) (%1 > 0 && %1 <= MaxClients)
#define IS_CONNECTED_INGAME(%1) (IsClientConnected(%1) && IsClientInGame(%1))
#define IS_SPECTATOR(%1) (GetClientTeam(%1) == 1)
#define IS_SURVIVOR(%1) (GetClientTeam(%1) == 2)
#define IS_INFECTED(%1) (GetClientTeam(%1) == 3)
#define IS_VALID_PLAYER(%1) (IS_VALID_CLIENT(%1) && IS_CONNECTED_INGAME(%1))
#define IS_VALID_BOT(%1) (IS_VALID_INGAME(%1) && IsFakeClient(%1))
#define IS_VALID_SPECTATOR(%1) (IS_VALID_PLAYER(%1) && IS_SPECTATOR(%1))
#define IS_VALID_SURVIVOR(%1) (IS_VALID_PLAYER(%1) && IS_SURVIVOR(%1))
#define IS_VALID_INFECTED(%1) (IS_VALID_PLAYER(%1) && IS_INFECTED(%1))
#define IS_SURVIVOR_ALIVE(%1) (IS_VALID_SURVIVOR(%1) && IsPlayerAlive(%1))
#define IS_INFECTED_ALIVE(%1) (IS_VALID_INFECTED(%1) && IsPlayerAlive(%1))
public Plugin myinfo =
{
name = PLUGIN_NAME,
author = PLUGIN_AUTHOR,
description = PLUGIN_DESCRIPTION,
version = PLUGIN_VERSION,
url = PLUGIN_URL
};
ConVar cvar_enable;
ConVar cvar_players_base;
ConVar cvar_check_mode;
ConVar cvar_hp_base[9];
ConVar cvar_hp_min[9];
ConVar cvar_hp_max[9];
ConVar cvar_hp_factor[9];
ConVar cvar_tank_hp;
ConVar cvar_si_health[9];
ConVar cvar_difficulty;
//ArrayList convar_hp;
bool IsEnable;
int CheckMode;
int PlayersBase;
char si_name[9][32]=
{
"",
"smoker",
"boomer",
"hunter",
"spitter",
"jockey",
"charger",
"witch",
"tank"
};
/*
z_hunter_health
z_gas_health //smoker
z_exploding_health // boomer
z_charger_health
z_spitter_health
z_jockey_health
z_witch_health
z_tank_health
*/
public void OnPluginStart()
{
cvar_enable = CreateConVar("balancer_hp_enable", "1","0: Enable, 1:Disable", FCVAR_NONE, true, 0.0, true, 1.0 );
cvar_players_base = CreateConVar("balancer_hp_players_base", "4", "Set survivor players default to set hp base", FCVAR_NONE, true, 0.0);
cvar_check_mode = CreateConVar("balancer_hp_check_mode","0","0: Check all players survivor in game, 1: Ignore check idle survivors, 2: Ignore check survivors bot, 4: Ignore check dead survivors, 7: Set all ignore check modes", FCVAR_NONE, true, 0.0, true, 7.0);
char strCvarName[64],strCvarDesc[256];
for(int i=1; i < sizeof(si_name); i++){
Format(strCvarName, sizeof strCvarName, "balancer_hp_base_%s", si_name[i]);
Format(strCvarDesc, sizeof strCvarDesc, " 0: Set Default value for cvar(z_health_%s), Value > 0 : Set Custom HP Base", si_name[i]);
cvar_hp_base[i] = CreateConVar(strCvarName, "0", strCvarDesc, FCVAR_NONE, true, 0.0 );
Format(strCvarName, sizeof strCvarName, "balancer_hp_min_%s", si_name[i]);
Format(strCvarDesc, sizeof strCvarDesc, " 0: Disable %s decrement HP(min HP = HP base) , (Value > 0): Set decrement limit HP", si_name[i]);
cvar_hp_min[i] = CreateConVar(strCvarName, "0", strCvarDesc, FCVAR_NONE, true, 0.0 );
Format(strCvarName, sizeof strCvarName, "balancer_hp_max_%s", si_name[i]);
Format(strCvarDesc, sizeof strCvarDesc, " 0: Disable %s limit max HP, (Value > 0): Set increment limit HP", si_name[i]);
cvar_hp_max[i] = CreateConVar(strCvarName, "0", strCvarDesc, FCVAR_NONE, true, 0.0 );
Format(strCvarName, sizeof strCvarName, "balancer_hp_factor_%s", si_name[i]);
Format(strCvarDesc, sizeof strCvarDesc, " 0: Disable %s increment/decrement balance HP, (Value < 1): Set factor percent of HP base [example:0.1 = 1%] to increment/decrement per players), (Value >= 1): Set HP value to increment/decrement per players", si_name[i]);
cvar_hp_factor[i] = CreateConVar(strCvarName, "0.1", strCvarDesc, FCVAR_NONE, true, 0.0 );
}
AutoExecConfig(true, "balancer_hp");
cvar_enable.AddChangeHook(CvarsChanged);
cvar_players_base.AddChangeHook(CvarsChanged);
cvar_check_mode.AddChangeHook(CvarsChanged);
HookConVarChange(CreateConVar("z_boomer_health","50", "Boomer health"), CvarChanged_BoomerHealth);
HookConVarChange(CreateConVar("z_smoker_health","250","Smoker health"), CvarChanged_SmokerHealth);
cvar_tank_hp = FindConVar("z_tank_health");
cvar_difficulty = FindConVar("z_difficulty");
for(int i=1; i < sizeof(cvar_si_health); i++){
char cvar_name[32];
Format(cvar_name, sizeof(cvar_name), "z_%s_health", si_name[i]);
cvar_si_health[i] = FindConVar(cvar_name);
}
GetConvars();
//HookEvent("tank_spawn", Event_TankSpawn);
}
public void CvarsChanged(ConVar convar, const char[] oldValue, const char[] newValue){
GetConvars();
}
void GetConvars(){
if(!IsEnable && cvar_enable.BoolValue)
HookEvent("tank_spawn", Event_TankSpawn);
else if(IsEnable && !cvar_enable.BoolValue)
UnhookEvent("tank_spawn", Event_TankSpawn);
IsEnable = cvar_enable.BoolValue;
PlayersBase = cvar_players_base.IntValue;
CheckMode = cvar_check_mode.IntValue;
}
public void CvarChanged_BoomerHealth(ConVar convar, const char[] oldValue, const char[] newValue)
{
SetConVarString(FindConVar("z_exploding_health"), newValue);
}
public void CvarChanged_SmokerHealth(ConVar convar, const char[] oldValue, const char[] newValue)
{
SetConVarString(FindConVar("z_gas_health"), newValue);
}
public Event_TankSpawn(Event event, const char[] name, bool dontBroadcast)
{
if(!IsEnable)
return;
int client = event.GetInt("tankid");
if(IsTank(client)){
// Note that, there are other things that can modify Tank's health which this plugin will end up overwriting, like VScript's "ZombieTankHealth" (Tank Run mutation uses it)
// There might be a better way, but I don't have a good one yet - mac
char difficultyname[12];
GetConVarString(cvar_difficulty, difficultyname, sizeof difficultyname);
if(StrEqual(difficultyname, "Impossible", false) ) {
SetPlayerHealth(client, cvar_tank_hp.IntValue * 2);
}
else if(StrEqual(difficultyname, "Hard", false) ) {
SetPlayerHealth(client, cvar_tank_hp.IntValue + (cvar_tank_hp.IntValue / 2));
}
else {
SetPlayerHealth(client, cvar_tank_hp.IntValue);
}
// PrintToChatAll("\x04[DEBUG] \x05Tank \x03HP \x05is set to: \x03%d", GetEntProp(client, Prop_Send, "m_iHealth") );
}
}
public void OnEntityCreated(int entity, const char[] classname)
{
if(!IsEnable)
return;
for(int i=1; i < sizeof(cvar_si_health); i++){
if(StrEqual(classname, si_name[i], false)){
int hp = GetHPIncrement(i);
SetConVarInt(cvar_si_health[i], hp);
//PrintToChatAll("set %s hp: %d ",classname, hp);
break;
}
}
}
int GetHPIncrement(int iclass){
int hp_min = cvar_hp_min[iclass].IntValue;
int hp_max = cvar_hp_max[iclass].IntValue;
char hpdefault[32];
cvar_si_health[iclass].GetDefault(hpdefault, sizeof hpdefault);
int hp_base = (cvar_hp_base[iclass].IntValue > 0) ? cvar_hp_base[iclass].IntValue : StringToInt(hpdefault);
int survivors = GetSurvivorsCount();
float hp_factor = ( cvar_hp_factor[iclass].FloatValue < 1 ) ? float(hp_base) * cvar_hp_factor[iclass].FloatValue : cvar_hp_factor[iclass].FloatValue ;
//int hp_inc = (survivors > PlayersBase ) ? RoundFloat(hp_factor) * ( survivors - PlayersBase ) : 0;
int hp_inc = RoundFloat(hp_factor) * ( survivors - PlayersBase ) ;
int hp = hp_base + hp_inc;
if(hp_min == 0)
hp_min = hp_base;
if(hp < hp_min)
return hp_min;
if(hp_max > 0 && hp > hp_max)
return hp_max;
return hp;
}
int GetSurvivorsCount(){
int survivors = 0;
for (int i=1; i <= MaxClients; i++)
{
if (IsValidSurvivorCheck(i))
{
survivors++;
}
}
return survivors;
}
bool IsValidSurvivorCheck(int client){
if(IS_VALID_SURVIVOR(client)){
if((CheckMode & 1) && GetBotOfIdle(client) == client)
return false;
if((CheckMode & 2) && IsFakeClient(client) && GetBotOfIdle(client) == 0)
return false;
if((CheckMode & 4) && !IsPlayerAlive(client) )
return false;
return true;
}
return false;
}
stock int GetBotOfIdle(client)
{
for(int i = 1; i <= MaxClients; i++)
{
if (GetIdlePlayer(i) == client) return i;
}
return 0;
}
stock int GetIdlePlayer(int bot)
{
if(IS_SURVIVOR_ALIVE(bot))
{
char sNetClass[12];
GetEntityNetClass(bot, sNetClass, sizeof(sNetClass));
if(strcmp(sNetClass, "SurvivorBot") == 0)
{
int client = GetClientOfUserId(GetEntProp(bot, Prop_Send, "m_humanSpectatorUserID"));
if(IS_VALID_SPECTATOR(client))
{
return client;
}
}
}
return 0;
}
stock bool IsTank(int client)
{
char classname[32];
GetEntityNetClass(client, classname, sizeof(classname));
return ( StrEqual(classname, "Tank", false) );
}
stock void SetPlayerHealth(int client, int amount)
{
SetEntProp(client, Prop_Send, "m_iMaxHealth", amount);
SetEntProp(client, Prop_Send, "m_iHealth", amount);
}