]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/t_items.qc
Fix invisibility icon shown for speed item in minstagib
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / t_items.qc
index b101c0202cc4b59ca3331e710c44c1350b8c2ea8..ad03d50ae09210236a4f004c313d78adc6e567d3 100644 (file)
@@ -1,3 +1,40 @@
+float have_pickup_item(void)
+{
+       // minstagib: only allow filtered items
+       if(g_minstagib)
+               if(self.classname != "minstagib")
+                       return FALSE;
+
+       if(self.items == IT_STRENGTH || self.items == IT_INVINCIBLE)
+       {
+               if(autocvar_g_powerups > 0)
+                       return TRUE;
+               if(autocvar_g_powerups == 0)
+                       return FALSE;
+               if(g_lms)
+                       return FALSE;
+               if(g_ca)
+                       return FALSE;
+               if(g_arena)
+                       return FALSE;
+       }
+       else
+       {
+               if(autocvar_g_pickup_items > 0)
+                       return TRUE;
+               if(autocvar_g_pickup_items == 0)
+                       return FALSE;
+               if(g_lms)
+                       return FALSE;
+               if(g_ca)
+                       return FALSE;
+               if(g_weaponarena)
+                       if((self.weapons & WEPBIT_ALL) || (self.items & IT_AMMO))
+                               return FALSE;
+       }
+       return TRUE;
+}
+
 #define ITEM_RESPAWN_TICKS 10
 
 #define ITEM_RESPAWNTIME(i)         ((i).respawntime + crandom() * (i).respawntimejitter)
@@ -94,7 +131,7 @@ void Item_Show (entity e, float mode)
 
                e.spawnshieldtime = 1;
        }
-       else if((e.flags & FL_WEAPON) && (g_weapon_stay == 3))
+       else if((e.flags & FL_WEAPON) && g_weapon_stay)
        {
                // make the item translucent and not touchable
                e.model = e.mdl;
@@ -142,17 +179,154 @@ void Item_Show (entity e, float mode)
        setorigin(e, e.origin);
 }
 
+float it_armor_large_time;
+float it_health_mega_time;
+float it_invisible_time;
+float it_speed_time;
+float it_extralife_time;
+float it_strength_time;
+float it_shield_time;
+float it_fuelregen_time;
+float it_jetpack_time;
+
+void Item_ItemsTime_Init()
+{
+       it_armor_large_time = -1;
+       it_health_mega_time = -1;
+       it_invisible_time = -1;
+       it_speed_time = -1;
+       it_extralife_time = -1;
+       it_strength_time = -1;
+       it_shield_time = -1;
+       it_fuelregen_time = -1;
+       it_jetpack_time = -1;
+}
+void Item_ClearItemsTime()
+{
+       self.item_armor_large_time = (it_armor_large_time == -1) ? -1 : 0;
+       self.item_health_mega_time = (it_health_mega_time == -1) ? -1 : 0;
+       self.item_invisible_time   = (it_invisible_time   == -1) ? -1 : 0;
+       self.item_speed_time       = (it_speed_time       == -1) ? -1 : 0;
+       self.item_extralife_time   = (it_extralife_time   == -1) ? -1 : 0;
+       self.item_strength_time    = (it_strength_time    == -1) ? -1 : 0;
+       self.item_shield_time      = (it_shield_time      == -1) ? -1 : 0;
+       self.item_fuelregen_time   = (it_fuelregen_time   == -1) ? -1 : 0;
+       self.item_jetpack_time     = (it_jetpack_time     == -1) ? -1 : 0;
+}
+void Item_GetItemsTime(entity e)
+{
+       e.item_armor_large_time = it_armor_large_time;
+       e.item_health_mega_time = it_health_mega_time;
+       e.item_invisible_time = it_invisible_time;
+       e.item_speed_time = it_speed_time;
+       e.item_extralife_time = it_extralife_time;
+       e.item_strength_time = it_strength_time;
+       e.item_shield_time = it_shield_time;
+       e.item_fuelregen_time = it_fuelregen_time;
+       e.item_jetpack_time = it_jetpack_time;
+}
+void Item_UpdateTime(entity e, float t)
+{
+       if(g_minstagib)
+       {
+               switch(e.items)
+               {
+                       case IT_STRENGTH://"item-invis"
+                               if (it_invisible_time > time && t > it_invisible_time)
+                                       return;
+                               it_invisible_time = t;
+                               return;
+                       case IT_NAILS://"item-extralife"
+                               if (it_extralife_time > time && t > it_extralife_time)
+                                       return;
+                               it_extralife_time = t;
+                               return;
+                       case IT_INVINCIBLE://"item-speed"
+                               if (it_speed_time > time && t > it_speed_time)
+                                       return;
+                               it_speed_time = t;
+                               return;
+               }
+       }
+       else
+       {
+               switch(e.items)
+               {
+                       case IT_HEALTH:
+                               //if (e.classname == "item_health_mega")
+                               {
+                                       if (it_health_mega_time > time && t > it_health_mega_time)
+                                               return;
+                                       it_health_mega_time = t;
+                               }
+                               return;
+                       case IT_ARMOR:
+                               if (e.classname == "item_armor_large")
+                               {
+                                       if (it_armor_large_time > time && t > it_armor_large_time)
+                                               return;
+                                       it_armor_large_time = t;
+                               }
+                               return;
+                       case IT_STRENGTH://"item-strength"
+                               if (it_strength_time > time && t > it_strength_time)
+                                       return;
+                               it_strength_time = t;
+                               return;
+                       case IT_INVINCIBLE://"item-shield"
+                               if (it_shield_time > time && t > it_shield_time)
+                                       return;
+                               it_shield_time = t;
+                               return;
+               }
+       }
+       switch(e.items)
+       {
+               case IT_FUEL_REGEN://"item-fuelregen"
+                       if (it_fuelregen_time > time && t > it_fuelregen_time)
+                               return;
+                       it_fuelregen_time = t;
+                       return;
+               case IT_JETPACK://"item-jetpack"
+                       if (it_jetpack_time > time && t > it_jetpack_time)
+                               return;
+                       it_jetpack_time = t;
+                       return;
+       }
+}
+
 void Item_Respawn (void)
 {
+       float t;
+       entity head;
        Item_Show(self, 1);
        if(!g_minstagib && self.items == IT_STRENGTH)
-               sound (self, CH_TRIGGER_SINGLE, "misc/strength_respawn.wav", VOL_BASE, ATTN_NORM);      // play respawn sound
+               sound (self, CH_TRIGGER, "misc/strength_respawn.wav", VOL_BASE, ATTN_NORM);     // play respawn sound
        else if(!g_minstagib && self.items == IT_INVINCIBLE)
-               sound (self, CH_TRIGGER_SINGLE, "misc/shield_respawn.wav", VOL_BASE, ATTN_NORM);        // play respawn sound
+               sound (self, CH_TRIGGER, "misc/shield_respawn.wav", VOL_BASE, ATTN_NORM);       // play respawn sound
        else
-               sound (self, CH_TRIGGER_SINGLE, "misc/itemrespawn.wav", VOL_BASE, ATTN_NORM);   // play respawn sound
+               sound (self, CH_TRIGGER, "misc/itemrespawn.wav", VOL_BASE, ATTN_NORM);  // play respawn sound
        setorigin (self, self.origin);
 
+       if (self.flags & FL_POWERUP || self.classname == "item_armor_large" || self.items == IT_HEALTH)
+       {
+               for(t = 0, head = world; (head = find(head, classname, self.classname)); )
+               {
+                       // in minstagib .classname is "minstagib" for every item
+                       if (g_minstagib && self.items != head.items)
+                               continue;
+                       if (head.scheduledrespawntime > time)
+                               if (t == 0 || head.scheduledrespawntime < t)
+                                       t = head.scheduledrespawntime;
+               }
+               Item_UpdateTime(self, t);
+               FOR_EACH_REALCLIENT(head)
+               {
+                       if (head.classname != "player")
+                               Item_GetItemsTime(head);
+               }
+       }
+
        //pointparticles(particleeffectnum("item_respawn"), self.origin + self.mins_z * '0 0 1' + '0 0 48', '0 0 0', 1);
        pointparticles(particleeffectnum("item_respawn"), self.origin + 0.5 * (self.mins + self.maxs), '0 0 0', 1);
 }
@@ -189,6 +363,14 @@ void Item_RespawnCountdown (void)
                                {
                                        case IT_STRENGTH:   name = "item-strength"; rgb = '0 0 1'; break;
                                        case IT_INVINCIBLE: name = "item-shield"; rgb = '1 0 1'; break;
+                                       case IT_HEALTH:
+                                               //if (self.classname == "item_health_mega")
+                                                       {name = "item_health_mega"; rgb = '1 0 0';}
+                                               break;
+                                       case IT_ARMOR:
+                                               if (self.classname == "item_armor_large")
+                                                       {name = "item_armor_large"; rgb = '0 1 0';}
+                                               break;
                                }
                        }
                        switch(self.items)
@@ -200,10 +382,14 @@ void Item_RespawnCountdown (void)
                        {
                                WaypointSprite_Spawn(name, 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, TRUE, RADARICON_POWERUP, rgb);
                                if(self.waypointsprite_attached)
+                               {
+                                       if (self.items == IT_HEALTH || self.items == IT_ARMOR)
+                                               WaypointSprite_UpdateRule(self.waypointsprite_attached, 0, SPRITERULE_SPECTATOR);
                                        WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, time + ITEM_RESPAWN_TICKS);
+                               }
                        }
                }
-               sound (self, CH_TRIGGER_SINGLE, "misc/itemrespawncountdown.wav", VOL_BASE, ATTN_NORM);  // play respawn sound
+               sound (self, CH_TRIGGER, "misc/itemrespawncountdown.wav", VOL_BASE, ATTN_NORM); // play respawn sound
                if(self.waypointsprite_attached)
                {
                        WaypointSprite_Ping(self.waypointsprite_attached);
@@ -214,16 +400,24 @@ void Item_RespawnCountdown (void)
 
 void Item_ScheduleRespawnIn(entity e, float t)
 {
-       if(e.flags & FL_POWERUP)
+       if(e.flags & FL_POWERUP || self.classname == "item_armor_large" || self.items == IT_HEALTH)
        {
                e.think = Item_RespawnCountdown;
                e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS);
+               e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS;
                e.count = 0;
        }
        else
        {
                e.think = Item_Respawn;
                e.nextthink = time + t;
+               e.scheduledrespawntime = e.nextthink;
+       }
+       Item_UpdateTime(e, e.scheduledrespawntime);
+       FOR_EACH_REALCLIENT(e)
+       {
+               if (e.classname != "player")
+                       Item_GetItemsTime(e);
        }
 }
 
@@ -244,6 +438,53 @@ void Item_ScheduleInitialRespawn(entity e)
        Item_ScheduleRespawnIn(e, game_starttime - time + ITEM_RESPAWNTIME_INITIAL(e));
 }
 
+float ITEM_MODE_NONE = 0;
+float ITEM_MODE_HEALTH = 1;
+float ITEM_MODE_ARMOR = 2;
+float ITEM_MODE_FUEL = 3;
+float Item_GiveAmmoTo(entity item, entity player, .float ammofield, float ammomax, float mode)
+{
+       if (!item.ammofield)
+               return FALSE;
+
+       if (item.spawnshieldtime)
+       {
+               if ((player.ammofield < ammomax) || item.pickup_anyway)
+               {
+                       player.ammofield = bound(player.ammofield, ammomax, player.ammofield + item.ammofield);
+                       goto YEAH;
+               }
+       }
+       else if(g_weapon_stay == 2)
+       {
+               float mi = min(item.ammofield, ammomax);
+               if (player.ammofield < mi)
+               {
+                       player.ammofield = mi;
+                       goto YEAH;
+               }
+       }
+
+       return FALSE;
+
+:YEAH
+       switch(mode)
+       {
+               case ITEM_MODE_FUEL:
+                       player.pauserotfuel_finished = max(player.pauserotfuel_finished, time + autocvar_g_balance_pause_fuel_rot);
+                       break;
+               case ITEM_MODE_HEALTH:
+                       player.pauserothealth_finished = max(player.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);
+                       break;
+               case ITEM_MODE_ARMOR:
+                       player.pauserotarmor_finished = max(player.pauserotarmor_finished, time + autocvar_g_balance_pause_armor_rot);
+                       break;
+               default:
+                       break;
+       }
+       return TRUE;
+}
+
 float Item_GiveTo(entity item, entity player)
 {
        float _switchweapon;
@@ -258,93 +499,71 @@ float Item_GiveTo(entity item, entity player)
 
        if (g_minstagib)
        {
-               if(item.spawnshieldtime)
+               float prevcells = player.ammo_cells;
+
+               pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL);
+               pickedup |= Item_GiveAmmoTo(item, player, ammo_cells, 999, ITEM_MODE_NONE);
+
+               if(player.ammo_cells > prevcells)
                {
-                       if (item.ammo_fuel)
-                       if (player.ammo_fuel < g_pickup_fuel_max)
-                       {
-                               pickedup = TRUE;
-                               player.ammo_fuel = bound(player.ammo_fuel, g_pickup_fuel_max, player.ammo_fuel + item.ammo_fuel);
-                               player.pauserotfuel_finished = max(player.pauserotfuel_finished, time + autocvar_g_balance_pause_fuel_rot);
-                       }
-                       if((it = (item.items - (item.items & player.items)) & IT_PICKUPMASK))
+                       _switchweapon = TRUE;
+
+                       // play some cool sounds ;)
+                       if (clienttype(player) == CLIENTTYPE_REAL)
                        {
-                               pickedup = TRUE;
-                               player.items |= it;
-                               sprint (player, strcat("You got the ^2", item.netname, "\n"));
+                               if(player.health <= 5)
+                                       AnnounceTo(player, "lastsecond");
+                               else if(player.health < 50)
+                                       AnnounceTo(player, "narrowly");
                        }
+                       // sound not available
+                       // else if(item.items == IT_CELLS)
+                       //      AnnounceTo(player, "ammo");
 
-                       _switchweapon = TRUE;
+                       if (item.weapons & WEPBIT_MINSTANEX)
+                               W_GiveWeapon (player, WEP_MINSTANEX, item.netname);
                        if (item.ammo_cells)
-                       {
-                               pickedup = TRUE;
-                               // play some cool sounds ;)
-                               centerprint(player, "\n");
-                               if (clienttype(player) == CLIENTTYPE_REAL)
-                               {
-                                       if(player.health <= 5)
-                                               AnnounceTo(player, "lastsecond");
-                                       else if(player.health < 50)
-                                               AnnounceTo(player, "narrowly");
-                               }
-                               // sound not available
-                               // else if(item.items == IT_CELLS)
-                               //      AnnounceTo(player, "ammo");
-
-                               if (item.weapons & WEPBIT_MINSTANEX)
-                                       W_GiveWeapon (player, WEP_MINSTANEX, item.netname);
-                               if (item.ammo_cells)
-                                       player.ammo_cells = bound(player.ammo_cells, 999, player.ammo_cells + autocvar_g_minstagib_ammo_drop);
-                               player.health = 100;
-                       }
+                               player.ammo_cells = bound(player.ammo_cells, 999, player.ammo_cells + autocvar_g_minstagib_ammo_drop);
+                       player.health = 100;
+               }
 
-                       // extralife powerup
-                       if (item.max_health)
-                       {
-                               pickedup = TRUE;
-                               // sound not available
-                               // AnnounceTo(player, "_lives");
-                               player.armorvalue = bound(player.armorvalue, 999, player.armorvalue + autocvar_g_minstagib_extralives);
-                               sprint(player, "^3You picked up some extra lives\n");
-                       }
+               if((it = (item.items - (item.items & player.items)) & IT_PICKUPMASK))
+               {
+                       pickedup = TRUE;
+                       player.items |= it;
+                       sprint (player, strcat("You got the ^2", item.netname, "\n"));
+               }
 
-                       // invis powerup
-                       if (item.strength_finished)
-                       {
-                               pickedup = TRUE;
-                               // sound not available
-                               // AnnounceTo(player, "invisible");
-                               player.strength_finished = max(player.strength_finished, time) + autocvar_g_balance_powerup_strength_time;
-                       }
+               // extralife powerup
+               if (item.max_health)
+               {
+                       pickedup = TRUE;
+                       // sound not available
+                       // AnnounceTo(player, "_lives");
+                       player.armorvalue = bound(player.armorvalue, 999, player.armorvalue + autocvar_g_minstagib_extralives);
+                       sprint(player, "^3You picked up some extra lives\n");
+               }
 
-                       // speed powerup
-                       if (item.invincible_finished)
-                       {
-                               pickedup = TRUE;
-                               // sound not available
-                               // AnnounceTo(player, "speed");
-                               player.invincible_finished = max(player.invincible_finished, time) + autocvar_g_balance_powerup_strength_time;
-                       }
+               // invis powerup
+               if (item.strength_finished)
+               {
+                       pickedup = TRUE;
+                       // sound not available
+                       // AnnounceTo(player, "invisible");
+                       player.strength_finished = max(player.strength_finished, time) + autocvar_g_balance_powerup_strength_time;
+               }
+
+               // speed powerup
+               if (item.invincible_finished)
+               {
+                       pickedup = TRUE;
+                       // sound not available
+                       // AnnounceTo(player, "speed");
+                       player.invincible_finished = max(player.invincible_finished, time) + autocvar_g_balance_powerup_strength_time;
                }
        }
        else
        {
-               if (g_weapon_stay == 1)
-               if not(item.flags & FL_NO_WEAPON_STAY)
-               if (item.flags & FL_WEAPON)
-               {
-                       if(item.classname == "droppedweapon")
-                       {
-                               if (player.weapons & item.weapons)      // don't let players stack ammo by tossing weapons
-                                       goto skip;
-                       }
-                       else
-                       {
-                               if (player.weapons & item.weapons)
-                                       goto skip;
-                       }
-               }
-
                // in case the player has autoswitch enabled do the following:
                // if the player is using their best weapon before items are given, they
                // probably want to switch to an even better weapon after items are given
@@ -355,43 +574,16 @@ float Item_GiveTo(entity item, entity player)
                if not(player.weapons & W_WeaponBit(player.switchweapon))
                        _switchweapon = TRUE;
 
-               if(item.spawnshieldtime)
-               {
-                       if (item.ammo_shells)
-                       if ((player.ammo_shells < g_pickup_shells_max) || item.pickup_anyway)
-                       {
-                               pickedup = TRUE;
-                               player.ammo_shells = bound(player.ammo_shells, g_pickup_shells_max, player.ammo_shells + item.ammo_shells);
-                       }
-                       if (item.ammo_nails)
-                       if ((player.ammo_nails < g_pickup_nails_max) || item.pickup_anyway)
-                       {
-                               pickedup = TRUE;
-                               player.ammo_nails = bound(player.ammo_nails, g_pickup_nails_max, player.ammo_nails + item.ammo_nails);
-                       }
-                       if (item.ammo_rockets)
-                       if ((player.ammo_rockets < g_pickup_rockets_max) || item.pickup_anyway)
-                       {
-                               pickedup = TRUE;
-                               player.ammo_rockets = bound(player.ammo_rockets, g_pickup_rockets_max, player.ammo_rockets + item.ammo_rockets);
-                       }
-                       if (item.ammo_cells)
-                       if ((player.ammo_cells < g_pickup_cells_max) || item.pickup_anyway)
-                       {
-                               pickedup = TRUE;
-                               player.ammo_cells = bound(player.ammo_cells, g_pickup_cells_max, player.ammo_cells + item.ammo_cells);
-                       }
-                       if (item.ammo_fuel)
-                       if ((player.ammo_fuel < g_pickup_fuel_max) || item.pickup_anyway)
-                       {
-                               pickedup = TRUE;
-                               player.ammo_fuel = bound(player.ammo_fuel, g_pickup_fuel_max, player.ammo_fuel + item.ammo_fuel);
-                               player.pauserotfuel_finished = max(player.pauserotfuel_finished, time + autocvar_g_balance_pause_fuel_rot);
-                       }
-               }
+               pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL);
+               pickedup |= Item_GiveAmmoTo(item, player, ammo_shells, g_pickup_shells_max, ITEM_MODE_NONE);
+               pickedup |= Item_GiveAmmoTo(item, player, ammo_nails, g_pickup_nails_max, ITEM_MODE_NONE);
+               pickedup |= Item_GiveAmmoTo(item, player, ammo_rockets, g_pickup_rockets_max, ITEM_MODE_NONE);
+               pickedup |= Item_GiveAmmoTo(item, player, ammo_cells, g_pickup_cells_max, ITEM_MODE_NONE);
+               pickedup |= Item_GiveAmmoTo(item, player, health, item.max_health, ITEM_MODE_HEALTH);
+               pickedup |= Item_GiveAmmoTo(item, player, armorvalue, item.max_armorvalue, ITEM_MODE_ARMOR);
 
                if (item.flags & FL_WEAPON)
-               if ((it = item.weapons - (item.weapons & player.weapons)) || (g_pickup_weapons_anyway && !(g_weapon_stay == 3 && !e.spawnshieldtime)))
+               if ((it = item.weapons - (item.weapons & player.weapons)) || (item.spawnshieldtime && g_pickup_weapons_anyway))
                {
                        pickedup = TRUE;
                        for(i = WEP_FIRST; i <= WEP_LAST; ++i)
@@ -409,33 +601,15 @@ float Item_GiveTo(entity item, entity player)
                        sprint (player, strcat("You got the ^2", item.netname, "\n"));
                }
 
-               if(item.spawnshieldtime)
+               if (item.strength_finished)
                {
-                       if (item.strength_finished)
-                       {
-                               pickedup = TRUE;
-                               player.strength_finished = max(player.strength_finished, time) + autocvar_g_balance_powerup_strength_time;
-                       }
-                       if (item.invincible_finished)
-                       {
-                               pickedup = TRUE;
-                               player.invincible_finished = max(player.invincible_finished, time) + autocvar_g_balance_powerup_invincible_time;
-                       }
-
-                       if (item.health)
-                       if ((player.health < item.max_health) || item.pickup_anyway)
-                       {
-                               pickedup = TRUE;
-                               player.health = bound(player.health, item.max_health, player.health + item.health);
-                               player.pauserothealth_finished = max(player.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);
-                       }
-                       if (item.armorvalue)
-                       if ((player.armorvalue < item.max_armorvalue) || item.pickup_anyway)
-                       {
-                               pickedup = TRUE;
-                               player.armorvalue = bound(player.armorvalue, item.max_armorvalue, player.armorvalue + item.armorvalue);
-                               player.pauserotarmor_finished = max(player.pauserotarmor_finished, time + autocvar_g_balance_pause_armor_rot);
-                       }
+                       pickedup = TRUE;
+                       player.strength_finished = max(player.strength_finished, time) + autocvar_g_balance_powerup_strength_time;
+               }
+               if (item.invincible_finished)
+               {
+                       pickedup = TRUE;
+                       player.invincible_finished = max(player.invincible_finished, time) + autocvar_g_balance_powerup_invincible_time;
                }
        }
 
@@ -447,7 +621,7 @@ float Item_GiveTo(entity item, entity player)
        if (!pickedup)
                return 0;
 
-       sound (player, CH_ITEMS, item.item_pickupsound, VOL_BASE, ATTN_NORM);
+       sound (player, CH_TRIGGER, item.item_pickupsound, VOL_BASE, ATTN_NORM);
        if (_switchweapon)
                if (player.switchweapon != w_getbestweapon(player))
                        W_SwitchWeapon_Force(player, w_getbestweapon(player));
@@ -485,8 +659,6 @@ void Item_Touch (void)
                remove (self);
        else if not(self.spawnshieldtime)
                return;
-       else if((self.flags & FL_WEAPON) && !(self.flags & FL_NO_WEAPON_STAY) && (g_weapon_stay == 1 || g_weapon_stay == 2))
-               return;
        else
        {
                if(self.team)
@@ -560,7 +732,7 @@ void RemoveItem(void)
 // pickup evaluation functions
 // these functions decide how desirable an item is to the bots
 
-float generic_pickupevalfunc(entity player, entity item) {return item.bot_pickupbasevalue;};
+float generic_pickupevalfunc(entity player, entity item) {return item.bot_pickupbasevalue;}
 
 float weapon_pickupevalfunc(entity player, entity item)
 {
@@ -570,7 +742,7 @@ float weapon_pickupevalfunc(entity player, entity item)
        if(player.weapons & item.weapons == item.weapons)
        {
                // If I can pick it up
-               if(g_weapon_stay == 1 || g_weapon_stay == 2 || !item.spawnshieldtime)
+               if(!item.spawnshieldtime)
                        c = 0;
                else if(player.ammo_cells || player.ammo_shells || player.ammo_nails || player.ammo_rockets)
                {
@@ -617,7 +789,7 @@ float weapon_pickupevalfunc(entity player, entity item)
        }
 
        return item.bot_pickupbasevalue * c;
-};
+}
 
 float commodity_pickupevalfunc(entity player, entity item)
 {
@@ -670,7 +842,7 @@ float commodity_pickupevalfunc(entity player, entity item)
                c = c + max(0, 1 - player.health / item.max_health);
 
        return item.bot_pickupbasevalue * c;
-};
+}
 
 
 .float is_item;
@@ -708,6 +880,13 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                        return;
                }
 
+               if(!have_pickup_item())
+               {
+                       startitem_failed = TRUE;
+                       remove (self);
+                       return;
+               }
+
                self.reset = Item_Reset;
                // it's a level item
                if(self.spawnflags & 1)
@@ -760,35 +939,6 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                        self.is_item = TRUE;
                }
 
-               if(g_lms || g_ca)
-               {
-                       startitem_failed = TRUE;
-                       remove(self);
-                       return;
-               }
-               else if (g_weaponarena && ((weaponid & WEPBIT_ALL) || (itemid & IT_AMMO)))
-               {
-                       startitem_failed = TRUE;
-                       remove(self);
-                       return;
-               }
-               else if (g_minstagib)
-               {
-                       // don't remove dropped items and powerups
-                       if (self.classname != "minstagib")
-                       {
-                               startitem_failed = TRUE;
-                               remove (self);
-                               return;
-                       }
-               }
-               else if (!autocvar_g_pickup_items && itemid != IT_STRENGTH && itemid != IT_INVINCIBLE && itemid != IT_HEALTH)
-               {
-                       startitem_failed = TRUE;
-                       remove (self);
-                       return;
-               }
-
                weaponsInMap |= weaponid;
 
                precache_model (itemmodel);
@@ -804,6 +954,8 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
 
                if((itemflags & (FL_POWERUP | FL_WEAPON)) || (itemid & (IT_HEALTH | IT_ARMOR | IT_KEY1 | IT_KEY2)))
                        self.target = "###item###"; // for finding the nearest item using find()
+
+               Item_UpdateTime(self, 0);
        }
 
        self.bot_pickup = TRUE;
@@ -856,13 +1008,13 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
  */
 void minstagib_items (float itemid)
 {
-       local float rnd;
+       float rnd;
        self.classname = "minstagib";
 
        // replace rocket launchers and nex guns with ammo cells
        if (itemid == IT_CELLS)
        {
-               self.ammo_cells = 1;
+               self.ammo_cells = autocvar_g_minstagib_ammo_drop;
                StartItem ("models/items/a_cells.md3",
                        "misc/itempickup.wav", 45, 0,
                        "MinstaNex Ammo", IT_CELLS, 0, 0, generic_pickupevalfunc, 100);
@@ -1025,16 +1177,6 @@ void weapon_defaultspawnfunc(float wpn)
        if(self.team)
                self.flags |= FL_NO_WEAPON_STAY;
 
-       if(g_weapon_stay == 2 && self.classname != "droppedweapon")
-       {
-               self.ammo_shells = 0;
-               self.ammo_nails = 0;
-               self.ammo_cells = 0;
-               self.ammo_rockets = 0;
-               // weapon stay 2: don't use ammo on weapon pickups; instead
-               // initialize all ammo types to the pickup ammo unless set by g_start_ammo_*
-       }
-
        StartItem(e.model, "weapons/weaponpickup.wav", self.respawntime, self.respawntimejitter, e.message, 0, e.weapons, FL_WEAPON, weapon_pickupevalfunc, e.bot_pickupbasevalue);
        if (self.modelindex) // don't precache if self was removed
                weapon_action(e.weapon, WR_PRECACHE);
@@ -1042,7 +1184,7 @@ void weapon_defaultspawnfunc(float wpn)
 
 void spawnfunc_weapon_shotgun (void);
 void spawnfunc_weapon_uzi (void) {
-       if(q3acompat_machineshotgunswap)
+       if(autocvar_sv_q3acompat_machineshotgunswap)
        if(self.classname != "droppedweapon")
        {
                weapon_defaultspawnfunc(WEP_SHOTGUN);
@@ -1052,7 +1194,7 @@ void spawnfunc_weapon_uzi (void) {
 }
 
 void spawnfunc_weapon_shotgun (void) {
-       if(q3acompat_machineshotgunswap)
+       if(autocvar_sv_q3acompat_machineshotgunswap)
        if(self.classname != "droppedweapon")
        {
                weapon_defaultspawnfunc(WEP_UZI);
@@ -1108,7 +1250,7 @@ void spawnfunc_item_rockets (void) {
 void spawnfunc_item_shells (void);
 void spawnfunc_item_bullets (void) {
        if(!weaponswapping)
-       if(q3acompat_machineshotgunswap)
+       if(autocvar_sv_q3acompat_machineshotgunswap)
        if(self.classname != "droppedweapon")
        {
                weaponswapping = TRUE;
@@ -1134,7 +1276,7 @@ void spawnfunc_item_cells (void) {
 
 void spawnfunc_item_shells (void) {
        if(!weaponswapping)
-       if(q3acompat_machineshotgunswap)
+       if(autocvar_sv_q3acompat_machineshotgunswap)
        if(self.classname != "droppedweapon")
        {
                weaponswapping = TRUE;
@@ -1221,12 +1363,6 @@ void spawnfunc_item_health_large (void) {
 }
 
 void spawnfunc_item_health_mega (void) {
-       if(!autocvar_g_powerup_superhealth)
-               return;
-
-       if((g_arena || g_ca) && !autocvar_g_arena_powerups)
-               return;
-
        if(g_minstagib) {
                minstagib_items(IT_NAILS);
        } else {
@@ -1248,12 +1384,6 @@ void spawnfunc_item_health25() { spawnfunc_item_health_medium(); }
 void spawnfunc_item_health100() { spawnfunc_item_health_mega(); }
 
 void spawnfunc_item_strength (void) {
-       if(!autocvar_g_powerup_strength)
-               return;
-
-       if((g_arena || g_ca) && !autocvar_g_arena_powerups)
-               return;
-
        if(g_minstagib) {
                minstagib_items(IT_STRENGTH);
        } else {
@@ -1264,12 +1394,6 @@ void spawnfunc_item_strength (void) {
 }
 
 void spawnfunc_item_invincible (void) {
-       if(!autocvar_g_powerup_shield)
-               return;
-
-       if((g_arena || g_ca) && !autocvar_g_arena_powerups)
-               return;
-
        if(g_minstagib) {
                minstagib_items(IT_INVINCIBLE);
        } else {
@@ -1532,12 +1656,12 @@ void GiveSound(entity e, float v0, float v1, float t, string snd_incr, string sn
        if(v1 <= v0 - t)
        {
                if(snd_decr != "")
-                       sound (e, CH_ITEMS, snd_decr, VOL_BASE, ATTN_NORM);
+                       sound (e, CH_TRIGGER, snd_decr, VOL_BASE, ATTN_NORM);
        }
        else if(v0 >= v0 + t)
        {
                if(snd_incr != "")
-                       sound (e, CH_ITEMS, snd_incr, VOL_BASE, ATTN_NORM);
+                       sound (e, CH_TRIGGER, snd_incr, VOL_BASE, ATTN_NORM);
        }
 }