Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
selection.qh File Reference
Include dependency graph for selection.qh:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define w_getbestweapon(ent, wepent)

Functions

bool client_hasweapon (entity this, Weapon wpn,.entity weaponentity, float andammo, bool complain)
void Send_WeaponComplain (entity e, float wpn, float type)
void W_CycleWeapon (entity this, string weaponorder, float dir,.entity weaponentity)
float W_GetCycleWeapon (entity this, string weaponorder, float dir, float imp, bool complain, bool skipmissing,.entity weaponentity)
void W_LastWeapon (entity this,.entity weaponentity)
void W_NextWeapon (entity this, float list,.entity weaponentity)
void W_NextWeaponOnImpulse (entity this, float imp,.entity weaponentity)
void W_PreviousWeapon (entity this, float list,.entity weaponentity)
void W_SwitchToOtherWeapon (entity this,.entity weaponentity)
bool W_SwitchWeapon (entity this, Weapon imp,.entity weaponentity)
void W_SwitchWeapon_Force (Player this, Weapon w,.entity weaponentity)
void W_SwitchWeapon_TryOthers (entity this, Weapon imp,.entity weaponentity)

Variables

int autocvar_g_showweaponspawns
bool autocvar_g_weaponswitch_debug
bool autocvar_g_weaponswitch_debug_alternate
WepSet dual_weapons
float hasweapon_complain_spam
int selectweapon
int weaponcomplainindex

Macro Definition Documentation

◆ w_getbestweapon

#define w_getbestweapon ( ent,
wepent )

Function Documentation

◆ client_hasweapon()

bool client_hasweapon ( entity this,
Weapon wpn,
.entity weaponentity,
float andammo,
bool complain )

Definition at line 48 of file selection.qc.

49{
50 float f = 0;
51
53 complain = 0;
54
55 // ignore hook button when using other offhand equipment
56 if (this.offhand != OFFHAND_HOOK)
57 if (wpn == WEP_HOOK && !((STAT(WEAPONS, this) | weaponsInMap) & WepSet_FromWeapon(wpn)))
58 complain = 0;
59
60 if (complain)
61 CS(this).hasweapon_complain_spam = time + 0.2;
62
63 if (wpn == WEP_Null)
64 {
65 if (complain)
66 sprint(this, "Invalid weapon\n");
67 return false;
68 }
69 if (autocvar_g_weaponswitch_debug == 2 && weaponslot(weaponentity) > 0 && !(wpn.spawnflags & WEP_FLAG_DUALWIELD) && !(PS(this).dual_weapons & wpn.m_wepset))
70 return false; // no complaints needed
71 if (STAT(WEAPONS, this) & WepSet_FromWeapon(wpn))
72 {
73 if (andammo)
74 {
75 if(this.items & IT_UNLIMITED_AMMO)
76 {
77 f = 1;
78 }
79 else
80 {
81 f = wpn.wr_checkammo1(wpn, this, weaponentity) + wpn.wr_checkammo2(wpn, this, weaponentity);
82
83 // always allow selecting the Mine Layer if we placed mines, so that we can detonate them
84 if(wpn == WEP_MINE_LAYER)
85 IL_EACH(g_mines, it.owner == this && it.weaponentity_fld == weaponentity,
86 {
87 f = 1;
88 break; // no need to continue
89 });
90 }
91 if (!f)
92 {
93 if (complain)
94 if(IS_REAL_CLIENT(this))
95 {
96 play2(this, SND(UNAVAILABLE));
97 Send_WeaponComplain (this, wpn.m_id, 0);
98 }
99 return false;
100 }
101 }
102 return true;
103 }
104 if (complain)
105 if(IS_REAL_CLIENT(this))
106 {
107 // DRESK - 3/16/07
108 // Report Proper Weapon Status / Modified Weapon Ownership Message
110 {
111 Send_WeaponComplain(this, wpn.m_id, 1);
113 Weapon_whereis(wpn, this);
114 else
115 {
116 FOREACH(Weapons, it.impulse == wpn.impulse,
117 {
118 Weapon_whereis(it, this);
119 });
120 }
121 }
122 else
123 {
124 Send_WeaponComplain (this, wpn.m_id, 2);
125 }
126
127 play2(this, SND(UNAVAILABLE));
128 }
129 return false;
130}
int impulse
M: impulse : weapon impulse.
Definition weapon.qh:53
int m_id
Definition weapon.qh:45
virtual void wr_checkammo2()
(SERVER) checks ammo for weapon second
Definition weapon.qh:94
int spawnflags
M: flags : WEPSPAWNFLAG_... combined.
Definition weapon.qh:55
virtual void wr_checkammo1()
(SERVER) checks ammo for weapon primary
Definition weapon.qh:92
const int IT_UNLIMITED_AMMO
Definition item.qh:23
int items
Definition player.qh:227
vector weaponsInMap
all the weapons actually spawned in the map, does not include filtered items
Definition stats.qh:53
OffhandHook OFFHAND_HOOK
Definition hook.qh:80
float time
#define IL_EACH(this, cond, body)
#define FOREACH(list, cond, body)
Definition iter.qh:19
#define STAT(...)
Definition stats.qh:82
void sprint(float clientnum, string text,...)
IntrusiveList g_mines
Definition minelayer.qh:83
void Send_WeaponComplain(entity e, float wpn, float type)
Definition selection.qc:18
void Weapon_whereis(Weapon this, entity cl)
Definition selection.qc:26
WepSet dual_weapons
Definition selection.qh:12
bool autocvar_g_weaponswitch_debug
Definition selection.qh:7
float hasweapon_complain_spam
Definition selection.qh:17
int autocvar_g_showweaponspawns
Definition selection.qh:6
void play2(entity e, string filename)
Definition all.qc:116
#define SND(id)
Definition all.qh:35
#define PS(this)
Definition state.qh:18
ClientState CS(Client this)
Definition state.qh:47
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define WepSet_FromWeapon(it)
Definition all.qh:46
const int WEP_FLAG_DUALWIELD
Definition weapon.qh:222
OffhandWeapon offhand
Definition weapon.qh:199
int weaponslot(.entity weaponentity)
Definition weapon.qh:19

References autocvar_g_showweaponspawns, autocvar_g_weaponswitch_debug, CS(), dual_weapons, entity(), FOREACH, g_mines, hasweapon_complain_spam, IL_EACH, Weapon::impulse, IS_REAL_CLIENT, IT_UNLIMITED_AMMO, items, Weapon::m_id, offhand, OFFHAND_HOOK, play2(), PS, Send_WeaponComplain(), SND, Weapon::spawnflags, sprint(), STAT, time, Weapon_whereis(), Weapons, weaponsInMap, weaponslot(), WEP_FLAG_DUALWIELD, WepSet_FromWeapon, Weapon::wr_checkammo1(), and Weapon::wr_checkammo2().

Referenced by bot_cmd_select_weapon(), GiveItems(), havocbot_chooseweapon(), havocbot_movetogoal(), Item_GiveTo(), NIX_GiveCurrentWeapon(), REGISTER_MUTATOR(), W_LastWeapon(), and W_SwitchWeapon().

◆ Send_WeaponComplain()

void Send_WeaponComplain ( entity e,
float wpn,
float type )

Definition at line 18 of file selection.qc.

19{
20 msg_entity = e;
21 WriteHeader(MSG_ONE, TE_CSQC_WEAPONCOMPLAIN);
22 WriteByte(MSG_ONE, wpn);
23 WriteByte(MSG_ONE, type);
24}
#define WriteHeader(to, id)
Definition net.qh:221
float MSG_ONE
Definition menudefs.qc:56
void WriteByte(float data, float dest, float desto)
entity msg_entity
Definition progsdefs.qc:63

References entity(), msg_entity, MSG_ONE, WriteByte(), and WriteHeader.

Referenced by client_hasweapon().

◆ W_CycleWeapon()

void W_CycleWeapon ( entity this,
string weaponorder,
float dir,
.entity weaponentity )

Definition at line 305 of file selection.qc.

306{
307 float w;
308 w = W_GetCycleWeapon(this, weaponorder, dir, -1, true, true, weaponentity);
309 if(w > 0)
310 W_SwitchWeapon(this, REGISTRY_GET(Weapons, w), weaponentity);
311}
bool W_SwitchWeapon(entity this, Weapon w,.entity weaponentity)
Definition selection.qc:275
int dir
Definition impulse.qc:89
entity weaponorder[REGISTRY_MAX(Weapons)]
Definition weapons.qc:81

References dir, entity(), REGISTRY_GET, W_GetCycleWeapon(), W_SwitchWeapon(), weaponorder, and Weapons.

Referenced by for(), W_NextWeapon(), and W_PreviousWeapon().

◆ W_GetCycleWeapon()

float W_GetCycleWeapon ( entity this,
string weaponorder,
float dir,
float imp,
bool complain,
bool skipmissing,
.entity weaponentity )

Definition at line 132 of file selection.qc.

133{
134 // We cannot tokenize in this function, as GiveItems calls this
135 // function. Thus we must use car/cdr.
136 float weaponwant, first_valid, prev_valid, switchtonext, switchtolast;
137 switchtonext = switchtolast = 0;
138 first_valid = prev_valid = 0;
139 float weaponcur;
140 entity wep;
141 string rest;
142
143 if(skipmissing || this.(weaponentity).selectweapon == 0)
144 weaponcur = this.(weaponentity).m_switchweapon.m_id;
145 else
146 weaponcur = this.(weaponentity).selectweapon;
147
148 if(dir == 0)
149 switchtonext = 1;
150
151 // complain-specific vars
152 int c = 0;
153 entity wepcomplain = NULL;
154 int wepcomplainindex = 0;
155 bool have_other = false;
156
157 // see if we have or can locate (not hidden), some other weapon in the group
158 WepSet customgroup = '0 0 0';
159 if(imp < 0) // custom cl_weaponpriorityN group
160 {
161 // These groups are client-specific, and (imp == -1) here,
162 // so generate a weapon set bitmask to represent the group.
163 rest = weaponorder;
164 while(rest != "")
165 {
166 weaponwant = stof(car(rest)); rest = cdr(rest);
167 customgroup |= REGISTRY_GET(Weapons, weaponwant).m_wepset;
168 }
169 }
170 else {} // standard weapon_group, defined by impulse sharing
171 FOREACH(Weapons, (imp >= 0 && it.impulse == imp) || (imp < 0 && (it.m_wepset & customgroup)),
172 {
173 if ((it.m_wepset & STAT(WEAPONS, this))
174 || ((it.m_wepset & weaponsInMap) && !(it.spawnflags & WEP_FLAG_HIDDEN)))
175 {
176 have_other = true;
177 break;
178 }
179 });
180
181 rest = weaponorder;
182 while(rest != "")
183 {
184 weaponwant = stof(car(rest)); rest = cdr(rest);
185 wep = REGISTRY_GET(Weapons, weaponwant);
186 if(imp >= 0)
187 if(wep.impulse != imp)
188 continue;
189
190 // skip weapons we don't own that aren't normal and aren't in the map
191 if(!(STAT(WEAPONS, this) & wep.m_wepset))
192 {
193 if(wep.spawnflags & WEP_FLAG_HIDDEN)
194 continue;
195
196 if(!(weaponsInMap & wep.m_wepset))
197 if((wep.spawnflags & WEP_FLAG_MUTATORBLOCKED) || have_other)
198 continue;
199 }
200
201 if(complain)
202 {
203 if(!wepcomplain || this.weaponcomplainindex == c)
204 {
205 wepcomplain = wep;
206 wepcomplainindex = c;
207 }
208 ++c;
209 }
210
211 if(!skipmissing || client_hasweapon(this, wep, weaponentity, true, false))
212 {
213 if(switchtonext)
214 return weaponwant;
215 if(!first_valid)
216 first_valid = weaponwant;
217 if(weaponwant == weaponcur)
218 {
219 if(dir >= 0)
220 switchtonext = 1;
221 else if(prev_valid)
222 return prev_valid;
223 else
224 switchtolast = 1;
225 }
226 prev_valid = weaponwant;
227 }
228 }
229 if(first_valid)
230 {
231 if(switchtolast)
232 return prev_valid;
233 else
234 return first_valid;
235 }
236
237 // complain (but only for one weapon on the button that has been pressed)
238 if(wepcomplain)
239 {
240 this.weaponcomplainindex = wepcomplainindex + 1;
241 client_hasweapon(this, wepcomplain, weaponentity, true, true);
242 }
243 return 0;
244}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float stof(string val,...)
#define NULL
Definition post.qh:14
bool client_hasweapon(entity this, Weapon wpn,.entity weaponentity, float andammo, bool complain)
Definition selection.qc:48
int weaponcomplainindex
Definition selection.qh:20
int selectweapon
Definition selection.qh:10
int int int imp
Definition impulse.qc:90
ERASEABLE string car(string s)
returns first word
Definition string.qh:259
ERASEABLE string cdr(string s)
returns all but first word
Definition string.qh:268
const int WEP_FLAG_MUTATORBLOCKED
Definition weapon.qh:219
vector WepSet
Definition weapon.qh:14
const int WEP_FLAG_HIDDEN
Definition weapon.qh:216
Weapon m_switchweapon
Definition wepent.qh:25

References car(), cdr(), dir, entity(), FOREACH, imp, m_switchweapon, NULL, REGISTRY_GET, selectweapon, stof(), weaponorder, and Weapons.

Referenced by W_CycleWeapon(), and W_NextWeaponOnImpulse().

◆ W_LastWeapon()

void W_LastWeapon ( entity this,
.entity weaponentity )

Definition at line 344 of file selection.qc.

345{
346 Weapon wep = REGISTRY_GET(Weapons, this.(weaponentity).cnt);
347 if (client_hasweapon(this, wep, weaponentity, true, false))
348 W_SwitchWeapon(this, wep, weaponentity);
349 else
350 W_SwitchToOtherWeapon(this, weaponentity);
351}
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:44
float cnt
Definition powerups.qc:24
void W_SwitchToOtherWeapon(entity this,.entity weaponentity)
Definition selection.qc:256

References client_hasweapon(), cnt, entity(), REGISTRY_GET, W_SwitchToOtherWeapon(), W_SwitchWeapon(), and Weapons.

Referenced by IMPULSE().

◆ W_NextWeapon()

void W_NextWeapon ( entity this,
float list,
.entity weaponentity )

References entity().

◆ W_NextWeaponOnImpulse()

void W_NextWeaponOnImpulse ( entity this,
float imp,
.entity weaponentity )

Definition at line 313 of file selection.qc.

314{
315 float w;
316 w = W_GetCycleWeapon(this, CS_CVAR(this).cvar_cl_weaponpriority, +1, imp, true, (CS_CVAR(this).cvar_cl_weaponimpulsemode == 0), weaponentity);
317 if(w > 0)
318 W_SwitchWeapon(this, REGISTRY_GET(Weapons, w), weaponentity);
319}

References CS_CVAR, entity(), imp, REGISTRY_GET, W_GetCycleWeapon(), W_SwitchWeapon(), and Weapons.

Referenced by W_SwitchWeapon_TryOthers(), and weapon_group_handle().

◆ W_PreviousWeapon()

void W_PreviousWeapon ( entity this,
float list,
.entity weaponentity )

Definition at line 333 of file selection.qc.

334{
335 if(list == 0)
336 W_CycleWeapon(this, weaponorder_byid, +1, weaponentity);
337 else if(list == 1)
338 W_CycleWeapon(this, CS_CVAR(this).weaponorder_byimpulse, +1, weaponentity);
339 else if(list == 2)
340 W_CycleWeapon(this, CS_CVAR(this).cvar_cl_weaponpriority, +1, weaponentity);
341}
void W_CycleWeapon(entity this, string weaponorder, float dir,.entity weaponentity)
Definition selection.qc:305
string weaponorder_byimpulse
Definition client.qh:62
string weaponorder_byid
Definition weapon.qh:230

References CS_CVAR, entity(), W_CycleWeapon(), weaponorder_byid, and weaponorder_byimpulse.

Referenced by IMPULSE(), IMPULSE(), and IMPULSE().

◆ W_SwitchToOtherWeapon()

void W_SwitchToOtherWeapon ( entity this,
.entity weaponentity )

Definition at line 256 of file selection.qc.

257{
258 // hack to ensure it switches to an OTHER weapon (in case the other fire mode still has ammo, we want that anyway)
259 Weapon ww;
260 WepSet set = WepSet_FromWeapon(this.(weaponentity).m_weapon);
261 if (STAT(WEAPONS, this) & set)
262 {
263 STAT(WEAPONS, this) &= ~set;
264 ww = w_getbestweapon(this, weaponentity);
265 STAT(WEAPONS, this) |= set;
266 }
267 else
268 {
269 ww = w_getbestweapon(this, weaponentity);
270 }
271 if (ww == WEP_Null) return;
272 W_SwitchWeapon_Force(this, ww, weaponentity);
273}
void W_SwitchWeapon_Force(Player this, Weapon wep,.entity weaponentity)
Definition selection.qc:246
#define w_getbestweapon(ent, wepent)
Definition selection.qh:23
Weapon m_weapon
Definition wepent.qh:26

References entity(), m_weapon, STAT, w_getbestweapon, W_SwitchWeapon_Force(), and WepSet_FromWeapon.

Referenced by W_Arc_Beam_Think(), W_Hagar_Attack2_Load(), W_LastWeapon(), W_Reload(), and weapon_prepareattack_checkammo().

◆ W_SwitchWeapon()

bool W_SwitchWeapon ( entity this,
Weapon imp,
.entity weaponentity )

Definition at line 275 of file selection.qc.

276{
277 if(this.(weaponentity).m_switchweapon != w)
278 {
279 if(client_hasweapon(this, w, weaponentity, true, true))
280 {
281 W_SwitchWeapon_Force(this, w, weaponentity);
282 return true;
283 }
284 else
285 {
286 this.(weaponentity).selectweapon = w.m_id; // update selectweapon anyway
287 return false;
288 }
289 }
290 else if(!weaponLocked(this) && CS_CVAR(this).cvar_cl_weapon_switch_reload)
291 {
292 entity actor = this;
293 w.wr_reload(w, actor, weaponentity);
294 }
295
296 return true; // player already has the weapon out or needs to reload
297}
bool weaponLocked(entity player)

References client_hasweapon(), CS_CVAR, entity(), Weapon::m_id, m_switchweapon, selectweapon, W_SwitchWeapon_Force(), weaponLocked(), and Weapon::wr_reload().

Referenced by GiveBall(), IMPULSE(), MUTATOR_HOOKFUNCTION(), NIX_GiveCurrentWeapon(), W_CycleWeapon(), W_LastWeapon(), W_NextWeaponOnImpulse(), W_SwitchWeapon_TryOthers(), and W_WeaponFrame().

◆ W_SwitchWeapon_Force()

void W_SwitchWeapon_Force ( Player this,
Weapon w,
.entity weaponentity )

Definition at line 246 of file selection.qc.

247{
248 TC(Weapon, wep);
249 entity w_ent = this.(weaponentity);
250 w_ent.cnt = w_ent.m_switchweapon.m_id;
251 w_ent.m_switchweapon = wep;
252 w_ent.selectweapon = wep.m_id;
253}
#define TC(T, sym)
Definition _all.inc:82

Referenced by W_SwitchToOtherWeapon(), and W_SwitchWeapon().

◆ W_SwitchWeapon_TryOthers()

void W_SwitchWeapon_TryOthers ( entity this,
Weapon imp,
.entity weaponentity )

Definition at line 299 of file selection.qc.

300{
301 if(!W_SwitchWeapon(this, w, weaponentity) && CS_CVAR(this).cvar_cl_weapon_switch_fallback_to_impulse)
302 W_NextWeaponOnImpulse(this, w.impulse, weaponentity);
303}
void W_NextWeaponOnImpulse(entity this, float imp,.entity weaponentity)
Definition selection.qc:313

References CS_CVAR, entity(), Weapon::impulse, W_NextWeaponOnImpulse(), and W_SwitchWeapon().

Referenced by weapon_byid_handle().

Variable Documentation

◆ autocvar_g_showweaponspawns

int autocvar_g_showweaponspawns

Definition at line 6 of file selection.qh.

Referenced by client_hasweapon(), and Weapon_whereis().

◆ autocvar_g_weaponswitch_debug

◆ autocvar_g_weaponswitch_debug_alternate

bool autocvar_g_weaponswitch_debug_alternate

Definition at line 8 of file selection.qh.

Referenced by weapon_prepareattack_do().

◆ dual_weapons

WepSet dual_weapons

Definition at line 12 of file selection.qh.

Referenced by client_hasweapon().

◆ hasweapon_complain_spam

float hasweapon_complain_spam

Definition at line 17 of file selection.qh.

Referenced by client_hasweapon().

◆ selectweapon

int selectweapon

Definition at line 10 of file selection.qh.

Referenced by W_GetCycleWeapon(), and W_SwitchWeapon().

◆ weaponcomplainindex

int weaponcomplainindex

Definition at line 20 of file selection.qh.