From 2a5d6b9eaf75537f5491791c8a86f7819a080d8f Mon Sep 17 00:00:00 2001 From: "[furrycat]" Date: Wed, 20 May 2009 10:02:51 -0400 Subject: [PATCH] Despawn ammo after use. Despawn ammo after a set number of uses defined in lw_despawn_ammo. --- limited_weapons.sp | 115 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 106 insertions(+), 9 deletions(-) diff --git a/limited_weapons.sp b/limited_weapons.sp index ce71fa1..81aa4d3 100644 --- a/limited_weapons.sp +++ b/limited_weapons.sp @@ -1,7 +1,17 @@ #include -#define Version "0.1" +#define Version "0.2" -new Handle:despawn; +new Handle:despawn_weapons; +new Handle:despawn_ammo; + +/* Array to track players grabbed ammo. */ +new grabbed_ammo[MAXPLAYERS]; +#define NAME_BUFFER_LEN 32 +new namebuffer[NAME_BUFFER_LEN]; +/* XXX: Surely this should be enough for ammo spawners. */ +#define NUM_AMMO_ENTITIES 32 +new ammo_entities[NUM_AMMO_ENTITIES]; +new ammo_counts[NUM_AMMO_ENTITIES]; public Plugin:myinfo = { name = "Limited weapons", @@ -19,23 +29,110 @@ public OnPluginStart() { } /* Set up cvars. */ - despawn = CreateConVar("limited_weapons_despawn", "1", "Remove weapon spawners immediately after use."); + despawn_weapons = CreateConVar("lw_despawn_weapons", "1", "Remove weapon spawners immediately after use."); + despawn_ammo = CreateConVar("lw_despawn_ammo", "4", "Remove ammo spawners after this many uses. Set to 0 to disable removal."); - AutoExecConfig(true, "limited_weapons"); + AutoExecConfig(true, "lw"); /* Hooks. */ HookEvent("spawner_give_item", spawner_give_item_callback); + HookEvent("player_use", player_use_callback); + HookEvent("ammo_pickup", ammo_pickup_callback); } -/* Remove item spawner as soon as it has given an item. */ +/* A player picked up an item from a spawner. */ public spawner_give_item_callback(Handle:event, const String:name[], bool:dontBroadcast) { - if (GetConVarInt(despawn)) { - new spawner = GetEventInt(event, "spawner"); - if (IsValidEntity(spawner)) RemoveEdict(spawner); + /* Remove item spawner as soon as it has given an item. */ + if (! GetConVarInt(despawn_weapons)) return; + + new spawner = GetEventInt(event, "spawner"); + if (! IsValidEntity(spawner)) return; + + GetEdictClassname(spawner, namebuffer, NAME_BUFFER_LEN); + + LogMessage("Removing %s (%d) after use.", namebuffer, spawner); + RemoveEdict(spawner); +} + +/* A player interacted with something. */ +public player_use_callback(Handle:event, const String:name[], bool:dontBroadcast) { + /* + By the time this fires the value of grabbed_ammo[userid] will be 1 + if ammo was picked up. + */ + new count = GetConVarInt(despawn_ammo); + if (! count) return; + + new userid = GetEventInt(event, "userid"); + new was_ammo = grabbed_ammo[userid]; + /* Forget that this player interacted with anything. */ + grabbed_ammo[userid] = 0; + + new spawner = GetEventInt(event, "targetid"); + if (! IsValidEntity(spawner)) return; + + if (! was_ammo) return; + + /* Check this is an ammo spawner. Surely it must be. */ + GetEdictClassname(spawner, namebuffer, NAME_BUFFER_LEN); + if (strcmp(namebuffer, "weapon_ammo_spawn")) return; + + /* How many times? */ + new index = get_ammo_index(spawner); + if (index == -1) return; + + new used = ammo_counts[index] + 1; + ammo_counts[index] = used; + + if (used >= count) { + LogMessage("Removing %s (%d) after %d use(s).", namebuffer, used, spawner); + RemoveEdict(spawner); } } - + +/* A player took ammo. This is called before player_use.*/ +public ammo_pickup_callback(Handle:event, const String:name[], bool:dontBroadcast) { + /* Remember how many times the ammo was used. */ + new count = GetConVarInt(despawn_ammo); + if (! count) return; + + new userid = GetEventInt(event, "userid"); + + grabbed_ammo[userid] = 1; +} + +/* Cheap hash-alike. */ +public int:get_ammo_index(int:entity) { + new i; + new count; + for (i = 0; i < NUM_AMMO_ENTITIES; i++) { + if (ammo_entities[i] == entity) return i; + else if (ammo_entities[i]) count++; + } + + /* Is the array full? */ + if (count >= NUM_AMMO_ENTITIES) { + return -1; + } + + /* Add this index. */ + for (i = 0; i < NUM_AMMO_ENTITIES; i++) { + if (ammo_entities[i]) continue; + ammo_entities[i] = entity; + return i; + } + + /* Compiler food. We shouldn't get here. */ + return -1; +} + public OnMapStart() { + /* Zero out the ammo counts. */ + new i; + for (i = 0; i < NUM_AMMO_ENTITIES; i++) { + ammo_entities[i] = 0; + ammo_counts[i] = 0; + } } public OnMapEnd() { -- 2.7.4