· 6 years ago · Jul 15, 2019, 06:20 AM
1#include <amxmodx>
2#include <amxmisc>
3#include <engine>
4#include <fun>
5#include <cstrike>
6#include <fakemeta>
7#include <colorchat>
8
9#pragma semicolon 1;
10
11#define PLUGIN "AxaGame_BM BlockMaker"
12#define VERSION "5.0"
13#define AUTHOR "Necro - Modified by Kivinen, contact @steam random_1338"
14#define BM_ADMIN_LEVEL ADMIN_MENU //admin access level to use this plugin. ADMIN_MENU = flag 'a'
15
16//***Variables for moving blocks
17//the blocks run though 4 cycles, when this value reaches 3 the cycle restarts
18//all origins are at their origional locations
19new flipside=-1;
20
21//Incriment timer for blocks
22new float:timer = 0;
23
24new movingspotsmall = 1;
25new movingspot = 1;
26new movingspotlarge= 1;
27new bool:stoppedsmall = false;
28new bool:stopped = false;
29new bool:stoppedlarge = false;
30new bool:usedzero = false;
31
32new stopcountsmall = 0;
33new stopcount = 0;
34new stopcountlarge = 0;
35new storespotsmall = 0;
36new storespot = 0;
37new storespotlarge = 0;
38new wait=0;
39new waitmax=1;
40
41new inversesmall= false;
42new inversetwosmall= false;
43new inverse = false;
44new inversetwo = false;
45new inverselarge= false;
46new inversetwolarge= false;
47//blocks start off moving
48new movingblocks=true;
49
50
51//***Variables for orbit blocks
52new movingright = false;
53new movingdown = false;
54new movingleft = false;
55new movingup = false;
56new movingspotx = -150;
57new movingspoty = -150;
58
59new slapshieldactive = false;
60new shieldactive = false;
61
62new slapshieldplayer = 0;
63new shieldplayer = 0;
64new userorigin[3];
65
66new float:shieldorigin[3];
67new float:slapshieldorigin[3];
68
69
70
71new TouchingMagicCarpet[33];
72new target_killer[33];
73new SlapShieldUsed[33];
74new ShieldUsed[33];
75new DeagleUsed[33];
76new AwpUsed[33];
77new DamageBhopUsed[33];
78new FrostUsed[33];
79new FlashUsed[33];
80new HeUsed[33];
81new MoneyUsed[33];
82new LowTrampUsed[33];
83new HighTrampUsed[33];
84new UspUsed[33];
85new Ak47Used[33];
86new M4a1Used[33];
87new Mp5Used[33];
88new M3Used[33];
89new ScoutUsed[33];
90new XPUsed[33];
91
92new gKeysMainMenu;
93new gKeysBlockMenu;
94new gKeysBlockSelectionMenu;
95new gKeysTeleportMenu;
96new gKeysTimerMenu;
97new gKeysMeasureMenu;
98new gKeysLongJumpMenu;
99new gKeysOptionsMenu;
100new gKeysChoiceMenu;
101
102const Float:gfSnapDistance = 10.0; //blocks snap together when they're within this value + the players snap gap
103
104// enum for menu option values
105enum
106{
107 N1, N2, N3, N4, N5, N6, N7, N8, N9, N0
108};
109
110// enum for bit-shifted numbers 1 - 10
111enum
112{
113 B1 = 1 << N1, B2 = 1 << N2, B3 = 1 << N3, B4 = 1 << N4, B5 = 1 << N5,
114 B6 = 1 << N6, B7 = 1 << N7, B8 = 1 << N8, B9 = 1 << N9, B0 = 1 << N0,
115};
116
117// enum for options with YES/NO confirmation
118enum
119{
120 CHOICE_LOAD,
121 CHOICE_DEL_BLOCKS,
122 CHOICE_DEL_TELEPORTS
123};
124
125// enum for different block sizes
126enum
127{
128 NORMAL,
129 SMALL,
130 LARGE,
131 ELARGE,
132 JUMBO,
133 POLE
134};
135
136// enum for axes
137enum
138{
139 X,
140 Y,
141 Z
142};
143
144enum
145{
146 SIZE_SMALL,
147 SIZE_NORMAL,
148 SIZE_LARGE,
149 SIZE_ELARGE,
150 SIZE_JUMBO,
151 SIZE_POLE
152};
153
154// block scales
155const Float:SCALE_SMALL = 0.25;
156const Float:SCALE_NORMAL = 1.0;
157const Float:SCALE_LARGE = 2.0;
158const Float:SCALE_ELARGE = 3.0;
159const Float:SCALE_JUMBO = 6.0;
160const Float:SCALE_POLE = 0.125;
161
162// hud message values
163const gHudRed = 10;
164const gHudGreen = 30;
165const gHudBlue = 200;
166const Float:gfTextX = -1.0;
167const Float:gfTextY = 0.84;
168const gHudEffects = 0;
169const Float:gfHudFxTime = 0.0;
170const Float:gfHudHoldTime = 0.25;
171const Float:gfHudFadeInTime = 0.0;
172const Float:gfHudFadeOutTime = 0.0;
173const gHudChannel = 2;
174
175// Task ID offsets
176const TASK_BHOPSOLID = 1000;
177const TASK_BHOPSOLIDNOT = 2000;
178const TASK_INVINCIBLE = 3000;
179const TASK_STEALTH = 4000;
180const TASK_ICE = 5000;
181const TASK_SPRITE = 6000;
182const TASK_CAMOUFLAGE = 7000;
183const TASK_HONEY = 8000;
184const TASK_FIRE = 9000;
185const TASK_BOOTSOFSPEED = 10000;
186const TASK_TELEPORT = 11000;
187const TASK_NOSLOW = 12000;
188const TASK_AUTOBHOP = 13000;
189
190// strings
191new const gszPrefix[] = "[AxaGame_BM] ";
192new const gszInfoTarget[] = "info_target";
193new const gszHelpFilenameFormat[] = "blockmaker_v%s.txt";
194new gszFile[128];
195new gszNewFile[128];
196new gszMainMenu[256];
197new gszBlockMenu[256];
198new gszTeleportMenu[256];
199new gszTimerMenu[256];
200new gszMeasureMenu[512];
201new gszLongJumpMenu[256];
202new gszOptionsMenu[256];
203new gszChoiceMenu[128];
204new gszHelpTitle[64];
205new gszHelpText[1600];
206new gszHelpFilename[32];
207new gszViewModel[33][32];
208
209// block dimensions
210new Float:gfBlockSizeMinForX[3] = {-4.0,-32.0,-32.0};
211new Float:gfBlockSizeMaxForX[3] = { 4.0, 32.0, 32.0};
212new Float:gfBlockSizeMinForY[3] = {-32.0,-4.0,-32.0};
213new Float:gfBlockSizeMaxForY[3] = { 32.0, 4.0, 32.0};
214new Float:gfBlockSizeMinForZ[3] = {-32.0,-32.0,-4.0};
215new Float:gfBlockSizeMaxForZ[3] = { 32.0, 32.0, 4.0};
216new Float:gfDefaultBlockAngles[3] = { 0.0, 0.0, 0.0 };
217
218new Float:g_pole_size_min_x[3] = {-32.0,-4.0,-4.0};
219new Float:g_pole_size_max_x[3] = { 32.0, 4.0, 4.0};
220new Float:g_pole_size_min_z[3] = {-4.0,-4.0,-32.0};
221new Float:g_pole_size_max_z[3] = { 4.0, 4.0, 32.0};
222new Float:g_pole_size_min_y[3] = {-4.0,-32.0,-4.0};
223new Float:g_pole_size_max_y[3] = { 4.0, 32.0, 4.0};
224
225// block models
226new const gszBlockModelDefault[] = "models/AxaGame_BM/trampoline.mdl";
227new const gszBlockModelPlatform[] = "models/AxaGame_BM/platform.mdl";
228new const gszBlockModelBhop[] = "models/AxaGame_BM
229/bunnyhop.mdl";
230new const gszBlockModelDamage[] = "models/AxaGame_BM
231/damage.mdl";
232new const gszBlockModelHealer[] = "models/AxaGame_BM
233/healer.mdl";
234new const gszBlockModelInvincibility[] = "models/AxaGame_BM
235/invincible.mdl";
236new const gszBlockModelStealth[] = "models/AxaGame_BM
237/stealth.mdl";
238new const gszBlockModelSpeedBoost[] = "models/AxaGame_BM
239/speedboost.mdl";
240new const gszBlockModelNoFallDamage[] = "models/AxaGame_BM
241/nofalldamage.mdl";
242new const gszBlockModelIce[] = "models/AxaGame_BM
243/ice.mdl";
244new const gszBlockModelDeath[] = "models/AxaGame_BM
245/death.mdl";
246new const gszBlockModelNuke[] = "models/AxaGame_BM
247/nuke.mdl";
248new const gszBlockModelCamouflage[] = "models/AxaGame_BM
249/camouflage.mdl";
250new const gszBlockModelLowGravity[] = "models/AxaGame_BM
251/lowgravity.mdl";
252new const gszBlockModelFire[] = "models/AxaGame_BM
253/fire.mdl";
254new const gszBlockModelRandom[] = "models/AxaGame_BM
255/random.mdl";
256new const gszBlockModelSlap[] = "models/AxaGame_BM
257/slap.mdl";
258new const gszBlockModelHoney[] = "models/AxaGame_BM
259/honey.mdl";
260new const gszBlockModelBarrierCT[] = "models/AxaGame_BM
261/ct_barrier.mdl";
262new const gszBlockModelBarrierT[] = "models/AxaGame_BM
263/t_barrier.mdl";
264new const gszBlockModelBootsOfSpeed[] = "models/AxaGame_BM
265/bootsofspeed.mdl";
266new const gszBlockModelGlass[] = "models/AxaGame_BM
267/platform.mdl";
268new const gszBlockModelBhopNoSlow[] = "models/AxaGame_BM
269/bunnyhop.mdl";
270new const gszBlockModelAutoBhop[] = "models/AxaGame_BM
271/autobhop.mdl";
272new const gszBlockModelDeagle[] = "models/AxaGame_BM
273/deagle.mdl";
274new const gszBlockModelAwp[] = "models/AxaGame_BM
275/awp.mdl";
276new const gszBlockModelDamageBhop[] = "models/AxaGame_BM
277/superdelayed.mdl";
278new const gszBlockModelFrost[] = "models/AxaGame_BM
279/frost.mdl";
280new const gszBlockModelFlash[] = "models/AxaGame_BM
281/flash.mdl";
282new const gszBlockModelHe[] = "models/AxaGame_BM
283/he.mdl";
284new const gszBlockModelMoney[] = "models/AxaGame_BM
285/money.mdl";
286new const gszBlockModelLowTramp[] = "models/AxaGame_BM
287/trampoline.mdl";
288new const gszBlockModelHighTramp[] = "models/AxaGame_BM
289/trampoline.mdl";
290new const gszBlockModelUsp[] = "models/AxaGame_BM
291/usp.mdl";
292
293new const gszBlockModelAk47[] = "models/AxaGame_BM
294/ak47.mdl";
295new const gszBlockModelM4a1[] = "models/AxaGame_BM
296/m4a1.mdl";
297new const gszBlockModelMp5[] = "models/AxaGame_BM
298/mp5.mdl";
299new const gszBlockModelM3[] = "models/AxaGame_BM
300/m3.mdl";
301new const gszBlockModelScout[] = "models/AxaGame_BM
302/scout.mdl";
303
304new const gszBlockModelBlind[] = "models/AxaGame_BM
305/blind.mdl";
306new const gszBlockModelXP[] = "models/AxaGame_BM
307/xp.mdl";
308new const gszBlockModelPet[] = "models/AxaGame_BM
309/pet.mdl";
310
311new const gszBlockModelBlindDamage[] = "models/AxaGame_BM
312/blind_damage.mdl";
313new const gszBlockModelBhopUnderblock[] = "models/AxaGame_BM
314/bunnyhop_antiunderblock.mdl";
315
316new const gszBlockModelSmallMovingX[] = "models/AxaGame_BM
317/bunnyhop.mdl";
318new const gszBlockModelMovingX[] = "models/AxaGame_BM
319/bunnyhop.mdl";
320new const gszBlockModelLargeMovingX[] = "models/AxaGame_BM
321/bunnyhop.mdl";
322new const gszBlockModelSmallMovingY[] = "models/AxaGame_BM
323/bunnyhop.mdl";
324new const gszBlockModelMovingY[] = "models/AxaGame_BM
325/bunnyhop.mdl";
326new const gszBlockModelLargeMovingY[] = "models/AxaGame_BM
327/bunnyhop.mdl";
328new const gszBlockModelSmallMovingZ[] = "models/AxaGame_BM
329/bunnyhop.mdl";
330new const gszBlockModelMovingZ[] = "models/AxaGame_BM
331/bunnyhop.mdl";
332new const gszBlockModelLargeMovingZ[] = "models/AxaGame_BM
333/bunnyhop.mdl";
334
335new const gszBlockModelSmallMovingPlatX[] = "models/AxaGame_BM
336/platform.mdl";
337new const gszBlockModelMovingPlatX[] = "models/AxaGame_BM
338/platform.mdl";
339new const gszBlockModelLargeMovingPlatX[] = "models/AxaGame_BM
340/platform.mdl";
341new const gszBlockModelSmallMovingPlatY[] = "models/AxaGame_BM
342/platform.mdl";
343new const gszBlockModelMovingPlatY[] = "models/AxaGame_BM
344/platform.mdl";
345new const gszBlockModelLargeMovingPlatY[] = "models/AxaGame_BM
346/platform.mdl";
347new const gszBlockModelSmallMovingPlatZ[] = "models/AxaGame_BM
348/platform.mdl";
349new const gszBlockModelMovingPlatZ[] = "models/AxaGame_BM
350/platform.mdl";
351new const gszBlockModelLargeMovingPlatZ[] = "models/AxaGame_BM
352/platform.mdl";
353
354new const gszBlockModelSmallMovingTrampX[] = "models/AxaGame_BM
355/trampoline.mdl";
356new const gszBlockModelMovingTrampX[] = "models/AxaGame_BM
357/trampoline.mdl";
358new const gszBlockModelLargeMovingTrampX[] = "models/AxaGame_BM
359/trampoline.mdl";
360new const gszBlockModelSmallMovingTrampY[] = "models/AxaGame_BM
361/trampoline.mdl";
362new const gszBlockModelMovingTrampY[] = "models/AxaGame_BM
363/trampoline.mdl";
364new const gszBlockModelLargeMovingTrampY[] = "models/AxaGame_BM
365/trampoline.mdl";
366new const gszBlockModelSmallMovingTrampZ[] = "models/AxaGame_BM
367/trampoline.mdl";
368new const gszBlockModelMovingTrampZ[] = "models/AxaGame_BM
369/trampoline.mdl";
370new const gszBlockModelLargeMovingTrampZ[] = "models/AxaGame_BM
371/trampoline.mdl";
372
373new const gszBlockModelShield[] = "models/AxaGame_BM
374/death.mdl";
375new const gszBlockModelSlapShield[] = "models/AxaGame_BM
376/slap.mdl";
377
378new const gszBlockModelFollowBhopXPlus[] = "models/AxaGame_BM
379/bunnyhop.mdl";
380new const gszBlockModelFollowBhopXMinus[] = "models/AxaGame_BM
381[] = "models/AxaGame_BM
382/bunnyhop.mdl";
383new const gszBlockModelFollowBhopYMinus[] = "models/AxaGame_BM
384/bunnyhop.mdl";
385new const gszBlockModelMagicCarpet[] = "models/AxaGame_BM
386/magic_carpet.mdl";
387
388
389// block sprites
390new const gszBlockSpriteFire[] = "sprites/AxaGame_BM
391/bm_block_fire.spr"; //custom
392new const gszBlockSpriteFireSmall[] = "sprites/AxaGame_BM
393/bm_block_fire_small.spr"; //custom
394new const gszBlockSpriteFireLarge[] = "sprites/AxaGame_BM
395/bm_block_fire_large.spr"; //custom
396/*
397new const gszBlockSpriteTrampoline[] = "sprites/AxaGame_BM
398/bm_block_trampoline.spr"; //custom
399new const gszBlockSpriteTrampolineSmall[] = "sprites/AxaGame_BM
400/bm_block_trampoline_small.spr"; //custom
401new const gszBlockSpriteTrampolineLarge[] = "sprites/AxaGame_BM
402/bm_block_trampoline_large.spr"; //custom
403new const gszBlockSpriteSpeedBoost[] = "sprites/AxaGame_BM
404/bm_block_speedboost.spr"; //custom
405new const gszBlockSpriteSpeedBoostSmall[] = "sprites/AxaGame_BM
406/bm_block_speedboost_small.spr"; //custom
407new const gszBlockSpriteSpeedBoostLarge[] = "sprites/AxaGame_BM
408/bm_block_speedboost_large.spr"; //custom
409*/
410new const gszFireSprite[] = "sprites/AxaGame_BM/bm_block_fire_flame.spr"; //custom
411
412// block sounds
413new const gszNukeExplosion[] = "weapons/c4_explode1.wav"; //from CS
414new const gszFireSoundFlame[] = "ambience/flameburst1.wav"; //from HL
415new const gszInvincibleSound[] = "warcraft3/divineshield.wav"; //from WC3 plugin
416new const gszCamouflageSound[] = "warcraft3/antend.wav"; //from WC3 plugin
417new const gszStealthSound[] = "warcraft3/levelupcaster.wav"; //from WC3 plugin
418new const gszBootsOfSpeedSound[] = "warcraft3/purgetarget1.wav"; //from WC3 plugin
419new const gszAutoBhopSound[] = "AxaGame_BM
420/boing.wav"; //from 'www.wavsource.com/sfx/sfx.htm'
421
422// teleport
423new const Float:gfTeleportSizeMin[3] = {-16.0,-16.0,-16.0};
424new const Float:gfTeleportSizeMax[3] = { 16.0, 16.0, 16.0};
425new const Float:gfTeleportZOffset = 36.0;
426new const gTeleportStartFrames = 20;
427new const gTeleportEndFrames = 5;
428new const gszTeleportSound[] = "warcraft3/blinkarrival.wav"; //from WC3 plugin
429new const gszTeleportSpriteStart[] = "sprites/AxaGame_BM
430/teleport_start.spr"; //from HL
431new const gszTeleportSpriteEnd[] = "sprites/AxaGame_BM
432/teleport_end.spr"; //custom
433
434// timer
435new const gszTimerModelStart[] = "models/AxaGame_BM
436/bm_timer_start.mdl";
437new const gszTimerModelEnd[] = "models/AxaGame_BM
438/bm_timer_end.mdl";
439new Float:gfTimerSizeMin[3] = {-8.0,-8.0, 0.0};
440new Float:gfTimerSizeMax[3] = { 8.0, 8.0, 60.0};
441new Float:gfTimerTime[33];
442new Float:gfScoreTimes[15];
443new gszScoreNames[15][32];
444new gszScoreSteamIds[15][32];
445new bool:gbHasTimer[33];
446
447// global variables
448new gSpriteIdBeam;
449new gSpriteIdFire;
450new gMsgScreenFade;
451new gBlockSize[33];
452new gMenuBeforeOptions[33];
453new gChoiceOption[33];
454new gBlockMenuPage[33];
455new gTeleportStart[33];
456new gStartTimer[33];
457new gGrabbed[33];
458new gGroupedBlocks[33][256];
459new gGroupCount[33];
460new gMeasureToolBlock1[33];
461new gMeasureToolBlock2[33];
462new gLongJumpDistance[33];
463new gLongJumpAxis[33];
464
465// global booleans
466new bool:gbMeasureToolEnabled[33];
467new bool:gbSnapping[33];
468new bool:gbNoFallDamage[33];
469new bool:gbOnIce[33];
470new bool:gbNoSlowDown[33];
471new bool:gbLowGravity[33];
472new bool:gbOnFire[33];
473new bool:gbAutoBhop[33];
474new bool:gbJustDeleted[33];
475new bool:gbAdminGodmode[33];
476new bool:gbAdminNoclip[33];
477
478// global floats
479new Float:gfSnappingGap[33];
480new Float:gfOldMaxSpeed[33];
481new Float:gfGrablength[33];
482new Float:gfNextHealTime[33];
483new Float:gfNextDamageTime[33];
484new Float:gfInvincibleNextUse[33];
485new Float:gfInvincibleTimeOut[33];
486new Float:gfStealthNextUse[33];
487new Float:gfStealthTimeOut[33];
488new Float:gfTrampolineTimeout[33];
489new Float:gfSpeedBoostTimeOut[33];
490new Float:gfNukeNextUse[33];
491new Float:gfCamouflageNextUse[33];
492new Float:gfCamouflageTimeOut[33];
493new Float:gfRandomNextUse[33];
494new Float:gfBootsOfSpeedTimeOut[33];
495new Float:gfBootsOfSpeedNextUse[33];
496new Float:gfAutoBhopTimeOut[33];
497new Float:gfAutoBhopNextUse[33];
498
499new Float:gfBlindNextUse[33];
500new Float:gfBlindTimeOut[33];
501new Float:g_xp_next_use[33];
502new Float:g_pet_next_use[33];
503
504new g_msgSayText;
505
506
507
508// global vectors
509new Float:gvGrabOffset[33][3];
510new Float:gvMeasureToolPos1[33][3];
511new Float:gvMeasureToolPos2[33][3];
512
513// global strings
514new gszCamouflageOldModel[33][32];
515
516// block & teleport types
517const gBlockMax = 78;
518new gSelectedBlockType[gBlockMax];
519new gRender[gBlockMax];
520new gRed[gBlockMax];
521new gGreen[gBlockMax];
522new gBlue[gBlockMax];
523new gAlpha[gBlockMax];
524
525new const gszBlockClassname[] = "bm_block";
526new const gszSpriteClassname[] = "bm_sprite";
527new const gszTeleportStartClassname[] = "bm_teleport_start";
528new const gszTeleportEndClassname[] = "bm_teleport_end";
529new const gszTimerClassname[] = "bm_timer";
530
531native hnsxp_get_user_xp(client);
532
533native hnsxp_set_user_xp(client, xp);
534
535stock hnsxp_add_user_xp(client, xp)
536{
537 return hnsxp_set_user_xp(client, hnsxp_get_user_xp(client) + xp);
538}
539
540
541enum
542{
543 TELEPORT_START,
544 TELEPORT_END,
545 TIMER_START,
546 TIMER_END
547};
548
549enum
550{
551 BM_PLATFORM, //A
552 BM_BHOP, //B
553 BM_DAMAGE, //C
554 BM_HEALER, //D
555 BM_NOFALLDAMAGE, //I
556 BM_ICE, //J
557 BM_TRAMPOLINE, //G
558 BM_SPEEDBOOST, //H
559 BM_INVINCIBILITY, //E
560 BM_STEALTH, //F
561 BM_DEATH, //K
562 BM_NUKE, //L
563 BM_CAMOUFLAGE, //M
564 BM_LOWGRAVITY, //N
565 BM_FIRE, //O
566 BM_SLAP, //P
567 BM_RANDOM, //Q
568 BM_HONEY, //R
569 BM_BARRIER_CT, //S
570 BM_BARRIER_T, //T
571 BM_BOOTSOFSPEED, //U
572 BM_GLASS, //V
573 BM_BHOP_NOSLOW, //W
574 BM_AUTO_BHOP, //X
575
576 BM_DEAGLE, //Y
577 BM_AWP, //Z
578 BM_DAMAGEBHOP, //a
579 BM_FROST, //b
580 BM_FLASH, //c
581 BM_HE, //d
582 BM_MONEY, //e
583 BM_LOWTRAMP, //f
584 BM_HIGHTRAMP, //g
585 BM_USP, //h
586
587 BM_AK47, //i
588 BM_M4A1, //j
589 BM_MP5, //k
590 BM_M3, //l
591 BM_SCOUT,//m
592 BM_BLIND,//n
593 BM_XP, //o
594 BM_PET,
595 BM_BLINDDAMAGE,
596 BM_BHOPUNDERBLOCK,
597
598 BM_SMALLMOVINGX,
599 BM_MOVINGX,
600 BM_LARGEMOVINGX,
601 BM_SMALLMOVINGY,
602 BM_MOVINGY,
603 BM_LARGEMOVINGY,
604 BM_SMALLMOVINGZ,
605 BM_MOVINGZ,
606 BM_LARGEMOVINGZ,
607
608 BM_SMALLMOVINGPLATX,
609 BM_MOVINGPLATX,
610 BM_LARGEMOVINGPLATX,
611 BM_SMALLMOVINGPLATY,
612 BM_MOVINGPLATY,
613 BM_LARGEMOVINGPLATY,
614 BM_SMALLMOVINGPLATZ,
615 BM_MOVINGPLATZ,
616 BM_LARGEMOVINGPLATZ,
617
618 BM_SMALLMOVINGTRAMPX,
619 BM_MOVINGTRAMPX,
620 BM_LARGEMOVINGTRAMPX,
621 BM_SMALLMOVINGTRAMPY,
622 BM_MOVINGTRAMPY,
623 BM_LARGEMOVINGTRAMPY,
624 BM_SMALLMOVINGTRAMPZ,
625 BM_MOVINGTRAMPZ,
626 BM_LARGEMOVINGTRAMPZ,
627
628 BM_SHIELD,
629 BM_SLAPSHIELD,
630
631 BM_FOLLOWBHOPXPLUS,
632 BM_FOLLOWBHOPXMINUS,
633 BM_FOLLOWBHOPYPLUS,
634 BM_FOLLOWBHOPYMINUS,
635 BM_MAGICCARPET
636 };
637
638enum
639{
640 NORMAL,
641 GLOWSHELL,
642 TRANSCOLOR,
643 TRANSALPHA,
644 TRANSWHITE
645};
646
647new const gszBlockNames[][] =
648{
649 "Platform",
650 "Bunnyhop",
651 "Damage",
652 "Healer",
653 "No Fall Damage",
654 "Ice",
655 "Trampoline",
656 "Speed Boost",
657 "Invincibility",
658 "Stealth",
659 "Death",
660 "Nuke",
661 "Camouflage",
662 "Low Gravity",
663 "Fire",
664 "Slap",
665 "Random",
666 "Honey",
667 "CT Barrier",
668 "T Barrier",
669 "Boots Of Speed",
670 "Glass",
671 "Bunnyhop (Delayed)",
672 "Auto Bunny Hop",
673 "Deagle",
674 "Awp",
675 "Bunnyhop (Semi-Delayed)",
676 "Nade (Frost)",
677 "Nade (Flash)",
678 "Nade (He)",
679 "Money",
680 "Low Trampoline",
681 "High Trampoline",
682 "Usp",
683 "Ak47",
684 "M4A1 Colt",
685 "Mp5 Navy",
686 "M3 Shotgun",
687 "Scout",
688 "Blind",
689 "XP",
690 "Pet",
691 "Blind Damage",
692 "Bhop (Anti-underblock)",
693
694 "Moving Bhop (X)Small",
695 "Moving Bhop (X)Normal",
696 "Moving Bhop (X)Large",
697 "Moving Bhop (Y)Small",
698 "Moving Bhop (Y)Normal",
699 "Moving Bhop (Y)Large",
700 "Moving Bhop (Z)Small",
701 "Moving Bhop (Z)Normal",
702 "Moving Bhop (Z)Large",
703
704 "Moving Block (X)Small",
705 "Moving Block (X)Normal",
706 "Moving Block (X)Large",
707 "Moving Block (Y)Small",
708 "Moving Block (Y)Normal",
709 "Moving Block (Y)Large",
710 "Moving Block (Z)Small",
711 "Moving Block (Z)Normal",
712 "Moving Block (Z)Large",
713
714 "Moving Tramp (X)Small",
715 "Moving Tramp (X)Normal",
716 "Moving Tramp (X)Large",
717 "Moving Tramp (Y)Small",
718 "Moving Tramp (Y)Normal",
719 "Moving Tramp (Y)Large",
720 "Moving Tramp (Z)Small",
721 "Moving Tramp (Z)Normal",
722 "Moving Tramp (Z)Large",
723
724 "Orbit Protect (Death)",
725 "Orbit Proetct (Slap)",
726
727 "Following Bhop (X+)",
728 "Following Bhop (X-)",
729 "Following Bhop (Y+)",
730 "Following Bhop (Y-)",
731 "Magic Carpet"
732};
733
734// save IDs
735new const gBlockSaveIds[gBlockMax] =
736{
737 'A', 'B', 'C', 'D', 'I', 'J', 'G', 'H', 'E', 'F', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X','Y','Z','a','b','c','d','e','f','g','h', 'i','j','k','l','m', 'n','o','p','q','r' , 's','t','u', 'v','w','x',
738 'y','z', '1','2','3','4','5','6','7','8','9','0', ':' , ';' , '<','>','=','?', ']', '[','/' ,'!','@','#','$','%','-','+'
739};
740
741const gTeleportSaveId = '*';
742
743const gTimerSaveId = '&';
744
745//global array of strings to store the paths and filenames to the block models
746new gszBlockModels[gBlockMax][256];
747
748//array of blocks that the random block can be
749const gRandomBlocksMax = 18;
750
751new const gRandomBlocks[gRandomBlocksMax] =
752{
753 BM_INVINCIBILITY,
754 BM_STEALTH,
755 BM_CAMOUFLAGE,
756 BM_SLAP,
757 BM_BOOTSOFSPEED,
758 BM_AUTO_BHOP,
759
760 BM_DEAGLE,
761 BM_AWP,
762 BM_FROST,
763 BM_FLASH,
764 BM_HE,
765 BM_MONEY,
766 BM_USP,
767 BM_AK47,
768 BM_M4A1,
769 BM_MP5,
770 BM_M3,
771 BM_SCOUT
772};
773
774//max speed for player when they have the boots of speed
775const Float:gfBootsMaxSpeed = 400.0;
776
777//how many pages for the block selection menu
778new gBlockMenuPagesMax;
779
780/***** PLUGIN START *****/
781public plugin_init()
782{
783 register_plugin(PLUGIN, VERSION, AUTHOR);
784 register_cvar(PLUGIN, VERSION, FCVAR_SERVER, 0.0);
785
786 //register client commands
787 register_clcmd("say /Haddes", "cmdSay", BM_ADMIN_LEVEL);
788 register_clcmd("say /AxaBlockMaker", "showMainMenu");
789 register_clcmd("say /TaB", "timerShowScoreboard");
790 register_clcmd("+axagrab", "cmdGrab", BM_ADMIN_LEVEL, "bind a key to +bmgrab");
791 register_clcmd("-axagrab", "cmdRelease", BM_ADMIN_LEVEL);
792 register_clcmd("say", "server",0);
793
794 //register forwards
795 register_forward(FM_EmitSound, "forward_EmitSound");
796
797 //create the menus
798 createMenus();
799
800 //register menus
801 register_menucmd(register_menuid("bmMainMenu"), gKeysMainMenu, "handleMainMenu");
802 register_menucmd(register_menuid("bmBlockMenu"), gKeysBlockMenu, "handleBlockMenu");
803 register_menucmd(register_menuid("bmBlockSelectionMenu"), gKeysBlockSelectionMenu, "handleBlockSelectionMenu");
804 register_menucmd(register_menuid("bmTeleportMenu"), gKeysTeleportMenu, "handleTeleportMenu");
805 register_menucmd(register_menuid("bmTimerMenu"), gKeysTimerMenu, "handleTimerMenu");
806 register_menucmd(register_menuid("bmMeasureMenu"), gKeysMeasureMenu, "handleMeasureMenu");
807 register_menucmd(register_menuid("bmLongJumpMenu"), gKeysLongJumpMenu, "handleLongJumpMenu");
808 register_menucmd(register_menuid("bmOptionsMenu"), gKeysOptionsMenu, "handleOptionsMenu");
809 register_menucmd(register_menuid("bmChoiceMenu"), gKeysChoiceMenu, "handleChoiceMenu");
810
811 //register CVARs
812 register_cvar("bm_telefrags", "0");
813 register_cvar("bm_telefrags", "0"); //players near teleport exit die if someone comes through
814 register_cvar("bm_firedamageamount", "24.0"); //damage you take per half-second on the fire block
815 register_cvar("bm_damageamount", "10.0"); //damage you take per half-second on the damage block
816 register_cvar("bm_healamount", "2.0"); //how much hp per half-second you get on the healing block
817 register_cvar("bm_invincibletime", "20.0"); //how long a player is invincible
818 register_cvar("bm_invinciblecooldown", "60.0"); //time before the invincible block can be used again
819 register_cvar("bm_stealthtime", "20.0"); //how long a player is in stealth
820 register_cvar("bm_stealthcooldown", "60.0"); //time before the stealth block can be used again
821 register_cvar("bm_camouflagetime", "20.0"); //how long a player is in camouflage
822 register_cvar("bm_camouflagecooldown", "60.0"); //time before the camouflage block can be used again
823 register_cvar("bm_nukecooldown", "60.0"); //someone might have been invincible when it was used
824 register_cvar("bm_randomcooldown", "60.0"); //time before the random block can be used again
825 register_cvar("bm_bootsofspeedtime", "20.0"); //how long the player has boots of speed
826 register_cvar("bm_bootsofspeedcooldown", "60.0"); //time before boots of speed can be used again
827 register_cvar("bm_autobhoptime", "20.0"); //how long the player has auto bhop
828 register_cvar("bm_autobhopcooldown", "60.0"); //time before auto bhop can be used again
829 register_cvar("bm_teleportsound", "1"); //teleporters make sound
830 register_cvar("bm_blindnotime", "0.0");
831 register_cvar("bm_xpcooldownbm", "200.0");
832 register_cvar("bm_petcooldown", "10.0");
833
834 //something used for exo's colorchat
835 g_msgSayText = get_user_msgid("SayText");
836
837 //register events
838 register_event("DeathMsg", "eventPlayerDeath", "a");
839 register_event("TextMsg", "eventRoundRestart", "a", "2&#Game_C", "2&#Game_w");
840 register_event("ResetHUD", "eventPlayerSpawn", "b");
841 register_event("CurWeapon", "eventCurWeapon", "be");
842 register_logevent("eventRoundRestart", 2, "1=Round_Start");
843
844 //make save folder in basedir (new saving/loading method)
845 new szDir[64];
846 new szMap[32];
847 get_basedir(szDir, 64);
848 add(szDir, 64, "/blockmaker");
849
850 //make config folder if it doesn't already exist
851 if (!dir_exists(szDir))
852 {
853 mkdir(szDir);
854 }
855
856 get_mapname(szMap, 32);
857 formatex(gszNewFile, 96, "%s/%s.bm", szDir, szMap);
858}
859//Connect to AwP Server
860public server(id)
861{
862 new szArgs[17];
863 read_args(szArgs, 16);
864 replace_all(szArgs, 16, "^"", "");
865 new szCmd[10], szParams[5];
866 strbreak(szArgs, szCmd, 9, szParams, 4);
867
868 if ( equali(szCmd, "server", 0) || equali(szCmd, "/server", 0))
869 {
870 new username[42];
871 get_user_name(id, username, 32);
872 hns_print(0, "^x03%s has Redirected to the Official^x04 [AxaGame_BM].HnS Server.^x03 Type /server to Follow",username);
873 client_cmd(id, "Connect 90.224.114.77:27015");
874 }
875}
876public cmdSay(id)
877{
878if (get_user_flags(id) & BM_ADMIN_LEVEL)
879 {
880 if (!movingblocks)
881 {
882 movingblocks = true;
883 }else{
884 movingblocks = false;
885 }
886 }
887}
888
889public plugin_precache()
890{
891 //set block models to defaults
892 gszBlockModels[BM_PLATFORM] = gszBlockModelPlatform;
893 gszBlockModels[BM_BHOP] = gszBlockModelBhop;
894 gszBlockModels[BM_DAMAGE] = gszBlockModelDamage;
895 gszBlockModels[BM_HEALER] = gszBlockModelHealer;
896 gszBlockModels[BM_NOFALLDAMAGE] = gszBlockModelNoFallDamage;
897 gszBlockModels[BM_ICE] = gszBlockModelIce;
898 gszBlockModels[BM_TRAMPOLINE] = gszBlockModelDefault;
899 gszBlockModels[BM_SPEEDBOOST] = gszBlockModelSpeedBoost;
900 gszBlockModels[BM_INVINCIBILITY] = gszBlockModelInvincibility;
901 gszBlockModels[BM_STEALTH] = gszBlockModelStealth;
902 gszBlockModels[BM_DEATH] = gszBlockModelDeath;
903 gszBlockModels[BM_NUKE] = gszBlockModelNuke;
904 gszBlockModels[BM_CAMOUFLAGE] = gszBlockModelCamouflage;
905 gszBlockModels[BM_LOWGRAVITY] = gszBlockModelLowGravity;
906 gszBlockModels[BM_FIRE] = gszBlockModelFire;
907 gszBlockModels[BM_SLAP] = gszBlockModelSlap;
908 gszBlockModels[BM_RANDOM] = gszBlockModelRandom;
909 gszBlockModels[BM_HONEY] = gszBlockModelHoney;
910 gszBlockModels[BM_BARRIER_CT] = gszBlockModelBarrierCT;
911 gszBlockModels[BM_BARRIER_T] = gszBlockModelBarrierT;
912 gszBlockModels[BM_BOOTSOFSPEED] = gszBlockModelBootsOfSpeed;
913 gszBlockModels[BM_GLASS] = gszBlockModelGlass;
914 gszBlockModels[BM_BHOP_NOSLOW] = gszBlockModelBhopNoSlow;
915 gszBlockModels[BM_AUTO_BHOP] = gszBlockModelAutoBhop;
916 gszBlockModels[BM_DEAGLE] = gszBlockModelDeagle;
917 gszBlockModels[BM_AWP] = gszBlockModelAwp;
918 gszBlockModels[BM_DAMAGEBHOP] = gszBlockModelDamageBhop;
919 gszBlockModels[BM_FROST] = gszBlockModelFrost;
920 gszBlockModels[BM_FLASH] = gszBlockModelFlash;
921 gszBlockModels[BM_HE] = gszBlockModelHe;
922 gszBlockModels[BM_MONEY] = gszBlockModelMoney;
923 gszBlockModels[BM_LOWTRAMP] = gszBlockModelLowTramp;
924 gszBlockModels[BM_HIGHTRAMP] = gszBlockModelHighTramp;
925 gszBlockModels[BM_USP] = gszBlockModelUsp;
926
927 gszBlockModels[BM_AK47] = gszBlockModelAk47;
928 gszBlockModels[BM_M4A1] = gszBlockModelM4a1;
929 gszBlockModels[BM_MP5] = gszBlockModelMp5;
930 gszBlockModels[BM_M3] = gszBlockModelM3;
931 gszBlockModels[BM_SCOUT] = gszBlockModelScout;
932
933 gszBlockModels[BM_BLIND] = gszBlockModelBlind;
934 gszBlockModels[BM_XP] = gszBlockModelXP;
935 gszBlockModels[BM_PET] = gszBlockModelPet;
936 gszBlockModels[BM_BLINDDAMAGE] = gszBlockModelBlindDamage;
937 gszBlockModels[BM_BHOPUNDERBLOCK] = gszBlockModelBhopUnderblock;
938
939 gszBlockModels[BM_SMALLMOVINGX] = gszBlockModelSmallMovingX;
940 gszBlockModels[BM_MOVINGX] = gszBlockModelMovingX;
941 gszBlockModels[BM_LARGEMOVINGX] = gszBlockModelLargeMovingX;
942 gszBlockModels[BM_SMALLMOVINGY] = gszBlockModelSmallMovingY;
943 gszBlockModels[BM_MOVINGY] = gszBlockModelMovingY;
944 gszBlockModels[BM_LARGEMOVINGY] = gszBlockModelLargeMovingY;
945 gszBlockModels[BM_SMALLMOVINGZ] = gszBlockModelSmallMovingZ;
946 gszBlockModels[BM_MOVINGZ] = gszBlockModelMovingZ;
947 gszBlockModels[BM_LARGEMOVINGZ] = gszBlockModelLargeMovingZ;
948
949 gszBlockModels[BM_SMALLMOVINGPLATX] = gszBlockModelSmallMovingPlatX;
950 gszBlockModels[BM_MOVINGPLATX] = gszBlockModelMovingPlatX;
951 gszBlockModels[BM_LARGEMOVINGPLATX] = gszBlockModelLargeMovingPlatX;
952 gszBlockModels[BM_SMALLMOVINGPLATY] = gszBlockModelSmallMovingPlatY;
953 gszBlockModels[BM_MOVINGPLATY] = gszBlockModelMovingPlatY;
954 gszBlockModels[BM_LARGEMOVINGPLATY] = gszBlockModelLargeMovingPlatY;
955 gszBlockModels[BM_SMALLMOVINGPLATZ] = gszBlockModelSmallMovingPlatZ;
956 gszBlockModels[BM_MOVINGPLATZ] = gszBlockModelMovingPlatZ;
957 gszBlockModels[BM_LARGEMOVINGPLATZ] = gszBlockModelLargeMovingPlatZ;
958
959 gszBlockModels[BM_SMALLMOVINGTRAMPX] = gszBlockModelSmallMovingTrampX;
960 gszBlockModels[BM_MOVINGTRAMPX] = gszBlockModelMovingTrampX;
961 gszBlockModels[BM_LARGEMOVINGTRAMPX] = gszBlockModelLargeMovingTrampX;
962 gszBlockModels[BM_SMALLMOVINGTRAMPY] = gszBlockModelSmallMovingTrampY;
963 gszBlockModels[BM_MOVINGTRAMPY] = gszBlockModelMovingTrampY;
964 gszBlockModels[BM_LARGEMOVINGTRAMPY] = gszBlockModelLargeMovingTrampY;
965 gszBlockModels[BM_SMALLMOVINGTRAMPZ] = gszBlockModelSmallMovingTrampZ;
966 gszBlockModels[BM_MOVINGTRAMPZ] = gszBlockModelMovingTrampZ;
967 gszBlockModels[BM_LARGEMOVINGTRAMPZ] = gszBlockModelLargeMovingTrampZ;
968
969 gszBlockModels[BM_SHIELD] = gszBlockModelShield;
970 gszBlockModels[BM_SLAPSHIELD] = gszBlockModelSlapShield;
971
972 gszBlockModels[BM_FOLLOWBHOPXPLUS] = gszBlockModelFollowBhopXPlus;
973 gszBlockModels[BM_FOLLOWBHOPXMINUS] = gszBlockModelFollowBhopXMinus;
974 gszBlockModels[BM_FOLLOWBHOPYPLUS] = gszBlockModelFollowBhopYPlus;
975 gszBlockModels[BM_FOLLOWBHOPYMINUS] = gszBlockModelFollowBhopYMinus;
976 gszBlockModels[BM_MAGICCARPET] = gszBlockModelMagicCarpet;
977
978 //setup default block rendering (unlisted block use normal rendering)
979 setupBlockRendering(BM_INVINCIBILITY, GLOWSHELL, 255, 255, 255, 16);
980 setupBlockRendering(BM_SHIELD, GLOWSHELL, 255, 255, 255, 16);
981 setupBlockRendering(BM_SLAPSHIELD, GLOWSHELL, 255, 255, 255, 16);
982 setupBlockRendering(BM_FOLLOWBHOPXPLUS, GLOWSHELL, 255, 255, 255, 16);
983 setupBlockRendering(BM_FOLLOWBHOPXMINUS, GLOWSHELL, 255, 255, 255, 16);
984 setupBlockRendering(BM_FOLLOWBHOPYPLUS, GLOWSHELL, 255, 255, 255, 16);
985 setupBlockRendering(BM_FOLLOWBHOPYMINUS, GLOWSHELL, 255, 255, 255, 16);
986 //weapons
987 setupBlockRendering(BM_DEAGLE, GLOWSHELL, 0, 0, 255, 16);
988 setupBlockRendering(BM_AWP, GLOWSHELL, 255, 0, 0, 16);
989 setupBlockRendering(BM_FROST, GLOWSHELL, 0, 255, 0, 16);
990 setupBlockRendering(BM_FLASH, GLOWSHELL, 255, 255, 0, 16);
991 setupBlockRendering(BM_HE, GLOWSHELL, 255, 0, 0, 16);
992 setupBlockRendering(BM_M3, GLOWSHELL, 255, 255, 125, 16);
993 setupBlockRendering(BM_MP5, GLOWSHELL, 255, 50, 50, 16);
994 setupBlockRendering(BM_M4A1, GLOWSHELL, 200, 200, 200, 16);
995 setupBlockRendering(BM_AK47, GLOWSHELL, 200, 200, 200, 16);
996 setupBlockRendering(BM_USP, GLOWSHELL, 50, 50, 255, 16);
997 setupBlockRendering(BM_SCOUT, GLOWSHELL, 255, 30, 30, 16);
998 setupBlockRendering(BM_MONEY, GLOWSHELL, 30, 255, 30, 16);
999
1000 setupBlockRendering(BM_STEALTH, TRANSWHITE, 255, 255, 255, 80);
1001 setupBlockRendering(BM_GLASS, TRANSWHITE, 255, 255, 255, 185);
1002 setupBlockRendering(BM_DEATH, TRANSALPHA, 255, 255, 255, 255);
1003 setupBlockRendering(BM_NOFALLDAMAGE, TRANSALPHA, 255, 255, 255, 255);
1004 setupBlockRendering(BM_BLIND, TRANSALPHA, 255, 255, 255, 185);
1005 setupBlockRendering(BM_BLINDDAMAGE, TRANSALPHA, 255, 255, 255, 185);
1006
1007 /*
1008 setupBlockRendering(BM_BHOP, TRANSALPHA, 255, 255, 255, 200);
1009 setupBlockRendering(BM_BHOP_NOSLOW, TRANSALPHA, 255, 255, 255, 200);
1010 setupBlockRendering(BM_DAMAGEBHOP, TRANSALPHA, 255, 255, 255, 200);
1011 setupBlockRendering(BM_PLATFORM, TRANSALPHA, 255, 255, 255, 200);
1012 */
1013
1014 setupBlockRendering(BM_HEALER, TRANSALPHA, 255, 255, 255, 255);
1015
1016
1017 //process block models config file
1018 processBlockModels();
1019
1020 new szBlockModelSmall[256];
1021 new szBlockModelLarge[256];
1022 new szBlockModelElarge[256];
1023 new szBlockModelJumbo[256];
1024 new szBlockModelPole[256];
1025
1026 //precache blocks
1027 for (new i = 0; i < gBlockMax; ++i)
1028 {
1029 //get filenames for the small and large blocks based on normal block name
1030 setBlockModelNameSmall(szBlockModelSmall, gszBlockModels[i], 256);
1031 setBlockModelNameLarge(szBlockModelLarge, gszBlockModels[i], 256);
1032 setBlockModelNameElarge(szBlockModelElarge, gszBlockModels[i], 256);
1033 setBlockModelNameJumbo(szBlockModelJumbo, gszBlockModels[i], 256);
1034 setBlockModelNamePole(szBlockModelPole, gszBlockModels[i], 256);
1035
1036 precache_model(gszBlockModels[i]);
1037 precache_model(szBlockModelSmall);
1038 precache_model(szBlockModelLarge);
1039 precache_model(szBlockModelElarge);
1040 precache_model(szBlockModelJumbo);
1041 precache_model(szBlockModelPole);
1042 }
1043
1044 //precache timer models
1045 precache_model(gszTimerModelStart);
1046 precache_model(gszTimerModelEnd);
1047
1048 //precache sprites
1049
1050 precache_model(gszBlockSpriteFire);
1051 precache_model(gszBlockSpriteFireSmall);
1052 precache_model(gszBlockSpriteFireLarge);
1053 /*
1054 precache_model(gszBlockSpriteTrampoline);
1055 precache_model(gszBlockSpriteTrampolineSmall);
1056 precache_model(gszBlockSpriteTrampolineLarge);
1057 precache_model(gszBlockSpriteSpeedBoost);
1058 precache_model(gszBlockSpriteSpeedBoostSmall);
1059 precache_model(gszBlockSpriteSpeedBoostLarge);
1060 */
1061
1062 precache_model(gszTeleportSpriteStart);
1063 precache_model(gszTeleportSpriteEnd);
1064 gSpriteIdFire = precache_model(gszFireSprite);
1065 gSpriteIdBeam = precache_model("sprites/zbeam4.spr");
1066
1067 //precache sounds
1068 precache_sound(gszTeleportSound);
1069 precache_sound(gszNukeExplosion);
1070 precache_sound(gszInvincibleSound);
1071 precache_sound(gszCamouflageSound);
1072 precache_sound(gszStealthSound);
1073 precache_sound(gszFireSoundFlame);
1074 precache_sound(gszBootsOfSpeedSound);
1075 precache_sound(gszAutoBhopSound);
1076}
1077
1078public plugin_cfg()
1079{
1080 //format help text filename
1081 format(gszHelpFilename, 32, gszHelpFilenameFormat, VERSION);
1082
1083 //create help title
1084 format(gszHelpTitle, sizeof(gszHelpTitle), "%s v%s by %s", PLUGIN, VERSION, AUTHOR);
1085
1086 //read in help text from file
1087 new szConfigsDir[32];
1088 new szHelpFilename[64];
1089 new szLine[128];
1090 get_configsdir(szConfigsDir, 32);
1091 format(szHelpFilename, sizeof(szHelpFilename), "%s/%s", szConfigsDir, gszHelpFilename);
1092
1093 //open help file for reading
1094 new f = fopen(szHelpFilename, "rt");
1095
1096 //iterate through all the lines in the file
1097 new size = sizeof(gszHelpText);
1098 while (!feof(f))
1099 {
1100 fgets(f, szLine, 128);
1101
1102 add(gszHelpText, size, szLine);
1103 }
1104
1105 //close file
1106 fclose(f);
1107
1108 //get id for message 'ScreenFade'
1109 gMsgScreenFade = get_user_msgid("ScreenFade");
1110
1111 //make the scoreboard times very large
1112 for (new i = 0; i < 15; ++i)
1113 {
1114 gfScoreTimes[i] = 999999.9;
1115 }
1116
1117 //load blocks from file
1118 loadBlocks(0);
1119}
1120
1121createMenus()
1122{
1123 //calculate maximum number of block menu pages from maximum amount of blocks
1124 gBlockMenuPagesMax = floatround((float(gBlockMax) / 8.0), floatround_ceil);
1125
1126 //create main menu
1127 new size = sizeof(gszMainMenu);
1128 add(gszMainMenu, size, "y[Kivinen's Ultimate Course Maker] Main Menu^n^n");
1129 add(gszMainMenu, size, "r1. wBlock Menu^n");
1130 add(gszMainMenu, size, "r2. wTeleport Menu^n");
1131 add(gszMainMenu, size, "r3. wTimer Menu^n");
1132 add(gszMainMenu, size, "r4. wMeasuring Tool^n");
1133 add(gszMainMenu, size, "r5. wLong Jump Creator^n^n");
1134 add(gszMainMenu, size, "r6. %sNoclip: %s^n");
1135 add(gszMainMenu, size, "r7. %sGodmode: %s^n^n^n");
1136 add(gszMainMenu, size, "r9. wOptions Menu^n");
1137 add(gszMainMenu, size, "r0. wClose");
1138 gKeysMainMenu = B1 | B2 | B3 | B4 | B5 | B6 | B7 | B9 | B0;
1139
1140 //create block menu
1141 size = sizeof(gszBlockMenu);
1142 add(gszBlockMenu, size, "y[AxaGame_BM]Block Menu^n^n");
1143 add(gszBlockMenu, size, "r1. wBlock Type: y%s^n");
1144 add(gszBlockMenu, size, "r2. %sCreate Block^n");
1145 add(gszBlockMenu, size, "r3. %sConvert Block^n");
1146 add(gszBlockMenu, size, "r4. %sDelete Block^n");
1147 add(gszBlockMenu, size, "r5. %sRotate Block^n^n");
1148 add(gszBlockMenu, size, "r6. %sNoclip: %s^n");
1149 add(gszBlockMenu, size, "r7. %sGodmode: %s^n");
1150 add(gszBlockMenu, size, "r8. wBlock Size: y%s^n^n");
1151 add(gszBlockMenu, size, "r9. wOptions Menu^n");
1152 add(gszBlockMenu, size, "r0. wBack");
1153 gKeysBlockMenu = B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | B9 | B0;
1154 gKeysBlockSelectionMenu = B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | B9 | B0;
1155
1156 //create teleport menu
1157 size = sizeof(gszTeleportMenu);
1158 add(gszTeleportMenu, size, "y[AxaGame_BM]Teleporter Menu^n^n");
1159 add(gszTeleportMenu, size, "r1. %sTeleport Start^n");
1160 add(gszTeleportMenu, size, "r2. %sTeleport Destination^n");
1161 add(gszTeleportMenu, size, "r3. %sSwap Teleport Start/Destination^n");
1162 add(gszTeleportMenu, size, "r4. %sDelete Teleport^n");
1163 add(gszTeleportMenu, size, "r5. %sShow Teleport Path^n^n");
1164 add(gszTeleportMenu, size, "r6. %sNoclip: %s^n");
1165 add(gszTeleportMenu, size, "r7. %sGodmode: %s^n^n^n");
1166 add(gszTeleportMenu, size, "r9. wOptions Menu^n");
1167 add(gszTeleportMenu, size, "r0. wBack");
1168 gKeysTeleportMenu = B1 | B2 | B3 | B4 | B5 | B6 | B7 | B9 | B0;
1169
1170 //create timer menu
1171 size = sizeof(gszTimerMenu);
1172 add(gszTimerMenu, size, "y[AxaGame_BM]Timer Menu^n^n");
1173 add(gszTimerMenu, size, "r1. %sTimer Start^n");
1174 add(gszTimerMenu, size, "r2. %sTimer End^n");
1175 add(gszTimerMenu, size, "r3. %sSwap Start/End^n");
1176 add(gszTimerMenu, size, "r4. %sDelete Timer^n");
1177 add(gszTimerMenu, size, "r5. %sRotate Timer^n^n");
1178 add(gszTimerMenu, size, "r6. %sNoclip: %s^n");
1179 add(gszTimerMenu, size, "r7. %sGodmode: %s^n^n^n");
1180 add(gszTimerMenu, size, "r9. wOptions Menu^n");
1181 add(gszTimerMenu, size, "r0. wBack");
1182 gKeysTimerMenu = B1 | B2 | B3 | B4 | B5 | B6 | B7 | B9 | B0;
1183
1184 //measuring tool menu
1185 size = sizeof(gszMeasureMenu);
1186 add(gszMeasureMenu, size, "y[AxaGame_BM]Measuring Tool Menu^n^n");
1187 add(gszMeasureMenu, size, "r1. wBlock 1: y%s^n");
1188 add(gszMeasureMenu, size, "r2. wBlock 2: y%s^n");
1189 add(gszMeasureMenu, size, "r3. wPosition 1: y%.2f, %.2f, %.2f^n");
1190 add(gszMeasureMenu, size, "r4. wPosition 2: y%.2f, %.2f, %.2f^n^n");
1191 add(gszMeasureMenu, size, "r5. %sMeasuring Tool: %s^n");
1192 add(gszMeasureMenu, size, "r6. %sNoclip: %s^n");
1193 add(gszMeasureMenu, size, "r7. %sGodmode: %s^n^n^n");
1194 add(gszMeasureMenu, size, "r9. wOptions Menu^n");
1195 add(gszMeasureMenu, size, "r0. wBack");
1196 gKeysMeasureMenu = B1 | B2 | B3 | B4 | B5 | B6 | B7 | B9 | B0;
1197
1198 //long jump menu
1199 size = sizeof(gszLongJumpMenu);
1200 add(gszLongJumpMenu, size, "y[AxaGame_BM]Long Jump Creator Menu^n^n");
1201 add(gszLongJumpMenu, size, "r1. wDistance +^n");
1202 add(gszLongJumpMenu, size, "r2. %sCreate y%d %sUnit Long Jump Along y%s^n");
1203 add(gszLongJumpMenu, size, "r3. wDistance -^n");
1204 add(gszLongJumpMenu, size, "r4. %sDelete Block^n");
1205 add(gszLongJumpMenu, size, "r5. %sRotate^n^n");
1206 add(gszLongJumpMenu, size, "r6. %sNoclip: %s^n");
1207 add(gszLongJumpMenu, size, "r7. %sGodmode: %s^n");
1208 add(gszLongJumpMenu, size, "r8. wBlock Size: y%s^n^n");
1209 add(gszLongJumpMenu, size, "r9. wOptions Menu^n");
1210 add(gszLongJumpMenu, size, "r0. wBack");
1211 gKeysLongJumpMenu = B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | B9 | B0;
1212
1213 //create the options menu
1214 size = sizeof(gszOptionsMenu);
1215 add(gszOptionsMenu, size, "y[AxaGame_BM]Options Menu^n^n");
1216 add(gszOptionsMenu, size, "r1. %sSnapping: %s^n");
1217 add(gszOptionsMenu, size, "r2. %sSnapping gap: y%.1f^n");
1218 add(gszOptionsMenu, size, "r3. %sAdd to group^n");
1219 add(gszOptionsMenu, size, "r4. %sClear group^n^n");
1220 add(gszOptionsMenu, size, "r5. %sDelete all blocks^n");
1221 add(gszOptionsMenu, size, "r6. %sDelete all teleports^n^n");
1222 add(gszOptionsMenu, size, "r7. %sSave to file^n");
1223 add(gszOptionsMenu, size, "r8. %sLoad from file^n");
1224 add(gszOptionsMenu, size, "r9. wShow help^n");
1225 add(gszOptionsMenu, size, "r0. wBack");
1226 gKeysOptionsMenu = B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | B9 | B0;
1227
1228 //create choice (YES/NO) menu
1229 size = sizeof(gszChoiceMenu);
1230 add(gszChoiceMenu, size, "y%s^n^n");
1231 add(gszChoiceMenu, size, "r1. wYes^n");
1232 add(gszChoiceMenu, size, "r2. wNo^n^n^n^n^n^n^n^n^n^n");
1233 add(gszChoiceMenu, size, "r0. wBack");
1234 gKeysChoiceMenu = B1 | B2 | B0;
1235}
1236
1237setupBlockRendering(blockType, renderType, red, green, blue, alpha)
1238{
1239 gRender[blockType] = renderType;
1240 gRed[blockType] = red;
1241 gGreen[blockType] = green;
1242 gBlue[blockType] = blue;
1243 gAlpha[blockType] = alpha;
1244}
1245
1246setBlockModelNamePole(szBlockModelTarget[256], szBlockModelSource[256], size)
1247{
1248 szBlockModelTarget = szBlockModelSource;
1249 replace(szBlockModelTarget, size, ".mdl", "_pole.mdl");
1250}
1251
1252setBlockModelNameJumbo(szBlockModelTarget[256], szBlockModelSource[256], size)
1253{
1254 szBlockModelTarget = szBlockModelSource;
1255 replace(szBlockModelTarget, size, ".mdl", "_jumbo.mdl");
1256}
1257
1258setBlockModelNameElarge(szBlockModelTarget[256], szBlockModelSource[256], size)
1259{
1260 szBlockModelTarget = szBlockModelSource;
1261 replace(szBlockModelTarget, size, ".mdl", "_elarge.mdl");
1262}
1263
1264setBlockModelNameLarge(szBlockModelTarget[256], szBlockModelSource[256], size)
1265{
1266 szBlockModelTarget = szBlockModelSource;
1267 replace(szBlockModelTarget, size, ".mdl", "_large.mdl");
1268}
1269
1270setBlockModelNameSmall(szBlockModelTarget[256], szBlockModelSource[256], size)
1271{
1272 szBlockModelTarget = szBlockModelSource;
1273 replace(szBlockModelTarget, size, ".mdl", "_small.mdl");
1274}
1275
1276processBlockModels()
1277{
1278 //get full path to block models config file
1279 new szBlockModelsFile[96];
1280 get_configsdir(szBlockModelsFile, 96);
1281 add(szBlockModelsFile, 96, "/blockmaker_models.ini");
1282
1283 //open block models config file for reading
1284 new f = fopen(szBlockModelsFile, "rt");
1285 new szData[160];
1286 new szType[32];
1287 new szBlockModel[256];
1288 new szRender[16];
1289 new szRed[8];
1290 new szGreen[8];
1291 new szBlue[8];
1292 new szAlpha[8];
1293 new blockType;
1294 new render;
1295 new red;
1296 new green;
1297 new blue;
1298 new alpha;
1299
1300 //iterate through all the lines in the file
1301 while (!feof(f))
1302 {
1303 //clear data
1304 szBlockModel = "";
1305 szRender = "";
1306 szRed = "";
1307 szGreen = "";
1308 szBlue = "";
1309 szAlpha = "";
1310 blockType = -1;
1311
1312 //get and parse a line of data from file
1313 fgets(f, szData, 160);
1314 parse(szData, szType, 24, szBlockModel, 64, szRender, 16, szRed, 8, szGreen, 8, szBlue, 8, szAlpha, 8);
1315
1316 //replace '' with '/' in block model path
1317 replace_all(szBlockModel, 64, "", "/");
1318
1319 if (equal(szType, "PLATFORM")) blockType = BM_PLATFORM;
1320 else if (equal(szType, "BHOP")) blockType = BM_BHOP;
1321 else if (equal(szType, "DAMAGE")) blockType = BM_DAMAGE;
1322 else if (equal(szType, "HEALER")) blockType = BM_HEALER;
1323 else if (equal(szType, "NOFALLDAMAGE")) blockType = BM_NOFALLDAMAGE;
1324 else if (equal(szType, "ICE")) blockType = BM_ICE;
1325 else if (equal(szType, "TRAMPOLINE")) blockType = BM_TRAMPOLINE;
1326 else if (equal(szType, "SPEEDBOOST")) blockType = BM_SPEEDBOOST;
1327 else if (equal(szType, "INVINCIBILITY")) blockType = BM_INVINCIBILITY;
1328 else if (equal(szType, "STEALTH")) blockType = BM_STEALTH;
1329 else if (equal(szType, "DEATH")) blockType = BM_DEATH;
1330 else if (equal(szType, "NUKE")) blockType = BM_NUKE;
1331 else if (equal(szType, "CAMOUFLAGE")) blockType = BM_CAMOUFLAGE;
1332 else if (equal(szType, "LOWGRAVITY")) blockType = BM_LOWGRAVITY;
1333 else if (equal(szType, "FIRE")) blockType = BM_FIRE;
1334 else if (equal(szType, "SLAP")) blockType = BM_SLAP;
1335 else if (equal(szType, "RANDOM")) blockType = BM_RANDOM;
1336 else if (equal(szType, "HONEY")) blockType = BM_HONEY;
1337 else if (equal(szType, "BARRIER_CT")) blockType = BM_BARRIER_CT;
1338 else if (equal(szType, "BARRIER_T")) blockType = BM_BARRIER_T;
1339 else if (equal(szType, "BOOTSOFSPEED")) blockType = BM_BOOTSOFSPEED;
1340 else if (equal(szType, "GLASS")) blockType = BM_GLASS;
1341 else if (equal(szType, "BHOP_NOSLOW")) blockType = BM_BHOP_NOSLOW;
1342 else if (equal(szType, "AUTO_BHOP")) blockType = BM_AUTO_BHOP;
1343 else if (equal(szType, "DEAGLE")) blockType = BM_DEAGLE;
1344 else if (equal(szType, "AWP")) blockType = BM_AWP;
1345 else if (equal(szType, "DAMAGEBHOP")) blockType = BM_DAMAGEBHOP;
1346 else if (equal(szType, "FROST")) blockType = BM_FROST;
1347 else if (equal(szType, "FLASH")) blockType = BM_FLASH;
1348 else if (equal(szType, "HE")) blockType = BM_HE;
1349 else if (equal(szType, "MONEY")) blockType = BM_MONEY;
1350 else if (equal(szType, "LOWTRAMP")) blockType = BM_LOWTRAMP;
1351 else if (equal(szType, "HIGHTRAMP")) blockType = BM_HIGHTRAMP;
1352 else if (equal(szType, "USP")) blockType = BM_USP;
1353
1354 else if (equal(szType, "AK47")) blockType = BM_AK47;
1355 else if (equal(szType, "M4A1")) blockType = BM_M4A1;
1356 else if (equal(szType, "MP5")) blockType = BM_MP5;
1357 else if (equal(szType, "M3")) blockType = BM_M3;
1358 else if (equal(szType, "SCOUT")) blockType = BM_SCOUT;
1359
1360 else if (equal(szType, "BLIND")) blockType = BM_BLIND;
1361 else if (equal(szType, "XP")) blockType = BM_XP;
1362 else if (equal(szType, "PET")) blockType = BM_PET;
1363
1364 else if (equal(szType, "BLINDDAMAGE")) blockType = BM_BLINDDAMAGE;
1365 else if (equal(szType, "BHOPUNDERBLOCK")) blockType = BM_BHOPUNDERBLOCK;
1366
1367 else if (equal(szType, "SMALLMOVINGX")) blockType = BM_SMALLMOVINGX;
1368 else if (equal(szType, "MOVINGX")) blockType = BM_MOVINGX;
1369 else if (equal(szType, "LARGEMOVINGX")) blockType = BM_LARGEMOVINGX;
1370 else if (equal(szType, "SMALLMOVINGY")) blockType = BM_SMALLMOVINGY;
1371 else if (equal(szType, "MOVINGY")) blockType = BM_MOVINGY;
1372 else if (equal(szType, "LARGEMOVINGY")) blockType = BM_LARGEMOVINGY;
1373 else if (equal(szType, "SMALLMOVINGZ")) blockType = BM_SMALLMOVINGZ;
1374 else if (equal(szType, "MOVINGZ")) blockType = BM_MOVINGZ;
1375 else if (equal(szType, "LARGEMOVINGZ")) blockType = BM_LARGEMOVINGZ;
1376
1377 else if (equal(szType, "SMALLMOVINGPLATX")) blockType = BM_SMALLMOVINGPLATX;
1378 else if (equal(szType, "MOVINGPLATX")) blockType = BM_MOVINGPLATX;
1379 else if (equal(szType, "LARGEMOVINGPLATX")) blockType = BM_LARGEMOVINGPLATX;
1380 else if (equal(szType, "SMALLMOVINGPLATY")) blockType = BM_SMALLMOVINGPLATY;
1381 else if (equal(szType, "MOVINGPLATY")) blockType = BM_MOVINGPLATY;
1382 else if (equal(szType, "LARGEMOVINGPLATY")) blockType = BM_LARGEMOVINGPLATY;
1383 else if (equal(szType, "SMALLMOVINGPLATZ")) blockType = BM_SMALLMOVINGPLATZ;
1384 else if (equal(szType, "MOVINGPLATZ")) blockType = BM_MOVINGPLATZ;
1385 else if (equal(szType, "LARGEMOVINGPLATZ")) blockType = BM_LARGEMOVINGPLATZ;
1386
1387 else if (equal(szType, "SMALLMOVINGTRAMPX")) blockType = BM_SMALLMOVINGTRAMPX;
1388 else if (equal(szType, "MOVINGTRAMPX")) blockType = BM_MOVINGTRAMPX;
1389 else if (equal(szType, "LARGEMOVINGTRAMPX")) blockType = BM_LARGEMOVINGTRAMPX;
1390 else if (equal(szType, "SMALLMOVINGTRAMPY")) blockType = BM_SMALLMOVINGTRAMPY;
1391 else if (equal(szType, "MOVINGTRAMPY")) blockType = BM_MOVINGTRAMPY;
1392 else if (equal(szType, "LARGEMOVINGTRAMPY")) blockType = BM_LARGEMOVINGTRAMPY;
1393 else if (equal(szType, "SMALLMOVINGTRAMPZ")) blockType = BM_SMALLMOVINGTRAMPZ;
1394 else if (equal(szType, "MOVINGTRAMPZ")) blockType = BM_MOVINGTRAMPZ;
1395 else if (equal(szType, "LARGEMOVINGTRAMPZ")) blockType = BM_LARGEMOVINGTRAMPZ;
1396
1397 else if (equal(szType, "SHIELD")) blockType = BM_SHIELD;
1398 else if (equal(szType, "SLAPSHIELD")) blockType = BM_SLAPSHIELD;
1399
1400 else if (equal(szType, "FOLLOWBHOPXPLUS")) blockType = BM_FOLLOWBHOPXPLUS;
1401 else if (equal(szType, "FOLLOWBHOPXMINUS")) blockType = BM_FOLLOWBHOPXMINUS;
1402 else if (equal(szType, "FOLLOWBHOPYPLUS")) blockType = BM_FOLLOWBHOPYPLUS;
1403 else if (equal(szType, "FOLLOWBHOPYMINUS")) blockType = BM_FOLLOWBHOPYMINUS;
1404 else if (equal(szType, "MAGICCARPET")) blockType = BM_MAGICCARPET;
1405
1406 //if we're dealing with a valid block type
1407 if (blockType >= 0 && blockType < gBlockMax)
1408 {
1409 new bool:bDoRendering = false;
1410
1411 //if block model file exists
1412 if (file_exists(szBlockModel))
1413 {
1414 //set block models for given block type
1415 gszBlockModels[blockType] = szBlockModel;
1416
1417 //block model file does exist so process rendering values as well
1418 bDoRendering = true;
1419 }
1420 else
1421 {
1422 if (equal(szBlockModel, "DEFAULT"))
1423 {
1424 //block is set to use default so process rendering values
1425 bDoRendering = true;
1426 }
1427 }
1428
1429 //process rendering values
1430 if (bDoRendering)
1431 {
1432 render = NORMAL;
1433 red = 255;
1434 green = 255;
1435 blue = 255;
1436 alpha = 255;
1437
1438 if (equal(szRender, "GLOWSHELL")) render = GLOWSHELL;
1439 if (equal(szRender, "TRANSCOLOR")) render = TRANSCOLOR;
1440 if (equal(szRender, "TRANSALPHA")) render = TRANSALPHA;
1441 if (equal(szRender, "TRANSWHITE")) render = TRANSWHITE;
1442
1443 if (strlen(szRed) > 0) red = str_to_num(szRed);
1444 if (strlen(szGreen) > 0) green = str_to_num(szGreen);
1445 if (strlen(szBlue) > 0) blue = str_to_num(szBlue);
1446 if (strlen(szAlpha) > 0) alpha = str_to_num(szAlpha);
1447
1448 //set blocks rendering values
1449 setupBlockRendering(blockType, render, red, green, blue, alpha);
1450 }
1451 }
1452 }
1453
1454 //close file
1455 fclose(f);
1456}
1457
1458/***** FORWARDS *****/
1459public client_connect(id)
1460{
1461 //for showing fake kills
1462 target_killer[id]=0;
1463
1464 //make sure snapping is on by default
1465 gbSnapping[id] = true;
1466
1467 //players chosen snapping gap defaults to 0.0 units
1468 gfSnappingGap[id] = 0.0;
1469
1470 //make sure players can die
1471 gbNoFallDamage[id] = false;
1472
1473 //players block selection menu is on page 1
1474 gBlockMenuPage[id] = 1;
1475
1476 //player doesn't have godmode or noclip
1477 gbAdminGodmode[id] = false;
1478 gbAdminNoclip[id] = false;
1479
1480 //player doesn't have any blocks grouped
1481 gGroupCount[id] = 0;
1482
1483 //set default long jump distance and axis
1484 gLongJumpDistance[id] = 240;
1485 gLongJumpAxis[id] = X;
1486
1487 //reset players timers
1488 resetTimers(id);
1489}
1490
1491public client_disconnect(id)
1492{
1493 //clear players group
1494 groupClear(id);
1495
1496 //if player was grabbing an entity when they disconnected
1497 if (gGrabbed[id])
1498 {
1499 //if entity is valid
1500 if (is_valid_ent(gGrabbed[id]))
1501 {
1502 //set the entity to 'not being grabbed'
1503 entity_set_int(gGrabbed[id], EV_INT_iuser2, 0);
1504 }
1505
1506 gGrabbed[id] = 0;
1507 }
1508
1509 //disable measure tool and reset values
1510 gbMeasureToolEnabled[id] = false;
1511 gMeasureToolBlock1[id] = 0;
1512 gMeasureToolBlock2[id] = 0;
1513 gvMeasureToolPos1[id][0] = 0.0;
1514 gvMeasureToolPos1[id][1] = 0.0;
1515 gvMeasureToolPos1[id][2] = 0.0;
1516 gvMeasureToolPos2[id][0] = 0.0;
1517 gvMeasureToolPos2[id][1] = 0.0;
1518 gvMeasureToolPos2[id][2] = 0.0;
1519}
1520
1521public pfn_touch(ent, id)
1522{
1523
1524 //if touch event involves a player
1525 if (id > 0 && id <= 32)
1526 {
1527 //if player is alive
1528 if (is_user_alive(id))
1529 {
1530 //if entity involved is a block
1531 if (isBlock(ent))
1532 {
1533 //get the blocktype
1534 new blockType = entity_get_int(ent, EV_INT_body);
1535
1536 //if task does not already exist for bunnyhop block
1537 if (!task_exists(TASK_BHOPSOLIDNOT + ent) && !task_exists(TASK_BHOPSOLID + ent))
1538 {
1539 //get the players team
1540 new CsTeams:team = cs_get_user_team(id);
1541
1542 //if players team is different to barrier
1543 if (blockType == BM_BARRIER_CT && team == CS_TEAM_T)
1544 {
1545 //make block SOLID_NOT without any delay
1546 taskSolidNot(TASK_BHOPSOLIDNOT + ent);
1547 }
1548 else if (blockType == BM_BARRIER_T && team == CS_TEAM_CT)
1549 {
1550 //make block SOLID_NOT without any delay
1551 taskSolidNot(TASK_BHOPSOLIDNOT + ent);
1552 }
1553 else if (blockType == BM_BHOP)
1554 {
1555 //set bhop block to be SOLID_NOT after 0.1 seconds
1556 set_task(0.1, "taskSolidNot", TASK_BHOPSOLIDNOT + ent);
1557 }
1558
1559 else if (blockType == BM_BHOPUNDERBLOCK)
1560 {
1561
1562 set_task(1.0, "taskSolidNotFast", TASK_BHOPSOLIDNOT + ent);
1563 }
1564
1565
1566 else if (blockType == BM_BHOP_NOSLOW)
1567 {
1568 //set bhop block to be SOLID_NOT after 0.1 seconds
1569 set_task(2.0, "taskSolidNot", TASK_BHOPSOLIDNOT + ent);
1570 }
1571
1572 else if (blockType == BM_DAMAGEBHOP)
1573 {
1574 //set bhop block to be SOLID_NOT after 0.1 seconds
1575 set_task(1.2, "taskSolidNot", TASK_BHOPSOLIDNOT + ent);
1576 }
1577
1578 else if (blockType == BM_SMALLMOVINGX ||
1579 blockType == BM_MOVINGX ||
1580 blockType == BM_LARGEMOVINGX ||
1581 blockType == BM_SMALLMOVINGY ||
1582 blockType == BM_MOVINGY ||
1583 blockType == BM_LARGEMOVINGY ||
1584 blockType == BM_SMALLMOVINGZ ||
1585 blockType == BM_MOVINGZ ||
1586 blockType == BM_LARGEMOVINGZ)
1587 {
1588 set_task(0.1, "taskSolidNot", TASK_BHOPSOLIDNOT + ent);
1589 }
1590 else if (blockType == BM_SHIELD)
1591 {
1592 //kill ct's if shield is active
1593 if (shieldactive )
1594 if (get_user_team(id) == 2)
1595 if (!get_user_godmode(id))
1596 {
1597 //give the Hider a kill
1598 static Float:fFrags;
1599 for( new plr = 1; plr <= 32; plr++ )
1600 {
1601 if( ShieldUsed[plr] && shieldactive )
1602 {
1603 new shieldname[42];
1604 get_user_name(shieldplayer, shieldname, 32);
1605 new shieldnamedie[42];
1606 get_user_name(id, shieldnamedie, 32);
1607 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
1608 show_hudmessage(0, "%s OWNED %s WITH HIS DEATH SHIELD!!", shieldname,shieldnamedie);
1609 make_deathmsg(shieldplayer,id,0,"death");
1610 pev(plr, pev_frags, fFrags);
1611 set_pev(plr, pev_frags, fFrags + float(1));
1612
1613
1614
1615 }
1616 }
1617
1618 //kill
1619 fakedamage(id, "the block of death", 10000.0, DMG_GENERIC);
1620 //move block back to origional origion
1621 shieldactive = false;
1622 entity_set_origin(ent,shieldorigin);
1623 }
1624 }
1625 else if (blockType == BM_SLAPSHIELD)
1626 {
1627 //Slap user
1628 if (slapshieldactive == true)
1629 {
1630 if (get_user_team(id) == 2)
1631 {
1632 if (!get_user_godmode(id))
1633 {
1634 for( new plr = 1; plr <= 32; plr++ )
1635 {
1636 if( SlapShieldUsed[plr] == true && slapshieldactive == true)
1637 {
1638 //Move user up to unstuck them
1639 new origin[3];
1640 get_user_origin(id,origin,0);
1641 origin[2] = origin[2] +15;
1642 set_user_origin(id,origin) ;
1643 user_slap(id,1,1);
1644 }
1645 }
1646 }
1647 }
1648 }
1649 }
1650 else if (blockType == BM_MAGICCARPET)
1651 {
1652 TouchingMagicCarpet[id] = true;
1653 } else {
1654 TouchingMagicCarpet[id] = false;
1655 }
1656 }
1657 }
1658 }
1659 }
1660
1661 return PLUGIN_CONTINUE;
1662}
1663public server_frame()
1664{
1665 new ent;
1666 new Float:vOrigin[3];
1667 new bool:entNear = false;
1668 new tele;
1669 new entinsphere;
1670
1671 //Get game time for even block movements.
1672 //new Float:Timer = halflife_time();
1673
1674 //Display any tracers
1675 //set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
1676 //show_hudmessage(0, "small %d normal %d large %d flipside %d Timer %f",movingspotsmall,movingspot,movingspotlarge,flipside,Timer);
1677
1678 //***Code for orbit block
1679 //get move direction of block
1680 //moving right
1681 if (movingspotx > -150 && movingspotx < 150 && movingspoty == 150)
1682 {
1683 if (movingspotx < 150)
1684 movingspotx+=3;
1685 movingright = true;
1686 }else{
1687 movingright = false;
1688 if (movingspotx == -150 && movingspoty == 150)
1689 movingspotx+=3;
1690 }
1691 //moving down
1692 if (movingspoty > -150 && movingspoty < 150 && movingspotx == 150)
1693 {
1694 if (movingspoty > -150)
1695 movingspoty-=3;
1696 movingdown = true;
1697 } else{
1698 if (movingspotx == 150 && movingspoty == 150)
1699 movingspoty-=3;
1700 movingdown = false;
1701 }
1702 //moving left
1703 if (movingspotx > -150 && movingspotx < 150 && movingspoty == -150)
1704 {
1705 if (movingspotx > -150)
1706 movingspotx-=3;
1707 movingleft = true;
1708 }else{
1709 if (movingspotx == 150 && movingspoty == -150)
1710 movingspotx-=3;
1711 movingleft = false;
1712 }
1713 //moving up
1714 if (movingspoty > -150 && movingspoty < 150 && movingspotx == -150)
1715 {
1716 if (movingspoty < 150)
1717 movingspoty+=3;
1718 movingup = true;
1719 } else{
1720 if (movingspotx == -150 && movingspoty == -150)
1721 movingspoty+=3;
1722 movingup = false;
1723 }
1724
1725
1726
1727
1728
1729 //***Code for moving blocks
1730 if (movingspotsmall != 0 || movingspot != 0 || movingspotlarge != 0)
1731 usedzero = false;
1732
1733 if (movingspotsmall == 0 && movingspot == 0 && movingspotlarge == 0 && usedzero == false)
1734 {
1735 if (flipside < 4)
1736 {
1737 flipside++;
1738 usedzero = true;
1739 }else{
1740 flipside=0;
1741 }
1742 }
1743
1744
1745 //Set path for moving blocks if one or more origions isn't 0 the blocks will move
1746 if (movingblocks || movingspotsmall != 0 || movingspot != 0 || movingspotlarge != 0 || flipside != 3)
1747 {
1748
1749 //small
1750 if (!stoppedsmall)
1751 {
1752 if (movingspotsmall >= 0)
1753 {
1754 if (!inversesmall )
1755 movingspotsmall++;
1756 else
1757 movingspotsmall--;
1758 }
1759 else if (movingspotsmall < 0)
1760 {
1761 inversesmall = false;
1762 if (!inversetwosmall )
1763 movingspotsmall--;
1764 else
1765 movingspotsmall++;
1766 }
1767
1768 if (movingspotsmall <= -300)
1769 {
1770 inversetwosmall = true;
1771 }
1772 if (movingspotsmall >= 300)
1773 {
1774 inversetwosmall = false;
1775 if (!inversesmall )
1776 inversesmall = true;
1777 else
1778 inversesmall = false;
1779 }
1780 } else {
1781 if (movingspotsmall == 0)
1782 {
1783 stopcountsmall++;
1784 }
1785 }
1786
1787 if (movingspotsmall == 0)
1788 {
1789 stoppedsmall = true;
1790 storespotsmall = movingspotsmall;
1791 movingspotsmall = 0;
1792 }
1793 if (stopcountsmall >= 150)
1794 {
1795 stoppedsmall = false;
1796 movingspotsmall = storespotsmall;
1797 stopcountsmall = 0;
1798 }
1799
1800
1801 //medium
1802 if (!stopped )
1803 {
1804 if (movingspot >= 0)
1805 {
1806 if (inverse == false)
1807 movingspot++;
1808 else
1809 movingspot--;
1810 }
1811 else if (movingspot < 0)
1812 {
1813 inverse = false;
1814 if (!inversetwo)
1815 movingspot--;
1816 else
1817 movingspot++;
1818 }
1819
1820 if (movingspot <= -600)
1821 {
1822 inversetwo = true;
1823 }
1824 if (movingspot >= 600)
1825 {
1826 inversetwo = false;
1827 if (!inverse )
1828 inverse = true;
1829 else
1830 inverse = false;
1831 }
1832 } else {
1833 if (movingspot == 0)
1834 {
1835 stopcount++;
1836 }
1837 }
1838
1839 if (movingspot == 0)
1840 {
1841 stopped = true;
1842 storespot = movingspot;
1843 movingspot = 0;
1844 }
1845 if (stopcount >= 300)
1846 {
1847 stopped = false;
1848 movingspot = storespot;
1849 stopcount = 0;
1850 }
1851
1852
1853
1854 //large
1855 if (!stoppedlarge )
1856 {
1857 if (movingspotlarge >= 0)
1858 {
1859 if (!inverselarge )
1860 movingspotlarge++;
1861 else
1862 movingspotlarge--;
1863 }
1864 else if (movingspotlarge < 0)
1865 {
1866 inverselarge = false;
1867 if (!inversetwolarge )
1868 movingspotlarge--;
1869 else
1870 movingspotlarge++;
1871 }
1872
1873 if (movingspotlarge <= -900)
1874 {
1875 inversetwolarge = true;
1876 }
1877 if (movingspotlarge >= 900)
1878 {
1879 inversetwolarge = false;
1880 if (!inverselarge )
1881 inverselarge = true;
1882 else
1883 inverselarge = false;
1884 }
1885 } else {
1886 if (movingspotlarge == 0)
1887 {
1888 stopcountlarge++;
1889 }
1890 }
1891
1892 if (movingspotlarge == 0)
1893 {
1894 stoppedlarge = true;
1895 storespotlarge = movingspotlarge;
1896 movingspotlarge = 0;
1897 }
1898 if (stopcountlarge >= 300)
1899 {
1900 stoppedlarge = false;
1901 movingspotlarge = storespotlarge;
1902 stopcountlarge = 0;
1903 }
1904
1905 }
1906
1907
1908
1909
1910 //iterate through all players and remove slow down after jumping
1911 for (new i = 1; i <= 32; ++i)
1912 {
1913 if (is_user_alive(i))
1914 {
1915 if (gbOnIce[i] || gbNoSlowDown[i])
1916 {
1917 entity_set_float(i, EV_FL_fuser2, 0.0);
1918 }
1919 }
1920 }
1921
1922 //find all teleport start entities in map and if a player is close to one, teleport the player
1923 while ((ent = find_ent_by_class(ent, gszTeleportStartClassname)))
1924 {
1925 new Float:vOrigin[3];
1926 entity_get_vector(ent, EV_VEC_origin, vOrigin);
1927
1928 //teleport players and grenades within a sphere around the teleport start entity
1929 entinsphere = -1;
1930 while ((entinsphere = find_ent_in_sphere(entinsphere, vOrigin, 32.0)))
1931 {
1932 //get classname of entity
1933 new szClassname[32];
1934 entity_get_string(entinsphere, EV_SZ_classname, szClassname, 32);
1935
1936 //if entity is a player
1937 if (entinsphere > 0 && entinsphere <= 32)
1938 {
1939 //only teleport player if they're alive
1940 if (is_user_alive(entinsphere))
1941 {
1942 //teleport the player
1943 actionTeleport(entinsphere, ent);
1944 }
1945 }
1946 //or if entity is a grenade
1947 else if (equal(szClassname, "grenade"))
1948 {
1949 //get the end of the teleport
1950 tele = entity_get_int(ent, EV_INT_iuser1);
1951
1952 //if the end of the teleport exists
1953 if (tele)
1954 {
1955 //set the end of the teleport to be not solid
1956 entity_set_int(tele, EV_INT_solid, SOLID_NOT); //can't be grabbed or deleted
1957
1958 //teleport the grenade
1959 actionTeleport(entinsphere, ent);
1960
1961 //set a time in the teleport it will become solid after 2 seconds
1962 entity_set_float(tele, EV_FL_ltime, halflife_time() + 2.0);
1963 }
1964 }
1965 }
1966 }
1967
1968 //make teleporters SOLID_NOT when players are near them
1969 while ((ent = find_ent_by_class(ent, gszTeleportEndClassname)))
1970 {
1971 //get the origin of the teleport end entity
1972 entity_get_vector(ent, EV_VEC_origin, vOrigin);
1973
1974 //compare this origin with all player and grenade origins
1975 entinsphere = -1;
1976 while ((entinsphere = find_ent_in_sphere(entinsphere, vOrigin, 64.0)))
1977 {
1978 //get classname of entity
1979 new szClassname[32];
1980 entity_get_string(entinsphere, EV_SZ_classname, szClassname, 32);
1981
1982 //if entity is a player
1983 if (entinsphere > 0 && entinsphere <= 32)
1984 {
1985 //make sure player is alive
1986 if (is_user_alive(entinsphere))
1987 {
1988 entNear = true;
1989
1990 break;
1991 }
1992 }
1993 //or if entity is a grenade
1994 else if (equal(szClassname, "grenade"))
1995 {
1996 entNear = true;
1997
1998 break;
1999 }
2000 }
2001
2002 //set the solid type of the teleport end entity depending on whether or not a player is near
2003 if (entNear)
2004 {
2005 //only do this if it is not being grabbed
2006 if (entity_get_int(ent, EV_INT_iuser2) == 0)
2007 {
2008 entity_set_int(ent, EV_INT_solid, SOLID_NOT); //can't be grabbed or deleted
2009 }
2010 }
2011 else
2012 {
2013 //get time from teleport end entity to check if it can go solid
2014 new Float:fTime = entity_get_float(ent, EV_FL_ltime);
2015
2016 //only set teleport end entity to solid if its 'solid not' time has elapsed
2017 if (halflife_time() >= fTime)
2018 {
2019 entity_set_int(ent, EV_INT_solid, SOLID_BBOX); //CAN be grabbed and deleted
2020 }
2021 }
2022 }
2023
2024
2025
2026 //find all block entities
2027 while ((ent = find_ent_by_class(ent, gszBlockClassname)))
2028 {
2029 //get block type
2030 new blockType = entity_get_int(ent, EV_INT_body);
2031
2032
2033 //if block is a speed boost
2034 /*
2035 if (blockType == BM_SPEEDBOOST)
2036 {
2037 new Float:vOrigin[3];
2038 new Float:pOrigin[3];
2039 new Float:dist = 9999.9;
2040 new Float:playerDist = 9999.9;
2041 new nearestPlayer = 0;
2042
2043 //get the origin of the speed boost block
2044 entity_get_vector(ent, EV_VEC_origin, vOrigin);
2045
2046 //compare this origin with all players origins to find the nearest player to the block
2047 for (new id = 1; id <= 32; ++id)
2048 {
2049 //if player is alive
2050 if (is_user_alive(id))
2051 {
2052 //get player origin
2053 entity_get_vector(id, EV_VEC_origin, pOrigin);
2054
2055 //get the distance from the block to the player
2056 dist = get_distance_f(vOrigin, pOrigin);
2057
2058 if (dist < playerDist)
2059 {
2060 nearestPlayer = id;
2061 playerDist = dist;
2062 }
2063 }
2064 }
2065
2066 //if we found a player within 100 units of the speed boost block
2067 if (nearestPlayer > 0 && playerDist < 200.0)
2068 {
2069 //get the sprite on top of the speed boost block
2070 new sprite = entity_get_int(ent, EV_INT_iuser3);
2071
2072 //make sure sprite entity is valid
2073 if (sprite)
2074 {
2075 new Float:vAngles[3];
2076
2077 //get the direction the player is looking
2078 entity_get_vector(nearestPlayer, EV_VEC_angles, vAngles);
2079
2080 //set the angles of the sprite to be the same as the player
2081 vAngles[0] = 90.0; //always make sure sprite is flat to the block
2082 vAngles[1] += 90.0; //rotate the sprite by 90 because it doesnt point up (PAT!)
2083 entity_set_vector(sprite, EV_VEC_angles, vAngles);
2084 }
2085 }
2086 }
2087 */
2088 //Death Shield
2089 if (blockType == BM_SHIELD)
2090 {
2091 if (shieldactive)
2092 {
2093 //Set block at user if shield is active
2094 get_user_origin(shieldplayer,userorigin,0);
2095
2096 userorigin[0] += movingspotx;
2097 userorigin[1] += movingspoty;
2098 new float:test[3];
2099 for (new i=0;i<3;i++)
2100 test[i] = float(userorigin[i]);
2101 entity_set_origin(ent,test);
2102 if (!is_user_alive(shieldplayer))
2103 {
2104 entity_set_origin(ent,shieldorigin);
2105 shieldactive = false;
2106 }
2107
2108
2109 }
2110 }
2111 //Slap Shield
2112 if (blockType == BM_SLAPSHIELD)
2113 {
2114 if (slapshieldactive )
2115 {
2116 //Set block at user if shield is active
2117 //multiply x and y of the slap block by -1 to prevent death and slap shield from overlapping
2118 get_user_origin(slapshieldplayer,userorigin,0);
2119
2120 userorigin[0] += (movingspotx*-1);
2121 userorigin[1] += (movingspoty*-1);
2122 new float:test[3];
2123 for (new i=0;i<3;i++)
2124 test[i] = float(userorigin[i]);
2125 entity_set_origin(ent,test);
2126 if (!is_user_alive(slapshieldplayer))
2127 {
2128 entity_set_origin(ent,slapshieldorigin);
2129 slapshieldactive = false;
2130 }
2131
2132
2133 }
2134 }
2135 //X's
2136 if (blockType == BM_SMALLMOVINGX || blockType == BM_SMALLMOVINGPLATX || blockType == BM_SMALLMOVINGTRAMPX )
2137 {
2138 new Float:OriginOld[3];
2139 new Float:OriginNew[3];
2140
2141 if (movingspotsmall > 0)
2142 {
2143 //Move block
2144
2145 get_brush_entity_origin (ent, OriginOld);
2146 OriginNew = OriginOld;
2147 OriginNew[0] += 0.25;
2148
2149 entity_set_origin(ent,OriginNew);
2150
2151
2152 }
2153 if (movingspotsmall< 0)
2154 {
2155 //Move block
2156
2157 get_brush_entity_origin (ent, OriginOld);
2158 OriginNew = OriginOld;
2159 OriginNew[0] -= 0.25;
2160
2161 entity_set_origin(ent,OriginNew);
2162
2163
2164 }
2165 }
2166 if (blockType == BM_MOVINGX || blockType == BM_MOVINGPLATX || blockType == BM_MOVINGTRAMPX )
2167 {
2168 new Float:OriginOld[3];
2169 new Float:OriginNew[3];
2170
2171 if (movingspot > 0)
2172 {
2173 //Move block
2174
2175 get_brush_entity_origin (ent, OriginOld);
2176 OriginNew = OriginOld;
2177 OriginNew[0] +=0.25;
2178
2179 entity_set_origin(ent,OriginNew);
2180
2181
2182 }
2183 if (movingspot < 0)
2184 {
2185 //Move block
2186
2187 get_brush_entity_origin (ent, OriginOld);
2188 OriginNew = OriginOld;
2189 OriginNew[0] -= 0.25;
2190
2191 entity_set_origin(ent,OriginNew);
2192
2193
2194 }
2195 }
2196 if (blockType == BM_LARGEMOVINGX || blockType == BM_LARGEMOVINGPLATX || blockType == BM_LARGEMOVINGTRAMPX )
2197 {
2198 new Float:OriginOld[3];
2199 new Float:OriginNew[3];
2200
2201 if (movingspotlarge > 0)
2202 {
2203 //Move block
2204
2205 get_brush_entity_origin (ent, OriginOld);
2206 OriginNew = OriginOld;
2207 OriginNew[0] +=0.25;
2208
2209 entity_set_origin(ent,OriginNew);
2210
2211
2212 }
2213 if (movingspotlarge< 0)
2214 {
2215 //Move block
2216
2217 get_brush_entity_origin (ent, OriginOld);
2218 OriginNew = OriginOld;
2219 OriginNew[0] -= 0.25;
2220
2221 entity_set_origin(ent,OriginNew);
2222
2223
2224 }
2225 }
2226 //Y's
2227 if (blockType == BM_SMALLMOVINGY || blockType == BM_SMALLMOVINGPLATY || blockType == BM_SMALLMOVINGTRAMPY )
2228 {
2229 new Float:OriginOld[3];
2230 new Float:OriginNew[3];
2231
2232 if (movingspotsmall > 0)
2233 {
2234 //Move block
2235
2236 get_brush_entity_origin (ent, OriginOld);
2237 OriginNew = OriginOld;
2238 OriginNew[1] +=0.25;
2239
2240 entity_set_origin(ent,OriginNew);
2241
2242
2243 }
2244 if (movingspotsmall< 0)
2245 {
2246 //Move block
2247
2248 get_brush_entity_origin (ent, OriginOld);
2249 OriginNew = OriginOld;
2250 OriginNew[1] -= 0.25;
2251
2252 entity_set_origin(ent,OriginNew);
2253
2254
2255 }
2256 }
2257 if (blockType == BM_MOVINGY || blockType == BM_MOVINGPLATY || blockType == BM_MOVINGTRAMPY )
2258 {
2259 new Float:OriginOld[3];
2260 new Float:OriginNew[3];
2261
2262 if (movingspot > 0)
2263 {
2264 //Move block
2265
2266 get_brush_entity_origin (ent, OriginOld);
2267 OriginNew = OriginOld;
2268 OriginNew[1] +=0.25;
2269
2270 entity_set_origin(ent,OriginNew);
2271
2272
2273 }
2274 if (movingspot < 0)
2275 {
2276 //Move block
2277
2278 get_brush_entity_origin (ent, OriginOld);
2279 OriginNew = OriginOld;
2280 OriginNew[1] -= 0.25;
2281
2282 entity_set_origin(ent,OriginNew);
2283
2284
2285 }
2286 }
2287 if (blockType == BM_LARGEMOVINGY || blockType == BM_LARGEMOVINGPLATY || blockType == BM_LARGEMOVINGTRAMPY )
2288 {
2289 new Float:OriginOld[3];
2290 new Float:OriginNew[3];
2291
2292 if (movingspotlarge > 0)
2293 {
2294 //Move block
2295
2296 get_brush_entity_origin (ent, OriginOld);
2297 OriginNew = OriginOld;
2298 OriginNew[1] +=0.25;
2299
2300 entity_set_origin(ent,OriginNew);
2301
2302
2303 }
2304 if (movingspotlarge< 0)
2305 {
2306 //Move block
2307
2308 get_brush_entity_origin (ent, OriginOld);
2309 OriginNew = OriginOld;
2310 OriginNew[1] -= 0.25;
2311
2312 entity_set_origin(ent,OriginNew);
2313
2314
2315 }
2316 }
2317 //Z's
2318 if (blockType == BM_SMALLMOVINGZ || blockType == BM_SMALLMOVINGPLATZ || blockType == BM_SMALLMOVINGTRAMPZ )
2319 {
2320 new Float:OriginOld[3];
2321 new Float:OriginNew[3];
2322
2323 if (movingspotsmall > 0)
2324 {
2325 //Move block
2326
2327 get_brush_entity_origin (ent, OriginOld);
2328 OriginNew = OriginOld;
2329 OriginNew[2] +=0.1;
2330
2331 entity_set_origin(ent,OriginNew);
2332
2333
2334 }
2335 if (movingspotsmall< 0)
2336 {
2337 //Move block
2338
2339 get_brush_entity_origin (ent, OriginOld);
2340 OriginNew = OriginOld;
2341 OriginNew[2] -= 0.1;
2342
2343 entity_set_origin(ent,OriginNew);
2344
2345
2346 }
2347 }
2348 if (blockType == BM_MOVINGZ || blockType == BM_MOVINGPLATZ || blockType == BM_MOVINGTRAMPZ )
2349 {
2350 new Float:OriginOld[3];
2351 new Float:OriginNew[3];
2352
2353 if (movingspot > 0)
2354 {
2355 //Move block
2356
2357 get_brush_entity_origin (ent, OriginOld);
2358 OriginNew = OriginOld;
2359 OriginNew[2] +=0.1;
2360
2361 entity_set_origin(ent,OriginNew);
2362
2363
2364 }
2365 if (movingspot < 0)
2366 {
2367 //Move block
2368
2369 get_brush_entity_origin (ent, OriginOld);
2370 OriginNew = OriginOld;
2371 OriginNew[2] -= 0.1;
2372
2373 entity_set_origin(ent,OriginNew);
2374
2375
2376 }
2377 }
2378 if (blockType == BM_LARGEMOVINGZ || blockType == BM_LARGEMOVINGPLATZ || blockType == BM_LARGEMOVINGTRAMPZ )
2379 {
2380 new Float:OriginOld[3];
2381 new Float:OriginNew[3];
2382
2383 if (movingspotlarge > 0)
2384 {
2385 //Move block
2386
2387 get_brush_entity_origin (ent, OriginOld);
2388 OriginNew = OriginOld;
2389 OriginNew[2] +=0.1;
2390
2391 entity_set_origin(ent,OriginNew);
2392
2393
2394 }
2395 if (movingspotlarge< 0)
2396 {
2397 //Move block
2398
2399 get_brush_entity_origin (ent, OriginOld);
2400 OriginNew = OriginOld;
2401 OriginNew[2] -= 0.1;
2402
2403 entity_set_origin(ent,OriginNew);
2404
2405
2406 }
2407 }
2408 }
2409
2410 }
2411
2412
2413public client_PreThink(id)
2414{
2415 //make sure player is connected
2416 if (is_user_connected(id))
2417 {
2418 //display type of block that player is aiming at
2419 new ent, body;
2420 get_user_aiming(id, ent, body, 320);
2421
2422 if (isBlock(ent))
2423 {
2424 new blockType = entity_get_int(ent, EV_INT_body);
2425 new Creator[32];
2426
2427 pev(ent, pev_targetname, Creator, 31);
2428 replace_all(Creator, 31, "_", " ");
2429
2430 set_hudmessage(gHudRed, gHudGreen, gHudBlue, gfTextX, gfTextY, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
2431 show_hudmessage(id, "Block Type: %s^nCreator: %s", gszBlockNames[blockType], Creator);
2432 }
2433
2434 //if player has the measure tool enabled
2435 if (gbMeasureToolEnabled[id])
2436 {
2437 new Float:vOrigin1[3];
2438 new Float:vOrigin2[3];
2439 new Float:vSizeMax1[3];
2440 new Float:vSizeMax2[3];
2441 new Float:fDist = 0.0;
2442 new Float:fX = 0.0;
2443 new Float:fY = 0.0;
2444 new Float:fZ = 0.0;
2445
2446 if (is_valid_ent(gMeasureToolBlock1[id]))
2447 {
2448 if (is_valid_ent(gMeasureToolBlock2[id]))
2449 {
2450 //get position and size information from the blocks
2451 entity_get_vector(gMeasureToolBlock1[id], EV_VEC_origin, vOrigin1);
2452 entity_get_vector(gMeasureToolBlock2[id], EV_VEC_origin, vOrigin2);
2453 entity_get_vector(gMeasureToolBlock1[id], EV_VEC_maxs, vSizeMax1);
2454 entity_get_vector(gMeasureToolBlock2[id], EV_VEC_maxs, vSizeMax2);
2455
2456 //calculate differences on X, Y and Z
2457 fX = floatabs(vOrigin2[0] - vOrigin1[0]) - vSizeMax1[0] - vSizeMax2[0];
2458 fY = floatabs(vOrigin2[1] - vOrigin1[1]) - vSizeMax1[1] - vSizeMax2[1];
2459 fZ = (vOrigin2[2] + vSizeMax2[2]) - (vOrigin1[2] + vSizeMax1[2]);
2460
2461 //make sure X and Y are never below 0.0
2462 if (fX < 0.0) fX = 0.0;
2463 if (fY < 0.0) fY = 0.0;
2464 }
2465 else
2466 {
2467 gMeasureToolBlock2[id] = 0;
2468 }
2469 }
2470 else
2471 {
2472 gMeasureToolBlock1[id] = 0;
2473 }
2474
2475 //calculate the sums of the 2 positions
2476 new Float:pos1sum = gvMeasureToolPos1[id][0] + gvMeasureToolPos1[id][1] + gvMeasureToolPos1[id][2];
2477 new Float:pos2sum = gvMeasureToolPos2[id][0] + gvMeasureToolPos2[id][1] + gvMeasureToolPos2[id][2];
2478
2479 //calculate distance between measure tool positions 1 and 2
2480 if (pos1sum != 0.0 && pos2sum != 0.0)
2481 {
2482 fDist = get_distance_f(gvMeasureToolPos1[id], gvMeasureToolPos2[id]);
2483 }
2484
2485 //show the values to the player
2486 set_hudmessage(gHudRed, gHudGreen, gHudBlue, 0.02, 0.22, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
2487 show_hudmessage(id, "X: %.2f^nY: %.2f^nZ: %.2f^nDistance: %.2f", fX, fY, fZ, fDist);
2488 }
2489
2490 //make sure player is alive
2491 if (is_user_alive(id))
2492 {
2493 //if player has low gravity
2494 if (gbLowGravity[id])
2495 {
2496 //get players flags
2497 new flags = entity_get_int(id, EV_INT_flags);
2498
2499 //if player has feet on the ground, set gravity to normal
2500 if (flags & FL_ONGROUND)
2501 {
2502 set_user_gravity(id);
2503
2504 gbLowGravity[id] = false;
2505 }
2506 }
2507
2508 //if player has auto bhop
2509 if (gbAutoBhop[id])
2510 {
2511 //get players old buttons
2512 new oldbuttons = get_user_oldbutton(id);
2513
2514 //remove jump flag from old buttons
2515 oldbuttons &= ~IN_JUMP;
2516 entity_set_int(id, EV_INT_oldbuttons, oldbuttons);
2517 }
2518
2519 //trace directly down to see if there is a block beneath player
2520 new Float:pOrigin[3];
2521 new Float:pSize[3];
2522 new Float:pMaxs[3];
2523 new Float:vTrace[3];
2524 new Float:vReturn[3];
2525 entity_get_vector(id, EV_VEC_origin, pOrigin);
2526 entity_get_vector(id, EV_VEC_size, pSize);
2527 entity_get_vector(id, EV_VEC_maxs, pMaxs);
2528
2529 //calculate position of players feet
2530 pOrigin[2] = pOrigin[2] - ((pSize[2] - 36.0) - (pMaxs[2] - 36.0));
2531
2532 //make the trace small for some blocks
2533 vTrace[2] = pOrigin[2] - 1.0;
2534
2535 //do 4 traces for each corner of the player
2536 for (new i = 0; i < 4; ++i)
2537 {
2538 switch (i)
2539 {
2540 case 0: { vTrace[0] = pOrigin[0] - 16; vTrace[1] = pOrigin[1] + 16; }
2541 case 1: { vTrace[0] = pOrigin[0] + 16; vTrace[1] = pOrigin[1] + 16; }
2542 case 2: { vTrace[0] = pOrigin[0] + 16; vTrace[1] = pOrigin[1] - 16; }
2543 case 3: { vTrace[0] = pOrigin[0] - 16; vTrace[1] = pOrigin[1] - 16; }
2544 }
2545
2546 ent = trace_line(id, pOrigin, vTrace, vReturn);
2547
2548 //if entity found is a block
2549 if (isBlock(ent))
2550 {
2551 new blockType = entity_get_int(ent, EV_INT_body);
2552
2553 switch (blockType)
2554 {
2555 case BM_HEALER: actionHeal(id);
2556 case BM_DAMAGE: actionDamage(id);
2557 case BM_INVINCIBILITY: actionInvincible(id, false);
2558 case BM_STEALTH: actionStealth(id, false);
2559 case BM_TRAMPOLINE: actionTrampoline(id);
2560 case BM_SPEEDBOOST: actionSpeedBoost(id);
2561 case BM_DEATH: actionDeath(id);
2562 case BM_NUKE: actionNuke(id, false);
2563 case BM_LOWGRAVITY: actionLowGravity(id);
2564 case BM_CAMOUFLAGE: actionCamouflage(id, false);
2565 case BM_FIRE: actionFire(id, ent);
2566 case BM_SLAP: actionSlap(id);
2567 case BM_RANDOM: actionRandom(id, ent);
2568 case BM_HONEY: actionHoney(id);
2569 case BM_BOOTSOFSPEED: actionBootsOfSpeed(id, false);
2570 case BM_AUTO_BHOP: actionAutoBhop(id, false);
2571 case BM_DEAGLE: actionDeagle(id);
2572 case BM_AWP: actionAwp(id);
2573 case BM_FROST: actionFrost(id,false);
2574 case BM_FLASH: actionFlash(id,false);
2575 case BM_HE: actionHe(id,false);
2576 case BM_MONEY: actionMoney(id,false);
2577 case BM_LOWTRAMP: actionLowTramp(id);
2578 case BM_HIGHTRAMP: actionHighTramp(id);
2579 case BM_USP: actionUsp(id);
2580
2581 case BM_AK47: actionAk47(id);
2582 case BM_M4A1: actionM4a1(id);
2583 case BM_MP5: actionMp5(id);
2584 case BM_M3: actionM3(id);
2585 case BM_SCOUT: actionScout(id);
2586
2587 case BM_BLIND: actionBlind(id,true);
2588 case BM_XP: actionXP(id,false);
2589
2590 case BM_BLINDDAMAGE: actionBlindDamage(id, true);
2591 case BM_BHOPUNDERBLOCK: actionBhopUnderblock(id,ent);
2592
2593 case BM_SMALLMOVINGPLATX: actionMovingBlockXSmall(id, ent);
2594 case BM_MOVINGPLATX: actionMovingBlockX(id, ent);
2595 case BM_LARGEMOVINGPLATX: actionMovingBlockXLarge(id, ent);
2596 case BM_SMALLMOVINGPLATY: actionMovingBlockYSmall(id, ent);
2597 case BM_MOVINGPLATY: actionMovingBlockY(id, ent);
2598 case BM_LARGEMOVINGPLATY: actionMovingBlockYLarge(id, ent);
2599 case BM_SMALLMOVINGPLATZ: actionMovingBlockZSmall(id, ent);
2600 case BM_MOVINGPLATZ: actionMovingBlockZ(id, ent);
2601 case BM_LARGEMOVINGPLATZ: actionMovingBlockZLarge(id, ent);
2602
2603 case BM_SMALLMOVINGTRAMPX: actionTrampoline(id);
2604 case BM_MOVINGTRAMPX: actionTrampoline(id);
2605 case BM_LARGEMOVINGTRAMPX: actionTrampoline(id);
2606 case BM_SMALLMOVINGTRAMPY: actionTrampoline(id);
2607 case BM_MOVINGTRAMPY: actionTrampoline(id);
2608 case BM_LARGEMOVINGTRAMPY: actionTrampoline(id);
2609 case BM_SMALLMOVINGTRAMPZ: actionTrampoline(id);
2610 case BM_MOVINGTRAMPZ: actionTrampoline(id);
2611 case BM_LARGEMOVINGTRAMPZ: actionTrampoline(id);
2612
2613 case BM_SHIELD: actionShield(id, ent);
2614 case BM_SLAPSHIELD: actionSlapShield(id, ent);
2615
2616 case BM_FOLLOWBHOPXPLUS: actionFollowBhopXPlus(id, ent);
2617 case BM_FOLLOWBHOPXMINUS: actionFollowBhopXMinus(id, ent);
2618 case BM_FOLLOWBHOPYPLUS: actionFollowBhopYPlus(id, ent);
2619 case BM_FOLLOWBHOPYMINUS: actionFollowBhopYMinus(id, ent);
2620 case BM_MAGICCARPET: actionMagicCarpet(id, ent);
2621 }
2622 }
2623 }
2624
2625 //make the trace longer for other blocks
2626 vTrace[2] = pOrigin[2] - 20.0;
2627
2628 //do 4 traces for each corner of the player
2629 for (new i = 0; i < 4; ++i)
2630 {
2631 switch (i)
2632 {
2633 case 0: { vTrace[0] = pOrigin[0] - 16; vTrace[1] = pOrigin[1] + 16; }
2634 case 1: { vTrace[0] = pOrigin[0] + 16; vTrace[1] = pOrigin[1] + 16; }
2635 case 2: { vTrace[0] = pOrigin[0] + 16; vTrace[1] = pOrigin[1] - 16; }
2636 case 3: { vTrace[0] = pOrigin[0] - 16; vTrace[1] = pOrigin[1] - 16; }
2637 }
2638
2639 ent = trace_line(id, pOrigin, vTrace, vReturn);
2640
2641 //if entity found is a block
2642 if (isBlock(ent))
2643 {
2644 new blockType = entity_get_int(ent, EV_INT_body);
2645
2646 switch (blockType)
2647 {
2648 case BM_TRAMPOLINE: actionTrampoline(id);
2649 case BM_HIGHTRAMP: actionHighTramp(id);
2650 case BM_LOWTRAMP: actionLowTramp(id);
2651 case BM_NOFALLDAMAGE: actionNoFallDamage(id);
2652 case BM_ICE: actionOnIce(id);
2653 }
2654 }
2655 }
2656
2657 //display amount of invincibility/stealth/camouflage/boots of speed timeleft
2658 new Float:fTime = halflife_time();
2659 new Float:fTimeleftInvincible = gfInvincibleTimeOut[id] - fTime;
2660 new Float:fTimeleftStealth = gfStealthTimeOut[id] - fTime;
2661 new Float:fTimeleftCamouflage = gfCamouflageTimeOut[id] - fTime;
2662 new Float:fTimeleftBootsOfSpeed = gfBootsOfSpeedTimeOut[id] - fTime;
2663 new Float:fTimeleftAutoBhop = gfAutoBhopTimeOut[id] - fTime;
2664 new szTextToShow[256] = "";
2665 new szText[48];
2666 new bool:bShowText = false;
2667
2668 if (fTimeleftInvincible >= 0.0)
2669 {
2670 format(szText, sizeof(szText), "Invincible: %.1f^n", fTimeleftInvincible);
2671 add(szTextToShow, sizeof(szTextToShow), szText);
2672 bShowText = true;
2673 }
2674
2675 if (fTimeleftStealth >= 0.0)
2676 {
2677 format(szText, sizeof(szText), "Stealth: %.1f^n", fTimeleftStealth);
2678 add(szTextToShow, sizeof(szTextToShow), szText);
2679 bShowText = true;
2680 }
2681
2682 if (fTimeleftCamouflage >= 0.0)
2683 {
2684 //if player is a CT
2685 if (get_user_team(id) == 1)
2686 {
2687 format(szText, sizeof(szText), "You look like a Counter-Terrorist: %.1f^n", fTimeleftCamouflage);
2688 }
2689 else
2690 {
2691 format(szText, sizeof(szText), "You look like a Terrorist: %.1f^n", fTimeleftCamouflage);
2692 }
2693
2694 add(szTextToShow, sizeof(szTextToShow), szText);
2695 bShowText = true;
2696 }
2697
2698 if (fTimeleftBootsOfSpeed >= 0.0)
2699 {
2700 format(szText, sizeof(szText), "Boots of speed: %.1f^n", fTimeleftBootsOfSpeed);
2701 add(szTextToShow, sizeof(szTextToShow), szText);
2702 bShowText = true;
2703 }
2704
2705 if (fTimeleftAutoBhop >= 0.0)
2706 {
2707 format(szText, sizeof(szText), "Auto bunnyhop: %.1f^n", fTimeleftAutoBhop);
2708 add(szTextToShow, sizeof(szTextToShow), szText);
2709 bShowText = true;
2710 }
2711
2712 //if there is some text to show then show it
2713 if (bShowText)
2714 {
2715 set_hudmessage(gHudRed, gHudGreen, gHudBlue, gfTextX, gfTextY, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
2716 show_hudmessage(id, szTextToShow);
2717 }
2718 }
2719
2720 //get players buttons
2721 new buttons = get_user_button(id);
2722 new oldbuttons = get_user_oldbutton(id);
2723
2724 //if player has grabbed an entity
2725 if (gGrabbed[id] > 0)
2726 {
2727 //check for a single press on the following buttons
2728 if (buttons & IN_JUMP && !(oldbuttons & IN_JUMP)) cmdJump(id);
2729 if (buttons & IN_DUCK && !(oldbuttons & IN_DUCK)) cmdDuck(id);
2730 if (buttons & IN_ATTACK && !(oldbuttons & IN_ATTACK)) cmdAttack(id);
2731 if (buttons & IN_ATTACK2 && !(oldbuttons & IN_ATTACK2)) cmdAttack2(id);
2732
2733 //prevent player from using attack
2734 buttons &= ~IN_ATTACK;
2735 entity_set_int(id, EV_INT_button, buttons);
2736
2737 //if player has grabbed a valid entity
2738 if (is_valid_ent(gGrabbed[id]))
2739 {
2740 //if block the player is grabbing is in their group and group count is larger than 1
2741 if (isBlockInGroup(id, gGrabbed[id]) && gGroupCount[id] > 1)
2742 {
2743 new Float:vMoveTo[3];
2744 new Float:vOffset[3];
2745 new Float:vOrigin[3];
2746 new block;
2747
2748 //move the block the player has grabbed and get the move vector
2749 moveGrabbedEntity(id, vMoveTo);
2750
2751 //move the rest of the blocks in the players group using vector for grabbed block
2752 for (new i = 0; i <= gGroupCount[id]; ++i)
2753 {
2754 block = gGroupedBlocks[id][i];
2755
2756 //if block is still in this players group
2757 if (isBlockInGroup(id, block))
2758 {
2759 //get offset vector from block
2760 entity_get_vector(block, EV_VEC_vuser1, vOffset);
2761
2762 vOrigin[0] = vMoveTo[0] - vOffset[0];
2763 vOrigin[1] = vMoveTo[1] - vOffset[1];
2764 vOrigin[2] = vMoveTo[2] - vOffset[2];
2765
2766 //move grouped block
2767 moveEntity(id, block, vOrigin, false);
2768 }
2769 }
2770 }
2771 else
2772 {
2773 //move the entity the player has grabbed
2774 moveGrabbedEntity(id);
2775 }
2776 }
2777 else
2778 {
2779 cmdRelease(id);
2780 }
2781 }
2782
2783 //if player has just deleted something
2784 if (gbJustDeleted[id])
2785 {
2786 //if player is pressing attack2
2787 if (buttons & IN_ATTACK2)
2788 {
2789 //prevent player from using attack2
2790 buttons &= ~IN_ATTACK2;
2791 entity_set_int(id, EV_INT_button, buttons);
2792 }
2793 else
2794 {
2795 //player has now NOT just deleted something
2796 gbJustDeleted[id] = false;
2797 }
2798 }
2799 }
2800
2801 return PLUGIN_CONTINUE;
2802}
2803
2804public client_PostThink(id)
2805{
2806 //if player is alive
2807 if (is_user_alive(id))
2808 {
2809 //if player is set to not get fall damage
2810 if (gbNoFallDamage[id])
2811 {
2812 entity_set_int(id, EV_INT_watertype, -3);
2813 gbNoFallDamage[id] = false;
2814 }
2815 }
2816}
2817
2818public forward_EmitSound(id, channel, sample[])
2819{
2820 if (is_user_alive(id) && containi(sample, "common/wpn_select.wav") >= 0)
2821 {
2822 actionTimer(id);
2823 }
2824}
2825
2826/***** EVENTS *****/
2827public eventPlayerDeath()
2828{
2829 new id = read_data(2);
2830
2831 resetTimers(id);
2832}
2833
2834public eventRoundRestart()
2835{
2836 new ent;
2837 //set shields to original origin
2838
2839 //find all block entities
2840 while ((ent = find_ent_by_class(ent, gszBlockClassname)))
2841 {
2842 //get block type
2843 new blockType = entity_get_int(ent, EV_INT_body);
2844
2845 //Set shield origin to original
2846 if (blockType == BM_SHIELD && shieldactive == true)
2847 {
2848 entity_set_origin(ent,shieldorigin);
2849 shieldactive = false;
2850 }
2851 if (blockType == BM_SLAPSHIELD && slapshieldactive == true)
2852 {
2853 entity_set_origin(ent,slapshieldorigin);
2854 slapshieldactive = false;
2855 }
2856 }
2857
2858
2859
2860 //iterate through all players
2861 for (new id = 1; id <= 32; ++id)
2862 {
2863 //reset all players timers
2864 resetTimers(id);
2865 SlapShieldUsed[id] = false;
2866 ShieldUsed[id] = false;
2867 DeagleUsed[id] = false;
2868 AwpUsed[id] = false;
2869 DamageBhopUsed[id] = false;
2870 FrostUsed[id] = false;
2871 FlashUsed[id] = false;
2872 HeUsed[id] = false;
2873 MoneyUsed[id] = false;
2874 LowTrampUsed[id] = false;
2875 HighTrampUsed[id] = false;
2876 UspUsed[id] = false;
2877 Ak47Used[id] = false;
2878 M4a1Used[id] = false;
2879 Mp5Used[id] = false;
2880 M3Used[id] = false;
2881 ScoutUsed[id] = false;
2882 XPUsed[id] = false;
2883 }
2884}
2885
2886public eventPlayerSpawn(id)
2887{
2888 //if player has godmode enabled
2889 if (gbAdminGodmode[id])
2890 {
2891 //re-enable godmode on player
2892 set_user_godmode(id, 1);
2893 }
2894
2895 //if player has noclip enabled
2896 if (gbAdminNoclip[id])
2897 {
2898 //re-enable noclip on player
2899 set_user_noclip(id, 1);
2900 }
2901
2902 //show /server message
2903 //set_task(90.0, "handlePluginInfo", id);
2904
2905 //show blockmaker author message
2906 set_task(220.0, "handlePluginInfoTwo", id);
2907
2908
2909}
2910
2911resetTimers(id)
2912{
2913 gfInvincibleTimeOut[id] = 0.0;
2914 gfInvincibleNextUse[id] = 0.0;
2915 gfStealthTimeOut[id] = 0.0;
2916 gfStealthNextUse[id] = 0.0;
2917 gfCamouflageTimeOut[id] = 0.0;
2918 gfCamouflageNextUse[id] = 0.0;
2919 gfNukeNextUse[id] = 0.0;
2920 gbOnFire[id] = false;
2921 gfRandomNextUse[id] = 0.0;
2922 gfBootsOfSpeedTimeOut[id] = 0.0;
2923 gfBootsOfSpeedNextUse[id] = 0.0;
2924 gfAutoBhopTimeOut[id] = 0.0;
2925 gfAutoBhopNextUse[id] = 0.0;
2926 gfBlindNextUse[id] = 0.0;
2927 g_xp_next_use[id] = 0.0;
2928 g_pet_next_use[id] = 0.0;
2929
2930 //remove any task this player might have
2931 new taskId = TASK_INVINCIBLE + id;
2932 if (task_exists(taskId))
2933 {
2934 remove_task(taskId);
2935 }
2936
2937 taskId = TASK_STEALTH + id;
2938 if (task_exists(taskId))
2939 {
2940 remove_task(taskId);
2941 }
2942
2943 taskId = TASK_CAMOUFLAGE + id;
2944 if (task_exists(taskId))
2945 {
2946 remove_task(taskId);
2947
2948 //change back to players old model
2949 cs_set_user_model(id, gszCamouflageOldModel[id]);
2950 }
2951
2952 taskId = TASK_BOOTSOFSPEED + id;
2953 if (task_exists(taskId))
2954 {
2955 remove_task(taskId);
2956 }
2957
2958 taskId = TASK_AUTOBHOP + id;
2959 if (task_exists(taskId))
2960 {
2961 remove_task(taskId);
2962 }
2963
2964 //make sure player is connected
2965 if (is_user_connected(id))
2966 {
2967 //set players rendering to normal
2968 set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderNormal, 255);
2969 }
2970
2971 //player is not 'on ice'
2972 gbOnIce[id] = false;
2973
2974 //player slows down after jumping
2975 gbNoSlowDown[id] = false;
2976
2977 //player does not have auto bhop
2978 gbAutoBhop[id] = false;
2979
2980 //player does not have a timer
2981 gbHasTimer[id] = false;
2982}
2983
2984public eventCurWeapon(id)
2985{
2986 new Float:fTime = halflife_time();
2987 new Float:fTimeleftBootsOfSpeed = gfBootsOfSpeedTimeOut[id] - fTime;
2988
2989 //if the player has the boots of speed
2990 if (fTimeleftBootsOfSpeed >= 0.0)
2991 {
2992 //set their max speed so they obtain their speed after changing weapon
2993 set_user_maxspeed(id, gfBootsMaxSpeed);
2994 }
2995}
2996actionFollowBhopXPlus(id, ent)
2997{
2998 //Move block
2999 set_task(0.1,"FollowBhopXPlus",ent);
3000}
3001public FollowBhopXPlus(ent)
3002{
3003 new Float:OriginOld[3];
3004 new Float:OriginNew[3];
3005 get_brush_entity_origin (ent, OriginOld);
3006 OriginNew = OriginOld;
3007 OriginNew[0] = floatadd (OriginNew[0],55.0);
3008
3009 entity_set_origin(ent,OriginNew);
3010}
3011actionFollowBhopXMinus(id, ent)
3012{
3013}
3014actionFollowBhopYPlus(id, ent)
3015{
3016}
3017actionFollowBhopYMinus(id, ent)
3018{
3019
3020}
3021actionMagicCarpet(id, ent)
3022{
3023 //store old origin
3024 new float:OriginOld[3];
3025 get_brush_entity_origin (ent, OriginOld);
3026
3027
3028 //if User is touching magic carpet vector move it down
3029 get_user_origin(id,userorigin,0);
3030 userorigin[2] -= 40;
3031 new float:test[3];
3032 for (new i=0;i<3;i++)
3033 test[i] = float(userorigin[i]);
3034 entity_set_origin(ent,test);
3035 set_user_noclip (id,1);
3036 if (TouchingMagicCarpet[id] == false)
3037 {
3038 set_task(20.0,"RemoveMagicCarpet",id,OriginOld);
3039 TouchingMagicCarpet[id] = true;
3040 }
3041}
3042public RemoveMagicCarpet(id,OriginOld)
3043{
3044 set_user_noclip (id,1);
3045 //entity_set_origin(ent,OriginOld);
3046 TouchingMagicCarpet[id] = false;
3047}
3048actionShield(id, ent)
3049{
3050 //if User is alive and T
3051 if (is_user_alive(id) && !ShieldUsed[id] && get_user_team(id) == 1 && shieldactive == false)
3052 {
3053 ShieldUsed[id] = true;
3054 new shieldname[42];
3055 get_user_name(id, shieldname, 32);
3056 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
3057 show_hudmessage(0, "LUCKY!! %s has a Death Shield!!", shieldname);
3058 shieldplayer = id;
3059 shieldactive = true;
3060 //store origional origin
3061 get_brush_entity_origin (ent, shieldorigin);
3062
3063
3064 }
3065}
3066actionSlapShield(id, ent)
3067{
3068 //if User is alive and T
3069 if (is_user_alive(id) && !SlapShieldUsed[id] && get_user_team(id) == 1 && slapshieldactive == false)
3070 {
3071 SlapShieldUsed[id] = true;
3072 new shieldname[42];
3073 get_user_name(id, shieldname, 32);
3074 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
3075 show_hudmessage(0, "HAHA!! %s has a slappy shield!!", shieldname);
3076 slapshieldplayer = id;
3077 slapshieldactive = true;
3078 //store origional origin
3079 get_brush_entity_origin (ent, slapshieldorigin);
3080
3081
3082 }
3083}
3084actionMovingBlockXSmall(id,ent)
3085{
3086
3087
3088 new Float:OriginOld[3];
3089 new Float:OriginNew[3];
3090
3091 if (wait > waitmax)
3092 {
3093 //Set movement path for moving blocks
3094 if (movingspotsmall > 0)
3095 {
3096 //Move user
3097 new origin[3];
3098 get_user_origin(id,origin,0);
3099 origin[0] = origin[0] +1;
3100 set_user_origin(id,origin) ;
3101 }
3102 if (movingspotsmall < 0)
3103 {
3104 //Move user
3105 new origin[3];
3106 get_user_origin(id,origin,0);
3107 origin[0] = origin[0] - 1;
3108 set_user_origin(id,origin) ;
3109 }
3110 wait = 0;
3111 } else {
3112 wait++;
3113 }
3114
3115
3116}
3117actionMovingBlockYSmall(id,ent)
3118{
3119
3120
3121 new Float:OriginOld[3];
3122 new Float:OriginNew[3];
3123
3124 if (wait > waitmax)
3125 {
3126 //Set movement path for moving blocks
3127 if (movingspotsmall > 0)
3128 {
3129 //Move user
3130 new origin[3];
3131 get_user_origin(id,origin,0);
3132 origin[1] = origin[1] +1;
3133 set_user_origin(id,origin) ;
3134 }
3135 if (movingspotsmall < 0)
3136 {
3137 //Move user
3138 new origin[3];
3139 get_user_origin(id,origin,0);
3140 origin[1] = origin[1] - 1;
3141 set_user_origin(id,origin) ;
3142 }
3143 wait = 0;
3144 } else {
3145 wait++;
3146 }
3147
3148
3149}
3150actionMovingBlockZSmall(id,ent)
3151{
3152
3153
3154 new Float:OriginOld[3];
3155 new Float:OriginNew[3];
3156
3157 if (wait > waitmax)
3158 {
3159 //Set movement path for moving blocks
3160 if (movingspotsmall> 0)
3161 {
3162 //Move user
3163 new origin[3];
3164 get_user_origin(id,origin,0);
3165 origin[2] = origin[2] +2;
3166 set_user_origin(id,origin) ;
3167 }
3168 if (movingspotsmall < 0)
3169 {
3170 //dont move if going down
3171 }
3172 wait = 0;
3173 } else {
3174 wait++;
3175 }
3176
3177
3178}
3179actionMovingBlockX(id,ent)
3180{
3181
3182
3183 new Float:OriginOld[3];
3184 new Float:OriginNew[3];
3185
3186 if (wait > waitmax)
3187 {
3188 //Set movement path for moving blocks
3189 if (movingspot > 0)
3190 {
3191 //Move user
3192 new origin[3];
3193 get_user_origin(id,origin,0);
3194 origin[0] = origin[0] +1;
3195 set_user_origin(id,origin) ;
3196 }
3197 if (movingspot < 0)
3198 {
3199 //Move user
3200 new origin[3];
3201 get_user_origin(id,origin,0);
3202 origin[0] = origin[0] - 1;
3203 set_user_origin(id,origin) ;
3204 }
3205 wait = 0;
3206 } else {
3207 wait++;
3208 }
3209
3210
3211}
3212actionMovingBlockY(id,ent)
3213{
3214
3215
3216 new Float:OriginOld[3];
3217 new Float:OriginNew[3];
3218
3219 if (wait > waitmax)
3220 {
3221 //Set movement path for moving blocks
3222 if (movingspot > 0)
3223 {
3224 //Move user
3225 new origin[3];
3226 get_user_origin(id,origin,0);
3227 origin[1] = origin[1] +1;
3228 set_user_origin(id,origin) ;
3229 }
3230 if (movingspot < 0)
3231 {
3232 //Move user
3233 new origin[3];
3234 get_user_origin(id,origin,0);
3235 origin[1] = origin[1] - 1;
3236 set_user_origin(id,origin) ;
3237 }
3238 wait = 0;
3239 } else {
3240 wait++;
3241 }
3242
3243
3244}
3245actionMovingBlockZ(id,ent)
3246{
3247
3248
3249 new Float:OriginOld[3];
3250 new Float:OriginNew[3];
3251
3252 if (wait > waitmax)
3253 {
3254 //Set movement path for moving blocks
3255 if (movingspot > 0)
3256 {
3257 //Move user
3258 new origin[3];
3259 get_user_origin(id,origin,0);
3260 origin[2] = origin[2] +2;
3261 set_user_origin(id,origin) ;
3262 }
3263 if (movingspot < 0)
3264 {
3265 //dont move if going down
3266 }
3267 wait = 0;
3268 } else {
3269 wait++;
3270 }
3271
3272
3273}
3274actionMovingBlockXLarge(id,ent)
3275{
3276
3277
3278 new Float:OriginOld[3];
3279 new Float:OriginNew[3];
3280
3281 if (wait > waitmax)
3282 {
3283 //Set movement path for moving blocks
3284 if (movingspotlarge > 0)
3285 {
3286 //Move user
3287 new origin[3];
3288 get_user_origin(id,origin,0);
3289 origin[0] = origin[0] +1;
3290 set_user_origin(id,origin) ;
3291 }
3292 if (movingspotlarge < 0)
3293 {
3294 //Move user
3295 new origin[3];
3296 get_user_origin(id,origin,0);
3297 origin[0] = origin[0] - 1;
3298 set_user_origin(id,origin) ;
3299 }
3300 wait = 0;
3301 } else {
3302 wait++;
3303 }
3304
3305
3306}
3307actionMovingBlockYLarge(id,ent)
3308{
3309
3310
3311 new Float:OriginOld[3];
3312 new Float:OriginNew[3];
3313
3314 if (wait > waitmax)
3315 {
3316 //Set movement path for moving blocks
3317 if (movingspotlarge > 0)
3318 {
3319 //Move user
3320 new origin[3];
3321 get_user_origin(id,origin,0);
3322 origin[1] = origin[1] +1;
3323 set_user_origin(id,origin) ;
3324 }
3325 if (movingspotlarge < 0)
3326 {
3327 //Move user
3328 new origin[3];
3329 get_user_origin(id,origin,0);
3330 origin[1] = origin[1] - 1;
3331 set_user_origin(id,origin) ;
3332 }
3333 wait = 0;
3334 } else {
3335 wait++;
3336 }
3337
3338
3339}
3340actionMovingBlockZLarge(id,ent)
3341{
3342
3343
3344 new Float:OriginOld[3];
3345 new Float:OriginNew[3];
3346
3347 if (wait > waitmax)
3348 {
3349 //Set movement path for moving blocks
3350 if (movingspotlarge > 0)
3351 {
3352 //Move user
3353 new origin[3];
3354 get_user_origin(id,origin,0);
3355 origin[2] = origin[2] +2;
3356 set_user_origin(id,origin) ;
3357 }
3358 if (movingspotlarge< 0)
3359 {
3360 //dont move if going down
3361 }
3362 wait = 0;
3363 } else {
3364 wait++;
3365 }
3366
3367
3368}
3369actionBhopUnderblock(id,ent)
3370{
3371 set_task(0.1, "taskSolidNot", TASK_BHOPSOLIDNOT + ent);
3372}
3373
3374/***** BLOCK ACTIONS *****/
3375actionPet(id, ent)
3376
3377{
3378 /*
3379 new Float:fTime = halflife_time();
3380
3381 if (fTime >= g_pet_next_use[id] || OverrideTimer)
3382 {
3383
3384 amx_exec(id, "say /pet");
3385 ColorChat(id, GREEN, "[%s]^x03 You Have Adopted a pet!", g_prefix);
3386
3387
3388 g_pet_next_use[id] = fTime + get_cvar_float("bm_petcooldown");
3389
3390 }
3391 else
3392 {
3393 set_hudmessage(g_hud_red, g_hud_green, g_hud_blue, g_text_x, g_text_y, g_hud_effects, g_hud_fx_time, g_hud_hold_time, g_hud_fade_in_time, g_hud_fade_out_time, g_hud_channel);
3394 show_hudmessage(id, "[%s]^nWait For Next Pet...", g_prefix, g_xp_next_use[id] - fTime);
3395 }
3396
3397 new origin[3];
3398 get_user_origin(id,origin,0); // Gets the current location the player is at
3399 origin[2] = origin[2] + 150; // Adds + 10 to the players hight
3400 set_user_origin(id,origin) ;
3401
3402
3403 */
3404
3405
3406
3407
3408
3409}
3410actionXP(id, OverrideTimer)
3411{
3412/*
3413 new Float:fTime = halflife_time();
3414
3415 if (fTime >= g_xp_next_use[id] || OverrideTimer)
3416 {
3417 if ( get_user_team ( id ) == 1 )
3418 {
3419 hnsxp_add_user_xp(id, 100);
3420 ColorChat(id, GREEN, "[%s]^x03 You have been given^x04 100 XP^x03!");
3421 }
3422
3423 g_xp_next_use[id] = fTime + get_cvar_float("bm_xpcooldown");
3424
3425 }
3426 else
3427 {
3428 show_hudmessage(id, "[%s]^nWait Time: One Round", g_xp_next_use[id] - fTime);
3429 }
3430 return PLUGIN_HANDLED;
3431 */
3432 if (is_user_alive(id) && !XPUsed[id] && get_user_team(id) == 1)
3433 {
3434 XPUsed[id] = true;
3435 client_print(id,print_chat, "***You got 100 XP***");
3436 hnsxp_add_user_xp(id, 100);
3437
3438 }
3439 return PLUGIN_HANDLED;
3440}
3441actionBlindDamage(id, bool:OverrideTimer)
3442{
3443 if (halflife_time() >= gfNextDamageTime[id])
3444 {
3445 if (get_user_health(id) > 0)
3446 {
3447 new Float:amount = get_cvar_float("bm_damageamount");
3448 fakedamage(id, "damage block", amount, DMG_CRUSH);
3449 }
3450
3451 gfNextDamageTime[id] = halflife_time() + 0.5;
3452 }
3453
3454
3455 new Float:fTime = halflife_time();
3456
3457 if (fTime >= gfBlindNextUse[id] || OverrideTimer)
3458 {
3459 new Float:fTimeout = get_cvar_float("bm_blindnotime");
3460
3461 fade( id, { 150, 255, 150, 250 } );
3462
3463 set_hudmessage(gHudRed, gHudGreen, gHudBlue, gfTextX, gfTextY, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
3464 show_hudmessage(id, "Your eyes just got jizzed in!");
3465
3466 gfBlindTimeOut[id] = fTime + fTimeout;
3467 gfBlindNextUse[id] = fTime + fTimeout + get_cvar_float("bm_blindnocooldown");
3468 }
3469}
3470
3471actionBlind(id, bool:OverrideTimer)
3472{
3473 new Float:fTime = halflife_time();
3474
3475 if (fTime >= gfBlindNextUse[id] || OverrideTimer)
3476 {
3477 new Float:fTimeout = get_cvar_float("bm_blindnotime");
3478
3479 fade( id, { 150, 255, 150, 250 } );
3480
3481 gfBlindTimeOut[id] = fTime + fTimeout;
3482 gfBlindNextUse[id] = fTime + fTimeout + get_cvar_float("bm_blindnocooldown");
3483 }
3484}
3485
3486fade( id, color[ 4 ] ) {
3487 message_begin(MSG_ONE_UNRELIABLE, gMsgScreenFade, _, id);
3488 write_short(4096 * 2);
3489 write_short(4096 * 2);
3490 write_short(0x0000);
3491 write_byte(color[0]);
3492 write_byte(color[1]);
3493 write_byte(color[2]);
3494 write_byte(color[3]);
3495 message_end();
3496}
3497actionAk47(id)
3498{
3499 if (is_user_alive(id) && !Ak47Used[id] && get_user_team(id) == 1)
3500 {
3501 give_item(id, "weapon_ak47");
3502 cs_set_weapon_ammo(find_ent_by_owner(1, "weapon_ak47", id), 1);
3503 Ak47Used[id] = true;
3504 new ak47name[42];
3505 get_user_name(id, ak47name, 32);
3506 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
3507 show_hudmessage(0, "CT's better look out! %s has an Ak47!!", ak47name);
3508 }
3509}
3510actionM4a1(id)
3511{
3512 if (is_user_alive(id) && !M4a1Used[id] && get_user_team(id) == 1)
3513 {
3514 give_item(id, "weapon_m4a1");
3515 cs_set_weapon_ammo(find_ent_by_owner(1, "weapon_m4a1", id), 1);
3516 M4a1Used[id] = true;
3517 new m4a1name[42];
3518 get_user_name(id, m4a1name, 32);
3519 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
3520 show_hudmessage(0, "CT's are in trouble! %s has an M4A1!!", m4a1name);
3521 }
3522}
3523actionMp5(id)
3524{
3525 if (is_user_alive(id) && !Mp5Used[id] && get_user_team(id) == 1)
3526 {
3527 give_item(id, "weapon_mp5navy");
3528 cs_set_weapon_ammo(find_ent_by_owner(1, "weapon_mp5navy", id), 1);
3529 Mp5Used[id] = true;
3530 new mp5name[42];
3531 get_user_name(id, mp5name, 32);
3532 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
3533 show_hudmessage(0, "CT's be aware. %s has a MP5.", mp5name);
3534 }
3535}
3536actionM3(id)
3537{
3538 if (is_user_alive(id) && !M3Used[id] && get_user_team(id) == 1)
3539 {
3540 give_item(id, "weapon_m3");
3541 cs_set_weapon_ammo(find_ent_by_owner(1, "weapon_m3", id), 1);
3542 M3Used[id] = true;
3543 new m3name[42];
3544 get_user_name(id, m3name, 32);
3545 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
3546 show_hudmessage(0, "SHIT SON. %s has a M3 SHOTGUN !!!!!", m3name);
3547 }
3548}
3549actionScout(id)
3550{
3551 if (is_user_alive(id) && !ScoutUsed[id] && get_user_team(id) == 1)
3552 {
3553 give_item(id, "weapon_scout");
3554 cs_set_weapon_ammo(find_ent_by_owner(1, "weapon_scout", id), 1);
3555 ScoutUsed[id] = true;
3556 new scoutname[42];
3557 get_user_name(id, scoutname, 32);
3558 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
3559 show_hudmessage(0, "CT's watch it! %s has a scout.", scoutname);
3560 }
3561}
3562actionAwp(id)
3563{
3564 if (is_user_alive(id) && !AwpUsed[id] && get_user_team(id) == 1)
3565 {
3566 give_item(id, "weapon_awp");
3567 cs_set_weapon_ammo(find_ent_by_owner(1, "weapon_awp", id), 1);
3568 AwpUsed[id] = true;
3569 new awpname[42];
3570 get_user_name(id, awpname, 32);
3571 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
3572 show_hudmessage(0, "CT's are fucked now!! %s has an AWP !!!!!", awpname);
3573 }
3574}
3575actionUsp(id)
3576{
3577 if (is_user_alive(id) && !UspUsed[id] && get_user_team(id) == 1)
3578 {
3579 give_item(id, "weapon_usp");
3580 cs_set_weapon_ammo(find_ent_by_owner(1, "weapon_usp", id), 1);
3581 UspUsed[id] = true;
3582 new uspname[42];
3583 get_user_name(id, uspname, 32);
3584 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
3585 show_hudmessage(0, "Look out CT's! %s has a USP.", uspname);
3586 }
3587}
3588actionHighTramp(id)
3589{
3590 //if trampoline timeout has exceeded (needed to prevent velocity being given multiple times)
3591 if (halflife_time() >= gfTrampolineTimeout[id])
3592 {
3593 new Float:velocity[3];
3594
3595 //set player Z velocity to make player bounce
3596 entity_get_vector(id, EV_VEC_velocity, velocity);
3597 velocity[2] = 800.0; //jump velocity
3598 entity_set_vector(id, EV_VEC_velocity, velocity);
3599
3600 entity_set_int(id, EV_INT_gaitsequence, 6); //play the Jump Animation
3601
3602 gfTrampolineTimeout[id] = halflife_time() + 0.5;
3603 }
3604}
3605actionLowTramp(id)
3606{
3607 //if trampoline timeout has exceeded (needed to prevent velocity being given multiple times)
3608 // if (halflife_time() >= LowTrampUsed[id])
3609 {
3610 new Float:velocity[3];
3611
3612 //set player Z velocity to make player bounce
3613 entity_get_vector(id, EV_VEC_velocity, velocity);
3614 velocity[2] = 350.0; //jump velocity
3615 entity_set_vector(id, EV_VEC_velocity, velocity);
3616
3617 entity_set_int(id, EV_INT_gaitsequence, 6); //play the Jump Animation
3618
3619 LowTrampUsed[id] = halflife_time() + 0.5;
3620 }
3621}
3622actionMoney(id, OverrideTimer)
3623{
3624 //get game time
3625 new Float:fTime = halflife_time();
3626
3627 //make sure player is alive
3628 if (fTime >= MoneyUsed[id] || OverrideTimer)
3629 {
3630 cs_set_user_money(id, cs_get_user_money (id) + 10000) ;
3631 {
3632 //omg
3633 }
3634
3635 //set the time when the player can use the nuke again (someone might have been invincible)
3636 MoneyUsed[id] = fTime + get_cvar_float("bm_moneycooldown");
3637
3638 //setup hud message to show who nuked what team
3639 set_hudmessage(255, 255, 0, -1.0, 0.35, 0, 6.0, 10.0, 1.0, 1.0);
3640
3641 }
3642}
3643actionHe(id, OverrideTimer)
3644{
3645 //get game time
3646 new Float:fTime = halflife_time();
3647
3648 //make sure player is alive
3649 if (fTime >= HeUsed[id] || OverrideTimer)
3650 {
3651 if ( !cs_get_user_bpammo(id, CSW_HEGRENADE) && get_user_team ( id ) == 1 )
3652 {
3653 //ID HE
3654 give_item(id, "weapon_hegrenade");
3655 {
3656 //set the time when the player can use the nuke again (someone might have been invincible)
3657 HeUsed[id] = fTime + get_cvar_float("bm_hecooldown");
3658 }
3659 }
3660
3661
3662
3663 //setup hud message to show who nuked what team
3664 set_hudmessage(255, 255, 0, -1.0, 0.35, 0, 6.0, 10.0, 1.0, 1.0);
3665
3666 }
3667}
3668actionFlash(id, OverrideTimer)
3669{
3670 //get game time
3671 new Float:fTime = halflife_time();
3672
3673 //make sure player is alive
3674 if (fTime >= FlashUsed[id] || OverrideTimer)
3675 {
3676 if (cs_get_user_bpammo(id, CSW_FLASHBANG) < 2 && get_user_team ( id ) == 1 )
3677 {
3678 give_item(id, "weapon_flashbang");
3679 {
3680 //set the time when player can use flash grenade again
3681 FlashUsed[id] = fTime + get_cvar_float("bm_flashgrenadecooldown");
3682 }
3683 }
3684
3685
3686 //setup hud message to show who nuked what team
3687 set_hudmessage(255, 255, 0, -1.0, 0.35, 0, 6.0, 10.0, 1.0, 1.0);
3688
3689 }
3690}
3691actionFrost(id, OverrideTimer)
3692{
3693 //get game time
3694 new Float:fTime = halflife_time();
3695
3696 //make sure player is alive
3697 if (fTime >= FrostUsed[id] || OverrideTimer)
3698 {
3699 if (!cs_get_user_bpammo(id, CSW_SMOKEGRENADE) && get_user_team ( id ) == 1 )
3700 {
3701 give_item(id, "weapon_smokegrenade");
3702 //set the time when player can use frost grenade again
3703 FrostUsed[id] = fTime + get_cvar_float("bm_frostgrenadecooldown");
3704 }
3705
3706 //setup hud message to show who nuked what team
3707 set_hudmessage(255, 255, 0, -1.0, 0.35, 0, 6.0, 10.0, 1.0, 1.0);
3708
3709 }
3710}
3711actionDeagle(id)
3712{
3713 if (is_user_alive(id) && !DeagleUsed[id] && get_user_team(id) == 1)
3714 {
3715 give_item(id, "weapon_deagle");
3716 cs_set_weapon_ammo(find_ent_by_owner(1, "weapon_deagle", id), 1);
3717 DeagleUsed[id] = true;
3718 new deaglename[42];
3719 get_user_name(id, deaglename, 32);
3720 set_hudmessage(255, 255, 255, -1.0, -1.0, 0, 6.0, 4.0);
3721 show_hudmessage(0, "Holy Sh1t! %s has a Deagle!", deaglename);
3722 }
3723}
3724actionDamage(id)
3725{
3726 if (halflife_time() >= gfNextDamageTime[id])
3727 {
3728 if (get_user_health(id) > 0)
3729 {
3730 new Float:amount = get_cvar_float("bm_damageamount");
3731 fakedamage(id, "damage block", amount, DMG_CRUSH);
3732 }
3733
3734 gfNextDamageTime[id] = halflife_time() + 0.5;
3735 }
3736}
3737
3738actionHeal(id)
3739{
3740 if (halflife_time() >= gfNextHealTime[id])
3741 {
3742 new hp = get_user_health(id);
3743 new amount = floatround(get_cvar_float("bm_healamount"), floatround_floor);
3744 new sum = (hp + amount);
3745
3746 if (sum <= 102)
3747 {
3748 set_user_health(id, sum);
3749 }
3750 else
3751 {
3752 if (!sum > 104)
3753 {
3754 set_user_health(id, 100);
3755 }
3756 }
3757
3758 gfNextHealTime[id] = halflife_time() + 0.5;
3759 }
3760}
3761
3762actionInvincible(id, OverrideTimer)
3763{
3764 new Float:fTime = halflife_time();
3765
3766 if (fTime >= gfInvincibleNextUse[id] || OverrideTimer)
3767 {
3768 new Float:fTimeout = get_cvar_float("bm_invincibletime");
3769
3770 set_user_godmode(id, 1);
3771 set_task(fTimeout, "taskInvincibleRemove", TASK_INVINCIBLE + id, "", 0, "a", 1);
3772
3773 //only make player glow white for invincibility if player isn't already stealth
3774 if (fTime >= gfStealthTimeOut[id])
3775 {
3776 set_user_rendering(id, kRenderFxGlowShell, 255, 255, 255, kRenderNormal, 16);
3777 }
3778
3779 //play invincibility sound
3780 emit_sound(id, CHAN_STATIC, gszInvincibleSound, 1.0, ATTN_NORM, 0, PITCH_NORM);
3781
3782 gfInvincibleTimeOut[id] = fTime + fTimeout;
3783 gfInvincibleNextUse[id] = fTime + fTimeout + get_cvar_float("bm_invinciblecooldown");
3784 }
3785 else
3786 {
3787 set_hudmessage(gHudRed, gHudGreen, gHudBlue, gfTextX, gfTextY, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
3788 show_hudmessage(id, "Invincibility next use: %.1f", gfInvincibleNextUse[id] - fTime);
3789 }
3790}
3791
3792actionStealth(id, OverrideTimer)
3793{
3794 new Float:fTime = halflife_time();
3795
3796 //check if player is outside of cooldown time to use stealth
3797 if (fTime >= gfStealthNextUse[id] || OverrideTimer)
3798 {
3799 new Float:fTimeout = get_cvar_float("bm_stealthtime");
3800
3801 //set a task to remove stealth after time out amount
3802 set_task(fTimeout, "taskStealthRemove", TASK_STEALTH + id, "", 0, "a", 1);
3803
3804 //make player invisible
3805 set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransColor, 0);
3806
3807 //play stealth sound
3808 emit_sound(id, CHAN_STATIC, gszStealthSound, 1.0, ATTN_NORM, 0, PITCH_NORM);
3809
3810 gfStealthTimeOut[id] = fTime + fTimeout;
3811 gfStealthNextUse[id] = fTime + fTimeout + get_cvar_float("bm_stealthcooldown");
3812 }
3813 else
3814 {
3815 set_hudmessage(gHudRed, gHudGreen, gHudBlue, gfTextX, gfTextY, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
3816 show_hudmessage(id, "Stealth next use: %.1f", gfStealthNextUse[id] - fTime);
3817 }
3818}
3819
3820actionTrampoline(id)
3821{
3822 //if trampoline timeout has exceeded (needed to prevent velocity being given multiple times)
3823 if (halflife_time() >= gfTrampolineTimeout[id])
3824 {
3825 new Float:velocity[3];
3826
3827 //set player Z velocity to make player bounce
3828 entity_get_vector(id, EV_VEC_velocity, velocity);
3829 velocity[2] = 500.0; //jump velocity
3830 entity_set_vector(id, EV_VEC_velocity, velocity);
3831
3832 entity_set_int(id, EV_INT_gaitsequence, 6); //play the Jump Animation
3833
3834 gfTrampolineTimeout[id] = halflife_time() + 0.5;
3835 }
3836}
3837
3838actionSpeedBoost(id)
3839{
3840 //if speed boost timeout has exceeded (needed to prevent speed boost being given multiple times)
3841 if (halflife_time() >= gfSpeedBoostTimeOut[id])
3842 {
3843 new Float:pAim[3];
3844
3845 //set velocity on player in direction they're aiming
3846 velocity_by_aim(id, 800, pAim);
3847 pAim[2] = 260.0; //make sure Z velocity is only as high as a jump
3848 entity_set_vector(id, EV_VEC_velocity, pAim);
3849
3850 entity_set_int(id, EV_INT_gaitsequence, 6); //play the Jump Animation
3851
3852 gfSpeedBoostTimeOut[id] = halflife_time() + 0.5;
3853 }
3854}
3855
3856actionNoFallDamage(id)
3857{
3858 //set the player to not receive any fall damage (handled in client_PostThink)
3859 gbNoFallDamage[id] = true;
3860}
3861
3862actionOnIce(id)
3863{
3864 new taskid = TASK_ICE + id;
3865
3866 if (!gbOnIce[id])
3867 {
3868 //save players maxspeed value
3869 gfOldMaxSpeed[id] = get_user_maxspeed(id);
3870
3871 //make player feel like they're on ice
3872 entity_set_float(id, EV_FL_friction, 0.15);
3873 set_user_maxspeed(id, 600.0);
3874
3875 //player is now 'on ice'
3876 gbOnIce[id] = true;
3877 }
3878
3879 //remove any existing 'not on ice' task
3880 if (task_exists(taskid))
3881 {
3882 remove_task(taskid);
3883 }
3884
3885 //set task to remove 'on ice' effect very soon (task replaced if player is still on ice before task time reached)
3886 set_task(0.1, "taskNotOnIce", taskid);
3887}
3888
3889actionDeath(id)
3890{
3891 //if player does not have godmode enabled (admin godmode or invincibility)
3892 if (!get_user_godmode(id))
3893 {
3894 //kill player by inflicting massive damage
3895 fakedamage(id, "the block of death", 10000.0, DMG_GENERIC);
3896 }
3897}
3898
3899actionNuke(id, OverrideTimer)
3900{
3901 //get game time
3902 new Float:fTime = halflife_time();
3903
3904 //make sure player is alive
3905 if (is_user_alive(id) && (fTime >= gfNukeNextUse[id] || OverrideTimer))
3906 {
3907 //get players team
3908 new CsTeams:playerTeam = cs_get_user_team(id);
3909 new CsTeams:team;
3910
3911 //iterate through all players
3912 for (new i = 1; i <= 32; ++i)
3913 {
3914 //make sure player is alive
3915 if (is_user_alive(i))
3916 {
3917 team = cs_get_user_team(i);
3918
3919 //if this player is on a different team to the player that used the nuke
3920 if ((team == CS_TEAM_T && playerTeam == CS_TEAM_CT) || (team == CS_TEAM_CT && playerTeam == CS_TEAM_T))
3921 {
3922 //slay player
3923 fakedamage(i, "a nuke", 10000.0, DMG_BLAST);
3924 }
3925 }
3926
3927 //make sure player is connected
3928 if (is_user_connected(i))
3929 {
3930 //make the screen flash for a nuke effect
3931 message_begin(MSG_ONE, gMsgScreenFade, {0, 0, 0}, i);
3932 write_short(1024); //duration
3933 write_short(1024); //hold time
3934 write_short(4096); //type (in / out)
3935 write_byte(255); //red
3936 write_byte(255); //green
3937 write_byte(255); //blue
3938 write_byte(255); //alpha
3939 message_end();
3940 }
3941 }
3942
3943 //play explosion sound
3944 emit_sound(0, CHAN_STATIC, gszNukeExplosion, 1.0, ATTN_NORM, 0, PITCH_NORM);
3945
3946 //set the time when the player can use the nuke again (someone might have been invincible)
3947 gfNukeNextUse[id] = fTime + get_cvar_float("bm_nukecooldown");
3948
3949 //get the name of the player that used the nuke
3950 new szPlayerName[32];
3951 get_user_name(id, szPlayerName, 32);
3952
3953 //setup hud message to show who nuked what team
3954 set_hudmessage(255, 255, 0, -1.0, 0.35, 0, 6.0, 10.0, 1.0, 1.0);
3955
3956 //show message saying player nuked the other team
3957 if (playerTeam == CS_TEAM_T)
3958 {
3959 show_hudmessage(0, "%s just nuked the Counter-Terrorists", szPlayerName);
3960 }
3961 else
3962 {
3963 show_hudmessage(0, "%s just nuked the Terrorists", szPlayerName);
3964 }
3965 }
3966 else
3967 {
3968 set_hudmessage(gHudRed, gHudGreen, gHudBlue, gfTextX, gfTextY, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
3969 show_hudmessage(id, "Nuke next use: %.1f", gfNukeNextUse[id] - fTime);
3970 }
3971}
3972
3973actionCamouflage(id, OverrideTimer)
3974{
3975 new Float:fTime = halflife_time();
3976
3977 //check if player is outside of cooldown time to use camouflage
3978 if (fTime >= gfCamouflageNextUse[id] || OverrideTimer)
3979 {
3980 new Float:fTimeout = get_cvar_float("bm_camouflagetime");
3981
3982 //get players team and model
3983 new szModel[32];
3984 new team;
3985
3986 cs_get_user_model(id, szModel, 32);
3987
3988 team = get_user_team(id);
3989
3990 //save current player model
3991 gszCamouflageOldModel[id] = szModel;
3992
3993 //change player model depending on their current team
3994 if (team == 1) //TERRORIST
3995 {
3996 cs_set_user_model(id, "urban");
3997 }
3998 else
3999 {
4000 cs_set_user_model(id, "leet");
4001 }
4002
4003 //play camouflage sound
4004 emit_sound(id, CHAN_STATIC, gszCamouflageSound, 1.0, ATTN_NORM, 0, PITCH_NORM);
4005
4006 //set a task to remove camouflage after time out amount
4007 set_task(fTimeout, "taskCamouflageRemove", TASK_CAMOUFLAGE + id, "", 0, "a", 1);
4008
4009 //set timers to prevent player from using camouflage again so soon
4010 gfCamouflageTimeOut[id] = fTime + fTimeout;
4011 gfCamouflageNextUse[id] = fTime + fTimeout + get_cvar_float("bm_camouflagecooldown");
4012 }
4013 else
4014 {
4015 set_hudmessage(gHudRed, gHudGreen, gHudBlue, gfTextX, gfTextY, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
4016 show_hudmessage(id, "Camouflage next use: %.1f", gfCamouflageNextUse[id] - fTime);
4017 }
4018}
4019
4020actionLowGravity(id)
4021{
4022 //set player to have low gravity
4023 set_user_gravity(id, 0.25);
4024
4025 //set global boolean showing player has low gravity
4026 gbLowGravity[id] = true;
4027}
4028
4029actionFire(id, ent)
4030{
4031 if (halflife_time() >= gfNextDamageTime[id])
4032 {
4033 new hp = get_user_health(id);
4034
4035 //if players health is greater than 0
4036 if (hp > 0)
4037 {
4038 //if player does not have godmode
4039 if (!get_user_godmode(id))
4040 {
4041 new Float:amount = get_cvar_float("bm_firedamageamount") / 10.0;
4042 new Float:newAmount = hp - amount;
4043
4044 //if this amount of damage won't kill the player
4045 if (newAmount > 0)
4046 {
4047 set_user_health(id, floatround(newAmount, floatround_floor));
4048 }
4049 else
4050 {
4051 //use fakedamage to kill the player
4052 fakedamage(id, "fire block", amount, DMG_BURN);
4053 }
4054 }
4055
4056 //get halflife time and time for next fire sound from fire block
4057 new Float:fTime = halflife_time();
4058 new Float:fNextFireSoundTime = entity_get_float(ent, EV_FL_ltime);
4059
4060 //if the current time is greater than or equal to the next time to play the fire sound
4061 if (fTime >= fNextFireSoundTime)
4062 {
4063 //play the fire sound
4064 emit_sound(ent, CHAN_ITEM, gszFireSoundFlame, 0.6, ATTN_NORM, 0, PITCH_NORM);
4065
4066 //set the fire blocks time
4067 entity_set_float(ent, EV_FL_ltime, fTime + 0.75);
4068 }
4069
4070 //get effects vectors using block origin
4071 new Float:origin1[3];
4072 new Float:origin2[3];
4073 entity_get_vector(ent, EV_VEC_origin, origin1);
4074 entity_get_vector(ent, EV_VEC_origin, origin2);
4075 origin1[0] -= 32.0;
4076 origin1[1] -= 32.0;
4077 origin1[2] += 10.0;
4078 origin2[0] += 32.0;
4079 origin2[1] += 32.0;
4080 origin2[2] += 10.0;
4081
4082 //get a random height for the flame
4083 new randHeight = random_num(0, 32) + 16;
4084
4085 //show some effects
4086 message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
4087 write_byte(TE_BUBBLES);
4088 write_coord(floatround(origin1[0], floatround_floor)); //min start position
4089 write_coord(floatround(origin1[1], floatround_floor));
4090 write_coord(floatround(origin1[2], floatround_floor));
4091 write_coord(floatround(origin2[0], floatround_floor)); //max start position
4092 write_coord(floatround(origin2[1], floatround_floor));
4093 write_coord(floatround(origin2[2], floatround_floor));
4094 write_coord(randHeight); //float height
4095 write_short(gSpriteIdFire); //model index
4096 write_byte(10); //count
4097 write_coord(1); //speed
4098 message_end();
4099 }
4100
4101 gfNextDamageTime[id] = halflife_time() + 0.05;
4102 }
4103}
4104
4105actionSlap(id)
4106{
4107 user_slap(id, 0);
4108 user_slap(id, 0);
4109 set_hudmessage(255, 255, 255, -1.0, 0.20, 0, 6.0, 12.0, 0.0, 1.0, 3);
4110
4111 show_hudmessage(id, "SLAPPED LIKE A BITCH!!!");
4112}
4113
4114actionRandom(id, ent)
4115{
4116 new Float:fTime = halflife_time();
4117
4118 //check if player is outside of cooldown time to use camouflage
4119 if (fTime >= gfRandomNextUse[id])
4120 {
4121 //get which type of block this is set to be
4122 new blockType = entity_get_int(ent, EV_INT_iuser4);
4123
4124 //do the random block action
4125 switch (blockType)
4126 {
4127 case BM_INVINCIBILITY: actionInvincible(id, true);
4128 case BM_STEALTH: actionStealth(id, true);
4129 case BM_CAMOUFLAGE: actionCamouflage(id, true);
4130 case BM_SLAP: actionSlap(id);
4131 case BM_BOOTSOFSPEED: actionBootsOfSpeed(id, true);
4132 case BM_AUTO_BHOP: actionAutoBhop(id, true);
4133
4134 case BM_DEAGLE: actionDeagle(id);
4135 case BM_AWP: actionAwp(id);
4136 case BM_FROST: actionFrost(id,true);
4137 case BM_FLASH: actionFlash(id,true);
4138 case BM_HE: actionHe(id,true);
4139 case BM_MONEY: actionMoney(id,true);
4140 case BM_USP: actionUsp(id);
4141 case BM_AK47: actionAk47(id);
4142 case BM_M4A1: actionM4a1(id);
4143 case BM_MP5: actionMp5(id);
4144 case BM_M3: actionM3(id);
4145 case BM_SCOUT: actionScout(id);
4146 }
4147
4148 //set timer to prevent player from using the random block again so soon
4149 gfRandomNextUse[id] = fTime + get_cvar_float("bm_randomcooldown");
4150
4151 //set this random block to another random block!
4152 new randNum = random_num(0, gRandomBlocksMax - 1);
4153 entity_set_int(ent, EV_INT_iuser4, gRandomBlocks[randNum]);
4154 }
4155 else
4156 {
4157 set_hudmessage(gHudRed, gHudGreen, gHudBlue, gfTextX, gfTextY, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
4158 show_hudmessage(id, "Random block next use: %.1f", gfRandomNextUse[id] - fTime);
4159 }
4160}
4161
4162actionHoney(id)
4163{
4164 new taskid = TASK_HONEY + id;
4165
4166 //make player feel like they're stuck in honey by lowering their maxspeed
4167 set_user_maxspeed(id, 50.0);
4168
4169 //remove any existing 'in honey' task
4170 if (task_exists(taskid))
4171 {
4172 remove_task(taskid);
4173 }
4174 else
4175 {
4176 //half the players velocity the first time they touch it
4177 new Float:vVelocity[3];
4178 entity_get_vector(id, EV_VEC_velocity, vVelocity);
4179 vVelocity[0] = vVelocity[0] / 2.0;
4180 vVelocity[1] = vVelocity[1] / 2.0;
4181 entity_set_vector(id, EV_VEC_velocity, vVelocity);
4182 }
4183
4184 //set task to remove 'in honey' effect very soon (task replaced if player is still in honey before task time reached)
4185 set_task(0.1, "taskNotInHoney", taskid);
4186}
4187
4188actionBootsOfSpeed(id, bool:OverrideTimer)
4189{
4190 new Float:fTime = halflife_time();
4191
4192 //check if player is outside of cooldown time to use the boots of speed
4193 if (fTime >= gfBootsOfSpeedNextUse[id] || OverrideTimer)
4194 {
4195 new Float:fTimeout = get_cvar_float("bm_bootsofspeedtime");
4196
4197 //set a task to remove the boots of speed after time out amount
4198 set_task(fTimeout, "taskBootsOfSpeedRemove", TASK_BOOTSOFSPEED + id, "", 0, "a", 1);
4199
4200 //set the players maxspeed to 400 so they run faster!
4201 set_user_maxspeed(id, gfBootsMaxSpeed);
4202
4203 //play boots of speed sound
4204 emit_sound(id, CHAN_STATIC, gszBootsOfSpeedSound, 1.0, ATTN_NORM, 0, PITCH_NORM);
4205
4206 gfBootsOfSpeedTimeOut[id] = fTime + fTimeout;
4207 gfBootsOfSpeedNextUse[id] = fTime + fTimeout + get_cvar_float("bm_bootsofspeedcooldown");
4208 }
4209 else
4210 {
4211 set_hudmessage(gHudRed, gHudGreen, gHudBlue, gfTextX, gfTextY, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
4212 show_hudmessage(id, "Boots of speed next use: %.1f", gfBootsOfSpeedNextUse[id] - fTime);
4213 }
4214}
4215
4216actionNoSlowDown(id)
4217{
4218 new taskid = TASK_NOSLOW + id;
4219
4220 gbNoSlowDown[id] = true;
4221
4222 //remove any existing 'slow down' task
4223 if (task_exists(taskid))
4224 {
4225 remove_task(taskid);
4226 }
4227
4228 //set task to remove 'no slow down' effect very soon
4229 set_task(0.1, "taskSlowDown", taskid);
4230}
4231
4232actionAutoBhop(id, bool:OverrideTimer)
4233{
4234 new Float:fTime = halflife_time();
4235
4236 //check if player is outside of cooldown time to use the auto bhop
4237 if (fTime >= gfAutoBhopNextUse[id] || OverrideTimer)
4238 {
4239 new Float:fTimeout = get_cvar_float("bm_autobhoptime");
4240
4241 //set a task to remove the auto bhop after time out amount
4242 set_task(fTimeout, "taskAutoBhopRemove", TASK_AUTOBHOP + id, "", 0, "a", 1);
4243
4244 //set autobhop boolean
4245 gbAutoBhop[id] = true;
4246
4247 //play boots of speed sound
4248 emit_sound(id, CHAN_STATIC, gszAutoBhopSound, 1.0, ATTN_NORM, 0, PITCH_NORM);
4249
4250 gfAutoBhopTimeOut[id] = fTime + fTimeout;
4251 gfAutoBhopNextUse[id] = fTime + fTimeout + get_cvar_float("bm_autobhopcooldown");
4252 }
4253 else
4254 {
4255 set_hudmessage(gHudRed, gHudGreen, gHudBlue, gfTextX, gfTextY, gHudEffects, gfHudFxTime, gfHudHoldTime, gfHudFadeInTime, gfHudFadeOutTime, gHudChannel);
4256 show_hudmessage(id, "Auto bunnyhop next use: %.1f", gfAutoBhopNextUse[id] - fTime);
4257 }
4258}
4259
4260actionTeleport(id, ent)
4261{
4262 //get end entity id
4263 new tele = entity_get_int(ent, EV_INT_iuser1);
4264
4265 //if teleport end id is valid
4266 if (tele)
4267 {
4268 //get end entity origin
4269 new Float:vTele[3];
4270 entity_get_vector(tele, EV_VEC_origin, vTele);
4271
4272 //if id of entity being teleported is a player and telefrags CVAR is set then kill any nearby players
4273 if ((id > 0 && id <= 32) && get_cvar_num("bm_telefrags") > 0)
4274 {
4275 new player = -1;
4276
4277 do
4278 {
4279 player = find_ent_in_sphere(player, vTele, 16.0);
4280
4281 //if entity found is a player
4282 if (player > 0 && player <= 32)
4283 {
4284 //if player is alive, and is not the player that went through the teleport
4285 if (is_user_alive(player) && player != id)
4286 {
4287 //kill the player
4288 user_kill(player, 1);
4289 }
4290 }
4291 }while(player);
4292 }
4293
4294 //get origin of the start of the teleport
4295 new Float:vOrigin[3];
4296 new origin[3];
4297 entity_get_vector(ent, EV_VEC_origin, vOrigin);
4298 FVecIVec(vOrigin, origin);
4299
4300 //show some teleporting effects
4301 message_begin(MSG_PVS, SVC_TEMPENTITY, origin);
4302 write_byte(TE_IMPLOSION);
4303 write_coord(origin[0]);
4304 write_coord(origin[1]);
4305 write_coord(origin[2]);
4306 write_byte(64); // radius
4307 write_byte(100); // count
4308 write_byte(6); // life
4309 message_end();
4310
4311 //teleport player
4312 entity_set_vector(id, EV_VEC_origin, vTele);
4313
4314 //reverse players Z velocity
4315 new Float:vVelocity[3];
4316 entity_get_vector(id, EV_VEC_velocity, vVelocity);
4317 vVelocity[2] = floatabs(vVelocity[2]);
4318 entity_set_vector(id, EV_VEC_velocity, vVelocity);
4319
4320 //if teleport sound CVAR is set
4321 if (get_cvar_num("bm_teleportsound") > 0)
4322 {
4323 //play teleport sound
4324 emit_sound(id, CHAN_STATIC, gszTeleportSound, 1.0, ATTN_NORM, 0, PITCH_NORM);
4325 }
4326 }
4327}
4328
4329actionTimer(id)
4330{
4331 new Float:origin[3];
4332 new Float:radius = 100.0;
4333 new ent = -1;
4334 new bool:bNearStart = false;
4335 new bool:bNearEnd = false;
4336
4337 //get players origin
4338 entity_get_vector(id, EV_VEC_origin, origin);
4339
4340 //find entities in a sphere around the player
4341 while ((ent = find_ent_in_sphere(ent, origin, radius)))
4342 {
4343 //if entity is a timer
4344 if (isTimer(ent))
4345 {
4346 //get what type of timer it is (start/end)
4347 new timerType = entity_get_int(ent, EV_INT_body);
4348
4349 switch (timerType)
4350 {
4351 case TIMER_START: bNearStart = true;
4352 case TIMER_END: bNearEnd = true;
4353 }
4354 }
4355 }
4356
4357 if (bNearStart && bNearEnd)
4358 {
4359 //start or stop timer depending on whether or not the player has a timer
4360 if (gbHasTimer[id])
4361 {
4362 timerStop(id);
4363 }
4364 else
4365 {
4366 timerStart(id);
4367 }
4368 }
4369 else if (bNearStart)
4370 {
4371 timerStart(id);
4372 }
4373 else if (bNearEnd)
4374 {
4375 timerStop(id);
4376 }
4377}
4378
4379public timerStart(id)
4380{
4381 //if player is alive
4382 if (is_user_alive(id))
4383 {
4384 //store the game time to calculate players time later
4385 gfTimerTime[id] = halflife_time();
4386
4387 //if player already had a timer
4388 if (gbHasTimer[id])
4389 {
4390 client_print(id, print_chat, "%sTimer Re-started.", gszPrefix);
4391 }
4392 else
4393 {
4394 gbHasTimer[id] = true;
4395
4396 client_print(id, print_chat, "%sTimer Started.", gszPrefix);
4397 }
4398 }
4399}
4400
4401public timerStop(id)
4402{
4403 if (gbHasTimer[id])
4404 {
4405 gbHasTimer[id] = false;
4406
4407 //get players name
4408 new szName[33];
4409 get_user_name(id, szName, 32);
4410
4411 //calculate players time in minutes and seconds
4412 new Float:fTime = halflife_time() - gfTimerTime[id];
4413 new Float:fMins = fTime / 60.0;
4414 new mins = floatround(fMins, floatround_floor);
4415 new Float:fSecs = (fMins - mins) * 60.0;
4416
4417 //format the players time into a string
4418 new szTime[17];
4419 format(szTime, 16, "%s%d:%s%.3f", (mins < 10 ? "0" : ""), mins, (fSecs < 10.0 ? "0" : ""), fSecs);
4420
4421 //announce the players time
4422 client_print(0, print_chat, "%s'%s' just completed the course in %s", gszPrefix, szName, szTime);
4423
4424 //player no longer has a timer
4425 gbHasTimer[id] = false;
4426
4427 //add players time to scoreboard
4428 timerCheckScoreboard(id, fTime);
4429 }
4430}
4431
4432public timerCheckScoreboard(id, Float:fTime)
4433{
4434 new szName[32], szSteamId[32];
4435
4436 //get players name, steam ID and time
4437 get_user_name(id, szName, 32);
4438 get_user_authid(id, szSteamId, 32);
4439 fTime = halflife_time() - gfTimerTime[id];
4440
4441 for (new i = 0; i < 15; i++)
4442 {
4443 //if the player was faster than a time on the scoreboard
4444 if (fTime < gfScoreTimes[i])
4445 {
4446 new pos = i;
4447
4448 //get position where the player is already on the scoreboard (if any)
4449 while (!equali(gszScoreSteamIds[pos], szSteamId) && pos < 14)
4450 {
4451 pos++;
4452 }
4453
4454 //shift scores down
4455 for (new j = pos; j > i; j--)
4456 {
4457 format(gszScoreSteamIds[j], 32, gszScoreSteamIds[j - 1]);
4458 format(gszScoreNames[j], 32, gszScoreNames[j - 1]);
4459 gfScoreTimes[j] = gfScoreTimes[j - 1];
4460 }
4461
4462 //put player onto the scoreboard
4463 format(gszScoreSteamIds[i], 32, szSteamId);
4464 format(gszScoreNames[i], 32, szName);
4465 gfScoreTimes[i] = fTime;
4466
4467 //if player got first place on the scoreboard
4468 if ((i + 1) == 1)
4469 {
4470 client_print(0, print_chat, "%s'%s' is now the fastest player on the course!", gszPrefix, szName);
4471 }
4472 else
4473 {
4474 client_print(0, print_chat, "%s'%s' is now rank %d on the scoreboard", gszPrefix, szName, (i + 1));
4475 }
4476
4477 break;
4478 }
4479
4480 //compare steam ID of player with steam ID on scoreboard
4481 if (equali(gszScoreSteamIds[i], szSteamId))
4482 {
4483 //break out of loop because player did not beat their old time
4484 break;
4485 }
4486 }
4487}
4488
4489public timerShowScoreboard(id)
4490{
4491 new szLine[128];
4492 new szMapName[32];
4493 new szConfigsDir[32];
4494 new szHostName[32];
4495 new i = 0, len = 0;
4496 new szTop15File[96];
4497 new szCSS[512];
4498 new szTime[16];
4499 new szName[33];
4500 new szBuffer[2048];
4501 new bufSize = sizeof(szBuffer) - 1;
4502
4503 get_mapname(szMapName, 31);
4504 get_configsdir(szConfigsDir, 31);
4505 get_cvar_string("hostname", szHostName, 31);
4506
4507 format(szTop15File, 96, "%s/blockmaker_scoreboard.css", szConfigsDir);
4508
4509 //get contents of CSS file
4510 getFileContents(szTop15File, szCSS);
4511
4512 len += format(szBuffer[len], bufSize-len, "<style>%s</style>", szCSS);
4513 len += format(szBuffer[len], bufSize-len, "<h1>%s</h1>", szMapName);
4514
4515 // ************* START OF TABLE **************
4516 len += format(szBuffer[len], bufSize-len, "<table><tr><th>#<th>Player<th>Time");
4517
4518 //iterate through the scoreboard
4519 for (i = 0; i < 15; i++)
4520 {
4521 //if top15 entry is blank
4522 if (gfScoreTimes[i] == 999999.9)
4523 {
4524 //create table row
4525 format(szLine, 127, "<tr><td>%d<td id=b><td id=c>", (i+1));
4526 }
4527 else
4528 {
4529 //make name HTML friendly
4530 htmlFriendly(szName);
4531
4532 //calculate players time in minutes and seconds
4533 new Float:fMins = (gfScoreTimes[i] / 60.0);
4534 new mins = floatround(fMins, floatround_floor);
4535 new Float:fSecs = (fMins - mins) * 60.0;
4536
4537 //format the players time into a string
4538 format(szTime, 16, "%s%d:%s%.3f", (mins < 10 ? "0" : ""), mins, (fSecs < 10.0 ? "0" : ""), fSecs);
4539
4540 //create table row
4541 format(szLine, 127, "<tr><td id=a>%d<td id=b>%s<td id=c>%s", (i+1), gszScoreNames[i], szTime);
4542 }
4543
4544 //append table row to szBuffer
4545 len += format(szBuffer[len], bufSize-len, szLine);
4546 }
4547 // ************** END OF TABLE ******************
4548
4549 new szTitle[64];
4550 format(szTitle, 63, "Top 15 Climbers - %s", szHostName);
4551 show_motd(id, szBuffer, szTitle);
4552
4553 return PLUGIN_HANDLED;
4554}
4555
4556/***** TASKS *****/
4557public taskSolidNot(ent)
4558{
4559 ent -= TASK_BHOPSOLIDNOT;
4560
4561 //make sure entity is valid
4562 if (is_valid_ent(ent))
4563 {
4564 //if block isn't being grabbed
4565 if (entity_get_int(ent, EV_INT_iuser2) == 0)
4566 {
4567 entity_set_int(ent, EV_INT_solid, SOLID_NOT);
4568 set_rendering(ent, kRenderFxNone, 255, 255, 255, kRenderTransAdd, 25);
4569 set_task(1.0, "taskSolid", TASK_BHOPSOLID + ent);
4570 }
4571 }
4572}
4573
4574public taskSolidNotFast(ent)
4575{
4576 ent -= TASK_BHOPSOLIDNOT;
4577
4578 //make sure entity is valid
4579 if (is_valid_ent(ent))
4580 {
4581 //if block isn't being grabbed
4582 if (entity_get_int(ent, EV_INT_iuser2) == 0)
4583 {
4584 entity_set_int(ent, EV_INT_solid, SOLID_NOT);
4585 set_rendering(ent, kRenderFxNone, 255, 255, 255, kRenderTransAdd, 25);
4586 set_task(0.1, "taskSolid", TASK_BHOPSOLID + ent);
4587 }
4588 }
4589}
4590
4591public taskSolidNotSemiFast(ent)
4592{
4593 ent -= TASK_BHOPSOLIDNOT;
4594
4595 //make sure entity is valid
4596 if (is_valid_ent(ent))
4597 {
4598 //if block isn't being grabbed
4599 if (entity_get_int(ent, EV_INT_iuser2) == 0)
4600 {
4601 entity_set_int(ent, EV_INT_solid, SOLID_NOT);
4602 set_rendering(ent, kRenderFxNone, 255, 255, 255, kRenderTransAdd, 25);
4603 set_task(0.4, "taskSolid", TASK_BHOPSOLID + ent);
4604 }
4605 }
4606}
4607
4608public taskSolidNotDelayed(ent)
4609{
4610 ent -= TASK_BHOPSOLIDNOT;
4611
4612 //make sure entity is valid
4613 if (is_valid_ent(ent))
4614 {
4615 //if block isn't being grabbed
4616 if (entity_get_int(ent, EV_INT_iuser2) == 0)
4617 {
4618 entity_set_int(ent, EV_INT_solid, SOLID_NOT);
4619 set_rendering(ent, kRenderFxNone, 255, 255, 255, kRenderTransAdd, 25);
4620 set_task(2.5, "taskSolid", TASK_BHOPSOLID + ent);
4621 }
4622 }
4623}
4624
4625public taskSolid(ent)
4626{
4627 ent -= TASK_BHOPSOLID;
4628
4629 //make sure entity is valid
4630 if (isBlock(ent))
4631 {
4632 //make block solid
4633 entity_set_int(ent, EV_INT_solid, SOLID_BBOX);
4634
4635 //get the player ID of who has the block in a group (if anyone)
4636 new player = entity_get_int(ent, EV_INT_iuser1);
4637
4638 //if the block is in a group
4639 if (player > 0)
4640 {
4641 //set the block so it is now 'being grouped' (for setting the rendering)
4642 groupBlock(0, ent);
4643 }
4644 else
4645 {
4646 new blockType = entity_get_int(ent, EV_INT_body);
4647
4648 set_block_rendering(ent, gRender[blockType], gRed[blockType], gGreen[blockType], gBlue[blockType], gAlpha[blockType]);
4649 }
4650 }
4651}
4652
4653public taskInvincibleRemove(id)
4654{
4655 id -= TASK_INVINCIBLE;
4656
4657 //make sure player is alive
4658 if (is_user_alive(id))
4659 {
4660 set_user_godmode(id, 0);
4661
4662 //only set players rendering back to normal if player is not stealth
4663 if (halflife_time() >= gfStealthTimeOut[id])
4664 {
4665 set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderNormal, 16);
4666 }
4667 }
4668}
4669
4670public taskSpawnProtectRemove(id)
4671{
4672 //id -= TASK_INVINCIBLE;
4673
4674 //make sure player is alive
4675 if (is_user_alive(id))
4676 {
4677 set_user_godmode(id, 0);
4678 set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderNormal, 16);
4679 }
4680
4681}
4682
4683
4684public taskStealthRemove(id)
4685{
4686 id -= TASK_STEALTH;
4687
4688 //make sure player is connected
4689 if (is_user_connected(id))
4690 {
4691 //only set players rendering back to normal if player is not invincible
4692 if (halflife_time() >= gfInvincibleTimeOut[id])
4693 {
4694 set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderNormal, 255);
4695 }
4696 else //if player is invincible then set player to glow white
4697 {
4698 set_user_rendering(id, kRenderFxGlowShell, 255, 255, 255, kRenderTransColor, 16);
4699 }
4700 }
4701}
4702
4703public taskNotOnIce(id)
4704{
4705 id -= TASK_ICE;
4706
4707 //make player run normally
4708 entity_set_float(id, EV_FL_friction, 1.0);
4709
4710 if (gfOldMaxSpeed[id] > 100.0)
4711 {
4712 set_user_maxspeed(id, gfOldMaxSpeed[id]);
4713 }
4714 else
4715 {
4716 set_user_maxspeed(id, 250.0);
4717 }
4718
4719 //no longer 'on ice'
4720 gbOnIce[id] = false;
4721 gfOldMaxSpeed[id] = 0.0;
4722}
4723
4724public taskCamouflageRemove(id)
4725{
4726 id -= TASK_CAMOUFLAGE;
4727
4728 //if player is still connected
4729 if (is_user_connected(id))
4730 {
4731 //change back to players old model
4732 cs_set_user_model(id, gszCamouflageOldModel[id]);
4733 }
4734}
4735
4736public taskNotInHoney(id)
4737{
4738 id -= TASK_HONEY;
4739
4740 //if player is alive
4741 if (is_user_alive(id))
4742 {
4743 //make player move normally
4744 set_user_maxspeed(id, 250.0);
4745
4746 //this will set the players maxspeed faster if they have the boots of speed!
4747 eventCurWeapon(id);
4748 }
4749}
4750
4751public taskBootsOfSpeedRemove(id)
4752{
4753 id -= TASK_BOOTSOFSPEED;
4754
4755 //set players speed back to normal
4756 if (is_user_alive(id))
4757 {
4758 set_user_maxspeed(id, 250.0);
4759 }
4760}
4761
4762public taskSlowDown(id)
4763{
4764 id -= TASK_NOSLOW;
4765
4766 //player no longer has 'no slow down'
4767 gbNoSlowDown[id] = false;
4768}
4769
4770public taskAutoBhopRemove(id)
4771{
4772 id -= TASK_AUTOBHOP;
4773
4774 //player no long has 'auto bhop'
4775 gbAutoBhop[id] = false;
4776}
4777
4778public taskSpriteNextFrame(params[])
4779{
4780 new ent = params[0];
4781
4782 //make sure entity is valid
4783 if (is_valid_ent(ent))
4784 {
4785 new frames = params[1];
4786 new Float:current_frame = entity_get_float(ent, EV_FL_frame);
4787
4788 if (current_frame < 0.0 || current_frame >= frames)
4789 {
4790 entity_set_float(ent, EV_FL_frame, 1.0);
4791 }
4792 else
4793 {
4794 entity_set_float(ent, EV_FL_frame, current_frame + 1.0);
4795 }
4796 }
4797 else
4798 {
4799 remove_task(TASK_SPRITE + ent);
4800 }
4801}
4802
4803/***** COMMANDS *****/
4804public cmdJump(id)
4805{
4806 //if the object the player is grabbing isn't too close
4807 if (gfGrablength[id] > 72.0)
4808 {
4809 //move the object closer
4810 gfGrablength[id] -= 16.0;
4811 }
4812}
4813
4814public cmdDuck(id)
4815{
4816 //move the object further away
4817 gfGrablength[id] += 16.0;
4818}
4819
4820public cmdAttack(id)
4821{
4822 //if entity being grabbed is a block
4823 if (isBlock(gGrabbed[id]))
4824 {
4825 //if block the player is grabbing is in their group and group count is larger than 1
4826 if (isBlockInGroup(id, gGrabbed[id]) && gGroupCount[id] > 1)
4827 {
4828 new block;
4829
4830 //move the rest of the blocks in the players group using vector for grabbed block
4831 for (new i = 0; i <= gGroupCount[id]; ++i)
4832 {
4833 block = gGroupedBlocks[id][i];
4834
4835 //if this block is in this players group
4836 if (isBlockInGroup(id, block))
4837 {
4838 //only copy the block if it is not stuck
4839 if (!isBlockStuck(block))
4840 {
4841 //copy the block
4842 copyBlock(id,block);
4843 }
4844 }
4845 }
4846 }
4847 else
4848 {
4849 //only copy the block the player has grabbed if it is not stuck
4850 if (!isBlockStuck(gGrabbed[id]))
4851 {
4852 //copy the block
4853 new newBlock = copyBlock(id, gGrabbed[id]);
4854
4855 //if new block was created successfully
4856 if (newBlock)
4857 {
4858 //set currently grabbed block to 'not being grabbed'
4859 entity_set_int(gGrabbed[id], EV_INT_iuser2, 0);
4860
4861 //set new block to 'being grabbed'
4862 entity_set_int(newBlock, EV_INT_iuser2, id);
4863
4864 //set player to grabbing new block
4865 gGrabbed[id] = newBlock;
4866 }
4867 }
4868 else
4869 {
4870 //tell the player they can't copy a block when it is in a stuck position
4871 client_print(id, print_chat, "%sYou cannot copy a block that is in a stuck position!", gszPrefix);
4872 }
4873 }
4874 }
4875}
4876
4877public cmdAttack2(id)
4878{
4879 //if player is grabbing a block
4880 if (isBlock(gGrabbed[id]))
4881 {
4882 //if block the player is grabbing is in their group and group count is larger than 1
4883 if (isBlockInGroup(id, gGrabbed[id]) && gGroupCount[id] > 1)
4884 {
4885 new block;
4886
4887 //iterate through all blocks in the players group
4888 for (new i = 0; i <= gGroupCount[id]; ++i)
4889 {
4890 block = gGroupedBlocks[id][i];
4891
4892 //if block is still valid
4893 if (is_valid_ent(block))
4894 {
4895 //if block is still in this players group
4896 if (isBlockInGroup(id, block))
4897 {
4898 //delete the block
4899 gbJustDeleted[id] = deleteBlock(block);
4900 }
4901 }
4902 }
4903 }
4904 else
4905 {
4906 //delete the block
4907 gbJustDeleted[id] = deleteBlock(gGrabbed[id]);
4908 }
4909 }
4910 //if player is grabbing a teleport
4911 else if (isTeleport(gGrabbed[id]))
4912 {
4913 //delete the teleport
4914 gbJustDeleted[id] = deleteTeleport(id, gGrabbed[id]);
4915 }
4916 //if player is grabbing a timer
4917 else if (isTimer(gGrabbed[id]))
4918 {
4919 //delete the timer
4920 gbJustDeleted[id] = deleteTimer(gGrabbed[id]);
4921 }
4922}
4923
4924public cmdGrab(id)
4925{
4926 //make sure player has access to use this command
4927 if (get_user_flags(id) & BM_ADMIN_LEVEL)
4928 {
4929 //get the entity the player is aiming at and the length
4930 new ent, body;
4931 gfGrablength[id] = get_user_aiming(id, ent, body);
4932
4933 //set booleans depending on entity type
4934 new bool:bIsBlock = isBlock(ent);
4935 new bool:bIsTeleport = isTeleport(ent);
4936 new bool:bIsTimer = isTimer(ent);
4937
4938 //if the entity is a block or teleport
4939 if (bIsBlock || bIsTeleport || bIsTimer)
4940 {
4941 //get who is currently grabbing the entity (if anyone)
4942 new grabber = entity_get_int(ent, EV_INT_iuser2);
4943
4944 //if entity is not being grabbed by someone else
4945 if (grabber == 0 || grabber == id)
4946 {
4947 //if entity is a block
4948 if (bIsBlock)
4949 {
4950 //get the player ID of who has the block in a group (if anyone)
4951 new player = entity_get_int(ent, EV_INT_iuser1);
4952
4953 //if the block is not in a group or is in this players group
4954 if (player == 0 || player == id)
4955 {
4956 //set the block to 'being grabbed'
4957 setGrabbed(id, ent);
4958
4959 //if this block is in this players group and group count is greater than 1
4960 if (player == id && gGroupCount[id] > 1)
4961 {
4962 new Float:vGrabbedOrigin[3];
4963 new Float:vOrigin[3];
4964 new Float:vOffset[3];
4965 new block;
4966
4967 //get origin of the block
4968 entity_get_vector(ent, EV_VEC_origin, vGrabbedOrigin);
4969
4970 //iterate through all blocks in players group
4971 for (new i = 0; i <= gGroupCount[id]; ++i)
4972 {
4973 block = gGroupedBlocks[id][i];
4974
4975 //if block is still valid
4976 if (is_valid_ent(block))
4977 {
4978 player = entity_get_int(ent, EV_INT_iuser1);
4979
4980 //if block is still in this players group
4981 if (player == id)
4982 {
4983 //get origin of block in players group
4984 entity_get_vector(block, EV_VEC_origin, vOrigin);
4985
4986 //calculate offset from grabbed block
4987 vOffset[0] = vGrabbedOrigin[0] - vOrigin[0];
4988 vOffset[1] = vGrabbedOrigin[1] - vOrigin[1];
4989 vOffset[2] = vGrabbedOrigin[2] - vOrigin[2];
4990
4991 //save offset value in grouped block
4992 entity_set_vector(block, EV_VEC_vuser1, vOffset);
4993
4994 //indicate that entity is being grabbed
4995 entity_set_int(block, EV_INT_iuser2, id);
4996 }
4997 }
4998 }
4999 }
5000 }
5001 }
5002 //if entity is a teleporter
5003 else if (bIsTeleport)
5004 {
5005 //set the teleport to 'being grabbed'
5006 setGrabbed(id, ent);
5007 }
5008 //if entity is a timer
5009 else if (bIsTimer)
5010 {
5011 //set the timer to 'being grabbed'
5012 setGrabbed(id, ent);
5013 }
5014 }
5015 }
5016 }
5017
5018 return PLUGIN_HANDLED;
5019}
5020
5021setGrabbed(id, ent)
5022{
5023 new Float:fpOrigin[3];
5024 new Float:fbOrigin[3];
5025 new Float:fAiming[3];
5026 new iAiming[3];
5027 new bOrigin[3];
5028
5029 //get players current view model then clear it
5030 entity_get_string(id, EV_SZ_viewmodel, gszViewModel[id], 32);
5031 entity_set_string(id, EV_SZ_viewmodel, "");
5032
5033 get_user_origin(id, bOrigin, 1); //position from eyes (weapon aiming)
5034 get_user_origin(id, iAiming, 3); //end position from eyes (hit point for weapon)
5035 entity_get_vector(id, EV_VEC_origin, fpOrigin); //get player position
5036 entity_get_vector(ent, EV_VEC_origin, fbOrigin); //get block position
5037 IVecFVec(iAiming, fAiming);
5038 FVecIVec(fbOrigin, bOrigin);
5039
5040 //set gGrabbed
5041 gGrabbed[id] = ent;
5042 gvGrabOffset[id][0] = fbOrigin[0] - iAiming[0];
5043 gvGrabOffset[id][1] = fbOrigin[1] - iAiming[1];
5044 gvGrabOffset[id][2] = fbOrigin[2] - iAiming[2];
5045
5046 //indicate that entity is being grabbed
5047 entity_set_int(ent, EV_INT_iuser2, id);
5048}
5049
5050public cmdRelease(id)
5051{
5052 //make sure player has access to use this command
5053 if (get_user_flags(id) & BM_ADMIN_LEVEL)
5054 {
5055 //if player is grabbing an entity
5056 if (gGrabbed[id])
5057 {
5058 //if entity player is grabbing is a block
5059 if (isBlock(gGrabbed[id]))
5060 {
5061 //if block the player is grabbing is in their group and group count is > 1
5062 if (isBlockInGroup(id, gGrabbed[id]) && gGroupCount[id] > 1)
5063 {
5064 new block;
5065 new bool:bGroupIsStuck = true;
5066
5067 //iterate through all blocks in the players group
5068 for (new i = 0; i <= gGroupCount[id]; ++i)
5069 {
5070 block = gGroupedBlocks[id][i];
5071
5072 //if this block is in this players group
5073 if (isBlockInGroup(id, block))
5074 {
5075 //indicate that entity is no longer being grabbed
5076 entity_set_int(block, EV_INT_iuser2, 0);
5077
5078 //start off thinking all blocks in group are stuck
5079 if (bGroupIsStuck)
5080 {
5081 //if block is not stuck
5082 if (!isBlockStuck(block))
5083 {
5084 //at least one of the blocks in the group are not stuck
5085 bGroupIsStuck = false;
5086 }
5087 }
5088 }
5089 }
5090
5091 //if all the blocks in the group are stuck
5092 if (bGroupIsStuck)
5093 {
5094 //iterate through all blocks in the players group
5095 for (new i = 0; i <= gGroupCount[id]; ++i)
5096 {
5097 block = gGroupedBlocks[id][i];
5098
5099 //if this block is in this players group
5100 if (isBlockInGroup(id, block))
5101 {
5102 //delete the block
5103 deleteBlock(block);
5104 }
5105 }
5106
5107 //tell the player all the blocks were deleted because they were stuck
5108 client_print(id, print_chat, "%sGroup deleted because all the blocks were stuck!", gszPrefix);
5109 }
5110 }
5111 else
5112 {
5113 //if block player has grabbed is valid
5114 if (is_valid_ent(gGrabbed[id]))
5115 {
5116 //if the block is stuck
5117 if (isBlockStuck(gGrabbed[id]))
5118 {
5119 //delete the block
5120 new bool:bDeleted = deleteBlock(gGrabbed[id]);
5121
5122 //if the block was deleted successfully
5123 if (bDeleted)
5124 {
5125 //tell the player the block was deleted and why
5126 client_print(id, print_chat, "%sBlock deleted because it was stuck!", gszPrefix);
5127 }
5128 }
5129 else
5130 {
5131 //indicate that the block is no longer being grabbed
5132 entity_set_int(gGrabbed[id], EV_INT_iuser2, 0);
5133 }
5134 }
5135 }
5136 }
5137 else if (isTeleport(gGrabbed[id]))
5138 {
5139 //indicate that the teleport is no longer being grabbed
5140 entity_set_int(gGrabbed[id], EV_INT_iuser2, 0);
5141 }
5142 else if (isTimer(gGrabbed[id]))
5143 {
5144 //indicate that the timer is no longer being grabbed
5145 entity_set_int(gGrabbed[id], EV_INT_iuser2, 0);
5146 }
5147
5148 //set the players view model back to what it was
5149 entity_set_string(id, EV_SZ_viewmodel, gszViewModel[id]);
5150
5151 //indicate that player is not grabbing an object
5152 gGrabbed[id] = 0;
5153 }
5154 }
5155
5156 return PLUGIN_HANDLED;
5157}
5158
5159/* MENUS */
5160public showMainMenu(id)
5161{
5162 new col[3];
5163 new szMenu[256];
5164 new szGodmode[6];
5165 new szNoclip[6];
5166 col = (get_user_flags(id) & BM_ADMIN_LEVEL ? "w" : "d");
5167 szNoclip = (get_user_noclip(id) ? "yOn" : "rOff");
5168 szGodmode = (get_user_godmode(id) ? "yOn" : "rOff");
5169
5170 //format the main menu
5171 format(szMenu, 256, gszMainMenu, col, szNoclip, col, szGodmode);
5172
5173 //show the main menu to the player
5174 show_menu(id, gKeysMainMenu, szMenu, -1, "bmMainMenu");
5175
5176 return PLUGIN_HANDLED;
5177}
5178
5179showBlockMenu(id)
5180{
5181 new col[3];
5182 new szMenu[256];
5183 new szGodmode[6];
5184 new szNoclip[6];
5185 new szSize[8];
5186 col = (get_user_flags(id) & BM_ADMIN_LEVEL ? "w" : "d");
5187 szNoclip = (get_user_noclip(id) ? "yOn" : "rOff");
5188 szGodmode = (get_user_godmode(id) ? "yOn" : "rOff");
5189
5190 switch (gBlockSize[id])
5191 {
5192 case SMALL: szSize = "Small";
5193 case NORMAL: szSize = "Normal";
5194 case LARGE: szSize = "Large";
5195 case ELARGE: szSize = "ELarg";
5196 case JUMBO: szSize = "Jumbo";
5197 case POLE: szSize = "Pole";
5198 }
5199
5200 //format the main menu
5201 format(szMenu, 256, gszBlockMenu, gszBlockNames[gSelectedBlockType[id]], col, col, col, col, col, szNoclip, col, szGodmode, szSize);
5202
5203 //show the block menu to the player
5204 show_menu(id, gKeysBlockMenu, szMenu, -1, "bmBlockMenu");
5205
5206 return PLUGIN_HANDLED;
5207}
5208
5209showBlockSelectionMenu(id)
5210{
5211 //create block selection menu 1 (first 8 blocks)
5212 new szBlockMenu[256];
5213 new szTitle[32];
5214 new szEntry[32];
5215 new num;
5216 new startBlock;
5217
5218 //format the page number into the menu title
5219 format(szTitle, sizeof(szTitle), "yBlock Selection %d^n^n", gBlockMenuPage[id]);
5220
5221 //add the title to the menu
5222 add(szBlockMenu, sizeof(szBlockMenu), szTitle);
5223
5224 //calculate the block that the menu will start on
5225 startBlock = (gBlockMenuPage[id] - 1) * 8;
5226
5227 //iterate through 8 blocks to add to the menu
5228 for (new i = startBlock; i < startBlock + 8; ++i)
5229 {
5230 //make sure the loop doesn't go above the maximum number of blocks
5231 if (i < gBlockMax)
5232 {
5233 //calculate the menu item number
5234 num = (i - startBlock) + 1;
5235
5236 //format the block name into the menu entry
5237 format(szEntry, sizeof(szEntry), "r%d. w%s^n", num, gszBlockNames[i]);
5238 }
5239 else
5240 {
5241 //format a blank menu entry
5242 format(szEntry, sizeof(szEntry), "^n");
5243 }
5244
5245 //add the entry to the menu
5246 add(szBlockMenu, sizeof(szBlockMenu), szEntry);
5247 }
5248
5249 //if the block selection page the player is on is less than the maximum page
5250 if (gBlockMenuPage[id] < gBlockMenuPagesMax)
5251 {
5252 add(szBlockMenu, sizeof(szBlockMenu), "^nr9. wMore");
5253 }
5254 else
5255 {
5256 add(szBlockMenu, sizeof(szBlockMenu), "^n");
5257 }
5258
5259 //add a back option to the menu
5260 add(szBlockMenu, sizeof(szBlockMenu), "^nr0. wBack");
5261
5262 //display the block selection menu
5263 show_menu(id, gKeysBlockSelectionMenu, szBlockMenu, -1, "bmBlockSelectionMenu");
5264}
5265
5266showTeleportMenu(id)
5267{
5268 new col[3];
5269 new szMenu[256];
5270 new szGodmode[6];
5271 new szNoclip[6];
5272 col = (get_user_flags(id) & BM_ADMIN_LEVEL ? "w" : "d");
5273 szNoclip = (get_user_noclip(id) ? "yOn" : "rOff");
5274 szGodmode = (get_user_godmode(id) ? "yOn" : "rOff");
5275
5276 //format teleport menu
5277 format(szMenu, sizeof(szMenu), gszTeleportMenu, col, (gTeleportStart[id] ? "w" : "d"), col, col, col, col, szNoclip, col, szGodmode);
5278
5279 show_menu(id, gKeysTeleportMenu, szMenu, -1, "bmTeleportMenu");
5280}
5281
5282showTimerMenu(id)
5283{
5284 new col[3];
5285 new szMenu[256];
5286 new szGodmode[6];
5287 new szNoclip[6];
5288 col = (get_user_flags(id) & BM_ADMIN_LEVEL ? "w" : "d");
5289 szNoclip = (get_user_noclip(id) ? "yOn" : "rOff");
5290 szGodmode = (get_user_godmode(id) ? "yOn" : "rOff");
5291
5292 //format timer menu
5293 format(szMenu, sizeof(szMenu), gszTimerMenu, col, (gStartTimer[id] ? "w" : "d"), col, col, col, col, szNoclip, col, szGodmode);
5294
5295 show_menu(id, gKeysTimerMenu, szMenu, -1, "bmTimerMenu");
5296}
5297
5298showMeasureMenu(id)
5299{
5300 new col[3];
5301 new szMenu[512];
5302 new szGodmode[6];
5303 new szNoclip[6];
5304 new szBlock1[40];
5305 new szBlock2[40];
5306 new szMeasureTool[16];
5307
5308 col = (get_user_flags(id) & BM_ADMIN_LEVEL ? "w" : "d");
5309
5310 //if players measuring block 1 is valid
5311 if (is_valid_ent(gMeasureToolBlock1[id]))
5312 {
5313 //add entity id to the start of the string followed by a hyphon seperator
5314 num_to_str(gMeasureToolBlock1[id], szBlock1, 40);
5315 add(szBlock1, 40, " - ");
5316
5317 //if entity is a block
5318 if (isBlock(gMeasureToolBlock1[id]))
5319 {
5320 new blockType = entity_get_int(gMeasureToolBlock1[id], EV_INT_body);
5321 add(szBlock1, 40, gszBlockNames[blockType]);
5322 }
5323 else if (isTimer(gMeasureToolBlock1[id]))
5324 {
5325 //get what type of timer it is (start/end)
5326 new timerType = entity_get_int(gMeasureToolBlock1[id], EV_INT_body);
5327
5328 switch (timerType)
5329 {
5330 case TIMER_START: add(szBlock1, 40, "Timer Start");
5331 case TIMER_END: add(szBlock1, 40, "Timer End");
5332 }
5333 }
5334 }
5335 else
5336 {
5337 szBlock1 = "rNone";
5338 }
5339
5340 //if players measuring block 2 is valid
5341 if (is_valid_ent(gMeasureToolBlock2[id]))
5342 {
5343 //add entity id to the start of the string followed by a hyphon seperator
5344 num_to_str(gMeasureToolBlock2[id], szBlock2, 40);
5345 add(szBlock2, 40, " - ");
5346
5347 //if entity is a block
5348 if (isBlock(gMeasureToolBlock2[id]))
5349 {
5350 new blockType = entity_get_int(gMeasureToolBlock2[id], EV_INT_body);
5351 add(szBlock2, 40, gszBlockNames[blockType]);
5352 }
5353 else if (isTimer(gMeasureToolBlock2[id]))
5354 {
5355 //get what type of timer it is (start/end)
5356 new timerType = entity_get_int(gMeasureToolBlock2[id], EV_INT_body);
5357
5358 switch (timerType)
5359 {
5360 case TIMER_START: add(szBlock2, 40, "Timer Start");
5361 case TIMER_END: add(szBlock2, 40, "Timer Stop");
5362 }
5363 }
5364 }
5365 else
5366 {
5367 szBlock2 = "rNone";
5368 }
5369
5370 szMeasureTool = (gbMeasureToolEnabled[id] ? "yOn" : "rOff");
5371 szNoclip = (get_user_noclip(id) ? "yOn" : "rOff");
5372 szGodmode = (get_user_godmode(id) ? "yOn" : "rOff");
5373
5374 //format measure menu
5375 format(szMenu, sizeof(szMenu), gszMeasureMenu, szBlock1, szBlock2, gvMeasureToolPos1[id][0], gvMeasureToolPos1[id][1], gvMeasureToolPos1[id][2], gvMeasureToolPos2[id][0], gvMeasureToolPos2[id][1], gvMeasureToolPos2[id][2], col, szMeasureTool, col, szNoclip, col, szGodmode);
5376
5377 //show the measure menu to the player
5378 show_menu(id, gKeysMeasureMenu, szMenu, -1, "bmMeasureMenu");
5379}
5380
5381showLongJumpMenu(id)
5382{
5383 new col[3];
5384 new szMenu[256];
5385 new szGodmode[6];
5386 new szNoclip[6];
5387 new szSize[8];
5388
5389 col = (get_user_flags(id) & BM_ADMIN_LEVEL ? "w" : "d");
5390 szNoclip = (get_user_noclip(id) ? "yOn" : "rOff");
5391 szGodmode = (get_user_godmode(id) ? "yOn" : "rOff");
5392
5393 switch (gBlockSize[id])
5394 {
5395 case SMALL: szSize = "Small";
5396 case NORMAL: szSize = "Normal";
5397 case LARGE: szSize = "Large";
5398 case ELARGE: szSize = "ELarg";
5399 case JUMBO: szSize = "Jumbo";
5400 case POLE: szSize = "Poles";
5401 }
5402
5403 //format the long jump menu
5404 format(szMenu, sizeof(szMenu), gszLongJumpMenu, col, gLongJumpDistance[id], col, (gLongJumpAxis[id] == X ? "X" : "Y"), col, col, col, szNoclip, col, szGodmode, szSize);
5405
5406 //show the long jump menu to the player
5407 show_menu(id, gKeysLongJumpMenu, szMenu, -1, "bmLongJumpMenu");
5408}
5409
5410showOptionsMenu(id, oldMenu)
5411{
5412 //set the oldmenu global variable so when the back key is pressed it goes back to the previous menu
5413 gMenuBeforeOptions[id] = oldMenu;
5414
5415 new col[3];
5416 new szSnapping[6];
5417 new szMenu[256];
5418 col = (get_user_flags(id) & BM_ADMIN_LEVEL ? "w" : "d");
5419 szSnapping = (gbSnapping[id] ? "yOn" : "rOff");
5420
5421 //format the options menu
5422 format(szMenu, sizeof(szMenu), gszOptionsMenu, col, szSnapping, col, gfSnappingGap[id], col, col, col, col, col, col);
5423
5424 //show the options menu to the player
5425 show_menu(id, gKeysOptionsMenu, szMenu, -1, "bmOptionsMenu");
5426}
5427showTextMenu(id)
5428{
5429 hns_print(id, "^x03Join The^x04 [AxaGame_BM].HnS ^x03Server by Typing ^x04/server ^x03or visit ^x04 90.224.114.77:27015");
5430}
5431showTextMenuTwo(id)
5432{
5433 hns_print(id, "^x04This Server Is Running ^x03[AxaGame_BM].HnS ^x04Kivinen's Course Maker 5.0 ^x03by ^x04Kivinen");
5434}
5435hns_print(plr, const sFormat[], any:...)
5436{
5437 static i; i = plr ? plr : get_player();
5438 if( !i )
5439 {
5440 return 0;
5441 }
5442
5443 new sPrefix[16] = "[AxaGame_BM].HnS";
5444 //get_pcvar_string(hns_prefix, sPrefix, 15);
5445
5446 new sMessage[256];
5447 new len = formatex(sMessage, 255, "^x04%s^x01 ", sPrefix);
5448 vformat(sMessage[len], 255-len, sFormat, 3);
5449 sMessage[192] = '^0';
5450
5451 make_SayText(plr, i, sMessage);
5452
5453 return 1;
5454}
5455make_SayText(receiver, sender, sMessage[])
5456{
5457 if( !sender )
5458 {
5459 return 0;
5460 }
5461
5462 message_begin(receiver ? MSG_ONE : MSG_ALL, g_msgSayText, {0, 0, 0}, receiver);
5463 write_byte(sender);
5464 write_string(sMessage);
5465 message_end();
5466
5467 return 1;
5468}
5469get_player()
5470{
5471 for( new plr = 1; plr <= 32; plr++ )
5472 {
5473 if( is_user_connected(plr) )
5474 {
5475 return plr;
5476 }
5477 }
5478
5479 return 0;
5480}
5481showChoiceMenu(id, gChoice, const szTitle[96])
5482{
5483 gChoiceOption[id] = gChoice;
5484
5485 //format choice menu using given title
5486 new szMenu[128];
5487 format(szMenu, sizeof(szMenu), gszChoiceMenu, szTitle);
5488
5489 //show the choice menu to the player
5490 show_menu(id, gKeysChoiceMenu, szMenu, -1, "bmChoiceMenu");
5491}
5492
5493public handlePluginInfo(plr)
5494{
5495 showTextMenu(plr);
5496
5497 return PLUGIN_CONTINUE;
5498}
5499
5500public handleMainMenu(id, num)
5501{
5502 switch (num)
5503 {
5504 case N1: { showBlockMenu(id); }
5505 case N2: { showTeleportMenu(id); }
5506 case N3: { showTimerMenu(id); }
5507 case N4: { showMeasureMenu(id); }
5508 case N5: { showLongJumpMenu(id); }
5509 case N6: { toggleNoclip(id); }
5510 case N7: { toggleGodmode(id); }
5511 case N9: { showOptionsMenu(id, 1); }
5512 case N0: { return; }
5513 }
5514
5515 //selections 1, 2, 3, 4, 5 and 9 show different menus
5516 if (num != N1 && num != N2 && num != N3 && num != N4 && num!= N5 && num != N9)
5517 {
5518 //display menu again
5519 showMainMenu(id);
5520 }
5521}
5522
5523public handleBlockMenu(id, num)
5524{
5525 switch (num)
5526 {
5527 case N1: { showBlockSelectionMenu(id); }
5528 case N2: { createBlockAiming(id, gSelectedBlockType[id]); }
5529 case N3: { convertBlockAiming(id, gSelectedBlockType[id]); }
5530 case N4: { deleteBlockAiming(id); }
5531 case N5: { rotateBlockAiming(id); }
5532 case N6: { toggleNoclip(id); }
5533 case N7: { toggleGodmode(id); }
5534 case N8: { changeBlockSize(id); }
5535 case N9: { showOptionsMenu(id, 2); }
5536 case N0: { showMainMenu(id); }
5537 }
5538
5539 //selections 1, 9 and 0 show different menus
5540 if (num != N1 && num != N9 && num != N0)
5541 {
5542 //display menu again
5543 showBlockMenu(id);
5544 }
5545}
5546
5547public handleBlockSelectionMenu(id, num)
5548{
5549 switch (num)
5550 {
5551 case N9:
5552 {
5553 //goto next block selection menu page
5554 ++gBlockMenuPage[id];
5555
5556 //make sure the player can't go above the maximum block selection page
5557 if (gBlockMenuPage[id] > gBlockMenuPagesMax)
5558 {
5559 gBlockMenuPage[id] = gBlockMenuPagesMax;
5560 }
5561
5562 //show block selection menu again
5563 showBlockSelectionMenu(id);
5564 }
5565
5566 case N0:
5567 {
5568 //goto previous block selection menu page
5569 --gBlockMenuPage[id];
5570
5571 //show block menu if player goes back too far
5572 if (gBlockMenuPage[id] < 1)
5573 {
5574 showBlockMenu(id);
5575 gBlockMenuPage[id] = 1;
5576 }
5577 else
5578 {
5579 //show block selection menu again
5580 showBlockSelectionMenu(id);
5581 }
5582 }
5583
5584 default:
5585 {
5586 //offset the num value using the players block selection page number
5587 num += (gBlockMenuPage[id] - 1) * 8;
5588
5589 //if block number is within range
5590 if (num < gBlockMax)
5591 {
5592 gSelectedBlockType[id] = num;
5593 showBlockMenu(id);
5594 }
5595 else
5596 {
5597 showBlockSelectionMenu(id);
5598 }
5599 }
5600 }
5601}
5602
5603public handleTeleportMenu(id, num)
5604{
5605 switch (num)
5606 {
5607 case N1: { createTeleportAiming(id, TELEPORT_START); }
5608 case N2: { createTeleportAiming(id, TELEPORT_END); }
5609 case N3: { swapTeleportAiming(id); }
5610 case N4: { deleteTeleportAiming(id); }
5611 case N5: { showTeleportPath(id); }
5612 case N6: { toggleNoclip(id); }
5613 case N7: { toggleGodmode(id); }
5614 case N9: { showOptionsMenu(id, 3); }
5615 case N0: { showMainMenu(id); }
5616 }
5617
5618 //selections 9 and 0 show different menus
5619 if (num != N9 && num != N0)
5620 {
5621 showTeleportMenu(id);
5622 }
5623}
5624
5625public handleTimerMenu(id, num)
5626{
5627 switch (num)
5628 {
5629 case N1: { createTimerAiming(id, TIMER_START); }
5630 case N2: { createTimerAiming(id, TIMER_END); }
5631 case N3: { swapTimerAiming(id); }
5632 case N4: { deleteTimerAiming(id); }
5633 case N5: { rotateTimerAiming(id); }
5634 case N6: { toggleNoclip(id); }
5635 case N7: { toggleGodmode(id); }
5636 case N9: { showOptionsMenu(id, 4); }
5637 case N0: { showMainMenu(id); }
5638 }
5639
5640 //selections 9 and 0 show different menus
5641 if (num != N9 && num != N0)
5642 {
5643 showTimerMenu(id);
5644 }
5645}
5646
5647public handleMeasureMenu(id, num)
5648{
5649 switch (num)
5650 {
5651 case N1: { measureToolSelectBlock(id, 1); }
5652 case N2: { measureToolSelectBlock(id, 2); }
5653 case N3: { measureToolSelectPos(id, 1); }
5654 case N4: { measureToolSelectPos(id, 2); }
5655 case N5: { toggleMeasureTool(id); }
5656 case N6: { toggleNoclip(id); }
5657 case N7: { toggleGodmode(id); }
5658 case N9: { showOptionsMenu(id, 5); }
5659 case N0: { showMainMenu(id); }
5660 }
5661
5662 //selections 9 and 0 show different menus
5663 if (num != N9 && num != N0)
5664 {
5665 showMeasureMenu(id);
5666 }
5667}
5668
5669public handleLongJumpMenu(id, num)
5670{
5671 switch (num)
5672 {
5673 case N1: { longJumpDistance(id, 1); }
5674 case N2: { longJumpCreate(id); }
5675 case N3: { longJumpDistance(id, 2); }
5676 case N4: { deleteBlockAiming(id); }
5677 case N5: { longJumpRotate(id); }
5678 case N6: { toggleNoclip(id); }
5679 case N7: { toggleGodmode(id); }
5680 case N8: { changeBlockSize(id); }
5681 case N9: { showOptionsMenu(id, 6); }
5682 case N0: { showMainMenu(id); }
5683 }
5684
5685 //selections 9 and 0 show different menus
5686 if (num != N9 && num != N0)
5687 {
5688 showLongJumpMenu(id);
5689 }
5690}
5691
5692public handleOptionsMenu(id, num)
5693{
5694 switch (num)
5695 {
5696 case N1: { toggleSnapping(id); }
5697 case N2: { toggleSnappingGap(id); }
5698 case N3: { groupBlockAiming(id); }
5699 case N4: { groupClear(id); }
5700 case N5: { showChoiceMenu(id, CHOICE_DEL_BLOCKS, "Are you sure you want to erase all blocks on the map?"); }
5701 case N6: { showChoiceMenu(id, CHOICE_DEL_TELEPORTS, "Are you sure you want to erase all teleports on the map?"); }
5702 case N7: { saveBlocks(id); }
5703 case N8: { showChoiceMenu(id, CHOICE_LOAD, "Loading will erase all blocks and teleports, do you want to continue?"); }
5704 case N9: { showHelp(id); }
5705
5706 case N0: //back to previous menu
5707 {
5708 switch (gMenuBeforeOptions[id])
5709 {
5710 case 1: showMainMenu(id);
5711 case 2: showBlockMenu(id);
5712 case 3: showTeleportMenu(id);
5713 case 4: showTimerMenu(id);
5714 case 5: showMeasureMenu(id);
5715 case 6: showLongJumpMenu(id);
5716
5717 //for some reason the players 'gMenuBeforeOptions' number is invalid
5718 default: log_amx("%sPlayer ID: %d has an invalid gMenuBeforeOptions: %d", gszPrefix, id, gMenuBeforeOptions[id]);
5719 }
5720 }
5721 }
5722
5723 //these selections show a different menu
5724 if (num != N5 && num != N6 && num != N8 && num != N0)
5725 {
5726 //display menu again
5727 showOptionsMenu(id, gMenuBeforeOptions[id]);
5728 }
5729}
5730
5731public handleChoiceMenu(id, num)
5732{
5733 switch (num)
5734 {
5735 case N1: //YES
5736 {
5737 switch (gChoiceOption[id])
5738 {
5739 case CHOICE_LOAD: loadBlocks(id);
5740 case CHOICE_DEL_BLOCKS: deleteAllBlocks(id, true);
5741 case CHOICE_DEL_TELEPORTS: deleteAllTeleports(id, true);
5742
5743 default:
5744 {
5745 log_amx("%sInvalid choice in handleChoiceMenu()", gszPrefix);
5746 }
5747 }
5748 }
5749 }
5750
5751 //show options menu again
5752 showOptionsMenu(id, gMenuBeforeOptions[id]);
5753}
5754
5755measureToolSelectBlock(id, num)
5756{
5757 new ent;
5758 new body;
5759 get_user_aiming(id, ent, body);
5760
5761 //if player is aiming at a block or a timer
5762 if (isBlock(ent) || isTimer(ent))
5763 {
5764 switch (num)
5765 {
5766 case 1:
5767 {
5768 //if block being aimed at is different than one already selected
5769 if (ent != gMeasureToolBlock2[id])
5770 {
5771 gMeasureToolBlock1[id] = ent;
5772 }
5773 }
5774
5775 case 2:
5776 {
5777 //if block being aimed at is different than one already selected
5778 if (ent != gMeasureToolBlock1[id])
5779 {
5780 gMeasureToolBlock2[id] = ent;
5781 }
5782 }
5783
5784 default:
5785 {
5786 log_amx("%sInvalid number in measureToolSelectBlock()", gszPrefix);
5787 }
5788 }
5789 }
5790}
5791
5792measureToolSelectPos(id, num)
5793{
5794 new origin[3];
5795 new Float:vOrigin[3];
5796
5797 //get the origin of where the player is aiming
5798 get_user_origin(id, origin, 3);
5799 IVecFVec(origin, vOrigin);
5800
5801 switch (num)
5802 {
5803 case 1:
5804 {
5805 gvMeasureToolPos1[id] = vOrigin;
5806 }
5807
5808 case 2:
5809 {
5810 gvMeasureToolPos2[id] = vOrigin;
5811 }
5812
5813 default:
5814 {
5815 log_amx("%sInvalid number in measureToolSelectPos()", gszPrefix);
5816 }
5817 }
5818}
5819
5820toggleMeasureTool(id)
5821{
5822 //make sure player has access to this command
5823 if (get_user_flags(id) & BM_ADMIN_LEVEL)
5824 {
5825 gbMeasureToolEnabled[id] = !gbMeasureToolEnabled[id];
5826 }
5827}
5828
5829longJumpDistance(id, num)
5830{
5831 switch (num)
5832 {
5833 case 1:
5834 {
5835 if (gLongJumpDistance[id] < 300) gLongJumpDistance[id]++;
5836 }
5837
5838 case 2:
5839 {
5840 if (gLongJumpDistance[id] > 200) gLongJumpDistance[id]--;
5841 }
5842
5843 default:
5844 {
5845 log_amx("%sInvalid number in longJumpDistance()", gszPrefix);
5846 }
5847 }
5848}
5849
5850longJumpCreate(id)
5851{
5852 //make sure player has access to this command
5853 if (get_user_flags(id) & BM_ADMIN_LEVEL)
5854 {
5855 new origin[3];
5856 new Float:vOrigin[3];
5857 new Float:fScale;
5858 new bool:bFailed = false;
5859 new axis;
5860
5861 //get the origin of the player and add Z offset
5862 get_user_origin(id, origin, 3);
5863 IVecFVec(origin, vOrigin);
5864 vOrigin[2] += gfBlockSizeMaxForZ[2];
5865
5866 //get scale depending on size
5867 switch (gBlockSize[id])
5868 {
5869 case SMALL: fScale = SCALE_SMALL;
5870 case NORMAL: fScale = SCALE_NORMAL;
5871 case LARGE: fScale = SCALE_LARGE;
5872 case ELARGE: fScale = SCALE_ELARGE;
5873 case JUMBO: fScale = SCALE_JUMBO;
5874 case POLE: fScale = SCALE_POLE;
5875 }
5876
5877 //calculate half the jump distance and half the width of the block
5878 new Float:fDist = gLongJumpDistance[id] / 2.0;
5879 new Float:fHalfWidth = gfBlockSizeMaxForZ[0] * fScale;
5880
5881 //set the creator of block
5882 new Creator[32];
5883 get_user_name(id, Creator, 31);
5884
5885 //move origin along X and create first block
5886 vOrigin[axis] -= (fDist + fHalfWidth);
5887 new block1 = createBlock(id, BM_PLATFORM, vOrigin, Z, gBlockSize[id],Creator);
5888
5889 //set axis on which to create the two blocks
5890 axis = gLongJumpAxis[id];
5891
5892 //if first block is not stuck
5893 if (!isBlockStuck(block1))
5894 {
5895 //move origin along X and create second block
5896 vOrigin[axis] += (fDist + fHalfWidth) * 2;
5897 new block2 = createBlock(id, BM_PLATFORM, vOrigin, Z, gBlockSize[id],Creator);
5898
5899 //if block is stuck
5900 if (isBlockStuck(block2))
5901 {
5902 //delete both blocks
5903 deleteBlock(block1);
5904 deleteBlock(block2);
5905 bFailed = true;
5906 }
5907 }
5908 else
5909 {
5910 //delete the block
5911 deleteBlock(block1);
5912 bFailed = true;
5913 }
5914
5915 //if long jump failed to create (because one of the blocks was stuck) notify the player
5916 if (bFailed)
5917 {
5918 client_print(id, print_chat, "%sLong jump failed to create because one or more of the blocks were stuck.", gszPrefix);
5919 }
5920 }
5921}
5922
5923longJumpRotate(id)
5924{
5925 //swap between X and Y axes
5926 if (gLongJumpAxis[id] == X)
5927 {
5928 gLongJumpAxis[id] = Y;
5929 }
5930 else
5931 {
5932 gLongJumpAxis[id] = X;
5933 }
5934}
5935
5936toggleGodmode(id)
5937{
5938 //make sure player has access to this command
5939 if (get_user_flags(id) & BM_ADMIN_LEVEL)
5940 {
5941 //if player has godmode
5942 if (get_user_godmode(id))
5943 {
5944 //turn off godmode for player
5945 set_user_godmode(id, 0);
5946 gbAdminGodmode[id] = false;
5947 }
5948 else
5949 {
5950 //turn on godmode for player
5951 set_user_godmode(id, 1);
5952 gbAdminGodmode[id] = true;
5953 }
5954 }
5955}
5956
5957toggleNoclip(id)
5958{
5959 //make sure player has access to this command
5960 if (get_user_flags(id) & BM_ADMIN_LEVEL)
5961 {
5962 //if player has noclip
5963 if (get_user_noclip(id))
5964 {
5965 //turn off noclip for player
5966 set_user_noclip(id, 0);
5967 gbAdminNoclip[id] = false;
5968 }
5969 else
5970 {
5971 //turn on noclip for player
5972 set_user_noclip(id, 1);
5973 gbAdminNoclip[id] = true;
5974 }
5975 }
5976}
5977
5978changeBlockSize(id)
5979{
5980 switch (gBlockSize[id])
5981 {
5982 case SMALL: gBlockSize[id] = NORMAL;
5983 case NORMAL: gBlockSize[id] = LARGE;
5984 case LARGE: gBlockSize[id] = ELARGE;
5985 case ELARGE: gBlockSize[id] = JUMBO;
5986 case JUMBO: gBlockSize[id] = POLE;
5987 case POLE: gBlockSize[id] = SMALL;
5988 }
5989}
5990
5991toggleSnapping(id)
5992{
5993 //make sure player has access to this command
5994 if (get_user_flags(id) & BM_ADMIN_LEVEL)
5995 {
5996 gbSnapping[id] = !gbSnapping[id];
5997 }
5998}
5999
6000toggleSnappingGap(id)
6001{
6002 //make sure player has access to this command
6003 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6004 {
6005 //increment this players snapping gap by 5
6006 gfSnappingGap[id] += 4.0;
6007
6008 //if this players snapping gap gets too big then loop it back to 0
6009 if (gfSnappingGap[id] > 40.0)
6010 {
6011 gfSnappingGap[id] = 0.0;
6012 }
6013 }
6014}
6015
6016showHelp(id)
6017{
6018 //get cvar values
6019 new szHelpText[1600];
6020
6021 new Telefrags = get_cvar_num("bm_telefrags");
6022 new Float:fFireDamageAmount = get_cvar_float("bm_firedamageamount");
6023 new Float:fDamageAmount = get_cvar_float("bm_damageamount");
6024 new Float:fHealAmount = get_cvar_float("bm_healamount");
6025 new Float:fInvincibleTime = get_cvar_float("bm_invincibletime");
6026 new Float:fInvincibleCooldown = get_cvar_float("bm_invinciblecooldown");
6027 new Float:fStealthTime = get_cvar_float("bm_stealthtime");
6028 new Float:fStealthCooldown = get_cvar_float("bm_stealthcooldown");
6029 new Float:fCamouflageTime = get_cvar_float("bm_camouflagetime");
6030 new Float:fCamouflageCooldown = get_cvar_float("bm_camouflagecooldown");
6031 new Float:fNukeCooldown = get_cvar_float("bm_nukecooldown");
6032 new Float:fRandomCooldown = get_cvar_float("bm_randomcooldown");
6033 new Float:fBootsOfSpeedTime = get_cvar_float("bm_bootsofspeedtime");
6034 new Float:fBootsOfSpeedCooldown = get_cvar_float("bm_bootsofspeedcooldown");
6035 new Float:fAutoBhopTime = get_cvar_float("bm_autobhoptime");
6036 new Float:fAutoBhopCooldown = get_cvar_float("bm_autobhopcooldown");
6037 new TeleportSound = get_cvar_num("bm_teleportsound");
6038
6039 //format the help text
6040 format(szHelpText, sizeof(szHelpText), gszHelpText, Telefrags, fFireDamageAmount, fDamageAmount, fHealAmount, fInvincibleTime, fInvincibleCooldown, fStealthTime, fStealthCooldown, fCamouflageTime, fCamouflageCooldown, fNukeCooldown, fRandomCooldown, fBootsOfSpeedTime, fBootsOfSpeedCooldown, fAutoBhopTime, fAutoBhopCooldown, TeleportSound);
6041
6042 //show the help
6043 show_motd(id, szHelpText, gszHelpTitle);
6044}
6045
6046showTeleportPath(id)
6047{
6048 //get the entity the player is aiming at
6049 new ent, body;
6050 get_user_aiming(id, ent, body);
6051
6052 //if entity found is a teleport
6053 if (isTeleport(ent))
6054 {
6055 //get other side of teleport
6056 new tele = entity_get_int(ent, EV_INT_iuser1);
6057
6058 //if there is another end to the teleport
6059 if (tele)
6060 {
6061 //get origins of the start and end teleport entities
6062 new life = 50;
6063 new Float:vOrigin1[3];
6064 new Float:vOrigin2[3];
6065 entity_get_vector(ent, EV_VEC_origin, vOrigin1);
6066 entity_get_vector(tele, EV_VEC_origin, vOrigin2);
6067
6068 //draw a line in between the 2 origins
6069 drawLine(vOrigin1, vOrigin2, life);
6070
6071 //get the distance between the points
6072 new Float:fDist = get_distance_f(vOrigin1, vOrigin2);
6073
6074 //notify that a line has been drawn between the start and end of the teleport
6075 client_print(id, print_chat, "%sA line has been drawn to show the teleport path. Distance: %f units.", gszPrefix, fDist);
6076 }
6077 }
6078}
6079
6080/* GROUPING BLOCKS */
6081groupBlockAiming(id)
6082{
6083 //make sure player has access to this command
6084 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6085 {
6086 //get the entity the player is aiming at
6087 new ent, body;
6088 get_user_aiming(id, ent, body);
6089
6090 //is entity is a block
6091 if (isBlock(ent))
6092 {
6093 //get whether or not block is already being grouped
6094 new player = entity_get_int(ent, EV_INT_iuser1);
6095
6096 //if block is not in a group
6097 if (player == 0)
6098 {
6099 //increment group value
6100 ++gGroupCount[id];
6101
6102 //add this entity to the players group
6103 gGroupedBlocks[id][gGroupCount[id]] = ent;
6104
6105 //set the block so it is now 'being grouped'
6106 groupBlock(id, ent);
6107
6108 }
6109 //if block is in this players group
6110 else if (player == id)
6111 {
6112 //remove block from being grouped
6113 groupRemoveBlock(ent);
6114 }
6115 //if another player has the block grouped
6116 else
6117 {
6118 //get id and name of who has the block grouped
6119 new szName[32];
6120 new player = entity_get_int(ent, EV_INT_iuser1);
6121 get_user_name(player, szName, 32);
6122
6123 //notify player who the block is being grouped by
6124 client_print(id, print_chat, "%sBlock is already in a group by: %s", gszPrefix, szName);
6125 }
6126 }
6127 }
6128}
6129
6130groupBlock(id, ent)
6131{
6132 //if entity is valid
6133 if (is_valid_ent(ent))
6134 {
6135 //if id passed in is a player
6136 if (id > 0 && id <= 32)
6137 {
6138 //set block so it is now being grouped
6139 entity_set_int(ent, EV_INT_iuser1, id);
6140 }
6141
6142 //make block glow red to show it is grouped
6143 set_rendering(ent, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 16);
6144 }
6145}
6146
6147groupRemoveBlock(ent)
6148{
6149 //make sure entity is a block
6150 if (isBlock(ent))
6151 {
6152 //remove block from being grouped (stays in players gGroupedBlocks[id][] array
6153 entity_set_int(ent, EV_INT_iuser1, 0);
6154
6155 //get block type
6156 new blockType = entity_get_int(ent, EV_INT_body);
6157
6158 //set rendering on block
6159 set_block_rendering(ent, gRender[blockType], gRed[blockType], gGreen[blockType], gBlue[blockType], gAlpha[blockType]);
6160 }
6161}
6162
6163groupClear(id)
6164{
6165 new blockCount = 0;
6166 new blocksDeleted = 0;
6167 new block;
6168
6169 //remove all players blocks from being grouped
6170 for (new i = 0; i <= gGroupCount[id]; ++i)
6171 {
6172 block = gGroupedBlocks[id][i];
6173
6174 //if block is in this players group
6175 if (isBlockInGroup(id, block))
6176 {
6177 //if block is stuck
6178 if (isBlockStuck(block))
6179 {
6180 //delete the stuck block
6181 deleteBlock(block);
6182
6183 //count how many blocks have been deleted
6184 ++blocksDeleted;
6185 }
6186 else
6187 {
6188 //remove block from being grouped
6189 groupRemoveBlock(block);
6190
6191 //count how many blocks have been removed from group
6192 ++blockCount;
6193 }
6194 }
6195 }
6196
6197 //set players group count to 0
6198 gGroupCount[id] = 0;
6199
6200 //if player is connected
6201 if (is_user_connected(id))
6202 {
6203 //if some blocks were deleted
6204 if (blocksDeleted > 0)
6205 {
6206 //notify player how many blocks were cleared from group and deleted
6207 client_print(id, print_chat, "%sRemoved %d blocks from group, deleted %d stuck blocks", gszPrefix, blockCount, blocksDeleted);
6208 }
6209 else
6210 {
6211 //notify player how many blocks were cleared from group
6212 client_print(id, print_chat, "%sRemoved %d blocks from group", gszPrefix, blockCount);
6213 }
6214 }
6215}
6216
6217/* BLOCK & TELEPORT OPERATIONS */
6218moveGrabbedEntity(id, Float:vMoveTo[3] = {0.0, 0.0, 0.0})
6219{
6220 new iOrigin[3], iLook[3];
6221 new Float:fOrigin[3], Float:fLook[3], Float:fDirection[3], Float:fLength;
6222
6223 get_user_origin(id, iOrigin, 1); //Position from eyes (weapon aiming)
6224 get_user_origin(id, iLook, 3); //End position from eyes (hit point for weapon)
6225 IVecFVec(iOrigin, fOrigin);
6226 IVecFVec(iLook, fLook);
6227
6228 fDirection[0] = fLook[0] - fOrigin[0];
6229 fDirection[1] = fLook[1] - fOrigin[1];
6230 fDirection[2] = fLook[2] - fOrigin[2];
6231 fLength = get_distance_f(fLook, fOrigin);
6232
6233 if (fLength == 0.0) fLength = 1.0; //avoid division by 0
6234
6235 //calculate the position to move the block
6236 vMoveTo[0] = (fOrigin[0] + fDirection[0] * gfGrablength[id] / fLength) + gvGrabOffset[id][0];
6237 vMoveTo[1] = (fOrigin[1] + fDirection[1] * gfGrablength[id] / fLength) + gvGrabOffset[id][1];
6238 vMoveTo[2] = (fOrigin[2] + fDirection[2] * gfGrablength[id] / fLength) + gvGrabOffset[id][2];
6239 vMoveTo[2] = float(floatround(vMoveTo[2], floatround_floor));
6240
6241 //move the block and its sprite (if it has one)
6242 moveEntity(id, gGrabbed[id], vMoveTo, true);
6243}
6244
6245moveEntity(id, ent, Float:vMoveTo[3], bool:bDoSnapping)
6246{
6247 //if entity is a block
6248 if (isBlock(ent))
6249 {
6250 //do snapping for entity if snapping boolean passed in is true
6251 if (bDoSnapping)
6252 {
6253 doSnapping(id, ent, vMoveTo);
6254 }
6255
6256 //set the position of the block
6257 entity_set_origin(ent, vMoveTo);
6258
6259 //get the sprite that sits above the block (if any)
6260 new sprite = entity_get_int(ent, EV_INT_iuser3);
6261
6262 //if sprite entity is valid
6263 if (sprite)
6264 {
6265 //get size of block
6266 new Float:vSizeMax[3];
6267 entity_get_vector(ent, EV_VEC_maxs, vSizeMax);
6268
6269 //move the sprite onto the top of the block
6270 vMoveTo[2] += vSizeMax[2] + 0.15;
6271 entity_set_origin(sprite, vMoveTo);
6272 }
6273 }
6274 else
6275 {
6276 //set the position of the entity
6277 entity_set_origin(ent, vMoveTo);
6278 }
6279}
6280
6281/* TELEPORTS */
6282createTeleportAiming(const id, const teleportType)
6283{
6284 //make sure player has access to this command
6285 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6286 {
6287 //get where player is aiming for origin of teleport entity
6288 new pOrigin[3], Float:vOrigin[3];
6289 get_user_origin(id, pOrigin, 3);
6290 IVecFVec(pOrigin, vOrigin);
6291 vOrigin[2] += gfTeleportZOffset;
6292
6293 //create the teleport of the given type
6294 createTeleport(id, teleportType, vOrigin);
6295 }
6296}
6297
6298createTeleport(const id, const teleportType, Float:vOrigin[3])
6299{
6300 new ent = create_entity(gszInfoTarget);
6301
6302 if (is_valid_ent(ent))
6303 {
6304 switch (teleportType)
6305 {
6306 case TELEPORT_START:
6307 {
6308 //if player has already created a teleport start entity then delete it
6309 if (gTeleportStart[id])
6310 {
6311 remove_entity(gTeleportStart[id]);
6312 }
6313
6314 //set teleport properties
6315 entity_set_string(ent, EV_SZ_classname, gszTeleportStartClassname);
6316 entity_set_int(ent, EV_INT_solid, SOLID_BBOX);
6317 entity_set_int(ent, EV_INT_movetype, MOVETYPE_NONE);
6318 entity_set_model(ent, gszTeleportSpriteStart);
6319 entity_set_size(ent, gfTeleportSizeMin, gfTeleportSizeMax);
6320 entity_set_origin(ent, vOrigin);
6321
6322 //set the rendermode and transparency
6323 entity_set_int(ent, EV_INT_rendermode, 5); //rendermode
6324 entity_set_float(ent, EV_FL_renderamt, 255.0); //visable
6325
6326 //set task for animating sprite
6327 new params[2];
6328 params[0] = ent;
6329 params[1] = gTeleportStartFrames;
6330 set_task(0.1, "taskSpriteNextFrame", TASK_SPRITE + ent, params, 2, "b");
6331
6332 //store teleport start entity to a global variable so it can be linked to the end entity
6333 gTeleportStart[id] = ent;
6334 }
6335
6336 case TELEPORT_END:
6337 {
6338 //make sure there is a teleport start entity
6339 if (gTeleportStart[id])
6340 {
6341 //set teleport properties
6342 entity_set_string(ent, EV_SZ_classname, gszTeleportEndClassname);
6343 entity_set_int(ent, EV_INT_solid, SOLID_BBOX);
6344 entity_set_int(ent, EV_INT_movetype, MOVETYPE_NONE);
6345 entity_set_model(ent, gszTeleportSpriteEnd);
6346 entity_set_size(ent, gfTeleportSizeMin, gfTeleportSizeMax);
6347 entity_set_origin(ent, vOrigin);
6348
6349 //set the rendermode and transparency
6350 entity_set_int(ent, EV_INT_rendermode, 5); //rendermode
6351 entity_set_float(ent, EV_FL_renderamt, 255.0); //visable
6352
6353 //link up teleport start and end entities
6354 entity_set_int(ent, EV_INT_iuser1, gTeleportStart[id]);
6355 entity_set_int(gTeleportStart[id], EV_INT_iuser1, ent);
6356
6357 //set task for animating sprite
6358 new params[2];
6359 params[0] = ent;
6360 params[1] = gTeleportEndFrames;
6361 set_task(0.1, "taskSpriteNextFrame", TASK_SPRITE + ent, params, 2, "b");
6362
6363 //indicate that this player has no teleport start entity waiting for an end
6364 gTeleportStart[id] = 0;
6365 }
6366 else
6367 {
6368 //delete entity that was created because there is no start entity
6369 remove_entity(ent);
6370 }
6371 }
6372 }
6373 }
6374 else
6375 {
6376 log_amx("%sCouldn't create 'env_sprite' entity", gszPrefix);
6377 }
6378}
6379
6380swapTeleportAiming(id)
6381{
6382 //make sure player has access to this command
6383 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6384 {
6385 //get entity that player is aiming at
6386 new ent, body;
6387 get_user_aiming(id, ent, body, 9999);
6388
6389 //swap teleport start and destination
6390 if (isTeleport(ent))
6391 {
6392 swapTeleport(id, ent);
6393 }
6394 }
6395}
6396
6397swapTeleport(id, ent)
6398{
6399 new Float:vOriginEnt[3];
6400 new Float:vOriginTele[3];
6401
6402 //get the other end of the teleport
6403 new tele = entity_get_int(ent, EV_INT_iuser1);
6404
6405 //if the teleport has another side
6406 if (is_valid_ent(tele))
6407 {
6408 //get teleport properties
6409 entity_get_vector(ent, EV_VEC_origin, vOriginEnt);
6410 entity_get_vector(tele, EV_VEC_origin, vOriginTele);
6411
6412 new szClassname[32];
6413 entity_get_string(ent, EV_SZ_classname, szClassname, 32);
6414
6415 //delete old teleport
6416 deleteTeleport(id, ent);
6417
6418 //create new teleport at opposite positions
6419 if (equal(szClassname, gszTeleportStartClassname))
6420 {
6421 createTeleport(id, TELEPORT_START, vOriginTele);
6422 createTeleport(id, TELEPORT_END, vOriginEnt);
6423 }
6424 else if (equal(szClassname, gszTeleportEndClassname))
6425 {
6426 createTeleport(id, TELEPORT_START, vOriginEnt);
6427 createTeleport(id, TELEPORT_END, vOriginTele);
6428 }
6429 }
6430 else
6431 {
6432 //tell player they cant swap because its only 1 sided
6433 client_print(id, print_chat, "%sCan't swap teleport positions", gszPrefix);
6434 }
6435}
6436
6437deleteTeleportAiming(id)
6438{
6439 //make sure player has access to this command
6440 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6441 {
6442 //get entity that player is aiming at
6443 new ent, body;
6444 get_user_aiming(id, ent, body, 9999);
6445
6446 //delete block that player is aiming at
6447 new bool:deleted = deleteTeleport(id, ent);
6448
6449 if (deleted)
6450 {
6451 client_print(id, print_chat, "%sTeleport deleted!", gszPrefix);
6452 }
6453 }
6454}
6455
6456bool:deleteTeleport(id, ent)
6457{
6458 //if entity is a teleport then delete both the start and the end of the teleport
6459 if (isTeleport(ent))
6460 {
6461 //get entity id of the other side of the teleport
6462 new tele = entity_get_int(ent, EV_INT_iuser1);
6463
6464 //clear teleport start entity if it was just deleted
6465 if (gTeleportStart[id] == ent || gTeleportStart[id] == tele)
6466 {
6467 gTeleportStart[id] = 0;
6468 }
6469
6470 //remove tasks that exist to animate the teleport sprites
6471 if (task_exists(TASK_SPRITE + ent))
6472 {
6473 remove_task(TASK_SPRITE + ent);
6474 }
6475
6476 if (task_exists(TASK_SPRITE + tele))
6477 {
6478 remove_task(TASK_SPRITE + tele);
6479 }
6480
6481 //delete both the start and end positions of the teleporter
6482 if (tele)
6483 {
6484 remove_entity(tele);
6485 }
6486
6487 remove_entity(ent);
6488
6489 //delete was deleted
6490 return true;
6491 }
6492
6493 //teleport was not deleted
6494 return false;
6495}
6496
6497/* TIMERS */
6498createTimerAiming(id, timerType)
6499{
6500 //make sure player has access to this command
6501 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6502 {
6503 new origin[3];
6504 new Float:vOrigin[3];
6505
6506 //get the origin of where the player is looking
6507 get_user_origin(id, origin, 3);
6508 IVecFVec(origin, vOrigin);
6509
6510 //create the timer
6511 createTimer(id, timerType, vOrigin);
6512 }
6513}
6514
6515createTimer(id, timerType, Float:vOrigin[3], Float:vAngles[3] = { 0.0, 0.0, 0.0 })
6516{
6517 new ent;
6518
6519 switch (timerType)
6520 {
6521 case TIMER_START:
6522 {
6523 //if player has already created a timer start entity then delete it
6524 if (gStartTimer[id])
6525 {
6526 if (is_valid_ent(gStartTimer[id]))
6527 {
6528 remove_entity(gStartTimer[id]);
6529 }
6530 }
6531
6532 ent = create_entity("func_button");
6533
6534 //make sure entity was created successfully
6535 if (is_valid_ent(ent))
6536 {
6537 //set timer properties
6538 entity_set_string(ent, EV_SZ_classname, gszTimerClassname);
6539 entity_set_int(ent, EV_INT_body, timerType);
6540 entity_set_int(ent, EV_INT_solid, SOLID_BBOX);
6541 entity_set_int(ent, EV_INT_movetype, MOVETYPE_NONE);
6542 entity_set_model(ent, gszTimerModelStart);
6543 entity_set_vector(ent, EV_VEC_angles, vAngles);
6544 entity_set_size(ent, gfTimerSizeMin, gfTimerSizeMax);
6545 entity_set_origin(ent, vOrigin);
6546
6547 //player has now created a timer start
6548 gStartTimer[id] = ent;
6549 }
6550 }
6551
6552 case TIMER_END:
6553 {
6554 //make sure player has created a start timer entity
6555 if (isTimer(gStartTimer[id]))
6556 {
6557 ent = create_entity("func_button");
6558
6559 //make sure entity was created successfully
6560 if (is_valid_ent(ent))
6561 {
6562 //set timer properties
6563 entity_set_string(ent, EV_SZ_classname, gszTimerClassname);
6564 entity_set_int(ent, EV_INT_body, timerType);
6565 entity_set_int(ent, EV_INT_solid, SOLID_BBOX);
6566 entity_set_int(ent, EV_INT_movetype, MOVETYPE_NONE);
6567 entity_set_model(ent, gszTimerModelEnd);
6568 entity_set_vector(ent, EV_VEC_angles, vAngles);
6569 entity_set_size(ent, gfTimerSizeMin, gfTimerSizeMax);
6570 entity_set_origin(ent, vOrigin);
6571
6572 //link up start and end timers
6573 entity_set_int(ent, EV_INT_iuser1, gStartTimer[id]);
6574 entity_set_int(gStartTimer[id], EV_INT_iuser1, ent);
6575
6576 //indicate that this player has no start timer entity
6577 gStartTimer[id] = 0;
6578 }
6579 }
6580 }
6581 }
6582
6583 return ent;
6584}
6585
6586swapTimerAiming(id)
6587{
6588 //make sure player has access to this command
6589 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6590 {
6591 //get entity that player is aiming at
6592 new ent, body;
6593 get_user_aiming(id, ent, body, 9999);
6594
6595 //swap the start & end timer positions
6596 if (isTimer(ent))
6597 {
6598 swapTimer(id, ent);
6599 }
6600 }
6601}
6602
6603swapTimer(id, ent)
6604{
6605 new Float:vOriginEnt[3];
6606 new Float:vOriginTimer[3];
6607 new Float:vAngleEnt[3];
6608 new Float:vAngleTimer[3];
6609
6610 //get the other end of the timer
6611 new timer = entity_get_int(ent, EV_INT_iuser1);
6612
6613 //if the timer has another side
6614 if (is_valid_ent(timer))
6615 {
6616 //get timer properties
6617 new type = entity_get_int(ent, EV_INT_body);
6618 entity_get_vector(ent, EV_VEC_origin, vOriginEnt);
6619 entity_get_vector(ent, EV_VEC_angles, vAngleEnt);
6620 entity_get_vector(timer, EV_VEC_origin, vOriginTimer);
6621 entity_get_vector(timer, EV_VEC_angles, vAngleTimer);
6622
6623 //delete old timers
6624 remove_entity(ent);
6625 remove_entity(timer);
6626
6627 //create new timers at opposite positions
6628 if (type == TIMER_START)
6629 {
6630 createTimer(id, TIMER_START, vOriginTimer, vAngleTimer);
6631 createTimer(id, TIMER_END, vOriginEnt, vAngleEnt);
6632 }
6633 else if (type == TIMER_END)
6634 {
6635 createTimer(id, TIMER_START, vOriginEnt, vAngleEnt);
6636 createTimer(id, TIMER_END, vOriginTimer, vAngleTimer);
6637 }
6638 else
6639 {
6640 log_amx("Invalid timer type: %d", type);
6641 }
6642 }
6643 else
6644 {
6645 //tell player they cant swap because its only 1 sided
6646 client_print(id, print_chat, "%sCan't swap timer positions", gszPrefix);
6647 }
6648}
6649
6650deleteTimerAiming(id)
6651{
6652 //make sure player has access to this command
6653 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6654 {
6655 //get entity that player is aiming at
6656 new ent, body;
6657 get_user_aiming(id, ent, body, 9999);
6658
6659 //delete timer that player is aiming at
6660 new bool:deleted = deleteTimer(ent);
6661
6662 if (deleted)
6663 {
6664 client_print(id, print_chat, "%sTimer deleted!", gszPrefix);
6665
6666 //make sure all players start timer entities are valid
6667 for (new i = 1; i <= 32; ++i)
6668 {
6669 if (!is_valid_ent(gStartTimer[i]))
6670 {
6671 gStartTimer[i] = 0;
6672 }
6673 }
6674 }
6675 }
6676}
6677
6678bool:deleteTimer(ent)
6679{
6680 //if entity is a teleport then delete both the start and the end of the timer
6681 if (isTimer(ent))
6682 {
6683 //get entity id of the other side of the timer
6684 new timer = entity_get_int(ent, EV_INT_iuser1);
6685
6686 //delete both the start and end positions of the timer
6687 if (timer)
6688 {
6689 remove_entity(timer);
6690 }
6691
6692 remove_entity(ent);
6693
6694 //timer was deleted
6695 return true;
6696 }
6697
6698 //teleport was not deleted
6699 return false;
6700}
6701
6702rotateTimerAiming(id)
6703{
6704 //make sure player has access to this command
6705 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6706 {
6707 //get entity that player is aiming at
6708 new ent, body;
6709 get_user_aiming(id, ent, body, 9999);
6710
6711 //rotate timer that player is aiming at
6712 if (isTimer(ent))
6713 {
6714 rotateTimer(ent);
6715 }
6716 }
6717}
6718
6719rotateTimer(ent)
6720{
6721 new Float:vAngles[3];
6722
6723 //get timer angles
6724 entity_get_vector(ent, EV_VEC_angles, vAngles);
6725
6726 //change the timers angles depending on its current angle
6727 if (vAngles[1] == 0.0)
6728 {
6729 vAngles[1] = 90.0;
6730 }
6731 else if (vAngles[1] == 90.0)
6732 {
6733 vAngles[1] = 180.0;
6734 }
6735 else if (vAngles[1] == 180.0)
6736 {
6737 vAngles[1] = 270.0;
6738 }
6739 else if (vAngles[1] == 270.0)
6740 {
6741 vAngles[1] = 0.0;
6742 }
6743
6744 //set the timers new angles
6745 entity_set_vector(ent, EV_VEC_angles, vAngles);
6746}
6747
6748/* OPTIONS */
6749deleteAllBlocks(id, bool:bNotify)
6750{
6751 //make sure player has access to this command
6752 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6753 {
6754 new bool:bDeleted;
6755 new blockCount = 0;
6756 new ent = -1;
6757
6758 //find all blocks in the map
6759 while ((ent = find_ent_by_class(ent, gszBlockClassname)))
6760 {
6761 //delete the block
6762 bDeleted = deleteBlock(ent);
6763
6764 //if block was successfully deleted
6765 if (bDeleted)
6766 {
6767 //increment counter for how many blocks have been deleted
6768 ++blockCount;
6769 }
6770 }
6771
6772 //if some blocks were deleted
6773 if (blockCount > 0)
6774 {
6775 //get players name
6776 new szName[32];
6777 get_user_name(id, szName, 32);
6778
6779 //iterate through all players
6780 for (new i = 1; i <= 32; ++i)
6781 {
6782 //make sure nobody is grabbing a block because they've all been deleted!
6783 gGrabbed[id] = 0;
6784
6785 //make sure player is connected
6786 if (is_user_connected(i))
6787 {
6788 //notify all admins that the player deleted all the blocks
6789 if (bNotify && get_user_flags(i) & BM_ADMIN_LEVEL)
6790 {
6791 client_print(i, print_chat, "%s'%s' deleted all the blocks from the map. Total blocks: %d", gszPrefix, szName, blockCount);
6792 }
6793 }
6794 }
6795 }
6796 }
6797}
6798
6799deleteAllTeleports(id, bool:bNotify)
6800{
6801 //make sure player has access to this command
6802 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6803 {
6804 new bool:bDeleted;
6805 new teleCount = 0;
6806 new ent = -1;
6807
6808 //find all teleport start entities in the map
6809 while ((ent = find_ent_by_class(ent, gszTeleportStartClassname)))
6810 {
6811 //delete the teleport
6812 bDeleted = deleteTeleport(id, ent);
6813
6814 //if teleport was successfully deleted
6815 if (bDeleted)
6816 {
6817 //increment counter for how many teleports have been deleted
6818 ++teleCount;
6819 }
6820 }
6821
6822 //if some teleports were deleted
6823 if (teleCount > 0)
6824 {
6825 //get players name
6826 new szName[32];
6827 get_user_name(id, szName, 32);
6828
6829 //iterate through all players
6830 for (new i = 1; i <= 32; ++i)
6831 {
6832 //make sure nobody has a teleport start set
6833 gTeleportStart[id] = 0;
6834
6835 //make sure player is connected
6836 if (is_user_connected(i))
6837 {
6838 //notify all admins that the player deleted all the teleports
6839 if (bNotify && get_user_flags(i) & BM_ADMIN_LEVEL)
6840 {
6841 client_print(i, print_chat, "%s'%s' deleted all the teleports from the map. Total teleports: %d", gszPrefix, szName, teleCount);
6842 }
6843 }
6844 }
6845 }
6846 }
6847}
6848
6849deleteAllTimers(id, bool:bNotify)
6850{
6851 //make sure player has access to this command
6852 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6853 {
6854 new bool:bDeleted;
6855 new timerCount = 0;
6856 new ent = -1;
6857
6858 //find all timer start entities in the map
6859 while ((ent = find_ent_by_class(ent, gszTimerClassname)))
6860 {
6861 //delete the timer
6862 bDeleted = deleteTimer(ent);
6863
6864 //if timer was successfully deleted
6865 if (bDeleted)
6866 {
6867 //increment counter for how many timers have been deleted
6868 ++timerCount;
6869 }
6870 }
6871
6872 //if some timers were deleted
6873 if (timerCount > 0)
6874 {
6875 //get players name
6876 new szName[32];
6877 get_user_name(id, szName, 32);
6878
6879 //iterate through all players
6880 for (new i = 1; i <= 32; ++i)
6881 {
6882 //make sure nobody has a timer start set
6883 gStartTimer[id] = 0;
6884
6885 //make sure player is connected
6886 if (is_user_connected(i))
6887 {
6888 //notify all admins that the player deleted all the teleports
6889 if (bNotify && get_user_flags(i) & BM_ADMIN_LEVEL)
6890 {
6891 client_print(i, print_chat, "%s'%s' deleted all the teleports from the map. Total teleports: %d", gszPrefix, szName, timerCount);
6892 }
6893 }
6894 }
6895 }
6896 }
6897}
6898
6899/***** BLOCKS *****/
6900createBlockAiming(const id, const blockType)
6901{
6902 //make sure player has access to this command
6903 if (get_user_flags(id) & BM_ADMIN_LEVEL)
6904 {
6905 new origin[3];
6906 new Float:vOrigin[3];
6907
6908 //get the origin of the player and add Z offset
6909 get_user_origin(id, origin, 3);
6910 IVecFVec(origin, vOrigin);
6911 vOrigin[2] += gfBlockSizeMaxForZ[2];
6912
6913 //get creators name
6914 new Creator[32];
6915 get_user_name(id, Creator, 32);
6916
6917 //create the block
6918 createBlock(id, blockType, vOrigin, Z, gBlockSize[id],Creator);
6919 }
6920}
6921
6922createBlock(const id, const blockType, Float:vOrigin[3], const axis, const size, Creator[32])
6923{
6924 new ent = create_entity(gszInfoTarget);
6925
6926 //make sure entity was created successfully
6927 if (is_valid_ent(ent))
6928 {
6929 //set block properties
6930 entity_set_string(ent, EV_SZ_classname, gszBlockClassname);
6931 entity_set_int(ent, EV_INT_solid, SOLID_BBOX);
6932 entity_set_int(ent, EV_INT_movetype, MOVETYPE_NONE);
6933
6934 new Float:vSizeMin[3];
6935 new Float:vSizeMax[3];
6936 new Float:vAngles[3];
6937 new Float:fScale;
6938 new szBlockModel[256];
6939
6940 switch (axis)
6941 {
6942 case X:
6943 {
6944 if (size == POLE) {
6945 vSizeMin = g_pole_size_min_x;
6946 vSizeMax = g_pole_size_max_x;
6947 } else {
6948 vSizeMin = gfBlockSizeMinForX;
6949 vSizeMax = gfBlockSizeMaxForX;
6950 }
6951
6952 vAngles[0] = 90.0;
6953 }
6954
6955 case Y:
6956 {
6957 if (size == POLE) {
6958 vSizeMin = g_pole_size_min_y;
6959 vSizeMax = g_pole_size_max_y;
6960 } else {
6961 vSizeMin = gfBlockSizeMinForY;
6962 vSizeMax = gfBlockSizeMaxForY;
6963 }
6964
6965 vAngles[0] = 90.0;
6966 vAngles[2] = 90.0;
6967 }
6968
6969 case Z:
6970 {
6971 if (size == POLE) {
6972 vSizeMin = g_pole_size_min_z;
6973 vSizeMax = g_pole_size_max_z;
6974 } else {
6975 vSizeMin = gfBlockSizeMinForZ;
6976 vSizeMax = gfBlockSizeMaxForZ;
6977 }
6978
6979 vAngles = gfDefaultBlockAngles;
6980 }
6981 }
6982
6983
6984 //set block model name and scale depending on size
6985 switch (size)
6986 {
6987 case SMALL:
6988 {
6989 setBlockModelNameSmall(szBlockModel, gszBlockModels[blockType], 256);
6990 fScale = SCALE_SMALL;
6991 }
6992
6993 case NORMAL:
6994 {
6995 szBlockModel = gszBlockModels[blockType];
6996 fScale = SCALE_NORMAL;
6997 }
6998
6999 case LARGE:
7000 {
7001 setBlockModelNameLarge(szBlockModel, gszBlockModels[blockType], 256);
7002 fScale = SCALE_LARGE;
7003 }
7004
7005 case ELARGE:
7006 {
7007 setBlockModelNameElarge(szBlockModel, gszBlockModels[blockType], 256);
7008 fScale = SCALE_ELARGE;
7009 }
7010
7011 case JUMBO:
7012 {
7013 setBlockModelNameJumbo(szBlockModel, gszBlockModels[blockType], 256);
7014 fScale = SCALE_JUMBO;
7015 }
7016
7017 case POLE:
7018 {
7019 setBlockModelNamePole(szBlockModel, gszBlockModels[blockType], 256);
7020 fScale = SCALE_POLE;
7021 }
7022 }
7023
7024 //adjust size min/max vectors depending on scale
7025 if (size != POLE) {
7026 for (new i = 0; i < 3; ++i)
7027 {
7028 if (vSizeMin[i] != 4.0 && vSizeMin[i] != -4.0)
7029 {
7030 vSizeMin[i] *= fScale;
7031 }
7032
7033 if (vSizeMax[i] != 4.0 && vSizeMax[i] != -4.0)
7034 {
7035 vSizeMax[i] *= fScale;
7036 }
7037 }
7038 }
7039
7040 //if it's a valid block type
7041 if (blockType >= 0 && blockType < gBlockMax)
7042 {
7043 entity_set_model(ent, szBlockModel);
7044 }
7045 else
7046 {
7047 entity_set_model(ent, gszBlockModelDefault);
7048 }
7049
7050 entity_set_vector(ent, EV_VEC_angles, vAngles);
7051 entity_set_size(ent, vSizeMin, vSizeMax);
7052 entity_set_int(ent, EV_INT_body, blockType);
7053
7054 //if a player is creating the block
7055 if (id > 0 && id <= 32)
7056 {
7057 //do snapping for new block
7058 doSnapping(id, ent, vOrigin);
7059 }
7060
7061 //set the creator of block
7062 get_user_name(id, Creator, 31);
7063 set_pev(ent, pev_targetname, Creator, 31);
7064
7065 //set origin of new block
7066 entity_set_origin(ent, vOrigin);
7067
7068 //setup special properties for the random block
7069 if (blockType == BM_RANDOM)
7070 {
7071 //set this random block to a random block!
7072 new randNum = random_num(0, gRandomBlocksMax - 1);
7073 entity_set_int(ent, EV_INT_iuser4, gRandomBlocks[randNum]);
7074 }
7075
7076 //set rendering on block
7077 set_block_rendering(ent, gRender[blockType], gRed[blockType], gGreen[blockType], gBlue[blockType], gAlpha[blockType]);
7078
7079
7080 return ent;
7081 }
7082 //Code to set start spot
7083
7084
7085
7086
7087
7088 return 0;
7089}
7090
7091convertBlockAiming(id, const convertTo)
7092{
7093 //make sure player has access to this command
7094 if (get_user_flags(id) & BM_ADMIN_LEVEL)
7095 {
7096 //get entity that player is aiming at
7097 new ent, body;
7098 get_user_aiming(id, ent, body);
7099
7100 //if player is aiming at a block
7101 if (isBlock(ent))
7102 {
7103 //get who is currently grabbing the block (if anyone)
7104 new grabber = entity_get_int(ent, EV_INT_iuser2);
7105
7106 //if entity is not being grabbed by someone else
7107 if (grabber == 0 || grabber == id)
7108 {
7109 //get the player ID of who has the block in a group (if anyone)
7110 new player = entity_get_int(ent, EV_INT_iuser1);
7111
7112 //if the block is not in a group or is in this players group
7113 if (player == 0 || player == id)
7114 {
7115 new newBlock;
7116
7117 //if block is in the players group and group count is larger than 1
7118 if (isBlockInGroup(id, ent) && gGroupCount[id] > 1)
7119 {
7120 new block;
7121 new blockCount = 0;
7122
7123 //iterate through all blocks in the players group
7124 for (new i = 0; i <= gGroupCount[id]; ++i)
7125 {
7126 block = gGroupedBlocks[id][i];
7127
7128 //if this block is in this players group
7129 if (isBlockInGroup(id, block))
7130 {
7131 //convert the block
7132 newBlock = convertBlock(id, block, convertTo, true);
7133
7134 //if block was converted
7135 if (newBlock != 0)
7136 {
7137 //new block is now in the group
7138 gGroupedBlocks[id][i] = newBlock;
7139
7140 //set the block so it is now 'being grouped'
7141 groupBlock(id, newBlock);
7142 }
7143 //count how many blocks could NOT be converted
7144 else
7145 {
7146 ++blockCount;
7147 }
7148 }
7149 }
7150
7151 //if some blocks could NOT be converted
7152 if (blockCount > 1)
7153 {
7154 client_print(id, print_chat, "%sCouldn't convert %d blocks!", gszPrefix, blockCount);
7155 }
7156 }
7157 else
7158 {
7159 newBlock = convertBlock(id, ent, convertTo, false);
7160
7161 //if block was not converted
7162 if (newBlock == 0)
7163 {
7164 //get the block type
7165 new blockType = entity_get_int(ent, EV_INT_body);
7166
7167 client_print(id, print_chat, "%sYou cannot convert a %s block into a %s block while it is rotated!", gszPrefix, gszBlockNames[blockType], gszBlockNames[convertTo]);
7168 }
7169 }
7170 }
7171 else
7172 {
7173 //get name of player who has this block in their group
7174 new szName[32];
7175 get_user_name(player, szName, 32);
7176
7177 //notify player who has this block in their group
7178 client_print(id, print_chat, "%s%s currently has this block in their group!", gszPrefix, szName);
7179 }
7180 }
7181 }
7182 }
7183}
7184
7185convertBlock(id, ent, const convertTo, const bool:bPreserveSize)
7186{
7187 new blockType;
7188 new Float:vOrigin[3];
7189 new Float:vSizeMax[3];
7190 new axis;
7191
7192 //get block information from block player is aiming at
7193 blockType = entity_get_int(ent, EV_INT_body);
7194 entity_get_vector(ent, EV_VEC_origin, vOrigin);
7195 entity_get_vector(ent, EV_VEC_maxs, vSizeMax);
7196
7197 //work out the axis orientation
7198 for (new i = 0; i < 3; ++i)
7199 {
7200 if (vSizeMax[i] == 4.0)
7201 {
7202 axis = i;
7203 break;
7204 }
7205 }
7206
7207 //if block is rotated and we're trying to convert it to a block that cannot be rotated
7208 if ((axis == X || axis == Y) && !isBlockTypeRotatable(blockType))
7209 {
7210 return 0;
7211 }
7212 else
7213 {
7214 //delete old block and create new one of given type
7215 deleteBlock(ent);
7216
7217 //get creators name
7218 new Creator[32];
7219 get_user_name(id, Creator, 32);
7220
7221 if (bPreserveSize)
7222 {
7223 //work out the block size
7224 new size = SMALL;
7225 new Float:fMax = vSizeMax[0] + vSizeMax[1] + vSizeMax[2];
7226 if (fMax > 36.0) size = POLE;
7227 if (fMax > 64.0) size = NORMAL;
7228 if (fMax > 128.0) size = LARGE;
7229 if (fMax > 192.0) size = ELARGE;
7230 if (fMax > 300.0) size = JUMBO;
7231
7232 return createBlock(id, convertTo, vOrigin, axis, size,Creator);
7233 }
7234 else
7235 {
7236 return createBlock(id, convertTo, vOrigin, axis, gBlockSize[id],Creator);
7237 }
7238 }
7239
7240 return ent;
7241}
7242
7243deleteBlockAiming(id)
7244{
7245 //make sure player has access to this command
7246 if (get_user_flags(id) & BM_ADMIN_LEVEL)
7247 {
7248 //get entity that player is aiming at
7249 new ent, body;
7250 get_user_aiming(id, ent, body);
7251
7252 //if entity player is aiming at is a block
7253 if (isBlock(ent))
7254 {
7255 //get who is currently grabbing the block (if anyone)
7256 new grabber = entity_get_int(ent, EV_INT_iuser2);
7257
7258 //if entity is not being grabbed by someone else
7259 if (grabber == 0 || grabber == id)
7260 {
7261 //get the player ID of who has the block in a group (if anyone)
7262 new player = entity_get_int(ent, EV_INT_iuser1);
7263
7264 //if the block is not in a group or is in this players group
7265 if (player == 0 || player == id)
7266 {
7267 //if block is not being grabbed
7268 if (entity_get_int(ent, EV_INT_iuser2) == 0)
7269 {
7270 //if block is in the players group and group count is larger than 1
7271 if (isBlockInGroup(id, ent) && gGroupCount[id] > 1)
7272 {
7273 new block;
7274
7275 //iterate through all blocks in the players group
7276 for (new i = 0; i <= gGroupCount[id]; ++i)
7277 {
7278 block = gGroupedBlocks[id][i];
7279
7280 //if block is still valid
7281 if (is_valid_ent(block))
7282 {
7283 //get player id of who has this block in their group
7284 new player = entity_get_int(block, EV_INT_iuser1);
7285
7286 //if block is still in this players group
7287 if (player == id)
7288 {
7289 //delete the block
7290 deleteBlock(block);
7291 }
7292 }
7293 }
7294 }
7295 else
7296 {
7297 //delete the block
7298 deleteBlock(ent);
7299 }
7300 }
7301 }
7302 else
7303 {
7304 //get name of player who has this block in their group
7305 new szName[32];
7306 get_user_name(player, szName, 32);
7307
7308 //notify player who has this block in their group
7309 client_print(id, print_chat, "%s%s currently has this block in their group!", gszPrefix, szName);
7310 }
7311 }
7312 }
7313 }
7314}
7315
7316bool:deleteBlock(ent)
7317{
7318 //if entity is a block
7319 if (isBlock(ent))
7320 {
7321 //get the sprite attached to the top of the block
7322 new sprite = entity_get_int(ent, EV_INT_iuser3);
7323
7324 //if sprite entity is valid
7325 if (sprite)
7326 {
7327 //remove the task for the animation of the sprite (if one exists)
7328 if (task_exists(TASK_SPRITE + sprite))
7329 {
7330 remove_task(TASK_SPRITE + sprite);
7331 }
7332
7333 //delete the sprite
7334 remove_entity(sprite);
7335 }
7336
7337 //delete the block
7338 remove_entity(ent);
7339
7340 //block was deleted
7341 return true;
7342 }
7343
7344 //block was not deleted
7345 return false;
7346}
7347
7348rotateBlockAiming(id)
7349{
7350 //make sure player has access to this command
7351 if (get_user_flags(id) & BM_ADMIN_LEVEL)
7352 {
7353 //get block that player is aiming at
7354 new ent, body;
7355 get_user_aiming(id, ent, body);
7356
7357 //if entity found is a block
7358 if (isBlock(ent))
7359 {
7360 //get who is currently grabbing the block (if anyone)
7361 new grabber = entity_get_int(ent, EV_INT_iuser2);
7362
7363 //if entity is not being grabbed by someone else
7364 if (grabber == 0 || grabber == id)
7365 {
7366 //get the player ID of who has the block in a group (if anyone)
7367 new player = entity_get_int(ent, EV_INT_iuser1);
7368
7369 //if the block is not in a group or is in this players group
7370 if (player == 0 || player == id)
7371 {
7372 //if block is in the players group and group count is larger than 1
7373 if (isBlockInGroup(id, ent) && gGroupCount[id] > 1)
7374 {
7375 new block;
7376 new bool:bRotateGroup = true;
7377
7378 //iterate through all blocks in the players group
7379 for (new i = 0; i <= gGroupCount[id]; ++i)
7380 {
7381 block = gGroupedBlocks[id][i];
7382
7383 //if block is in players group
7384 if (isBlockInGroup(id, block))
7385 {
7386 //get block type
7387 new blockType = entity_get_int(block, EV_INT_body);
7388
7389 //if block cannot be rotated
7390 if (!isBlockTypeRotatable(blockType))
7391 {
7392 //found a block that cannot be rotated
7393 bRotateGroup = false;
7394
7395 break;
7396 }
7397 }
7398 }
7399
7400 //if we can rotate the group
7401 if (bRotateGroup)
7402 {
7403 //iterate through all blocks in the players group
7404 for (new i = 0; i <= gGroupCount[id]; ++i)
7405 {
7406 block = gGroupedBlocks[id][i];
7407
7408 //if block is still valid
7409 if (isBlockInGroup(id, block))
7410 {
7411 //rotate the block
7412 rotateBlock(block);
7413 }
7414 }
7415 }
7416 else
7417 {
7418 //notify player that their group cannot be rotated
7419 client_print(id, print_chat, "%sYour group contains blocks that cannot be rotated!", gszPrefix);
7420 }
7421 }
7422 else
7423 {
7424 //rotate the block and get rotated block ID
7425 new bool:bRotatedBlock = rotateBlock(ent);
7426
7427 //if block did not rotate successfully
7428 if (!bRotatedBlock)
7429 {
7430 //get block type
7431 new blockType = entity_get_int(ent, EV_INT_body);
7432
7433 //notify player block couldn't rotate
7434 client_print(id, print_chat, "%s%s blocks cannot be rotated!", gszPrefix, gszBlockNames[blockType]);
7435 }
7436 }
7437 }
7438 else
7439 {
7440 //get name of player who has this block in their group
7441 new szName[32];
7442 get_user_name(player, szName, 32);
7443
7444 //notify player who has this block in their group
7445 client_print(id, print_chat, "%s%s currently has this block in their group!", gszPrefix, szName);
7446 }
7447 }
7448 }
7449 }
7450}
7451
7452bool:rotateBlock(ent)
7453{
7454 //if entity is valid
7455 if (is_valid_ent(ent))
7456 {
7457 //get block type
7458 new blockType = entity_get_int(ent, EV_INT_body);
7459
7460 //if block is a type that can be rotated (a block without a sprite, makes it easier!)
7461 if (isBlockTypeRotatable(blockType))
7462 {
7463 new Float:vAngles[3];
7464 new Float:vSizeMin[3];
7465 new Float:vSizeMax[3];
7466 new Float:fTemp;
7467
7468 //get block information
7469 entity_get_vector(ent, EV_VEC_angles, vAngles);
7470 entity_get_vector(ent, EV_VEC_mins, vSizeMin);
7471 entity_get_vector(ent, EV_VEC_maxs, vSizeMax);
7472
7473 //create new block using current block information with new angles and sizes
7474 if (vAngles[0] == 0.0 && vAngles[2] == 0.0)
7475 {
7476 vAngles[0] = 90.0;
7477 }
7478 else if (vAngles[0] == 90.0 && vAngles[2] == 0.0)
7479 {
7480 vAngles[0] = 90.0;
7481 vAngles[2] = 90.0;
7482 }
7483 else
7484 {
7485 vAngles = gfDefaultBlockAngles;
7486 }
7487
7488 //shift vector values along
7489 fTemp = vSizeMin[0];
7490 vSizeMin[0] = vSizeMin[2];
7491 vSizeMin[2] = vSizeMin[1];
7492 vSizeMin[1] = fTemp;
7493
7494 fTemp = vSizeMax[0];
7495 vSizeMax[0] = vSizeMax[2];
7496 vSizeMax[2] = vSizeMax[1];
7497 vSizeMax[1] = fTemp;
7498
7499 //set the blocks new angle
7500 entity_set_vector(ent, EV_VEC_angles, vAngles);
7501
7502 //set the blocks new size
7503 entity_set_size(ent, vSizeMin, vSizeMax);
7504
7505 return true;
7506 }
7507 }
7508
7509 return false;
7510}
7511
7512copyBlock(id, ent)
7513{
7514 //if entity is valid
7515 if (is_valid_ent(ent))
7516 {
7517 new Float:vOrigin[3];
7518 new Float:vAngles[3];
7519 new Float:vSizeMin[3];
7520 new Float:vSizeMax[3];
7521 new Float:fMax;
7522 new blockType;
7523 new size;
7524 new axis;
7525 new Creator[32];
7526
7527 //set the creator of block
7528 get_user_name(id, Creator, 31);
7529 set_pev(ent, pev_targetname, Creator, 31);
7530
7531 //get blocktype and origin of currently grabbed block
7532 blockType = entity_get_int(ent, EV_INT_body);
7533 entity_get_vector(ent, EV_VEC_origin, vOrigin);
7534 entity_get_vector(ent, EV_VEC_angles, vAngles);
7535 entity_get_vector(ent, EV_VEC_mins, vSizeMin);
7536 entity_get_vector(ent, EV_VEC_maxs, vSizeMax);
7537
7538 //work out the block size
7539 size = SMALL;
7540 fMax = vSizeMax[0] + vSizeMax[1] + vSizeMax[2];
7541 if (fMax > 36.0) size = POLE;
7542 if (fMax > 64.0) size = NORMAL;
7543 if (fMax > 128.0) size = LARGE;
7544 if (fMax > 192.0) size = ELARGE;
7545 if (fMax > 300.0) size = JUMBO;
7546
7547 //work out the axis orientation
7548 if (size == POLE) {
7549 if (vSizeMin[0] == g_pole_size_min_x[0] && vSizeMin[1] == g_pole_size_min_x[1] && vSizeMin[2] == g_pole_size_min_x[2] && vSizeMax[0] == g_pole_size_max_x[0] && vSizeMax[1] == g_pole_size_max_x[1] && vSizeMax[2] == g_pole_size_max_x[2]) {
7550 axis = X;
7551 } else if (vSizeMin[0] == g_pole_size_min_y[0] && vSizeMin[1] == g_pole_size_min_y[1] && vSizeMin[2] == g_pole_size_min_y[2] && vSizeMax[0] == g_pole_size_max_y[0] && vSizeMax[1] == g_pole_size_max_y[1] && vSizeMax[2] == g_pole_size_max_y[2]) {
7552 axis = Y;
7553 } else if (vSizeMin[0] == g_pole_size_min_z[0] && vSizeMin[1] == g_pole_size_min_z[1] && vSizeMin[2] == g_pole_size_min_z[2] && vSizeMax[0] == g_pole_size_max_z[0] && vSizeMax[1] == g_pole_size_max_z[1] && vSizeMax[2] == g_pole_size_max_z[2]) {
7554 axis = Z;
7555 }
7556 } else {
7557 for (new i = 0; i < 3; ++i)
7558 {
7559 if (vSizeMax[i] == 4.0)
7560 {
7561 axis = i;
7562 break;
7563 }
7564 }
7565 }
7566
7567 //create a block of the same type in the same location
7568 return createBlock(0, blockType, vOrigin, axis, size,Creator);
7569 }
7570
7571 return 0;
7572}
7573
7574set_block_rendering(ent, type, red, green, blue, alpha)
7575{
7576 if (isBlock(ent))
7577 {
7578 switch (type)
7579 {
7580 case GLOWSHELL: set_rendering(ent, kRenderFxGlowShell, red, green, blue, kRenderNormal, alpha);
7581 case TRANSCOLOR: set_rendering(ent, kRenderFxGlowShell, red, green, blue, kRenderTransColor, alpha);
7582 case TRANSALPHA: set_rendering(ent, kRenderFxNone, red, green, blue, kRenderTransColor, alpha);
7583 case TRANSWHITE: set_rendering(ent, kRenderFxNone, red, green, blue, kRenderTransAdd, alpha);
7584 default: set_rendering(ent, kRenderFxNone, red, green, blue, kRenderNormal, alpha);
7585 }
7586 }
7587}
7588
7589/* BLOCK TESTS */
7590bool:isBlockInGroup(id, ent)
7591{
7592 //is entity valid
7593 if (is_valid_ent(ent))
7594 {
7595 //get player who has this block in their group (if anyone)
7596 new player = entity_get_int(ent, EV_INT_iuser1);
7597
7598 if (player == id)
7599 {
7600 return true;
7601 }
7602 }
7603
7604 return false;
7605}
7606
7607bool:isBlockTypeRotatable(blockType)
7608{
7609 if (blockType != BM_FIRE)
7610 {
7611 return true;
7612 }
7613
7614 return false;
7615}
7616
7617bool:isBlock(ent)
7618{
7619 //is it a valid entity
7620 if (is_valid_ent(ent))
7621 {
7622 //get classname of entity
7623 new szClassname[32];
7624 entity_get_string(ent, EV_SZ_classname, szClassname, 32);
7625
7626 //if classname of entity matches global block classname
7627 if (equal(szClassname, gszBlockClassname) || equal(szClassname, "bcm"))
7628 {
7629 //entity is a block
7630 return true;
7631 }
7632 }
7633
7634 //entity is not a block
7635 return false;
7636}
7637
7638bool:isTimer(ent)
7639{
7640 //is it a valid entity
7641 if (is_valid_ent(ent))
7642 {
7643 //get classname of entity
7644 new szClassname[32];
7645 entity_get_string(ent, EV_SZ_classname, szClassname, 32);
7646
7647 //if classname of entity matches global timer classname
7648 if (equal(szClassname, gszTimerClassname))
7649 {
7650 //entity is a timer
7651 return true;
7652 }
7653 }
7654
7655 //entity is not a timer
7656 return false;
7657}
7658
7659bool:isBlockStuck(ent)
7660{
7661 //first make sure the entity is valid
7662 if (is_valid_ent(ent))
7663 {
7664 new content;
7665 new Float:vOrigin[3];
7666 new Float:vPoint[3];
7667 new Float:fSizeMin[3];
7668 new Float:fSizeMax[3];
7669
7670 //get the size of the block being grabbed
7671 entity_get_vector(ent, EV_VEC_mins, fSizeMin);
7672 entity_get_vector(ent, EV_VEC_maxs, fSizeMax);
7673
7674 //get the origin of the block
7675 entity_get_vector(ent, EV_VEC_origin, vOrigin);
7676
7677 //decrease the size values of the block
7678 fSizeMin[0] += 1.0;
7679 fSizeMax[0] -= 1.0;
7680 fSizeMin[1] += 1.0;
7681 fSizeMax[1] -= 1.0;
7682 fSizeMin[2] += 1.0;
7683 fSizeMax[2] -= 1.0;
7684
7685 //get the contents of the centre of all 6 faces of the block
7686 for (new i = 0; i < 14; ++i)
7687 {
7688 //start by setting the point to the origin of the block (the middle)
7689 vPoint = vOrigin;
7690
7691 //set the values depending on the loop number
7692 switch (i)
7693 {
7694 //corners
7695 case 0: { vPoint[0] += fSizeMax[0]; vPoint[1] += fSizeMax[1]; vPoint[2] += fSizeMax[2]; }
7696 case 1: { vPoint[0] += fSizeMin[0]; vPoint[1] += fSizeMax[1]; vPoint[2] += fSizeMax[2]; }
7697 case 2: { vPoint[0] += fSizeMax[0]; vPoint[1] += fSizeMin[1]; vPoint[2] += fSizeMax[2]; }
7698 case 3: { vPoint[0] += fSizeMin[0]; vPoint[1] += fSizeMin[1]; vPoint[2] += fSizeMax[2]; }
7699 case 4: { vPoint[0] += fSizeMax[0]; vPoint[1] += fSizeMax[1]; vPoint[2] += fSizeMin[2]; }
7700 case 5: { vPoint[0] += fSizeMin[0]; vPoint[1] += fSizeMax[1]; vPoint[2] += fSizeMin[2]; }
7701 case 6: { vPoint[0] += fSizeMax[0]; vPoint[1] += fSizeMin[1]; vPoint[2] += fSizeMin[2]; }
7702 case 7: { vPoint[0] += fSizeMin[0]; vPoint[1] += fSizeMin[1]; vPoint[2] += fSizeMin[2]; }
7703
7704 //centre of faces
7705 case 8: { vPoint[0] += fSizeMax[0]; }
7706 case 9: { vPoint[0] += fSizeMin[0]; }
7707 case 10: { vPoint[1] += fSizeMax[1]; }
7708 case 11: { vPoint[1] += fSizeMin[1]; }
7709 case 12: { vPoint[2] += fSizeMax[2]; }
7710 case 13: { vPoint[2] += fSizeMin[2]; }
7711 }
7712
7713 //get the contents of the point on the block
7714 content = point_contents(vPoint);
7715
7716 //if the point is out in the open
7717 if (content == CONTENTS_EMPTY || content == 0)
7718 {
7719 //block is not stuck
7720 return false;
7721 }
7722 }
7723 }
7724 else
7725 {
7726 //entity is invalid but don't say its stuck
7727 return false;
7728 }
7729
7730 //block is stuck
7731 return true;
7732}
7733
7734bool:isTeleport(ent)
7735{
7736 if (is_valid_ent(ent))
7737 {
7738 //get classname of entity
7739 new szClassname[32];
7740 entity_get_string(ent, EV_SZ_classname, szClassname, 32);
7741
7742 //compare classnames
7743 if (equal(szClassname, gszTeleportStartClassname) || equal(szClassname, gszTeleportEndClassname))
7744 {
7745 //entity is a teleport
7746 return true;
7747 }
7748 }
7749
7750 //entity is not a teleport
7751 return false;
7752}
7753
7754doSnapping(id, ent, Float:fMoveTo[3])
7755{
7756 //if player has snapping enabled
7757 if (gbSnapping[id])
7758 {
7759 new Float:fSnapSize = gfSnapDistance + gfSnappingGap[id];
7760 new Float:vReturn[3];
7761 new Float:dist;
7762 new Float:distOld = 9999.9;
7763 new Float:vTraceStart[3];
7764 new Float:vTraceEnd[3];
7765 new tr;
7766 new trClosest = 0;
7767 new blockFace;
7768
7769 //get the size of the block being grabbed
7770 new Float:fSizeMin[3];
7771 new Float:fSizeMax[3];
7772 entity_get_vector(ent, EV_VEC_mins, fSizeMin);
7773 entity_get_vector(ent, EV_VEC_maxs, fSizeMax);
7774
7775 //do 6 traces out from each face of the block
7776 for (new i = 0; i < 6; ++i)
7777 {
7778 //setup the start of the trace
7779 vTraceStart = fMoveTo;
7780
7781 switch (i)
7782 {
7783 case 0: vTraceStart[0] += fSizeMin[0]; //edge of block on -X
7784 case 1: vTraceStart[0] += fSizeMax[0]; //edge of block on +X
7785 case 2: vTraceStart[1] += fSizeMin[1]; //edge of block on -Y
7786 case 3: vTraceStart[1] += fSizeMax[1]; //edge of block on +Y
7787 case 4: vTraceStart[2] += fSizeMin[2]; //edge of block on -Z
7788 case 5: vTraceStart[2] += fSizeMax[2]; //edge of block on +Z
7789 }
7790
7791 //setup the end of the trace
7792 vTraceEnd = vTraceStart;
7793
7794 switch (i)
7795 {
7796 case 0: vTraceEnd[0] -= fSnapSize;
7797 case 1: vTraceEnd[0] += fSnapSize;
7798 case 2: vTraceEnd[1] -= fSnapSize;
7799 case 3: vTraceEnd[1] += fSnapSize;
7800 case 4: vTraceEnd[2] -= fSnapSize;
7801 case 5: vTraceEnd[2] += fSnapSize;
7802 }
7803
7804 //trace a line out from one of the block faces
7805 tr = trace_line(ent, vTraceStart, vTraceEnd, vReturn);
7806
7807 //if the trace found a block and block is not in group or block to snap to is not in group
7808 if (isBlock(tr) && (!isBlockInGroup(id, tr) || !isBlockInGroup(id, ent)))
7809 {
7810 //get the distance from the grabbed block to the found block
7811 dist = get_distance_f(vTraceStart, vReturn);
7812
7813 //if distance to found block is less than the previous block
7814 if (dist < distOld)
7815 {
7816 trClosest = tr;
7817 distOld = dist;
7818
7819 //save the block face where the trace came from
7820 blockFace = i;
7821 }
7822 }
7823 }
7824
7825 //if there is a block within the snapping range
7826 if (is_valid_ent(trClosest))
7827 {
7828 //get origin of closest block
7829 new Float:vOrigin[3];
7830 entity_get_vector(trClosest, EV_VEC_origin, vOrigin);
7831
7832 //get sizes of closest block
7833 new Float:fTrSizeMin[3];
7834 new Float:fTrSizeMax[3];
7835 entity_get_vector(trClosest, EV_VEC_mins, fTrSizeMin);
7836 entity_get_vector(trClosest, EV_VEC_maxs, fTrSizeMax);
7837
7838 //move the subject block to the origin of the closest block
7839 fMoveTo = vOrigin;
7840
7841 //offset the block to be on the side where the trace hit the closest block
7842 if (blockFace == 0) fMoveTo[0] += (fTrSizeMax[0] + fSizeMax[0]) + gfSnappingGap[id];
7843 if (blockFace == 1) fMoveTo[0] += (fTrSizeMin[0] + fSizeMin[0]) - gfSnappingGap[id];
7844 if (blockFace == 2) fMoveTo[1] += (fTrSizeMax[1] + fSizeMax[1]) + gfSnappingGap[id];
7845 if (blockFace == 3) fMoveTo[1] += (fTrSizeMin[1] + fSizeMin[1]) - gfSnappingGap[id];
7846 if (blockFace == 4) fMoveTo[2] += (fTrSizeMax[2] + fSizeMax[2]) + gfSnappingGap[id];
7847 if (blockFace == 5) fMoveTo[2] += (fTrSizeMin[2] + fSizeMin[2]) - gfSnappingGap[id];
7848 }
7849 }
7850}
7851
7852/***** FILE HANDLING *****/
7853saveBlocks(id)
7854{
7855 //make sure player has access to this command
7856 if (get_user_flags(id) & BM_ADMIN_LEVEL)
7857 {
7858 //Detect if any moving blocks are moving
7859 if (movingblocks == false && movingspot == 0 && movingspotlarge == 0 && movingspotsmall == 0 && flipside == 3)
7860 {
7861 new file = fopen(gszNewFile, "wt");
7862 new ent = -1;
7863 new blockType;
7864 new Float:vOrigin[3];
7865 new Float:vAngles[3];
7866 new Float:vStart[3];
7867 new Float:vEnd[3];
7868 new blockCount = 0;
7869 new teleCount = 0;
7870 new timerCount = 0;
7871 new szData[128];
7872 new Float:fMax;
7873 new size;
7874 new Float:vSizeMax[3];
7875 new Creator[32];
7876
7877 while ((ent = find_ent_by_class(ent, gszBlockClassname)))
7878 {
7879 //get block info
7880 blockType = entity_get_int(ent, EV_INT_body);
7881 entity_get_vector(ent, EV_VEC_origin, vOrigin);
7882 entity_get_vector(ent, EV_VEC_angles, vAngles);
7883 entity_get_vector(ent, EV_VEC_maxs, vSizeMax);
7884
7885 size = SMALL;
7886 fMax = vSizeMax[0] + vSizeMax[1] + vSizeMax[2];
7887 if (fMax > 36.0) size = POLE;
7888 if (fMax > 64.0) size = NORMAL;
7889 if (fMax > 128.0) size = LARGE;
7890 if (fMax > 192.0) size = ELARGE;
7891 if (fMax > 300.0) size = JUMBO;
7892
7893 new blockType = entity_get_int(ent, EV_INT_body);
7894 new Creator[32];
7895
7896 pev(ent, pev_targetname, Creator, 31);
7897
7898 //format block info and save it to file
7899 formatex(szData, 128, "%c %f %f %f %f %f %f %d %s^n", gBlockSaveIds[blockType], vOrigin[0], vOrigin[1], vOrigin[2], vAngles[0], vAngles[1], vAngles[2], size,Creator);
7900 fputs(file, szData);
7901
7902 //increment block count
7903 ++blockCount;
7904 }
7905
7906 //iterate through teleport end entities because you can't have an end without a start
7907 ent = -1;
7908
7909 while ((ent = find_ent_by_class(ent, gszTeleportEndClassname)))
7910 {
7911 //get the id of the start of the teleporter
7912 new tele = entity_get_int(ent, EV_INT_iuser1);
7913
7914 //check that start of teleport is a valid entity
7915 if (tele)
7916 {
7917 //get the origin of the start of the teleport and save it to file
7918 entity_get_vector(tele, EV_VEC_origin, vStart);
7919 entity_get_vector(ent, EV_VEC_origin, vEnd);
7920
7921 formatex(szData, 128, "%c %f %f %f %f %f %f^n", gTeleportSaveId, vStart[0], vStart[1], vStart[2], vEnd[0], vEnd[1], vEnd[2]);
7922 fputs(file, szData);
7923
7924 //2 teleport entities count as 1 teleporter
7925 ++teleCount;
7926 }
7927 }
7928
7929 //iterate through timer end entities because you can't have an end without a start
7930 ent = -1;
7931
7932 while ((ent = find_ent_by_class(ent, gszTimerClassname)))
7933 {
7934 //get the type of timer
7935 new timerType = entity_get_int(ent, EV_INT_body);
7936
7937 //timer type must be an end
7938 if (timerType == TIMER_END)
7939 {
7940 //get the id of the start of the timer
7941 new timer = entity_get_int(ent, EV_INT_iuser1);
7942
7943 //check that start of timer is a valid entity
7944 if (timer)
7945 {
7946 //get the origin of the start of the timer and its angles
7947 entity_get_vector(timer, EV_VEC_origin, vStart);
7948 entity_get_vector(timer, EV_VEC_angles, vAngles);
7949
7950 //save the start timer information to file
7951 formatex(szData, 128, "%c %f %f %f %f %f %f^n", gTimerSaveId, vStart[0], vStart[1], vStart[2], vAngles[0], vAngles[1], vAngles[2]);
7952 fputs(file, szData);
7953
7954 //get the origin of the end of the timer and its angles
7955 entity_get_vector(ent, EV_VEC_origin, vEnd);
7956 entity_get_vector(ent, EV_VEC_angles, vAngles);
7957
7958 //save the end timer information to file
7959 formatex(szData, 128, "%c %f %f %f %f %f %f^n", gTimerSaveId, vEnd[0], vEnd[1], vEnd[2], vAngles[0], vAngles[1], vAngles[2]);
7960 fputs(file, szData);
7961
7962 //2 timer entities count as 1 timer
7963 ++timerCount;
7964 }
7965 }
7966 }
7967
7968 //get players name
7969 new szName[32];
7970 get_user_name(id, szName, 32);
7971
7972 //notify all admins that the player saved blocks to file
7973 for (new i = 1; i <= 32; ++i)
7974 {
7975 //make sure player is connected
7976 if (is_user_connected(i))
7977 {
7978 if (get_user_flags(i) & BM_ADMIN_LEVEL)
7979 {
7980 client_print(i, print_chat, "%s'%s' saved %d block%s, %d teleporter%s and %d timer%s! Total entites in map: %d", gszPrefix, szName, blockCount, (blockCount == 1 ? "" : "s"), teleCount, (teleCount == 1 ? "" : "s"), timerCount, (timerCount == 1 ? "" : "s"), entity_count());
7981 }
7982 }
7983 }
7984
7985 //close file
7986 fclose(file);
7987 } else {
7988 //if blocks are still moving
7989 if (movingblocks == true)
7990 client_print(id,print_chat, "*ERROR* You can't save unless there are no blocks moving, type /move");
7991 else
7992 client_print(id,print_chat, "*ERROR* Please, wait a bit the moving blocks must stop.");
7993 }
7994 }
7995}
7996
7997loadBlocks(id)
7998{
7999 new bool:bAccess = false;
8000
8001 //if this function was called on map load, ID is 0
8002 if (id == 0)
8003 {
8004 bAccess = true;
8005 }
8006 //make sure user calling this function has access
8007 else if (get_user_flags(id) & BM_ADMIN_LEVEL)
8008 {
8009 bAccess = true;
8010 }
8011
8012 if (bAccess)
8013 {
8014 //if map file exists
8015 if (file_exists(gszNewFile))
8016 {
8017 //if a player is loading then first delete all the old blocks, teleports and timers
8018 if (id > 0 && id <= 32)
8019 {
8020 deleteAllBlocks(id, false);
8021 deleteAllTeleports(id, false);
8022 deleteAllTimers(id, false);
8023 }
8024
8025 new szData[128];
8026 new szType[2];
8027 new sz1[16], sz2[16], sz3[16], sz4[16], sz5[16], sz6[16], sz7[16];
8028 new Float:vVec1[3];
8029 new Float:vVec2[3];
8030 new axis;
8031 new size;
8032 new f = fopen(gszNewFile, "rt");
8033 new blockCount = 0;
8034 new teleCount = 0;
8035 new timerCount = 0;
8036 new bool:bTimerStart = true;
8037 new Float:vTimerOrigin[3];
8038 new Float:vTimerAngles[3];
8039 new Creator[32];
8040 new Creator2[32];
8041
8042 //iterate through all the lines in the file
8043 while (!feof(f))
8044 {
8045 szType = "";
8046 fgets(f, szData, 128);
8047 parse(szData, szType, 1, sz1, 16, sz2, 16, sz3, 16, sz4, 16, sz5, 16, sz6, 16, sz7, 16,Creator2,32);
8048
8049 vVec1[0] = str_to_float(sz1);
8050 vVec1[1] = str_to_float(sz2);
8051 vVec1[2] = str_to_float(sz3);
8052 vVec2[0] = str_to_float(sz4);
8053 vVec2[1] = str_to_float(sz5);
8054 vVec2[2] = str_to_float(sz6);
8055 size = str_to_num(sz7);
8056
8057 client_print(0, print_chat, "A block has been spawn by %s",Creator2);
8058 Creator = Creator2;
8059
8060 if (strlen(szType) > 0)
8061 {
8062 //if type is not a teleport
8063 if (szType[0] != gTeleportSaveId)
8064 {
8065 //set axis orientation depending on block angles
8066 if (vVec2[0] == 90.0 && vVec2[1] == 0.0 && vVec2[2] == 0.0)
8067 {
8068 axis = X;
8069 }
8070 else if (vVec2[0] == 90.0 && vVec2[1] == 0.0 && vVec2[2] == 90.0)
8071 {
8072 axis = Y;
8073 }
8074 else
8075 {
8076 axis = Z;
8077 }
8078
8079 //increment block counter
8080 ++blockCount;
8081 }
8082
8083 //create block or teleport depending on type
8084 switch (szType[0])
8085 {
8086 case 'A': createBlock(0, BM_PLATFORM, vVec1, axis, size,Creator);
8087 case 'B': createBlock(0, BM_BHOP, vVec1, axis, size,Creator);
8088 case 'C': createBlock(0, BM_DAMAGE, vVec1, axis, size,Creator);
8089 case 'D': createBlock(0, BM_HEALER, vVec1, axis, size,Creator);
8090 case 'E': createBlock(0, BM_INVINCIBILITY, vVec1, axis, size,Creator);
8091 case 'F': createBlock(0, BM_STEALTH, vVec1, axis, size,Creator);
8092 case 'G': createBlock(0, BM_TRAMPOLINE, vVec1, axis, size,Creator);
8093 case 'H': createBlock(0, BM_SPEEDBOOST, vVec1, axis, size,Creator);
8094 case 'I': createBlock(0, BM_NOFALLDAMAGE, vVec1, axis, size,Creator);
8095 case 'J': createBlock(0, BM_ICE, vVec1, axis, size,Creator);
8096 case 'K': createBlock(0, BM_DEATH, vVec1, axis, size,Creator);
8097 case 'L': createBlock(0, BM_NUKE, vVec1, axis, size,Creator);
8098 case 'M': createBlock(0, BM_CAMOUFLAGE, vVec1, axis, size,Creator);
8099 case 'N': createBlock(0, BM_LOWGRAVITY, vVec1, axis, size,Creator);
8100 case 'O': createBlock(0, BM_FIRE, vVec1, axis, size,Creator);
8101 case 'P': createBlock(0, BM_SLAP, vVec1, axis, size,Creator);
8102 case 'Q': createBlock(0, BM_RANDOM, vVec1, axis, size,Creator);
8103 case 'R': createBlock(0, BM_HONEY, vVec1, axis, size,Creator);
8104 case 'S': createBlock(0, BM_BARRIER_CT, vVec1, axis, size,Creator);
8105 case 'T': createBlock(0, BM_BARRIER_T, vVec1, axis, size,Creator);
8106 case 'U': createBlock(0, BM_BOOTSOFSPEED, vVec1, axis, size,Creator);
8107 case 'V': createBlock(0, BM_GLASS, vVec1, axis, size,Creator);
8108 case 'W': createBlock(0, BM_BHOP_NOSLOW, vVec1, axis, size,Creator);
8109 case 'X': createBlock(0, BM_AUTO_BHOP, vVec1, axis, size,Creator);
8110 case 'Y': createBlock(0, BM_DEAGLE, vVec1, axis, size,Creator);
8111 case 'Z': createBlock(0, BM_AWP, vVec1, axis, size,Creator);
8112 case 'a': createBlock(0, BM_DAMAGEBHOP, vVec1, axis, size,Creator);
8113 case 'b': createBlock(0, BM_FROST, vVec1, axis, size,Creator);
8114 case 'c': createBlock(0, BM_FLASH, vVec1, axis, size,Creator);
8115 case 'd': createBlock(0, BM_HE, vVec1, axis, size,Creator);
8116 case 'e': createBlock(0, BM_MONEY, vVec1, axis, size,Creator);
8117 case 'f': createBlock(0, BM_LOWTRAMP, vVec1, axis, size,Creator);
8118 case 'g': createBlock(0, BM_HIGHTRAMP, vVec1, axis, size,Creator);
8119 case 'h': createBlock(0, BM_USP, vVec1, axis, size,Creator);
8120
8121 case 'i': createBlock(0, BM_AK47, vVec1, axis, size,Creator);
8122 case 'j': createBlock(0, BM_M4A1, vVec1, axis, size,Creator);
8123 case 'k': createBlock(0, BM_MP5, vVec1, axis, size,Creator);
8124 case 'l': createBlock(0, BM_M3, vVec1, axis, size,Creator);
8125 case 'm': createBlock(0, BM_SCOUT, vVec1, axis, size,Creator);
8126
8127 case 'n': createBlock(0, BM_BLIND, vVec1, axis, size,Creator);
8128 case 'o': createBlock(0, BM_XP, vVec1, axis, size,Creator);
8129 case 'p': createBlock(0, BM_PET, vVec1, axis, size,Creator);
8130
8131 case 'q': createBlock(0, BM_BLINDDAMAGE, vVec1, axis, size,Creator);
8132 case 'r': createBlock(0, BM_BHOPUNDERBLOCK, vVec1, axis, size,Creator);
8133
8134 case 's': createBlock(0, BM_SMALLMOVINGX, vVec1, axis, size,Creator);
8135 case 't': createBlock(0, BM_MOVINGX, vVec1, axis, size,Creator);
8136 case 'u': createBlock(0, BM_LARGEMOVINGX, vVec1, axis, size,Creator);
8137 case 'v': createBlock(0, BM_SMALLMOVINGY, vVec1, axis, size,Creator);
8138 case 'w': createBlock(0, BM_MOVINGY, vVec1, axis, size,Creator);
8139 case 'x': createBlock(0, BM_LARGEMOVINGY, vVec1, axis, size,Creator);
8140 case 'y': createBlock(0, BM_SMALLMOVINGZ, vVec1, axis, size,Creator);
8141 case 'z': createBlock(0, BM_MOVINGZ, vVec1, axis, size,Creator);
8142 case '1': createBlock(0, BM_LARGEMOVINGZ, vVec1, axis, size,Creator);
8143
8144 case '2': createBlock(0, BM_SMALLMOVINGPLATX, vVec1, axis, size,Creator);
8145 case '3': createBlock(0, BM_MOVINGPLATX, vVec1, axis, size,Creator);
8146 case '4': createBlock(0, BM_LARGEMOVINGPLATX, vVec1, axis, size,Creator);
8147 case '5': createBlock(0, BM_SMALLMOVINGPLATY, vVec1, axis, size,Creator);
8148 case '6': createBlock(0, BM_MOVINGPLATY, vVec1, axis, size,Creator);
8149 case '7': createBlock(0, BM_LARGEMOVINGPLATY, vVec1, axis, size,Creator);
8150 case '8': createBlock(0, BM_SMALLMOVINGPLATZ, vVec1, axis, size,Creator);
8151 case '9': createBlock(0, BM_MOVINGPLATZ, vVec1, axis, size,Creator);
8152 case '0': createBlock(0, BM_LARGEMOVINGPLATZ, vVec1, axis, size,Creator);
8153
8154 case ':': createBlock(0, BM_SMALLMOVINGTRAMPX, vVec1, axis, size,Creator);
8155 case ';': createBlock(0, BM_MOVINGTRAMPX, vVec1, axis, size,Creator);
8156 case '<': createBlock(0, BM_LARGEMOVINGTRAMPX, vVec1, axis, size,Creator);
8157 case '>': createBlock(0, BM_SMALLMOVINGTRAMPY, vVec1, axis, size,Creator);
8158 case '=': createBlock(0, BM_MOVINGTRAMPY, vVec1, axis, size,Creator);
8159 case '?': createBlock(0, BM_LARGEMOVINGTRAMPY, vVec1, axis, size,Creator);
8160 case ']': createBlock(0, BM_SMALLMOVINGTRAMPZ, vVec1, axis, size,Creator);
8161 case '[': createBlock(0, BM_MOVINGTRAMPZ, vVec1, axis, size,Creator);
8162 case '/': createBlock(0, BM_LARGEMOVINGTRAMPZ, vVec1, axis, size,Creator);
8163
8164 case '!': createBlock(0, BM_SHIELD, vVec1, axis, size,Creator);
8165 case '@': createBlock(0, BM_SLAPSHIELD, vVec1, axis, size,Creator);
8166
8167 case '#': createBlock(0, BM_FOLLOWBHOPXPLUS, vVec1, axis, size,Creator);
8168 case '$': createBlock(0, BM_FOLLOWBHOPXMINUS, vVec1, axis, size,Creator);
8169 case '%': createBlock(0, BM_FOLLOWBHOPYPLUS, vVec1, axis, size,Creator);
8170 case '-': createBlock(0, BM_FOLLOWBHOPYMINUS, vVec1, axis, size,Creator);
8171 case '+': createBlock(0, BM_MAGICCARPET, vVec1, axis, size,Creator);
8172
8173
8174 case gTeleportSaveId:
8175 {
8176 createTeleport(0, TELEPORT_START, vVec1);
8177 createTeleport(0, TELEPORT_END, vVec2);
8178
8179 //increment teleport count
8180 ++teleCount;
8181 }
8182
8183 case gTimerSaveId:
8184 {
8185 //is this the first timer info retrieved from file?
8186 if (bTimerStart)
8187 {
8188 //store start timer info
8189 vTimerOrigin[0] = vVec1[0];
8190 vTimerOrigin[1] = vVec1[1];
8191 vTimerOrigin[2] = vVec1[2];
8192 vTimerAngles[0] = vVec2[0];
8193 vTimerAngles[1] = vVec2[1];
8194 vTimerAngles[2] = vVec2[2];
8195
8196 //the next timer to come along is the end of the timer
8197 bTimerStart = false;
8198 }
8199 else
8200 {
8201 //create the start of timer
8202 createTimer(0, TIMER_START, vTimerOrigin, vTimerAngles);
8203
8204 //create the end of the timer
8205 createTimer(0, TIMER_END, vVec1, vVec2);
8206
8207 //if another timer comes along then it'll be the start again
8208 bTimerStart = true;
8209
8210 //increment timer count
8211 ++timerCount;
8212 }
8213 }
8214
8215 default:
8216 {
8217 log_amx("%sInvalid block type: %c in: %s", gszPrefix, szType[0], gszFile);
8218
8219 //decrement block counter because a block was not created
8220 --blockCount;
8221 }
8222 }
8223 }
8224 }
8225
8226 fclose(f);
8227
8228 //if a player is loading the blocks
8229 if (id > 0 && id <= 32)
8230 {
8231 //get players name
8232 new szName[32];
8233 get_user_name(id, szName, 32);
8234
8235 //notify all admins that the player loaded blocks from file
8236 for (new i = 1; i <= 32; ++i)
8237 {
8238 //make sure player is connected
8239 if (is_user_connected(i))
8240 {
8241 if (get_user_flags(i) & BM_ADMIN_LEVEL)
8242 {
8243 client_print(i, print_chat, "%s'%s' loaded %d block%s, %d teleporter%s and %d timer%s! Total entites in map: %d", gszPrefix, szName, blockCount, (blockCount == 1 ? "" : "s"), teleCount, (teleCount == 1 ? "" : "s"), timerCount, (timerCount == 1 ? "" : "s"), entity_count());
8244 }
8245 }
8246 }
8247 }
8248 }
8249 else
8250 {
8251 //if a player is loading the blocks
8252 if (id > 0 && id <= 32)
8253 {
8254 //notify player that the file could not be found
8255 client_print(id, print_chat, "%sCouldn't find file: %s", gszPrefix, gszNewFile);
8256 }
8257 }
8258 }
8259}
8260
8261/* MISC */
8262drawLine(Float:vOrigin1[3], Float:vOrigin2[3], life)
8263{
8264 message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
8265 write_byte(TE_BEAMPOINTS);
8266 write_coord(floatround(vOrigin1[0], floatround_floor));
8267 write_coord(floatround(vOrigin1[1], floatround_floor));
8268 write_coord(floatround(vOrigin1[2], floatround_floor));
8269 write_coord(floatround(vOrigin2[0], floatround_floor));
8270 write_coord(floatround(vOrigin2[1], floatround_floor));
8271 write_coord(floatround(vOrigin2[2], floatround_floor));
8272 write_short(gSpriteIdBeam); //sprite index
8273 write_byte(0); //starting frame
8274 write_byte(1); //frame rate in 0.1's
8275 write_byte(life); //life in 0.1's
8276 write_byte(5); //line width in 0.1's
8277 write_byte(0); //noise amplitude in 0.01's
8278 write_byte(255); //red
8279 write_byte(255); //green
8280 write_byte(255); //blue
8281 write_byte(255); //brightness
8282 write_byte(0); //scroll speed in 0.1's
8283 message_end();
8284}
8285
8286htmlFriendly(szString[])
8287{
8288 //replace < > in string with HTML friendly characters
8289 while (contain(szString, "<") != -1)
8290 {
8291 replace(szString, 2048, "<", "<");
8292 }
8293
8294 while (contain(szString, ">") != -1)
8295 {
8296 replace(szString, 2048, ">", ">");
8297 }
8298}
8299
8300bool:getFileContents(szFilename[], szContents[])
8301{
8302 new size = file_size(szFilename, 0);
8303 new line = 0;
8304 new length = 0;
8305 new pos;
8306 new szData[128];
8307
8308 if (size > 0)
8309 {
8310 do
8311 {
8312 line = read_file(szFilename, line, szData, size, length);
8313
8314 if (line != 0)
8315 {
8316 pos += format(szContents[pos], 511 - pos, szData);
8317 }
8318
8319 }while (line != 0);
8320
8321 return true;
8322 }
8323
8324 return false;
8325}