]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/mutators/mutator/overkill/okshotgun.qc
Overkill weapons: better secondary refire.
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / overkill / okshotgun.qc
1 #include "okshotgun.qh"
2
3 #ifdef SVQC
4 spawnfunc(weapon_okshotgun) { weapon_defaultspawnfunc(this, WEP_OVERKILL_SHOTGUN); }
5
6 METHOD(OverkillShotgun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
7 {
8         if (vdist(actor.origin - actor.enemy.origin, >, WEP_CVAR_PRI(okshotgun, bot_range)))
9         {
10                 PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
11         }
12         else
13         {
14                 PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
15         }
16 }
17
18 METHOD(OverkillShotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
19 {
20         if ((WEP_CVAR_SEC(okshotgun, refire_type) == 1) && (fire & 2) && (time >= actor.jump_interval))
21         {
22                 // Secondary uses it's own refire timer if refire_type is 1.
23                 actor.jump_interval = time + WEP_CVAR_SEC(okshotgun, refire) * W_WeaponRateFactor(actor);
24                 // Ugly hack to reuse the fire mode of the blaster.
25                 makevectors(actor.v_angle);
26                 Weapon oldwep = actor.(weaponentity).m_weapon; // we can't avoid this hack
27                 actor.(weaponentity).m_weapon = WEP_BLASTER;
28                 W_Blaster_Attack(
29                         actor,
30                         weaponentity,
31                         WEP_BLASTER.m_id | HITTYPE_SECONDARY,
32                         WEP_CVAR_SEC(okshotgun, shotangle),
33                         WEP_CVAR_SEC(okshotgun, damage),
34                         WEP_CVAR_SEC(okshotgun, edgedamage),
35                         WEP_CVAR_SEC(okshotgun, radius),
36                         WEP_CVAR_SEC(okshotgun, force),
37                         WEP_CVAR_SEC(okshotgun, speed),
38                         WEP_CVAR_SEC(okshotgun, spread),
39                         WEP_CVAR_SEC(okshotgun, delay),
40                         WEP_CVAR_SEC(okshotgun, lifetime)
41                 );
42                 actor.(weaponentity).m_weapon = oldwep;
43         }
44         if (WEP_CVAR(okshotgun, reload_ammo) && actor.(weaponentity).clip_load < WEP_CVAR_PRI(okshotgun, ammo))
45         {
46                 // Forced reload
47                 thiswep.wr_reload(thiswep, actor, weaponentity);
48                 return;
49         }
50         if (fire & 1) // Primary attack
51         {
52                 if (!weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(okshotgun, animtime)))
53                 {
54                         return;
55                 }
56                 W_Shotgun_Attack(thiswep, actor, weaponentity, true,
57                         WEP_CVAR_PRI(okshotgun, ammo),
58                         WEP_CVAR_PRI(okshotgun, damage),
59                         WEP_CVAR_PRI(okshotgun, bullets),
60                         WEP_CVAR_PRI(okshotgun, spread),
61                         WEP_CVAR_PRI(okshotgun, solidpenetration),
62                         WEP_CVAR_PRI(okshotgun, force));
63                 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(okshotgun, animtime), w_ready);
64                 return;
65         }
66         if ((fire & 2) && (WEP_CVAR_SEC(okshotgun, refire_type) == 0)) // Secondary attack
67         {
68                 if (!weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_SEC(okshotgun, refire)))
69                 {
70                         return;
71                 }
72                 // ugly instagib hack to reuse the fire mode of the laser
73                 makevectors(actor.v_angle);
74                 Weapon oldwep = actor.(weaponentity).m_weapon; // we can't avoid this hack
75                 actor.(weaponentity).m_weapon = WEP_BLASTER;
76                 W_Blaster_Attack(
77                         actor,
78                         weaponentity,
79                         WEP_BLASTER.m_id | HITTYPE_SECONDARY,
80                         WEP_CVAR_SEC(okshotgun, shotangle),
81                         WEP_CVAR_SEC(okshotgun, damage),
82                         WEP_CVAR_SEC(okshotgun, edgedamage),
83                         WEP_CVAR_SEC(okshotgun, radius),
84                         WEP_CVAR_SEC(okshotgun, force),
85                         WEP_CVAR_SEC(okshotgun, speed),
86                         WEP_CVAR_SEC(okshotgun, spread),
87                         WEP_CVAR_SEC(okshotgun, delay),
88                         WEP_CVAR_SEC(okshotgun, lifetime)
89                 );
90                 actor.(weaponentity).m_weapon = oldwep;
91                 weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(okshotgun, animtime), w_ready);
92         }
93 }
94
95 METHOD(OverkillShotgun, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
96 {
97         float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_PRI(okshotgun, ammo);
98         ammo_amount += actor.(weaponentity).(weapon_load[WEP_OVERKILL_SHOTGUN.m_id]) >= WEP_CVAR_PRI(okshotgun, ammo);
99         return ammo_amount;
100 }
101
102 METHOD(OverkillShotgun, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
103 {
104         if (WEP_CVAR_SEC(okshotgun, ammo) == 0)
105         {
106                 return true;
107         }
108         float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR_SEC(okshotgun, ammo);
109         ammo_amount += actor.(weaponentity).(weapon_load[WEP_OVERKILL_SHOTGUN.m_id]) >= WEP_CVAR_SEC(okshotgun, ammo);
110         return ammo_amount;
111 }
112
113 METHOD(OverkillShotgun, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
114 {
115         W_Reload(actor, weaponentity, WEP_CVAR_PRI(okshotgun, ammo), SND_RELOAD); // WEAPONTODO
116 }
117
118 METHOD(OverkillShotgun, wr_suicidemessage, Notification(entity thiswep))
119 {
120         return WEAPON_THINKING_WITH_PORTALS;
121 }
122
123 METHOD(OverkillShotgun, wr_killmessage, Notification(entity thiswep))
124 {
125         if(w_deathtype & HITTYPE_SECONDARY)
126                 return WEAPON_BLASTER_MURDER;
127         else
128                 return WEAPON_SHOTGUN_MURDER;
129 }
130
131 #endif
132 #ifdef CSQC
133 .float prevric;
134
135 METHOD(OverkillShotgun, wr_impacteffect, void(entity thiswep, entity actor))
136 {
137         vector org2 = w_org + w_backoff * 2;
138         pointparticles(EFFECT_SHOTGUN_IMPACT, org2, w_backoff * 1000, 1);
139         if(!w_issilent && time - actor.prevric > 0.25)
140         {
141                 if(w_random < 0.05)
142                         sound(actor, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTEN_NORM);
143                 actor.prevric = time;
144         }
145 }
146
147 #endif