]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/weapons/weapons.qh
commit message goes here
[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 modelname,
142         string crosshair,
143         string shortname,
144         string wname);
145
146 void register_weapons_done();
147
148 // entity properties of weaponinfo:
149 // fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A"
150 .float weapon;              // M: WEP_id     // WEP_...
151 .WepSet weapons;            // A: WEPSET_id  // WEPSET_...
152 .float(float) weapon_func;  // M: function   // w_...
153 ..float ammo_field;         // M: ammotype   // main ammo field
154 .float impulse;             // M: impulse    // weapon impulse
155 .float spawnflags;          // M: flags      // WEPSPAWNFLAG_... combined
156 .float bot_pickupbasevalue; // M: rating     // bot weapon priority
157 .vector wpcolor;            // M: color      // waypointsprite color
158 .string model2;             // A: wpn-id     // wpn- sprite name
159 .string mdl;                // M: model      // modelname without g_, v_, w_
160 .string model;              // A: model      // full name of g_ model
161 .string w_crosshair;        // M: crosshair  // per-weapon crosshair: "CrosshairImage Size"
162 .float w_crosshair_size;    // A: crosshair  // per-weapon crosshair size (argument two of "crosshair" field)
163 .string netname;            // M: refname    // reference name name
164 .string message;            // M: wepname    // human readable name
165
166
167 // note: the fabs call is just there to hide "if result is constant" warning
168 #define REGISTER_WEAPON_2(id,bit,function,ammotype,impulse,flags,rating,color,model,crosshair,refname,wepname) \
169         float id; \
170         WepSet bit; \
171         float function(float); \
172         void RegisterWeapons_##id() \
173         { \
174                 WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \
175                 bit = WepSet_FromWeapon(id); \
176                 WEPSET_ALL |= bit; \
177                 if((flags) & WEP_FLAG_SUPERWEAPON) \
178                         WEPSET_SUPERWEAPONS |= bit; \
179                 ++WEP_COUNT; \
180                 register_weapon(id,bit,function,ammotype,impulse,flags,rating,color,model,crosshair,refname,wepname); \
181         } \
182         ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)
183 #ifdef MENUQC
184 #define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,model,crosshair,refname,wepname) \
185         REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,w_null,ammotype,impulse,flags,rating,color,model,crosshair,refname,wepname)
186 #else
187 #define REGISTER_WEAPON(id,function,ammotype,impulse,flags,rating,color,model,crosshair,refname,wepname) \
188         REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,function,ammotype,impulse,flags,rating,color,model,crosshair,refname,wepname)
189 #endif
190
191 #include "all.qh"
192
193 #undef WEP_ADD_CVAR_MO_PRI
194 #undef WEP_ADD_CVAR_MO_SEC
195 #undef WEP_ADD_CVAR_MO_BOTH
196 #undef WEP_ADD_CVAR_MO_NONE
197 #undef WEP_ADD_CVAR
198 #undef WEP_ADD_PROP
199 #undef REGISTER_WEAPON
200
201 ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done);