]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/weapons/weapons.qh
Merge branch 'samual/weapons' into Mario/weapons
[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_plasma;
87 .float ammo_fuel;
88 .float ammo_none;
89
90 // other useful macros
91 #define WEP_ACTION(wpn,wrequest) (get_weaponinfo(wpn)).weapon_func(wrequest)
92 #define WEP_AMMO(wpn) ((get_weaponinfo(WEP_##wpn)).ammo_field) // only used inside weapon files/with direct name, don't duplicate prefix
93 #define WEP_NAME(wpn) ((get_weaponinfo(wpn)).message)
94
95
96 // ======================
97 //  Configuration Macros
98 // ======================
99
100 // create cvars for weapon settings
101 #define WEP_ADD_CVAR_NONE(wepname,name) [[last]] float autocvar_g_balance_##wepname##_##name;
102
103 #define WEP_ADD_CVAR_PRI(wepname,name) WEP_ADD_CVAR_NONE(wepname, primary_##name)
104 #define WEP_ADD_CVAR_SEC(wepname,name) WEP_ADD_CVAR_NONE(wepname, secondary_##name)
105 #define WEP_ADD_CVAR_BOTH(wepname,name) \
106         WEP_ADD_CVAR_PRI(wepname, name) \
107         WEP_ADD_CVAR_SEC(wepname, name)
108
109 #define WEP_ADD_CVAR(wepid,wepname,mode,name) WEP_ADD_CVAR_##mode(wepname, name)
110
111 // create properties for weapon settings
112 #define WEP_ADD_PROP(wepid,wepname,type,prop,name) \
113         .type prop; \
114         [[last]] type autocvar_g_balance_##wepname##_##name;
115
116 // read cvars from weapon settings
117 #define WEP_CVAR(wepname,name) autocvar_g_balance_##wepname##_##name
118 #define WEP_CVAR_PRI(wepname,name) WEP_CVAR(wepname, primary_##name)
119 #define WEP_CVAR_SEC(wepname,name) WEP_CVAR(wepname, secondary_##name)
120 #define WEP_CVAR_BOTH(wepname,isprimary,name) ((isprimary) ? WEP_CVAR_PRI(wepname, name) : WEP_CVAR_SEC(wepname, name))
121
122 // set initialization values for weapon settings
123 #define WEP_SKIP_CVAR(unuseda,unusedb,unusedc,unusedd) /* skip cvars */
124 #define WEP_SET_PROP(wepid,wepname,type,prop,name) get_weaponinfo(WEP_##wepid).##prop = autocvar_g_balance_##wepname##_##name;
125
126
127 // =====================
128 //  Weapon Registration
129 // =====================
130
131 float w_null(float dummy);
132
133 void register_weapon(
134         float id,
135         WepSet bit,
136         float(float) func,
137         .float ammotype,
138         float i,
139         float weapontype,
140         float pickupbasevalue,
141         vector clr,
142         string modelname,
143         string simplemdl,
144         string crosshair,
145         string wepimg,
146         string refname,
147         string wepname);
148
149 void register_weapons_done();
150
151 // entity properties of weaponinfo:
152 // fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A"
153 .float weapon;              // M: WEP_id    // WEP_...
154 .WepSet weapons;            // A: WEPSET_id // WEPSET_...
155 .float(float) weapon_func;  // M: function  // w_...
156 ..float ammo_field;         // M: ammotype  // main ammo field
157 .float impulse;             // M: impulse   // weapon impulse
158 .float spawnflags;          // M: flags     // WEPSPAWNFLAG_... combined
159 .float bot_pickupbasevalue; // M: rating    // bot weapon priority
160 .vector wpcolor;            // M: color     // waypointsprite color
161 .string wpmodel;            // A: wpn-id    // wpn- sprite name
162 .string mdl;                // M: modelname // name of model (without g_ v_ or h_ prefixes)
163 .string model;              // A: modelname // full path to g_ model
164 .string w_simplemdl;        // M: simplemdl // simpleitems weapon model/image
165 .string w_crosshair;        // M: crosshair // per-weapon crosshair: "CrosshairImage Size"
166 .float w_crosshair_size;    // A: crosshair // per-weapon crosshair size (argument two of "crosshair" field)
167 .string model2;             // M: wepimg    // "weaponfoobar" side view image file of weapon // WEAPONTODO: Move out of skin files, move to common files
168 .string netname;            // M: refname   // reference name name
169 .string message;            // M: wepname   // human readable name
170
171
172 // note: the fabs call is just there to hide "if result is constant" warning
173 #define REGISTER_WEAPON_2(id,bit,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
174         float id; \
175         WepSet bit; \
176         float function(float); \
177         void RegisterWeapons_##id() \
178         { \
179                 WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \
180                 bit = WepSet_FromWeapon(id); \
181                 WEPSET_ALL |= bit; \
182                 if((flags) & WEP_FLAG_SUPERWEAPON) \
183                         WEPSET_SUPERWEAPONS |= bit; \
184                 ++WEP_COUNT; \
185                 register_weapon(id,bit,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname); \
186         } \
187         ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)
188 #ifdef MENUQC
189 #define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
190         REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,w_null,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname)
191 #else
192 #define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname) \
193         REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,function,ammotype,impulse,flags,rating,color,modelname,simplemdl,crosshair,wepimg,refname,wepname)
194 #endif
195
196 #include "all.qh"
197
198 #undef WEP_ADD_CVAR_MO_PRI
199 #undef WEP_ADD_CVAR_MO_SEC
200 #undef WEP_ADD_CVAR_MO_BOTH
201 #undef WEP_ADD_CVAR_MO_NONE
202 #undef WEP_ADD_CVAR
203 #undef WEP_ADD_PROP
204 #undef REGISTER_WEAPON
205
206 ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done);