]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/weapons/all.qh
e00b38c0154df658bf3284c401583cb2e411198b
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / weapons / all.qh
1 #ifndef WEAPONS_ALL_H
2 #define WEAPONS_ALL_H
3
4 #ifndef MENUQC
5 #include "calculations.qh"
6 #endif
7
8 #include "../util.qh"
9 #ifdef SVQC
10 #include "../../server/bot/aim.qh"
11 #endif
12 const int MAX_SHOT_DISTANCE = 32768;
13
14 // weapon pickup ratings for bot logic
15 const int BOT_PICKUP_RATING_LOW  =  2500;
16 const int BOT_PICKUP_RATING_MID  =  5000;
17 const int BOT_PICKUP_RATING_HIGH = 10000;
18
19 // weapon flags
20 const int WEP_TYPE_OTHER          =  0x00; // not for damaging people
21 const int WEP_TYPE_SPLASH         =  0x01; // splash damage
22 const int WEP_TYPE_HITSCAN        =  0x02; // hitscan
23 const int WEP_TYPEMASK            =  0x0F;
24 const int WEP_FLAG_CANCLIMB       =  0x10; // can be used for movement
25 const int WEP_FLAG_NORMAL         =  0x20; // in "most weapons" set
26 const int WEP_FLAG_HIDDEN         =  0x40; // hides from menu
27 const int WEP_FLAG_RELOADABLE     =  0x80; // can has reload
28 const int WEP_FLAG_SUPERWEAPON    = 0x100; // powerup timer
29 const int WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag)
30
31 // weapon requests
32 const int WR_SETUP          =  1; // (SERVER) setup weapon data
33 const int WR_THINK          =  2; // (SERVER) logic to run every frame
34 const int WR_CHECKAMMO1     =  3; // (SERVER) checks ammo for weapon primary
35 const int WR_CHECKAMMO2     =  4; // (SERVER) checks ammo for weapon second
36 const int WR_AIM            =  5; // (SERVER) runs bot aiming code for this weapon
37 const int WR_INIT           =  6; // (BOTH)   precaches models/sounds used by this weapon, also sets up weapon properties
38 const int WR_SUICIDEMESSAGE =  7; // (SERVER) notification number for suicide message (may inspect w_deathtype for details)
39 const int WR_KILLMESSAGE    =  8; // (SERVER) notification number for kill message (may inspect w_deathtype for details)
40 const int WR_RELOAD         =  9; // (SERVER) handles reloading for weapon
41 const int WR_RESETPLAYER    = 10; // (SERVER) clears fields that the weapon may use
42 const int WR_IMPACTEFFECT   = 11; // (CLIENT) impact effect for weapon explosion
43 const int WR_PLAYERDEATH    = 12; // (SERVER) called whenever a player dies
44 const int WR_GONETHINK      = 13; // (SERVER) logic to run when weapon is lost
45 const int WR_CONFIG         = 14; // (ALL)    dump weapon cvars to config in data directory (see: sv_cmd dumpweapons)
46 const int WR_ZOOMRETICLE    = 15; // (CLIENT) weapon specific zoom reticle
47 const int WR_DROP           = 16; // (SERVER) the weapon is dropped
48 const int WR_PICKUP         = 17; // (SERVER) a weapon is picked up
49
50 // variables:
51 string weaponorder_byid;
52
53 // weapon sets
54 typedef vector WepSet;
55 WepSet WepSet_FromWeapon(int a);
56 #ifdef SVQC
57 void WepSet_AddStat();
58 void WepSet_AddStat_InMap();
59 void WriteWepSet(float dest, WepSet w);
60 #endif
61 #ifdef CSQC
62 WepSet WepSet_GetFromStat();
63 WepSet WepSet_GetFromStat_InMap();
64 WepSet ReadWepSet();
65 #endif
66
67 // weapon name macros
68 const int WEP_FIRST = 1;
69 #define WEP_MAXCOUNT 24 // Increase as needed. Can be up to three times as much.
70 int WEP_COUNT;
71 #define WEP_LAST (WEP_FIRST + WEP_COUNT - 1)
72 WepSet WEPSET_ALL;
73 WepSet WEPSET_SUPERWEAPONS;
74
75 // functions:
76 entity get_weaponinfo(int id);
77 string W_FixWeaponOrder(string order, float complete);
78 string W_UndeprecateName(string s);
79 string W_NameWeaponOrder(string order);
80 string W_NumberWeaponOrder(string order);
81 string W_FixWeaponOrder_BuildImpulseList(string o);
82 string W_FixWeaponOrder_AllowIncomplete(string order);
83 string W_FixWeaponOrder_ForceComplete(string order);
84 void W_RandomWeapons(entity e, float n);
85
86 string GetAmmoPicture(.int ammotype);
87
88 #ifdef CSQC
89 .int GetAmmoFieldFromNum(int i);
90 int GetAmmoStat(.int ammotype);
91 #endif
92
93 #ifdef SVQC
94 string W_Sound(string w_snd);
95 string W_Model(string w_mdl);
96 #endif
97
98 // ammo types
99 .int ammo_shells;
100 .int ammo_nails;
101 .int ammo_rockets;
102 .int ammo_cells;
103 .int ammo_plasma;
104 .int ammo_fuel;
105 .int ammo_none;
106
107 // other useful macros
108 #define WEP_ACTION(wpn,wrequest) (get_weaponinfo(wpn)).weapon_func(wrequest)
109 #define WEP_AMMO(wpn) (WEP_##wpn.ammo_field) // only used inside weapon files/with direct name, don't duplicate prefix
110 #define WEP_NAME(wpn) ((get_weaponinfo(wpn)).message)
111
112
113 // ======================
114 //  Configuration Macros
115 // ======================
116
117 // create cvars for weapon settings
118 #define WEP_ADD_CVAR_NONE(wepname,name) [[last]] float autocvar_g_balance_##wepname##_##name;
119
120 #define WEP_ADD_CVAR_PRI(wepname,name) WEP_ADD_CVAR_NONE(wepname, primary_##name)
121 #define WEP_ADD_CVAR_SEC(wepname,name) WEP_ADD_CVAR_NONE(wepname, secondary_##name)
122 #define WEP_ADD_CVAR_BOTH(wepname,name) \
123         WEP_ADD_CVAR_PRI(wepname, name) \
124         WEP_ADD_CVAR_SEC(wepname, name)
125
126 #define WEP_ADD_CVAR(wepid,wepname,mode,name) WEP_ADD_CVAR_##mode(wepname, name)
127
128 // create properties for weapon settings
129 #define WEP_ADD_PROP(wepid,wepname,type,prop,name) \
130         .type prop; \
131         [[last]] type autocvar_g_balance_##wepname##_##name;
132
133 // read cvars from weapon settings
134 #define WEP_CVAR(wepname,name) autocvar_g_balance_##wepname##_##name
135 #define WEP_CVAR_PRI(wepname,name) WEP_CVAR(wepname, primary_##name)
136 #define WEP_CVAR_SEC(wepname,name) WEP_CVAR(wepname, secondary_##name)
137 #define WEP_CVAR_BOTH(wepname,isprimary,name) ((isprimary) ? WEP_CVAR_PRI(wepname, name) : WEP_CVAR_SEC(wepname, name))
138
139 // set initialization values for weapon settings
140 #define WEP_SKIP_CVAR(unuseda,unusedb,unusedc,unusedd) /* skip cvars */
141 #define WEP_SET_PROP(wepid,wepname,type,prop,name) WEP_##wepid.prop = autocvar_g_balance_##wepname##_##name;
142
143
144 // =====================
145 //  Weapon Registration
146 // =====================
147
148 bool w_null(int) { return false; }
149
150 /** fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A" */
151 CLASS(Weapon, Object)
152         ATTRIB(Weapon, m_id, int, 0)
153     /**
154      * M: WEP_id    : WEP_...
155      * you can recognize dummies when this == 0
156      */
157     ATTRIB(Weapon, weapon, int, 0);
158     /** A: WEPSET_id : WEPSET_... */
159     ATTRIB(Weapon, weapons, WepSet, '0 0 0');
160     /** M: function  : w_... */
161     ATTRIB(Weapon, weapon_func, bool(int), w_null);
162     /** M: ammotype  : main ammo field */
163     ATTRIB(Weapon, ammo_field, .int, ammo_none);
164     /** M: impulse   : weapon impulse */
165     ATTRIB(Weapon, impulse, int, -1);
166     /** M: flags     : WEPSPAWNFLAG_... combined */
167     ATTRIB(Weapon, spawnflags, int, 0);
168     /** M: rating    : bot weapon priority */
169     ATTRIB(Weapon, bot_pickupbasevalue, float, 0);
170     /** M: color     : waypointsprite color */
171     ATTRIB(Weapon, wpcolor, vector, '0 0 0');
172     /** A: wpn-id    : wpn- sprite name */
173     ATTRIB(Weapon, wpmodel, string, "");
174     /** M: modelname : name of model (without g_ v_ or h_ prefixes) */
175     ATTRIB(Weapon, mdl, string, "");
176     /** A: modelname : full path to g_ model */
177     ATTRIB(Weapon, model, string, "");
178     /** M: simplemdl : simpleitems weapon model/image */
179     ATTRIB(Weapon, w_simplemdl, string, "foobar");
180     /** M: crosshair : per-weapon crosshair: "CrosshairImage Size" */
181     ATTRIB(Weapon, w_crosshair, string, "gfx/crosshair1");
182     /** A: crosshair : per-weapon crosshair size (argument two of "crosshair" field) */
183     ATTRIB(Weapon, w_crosshair_size, float, 1);
184     /** M: wepimg    : "weaponfoobar" side view image file of weapon. WEAPONTODO: Move out of skin files, move to common files */
185     ATTRIB(Weapon, model2, string, "");
186     /** M: refname   : reference name name */
187     ATTRIB(Weapon, netname, string, "");
188     /** M: wepname   : human readable name */
189     ATTRIB(Weapon, message, string, "AOL CD Thrower");
190
191         METHOD(Weapon, display, void(entity this, void(string name, string icon) returns)) {
192                 returns(this.message, this.model2 ? sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.model2) : string_null);
193         }
194
195         CONSTRUCTOR(Weapon,
196                 bool(int) function,
197                 .int ammotype,
198                 int i,
199                 int weapontype,
200                 float pickupbasevalue,
201                 vector clr,
202                 string modelname,
203                 string simplemdl,
204                 string crosshair,
205                 string wepimg,
206                 string refname,
207                 string wepname
208         ) {
209                 CONSTRUCT(Weapon);
210                 this.weapon_func = function;
211                 this.ammo_field = ammotype;
212                 this.impulse = i;
213                 this.spawnflags = weapontype;
214                 this.bot_pickupbasevalue = pickupbasevalue;
215                 this.wpcolor = clr;
216                 this.mdl = modelname;
217                 #ifdef SVQC
218                 this.model = strzone(W_Model(strcat("g_", modelname, ".md3")));
219                 #elif defined(CSQC)
220                 this.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
221                 #endif
222                 this.w_simplemdl = strzone(simplemdl); // simpleitems weapon model/image
223                 this.w_crosshair = strzone(car(crosshair));
224                 string s = cdr(crosshair);
225                 this.w_crosshair_size = ((s != "") ? stof(s) : 1); // so that we can scale the crosshair from code (for compat)
226                 this.model2 = strzone(wepimg);
227                 this.netname = refname;
228                 this.message = wepname;
229         }
230         void register_weapon(entity this, int id, WepSet bit)
231         {
232                 this.classname = "weapon_info";
233                 this.weapon = id;
234                 this.weapons = bit;
235                 this.wpmodel = strzone(strcat("wpn-", ftos(id)));
236                 #ifdef CSQC
237                 this.weapon_func(WR_INIT);
238                 #endif
239         }
240 ENDCLASS(Weapon)
241
242 void RegisterWeapons();
243 REGISTER_REGISTRY(RegisterWeapons)
244 entity weapon_info[WEP_MAXCOUNT], weapon_info_first, weapon_info_last;
245 entity dummy_weapon_info;
246
247 #define _REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
248         WepSet WEPSET_##id; \
249         REGISTER(RegisterWeapons, WEP, weapon_info, WEP_COUNT, id, m_id, \
250                 NEW(Weapon, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
251         ) { \
252                 this.m_id++; \
253                 WEPSET_ALL |= (WEPSET_##id = WepSet_FromWeapon(this.m_id)); \
254                 if ((flags) & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= WEPSET_##id; \
255                 register_weapon(this, this.m_id, WEPSET_##id); \
256         }
257
258 #ifndef MENUQC
259         #define REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
260         bool function(int); \
261         _REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname)
262 #else
263         #define REGISTER_WEAPON(id, function, ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname) \
264                 _REGISTER_WEAPON(id, w_null,   ammotype, impulse, flags, rating, color, modelname, simplemdl, crosshair, wepimg, refname, wepname)
265 #endif
266
267 #include "all.inc"
268
269 #undef WEP_ADD_CVAR_MO_PRI
270 #undef WEP_ADD_CVAR_MO_SEC
271 #undef WEP_ADD_CVAR_MO_BOTH
272 #undef WEP_ADD_CVAR_MO_NONE
273 #undef WEP_ADD_CVAR
274 #undef WEP_ADD_PROP
275 void register_weapons_done();
276 ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done);
277 #endif