Skip to content

Commit 14d47c3

Browse files
committed
安全屋近战
1 parent 8cd3dc1 commit 14d47c3

3 files changed

Lines changed: 321 additions & 0 deletions

File tree

7.81 KB
Binary file not shown.
Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
#pragma semicolon 1
2+
#pragma newdecls required
3+
#include <sourcemod>
4+
#include <sdktools>
5+
6+
#define VERSION "3.1.0"
7+
8+
ArrayList
9+
g_aMeleeScripts;
10+
11+
ConVar
12+
g_hEnabled,
13+
g_hSpawnType,
14+
g_hRandomAmount,
15+
g_hMapBaseAmount,
16+
g_hMeleeItems[14];
17+
18+
int
19+
g_iRoundStart,
20+
g_iPlayerSpawn;
21+
22+
static const char
23+
g_sMeleeModels[][] =
24+
{
25+
"models/weapons/melee/v_fireaxe.mdl",
26+
"models/weapons/melee/w_fireaxe.mdl",
27+
"models/weapons/melee/v_frying_pan.mdl",
28+
"models/weapons/melee/w_frying_pan.mdl",
29+
"models/weapons/melee/v_machete.mdl",
30+
"models/weapons/melee/w_machete.mdl",
31+
"models/weapons/melee/v_bat.mdl",
32+
"models/weapons/melee/w_bat.mdl",
33+
"models/weapons/melee/v_crowbar.mdl",
34+
"models/weapons/melee/w_crowbar.mdl",
35+
"models/weapons/melee/v_cricket_bat.mdl",
36+
"models/weapons/melee/w_cricket_bat.mdl",
37+
"models/weapons/melee/v_tonfa.mdl",
38+
"models/weapons/melee/w_tonfa.mdl",
39+
"models/weapons/melee/v_katana.mdl",
40+
"models/weapons/melee/w_katana.mdl",
41+
"models/weapons/melee/v_electric_guitar.mdl",
42+
"models/weapons/melee/w_electric_guitar.mdl",
43+
"models/v_models/v_knife_t.mdl",
44+
"models/w_models/weapons/w_knife_t.mdl",
45+
"models/weapons/melee/v_golfclub.mdl",
46+
"models/weapons/melee/w_golfclub.mdl",
47+
"models/weapons/melee/v_shovel.mdl",
48+
"models/weapons/melee/w_shovel.mdl",
49+
"models/weapons/melee/v_pitchfork.mdl",
50+
"models/weapons/melee/w_pitchfork.mdl",
51+
"models/weapons/melee/v_riotshield.mdl",
52+
"models/weapons/melee/w_riotshield.mdl"
53+
},
54+
g_sMeleeName[][] =
55+
{
56+
"fireaxe", //斧头
57+
"frying_pan", //平底锅
58+
"machete", //砍刀
59+
"baseball_bat", //棒球棒
60+
"crowbar", //撬棍
61+
"cricket_bat", //球拍
62+
"tonfa", //警棍
63+
"katana", //武士刀
64+
"electric_guitar", //吉他
65+
"knife", //小刀
66+
"golfclub", //高尔夫球棍
67+
"shovel", //铁铲
68+
"pitchfork", //草叉
69+
"riotshield", //盾牌
70+
};
71+
72+
public Plugin myinfo =
73+
{
74+
name = "Melee In The Saferoom",
75+
author = "$atanic $pirit, N3wton",
76+
description = "Spawns a selection of melee weapons in the saferoom, at the start of each round.",
77+
version = VERSION
78+
};
79+
80+
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
81+
{
82+
if(GetEngineVersion() != Engine_Left4Dead2)
83+
{
84+
strcopy(error, err_max, "Melee in the Saferoom only supports Left 4 Dead 2.");
85+
return APLRes_SilentFailure;
86+
}
87+
return APLRes_Success;
88+
}
89+
90+
public void OnPluginStart()
91+
{
92+
g_aMeleeScripts = new ArrayList(64);
93+
94+
CreateConVar("l4d2_mitsr_version", VERSION, "The version of Melee In The Saferoom");
95+
g_hEnabled = CreateConVar("l4d2_mitsr_enabled", "1", "Should the plugin be enabled", _, true, 0.0, true, 1.0);
96+
g_hSpawnType = CreateConVar("l4d2_mitsr_spawn_type", "0", "0 = Custom list, 1 = Random Weapon and 2 = Map based weapons.", _, true, 0.0, true, 2.0);
97+
g_hRandomAmount = CreateConVar("l4d2_mitsr_random_amount", "4","Number of weapons to spawn if l4d2_mitsr_spawn_type is set to 1.", _, true, 0.0, true, 32.0);
98+
g_hMapBaseAmount = CreateConVar("l4d2_mitsr_mapbase_amount", "4", "Number multiple if l4d2_mitsr_spawn_type is set to 2.", _, true, 0.0, true, 32.0);
99+
100+
g_hMeleeItems[0] = CreateConVar("l4d2_mitsr_fireaxe", "1", "Number of fireaxes to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
101+
g_hMeleeItems[1] = CreateConVar("l4d2_mitsr_fryingpan", "0", "Number of frying pans to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
102+
g_hMeleeItems[2] = CreateConVar("l4d2_mitsr_machete", "0", "Number of machetes to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
103+
g_hMeleeItems[3] = CreateConVar("l4d2_mitsr_baseballbat", "0", "Number of baseball bats to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
104+
g_hMeleeItems[4] = CreateConVar("l4d2_mitsr_crowbar", "0", "Number of crowbars to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
105+
g_hMeleeItems[5] = CreateConVar("l4d2_mitsr_cricketbat", "0", "Number of cricket bats to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
106+
g_hMeleeItems[6] = CreateConVar("l4d2_mitsr_tonfa", "1", "Number of tonfas to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
107+
g_hMeleeItems[7] = CreateConVar("l4d2_mitsr_katana", "0", "Number of katanas to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
108+
g_hMeleeItems[8] = CreateConVar("l4d2_mitsr_elecguitar", "0", "Number of electric guitars to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
109+
g_hMeleeItems[9] = CreateConVar("l4d2_mitsr_knife", "0", "Number of knifes to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
110+
g_hMeleeItems[10] = CreateConVar("l4d2_mitsr_golfclub", "0", "Number of golf clubs to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
111+
g_hMeleeItems[11] = CreateConVar("l4d2_mitsr_shovel", "0", "Number of shovels to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
112+
g_hMeleeItems[12] = CreateConVar("l4d2_mitsr_pitchfork", "0", "Number of pitchforks to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
113+
g_hMeleeItems[13] = CreateConVar("l4d2_mitsr_riotshield", "0", "Number of tonfas to spawn (l4d2_mitsr_spawn_type must be 0)", _, true, 0.0, true, 10.0);
114+
115+
//AutoExecConfig(true, "l4d2_melee_in_the_saferoom");
116+
117+
HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy);
118+
HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
119+
HookEvent("player_spawn", Event_PlayerSpawn, EventHookMode_PostNoCopy);
120+
121+
RegAdminCmd("sm_melee", cmdMelee, ADMFLAG_KICK, "Lists all melee weapons spawnable in current campaign");
122+
}
123+
124+
Action cmdMelee(int client, int args)
125+
{
126+
if(g_iRoundStart == 0 || g_iPlayerSpawn == 0)
127+
ReplyToCommand(client, "地图尚未开始");
128+
else
129+
{
130+
ReplyToCommand(client, "当前地图已解锁近战:");
131+
132+
char sScriptName[64];
133+
int iLength = g_aMeleeScripts.Length;
134+
for(int i; i < iLength; i++)
135+
{
136+
g_aMeleeScripts.GetString(i, sScriptName, sizeof sScriptName);
137+
ReplyToCommand(client, "%d : %s", i, sScriptName);
138+
}
139+
}
140+
141+
return Plugin_Handled;
142+
}
143+
144+
public void OnMapStart()
145+
{
146+
int i;
147+
int iLength = sizeof g_sMeleeModels;
148+
for(; i < iLength; i++)
149+
{
150+
if(!IsModelPrecached(g_sMeleeModels[i]))
151+
PrecacheModel(g_sMeleeModels[i], true);
152+
}
153+
154+
iLength = sizeof g_sMeleeName;
155+
char sBuffer[64];
156+
for(i = 0; i < iLength; i++)
157+
{
158+
FormatEx(sBuffer, sizeof sBuffer, "scripts/melee/%s.txt", g_sMeleeName[i]);
159+
if(!IsGenericPrecached(sBuffer))
160+
PrecacheGeneric(sBuffer, true);
161+
}
162+
163+
vGetMeleeWeaponsStringTable();
164+
}
165+
166+
void vGetMeleeWeaponsStringTable()
167+
{
168+
g_aMeleeScripts.Clear();
169+
170+
int iTable = FindStringTable("meleeweapons");
171+
if(iTable != INVALID_STRING_TABLE)
172+
{
173+
int iNum = GetStringTableNumStrings(iTable);
174+
char sMeleeName[64];
175+
for(int i; i < iNum; i++)
176+
{
177+
ReadStringTable(iTable, i, sMeleeName, sizeof sMeleeName);
178+
g_aMeleeScripts.PushString(sMeleeName);
179+
}
180+
}
181+
}
182+
183+
public void OnMapEnd()
184+
{
185+
g_iRoundStart = 0;
186+
g_iPlayerSpawn = 0;
187+
}
188+
189+
void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
190+
{
191+
OnMapEnd();
192+
}
193+
194+
void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast)
195+
{
196+
if(g_iRoundStart == 1 && g_iPlayerSpawn == 0)
197+
CreateTimer(1.0, tmrStartSpawnMelee, _, TIMER_FLAG_NO_MAPCHANGE);
198+
g_iPlayerSpawn = 1;
199+
}
200+
201+
void Event_RoundStart(Event event, const char[] name, bool dontBroadcast)
202+
{
203+
if(g_iRoundStart == 0 && g_iPlayerSpawn == 1)
204+
CreateTimer(1.0, tmrStartSpawnMelee, _, TIMER_FLAG_NO_MAPCHANGE);
205+
g_iRoundStart = 1;
206+
}
207+
208+
Action tmrStartSpawnMelee(Handle timer)
209+
{
210+
vStartSpawnMelee();
211+
return Plugin_Continue;
212+
}
213+
214+
void vStartSpawnMelee()
215+
{
216+
if(!g_hEnabled.BoolValue)
217+
return;
218+
219+
int client = ivGetInGameClient();
220+
if(!client)
221+
return;
222+
223+
int iLimit;
224+
float vOrigin[3];
225+
float vAngles[3];
226+
GetClientAbsOrigin(client, vOrigin);
227+
228+
vOrigin[2] += 20.0;
229+
vAngles[0] = 90.0;
230+
231+
int iLength = g_aMeleeScripts.Length;
232+
if(g_hSpawnType.IntValue == 1)
233+
{
234+
static ArrayList aRandomMelee;
235+
236+
if(bIsGameInFirstHalf())
237+
{
238+
if(aRandomMelee != null)
239+
delete aRandomMelee;
240+
241+
aRandomMelee = g_aMeleeScripts.Clone();
242+
aRandomMelee.Sort(Sort_Random, Sort_String);
243+
}
244+
245+
char sScriptName[64];
246+
iLimit = g_hRandomAmount.IntValue;
247+
for(int i; i < iLimit; i++)
248+
{
249+
aRandomMelee.GetString(i < iLength ? i : GetRandomInt(0, iLength - 1), sScriptName, sizeof sScriptName);
250+
vSpawnMelee(sScriptName, vOrigin, vAngles);
251+
}
252+
}
253+
else if(g_hSpawnType.IntValue == 2)
254+
{
255+
char sScriptName[64];
256+
iLimit = g_hMapBaseAmount.IntValue;
257+
for(int i; i < iLimit; i++)
258+
{
259+
g_aMeleeScripts.GetString(i < iLength ? i : i - (RoundToFloor(float(i / iLength)) * iLength), sScriptName, sizeof sScriptName);
260+
vSpawnMelee(sScriptName, vOrigin, vAngles);
261+
}
262+
}
263+
else
264+
vSpawnCustomList(vOrigin, vAngles);
265+
}
266+
267+
void vSpawnMelee(const char[] sClass, const float vPos[3], const float vAng[3])
268+
{
269+
float vOrigin[3];
270+
float vAngles[3];
271+
vOrigin = vPos;
272+
vAngles = vAng;
273+
274+
vOrigin[0] += (-10.0 + GetRandomFloat(0.0, 20.0));
275+
vOrigin[1] += (-10.0 + GetRandomFloat(0.0, 20.0));
276+
vOrigin[2] += GetRandomFloat(0.0, 10.0);
277+
vAngles[1] = GetRandomFloat(0.0, 360.0);
278+
279+
int entity = CreateEntityByName("weapon_melee");
280+
DispatchKeyValue(entity, "solid", "6");
281+
DispatchKeyValue(entity, "melee_script_name", sClass);
282+
DispatchSpawn(entity);
283+
TeleportEntity(entity, vOrigin, vAngles, NULL_VECTOR);
284+
285+
//SetEntityMoveType(entity, MOVETYPE_NONE);
286+
}
287+
288+
void vSpawnCustomList(const float vPos[3], const float vAng[3])
289+
{
290+
char sScriptName[64];
291+
int iLength = sizeof g_hMeleeItems;
292+
for(int x; x < iLength; x++)
293+
{
294+
for(int i; i < g_hMeleeItems[x].IntValue; i++)
295+
{
296+
if(g_aMeleeScripts.FindString(g_sMeleeName[x]) != -1)
297+
strcopy(sScriptName, sizeof sScriptName, g_sMeleeName[x]);
298+
else
299+
g_aMeleeScripts.GetString(GetRandomInt(0, g_aMeleeScripts.Length - 1), sScriptName, sizeof sScriptName);
300+
301+
vSpawnMelee(sScriptName, vPos, vAng);
302+
}
303+
}
304+
}
305+
306+
int ivGetInGameClient()
307+
{
308+
for(int i = 1; i <= MaxClients; i++)
309+
{
310+
if(IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i))
311+
return i;
312+
}
313+
return 0;
314+
}
315+
316+
bool bIsGameInFirstHalf()
317+
{
318+
return GameRules_GetProp("m_bInSecondHalfOfRound") ? false : true;
319+
}

‎cfg/cfgogl/hyzmtf/shared_plugins.cfg‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ sm plugins load optional/safearea_teleport.smx
149149
sm plugins load optional/Trails_Projectile.smx
150150
sm plugins load optional/l4d2_random_glow_item.smx
151151
sm plugins load afkspec_kick.smx
152+
153+
sm plugins load optional/l4d2_melee_in_the_saferoom.smx
152154
// Letzzzz go.
153155
sm plugins load confoglcompmod.smx
154156
sm plugins load match_vote.smx

0 commit comments

Comments
 (0)