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

Go to the source code of this file.

Functions

void electro_orb_draw (entity this)
bool electro_orb_send (entity this, entity to, int sf)
void electro_orb_setup (entity e)
 NET_HANDLE (Electro_Orb, bool isNew)
void W_Electro_Attack_Bolt (Weapon thiswep, entity actor,.entity weaponentity)
void W_Electro_Attack_Orb (Weapon thiswep, entity actor,.entity weaponentity)
void W_Electro_Bolt_Think (entity this)
void W_Electro_CheckAttack (Weapon thiswep, entity actor,.entity weaponentity, int fire)
void W_Electro_Explode (entity this, entity directhitentity)
void W_Electro_Explode_use (entity this, entity actor, entity trigger)
void W_Electro_ExplodeCombo (entity this)
void W_Electro_ExplodeComboThink (entity this)
void W_Electro_Orb_Damage (entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
void W_Electro_Orb_ExplodeOverTime (entity this)
void W_Electro_Orb_Follow_Think (entity this)
void W_Electro_Orb_Stick (entity this, entity to)
void W_Electro_Orb_Touch (entity this, entity toucher)
void W_Electro_TouchExplode (entity this, entity toucher)
void W_Electro_TriggerCombo (vector org, float rad, entity own)

Variables

float bot_secondary_electromooth
float ltime

Function Documentation

◆ electro_orb_draw()

void electro_orb_draw ( entity this)

Definition at line 8 of file electro.qc.

9{
10 float dt = time - this.move_time;
11 this.move_time = time;
12 if(dt <= 0)
13 return;
14
15 float myscale = bound(0, (this.ltime - time) * 4, 1);
16 this.scale = (WEP_CVAR(WEP_ELECTRO, combo_radius) * 0.05) * myscale;
17 this.angles = this.angles + dt * this.avelocity;
18}
vector avelocity
float time
ent angles
Definition ent_cs.qc:121
float bound(float min, float value, float max)
float move_time
Definition movetypes.qh:77
float ltime
Definition net.qc:10
float scale
Definition projectile.qc:14
#define WEP_CVAR(wep, name)
Definition all.qh:321

References angles, avelocity, bound(), entity(), ltime, move_time, scale, time, and WEP_CVAR.

Referenced by electro_orb_setup().

◆ electro_orb_send()

bool electro_orb_send ( entity this,
entity to,
int sf )

Definition at line 57 of file electro.qc.

58{
59 int channel = MSG_ENTITY;
60 WriteHeader(channel, Electro_Orb);
61 WriteByte(channel, sf);
62 if (sf & 1) {
63 WriteVector(channel, this.origin);
64
65 // round time delta to a 1/10th of a second
66 WriteByte(channel, (this.ltime - time)*10.0+0.5);
67 }
68 return true;
69}
vector origin
const int MSG_ENTITY
Definition net.qh:115
#define WriteHeader(to, id)
Definition net.qh:221
void WriteByte(float data, float dest, float desto)

References entity(), ltime, MSG_ENTITY, origin, time, WriteByte(), and WriteHeader.

Referenced by W_Electro_Orb_ExplodeOverTime().

◆ electro_orb_setup()

void electro_orb_setup ( entity e)

Definition at line 20 of file electro.qc.

21{
22 setmodel(e, MDL_PROJECTILE_ELECTRO);
23 setsize(e, '-4 -4 -4', '4 4 4');
24
25 setorigin(e, e.origin);
26
27 e.draw = electro_orb_draw;
29 SetResourceExplicit(e, RES_HEALTH, 255);
31 e.solid = SOLID_NOT;
32 e.avelocity = '7 0 11';
33 e.drawmask = MASK_NORMAL;
34 e.alpha = 0.7;
35}
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
IntrusiveList g_drawables
Definition main.qh:91
#define setmodel(this, m)
Definition model.qh:26
const float MASK_NORMAL
const float SOLID_NOT
void electro_orb_draw(entity this)
Definition electro.qc:8
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_NONE
Definition movetypes.qh:129

References electro_orb_draw(), entity(), g_drawables, IL_PUSH(), MASK_NORMAL, MOVETYPE_NONE, set_movetype(), setmodel, SetResourceExplicit(), and SOLID_NOT.

Referenced by NET_HANDLE().

◆ NET_HANDLE()

NET_HANDLE ( Electro_Orb ,
bool isNew )

Definition at line 41 of file electro.qc.

42{
43 Net_Accept(Electro_Orb);
44 int sf = ReadByte();
45 if (sf & 1) {
46 this.origin = ReadVector();
47 setorigin(this, this.origin);
48 this.ltime = time + ReadByte()/10.0;
49 // this.ltime = time + this.orb_lifetime;
51 }
52 return true;
53}
void electro_orb_setup(entity e)
Definition electro.qc:20
#define ReadVector()
Definition net.qh:367
#define Net_Accept(classname)
Definition net.qh:201
int ReadByte()

References electro_orb_setup(), ltime, Net_Accept, origin, ReadByte(), ReadVector, and time.

◆ W_Electro_Attack_Bolt()

void W_Electro_Attack_Bolt ( Weapon thiswep,
entity actor,
.entity weaponentity )

Definition at line 338 of file electro.qc.

339{
340 entity proj;
341
342 W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(WEP_ELECTRO, ammo), weaponentity);
343
345 actor,
346 weaponentity,
347 '0 0 -3',
348 '0 0 -3',
349 false,
350 2,
351 SND_ELECTRO_FIRE,
353 WEP_CVAR_PRI(WEP_ELECTRO, damage),
354 thiswep.m_id
355 );
356
357 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
358
359 proj = new(electro_bolt);
360 proj.owner = proj.realowner = actor;
361 proj.bot_dodge = true;
362 proj.bot_dodgerating = WEP_CVAR_PRI(WEP_ELECTRO, damage);
363 proj.use = W_Electro_Explode_use;
365 proj.nextthink = time;
366 proj.ltime = time + WEP_CVAR_PRI(WEP_ELECTRO, lifetime);
368 proj.projectiledeathtype = thiswep.m_id;
369 proj.weaponentity_fld = weaponentity;
370 setorigin(proj, w_shotorg);
371
372 // if (IS_CSQC)
374 W_SetupProjVelocity_PRI(proj, WEP_ELECTRO);
375 proj.angles = vectoangles(proj.velocity);
377 setsize(proj, '0 0 -3', '0 0 -3');
378 proj.flags = FL_PROJECTILE;
379 IL_PUSH(g_projectiles, proj);
380 IL_PUSH(g_bot_dodge, proj);
381 proj.missile_flags = MIF_SPLASH;
382
383 CSQCProjectile(proj, true, PROJECTILE_ELECTRO_BEAM, true);
384
385 MUTATOR_CALLHOOK(EditProjectile, actor, proj);
386 // proj.com_phys_pos = proj.origin;
387 // proj.com_phys_vel = proj.velocity;
388}
IntrusiveList g_bot_dodge
Definition api.qh:150
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
int m_id
Definition weapon.qh:45
float lifetime
Definition powerups.qc:23
const int FL_PROJECTILE
Definition constants.qh:85
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
void W_Electro_TouchExplode(entity this, entity toucher)
Definition electro.qc:256
void W_Electro_Explode_use(entity this, entity actor, entity trigger)
Definition electro.qc:251
void W_Electro_Bolt_Think(entity this)
Definition electro.qc:265
vector vectoangles(vector v)
const int MOVETYPE_FLY
Definition movetypes.qh:134
const int PROJECTILE_ELECTRO_BEAM
Definition projectiles.qh:7
#define setthink(e, f)
#define settouch(e, f)
Definition self.qh:73
const int MIF_SPLASH
Definition common.qh:46
IntrusiveList g_projectiles
Definition common.qh:58
#define PROJECTILE_MAKETRIGGER(e)
Definition common.qh:34
const int CH_WEAPON_A
Definition sound.qh:7
float ammo
Definition sv_turrets.qh:43
vector w_shotdir
Definition tracing.qh:20
#define W_SetupShot_ProjectileSize(ent, wepent, mi, ma, antilag, recoil, snd, chan, maxdamage, deathtype)
Definition tracing.qh:30
#define W_SetupProjVelocity_PRI(ent, wep)
Definition tracing.qh:65
vector w_shotorg
Definition tracing.qh:19
void W_MuzzleFlash(Weapon thiswep, entity actor,.entity weaponentity, vector shotorg, vector shotdir)
Definition all.qc:728
#define WEP_CVAR_PRI(wep, name)
Definition all.qh:322
void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use,.entity weaponentity)

References ammo, CH_WEAPON_A, CSQCProjectile(), entity(), FL_PROJECTILE, g_bot_dodge, g_projectiles, IL_PUSH(), lifetime, Weapon::m_id, MIF_SPLASH, MOVETYPE_FLY, MUTATOR_CALLHOOK, PROJECTILE_ELECTRO_BEAM, PROJECTILE_MAKETRIGGER, set_movetype(), setthink, settouch, time, vectoangles(), W_DecreaseAmmo(), W_Electro_Bolt_Think(), W_Electro_Explode_use(), W_Electro_TouchExplode(), W_MuzzleFlash(), W_SetupProjVelocity_PRI, W_SetupShot_ProjectileSize, w_shotdir, w_shotorg, and WEP_CVAR_PRI.

◆ W_Electro_Attack_Orb()

void W_Electro_Attack_Orb ( Weapon thiswep,
entity actor,
.entity weaponentity )

Definition at line 543 of file electro.qc.

544{
545 W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(WEP_ELECTRO, ammo), weaponentity);
546
548 actor,
549 weaponentity,
550 '-4 -4 -4',
551 '4 4 4',
552 false,
553 2,
554 SND_ELECTRO_FIRE2,
556 WEP_CVAR_SEC(WEP_ELECTRO, damage),
557 thiswep.m_id | HITTYPE_SECONDARY
558 );
559
560 w_shotdir = v_forward; // no TrueAim for grenades please
561
562 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
563
564 entity proj = new(electro_orb);
565 proj.owner = proj.realowner = actor;
566 proj.use = W_Electro_Explode_use;
568 proj.bot_dodge = true;
569 proj.bot_dodgerating = WEP_CVAR_SEC(WEP_ELECTRO, damage);
570 proj.nextthink = time + WEP_CVAR_SEC(WEP_ELECTRO, lifetime);
571 proj.death_time = time + WEP_CVAR_SEC(WEP_ELECTRO, lifetime);
573 proj.projectiledeathtype = thiswep.m_id | HITTYPE_SECONDARY;
574 proj.weaponentity_fld = weaponentity;
575 setorigin(proj, w_shotorg);
576
577 //proj.glow_size = 50;
578 //proj.glow_color = 45;
580 W_SetupProjVelocity_UP_SEC(proj, WEP_ELECTRO);
582 setsize(proj, '-4 -4 -4', '4 4 4');
583 proj.takedamage = DAMAGE_YES;
584 proj.damageforcescale = WEP_CVAR_SEC(WEP_ELECTRO, damageforcescale);
585 SetResourceExplicit(proj, RES_HEALTH, WEP_CVAR_SEC(WEP_ELECTRO, health));
586 proj.event_damage = W_Electro_Orb_Damage;
587 proj.flags = FL_PROJECTILE;
588 IL_PUSH(g_projectiles, proj);
589 IL_PUSH(g_bot_dodge, proj);
590 proj.damagedbycontents = (WEP_CVAR_SEC(WEP_ELECTRO, damagedbycontents));
591 if(proj.damagedbycontents)
593
594 proj.bouncefactor = WEP_CVAR_SEC(WEP_ELECTRO, bouncefactor);
595 proj.bouncestop = WEP_CVAR_SEC(WEP_ELECTRO, bouncestop);
596 proj.missile_flags = MIF_SPLASH | MIF_ARC;
597
598 if(WEP_CVAR_SEC(WEP_ELECTRO, limit) > 0)
599 {
604 }
605
606 CSQCProjectile(proj, true, PROJECTILE_ELECTRO, false); // no culling, it has sound
607
608 MUTATOR_CALLHOOK(EditProjectile, actor, proj);
609}
vector v_forward
float damagedbycontents
Definition damage.qh:45
IntrusiveList g_damagedbycontents
Definition damage.qh:135
float damageforcescale
const int HITTYPE_SECONDARY
Definition all.qh:29
void W_Electro_Orb_Touch(entity this, entity toucher)
Definition electro.qc:484
void W_Electro_Orb_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition electro.qc:507
IntrusiveList LimitedElectroBallRubbleList
Definition electro.qh:96
#define IL_NEW()
float bouncefactor
Definition movetypes.qh:47
float bouncestop
Definition movetypes.qh:46
const int MOVETYPE_BOUNCE
Definition movetypes.qh:139
const int PROJECTILE_ELECTRO
Definition projectiles.qh:3
float health
Legacy fields for the resources. To be removed.
Definition resources.qh:9
void LimitedChildrenRubble(IntrusiveList list, string cname, int limit, void(entity) deleteproc, entity parent)
Definition rubble.qc:5
entity ListNewChildRubble(IntrusiveList list, entity child)
Definition rubble.qc:46
void adaptor_think2use_hittype_splash(entity this)
Definition common.qc:106
const int MIF_ARC
Definition common.qh:47
const int DAMAGE_YES
Definition subs.qh:80
#define W_SetupProjVelocity_UP_SEC(ent, wep)
Definition tracing.qh:56
#define WEP_CVAR_SEC(wep, name)
Definition all.qh:323

References adaptor_think2use_hittype_splash(), ammo, bouncefactor, bouncestop, CH_WEAPON_A, CSQCProjectile(), DAMAGE_YES, damagedbycontents, damageforcescale, entity(), FL_PROJECTILE, g_bot_dodge, g_damagedbycontents, g_projectiles, health, HITTYPE_SECONDARY, IL_NEW, IL_PUSH(), lifetime, LimitedChildrenRubble(), LimitedElectroBallRubbleList, ListNewChildRubble(), Weapon::m_id, MIF_ARC, MIF_SPLASH, MOVETYPE_BOUNCE, MUTATOR_CALLHOOK, PROJECTILE_ELECTRO, PROJECTILE_MAKETRIGGER, set_movetype(), SetResourceExplicit(), setthink, settouch, time, v_forward, W_DecreaseAmmo(), W_Electro_Explode_use(), W_Electro_Orb_Damage(), W_Electro_Orb_Touch(), W_MuzzleFlash(), W_SetupProjVelocity_UP_SEC, W_SetupShot_ProjectileSize, w_shotdir, w_shotorg, and WEP_CVAR_SEC.

Referenced by W_Electro_CheckAttack().

◆ W_Electro_Bolt_Think()

void W_Electro_Bolt_Think ( entity this)

Definition at line 265 of file electro.qc.

266{
267 // sys_phys_update_single(this);
268 if(time >= this.ltime)
269 {
270 this.use(this, NULL, NULL);
271 return;
272 }
273
274 if(WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_radius))
275 {
276 float found = 0;
277 entity e = WarpZone_FindRadius(this.origin, WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_radius), true);
278
279 // loop through nearby orbs and trigger them
280 while(e)
281 {
282 if(e.classname == "electro_orb")
283 {
284 // check if the ball we are exploding is not owned by an
285 // independent player which is not the player who shot the ball
286 if(IS_INDEPENDENT_PLAYER(e.realowner) && this.realowner != e.realowner)
287 {
288 e = e.chain;
289 continue;
290 }
291 bool explode;
292 if (this.owner == e.owner)
293 {
294 explode = WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_own);
295 }
296 else if (SAME_TEAM(this.owner, e.owner))
297 {
298 explode = WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_teammate);
299 }
300 else
301 {
302 explode = WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_enemy);
303 }
304
305 if (explode)
306 {
307 // change owner to whoever caused the combo explosion
308 e.realowner = this.realowner;
309 e.takedamage = DAMAGE_NO;
310 e.classname = "electro_orb_chain";
311
312 // Only first orb explosion uses midaircombo_speed, others use the normal combo_speed.
313 // This allows to avoid the delay on the first explosion which looks better
314 // (the bolt and orb should explode together because they interacted together)
315 // while keeping the chaining delay.
317 float delay = 0;
318 if (WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_speed))
319 delay = vlen(e.WarpZone_findradius_dist) / WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_speed);
320 e.nextthink = time + delay;
321
322 ++found;
323 }
324 }
325 e = e.chain;
326 }
327
328 // if we triggered an orb, should we explode? if not, lets try again next time
329 if(found && WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_explode))
330 { this.use(this, NULL, NULL); }
331 else
332 { this.nextthink = min(time + WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_interval), this.ltime); }
333 }
334 else { this.nextthink = this.ltime; }
335 // this.nextthink = time;
336}
float delay
Definition items.qc:17
entity owner
Definition main.qh:87
float nextthink
#define use
void W_Electro_ExplodeCombo(entity this)
Definition electro.qc:167
entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
Definition common.qc:686
float vlen(vector v)
float min(float f,...)
#define NULL
Definition post.qh:14
#define IS_INDEPENDENT_PLAYER(e)
Definition client.qh:312
const int DAMAGE_NO
Definition subs.qh:79
#define SAME_TEAM(a, b)
Definition teams.qh:241
entity realowner

References DAMAGE_NO, delay, entity(), IS_INDEPENDENT_PLAYER, ltime, min(), nextthink, NULL, origin, owner, realowner, SAME_TEAM, setthink, time, use, vlen(), W_Electro_ExplodeCombo(), WarpZone_FindRadius(), and WEP_CVAR_PRI.

Referenced by W_Electro_Attack_Bolt().

◆ W_Electro_CheckAttack()

void W_Electro_CheckAttack ( Weapon thiswep,
entity actor,
.entity weaponentity,
int fire )

Definition at line 611 of file electro.qc.

612{
613 if(actor.(weaponentity).electro_count > 1)
614 if(PHYS_INPUT_BUTTON_ATCK2(actor))
615 if(weapon_prepareattack(thiswep, actor, weaponentity, true, -1))
616 {
617 W_Electro_Attack_Orb(thiswep, actor, weaponentity);
618 actor.(weaponentity).electro_count -= 1;
619 actor.(weaponentity).electro_secondarytime = time;
620 weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_ELECTRO, animtime), W_Electro_CheckAttack);
621 return;
622 }
623 w_ready(thiswep, actor, weaponentity, fire);
624}
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition player.qh:152
void W_Electro_Attack_Orb(Weapon thiswep, entity actor,.entity weaponentity)
Definition electro.qc:543
void W_Electro_CheckAttack(Weapon thiswep, entity actor,.entity weaponentity, int fire)
Definition electro.qc:611
float electro_count
Definition electro.qh:97
float electro_secondarytime
Definition electro.qh:98
void weapon_thinkf(entity actor,.entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor,.entity weaponentity, int fire) func)
bool weapon_prepareattack(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
void w_ready(Weapon thiswep, entity actor,.entity weaponentity, int fire)

References electro_count, electro_secondarytime, entity(), PHYS_INPUT_BUTTON_ATCK2, time, W_Electro_Attack_Orb(), W_Electro_CheckAttack(), w_ready(), weapon_prepareattack(), weapon_thinkf(), and WEP_CVAR_SEC.

Referenced by W_Electro_CheckAttack().

◆ W_Electro_Explode()

void W_Electro_Explode ( entity this,
entity directhitentity )

Definition at line 200 of file electro.qc.

201{
202 if(directhitentity.takedamage == DAMAGE_AIM)
203 if(IS_PLAYER(directhitentity))
204 if(DIFF_TEAM(this.realowner, directhitentity))
205 if(!IS_DEAD(directhitentity))
206 if(IsFlying(directhitentity))
207 Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
208
209 this.event_damage = func_null;
210 this.takedamage = DAMAGE_NO;
211 if (!this.velocity)
212 this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work
213
214 if(this.move_movetype == MOVETYPE_BOUNCE || this.classname == "electro_orb") // TODO: classname is more reliable anyway?
215 {
217 this,
218 this.realowner,
219 WEP_CVAR_SEC(WEP_ELECTRO, damage),
220 WEP_CVAR_SEC(WEP_ELECTRO, edgedamage),
221 WEP_CVAR_SEC(WEP_ELECTRO, radius),
222 NULL,
223 NULL,
224 WEP_CVAR_SEC(WEP_ELECTRO, force),
226 this.weaponentity_fld,
227 directhitentity
228 );
229 }
230 else
231 {
232 W_Electro_TriggerCombo(this.origin, WEP_CVAR_PRI(WEP_ELECTRO, comboradius), this.realowner);
234 this,
235 this.realowner,
236 WEP_CVAR_PRI(WEP_ELECTRO, damage),
237 WEP_CVAR_PRI(WEP_ELECTRO, edgedamage),
238 WEP_CVAR_PRI(WEP_ELECTRO, radius),
239 NULL,
240 NULL,
241 WEP_CVAR_PRI(WEP_ELECTRO, force),
243 this.weaponentity_fld,
244 directhitentity
245 );
246 }
247
248 delete(this);
249}
float radius
Definition impulse.qh:11
bool IsFlying(entity this)
Definition player.qc:836
#define IS_DEAD(s)
Definition player.qh:245
#define IS_PLAYER(s)
Definition player.qh:243
string classname
vector velocity
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:981
void W_Electro_TriggerCombo(vector org, float rad, entity own)
Definition electro.qc:77
vector movedir
Definition viewloc.qh:18
float move_movetype
Definition movetypes.qh:76
var void func_null()
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1573
int projectiledeathtype
Definition common.qh:21
const int DAMAGE_AIM
Definition subs.qh:81
float takedamage
Definition subs.qh:78
#define DIFF_TEAM(a, b)
Definition teams.qh:242
entity weaponentity_fld

References classname, DAMAGE_AIM, DAMAGE_NO, DIFF_TEAM, entity(), func_null(), IS_DEAD, IS_PLAYER, IsFlying(), move_movetype, movedir, MOVETYPE_BOUNCE, NULL, origin, projectiledeathtype, radius, RadiusDamage(), realowner, Send_Notification(), takedamage, velocity, W_Electro_TriggerCombo(), weaponentity_fld, WEP_CVAR_PRI, and WEP_CVAR_SEC.

Referenced by W_Electro_Explode_use(), W_Electro_Orb_Touch(), and W_Electro_TouchExplode().

◆ W_Electro_Explode_use()

void W_Electro_Explode_use ( entity this,
entity actor,
entity trigger )

Definition at line 251 of file electro.qc.

252{
253 W_Electro_Explode(this, trigger);
254}
void W_Electro_Explode(entity this, entity directhitentity)
Definition electro.qc:200

References entity(), and W_Electro_Explode().

Referenced by W_Electro_Attack_Bolt(), W_Electro_Attack_Orb(), and W_Electro_Orb_Damage().

◆ W_Electro_ExplodeCombo()

void W_Electro_ExplodeCombo ( entity this)

Definition at line 167 of file electro.qc.

168{
169 W_Electro_TriggerCombo(this.origin, WEP_CVAR(WEP_ELECTRO, combo_comboradius), this.realowner);
170
171 this.event_damage = func_null;
172 if (!this.velocity)
173 this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work
174
175 if(WEP_CVAR(WEP_ELECTRO, combo_duration))
176 {
178
179 delete(this);
180 return;
181 }
182
184 this,
185 this.realowner,
186 WEP_CVAR(WEP_ELECTRO, combo_damage),
187 WEP_CVAR(WEP_ELECTRO, combo_edgedamage),
188 WEP_CVAR(WEP_ELECTRO, combo_radius),
189 NULL,
190 NULL,
191 WEP_CVAR(WEP_ELECTRO, combo_force),
192 WEP_ELECTRO.m_id | HITTYPE_BOUNCE, // use THIS type for a combo because primary can't bounce
193 this.weaponentity_fld,
194 NULL
195 );
196
197 delete(this);
198}
const int HITTYPE_BOUNCE
Definition all.qh:31
void W_Electro_Orb_ExplodeOverTime(entity this)
Definition electro.qc:142

References entity(), func_null(), HITTYPE_BOUNCE, movedir, NULL, origin, RadiusDamage(), realowner, velocity, W_Electro_Orb_ExplodeOverTime(), W_Electro_TriggerCombo(), and WEP_CVAR.

Referenced by W_Electro_Bolt_Think(), W_Electro_Orb_Damage(), and W_Electro_TriggerCombo().

◆ W_Electro_ExplodeComboThink()

void W_Electro_ExplodeComboThink ( entity this)

Definition at line 125 of file electro.qc.

126{
127 if(time >= this.ltime)
128 {
129 delete(this);
130 return;
131 }
132
133 this.nextthink = time;
134
135 float damage = WEP_CVAR(WEP_ELECTRO, combo_damage) * PHYS_INPUT_TIMELENGTH;
136 float edgedamage = WEP_CVAR(WEP_ELECTRO, combo_edgedamage) * PHYS_INPUT_TIMELENGTH;
137
138 RadiusDamage(this, this.realowner, damage, edgedamage, WEP_CVAR(WEP_ELECTRO, combo_radius), NULL, NULL, 0, this.projectiledeathtype, this.weaponentity_fld, NULL);
139 this.projectiledeathtype |= HITTYPE_SPAM; // ensure it doesn't spam its effect
140}
#define PHYS_INPUT_TIMELENGTH
Definition player.qh:254
const int HITTYPE_SPAM
Definition all.qh:34

References entity(), HITTYPE_SPAM, ltime, nextthink, NULL, PHYS_INPUT_TIMELENGTH, projectiledeathtype, RadiusDamage(), realowner, time, weaponentity_fld, and WEP_CVAR.

Referenced by W_Electro_Orb_ExplodeOverTime().

◆ W_Electro_Orb_Damage()

void W_Electro_Orb_Damage ( entity this,
entity inflictor,
entity attacker,
float damage,
int deathtype,
.entity weaponentity,
vector hitloc,
vector force )

Definition at line 507 of file electro.qc.

508{
509 if(GetResource(this, RES_HEALTH) <= 0)
510 return;
511
512 // note: combos are usually triggered by W_Electro_TriggerCombo, not damage
513 float is_combo = (inflictor.classname == "electro_orb_chain" || inflictor.classname == "electro_bolt");
514
515 if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, (is_combo ? 1 : -1)))
516 return; // g_projectiles_damage says to halt
517
518 TakeResource(this, RES_HEALTH, damage);
519 if(GetResource(this, RES_HEALTH) <= 0)
520 {
521 this.takedamage = DAMAGE_NO;
522 this.nextthink = time;
523 if(is_combo)
524 {
525 // change owner to whoever caused the combo explosion
526 this.realowner = inflictor.realowner;
527 this.classname = "electro_orb_chain";
529 // delay combo chains, looks cooler
530 // bound the length, inflictor may be in a galaxy far far away (warpzones)
531 float len = min(WEP_CVAR(WEP_ELECTRO, combo_radius), vlen(this.origin - inflictor.origin));
532 float delay = len / WEP_CVAR(WEP_ELECTRO, combo_speed);
533 this.nextthink = time + delay;
534 }
535 else
536 {
538 setthink(this, adaptor_think2use); // not _hittype_splash, as this runs "immediately"
539 }
540 }
541}
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.
float W_CheckProjectileDamage(entity inflictor, entity projowner, int deathtype, float exception)
Definition common.qc:45

References classname, DAMAGE_NO, delay, entity(), GetResource(), min(), nextthink, origin, realowner, setthink, takedamage, TakeResource(), time, use, vector, vlen(), W_CheckProjectileDamage(), W_Electro_Explode_use(), W_Electro_ExplodeCombo(), and WEP_CVAR.

Referenced by W_Electro_Attack_Orb().

◆ W_Electro_Orb_ExplodeOverTime()

void W_Electro_Orb_ExplodeOverTime ( entity this)

Definition at line 142 of file electro.qc.

143{
144 entity newproj = spawn();
145 newproj.classname = this.classname;
146 newproj.solid = this.solid;
147 setorigin(newproj, this.origin);
148 setmodel(newproj, MDL_PROJECTILE_ELECTRO);
149 setsize(newproj, this.mins, this.maxs);
150 newproj.owner = this.owner;
151 newproj.realowner = this.realowner;
152 newproj.weaponentity_fld = this.weaponentity_fld;
153 newproj.projectiledeathtype = WEP_ELECTRO.m_id | HITTYPE_BOUNCE; // use THIS type for a combo because primary can't bounce
154
156 newproj.nextthink = time;
157 newproj.ltime = time + WEP_CVAR(WEP_ELECTRO, combo_duration);
158 set_movetype(newproj, MOVETYPE_NONE);
159
160 Net_LinkEntity(newproj, true, 0, electro_orb_send);
161 newproj.SendFlags |= 1;
162
163 // fire the first damage tick immediately
164 getthink(newproj)(newproj);
165}
vector mins
vector maxs
#define spawn
bool electro_orb_send(entity this, entity to, int sf)
Definition electro.qc:57
void W_Electro_ExplodeComboThink(entity this)
Definition electro.qc:125
solid
Definition ent_cs.qc:165
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
Definition net.qh:123
#define getthink(e)

References classname, electro_orb_send(), entity(), getthink, HITTYPE_BOUNCE, maxs, mins, MOVETYPE_NONE, Net_LinkEntity(), origin, owner, realowner, set_movetype(), setmodel, setthink, solid, spawn, time, W_Electro_ExplodeComboThink(), weaponentity_fld, and WEP_CVAR.

Referenced by W_Electro_ExplodeCombo().

◆ W_Electro_Orb_Follow_Think()

void W_Electro_Orb_Follow_Think ( entity this)

Definition at line 390 of file electro.qc.

391{
392 if (time > this.death_time)
393 {
395 return;
396 }
397 if (this.move_movetype == MOVETYPE_FOLLOW)
398 {
399 int lost = LostMovetypeFollow(this);
400 if (lost == 2)
401 {
402 // FIXME if player disconnected, it isn't possible to drop the orb at player's origin
403 // see comment in LostMovetypeFollow implementation
404 delete(this);
405 return;
406 }
407 if (lost)
408 {
409 // drop the orb at the corpse's location
412
414 this.nextthink = this.death_time;
415 return;
416 }
417 }
418 this.nextthink = time;
419}
int LostMovetypeFollow(entity ent)
Definition util.qc:2063
float death_time
const int MOVETYPE_FOLLOW
Definition movetypes.qh:141
const int MOVETYPE_TOSS
Definition movetypes.qh:135

References adaptor_think2use_hittype_splash(), death_time, entity(), LostMovetypeFollow(), move_movetype, MOVETYPE_FOLLOW, MOVETYPE_TOSS, nextthink, PROJECTILE_MAKETRIGGER, set_movetype(), setthink, and time.

Referenced by W_Electro_Orb_Stick().

◆ W_Electro_Orb_Stick()

void W_Electro_Orb_Stick ( entity this,
entity to )

Definition at line 421 of file electro.qc.

422{
423 entity newproj = spawn();
424 newproj.classname = this.classname;
425
426 newproj.bot_dodge = this.bot_dodge;
427 newproj.bot_dodgerating = this.bot_dodgerating;
428
429 newproj.owner = this.owner;
430 newproj.realowner = this.realowner;
431 PROJECTILE_MAKETRIGGER(newproj);
432 setorigin(newproj, this.origin);
433 setmodel(newproj, MDL_PROJECTILE_ELECTRO);
434 setsize(newproj, this.mins, this.maxs);
435 newproj.angles = vectoangles(-trace_plane_normal); // face against the surface
436 newproj.traileffectnum = _particleeffectnum(EFFECT_TR_NEXUIZPLASMA.eent_eff_name);
437
438 newproj.movedir = -trace_plane_normal;
439
440 newproj.takedamage = this.takedamage;
441 newproj.damageforcescale = this.damageforcescale;
442 SetResourceExplicit(newproj, RES_HEALTH, GetResource(this, RES_HEALTH));
443 newproj.event_damage = this.event_damage;
444 newproj.spawnshieldtime = this.spawnshieldtime;
445 newproj.damagedbycontents = true;
447
448 set_movetype(newproj, MOVETYPE_NONE); // lock the orb in place
449 newproj.projectiledeathtype = this.projectiledeathtype;
450 newproj.weaponentity_fld = this.weaponentity_fld;
451
452 settouch(newproj, func_null);
453 if(WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime) > 0)
454 newproj.death_time = time + WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime);
455 else
456 newproj.death_time = this.death_time;
457 newproj.use = this.use;
458 newproj.flags = this.flags;
459 IL_PUSH(g_projectiles, newproj);
460 IL_PUSH(g_bot_dodge, newproj);
461
462 // check if limits are enabled (we can tell by checking if the original orb is listed) and push it to the list if so
464 {
466 }
467
468 delete(this);
469
470 if(to)
471 {
472 SetMovetypeFollow(newproj, to);
473
475 newproj.nextthink = time;
476 }
477 else
478 {
480 newproj.nextthink = newproj.death_time;
481 }
482}
float bot_dodge
Definition api.qh:40
float bot_dodgerating
Definition api.qh:39
void SetMovetypeFollow(entity ent, entity e)
Definition util.qc:2033
float flags
vector trace_plane_normal
float spawnshieldtime
Definition damage.qh:61
void W_Electro_Orb_Follow_Think(entity this)
Definition electro.qc:390
ERASEABLE bool IL_CONTAINS(IntrusiveList this, entity it)
entity ReplaceOldListedChildRubble(IntrusiveList list, entity child, entity oldChild)
Definition rubble.qc:39

References adaptor_think2use_hittype_splash(), bot_dodge, bot_dodgerating, classname, damageforcescale, death_time, entity(), flags, func_null(), g_bot_dodge, g_damagedbycontents, g_projectiles, GetResource(), IL_CONTAINS(), IL_PUSH(), LimitedElectroBallRubbleList, maxs, mins, MOVETYPE_NONE, origin, owner, PROJECTILE_MAKETRIGGER, projectiledeathtype, realowner, ReplaceOldListedChildRubble(), set_movetype(), setmodel, SetMovetypeFollow(), SetResourceExplicit(), setthink, settouch, spawn, spawnshieldtime, takedamage, time, trace_plane_normal, use, vectoangles(), W_Electro_Orb_Follow_Think(), weaponentity_fld, and WEP_CVAR_SEC.

Referenced by W_Electro_Orb_Touch().

◆ W_Electro_Orb_Touch()

void W_Electro_Orb_Touch ( entity this,
entity toucher )

Definition at line 484 of file electro.qc.

485{
487 if(toucher.takedamage == DAMAGE_AIM && WEP_CVAR_SEC(WEP_ELECTRO, touchexplode))
488 {
490 }
491 else if(toucher.owner != this.owner && toucher.classname != this.classname) // don't stick to player's other projectiles!
492 {
493 //UpdateCSQCProjectile(this);
494 spamsound(this, CH_SHOTS, SND_ELECTRO_BOUNCE, VOL_BASE, ATTEN_NORM);
496
497 if(WEP_CVAR_SEC(WEP_ELECTRO, stick))
498 {
499 if(WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime) == 0)
501 else
503 }
504 }
505}
void W_Electro_Orb_Stick(entity this, entity to)
Definition electro.qc:421
entity entity toucher
Definition self.qh:72
#define PROJECTILE_TOUCH(e, t)
Definition common.qh:28
const float VOL_BASE
Definition sound.qh:36
const int CH_SHOTS
Definition sound.qh:14
const float ATTEN_NORM
Definition sound.qh:30
float spamsound(entity e, int chan, Sound samp, float vol, float _atten)
use this one if you might be causing spam (e.g.
Definition all.qc:124

References ATTEN_NORM, CH_SHOTS, DAMAGE_AIM, entity(), HITTYPE_BOUNCE, PROJECTILE_TOUCH, projectiledeathtype, spamsound(), toucher, VOL_BASE, W_Electro_Explode(), W_Electro_Orb_Stick(), and WEP_CVAR_SEC.

Referenced by W_Electro_Attack_Orb().

◆ W_Electro_TouchExplode()

void W_Electro_TouchExplode ( entity this,
entity toucher )

Definition at line 256 of file electro.qc.

257{
260}

References entity(), PROJECTILE_TOUCH, toucher, and W_Electro_Explode().

Referenced by W_Electro_Attack_Bolt().

◆ W_Electro_TriggerCombo()

void W_Electro_TriggerCombo ( vector org,
float rad,
entity own )

Definition at line 77 of file electro.qc.

78{
79 entity e = WarpZone_FindRadius(org, rad, !WEP_CVAR(WEP_ELECTRO, combo_comboradius_thruwall));
80 while(e)
81 {
82 if(e.classname == "electro_orb")
83 {
84 // check if the ball we are exploding is not owned by an
85 // independent player which is not the player who shot the ball
86 if(IS_INDEPENDENT_PLAYER(e.realowner) && own != e.realowner)
87 {
88 e = e.chain;
89 continue;
90 }
91 // do we allow thruwall triggering?
92 if(WEP_CVAR(WEP_ELECTRO, combo_comboradius_thruwall))
93 {
94 // if distance is greater than thruwall distance, check to make sure it's not through a wall
95 if(vdist(e.WarpZone_findradius_dist, >, WEP_CVAR(WEP_ELECTRO, combo_comboradius_thruwall)))
96 {
98 if(trace_fraction != 1)
99 {
100 // trigger is through a wall and outside of thruwall range, abort
101 e = e.chain;
102 continue;
103 }
104 }
105 }
106
107 // change owner to whoever caused the combo explosion
108 e.realowner = own;
109 e.takedamage = DAMAGE_NO;
110 e.classname = "electro_orb_chain";
111
112 // now set the next one to trigger as well
114
115 // delay combo chains, looks cooler
116 float delay = 0;
117 if (WEP_CVAR(WEP_ELECTRO, combo_speed))
118 delay = vlen(e.WarpZone_findradius_dist) / WEP_CVAR(WEP_ELECTRO, combo_speed);
119 e.nextthink = time + delay;
120 }
121 e = e.chain;
122 }
123}
const float MOVE_NOMONSTERS
float trace_fraction
void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
Definition common.qc:348
vector org
Definition self.qh:92
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8

References DAMAGE_NO, delay, entity(), IS_INDEPENDENT_PLAYER, MOVE_NOMONSTERS, org, setthink, time, trace_fraction, vdist, vector, vlen(), W_Electro_ExplodeCombo(), WarpZone_FindRadius(), WarpZone_TraceLine(), and WEP_CVAR.

Referenced by W_Electro_Explode(), and W_Electro_ExplodeCombo().

Variable Documentation

◆ bot_secondary_electromooth

float bot_secondary_electromooth

Definition at line 626 of file electro.qc.

◆ ltime

float ltime

Definition at line 7 of file electro.qc.