Xonotic
hlac.qc
Go to the documentation of this file.
1 #include "hlac.qh"
2 
3 #ifdef SVQC
4 
5 void W_HLAC_Touch(entity this, entity toucher)
6 {
7  float isprimary;
8 
9  PROJECTILE_TOUCH(this, toucher);
10 
11  this.event_damage = func_null;
12 
13  isprimary = !(this.projectiledeathtype & HITTYPE_SECONDARY);
14 
15  RadiusDamage(this, this.realowner, WEP_CVAR_BOTH(hlac, isprimary, damage), WEP_CVAR_BOTH(hlac, isprimary, edgedamage), WEP_CVAR_BOTH(hlac, isprimary, radius),
16  NULL, NULL, WEP_CVAR_BOTH(hlac, isprimary, force), this.projectiledeathtype, this.weaponentity_fld, toucher);
17 
18  delete(this);
19 }
20 
21 void W_HLAC_Attack(Weapon thiswep, entity actor, .entity weaponentity)
22 {
23  entity missile;
24 
25  W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(hlac, ammo), weaponentity);
26 
27  float spread = WEP_CVAR_PRI(hlac, spread_min) + (WEP_CVAR_PRI(hlac, spread_add) * actor.(weaponentity).misc_bulletcounter);
28  spread = min(spread,WEP_CVAR_PRI(hlac, spread_max));
29  if(IS_DUCKED(actor))
30  spread = spread * WEP_CVAR_PRI(hlac, spread_crouchmod);
31 
32  W_SetupShot(actor, weaponentity, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR_PRI(hlac, damage), thiswep.m_id);
33  W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
35  {
36  actor.punchangle_x = random() - 0.5;
37  actor.punchangle_y = random() - 0.5;
38  }
39 
40  missile = new(hlacbolt);
41  missile.owner = missile.realowner = actor;
42  missile.bot_dodge = true;
43 
44  missile.bot_dodgerating = WEP_CVAR_PRI(hlac, damage);
45 
46  set_movetype(missile, MOVETYPE_FLY);
47  PROJECTILE_MAKETRIGGER(missile);
48 
49  setorigin(missile, w_shotorg);
50  setsize(missile, '0 0 0', '0 0 0');
51 
52  W_SetupProjVelocity_Basic(missile, WEP_CVAR_PRI(hlac, speed), spread);
53  //missile.angles = vectoangles(missile.velocity); // csqc
54 
55  settouch(missile, W_HLAC_Touch);
56  setthink(missile, SUB_Remove);
57 
58  missile.nextthink = time + WEP_CVAR_PRI(hlac, lifetime);
59 
60  missile.flags = FL_PROJECTILE;
61  IL_PUSH(g_projectiles, missile);
62  IL_PUSH(g_bot_dodge, missile);
63  missile.projectiledeathtype = thiswep.m_id;
64  missile.weaponentity_fld = weaponentity;
65 
66  CSQCProjectile(missile, true, PROJECTILE_HLAC, true);
67 
68  MUTATOR_CALLHOOK(EditProjectile, actor, missile);
69 }
70 
71 void W_HLAC_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
72 {
73  entity missile;
74  float spread = WEP_CVAR_SEC(hlac, spread);
75 
76  if(IS_DUCKED(actor))
77  spread = spread * WEP_CVAR_SEC(hlac, spread_crouchmod);
78 
79  W_SetupShot(actor, weaponentity, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(hlac, damage), thiswep.m_id | HITTYPE_SECONDARY);
80  W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
81 
82  missile = new(hlacbolt);
83  missile.owner = missile.realowner = actor;
84  missile.bot_dodge = true;
85 
86  missile.bot_dodgerating = WEP_CVAR_SEC(hlac, damage);
87 
88  set_movetype(missile, MOVETYPE_FLY);
89  PROJECTILE_MAKETRIGGER(missile);
90 
91  setorigin(missile, w_shotorg);
92  setsize(missile, '0 0 0', '0 0 0');
93 
94  W_SetupProjVelocity_Basic(missile, WEP_CVAR_SEC(hlac, speed), spread);
95  //missile.angles = vectoangles(missile.velocity); // csqc
96 
97  settouch(missile, W_HLAC_Touch);
98  setthink(missile, SUB_Remove);
99 
100  missile.nextthink = time + WEP_CVAR_SEC(hlac, lifetime);
101 
102  missile.flags = FL_PROJECTILE;
103  IL_PUSH(g_projectiles, missile);
104  IL_PUSH(g_bot_dodge, missile);
105  missile.missile_flags = MIF_SPLASH;
106  missile.projectiledeathtype = thiswep.m_id | HITTYPE_SECONDARY;
107  missile.weaponentity_fld = weaponentity;
108 
109  CSQCProjectile(missile, true, PROJECTILE_HLAC, true);
110 
111  MUTATOR_CALLHOOK(EditProjectile, actor, missile);
112 }
113 
114 // weapon frames
115 void W_HLAC_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentity, int fire)
116 {
117  if(actor.(weaponentity).m_weapon != actor.(weaponentity).m_switchweapon) // abort immediately if switching
118  {
119  w_ready(thiswep, actor, weaponentity, fire);
120  return;
121  }
122 
123  if(PHYS_INPUT_BUTTON_ATCK(actor))
124  {
125  if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity))
126  if(!(actor.items & IT_UNLIMITED_AMMO))
127  {
128  W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
129  w_ready(thiswep, actor, weaponentity, fire);
130  return;
131  }
132 
133  ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR_PRI(hlac, refire) * W_WeaponRateFactor(actor);
134  W_HLAC_Attack(thiswep, actor, weaponentity);
135  actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
136  weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame);
137  }
138  else
139  {
140  weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, animtime), w_ready);
141  }
142 }
143 
144 void W_HLAC_Attack2_Frame(Weapon thiswep, entity actor, .entity weaponentity)
145 {
146  W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(hlac, ammo), weaponentity);
147 
148  for(float i = WEP_CVAR_SEC(hlac, shots); i > 0; --i)
149  W_HLAC_Attack2(thiswep, actor, weaponentity);
150 
152  {
153  actor.punchangle_x = random() - 0.5;
154  actor.punchangle_y = random() - 0.5;
155  }
156 }
157 
158 METHOD(HLAC, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
159 {
160  PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(hlac, speed), 0, WEP_CVAR_PRI(hlac, lifetime), false);
161 }
162 METHOD(HLAC, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
163 {
164  if(autocvar_g_balance_hlac_reload_ammo && actor.(weaponentity).clip_load < min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo))) { // forced reload
165  thiswep.wr_reload(thiswep, actor, weaponentity);
166  } else if(fire & 1)
167  {
168  if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(hlac, refire)))
169  {
170  actor.(weaponentity).misc_bulletcounter = 0;
171  W_HLAC_Attack(thiswep, actor, weaponentity);
172  weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(hlac, refire), W_HLAC_Attack_Frame);
173  }
174  }
175 
176  else if((fire & 2) && WEP_CVAR(hlac, secondary))
177  {
178  if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(hlac, refire)))
179  {
180  W_HLAC_Attack2_Frame(thiswep, actor, weaponentity);
181  weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(hlac, animtime), w_ready);
182  }
183  }
184 }
185 METHOD(HLAC, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
186 {
187  float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_PRI(hlac, ammo);
188  ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_PRI(hlac, ammo);
189  return ammo_amount;
190 }
191 METHOD(HLAC, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
192 {
193  float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR_SEC(hlac, ammo);
194  ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(hlac, ammo);
195  return ammo_amount;
196 }
197 METHOD(HLAC, wr_reload, void(entity thiswep, entity actor, .entity weaponentity))
198 {
199  W_Reload(actor, weaponentity, min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo)), SND_RELOAD);
200 }
201 METHOD(HLAC, wr_suicidemessage, Notification(entity thiswep))
202 {
203  return WEAPON_HLAC_SUICIDE;
204 }
205 METHOD(HLAC, wr_killmessage, Notification(entity thiswep))
206 {
207  return WEAPON_HLAC_MURDER;
208 }
209 
210 #endif
211 #ifdef CSQC
212 
213 METHOD(HLAC, wr_impacteffect, void(entity thiswep, entity actor))
214 {
215  vector org2;
216  org2 = w_org + w_backoff * 6;
217  pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1);
218  if(!w_issilent)
219  sound(actor, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM);
220 }
221 
222 #endif
#define WEP_CVAR_PRI(wepname, name)
Definition: all.qh:300
#define W_SetupProjVelocity_Basic(ent, pspeed, pspread)
Definition: tracing.qh:48
bool bot_aim(entity this,.entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, float applygravity)
#define WEP_CVAR_SEC(wepname, name)
Definition: all.qh:301
float weapon_load[REGISTRY_MAX(Weapons)]
Definition: weaponsystem.qh:29
float speed
Definition: subs.qh:41
vector w_shotorg
Definition: tracing.qh:18
void W_SwitchWeapon_Force(Player this, Weapon w,.entity weaponentity)
Definition: selection.qc:243
#define PROJECTILE_MAKETRIGGER(e)
Definition: common.qh:29
const int MIF_SPLASH
Definition: common.qh:34
#define w_getbestweapon(ent, wepent)
Definition: selection.qh:23
#define IS_DUCKED(s)
Definition: player.qh:206
Definition: hlac.qh:3
entity() spawn
void w_ready(Weapon thiswep, entity actor,.entity weaponentity, int fire)
float radius
Definition: impulse.qh:11
const int PROJECTILE_HLAC
Definition: projectiles.qh:12
#define WEP_CVAR(wepname, name)
Definition: all.qh:299
vector w_shotdir
Definition: tracing.qh:19
entity weaponentity_fld
Definition: weaponsystem.qh:27
#define METHOD(cname, name, prototype)
Definition: oo.qh:257
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
IntrusiveList g_bot_dodge
Definition: api.qh:150
#define PROJECTILE_TOUCH(e, t)
Definition: common.qh:27
const float ATTN_NORM
Definition: csprogsdefs.qc:226
float ammo
Definition: sv_turrets.qh:44
float lifetime
Definition: powerups.qc:23
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
const int CH_WEAPON_A
Definition: sound.qh:7
bool weapon_prepareattack(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
#define WEP_CVAR_BOTH(wepname, isprimary, name)
Definition: all.qh:302
float misc_bulletcounter
Definition: common.qh:18
#define pointparticles
Definition: csprogsdefs.qh:13
#define NULL
Definition: post.qh:17
const float VOL_BASE
Definition: sound.qh:36
#define PHYS_INPUT_BUTTON_ATCK(s)
Definition: player.qh:146
const int HITTYPE_SECONDARY
Definition: all.qh:25
#define W_SetupShot(ent, wepent, antilag, recoil, snd, chan, maxdamage, deathtype)
Definition: tracing.qh:33
const int CH_SHOTS
Definition: sound.qh:14
vector(float skel, float bonenum) _skel_get_boneabs_hidden
IntrusiveList g_projectiles
Definition: common.qh:46
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
entity Notification
always last
Definition: all.qh:82
void weapon_thinkf(entity actor,.entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor,.entity weaponentity, int fire) func)
float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
Definition: damage.qc:1057
entity realowner
Definition: common.qh:25
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
setorigin(ent, v)
#define setthink(e, f)
#define ATTACK_FINISHED(ent, w)
Definition: weaponsystem.qh:42
void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use,.entity weaponentity)
#define sound(e, c, s, v, a)
Definition: sound.qh:52
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition: weapon.qh:41
float time
Definition: csprogsdefs.qc:16
int m_id
Definition: weapon.qh:42
float W_WeaponRateFactor(entity this)
Definition: weaponsystem.qc:33
bool autocvar_g_norecoil
Definition: tracing.qh:15
void set_movetype(entity this, int mt)
float MOVETYPE_FLY
Definition: progsdefs.qc:251
var void func_null()
void W_Reload(entity actor,.entity weaponentity, float sent_ammo_min, Sound sent_sound)
int projectiledeathtype
Definition: common.qh:20