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