switch(_imp)
{
case 1:
- case 230:
self.vehicle.vehicle_weapon2mode = RSM_BOMB;
CSQCVehicleSetup(self, 0);
return true;
case 2:
- case 231:
self.vehicle.vehicle_weapon2mode = RSM_FLARE;
CSQCVehicleSetup(self, 0);
return true;
switch(_imp)
{
case 1:
- case 230:
self.vehicle.vehicle_weapon2mode = SBRM_VOLLY;
CSQCVehicleSetup(self, 0);
return true;
case 2:
- case 231:
self.vehicle.vehicle_weapon2mode = SBRM_GUIDE;
CSQCVehicleSetup(self, 0);
return true;
case 3:
- case 232:
- case 251:
self.vehicle.vehicle_weapon2mode = SBRM_ARTILLERY;
CSQCVehicleSetup(self, 0);
return true;
string W_FixWeaponOrder(string order, float complete)
{
- return fixPriorityList(order, WEP_FIRST, WEP_LAST, 230 - WEP_FIRST, complete);
+ return fixPriorityList(order, WEP_FIRST, WEP_LAST, WEP_IMPULSE_BEGIN - WEP_FIRST, complete);
}
string W_NameWeaponOrder_MapFunc(string s)
{
if(s == "0" || stof(s))
{
wi = get_weaponinfo(stof(s));
- if(wi != dummy_weapon_info)
+ if(wi != WEP_Null)
return wi.netname;
}
return s;
// weapon sets
typedef vector WepSet;
+#define WEPSET(id) WepSet_FromWeapon(WEP_##id.m_id)
WepSet WepSet_FromWeapon(int a);
#ifdef SVQC
void WepSet_AddStat();
const int WEP_FIRST = 1;
#define WEP_MAXCOUNT 72 // Increase as needed. Can be up to 72.
int WEP_COUNT;
-#define WEP_LAST (WEP_FIRST + WEP_COUNT - 1)
+#define WEP_LAST (WEP_FIRST + (WEP_COUNT - 1) - 1)
WepSet WEPSET_ALL;
WepSet WEPSET_SUPERWEAPONS;
void RegisterWeapons();
REGISTER_REGISTRY(RegisterWeapons)
entity weapon_info[WEP_MAXCOUNT], weapon_info_first, weapon_info_last;
-entity dummy_weapon_info;
-#define WEP_Null dummy_weapon_info
-entity get_weaponinfo(int id)
-{
- entity w;
- if(id < WEP_FIRST || id > WEP_LAST)
- return dummy_weapon_info;
- w = weapon_info[id - 1];
- if(w)
- return w;
- return dummy_weapon_info;
-}
+entity get_weaponinfo(int id);
#define REGISTER_WEAPON(id, inst) \
- WepSet WEPSET_##id; \
- REGISTER(RegisterWeapons, WEP, weapon_info, WEP_COUNT, id, m_id, inst) { \
- this.m_id++; \
- WEPSET_ALL |= (WEPSET_##id = WepSet_FromWeapon(this.m_id)); \
- if ((this.spawnflags) & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= WEPSET_##id; \
- register_weapon(this, this.m_id, WEPSET_##id); \
- localcmd(sprintf("alias weapon_%s \"impulse %d\"\n", this.netname, 230 + this.m_id - 1)); \
- } \
- REGISTER_INIT(WEP, id)
+ /* WepSet WEPSET_##id; */ \
+ REGISTER(RegisterWeapons, WEP, weapon_info, WEP_COUNT, id, m_id, inst)
// create cvars for weapon settings
#define WEP_ADD_CVAR_NONE(wepname,name) [[last]] float autocvar_g_balance_##wepname##_##name;
#define WEP_SKIP_CVAR(unuseda,unusedb,unusedc,unusedd) /* skip cvars */
#define WEP_SET_PROP(wepid,wepname,type,prop,name) WEP_##wepid.prop = autocvar_g_balance_##wepname##_##name;
+REGISTER_WEAPON(Null, NEW(Weapon));
+
#include "all.inc"
-void register_weapons_done()
+entity get_weaponinfo(int id)
{
- dummy_weapon_info = NEW(Weapon);
+ if(id < WEP_FIRST || id > WEP_LAST)
+ return WEP_Null;
+ Weapon w = weapon_info[id];
+ if(w)
+ return w;
+ return WEP_Null;
+}
+
+// TODO: remove after 0.8.2. Retains impulse number compatibility because 0.8.1 clients don't reload the weapons.cfg
+#define WEP_HARDCODED_IMPULSES 22
+
+void _REGISTRY_SWAP(int i, int j, entity pass)
+{
+ i += WEP_HARDCODED_IMPULSES + 1; j += WEP_HARDCODED_IMPULSES + 1;
+ entity e = weapon_info[i];
+ weapon_info[i] = weapon_info[j];
+ weapon_info[j] = e;
+}
+float _REGISTRY_CMP(int i, int j, entity pass)
+{
+ i += WEP_HARDCODED_IMPULSES + 1; j += WEP_HARDCODED_IMPULSES + 1;
+ string a = weapon_info[i].netname;
+ string b = weapon_info[j].netname;
+ return strcasecmp(a, b);
+}
+
+// TODO: invert after 0.8.2. Will require moving 'best weapon' impulses
+#define WEP_IMPULSE_BEGIN 230
+#define WEP_IMPULSE_END bound(WEP_IMPULSE_BEGIN, WEP_IMPULSE_BEGIN + (WEP_COUNT - 1) - 1, 253)
+
+STATIC_INIT(register_weapons_done)
+{
+ // Sort all extra weapons not #included in all.inc by their netname so it doesn't matter when they were initialized
+ heapsort(WEP_COUNT - (1 /* WEP_Null */ + WEP_HARDCODED_IMPULSES), _REGISTRY_SWAP, _REGISTRY_CMP, NULL);
+ for (int i = 0; i < WEP_COUNT; ++i) {
+ Weapon it = weapon_info[i];
+ it.m_id = i;
+ WepSet set = WepSet_FromWeapon(it.m_id);
+ WEPSET_ALL |= set;
+ if ((it.spawnflags) & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= set;
+ it.weapon = it.m_id;
+ it.weapons = set;
+ #ifdef CSQC
+ it.wr_init(it);
+ #endif
+ int imp = WEP_IMPULSE_BEGIN + it.m_id - 1;
+ if (imp <= WEP_IMPULSE_END)
+ localcmd(sprintf("alias weapon_%s \"impulse %d\"\n", it.netname, imp));
+ else
+ LOG_TRACEF(_("Impulse limit exceeded, weapon will not be directly accessible: %s\n"), it.netname);
+ }
weaponorder_byid = "";
- for (int i = WEP_MAXCOUNT - 1; i >= 0; --i)
+ for (int i = WEP_MAXCOUNT - 1; i >= 1; --i)
if (weapon_info[i])
weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
}
-ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done)
#endif
ATTRIB(Weapon, bot_pickupbasevalue, float, 0);
/** M: color : waypointsprite color */
ATTRIB(Weapon, wpcolor, vector, '0 0 0');
- /** A: wpn-id : wpn- sprite name */
- ATTRIB(Weapon, wpmodel, string, "");
/** M: modelname : name of model (without g_ v_ or h_ prefixes) */
ATTRIB(Weapon, mdl, string, "");
/** M: model MDL_id_ITEM */
METHOD(Weapon, display, void(entity this, void(string name, string icon) returns)) {
returns(this.message, this.model2 ? sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.model2) : string_null);
}
-
- void register_weapon(entity this, int id, WepSet bit)
- {
- this.weapon = id;
- this.weapons = bit;
- this.wpmodel = strzone(strcat("wpn-", ftos(id)));
- #ifdef CSQC
- this.wr_init(this);
- #endif
- }
ENDCLASS(Weapon)
CLASS(OffhandWeapon, Object)
self.realowner.porto_current = world;
- if(self.cnt < 0 && !failhard && self.realowner.playerid == self.playerid && self.realowner.deadflag == DEAD_NO && !(self.realowner.weapons & WEPSET_PORTO))
+ if(self.cnt < 0 && !failhard && self.realowner.playerid == self.playerid && self.realowner.deadflag == DEAD_NO && !(self.realowner.weapons & WEPSET(PORTO)))
{
setsize(self, '-16 -16 0', '16 16 32');
setorigin(self, self.origin + trace_plane_normal);
int i;
// ;)
- if(g_weaponarena_weapons == WEPSET_TUBA)
+ if(g_weaponarena_weapons == WEPSET(TUBA))
{
self.switchweapon = WEP_TUBA.m_id;
return;
if(g_weaponarena_random) // WEAPONTODO: more stuff that should be in a mutator. also: rename those cvars
{
if(g_weaponarena_random_with_blaster)
- self.weapons &= ~WEPSET_BLASTER;
+ self.weapons &= ~WEPSET(BLASTER);
W_RandomWeapons(self, g_weaponarena_random);
if(g_weaponarena_random_with_blaster)
- self.weapons |= WEPSET_BLASTER;
+ self.weapons |= WEPSET(BLASTER);
}
self.items = start_items;
Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
}
- if(autocvar_g_bugrigs || (g_weaponarena_weapons == WEPSET_TUBA))
+ if(autocvar_g_bugrigs || (g_weaponarena_weapons == WEPSET(TUBA)))
stuffcmd(self, "cl_cmd settemp chase_active 1\n");
}
else
self.impulse = imp; // retry in next frame
}
- else if(imp >= 230 && imp <= 253)
+ else if(imp >= WEP_IMPULSE_BEGIN && imp <= WEP_IMPULSE_END)
{
if(!self.vehicle)
if(self.deadflag == DEAD_NO)
- W_SwitchWeapon (imp - 230 + WEP_FIRST);
+ W_SwitchWeapon (imp - WEP_IMPULSE_BEGIN + WEP_FIRST);
else
self.impulse = imp; // retry in next frame
}
plyr.weaponentity.weapons = plyr.weapons;
plyr.weaponentity.switchweapon = plyr.weapon;
- plyr.weapons = WEPSET_NEXBALL;
+ plyr.weapons = WEPSET(NEXBALL);
setself(plyr);
Weapon w = WEP_NEXBALL;
w.wr_resetplayer(w);
self.weaponentity.weapons = '0 0 0';
if(nexball_mode & NBM_BASKETBALL)
- self.weapons |= WEPSET_NEXBALL;
+ self.weapons |= WEPSET(NEXBALL);
else
self.weapons = '0 0 0';
start_ammo_rockets = warmup_start_ammo_rockets = 0;
start_ammo_fuel = warmup_start_ammo_fuel = 0;
- start_weapons = warmup_start_weapons = WEPSET_VAPORIZER;
+ start_weapons = warmup_start_weapons = WEPSET(VAPORIZER);
start_items |= IT_UNLIMITED_SUPERWEAPONS;
return false;
MUTATOR_HOOKFUNCTION(melee_SetStartItems)
{
start_ammo_shells = warmup_start_ammo_shells = 0;
- start_weapons = warmup_start_weapons = WEPSET_SHOTGUN;
+ start_weapons = warmup_start_weapons = WEPSET(SHOTGUN);
return false;
}
self.weapons = '0 0 0';
if(g_nix_with_blaster)
- self.weapons |= WEPSET_BLASTER;
+ self.weapons |= WEPSET(BLASTER);
self.weapons |= WepSet_FromWeapon(nix_weapon);
if(self.switchweapon != nix_weapon)
MUTATOR_HOOKFUNCTION(ok_StartItems)
{
- WepSet ok_start_items = (WEPSET_MACHINEGUN | WEPSET_VORTEX | WEPSET_SHOTGUN);
+ WepSet ok_start_items = (WEPSET(MACHINEGUN) | WEPSET(VORTEX) | WEPSET(SHOTGUN));
- if(WEP_RPC.weaponstart > 0) { ok_start_items |= WEPSET_RPC; }
- if(WEP_HMG.weaponstart > 0) { ok_start_items |= WEPSET_HMG; }
+ if(WEP_RPC.weaponstart > 0) { ok_start_items |= WEPSET(RPC); }
+ if(WEP_HMG.weaponstart > 0) { ok_start_items |= WEPSET(HMG); }
start_items |= IT_UNLIMITED_WEAPON_AMMO;
start_weapons = warmup_start_weapons = ok_start_items;