forked from DouglasSherk/AMXModX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
duelmod.sma
653 lines (516 loc) · 16.2 KB
/
duelmod.sma
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
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
/*
Copyleft 2008
Plugin thread: http://forums.alliedmods.net/showthread.php?p=633284
DUEL MOD
========
Description
This mod is designed to allow dueling, where players challenge each
other and engage in battle. It is designed for the mod "The Specialists",
but can be used on other mods.
Commands
say /duel - Will challenge the player being looked at to a duel.
say /accept - Will accept a challenge. Note that you can also use /duel,
but you must be looking at the person who challenged you. With /accept,
the last person to challenge you will be accepted.
say /punchingbag - Turns the player into a punching bag
(requires amx_duel_punchingbag to be set to 1).
Credits
Havoc9 Community - Testing help (specifically SaderBiscut and Jimmy Striker).
Lord_Destros - Testing help.
Steely - Testing help.
sawyer - Testing help.
Frost - Testing help.
coderiz - New semiclip method.
Charming - Encouragement.
Changelog:
Jun 1, 2008 - v1.0 - Initial release
Jun 2, 2008 - v1.1 - [FIXED] Some repeated variables
[FIXED] Message printing incorrectly
[FIXED] Duel off not working properly
[ADDED] Punching bag mode
[ADDED] True semiclip
[ADDED] Attack blocking between
duelists <-> players
[ADDED] God mode to normal players
Jun 4, 2008 - v1.2 - [ADDED] Deny command
[ADDED] Pair command
[ADDED] Name parameter to /duel command
[ADDED] Glow cvar
[FIXED] Messages printing incorrectly
*/
#include <amxmodx>
#include <amxmisc>
#include <fun>
#include <fakemeta>
#include <hamsandwich>
new g_Dueling[33]
new g_Challenge[33]
new g_LastChallenge[33]
new g_PlayerSolid[33]
new g_MessageShown[33]
new g_Countdown[33]
new Float:g_Glow[33][3]
new g_Denied[33]
new g_Pair[33]
new g_HudObject
new g_MaxPlayers
new g_Version[] = "1.2"
new p_On
new p_OnlyDuel
new p_BlockKill
new p_Countdown
new p_PunchingBag
new p_Transparency
new p_Glow
new g_Say[11][] =
{
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten"
}
public plugin_init()
{
register_plugin("Duel Mod",g_Version,"Hawk552")
register_cvar("duelmod_version",g_Version,FCVAR_SERVER)
register_clcmd("say /accept","CmdAccept")
register_clcmd("say /punchingbag","CmdPunchingBag")
register_clcmd("say /deny","CmdDeny")
register_clcmd("say /pair","CmdPair")
register_clcmd("say","CmdSay")
RegisterHam(Ham_TakeDamage,"player","_Ham_TakeDamage")
register_forward(FM_TraceLine,"ForwardTraceLine",1)
register_forward(FM_TraceHull,"ForwardTraceHull",1)
register_forward(FM_PlayerPreThink,"ForwardPlayerPreThink")
register_forward(FM_PlayerPostThink,"ForwardPlayerPostThink")
register_forward(FM_AddToFullPack,"ForwardAddToFullPack",1)
register_event("DeathMsg","EventDeathMsg","a")
register_event("ResetHUD","EventResetHUD","b")
p_On = register_cvar("amx_duel","1")
p_OnlyDuel = register_cvar("amx_duel_onlyduel","1")
p_BlockKill = register_cvar("amx_duel_blockkill","1")
p_Countdown = register_cvar("amx_duel_countdown","3")
p_PunchingBag = register_cvar("amx_duel_punchingbag","1")
p_Transparency = register_cvar("amx_duel_transparency","80")
p_Glow = register_cvar("amx_duel_glow","2")
g_HudObject = CreateHudSyncObj()
g_MaxPlayers = get_maxplayers()
}
public ForwardTraceLine(Float:v1[3],Float:v2[3],NoMonsters,SkipEnt,Ptr)
{
if(!is_user_alive(SkipEnt))
return FMRES_IGNORED
new Ptr2
engfunc(EngFunc_TraceLine,v1,v2,NoMonsters,SkipEnt,Ptr2)
new Hit = get_tr2(0,TR_pHit)
if(is_user_alive(Hit) && ((Hit != g_Dueling[SkipEnt] && g_Dueling[SkipEnt]) || (!g_Dueling[SkipEnt] && g_Dueling[Hit])))
set_tr(TR_flFraction,1.0)
return FMRES_IGNORED
}
public ForwardTraceHull(Float:v1[3],Float:v2[3],NoMonsters,Hull,SkipEnt,Ptr)
{
if(!is_user_alive(SkipEnt))
return FMRES_IGNORED
new Ptr2
engfunc(EngFunc_TraceHull,v1,v2,NoMonsters,Hull,SkipEnt,Ptr2)
new Hit = get_tr2(0,TR_pHit)
if(is_user_alive(Hit) && ((Hit != g_Dueling[SkipEnt] && g_Dueling[SkipEnt]) || (!g_Dueling[SkipEnt] && g_Dueling[Hit])))
set_tr(TR_flFraction,1.0)
return FMRES_IGNORED
}
public client_kill(id)
{
if(get_pcvar_num(p_BlockKill) && g_Dueling[id] && get_pcvar_num(p_On))
{
client_print(id,print_chat,"[DUEL] You cannot kill yourself while dueling.")
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public client_disconnect(id)
{
if(!get_pcvar_num(p_On))
return
g_MessageShown[id] = 0
for(new Count;Count < g_MaxPlayers;Count++)
if(g_Challenge[Count] == id)
g_Challenge[Count] = 0
g_LastChallenge[id] = 0
g_Denied[id] = 0
g_Pair[id] = 0
if(!g_Dueling[id])
return
new Name[33],Other = g_Dueling[id]
get_user_name(id,Name,32)
HudMessage(0,"%s has left while dueling",Name)
g_Dueling[Other] = 0
g_Dueling[id] = 0
Render(Other,0,Float:{255.0,255.0,255.0})
set_pev(Other,pev_health,100.0)
}
public _Ham_TakeDamage(id,Inflictor,Attacker,Float:Damage,DamageBits)
{
if(get_pcvar_num(p_On) && is_user_alive(id) && is_user_alive(Attacker) && (g_Countdown[id] > 1 || (g_Dueling[id] != Attacker && g_Dueling[id]) || (!g_Dueling[id] && g_Dueling[Attacker]) || (get_pcvar_num(p_OnlyDuel) && !g_Dueling[id] && !g_Dueling[Attacker])))
SetHamParamFloat(4,0.0)
return HAM_IGNORED
}
public CmdPunchingBag(id)
{
if(!get_pcvar_num(p_On))
{
client_print(id,print_chat,"[DUEL] Duel Mod is currently disabled.")
return PLUGIN_HANDLED
}
if(!is_user_alive(id))
{
client_print(id,print_chat,"[DUEL] You cannot use this command while dead.")
return PLUGIN_HANDLED
}
if(!get_pcvar_num(p_PunchingBag) || !get_pcvar_num(p_OnlyDuel))
{
client_print(id,print_chat,"[DUEL] Punching bag mode is currently disabled.")
return PLUGIN_HANDLED
}
if(g_Dueling[id])
{
client_print(id,print_chat,"[DUEL] You cannot use punching bag mode while in a duel.")
return PLUGIN_HANDLED
}
new Godmode = !get_user_godmode(id)
set_user_godmode(id,Godmode)
client_print(id,print_chat,"[DUEL] You are now a %s.",Godmode ? "normal player" : "punching bag")
return PLUGIN_HANDLED
}
public CmdPair(id)
{
if(!get_pcvar_num(p_On))
{
client_print(id,print_chat,"[DUEL] Duel Mod is currently disabled.")
return PLUGIN_HANDLED
}
if(g_Dueling[id])
{
client_print(id,print_chat,"[DUEL] You cannot pair up while in a duel.")
return PLUGIN_HANDLED
}
if(!is_user_alive(id))
{
client_print(id,print_chat,"[DUEL] You cannot use this command while dead.")
return PLUGIN_HANDLED
}
g_Pair[id] = !g_Pair[id]
if(g_Pair[id])
for(new Count;Count < g_MaxPlayers;Count++)
if(g_Pair[Count] && Count != id && !(g_Denied[Count] & (1<<(id - 1))))
{
Accept(Count,id,1)
g_Pair[id] = 0
g_Pair[Count] = 0
return PLUGIN_HANDLED
}
client_print(id,print_chat,"[DUEL] You will %s be paired with the next available player.",g_Pair[id] ? "now" : "no longer")
return PLUGIN_HANDLED
}
public CmdAccept(id)
{
if(!get_pcvar_num(p_On))
{
client_print(id,print_chat,"[DUEL] Duel Mod is currently disabled.")
return PLUGIN_HANDLED
}
if(!is_user_alive(id))
{
client_print(id,print_chat,"[DUEL] You cannot use this command while dead.")
return PLUGIN_HANDLED
}
if(!g_LastChallenge[id])
{
client_print(id,print_chat,"[DUEL] You have not been challenged.")
return PLUGIN_HANDLED
}
if(g_Dueling[g_LastChallenge[id]])
{
client_print(id,print_chat,"[DUEL] The person who challenged you is already dueling.")
return PLUGIN_HANDLED
}
if(!is_user_connected(g_LastChallenge[id]))
{
client_print(id,print_chat,"[DUEL] The person who challenged you has left the server.")
return PLUGIN_HANDLED
}
if(!is_user_alive(g_LastChallenge[id]))
{
client_print(id,print_chat,"[DUEL] The person who challenged you is dead.")
return PLUGIN_HANDLED
}
Accept(g_LastChallenge[id],id,0)
return PLUGIN_HANDLED
}
public CmdDeny(id)
{
if(!get_pcvar_num(p_On))
{
client_print(id,print_chat,"[DUEL] Duel Mod is currently disabled.")
return PLUGIN_HANDLED
}
if(!g_LastChallenge[id])
{
client_print(id,print_chat,"[DUEL] You have not been challenged.")
return PLUGIN_HANDLED
}
if(!is_user_connected(g_LastChallenge[id]))
{
client_print(id,print_chat,"[DUEL] The person who challenged you has left the server.")
return PLUGIN_HANDLED
}
new Names[2][33]
get_user_name(id,Names[0],32)
get_user_name(g_LastChallenge[id],Names[1],32)
g_Denied[id] |= (1<<(g_LastChallenge[id] - 1))
client_print(id,print_chat,"[DUEL] You have denied %s a duel. Say /duel or /accept to him to deactivate deny mode.",Names[1])
client_print(g_LastChallenge[id],print_chat,"[DUEL] You have been denied a duel by %s.",Names[0])
return PLUGIN_HANDLED
}
Accept(id,Index,Pair)
{
g_Denied[id] &= ~(1<<(Index - 1))
g_Denied[Index] &= ~(1<<(id - 1))
g_LastChallenge[id] = 0
g_LastChallenge[Index] = 0
set_user_godmode(id)
set_user_godmode(Index)
new Names[2][33]
get_user_name(id,Names[0],32)
get_user_name(Index,Names[1],32)
set_pev(id,pev_health,100.0)
set_pev(Index,pev_health,100.0)
g_Dueling[id] = Index
g_Dueling[Index] = id
g_Pair[id] = 0
g_Pair[Index] = 0
g_Challenge[id] = 0
g_Challenge[Index] = 0
g_Countdown[id] = clamp(get_pcvar_num(p_Countdown),0,10)
g_Countdown[Index] = g_Countdown[id]
set_task(1.0,"Countdown",id)
set_task(1.0,"Countdown",Index)
for(new Count;Count < 3;Count++)
{
g_Glow[id][Count] = random_float(0.0,255.0)
g_Glow[Index][Count] = g_Glow[id][Count]
}
Render(id,1,g_Glow[id])
Render(Index,1,g_Glow[id])
client_print(id,print_chat,Pair ? "[DUEL] You have been paired with %s." : "[DUEL] %s has accepted your challenge!",Names[1])
client_print(Index,print_chat,Pair ? "[DUEL] You have been paired with %s." : "[DUEL] You have accepted %s's challenge.",Names[0])
HudMessage(0,"%s has engaged in a duel with %s!",Names[1],Names[0])
}
public Countdown(id)
{
if(g_Countdown[id])
set_task(1.0,"Countdown",id)
else
{
HudMessage(id,"The duel has begun!")
new Float:Glow = g_Glow[id][2],Float:Glow2 = g_Glow[id][1]
g_Glow[id][2] = g_Glow[id][0]
g_Glow[id][1] = Glow
g_Glow[id][0] = Glow2
Render(id,1,g_Glow[id])
}
client_cmd(id,"spk fvox/%s",g_Say[g_Countdown[id]--])
}
public EventResetHUD(id)
set_task(1.0,"ShowGreeting",id)
public ShowGreeting(id)
{
if(!is_user_alive(id) || !get_pcvar_num(p_On))
return
if(get_pcvar_num(p_OnlyDuel))
set_user_godmode(id,1)
if(!g_MessageShown[id])
{
client_print(id,print_chat,"[DUEL] This server is running Duel Mod version %s by Doug ^"Hawk552^" Karlmann.",g_Version)
client_print(id,print_chat,"[DUEL] To begin, say ^"/duel^" in front of a player you want to duel.")
client_print(id,print_chat,"[DUEL] You can also say ^"/pair^" to duel the next available player.")
g_MessageShown[id] = 1
}
}
public EventDeathMsg()
{
if(!get_pcvar_num(p_On))
return
new id = read_data(2),Other = g_Dueling[id]
if(g_Dueling[id])
{
ForwardPlayerPostThink(id)
g_Dueling[id] = 0
Render(id,0,Float:{255.0,255.0,255.0})
new Names[2][33],Attacker = read_data(1)
get_user_name(id,Names[0],32)
get_user_name(Attacker ? Attacker : Other,Names[1],32)
new Health = get_user_health(Attacker)
if(!Attacker || !is_user_alive(Attacker))
{
HudMessage(0,"%s died while dueling",Names[0])
g_Dueling[Other] = 0
Render(Other,0,Float:{255.0,255.0,255.0})
set_pev(Other,pev_health,100.0)
return
}
client_print(id,print_chat,"[DUEL] %s has defeated you with %d health remaining.",Names[1],Health)
client_print(Attacker,print_chat,"[DUEL] You have defeated %s with %d health remaining.",Names[0],Health)
HudMessage(0,"%s was defeated by %s with %d health remaining!",Names[0],Names[1],Health)
Render(Attacker,0,Float:{255.0,255.0,255.0})
set_task(0.3,"ResetHealth",Attacker)
if(get_pcvar_num(p_OnlyDuel))
set_user_godmode(Attacker,1)
g_Dueling[Attacker] = 0
}
}
public ResetHealth(id)
set_pev(id,pev_health,100.0)
public ForwardAddToFullPack(ES,e,Ent,Host,HostFlags,Player,pSet)
if(Player && get_pcvar_num(p_On) && is_user_alive(Host) && is_user_alive(Ent) && ((g_Dueling[Host] && Ent != g_Dueling[Host]) || (!g_Dueling[Host] && g_Dueling[Ent])))
{
set_es(ES,ES_Solid,SOLID_NOT)
set_es(ES,ES_RenderMode,kRenderTransAlpha)
set_es(ES,ES_RenderAmt,clamp(get_pcvar_num(p_Transparency),0,255))
}
public ForwardPlayerPreThink(id)
{
if(!get_pcvar_num(p_On))
return FMRES_IGNORED
for(new Count = 1;Count <= g_MaxPlayers;Count++)
{
if(!is_user_connected(Count) || Count == id || (!g_Dueling[id] && !g_Dueling[Count]) || g_Dueling[id] == Count)
continue
g_PlayerSolid[Count] = pev(Count,pev_solid)
set_pev(Count,pev_solid,SOLID_NOT)
}
return FMRES_IGNORED
}
public ForwardPlayerPostThink(id)
{
if(!get_pcvar_num(p_On))
return FMRES_IGNORED
for(new Count;Count < g_MaxPlayers;Count++)
{
if(!is_user_connected(Count) || Count == id || (!g_Dueling[id] && !g_Dueling[Count]) || g_Dueling[id] == Count)
continue
set_pev(Count,pev_solid,g_PlayerSolid[Count])
}
return FMRES_IGNORED
}
public CmdSay(id)
{
new Args[256]
read_args(Args,255)
remove_quotes(Args)
trim(Args)
// note that this does NOT mean that it contains no reference of it
// it means that it's in the first cell
if(!containi(Args,"/duel"))
{
if(!get_pcvar_num(p_On))
{
client_print(id,print_chat,"[DUEL] Duel Mod is currently disabled.")
return PLUGIN_HANDLED
}
if(g_Dueling[id])
{
client_print(id,print_chat,"[DUEL] You are already dueling.")
return PLUGIN_HANDLED
}
if(!is_user_alive(id))
{
client_print(id,print_chat,"[DUEL] You cannot use this command while dead.")
return PLUGIN_HANDLED
}
new Command[64],Index,Body
read_args(Command,63)
replace(Command,63,"say","")
remove_quotes(Command)
trim(Command)
replace(Command,63,"/duel","")
if(strlen(Command))
{
trim(Command)
Index = cmd_target(id,Command,0)
if(!Index)
{
client_print(id,print_chat,"[DUEL] Invalid player; please rephrase your input.")
return PLUGIN_HANDLED
}
}
else
get_user_aiming(id,Index,Body)
if(!Index || !is_user_alive(Index))
{
client_print(id,print_chat,"[DUEL] You are not looking at anyone to challenge.")
return PLUGIN_HANDLED
}
if(g_Denied[Index] & (1<<(id - 1)))
{
client_print(id,print_chat,"[DUEL] You have been denied by this player.")
return PLUGIN_HANDLED
}
if(g_Dueling[Index])
{
client_print(id,print_chat,"[DUEL] That user is already dueling.")
return PLUGIN_HANDLED
}
g_Challenge[id] = Index
g_LastChallenge[Index] = id
new Names[2][33]
get_user_name(id,Names[0],32)
get_user_name(Index,Names[1],32)
if(g_Challenge[Index] == id || g_Pair[Index])
{
Accept(id,Index,0)
return PLUGIN_HANDLED
}
client_print(id,print_chat,"[DUEL] You have challenged %s to a duel.",Names[1])
client_print(Index,print_chat,"[DUEL] You have been challenged to a duel by %s. Look at them and say /duel or say /accept to start!",Names[0])
HudMessage(Index,"%s has challenged you to a duel!",Names[0])
return PLUGIN_HANDLED
}
if(containi(Args,"duel") != -1 && containi(Args,"/duel") == -1)
client_print(id,print_chat,"[DUEL] Say /duel to challenge someone.")
return PLUGIN_CONTINUE
}
Render(id,Mode,Float:Glow[3])
{
new GlowCvar = get_pcvar_num(p_Glow)
if(GlowCvar)
return
set_pev(id,pev_renderamt,Mode ? 16.0 : 255.0)
set_pev(id,pev_rendercolor,Glow)
switch(GlowCvar)
{
case 1 :
{
set_pev(id,pev_renderfx,Mode ? kRenderFxGlowShell : kRenderFxNone)
set_pev(id,pev_rendermode,kRenderNormal)
}
case 2 :
{
set_pev(id,pev_renderfx,kRenderFxHologram)
set_pev(id,pev_rendermode,kRenderNormal)
}
}
}
HudMessage(id,Message[],{Float,Sql,Result,_}:...)
{
static Msg[512]
vformat(Msg,511,Message,3)
set_hudmessage(255,255,255,0.5,-0.8,0,6.0,6.0,0.5,0.15,-1)
ShowSyncHudMsg(id,g_HudObject,Msg)
}