]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/weapons/weapons.qh
f05ae184f805a428f6b92eb1ed7301feeea17fd5
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / weapons / weapons.qh
1 #ifndef MENUQC
2 #include "calculations.qh"
3 #endif
4
5 const float MAX_SHOT_DISTANCE = 32768;
6
7 // weapon pickup ratings for bot logic
8 const float BOT_PICKUP_RATING_LOW  =  2500;
9 const float BOT_PICKUP_RATING_MID  =  5000;
10 const float BOT_PICKUP_RATING_HIGH = 10000;
11
12 // weapon flags
13 const float WEP_TYPE_OTHER          =  0x00; // not for damaging people
14 const float WEP_TYPE_SPLASH         =  0x01; // splash damage
15 const float WEP_TYPE_HITSCAN        =  0x02; // hitscan
16 const float WEP_TYPEMASK            =  0x0F;
17 const float WEP_FLAG_CANCLIMB       =  0x10; // can be used for movement
18 const float WEP_FLAG_NORMAL         =  0x20; // in "most weapons" set
19 const float WEP_FLAG_HIDDEN         =  0x40; // hides from menu
20 const float WEP_FLAG_RELOADABLE     =  0x80; // can has reload
21 const float WEP_FLAG_SUPERWEAPON    = 0x100; // powerup timer
22 const float WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag)
23
24 // weapon requests
25 const float WR_SETUP          =  1; // (SERVER) setup weapon data
26 const float WR_THINK          =  2; // (SERVER) logic to run every frame
27 const float WR_CHECKAMMO1     =  3; // (SERVER) checks ammo for weapon primary
28 const float WR_CHECKAMMO2     =  4; // (SERVER) checks ammo for weapon second
29 const float WR_AIM            =  5; // (SERVER) runs bot aiming code for this weapon
30 const float WR_INIT           =  6; // (BOTH)   precaches models/sounds used by this weapon, also sets up weapon properties
31 const float WR_SUICIDEMESSAGE =  7; // (SERVER) notification number for suicide message (may inspect w_deathtype for details)
32 const float WR_KILLMESSAGE    =  8; // (SERVER) notification number for kill message (may inspect w_deathtype for details)
33 const float WR_RELOAD         =  9; // (SERVER) handles reloading for weapon
34 const float WR_RESETPLAYER    = 10; // (SERVER) clears fields that the weapon may use
35 const float WR_IMPACTEFFECT   = 11; // (CLIENT) impact effect for weapon explosion
36 const float WR_PLAYERDEATH    = 12; // (SERVER) called whenever a player dies
37 const float WR_GONETHINK      = 13; // (SERVER) logic to run when weapon is lost
38 const float WR_CONFIG         = 14; // (ALL)    dump weapon cvars to config in data directory (see: sv_cmd dumpweapons)
39 const float WR_ZOOMRETICLE    = 15; // (CLIENT) weapon specific zoom reticle
40
41 // variables:
42 string weaponorder_byid;
43
44 // weapon sets
45 typedef vector WepSet;
46 WepSet WepSet_FromWeapon(float a);
47 #ifdef SVQC
48 void WepSet_AddStat();
49 void WriteWepSet(float dest, WepSet w);
50 #endif
51 #ifdef CSQC
52 WepSet WepSet_GetFromStat();
53 WepSet ReadWepSet();
54 #endif
55
56 // weapon name macros
57 #define WEP_FIRST 1
58 #define WEP_MAXCOUNT 24 // Increase as needed. Can be up to three times as much.
59 float WEP_COUNT;
60 float WEP_LAST;
61 WepSet WEPSET_ALL;
62 WepSet WEPSET_SUPERWEAPONS;
63
64 // functions:
65 entity get_weaponinfo(float id);
66 string W_FixWeaponOrder(string order, float complete);
67 string W_NameWeaponOrder(string order);
68 string W_NumberWeaponOrder(string order);
69 string W_FixWeaponOrder_BuildImpulseList(string o);
70 string W_FixWeaponOrder_AllowIncomplete(string order);
71 string W_FixWeaponOrder_ForceComplete(string order);
72 void W_RandomWeapons(entity e, float n);
73
74 string GetAmmoPicture(.float ammotype);
75
76 #ifdef CSQC
77 .float GetAmmoFieldFromNum(float i);
78 float GetAmmoStat(.float ammotype);
79 #endif
80
81 // ammo types
82 .float ammo_shells;
83 .float ammo_nails;
84 .float ammo_rockets;
85 .float ammo_cells;
86 .float ammo_fuel;
87 .float ammo_none;
88
89 // other useful macros
90 #define WEP_ACTION(wpn,wrequest) (get_weaponinfo(wpn)).weapon_func(wrequest)
91 #define WEP_AMMO(wpn) ((get_weaponinfo(WEP_##wpn)).ammo_field) // only used inside weapon files/with direct name, don't duplicate prefix
92 #define WEP_NAME(wpn) ((get_weaponinfo(wpn)).message)
93
94
95 // ======================
96 //  Configuration Macros
97 // ======================
98
99 // create cvars for weapon settings
100 #define WEP_ADD_CVAR_NONE(wepname,name) [[last]] float autocvar_g_balance_##wepname##_##name;
101
102 #define WEP_ADD_CVAR_PRI(wepname,name) WEP_ADD_CVAR_NONE(wepname, primary_##name)
103 #define WEP_ADD_CVAR_SEC(wepname,name) WEP_ADD_CVAR_NONE(wepname, secondary_##name)
104 #define WEP_ADD_CVAR_BOTH(wepname,name) \
105         WEP_ADD_CVAR_PRI(wepname, name) \
106         WEP_ADD_CVAR_SEC(wepname, name)
107
108 #define WEP_ADD_CVAR(wepid,wepname,mode,name) WEP_ADD_CVAR_##mode(wepname, name)
109
110 // create properties for weapon settings
111 #define WEP_ADD_PROP(wepid,wepname,type,prop,name) \
112         .type ##prop; \
113         [[last]] type autocvar_g_balance_##wepname##_##name;
114
115 // read cvars from weapon settings
116 #define WEP_CVAR(wepname,name) autocvar_g_balance_##wepname##_##name
117 #define WEP_CVAR_PRI(wepname,name) WEP_CVAR(wepname, primary_##name)
118 #define WEP_CVAR_SEC(wepname,name) WEP_CVAR(wepname, secondary_##name)
119 #define WEP_CVAR_BOTH(wepname,isprimary,name) ((isprimary) ? WEP_CVAR_PRI(wepname, name) : WEP_CVAR_SEC(wepname, name))
120
121 // set initialization values for weapon settings
122 #define WEP_SKIP_CVAR(unuseda,unusedb,unusedc,unusedd) /* skip cvars */
123 #define WEP_SET_PROP(wepid,wepname,type,prop,name) get_weaponinfo(WEP_##wepid).##prop = autocvar_g_balance_##wepname##_##name;
124
125
126 // =====================
127 //  Weapon Registration
128 // =====================
129
130 float w_null(float dummy);
131
132 void register_weapon(
133         float id,
134         WepSet bit,
135         float(float) func,
136         .float ammotype,
137         float i,
138         float weapontype,
139         float pickupbasevalue,
140         vector clr,
141         string modelname,
142         string simplemdl,
143         string crosshair,
144         string wepimg,
145         string refname,
146         string wepname);
147
148 void register_weapons_done();
149
150 // entity properties of weaponinfo:
151 // fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A"
152 .float weapon;              // M: WEP_id    // WEP_...
153 .WepSet weapons;            // A: WEPSET_id // WEPSET_...
154 .float(float) weapon_func;  // M: function  // w_...
155 ..float ammo_field;         // M: ammotype  // main ammo field
156 .float impulse;             // M: impulse   // weapon impulse
157 .float spawnflags;          // M: flags     // WEPSPAWNFLAG_... combined
158 .float bot_pickupbasevalue; // M: rating    // bot weapon priority
159 .vector wpcolor;            // M: color     // waypointsprite color
160 .string wpmodel;            // A: wpn-id    // wpn- sprite name
161 .string mdl;                // M: modelname // name of model (without g_ v_ or h_ prefixes)
162 .string model;              // A: modelname // full path to g_ model
163 .string w_simplemdl;        // M: simplemdl // simpleitems weapon model/image
164 .string w_crosshair;        // M: crosshair // per-weapon crosshair: "CrosshairImage Size"
165 .float w_crosshair_size;    // A: crosshair // per-weapon crosshair size (argument two of "crosshair" field)
166 .string model2;             // M: wepimg    // "weaponfoobar" side view image file of weapon // WEAPONTODO: Move out of skin files, move to common files
167 .string netname;            // M: refname   // reference name name
168 .string message;            // M: wepname   // human readable name
169
170
171 // note: the fabs call is just there to hide "if result is constant" warning
172 #define REGISTER_WEAPON_2(id,bit,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
173         float id; \
174         WepSet bit; \
175         float function(float); \
176         void RegisterWeapons_##id() \
177         { \
178                 WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \
179                 bit = WepSet_FromWeapon(id); \
180                 WEPSET_ALL |= bit; \
181                 if((flags) & WEP_FLAG_SUPERWEAPON) \
182                         WEPSET_SUPERWEAPONS |= bit; \
183                 ++WEP_COUNT; \
184                 register_weapon(id,bit,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname); \
185         } \
186         ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)
187 #ifdef MENUQC
188 #define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
189         REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,w_null,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname)
190 #else
191 #define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
192         REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname)
193 #endif
194
195 #include "all.qh"
196
197 #undef WEP_ADD_CVAR_MO_PRI
198 #undef WEP_ADD_CVAR_MO_SEC
199 #undef WEP_ADD_CVAR_MO_BOTH
200 #undef WEP_ADD_CVAR_MO_NONE
201 #undef WEP_ADD_CVAR
202 #undef WEP_ADD_PROP
203 #undef REGISTER_WEAPON
204
205 ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done);