set g_instagib_ammo_convert_cells 0 "convert normal cell ammo packs to insta cell ammo packs"
set g_instagib_ammo_convert_rockets 0 "convert rocket ammo packs to insta cell ammo packs"
set g_instagib_ammo_convert_shells 0 "convert shell ammo packs to insta cell ammo packs"
+set g_instagib_invisibility_time 30 "Time of ivisibility powerup in seconds."
set g_instagib_invis_alpha 0.15
+set g_instagib_speed_time 30 "Time of speed powerup in seconds."
set g_instagib_speed_highspeed 1.5 "speed-multiplier that applies while you carry the invincibility powerup"
set g_instagib_damagedbycontents 1 "allow damage from lava pits in instagib"
set g_instagib_blaster_keepdamage 0 "allow secondary fire to hurt players"
set g_smneg_bonus 1 "Stale-move negation: allow weapons to become stronger than their baseline"
set g_smneg_bonus_asymptote 4 "Stale-move negation: damage = infinity at this bonus level"
set g_smneg_cooldown_factor 0.25 "Stale-move negation: penalty cooldown factor"
+
+// ==============
+// random items
+// ==============
+set g_random_items 0 "Whether to enable random items."
+set g_random_loot 0 "Whether to enable random loot."
+exec randomitems-xonotic.cfg
{
entity item = M_ARGV(0, entity);
- if(item.classname == "droppedweapon")
+ if(Item_IsLoot(item))
if(item.weapon == WEP_NEXBALL.m_id)
return true;
#pragma once
#include "all.qh"
-#include "item/pickup.qh"
CLASS(Inventory, Object)
/** Stores counts of items, the id being the index */
if (!(minorBits & BIT(j))) { \
continue; \
} \
- const GameItem it = Items_from(Inventory_groups_minor * maj + j); \
+ const entity it = Items_from(Inventory_groups_minor * maj + j); \
WriteByte(MSG_ENTITY, data.inv_items[it.m_id]); \
} \
} \
#pragma once
-#include <common/t_items.qh>
#ifdef GAMEQC
+#include <common/models/all.qh>
#include <common/sounds/all.qh>
#include <common/sounds/all.inc>
+#include <common/stats.qh>
#endif
const int IT_UNLIMITED_WEAPON_AMMO = BIT(0); // when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup.
#ifdef SVQC
.float strength_finished = _STAT(STRENGTH_FINISHED);
.float invincible_finished = _STAT(INVINCIBLE_FINISHED);
+
+#define SPAWNFUNC_ITEM(name, item) \
+ spawnfunc(name) { StartItem(this, item); }
+
+#else
+
+#define SPAWNFUNC_ITEM(name, item)
+
#endif
+enum
+{
+ ITEM_FLAG_NORMAL = BIT(0), ///< Item is usable during normal gameplay.
+ ITEM_FLAG_INSTAGIB = BIT(1), ///< Item is usable in instagib.
+ ITEM_FLAG_OVERKILL = BIT(2), ///< Item is usable in overkill.
+ ITEM_FLAG_MUTATORBLOCKED = BIT(3)
+};
+
#define ITEM_HANDLE(signal, ...) __Item_Send_##signal(__VA_ARGS__)
CLASS(GameItem, Object)
ATTRIB(GameItem, m_id, int, 0);
+ /** the canonical spawnfunc name */
+ ATTRIB(GameItem, m_canonical_spawnfunc, string);
+ METHOD(GameItem, m_spawnfunc_hookreplace, GameItem(GameItem this, entity e)) { return this; }
ATTRIB(GameItem, m_name, string);
ATTRIB(GameItem, m_icon, string);
ATTRIB(GameItem, m_color, vector, '1 1 1');
#include "ammo.qh"
+
+#ifdef SVQC
+
+METHOD(Bullets, m_spawnfunc_hookreplace, GameItem(Bullets this, entity e))
+{
+ if (autocvar_sv_q3acompat_machineshotgunswap && !Item_IsLoot(e))
+ {
+ return ITEM_Shells;
+ }
+ return this;
+}
+
+METHOD(Shells, m_spawnfunc_hookreplace, GameItem(Shells this, entity e))
+{
+ if (autocvar_sv_q3acompat_machineshotgunswap && !Item_IsLoot(e))
+ {
+ return ITEM_Bullets;
+ }
+ return this;
+}
+
+#endif
#pragma once
#include "pickup.qh"
+#ifdef SVQC
+ #include <common/t_items.qh>
+#endif
+
+.int ammo_none;
+.int ammo_shells;
+.int ammo_nails;
+.int ammo_rockets;
+.int ammo_cells;
+#ifdef SVQC
+.int ammo_plasma = _STAT(PLASMA);
+.int ammo_fuel = _STAT(FUEL);
+#else
+.int ammo_plasma;
+.int ammo_fuel;
+#endif
+
#ifdef SVQC
PROPERTY(float, g_pickup_ammo_anyway);
#endif
#endif
ENDCLASS(Ammo)
-#ifdef SVQC
- #include <common/t_items.qh>
-#endif
#ifdef GAMEQC
MODEL(Bullets_ITEM, Item_Model("a_bullets.mdl"));
item.ammo_nails = g_pickup_nails;
}
#endif
-REGISTER_ITEM(Bullets, Ammo) {
+
+CLASS(Bullets, Ammo)
+ENDCLASS(Bullets)
+
+REGISTER_ITEM(Bullets, Bullets) {
+ this.m_canonical_spawnfunc = "item_bullets";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_Bullets_ITEM;
#endif
this.netname = "bullets";
#endif
}
+SPAWNFUNC_ITEM(item_bullets, ITEM_Bullets)
+
#ifdef GAMEQC
MODEL(Cells_ITEM, Item_Model("a_cells.md3"));
#endif
}
#endif
REGISTER_ITEM(Cells, Ammo) {
+ this.m_canonical_spawnfunc = "item_cells";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_Cells_ITEM;
#endif
this.netname = "cells";
#endif
}
+SPAWNFUNC_ITEM(item_cells, ITEM_Cells)
+
#ifdef GAMEQC
MODEL(Plasma_ITEM, Item_Model("a_cells.md3"));
#endif
}
#endif
REGISTER_ITEM(Plasma, Ammo) {
+ this.m_canonical_spawnfunc = "item_plasma";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_Plasma_ITEM;
#endif
this.netname = "plasma";
#endif
}
+SPAWNFUNC_ITEM(item_plasma, ITEM_Plasma)
+
#ifdef GAMEQC
MODEL(Rockets_ITEM, Item_Model("a_rockets.md3"));
#endif
}
#endif
REGISTER_ITEM(Rockets, Ammo) {
+ this.m_canonical_spawnfunc = "item_rockets";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_Rockets_ITEM;
#endif
this.netname = "rockets";
#endif
}
+SPAWNFUNC_ITEM(item_rockets, ITEM_Rockets)
+
#ifdef GAMEQC
MODEL(Shells_ITEM, Item_Model("a_shells.md3"));
#endif
item.ammo_shells = g_pickup_shells;
}
#endif
-REGISTER_ITEM(Shells, Ammo) {
+
+CLASS(Shells, Ammo)
+ENDCLASS(Shells)
+
+REGISTER_ITEM(Shells, Shells) {
+ this.m_canonical_spawnfunc = "item_shells";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_Shells_ITEM;
#endif
this.netname = "shells";
this.m_iteminit = ammo_shells_init;
#endif
}
+
+SPAWNFUNC_ITEM(item_shells, ITEM_Shells)
#endif
REGISTER_ITEM(ArmorSmall, Armor) {
+ this.m_canonical_spawnfunc = "item_armor_small";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_OVERKILL;
this.m_model = MDL_ArmorSmall_ITEM;
this.m_sound = SND_ArmorSmall;
#endif
#endif
}
+SPAWNFUNC_ITEM(item_armor_small, ITEM_ArmorSmall)
+
#ifdef GAMEQC
MODEL(ArmorMedium_ITEM, Item_Model("item_armor_medium.md3"));
SOUND(ArmorMedium, Item_Sound("armor10"));
#endif
REGISTER_ITEM(ArmorMedium, Armor) {
+ this.m_canonical_spawnfunc = "item_armor_medium";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_OVERKILL;
this.m_model = MDL_ArmorMedium_ITEM;
this.m_sound = SND_ArmorMedium;
#endif
#endif
}
+SPAWNFUNC_ITEM(item_armor_medium, ITEM_ArmorMedium)
+
#ifdef GAMEQC
MODEL(ArmorBig_ITEM, Item_Model("item_armor_big.md3"));
SOUND(ArmorBig, Item_Sound("armor17_5"));
#endif
REGISTER_ITEM(ArmorBig, Armor) {
+ this.m_canonical_spawnfunc = "item_armor_big";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_OVERKILL;
this.m_model = MDL_ArmorBig_ITEM;
this.m_sound = SND_ArmorBig;
#endif
#endif
}
+SPAWNFUNC_ITEM(item_armor_big, ITEM_ArmorBig)
+
#ifdef GAMEQC
MODEL(ArmorMega_ITEM, Item_Model("item_armor_large.md3"));
SOUND(ArmorMega, Item_Sound("armor25"));
#endif
REGISTER_ITEM(ArmorMega, Armor) {
+ this.m_canonical_spawnfunc = "item_armor_mega";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_OVERKILL;
this.m_model = MDL_ArmorMega_ITEM;
this.m_sound = SND_ArmorMega;
#endif
this.m_iteminit = item_armormega_init;
#endif
}
+
+SPAWNFUNC_ITEM(item_armor_mega, ITEM_ArmorMega)
#endif
REGISTER_ITEM(HealthSmall, Health) {
+ this.m_canonical_spawnfunc = "item_health_small";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_HealthSmall_ITEM;
this.m_sound = SND_HealthSmall;
#endif
#endif
}
+SPAWNFUNC_ITEM(item_health_small, ITEM_HealthSmall)
+
#ifdef GAMEQC
MODEL(HealthMedium_ITEM, Item_Model("g_h25.md3"));
SOUND(HealthMedium, Item_Sound("mediumhealth"));
#endif
REGISTER_ITEM(HealthMedium, Health) {
+ this.m_canonical_spawnfunc = "item_health_medium";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_HealthMedium_ITEM;
this.m_sound = SND_HealthMedium;
#endif
#endif
}
+SPAWNFUNC_ITEM(item_health_medium, ITEM_HealthMedium)
+
#ifdef GAMEQC
MODEL(HealthBig_ITEM, Item_Model("g_h50.md3"));
SOUND(HealthBig, Item_Sound("mediumhealth"));
#endif
REGISTER_ITEM(HealthBig, Health) {
+ this.m_canonical_spawnfunc = "item_health_big";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_HealthBig_ITEM;
this.m_sound = SND_HealthBig;
#endif
#endif
}
+SPAWNFUNC_ITEM(item_health_big, ITEM_HealthBig)
+
#ifdef GAMEQC
MODEL(HealthMega_ITEM, Item_Model("g_h100.md3"));
SOUND(HealthMega, Item_Sound("megahealth"));
#endif
REGISTER_ITEM(HealthMega, Health) {
+ this.m_canonical_spawnfunc = "item_health_mega";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_OVERKILL;
this.m_model = MDL_HealthMega_ITEM;
this.m_sound = SND_HealthMega;
#endif
this.m_iteminit = item_healthmega_init;
#endif
}
+
+SPAWNFUNC_ITEM(item_health_mega, ITEM_HealthMega)
#include "jetpack.qh"
+
+#ifdef SVQC
+
+METHOD(Jetpack, m_spawnfunc_hookreplace, GameItem(Jetpack this, entity e))
+{
+ if(start_items & ITEM_Jetpack.m_itemid)
+ {
+ return ITEM_JetpackFuel;
+ }
+ return this;
+}
+
+METHOD(JetpackRegen, m_spawnfunc_hookreplace, GameItem(JetpackRegen this, entity e))
+{
+ if (start_items & ITEM_JetpackRegen.m_itemid)
+ {
+ return ITEM_JetpackFuel;
+ }
+ return this;
+}
+
+#endif
item.ammo_fuel = g_pickup_fuel_jetpack;
}
#endif
+
+CLASS(Jetpack, Powerup)
+ENDCLASS(Jetpack)
+
REGISTER_ITEM(Jetpack, Powerup) {
+ this.m_canonical_spawnfunc = "item_jetpack";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_Jetpack_ITEM;
this.m_itemid = IT_JETPACK;
#endif
#endif
}
+SPAWNFUNC_ITEM(item_jetpack, ITEM_Jetpack)
+
#ifdef GAMEQC
MODEL(JetpackFuel_ITEM, Item_Model("g_fuel.md3"));
#endif
}
#endif
REGISTER_ITEM(JetpackFuel, Ammo) {
+ this.m_canonical_spawnfunc = "item_fuel";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_JetpackFuel_ITEM;
#endif
this.netname = "fuel";
#endif
}
+SPAWNFUNC_ITEM(item_fuel, ITEM_JetpackFuel)
+
#ifdef GAMEQC
MODEL(JetpackRegen_ITEM, Item_Model("g_fuelregen.md3"));
#endif
-REGISTER_ITEM(JetpackRegen, Powerup) {
+CLASS(JetpackRegen, Powerup)
+ENDCLASS(JetpackRegen)
+
+REGISTER_ITEM(JetpackRegen, JetpackRegen) {
+ this.m_canonical_spawnfunc = "item_fuel_regen";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_JetpackRegen_ITEM;
#endif
this.netname = "fuel_regen";
this.m_pickupevalfunc = ammo_pickupevalfunc;
#endif
}
+
+SPAWNFUNC_ITEM(item_fuel_regen, ITEM_JetpackRegen)
#include "pickup.qh"
+#include <common/items/inventory.qh>
#ifdef SVQC
bool ITEM_HANDLE(Pickup, entity this, entity item, entity player) {
return this.giveTo(this, item, player);
}
+
+METHOD(Pickup, giveTo, bool(Pickup this, entity item, entity player))
+{
+ TC(Pickup, this);
+ bool b = Item_GiveTo(item, player);
+ if (b) {
+ LOG_DEBUGF("entity %i picked up %s", player, this.m_name);
+ player.inventory.inv_items[this.m_id]++;
+ Inventory_update(player);
+ }
+ return b;
+}
+
#endif
PROPERTY(float, g_pickup_respawntimejitter_powerup)
#endif
-#include <common/items/inventory.qh>
#include <common/items/item.qh>
-#include <common/t_items.qh>
-
-#ifdef GAMEQC
-#include <common/models/all.qh>
-#include <common/sounds/all.qh>
-#include <common/sounds/all.inc>
-#endif
CLASS(Pickup, GameItem)
#ifdef GAMEQC
ATTRIB(Pickup, m_pickupanyway, float());
ATTRIB(Pickup, m_iteminit, void(entity item));
float Item_GiveTo(entity item, entity player);
- METHOD(Pickup, giveTo, bool(Pickup this, entity item, entity player))
- {
- TC(Pickup, this);
- bool b = Item_GiveTo(item, player);
- if (b) {
- LOG_DEBUGF("entity %i picked up %s", player, this.m_name);
- player.inventory.inv_items[this.m_id]++;
- Inventory_update(player);
- }
- return b;
- }
+ METHOD(Pickup, giveTo, bool(Pickup this, entity item, entity player));
bool ITEM_HANDLE(Pickup, Pickup this, entity item, entity player);
#endif
ENDCLASS(Pickup)
}
#endif
REGISTER_ITEM(Strength, Powerup) {
+ this.m_canonical_spawnfunc = "item_strength";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_Strength_ITEM;
this.m_sound = SND_Strength;
this.m_glow = true;
#endif
}
+SPAWNFUNC_ITEM(item_strength, ITEM_Strength)
+
#ifdef GAMEQC
MODEL(Shield_ITEM, Item_Model("g_invincible.md3"));
SOUND(Shield, Item_Sound("powerup_shield"));
}
#endif
REGISTER_ITEM(Shield, Powerup) {
+ this.m_canonical_spawnfunc = "item_shield";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_NORMAL;
this.m_model = MDL_Shield_ITEM;
this.m_sound = SND_Shield;
this.m_glow = true;
this.m_iteminit = powerup_shield_init;
#endif
}
+
+SPAWNFUNC_ITEM(item_shield, ITEM_Shield)
+SPAWNFUNC_ITEM(item_invincible, ITEM_Shield)
return;
vector org = CENTER_OR_VIEWOFS(this);
- entity e = new(droppedweapon); // use weapon handling to remove it on touch
+ entity e = spawn();
+ Item_SetLoot(e, true);
e.spawnfunc_checked = true;
e.monster_loot = this.monster_loot;
e.noalign = true;
StartItem(e, e.monster_loot);
e.gravity = 1;
- set_movetype(e, MOVETYPE_TOSS);
- e.reset = SUB_Remove;
setorigin(e, org);
e.velocity = randomvec() * 175 + '0 0 325';
e.item_spawnshieldtime = time + 0.7;
#include <common/mutators/mutator/physical_items/_mod.inc>
#include <common/mutators/mutator/pinata/_mod.inc>
#include <common/mutators/mutator/random_gravity/_mod.inc>
+#include <common/mutators/mutator/random_items/_mod.inc>
#include <common/mutators/mutator/rocketflying/_mod.inc>
#include <common/mutators/mutator/rocketminsta/_mod.inc>
#include <common/mutators/mutator/running_guns/_mod.inc>
#include <common/mutators/mutator/physical_items/_mod.qh>
#include <common/mutators/mutator/pinata/_mod.qh>
#include <common/mutators/mutator/random_gravity/_mod.qh>
+#include <common/mutators/mutator/random_items/_mod.qh>
#include <common/mutators/mutator/rocketflying/_mod.qh>
#include <common/mutators/mutator/rocketminsta/_mod.qh>
#include <common/mutators/mutator/running_guns/_mod.qh>
switch(ent.classname)
{
case "item_strength":
- case "item_invincible":
+ case "item_shield":
{
entity e = spawn();
buff_SpawnReplacement(e, ent);
// generated file; do not modify
#include <common/mutators/mutator/instagib/items.qc>
+#ifdef SVQC
+ #include <common/mutators/mutator/instagib/sv_items.qc>
+#endif
#ifdef SVQC
#include <common/mutators/mutator/instagib/sv_instagib.qc>
#endif
}
#endif
REGISTER_ITEM(VaporizerCells, Ammo) {
+ this.m_canonical_spawnfunc = "item_vaporizer_cells";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_INSTAGIB | ITEM_FLAG_MUTATORBLOCKED;
this.m_model = MDL_VaporizerCells_ITEM;
this.m_sound = SND_VaporizerCells;
#endif
- this.netname = "minst_cells";
+ this.netname = "vaporizer_cells";
this.m_name = "Vaporizer Ammo";
this.m_icon = "ammo_supercells";
#ifdef SVQC
#endif
}
+SPAWNFUNC_ITEM(item_vaporizer_cells, ITEM_VaporizerCells)
+SPAWNFUNC_ITEM(item_minst_cells, ITEM_VaporizerCells)
+
#ifdef GAMEQC
MODEL(ExtraLife_ITEM, Item_Model("g_h100.md3"));
SOUND(ExtraLife, Item_Sound("megahealth"));
#endif
REGISTER_ITEM(ExtraLife, Powerup) {
+ this.m_canonical_spawnfunc = "item_extralife";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_INSTAGIB;
this.m_model = MDL_ExtraLife_ITEM;
this.m_sound = SND_ExtraLife;
#endif
- this.netname = "health_mega";
+ this.netname = "extralife";
this.m_name = "Extra life";
this.m_icon = "item_mega_health";
this.m_color = '1 0 0';
this.m_itemid = IT_NAILS;
}
+SPAWNFUNC_ITEM(item_extralife, ITEM_ExtraLife)
+
#ifdef GAMEQC
MODEL(Invisibility_ITEM, Item_Model("g_strength.md3"));
SOUND(Invisibility, Item_Sound("powerup"));
#endif
+#ifdef SVQC
+/// \brief Initializes the invisibility powerup.
+/// \param[in,out] item Item to initialize.
+/// \return No return.
+void powerup_invisibility_init(entity item);
+#endif
+
REGISTER_ITEM(Invisibility, Powerup) {
+ this.m_canonical_spawnfunc = "item_invisibility";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_INSTAGIB;
this.m_model = MDL_Invisibility_ITEM;
this.m_sound = SND_Invisibility;
+ this.m_glow = true;
+ this.m_respawnsound = SND_STRENGTH_RESPAWN;
#endif
- this.netname = "strength";
+ this.netname = "invisibility";
this.m_name = "Invisibility";
this.m_icon = "strength";
this.m_color = '0 0 1';
this.m_waypoint = _("Invisibility");
this.m_waypointblink = 2;
this.m_itemid = IT_STRENGTH;
+#ifdef SVQC
+ this.m_iteminit = powerup_invisibility_init;
+#endif
}
+SPAWNFUNC_ITEM(item_invisibility, ITEM_Invisibility)
+
#ifdef GAMEQC
MODEL(Speed_ITEM, Item_Model("g_invincible.md3"));
SOUND(Speed, Item_Sound("powerup_shield"));
#endif
+#ifdef SVQC
+/// \brief Initializes the speed powerup.
+/// \param[in,out] item Item to initialize.
+/// \return No return.
+void powerup_speed_init(entity item);
+#endif
+
REGISTER_ITEM(Speed, Powerup) {
+ this.m_canonical_spawnfunc = "item_speed";
#ifdef GAMEQC
+ this.spawnflags = ITEM_FLAG_INSTAGIB;
this.m_model = MDL_Speed_ITEM;
this.m_sound = SND_Speed;
+ this.m_glow = true;
+ this.m_respawnsound = SND_SHIELD_RESPAWN;
#endif
- this.netname = "invincible";
+ this.netname = "speed";
this.m_name = "Speed";
this.m_icon = "shield";
this.m_color = '1 0 1';
this.m_waypoint = _("Speed");
this.m_waypointblink = 2;
this.m_itemid = IT_INVINCIBLE;
+#ifdef SVQC
+ this.m_iteminit = powerup_speed_init;
+#endif
}
+
+SPAWNFUNC_ITEM(item_speed, ITEM_Speed)
#include <common/items/_mod.qh>
-REGISTER_MUTATOR(mutator_instagib, autocvar_g_instagib && !g_nexball);
-
-spawnfunc(item_minst_cells)
+REGISTER_MUTATOR(mutator_instagib, autocvar_g_instagib && !g_nexball)
{
- if (!g_instagib) { delete(this); return; }
- StartItem(this, ITEM_VaporizerCells);
+ MUTATOR_ONADD
+ {
+ ITEM_VaporizerCells.spawnflags &= ~ITEM_FLAG_MUTATORBLOCKED;
+ }
+ MUTATOR_ONROLLBACK_OR_REMOVE
+ {
+ ITEM_VaporizerCells.spawnflags |= ITEM_FLAG_MUTATORBLOCKED;
+ }
}
void instagib_invisibility(entity this)
void replace_with_insta_cells(entity item)
{
- entity e = spawn();
+ entity e = new(item_vaporizer_cells);
setorigin(e, item.origin);
e.noalign = item.noalign;
e.cnt = item.cnt;
e.team = item.team;
e.spawnfunc_checked = true;
- spawnfunc_item_minst_cells(e);
+ spawnfunc_item_vaporizer_cells(e);
}
MUTATOR_HOOKFUNCTION(mutator_instagib, FilterItem)
return true;
}
- if(item.weapon == WEP_VAPORIZER.m_id && item.classname == "droppedweapon")
+ if(item.weapon == WEP_VAPORIZER.m_id && Item_IsLoot(item))
{
SetResourceAmount(item, RESOURCE_CELLS, autocvar_g_instagib_ammo_drop);
return false;
return false;
float cells = GetResourceAmount(item, RESOURCE_CELLS);
- if(cells > autocvar_g_instagib_ammo_drop && item.classname != "item_minst_cells")
+ if(cells > autocvar_g_instagib_ammo_drop && item.classname != "item_vaporizer_cells")
SetResourceAmount(item, RESOURCE_CELLS, autocvar_g_instagib_ammo_drop);
if(cells && !item.weapon)
if (!autocvar_g_powerups) { return; }
entity ent = M_ARGV(0, entity);
// Can't use .itemdef here
- if (!(ent.classname == "item_strength" || ent.classname == "item_invincible" || ent.classname == "item_health_mega"))
+ if (!(ent.classname == "item_strength" || ent.classname == "item_shield" || ent.classname == "item_health_mega"))
return;
entity e = spawn();
float r = random();
if (r < 0.3)
+ {
+ e.classname = "item_invisibility";
setthink(e, instagib_invisibility);
+ }
else if (r < 0.6)
+ {
+ e.classname = "item_extralife";
setthink(e, instagib_extralife);
+ }
else
+ {
+ e.classname = "item_speed";
setthink(e, instagib_speed);
+ }
e.nextthink = time + 0.1;
e.spawnflags = ent.spawnflags;
#include "items.qh"
float autocvar_g_instagib_invis_alpha;
+
+void instagib_invisibility(entity this);
+void instagib_extralife(entity this);
+void instagib_speed(entity this);
--- /dev/null
+#include "items.qh"
+
+/// \brief Time of ivisibility powerup in seconds.
+float autocvar_g_instagib_invisibility_time;
+/// \brief Time of speed powerup in seconds.
+float autocvar_g_instagib_speed_time;
+
+void powerup_invisibility_init(entity item)
+{
+ if(!item.strength_finished)
+ {
+ item.strength_finished = autocvar_g_instagib_invisibility_time;
+ }
+}
+
+
+void powerup_speed_init(entity item)
+{
+ if(!item.invincible_finished)
+ {
+ item.invincible_finished = autocvar_g_instagib_speed_time;
+ }
+}
#include "sv_new_toys.qh"
+#include "../random_items/sv_random_items.qh"
+
/*
CORE laser vortex lg rl cry gl elec hagar fireb hook
MUTATOR_HOOKFUNCTION(nt, SetWeaponreplace)
{
+ if (autocvar_g_random_items)
+ {
+ // Do not replace weapons when random items are enabled.
+ return;
+ }
entity wep = M_ARGV(0, entity);
entity wepinfo = M_ARGV(1, entity);
string ret_string = M_ARGV(2, string);
M_ARGV(3, float) /* damage */ = (M_ARGV(0, entity)).max_health * 0.1;
}
-spawnfunc(weapon_hmg) { weapon_defaultspawnfunc(this, WEP_HMG); }
-
void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity, int fire)
{
if (!PHYS_INPUT_BUTTON_ATCK(actor))
#pragma once
+#include <common/weapons/all.qh>
+
CLASS(HeavyMachineGun, Weapon)
+/* spawnfunc */ ATTRIB(HeavyMachineGun, m_canonical_spawnfunc, string, "weapon_hmg");
/* ammotype */ ATTRIB(HeavyMachineGun, ammo_type, int, RESOURCE_BULLETS);
/* impulse */ ATTRIB(HeavyMachineGun, impulse, int, 3);
/* flags */ ATTRIB(HeavyMachineGun, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_SUPERWEAPON);
ENDCLASS(HeavyMachineGun)
REGISTER_WEAPON(HMG, hmg, NEW(HeavyMachineGun));
+
+SPAWNFUNC_WEAPON(weapon_hmg, WEP_HMG)
#include "rpc.qh"
#ifdef SVQC
-spawnfunc(weapon_rpc) { weapon_defaultspawnfunc(this, WEP_RPC); }
void W_RocketPropelledChainsaw_Explode(entity this, entity directhitentity)
{
#pragma once
+#include <common/weapons/all.qh>
+
CLASS(RocketPropelledChainsaw, Weapon)
+/* spawnfunc */ ATTRIB(RocketPropelledChainsaw, m_canonical_spawnfunc, string, "weapon_rpc");
/* ammotype */ ATTRIB(RocketPropelledChainsaw, ammo_type, int, RESOURCE_ROCKETS);
/* impulse */ ATTRIB(RocketPropelledChainsaw, impulse, int, 9);
/* flags */ ATTRIB(RocketPropelledChainsaw, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_SUPERWEAPON);
ENDCLASS(RocketPropelledChainsaw)
REGISTER_WEAPON(RPC, rpc, NEW(RocketPropelledChainsaw));
+
+SPAWNFUNC_WEAPON(weapon_rpc, WEP_RPC)
bool autocvar_g_overkill_itemwaypoints = true;
-bool autocvar_g_overkill_filter_healthmega;
-bool autocvar_g_overkill_filter_armormedium;
-bool autocvar_g_overkill_filter_armorbig;
-bool autocvar_g_overkill_filter_armormega;
-
-.float ok_item;
-
.Weapon ok_lastwep[MAX_WEAPONSLOTS];
-void ok_Initialize();
-
REGISTER_MUTATOR(ok, expr_evaluate(autocvar_g_overkill) && !cvar("g_instagib") && !g_nexball && cvar_string("g_mod_balance") == "Overkill")
{
MUTATOR_ONADD
{
- ok_Initialize();
+ precache_all_playermodels("models/ok_player/*.dpm");
+
+ if (autocvar_g_overkill_filter_healthmega)
+ {
+ ITEM_HealthMega.spawnflags |= ITEM_FLAG_MUTATORBLOCKED;
+ }
+ if (autocvar_g_overkill_filter_armormedium)
+ {
+ ITEM_ArmorMedium.spawnflags |= ITEM_FLAG_MUTATORBLOCKED;
+ }
+ if (autocvar_g_overkill_filter_armorbig)
+ {
+ ITEM_ArmorBig.spawnflags |= ITEM_FLAG_MUTATORBLOCKED;
+ }
+ if (autocvar_g_overkill_filter_armormega)
+ {
+ ITEM_ArmorMega.spawnflags |= ITEM_FLAG_MUTATORBLOCKED;
+ }
+
+ WEP_RPC.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
+ WEP_HMG.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
+
+ WEP_SHOTGUN.mdl = "ok_shotgun";
+ WEP_MACHINEGUN.mdl = "ok_mg";
+ WEP_VORTEX.mdl = "ok_sniper";
}
MUTATOR_ONREMOVE
{
+ ITEM_HealthMega.spawnflags &= ~ITEM_FLAG_MUTATORBLOCKED;
+ ITEM_ArmorMedium.spawnflags &= ~ITEM_FLAG_MUTATORBLOCKED;
+ ITEM_ArmorBig.spawnflags &= ~ITEM_FLAG_MUTATORBLOCKED;
+ ITEM_ArmorMega.spawnflags &= ~ITEM_FLAG_MUTATORBLOCKED;
+
WEP_RPC.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
WEP_HMG.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
}
}
void W_Blaster_Attack(entity, .entity, float, float, float, float, float, float, float, float, float, float);
-spawnfunc(weapon_hmg);
-spawnfunc(weapon_rpc);
MUTATOR_HOOKFUNCTION(ok, Damage_Calculate, CBC_ORDER_LAST)
{
void ok_DropItem(entity this, entity targ)
{
- entity e = new(droppedweapon); // hax
+ entity e = spawn();
e.ok_item = true;
- e.noalign = true;
- e.pickup_anyway = true;
- e.spawnfunc_checked = true;
- spawnfunc_item_armor_small(e);
- if (!wasfreed(e)) { // might have been blocked by a mutator
- set_movetype(e, MOVETYPE_TOSS);
- e.gravity = 1;
- e.reset = SUB_Remove;
- setorigin(e, this.origin + '0 0 32');
- e.velocity = '0 0 200' + normalize(targ.origin - this.origin) * 500;
- SUB_SetFade(e, time + 5, 1);
- }
+ Item_InitializeLoot(e, "item_armor_small", this.origin + '0 0 32',
+ '0 0 200' + normalize(targ.origin - this.origin) * 500, 5);
}
MUTATOR_HOOKFUNCTION(ok, PlayerDies)
wep.nextthink = time + 0.1;
return true;
}
- else if(ent.classname == "item_invincible")
+ else if(ent.classname == "item_shield")
{
entity wep = new(weapon_rpc);
setorigin(wep, ent.origin);
if(item.ok_item)
return false;
- switch(item.itemdef)
- {
- case ITEM_HealthMega: return autocvar_g_overkill_filter_healthmega;
- case ITEM_ArmorMedium: return autocvar_g_overkill_filter_armormedium;
- case ITEM_ArmorBig: return autocvar_g_overkill_filter_armorbig;
- case ITEM_ArmorMega: return autocvar_g_overkill_filter_armormega;
- }
-
return true;
}
M_ARGV(0, string) = "Overkill";
return true;
}
-
-void ok_Initialize()
-{
- precache_all_playermodels("models/ok_player/*.dpm");
-
- WEP_RPC.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
- WEP_HMG.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
-
- WEP_SHOTGUN.mdl = "ok_shotgun";
- WEP_MACHINEGUN.mdl = "ok_mg";
- WEP_VORTEX.mdl = "ok_sniper";
-}
#pragma once
+
+bool autocvar_g_overkill_filter_healthmega;
+bool autocvar_g_overkill_filter_armormedium;
+bool autocvar_g_overkill_filter_armorbig;
+bool autocvar_g_overkill_filter_armormega;
+
+.float ok_item;
--- /dev/null
+// generated file; do not modify
+#ifdef SVQC
+ #include <common/mutators/mutator/random_items/sv_random_items.qc>
+#endif
--- /dev/null
+// generated file; do not modify
+#ifdef SVQC
+ #include <common/mutators/mutator/random_items/sv_random_items.qh>
+#endif
--- /dev/null
+#include "sv_random_items.qh"
+
+/// \file
+/// \brief Source file that contains implementation of the random items mutator.
+/// \author Lyberta
+/// \copyright GNU GPLv2 or any later version.
+
+//============================ Constants ======================================
+
+enum
+{
+ RANDOM_ITEM_TYPE_HEALTH = 1,
+ RANDOM_ITEM_TYPE_ARMOR,
+ RANDOM_ITEM_TYPE_RESOURCE,
+ RANDOM_ITEM_TYPE_WEAPON,
+ RANDOM_ITEM_TYPE_POWERUP
+};
+
+//======================= Global variables ====================================
+
+// Replace cvars
+
+/// \brief Classnames to replace %s with.
+/// string autocvar_g_random_items_replace_%s;
+
+// Map probability cvars
+
+/// \brief Probability of random %s spawning in the map.
+/// float autocvar_g_random_items_%s_probability;
+
+/// \brief Probability of random %s spawning in the map during overkill.
+/// float autocvar_g_random_items_overkill_%s_probability;
+
+// Loot
+
+bool autocvar_g_random_loot; ///< Whether to enable random loot.
+
+float autocvar_g_random_loot_min; ///< Minimum amount of loot items.
+float autocvar_g_random_loot_max; ///< Maximum amount of loot items.
+float autocvar_g_random_loot_time; ///< Amount of time the loot will stay.
+float autocvar_g_random_loot_spread; ///< How far can loot be thrown.
+
+// Loot probability cvars
+
+/// \brief Probability of random %s spawning as loot.
+/// float autocvar_g_random_loot_%s_probability;
+
+/// \brief Probability of random %s spawning as loot during overkill.
+/// float autocvar_g_random_loot_overkill_%s_probability;
+
+/// \brief Holds whether random item is spawning. Used to prevent infinite
+/// recursion.
+bool random_items_is_spawning = false;
+
+//====================== Forward declarations =================================
+
+/// \brief Returns a random classname of the item with specific property.
+/// \param[in] prefix Prefix of the cvars that hold probabilities.
+/// \return Random classname of the item.
+string RandomItems_GetRandomItemClassNameWithProperty(string prefix,
+ .bool item_property);
+
+//=========================== Public API ======================================
+
+string RandomItems_GetRandomItemClassName(string prefix)
+{
+ if (autocvar_g_instagib)
+ {
+ return RandomItems_GetRandomInstagibItemClassName(prefix);
+ }
+ if (expr_evaluate(autocvar_g_overkill))
+ {
+ return RandomItems_GetRandomOverkillItemClassName(prefix);
+ }
+ return RandomItems_GetRandomVanillaItemClassName(prefix);
+}
+
+string RandomItems_GetRandomVanillaItemClassName(string prefix)
+{
+ RandomSelection_Init();
+ string cvar_name = sprintf("g_%s_health_probability", prefix);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ }
+ else
+ {
+ RandomSelection_AddFloat(RANDOM_ITEM_TYPE_HEALTH, cvar(cvar_name), 1);
+ }
+ cvar_name = sprintf("g_%s_armor_probability", prefix);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ }
+ else
+ {
+ RandomSelection_AddFloat(RANDOM_ITEM_TYPE_ARMOR, cvar(cvar_name), 1);
+ }
+ cvar_name = sprintf("g_%s_resource_probability", prefix);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ }
+ else
+ {
+ RandomSelection_AddFloat(RANDOM_ITEM_TYPE_RESOURCE, cvar(cvar_name), 1);
+ }
+ cvar_name = sprintf("g_%s_weapon_probability", prefix);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ }
+ else
+ {
+ RandomSelection_AddFloat(RANDOM_ITEM_TYPE_WEAPON, cvar(cvar_name), 1);
+ }
+ cvar_name = sprintf("g_%s_powerup_probability", prefix);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ }
+ else
+ {
+ RandomSelection_AddFloat(RANDOM_ITEM_TYPE_POWERUP, cvar(cvar_name), 1);
+ }
+ int item_type = RandomSelection_chosen_float;
+ switch (item_type)
+ {
+ case RANDOM_ITEM_TYPE_HEALTH:
+ {
+ return RandomItems_GetRandomItemClassNameWithProperty(prefix,
+ instanceOfHealth);
+ }
+ case RANDOM_ITEM_TYPE_ARMOR:
+ {
+ return RandomItems_GetRandomItemClassNameWithProperty(prefix,
+ instanceOfArmor);
+ }
+ case RANDOM_ITEM_TYPE_RESOURCE:
+ {
+ return RandomItems_GetRandomItemClassNameWithProperty(prefix,
+ instanceOfAmmo);
+ }
+ case RANDOM_ITEM_TYPE_WEAPON:
+ {
+ RandomSelection_Init();
+ FOREACH(Weapons, it != WEP_Null &&
+ !(it.spawnflags & WEP_FLAG_MUTATORBLOCKED),
+ {
+ cvar_name = sprintf("g_%s_%s_probability", prefix,
+ it.m_canonical_spawnfunc);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.",
+ cvar_name);
+ continue;
+ }
+ RandomSelection_AddString(it.m_canonical_spawnfunc,
+ cvar(cvar_name), 1);
+ });
+ return RandomSelection_chosen_string;
+ }
+ case RANDOM_ITEM_TYPE_POWERUP:
+ {
+ return RandomItems_GetRandomItemClassNameWithProperty(prefix,
+ instanceOfPowerup);
+ }
+ }
+ return "";
+}
+
+string RandomItems_GetRandomInstagibItemClassName(string prefix)
+{
+ RandomSelection_Init();
+ FOREACH(Items, it.spawnflags & ITEM_FLAG_INSTAGIB,
+ {
+ string cvar_name = sprintf("g_%s_%s_probability", prefix,
+ it.m_canonical_spawnfunc);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ continue;
+ }
+ RandomSelection_AddString(it.m_canonical_spawnfunc, cvar(cvar_name), 1);
+ });
+ return RandomSelection_chosen_string;
+}
+
+string RandomItems_GetRandomOverkillItemClassName(string prefix)
+{
+ RandomSelection_Init();
+ FOREACH(Items, (it.spawnflags & ITEM_FLAG_OVERKILL) &&
+ !(it.spawnflags & ITEM_FLAG_MUTATORBLOCKED),
+ {
+ string cvar_name = sprintf("g_%s_overkill_%s_probability", prefix,
+ it.m_canonical_spawnfunc);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ continue;
+ }
+ RandomSelection_AddString(it.m_canonical_spawnfunc, cvar(cvar_name), 1);
+ });
+ string cvar_name = sprintf("g_%s_overkill_weapon_hmg_probability", prefix);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ }
+ else
+ {
+ RandomSelection_AddString("weapon_hmg", cvar(cvar_name), 1);
+ }
+ cvar_name = sprintf("g_%s_overkill_weapon_rpc_probability", prefix);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ }
+ else
+ {
+ RandomSelection_AddString("weapon_rpc", cvar(cvar_name), 1);
+ }
+ return RandomSelection_chosen_string;
+}
+
+//========================= Free functions ====================================
+
+/// \brief Returns list of classnames to replace a map item with.
+/// \param[in] item Item to inspect.
+/// \return List of classnames to replace a map item with.
+string RandomItems_GetItemReplacementClassNames(entity item)
+{
+ string cvar_name = sprintf("g_random_items_replace_%s", item.classname);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ return "";
+ }
+ return cvar_string(cvar_name);
+}
+
+string RandomItems_GetRandomItemClassNameWithProperty(string prefix,
+ .bool item_property)
+{
+ RandomSelection_Init();
+ FOREACH(Items, it.item_property && (it.spawnflags & ITEM_FLAG_NORMAL),
+ {
+ string cvar_name = sprintf("g_%s_%s_probability", prefix,
+ it.m_canonical_spawnfunc);
+ if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS))
+ {
+ LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name);
+ continue;
+ }
+ RandomSelection_AddString(it.m_canonical_spawnfunc, cvar(cvar_name), 1);
+ });
+ return RandomSelection_chosen_string;
+}
+
+/// \brief Replaces a map item.
+/// \param[in] item Item to replace.
+/// \return Spawned item on success, NULL otherwise.
+entity RandomItems_ReplaceMapItem(entity item)
+{
+ //PrintToChatAll(strcat("Replacing ", item.classname));
+ string new_classnames = RandomItems_GetItemReplacementClassNames(item);
+ if (new_classnames == "")
+ {
+ return NULL;
+ }
+ string new_classname;
+ if (new_classnames == "random")
+ {
+ new_classname = RandomItems_GetRandomItemClassName("random_items");
+ if (new_classname == "")
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ int num_new_classnames = tokenize_console(new_classnames);
+ if (num_new_classnames == 1)
+ {
+ new_classname = new_classnames;
+ }
+ else
+ {
+ int classname_index = floor(random() * num_new_classnames);
+ new_classname = argv(classname_index);
+ }
+ }
+ //PrintToChatAll(strcat("Replacing with ", new_classname));
+ if (new_classname == item.classname)
+ {
+ return NULL;
+ }
+ random_items_is_spawning = true;
+ entity new_item;
+ if (!expr_evaluate(autocvar_g_overkill))
+ {
+ new_item = Item_Create(strzone(new_classname), item.origin,
+ item.noalign);
+ random_items_is_spawning = false;
+ if (new_item == NULL)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ new_item = spawn();
+ new_item.classname = strzone(new_classname);
+ new_item.spawnfunc_checked = true;
+ new_item.noalign = item.noalign;
+ new_item.ok_item = true;
+ Item_Initialize(new_item, new_classname);
+ random_items_is_spawning = false;
+ if (wasfreed(new_item))
+ {
+ return NULL;
+ }
+ setorigin(new_item, item.origin);
+ }
+ if (item.team)
+ {
+ new_item.team = item.team;
+ }
+ return new_item;
+}
+
+/// \brief Spawns a random loot item.
+/// \param[in] position Position of the item.
+/// \return No return.
+void RandomItems_SpawnLootItem(vector position)
+{
+ string class_name = RandomItems_GetRandomItemClassName("random_loot");
+ if (class_name == "")
+ {
+ return;
+ }
+ vector spread = '0 0 0';
+ spread.z = autocvar_g_random_loot_spread / 2;
+ spread += randomvec() * autocvar_g_random_loot_spread;
+ random_items_is_spawning = true;
+ if (!expr_evaluate(autocvar_g_overkill))
+ {
+ Item_CreateLoot(class_name, position, spread,
+ autocvar_g_random_loot_time);
+ }
+ else
+ {
+ entity item = spawn();
+ item.ok_item = true;
+ item.classname = class_name;
+ Item_InitializeLoot(item, class_name, position, spread,
+ autocvar_g_random_loot_time);
+ }
+ random_items_is_spawning = false;
+}
+
+//============================= Hooks ========================================
+
+REGISTER_MUTATOR(random_items, (autocvar_g_random_items ||
+ autocvar_g_random_loot));
+
+MUTATOR_HOOKFUNCTION(random_items, BuildMutatorsString)
+{
+ M_ARGV(0, string) = strcat(M_ARGV(0, string), ":random_items");
+}
+
+MUTATOR_HOOKFUNCTION(random_items, BuildMutatorsPrettyString)
+{
+ M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Random items");
+}
+
+/// \brief Hook that is called when an item is about to spawn.
+MUTATOR_HOOKFUNCTION(random_items, FilterItem, CBC_ORDER_LAST)
+{
+ //PrintToChatAll("FilterItem");
+ if (!autocvar_g_random_items)
+ {
+ return false;
+ }
+ if (random_items_is_spawning == true)
+ {
+ return false;
+ }
+ entity item = M_ARGV(0, entity);
+ if (Item_IsLoot(item))
+ {
+ return false;
+ }
+ if (RandomItems_ReplaceMapItem(item) == NULL)
+ {
+ return false;
+ }
+ return true;
+}
+
+/// \brief Hook that is called after the player has touched an item.
+MUTATOR_HOOKFUNCTION(random_items, ItemTouched, CBC_ORDER_LAST)
+{
+ //PrintToChatAll("ItemTouched");
+ if (!autocvar_g_random_items)
+ {
+ return;
+ }
+ entity item = M_ARGV(0, entity);
+ if (Item_IsLoot(item))
+ {
+ return;
+ }
+ entity new_item = RandomItems_ReplaceMapItem(item);
+ if (new_item == NULL)
+ {
+ return;
+ }
+ Item_ScheduleRespawn(new_item);
+ delete(item);
+}
+
+/// \brief Hook which is called when the player dies.
+MUTATOR_HOOKFUNCTION(random_items, PlayerDies)
+{
+ //PrintToChatAll("PlayerDies");
+ if (!autocvar_g_random_loot)
+ {
+ return;
+ }
+ entity victim = M_ARGV(2, entity);
+ vector loot_position = victim.origin + '0 0 32';
+ int num_loot_items = floor(autocvar_g_random_loot_min + random() *
+ autocvar_g_random_loot_max);
+ for (int item_index = 0; item_index < num_loot_items; ++item_index)
+ {
+ RandomItems_SpawnLootItem(loot_position);
+ }
+}
--- /dev/null
+#pragma once
+
+/// \file
+/// \brief Header file that describes the random items mutator.
+/// \author Lyberta
+/// \copyright GNU GPLv2 or any later version.
+
+bool autocvar_g_random_items; ///< Whether to enable random items.
+
+/// \brief Returns a random classname of the item.
+/// \param[in] prefix Prefix of the cvars that hold probabilities.
+/// \return Random classname of the item.
+/// \note This function will automatically detect gamemode and use cvars from
+/// that gamemode.
+string RandomItems_GetRandomItemClassName(string prefix);
+
+/// \brief Returns a random classname of the vanilla item.
+/// \param[in] prefix Prefix of the cvars that hold probabilities.
+/// \return Random classname of the vanilla item.
+/// \note This includes mutator items that don't change gameplay a lot such as
+/// jetpack and new toys.
+string RandomItems_GetRandomVanillaItemClassName(string prefix);
+
+/// \brief Returns a random classname of the instagib item.
+/// \param[in] prefix Prefix of the cvars that hold probabilities.
+/// \return Random classname of the instagib item.
+string RandomItems_GetRandomInstagibItemClassName(string prefix);
+
+/// \brief Returns a random classname of the overkill item.
+/// \param[in] prefix Prefix of the cvars that hold probabilities.
+/// \return Random classname of the overkill item.
+string RandomItems_GetRandomOverkillItemClassName(string prefix);
#ifdef SVQC
#include "physics/movetypes/movetypes.qh"
+float warmup_limit;
#endif
REGISTER_STAT(MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, float)
void Item_Touch(entity this, entity toucher)
{
-
// remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky)
- if (this.classname == "droppedweapon")
+ if (Item_IsLoot(this))
{
if (ITEM_TOUCH_NEEDKILL())
{
toucher = M_ARGV(1, entity);
- if (this.classname == "droppedweapon")
+ if (Item_IsExpiring(this))
{
this.strength_finished = max(0, this.strength_finished - time);
this.invincible_finished = max(0, this.invincible_finished - time);
this.superweapons_finished = max(0, this.superweapons_finished - time);
}
- entity it = this.itemdef;
- bool gave = ITEM_HANDLE(Pickup, it, this, toucher);
+ bool gave = ITEM_HANDLE(Pickup, this.itemdef, this, toucher);
if (!gave)
{
- if (this.classname == "droppedweapon")
+ if (Item_IsExpiring(this))
{
// undo what we did above
this.strength_finished += time;
Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
_sound (toucher, (this.itemdef.instanceOfPowerup ? CH_TRIGGER_SINGLE : CH_TRIGGER), (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM);
- if (this.classname == "droppedweapon")
+ MUTATOR_CALLHOOK(ItemTouched, this, toucher);
+ if (wasfreed(this))
+ {
+ return;
+ }
+
+ if (Item_IsLoot(this))
+ {
delete(this);
- else if (this.spawnshieldtime)
+ return;
+ }
+ if (!this.spawnshieldtime)
{
- entity e;
- if(this.team)
+ return;
+ }
+ entity e;
+ if (this.team)
+ {
+ RandomSelection_Init();
+ IL_EACH(g_items, it.team == this.team,
{
- RandomSelection_Init();
- IL_EACH(g_items, it.team == this.team,
+ if (it.itemdef) // is a registered item
{
- if(it.itemdef) // is a registered item
- {
- Item_Show(it, -1);
- it.scheduledrespawntime = 0;
- RandomSelection_AddEnt(it, it.cnt, 0);
- }
- });
- e = RandomSelection_chosen_ent;
- Item_Show(e, 1); // reset its state so it is visible (extra sendflags doesn't matter, this happens anyway)
- }
- else
- e = this;
- Item_ScheduleRespawn(e);
+ Item_Show(it, -1);
+ it.scheduledrespawntime = 0;
+ RandomSelection_AddEnt(it, it.cnt, 0);
+ }
+ });
+ e = RandomSelection_chosen_ent;
+ Item_Show(e, 1); // reset its state so it is visible (extra sendflags doesn't matter, this happens anyway)
}
+ else
+ e = this;
+ Item_ScheduleRespawn(e);
}
void Item_Reset(entity this)
Item_Show(this, !this.state);
setorigin(this, this.origin);
- if (this.classname != "droppedweapon")
+ if (Item_IsLoot(this))
{
- setthink(this, Item_Think);
- this.nextthink = time;
-
- if (this.waypointsprite_attached)
- WaypointSprite_Kill(this.waypointsprite_attached);
-
- if (this.itemdef.instanceOfPowerup || (this.weapons & WEPSET_SUPERWEAPONS)) // do not spawn powerups initially!
- Item_ScheduleInitialRespawn(this);
+ return;
+ }
+ setthink(this, Item_Think);
+ this.nextthink = time;
+ if (this.waypointsprite_attached)
+ {
+ WaypointSprite_Kill(this.waypointsprite_attached);
+ }
+ if (this.itemdef.instanceOfPowerup || (this.weapons & WEPSET_SUPERWEAPONS)) // do not spawn powerups initially!
+ {
+ Item_ScheduleInitialRespawn(this);
}
}
return;
}
- // is it a dropped weapon?
- if (this.classname == "droppedweapon")
+ if (Item_IsLoot(this))
{
this.reset = SUB_Remove;
- // it's a dropped weapon
set_movetype(this, MOVETYPE_TOSS);
// Savage: remove thrown items after a certain period of time ("garbage collection")
this.takedamage = DAMAGE_YES;
this.event_damage = Item_Damage;
- if(this.strength_finished || this.invincible_finished || this.superweapons_finished)
+ if (Item_IsExpiring(this))
{
// if item is worthless after a timer, have it expire then
this.nextthink = max(this.strength_finished, this.invincible_finished, this.superweapons_finished);
if(def.instanceOfWeaponPickup)
{
- if (this.classname != "droppedweapon") // if dropped, colormap is already set up nicely
+ if (!Item_IsLoot(this)) // if dropped, colormap is already set up nicely
this.colormap = 1024; // color shirt=0 pants=0 grey
else
this.gravity = 1;
void StartItem(entity this, GameItem def)
{
+ def = def.m_spawnfunc_hookreplace(def, this);
+ if (def.spawnflags & ITEM_FLAG_MUTATORBLOCKED)
+ {
+ delete(this);
+ return;
+ }
+ this.classname = def.m_canonical_spawnfunc;
_StartItem(
this,
this.itemdef = def,
}
}
-spawnfunc(item_rockets)
-{
- StartItem(this, ITEM_Rockets);
-}
-
-spawnfunc(item_bullets)
-{
- if(!weaponswapping && autocvar_sv_q3acompat_machineshotgunswap &&
- (this.classname != "droppedweapon"))
- {
- weaponswapping = true;
- spawnfunc_item_shells(this);
- weaponswapping = false;
- return;
- }
-
- StartItem(this, ITEM_Bullets);
-}
-
-spawnfunc(item_cells)
-{
- StartItem(this, ITEM_Cells);
-}
-
-spawnfunc(item_plasma)
-{
- StartItem(this, ITEM_Plasma);
-}
-
-spawnfunc(item_shells)
-{
- if(!weaponswapping && autocvar_sv_q3acompat_machineshotgunswap &&
- (this.classname != "droppedweapon"))
- {
- weaponswapping = true;
- spawnfunc_item_bullets(this);
- weaponswapping = false;
- return;
- }
-
- StartItem(this, ITEM_Shells);
-}
-
-spawnfunc(item_armor_small)
-{
- StartItem(this, ITEM_ArmorSmall);
-}
-
-spawnfunc(item_armor_medium)
-{
- StartItem(this, ITEM_ArmorMedium);
-}
-
-spawnfunc(item_armor_big)
-{
- StartItem(this, ITEM_ArmorBig);
-}
-
-spawnfunc(item_armor_mega)
-{
- StartItem(this, ITEM_ArmorMega);
-}
-
-spawnfunc(item_health_small)
-{
- StartItem(this, ITEM_HealthSmall);
-}
-
-spawnfunc(item_health_medium)
-{
- StartItem(this, ITEM_HealthMedium);
-}
-
-spawnfunc(item_health_big)
-{
- StartItem(this, ITEM_HealthBig);
-}
-
-spawnfunc(item_health_mega)
-{
- StartItem(this, ITEM_HealthMega);
-}
-
-// support old misnamed entities
-spawnfunc(item_armor1) { spawnfunc_item_armor_small(this); } // FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
-spawnfunc(item_armor25) { spawnfunc_item_armor_mega(this); }
-spawnfunc(item_armor_large) { spawnfunc_item_armor_mega(this); }
-spawnfunc(item_health1) { spawnfunc_item_health_small(this); }
-spawnfunc(item_health25) { spawnfunc_item_health_medium(this); }
-spawnfunc(item_health_large) { spawnfunc_item_health_big(this); }
-spawnfunc(item_health100) { spawnfunc_item_health_mega(this); }
-
-spawnfunc(item_strength)
-{
- StartItem(this, ITEM_Strength);
-}
-
-spawnfunc(item_invincible)
-{
- StartItem(this, ITEM_Shield);
-}
-
-// compatibility:
-spawnfunc(item_quad) { this.classname = "item_strength";spawnfunc_item_strength(this);}
-
void target_items_use(entity this, entity actor, entity trigger)
{
- if(actor.classname == "droppedweapon")
+ if(Item_IsLoot(actor))
{
EXACTTRIGGER_TOUCH(this, trigger);
delete(actor);
EXACTTRIGGER_TOUCH(this, trigger);
}
- IL_EACH(g_items, it.enemy == actor && it.classname == "droppedweapon",
+ IL_EACH(g_items, it.enemy == actor && Item_IsLoot(it),
{
delete(it);
});
}
}
-spawnfunc(item_fuel)
-{
- StartItem(this, ITEM_JetpackFuel);
-}
-
-spawnfunc(item_fuel_regen)
-{
- if(start_items & ITEM_JetpackRegen.m_itemid)
- {
- spawnfunc_item_fuel(this);
- return;
- }
- StartItem(this, ITEM_JetpackRegen);
-}
-
-spawnfunc(item_jetpack)
-{
- if(start_items & ITEM_Jetpack.m_itemid)
- {
- spawnfunc_item_fuel(this);
- return;
- }
- StartItem(this, ITEM_Jetpack);
-}
-
float GiveWeapon(entity e, float wpn, float op, float val)
{
WepSet v0, v1;
#pragma once
-#ifdef SVQC
-#include <server/defs.qh>
-#endif
-
const int AMMO_COUNT = 4; // amount of ammo types to show in the inventory panel
// item networking
#endif
#ifdef SVQC
-spawnfunc(item_strength);
-spawnfunc(item_invincible);
-spawnfunc(item_armor_small);
-spawnfunc(item_shells);
-spawnfunc(item_bullets);
-spawnfunc(item_rockets);
float autocvar_sv_simple_items;
bool ItemSend(entity this, entity to, int sf);
-
bool have_pickup_item(entity this);
const float ITEM_RESPAWN_TICKS = 10;
/** idle frame */
const int WS_READY = 4;
-#ifdef SVQC
-.int ammo_shells;
-.int ammo_nails;
-.int ammo_rockets;
-.int ammo_cells;
-.int ammo_plasma = _STAT(PLASMA);
-.int ammo_fuel = _STAT(FUEL);
-.int ammo_none;
-#else
-.int ammo_shells;
-.int ammo_nails;
-.int ammo_rockets;
-.int ammo_cells;
-.int ammo_plasma;
-.int ammo_fuel;
-.int ammo_none;
-#endif
-
/** fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A" */
CLASS(Weapon, Object)
ATTRIB(Weapon, m_id, int, 0);
+ /** the canonical spawnfunc name */
+ ATTRIB(Weapon, m_canonical_spawnfunc, string);
+ /** control what happens when this weapon is spawned */
+ METHOD(Weapon, m_spawnfunc_hookreplace, Weapon(Weapon this, entity e)) { return this; }
/** A: WEPSET_id : WEPSET_... */
ATTRIB(Weapon, weapons, WepSet, '0 0 0');
/** M: ammotype : main ammo type */
}
ENDCLASS(Weapon)
+#ifdef SVQC
+
+void weapon_defaultspawnfunc(entity this, Weapon e);
+#define SPAWNFUNC_WEAPON(name, weapon) \
+ spawnfunc(name) { weapon_defaultspawnfunc(this, weapon); }
+
+#else
+
+#define SPAWNFUNC_WEAPON(name, weapon)
+
+#endif
+
#include <common/items/_mod.qh>
CLASS(WeaponPickup, Pickup)
ATTRIB(WeaponPickup, m_weapon, Weapon);
#include "arc.qh"
#ifdef SVQC
-spawnfunc(weapon_arc) { weapon_defaultspawnfunc(this, WEP_ARC); }
bool W_Arc_Beam_Send(entity this, entity to, int sf)
{
#pragma once
CLASS(Arc, Weapon)
+/* spawnfunc */ ATTRIB(Arc, m_canonical_spawnfunc, string, "weapon_arc");
/* ammotype */ ATTRIB(Arc, ammo_type, int, RESOURCE_CELLS);
/* impulse */ ATTRIB(Arc, impulse, int, 3);
/* flags */ ATTRIB(Arc, spawnflags, int, WEP_TYPE_HITSCAN);
ENDCLASS(Arc)
REGISTER_WEAPON(ARC, arc, NEW(Arc));
+SPAWNFUNC_WEAPON(weapon_arc, WEP_ARC)
#ifdef GAMEQC
const float ARC_MAX_SEGMENTS = 20;
#include "blaster.qh"
#ifdef SVQC
-spawnfunc(weapon_blaster) { weapon_defaultspawnfunc(this, WEP_BLASTER); }
-spawnfunc(weapon_laser) { spawnfunc_weapon_blaster(this); }
void W_Blaster_Touch(entity this, entity toucher)
{
#pragma once
CLASS(Blaster, Weapon)
+/* spawnfunc */ ATTRIB(Blaster, m_canonical_spawnfunc, string, "weapon_blaster");
/* ammotype */ //ATTRIB(Blaster, ammo_type, int, RESOURCE_NONE);
/* impulse */ ATTRIB(Blaster, impulse, int, 1);
/* flags */ ATTRIB(Blaster, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
ENDCLASS(Blaster)
REGISTER_WEAPON(BLASTER, blaster, NEW(Blaster));
+SPAWNFUNC_WEAPON(weapon_blaster, WEP_BLASTER)
+SPAWNFUNC_WEAPON(weapon_laser, WEP_BLASTER)
+
#ifdef SVQC
.float blaster_damage;
.float blaster_edgedamage;
.float blaster_radius;
.float blaster_force;
.float blaster_lifetime;
+
#endif
#include "crylink.qh"
#ifdef SVQC
-spawnfunc(weapon_crylink) { weapon_defaultspawnfunc(this, WEP_CRYLINK); }
void W_Crylink_CheckLinks(entity e)
{
#pragma once
CLASS(Crylink, Weapon)
+/* spawnfunc */ ATTRIB(Crylink, m_canonical_spawnfunc, string, "weapon_crylink");
/* ammotype */ ATTRIB(Crylink, ammo_type, int, RESOURCE_CELLS);
/* impulse */ ATTRIB(Crylink, impulse, int, 6);
/* flags */ ATTRIB(Crylink, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_CANCLIMB | WEP_FLAG_NODUAL);
ENDCLASS(Crylink)
REGISTER_WEAPON(CRYLINK, crylink, NEW(Crylink));
+SPAWNFUNC_WEAPON(weapon_crylink, WEP_CRYLINK)
+
#ifdef SVQC
.float gravity;
.float crylink_waitrelease;
#include "devastator.qh"
#ifdef SVQC
-spawnfunc(weapon_devastator) { weapon_defaultspawnfunc(this, WEP_DEVASTATOR); }
-spawnfunc(weapon_rocketlauncher) { spawnfunc_weapon_devastator(this); }
.entity lastrocket;
#pragma once
CLASS(Devastator, Weapon)
+/* spawnfunc */ ATTRIB(Devastator, m_canonical_spawnfunc, string, "weapon_devastator");
/* ammotype */ ATTRIB(Devastator, ammo_type, int, RESOURCE_ROCKETS);
/* impulse */ ATTRIB(Devastator, impulse, int, 9);
/* flags */ ATTRIB(Devastator, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH | WEP_FLAG_NODUAL);
ENDCLASS(Devastator)
REGISTER_WEAPON(DEVASTATOR, devastator, NEW(Devastator));
+SPAWNFUNC_WEAPON(weapon_devastator, WEP_DEVASTATOR)
+SPAWNFUNC_WEAPON(weapon_rocketlauncher, WEP_DEVASTATOR)
+
#ifdef SVQC
.float rl_release;
.float rl_detonate_later;
#include "electro.qh"
#ifdef SVQC
-spawnfunc(weapon_electro) { weapon_defaultspawnfunc(this, WEP_ELECTRO); }
void W_Electro_TriggerCombo(vector org, float rad, entity own)
{
#pragma once
CLASS(Electro, Weapon)
+/* spawnfunc */ ATTRIB(Electro, m_canonical_spawnfunc, string, "weapon_electro");
/* ammotype */ ATTRIB(Electro, ammo_type, int, RESOURCE_CELLS);
/* impulse */ ATTRIB(Electro, impulse, int, 5);
/* flags */ ATTRIB(Electro, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
ENDCLASS(Electro)
REGISTER_WEAPON(ELECTRO, electro, NEW(Electro));
+SPAWNFUNC_WEAPON(weapon_electro, WEP_ELECTRO)
#ifdef SVQC
.float electro_count;
#include "fireball.qh"
#ifdef SVQC
-spawnfunc(weapon_fireball) { weapon_defaultspawnfunc(this, WEP_FIREBALL); }
void W_Fireball_Explode(entity this, entity directhitentity)
{
#pragma once
CLASS(Fireball, Weapon)
+/* spawnfunc */ ATTRIB(Fireball, m_canonical_spawnfunc, string, "weapon_fireball");
/* ammotype */ //ATTRIB(Fireball, ammo_type, int, RESOURCE_NONE);
/* impulse */ ATTRIB(Fireball, impulse, int, 9);
/* flags */ ATTRIB(Fireball, spawnflags, int, WEP_FLAG_SUPERWEAPON | WEP_TYPE_SPLASH | WEP_FLAG_NODUAL);
ENDCLASS(Fireball)
REGISTER_WEAPON(FIREBALL, fireball, NEW(Fireball));
+SPAWNFUNC_WEAPON(weapon_fireball, WEP_FIREBALL)
+
#ifdef SVQC
.float bot_primary_fireballmooth; // whatever a mooth is
.vector fireball_impactvec;
#include "hagar.qh"
#ifdef SVQC
-spawnfunc(weapon_hagar) { weapon_defaultspawnfunc(this, WEP_HAGAR); }
// NO bounce protection, as bounces are limited!
#pragma once
CLASS(Hagar, Weapon)
+/* spawnfunc */ ATTRIB(Hagar, m_canonical_spawnfunc, string, "weapon_hagar");
/* ammotype */ ATTRIB(Hagar, ammo_type, int, RESOURCE_ROCKETS);
/* impulse */ ATTRIB(Hagar, impulse, int, 8);
/* flags */ ATTRIB(Hagar, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
ENDCLASS(Hagar)
REGISTER_WEAPON(HAGAR, hagar, NEW(Hagar));
+
+SPAWNFUNC_WEAPON(weapon_hagar, WEP_HAGAR)
#include "hlac.qh"
#ifdef SVQC
-spawnfunc(weapon_hlac) { weapon_defaultspawnfunc(this, WEP_HLAC); }
void W_HLAC_Touch(entity this, entity toucher)
{
#pragma once
CLASS(HLAC, Weapon)
+/* spawnfunc */ ATTRIB(HLAC, m_canonical_spawnfunc, string, "weapon_hlac");
/* ammotype */ ATTRIB(HLAC, ammo_type, int, RESOURCE_CELLS);
/* impulse */ ATTRIB(HLAC, impulse, int, 6);
/* flags */ ATTRIB(HLAC, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
ENDCLASS(HLAC)
REGISTER_WEAPON(HLAC, hlac, NEW(HLAC));
+
+SPAWNFUNC_WEAPON(weapon_hlac, WEP_HLAC)
#ifdef SVQC
-spawnfunc(weapon_hook) { weapon_defaultspawnfunc(this, WEP_HOOK); }
-
void W_Hook_ExplodeThink(entity this)
{
float dt, dmg_remaining_next, f;
#pragma once
CLASS(Hook, Weapon)
+/* spawnfunc */ ATTRIB(Hook, m_canonical_spawnfunc, string, "weapon_hook");
/* ammotype */ ATTRIB(Hook, ammo_type, int, RESOURCE_FUEL);
/* impulse */ ATTRIB(Hook, impulse, int, 0);
/* flags */ ATTRIB(Hook, spawnflags, int, WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
ENDCLASS(Hook)
REGISTER_WEAPON(HOOK, hook, NEW(Hook));
+SPAWNFUNC_WEAPON(weapon_hook, WEP_HOOK)
+
CLASS(OffhandHook, OffhandWeapon)
#ifdef SVQC
METHOD(OffhandHook, offhand_think, void(OffhandHook this, entity actor, bool key_pressed))
#ifdef SVQC
-spawnfunc(weapon_machinegun)
+METHOD(MachineGun, m_spawnfunc_hookreplace, Weapon(MachineGun this, entity e))
{
- if(autocvar_sv_q3acompat_machineshotgunswap)
- if(this.classname != "droppedweapon")
+ if (autocvar_sv_q3acompat_machineshotgunswap && !Item_IsLoot(e))
{
- weapon_defaultspawnfunc(this, WEP_SHOCKWAVE);
- return;
+ return WEP_SHOCKWAVE;
}
- weapon_defaultspawnfunc(this, WEP_MACHINEGUN);
+ return this;
}
-spawnfunc(weapon_uzi) { spawnfunc_weapon_machinegun(this); }
void W_MachineGun_MuzzleFlash_Think(entity this)
{
#pragma once
CLASS(MachineGun, Weapon)
+/* spawnfunc */ ATTRIB(MachineGun, m_canonical_spawnfunc, string, "weapon_machinegun");
/* ammotype */ ATTRIB(MachineGun, ammo_type, int, RESOURCE_BULLETS);
/* impulse */ ATTRIB(MachineGun, impulse, int, 3);
/* flags */ ATTRIB(MachineGun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_PENETRATEWALLS);
ENDCLASS(MachineGun)
REGISTER_WEAPON(MACHINEGUN, machinegun, NEW(MachineGun));
+
+SPAWNFUNC_WEAPON(weapon_machinegun, WEP_MACHINEGUN)
+SPAWNFUNC_WEAPON(weapon_uzi, WEP_MACHINEGUN)
#include "minelayer.qh"
#ifdef SVQC
-spawnfunc(weapon_minelayer) { weapon_defaultspawnfunc(this, WEP_MINE_LAYER); }
void W_MineLayer_Stick(entity this, entity to)
{
#pragma once
CLASS(MineLayer, Weapon)
+/* spawnfunc */ ATTRIB(MineLayer, m_canonical_spawnfunc, string, "weapon_minelayer");
/* ammotype */ ATTRIB(MineLayer, ammo_type, int, RESOURCE_ROCKETS);
/* impulse */ ATTRIB(MineLayer, impulse, int, 4);
/* flags */ ATTRIB(MineLayer, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
ENDCLASS(MineLayer)
REGISTER_WEAPON(MINE_LAYER, minelayer, NEW(MineLayer));
+SPAWNFUNC_WEAPON(weapon_minelayer, WEP_MINE_LAYER)
+
#ifdef SVQC
void W_MineLayer_Think(entity this);
.float minelayer_detonate, mine_explodeanyway;
#ifdef SVQC
-spawnfunc(weapon_mortar) { weapon_defaultspawnfunc(this, WEP_MORTAR); }
-spawnfunc(weapon_grenadelauncher) { spawnfunc_weapon_mortar(this); }
-
void W_Mortar_Grenade_Explode(entity this, entity directhitentity)
{
if(directhitentity.takedamage == DAMAGE_AIM)
#pragma once
CLASS(Mortar, Weapon)
+/* spawnfunc */ ATTRIB(Mortar, m_canonical_spawnfunc, string, "weapon_mortar");
/* ammotype */ ATTRIB(Mortar, ammo_type, int, RESOURCE_ROCKETS);
/* impulse */ ATTRIB(Mortar, impulse, int, 4);
/* flags */ ATTRIB(Mortar, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
ENDCLASS(Mortar)
REGISTER_WEAPON(MORTAR, mortar, NEW(Mortar));
+SPAWNFUNC_WEAPON(weapon_mortar, WEP_MORTAR)
+SPAWNFUNC_WEAPON(weapon_grenadelauncher, WEP_MORTAR)
#ifdef SVQC
.float gl_detonate_later;
#ifdef SVQC
#include <common/triggers/trigger/jumppads.qh>
-spawnfunc(weapon_porto) { weapon_defaultspawnfunc(this, WEP_PORTO); }
-
REGISTER_MUTATOR(porto_ticker, true);
MUTATOR_HOOKFUNCTION(porto_ticker, SV_StartFrame) {
FOREACH_CLIENT(IS_PLAYER(it), it.porto_forbidden = max(0, it.porto_forbidden - 1));
#pragma once
CLASS(PortoLaunch, Weapon)
+/* spawnfunc */ ATTRIB(PortoLaunch, m_canonical_spawnfunc, string, "weapon_porto");
/* ammotype */ ATTRIB(PortoLaunch, ammo_type, int, RESOURCE_NONE);
/* impulse */ ATTRIB(PortoLaunch, impulse, int, 0);
/* flags */ ATTRIB(PortoLaunch, spawnflags, int, WEP_TYPE_OTHER | WEP_FLAG_SUPERWEAPON | WEP_FLAG_NODUAL);
ENDCLASS(PortoLaunch)
REGISTER_WEAPON(PORTO, porto, NEW(PortoLaunch));
+SPAWNFUNC_WEAPON(weapon_porto, WEP_PORTO)
+
#ifdef SVQC
.entity porto_current;
.vector porto_v_angle; // holds "held" view angles
#include "rifle.qh"
#ifdef SVQC
-spawnfunc(weapon_rifle) { weapon_defaultspawnfunc(this, WEP_RIFLE); }
-spawnfunc(weapon_campingrifle) { spawnfunc_weapon_rifle(this); }
-spawnfunc(weapon_sniperrifle) { spawnfunc_weapon_rifle(this); }
void W_Rifle_FireBullet(Weapon thiswep, .entity weaponentity, float pSpread, float pDamage, float pForce, float pSolidPenetration, float pAmmo, int deathtype, float pTracer, float pShots, Sound pSound, entity actor)
{
#pragma once
CLASS(Rifle, Weapon)
+/* spawnfunc */ ATTRIB(Rifle, m_canonical_spawnfunc, string, "weapon_rifle");
/* ammotype */ ATTRIB(Rifle, ammo_type, int, RESOURCE_BULLETS);
/* impulse */ ATTRIB(Rifle, impulse, int, 7);
/* flags */ ATTRIB(Rifle, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_PENETRATEWALLS);
ENDCLASS(Rifle)
REGISTER_WEAPON(RIFLE, rifle, NEW(Rifle));
+SPAWNFUNC_WEAPON(weapon_rifle, WEP_RIFLE)
+SPAWNFUNC_WEAPON(weapon_campingrifle, WEP_RIFLE)
+SPAWNFUNC_WEAPON(weapon_sniperrifle, WEP_RIFLE)
#ifdef SVQC
.float rifle_accumulator;
#include "seeker.qh"
#ifdef SVQC
-spawnfunc(weapon_seeker) { weapon_defaultspawnfunc(this, WEP_SEEKER); }
// ============================
// Begin: Missile functions, these are general functions to be manipulated by other code
#pragma once
CLASS(Seeker, Weapon)
+/* spawnfunc */ ATTRIB(Seeker, m_canonical_spawnfunc, string, "weapon_seeker");
/* ammotype */ ATTRIB(Seeker, ammo_type, int, RESOURCE_ROCKETS);
/* impulse */ ATTRIB(Seeker, impulse, int, 8);
/* flags */ ATTRIB(Seeker, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
ENDCLASS(Seeker)
REGISTER_WEAPON(SEEKER, seeker, NEW(Seeker));
+SPAWNFUNC_WEAPON(weapon_seeker, WEP_SEEKER)
+
#ifdef SVQC
.entity tag_target, wps_tag_tracker;
.float tag_time;
REGISTER_NET_TEMP(TE_CSQC_SHOCKWAVEPARTICLE)
#ifdef SVQC
-spawnfunc(weapon_shockwave)
+METHOD(Shockwave, m_spawnfunc_hookreplace, Weapon(Shockwave this, entity e))
{
//if(autocvar_sv_q3acompat_machineshockwaveswap) // WEAPONTODO
- if(autocvar_sv_q3acompat_machineshotgunswap)
- if(this.classname != "droppedweapon")
+ if (autocvar_sv_q3acompat_machineshotgunswap && !Item_IsLoot(e))
{
- weapon_defaultspawnfunc(this, WEP_MACHINEGUN);
- return;
+ return WEP_MACHINEGUN;
}
- weapon_defaultspawnfunc(this, WEP_SHOCKWAVE);
+ return this;
}
const float MAX_SHOCKWAVE_HITS = 10;
#pragma once
CLASS(Shockwave, Weapon)
+/* spawnfunc */ ATTRIB(Shockwave, m_canonical_spawnfunc, string, "weapon_shockwave");
/* ammotype */ //ATTRIB(Shockwave, ammo_type, int, RESOURCE_NONE);
/* impulse */ ATTRIB(Shockwave, impulse, int, 2);
/* flags */ ATTRIB(Shockwave, spawnflags, int, WEP_TYPE_HITSCAN | WEP_FLAG_CANCLIMB | WEP_TYPE_MELEE_SEC);
ENDCLASS(Shockwave)
REGISTER_WEAPON(SHOCKWAVE, shockwave, NEW(Shockwave));
+SPAWNFUNC_WEAPON(weapon_shockwave, WEP_SHOCKWAVE)
#ifdef CSQC
void Net_ReadShockwaveParticle();
#include "shotgun.qh"
#ifdef SVQC
-spawnfunc(weapon_shotgun) { weapon_defaultspawnfunc(this, WEP_SHOTGUN); }
void W_Shotgun_Attack(Weapon thiswep, entity actor, .entity weaponentity, float isprimary)
{
#pragma once
CLASS(Shotgun, Weapon)
+/* spawnfunc */ ATTRIB(Shotgun, m_canonical_spawnfunc, string, "weapon_shotgun");
/* ammotype */ ATTRIB(Shotgun, ammo_type, int, RESOURCE_SHELLS);
/* impulse */ ATTRIB(Shotgun, impulse, int, 2);
/* flags */ ATTRIB(Shotgun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_TYPE_MELEE_SEC);
ENDCLASS(Shotgun)
REGISTER_WEAPON(SHOTGUN, shotgun, NEW(Shotgun));
+
+SPAWNFUNC_WEAPON(weapon_shotgun, WEP_SHOTGUN)
.float tuba_lastnotes_cnt; // over
.vector tuba_lastnotes[MAX_TUBANOTES];
-spawnfunc(weapon_tuba) { weapon_defaultspawnfunc(this, WEP_TUBA); }
-
bool W_Tuba_HasPlayed(entity pl, .entity weaponentity, string melody, int instrument, bool ignorepitch, float mintempo, float maxtempo)
{
float i, j, mmin, mmax, nolength;
#pragma once
CLASS(Tuba, Weapon)
+/* spawnfunc */ ATTRIB(Tuba, m_canonical_spawnfunc, string, "weapon_tuba");
/* impulse */ ATTRIB(Tuba, impulse, int, 1);
/* flags */ ATTRIB(Tuba, spawnflags, int, WEP_FLAG_HIDDEN | WEP_TYPE_SPLASH | WEP_FLAG_NODUAL);
/* rating */ ATTRIB(Tuba, bot_pickupbasevalue, float, 2000);
ENDCLASS(Tuba)
REGISTER_WEAPON(TUBA, tuba, NEW(Tuba));
+SPAWNFUNC_WEAPON(weapon_tuba, WEP_TUBA)
+
#ifdef CSQC
entityclass(Tuba);
class(Tuba) .int note;
#endif
#ifdef SVQC
-spawnfunc(weapon_vaporizer) { weapon_defaultspawnfunc(this, WEP_VAPORIZER); }
-spawnfunc(weapon_minstanex) { spawnfunc_weapon_vaporizer(this); }
void W_RocketMinsta_Explosion(entity actor, vector loc)
{
#pragma once
CLASS(Vaporizer, Weapon)
+/* spawnfunc */ ATTRIB(Vaporizer, m_canonical_spawnfunc, string, "weapon_vaporizer");
/* ammotype */ ATTRIB(Vaporizer, ammo_type, int, RESOURCE_CELLS);
/* impulse */ ATTRIB(Vaporizer, impulse, int, 7);
/* flags */ ATTRIB(Vaporizer, spawnflags, int, WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_FLAG_SUPERWEAPON | WEP_TYPE_HITSCAN | WEP_FLAG_NODUAL);
ENDCLASS(Vaporizer)
REGISTER_WEAPON(VAPORIZER, vaporizer, NEW(Vaporizer));
+SPAWNFUNC_WEAPON(weapon_vaporizer, WEP_VAPORIZER)
+SPAWNFUNC_WEAPON(weapon_minstanex, WEP_VAPORIZER)
#ifdef SVQC
.float vaporizer_lasthit;
#endif
#ifdef SVQC
-spawnfunc(weapon_vortex) { weapon_defaultspawnfunc(this, WEP_VORTEX); }
-spawnfunc(weapon_nex) { spawnfunc_weapon_vortex(this); }
REGISTER_MUTATOR(vortex_charge, true);
#pragma once
CLASS(Vortex, Weapon)
+/* spawnfunc */ ATTRIB(Vortex, m_canonical_spawnfunc, string, "weapon_vortex");
/* ammotype */ ATTRIB(Vortex, ammo_type, int, RESOURCE_CELLS);
/* impulse */ ATTRIB(Vortex, impulse, int, 7);
/* flags */ ATTRIB(Vortex, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_NODUAL);
ENDCLASS(Vortex)
REGISTER_WEAPON(VORTEX, vortex, NEW(Vortex));
+SPAWNFUNC_WEAPON(weapon_vortex, WEP_VORTEX)
+SPAWNFUNC_WEAPON(weapon_nex, WEP_VORTEX)
#ifdef SVQC
-
.float vortex_lasthit;
#endif
#include <server/impulse.qc>
#include <server/ipban.qc>
#include <server/item_key.qc>
+#include <server/items.qc>
#include <server/mapvoting.qc>
#include <server/matrix.qc>
#include <server/miscfunctions.qc>
#include <server/impulse.qh>
#include <server/ipban.qh>
#include <server/item_key.qh>
+#include <server/items.qh>
#include <server/mapvoting.qh>
#include <server/matrix.qh>
#include <server/miscfunctions.qh>
#include <server/defs.qh>
#include <server/miscfunctions.qh>
+#include <server/items.qh>
#include "havocbot.qh"
#include "../cvars.qh"
continue;
// Check if the item can be picked up safely
- if(it.classname == "droppedweapon")
+ if(Item_IsLoot(it))
{
if(!IS_ONGROUND(it))
continue;
#include <server/miscfunctions.qh>
#include <common/weapons/_all.qh>
-spawnfunc(weapon_electro);
-spawnfunc(weapon_hagar);
-spawnfunc(weapon_machinegun);
-spawnfunc(item_bullets);
-spawnfunc(item_armor_mega);
-spawnfunc(item_health_mega);
-spawnfunc(item_health_medium);
-
//***********************
//QUAKE 1 ENTITIES - So people can play quake1 maps with the xonotic weapons
//***********************
-spawnfunc(weapon_nailgun) {spawnfunc_weapon_electro(this);}
-spawnfunc(weapon_supernailgun) {spawnfunc_weapon_hagar(this);}
-spawnfunc(weapon_supershotgun) {spawnfunc_weapon_machinegun(this);}
+SPAWNFUNC_WEAPON(weapon_nailgun, WEP_ELECTRO)
+SPAWNFUNC_WEAPON(weapon_supernailgun, WEP_HAGAR)
+SPAWNFUNC_WEAPON(weapon_supershotgun, WEP_MACHINEGUN)
-spawnfunc(item_spikes) {spawnfunc_item_bullets(this);}
+SPAWNFUNC_ITEM(item_spikes, ITEM_Bullets)
//spawnfunc(item_armor1) {spawnfunc_item_armor_medium(this);} // FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
-spawnfunc(item_armor2) {spawnfunc_item_armor_mega(this);}
-spawnfunc(item_armorInv) {spawnfunc_item_armor_mega(this);} // TODO: make sure we actually want this
-spawnfunc(item_health) {if (this.spawnflags & 2) spawnfunc_item_health_mega(this);else spawnfunc_item_health_medium(this);}
-
-//spawnfunc_item_spikes
-//spawnfunc_item_health
-
-
-
+SPAWNFUNC_ITEM(item_armor2, ITEM_ArmorMega)
+SPAWNFUNC_ITEM(item_armorInv, ITEM_ArmorMega) // TODO: make sure we actually want this
+spawnfunc(item_health) {if (this.spawnflags & 2) StartItem(this, ITEM_HealthMega);else StartItem(this, ITEM_HealthMedium);}
#include "quake2.qh"
-spawnfunc(item_armor_medium);
-
-spawnfunc(item_invincible);
-
+#include <common/items/_mod.qh>
//***********************
//QUAKE 2 ENTITIES - So people can play quake2 maps with the xonotic weapons
//***********************
-spawnfunc(item_armor_jacket) {spawnfunc_item_armor_medium(this);}
+SPAWNFUNC_ITEM(item_armor_jacket, ITEM_ArmorMedium)
-spawnfunc(item_invulnerability) {spawnfunc_item_invincible(this);}
+SPAWNFUNC_ITEM(item_invulnerability, ITEM_Shield)
// rest of the quake 2 entities are handled by q1 and q3 compat
#include <server/defs.qh>
#include <server/miscfunctions.qh>
+#include <server/items.qh>
#include <common/weapons/_all.qh>
-spawnfunc(weapon_crylink);
-spawnfunc(weapon_electro);
-spawnfunc(weapon_hagar);
-spawnfunc(weapon_hook);
-spawnfunc(weapon_machinegun);
-spawnfunc(weapon_vortex);
-spawnfunc(weapon_minelayer);
-
spawnfunc(target_items);
-spawnfunc(item_bullets);
-spawnfunc(item_cells);
-spawnfunc(item_rockets);
-spawnfunc(item_shells);
-
-spawnfunc(item_strength);
-
-spawnfunc(item_armor_big);
-spawnfunc(item_armor_mega);
-spawnfunc(item_armor_small);
-
-spawnfunc(item_health_medium);
-spawnfunc(item_health_mega);
-
//***********************
//QUAKE 3 ENTITIES - So people can play quake3 maps with the xonotic weapons
//***********************
// NOTE: for best experience, you need to swap MGs with SGs in the map or it won't have a MG
// SG -> SG
-spawnfunc(ammo_shells) { spawnfunc_item_shells(this); }
+SPAWNFUNC_ITEM(ammo_shells, ITEM_Shells)
// MG -> MG
-spawnfunc(ammo_bullets) { spawnfunc_item_bullets(this); }
+SPAWNFUNC_ITEM(ammo_bullets, ITEM_Bullets)
// GL -> Mortar
-spawnfunc(ammo_grenades) { spawnfunc_item_rockets(this); }
+SPAWNFUNC_ITEM(ammo_grenades, ITEM_Rockets)
// Mines -> Rockets
-spawnfunc(weapon_prox_launcher) { spawnfunc_weapon_minelayer(this); }
-spawnfunc(ammo_mines) { spawnfunc_item_rockets(this); }
+SPAWNFUNC_WEAPON(weapon_prox_launcher, WEP_MINE_LAYER)
+SPAWNFUNC_ITEM(ammo_mines, ITEM_Rockets)
// LG -> Lightning
-spawnfunc(weapon_lightning) { spawnfunc_weapon_electro(this); }
-spawnfunc(ammo_lightning) { spawnfunc_item_cells(this); }
+SPAWNFUNC_WEAPON(weapon_lightning, WEP_ELECTRO)
+SPAWNFUNC_ITEM(ammo_lightning, ITEM_Cells)
// Plasma -> Hagar
-spawnfunc(weapon_plasmagun) { spawnfunc_weapon_hagar(this); }
-spawnfunc(ammo_cells) { spawnfunc_item_rockets(this); }
+SPAWNFUNC_WEAPON(weapon_plasmagun, WEP_HAGAR)
+SPAWNFUNC_ITEM(ammo_cells, ITEM_Rockets)
// Rail -> Vortex
-spawnfunc(weapon_railgun) { spawnfunc_weapon_vortex(this); }
-spawnfunc(ammo_slugs) { spawnfunc_item_cells(this); }
+SPAWNFUNC_WEAPON(weapon_railgun, WEP_VORTEX)
+SPAWNFUNC_ITEM(ammo_slugs, ITEM_Cells)
// BFG -> Crylink
-spawnfunc(weapon_bfg) { spawnfunc_weapon_crylink(this); }
-spawnfunc(ammo_bfg) { spawnfunc_item_cells(this); }
+SPAWNFUNC_WEAPON(weapon_bfg, WEP_CRYLINK)
+SPAWNFUNC_ITEM(ammo_bfg, ITEM_Cells)
// grappling hook -> hook
-spawnfunc(weapon_grapplinghook) { spawnfunc_weapon_hook(this); }
+SPAWNFUNC_WEAPON(weapon_grapplinghook, WEP_HOOK)
// RL -> RL
-spawnfunc(ammo_rockets) { spawnfunc_item_rockets(this); }
+SPAWNFUNC_ITEM(ammo_rockets, ITEM_Rockets)
// Armor
-spawnfunc(item_armor_body) { spawnfunc_item_armor_mega(this); }
-spawnfunc(item_armor_combat) { spawnfunc_item_armor_big(this); }
-spawnfunc(item_armor_shard) { spawnfunc_item_armor_small(this); }
-spawnfunc(item_enviro) { spawnfunc_item_invincible(this); }
+SPAWNFUNC_ITEM(item_armor_body, ITEM_ArmorMega)
+SPAWNFUNC_ITEM(item_armor_combat, ITEM_ArmorBig)
+SPAWNFUNC_ITEM(item_armor_shard, ITEM_ArmorSmall)
+SPAWNFUNC_ITEM(item_enviro, ITEM_Shield)
// medkit -> armor (we have no holdables)
-spawnfunc(holdable_medkit) { spawnfunc_item_armor_mega(this); }
+SPAWNFUNC_ITEM(holdable_medkit, ITEM_ArmorMega)
// doubler -> strength
-spawnfunc(item_doubler) { spawnfunc_item_strength(this); }
+SPAWNFUNC_ITEM(item_doubler, ITEM_Strength)
.float wait;
.float delay;
#include <server/defs.qh>
#include <server/miscfunctions.qh>
+#include <server/items.qh>
#include <common/weapons/_all.qh>
-// #include <server/mutators/gamemode.qh>
-
-spawnfunc(weapon_arc);
-spawnfunc(weapon_crylink);
-spawnfunc(weapon_electro);
-spawnfunc(weapon_mortar);
-spawnfunc(weapon_hagar);
-spawnfunc(weapon_machinegun);
-spawnfunc(weapon_devastator);
-spawnfunc(weapon_shotgun);
-spawnfunc(weapon_vortex);
-
-spawnfunc(item_armor_big);
-spawnfunc(item_armor_mega);
-spawnfunc(item_armor_small);
-
-spawnfunc(item_bullets);
-spawnfunc(item_cells);
-spawnfunc(item_quad);
-spawnfunc(item_rockets);
-spawnfunc(item_shells);
-
-spawnfunc(item_jetpack);
spawnfunc(item_haste);
-spawnfunc(item_health_medium);
-spawnfunc(item_health_mega);
spawnfunc(item_invis);
//***********************
-//WORD OF PADMAN ENTITIES - So people can play wop maps with the xonotic weapons
+//WORLD OF PADMAN ENTITIES - So people can play wop maps with the xonotic weapons
//***********************
//spawnfunc(item_revival) /* handled by buffs mutator */
//spawnfunc(item_jumper) /* handled by buffs mutator */
-spawnfunc(weapon_punchy) { spawnfunc_weapon_arc(this); }
-spawnfunc(weapon_nipper) { spawnfunc_weapon_machinegun(this); }
-spawnfunc(weapon_pumper) { spawnfunc_weapon_shotgun(this); }
-spawnfunc(weapon_boaster) { spawnfunc_weapon_electro(this); }
-spawnfunc(weapon_splasher) { spawnfunc_weapon_vortex(this); }
-spawnfunc(weapon_bubbleg) { spawnfunc_weapon_hagar(this); }
-spawnfunc(weapon_balloony) { spawnfunc_weapon_mortar(this); }
-spawnfunc(weapon_betty) { spawnfunc_weapon_devastator(this); }
-spawnfunc(weapon_imperius) { spawnfunc_weapon_crylink(this); }
-
-spawnfunc(ammo_pumper) { spawnfunc_item_shells(this); }
-spawnfunc(ammo_nipper) { spawnfunc_item_bullets(this); }
-spawnfunc(ammo_balloony) { spawnfunc_item_rockets(this); }
-spawnfunc(ammo_bubbleg) { spawnfunc_item_rockets(this); }
-spawnfunc(ammo_boaster) { spawnfunc_item_cells(this); }
-spawnfunc(ammo_betty) { spawnfunc_item_rockets(this); }
-spawnfunc(ammo_imperius) { spawnfunc_item_cells(this); }
-
-spawnfunc(item_padpower) { spawnfunc_item_quad(this); }
-spawnfunc(item_climber) { spawnfunc_item_invincible(this); }
+SPAWNFUNC_WEAPON(weapon_punchy, WEP_ARC)
+SPAWNFUNC_WEAPON(weapon_nipper, WEP_MACHINEGUN)
+SPAWNFUNC_WEAPON(weapon_pumper, WEP_SHOTGUN)
+SPAWNFUNC_WEAPON(weapon_boaster, WEP_ELECTRO)
+SPAWNFUNC_WEAPON(weapon_splasher, WEP_VORTEX)
+SPAWNFUNC_WEAPON(weapon_bubbleg, WEP_HAGAR)
+SPAWNFUNC_WEAPON(weapon_balloony, WEP_MORTAR)
+SPAWNFUNC_WEAPON(weapon_betty, WEP_DEVASTATOR)
+SPAWNFUNC_WEAPON(weapon_imperius, WEP_CRYLINK)
+
+SPAWNFUNC_ITEM(ammo_pumper, ITEM_Shells)
+SPAWNFUNC_ITEM(ammo_nipper, ITEM_Bullets)
+SPAWNFUNC_ITEM(ammo_balloony, ITEM_Rockets)
+SPAWNFUNC_ITEM(ammo_bubbleg, ITEM_Rockets)
+SPAWNFUNC_ITEM(ammo_boaster, ITEM_Cells)
+SPAWNFUNC_ITEM(ammo_betty, ITEM_Rockets)
+SPAWNFUNC_ITEM(ammo_imperius, ITEM_Cells)
+
+SPAWNFUNC_ITEM(item_padpower, ITEM_Strength)
+SPAWNFUNC_ITEM(item_climber, ITEM_Shield)
spawnfunc(item_speedy) { spawnfunc_item_haste(this); }
spawnfunc(item_visionless) { spawnfunc_item_invis(this); }
-spawnfunc(item_armor_padshield) { spawnfunc_item_armor_mega(this); }
+SPAWNFUNC_ITEM(item_armor_padshield, ITEM_ArmorMega)
-spawnfunc(holdable_floater) { spawnfunc_item_jetpack(this); }
+SPAWNFUNC_ITEM(holdable_floater, ITEM_Jetpack)
#pragma once
-float warmup_limit;
#include <common/weapons/_all.qh>
#include <common/stats.qh>
--- /dev/null
+#include "items.qh"
+
+/// \file
+/// \brief Source file that contains implementation of the functions related to
+/// game items.
+/// \copyright GNU GPLv2 or any later version.
+
+#include "g_subs.qh"
+#include <common/weapons/all.qh>
+
+.bool m_isloot; ///< Holds whether item is loot.
+/// \brief Holds whether strength, shield or superweapon timers expire while
+/// this item is on the ground.
+.bool m_isexpiring;
+
+entity Item_Create(string class_name, vector position, bool no_align)
+{
+ entity item = spawn();
+ item.classname = class_name;
+ item.spawnfunc_checked = true;
+ setorigin(item, position);
+ item.noalign = no_align;
+ Item_Initialize(item, class_name);
+ if (wasfreed(item))
+ {
+ return NULL;
+ }
+ return item;
+}
+
+void Item_Initialize(entity item, string class_name)
+{
+ FOREACH(Weapons, it.m_canonical_spawnfunc == class_name,
+ {
+ weapon_defaultspawnfunc(item, it);
+ return;
+ });
+ FOREACH(Items, it.m_canonical_spawnfunc == class_name,
+ {
+ StartItem(item, it);
+ return;
+ });
+ LOG_FATALF("Item_Initialize: Invalid classname: %s", class_name);
+}
+
+entity Item_CreateLoot(string class_name, vector position, vector vel,
+ float time_to_live)
+{
+ entity item = spawn();
+ if (!Item_InitializeLoot(item, class_name, position, vel, time_to_live))
+ {
+ return NULL;
+ }
+ return item;
+}
+
+bool Item_InitializeLoot(entity item, string class_name, vector position,
+ vector vel, float time_to_live)
+{
+ item.classname = class_name;
+ Item_SetLoot(item, true);
+ item.noalign = true;
+ setorigin(item, position);
+ item.pickup_anyway = true;
+ item.spawnfunc_checked = true;
+ Item_Initialize(item, class_name);
+ if (wasfreed(item))
+ {
+ return false;
+ }
+ item.gravity = 1;
+ item.velocity = vel;
+ SUB_SetFade(item, time + time_to_live, 1);
+ return true;
+}
+
+bool Item_IsLoot(entity item)
+{
+ return item.m_isloot;
+}
+
+void Item_SetLoot(entity item, bool loot)
+{
+ item.m_isloot = loot;
+}
+
+bool Item_IsExpiring(entity item)
+{
+ return item.m_isexpiring;
+}
+
+void Item_SetExpiring(entity item, bool expiring)
+{
+ item.m_isexpiring = expiring;
+}
+
+// Compatibility spawn functions
+
+// FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
+SPAWNFUNC_ITEM(item_armor1, ITEM_ArmorSmall)
+
+SPAWNFUNC_ITEM(item_armor25, ITEM_ArmorMega)
+
+SPAWNFUNC_ITEM(item_armor_large, ITEM_ArmorMega)
+
+SPAWNFUNC_ITEM(item_health1, ITEM_HealthSmall)
+
+SPAWNFUNC_ITEM(item_health25, ITEM_HealthMedium)
+
+SPAWNFUNC_ITEM(item_health_large, ITEM_HealthBig)
+
+SPAWNFUNC_ITEM(item_health100, ITEM_HealthMega)
+
+SPAWNFUNC_ITEM(item_quad, ITEM_Strength)
--- /dev/null
+#pragma once
+
+/// \file
+/// \brief Header file that describes the functions related to game items.
+/// \copyright GNU GPLv2 or any later version.
+
+/// \brief Creates a new item.
+/// \param[in] class_name Class name of the item.
+/// \param[in] position Position of the item.
+/// \param[in] no_align True if item should be placed directly at specified
+/// position, false to let it drop to the ground.
+/// \return Item on success, NULL otherwise.
+entity Item_Create(string class_name, vector position, bool no_align);
+
+/// \brief Initializes the item according to classname.
+/// \param[in,out] item Item to initialize.
+/// \param[in] class_name Class name to use.
+/// \return No return.
+/// \nore This function is useful if you want to set some item properties before
+/// initialization.
+void Item_Initialize(entity item, string class_name);
+
+/// \brief Creates a loot item.
+/// \param[in] class_name Class name of the item.
+/// \param[in] position Position of the item.
+/// \param[in] velocity of the item.
+/// \param[in] time_to_live Amount of time after which the item will disappear.
+/// \return Item on success, NULL otherwise.
+entity Item_CreateLoot(string class_name, vector position, vector vel,
+ float time_to_live);
+
+/// \brief Initializes the loot item.
+/// \param[in] class_name Class name of the item.
+/// \param[in] position Position of the item.
+/// \param[in] velocity of the item.
+/// \param[in] time_to_live Amount of time after which the item will disappear.
+/// \return True on success, false otherwise.
+/// \nore This function is useful if you want to set some item properties before
+/// initialization.
+bool Item_InitializeLoot(entity item, string class_name, vector position,
+ vector vel, float time_to_live);
+
+/// \brief Returns whether the item is loot.
+/// \param[in] item Item to check.
+/// \return True if the item is loot, false otherwise.
+bool Item_IsLoot(entity item);
+
+/// \brief Sets the item loot status.
+/// \param[in,out] item Item to adjust.
+/// \param[in] loot Whether item is loot.
+/// \return No return.
+void Item_SetLoot(entity item, bool loot);
+
+/// \brief Returns whether the item is expiring (i.e. its strength, shield and
+/// superweapon timers expire while it is on the ground).
+/// \param[in] item Item to check.
+/// \return True if the item is expiring, false otherwise.
+bool Item_IsExpiring(entity item);
+
+/// \brief Sets the item expiring status (i.e. whether its strength, shield
+/// and superweapon timers expire while it is on the ground).
+/// \param[in,out] item Item to adjust.
+/// \param[in] expiring Whether item is expiring.
+/// \return No return.
+void Item_SetExpiring(entity item, bool expiring);
#include "mutators/_mod.qh"
#include "../common/t_items.qh"
#include "resources.qh"
+#include "items.qh"
#include "weapons/accuracy.qh"
#include "weapons/csqcprojectile.qh"
#include "weapons/selection.qh"
"g_random_start_shells"));
SetResourceAmount(random_start_ammo, RESOURCE_BULLETS, cvar(
"g_random_start_bullets"));
- SetResourceAmount(random_start_ammo, RESOURCE_ROCKETS,
+ SetResourceAmount(random_start_ammo, RESOURCE_ROCKETS,
cvar("g_random_start_rockets"));
SetResourceAmount(random_start_ammo, RESOURCE_CELLS, cvar(
"g_random_start_cells"));
return false;
if(e.iscreature)
return true;
+ if (Item_IsLoot(e))
+ {
+ return true;
+ }
switch(e.classname)
{
case "body":
- case "droppedweapon":
return true;
case "bullet": // antilagged bullets can't hit this either
return false;
MUT_ITEMTOUCH_PICKUP // return this flag to have the item "picked up" and taken even after mutator handled it
};
+/** called after the item has been touched. */
+#define EV_ItemTouched(i, o) \
+ /** item */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** toucher */ i(entity, MUTATOR_ARGV_1_entity) \
+ /**/
+MUTATOR_HOOKABLE(ItemTouched, EV_ItemTouched);
+
/** Called when the amount of entity resources changes. Can be used to override
resource limit. */
#define EV_GetResourceLimit(i, o) \
#include "gamemode_cts.qh"
-#include <server/race.qh>
#include <server/race.qh>
+#include <server/items.qh>
float autocvar_g_cts_finish_kill_delay;
bool autocvar_g_cts_selfdamage;
{
entity item = M_ARGV(0, entity);
- if(item.classname == "droppedweapon")
+ if (Item_IsLoot(item))
+ {
return true;
+ }
}
MUTATOR_HOOKFUNCTION(cts, Damage_Calculate)
#include "gamemode_lms.qh"
-#include <common/mutators/mutator/instagib/items.qc>
+#include <common/mutators/mutator/instagib/items.qh>
#include <server/campaign.qh>
#include <server/command/_mod.qh>
#include "weaponsystem.qh"
#include <common/t_items.qh>
+#include <server/items.qh>
#include <common/constants.qh>
#include <common/net_linked.qh>
#include <common/util.qh>
if (!autocvar_g_showweaponspawns) return;
IL_EACH(g_items, it.weapon == this.m_id && (!it.team || (it.ItemStatus & ITS_AVAILABLE)),
{
- if (it.classname == "droppedweapon" && autocvar_g_showweaponspawns < 2)
+ if (Item_IsLoot(it) && (autocvar_g_showweaponspawns < 2))
+ {
continue;
+ }
entity wp = WaypointSprite_Spawn(
WP_Weapon,
-2, 0,
#include "../resources.qh"
#include "../mutators/_mod.qh"
#include <common/t_items.qh>
+#include <server/items.qh>
#include <common/weapons/_all.qh>
+.bool m_isreplaced; ///< Holds whether the weapon has been replaced.
+
string W_Apply_Weaponreplace(string in)
{
string out = "";
void weapon_defaultspawnfunc(entity this, Weapon e)
{
Weapon wpn = e;
- if (this.classname != "droppedweapon" && this.classname != "replacedweapon")
+ e = wpn = wpn.m_spawnfunc_hookreplace(wpn, this);
+ this.classname = wpn.m_canonical_spawnfunc;
+ if (!Item_IsLoot(this) && !this.m_isreplaced)
{
if (e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
{
{
entity replacement = spawn();
copyentity(this, replacement);
- replacement.classname = "replacedweapon";
+ replacement.m_isreplaced = true;
weapon_defaultspawnfunc(replacement, it);
break;
}
#include "weaponsystem.qh"
#include "../resources.qh"
+#include "../items.qh"
#include "../mutators/_mod.qh"
#include <common/t_items.qh>
#include "../g_damage.qh"
Weapon info = Weapons_from(wpn);
int ammotype = info.ammo_type;
- entity wep = new(droppedweapon);
-
+ entity wep = spawn();
+ Item_SetLoot(wep, true);
setorigin(wep, org);
wep.velocity = velo;
wep.owner = wep.enemy = own;
if(WepSet_FromWeapon(Weapons_from(wpn)) & WEPSET_SUPERWEAPONS)
{
+ Item_SetExpiring(wep, true);
if(own.items & IT_UNLIMITED_SUPERWEAPONS)
{
wep.superweapons_finished = time + autocvar_g_balance_superweapons_time;
#include <server/miscfunctions.qh>
float internalteam;
-float weaponswapping;
entity weapon_dropevent_item;
..entity weaponentity_fld;
--- /dev/null
+// Random items mutator config
+
+// Map items
+
+set g_random_items_replace_item_health_small "random" "Classnames to replace small health with."
+set g_random_items_replace_item_health_medium "random" "Classnames to replace medium health with."
+set g_random_items_replace_item_health_big "random" "Classnames to replace big health with."
+set g_random_items_replace_item_health_mega "random" "Classnames to replace mega health with."
+set g_random_items_replace_item_armor_small "random" "Classnames to replace small armor with."
+set g_random_items_replace_item_armor_medium "random" "Classnames to replace medium armor with."
+set g_random_items_replace_item_armor_big "random" "Classnames to replace big armor with."
+set g_random_items_replace_item_armor_mega "random" "Classnames to replace mega armor with."
+set g_random_items_replace_item_shells "random" "Classnames to replace shells with."
+set g_random_items_replace_item_bullets "random" "Classnames to replace bullets with."
+set g_random_items_replace_item_rockets "random" "Classnames to replace rockets with."
+set g_random_items_replace_item_cells "random" "Classnames to replace cells with."
+set g_random_items_replace_item_plasma "random" "Classnames to replace plasma with."
+set g_random_items_replace_item_fuel "random" "Classnames to replace fuel with."
+set g_random_items_replace_weapon_blaster "random" "Classnames to replace blaster with."
+set g_random_items_replace_weapon_shotgun "random" "Classnames to replace shotgun with."
+set g_random_items_replace_weapon_machinegun "random" "Classnames to replace machinegun with."
+set g_random_items_replace_weapon_mortar "random" "Classnames to replace mortar with."
+set g_random_items_replace_weapon_electro "random" "Classnames to replace electro with."
+set g_random_items_replace_weapon_crylink "random" "Classnames to replace crylink with."
+set g_random_items_replace_weapon_vortex "random" "Classnames to replace vortex with."
+set g_random_items_replace_weapon_hagar "random" "Classnames to replace hagar with."
+set g_random_items_replace_weapon_devastator "random" "Classnames to replace devastator with."
+set g_random_items_replace_weapon_shockwave "random" "Classnames to replace shockwave with."
+set g_random_items_replace_weapon_arc "random" "Classnames to replace arc with."
+set g_random_items_replace_weapon_hook "random" "Classnames to replace hook with."
+set g_random_items_replace_weapon_tuba "random" "Classnames to replace tuba with."
+set g_random_items_replace_weapon_porto "random" "Classnames to replace port-o-launch with."
+set g_random_items_replace_weapon_fireball "random" "Classnames to replace fireball with."
+set g_random_items_replace_weapon_minelayer "random" "Classnames to replace mine layer with."
+set g_random_items_replace_weapon_hlac "random" "Classnames to replace HLAC with."
+set g_random_items_replace_weapon_rifle "random" "Classnames to replace rifle with."
+set g_random_items_replace_weapon_seeker "random" "Classnames to replace TAG seeker with."
+set g_random_items_replace_weapon_vaporizer "random" "Classnames to replace vaporizer with."
+set g_random_items_replace_weapon_hmg "random" "Classnames to replace HMG with."
+set g_random_items_replace_weapon_rpc "random" "Classnames to replace RPC with."
+set g_random_items_replace_item_strength "random" "Classnames to replace strength with."
+set g_random_items_replace_item_shield "random" "Classnames to replace shield with."
+set g_random_items_replace_item_fuel_regen "random" "Classnames to replace fuel regeneration with."
+set g_random_items_replace_item_jetpack "random" "Classnames to replace jetpack with."
+set g_random_items_replace_item_vaporizer_cells "random" "Classnames to replace vaporizer cells with."
+set g_random_items_replace_item_invisibility "random" "Classnames to replace invisibility with."
+set g_random_items_replace_item_extralife "random" "Classnames to replace extra life with."
+set g_random_items_replace_item_speed "random" "Classnames to replace speed with."
+set g_random_items_health_probability 1 "Probability of random health items spawning in the map."
+set g_random_items_armor_probability 1 "Probability of random armor items spawning in the map."
+set g_random_items_resource_probability 1 "Probability of random resource items spawning in the map."
+set g_random_items_weapon_probability 1 "Probability of random weapons spawning in the map."
+set g_random_items_powerup_probability 0.15 "Probability of random powerups spawning in the map."
+set g_random_items_item_health_small_probability 10 "Probability of random small health spawning in the map."
+set g_random_items_item_health_medium_probability 4 "Probability of random medium health spawning in the map."
+set g_random_items_item_health_big_probability 2 "Probability of random big health spawning in the map."
+set g_random_items_item_health_mega_probability 1 "Probability of random mega health spawning in the map."
+set g_random_items_item_armor_small_probability 10 "Probability of random small armor spawning in the map."
+set g_random_items_item_armor_medium_probability 4 "Probability of random medium armor spawning in the map."
+set g_random_items_item_armor_big_probability 2 "Probability of random big armor spawning in the map."
+set g_random_items_item_armor_mega_probability 1 "Probability of random mega armor spawning in the map."
+set g_random_items_item_shells_probability 1 "Probability of random shells spawning in the map."
+set g_random_items_item_bullets_probability 1 "Probability of random bullets spawning in the map."
+set g_random_items_item_rockets_probability 1 "Probability of random rockets spawning in the map."
+set g_random_items_item_cells_probability 1 "Probability of random cells spawning in the map."
+set g_random_items_item_plasma_probability 0 "Probability of random plasma spawning in the map."
+set g_random_items_item_fuel_probability 0 "Probability of random fuel spawning in the map."
+set g_random_items_weapon_blaster_probability 0 "Probability of random blaster spawning in the map."
+set g_random_items_weapon_shotgun_probability 0 "Probability of random shotgun spawning in the map."
+set g_random_items_weapon_machinegun_probability 1 "Probability of random machinegun spawning in the map."
+set g_random_items_weapon_mortar_probability 1 "Probability of random mortar spawning in the map."
+set g_random_items_weapon_electro_probability 1 "Probability of random electro spawning in the map."
+set g_random_items_weapon_crylink_probability 1 "Probability of random crylink spawning in the map."
+set g_random_items_weapon_vortex_probability 1 "Probability of random vortex spawning in the map."
+set g_random_items_weapon_hagar_probability 1 "Probability of random hagar spawning in the map."
+set g_random_items_weapon_devastator_probability 1 "Probability of random devastator spawning in the map."
+set g_random_items_weapon_shockwave_probability 0 "Probability of random shockwave spawning in the map."
+set g_random_items_weapon_arc_probability 0 "Probability of random arc spawning in the map."
+set g_random_items_weapon_hook_probability 0 "Probability of random hook spawning in the map."
+set g_random_items_weapon_tuba_probability 0 "Probability of random tuba spawning in the map."
+set g_random_items_weapon_porto_probability 0 "Probability of random port-o-launch spawning in the map."
+set g_random_items_weapon_fireball_probability 0 "Probability of random fireball spawning in the map."
+set g_random_items_weapon_minelayer_probability 0 "Probability of random mine layer spawning in the map."
+set g_random_items_weapon_hlac_probability 0 "Probability of random HLAC spawning in the map."
+set g_random_items_weapon_rifle_probability 0 "Probability of random rifle spawning in the map."
+set g_random_items_weapon_seeker_probability 0 "Probability of random TAG seeker spawning in the map."
+set g_random_items_weapon_vaporizer_probability 0 "Probability of random vaporizer spawning in the map."
+set g_random_items_item_strength_probability 1 "Probability of random strength spawning in the map."
+set g_random_items_item_shield_probability 1 "Probability of random shield spawning in the map."
+set g_random_items_item_fuel_regen_probability 0 "Probability of random fuel regeneration spawning in the map."
+set g_random_items_item_jetpack_probability 0 "Probability of random jetpack spawning in the map."
+set g_random_items_item_vaporizer_cells_probability 20 "Probability of random vaporizer cells spawning in the map."
+set g_random_items_item_invisibility_probability 1 "Probability of random invisibility spawning in the map."
+set g_random_items_item_extralife_probability 1 "Probability of random extra life spawning in the map."
+set g_random_items_item_speed_probability 1 "Probability of random speed spawning in the map."
+set g_random_items_overkill_item_health_mega_probability 1 "Probability of random mega health spawning in the map during overkill."
+set g_random_items_overkill_item_armor_small_probability 10 "Probability of random small armor spawning in the map during overkill."
+set g_random_items_overkill_item_armor_medium_probability 4 "Probability of random medium armor spawning in the map during overkill."
+set g_random_items_overkill_item_armor_big_probability 2 "Probability of random big armor spawning in the map during overkill."
+set g_random_items_overkill_item_armor_mega_probability 1 "Probability of random mega armor spawning in the map during overkill."
+set g_random_items_overkill_weapon_hmg_probability 0.5 "Probability of random HMG spawning in the map during overkill."
+set g_random_items_overkill_weapon_rpc_probability 0.5 "Probability of random RPC spawning in the map during overkill."
+
+// Loot
+
+set g_random_loot_min 0 "Minimum amount of loot items."
+set g_random_loot_max 4 "Maximum amount of loot items."
+set g_random_loot_time 10 "Amount of time the loot will stay in seconds."
+set g_random_loot_spread 200 "How far can loot be thrown."
+set g_random_loot_health_probability 1 "Probability of random health items spawning as loot."
+set g_random_loot_armor_probability 1 "Probability of random armor items spawning as loot."
+set g_random_loot_resource_probability 1 "Probability of random ammo items spawning as loot."
+set g_random_loot_weapon_probability 1 "Probability of random weapons spawning as loot."
+set g_random_loot_powerup_probability 0.2 "Probability of random powerups spawning as loot."
+set g_random_loot_item_health_small_probability 4 "Probability of random small health spawning as loot."
+set g_random_loot_item_health_medium_probability 3 "Probability of random medium health spawning as loot."
+set g_random_loot_item_health_big_probability 2 "Probability of random big health spawning as loot."
+set g_random_loot_item_health_mega_probability 1 "Probability of random mega health spawning as loot."
+set g_random_loot_item_armor_small_probability 4 "Probability of random small armor spawning as loot."
+set g_random_loot_item_armor_medium_probability 3 "Probability of random medium armor spawning as loot."
+set g_random_loot_item_armor_big_probability 2 "Probability of random big armor spawning as loot."
+set g_random_loot_item_armor_mega_probability 1 "Probability of random mega armor spawning as loot."
+set g_random_loot_item_shells_probability 1 "Probability of random shells spawning as loot."
+set g_random_loot_item_bullets_probability 1 "Probability of random bullets spawning as loot."
+set g_random_loot_item_rockets_probability 1 "Probability of random rockets spawning as loot."
+set g_random_loot_item_cells_probability 1 "Probability of random cells spawning as loot."
+set g_random_loot_item_plasma_probability 0 "Probability of random plasma spawning as loot."
+set g_random_loot_item_fuel_probability 0 "Probability of random fuel spawning as loot."
+set g_random_loot_weapon_blaster_probability 0 "Probability of random blaster spawning as loot."
+set g_random_loot_weapon_shotgun_probability 0 "Probability of random shotgun spawning as loot."
+set g_random_loot_weapon_machinegun_probability 1 "Probability of random machinegun spawning as loot."
+set g_random_loot_weapon_mortar_probability 1 "Probability of random mortar spawning as loot."
+set g_random_loot_weapon_electro_probability 1 "Probability of random electro spawning as loot."
+set g_random_loot_weapon_crylink_probability 1 "Probability of random crylink spawning as loot."
+set g_random_loot_weapon_vortex_probability 1 "Probability of random vortex spawning as loot."
+set g_random_loot_weapon_hagar_probability 1 "Probability of random hagar spawning as loot."
+set g_random_loot_weapon_devastator_probability 1 "Probability of random devastator spawning as loot."
+set g_random_loot_weapon_shockwave_probability 0 "Probability of random shockwave spawning as loot."
+set g_random_loot_weapon_arc_probability 0 "Probability of random arc spawning as loot."
+set g_random_loot_weapon_hook_probability 0 "Probability of random hook spawning as loot."
+set g_random_loot_weapon_tuba_probability 0 "Probability of random tuba spawning as loot."
+set g_random_loot_weapon_porto_probability 0 "Probability of random port-o-launch spawning as loot."
+set g_random_loot_weapon_fireball_probability 0 "Probability of random fireball spawning as loot."
+set g_random_loot_weapon_minelayer_probability 0 "Probability of random mine layer spawning as loot."
+set g_random_loot_weapon_hlac_probability 0 "Probability of random HLAC spawning as loot."
+set g_random_loot_weapon_rifle_probability 0 "Probability of random rifle spawning as loot."
+set g_random_loot_weapon_seeker_probability 0 "Probability of random TAG seeker spawning as loot."
+set g_random_loot_weapon_vaporizer_probability 0 "Probability of random vaporizer spawning as loot."
+set g_random_loot_item_strength_probability 1 "Probability of random strength spawning as loot."
+set g_random_loot_item_shield_probability 1 "Probability of random shield spawning as loot."
+set g_random_loot_item_fuel_regen_probability 0 "Probability of random fuel regeneration spawning as loot."
+set g_random_loot_item_jetpack_probability 0 "Probability of random jetpack spawning as loot."
+set g_random_loot_item_vaporizer_cells_probability 20 "Probability of random vaporizer cells spawning as loot."
+set g_random_loot_item_invisibility_probability 1 "Probability of random invisibility spawning as loot."
+set g_random_loot_item_extralife_probability 1 "Probability of random extra life spawning as loot."
+set g_random_loot_item_speed_probability 1 "Probability of random speed spawning as loot."
+set g_random_loot_overkill_item_health_mega_probability 1 "Probability of random mega health spawning as loot during overkill."
+set g_random_loot_overkill_item_armor_small_probability 10 "Probability of random small armor spawning as loot during overkill."
+set g_random_loot_overkill_item_armor_medium_probability 4 "Probability of random medium armor spawning as loot during overkill."
+set g_random_loot_overkill_item_armor_big_probability 2 "Probability of random big armor spawning as loot during overkill."
+set g_random_loot_overkill_item_armor_mega_probability 1 "Probability of random mega armor spawning as loot during overkill."
+set g_random_loot_overkill_weapon_hmg_probability 1 "Probability of random HMG spawning as loot during overkill."
+set g_random_loot_overkill_weapon_rpc_probability 1 "Probability of random RPC spawning as loot during overkill."