AMXX-BG.INFO reapi_stocks.inc Raw include

reapi_stocks.inc

Original include source with line numbers.

Back Download .inc
1 // Copyright © 2017-XXXX Vaqtincha
2
3 // Update 21.08.2022 (Huehue):
4 /* Added:
5 rg_get_user_health()
6 rg_add_user_health()
7 rg_set_user_heath()
8 rg_is_user_first_spawn()
9 rg_is_one_on_one()
10 rg_transfer_money()
11 rg_play_user_sound()
12 client_cmd_ex()
13 rg_get_team_score_diff()
14 rg_get_team_count_diff()
15 rg_set_entity_model()
16 rg_remove_entity()
17 rg_create_explode_grenade()
18 rg_set_entity_skin()
19 rg_get_entity_skin()
20 rg_get_user_noclip()
21 rg_get_user_godmode()
22 is_user_vip()
23 is_happy_hour()
24 rg_get_user_gravity()
25 rg_send_hudmessage()
26 try_precache_player_model()
27 try_precache_sounds()
28
29
30 */
31
32 #if defined _reapi_stocks_included
33 #endinput
34 #endif
35
36 #define _reapi_stocks_included
37
38 #if !defined _reapi_included
39 #include <reapi>
40 #endif
41
42
43 const GRENADES_BIT_SUM = ((1<<_:WEAPON_HEGRENADE)|(1<<_:WEAPON_SMOKEGRENADE)|(1<<_:WEAPON_FLASHBANG))
44 const NOCLIP_WEAPONS_BIT_SUM = (GRENADES_BIT_SUM|(1<<_:WEAPON_KNIFE)|(1<<_:WEAPON_C4))
45 const SECONDARY_WEAPONS_BIT_SUM = ((1<<_:WEAPON_P228)|(1<<_:WEAPON_ELITE)|(1<<_:WEAPON_FIVESEVEN)|(1<<_:WEAPON_USP)|(1<<_:WEAPON_GLOCK18)|(1<<_:WEAPON_DEAGLE))
46 const PRIMARY_WEAPONS_BIT_SUM =
47 (
48 (1<<_:WEAPON_SCOUT)|(1<<_:WEAPON_XM1014)|(1<<_:WEAPON_MAC10)|(1<<_:WEAPON_AUG)|(1<<_:WEAPON_UMP45)|(1<<_:WEAPON_SG550)
49 |(1<<_:WEAPON_GALIL)|(1<<_:WEAPON_FAMAS)|(1<<_:WEAPON_AWP)|(1<<_:WEAPON_MP5N)|(1<<_:WEAPON_M249)|(1<<_:WEAPON_M3)
50 |(1<<_:WEAPON_M4A1)|(1<<_:WEAPON_TMP)|(1<<_:WEAPON_G3SG1)|(1<<_:WEAPON_SG552)|(1<<_:WEAPON_AK47)|(1<<_:WEAPON_P90)
51 )
52
53 const PRIMARY_WEAPONS_WITH_SCOPE_BIT_SUM = (1<<_:WEAPON_SCOUT)|(1<<_:WEAPON_AUG)|(1<<_:WEAPON_SG550)|(1<<_:WEAPON_AWP)|(1<<_:WEAPON_G3SG1)|(1<<_:WEAPON_SG552)
54
55
56 enum GiveAmmoType
57 {
58 GAT_GIVE_AMMO,
59 GAT_SET_AMMO
60 }
61
62 enum AmmoTypes
63 {
64 AMMO_NONE,
65 AMMO_338MAGNUM,
66 AMMO_762NATO,
67 AMMO_556NATOBOX,
68 AMMO_556NATO,
69 AMMO_BUCKSHOT,
70 AMMO_45ACP,
71 AMMO_57MM,
72 AMMO_50AE,
73 AMMO_357SIG,
74 AMMO_9MM,
75 AMMO_FLASHBANG,
76 AMMO_HEGRENADE,
77 AMMO_SMOKEGRENADE,
78 AMMO_C4,
79
80 AMMO_MAX_TYPES
81 }
82
83 enum /* RewardAccount */ // from gamerules.h
84 {
85 REWARD_TARGET_BOMB = 3500,
86 REWARD_VIP_ESCAPED = 3500,
87 REWARD_VIP_ASSASSINATED = 3250,
88 REWARD_TERRORISTS_ESCAPED = 3150,
89 REWARD_CTS_PREVENT_ESCAPE = 3500,
90 REWARD_ESCAPING_TT_NEUTRALIZED = 3250,
91 REWARD_BOMB_DEFUSED = 3250,
92 REWARD_BOMB_PLANTED = 800,
93 REWARD_BOMB_EXPLODED = 3250,
94 REWARD_CTS_WIN = 3000,
95 REWARD_TERRORISTS_WIN = 3000,
96 REWARD_ALL_HOSTAGES_RESCUED = 2500,
97 REWARD_TARGET_BOMB_SAVED = 3250,
98 REWARD_HOSTAGE_NOT_RESCUED = 3250,
99 REWARD_VIP_NOT_ESCAPED = 3250,
100 REWARD_LOSER_BONUS_DEFAULT = 1400,
101 REWARD_LOSER_BONUS_MIN = 1500,
102 REWARD_LOSER_BONUS_MAX = 3000,
103 REWARD_LOSER_BONUS_ADD = 500,
104 REWARD_RESCUED_HOSTAGE = 750,
105 // REWARD_KILLED_ENEMY = 300,
106 // REWARD_KILLED_VIP = 2500,
107 // REWARD_VIP_HAVE_SELF_RESCUED = 2500,
108 // REWARD_TAKEN_HOSTAGE = 1000,
109 REWARD_TOOK_HOSTAGE_ACC = 100,
110 REWARD_TOOK_HOSTAGE = 150,
111 }
112
113 enum
114 {
115 WEATHER_NONE = 0,
116 WEATHER_RAIN,
117 WEATHER_SNOW
118 }
119
120
121 #define rg_is_valid_weapon_id(%1) (WEAPON_P228 <= %1 <= WEAPON_P90 && %1 != WEAPON_GLOCK)
122 #define rg_is_primary_weapon_id(%1) (PRIMARY_WEAPONS_BIT_SUM & (1 << any:%1))
123 #define rg_is_secondary_weapon_id(%1) (SECONDARY_WEAPONS_BIT_SUM & (1 << any:%1))
124 #define rg_is_grenade_weapon_id(%1) (GRENADES_BIT_SUM & (1 << any:%1))
125 #define rg_is_noclip_weapon_id(%1) (NOCLIP_WEAPONS_BIT_SUM & (1 << any:%1))
126 #define rg_is_weapon_with_scope(%1) (PRIMARY_WEAPONS_WITH_SCOPE_BIT_SUM & (1 << any:%1))
127
128 #define rg_is_valid_slot_type(%1) (PRIMARY_WEAPON_SLOT <= %1 <= C4_SLOT)
129 #define rg_is_valid_armoury(%1) (ARMOURY_MP5NAVY <= %1 <= ARMOURY_DEAGLE)
130
131 #define rg_is_valid_rule_id(%1) (RR_CTS_WIN <= %1 < RR_END)
132 #define rg_is_valid_ammo_id(%1) (AMMO_338MAGNUM <= %1 < AMMO_MAX_TYPES)
133 #define rg_is_valid_team(%1) (TEAM_TERRORIST <= get_member(%1, m_iTeam) <= TEAM_CT)
134
135 #define get_bit(%1,%2) (%1 & (1 << (%2 & 31)))
136 #define set_bit(%1,%2) (%1 |= (1 << (%2 & 31)))
137 #define reset_bit(%1,%2) (%1 &= ~(1 << (%2 & 31)))
138 #define invert_bit(%1,%2) (%1 ^= (1 << (%2 & 31)))
139 #define rset_bit(%1,%2,%3) (%3 && (%1 |= (1 << (%2 & 31))) || (%1 &= ~(1 << (%2 & 31)))) // Reset & Set Bit directly
140
141 #define IsNullVector(%0) bool:((%0[0] + %0[1] + %0[2]) == 0.0)
142 #define IsNullString(%0) bool:(%0[0] == EOS)
143
144 #define CLIENT_IN_DUCK 15.0
145 #define CLIENT_NOT_IN_DUCK 35.0
146
147 enum _:XYZ {
148 Float:X,Float:Y,Float:Z
149 };
150
151 enum _:fRGB {
152 Float:fR,Float:fG,Float:fB
153 };
154
155 enum _:RGB {
156 R,G,B
157 };
158
159 /**■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ Other stocks ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
160
161
162 // by s1lent
163 stock rg_map_buy_status(bool:enabled)
164 {
165 new pBuyzone = NULLENT, count
166 while((pBuyzone = rg_find_ent_by_class(pBuyzone, "func_buyzone", .useHashTable = true)))
167 {
168 set_entvar(pBuyzone, var_solid, enabled ? SOLID_TRIGGER : SOLID_NOT)
169 count++
170 }
171
172 // old
173 if(!count)
174 {
175 set_member_game(m_bCTCantBuy, enabled)
176 set_member_game(m_bTCantBuy, enabled)
177 }
178 }
179
180
181 // change roundtime
182 stock rg_set_round_time(const newTime)
183 {
184 new iRoundTime = clamp(newTime, 0, 999)
185
186 set_member_game(m_fRoundStartTime, get_gametime())
187 set_member_game(m_iRoundTimeSecs, iRoundTime)
188
189 static gmsgShowTimer, gmsgRoundTime
190 if(gmsgShowTimer || (gmsgShowTimer = get_user_msgid("ShowTimer")))
191 {
192 message_begin(MSG_ALL, gmsgShowTimer)
193 message_end()
194 }
195
196 if(gmsgRoundTime || (gmsgRoundTime = get_user_msgid("RoundTime")))
197 {
198 message_begin(MSG_ALL, gmsgRoundTime)
199 write_short(iRoundTime)
200 message_end()
201 }
202 }
203
204 stock bool:rg_freezetime_ended(){
205 return !get_member_game(m_bFreezePeriod)
206 }
207
208 stock bool:rg_map_has_bombtarget(){
209 return get_member_game(m_bMapHasBombTarget)
210 }
211
212 stock bool:rg_buytime_expired()
213 {
214 static mp_buytime
215 if(mp_buytime || (mp_buytime = get_cvar_pointer("mp_buytime")))
216 {
217 new Float:flBuyTime = get_pcvar_float(mp_buytime)
218 if(flBuyTime == -1.0) { // no limit
219 return false
220 }
221 if(flBuyTime == 0.0 || (get_gametime() - Float:get_member_game(m_fRoundStartTime) > (flBuyTime * 60))) {
222 return true
223 }
224 }
225
226 return false
227 }
228
229 stock rg_set_round_winner(const WinStatus:st, const iAddPoints = 1)
230 {
231 new ScenarioEventEndRound:Event, ctScore, ttScore
232 switch(st)
233 {
234 case WINSTATUS_CTS: {
235 Event = ROUND_CTS_WIN
236 ctScore = iAddPoints
237 }
238 case WINSTATUS_TERRORISTS: {
239 Event = ROUND_TERRORISTS_WIN
240 ttScore = iAddPoints
241 }
242 case WINSTATUS_DRAW: {
243 Event = ROUND_NONE
244 }
245 default:return
246 }
247
248 rg_round_end(5.0, st, Event)
249
250 if(Event != ROUND_NONE && (ctScore || ttScore)) {
251 rg_update_teamscores(ctScore, ttScore)
252 }
253 }
254
255 // RR_END = reset all rules
256 stock rg_reset_account_rules(RewardRules:iRulesID = RR_END)
257 {
258 static const rgRewardAccountRules[any:RR_END] = {
259 REWARD_CTS_WIN, // RR_CTS_WIN
260 REWARD_TERRORISTS_WIN, // RR_TERRORISTS_WIN
261 REWARD_TARGET_BOMB, // RR_TARGET_BOMB
262 REWARD_VIP_ESCAPED, // RR_VIP_ESCAPED
263 REWARD_VIP_ASSASSINATED, // RR_VIP_ASSASSINATED
264 REWARD_TERRORISTS_ESCAPED, // RR_TERRORISTS_ESCAPED
265 REWARD_CTS_PREVENT_ESCAPE, // RR_CTS_PREVENT_ESCAPE
266 REWARD_ESCAPING_TT_NEUTRALIZED, // RR_ESCAPING_TERRORISTS_NEUTRALIZED
267 REWARD_BOMB_DEFUSED, // RR_BOMB_DEFUSED
268 REWARD_BOMB_PLANTED, // RR_BOMB_PLANTED
269 REWARD_BOMB_EXPLODED, // RR_BOMB_EXPLODED
270 REWARD_ALL_HOSTAGES_RESCUED, // RR_ALL_HOSTAGES_RESCUED
271 REWARD_TARGET_BOMB_SAVED, // RR_TARGET_BOMB_SAVED
272 REWARD_HOSTAGE_NOT_RESCUED, // RR_HOSTAGE_NOT_RESCUED
273 REWARD_VIP_NOT_ESCAPED, // RR_VIP_NOT_ESCAPED
274 REWARD_LOSER_BONUS_DEFAULT, // RR_LOSER_BONUS_DEFAULT
275 REWARD_LOSER_BONUS_MIN, // RR_LOSER_BONUS_MIN
276 REWARD_LOSER_BONUS_MAX, // RR_LOSER_BONUS_MAX
277 REWARD_LOSER_BONUS_ADD, // RR_LOSER_BONUS_ADD
278 REWARD_RESCUED_HOSTAGE, // RR_RESCUED_HOSTAGE
279 REWARD_TOOK_HOSTAGE_ACC, // RR_TOOK_HOSTAGE_ACC
280 REWARD_TOOK_HOSTAGE // RR_TOOK_HOSTAGE
281 }
282
283 if(rg_is_valid_rule_id(iRulesID))
284 {
285 rg_set_account_rules(iRulesID, rgRewardAccountRules[iRulesID])
286 }
287 else if(iRulesID == RR_END)
288 {
289 for(iRulesID = RR_CTS_WIN; iRulesID < RR_END; iRulesID++)
290 {
291 rg_set_account_rules(iRulesID, rgRewardAccountRules[iRulesID])
292 }
293 }
294 }
295
296 /**■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ Player stocks ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
297
298 stock Float:rg_get_user_health(const player) {
299 return Float:get_entvar(player, var_health)
300 }
301
302 stock rg_add_user_health(const player, const Float:hp, Float:fMins = 1.0, Float:fMaxs = 100.0, bool:ClampHp = false) {
303 if (ClampHp)
304 set_entvar(player, var_health, floatclamp((rg_get_user_health(player) + hp), fMins, fMaxs))
305 else
306 set_entvar(player, var_health, rg_get_user_health(player) + hp)
307 }
308
309 stock rg_set_user_health(const player, const Float:hp) {
310 set_entvar(player, var_health, hp)
311 }
312
313 stock rg_set_user_noclip(const player, bool:noclip) {
314 set_entvar(player, var_movetype, noclip ? MOVETYPE_NOCLIP : MOVETYPE_WALK)
315 }
316
317 stock bool:rg_get_user_noclip(const player) {
318 return bool:(get_entvar(player, var_movetype) == MOVETYPE_NOCLIP)
319 }
320
321 stock rg_set_user_godmode(const player, bool:godmode) {
322 set_entvar(player, var_takedamage, godmode ? DAMAGE_NO : DAMAGE_AIM)
323 }
324
325 stock bool:rg_get_user_godmode(const player) {
326 return bool:(get_entvar(player, var_takedamage) == DAMAGE_NO)
327 }
328
329 stock rg_is_user_vip(const player, const flag) {
330 return (get_user_flags(player) & flag)
331 }
332
333 stock bool:is_happy_hour(const start, const end)
334 {
335 static hour
336 time(hour)
337
338 return bool:(start < end ? (start <= hour < end) : (start <= hour || hour < end))
339 }
340
341 /**
342 * Check if it is the first spawn of the player
343 * @NOTE: by Emma Jule
344 *
345 *
346 * @return bool
347 */
348 stock bool:rg_is_user_first_spawn(const player) {
349 return bool:(get_member(player, m_iNumSpawns) == 1)
350 }
351
352 stock bool:rg_is_one_on_one() {
353 new iAliveTs, iAliveCTs
354 rg_initialize_player_counts(iAliveTs, iAliveCTs)
355
356 return bool:(iAliveTs == 1 && iAliveCTs == 1)
357 }
358
359 stock bool:rg_is_last_player_terrorist() {
360 new iAliveTs
361 rg_initialize_player_counts(iAliveTs)
362
363 return bool:(iAliveTs == 1)
364 }
365
366 stock bool:rg_is_last_player_ct() {
367 new iAliveTs, iAliveCTs
368 rg_initialize_player_counts(iAliveTs, iAliveCTs)
369
370 return bool:(iAliveCTs == 1)
371 }
372
373 stock bool:rg_is_last_player() {
374 new iAliveTs, iAliveCTs
375 rg_initialize_player_counts(iAliveTs, iAliveCTs)
376
377 return bool:((iAliveTs == 1 && iAliveCTs > 1) || (iAliveCTs == 1 && iAliveTs > 1))
378 }
379
380 stock rg_play_user_sound(const player = 0, const sound[], bool:bStopSound = false) {
381 if (bStopSound)
382 client_cmd_ex(player, "mp3 stop;stopsound")
383
384 if (containi(sound, ".mp3") != -1)
385 {
386 if (containi(sound, "sound/") != -1)
387 client_cmd_ex(player, "mp3 play ^"%s^"", sound)
388 else
389 client_cmd_ex(player, "mp3 play ^"sound/%s^"", sound)
390 }
391 else
392 client_cmd_ex(player, "spk ^"%s^"", sound)
393 }
394
395 stock client_cmd_ex(id, const command[], any:...)
396 {
397 #pragma unused command
398
399 if (id == 0 || is_user_connected(id))
400 {
401 new szMessage[256]
402
403 format_args(szMessage, charsmax(szMessage), 1)
404
405 message_begin(id == 0 ? MSG_ALL : MSG_ONE, 51, _, id)
406 write_byte(strlen(szMessage) + 2)
407 write_byte(10)
408 write_string(szMessage)
409 message_end()
410 }
411 }
412
413 /*
414 Similar to GodMode
415 */
416 stock rg_set_user_taketamage(const player, bool:take) {
417 set_entvar(player, var_takedamage, take ? DAMAGE_AIM : DAMAGE_NO)
418 }
419
420 stock Float:rg_get_user_maxspeed(const player) {
421 return Float:get_entvar(player, var_maxspeed)
422 }
423 /* Sets player max. speed.
424 */
425 stock rg_set_user_maxspeed(const player, Float:speed = -1.0)
426 {
427 if(speed != -1) // reset
428 set_entvar(player, var_maxspeed, speed)
429 else
430 rg_reset_maxspeed(player)
431 }
432
433 /* Sets player gravity.
434 */
435 stock rg_set_user_gravity(const player, Float:gravity = 1.0) {
436 set_entvar(player, var_gravity, gravity)
437 }
438
439 stock rg_get_user_gravity(const player) {
440 return Float:get_entvar(player, var_gravity)
441 }
442
443 stock rg_set_user_unlimited_ammo(id, bool:unlimited = true) {
444 set_member(id, m_iWeaponInfiniteAmmo, unlimited ? 1 : 0)
445 }
446
447 /* Returns in bitwise (see enum SignalState) form if the user is in a specific map zone.
448 */
449 stock SignalState:rg_get_user_mapzones(const player)
450 {
451 new iSignals[UnifiedSignals]
452 get_member(player, m_signals, iSignals)
453
454 return SignalState:iSignals[US_State]
455 }
456
457 stock bool:rg_user_in_buyzone(const player) {
458 return bool:(rg_get_user_mapzones(player) & SIGNAL_BUY)
459 }
460
461 stock bool:rg_user_in_bombzone(const player) {
462 return bool:((rg_get_user_mapzones(player) & SIGNAL_BOMB) == SIGNAL_BOMB)
463 }
464
465 stock bool:rg_user_in_water(const player) {
466 return bool:(get_entvar(player, var_waterlevel) > 0)
467 }
468
469 stock bool:rg_user_on_ladder(const player) {
470 return bool:(get_entvar(player, var_movetype) == MOVETYPE_FLY)
471 }
472
473 stock bool:rg_get_user_invisibility(const player) {
474 return bool:(get_entvar(player, var_effects) & EF_NODRAW)
475 }
476
477 stock rg_set_user_invisibility(const player, bool:hide = true) {
478 new iFlags = get_entvar(player, var_effects)
479 set_entvar(player, var_effects, hide ? (iFlags |= EF_NODRAW) : (iFlags &= ~EF_NODRAW))
480 }
481
482 /**
483 * Check the WIN differences between CTs and Terrorists
484 * @NOTE: by Emma Jule
485 *
486 *
487 * @return int
488 */
489 stock rg_get_team_score_diff() {
490 return abs(get_member_game(m_iNumTerroristWins) - get_member_game(m_iNumCTWins));
491 }
492
493 /**
494 * Check the team count differences between CTs and Terrorists
495 * @NOTE: by Emma Jule
496 *
497 *
498 * @return int
499 */
500 stock rg_get_team_count_diff() {
501 return abs(get_member_game(m_iNumTerrorist) - get_member_game(m_iNumCT));
502 }
503
504
505 stock rg_get_user_money(const player) {
506 return get_member(player, m_iAccount)
507 }
508
509 stock rg_set_user_money(const player, amount, const bool:bTrackChange = true) {
510 rg_add_account(player, rg_get_user_money(player) + amount, AS_SET, bTrackChange)
511 }
512
513 stock rg_give_user_money(const player, amount, const bool:bTrackChange = true) {
514 rg_add_account(player, amount, AS_ADD, bTrackChange)
515 }
516
517 stock rg_take_user_money(const player, amount, const bool:bTrackChange = true) {
518 rg_add_account(player, -amount, AS_ADD, bTrackChange)
519 }
520
521 stock rg_transfer_money(const player, const sender, const amount, bool:bTrackChange = false) {
522 rg_take_user_money(player, amount, bTrackChange)
523 rg_give_user_money(sender, amount, bTrackChange)
524 }
525
526 stock rg_get_user_next_spraytime(const player, Float:time) {
527 set_member(player, m_flNextDecalTime, get_gametime() + time)
528 }
529
530 stock rg_set_user_sprayframe(const player, frames = -1) {
531 set_member(player, m_nCustomSprayFrames, frames)
532 }
533
534 // Adidasman
535 stock rg_skip_user_vguimenu(const player) {
536 set_member(player, m_bForceShowMenu, true)
537 }
538
539 stock rg_get_user_deaths(const player) {
540 return get_member(player, m_iDeaths)
541 }
542
543 stock rg_get_user_frags(const player) {
544 return get_entvar(player, var_frags)
545 }
546
547 stock rg_set_user_score(const player, frags, deaths, bool:bUpdateTabScore = true) {
548 set_entvar(player, var_frags, float(frags))
549 set_member(player, m_iDeaths, deaths)
550
551 if (bUpdateTabScore)
552 {
553 // Update tabscore
554 message_begin(MSG_BROADCAST, get_user_msgid("ScoreInfo"))
555 write_byte(player)
556 write_short(frags) // Frags
557 write_short(deaths) // Deaths
558 write_short(0)
559 write_short(get_user_team(player))
560 message_end()
561 }
562 }
563
564 stock rg_reset_user_score(const player, bool:bUpdateTabScore = true) {
565 set_entvar(player, var_frags, 0)
566 set_member(player, m_iDeaths, 0)
567
568 if (bUpdateTabScore)
569 {
570 // Update tabscore
571 message_begin(MSG_BROADCAST, get_user_msgid("ScoreInfo"))
572 write_byte(player)
573 write_short(0) // Frags
574 write_short(0) // Deaths
575 write_short(0)
576 write_short(get_user_team(player))
577 message_end()
578 }
579 }
580
581 stock bool:rg_is_user_joined(const player) {
582 return bool:(get_member(player, m_iJoiningState) == JOINED)
583 }
584
585 /* Returns true user has blinded.
586 */
587 stock bool:rg_is_user_blinded(const player) {
588 return bool:(Float:get_member(player, m_blindStartTime) + Float:get_member(player, m_blindFadeTime) >= get_gametime())
589 }
590
591 // original code by ConnorMcLeod 2011 (see: https://forums.alliedmods.net/showpost.php?p=1612876&postcount=2)
592
593 stock rg_get_user_blind_percent(const player)
594 {
595 static const BLINDED_FULLY = 255
596 #define fPercent(%1,%2) 100.0 - (((%1) * 100.0) / %2)
597
598 new Float:flCurTime = get_gametime(),
599 Float:flBlindStartTime = Float:get_member(player, m_blindStartTime),
600 Float:flBlindHoldTime = Float:get_member(player, m_blindHoldTime),
601 Float:flBlindFadeTime = Float:get_member(player, m_blindFadeTime),
602 Float:flEndTime = flBlindFadeTime + flBlindHoldTime
603
604 if((flCurTime - flBlindStartTime) > flEndTime)
605 return 0
606
607 if(get_member(player, m_blindAlpha) == BLINDED_FULLY)
608 {
609 if((flBlindStartTime + flBlindHoldTime) >= flCurTime)
610 return 100 // 100 percent
611
612 return floatround(fPercent(flCurTime - (flBlindStartTime + flBlindHoldTime), flBlindFadeTime))
613 }
614
615 return floatround(fPercent(flCurTime - flBlindStartTime, flEndTime))
616 }
617
618 /* return enum ModelName
619 */
620 stock ModelName:rg_get_user_class(const player) {
621 return get_member(player, m_iModelName)
622 }
623
624 stock TeamName:rg_get_user_team(const player, &{ModelName,_}:model = MODEL_UNASSIGNED)
625 {
626 model = rg_get_user_class(player)
627 return TeamName:get_member(player, m_iTeam)
628 }
629
630
631 /* Does user have night vision goggles?
632 */
633 stock rg_get_user_nvg(const player) {
634 return get_member(player, m_bHasNightVision)
635 }
636
637 /* Set nvgoggles to 1 to give night vision goggles to index. Set it to 0 to remove them.
638 */
639 stock rg_set_user_nvg(const player, bool:nvgoggles = true) {
640 set_member(player, m_bHasNightVision, nvgoggles)
641 }
642
643 stock bool:rg_user_has_defuser(const player) {
644 return bool:(get_member(player, m_bHasDefuser))
645 }
646
647 /* return enum HitBoxGroup
648 */
649 stock HitBoxGroup:rg_get_user_last_hitgroup(const player) {
650 return get_member(player, m_LastHitGroup)
651 }
652
653 stock bool:rg_user_killed_by_headshot(const player) {
654 return bool:(rg_get_user_last_hitgroup(player) == HITGROUP_HEAD || get_member(player, m_bHeadshotKilled))
655 }
656
657 /* Returns true if user has a shield, else false.
658 */
659 stock bool:rg_user_has_shield(const player, &bool:bShieldDrawn = false)
660 {
661 if(get_member(player, m_bOwnsShield))
662 {
663 bShieldDrawn = get_member(player, m_bShieldDrawn)
664 return true
665 }
666
667 return false
668 }
669
670 stock bool:rg_user_has_secondary(const player) {
671 return bool:(get_member(player, m_rgpPlayerItems, PISTOL_SLOT) > 0)
672 }
673
674 /* Returns 1 when user has a primary weapon OR a shield in inventory, else 0.
675 */
676 stock bool:rg_user_has_primary(const player) {
677 return bool:((get_member(player, m_rgpPlayerItems, PRIMARY_WEAPON_SLOT) > 0) || get_member(player, m_bHasPrimary))
678 }
679
680 stock rg_set_user_can_shot(const player, bool:can = true) {
681 set_member(player, m_bIsDefusing, can)
682 }
683
684 stock rg_set_user_team_changed(const player, bool:changed = true) {
685 set_member(player, m_bTeamChanged, changed)
686 }
687
688 stock rg_set_user_radio_message(const player, num) {
689 set_member(player, m_iRadioMessages, num)
690 }
691
692 stock rg_set_user_ignore_radio(const player, bool:ignore = true) {
693 set_member(player, m_bIgnoreRadio, !ignore)
694 }
695
696 stock WeaponIdType:rg_get_user_weapon(const player, InventorySlotType:iSlot, &pWeapon = NULLENT)
697 {
698 if(!rg_is_valid_slot_type(iSlot))
699 return WEAPON_NONE
700
701 return ((pWeapon = get_member(player, m_rgpPlayerItems, iSlot)) > 0) ? rg_get_weapon_id(pWeapon) : WEAPON_NONE
702 }
703
704 stock WeaponIdType:rg_get_user_active_weapon(const player, &pWeapon = NULLENT) {
705 return ((pWeapon = get_member(player, m_pActiveItem)) > 0) ? rg_get_weapon_id(pWeapon) : WEAPON_NONE
706 }
707
708 stock rg_get_player_item(const player, const szWeapon_Classname[], const InventorySlotType:iSlot = NONE_SLOT) {
709 new item = get_member(player, m_rgpPlayerItems, iSlot)
710
711 while (!is_nullent(item)) {
712 if (FClassnameIs(item, szWeapon_Classname)) {
713 return item
714 }
715 item = get_member(item, m_pNext)
716 }
717
718 return 0
719 }
720
721 stock rg_set_user_weapon_model_v(const player, szModel[]) {
722 set_entvar(player, var_viewmodel, szModel)
723 }
724
725 stock rg_set_user_weapon_model_p(const player, szModel[]) {
726 set_entvar(player, var_weaponmodel, szModel)
727 }
728
729 // Max = 0 default max (works with GAT_GIVE_AMMO)
730 stock rg_user_add_ammo(const player, AmmoTypes:AmmoId, Amount, Max = 0, GiveAmmoType:type = GAT_SET_AMMO, bool:bShowPickup = true)
731 {
732 if(!rg_is_valid_ammo_id(AmmoId))
733 return
734
735 static const iMaxBpAmmo[AMMO_MAX_TYPES] = {
736 0, 30, 90, 200, 90, 32, 100, 100, 35, 52, 120, 2, 1, 1, 1
737 }
738
739 new finalAmount, userAmmo, finalMax = (Max > 0 ? Max : iMaxBpAmmo[AmmoId])
740
741 if(type == GAT_SET_AMMO)
742 {
743 set_member(player, m_rgAmmo, Amount, AmmoId)
744 return
745 }
746 else if(type == GAT_GIVE_AMMO)
747 {
748 if(Amount <= 0 || ((userAmmo = get_member(player, m_rgAmmo, AmmoId)) >= finalMax))
749 return
750
751 set_member(player, m_rgAmmo, userAmmo + (finalAmount = min(finalMax, Amount)), AmmoId)
752 }
753
754 static gmsgAmmoPickup
755 if(finalAmount && bShowPickup && (gmsgAmmoPickup || (gmsgAmmoPickup = get_user_msgid("AmmoPickup"))))
756 {
757 message_begin(MSG_ONE, gmsgAmmoPickup, .player = player)
758 write_byte(any:AmmoId)
759 write_byte(finalAmount)
760 message_end()
761 }
762 }
763
764 stock rg_send_weapon_anim(const player, const anim, const Float:fAnimTime, weapon = NULLENT)
765 {
766 if(weapon > 0 || (weapon = get_member(player, m_pActiveItem)) > 0)
767 {
768 set_entvar(player, var_weaponanim, anim)
769
770 message_begin(MSG_ONE, SVC_WEAPONANIM, .player = player)
771 write_byte(anim)
772 write_byte(get_entvar(weapon, var_body))
773 message_end()
774
775 set_member(weapon, m_Weapon_flTimeWeaponIdle, fAnimTime)
776 }
777 }
778
779 /**■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ WeaponBox stocks ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
780
781 stock rg_kill_weaponbox(const weaponbox)
782 {
783 if(!get_member(weaponbox, m_WeaponBox_bIsBomb))
784 {
785 set_entvar(weaponbox, var_nextthink, get_gametime() + 0.1)
786 return
787 }
788
789 new pWeapon = get_member(weaponbox, m_WeaponBox_rgpPlayerItems, C4_SLOT)
790 if(!is_nullent(pWeapon)) {
791 set_entvar(pWeapon, var_flags, FL_KILLME)
792 }
793
794 set_entvar(weaponbox, var_flags, FL_KILLME)
795
796 static gmsgBombPickup
797 if(gmsgBombPickup || (gmsgBombPickup = get_user_msgid("BombPickup")))
798 {
799 message_begin(MSG_ALL, gmsgBombPickup)
800 message_end()
801 }
802 }
803
804 // alternate native WeaponIdType:rg_get_weaponbox_id(const entity)
805
806 stock WeaponIdType:rg_get_weaponbox_weapon(const weaponbox, InventorySlotType:iSlot, &pWeapon = NULLENT)
807 {
808 if(!rg_is_valid_slot_type(iSlot))
809 return WEAPON_NONE
810
811 return ((pWeapon = get_member(weaponbox, m_WeaponBox_rgpPlayerItems, iSlot)) > 0) ? rg_get_weapon_id(pWeapon) : WEAPON_NONE
812 }
813
814 stock rg_get_weaponbox_ammo(const weaponbox) {
815 return get_member(weaponbox, m_WeaponBox_rgAmmo, rg_is_grenade_weapon_id(rg_get_weaponbox_id(weaponbox)) ? 1 : 0)
816 }
817
818 stock rg_set_weaponbox_ammo(const weaponbox, const AmmoTypes:AmmoId, const iCount)
819 {
820 if(!rg_is_valid_ammo_id(AmmoId))
821 return
822
823 static const szAmmoTypes[AMMO_MAX_TYPES][] = {
824 "", "338Magnum", "762Nato", "556NatoBox", "556Nato", "buckshot", "45acp", "57mm",
825 "50AE", "357SIG", "9mm", "Flashbang", "HEGrenade", "SmokeGrenade", "C4"
826 }
827
828 new element = rg_is_grenade_weapon_id(rg_get_weaponbox_id(weaponbox)) ? 1 : 0
829
830 set_member(weaponbox, m_WeaponBox_rgiszAmmo, szAmmoTypes[AmmoId], element)
831 set_member(weaponbox, m_WeaponBox_rgAmmo, (iCount < 0) ? 0 : iCount, element)
832 }
833
834 /**■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ Weapon stocks ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
835
836 // rg_get_weapon_info() WI_SLOT
837 stock InventorySlotType:rg_get_weapon_slot(const weapon) {
838 return (weapon > 0) ? rg_get_weaponid_slot(rg_get_weapon_id(weapon)) : NONE_SLOT
839 }
840
841 stock InventorySlotType:rg_get_weaponid_slot(const WeaponIdType:weaponid)
842 {
843 static const InventorySlotType:iWeaponsSlots[any:WEAPON_P90 + 1] = {
844 NONE_SLOT,
845 PISTOL_SLOT,
846 NONE_SLOT,
847 PRIMARY_WEAPON_SLOT,
848 GRENADE_SLOT,
849 PRIMARY_WEAPON_SLOT,
850 C4_SLOT,
851 PRIMARY_WEAPON_SLOT,
852 PRIMARY_WEAPON_SLOT,
853 GRENADE_SLOT,
854 PISTOL_SLOT,
855 PISTOL_SLOT,
856 PRIMARY_WEAPON_SLOT,
857 PRIMARY_WEAPON_SLOT,
858 PRIMARY_WEAPON_SLOT,
859 PRIMARY_WEAPON_SLOT,
860 PISTOL_SLOT,
861 PISTOL_SLOT,
862 PRIMARY_WEAPON_SLOT,
863 PRIMARY_WEAPON_SLOT,
864 PRIMARY_WEAPON_SLOT,
865 PRIMARY_WEAPON_SLOT,
866 PRIMARY_WEAPON_SLOT,
867 PRIMARY_WEAPON_SLOT,
868 PRIMARY_WEAPON_SLOT,
869 GRENADE_SLOT,
870 PISTOL_SLOT,
871 PRIMARY_WEAPON_SLOT,
872 PRIMARY_WEAPON_SLOT,
873 KNIFE_SLOT,
874 PRIMARY_WEAPON_SLOT
875 }
876
877 return rg_is_valid_weapon_id(weaponid) ? iWeaponsSlots[weaponid] : NONE_SLOT
878 }
879
880 stock WeaponIdType:rg_get_weapon_id(const weapon) {
881 return get_member(weapon, m_iId)
882 }
883
884 stock WeaponState:rg_get_weapon_state(const weapon) {
885 return get_member(weapon, m_Weapon_iWeaponState)
886 }
887
888 stock WeaponState:rg_get_weapon_owner(const weapon) {
889 return get_member(weapon, m_pPlayer)
890 }
891
892 stock rg_set_weapon_can_shot(const weapon, bool:can = true) {
893 set_member(weapon, m_Weapon_iWeaponState, (can ? (any:0) : WPNSTATE_SHIELD_DRAWN))
894 }
895
896 /**■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ Armoury entity stocks ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
897
898 // -1 = all armoury items
899 stock rg_invisibility_armoury(const ArmouryItemPack:itemID = any:-1, bool:visible = false)
900 {
901 new pArmoury = NULLENT
902 while((pArmoury = rg_find_ent_by_class(pArmoury, "armoury_entity", .useHashTable = true)))
903 {
904 if(itemID != any:-1 && itemID != get_member(pArmoury, m_Armoury_iItem))
905 continue
906
907 if(!visible)
908 {
909 set_entvar(pArmoury, var_effects, get_entvar(pArmoury, var_effects) | EF_NODRAW)
910 set_entvar(pArmoury, var_solid, SOLID_NOT)
911 }
912 else
913 {
914 set_entvar(pArmoury, var_effects, get_entvar(pArmoury, var_effects) & ~EF_NODRAW)
915 set_entvar(pArmoury, var_solid, SOLID_TRIGGER)
916 }
917 }
918 }
919
920 /* To get ArmouryItem ID from armoury_entity
921 *
922 * @param entity armoury_entity
923 * @param count count item
924 * @return return enum's of ArmouryItemPack
925 */
926 stock ArmouryItemPack:rg_get_armoury_info(const entity, &count = 1)
927 {
928 new ArmouryItemPack:item = get_member(entity, m_Armoury_iItem)
929 if(!rg_is_valid_armoury(item))
930 return any:-1
931
932 count = get_member(entity, m_Armoury_iCount)
933 return item
934 }
935
936 /* Set an armoury_entity to be of specified type.
937 */
938 stock bool:rg_set_armoury_type(const entity, const ArmouryItemPack:item)
939 {
940 if(!rg_is_valid_armoury(item))
941 return false
942
943 set_member(entity, m_Armoury_iItem, item)
944 return true
945 }
946
947 /**■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ Other entity stocks ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
948
949 /* Sets the submodel setting of the entity.
950 * If this is 1, then the user has a backpack or defuser on their model (depending on team)
951 * 0 removes it.
952 */
953 stock rg_set_entity_submodel(const entity, const value) {
954 set_entvar(entity, var_body, value)
955 }
956
957 stock rg_get_entity_submodel(const entity) {
958 return get_entvar(entity, var_body)
959 }
960
961 stock rg_set_entity_skin(const entity, const value) {
962 set_entvar(entity, var_skin, value)
963 }
964
965 stock rg_get_entity_skin(const entity) {
966 return get_entvar(entity, var_skin)
967 }
968
969 stock rg_set_entity_model(const entity, const model[], const modelindex) {
970 set_entvar(entity, var_model, model)
971 set_entvar(entity, var_modelindex, modelindex)
972 }
973
974 #if !defined rg_remove_entity
975 stock rg_remove_entity(const entity) {
976 if (!is_nullent(entity))
977 set_entvar(entity, var_flags, get_entvar(entity, var_flags) | FL_KILLME)
978 }
979 #endif
980
981 /* Sets player/entity rendering mode.
982 */
983 stock rg_set_entity_rendering(const entity, fx = kRenderFxNone, Float:color[] = {255.0, 255.0, 255.0}, render = kRenderNormal, Float:amount = 16.0) {
984 set_entvar(entity, var_renderfx, fx)
985 set_entvar(entity, var_rendercolor, color)
986 set_entvar(entity, var_rendermode, render)
987 set_entvar(entity, var_renderamt, amount)
988 }
989
990 stock rg_set_user_rendering_ex(iEntity, iRender = kRenderFxNone, iRed = 255, iGreen = 255, iBlue = 255, iRenderNormal = kRenderNormal, iAmount = 16) {
991 set_entvar(iEntity, var_renderfx, iRender)
992
993 new Float:vecRenderColor[RGB]
994
995 vecRenderColor[R] = float(iRed)
996 vecRenderColor[G] = float(iGreen)
997 vecRenderColor[B] = float(iBlue)
998
999 set_entvar(iEntity, var_rendercolor, vecRenderColor)
1000 set_entvar(iEntity, var_rendermode, iRenderNormal)
1001 set_entvar(iEntity, var_renderamt, float(iAmount))
1002
1003 return 1
1004 }
1005
1006 /**■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ReAPI native fixes ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
1007
1008 // fix shield/elite drop
1009 stock rg_give_item_fix(const player, const pszName[], GiveType:type = GT_APPEND) {
1010 if(type != GT_APPEND)
1011 {
1012 new WeaponIdType:iId = rg_get_weapon_info(pszName, WI_ID)
1013
1014 if((rg_is_primary_weapon_id(iId) || iId == WEAPON_ELITE) && get_member(player, m_bOwnsShield))
1015 {
1016 rg_remove_item(player, "weapon_shield")
1017 }
1018 else if(iId == WEAPON_SHIELDGUN && user_has_weapon(player, any:WEAPON_ELITE))
1019 {
1020 rg_remove_item(player, "weapon_elite")
1021 }
1022 }
1023
1024 return rg_give_item(player, pszName, type)
1025 }
1026
1027 // Fixed version of rg_give_item_ex
1028 /*
1029 * Gives the player an item.
1030 *
1031 * @param player Client index
1032 * @param pszName Item name eg. "weapon_ak47"
1033 * @param type Look at the enums with name GiveType
1034 * @param ammo Amount of ammo item will have when given (-1 equal to max weapon gun clip size)
1035 * @param bpammo Amount of backpack ammo item will have when given (-1 equal to max weapon rounds size)
1036 * @param uid Sets a unique index for the entity
1037 *
1038 * @return Index of entity if successfull, -1 otherwise
1039 */
1040 stock rg_give_item_ex(const player, pszName[], GiveType:type = GT_APPEND, ammo = 0, bpammo = 0, uid = 0) {
1041 new WeaponIdType:iWeaponID = rg_get_weapon_info(pszName, WI_ID)
1042
1043 if(rg_is_primary_weapon_id(iWeaponID) && get_member(player, m_bOwnsShield))
1044 {
1045 rg_remove_item(player, "weapon_shield")
1046 }
1047
1048 if (uid)
1049 uid = rg_give_custom_item(player, pszName, type, uid)
1050 else
1051 uid = rg_give_item(player, pszName, type)
1052
1053 if (!rg_is_grenade_weapon_id(iWeaponID))
1054 {
1055 if (ammo == -1)
1056 rg_set_user_ammo(player, iWeaponID, rg_get_weapon_info(iWeaponID, WI_GUN_CLIP_SIZE))
1057 else if (ammo >= 0)
1058 rg_set_user_ammo(player, iWeaponID, ammo)
1059 }
1060
1061 if (bpammo == -1)
1062 rg_set_user_bpammo(player, iWeaponID, rg_get_weapon_info(iWeaponID, WI_MAX_ROUNDS))
1063 else if (bpammo >= 0)
1064 rg_set_user_bpammo(player, iWeaponID, bpammo)
1065
1066 if (contain(pszName, "shield") || iWeaponID == WEAPON_SHIELDGUN)
1067 rg_give_item_fix(player, pszName, type)
1068
1069 return uid
1070 }
1071
1072 stock rg_give_nades(const player, grenade[], GiveType:type = GT_APPEND, amount = 0) {
1073 new WeaponIdType:iWeaponID = rg_get_weapon_info(grenade, WI_ID)
1074
1075 if (!rg_is_grenade_weapon_id(iWeaponID))
1076 {
1077 log_amx("Only grenades can be given with this stock! Please fix it now!")
1078 return
1079 }
1080
1081 rg_give_item_ex(player, grenade, type, .bpammo = amount)
1082 }
1083
1084 stock rg_give_he_grenade(const player, GiveType:type = GT_APPEND, amount = 0) {
1085 rg_give_item_ex(player, "weapon_hegrenade", type, .bpammo = amount)
1086 }
1087
1088 stock rg_give_flash_bang(const player, GiveType:type = GT_APPEND, amount = 0) {
1089 rg_give_item_ex(player, "weapon_flashbang", type, .bpammo = amount)
1090 }
1091
1092 stock rg_give_smoke_grenade(const player, GiveType:type = GT_APPEND, amount = 0) {
1093 rg_give_item_ex(player, "weapon_smokegrenade", type, .bpammo = amount)
1094 }
1095
1096 stock UTIL_Weather(const player, iMode, bool:bReliable = false) {
1097 static iMsgReceiveW
1098 if (!iMsgReceiveW)
1099 iMsgReceiveW = get_user_msgid("ReceiveW")
1100
1101 if (bReliable) message_begin(player ? MSG_ONE : MSG_ALL, iMsgReceiveW, _, player)
1102 else message_begin(player ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, iMsgReceiveW, _, player)
1103 write_byte(iMode)
1104 message_end()
1105 }
1106
1107 stock color_gradient(Float:c1[3], Float:c2[3], Float:value, Float:range, Float:result[3]) {
1108 new Float:p = floatmin(value, range)/range
1109
1110 for (new i = 0; i < 3; i++)
1111 result[i] = (1.0-p) * c1[i] + p * c2[i]
1112 }
1113
1114 /**
1115 * Creates explode of HE Grenade
1116 *
1117 * @param owner Owner of the explode
1118 * @param vecOrigin coordinates XYZ
1119 * @param fDamage Damage
1120 * @param fRadius Radius of the explode
1121 *
1122 * @return
1123 */
1124
1125 stock rg_create_explode_grenade(const owner = 0, Float:vecOrigin[XYZ] = {0.0, 0.0, 0.0}, const Float:fDamage = 0.0, const Float:fRadius = 0.0) {
1126 new entity = rg_create_entity("grenade", .useHashTable = true)
1127
1128 if (is_nullent(entity))
1129 return
1130
1131 if (owner)
1132 set_member(entity, m_Grenade_iTeam, get_member(owner, m_iTeam))
1133
1134 set_entvar(entity, var_owner, owner)
1135 rg_dmg_radius(vecOrigin, entity, owner, fDamage, fRadius, 0, DMG_GRENADE)
1136 set_entvar(entity, var_flags, FL_KILLME)
1137 }
1138
1139 /**
1140 * Creates bigger explosion effect
1141 *
1142 * @param vecOrigin coordinates XYZ
1143 * @param sprite Sprite to show [Default: "sprites/zerogxplode.spr"]
1144 * @param size Size of the sprite showing [Default: 30]
1145 & @param speed How fast the sprite will be shown & hidden [Default: 15]
1146 *
1147 * @return
1148 */
1149
1150 stock UTIL_BiggerExplosion(Float:vecOrigin[XYZ], sprite, size = 30, speed = 15) {
1151 message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
1152 write_byte(TE_EXPLOSION)
1153 write_coord_f(vecOrigin[X])
1154 write_coord_f(vecOrigin[Y])
1155 write_coord_f(vecOrigin[Z])
1156 write_short(sprite)
1157 write_byte(size)
1158 write_byte(speed)
1159 write_byte(0)
1160 message_end()
1161 }
1162
1163 stock rg_send_float_bartime(id, Float:flTime, bool:observer = true) {
1164 new iCeilTime = floatround(flTime, floatround_ceil);
1165 new iStartTime = floatround((1.0 - flTime / iCeilTime) * 100);
1166
1167 rg_send_bartime2(id, iCeilTime, iStartTime, observer);
1168 }
1169
1170 // iWins - сколько раундов должна та или иная команда выигрывать подряд
1171 stock TeamName:rg_get_team_wins_row(const iWins) {
1172 if (get_member_game(m_iNumConsecutiveCTLoses) >= iWins)
1173 {
1174 return TEAM_TERRORIST;
1175 }
1176 else if (get_member_game(m_iNumConsecutiveTerroristLoses) >= iWins)
1177 {
1178 return TEAM_CT;
1179 }
1180
1181 return TEAM_UNASSIGNED;
1182 }
1183
1184 stock Float:rg_get_remaining_time() {
1185 return (float(get_member_game(m_iRoundTimeSecs)) - get_gametime() + Float:get_member_game(m_fRoundStartTimeReal));
1186 }
1187
1188 stock TeamName:rg_get_team_loses_row(const loses) {
1189 if (get_member_game(m_iNumConsecutiveCTLoses) >= loses)
1190 {
1191 return TEAM_CT;
1192 }
1193 else if (get_member_game(m_iNumConsecutiveTerroristLoses) >= loses)
1194 {
1195 return TEAM_TERRORIST;
1196 }
1197
1198 return TEAM_UNASSIGNED;
1199 }
1200 /*
1201 stock TeamName:rg_get_team_loses_row(const loses)
1202 {
1203 return (get_member_game(m_iNumConsecutiveCTLoses) >= loses) ? TEAM_CT : (get_member_game(m_iNumConsecutiveTerroristLoses) >= loses) ? TEAM_TERRORIST : TEAM_UNASSIGNED;
1204 }
1205 */
1206
1207 /* -> Player Animation <- */
1208 stock UTIL_PlayerAnimation(const pPlayer, const szAnim[], const Float:flFrameRateAnim = 1.0, const Activity:iActivity = ACT_RANGE_ATTACK1) {
1209 new iAnimDesired, Float:flFrameRate, Float:flGroundSpeed, bool:bLoops;
1210 if ((iAnimDesired = lookup_sequence(pPlayer, szAnim, flFrameRate, bLoops, flGroundSpeed)) == -1)
1211 iAnimDesired = 0;
1212
1213 static Float:flGameTime; flGameTime = get_gametime();
1214
1215 UTIL_SetEntityAnim(pPlayer, iAnimDesired, .flFrameRate = flFrameRateAnim);
1216
1217 set_member(pPlayer, m_fSequenceLoops, bLoops)
1218 set_member(pPlayer, m_fSequenceFinished, 0)
1219 set_member(pPlayer, m_flFrameRate, flFrameRate)
1220 set_member(pPlayer, m_flGroundSpeed, flGroundSpeed)
1221 set_member(pPlayer, m_flLastEventCheck, flGameTime);
1222 set_member(pPlayer, m_Activity, iActivity)
1223 set_member(pPlayer, m_IdealActivity, iActivity)
1224 set_member(pPlayer, m_flLastFired, flGameTime)
1225 }
1226
1227 /* -> Entity Animation <- */
1228 stock UTIL_SetEntityAnim(const pEntity, const iSequence = 0, const Float:flFrame = 0.0, const Float:flFrameRate = 1.0) {
1229 set_entvar(pEntity, var_frame, flFrame);
1230 set_entvar(pEntity, var_framerate, flFrameRate);
1231 set_entvar(pEntity, var_animtime, get_gametime());
1232 set_entvar(pEntity, var_sequence, iSequence);
1233 }
1234
1235 /**
1236 * Format number to string with a special character
1237
1238 new iValue = random_num( 10000, 99999999 );
1239 new szFormatedValue[16]; UTIL_FormatNumber(iValue, szFormatedValue, charsmax( szFormatedValue ) );
1240 server_print( "Input: %i, Output: %s", iValue, szFormatedValue );
1241
1242 Output:
1243
1244 Input: 82275013, Output: 82 275 013
1245 */
1246 stock UTIL_FormatNumber(iValue, szOutput[], iLen, const szSpecialChar = ' ') {
1247 static szBuffer[16], iOutputPos, iNumPos, iNumLen
1248 szBuffer[0] = '^0', iOutputPos = iNumPos = iNumLen = 0
1249
1250 if (iValue < 0)
1251 {
1252 szOutput[ iOutputPos++ ] = '-';
1253 iValue = abs( iValue );
1254 }
1255
1256 iNumLen = num_to_str(iValue, szBuffer, charsmax(szBuffer))
1257
1258 if (iNumLen <= 3)
1259 iOutputPos += copy( szOutput[ iOutputPos ], iLen, szBuffer)
1260 else
1261 {
1262 while ((iNumPos < iNumLen) && (iOutputPos < iLen))
1263 {
1264 szOutput[iOutputPos++] = szBuffer[iNumPos++]
1265 if ((iNumLen - iNumPos) && !((iNumLen - iNumPos) % 3))
1266 szOutput[iOutputPos++] = szSpecialChar
1267 }
1268 szOutput[iOutputPos] = EOS
1269 }
1270
1271 return iOutputPos
1272 }
1273
1274 /*
1275 * Возвращает адрес переменной.
1276 */
1277 stock get_var_address(...) {
1278 assert numargs() == 1;
1279
1280 #emit LOAD.S.pri 0xC // First argument.
1281 #emit RETN
1282
1283 return 0;
1284 }
1285
1286 /*
1287 * Пишет в память AMX по указанному адресу.
1288 */
1289 stock write_amx_memory(iAddress, iValue) {
1290 #emit LOAD.S.pri iValue
1291 #emit SREF.S.pri iAddress
1292 #emit RETN
1293
1294 return 0;
1295 }
1296
1297 stock rg_get_players_num(&terrorist = 0, &ct = 0, &spec = 0, &unassigned = 0) {
1298 for (new id = 1; id <= MaxClients; id++)
1299 {
1300 if (!is_user_connected(id))
1301 continue;
1302
1303 switch (get_member(id, m_iTeam))
1304 {
1305 case TEAM_TERRORIST: terrorist++;
1306 case TEAM_CT: ct++;
1307 case TEAM_SPECTATOR: spec++;
1308 case TEAM_UNASSIGNED: unassigned++;
1309 }
1310 }
1311 }
1312
1313 // Garey
1314 /*
1315 FORPLAYERS(i, iPlayers, iAliveCount, GetPlayers_ExcludeDead, "")
1316 {
1317 rg_set_user_team(iPlayers[i], TEAM_CT);
1318 }
1319
1320 new iPlayers[MAX_PLAYERS], iAliveCount;
1321 get_players_ex(iPlayers, iAliveCount, GetPlayers_ExcludeDead, "")
1322 for(new i = 0; i < iAliveCount; i++)
1323 {
1324 rg_set_user_team(iPlayers[i], TEAM_CT);
1325 }
1326 */
1327 #define GETPLAYERS(%1,%2,%3,%4) \
1328 new %1[MAX_PLAYERS], %2; \
1329 get_players_ex(%1, %2, %3, %4)
1330
1331 #define FORPLAYERS(%1,%2,%3,%4,%5) \
1332 GETPLAYERS(%2,%3,%4,%5); \
1333 for(new %1 = 0; %1 < %3; %1++)
1334
1335
1336 /*
1337 * id
1338 * Player to send the message to.
1339 * 0 = everyone
1340 *
1341 * text[]
1342 * Text to send.
1343 *
1344 * Float:X
1345 * X position on screen.
1346 *
1347 * Float:Y
1348 * Y position on screen.
1349 *
1350 * R
1351 * Red color.
1352 *
1353 * G
1354 * Green color.
1355 *
1356 * B
1357 * Blue color.
1358 *
1359 * A
1360 * Alpha.
1361 * Default value: 255
1362 *
1363 * Float:holdtime
1364 * Float:fadeintime
1365 * Time to fade in message
1366 * Default value: 0.1
1367 *
1368 * Float:fadeouttime
1369 * Time to fade out message
1370 * Default value: 0.1
1371 *
1372 * channel
1373 * Textchannel
1374 * -1 = auto choose.
1375 * Default value: -1
1376 *
1377 * effect
1378 * Effect of message.
1379 * 1 = Flicker with 2nd color.
1380 * 2 = Print out as 2nd color, fade into 1st color.
1381 * effecttime decides fade time between colors.
1382 * fadeintime decides how fast the letters should be printed out.
1383 * Default value: 0
1384 *
1385 * effect_R
1386 * Red color of effect.
1387 * Default value: 0
1388 *
1389 * effect_G
1390 * Green color of effect.
1391 * Default value: 0
1392 *
1393 * effect_B
1394 * Blue color of effect.
1395 * Default value: 0
1396 *
1397 * effect_A
1398 * Alpha of effect.
1399 * Default value: 255
1400 *
1401 * Float:effecttime
1402 * Only for effect 2.
1403 * Default value: 0.0
1404 *
1405 *
1406 *
1407 * Example:
1408 * rg_send_hudmessage(index, szMessage, 0.05, 0.30, random(256), random_num(100, 255), random(256), 150, 5.0, 0.10, 0.20, -1, 2, random_num(0, 100), random_num(0, 100), random_num(0, 100), 200, 2.0)
1409 */
1410 stock rg_send_hudmessage(id,text[],Float:fX,Float:fY,C_RED,C_GREEN,C_BLUE,A=255,Float:holdtime=5.0,Float:fadeintime=0.1,Float:fadeouttime=0.1,channel=-1,effect=0,effect_R=0,effect_G=0,effect_B=0,effect_A=255,Float:effecttime=0.0) {
1411 if (id)
1412 message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, {0,0,0}, id)
1413 else
1414 message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
1415 write_byte(TE_TEXTMESSAGE)
1416 write_byte(channel)
1417 write_short(rg_coord_to_hudmsgshort(fX))
1418 write_short(rg_coord_to_hudmsgshort(fY))
1419 write_byte(effect)
1420 write_byte(C_RED)
1421 write_byte(C_GREEN)
1422 write_byte(C_BLUE)
1423 write_byte(A)
1424 write_byte(effect_R)
1425 write_byte(effect_G)
1426 write_byte(effect_B)
1427 write_byte(effect_A)
1428 write_short(rg_seconds_to_hudmsgshort(fadeintime))
1429 write_short(rg_seconds_to_hudmsgshort(fadeouttime))
1430 write_short(rg_seconds_to_hudmsgshort(holdtime))
1431 if (effect == 2)
1432 write_short(rg_seconds_to_hudmsgshort(effecttime))
1433 write_string(text)
1434 message_end()
1435 }
1436
1437 /* 0.0 - 255.99609375 seconds */
1438 stock rg_seconds_to_hudmsgshort(Float:sec) {
1439 new output = floatround(sec * 256)
1440 return output < 0 ? 0 : output > 65535 ? 65535 : output
1441 }
1442
1443 stock rg_coord_to_hudmsgshort(Float:coord) {
1444 new output = floatround(coord * 8192)
1445 return output < -32768 ? -32768 : output > 32767 ? 32767 : output
1446 }
1447
1448 // Credits OciXCrom
1449 stock try_precache_player_model(const name[], &id = 0) {
1450 new model[128]
1451 formatex(model, charsmax(model), "models/player/%s/%sT.mdl", name, name)
1452
1453 if(file_exists(model))
1454 id = precache_generic(model)
1455
1456 static const extension[] = "T.mdl"
1457 #pragma unused extension
1458
1459 copy(model[strlen(model) - charsmax(extension)], charsmax(model), ".mdl")
1460 return precache_model(model)
1461 }
1462
1463 stock try_precache_sounds(const name[]) {
1464 if (file_exists(name))
1465 {
1466 if (containi(name, ".mp3") != -1)
1467 precache_sound(name)
1468 else
1469 precache_generic(name)
1470 }
1471
1472 }
1473
1474 // Credits: OciXCrom for bad calculation of percentage!!
1475 // Credits: Huehue for fixing his bad math..
1476 stock discount_math_fix(iNum, const szPercent[]) {
1477 static szNewMath[16], bool:bPercent, cOperator, iMath, iCalculate
1478
1479 copy(szNewMath, charsmax(szNewMath), szPercent)
1480 bPercent = szNewMath[strlen(szNewMath) - 1] == '%'
1481 cOperator = szNewMath[0]
1482
1483 if (!isdigit(szNewMath[0]))
1484 szNewMath[0] = ' '
1485
1486 if (bPercent)
1487 replace(szNewMath, charsmax(szNewMath), "%", "")
1488
1489 trim(szNewMath)
1490 iMath = str_to_num(szNewMath)
1491
1492 if (bPercent)
1493 iCalculate = (iNum * iMath) / 100
1494
1495 switch(cOperator)
1496 {
1497 case '+': iNum += bPercent ? iCalculate : iMath
1498 case '-': iNum -= bPercent ? iCalculate : iMath
1499 case '/': iNum /= bPercent ? iCalculate : iMath
1500 case '*': iNum *= bPercent ? iCalculate : iMath
1501 default: iNum = bPercent ? iCalculate : iMath
1502 }
1503
1504 return iNum
1505 }