Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
all.qc
Go to the documentation of this file.
1#include "all.qh"
2#ifndef WEAPONS_ALL_C
3#define WEAPONS_ALL_C
4
5#if defined(CSQC)
6 #include <client/main.qh>
7 #include <common/constants.qh>
10 #include <common/stats.qh>
11 #include <common/util.qh>
17 #include <lib/warpzone/client.qh>
18 #include <lib/warpzone/common.qh>
19#elif defined(MENUQC)
21#elif defined(SVQC)
22 #include <common/constants.qh>
24 #include <common/items/_mod.qh>
25 #include <common/mapinfo.qh>
28 #include <common/stats.qh>
29 #include <common/teams.qh>
30 #include <common/util.qh>
37 #include <lib/warpzone/common.qh>
38 #include <lib/warpzone/server.qh>
40 #include <server/command/_mod.qh>
41 #include <server/hook.qh>
44 #include <server/portals.qh>
48#endif
49
50
51// WEAPON PLUGIN SYSTEM
52
54{
55 a -= WEP_FIRST;
56 if (REGISTRY_MAX(Weapons) > 24 && a >= 24)
57 {
58 a -= 24;
59 if (REGISTRY_MAX(Weapons) > 48 && a >= 24)
60 {
61 a -= 24;
62 return '0 0 1' * BIT(a);
63 }
64 return '0 1 0' * BIT(a);
65 }
66 return '1 0 0' * BIT(a);
67}
68#ifdef SVQC
69void WriteWepSet(float dst, WepSet w)
70{
71 if (REGISTRY_MAX(Weapons) > 48)
72 WriteInt72_t(dst, w);
73 else if (REGISTRY_MAX(Weapons) > 24)
74 WriteInt48_t(dst, w);
75 else
76 WriteInt24_t(dst, w.x);
77}
78#endif
79#ifdef CSQC
81{
82 if (REGISTRY_MAX(Weapons) > 48)
83 return ReadInt72_t();
84 if (REGISTRY_MAX(Weapons) > 24)
85 return ReadInt48_t();
86 return vec3(ReadInt24_t(), 0, 0);
87}
88#endif
89
91{
92 int i = stof(s);
93 if (s == "0" || i)
94 {
96 if (wi != WEP_Null)
97 return wi.netname;
98 }
99 return s;
100}
101
103{
104 if (s == "0" || stof(s))
105 return s;
106 FOREACH(Weapons, it != WEP_Null && (it.netname == s || it.m_deprecated_netname == s), return ftos(i));
107 return s;
108}
109
119{
121 Weapon e1 = REGISTRY_GET(Weapons, si);
123 Weapon e2 = REGISTRY_GET(Weapons, sj);
124 int d = (e1.impulse + 9) % 10 - (e2.impulse + 9) % 10;
125 if (d)
126 return -d; // high impulse first!
128 return strstrofs(s, sprintf(" %d ", si), 0)
129 - strstrofs(s, sprintf(" %d ", sj), 0); // low char index first!
130}
144
145string W_FixWeaponOrder_AllowIncomplete(entity this, string order)
146{
147 return W_FixWeaponOrder(order, 0);
148}
149
151{
152 if (order == "")
153 order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
154 return W_FixWeaponOrder(order, 1);
155}
156
158{
159 WepSet result = '0 0 0';
160 for (int j = 0; j < n; ++j)
161 {
163 FOREACH(Weapons, it != WEP_Null,
164 {
165 if (remaining & (it.m_wepset))
166 RandomSelection_AddEnt(it, 1, 1);
167 });
170 remaining &= ~WepSet_FromWeapon(w);
171 }
172 return result;
173}
174
176{
177 FOREACH(Items, it.netname == ammotype.netname, return it);
178 LOG_WARNF("Invalid ammo type %d ", ammotype.m_id);
179 return NULL;
180}
181
183{
184 FOREACH(Resources, it.netname == ammotype.netname, return it);
185 LOG_WARNF("Invalid ammo type %d ", ammotype.m_id);
186 return NULL;
187}
188
189#ifdef CSQC
191{
192 // TODO: handle networking via resources
193 switch (ammotype)
194 {
195 case RES_SHELLS: return STAT_SHELLS;
196 case RES_BULLETS: return STAT_NAILS;
197 case RES_ROCKETS: return STAT_ROCKETS;
198 case RES_CELLS: return STAT_CELLS;
199 case RES_FUEL: return STAT_FUEL.m_id;
200 default: return -1;
201 }
202}
203#endif
204
205string W_Sound(string w_snd)
206{
207 string output = strcat("weapons/", w_snd);
208 MUTATOR_CALLHOOK(WeaponSound, w_snd, output);
209 return M_ARGV(1, string);
210}
211
212string W_Model(string w_mdl)
213{
214 string output = strcat("models/weapons/", w_mdl);
215 MUTATOR_CALLHOOK(WeaponModel, w_mdl, output);
216 return M_ARGV(1, string);
217}
218
219#ifdef GAMEQC
220vector shotorg_adjustfromclient(vector vecs, float y_is_right, float algn)
221{
222 switch (algn)
223 {
224 default:
225 case 3: // right alignment
226 break;
227 case 4: // left
228 vecs.y = -vecs.y;
229 break;
230 case 1: // center
231 case 2: // center
232 vecs.y = 0;
233 vecs.z -= 2;
234 break;
235 }
236 return vecs;
237}
238
239vector shotorg_adjust(vector vecs, bool y_is_right, bool visual, int algn)
240{
241 string s;
242 if (visual)
243 vecs = shotorg_adjustfromclient(vecs, y_is_right, algn);
244 else if (STAT(SHOOTFROMEYE))
245 vecs.y = vecs.z = 0;
246 else if (STAT(SHOOTFROMCENTER))
247 {
248 vecs.y = 0;
249 vecs.z -= 2;
250 }
251 else if ((s = G_SHOOTFROMFIXEDORIGIN) != "")
252 {
253 vector v = stov(s);
254 if (y_is_right)
255 v.y = -v.y;
256 if (v.x != 0)
257 vecs.x = v.x;
258 vecs.y = v.y;
259 vecs.z = v.z;
260 }
261 else // just do the same as top
262 vecs = shotorg_adjustfromclient(vecs, y_is_right, algn);
263
264 return vecs;
265}
266
267
320void CL_WeaponEntity_SetModel(entity this, string name, bool _anim)
321{
322 if (name == "")
323 {
324 vector oldmin = this.mins;
325 vector oldmax = this.maxs;
326 setmodel(this, MDL_Null);
327 setsize(this, oldmin, oldmax);
328 if (this.weaponchild)
329 delete(this.weaponchild);
330 this.weaponchild = NULL;
331 this.movedir = '0 0 0';
332#ifdef SVQC
333 this.spawnorigin = '0 0 0';
334#endif
335 this.oldorigin = '0 0 0';
336 this.anim_fire1 = '0 1 0.01';
337 this.anim_fire2 = '0 1 0.01';
338 this.anim_idle = '0 1 0.01';
339 this.anim_reload = '0 1 0.01';
340 }
341 else
342 {
343 // if there is a child entity, hide it until we're sure we use it
344 if (this.weaponchild)
345 this.weaponchild.model = "";
346 _setmodel(this, W_Model(strcat("v_", name, ".md3")));
347 int v_shot_idx;
348 (v_shot_idx = gettagindex(this, "shot")) || (v_shot_idx = gettagindex(this, "tag_shot"));
349
350 _setmodel(this, W_Model(strcat("h_", name, ".iqm")));
351 // preset some defaults that work great for renamed zym files (which don't need an animinfo)
352 this.anim_fire1 = animfixfps(this, '0 1 0.01', '0 0 0');
353 this.anim_fire2 = animfixfps(this, '1 1 0.01', '0 0 0');
354 this.anim_idle = animfixfps(this, '2 1 0.01', '0 0 0');
355 this.anim_reload = animfixfps(this, '3 1 0.01', '0 0 0');
356
357 // if we have a "weapon" tag, let's attach the v_ model to it ("invisible hand" style model)
358 // if we don't, this is a "real" animated model
359 string t;
360 if ((t = "weapon", gettagindex(this, t)) || (t = "tag_weapon", gettagindex(this, t)))
361 {
362 if (!this.weaponchild)
363 {
364 this.weaponchild = new(weaponchild);
365#ifdef CSQC
366 this.weaponchild.drawmask = MASK_NORMAL;
367 this.weaponchild.renderflags |= RF_VIEWMODEL;
368#endif
369 }
370 _setmodel(this.weaponchild, W_Model(strcat("v_", name, ".md3")));
371 setsize(this.weaponchild, '0 0 0', '0 0 0');
372 setattachment(this.weaponchild, this, t);
373 }
374 else
375 {
376 if (this.weaponchild)
377 delete(this.weaponchild);
378 this.weaponchild = NULL;
379 }
380
381 setsize(this, '0 0 0', '0 0 0');
382 setorigin(this, '0 0 0');
383 this.angles = '0 0 0';
384 this.frame = 0;
385#ifdef SVQC
387#else
389#endif
390 if (v_shot_idx) // v_ model attached to invisible h_ model
391 this.movedir = gettaginfo(this.weaponchild, v_shot_idx);
392 else
393 {
394 int idx;
395 if ((idx = gettagindex(this, "shot")) || (idx = gettagindex(this, "tag_shot")))
396 this.movedir = gettaginfo(this, idx);
397 else
398 {
399 LOG_WARNF("weapon model %s does not support the 'shot' tag, will display shots TOTALLY wrong",
400 this.model);
401 this.movedir = '0 0 0';
402 }
403 }
404#ifdef SVQC
405 {
406 int idx = 0;
407 // v_ model attached to invisible h_ model
408 if (this.weaponchild
409 && ((idx = gettagindex(this.weaponchild, "shell")) || (idx = gettagindex(this.weaponchild, "tag_shell"))))
410 this.spawnorigin = gettaginfo(this.weaponchild, idx);
411 else if ((idx = gettagindex(this, "shell")) || (idx = gettagindex(this, "tag_shell")))
412 this.spawnorigin = gettaginfo(this, idx);
413 else
414 {
415 LOG_WARNF("weapon model %s does not support the 'shell' tag, will display casings wrong",
416 this.model);
417 this.spawnorigin = this.movedir;
418 }
419 }
420#endif
421 if (v_shot_idx)
422 this.oldorigin = '0 0 0'; // use regular attachment
423 else
424 {
425 int idx;
426 if (this.weaponchild)
427 (idx = gettagindex(this, "weapon")) || (idx = gettagindex(this, "tag_weapon"));
428 else
429 (idx = gettagindex(this, "handle")) || (idx = gettagindex(this, "tag_handle"));
430 if (idx)
431 this.oldorigin = this.movedir - gettaginfo(this, idx);
432 else
433 {
434 LOG_WARNF(
435 "weapon model %s does not support the 'handle' tag "
436 "and neither does the v_ model support the 'shot' tag, "
437 "will display muzzle flashes TOTALLY wrong\n",
438 this.model);
439 this.oldorigin = '0 0 0'; // there is no way to recover from this
440 }
441 }
442
443#ifdef SVQC
444 this.viewmodelforclient = this.owner;
445#else
447#endif
448 }
449
450 this.view_ofs = '0 0 0';
451 this.movedir_aligned = this.movedir;
452
453 if (this.movedir.x >= 0)
454 {
455 //int algn = STAT(GUNALIGN, this.owner);
456 int algn = W_GunAlign(this, STAT(GUNALIGN, this.owner));
457 #ifdef SVQC
458 this.m_gunalign = algn;
459 #endif
460 vector v = this.movedir;
461 this.movedir = shotorg_adjust(v, false, false, algn);
462 this.movedir_aligned = shotorg_adjust(v, false, true, algn);
463 this.view_ofs = this.movedir_aligned - v;
464 }
465
466 // shotorg_adjust can give negative .x from shootfromfixedorigin
467 // recheck .x here due to it
468 if (this.movedir.x >= 0)
469 {
470 int compressed_shotorg = compressShotOrigin(this.movedir);
471 // make them match perfectly
472 #ifdef SVQC
473 // null during init
474 if (this.owner)
475 STAT(SHOTORG, this.owner) = compressed_shotorg;
476 #endif
477 this.movedir = decompressShotOrigin(compressed_shotorg);
478 }
479 else
480 {
481 // don't support negative x shotorgs
482 this.movedir = '0 0 0';
483
484 // reset _aligned here too even though as a side effect
485 // g_shootfromfixedorigin can make it reset
486 // it'd be only slightly better if it was checked individually
487 this.movedir_aligned = '0 0 0';
488
489 #ifdef SVQC
490 // null during init
491 if (this.owner)
492 STAT(SHOTORG, this.owner) = 0;
493 #endif
494 }
495
496#ifdef SVQC
497 this.spawnorigin += this.view_ofs; // offset the casings origin by the same amount
498#endif
499
500 // check if an instant weapon switch occurred
501 setorigin(this, this.view_ofs);
502 if (!_anim)
503 return;
504 // reset animstate now
505 this.wframe = WFRAME_IDLE;
506 setanim(this, this.anim_idle, true, false, true);
507}
508#endif
509
510#ifdef GAMEQC
511
513#ifdef CSQC
514NET_HANDLE(wframe, bool isNew)
515{
516 WFRAME fr = ReadByte();
517 float t = ReadFloat();
518 int slot = ReadByte();
519 bool restartanim = ReadByte();
520 entity wepent = viewmodels[slot];
521 if (fr == WFRAME_IDLE)
522 wepent.animstate_looping = false; // we don't need to enforce idle animation
523 else
524 {
525 vector a = '0 0 0';
526 switch (fr)
527 {
528 default:
529 case WFRAME_IDLE: a = wepent.anim_idle; break;
530 case WFRAME_FIRE1: a = wepent.anim_fire1; break;
531 case WFRAME_FIRE2: a = wepent.anim_fire2; break;
532 case WFRAME_RELOAD: a = wepent.anim_reload; break;
533 }
534 a.z *= t;
535 anim_set(wepent, a, !restartanim, restartanim, restartanim);
536 }
537 wepent.state = ReadByte();
538 wepent.weapon_nextthink = ReadFloat();
539 switch (wepent.state)
540 {
541 case WS_RAISE:
542 wepent.weapon_switchdelay = wepent.switchweapon.switchdelay_raise;
543 break;
544 case WS_DROP:
545 wepent.weapon_switchdelay = wepent.activeweapon.switchdelay_drop;
546 break;
547 default:
548 wepent.weapon_switchdelay = 0;
549 break;
550 }
551 return true;
552}
553#endif
554
555#ifdef SVQC
556void wframe_send(entity actor, entity weaponentity, int wepframe, float attackrate, bool restartanim)
557{
558 if (!IS_REAL_CLIENT(actor))
559 return;
560 int channel = MSG_ONE;
561 msg_entity = actor;
562 WriteHeader(channel, wframe);
563 WriteByte(channel, wepframe);
564 WriteFloat(channel, attackrate);
565 WriteByte(channel, weaponslot(weaponentity.weaponentity_fld));
566 WriteByte(channel, restartanim);
567 WriteByte(channel, weaponentity.state);
568 WriteFloat(channel, weaponentity.weapon_nextthink);
569}
570#endif
571
572REGISTER_NET_C2S(w_whereis)
573#ifdef SVQC
574void Weapon_whereis(Weapon this, entity cl);
575NET_HANDLE(w_whereis, bool)
576{
578 if (wpn != WEP_Null)
579 Weapon_whereis(wpn, sender);
580 return true;
581}
582#else
583void w_whereis(Weapon this)
584{
585 int channel = MSG_C2S;
586 WriteHeader(channel, w_whereis);
587 WriteRegistered(Weapons, channel, this);
588}
589CLIENT_COMMAND(weapon_find, "Show spawn locations of a weapon")
590{
591 switch (request)
592 {
594 {
595 string s = argv(1);
596 if (s == "all")
597 {
598 FOREACH(Weapons, it != WEP_Null, w_whereis(it));
599 return;
600 }
601 if (s == "unowned")
602 {
603 FOREACH(Weapons, it != WEP_Null && !(STAT(WEAPONS) & it.m_wepset), w_whereis(it));
604 return;
605 }
606 FOREACH(Weapons, it != WEP_Null && it.netname == s,
607 {
608 w_whereis(it);
609 return;
610 });
611 }
612 default:
613 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
615 LOG_HELP("Usage:^3 cl_cmd weapon_find <weapon>");
616 LOG_HELP(" Where <weapon> is the lowercase weapon name, 'all' or 'unowned'.");
617 return;
618 }
619}
620#endif
621
622#ifdef SVQC
623void W_MuzzleFlash_Model_AttachToShotorg(entity actor, .entity weaponentity, entity flash, vector offset)
624{
625 flash.owner = actor;
626 flash.angles.z = random() * 360;
627
628 entity view = actor.(weaponentity);
629 entity exterior = actor.exteriorweaponentity;
630
631 if (view.oldorigin.x > 0)
632 {
633 setattachment(flash, exterior, "");
634 setorigin(flash, view.oldorigin + offset);
635 }
636 else
637 {
638 setattachment(flash, exterior, (gettagindex(exterior, "shot") ? "shot" : "tag_shot"));
639 setorigin(flash, offset);
640 }
641}
642#elif defined(CSQC)
644{
645 flash.owner = wepent;
646 flash.angles.z = random() * 360;
647
648 setattachment(flash, wepent, (gettagindex(wepent, "shot")) ? "shot" : "tag_shot");
649 setorigin(flash, offset);
650}
651#endif
652
654{
655 this.frame += 2;
656 this.scale *= 0.5;
657 this.alpha -= 0.25;
658 this.nextthink = time + 0.05;
659
660 if (this.alpha <= 0)
661 {
662 setthink(this, SUB_Remove);
663 this.nextthink = time;
664 this.realowner.muzzle_flash = NULL;
665 return;
666 }
667}
668
669void W_MuzzleFlash_Model(entity wepent, entity muzzlemodel)
670{
671 if (wepent.muzzle_flash == NULL)
672 wepent.muzzle_flash = spawn();
673
674 entity flash = wepent.muzzle_flash;
675 setmodel(flash, muzzlemodel); // precision set below
676
677 flash.scale = 0.75;
679 flash.nextthink = time + 0.02;
680 flash.frame = 2;
681 flash.alpha = 0.75;
682 flash.angles.z = random() * 180;
683 flash.effects = EF_ADDITIVE | EF_FULLBRIGHT;
684 flash.owner = flash.realowner = wepent;
685
686#ifdef CSQC
687 flash.drawmask = MASK_NORMAL;
688#endif
689}
690
691REGISTER_NET_TEMP(w_muzzleflash)
692
693#ifdef SVQC
694void W_MuzzleFlash(Weapon thiswep, entity actor, .entity weaponentity, vector shotorg, vector shotdir)
695{
696 // don't show an exterior muzzle effect for the off-hand
697 if (weaponslot(weaponentity) == 0)
698 {
699 Send_Effect_Core(thiswep.m_muzzleeffect, shotorg, shotdir * 1000, 1, '0 0 0', '0 0 0', -1, -1, -1, actor);
700
701 if (thiswep.m_muzzlemodel != MDL_Null)
702 {
703 W_MuzzleFlash_Model(actor.exteriorweaponentity, thiswep.m_muzzlemodel);
704 W_MuzzleFlash_Model_AttachToShotorg(actor, weaponentity, actor.exteriorweaponentity.muzzle_flash, '5 0 0');
705 }
706 }
707
708 FOREACH_CLIENT(it == actor || (IS_SPEC(it) && it.enemy == actor),
709 {
710 if (!IS_REAL_CLIENT(it))
711 continue;
712 int channel = MSG_ONE;
713 msg_entity = it;
714 WriteHeader(channel, w_muzzleflash);
715 WriteRegistered(Weapons, channel, thiswep);
716 WriteByte(channel, weaponslot(weaponentity));
717 WriteVector(channel, shotorg);
718 });
719}
720#elif defined(CSQC)
721NET_HANDLE(w_muzzleflash, bool isNew)
722{
723 return = true;
724 int weapon_id = ReadRegistered(Weapons).m_id;
725 int slot = ReadByte();
726 vector sv_shotorg = ReadVector();
727
728 Weapon thiswep = REGISTRY_GET(Weapons, weapon_id);
729 vector viewangles = getpropertyvec(VF_CL_VIEWANGLES);
730 vector forward, right, up;
731 MAKE_VECTORS(viewangles, forward, right, up);
732
734 {
735 // in third person mode, show the muzzle flash from the server side weapon position
736 // we don't have a view model to reference in this case
737 pointparticles(thiswep.m_muzzleeffect, sv_shotorg, forward * 1000, 1);
738 return;
739 }
741 return;
742
743 entity wepent = viewmodels[slot];
744 // get the local player entity to calculate shot origin
746 if (!rlplayer)
747 rlplayer = csqcplayer; // fall back to the global
748
749 vector md = wepent.movedir_aligned;
750 vector dv = forward * md.x + right * -md.y + up * md.z;
751 vector org = rlplayer.origin + rlplayer.view_ofs + dv;
752
753 pointparticles(thiswep.m_muzzleeffect, org, forward * 1000, 1);
754
755 if (thiswep.m_muzzlemodel != MDL_Null)
756 {
757 W_MuzzleFlash_Model(wepent, thiswep.m_muzzlemodel);
758 W_MuzzleFlash_Model_AttachToShotorg(wepent, wepent.muzzle_flash, '5 0 0');
759 }
760}
761#endif
762
763
764#endif
765
766#endif
767
768#ifdef SVQC
775#endif
776
777#ifdef CSQC
778REPLICATE(cvar_cl_accuracy_data_share, bool, "cl_accuracy_data_share");
779REPLICATE(cvar_cl_accuracy_data_receive, bool, "cl_accuracy_data_receive");
780#endif
781
782#ifdef GAMEQC
783REPLICATE(cvar_cl_gunalign, int, "cl_gunalign");
784REPLICATE(cvar_cl_weapon_switch_reload, bool, "cl_weapon_switch_reload");
785REPLICATE(cvar_cl_weapon_switch_fallback_to_impulse, bool, "cl_weapon_switch_fallback_to_impulse");
786REPLICATE(cvar_cl_weaponimpulsemode, int, "cl_weaponimpulsemode");
787REPLICATE(cvar_cl_weaponpriority, string, "cl_weaponpriority", W_FixWeaponOrder_ForceComplete_AndBuildImpulseList);
788REPLICATE(cvar_cl_weaponpriorities[0], string, "cl_weaponpriority0", W_FixWeaponOrder_AllowIncomplete);
789REPLICATE(cvar_cl_weaponpriorities[1], string, "cl_weaponpriority1", W_FixWeaponOrder_AllowIncomplete);
790REPLICATE(cvar_cl_weaponpriorities[2], string, "cl_weaponpriority2", W_FixWeaponOrder_AllowIncomplete);
791REPLICATE(cvar_cl_weaponpriorities[3], string, "cl_weaponpriority3", W_FixWeaponOrder_AllowIncomplete);
792REPLICATE(cvar_cl_weaponpriorities[4], string, "cl_weaponpriority4", W_FixWeaponOrder_AllowIncomplete);
793REPLICATE(cvar_cl_weaponpriorities[5], string, "cl_weaponpriority5", W_FixWeaponOrder_AllowIncomplete);
794REPLICATE(cvar_cl_weaponpriorities[6], string, "cl_weaponpriority6", W_FixWeaponOrder_AllowIncomplete);
795REPLICATE(cvar_cl_weaponpriorities[7], string, "cl_weaponpriority7", W_FixWeaponOrder_AllowIncomplete);
796REPLICATE(cvar_cl_weaponpriorities[8], string, "cl_weaponpriority8", W_FixWeaponOrder_AllowIncomplete);
797REPLICATE(cvar_cl_weaponpriorities[9], string, "cl_weaponpriority9", W_FixWeaponOrder_AllowIncomplete);
798#endif
799
800
801#ifdef MENUQC
802// Finds keybinds for a weapon
804{
805 string command, key, keys = "";
806 int n, j;
807 float k;
808 bool joy_active = cvar("joy_active");
809
810 for (int cmd_type = 0; cmd_type < 2; ++cmd_type)
811 {
812 command = cmd_type
813 ? strcat("weapon_", wep.netname)
814 : strcat("weapon_group_", itos(wep.impulse));
815 n = tokenize(findkeysforcommand(command, 0)); // uses '...' strings
816
817 for (j = 0; j < n; ++j)
818 {
819 k = stof(argv(j));
820 if (k == -1)
821 continue;
822 key = keynumtostring(k);
823 if (!joy_active && startsWith(key, "JOY"))
824 continue;
825
826 key = translate_key(key);
827 if (keys == "")
828 keys = strcat("^3", key);
829 else
830 keys = strcat(keys, "^7, ^3", key);
831 }
832 }
833
834 if (keys == "")
835 return _("This weapon has not been bound directly."); // code may miss some weird bind configs, so say "directly"
836 return sprintf(_("You have bound this weapon to: %s."), strcat(keys, "^7"));
837}
838
839
840// Author: k9er
841#define COLORED_DAMAGE(dmg) strcat("^9", dmg, "^7")
842#define DEFINE_WEPBAL() string wepbal_s = strcat("g_balance_", name)
843#define DEFINE_WEPBAL_() string wepbal_s = strcat("g_balance_", name, "_")
844#define WEPBAL(...) EVAL_WEPBAL(OVERLOAD(WEPBAL, __VA_ARGS__))
845#define EVAL_WEPBAL(...) __VA_ARGS__
846#define WEPBAL_1(a1) cvar_defstring(strcat(wepbal_s, a1))
847#define WEPBAL_2(a1, a2) cvar_defstring(strcat(wepbal_s, a1, a2))
848
849#define DPS_ONE(mode) sprintf(_("(DPS: %.2f)"), (mode##rft <= 0) ? 1337 : stof(mode##dmg_s) / mode##rft)
850#define DPS_MUL(mode) sprintf(_("(DPS: %.2f)"), (mode##rft <= 0) ? 1337 : stof(mode##dmg_s) * stof(mode##shots_s) / mode##rft)
851#define DPS_DIRECT(mode) sprintf(_("(DPS: %.2f)"), (mode##rft <= 0) ? 1337 : stof(mode##dir_dmg_s) / mode##rft)
852#define DPS_SEEKER(mode) sprintf(_("(DPS: %.2f)"), (mode##rft <= 0) ? 1337 : (stof(mode##dmg_s) * stof(mode##shots_s) + stof(mode##extra_s)) / mode##rft)
853#define DPS_COMBO(mode, pri, sec) sprintf(_("(total DPS: %.2f)"), (mode##rft <= 0) ? 1337 : (stof(pri##dmg_s) + stof(sec##dmg_s) * stof(sec##shots_s) + stof(mode##dmg_s)) / mode##rft)
854
855#define pri_str _("primary")
856#define sec_str _("secondary")
857#define _IT_DOES_MSG() strcat("\n* ", sprintf(_("It does %s damage"), COLORED_DAMAGE(dmg_s)), " ", DPS_ONE())
858#define _IT_SHOOTS_MSG() strcat("\n* ", sprintf(_("It shoots %s shots doing %s damage each"), shots_s, COLORED_DAMAGE(dmg_s)), " ", DPS_MUL())
859#define _DIRECT_DOES_MSG() strcat("\n* ", sprintf(_("A direct hit does %s damage"), COLORED_DAMAGE(dir_dmg_s)), " ", DPS_DIRECT())
860#define _DOES_MSG(mode) strcat("\n* ", sprintf(_("The %s does %s damage"), mode##str, COLORED_DAMAGE(mode##dmg_s)), " ", DPS_ONE(mode))
861#define _DOES_PERSEC_MSG(mode) strcat("\n* ", sprintf(_("The %s does %s damage per second"), mode##str, COLORED_DAMAGE(mode##dmg_s)))
862#define _SHOOTS_MSG(mode) strcat("\n* ", sprintf(_("The %s shoots %s shots doing %s damage each"), mode##str, mode##shots_s, COLORED_DAMAGE(mode##dmg_s)), " ", DPS_MUL(mode))
863#define _SHOOTS_UPTO_MSG(mode) strcat("\n* ", sprintf(_("The %s shoots up to %s shots doing %s damage each"), mode##str, mode##shots_s, COLORED_DAMAGE(mode##dmg_s)), " ", DPS_MUL(mode))
864#define _SEEKER_MSG(mode) strcat("\n* ", sprintf(_("The %s does %s damage then shoots %s shots doing %s damage each"), mode##str, COLORED_DAMAGE(mode##extra_s), mode##shots_s, COLORED_DAMAGE(mode##dmg_s)), " ", DPS_SEEKER(mode))
865#define _COMBO_MSG(mode, pri, sec) strcat("\n* ", sprintf(_("The combo adds an extra %s damage"), COLORED_DAMAGE(mode##dmg_s)), " ", DPS_COMBO(mode, pri, sec))
866
867// We could use the _*_MSG macros directly, but these are more intuitive and readable
868#define IT_DOES() _IT_DOES_MSG()
869#define IT_SHOOTS() _IT_SHOOTS_MSG()
870#define DIRECT_DOES() _DIRECT_DOES_MSG()
871#define THE_PRIMARY_DOES() _DOES_MSG(pri_)
872#define THE_PRIMARY_SHOOTS() _SHOOTS_MSG(pri_)
873#define THE_PRIMARY_SHOOTS_UPTO() _SHOOTS_UPTO_MSG(pri_)
874#define THE_PRIMARY_DOES_PERSEC() _DOES_PERSEC_MSG(pri_)
875#define THE_SECONDARY_DOES() _DOES_MSG(sec_)
876#define THE_SECONDARY_SHOOTS() _SHOOTS_MSG(sec_)
877#define THE_SECONDARY_SHOOTS_UPTO() _SHOOTS_UPTO_MSG(sec_)
878#define THE_SECONDARY_DOES_PERSEC() _DOES_PERSEC_MSG(sec_)
879#define THE_SEEKER_PRIMARY_SHOOTS() _SEEKER_MSG(pri_)
880#define THE_COMBO_ADDS() _COMBO_MSG(cmb_, pri_, sec_)
881
882// One function for each translatable string
883
885{
887 string dmg_s = WEPBAL("_damage");
888 float rft = stof(WEPBAL("_refire"));
889 string dir_dmg_s = WEPBAL("_damage2");
890 return strcat(_("Default damage stats:"),
891 IT_DOES(),
892 DIRECT_DOES());
893}
895{
897 string dmg_s = WEPBAL("_damage");
898 float rft = stof(WEPBAL("_refire"));
899 return strcat(_("Default damage stats:"),
900 IT_DOES());
901}
902string W_Guide_DPS_onlyOne_andDirectHit(string name, string fire)
903{
905}
906string W_Guide_DPS_onlyOne(string name, string fire)
907{
908 return W_Guide_DPS_onlyOne_unnamed(strcat(name, "_", fire));
909}
910string W_Guide_DPS(string name, string pri, string sec)
911{
912 // TODO: rename all wep primary cvars to g_balance_*_primary_*, vice versa for secondary.
913 // Example exception: g_balance_arc_beam_* (primary)
915 string pri_dmg_s = WEPBAL(pri, "_damage");
916 float pri_rft = stof(WEPBAL(pri, "_refire"));
917 string sec_dmg_s = WEPBAL(sec, "_damage");
918 float sec_rft = stof(WEPBAL(sec, "_refire"));
919 return strcat(_("Default damage stats:"),
922}
923string W_Guide_DPS_bothMultishot(string name, string pri, string sec)
924{
926 string pri_dmg_s = WEPBAL(pri, "_damage");
927 float pri_rft = stof(WEPBAL(pri, "_refire"));
928 string pri_shots_s = WEPBAL(pri, "_shots");
929 string sec_dmg_s = WEPBAL(sec, "_damage");
930 float sec_rft = stof(WEPBAL(sec, "_refire"));
931 string sec_shots_s = WEPBAL(sec, "_shots");
932 return strcat(_("Default damage stats:"),
935}
936string W_Guide_DPS_onlySecondary(string name, string sec)
937{
939 string sec_dmg_s = WEPBAL(sec, "_damage");
940 float sec_rft = stof(WEPBAL(sec, "_refire"));
941 return strcat(_("Default damage stats:"),
943}
944string W_Guide_DPS_secondaryMultishot(string name, string pri, string sec, string shots, string refire2, bool sec_variable)
945{
947 string pri_dmg_s = WEPBAL(pri, "_damage");
948 float pri_rft = stof(WEPBAL(pri, "_refire"));
949 string sec_dmg_s = WEPBAL(sec, "_damage");
950 float sec_rft = stof(WEPBAL(sec, "_refire"));
951 string sec_shots_s = WEPBAL(shots);
952 if (sec_dmg_s == "")
953 sec_dmg_s = pri_dmg_s;
954 float num_shots = stof(sec_shots_s);
955 if (refire2 != "")
956 sec_rft = (num_shots - 1) * sec_rft + stof(WEPBAL(refire2));
957 return strcat(_("Default damage stats:"),
959 (sec_variable ? THE_SECONDARY_SHOOTS_UPTO() : THE_SECONDARY_SHOOTS()));
960}
961string W_Guide_DPS_MachineGun(string name, string pri, string sec, string other, string shots, string refire2, bool sec_variable)
962{
964 return (stof(WEPBAL("_mode")) == 1)
965 ? W_Guide_DPS_secondaryMultishot(name, pri, sec, shots, refire2, sec_variable)
966 : W_Guide_DPS(name, pri, other);
967}
968string W_Guide_DPS_primaryMultishot(string name, string pri, string sec, string shots)
969{
971 string pri_dmg_s = WEPBAL(pri, "_damage");
972 float pri_rft = stof(WEPBAL(pri, "_refire"));
973 string pri_shots_s = WEPBAL(shots);
974 string sec_dmg_s = WEPBAL(sec, "_damage");
975 float sec_rft = stof(WEPBAL(sec, "_refire"));
976 return strcat(_("Default damage stats:"),
979}
980string W_Guide_DPS_Seeker(string name, string pri, string sec, string other, string shots)
981{
983 if (stof(WEPBAL("type")) == 1)
984 return W_Guide_DPS(name, pri, other);
985
986 string pri_dmg_s = WEPBAL(pri, "_damage");
987 float pri_rft = stof(WEPBAL(other, "_refire"));
988 string pri_shots_s = WEPBAL(shots);
989 string pri_extra_s = WEPBAL(other, "_damage");
990 string sec_dmg_s = WEPBAL(sec, "_damage");
991 float sec_rft = stof(WEPBAL(sec, "_refire"));
992 return strcat(_("Default damage stats:"),
995}
996string W_Guide_DPS_onlyOneMultishot(string name, string fire, string shots, string refire2)
997{
999 string dmg_s = WEPBAL(fire, "_damage");
1000 float rft = stof(WEPBAL(fire, "_refire"));
1001 string shots_s = WEPBAL(shots);
1002 float num_shots = stof(shots_s);
1003 if (refire2 != "")
1004 rft = (num_shots - 1) * rft + stof(WEPBAL(refire2));
1005 return strcat(_("Default damage stats:"),
1006 IT_SHOOTS());
1007}
1008string W_Guide_DPS_secondaryMultishotWithCombo(string name, string pri, string sec, string shots, string refire2, string combo, bool sec_variable)
1009{
1011 string pri_dmg_s = WEPBAL(pri, "_damage");
1012 float pri_rft = stof(WEPBAL(pri, "_refire"));
1013 string sec_dmg_s = WEPBAL(sec, "_damage");
1014 float sec_rft = stof(WEPBAL(sec, "_refire"));
1015 string sec_shots_s = WEPBAL(shots);
1016 string cmb_dmg_s = WEPBAL(combo, "_damage");
1017 float num_shots = stof(sec_shots_s);
1018 float cmb_rft = max(pri_rft, sec_rft);
1019 if (refire2 != "")
1020 {
1021 float sec_rft2 = sec_rft;
1022 sec_rft = stof(WEPBAL(refire2));
1023 cmb_rft = max(cmb_rft, num_shots * sec_rft + sec_rft2);
1024 sec_rft = (num_shots - 1) * sec_rft + sec_rft2;
1025 }
1026 return strcat(_("Default damage stats:"),
1028 (sec_variable ? THE_SECONDARY_SHOOTS_UPTO() : THE_SECONDARY_SHOOTS()),
1029 THE_COMBO_ADDS());
1030}
1031string W_Guide_DPS_primaryDPS(string name, string pri, string sec)
1032{
1034 string pri_dmg_s = WEPBAL(pri, "_damage"); // actually damage per second
1035 string sec_dmg_s = WEPBAL(sec, "_damage");
1036 float sec_rft = stof(WEPBAL(sec, "_refire"));
1037 return strcat(_("Default damage stats:"),
1040}
1041
1042#undef COLORED_DAMAGE
1043#undef DEFINE_WEPBAL
1044#undef DEFINE_WEPBAL_
1045#undef WEPBAL
1046#undef EVAL_WEPBAL
1047#undef WEPBAL_1
1048#undef WEPBAL_2
1049#undef DPS_ONE
1050#undef DPS_MUL
1051#undef DPS_DIRECT
1052#undef DPS_SEEKER
1053#undef DPS_COMBO
1054#undef pri_str
1055#undef sec_str
1056#undef _IT_DOES_MSG
1057#undef _IT_SHOOTS_MSG
1058#undef _DIRECT_DOES_MSG
1059#undef _DOES_MSG
1060#undef _DOES_PERSEC_MSG
1061#undef _SHOOTS_MSG
1062#undef _SHOOTS_UPTO_MSG
1063#undef _SEEKER_MSG
1064#undef _COMBO_MSG
1065#undef IT_DOES
1066#undef IT_SHOOTS
1067#undef DIRECT_DOES
1068#undef THE_PRIMARY_DOES
1069#undef THE_PRIMARY_SHOOTS
1070#undef THE_PRIMARY_SHOOTS_UPTO
1071#undef THE_PRIMARY_DOES_PERSEC
1072#undef THE_SECONDARY_DOES
1073#undef THE_SECONDARY_SHOOTS
1074#undef THE_SECONDARY_SHOOTS_UPTO
1075#undef THE_SECONDARY_DOES_PERSEC
1076#undef THE_SEEKER_PRIMARY_SHOOTS
1077#undef THE_COMBO_ADDS
1078#endif // MENUQC
vector shotorg
Definition aim.qh:10
vector shotdir
Definition aim.qh:11
void anim_set(entity e, vector anim, bool looping, bool override, bool restart)
Definition anim.qc:6
#define setanim(...)
Definition anim.qh:45
float frame
primary framegroup animation (strength = 1 - lerpfrac - lerpfrac3 - lerpfrac4)
Definition anim.qh:6
#define MUTATOR_CALLHOOK(name,...)
Definition base.qh:186
#define M_ARGV(idx, type)
Definition base.qh:153
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition bits.qh:8
int W_GunAlign(entity this, int preferred_align)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define CLIENT_COMMAND(id, description)
Definition cl_cmd.qh:16
entity csqcplayer
Definition cl_player.qh:26
Definition ammo.qh:26
int m_id
Definition item.qh:128
string netname
Definition resources.qh:27
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:36
int impulse
M: impulse : weapon impulse.
Definition weapon.qh:52
string netname
M: refname : reference name name.
Definition weapon.qh:78
entity m_muzzlemodel
M: flash model MDL_id_MUZZLEFLASH.
Definition weapon.qh:63
float alpha
Definition items.qc:13
entity owner
Definition main.qh:87
float renderflags
Definition main.qh:111
const int CMD_REQUEST_COMMAND
Definition command.qh:3
const int CMD_REQUEST_USAGE
Definition command.qh:4
#define setmodel(this, m)
Definition model.qh:26
float compressShotOrigin(vector v)
Definition util.qc:1350
string translate_key(string key)
Definition util.qc:1612
vector decompressShotOrigin(int f)
Definition util.qc:1377
const float VF_CL_VIEWANGLES
entity other
const float STAT_CELLS
const float STAT_ROCKETS
const float MASK_NORMAL
vector mins
const float STAT_SHELLS
const float EF_ADDITIVE
const float EF_FULLBRIGHT
const float RF_VIEWMODEL
float time
const float STAT_NAILS
vector maxs
float nextthink
float player_localentnum
vector oldorigin
#define spawn
void SUB_Remove(entity this)
Remove entity.
Definition defer.qh:12
#define MAKE_VECTORS(angles, forward, right, up)
Same as the makevectors builtin but uses the provided locals instead of the v_* globals.
entity viewmodelforclient
#define strstrofs
#define gettagindex
#define pointparticles(effect, org, vel, howmany)
Definition effect.qh:6
#define pass(name, colormin, colormax)
void Send_Effect_Core(entity eff, vector eff_loc, vector eff_vel, int eff_cnt, vector eff_col_min, vector eff_col_max, float eff_alpha_min, float eff_alpha_max, float eff_alpha_fade, entity ignore)
Definition all.qc:74
ent angles
Definition ent_cs.qc:146
model
Definition ent_cs.qc:164
WriteByte(chan, ent.angles.y/DEC_FACTOR)
entity CSQCModel_server2csqc(int i)
Definition cl_model.qc:314
Weapons
Definition guide.qh:113
#define itos(i)
Definition int.qh:6
Header file that describes the functions related to game items.
#define FOREACH(list, cond, body)
Definition iter.qh:19
#define ReadFloat()
Definition net.qh:348
#define NET_HANDLE(id, param)
Definition net.qh:15
#define ReadVector()
Definition net.qh:349
int ReadInt24_t()
Definition net.qh:337
#define ReadRegistered(r)
Definition net.qh:290
#define ReadInt48_t()
Definition net.qh:343
#define ReadInt72_t()
Definition net.qh:344
#define WriteHeader(to, id)
Definition net.qh:265
#define REGISTER_NET_C2S(id)
Definition net.qh:128
int ReadByte()
#define WriteRegistered(r, to, it)
Definition net.qh:292
#define REGISTER_NET_TEMP(id)
Definition net.qh:31
#define REPLICATE(...)
Replicates a client cvar into a server field.
Definition replicate.qh:23
#define STAT(...)
Definition stats.qh:94
#define LOG_WARNF(...)
Definition log.qh:59
#define LOG_HELP(...)
Definition log.qh:83
#define LOG_INFOF(...)
Definition log.qh:63
vector movedir
Definition viewloc.qh:18
string name
Definition menu.qh:30
float MSG_ONE
Definition menudefs.qc:56
float stof(string val,...)
string substring(string s, float start, float length)
float cvar(string name)
string keynumtostring(float keynum)
vector stov(string s)
float random(void)
string ftos(float f)
const string cvar_defstring(string name)
float tokenize(string s)
string argv(float n)
float max(float f,...)
vector animfixfps(entity e, vector a, vector b)
Definition util.qc:1907
string string_null
Definition nil.qh:9
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
#define NULL
Definition post.qh:14
#define gettaginfo
Definition post.qh:32
entity msg_entity
Definition progsdefs.qc:63
vector view_ofs
Definition progsdefs.qc:151
float scale
Definition projectile.qc:14
entity result
Definition promise.qc:45
ERASEABLE void RandomSelection_Init()
Definition random.qc:4
#define RandomSelection_AddEnt(e, weight, priority)
Definition random.qh:14
entity RandomSelection_chosen_ent
Definition random.qh:5
#define REGISTRY_GET(id, i)
Definition registry.qh:62
#define REGISTRY_MAX(id)
Definition registry.qh:17
#define setthink(e, f)
vector
Definition self.qh:96
vector org
Definition self.qh:96
string weaponorder_byimpulse
Definition client.qh:61
ERASEABLE void heapsort(int n, swapfunc_t swap, comparefunc_t cmp, entity pass)
Definition sort.qh:9
#define CS_CVAR(this)
Definition state.qh:51
#define startsWith(haystack, needle)
Definition string.qh:234
#define strcpy(this, s)
Definition string.qh:51
entity realowner
#define IS_SPEC(v)
Definition utils.qh:10
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:52
#define vec3(_x, _y, _z)
Definition vector.qh:100
int autocvar_chase_active
Definition view.qh:17
bool autocvar_r_drawviewmodel
Definition view.qh:97
entity viewmodels[MAX_WEAPONSLOTS]
Definition view.qh:108
string W_FixWeaponOrder_ForceComplete(string order)
Definition all.qc:150
string W_FixWeaponOrder_AllowIncomplete(entity this, string order)
Definition all.qc:145
vector shotorg_adjustfromclient(vector vecs, float y_is_right, float algn)
Definition all.qc:220
void wframe_send(entity actor, entity weaponentity, int wepframe, float attackrate, bool restartanim)
Definition all.qc:556
string W_Model(string w_mdl)
Definition all.qc:212
string W_Guide_Keybinds(Weapon wep)
Definition all.qc:803
#define THE_COMBO_ADDS()
Definition all.qc:880
#define THE_SEEKER_PRIMARY_SHOOTS()
Definition all.qc:879
#define DIRECT_DOES()
Definition all.qc:870
void CL_WeaponEntity_SetModel(entity this, string name, bool _anim)
supported formats:
Definition all.qc:320
string W_Guide_DPS_secondaryMultishot(string name, string pri, string sec, string shots, string refire2, bool sec_variable)
Definition all.qc:944
void WriteWepSet(float dst, WepSet w)
Definition all.qc:69
int GetAmmoStat(Resource ammotype)
Definition all.qc:190
void W_FixWeaponOrder_BuildImpulseList_swap(int i, int j, entity pass)
Definition all.qc:112
entity GetAmmoResource(Ammo ammotype)
Definition all.qc:182
float W_FixWeaponOrder_BuildImpulseList_buf[REGISTRY_MAX(Weapons)]
Definition all.qc:110
void W_MuzzleFlash_Model_Think(entity this)
Definition all.qc:653
float W_FixWeaponOrder_BuildImpulseList_cmp(int i, int j, entity pass)
Definition all.qc:118
string W_FixWeaponOrder_BuildImpulseList(string o)
Definition all.qc:131
string W_Guide_DPS(string name, string pri, string sec)
Definition all.qc:910
#define THE_SECONDARY_DOES()
Definition all.qc:875
string W_NumberWeaponOrder_MapFunc(string s)
Definition all.qc:102
string W_Sound(string w_snd)
Definition all.qc:205
string W_Guide_DPS_bothMultishot(string name, string pri, string sec)
Definition all.qc:923
string W_Guide_DPS_onlySecondary(string name, string sec)
Definition all.qc:936
void Weapon_whereis(Weapon this, entity cl)
Definition selection.qc:26
string W_Guide_DPS_primaryMultishot(string name, string pri, string sec, string shots)
Definition all.qc:968
void W_MuzzleFlash_Model(entity wepent, entity muzzlemodel)
Definition all.qc:669
string W_Guide_DPS_onlyOne_andDirectHit(string name, string fire)
Definition all.qc:902
void W_MuzzleFlash(Weapon thiswep, entity actor,.entity weaponentity, vector shotorg, vector shotdir)
Definition all.qc:694
#define THE_SECONDARY_SHOOTS_UPTO()
Definition all.qc:877
string W_NameWeaponOrder_MapFunc(string s)
Definition all.qc:90
string W_FixWeaponOrder_ForceComplete_AndBuildImpulseList(entity this, string wo)
Definition all.qc:769
string W_Guide_DPS_secondaryMultishotWithCombo(string name, string pri, string sec, string shots, string refire2, string combo, bool sec_variable)
Definition all.qc:1008
string W_Guide_DPS_Seeker(string name, string pri, string sec, string other, string shots)
Definition all.qc:980
#define THE_PRIMARY_SHOOTS()
Definition all.qc:872
#define IT_DOES()
Definition all.qc:868
#define DEFINE_WEPBAL_()
Definition all.qc:843
string W_Guide_DPS_MachineGun(string name, string pri, string sec, string other, string shots, string refire2, bool sec_variable)
Definition all.qc:961
string W_Guide_DPS_onlyOneMultishot(string name, string fire, string shots, string refire2)
Definition all.qc:996
WepSet _WepSet_FromWeapon(int a)
Definition all.qc:53
#define THE_PRIMARY_DOES_PERSEC()
Definition all.qc:874
string W_Guide_DPS_onlyOne_unnamed(string name)
Definition all.qc:894
void W_MuzzleFlash_Model_AttachToShotorg(entity actor,.entity weaponentity, entity flash, vector offset)
Definition all.qc:623
string W_Guide_DPS_onlyOne(string name, string fire)
Definition all.qc:906
string W_Guide_DPS_primaryDPS(string name, string pri, string sec)
Definition all.qc:1031
#define DEFINE_WEPBAL()
Definition all.qc:842
#define WEPBAL(...)
Definition all.qc:844
string W_FixWeaponOrder_BuildImpulseList_order
Definition all.qc:111
#define IT_SHOOTS()
Definition all.qc:869
entity GetAmmoItem(Resource ammotype)
Definition all.qc:175
#define THE_SECONDARY_SHOOTS()
Definition all.qc:876
WepSet ReadWepSet()
Definition all.qc:80
vector shotorg_adjust(vector vecs, bool y_is_right, bool visual, int algn)
Definition all.qc:239
string W_Guide_DPS_onlyOne_unnamed_andDirectHit(string name)
Definition all.qc:884
WepSet W_RandomWeapons(entity e, WepSet remaining, int n)
Definition all.qc:157
#define THE_PRIMARY_DOES()
Definition all.qc:871
int m_gunalign
Definition all.qh:412
#define G_SHOOTFROMFIXEDORIGIN
Definition all.qh:445
vector movedir_aligned
Definition all.qh:421
vector anim_reload
Definition all.qh:427
#define WEP_LAST
Definition all.qh:345
vector anim_fire2
Definition all.qh:425
vector anim_idle
Definition all.qh:426
const int WEP_FIRST
Definition all.qh:344
entity weaponchild
Definition all.qh:402
#define W_NumberWeaponOrder(order)
Definition all.qh:482
vector anim_fire1
Definition all.qh:424
WFRAME wframe
Definition all.qh:441
#define W_FixWeaponOrder(order, complete)
Definition all.qh:483
vector spawnorigin
Definition all.qh:418
#define WepSet_FromWeapon(it)
Definition all.qh:48
const int WS_RAISE
raise frame
Definition weapon.qh:29
int weaponslot(.entity weaponentity)
Definition weapon.qh:18
const int WS_DROP
deselecting frame
Definition weapon.qh:30
vector WepSet
Definition weapon.qh:13