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

bool 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 += dt * this.avelocity;
18}
float ltime
Definition net.qh:10
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 scale
Definition projectile.qc:14
#define WEP_CVAR(wep, name)
Definition all.qh:337

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 54 of file electro.qc.

55{
56 int channel = MSG_ENTITY;
57 WriteHeader(channel, Electro_Orb);
58 WriteVector(channel, this.origin);
59 // round time delta to a 1/10th of a second
60 WriteByte(channel, (this.ltime - time) * 10 + 0.5);
61 return true;
62}
vector origin
const int MSG_ENTITY
Definition net.qh:156
#define WriteHeader(to, id)
Definition net.qh:265
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 this.origin = ReadVector();
45 setorigin(this, this.origin);
46 this.ltime = time + ReadByte() / 10.0;
47 // this.ltime = time + this.orb_lifetime;
49 return true;
50}
void electro_orb_setup(entity e)
Definition electro.qc:20
#define ReadVector()
Definition net.qh:350
int ReadByte()

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

◆ W_Electro_Attack_Bolt()

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

Definition at line 312 of file electro.qc.

313{
314 W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(WEP_ELECTRO, ammo), weaponentity);
315
317 actor,
318 weaponentity,
319 '0 0 -3',
320 '0 0 -3',
321 false,
322 2,
323 SND_ELECTRO_FIRE,
325 WEP_CVAR_PRI(WEP_ELECTRO, damage),
326 thiswep.m_id
327 );
328
329 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
330
331 entity proj = new(electro_bolt);
332 proj.owner = proj.realowner = actor;
333 proj.bot_dodge = true;
334 proj.bot_dodgerating = WEP_CVAR_PRI(WEP_ELECTRO, damage);
335 proj.use = W_Electro_Explode_use;
337 proj.nextthink = time;
338 proj.ltime = time + WEP_CVAR_PRI(WEP_ELECTRO, lifetime);
340 proj.projectiledeathtype = thiswep.m_id;
341 proj.weaponentity_fld = weaponentity;
342 setorigin(proj, w_shotorg);
343
344 // if (IS_CSQC)
346 W_SetupProjVelocity_PRI(proj, WEP_ELECTRO);
347 proj.angles = vectoangles(proj.velocity);
349 setsize(proj, '0 0 -3', '0 0 -3');
350 proj.flags = FL_PROJECTILE;
351 IL_PUSH(g_projectiles, proj);
352 IL_PUSH(g_bot_dodge, proj);
353 proj.missile_flags = MIF_SPLASH;
354
355 CSQCProjectile(proj, true, PROJECTILE_ELECTRO_BEAM, true);
356
357 MUTATOR_CALLHOOK(EditProjectile, actor, proj);
358 // proj.com_phys_pos = proj.origin;
359 // proj.com_phys_vel = proj.velocity;
360}
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:43
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:240
void W_Electro_Explode_use(entity this, entity actor, entity trigger)
Definition electro.qc:235
void W_Electro_Bolt_Think(entity this)
Definition electro.qc:249
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:67
vector w_shotorg
Definition tracing.qh:19
void W_MuzzleFlash(Weapon thiswep, entity actor,.entity weaponentity, vector shotorg, vector shotdir)
Definition all.qc:715
#define WEP_CVAR_PRI(wep, name)
Definition all.qh:338
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 511 of file electro.qc.

512{
513 W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(WEP_ELECTRO, ammo), weaponentity);
514
516 actor,
517 weaponentity,
518 '-4 -4 -4',
519 '4 4 4',
520 false,
521 2,
522 SND_ELECTRO_FIRE2,
524 WEP_CVAR_SEC(WEP_ELECTRO, damage),
525 thiswep.m_id | HITTYPE_SECONDARY
526 );
527
528 w_shotdir = v_forward; // no TrueAim for grenades please
529
530 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
531
532 entity proj = new(electro_orb);
533 proj.owner = proj.realowner = actor;
534 proj.use = W_Electro_Explode_use;
536 proj.bot_dodge = true;
537 proj.bot_dodgerating = WEP_CVAR_SEC(WEP_ELECTRO, damage);
538 proj.nextthink = time + WEP_CVAR_SEC(WEP_ELECTRO, lifetime);
539 proj.death_time = time + WEP_CVAR_SEC(WEP_ELECTRO, lifetime);
541 proj.projectiledeathtype = thiswep.m_id | HITTYPE_SECONDARY;
542 proj.weaponentity_fld = weaponentity;
543 setorigin(proj, w_shotorg);
544
545 //proj.glow_size = 50;
546 //proj.glow_color = 45;
548 W_SetupProjVelocity_UP_SEC(proj, WEP_ELECTRO);
550 setsize(proj, '-4 -4 -4', '4 4 4');
551 proj.takedamage = DAMAGE_YES;
552 proj.damageforcescale = WEP_CVAR_SEC(WEP_ELECTRO, damageforcescale);
553 SetResourceExplicit(proj, RES_HEALTH, WEP_CVAR_SEC(WEP_ELECTRO, health));
554 proj.event_damage = W_Electro_Orb_Damage;
555 proj.flags = FL_PROJECTILE;
556 IL_PUSH(g_projectiles, proj);
557 IL_PUSH(g_bot_dodge, proj);
558 proj.damagedbycontents = (WEP_CVAR_SEC(WEP_ELECTRO, damagedbycontents));
559 if (proj.damagedbycontents)
561
562 proj.bouncefactor = WEP_CVAR_SEC(WEP_ELECTRO, bouncefactor);
563 proj.bouncestop = WEP_CVAR_SEC(WEP_ELECTRO, bouncestop);
564 proj.missile_flags = MIF_SPLASH | MIF_ARC;
565
566 if (WEP_CVAR_SEC(WEP_ELECTRO, limit) > 0)
567 {
572 }
573
574 CSQCProjectile(proj, true, PROJECTILE_ELECTRO, false); // no culling, it has sound
575
576 MUTATOR_CALLHOOK(EditProjectile, actor, proj);
577}
vector v_forward
float damagedbycontents
Definition damage.qh:45
IntrusiveList g_damagedbycontents
Definition damage.qh:143
float damageforcescale
const int HITTYPE_SECONDARY
Definition all.qh:29
void W_Electro_Orb_Touch(entity this, entity toucher)
Definition electro.qc:454
void W_Electro_Orb_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition electro.qc:475
IntrusiveList LimitedElectroBallRubbleList
Definition electro.qh:100
#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:339

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 249 of file electro.qc.

250{
251 // sys_phys_update_single(this);
252 if (time >= this.ltime)
253 {
254 this.use(this, NULL, NULL);
255 return;
256 }
257
258 if (WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_radius))
259 {
260 int found = 0;
261 entity e = WarpZone_FindRadius(this.origin, WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_radius), true);
262
263 // loop through nearby orbs and trigger them
264 for (; e; e = e.chain)
265 if (e.classname == "electro_orb")
266 {
267 // check if the ball we are exploding is not owned by an
268 // independent player which is not the player who shot the ball
269 if (IS_INDEPENDENT_PLAYER(e.realowner) && this.realowner != e.realowner)
270 continue;
271
272 bool explode;
273 if (this.owner == e.owner)
274 explode = WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_own);
275 else if (SAME_TEAM(this.owner, e.owner))
276 explode = WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_teammate);
277 else
278 explode = WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_enemy);
279
280 if (explode)
281 {
282 // change owner to whoever caused the combo explosion
283 e.realowner = this.realowner;
284 e.takedamage = DAMAGE_NO;
285 e.classname = "electro_orb_chain";
286
287 // Only first orb explosion uses midaircombo_speed, others use the normal combo_speed.
288 // This allows to avoid the delay on the first explosion which looks better
289 // (the bolt and orb should explode together because they interacted together)
290 // while keeping the chaining delay.
292 float delay = (WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_speed))
293 ? vlen(e.WarpZone_findradius_dist) / WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_speed)
294 : 0;
295 e.nextthink = time + delay;
296
297 ++found;
298 }
299 }
300
301 // if we triggered an orb, should we explode? if not, lets try again next time
302 if (found && WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_explode))
303 this.use(this, NULL, NULL);
304 else
305 this.nextthink = min(time + WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_interval), this.ltime);
306 }
307 else
308 this.nextthink = this.ltime;
309 // this.nextthink = time;
310}
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:161
entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
Definition common.qc:684
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 579 of file electro.qc.

580{
581 if (actor.(weaponentity).electro_count > 1
583 && weapon_prepareattack(thiswep, actor, weaponentity, true, -1))
584 {
585 W_Electro_Attack_Orb(thiswep, actor, weaponentity);
586 --actor.(weaponentity).electro_count;
587 actor.(weaponentity).electro_secondarytime = time;
588 weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_ELECTRO, animtime), W_Electro_CheckAttack);
589 return;
590 }
591 w_ready(thiswep, actor, weaponentity, fire);
592}
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition player.qh:154
void W_Electro_Attack_Orb(Weapon thiswep, entity actor,.entity weaponentity)
Definition electro.qc:511
void W_Electro_CheckAttack(Weapon thiswep, entity actor,.entity weaponentity, int fire)
Definition electro.qc:579
float electro_count
Definition electro.qh:101
float electro_secondarytime
Definition electro.qh:102
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 192 of file electro.qc.

193{
194 if (directhitentity.takedamage == DAMAGE_AIM
195 && IS_PLAYER(directhitentity) && DIFF_TEAM(this.realowner, directhitentity) && !IS_DEAD(directhitentity)
196 && IsFlying(directhitentity))
197 Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
198
199 this.event_damage = func_null;
200 this.takedamage = DAMAGE_NO;
201 if (!this.velocity)
202 this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work
203
204 if (this.move_movetype == MOVETYPE_BOUNCE || this.classname == "electro_orb") // TODO: classname is more reliable anyway?
205 RadiusDamage(this, this.realowner,
206 WEP_CVAR_SEC(WEP_ELECTRO, damage),
207 WEP_CVAR_SEC(WEP_ELECTRO, edgedamage),
208 WEP_CVAR_SEC(WEP_ELECTRO, radius),
209 NULL,
210 NULL,
211 WEP_CVAR_SEC(WEP_ELECTRO, force),
213 this.weaponentity_fld,
214 directhitentity
215 );
216 else
217 {
218 W_Electro_TriggerCombo(this.origin, WEP_CVAR_PRI(WEP_ELECTRO, comboradius), this.realowner);
219 RadiusDamage(this, this.realowner,
220 WEP_CVAR_PRI(WEP_ELECTRO, damage),
221 WEP_CVAR_PRI(WEP_ELECTRO, edgedamage),
222 WEP_CVAR_PRI(WEP_ELECTRO, radius),
223 NULL,
224 NULL,
225 WEP_CVAR_PRI(WEP_ELECTRO, force),
227 this.weaponentity_fld,
228 directhitentity
229 );
230 }
231
232 delete(this);
233}
float radius
Definition impulse.qh:11
bool IsFlying(entity this)
Definition player.qc:843
#define IS_DEAD(s)
Definition player.qh:244
#define IS_PLAYER(s)
Definition player.qh:242
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:943
void W_Electro_TriggerCombo(vector org, float rad, entity own)
Definition electro.qc:70
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 235 of file electro.qc.

236{
237 W_Electro_Explode(this, trigger);
238}
void W_Electro_Explode(entity this, entity directhitentity)
Definition electro.qc:192

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 161 of file electro.qc.

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

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 112 of file electro.qc.

113{
114 if (time >= this.ltime)
115 {
116 delete(this);
117 return;
118 }
119
120 this.nextthink = time;
121
122 RadiusDamage(this, this.realowner,
123 PHYS_INPUT_TIMELENGTH * WEP_CVAR(WEP_ELECTRO, combo_damage),
124 PHYS_INPUT_TIMELENGTH * WEP_CVAR(WEP_ELECTRO, combo_edgedamage),
125 WEP_CVAR(WEP_ELECTRO, combo_radius),
126 NULL,
127 NULL,
128 0,
130 this.weaponentity_fld,
131 NULL
132 );
133 this.projectiledeathtype |= HITTYPE_SPAM; // ensure it doesn't spam its effect
134}
#define PHYS_INPUT_TIMELENGTH
Definition player.qh:253
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 475 of file electro.qc.

476{
477 if (GetResource(this, RES_HEALTH) <= 0)
478 return;
479
480 // note: combos are usually triggered by W_Electro_TriggerCombo, not damage
481 float is_combo = (inflictor.classname == "electro_orb_chain" || inflictor.classname == "electro_bolt");
482
483 if (!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, (is_combo ? 1 : -1)))
484 return; // g_projectiles_damage says to halt
485
486 TakeResource(this, RES_HEALTH, damage);
487 if (GetResource(this, RES_HEALTH) <= 0)
488 {
489 this.takedamage = DAMAGE_NO;
490 this.nextthink = time;
491 if (is_combo)
492 {
493 // change owner to whoever caused the combo explosion
494 this.realowner = inflictor.realowner;
495 this.classname = "electro_orb_chain";
497 // delay combo chains, looks cooler
498 // bound the length, inflictor may be in a galaxy far far away (warpzones)
499 float len = min(WEP_CVAR(WEP_ELECTRO, combo_radius), vlen(this.origin - inflictor.origin));
500 float delay = len / WEP_CVAR(WEP_ELECTRO, combo_speed);
501 this.nextthink = time + delay;
502 }
503 else
504 {
506 setthink(this, adaptor_think2use); // not _hittype_splash, as this runs "immediately"
507 }
508 }
509}
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 136 of file electro.qc.

137{
138 entity newproj = spawn();
139 newproj.classname = this.classname;
140 newproj.solid = this.solid;
141 setorigin(newproj, this.origin);
142 setmodel(newproj, MDL_PROJECTILE_ELECTRO);
143 setsize(newproj, this.mins, this.maxs);
144 newproj.owner = this.owner;
145 newproj.realowner = this.realowner;
146 newproj.weaponentity_fld = this.weaponentity_fld;
147 newproj.projectiledeathtype = WEP_ELECTRO.m_id | HITTYPE_BOUNCE; // use THIS type for a combo because primary can't bounce
148
150 newproj.nextthink = time;
151 newproj.ltime = time + WEP_CVAR(WEP_ELECTRO, combo_duration);
152 set_movetype(newproj, MOVETYPE_NONE);
153
154 Net_LinkEntity(newproj, true, 0, electro_orb_send);
155 newproj.SendFlags = 0xFFFFFF;
156
157 // fire the first damage tick immediately
158 getthink(newproj)(newproj);
159}
vector mins
vector maxs
#define spawn
bool electro_orb_send(entity this, entity to, int sf)
Definition electro.qc:54
void W_Electro_ExplodeComboThink(entity this)
Definition electro.qc:112
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:167
#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 362 of file electro.qc.

363{
364 if (time > this.death_time)
365 {
367 return;
368 }
369 if (this.move_movetype == MOVETYPE_FOLLOW)
370 {
371 int lost = LostMovetypeFollow(this);
372 if (lost == 2)
373 {
374 // FIXME if player disconnected, it isn't possible to drop the orb at player's origin
375 // see comment in LostMovetypeFollow implementation
376 delete(this);
377 return;
378 }
379 if (lost)
380 {
381 // drop the orb at the corpse's location
384
386 this.nextthink = this.death_time;
387 return;
388 }
389 }
390 this.nextthink = time;
391}
int LostMovetypeFollow(entity ent)
Definition util.qc:2159
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 393 of file electro.qc.

394{
395 entity newproj = spawn();
396 newproj.classname = this.classname;
397
398 newproj.bot_dodge = this.bot_dodge;
399 newproj.bot_dodgerating = this.bot_dodgerating;
400
401 newproj.owner = this.owner;
402 newproj.realowner = this.realowner;
403 PROJECTILE_MAKETRIGGER(newproj);
404 setorigin(newproj, this.origin);
405 setmodel(newproj, MDL_PROJECTILE_ELECTRO);
406 setsize(newproj, this.mins, this.maxs);
407 newproj.angles = vectoangles(-trace_plane_normal); // face against the surface
408 newproj.traileffectnum = _particleeffectnum(EFFECT_TR_NEXUIZPLASMA.eent_eff_name);
409
410 newproj.movedir = -trace_plane_normal;
411
412 newproj.takedamage = this.takedamage;
413 newproj.damageforcescale = this.damageforcescale;
414 SetResourceExplicit(newproj, RES_HEALTH, GetResource(this, RES_HEALTH));
415 newproj.event_damage = this.event_damage;
416 newproj.spawnshieldtime = this.spawnshieldtime;
417 newproj.damagedbycontents = true;
419
420 set_movetype(newproj, MOVETYPE_NONE); // lock the orb in place
421 newproj.projectiledeathtype = this.projectiledeathtype;
422 newproj.weaponentity_fld = this.weaponentity_fld;
423
424 settouch(newproj, func_null);
425 if (WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime) > 0)
426 newproj.death_time = time + WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime);
427 else
428 newproj.death_time = this.death_time;
429 newproj.use = this.use;
430 newproj.flags = this.flags;
431 IL_PUSH(g_projectiles, newproj);
432 IL_PUSH(g_bot_dodge, newproj);
433
434 // check if limits are enabled (we can tell by checking if the original orb is listed) and push it to the list if so
437
438 delete(this);
439
440 if (to)
441 {
442 SetMovetypeFollow(newproj, to);
443
445 newproj.nextthink = time;
446 }
447 else
448 {
450 newproj.nextthink = newproj.death_time;
451 }
452}
float bot_dodge
Definition api.qh:40
float bot_dodgerating
Definition api.qh:39
void SetMovetypeFollow(entity ent, entity e)
Definition util.qc:2129
float flags
vector trace_plane_normal
float spawnshieldtime
Definition damage.qh:61
void W_Electro_Orb_Follow_Think(entity this)
Definition electro.qc:362
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 454 of file electro.qc.

455{
457 if (toucher.takedamage == DAMAGE_AIM && WEP_CVAR_SEC(WEP_ELECTRO, touchexplode))
459 else if (toucher.owner != this.owner && toucher.classname != this.classname) // don't stick to player's other projectiles!
460 {
461 //UpdateCSQCProjectile(this);
462 spamsound(this, CH_SHOTS, SND_ELECTRO_BOUNCE, VOL_BASE, ATTEN_NORM);
464
465 if (WEP_CVAR_SEC(WEP_ELECTRO, stick))
466 {
467 if (WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime) == 0)
469 else
471 }
472 }
473}
void W_Electro_Orb_Stick(entity this, entity to)
Definition electro.qc:393
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 240 of file electro.qc.

241{
244}

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 70 of file electro.qc.

71{
72 entity e = WarpZone_FindRadius(org, rad, !WEP_CVAR(WEP_ELECTRO, combo_comboradius_thruwall));
73 for (; e; e = e.chain)
74 if (e.classname == "electro_orb")
75 {
76 // check if the ball we are exploding is not owned by an
77 // independent player which is not the player who shot the ball
78 if (IS_INDEPENDENT_PLAYER(e.realowner) && own != e.realowner)
79 continue;
80
81 // do we allow thruwall triggering?
82 if (WEP_CVAR(WEP_ELECTRO, combo_comboradius_thruwall))
83 {
84 // if distance is greater than thruwall distance, check to make sure it's not through a wall
85 if (vdist(e.WarpZone_findradius_dist, >, WEP_CVAR(WEP_ELECTRO, combo_comboradius_thruwall)))
86 {
88 if (trace_fraction != 1)
89 {
90 // trigger is through a wall and outside of thruwall range, abort
91 continue;
92 }
93 }
94 }
95
96 // change owner to whoever caused the combo explosion
97 e.realowner = own;
98 e.takedamage = DAMAGE_NO;
99 e.classname = "electro_orb_chain";
100
101 // now set the next one to trigger as well
103
104 // delay combo chains, looks cooler
105 float delay = (WEP_CVAR(WEP_ELECTRO, combo_speed))
106 ? vlen(e.WarpZone_findradius_dist) / WEP_CVAR(WEP_ELECTRO, combo_speed)
107 : 0;
108 e.nextthink = time + delay;
109 }
110}
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

bool bot_secondary_electromooth

Definition at line 594 of file electro.qc.

◆ ltime

float ltime

Definition at line 7 of file electro.qc.