Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Wklejka 8keecs7wa8kc dodana przez Amaroq, 07.03.2013 21:30
Typ:



1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
/* AMX Mod X
*   Real Nade Drops
*
* (c) Copyright 2005-2006 by VEN
*
* This file is provided as is (no warranties)
*
*        DESCRIPTION
*          Plugin allow to players drop grenades while alive and leave grenades on death.
*
*        FEATURES
*          Plugin obey all weapon drop/leave/collect/remove CS standards.
*          - "drop [weapon_name]" command support
*          - CS standard-like weapon switching after drop
*          - death players leave nades on any death type
*          - cleanup of dropped nades on every new round
*          - unique throw-on-death fix
*          - server crash protection
*          - buy/drop flood protection
*
*        MODULES
*          fakemeta 1.71+
*
*        COMMANDS
*          rnd_alive [0|1] (default: 1) - disallows/allows to alive players drop nades
*          rnd_death [0|1] (default: 1) - disables/enables drop player nades on death
*          rnd_buy [0|1] (default: 1) - disables/enables alive drops mode during buytime
*
*        VERSIONS
*          0.4   now only fakemeta (v1.71+) module instead of engine+cstrike modules required
*                        excluded "rnd_fun" command (not work properly under the current version)
*                        added "rnd_buy" command which allows to restrict alive drops mode during buytime
*                        added description for all commands which can be listed with "amx_help" command
*                        now on player's death dropped nades recieves velocity accordingly
*                        now total number of the dropped nades not re-counted every nade drop
*                        immediate nade drop/collect prevention method changed to "on ground" check
*                        made code optimization and some other improvements
*          0.3.1 fixed: "To many dropped nades on the map!" message was never displayed
*                        added client center text error message in case nade entity not created
*          0.3   excluded "fake" version of plugin
*                        fakemeta module not required anymore
*                        fixed: nade entity wasn't actually removed on collect
*                        nade drop attempt recognize method changed to "drop" client command hook
*                        added "drop [weapon_name]" command support
*                        added limit of total number of dropped nades to prevent possibility of server crash
*                        code changed so exploits can't be used so corresponding protection methods removed
*                        added fun drops mode for alive players
*                        CVARs replaced with CVAR-behaviour-like commands
*                        added CS standard-like weapon switching after drop for alive players
*                        changed death recognize method to distinguish any death type
*                        new round (freezetime) start recognize method changed to more efficient one
*                        drop/collect delay method changed to nade think
*                        some other changes and additions
*          0.2   included "fake" version of plugin (fake entity, fake collect)
*                        restricted ability of using nade multiple drop exploit
*                        restricted ability of using nade drop/buy exploit
*                        fixed: duplicate of throwed and exploded on death nade also remain on the ground
*                        cleanup of all dropped nades take place on every new round (freezetime) start
*                        geometric nade immediate drop/collect prevention method changed to touch ignore
*                        some other small changes and additions
*          0.1   first release
*/
 
/* *************************************************** Init **************************************************** */
 
#include <amxmodx>      // AMX Mod X 1.71+ required, check your addons/metamod/plugins.ini
#include <fakemeta>     // fakemeta module required, check your configs/modules.ini
#include <amxmisc>      // this is not a module!
 
// plugin's main information
#define PLUGIN_NAME "Real Nade Drops"
#define PLUGIN_VERSION "0.4"
#define PLUGIN_AUTHOR "VEN"
 
// OPTIONS BELOW
 
// console commands' names
new CMD_ALIVE[] = "rnd_alive"
new CMD_BUY[] = "rnd_buy"
new CMD_DEATH[] = "rnd_death"
 
// console commands' access level
#define CMD_ACCESS_LEVEL ADMIN_CVAR
 
// modes' default state (true: ON, false: OFF)
new bool:MODE_ALIVE = true
new bool:MODE_BUY = true
new bool:MODE_DEATH = true
 
// uncomment to allow alive drops mode during buytime only for players who is outside buyzone (for rnd_buy 0)
//#define OBEY_BUYZONE
 
// center text client message (for rnd_buy 0)
#if defined OBEY_BUYZONE
        new MSG_BUY[] = "You have to be outside buyzone!"
#else
        new MSG_BUY[] = "You have to wait %d second(s)!"
#endif
 
// center text client message
new MSG_TOMANY[] = "To many dropped nades on the map!"
 
// error log and center text client message
new MSG_ERROR[] = "ERROR: Unable to create grenade entity!"
 
// max. allowed number of the dropped nades
#define MAX_NADE_ENTITIES 192
 
// nade unique classname
new NADE_NAME[] = "real_nade"
 
// for alive drops
#define NADE_PLR_DIFF_ANGLE_HOR 0 // player/nade horisontal angle difference in degrees
#define NADE_VELOCITY 350 // nade drop start velocity
 
// not really a configurable value unless you edited every corresponding array
#define NADE_TYPES 3 // nuber of nade types
 
// for drop on death
new const NADE_PLR_DIFF_DIST[NADE_TYPES] = {8, 8, 8} // player/nade distance difference
new const NADE_DIFF_DIST[NADE_TYPES] = {14, 0, -14} // nades distance difference
new const NADE_PLR_DIFF_ANGLE[NADE_TYPES] = {45, 45, 45} // player/nade angle difference in degrees
 
// uncomment to disable automatic 32/64bit processor detection
// possible values are <0: 32bit | 1: 64bit>
//#define PROCESSOR_TYPE 0
 
// OPTIONS ABOVE
 
// player nades ammo private data 32bit offsets
#define OFFSET_AMMO_HE_32BIT 388
#define OFFSET_AMMO_FB_32BIT 387
#define OFFSET_AMMO_SG_32BIT 389
 
// player nades ammo private data 64bit offsets
#define OFFSET_AMMO_HE_64BIT 437
#define OFFSET_AMMO_FB_64BIT 436
#define OFFSET_AMMO_SG_64BIT 438
 
// player nades ammo linux offset difference
#define OFFSET_AMMO_LINUXDIFF 5
 
// determination of actual offsets
#if !defined PROCESSOR_TYPE // is automatic 32/64bit processor detection?
        #if cellbits == 32 // is the size of a cell are 32 bits?
                // then considering processor as 32bit
                new NADE_OFFSET_AMMO[NADE_TYPES] = {OFFSET_AMMO_HE_32BIT, OFFSET_AMMO_FB_32BIT, OFFSET_AMMO_SG_32BIT}
        #else // in other case considering the size of a cell as 64 bits
                // and then considering processor as 64bit
                new NADE_OFFSET_AMMO[NADE_TYPES] = {OFFSET_AMMO_HE_64BIT, OFFSET_AMMO_FB_64BIT, OFFSET_AMMO_SG_64BIT}
        #endif
#else // processor type specified by PROCESSOR_TYPE define
        #if PROCESSOR_TYPE == 0 // 32bit processor defined
                new NADE_OFFSET_AMMO[NADE_TYPES] = {OFFSET_AMMO_HE_32BIT, OFFSET_AMMO_FB_32BIT, OFFSET_AMMO_SG_32BIT}
        #else // considering that 64bit processor defined
                new NADE_OFFSET_AMMO[NADE_TYPES] = {OFFSET_AMMO_HE_64BIT, OFFSET_AMMO_FB_64BIT, OFFSET_AMMO_SG_64BIT}
        #endif
#endif
 
new NADE_ENTITY[] = "armoury_entity" // nade entity type
 
new const NADE_WEAPON_ID[NADE_TYPES] = {CSW_HEGRENADE, CSW_FLASHBANG, CSW_SMOKEGRENADE} // nade weapon id
new const NADE_WEAPON_NAME[NADE_TYPES][] = {"weapon_hegrenade", "weapon_flashbang", "weapon_smokegrenade"} // nade weapon name
new const NADE_ITEM_ID[NADE_TYPES][] = {"15", "14", "18"} // nade armoury item id
 
#define WEAPONS 29 // number of weapons in weapons priority list
// This is CS standard-like weapons priority list. Weapon ids placed in decreasing priority order.
// Actually this list keep only follow exact priority order: primary, secondary, c4, grenades, knife.
// Inside primary and secondary class here are no exact priority order because by default player can have only one weapon of each class.
// Inside grenades class here are exact priority order because player can have different grenades at the same time.
new const WEAPON_PRIORITY[WEAPONS] = {3, 5, 7, 8, 12, 13, 14, 15, 18, 19, 20, 21, 22, 23, 24, 27, 28, 30, 1, 10, 11, 16, 17, 26, 6, 4, 9, 25, 29}
 
// HLSDK constants
#define FL_ONGROUND (1<<9)
#define EF_NODRAW 128
#define IN_ATTACK (1<<0)
 
new bool:g_freezetime
new Float:g_round_start_time
 
#define MAX_PLAYERS 32
new bool:g_alive[MAX_PLAYERS + 1]
new bool:g_buyzone[MAX_PLAYERS + 1]
 
new g_nades_number
 
new g_maxplayers
new g_pcvar_buytime
new g_ipsz_armoury_entity
 
// strings cache
new g_classname[] = "classname"
new g_lastinv[] = "lastinv"
new g_item[] = "item"
new g_count[] = "count"
 
public plugin_init() {
        register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR) // register plugin
 
        // register console commands
        register_concmd(CMD_ALIVE, "concmd_config", CMD_ACCESS_LEVEL, "[0|1] - disallows/allows to alive players drop nades")
        register_concmd(CMD_BUY, "concmd_config", CMD_ACCESS_LEVEL, "[0|1] - disables/enables alive drops mode during buytime")
        register_concmd(CMD_DEATH, "concmd_config", CMD_ACCESS_LEVEL, "[0|1] - disables/enables drop player nades on death")
 
        // register events and log events
        register_event("HLTV", "event_new_round", "a", "1=0", "2=0") // new round
        register_event("ResetHUD", "event_hud_reset", "be") // alive player hud reset
        register_event("Health", "event_dying", "bd", "1=0") // player dying (but not only!)
        register_event("StatusIcon", "event_buyzone_icon", "b", "2=buyzone") // buyzone icon
        register_logevent("logevent_round_start", 2, "0=World triggered", "1=Round_Start") // round start
 
        // register client console commands
        register_clcmd("drop", "clcmd_drop") // register "drop" client console command
        register_clcmd("fullupdate", "clcmd_fullupdate") // register "fullupdate" client console command
 
        // register forwards
        register_forward(FM_Touch, "forward_touch") // register touch forward
 
        // caching some values
        g_maxplayers = get_maxplayers() // actual max. players number
        g_pcvar_buytime = get_cvar_pointer("mp_buytime") // mp_buytime CVAR pointer
        g_ipsz_armoury_entity = engfunc(EngFunc_AllocString, NADE_ENTITY) // nade original integer classname
}
 
/* *************************************************** Base **************************************************** */
 
public clcmd_drop(id) {
        if (!MODE_ALIVE || !is_user_alive(id)) // if nade drops not allowed to alive players or player isn't alive
                return PLUGIN_CONTINUE
 
        new current, clip, ammo, i
        current = get_user_weapon(id, clip, ammo) // get id and ammo of current weapon
 
        new arg[21]
        read_argv(1, arg, 20) // get name of weapon to drop
        if (!arg[0]) { // if weapon name isn't specified
                if (!ammo) // if no weapon ammo (usually knife)
                        return PLUGIN_CONTINUE
 
                // get nade index
                for (i = 0; i < NADE_TYPES; ++i) {
                        if (current == NADE_WEAPON_ID[i]) // if current weapon is nade
                                break
                }
        }
        else {
                // check if weapon to drop is nade
                for (i = 0; i < NADE_TYPES; ++i) {
                        if (equal(arg, NADE_WEAPON_NAME[i])) // if weapon to drop is nade
                                break
                }
        }
 
        if (i == NADE_TYPES) // if weapon to drop isn't nade
                return PLUGIN_CONTINUE
 
        new weapon = NADE_WEAPON_ID[i]
        ammo = get_pdata_int(id, NADE_OFFSET_AMMO[i], OFFSET_AMMO_LINUXDIFF) // get nade actual ammo
        if (ammo < 1) // if no nade ammo
                return PLUGIN_CONTINUE
 
        if (g_nades_number >= MAX_NADE_ENTITIES) {
                client_print(id, print_center, MSG_TOMANY)
                return PLUGIN_HANDLED
        }
 
        if (!MODE_BUY && !g_freezetime) { // is rnd_buy is 0 and currently not a freezetime
                new Float:wait = get_pcvar_float(g_pcvar_buytime) * 60 - (get_gametime() - g_round_start_time)
                if (wait > 0) { // is currently a buytime
                        #if defined OBEY_BUYZONE
                                if (g_buyzone[id]) { // is player in buyzone
                                        client_print(id, print_center, MSG_BUY)
                                        return PLUGIN_HANDLED
                                }
                        #else
                                new seconds = floatround(wait, floatround_floor)
                                client_print(id, print_center, MSG_BUY, seconds ? seconds : 1)
                                return PLUGIN_HANDLED
                        #endif
                }
        }
 
        new nade = engfunc(EngFunc_CreateNamedEntity, g_ipsz_armoury_entity) // create nade entity
        if (!nade) { // if nade entity not created
                client_print(id, print_center, MSG_ERROR) // client error center text message
                log_amx(MSG_ERROR) // log error
                return PLUGIN_HANDLED
        }
 
        g_nades_number++
 
        set_pdata_int(id, NADE_OFFSET_AMMO[i], --ammo, OFFSET_AMMO_LINUXDIFF) // reduce nade ammo over one unit
        if (!ammo) { // no more weapon ammo
                if (current == weapon) { // if current weapon is weapon to drop
                        // CS standard-like weapon switching after drop
                        for (new j = 0; j < WEAPONS; ++j) {
                                if (user_has_weapon(id, WEAPON_PRIORITY[j]) && weapon != WEAPON_PRIORITY[j]) { // search for player main weapon id
                                        new wname[20] // longest weapon name is "weapon_smokegrenade" (19 characters long)
                                        get_weaponname(WEAPON_PRIORITY[j], wname, 19) // get name of player main weapon
                                        engclient_cmd(id, wname) // switch player to his main weapon
                                        break
                                }
                        }
                }
                else {
                        // this is necessary to strip nade properly
                        engclient_cmd(id, NADE_WEAPON_NAME[i]) // switch to nade
                        engclient_cmd(id, g_lastinv) // switch to previous weapon
                }
        }
 
        set_nade_kvd(nade, g_item, NADE_ITEM_ID[i]) // set nade item type
 
        set_pev(nade, pev_classname, NADE_NAME) // set nade unique classname
 
        // setup nade start origin
        new Float:origin[3]
        pev(id, pev_origin, origin)
        engfunc(EngFunc_SetOrigin, nade, origin)
 
        // setup nade angles
        new Float:angles[3]
        pev(id, pev_angles, angles)
        angles[0] = 0.0 // we don't need specific vertical angle
        angles[1] += NADE_PLR_DIFF_ANGLE_HOR
        set_pev(nade, pev_angles, angles)
 
        // setup nade velocity
        new Float:anglevec[3], Float:velocity[3]
        pev(id, pev_v_angle, anglevec)
        engfunc(EngFunc_MakeVectors, anglevec)
        global_get(glb_v_forward, anglevec)
        velocity[0] = anglevec[0] * NADE_VELOCITY
        velocity[1] = anglevec[1] * NADE_VELOCITY
        velocity[2] = anglevec[2] * NADE_VELOCITY
        set_pev(nade, pev_velocity, velocity)
 
        dllfunc(DLLFunc_Spawn, nade) // spawn nade
 
        return PLUGIN_HANDLED
}
 
public forward_touch(nade, id) {
        if (!pev_valid(nade) || !is_user_alive(id)) // check nade/player indexes
                return FMRES_IGNORED
 
        new class[32]
        pev(nade, pev_classname, class, 31)
        if (!equal(class, NADE_NAME)) // check if it's not dropped nade
                return FMRES_IGNORED
 
        if (!(pev(nade, pev_flags) & FL_ONGROUND)) // if nade is still not on the ground
                return FMRES_SUPERCEDE // prevent immediate nade drop/collect
 
        if (pev(nade, pev_effects) & EF_NODRAW) { // nade was collected and it's not visible because of NODRAW effect
                engfunc(EngFunc_RemoveEntity, nade) // remove nade entity
                g_nades_number--
                return FMRES_SUPERCEDE
        }
 
        return FMRES_IGNORED
}
 
public event_hud_reset(id) {
        g_alive[id] = true
}
 
public event_dying(id) {
        if (!g_alive[id]) // if player already dead
                return
 
        g_alive[id] = false
 
        if (!MODE_DEATH) // if drop player nades on death is disabled
                return
 
        new ammo_fix[NADE_TYPES]
        if (pev(id, pev_button) & IN_ATTACK) { // if player hold down attack button
                new clip, ammo, weapon = get_user_weapon(id, clip, ammo) // get id of current weapon
 
                for (new i = 0; i < NADE_TYPES; ++i) {
                        if (weapon == NADE_WEAPON_ID[i]) { // if current weapon is nade
                                ammo_fix[i] = -1 // create ammo fix since nade will be throwed
                                break
                        }
                }
        }
 
        for (new i = 0; i < NADE_TYPES; ++i) {
                new ammo = get_pdata_int(id, NADE_OFFSET_AMMO[i], OFFSET_AMMO_LINUXDIFF) // get nade actual ammo
                ammo += ammo_fix[i] // apply ammo fix
                if (ammo < 1) // if no nade ammo
                        continue
 
                new nade = engfunc(EngFunc_CreateNamedEntity, g_ipsz_armoury_entity) // create nade entity
                if (!nade) { // if nade entity not created
                        log_amx(MSG_ERROR) // log error
                        continue
                }
 
                g_nades_number++
 
                set_nade_kvd(nade, g_item, NADE_ITEM_ID[i]) // set nade item type
 
                // setup nade ammo
                new count[4]
                num_to_str(ammo, count, 3)
                set_nade_kvd(nade, g_count, count)
 
                set_pev(nade, pev_classname, NADE_NAME) // set nade unique classname
 
                // setup nade origin and angle
                new Float:origin[3]
                pev(id, pev_origin, origin)
                new Float:angles[3]
                pev(id, pev_angles, angles)
                origin[0] += floatcos(angles[1], degrees) * NADE_PLR_DIFF_DIST[i] + floatcos(angles[1] + 90, degrees) * NADE_DIFF_DIST[i]
                origin[1] += floatsin(angles[1], degrees) * NADE_PLR_DIFF_DIST[i] + floatsin(angles[1] + 90, degrees) * NADE_DIFF_DIST[i]
                engfunc(EngFunc_SetOrigin, nade, origin)
                angles[0] = 0.0 // we don't need specific vertical angle
                angles[1] += NADE_PLR_DIFF_ANGLE[i]
                set_pev(nade, pev_angles, angles)
 
                // setup nade velocity
                new Float:velocity[3]
                pev(id, pev_velocity, velocity)
                set_pev(nade, pev_velocity, velocity)
 
                dllfunc(DLLFunc_Spawn, nade) // spawn nade
        }
}
 
public event_new_round() {
        g_freezetime = true
        g_nades_number = 0
 
        // remove all dropped nades
        new nade = -1
        while ((nade = engfunc(EngFunc_FindEntityByString, nade, g_classname, NADE_NAME))) // find nade entity id by nade unique classname
                engfunc(EngFunc_RemoveEntity, nade) // remove nade entity
}
 
public logevent_round_start() {
        g_freezetime = false
        g_round_start_time = get_gametime()
}
 
public event_buyzone_icon(id) {
        g_buyzone[id] = bool:read_data(1)
}
 
public client_disconnect(id) {
        g_alive[id] = false // if player is disconnected he is not alive
        g_buyzone[id] = false
}
 
public clcmd_fullupdate(id) {
        return PLUGIN_HANDLED // can block fake "not in buyzone" exploit
}
 
// function to view and change plugin modes state via console commands
public concmd_config(id, level, cid) {
        if (!cmd_access(id, level, cid, 1))
                return PLUGIN_HANDLED
 
        new command[32], argument[2]
			

Dodanych wklejek: 4031
Powered By (Pav32) Pastebin © 2011