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)
bool W_Electro_search_cond (entity e)
void W_Electro_TouchExplode (entity this, entity toucher)
void W_Electro_TriggerCombo (vector org, float rad, entity own)

Variables

bool bot_secondary_electromooth
const float ELECTRO_COMBO_OVERTIME_DELAY = 0.0625
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:146
float bound(float min, float value, float max)
float move_time
Definition movetypes.qh:81
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 56 of file electro.qc.

57{
58 int channel = MSG_ENTITY;
59 WriteHeader(channel, Electro_Orb);
60 WriteVector(channel, this.origin);
61 WriteByte(channel, etof(this.realowner));
62 // round time delta to a 1/10th of a second
63 WriteByte(channel, (this.ltime - time) * 10 + 0.5);
64 return true;
65}
vector origin
WriteByte(chan, ent.angles.y/DEC_FACTOR)
const int MSG_ENTITY
Definition net.qh:156
#define WriteHeader(to, id)
Definition net.qh:265
#define etof(e)
Definition misc.qh:25
entity realowner

References entity(), etof, ltime, MSG_ENTITY, origin, realowner, 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}
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
SetResourceExplicit(ent, RES_ARMOR, ReadByte() *DEC_FACTOR)) ENTCS_PROP(NAME
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:133

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 int myowner = ReadByte();
46 setorigin(this, this.origin);
47 this.colormap = entcs_GetClientColors(myowner - 1);
48 this.ltime = time + ReadByte() / 10.0;
49 // this.ltime = time + this.orb_lifetime;
51 return true;
52}
float colormap
void electro_orb_setup(entity e)
Definition electro.qc:20
int entcs_GetClientColors(int i)
Definition ent_cs.qh:111
#define ReadVector()
Definition net.qh:349
int ReadByte()

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

◆ W_Electro_Attack_Bolt()

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

Definition at line 300 of file electro.qc.

301{
302 W_DecreaseAmmo(thiswep, actor, WEP_CVAR_PRI(WEP_ELECTRO, ammo), weaponentity);
303
305 actor,
306 weaponentity,
307 '0 0 -3',
308 '0 0 -3',
309 false,
310 2,
311 SND_ELECTRO_FIRE,
313 WEP_CVAR_PRI(WEP_ELECTRO, damage),
314 thiswep.m_id
315 );
316
317 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
318
319 entity proj = new(electro_bolt);
320 proj.owner = proj.realowner = actor;
321 proj.bot_dodge = true;
322 proj.bot_dodgerating = WEP_CVAR_PRI(WEP_ELECTRO, damage);
323 proj.use = W_Electro_Explode_use;
325 proj.nextthink = time;
326 proj.ltime = time + WEP_CVAR_PRI(WEP_ELECTRO, lifetime);
328 proj.projectiledeathtype = thiswep.m_id;
329 proj.weaponentity_fld = weaponentity;
330 setorigin(proj, w_shotorg);
331
332 // if (IS_CSQC)
334 W_SetupProjVelocity_PRI(proj, WEP_ELECTRO);
335 proj.angles = vectoangles(proj.velocity);
337 setsize(proj, '0 0 -3', '0 0 -3');
338 proj.flags = FL_PROJECTILE;
339 IL_PUSH(g_projectiles, proj);
340 IL_PUSH(g_bot_dodge, proj);
341 proj.missile_flags = MIF_SPLASH;
342
343 CSQCProjectile(proj, true, PROJECTILE_ELECTRO_BEAM, true);
344
345 MUTATOR_CALLHOOK(EditProjectile, actor, proj);
346 // proj.com_phys_pos = proj.origin;
347 // proj.com_phys_vel = proj.velocity;
348}
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:77
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
void W_Electro_TouchExplode(entity this, entity toucher)
Definition electro.qc:233
void W_Electro_Explode_use(entity this, entity actor, entity trigger)
Definition electro.qc:228
void W_Electro_Bolt_Think(entity this)
Definition electro.qc:242
vector vectoangles(vector v)
const int MOVETYPE_FLY
Definition movetypes.qh:138
const int PROJECTILE_ELECTRO_BEAM
Definition projectiles.qh:7
#define setthink(e, f)
#define settouch(e, f)
Definition self.qh:77
const int MIF_SPLASH
Definition common.qh:58
IntrusiveList g_projectiles
Definition common.qh:70
#define PROJECTILE_MAKETRIGGER(e)
Definition common.qh:46
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:69
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 499 of file electro.qc.

500{
501 W_DecreaseAmmo(thiswep, actor, WEP_CVAR_SEC(WEP_ELECTRO, ammo), weaponentity);
502
504 actor,
505 weaponentity,
506 '-4 -4 -4',
507 '4 4 4',
508 false,
509 2,
510 SND_ELECTRO_FIRE2,
512 WEP_CVAR_SEC(WEP_ELECTRO, damage),
513 thiswep.m_id | HITTYPE_SECONDARY
514 );
515
516 w_shotdir = v_forward; // no TrueAim for grenades please
517
518 W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir);
519
520 entity proj = new(electro_orb);
521 proj.owner = proj.realowner = actor;
522 proj.use = W_Electro_Explode_use;
524 proj.bot_dodge = true;
525 proj.bot_dodgerating = WEP_CVAR_SEC(WEP_ELECTRO, damage);
526 proj.nextthink = time + WEP_CVAR_SEC(WEP_ELECTRO, lifetime);
527 proj.death_time = time + WEP_CVAR_SEC(WEP_ELECTRO, lifetime);
529 proj.projectiledeathtype = thiswep.m_id | HITTYPE_SECONDARY;
530 proj.weaponentity_fld = weaponentity;
531 setorigin(proj, w_shotorg);
532
533 //proj.glow_size = 50;
534 //proj.glow_color = 45;
536 W_SetupProjVelocity_UP_SEC(proj, WEP_ELECTRO);
538 setsize(proj, '-4 -4 -4', '4 4 4');
539 proj.takedamage = DAMAGE_YES;
540 proj.damageforcescale = WEP_CVAR_SEC(WEP_ELECTRO, damageforcescale);
541 SetResourceExplicit(proj, RES_HEALTH, WEP_CVAR_SEC(WEP_ELECTRO, health));
542 proj.event_damage = W_Electro_Orb_Damage;
543 proj.flags = FL_PROJECTILE;
544 IL_PUSH(g_projectiles, proj);
545 IL_PUSH(g_bot_dodge, proj);
546 proj.damagedbycontents = (WEP_CVAR_SEC(WEP_ELECTRO, damagedbycontents));
547 if (proj.damagedbycontents)
549
550 proj.bouncefactor = WEP_CVAR_SEC(WEP_ELECTRO, bouncefactor);
551 proj.bouncestop = WEP_CVAR_SEC(WEP_ELECTRO, bouncestop);
552 proj.missile_flags = MIF_SPLASH | MIF_ARC;
553
554 if (WEP_CVAR_SEC(WEP_ELECTRO, limit) > 0)
555 {
560 }
561
562 CSQCProjectile(proj, true, PROJECTILE_ELECTRO, false); // no culling, it has sound
563
564 MUTATOR_CALLHOOK(EditProjectile, actor, proj);
565}
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:31
void W_Electro_Orb_Touch(entity this, entity toucher)
Definition electro.qc:442
void W_Electro_Orb_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition electro.qc:463
IntrusiveList LimitedElectroBallRubbleList
Definition electro.qh:100
#define IL_NEW()
float bouncefactor
Definition movetypes.qh:45
float bouncestop
Definition movetypes.qh:44
const int MOVETYPE_BOUNCE
Definition movetypes.qh:143
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:59
const int DAMAGE_YES
Definition subs.qh:80
#define W_SetupProjVelocity_UP_SEC(ent, wep)
Definition tracing.qh:58
#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 242 of file electro.qc.

243{
244 // sys_phys_update_single(this);
245 if (time >= this.ltime)
246 {
247 this.use(this, NULL, NULL);
248 return;
249 }
250
251 if (WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_radius))
252 {
253 int found = 0;
255 entity e = WarpZone_SearchInRadius(this.origin, WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_radius), MOVE_NOMONSTERS, W_Electro_search_cond);
256
257 // loop through nearby orbs and trigger them
258 for (; e; e = e.chain)
259 {
260 bool explode;
261 if (this.owner == e.owner)
262 explode = WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_own);
263 else if (SAME_TEAM(this.owner, e.owner))
264 explode = WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_teammate);
265 else
266 explode = WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_enemy);
267
268 if (explode)
269 {
270 // change owner to whoever caused the combo explosion
271 e.realowner = this.realowner;
272 e.takedamage = DAMAGE_NO;
273 e.classname = "electro_orb_chain";
274
275 // Only first orb explosion uses midaircombo_speed, others use the normal combo_speed.
276 // This allows to avoid the delay on the first explosion which looks better
277 // (the bolt and orb should explode together because they interacted together)
278 // while keeping the chaining delay.
280 float delay = (WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_speed))
281 ? vlen(e.WarpZone_findradius_dist) / WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_speed)
282 : 0;
283 e.nextthink = time + delay;
284
285 ++found;
286 }
287 }
288
289 // if we triggered an orb, should we explode? if not, lets try again next time
290 if (found && WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_explode))
291 this.use(this, NULL, NULL);
292 else
293 this.nextthink = min(time + WEP_CVAR_PRI(WEP_ELECTRO, midaircombo_interval), this.ltime);
294 }
295 else
296 this.nextthink = this.ltime;
297 // this.nextthink = time;
298}
float delay
Definition items.qc:17
entity owner
Definition main.qh:87
const float MOVE_NOMONSTERS
float nextthink
#define use
bool W_Electro_search_cond(entity e)
Definition electro.qc:73
void W_Electro_ExplodeCombo(entity this)
Definition electro.qc:154
entity WarpZone_SearchInRadius(vector org, float rad, float nomonsters, WarpZone_FindRadius_cond_callback_t cb)
Modified findradius aware of warpzones, that only includes entities that meet the "cb" criteria.
Definition common.qc:680
noref entity WarpZone_SearchInRadius_otherent
Free to use in the callback.
Definition common.qh:71
float vlen(vector v)
float min(float f,...)
#define NULL
Definition post.qh:14
const int DAMAGE_NO
Definition subs.qh:79
#define SAME_TEAM(a, b)
Definition teams.qh:241

References DAMAGE_NO, delay, entity(), ltime, min(), MOVE_NOMONSTERS, nextthink, NULL, origin, owner, realowner, SAME_TEAM, setthink, time, use, vlen(), W_Electro_ExplodeCombo(), W_Electro_search_cond(), WarpZone_SearchInRadius(), WarpZone_SearchInRadius_otherent, 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 567 of file electro.qc.

568{
569 if (actor.(weaponentity).electro_count > 1
571 && weapon_prepareattack(thiswep, actor, weaponentity, true, -1))
572 {
573 W_Electro_Attack_Orb(thiswep, actor, weaponentity);
574 --actor.(weaponentity).electro_count;
575 actor.(weaponentity).electro_secondarytime = time;
576 weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR_SEC(WEP_ELECTRO, animtime), W_Electro_CheckAttack);
577 return;
578 }
579 w_ready(thiswep, actor, weaponentity, fire);
580}
#define PHYS_INPUT_BUTTON_ATCK2(s)
Definition player.qh:154
void W_Electro_Attack_Orb(Weapon thiswep, entity actor,.entity weaponentity)
Definition electro.qc:499
void W_Electro_CheckAttack(Weapon thiswep, entity actor,.entity weaponentity, int fire)
Definition electro.qc:567
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 185 of file electro.qc.

186{
187 if (directhitentity.takedamage == DAMAGE_AIM
188 && IS_PLAYER(directhitentity) && DIFF_TEAM(this.realowner, directhitentity) && !IS_DEAD(directhitentity)
189 && IsFlying(directhitentity))
190 Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
191
192 this.event_damage = func_null;
193 this.takedamage = DAMAGE_NO;
194 if (!this.velocity)
195 this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work
196
197 if (this.move_movetype == MOVETYPE_BOUNCE || this.classname == "electro_orb") // TODO: classname is more reliable anyway?
198 RadiusDamage(this, this.realowner,
199 WEP_CVAR_SEC(WEP_ELECTRO, damage),
200 WEP_CVAR_SEC(WEP_ELECTRO, edgedamage),
201 WEP_CVAR_SEC(WEP_ELECTRO, radius),
202 NULL,
203 NULL,
204 WEP_CVAR_SEC(WEP_ELECTRO, force),
206 this.weaponentity_fld,
207 directhitentity
208 );
209 else
210 {
211 W_Electro_TriggerCombo(this.origin, WEP_CVAR_PRI(WEP_ELECTRO, comboradius), this.realowner);
212 RadiusDamage(this, this.realowner,
213 WEP_CVAR_PRI(WEP_ELECTRO, damage),
214 WEP_CVAR_PRI(WEP_ELECTRO, edgedamage),
215 WEP_CVAR_PRI(WEP_ELECTRO, radius),
216 NULL,
217 NULL,
218 WEP_CVAR_PRI(WEP_ELECTRO, force),
220 this.weaponentity_fld,
221 directhitentity
222 );
223 }
224
225 delete(this);
226}
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:937
void W_Electro_TriggerCombo(vector org, float rad, entity own)
Definition electro.qc:80
vector movedir
Definition viewloc.qh:18
float move_movetype
Definition movetypes.qh:80
var void func_null()
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1500
int projectiledeathtype
Definition common.qh:33
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 228 of file electro.qc.

229{
230 W_Electro_Explode(this, trigger);
231}
void W_Electro_Explode(entity this, entity directhitentity)
Definition electro.qc:185

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

155{
156 W_Electro_TriggerCombo(this.origin, WEP_CVAR(WEP_ELECTRO, combo_comboradius), this.realowner);
157
158 this.event_damage = func_null;
159 if (!this.velocity)
160 this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work
161
162 if (WEP_CVAR(WEP_ELECTRO, combo_duration))
163 {
165
166 delete(this);
167 return;
168 }
169
170 RadiusDamage(this, this.realowner,
171 WEP_CVAR(WEP_ELECTRO, combo_damage),
172 WEP_CVAR(WEP_ELECTRO, combo_edgedamage),
173 WEP_CVAR(WEP_ELECTRO, combo_radius),
174 NULL,
175 NULL,
176 WEP_CVAR(WEP_ELECTRO, combo_force),
177 WEP_ELECTRO.m_id | HITTYPE_BOUNCE, // use THIS type for a combo because primary can't bounce
178 this.weaponentity_fld,
179 NULL
180 );
181
182 delete(this);
183}
const int HITTYPE_BOUNCE
set manually after projectile has bounced
Definition all.qh:33
void W_Electro_Orb_ExplodeOverTime(entity this)
Definition electro.qc:131

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

119{
121 WEP_CVAR(WEP_ELECTRO, combo_duration),
122 1,
123 WEP_CVAR(WEP_ELECTRO, combo_damage),
124 WEP_CVAR(WEP_ELECTRO, combo_edgedamage),
125 WEP_CVAR(WEP_ELECTRO, combo_radius),
126 0,
127 NULL,
129}
const float ELECTRO_COMBO_OVERTIME_DELAY
Definition electro.qc:117
void W_DamageOverTime_Think(entity this, float duration, float duration_power, float damage, float edgedamage, float rad, float force, entity cantbe, float think_delay)
Applies damage over time, called within a think function.
Definition common.qc:285

References ELECTRO_COMBO_OVERTIME_DELAY, entity(), NULL, W_DamageOverTime_Think(), 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 463 of file electro.qc.

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

132{
133 entity newproj = spawn();
134 newproj.classname = this.classname;
135 newproj.solid = this.solid;
136 setorigin(newproj, this.origin);
137 setmodel(newproj, MDL_PROJECTILE_ELECTRO);
138 setsize(newproj, this.mins, this.maxs);
139 newproj.owner = this.owner;
140 newproj.realowner = this.realowner;
141 newproj.weaponentity_fld = this.weaponentity_fld;
142 newproj.projectiledeathtype = WEP_ELECTRO.m_id | HITTYPE_BOUNCE; // use THIS type for a combo because primary can't bounce
143
145 newproj.nextthink = time + ELECTRO_COMBO_OVERTIME_DELAY;
146 newproj.teleport_time = time;
147 newproj.dmg_last = 1;
148 set_movetype(newproj, MOVETYPE_NONE);
149
150 Net_LinkEntity(newproj, true, 0, electro_orb_send);
151 newproj.SendFlags = 0xFFFFFF;
152}
vector mins
vector maxs
float solid
#define spawn
bool electro_orb_send(entity this, entity to, int sf)
Definition electro.qc:56
void W_Electro_ExplodeComboThink(entity this)
Definition electro.qc:118
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
Definition net.qh:167

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

Referenced by W_Electro_ExplodeCombo().

◆ W_Electro_Orb_Follow_Think()

void W_Electro_Orb_Follow_Think ( entity this)

Definition at line 350 of file electro.qc.

351{
352 if (time > this.death_time)
353 {
355 return;
356 }
357 if (this.move_movetype == MOVETYPE_FOLLOW)
358 {
359 int lost = LostMovetypeFollow(this);
360 if (lost == 2)
361 {
362 // FIXME if player disconnected, it isn't possible to drop the orb at player's origin
363 // see comment in LostMovetypeFollow implementation
364 delete(this);
365 return;
366 }
367 if (lost)
368 {
369 // drop the orb at the corpse's location
372
374 this.nextthink = this.death_time;
375 return;
376 }
377 }
378 this.nextthink = time;
379}
int LostMovetypeFollow(entity ent)
Definition util.qc:2171
float death_time
const int MOVETYPE_FOLLOW
Definition movetypes.qh:145
const int MOVETYPE_TOSS
Definition movetypes.qh:139

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

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

443{
445 if (toucher.takedamage == DAMAGE_AIM && WEP_CVAR_SEC(WEP_ELECTRO, touchexplode))
447 else if (toucher.owner != this.owner && toucher.classname != this.classname) // don't stick to player's other projectiles!
448 {
449 //UpdateCSQCProjectile(this);
450 spamsound(this, CH_SHOTS, SND_ELECTRO_BOUNCE, VOL_BASE, ATTEN_NORM);
452
453 if (WEP_CVAR_SEC(WEP_ELECTRO, stick))
454 {
455 if (WEP_CVAR_SEC(WEP_ELECTRO, stick_lifetime) == 0)
457 else
459 }
460 }
461}
void W_Electro_Orb_Stick(entity this, entity to)
Definition electro.qc:381
entity entity toucher
Definition self.qh:76
#define PROJECTILE_TOUCH(e, t)
Definition common.qh:40
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_search_cond()

bool W_Electro_search_cond ( entity e)

Definition at line 73 of file electro.qc.

74{
75 return (e.classname == "electro_orb"
76 && !(IS_INDEPENDENT_PLAYER(e.realowner) && WarpZone_SearchInRadius_otherent != e.realowner));
77 // check if the ball we are exploding is not owned by an
78 // independent player which is not the player who shot the ball
79}
#define IS_INDEPENDENT_PLAYER(e)
Definition client.qh:312

References entity(), IS_INDEPENDENT_PLAYER, and WarpZone_SearchInRadius_otherent.

Referenced by W_Electro_Bolt_Think(), and W_Electro_TriggerCombo().

◆ W_Electro_TouchExplode()

void W_Electro_TouchExplode ( entity this,
entity toucher )

Definition at line 233 of file electro.qc.

234{
237}

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

81{
83 entity e = WarpZone_SearchInRadius(org, rad, (WEP_CVAR(WEP_ELECTRO, combo_comboradius_thruwall) ? MOVE_NOTHING : MOVE_NOMONSTERS), W_Electro_search_cond);
84 for (; e; e = e.chain)
85 {
86 // do we allow thruwall triggering?
87 if (WEP_CVAR(WEP_ELECTRO, combo_comboradius_thruwall))
88 {
89 // if distance is greater than thruwall distance, check to make sure it's not through a wall
90 if (vdist(e.WarpZone_findradius_dist, >, WEP_CVAR(WEP_ELECTRO, combo_comboradius_thruwall)))
91 {
93 if (trace_fraction != 1)
94 {
95 // trigger is through a wall and outside of thruwall range, abort
96 continue;
97 }
98 }
99 }
100
101 // change owner to whoever caused the combo explosion
102 e.realowner = own;
103 e.takedamage = DAMAGE_NO;
104 e.classname = "electro_orb_chain";
105
106 // now set the next one to trigger as well
108
109 // delay combo chains, looks cooler
110 float delay = (WEP_CVAR(WEP_ELECTRO, combo_speed))
111 ? vlen(e.WarpZone_findradius_dist) / WEP_CVAR(WEP_ELECTRO, combo_speed)
112 : 0;
113 e.nextthink = time + delay;
114 }
115}
float trace_fraction
#define WarpZone_TraceLine(org, end, nomonsters, forent)
Definition common.qh:51
#define MOVE_NOTHING
Definition common.qh:35
vector org
Definition self.qh:96
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt().
Definition vector.qh:8

References DAMAGE_NO, delay, entity(), MOVE_NOMONSTERS, MOVE_NOTHING, org, setthink, time, trace_fraction, vdist, vector, vlen(), W_Electro_ExplodeCombo(), W_Electro_search_cond(), WarpZone_SearchInRadius(), WarpZone_SearchInRadius_otherent, 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 582 of file electro.qc.

◆ ELECTRO_COMBO_OVERTIME_DELAY

const float ELECTRO_COMBO_OVERTIME_DELAY = 0.0625

Definition at line 117 of file electro.qc.

Referenced by W_Electro_ExplodeComboThink(), and W_Electro_Orb_ExplodeOverTime().

◆ ltime

float ltime

Definition at line 7 of file electro.qc.