Xonotic
blaster.qc
Go to the documentation of this file.
1 #include "blaster.qh"
2 
3 #ifdef SVQC
4 
5 void W_Blaster_Touch(entity this, entity toucher)
6 {
7  PROJECTILE_TOUCH(this, toucher);
8 
9  this.event_damage = func_null;
10 
12  this,
13  (this.origin + (this.mins + this.maxs) * 0.5),
14  this.velocity,
15  this.realowner,
16  this.blaster_damage,
17  this.blaster_edgedamage,
18  this.blaster_radius,
19  NULL,
20  NULL,
21  false,
22  this.blaster_force,
23  this.blaster_force_zscale,
25  this.weaponentity_fld,
26  toucher
27  );
28 
29  delete(this);
30 }
31 
32 void W_Blaster_Think(entity this)
33 {
35  setthink(this, SUB_Remove);
36  this.nextthink = time + this.blaster_lifetime;
37  CSQCProjectile(this, true, PROJECTILE_BLASTER, true);
38 }
39 
40 void W_Blaster_Attack(
41  entity actor,
42  .entity weaponentity,
43  float atk_deathtype,
44  float atk_shotangle,
45  float atk_damage,
46  float atk_edgedamage,
47  float atk_radius,
48  float atk_force,
49  float atk_force_zscale,
50  float atk_speed,
51  float atk_spread,
52  float atk_delay,
53  float atk_lifetime)
54 {
55  vector s_forward = v_forward * cos(atk_shotangle * DEG2RAD) + v_up * sin(atk_shotangle * DEG2RAD);
56 
57  W_SetupShot_Dir(actor, weaponentity, s_forward, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_B, atk_damage, atk_deathtype);
58  W_MuzzleFlash(WEP_BLASTER, actor, weaponentity, w_shotorg, w_shotdir);
59 
60  entity missile = new(blasterbolt);
61  missile.owner = missile.realowner = actor;
62  missile.bot_dodge = true;
63  missile.bot_dodgerating = atk_damage;
64  PROJECTILE_MAKETRIGGER(missile);
65 
66  missile.blaster_damage = atk_damage;
67  missile.blaster_edgedamage = atk_edgedamage;
68  missile.blaster_radius = atk_radius;
69  missile.blaster_force = atk_force;
70  missile.blaster_force_zscale = atk_force_zscale;
71  missile.blaster_lifetime = atk_lifetime;
72 
73  setorigin(missile, w_shotorg);
74  setsize(missile, '0 0 0', '0 0 0');
75 
77  missile,
78  w_shotdir,
79  v_up,
80  atk_speed,
81  0,
82  0,
83  atk_spread,
84  false
85  );
86 
87  missile.angles = vectoangles(missile.velocity);
88 
89  //missile.glow_color = 250; // 244, 250
90  //missile.glow_size = 120;
91 
92  settouch(missile, W_Blaster_Touch);
93  missile.flags = FL_PROJECTILE;
94  IL_PUSH(g_projectiles, missile);
95  IL_PUSH(g_bot_dodge, missile);
96  missile.missile_flags = MIF_SPLASH;
97  missile.projectiledeathtype = atk_deathtype;
98  missile.weaponentity_fld = weaponentity;
99  setthink(missile, W_Blaster_Think);
100  missile.nextthink = time + atk_delay;
101 
102  MUTATOR_CALLHOOK(EditProjectile, actor, missile);
103 
104  if (time >= missile.nextthink)
105  {
106  getthink(missile)(missile);
107  }
108 }
109 
110 METHOD(Blaster, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
111 {
112  if(WEP_CVAR(blaster, secondary))
113  {
114  if((random() * (WEP_CVAR_PRI(blaster, damage) + WEP_CVAR_SEC(blaster, damage))) > WEP_CVAR_PRI(blaster, damage))
115  { PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_SEC(blaster, speed), 0, WEP_CVAR_SEC(blaster, lifetime), false); }
116  else
117  { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
118  }
119  else
120  { PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), false); }
121 }
122 
123 METHOD(Blaster, wr_think, void(Blaster thiswep, entity actor, .entity weaponentity, int fire))
124 {
125  if(fire & 1)
126  {
127  if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(blaster, refire)))
128  {
129  W_Blaster_Attack(
130  actor,
131  weaponentity,
132  WEP_BLASTER.m_id,
133  WEP_CVAR_PRI(blaster, shotangle),
134  WEP_CVAR_PRI(blaster, damage),
135  WEP_CVAR_PRI(blaster, edgedamage),
136  WEP_CVAR_PRI(blaster, radius),
137  WEP_CVAR_PRI(blaster, force),
138  WEP_CVAR_PRI(blaster, force_zscale),
139  WEP_CVAR_PRI(blaster, speed),
140  WEP_CVAR_PRI(blaster, spread),
141  WEP_CVAR_PRI(blaster, delay),
142  WEP_CVAR_PRI(blaster, lifetime)
143  );
144  weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(blaster, animtime), w_ready);
145  }
146  }
147  else if(fire & 2)
148  {
149  switch(WEP_CVAR(blaster, secondary))
150  {
151  case 0: // switch to last used weapon
152  {
153  if(actor.(weaponentity).m_switchweapon == WEP_BLASTER) // don't do this if already switching
154  W_LastWeapon(actor, weaponentity);
155  break;
156  }
157 
158  case 1: // normal projectile secondary
159  {
160  if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(blaster, refire)))
161  {
162  W_Blaster_Attack(
163  actor,
164  weaponentity,
165  WEP_BLASTER.m_id | HITTYPE_SECONDARY,
166  WEP_CVAR_SEC(blaster, shotangle),
167  WEP_CVAR_SEC(blaster, damage),
168  WEP_CVAR_SEC(blaster, edgedamage),
169  WEP_CVAR_SEC(blaster, radius),
170  WEP_CVAR_SEC(blaster, force),
171  WEP_CVAR_SEC(blaster, force_zscale),
172  WEP_CVAR_SEC(blaster, speed),
173  WEP_CVAR_SEC(blaster, spread),
174  WEP_CVAR_SEC(blaster, delay),
175  WEP_CVAR_SEC(blaster, lifetime)
176  );
177  weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(blaster, animtime), w_ready);
178  }
179 
180  break;
181  }
182  }
183  }
184 }
185 
186 METHOD(Blaster, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity))
187 {
188  return true; // infinite ammo
189 }
190 
191 METHOD(Blaster, wr_checkammo2, bool(entity thiswep, entity actor, .entity weaponentity))
192 {
193  return true; // blaster has infinite ammo
194 }
195 
196 METHOD(Blaster, wr_suicidemessage, Notification(entity thiswep))
197 {
198  return WEAPON_BLASTER_SUICIDE;
199 }
200 
201 METHOD(Blaster, wr_killmessage, Notification(entity thiswep))
202 {
203  return WEAPON_BLASTER_MURDER;
204 }
205 
206 METHOD(OffhandBlaster, offhand_think, void(OffhandBlaster this, entity actor, bool key_pressed))
207 {
208  if (!key_pressed || (time < actor.jump_interval))
209  {
210  return;
211  }
212  actor.jump_interval = time + WEP_CVAR_SEC(blaster, refire) * W_WeaponRateFactor(actor);
213  .entity weaponentity = weaponentities[1];
214  BLASTER_SECONDARY_ATTACK(blaster, actor, weaponentity);
215 }
216 
217 #endif
218 #ifdef CSQC
219 
220 METHOD(Blaster, wr_impacteffect, void(entity thiswep, entity actor))
221 {
222  vector org2;
223  org2 = w_org + w_backoff * 6;
224  pointparticles(EFFECT_BLASTER_IMPACT, org2, w_backoff * 1000, 1);
225  if(!w_issilent) { sound(actor, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); }
226 }
227 
228 #endif
#define WEP_CVAR_PRI(wepname, name)
Definition: all.qh:300
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition: player.qh:148
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 DEG2RAD
Definition: csprogsdefs.qc:961
float speed
Definition: subs.qh:41
vector w_shotorg
Definition: tracing.qh:18
#define PROJECTILE_MAKETRIGGER(e)
Definition: common.qh:29
#define getthink(e)
const int MIF_SPLASH
Definition: common.qh:34
entity() spawn
void w_ready(Weapon thiswep, entity actor,.entity weaponentity, int fire)
float radius
Definition: impulse.qh:11
vector maxs
Definition: csprogsdefs.qc:113
#define WEP_CVAR(wepname, name)
Definition: all.qh:299
vector w_shotdir
Definition: tracing.qh:19
entity weaponentity_fld
Definition: weaponsystem.qh:27
origin
Definition: ent_cs.qc:114
#define METHOD(cname, name, prototype)
Definition: oo.qh:257
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
const int PROJECTILE_BLASTER
Definition: projectiles.qh:11
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
void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float pSpeed, float pUpSpeed, float pZSpeed, float spread, float forceAbsolute)
Definition: tracing.qc:185
float lifetime
Definition: powerups.qc:23
vector mins
Definition: csprogsdefs.qc:113
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
vector v_up
Definition: csprogsdefs.qc:31
bool weapon_prepareattack(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
#define pointparticles
Definition: csprogsdefs.qh:13
float delay
Definition: subs.qh:38
#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
float nextthink
Definition: csprogsdefs.qc:121
#define W_SetupShot_Dir(ent, wepent, s_forward, antilag, recoil, snd, chan, maxdamage, deathtype)
Definition: tracing.qh:31
const int CH_SHOTS
Definition: sound.qh:14
vector(float skel, float bonenum) _skel_get_boneabs_hidden
IntrusiveList g_projectiles
Definition: common.qh:46
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)
entity realowner
Definition: common.qh:25
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
entity weaponentities[MAX_WEAPONSLOTS]
Definition: weapon.qh:14
setorigin(ent, v)
#define setthink(e, f)
float RadiusDamageForSource(entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, float forcezscale, int deathtype,.entity weaponentity, entity directhitentity)
Definition: damage.qc:866
#define sound(e, c, s, v, a)
Definition: sound.qh:52
float time
Definition: csprogsdefs.qc:16
vector velocity
Definition: csprogsdefs.qc:103
const int CH_WEAPON_B
Definition: sound.qh:8
float W_WeaponRateFactor(entity this)
Definition: weaponsystem.qc:33
void set_movetype(entity this, int mt)
float MOVETYPE_FLY
Definition: progsdefs.qc:251
var void func_null()
void W_LastWeapon(entity this,.entity weaponentity)
Definition: selection.qc:341
vector v_forward
Definition: csprogsdefs.qc:31
int projectiledeathtype
Definition: common.qh:20