]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/weapons/weapons.qh
825a03e2ac81131e635e9d37e0b43f6fbeb342ad
[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_SWITCHABLE     = 12; // (CLIENT) decides whether the player is able to switch away from this weapon
37 const float WR_PLAYERDEATH    = 13; // (SERVER) called whenever a player dies
38 const float WR_GONETHINK      = 14; // (SERVER) logic to run when weapon is lost/switched away from
39 const float WR_CONFIG         = 15; // (ALL)    dump weapon cvars to config in data directory (see: sv_cmd dumpweapons)
40 const float WR_ZOOMRETICLE    = 16; // (CLIENT) weapon specific zoom reticle
41
42 // variables:
43 string weaponorder_byid;
44
45 // weapon sets
46 typedef vector WepSet;
47 WepSet WepSet_FromWeapon(float a);
48 #ifdef SVQC
49 void WepSet_AddStat();
50 void WriteWepSet(float dest, WepSet w);
51 #endif
52 #ifdef CSQC
53 WepSet WepSet_GetFromStat();
54 WepSet ReadWepSet();
55 #endif
56
57 // weapon name macros
58 #define WEP_FIRST 1
59 #define WEP_MAXCOUNT 24 // Increase as needed. Can be up to three times as much.
60 float WEP_COUNT;
61 float WEP_LAST;
62 WepSet WEPSET_ALL;
63 WepSet WEPSET_SUPERWEAPONS;
64
65 // functions:
66 entity get_weaponinfo(float id);
67 string W_FixWeaponOrder(string order, float complete);
68 string W_NameWeaponOrder(string order);
69 string W_NumberWeaponOrder(string order);
70 string W_FixWeaponOrder_BuildImpulseList(string o);
71 string W_FixWeaponOrder_AllowIncomplete(string order);
72 string W_FixWeaponOrder_ForceComplete(string order);
73 void W_RandomWeapons(entity e, float n);
74
75 #ifdef CSQC
76 .float GetAmmoFieldFromNum(float i);
77 string GetAmmoPicture(.float ammotype);
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 firstmodel,
142         string thirdmodel,
143         string pickupmodel,
144         string simplemodel,
145         string crosshair,
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 model;              // M: firstmodel  // first person view weapon model (h_)
163 .string model2;             // M: thirdmodel  // third person weapon model (v_)
164 .string model3;             // M: pickupmodel // pickup weapon model (g_)
165 .string mdl;                // M: simplemodel // simpleitems weapon model/image
166 .string w_crosshair;        // M: crosshair  // per-weapon crosshair: "CrosshairImage Size"
167 .float w_crosshair_size;    // A: crosshair  // per-weapon crosshair size (argument two of "crosshair" field)
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,model,crosshair,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,model,crosshair,refname,wepname); \
186         } \
187         ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)
188 #ifdef MENUQC
189 #define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,model,crosshair,refname,wepname) \
190         REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,w_null,ammotype,impulse,flags,rating,color,model,crosshair,refname,wepname)
191 #else
192 #define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,model,crosshair,refname,wepname) \
193         REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,function,ammotype,impulse,flags,rating,color,model,crosshair,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);