../common/teams.qh
../common/util.qh
../common/counting.qh
-../common/items.qh
-../common/explosion_equation.qh
+../common/weapons/weapons.qh // TODO
../common/mapinfo.qh
../common/command/markup.qh
../common/command/rpn.qh
../common/command/rpn.qc
../common/command/generic.qc
../common/mapinfo.qc
-../common/items.qc
-../server/weapons/w_all.qc
-../common/explosion_equation.qc
+../common/weapons/weapons.qc // TODO
../common/urllib.qc
command/cl_cmd.qc
+++ /dev/null
-float explosion_calcpush_getmultiplier(vector explosion_v, vector target_v)
-{
- float a;
- a = explosion_v * (explosion_v - target_v);
-
- if(a <= 0)
- // target is too fast to be hittable by this
- return 0;
-
- a /= (explosion_v * explosion_v);
- // we know we can divide by this, or above a would be == 0
-
- return a;
-}
-
-#if 0
-vector explosion_calcpush(vector explosion_v, float explosion_m, vector target_v, float target_m, float elasticity)
-{
- // solution of the equations:
- // v' = v + a vp // central hit
- // m*v' + mp*vp' = m*v + mp*vp // conservation of momentum
- // m*v'^2 + mp*vp'^2 = m*v^2 + mp*vp^2 // conservation of energy (ELASTIC hit)
- // -> a = 0 // case 1: did not hit
- // -> a = 2*mp*(vp^2 - vp.v) / ((m+mp) * vp^2) // case 2: did hit
- // // non-elastic hits are somewhere between these two
-
- // this would be physically correct, but we don't do that
- return explosion_v * explosion_calcpush_getmultiplier(explosion_v, target_v) * (
- (1 + elasticity) * (
- explosion_m
- ) / (
- target_m + explosion_m
- )
- ); // note: this factor is at least 0, at most 2
-}
-#endif
-
-// simplified formula, tuned so that if the target has velocity 0, we get exactly the original force
-vector damage_explosion_calcpush(vector explosion_f, vector target_v, float speedfactor)
-{
- // if below 1, the formulas make no sense (and would cause superjumps)
- if(speedfactor < 1)
- return explosion_f;
-
-#if 0
- float m;
- // find m so that
- // speedfactor * (1 + e) * m / (1 + m) == 1
- m = 1 / ((1 + 0) * speedfactor - 1);
- vector v;
- v = explosion_calcpush(explosion_f * speedfactor, m, target_v, 1, 0);
- // the factor we then get is:
- // 1
- print(sprintf("MASS: %f\nv: %v -> %v\nENERGY BEFORE == %f + %f = %f\nENERGY AFTER >= %f\n",
- m,
- target_v, target_v + v,
- target_v * target_v, m * explosion_f * speedfactor * explosion_f * speedfactor, target_v * target_v + m * explosion_f * speedfactor * explosion_f * speedfactor,
- (target_v + v) * (target_v + v)));
- return v;
-#endif
- return explosion_f * explosion_calcpush_getmultiplier(explosion_f * speedfactor, target_v);
-}
+++ /dev/null
-vector damage_explosion_calcpush(vector explosion_f, vector target_v, float speedfactor);
+++ /dev/null
-// WEAPON PLUGIN SYSTEM
-entity weapon_info[WEP_MAXCOUNT];
-entity dummy_weapon_info;
-
-void register_weapon(float id, float(float) func, float ammotype, float i, float weapontype, float pickupbasevalue, string modelname, string shortname, string wname)
-{
- entity e;
- weapon_info[id - 1] = e = spawn();
- e.classname = "weapon_info";
- e.weapon = id;
- WEPSET_COPY_EW(e, id);
- e.netname = shortname;
- e.message = wname;
- e.items = ammotype;
- e.weapon_func = func;
- e.mdl = modelname;
- e.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
- e.spawnflags = weapontype;
- e.model2 = strzone(strcat("wpn-", e.mdl));
- e.impulse = i;
- e.bot_pickupbasevalue = pickupbasevalue;
- if(ammotype & IT_SHELLS)
- e.ammo_field = ammo_shells;
- else if(ammotype & IT_NAILS)
- e.ammo_field = ammo_nails;
- else if(ammotype & IT_ROCKETS)
- e.ammo_field = ammo_rockets;
- else if(ammotype & IT_CELLS)
- e.ammo_field = ammo_cells;
- else if(ammotype & IT_FUEL)
- e.ammo_field = ammo_fuel;
- else
- e.ammo_field = ammo_batteries;
-}
-float w_null(float dummy)
-{
- return 0;
-}
-void register_weapons_done()
-{
- dummy_weapon_info = spawn();
- dummy_weapon_info.classname = "weapon_info";
- dummy_weapon_info.weapon = 0; // you can recognize dummies by this
- WEPSET_CLEAR_E(dummy_weapon_info);
- dummy_weapon_info.netname = "";
- dummy_weapon_info.message = "AOL CD Thrower";
- dummy_weapon_info.items = 0;
- dummy_weapon_info.weapon_func = w_null;
- dummy_weapon_info.mdl = "";
- dummy_weapon_info.model = "";
- dummy_weapon_info.spawnflags = 0;
- dummy_weapon_info.model2 = "";
- dummy_weapon_info.impulse = -1;
- dummy_weapon_info.bot_pickupbasevalue = 0;
-
- float i;
- weaponorder_byid = "";
- for(i = WEP_MAXCOUNT; i >= 1; --i)
- if(weapon_info[i-1])
- weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
- weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
-}
-entity get_weaponinfo(float 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;
-}
-string W_FixWeaponOrder(string order, float complete)
-{
- return fixPriorityList(order, WEP_FIRST, WEP_LAST, 230 - WEP_FIRST, complete);
-}
-string W_NameWeaponOrder_MapFunc(string s)
-{
- entity wi;
- if(s == "0" || stof(s))
- {
- wi = get_weaponinfo(stof(s));
- if(wi != dummy_weapon_info)
- return wi.netname;
- }
- return s;
-}
-string W_NameWeaponOrder(string order)
-{
- return mapPriorityList(order, W_NameWeaponOrder_MapFunc);
-}
-string W_NumberWeaponOrder_MapFunc(string s)
-{
- float i;
- if(s == "0" || stof(s))
- return s;
- for(i = WEP_FIRST; i <= WEP_LAST; ++i)
- if(s == get_weaponinfo(i).netname)
- return ftos(i);
- return s;
-}
-string W_NumberWeaponOrder(string order)
-{
- return mapPriorityList(order, W_NumberWeaponOrder_MapFunc);
-}
-
-float W_FixWeaponOrder_BuildImpulseList_buf[WEP_MAXCOUNT];
-string W_FixWeaponOrder_BuildImpulseList_order;
-void W_FixWeaponOrder_BuildImpulseList_swap(float i, float j, entity pass)
-{
- float h;
- h = W_FixWeaponOrder_BuildImpulseList_buf[i];
- W_FixWeaponOrder_BuildImpulseList_buf[i] = W_FixWeaponOrder_BuildImpulseList_buf[j];
- W_FixWeaponOrder_BuildImpulseList_buf[j] = h;
-}
-float W_FixWeaponOrder_BuildImpulseList_cmp(float i, float j, entity pass)
-{
- entity e1, e2;
- float d;
- e1 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[i]);
- e2 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[j]);
- d = mod(e1.impulse + 9, 10) - mod(e2.impulse + 9, 10);
- if(d != 0)
- return -d; // high impulse first!
- return
- strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
- -
- strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
- ; // low char index first!
-}
-string W_FixWeaponOrder_BuildImpulseList(string o)
-{
- float i;
- W_FixWeaponOrder_BuildImpulseList_order = o;
- for(i = WEP_FIRST; i <= WEP_LAST; ++i)
- W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST] = i;
- heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp, world);
- o = "";
- for(i = WEP_FIRST; i <= WEP_LAST; ++i)
- o = strcat(o, " ", ftos(W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST]));
- W_FixWeaponOrder_BuildImpulseList_order = string_null;
- return substring(o, 1, -1);
-}
-
-string W_FixWeaponOrder_AllowIncomplete(string order)
-{
- return W_FixWeaponOrder(order, 0);
-}
-
-string W_FixWeaponOrder_ForceComplete(string order)
-{
- if(order == "")
- order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
- return W_FixWeaponOrder(order, 1);
-}
-
-void W_RandomWeapons(entity e, float n)
-{
- float i, j;
- WEPSET_DECLARE_A(remaining);
- WEPSET_DECLARE_A(result);
- WEPSET_COPY_AE(remaining, e);
- WEPSET_CLEAR_A(result);
- for(i = 0; i < n; ++i)
- {
- RandomSelection_Init();
- for(j = WEP_FIRST; j <= WEP_LAST; ++j)
- if(WEPSET_CONTAINS_AW(remaining, j))
- RandomSelection_Add(world, j, string_null, 1, 1);
- WEPSET_OR_AW(result, RandomSelection_chosen_float);
- WEPSET_ANDNOT_AW(remaining, RandomSelection_chosen_float);
- }
- WEPSET_COPY_EA(e, result);
-}
-
-string W_Name(float weaponid)
-{
- return (get_weaponinfo(weaponid)).message;
-}
-
-float W_AmmoItemCode(float wpn)
-{
- return (get_weaponinfo(wpn)).items & IT_AMMO;
-}
+++ /dev/null
-float BOT_PICKUP_RATING_LOW = 2500;
-float BOT_PICKUP_RATING_MID = 5000;
-float BOT_PICKUP_RATING_HIGH = 10000;
-
-float WEP_TYPE_OTHER = 0x00; // not for damaging people
-float WEP_TYPE_SPLASH = 0x01; // splash damage
-float WEP_TYPE_HITSCAN = 0x02; // hitscan
-float WEP_TYPEMASK = 0x0F;
-float WEP_FLAG_CANCLIMB = 0x10; // can be used for movement
-float WEP_FLAG_NORMAL = 0x20; // in "most weapons" set
-float WEP_FLAG_HIDDEN = 0x40; // hides from menu
-float WEP_FLAG_RELOADABLE = 0x80; // can has reload
-float WEP_FLAG_SUPERWEAPON = 0x100; // powerup timer
-float WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag)
-
-float IT_UNLIMITED_WEAPON_AMMO = 1;
-// when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup.
-float IT_UNLIMITED_SUPERWEAPONS = 2;
-// when this bit is set, superweapons don't expire. Checkpoints can give this powerup.
-float IT_CTF_SHIELDED = 4; // set for the flag shield
-float IT_USING_JETPACK = 8; // confirmation that button is pressed
-float IT_JETPACK = 16; // actual item
-float IT_FUEL_REGEN = 32; // fuel regeneration trigger
-float IT_SHELLS = 256;
-float IT_NAILS = 512;
-float IT_ROCKETS = 1024;
-float IT_CELLS = 2048;
-float IT_SUPERWEAPON = 4096;
-float IT_FUEL = 128;
-float IT_STRENGTH = 8192;
-float IT_INVINCIBLE = 16384;
-float IT_HEALTH = 32768;
-// union:
- // for items:
- float IT_KEY1 = 131072;
- float IT_KEY2 = 262144;
- // for players:
- float IT_RED_FLAG_TAKEN = 32768;
- float IT_RED_FLAG_LOST = 65536;
- float IT_RED_FLAG_CARRYING = 98304;
- float IT_BLUE_FLAG_TAKEN = 131072;
- float IT_BLUE_FLAG_LOST = 262144;
- float IT_BLUE_FLAG_CARRYING = 393216;
-// end
-float IT_5HP = 524288;
-float IT_25HP = 1048576;
-float IT_ARMOR_SHARD = 2097152;
-float IT_ARMOR = 4194304;
-
-float IT_AMMO = 3968; // IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS | IT_FUEL;
-float IT_PICKUPMASK = 51; // IT_FUEL_REGEN | IT_JETPACK | IT_UNLIMITED_AMMO; // strength and invincible are handled separately
-float IT_UNLIMITED_AMMO = 3; // IT_UNLIMITED_SUPERWEAPONS | IT_UNLIMITED_WEAPON_AMMO;
-
-float AMMO_COUNT = 4; // amount of ammo types to show in the inventory panel
-
-// variables:
-string weaponorder_byid;
-
-// functions:
-entity get_weaponinfo(float id);
-string W_FixWeaponOrder(string order, float complete);
-string W_NameWeaponOrder(string order);
-string W_NumberWeaponOrder(string order);
-
-// ammo types
-.float ammo_shells;
-.float ammo_nails;
-.float ammo_rockets;
-.float ammo_cells;
-.float ammo_fuel;
-.float ammo_batteries; // dummy
-
-// entity properties of weaponinfo:
-.float weapon; // WEP_...
-.string netname; // short name
-.string message; // human readable name
-.float items; // IT_...
-.float(float) weapon_func; // w_...
-.string mdl; // modelname without g_, v_, w_
-.string model; // full name of g_ model
-.float spawnflags; // WEPSPAWNFLAG_... combined
-.float impulse; // weapon impulse
-.float bot_pickupbasevalue; // bot weapon priority
-.string model2; // wpn- sprite name
-..float ammo_field; // main ammo field
-// also, weaponinfo ents can act as a WEPSET
-
-// dynamic weapon adding
-float w_null(float dummy);
-void register_weapon(float id, float(float) func, float ammotype, float i, float weapontype, float pickupbasevalue, string modelname, string shortname, string wname);
-void register_weapons_done();
-
-#define WEP_FIRST 1
-float WEP_COUNT;
-float WEP_LAST;
-
-#if 1
-# define WEP_MAXCOUNT 24
-// default storage
-.float _WS_weapons;
-# define WEPSET_BIT(a) power2of((a) - WEP_FIRST)
-# define WEPSET_DECLARE_A(a) float _WS_##a
-# define WEPSET_CLEAR_E(e) ((e)._WS_weapons = 0)
-# define WEPSET_CLEAR_A(a) (_WS_##a = 0)
-# define WEPSET_EMPTY_E(e) ((e)._WS_weapons == 0)
-# define WEPSET_EMPTY_A(a) (_WS_##a == 0)
-# define WEPSET_COPY_AS(a) (_WS_##a = getstati(STAT_WEAPONS))
-# define WEPSET_ADDSTAT() addstat(STAT_WEAPONS, AS_INT, _WS_weapons)
-# define WEPSET_WRITE_E(dest,a) WriteInt24_t(dest, (a)._WS_weapons)
-# define WEPSET_WRITE_A(dest,a) WriteInt24_t(dest, _WS_##a)
-# define WEPSET_WRITE_W(dest,a) WriteInt24_t(dest, WEPSET_BIT(a))
-# define WEPSET_READ_E(a) (a)._WS_weapons = ReadInt24_t()
-# define WEPSET_READ_A(a) (_WS_##a) = ReadInt24_t()
-# define WEPSET_OP1_EE(a,b,mergeop,x) ((a)._WS_weapons x (b)._WS_weapons)
-# define WEPSET_OP2_EE(a,b,mergeop,x,y) ((a)._WS_weapons x (b)._WS_weapons y (a)._WS_weapons)
-# define WEPSET_OP1_EA(a,b,mergeop,x) ((a)._WS_weapons x _WS_##b)
-# define WEPSET_OP2_EA(a,b,mergeop,x,y) ((a)._WS_weapons x _WS_##b y (a)._WS_weapons)
-# define WEPSET_OP1_EW(a,b,mergeop,x) ((a)._WS_weapons x WEPSET_BIT(b))
-# define WEPSET_OP2_EW(a,b,mergeop,x,y) ((a)._WS_weapons x WEPSET_BIT(b) y (a)._WS_weapons)
-# define WEPSET_OP1_AE(a,b,mergeop,x) (_WS_##a x (b)._WS_weapons)
-# define WEPSET_OP2_AE(a,b,mergeop,x,y) (_WS_##a x (b)._WS_weapons y _WS_##a)
-# define WEPSET_OP1_AA(a,b,mergeop,x) (_WS_##a x _WS_##b)
-# define WEPSET_OP2_AA(a,b,mergeop,x,y) (_WS_##a x _WS_##b y _WS_##a)
-# define WEPSET_OP1_AW(a,b,mergeop,x) (_WS_##a x WEPSET_BIT(b))
-# define WEPSET_OP2_AW(a,b,mergeop,x,y) (_WS_##a x WEPSET_BIT(b) y _WS_##a)
-#else
-# define WEP_MAXCOUNT 48
-# define WEP_FIRST2 25
-.float _WS1_weapons;
-.float _WS2_weapons;
-# define WEPSET_BIT1(a) (((a) < WEP_FIRST2) ? power2of((a) - WEP_FIRST) : 0)
-# define WEPSET_BIT2(a) (((a) >= WEP_FIRST2) ? power2of((a) - WEP_FIRST2) : 0)
-# define WEPSET_DECLARE_A(a) float _WS1_##a, _WS2_##a
-# define WEPSET_CLEAR_E(e) ((e)._WS1_weapons = (e)._WS2_weapons = 0)
-# define WEPSET_CLEAR_A(a) ((_WS1_##a) = (_WS2_##a) = 0)
-# define WEPSET_EMPTY_E(e) ((e)._WS1_weapons == 0 && (e)._WS2_weapons == 0)
-# define WEPSET_EMPTY_A(a) ((_WS1_##a) == 0 && (_WS2_##a) == 0)
-# define WEPSET_COPY_AS(a) ((_WS1_##a) = getstati(STAT_WEAPONS), (_WS2_##a) = getstati(STAT_WEAPONS2))
-# define WEPSET_ADDSTAT() addstat(STAT_WEAPONS, AS_INT, _WS1_weapons); addstat(STAT_WEAPONS2, AS_INT, _WS2_weapons)
-# define WEPSET_WRITE_E(dest,a) WriteInt24_t(dest, (a)._WS1_weapons); WriteInt24_t(dest, (a)._WS2_weapons)
-# define WEPSET_WRITE_A(dest,a) WriteInt24_t(dest, _WS1_##a); WriteInt24_t(dest, _WS2_##a)
-# define WEPSET_WRITE_W(dest,a) WriteInt24_t(dest, WEPSET_BIT1(a)); WriteInt24_t(dest, WEPSET_BIT2(a))
-# define WEPSET_READ_E(a) (a)._WS1_weapons = ReadInt24_t(); (a)._WS2_weapons = ReadInt24_t()
-# define WEPSET_READ_A(a) (_WS1_##a) = ReadInt24_t(); (_WS2_##a) = ReadInt24_t()
-# define WEPSET_OP1_EE(a,b,mergeop,x) (((a)._WS1_weapons x (b)._WS1_weapons) mergeop ((a)._WS2_weapons x (b)._WS2_weapons))
-# define WEPSET_OP2_EE(a,b,mergeop,x,y) (((a)._WS1_weapons x (b)._WS1_weapons y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x (b)._WS2_weapons y (a)._WS2_weapons))
-# define WEPSET_OP1_EA(a,b,mergeop,x) (((a)._WS1_weapons x _WS1_##b) mergeop ((a)._WS2_weapons x _WS2_##b))
-# define WEPSET_OP2_EA(a,b,mergeop,x,y) (((a)._WS1_weapons x _WS1_##b y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x _WS2_##b y (a)._WS2_weapons))
-# define WEPSET_OP1_EW(a,b,mergeop,x) (((a)._WS1_weapons x WEPSET_BIT1(b)) mergeop ((a)._WS2_weapons x WEPSET_BIT2(b)))
-# define WEPSET_OP2_EW(a,b,mergeop,x,y) (((a)._WS1_weapons x WEPSET_BIT1(b) y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x WEPSET_BIT2(b) y (a)._WS2_weapons))
-# define WEPSET_OP1_AE(a,b,mergeop,x) ((_WS1_##a x (b)._WS1_weapons) mergeop (_WS2_##a x (b)._WS2_weapons))
-# define WEPSET_OP2_AE(a,b,mergeop,x,y) ((_WS1_##a x (b)._WS1_weapons y _WS1_##a) mergeop (_WS2_##a x (b)._WS2_weapons y _WS2_##a))
-# define WEPSET_OP1_AA(a,b,mergeop,x) ((_WS1_##a x _WS1_##b) mergeop (_WS2_##a x _WS2_##b))
-# define WEPSET_OP2_AA(a,b,mergeop,x,y) ((_WS1_##a x _WS1_##b y _WS1_##a) mergeop (_WS2_##a x _WS2_##b y _WS2_##a))
-# define WEPSET_OP1_AW(a,b,mergeop,x) ((_WS1_##a x WEPSET_BIT1(b)) mergeop (_WS2_##a x WEPSET_BIT2(b)))
-# define WEPSET_OP2_AW(a,b,mergeop,x,y) ((_WS1_##a x WEPSET_BIT1(b) y _WS1_##a) mergeop (_WS2_##a x WEPSET_BIT2(b) y _WS2_##a))
-#endif
-
-#define XX ,
-
-#define WEPSET_COPY_EE(a,b) WEPSET_OP1_EE(a,b,XX,=)
-#define WEPSET_EQ_EE(a,b) WEPSET_OP1_EE(a,b,&&,==)
-#define WEPSET_OR_EE(a,b) WEPSET_OP1_EE(a,b,XX,|=)
-#define WEPSET_AND_EE(a,b) WEPSET_OP2_EE(a,b,XX,=,&)
-#define WEPSET_ANDNOT_EE(a,b) WEPSET_OP1_EE(a,b,XX,&~=)
-#define WEPSET_CONTAINS_ANY_EE(a,b) !!(WEPSET_OP1_EE(a,b,||,&))
-#define WEPSET_CONTAINS_ALL_EE(a,b) WEPSET_OP2_EE(b,a,&&,==,&)
-
-#define WEPSET_COPY_EA(a,b) WEPSET_OP1_EA(a,b,XX,=)
-#define WEPSET_EQ_EA(a,b) WEPSET_OP1_EA(a,b,&&,==)
-#define WEPSET_OR_EA(a,b) WEPSET_OP1_EA(a,b,XX,|=)
-#define WEPSET_AND_EA(a,b) WEPSET_OP2_EA(a,b,XX,=,&)
-#define WEPSET_ANDNOT_EA(a,b) WEPSET_OP1_EA(a,b,XX,&~=)
-#define WEPSET_CONTAINS_ANY_EA(a,b) !!(WEPSET_OP1_EA(a,b,||,&))
-#define WEPSET_CONTAINS_ALL_EA(a,b) WEPSET_OP2_EA(b,a,&&,==,&)
-
-#define WEPSET_COPY_EW(a,b) WEPSET_OP1_EW(a,b,XX,=)
-#define WEPSET_EQ_EW(a,b) WEPSET_OP1_EW(a,b,&&,==)
-#define WEPSET_OR_EW(a,b) WEPSET_OP1_EW(a,b,XX,|=)
-#define WEPSET_AND_EW(a,b) WEPSET_OP2_EW(a,b,XX,=,&)
-#define WEPSET_ANDNOT_EW(a,b) WEPSET_OP1_EW(a,b,XX,&~=)
-#define WEPSET_CONTAINS_EW(a,b) !!(WEPSET_OP1_EW(a,b,||,&))
-
-#define WEPSET_COPY_AE(a,b) WEPSET_OP1_AE(a,b,XX,=)
-#define WEPSET_EQ_AE(a,b) WEPSET_OP1_AE(a,b,&&,==)
-#define WEPSET_OR_AE(a,b) WEPSET_OP1_AE(a,b,XX,|=)
-#define WEPSET_AND_AE(a,b) WEPSET_OP2_AE(a,b,XX,=,&)
-#define WEPSET_ANDNOT_AE(a,b) WEPSET_OP1_AE(a,b,XX,&~=)
-#define WEPSET_CONTAINS_ANY_AE(a,b) !!(WEPSET_OP1_AE(a,b,||,&))
-#define WEPSET_CONTAINS_ALL_AE(a,b) WEPSET_OP2_AE(b,a,&&,==,&)
-
-#define WEPSET_COPY_AA(a,b) WEPSET_OP1_AA(a,b,XX,=)
-#define WEPSET_EQ_AA(a,b) WEPSET_OP1_AA(a,b,&&,==)
-#define WEPSET_OR_AA(a,b) WEPSET_OP1_AA(a,b,XX,|=)
-#define WEPSET_AND_AA(a,b) WEPSET_OP2_AA(a,b,XX,=,&)
-#define WEPSET_ANDNOT_AA(a,b) WEPSET_OP1_AA(a,b,XX,&~=)
-#define WEPSET_CONTAINS_ANY_AA(a,b) !!(WEPSET_OP1_AA(a,b,||,&))
-#define WEPSET_CONTAINS_ALL_AA(a,b) WEPSET_OP2_AA(b,a,&&,==,&)
-
-#define WEPSET_COPY_AW(a,b) WEPSET_OP1_AW(a,b,XX,=)
-#define WEPSET_EQ_AW(a,b) WEPSET_OP1_AW(a,b,&&,==)
-#define WEPSET_OR_AW(a,b) WEPSET_OP1_AW(a,b,XX,|=)
-#define WEPSET_AND_AW(a,b) WEPSET_OP2_AW(a,b,XX,=,&)
-#define WEPSET_ANDNOT_AW(a,b) WEPSET_OP1_AW(a,b,XX,&~=)
-#define WEPSET_CONTAINS_AW(a,b) !!(WEPSET_OP1_AW(a,b,||,&))
-
-WEPSET_DECLARE_A(WEPBIT_ALL);
-WEPSET_DECLARE_A(WEPBIT_SUPERWEAPONS);
-// note: the fabs call is just there to hide "if result is constant" warning
-#define REGISTER_WEAPON_2(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
- float id; \
- float func(float); \
- void RegisterWeapons_##id() \
- { \
- WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \
- WEPSET_OR_AW(WEPBIT_ALL, id); \
- if(fabs(weapontype & WEP_FLAG_SUPERWEAPON)) \
- WEPSET_OR_AW(WEPBIT_SUPERWEAPONS, id); \
- ++WEP_COUNT; \
- register_weapon(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname); \
- } \
- ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)
-#ifdef MENUQC
-#define REGISTER_WEAPON(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
- REGISTER_WEAPON_2(WEP_##id,w_null,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname)
-#else
-#define REGISTER_WEAPON(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
- REGISTER_WEAPON_2(WEP_##id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname)
-#endif
-
-#include "../server/weapons/w_all.qc"
-
-#undef REGISTER_WEAPON
-ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done)
-
-
-string W_FixWeaponOrder(string order, float complete);
-string W_NumberWeaponOrder(string order);
-string W_NameWeaponOrder(string order);
-string W_FixWeaponOrder_BuildImpulseList(string o);
-string W_FixWeaponOrder_AllowIncomplete(string order);
-string W_FixWeaponOrder_ForceComplete(string order);
-
-void W_RandomWeapons(entity e, float n);
-
-string W_Name(float weaponid);
-
-float W_AmmoItemCode(float wpn);
queue_start.FindConnectedComponent_processing = 0;
}
-
-#ifndef MENUQC
-vector cliptoplane(vector v, vector p)
-{
- return v - (v * p) * p;
-}
-
-vector solve_cubic_pq(float p, float q)
-{
- float D, u, v, a;
- D = q*q/4.0 + p*p*p/27.0;
- if(D < 0)
- {
- // irreducibilis
- a = 1.0/3.0 * acos(-q/2.0 * sqrt(-27.0/(p*p*p)));
- u = sqrt(-4.0/3.0 * p);
- // a in range 0..pi/3
- // cos(a)
- // cos(a + 2pi/3)
- // cos(a + 4pi/3)
- return
- u *
- (
- '1 0 0' * cos(a + 2.0/3.0*M_PI)
- +
- '0 1 0' * cos(a + 4.0/3.0*M_PI)
- +
- '0 0 1' * cos(a)
- );
- }
- else if(D == 0)
- {
- // simple
- if(p == 0)
- return '0 0 0';
- u = 3*q/p;
- v = -u/2;
- if(u >= v)
- return '1 1 0' * v + '0 0 1' * u;
- else
- return '0 1 1' * v + '1 0 0' * u;
- }
- else
- {
- // cardano
- u = cbrt(-q/2.0 + sqrt(D));
- v = cbrt(-q/2.0 - sqrt(D));
- return '1 1 1' * (u + v);
- }
-}
-vector solve_cubic_abcd(float a, float b, float c, float d)
-{
- // y = 3*a*x + b
- // x = (y - b) / 3a
- float p, q;
- vector v;
- p = (9*a*c - 3*b*b);
- q = (27*a*a*d - 9*a*b*c + 2*b*b*b);
- v = solve_cubic_pq(p, q);
- v = (v - b * '1 1 1') * (1.0 / (3.0 * a));
- if(a < 0)
- v += '1 0 -1' * (v_z - v_x); // swap x, z
- return v;
-}
-
-vector findperpendicular(vector v)
-{
- vector p;
- p_x = v_z;
- p_y = -v_x;
- p_z = v_y;
- return normalize(cliptoplane(p, v));
-}
-
-vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle)
-{
- float sigma;
- vector v1 = '0 0 0', v2;
- float dx, dy, r;
- float sstyle;
- spread *= spreadfactor; //g_weaponspreadfactor;
- if(spread <= 0)
- return forward;
- sstyle = spreadstyle; //autocvar_g_projectiles_spread_style;
-
- if(sstyle == 0)
- {
- // this is the baseline for the spread value!
- // standard deviation: sqrt(2/5)
- // density function: sqrt(1-r^2)
- return forward + randomvec() * spread;
- }
- else if(sstyle == 1)
- {
- // same thing, basically
- return normalize(forward + cliptoplane(randomvec() * spread, forward));
- }
- else if(sstyle == 2)
- {
- // circle spread... has at sigma=1 a standard deviation of sqrt(1/2)
- sigma = spread * 0.89442719099991587855; // match baseline stddev
- v1 = findperpendicular(forward);
- v2 = cross(forward, v1);
- // random point on unit circle
- dx = random() * 2 * M_PI;
- dy = sin(dx);
- dx = cos(dx);
- // radius in our dist function
- r = random();
- r = sqrt(r);
- return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
- }
- else if(sstyle == 3) // gauss 3d
- {
- sigma = spread * 0.44721359549996; // match baseline stddev
- // note: 2D gaussian has sqrt(2) times the stddev of 1D, so this factor is right
- v1 = forward;
- v1_x += gsl_ran_gaussian(sigma);
- v1_y += gsl_ran_gaussian(sigma);
- v1_z += gsl_ran_gaussian(sigma);
- return v1;
- }
- else if(sstyle == 4) // gauss 2d
- {
- sigma = spread * 0.44721359549996; // match baseline stddev
- // note: 2D gaussian has sqrt(2) times the stddev of 1D, so this factor is right
- v1_x = gsl_ran_gaussian(sigma);
- v1_y = gsl_ran_gaussian(sigma);
- v1_z = gsl_ran_gaussian(sigma);
- return normalize(forward + cliptoplane(v1, forward));
- }
- else if(sstyle == 5) // 1-r
- {
- sigma = spread * 1.154700538379252; // match baseline stddev
- v1 = findperpendicular(forward);
- v2 = cross(forward, v1);
- // random point on unit circle
- dx = random() * 2 * M_PI;
- dy = sin(dx);
- dx = cos(dx);
- // radius in our dist function
- r = random();
- r = solve_cubic_abcd(-2, 3, 0, -r) * '0 1 0';
- return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
- }
- else if(sstyle == 6) // 1-r^2
- {
- sigma = spread * 1.095445115010332; // match baseline stddev
- v1 = findperpendicular(forward);
- v2 = cross(forward, v1);
- // random point on unit circle
- dx = random() * 2 * M_PI;
- dy = sin(dx);
- dx = cos(dx);
- // radius in our dist function
- r = random();
- r = sqrt(1 - r);
- r = sqrt(1 - r);
- return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
- }
- else if(sstyle == 7) // (1-r) (2-r)
- {
- sigma = spread * 1.224744871391589; // match baseline stddev
- v1 = findperpendicular(forward);
- v2 = cross(forward, v1);
- // random point on unit circle
- dx = random() * 2 * M_PI;
- dy = sin(dx);
- dx = cos(dx);
- // radius in our dist function
- r = random();
- r = 1 - sqrt(r);
- r = 1 - sqrt(r);
- return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
- }
- else
- error("g_projectiles_spread_style must be 0 (sphere), 1 (flattened sphere), 2 (circle), 3 (gauss 3D), 4 (gauss plane), 5 (linear falloff), 6 (quadratic falloff), 7 (stronger falloff)!");
- return '0 0 0';
- /*
- * how to derive falloff functions:
- * rho(r) := (2-r) * (1-r);
- * a : 0;
- * b : 1;
- * rhor(r) := r * rho(r);
- * cr(t) := integrate(rhor(r), r, a, t);
- * scr(t) := integrate(rhor(r) * r^2, r, a, t);
- * variance : scr(b) / cr(b);
- * solve(cr(r) = rand * cr(b), r), programmmode:false;
- * sqrt(0.4 / variance), numer;
- */
-}
-#endif
-
#ifdef SVQC
vector combine_to_vector(float x, float y, float z)
{
typedef float(entity a, entity b, entity pass) isConnectedFunction_t;
void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass);
-#ifndef MENUQC
-vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle);
-#endif
-
#ifdef SVQC
vector get_corner_position(entity box, float corner);
#endif
--- /dev/null
+// ONLY EVER ADD NEW WEAPONS AT THE END. IF YOU REMOVE ONE, PUT THE LAST ONE ON
+// ITS PLACE. THIS IS TO AVOID UNNECESSARY RENUMBERING OF WEAPON IMPULSES.
+// IF YOU DISREGARD THIS NOTICE, I'LL KILL YOU WITH THE @!#%'N TUBA
+
+// core weapons
+#include "blaster.qc"
+#include "shockwave.qc"
+#include "machinegun.qc"
+#include "mortar.qc"
+#include "minelayer.qc"
+#include "electro.qc"
+#include "arc.qc"
+#include "crylink.qc"
+#include "nex.qc"
+#include "hagar.qc"
+#include "devastator.qc"
+
+// other weapons
+#include "porto.qc"
+#include "minstanex.qc"
+#include "hook.qc"
+#include "hlac.qc"
+#include "tuba.qc"
+#include "rifle.qc"
+#include "fireball.qc"
+#include "seeker.qc"
--- /dev/null
+// =============================
+// Explosion Force Calculation
+// =============================
+float explosion_calcpush_getmultiplier(vector explosion_v, vector target_v)
+{
+ float a;
+ a = explosion_v * (explosion_v - target_v);
+
+ if(a <= 0)
+ // target is too fast to be hittable by this
+ return 0;
+
+ a /= (explosion_v * explosion_v);
+ // we know we can divide by this, or above a would be == 0
+
+ return a;
+}
+
+#if 0
+vector explosion_calcpush(vector explosion_v, float explosion_m, vector target_v, float target_m, float elasticity)
+{
+ // solution of the equations:
+ // v' = v + a vp // central hit
+ // m*v' + mp*vp' = m*v + mp*vp // conservation of momentum
+ // m*v'^2 + mp*vp'^2 = m*v^2 + mp*vp^2 // conservation of energy (ELASTIC hit)
+ // -> a = 0 // case 1: did not hit
+ // -> a = 2*mp*(vp^2 - vp.v) / ((m+mp) * vp^2) // case 2: did hit
+ // // non-elastic hits are somewhere between these two
+
+ // this would be physically correct, but we don't do that
+ return explosion_v * explosion_calcpush_getmultiplier(explosion_v, target_v) * (
+ (1 + elasticity) * (
+ explosion_m
+ ) / (
+ target_m + explosion_m
+ )
+ ); // note: this factor is at least 0, at most 2
+}
+#endif
+
+// simplified formula, tuned so that if the target has velocity 0, we get exactly the original force
+vector damage_explosion_calcpush(vector explosion_f, vector target_v, float speedfactor)
+{
+ // if below 1, the formulas make no sense (and would cause superjumps)
+ if(speedfactor < 1)
+ return explosion_f;
+
+#if 0
+ float m;
+ // find m so that
+ // speedfactor * (1 + e) * m / (1 + m) == 1
+ m = 1 / ((1 + 0) * speedfactor - 1);
+ vector v;
+ v = explosion_calcpush(explosion_f * speedfactor, m, target_v, 1, 0);
+ // the factor we then get is:
+ // 1
+ print(sprintf("MASS: %f\nv: %v -> %v\nENERGY BEFORE == %f + %f = %f\nENERGY AFTER >= %f\n",
+ m,
+ target_v, target_v + v,
+ target_v * target_v, m * explosion_f * speedfactor * explosion_f * speedfactor, target_v * target_v + m * explosion_f * speedfactor * explosion_f * speedfactor,
+ (target_v + v) * (target_v + v)));
+ return v;
+#endif
+ return explosion_f * explosion_calcpush_getmultiplier(explosion_f * speedfactor, target_v);
+}
+
+
+// =========================
+// Shot Spread Calculation
+// =========================
+
+vector cliptoplane(vector v, vector p)
+{
+ return v - (v * p) * p;
+}
+
+vector solve_cubic_pq(float p, float q)
+{
+ float D, u, v, a;
+ D = q*q/4.0 + p*p*p/27.0;
+ if(D < 0)
+ {
+ // irreducibilis
+ a = 1.0/3.0 * acos(-q/2.0 * sqrt(-27.0/(p*p*p)));
+ u = sqrt(-4.0/3.0 * p);
+ // a in range 0..pi/3
+ // cos(a)
+ // cos(a + 2pi/3)
+ // cos(a + 4pi/3)
+ return
+ u *
+ (
+ '1 0 0' * cos(a + 2.0/3.0*M_PI)
+ +
+ '0 1 0' * cos(a + 4.0/3.0*M_PI)
+ +
+ '0 0 1' * cos(a)
+ );
+ }
+ else if(D == 0)
+ {
+ // simple
+ if(p == 0)
+ return '0 0 0';
+ u = 3*q/p;
+ v = -u/2;
+ if(u >= v)
+ return '1 1 0' * v + '0 0 1' * u;
+ else
+ return '0 1 1' * v + '1 0 0' * u;
+ }
+ else
+ {
+ // cardano
+ u = cbrt(-q/2.0 + sqrt(D));
+ v = cbrt(-q/2.0 - sqrt(D));
+ return '1 1 1' * (u + v);
+ }
+}
+vector solve_cubic_abcd(float a, float b, float c, float d)
+{
+ // y = 3*a*x + b
+ // x = (y - b) / 3a
+ float p, q;
+ vector v;
+ p = (9*a*c - 3*b*b);
+ q = (27*a*a*d - 9*a*b*c + 2*b*b*b);
+ v = solve_cubic_pq(p, q);
+ v = (v - b * '1 1 1') * (1.0 / (3.0 * a));
+ if(a < 0)
+ v += '1 0 -1' * (v_z - v_x); // swap x, z
+ return v;
+}
+
+vector findperpendicular(vector v)
+{
+ vector p;
+ p_x = v_z;
+ p_y = -v_x;
+ p_z = v_y;
+ return normalize(cliptoplane(p, v));
+}
+
+vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle)
+{
+ float sigma;
+ vector v1 = '0 0 0', v2;
+ float dx, dy, r;
+ float sstyle;
+ spread *= spreadfactor; //g_weaponspreadfactor;
+ if(spread <= 0)
+ return forward;
+ sstyle = spreadstyle; //autocvar_g_projectiles_spread_style;
+
+ if(sstyle == 0)
+ {
+ // this is the baseline for the spread value!
+ // standard deviation: sqrt(2/5)
+ // density function: sqrt(1-r^2)
+ return forward + randomvec() * spread;
+ }
+ else if(sstyle == 1)
+ {
+ // same thing, basically
+ return normalize(forward + cliptoplane(randomvec() * spread, forward));
+ }
+ else if(sstyle == 2)
+ {
+ // circle spread... has at sigma=1 a standard deviation of sqrt(1/2)
+ sigma = spread * 0.89442719099991587855; // match baseline stddev
+ v1 = findperpendicular(forward);
+ v2 = cross(forward, v1);
+ // random point on unit circle
+ dx = random() * 2 * M_PI;
+ dy = sin(dx);
+ dx = cos(dx);
+ // radius in our dist function
+ r = random();
+ r = sqrt(r);
+ return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
+ }
+ else if(sstyle == 3) // gauss 3d
+ {
+ sigma = spread * 0.44721359549996; // match baseline stddev
+ // note: 2D gaussian has sqrt(2) times the stddev of 1D, so this factor is right
+ v1 = forward;
+ v1_x += gsl_ran_gaussian(sigma);
+ v1_y += gsl_ran_gaussian(sigma);
+ v1_z += gsl_ran_gaussian(sigma);
+ return v1;
+ }
+ else if(sstyle == 4) // gauss 2d
+ {
+ sigma = spread * 0.44721359549996; // match baseline stddev
+ // note: 2D gaussian has sqrt(2) times the stddev of 1D, so this factor is right
+ v1_x = gsl_ran_gaussian(sigma);
+ v1_y = gsl_ran_gaussian(sigma);
+ v1_z = gsl_ran_gaussian(sigma);
+ return normalize(forward + cliptoplane(v1, forward));
+ }
+ else if(sstyle == 5) // 1-r
+ {
+ sigma = spread * 1.154700538379252; // match baseline stddev
+ v1 = findperpendicular(forward);
+ v2 = cross(forward, v1);
+ // random point on unit circle
+ dx = random() * 2 * M_PI;
+ dy = sin(dx);
+ dx = cos(dx);
+ // radius in our dist function
+ r = random();
+ r = solve_cubic_abcd(-2, 3, 0, -r) * '0 1 0';
+ return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
+ }
+ else if(sstyle == 6) // 1-r^2
+ {
+ sigma = spread * 1.095445115010332; // match baseline stddev
+ v1 = findperpendicular(forward);
+ v2 = cross(forward, v1);
+ // random point on unit circle
+ dx = random() * 2 * M_PI;
+ dy = sin(dx);
+ dx = cos(dx);
+ // radius in our dist function
+ r = random();
+ r = sqrt(1 - r);
+ r = sqrt(1 - r);
+ return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
+ }
+ else if(sstyle == 7) // (1-r) (2-r)
+ {
+ sigma = spread * 1.224744871391589; // match baseline stddev
+ v1 = findperpendicular(forward);
+ v2 = cross(forward, v1);
+ // random point on unit circle
+ dx = random() * 2 * M_PI;
+ dy = sin(dx);
+ dx = cos(dx);
+ // radius in our dist function
+ r = random();
+ r = 1 - sqrt(r);
+ r = 1 - sqrt(r);
+ return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
+ }
+ else
+ error("g_projectiles_spread_style must be 0 (sphere), 1 (flattened sphere), 2 (circle), 3 (gauss 3D), 4 (gauss plane), 5 (linear falloff), 6 (quadratic falloff), 7 (stronger falloff)!");
+ return '0 0 0';
+ /*
+ * how to derive falloff functions:
+ * rho(r) := (2-r) * (1-r);
+ * a : 0;
+ * b : 1;
+ * rhor(r) := r * rho(r);
+ * cr(t) := integrate(rhor(r), r, a, t);
+ * scr(t) := integrate(rhor(r) * r^2, r, a, t);
+ * variance : scr(b) / cr(b);
+ * solve(cr(r) = rand * cr(b), r), programmmode:false;
+ * sqrt(0.4 / variance), numer;
+ */
+}
--- /dev/null
+vector damage_explosion_calcpush(vector explosion_f, vector target_v, float speedfactor);
+vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle);
--- /dev/null
+#ifndef MENUQC
+#include "calculations.qc"
+#endif
+#include "all.qh"
+
+// WEAPON PLUGIN SYSTEM
+entity weapon_info[WEP_MAXCOUNT];
+entity dummy_weapon_info;
+
+void register_weapon(float id, float(float) func, float ammotype, float i, float weapontype, float pickupbasevalue, string modelname, string shortname, string wname)
+{
+ entity e;
+ weapon_info[id - 1] = e = spawn();
+ e.classname = "weapon_info";
+ e.weapon = id;
+ WEPSET_COPY_EW(e, id);
+ e.netname = shortname;
+ e.message = wname;
+ e.items = ammotype;
+ e.weapon_func = func;
+ e.mdl = modelname;
+ e.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
+ e.spawnflags = weapontype;
+ e.model2 = strzone(strcat("wpn-", e.mdl));
+ e.impulse = i;
+ e.bot_pickupbasevalue = pickupbasevalue;
+ if(ammotype & IT_SHELLS)
+ e.ammo_field = ammo_shells;
+ else if(ammotype & IT_NAILS)
+ e.ammo_field = ammo_nails;
+ else if(ammotype & IT_ROCKETS)
+ e.ammo_field = ammo_rockets;
+ else if(ammotype & IT_CELLS)
+ e.ammo_field = ammo_cells;
+ else if(ammotype & IT_FUEL)
+ e.ammo_field = ammo_fuel;
+ else
+ e.ammo_field = ammo_batteries;
+}
+float w_null(float dummy)
+{
+ return 0;
+}
+void register_weapons_done()
+{
+ dummy_weapon_info = spawn();
+ dummy_weapon_info.classname = "weapon_info";
+ dummy_weapon_info.weapon = 0; // you can recognize dummies by this
+ WEPSET_CLEAR_E(dummy_weapon_info);
+ dummy_weapon_info.netname = "";
+ dummy_weapon_info.message = "AOL CD Thrower";
+ dummy_weapon_info.items = 0;
+ dummy_weapon_info.weapon_func = w_null;
+ dummy_weapon_info.mdl = "";
+ dummy_weapon_info.model = "";
+ dummy_weapon_info.spawnflags = 0;
+ dummy_weapon_info.model2 = "";
+ dummy_weapon_info.impulse = -1;
+ dummy_weapon_info.bot_pickupbasevalue = 0;
+
+ float i;
+ weaponorder_byid = "";
+ for(i = WEP_MAXCOUNT; i >= 1; --i)
+ if(weapon_info[i-1])
+ weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
+ weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
+}
+entity get_weaponinfo(float 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;
+}
+string W_FixWeaponOrder(string order, float complete)
+{
+ return fixPriorityList(order, WEP_FIRST, WEP_LAST, 230 - WEP_FIRST, complete);
+}
+string W_NameWeaponOrder_MapFunc(string s)
+{
+ entity wi;
+ if(s == "0" || stof(s))
+ {
+ wi = get_weaponinfo(stof(s));
+ if(wi != dummy_weapon_info)
+ return wi.netname;
+ }
+ return s;
+}
+string W_NameWeaponOrder(string order)
+{
+ return mapPriorityList(order, W_NameWeaponOrder_MapFunc);
+}
+string W_NumberWeaponOrder_MapFunc(string s)
+{
+ float i;
+ if(s == "0" || stof(s))
+ return s;
+ for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+ if(s == get_weaponinfo(i).netname)
+ return ftos(i);
+ return s;
+}
+string W_NumberWeaponOrder(string order)
+{
+ return mapPriorityList(order, W_NumberWeaponOrder_MapFunc);
+}
+
+float W_FixWeaponOrder_BuildImpulseList_buf[WEP_MAXCOUNT];
+string W_FixWeaponOrder_BuildImpulseList_order;
+void W_FixWeaponOrder_BuildImpulseList_swap(float i, float j, entity pass)
+{
+ float h;
+ h = W_FixWeaponOrder_BuildImpulseList_buf[i];
+ W_FixWeaponOrder_BuildImpulseList_buf[i] = W_FixWeaponOrder_BuildImpulseList_buf[j];
+ W_FixWeaponOrder_BuildImpulseList_buf[j] = h;
+}
+float W_FixWeaponOrder_BuildImpulseList_cmp(float i, float j, entity pass)
+{
+ entity e1, e2;
+ float d;
+ e1 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[i]);
+ e2 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[j]);
+ d = mod(e1.impulse + 9, 10) - mod(e2.impulse + 9, 10);
+ if(d != 0)
+ return -d; // high impulse first!
+ return
+ strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
+ -
+ strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
+ ; // low char index first!
+}
+string W_FixWeaponOrder_BuildImpulseList(string o)
+{
+ float i;
+ W_FixWeaponOrder_BuildImpulseList_order = o;
+ for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+ W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST] = i;
+ heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp, world);
+ o = "";
+ for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+ o = strcat(o, " ", ftos(W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST]));
+ W_FixWeaponOrder_BuildImpulseList_order = string_null;
+ return substring(o, 1, -1);
+}
+
+string W_FixWeaponOrder_AllowIncomplete(string order)
+{
+ return W_FixWeaponOrder(order, 0);
+}
+
+string W_FixWeaponOrder_ForceComplete(string order)
+{
+ if(order == "")
+ order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
+ return W_FixWeaponOrder(order, 1);
+}
+
+void W_RandomWeapons(entity e, float n)
+{
+ float i, j;
+ WEPSET_DECLARE_A(remaining);
+ WEPSET_DECLARE_A(result);
+ WEPSET_COPY_AE(remaining, e);
+ WEPSET_CLEAR_A(result);
+ for(i = 0; i < n; ++i)
+ {
+ RandomSelection_Init();
+ for(j = WEP_FIRST; j <= WEP_LAST; ++j)
+ if(WEPSET_CONTAINS_AW(remaining, j))
+ RandomSelection_Add(world, j, string_null, 1, 1);
+ WEPSET_OR_AW(result, RandomSelection_chosen_float);
+ WEPSET_ANDNOT_AW(remaining, RandomSelection_chosen_float);
+ }
+ WEPSET_COPY_EA(e, result);
+}
+
+string W_Name(float weaponid)
+{
+ return (get_weaponinfo(weaponid)).message;
+}
+
+float W_AmmoItemCode(float wpn)
+{
+ return (get_weaponinfo(wpn)).items & IT_AMMO;
+}
-// ONLY EVER ADD NEW WEAPONS AT THE END. IF YOU REMOVE ONE, PUT THE LAST ONE ON
-// ITS PLACE. THIS IS TO AVOID UNNECESSARY RENUMBERING OF WEAPON IMPULSES.
-// IF YOU DISREGARD THIS NOTICE, I'LL KILL YOU WITH THE @!#%'N TUBA
-
-// core weapons
-#include "blaster.qc"
-#include "shockwave.qc"
-#include "machinegun.qc"
-#include "mortar.qc"
-#include "minelayer.qc"
-#include "electro.qc"
-#include "arc.qc"
-#include "crylink.qc"
-#include "nex.qc"
-#include "hagar.qc"
-#include "devastator.qc"
-#include "porto.qc"
-#include "minstanex.qc"
-#include "hook.qc"
-#include "hlac.qc"
-#include "tuba.qc"
-#include "rifle.qc"
-#include "fireball.qc"
-#include "seeker.qc"
-
-// other weapons
+#ifndef MENUQC
+#include "calculations.qh"
+#endif
+
+float BOT_PICKUP_RATING_LOW = 2500;
+float BOT_PICKUP_RATING_MID = 5000;
+float BOT_PICKUP_RATING_HIGH = 10000;
+
+float WEP_TYPE_OTHER = 0x00; // not for damaging people
+float WEP_TYPE_SPLASH = 0x01; // splash damage
+float WEP_TYPE_HITSCAN = 0x02; // hitscan
+float WEP_TYPEMASK = 0x0F;
+float WEP_FLAG_CANCLIMB = 0x10; // can be used for movement
+float WEP_FLAG_NORMAL = 0x20; // in "most weapons" set
+float WEP_FLAG_HIDDEN = 0x40; // hides from menu
+float WEP_FLAG_RELOADABLE = 0x80; // can has reload
+float WEP_FLAG_SUPERWEAPON = 0x100; // powerup timer
+float WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag)
+
+float IT_UNLIMITED_WEAPON_AMMO = 1;
+// when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup.
+float IT_UNLIMITED_SUPERWEAPONS = 2;
+// when this bit is set, superweapons don't expire. Checkpoints can give this powerup.
+float IT_CTF_SHIELDED = 4; // set for the flag shield
+float IT_USING_JETPACK = 8; // confirmation that button is pressed
+float IT_JETPACK = 16; // actual item
+float IT_FUEL_REGEN = 32; // fuel regeneration trigger
+float IT_SHELLS = 256;
+float IT_NAILS = 512;
+float IT_ROCKETS = 1024;
+float IT_CELLS = 2048;
+float IT_SUPERWEAPON = 4096;
+float IT_FUEL = 128;
+float IT_STRENGTH = 8192;
+float IT_INVINCIBLE = 16384;
+float IT_HEALTH = 32768;
+// union:
+ // for items:
+ float IT_KEY1 = 131072;
+ float IT_KEY2 = 262144;
+ // for players:
+ float IT_RED_FLAG_TAKEN = 32768;
+ float IT_RED_FLAG_LOST = 65536;
+ float IT_RED_FLAG_CARRYING = 98304;
+ float IT_BLUE_FLAG_TAKEN = 131072;
+ float IT_BLUE_FLAG_LOST = 262144;
+ float IT_BLUE_FLAG_CARRYING = 393216;
+// end
+float IT_5HP = 524288;
+float IT_25HP = 1048576;
+float IT_ARMOR_SHARD = 2097152;
+float IT_ARMOR = 4194304;
+
+float IT_AMMO = 3968; // IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS | IT_FUEL;
+float IT_PICKUPMASK = 51; // IT_FUEL_REGEN | IT_JETPACK | IT_UNLIMITED_AMMO; // strength and invincible are handled separately
+float IT_UNLIMITED_AMMO = 3; // IT_UNLIMITED_SUPERWEAPONS | IT_UNLIMITED_WEAPON_AMMO;
+
+float AMMO_COUNT = 4; // amount of ammo types to show in the inventory panel
+
+// variables:
+string weaponorder_byid;
+
+// functions:
+entity get_weaponinfo(float id);
+string W_FixWeaponOrder(string order, float complete);
+string W_NameWeaponOrder(string order);
+string W_NumberWeaponOrder(string order);
+
+// ammo types
+.float ammo_shells;
+.float ammo_nails;
+.float ammo_rockets;
+.float ammo_cells;
+.float ammo_fuel;
+.float ammo_batteries; // dummy
+
+// entity properties of weaponinfo:
+.float weapon; // WEP_...
+.string netname; // short name
+.string message; // human readable name
+.float items; // IT_...
+.float(float) weapon_func; // w_...
+.string mdl; // modelname without g_, v_, w_
+.string model; // full name of g_ model
+.float spawnflags; // WEPSPAWNFLAG_... combined
+.float impulse; // weapon impulse
+.float bot_pickupbasevalue; // bot weapon priority
+.string model2; // wpn- sprite name
+..float ammo_field; // main ammo field
+// also, weaponinfo ents can act as a WEPSET
+
+
+// ===================
+// Weapon Operations
+// ===================
+#if 1
+# define WEP_MAXCOUNT 24
+// default storage
+.float _WS_weapons;
+# define WEPSET_BIT(a) power2of((a) - WEP_FIRST)
+# define WEPSET_DECLARE_A(a) float _WS_##a
+# define WEPSET_CLEAR_E(e) ((e)._WS_weapons = 0)
+# define WEPSET_CLEAR_A(a) (_WS_##a = 0)
+# define WEPSET_EMPTY_E(e) ((e)._WS_weapons == 0)
+# define WEPSET_EMPTY_A(a) (_WS_##a == 0)
+# define WEPSET_COPY_AS(a) (_WS_##a = getstati(STAT_WEAPONS))
+# define WEPSET_ADDSTAT() addstat(STAT_WEAPONS, AS_INT, _WS_weapons)
+# define WEPSET_WRITE_E(dest,a) WriteInt24_t(dest, (a)._WS_weapons)
+# define WEPSET_WRITE_A(dest,a) WriteInt24_t(dest, _WS_##a)
+# define WEPSET_WRITE_W(dest,a) WriteInt24_t(dest, WEPSET_BIT(a))
+# define WEPSET_READ_E(a) (a)._WS_weapons = ReadInt24_t()
+# define WEPSET_READ_A(a) (_WS_##a) = ReadInt24_t()
+# define WEPSET_OP1_EE(a,b,mergeop,x) ((a)._WS_weapons x (b)._WS_weapons)
+# define WEPSET_OP2_EE(a,b,mergeop,x,y) ((a)._WS_weapons x (b)._WS_weapons y (a)._WS_weapons)
+# define WEPSET_OP1_EA(a,b,mergeop,x) ((a)._WS_weapons x _WS_##b)
+# define WEPSET_OP2_EA(a,b,mergeop,x,y) ((a)._WS_weapons x _WS_##b y (a)._WS_weapons)
+# define WEPSET_OP1_EW(a,b,mergeop,x) ((a)._WS_weapons x WEPSET_BIT(b))
+# define WEPSET_OP2_EW(a,b,mergeop,x,y) ((a)._WS_weapons x WEPSET_BIT(b) y (a)._WS_weapons)
+# define WEPSET_OP1_AE(a,b,mergeop,x) (_WS_##a x (b)._WS_weapons)
+# define WEPSET_OP2_AE(a,b,mergeop,x,y) (_WS_##a x (b)._WS_weapons y _WS_##a)
+# define WEPSET_OP1_AA(a,b,mergeop,x) (_WS_##a x _WS_##b)
+# define WEPSET_OP2_AA(a,b,mergeop,x,y) (_WS_##a x _WS_##b y _WS_##a)
+# define WEPSET_OP1_AW(a,b,mergeop,x) (_WS_##a x WEPSET_BIT(b))
+# define WEPSET_OP2_AW(a,b,mergeop,x,y) (_WS_##a x WEPSET_BIT(b) y _WS_##a)
+#else
+# define WEP_MAXCOUNT 48
+# define WEP_FIRST2 25
+.float _WS1_weapons;
+.float _WS2_weapons;
+# define WEPSET_BIT1(a) (((a) < WEP_FIRST2) ? power2of((a) - WEP_FIRST) : 0)
+# define WEPSET_BIT2(a) (((a) >= WEP_FIRST2) ? power2of((a) - WEP_FIRST2) : 0)
+# define WEPSET_DECLARE_A(a) float _WS1_##a, _WS2_##a
+# define WEPSET_CLEAR_E(e) ((e)._WS1_weapons = (e)._WS2_weapons = 0)
+# define WEPSET_CLEAR_A(a) ((_WS1_##a) = (_WS2_##a) = 0)
+# define WEPSET_EMPTY_E(e) ((e)._WS1_weapons == 0 && (e)._WS2_weapons == 0)
+# define WEPSET_EMPTY_A(a) ((_WS1_##a) == 0 && (_WS2_##a) == 0)
+# define WEPSET_COPY_AS(a) ((_WS1_##a) = getstati(STAT_WEAPONS), (_WS2_##a) = getstati(STAT_WEAPONS2))
+# define WEPSET_ADDSTAT() addstat(STAT_WEAPONS, AS_INT, _WS1_weapons); addstat(STAT_WEAPONS2, AS_INT, _WS2_weapons)
+# define WEPSET_WRITE_E(dest,a) WriteInt24_t(dest, (a)._WS1_weapons); WriteInt24_t(dest, (a)._WS2_weapons)
+# define WEPSET_WRITE_A(dest,a) WriteInt24_t(dest, _WS1_##a); WriteInt24_t(dest, _WS2_##a)
+# define WEPSET_WRITE_W(dest,a) WriteInt24_t(dest, WEPSET_BIT1(a)); WriteInt24_t(dest, WEPSET_BIT2(a))
+# define WEPSET_READ_E(a) (a)._WS1_weapons = ReadInt24_t(); (a)._WS2_weapons = ReadInt24_t()
+# define WEPSET_READ_A(a) (_WS1_##a) = ReadInt24_t(); (_WS2_##a) = ReadInt24_t()
+# define WEPSET_OP1_EE(a,b,mergeop,x) (((a)._WS1_weapons x (b)._WS1_weapons) mergeop ((a)._WS2_weapons x (b)._WS2_weapons))
+# define WEPSET_OP2_EE(a,b,mergeop,x,y) (((a)._WS1_weapons x (b)._WS1_weapons y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x (b)._WS2_weapons y (a)._WS2_weapons))
+# define WEPSET_OP1_EA(a,b,mergeop,x) (((a)._WS1_weapons x _WS1_##b) mergeop ((a)._WS2_weapons x _WS2_##b))
+# define WEPSET_OP2_EA(a,b,mergeop,x,y) (((a)._WS1_weapons x _WS1_##b y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x _WS2_##b y (a)._WS2_weapons))
+# define WEPSET_OP1_EW(a,b,mergeop,x) (((a)._WS1_weapons x WEPSET_BIT1(b)) mergeop ((a)._WS2_weapons x WEPSET_BIT2(b)))
+# define WEPSET_OP2_EW(a,b,mergeop,x,y) (((a)._WS1_weapons x WEPSET_BIT1(b) y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x WEPSET_BIT2(b) y (a)._WS2_weapons))
+# define WEPSET_OP1_AE(a,b,mergeop,x) ((_WS1_##a x (b)._WS1_weapons) mergeop (_WS2_##a x (b)._WS2_weapons))
+# define WEPSET_OP2_AE(a,b,mergeop,x,y) ((_WS1_##a x (b)._WS1_weapons y _WS1_##a) mergeop (_WS2_##a x (b)._WS2_weapons y _WS2_##a))
+# define WEPSET_OP1_AA(a,b,mergeop,x) ((_WS1_##a x _WS1_##b) mergeop (_WS2_##a x _WS2_##b))
+# define WEPSET_OP2_AA(a,b,mergeop,x,y) ((_WS1_##a x _WS1_##b y _WS1_##a) mergeop (_WS2_##a x _WS2_##b y _WS2_##a))
+# define WEPSET_OP1_AW(a,b,mergeop,x) ((_WS1_##a x WEPSET_BIT1(b)) mergeop (_WS2_##a x WEPSET_BIT2(b)))
+# define WEPSET_OP2_AW(a,b,mergeop,x,y) ((_WS1_##a x WEPSET_BIT1(b) y _WS1_##a) mergeop (_WS2_##a x WEPSET_BIT2(b) y _WS2_##a))
+#endif
+
+#define XX ,
+
+#define WEPSET_COPY_EE(a,b) WEPSET_OP1_EE(a,b,XX,=)
+#define WEPSET_EQ_EE(a,b) WEPSET_OP1_EE(a,b,&&,==)
+#define WEPSET_OR_EE(a,b) WEPSET_OP1_EE(a,b,XX,|=)
+#define WEPSET_AND_EE(a,b) WEPSET_OP2_EE(a,b,XX,=,&)
+#define WEPSET_ANDNOT_EE(a,b) WEPSET_OP1_EE(a,b,XX,&~=)
+#define WEPSET_CONTAINS_ANY_EE(a,b) !!(WEPSET_OP1_EE(a,b,||,&))
+#define WEPSET_CONTAINS_ALL_EE(a,b) WEPSET_OP2_EE(b,a,&&,==,&)
+
+#define WEPSET_COPY_EA(a,b) WEPSET_OP1_EA(a,b,XX,=)
+#define WEPSET_EQ_EA(a,b) WEPSET_OP1_EA(a,b,&&,==)
+#define WEPSET_OR_EA(a,b) WEPSET_OP1_EA(a,b,XX,|=)
+#define WEPSET_AND_EA(a,b) WEPSET_OP2_EA(a,b,XX,=,&)
+#define WEPSET_ANDNOT_EA(a,b) WEPSET_OP1_EA(a,b,XX,&~=)
+#define WEPSET_CONTAINS_ANY_EA(a,b) !!(WEPSET_OP1_EA(a,b,||,&))
+#define WEPSET_CONTAINS_ALL_EA(a,b) WEPSET_OP2_EA(b,a,&&,==,&)
+
+#define WEPSET_COPY_EW(a,b) WEPSET_OP1_EW(a,b,XX,=)
+#define WEPSET_EQ_EW(a,b) WEPSET_OP1_EW(a,b,&&,==)
+#define WEPSET_OR_EW(a,b) WEPSET_OP1_EW(a,b,XX,|=)
+#define WEPSET_AND_EW(a,b) WEPSET_OP2_EW(a,b,XX,=,&)
+#define WEPSET_ANDNOT_EW(a,b) WEPSET_OP1_EW(a,b,XX,&~=)
+#define WEPSET_CONTAINS_EW(a,b) !!(WEPSET_OP1_EW(a,b,||,&))
+
+#define WEPSET_COPY_AE(a,b) WEPSET_OP1_AE(a,b,XX,=)
+#define WEPSET_EQ_AE(a,b) WEPSET_OP1_AE(a,b,&&,==)
+#define WEPSET_OR_AE(a,b) WEPSET_OP1_AE(a,b,XX,|=)
+#define WEPSET_AND_AE(a,b) WEPSET_OP2_AE(a,b,XX,=,&)
+#define WEPSET_ANDNOT_AE(a,b) WEPSET_OP1_AE(a,b,XX,&~=)
+#define WEPSET_CONTAINS_ANY_AE(a,b) !!(WEPSET_OP1_AE(a,b,||,&))
+#define WEPSET_CONTAINS_ALL_AE(a,b) WEPSET_OP2_AE(b,a,&&,==,&)
+
+#define WEPSET_COPY_AA(a,b) WEPSET_OP1_AA(a,b,XX,=)
+#define WEPSET_EQ_AA(a,b) WEPSET_OP1_AA(a,b,&&,==)
+#define WEPSET_OR_AA(a,b) WEPSET_OP1_AA(a,b,XX,|=)
+#define WEPSET_AND_AA(a,b) WEPSET_OP2_AA(a,b,XX,=,&)
+#define WEPSET_ANDNOT_AA(a,b) WEPSET_OP1_AA(a,b,XX,&~=)
+#define WEPSET_CONTAINS_ANY_AA(a,b) !!(WEPSET_OP1_AA(a,b,||,&))
+#define WEPSET_CONTAINS_ALL_AA(a,b) WEPSET_OP2_AA(b,a,&&,==,&)
+
+#define WEPSET_COPY_AW(a,b) WEPSET_OP1_AW(a,b,XX,=)
+#define WEPSET_EQ_AW(a,b) WEPSET_OP1_AW(a,b,&&,==)
+#define WEPSET_OR_AW(a,b) WEPSET_OP1_AW(a,b,XX,|=)
+#define WEPSET_AND_AW(a,b) WEPSET_OP2_AW(a,b,XX,=,&)
+#define WEPSET_ANDNOT_AW(a,b) WEPSET_OP1_AW(a,b,XX,&~=)
+#define WEPSET_CONTAINS_AW(a,b) !!(WEPSET_OP1_AW(a,b,||,&))
+
+WEPSET_DECLARE_A(WEPBIT_ALL);
+WEPSET_DECLARE_A(WEPBIT_SUPERWEAPONS);
+
+
+// =====================
+// Weapon Registration
+// =====================
+
+float w_null(float dummy);
+void register_weapon(float id, float(float) func, float ammotype, float i, float weapontype, float pickupbasevalue, string modelname, string shortname, string wname);
+void register_weapons_done();
+
+#define WEP_FIRST 1
+float WEP_COUNT;
+float WEP_LAST;
+
+// note: the fabs call is just there to hide "if result is constant" warning
+#define REGISTER_WEAPON_2(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
+ float id; \
+ float func(float); \
+ void RegisterWeapons_##id() \
+ { \
+ WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \
+ WEPSET_OR_AW(WEPBIT_ALL, id); \
+ if(fabs(weapontype & WEP_FLAG_SUPERWEAPON)) \
+ WEPSET_OR_AW(WEPBIT_SUPERWEAPONS, id); \
+ ++WEP_COUNT; \
+ register_weapon(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname); \
+ } \
+ ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)
+#ifdef MENUQC
+#define REGISTER_WEAPON(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
+ REGISTER_WEAPON_2(WEP_##id,w_null,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname)
+#else
+#define REGISTER_WEAPON(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
+ REGISTER_WEAPON_2(WEP_##id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname)
+#endif
+
+#include "all.qh"
+
+#undef REGISTER_WEAPON
+ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done)
+
+string W_FixWeaponOrder(string order, float complete);
+string W_NumberWeaponOrder(string order);
+string W_NameWeaponOrder(string order);
+string W_FixWeaponOrder_BuildImpulseList(string o);
+string W_FixWeaponOrder_AllowIncomplete(string order);
+string W_FixWeaponOrder_ForceComplete(string order);
+
+void W_RandomWeapons(entity e, float n);
+
+string W_Name(float weaponid);
+
+float W_AmmoItemCode(float wpn);
../common/constants.qh
../common/mapinfo.qh
../common/campaign_common.qh
-../common/items.qh
+../common/weapons/weapons.qh // TODO
../common/counting.qh
../common/command/markup.qh
../common/command/rpn.qh
../common/campaign_file.qc
../common/campaign_setup.qc
../common/mapinfo.qc
-../common/items.qc
+../common/weapons/weapons.qc // TODO
../common/urllib.qc
../warpzonelib/mathlib.qc
../common/teams.qh
../common/util.qh
../common/counting.qh
-../common/items.qh
-../common/explosion_equation.qh
+../common/weapons/weapons.qh // TODO
../common/urllib.qh
../common/command/markup.qh
../common/command/rpn.qh
command/sv_cmd.qh
accuracy.qh
-csqcprojectile.qh
+weapons/csqcprojectile.qh // TODO
../common/csqcmodel_settings.qh
../csqcmodellib/common.qh
../csqcmodellib/sv_model.qh
portals.qh
g_hook.qh
-weapons/w_electro.qh
-weapons/w_lightning.qh
+../common/weapons/electro.qh // TODO
+../common/weapons/arc.qh
scores.qh
item_key.qc
secret.qc
-weapons/cl_weaponsystem.qc
-weapons/w_common.qc
-
-weapons/w_all.qc
+weapons/main.qc
+weapons/common.qc
+weapons/csqcprojectile.qc // TODO
+../common/weapons/weapons.qc // TODO
t_items.qc
-weapons/cl_weapons.qc
+weapons/cl_weapons.qc // TODO
cl_impulse.qc
ent_cs.qc
func_breakable.qc
target_music.qc
-../common/items.qc
-
accuracy.qc
../csqcmodellib/sv_model.qc
-csqcprojectile.qc
playerdemo.qc
round_handler.qc
-../common/explosion_equation.qc
-
mutators/base.qc
mutators/gamemode_assault.qc
mutators/gamemode_arena.qc