Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
mage.qc
Go to the documentation of this file.
1#include "mage.qh"
2
3#ifdef SVQC
5string autocvar_g_monster_mage_loot = "health_big";
38
39SOUND(MageSpike_FIRE, W_Sound("electro_fire"));
40SOUND(MageSpike_IMPACT, W_Sound("grenade_impact"));
41SOUND(MageSpike_PUSH, W_Sound("tagexp1"));
42
44void M_Mage_Attack_Push(entity this);
45METHOD(MageSpike, wr_think, void(MageSpike thiswep, entity actor, .entity weaponentity, int fire))
46{
47 TC(MageSpike, thiswep);
48 if (fire & 1)
49 if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, weaponentity, false, 0.2))
50 {
51 if (!actor.target_range)
52 actor.target_range = autocvar_g_monsters_target_range;
53 actor.enemy = Monster_FindTarget(actor);
54 monster_makevectors(actor, actor.enemy);
55 W_SetupShot_Dir(actor, weaponentity, v_forward, false, 0, SND_MageSpike_FIRE, CH_WEAPON_B, 0, DEATH_MONSTER_MAGE.m_id);
56 if (!IS_PLAYER(actor))
57 w_shotdir = normalize((actor.enemy.origin + '0 0 10') - actor.origin);
59 weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, w_ready);
60 }
61 if (fire & 2)
62 if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, weaponentity, true, 0.5))
63 {
64 M_Mage_Attack_Push(actor);
65 weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, 0, w_ready);
66 }
67}
68
69void M_Mage_Attack_Teleport(entity this, entity targ);
70
73 METHOD(OffhandMageTeleport, offhand_think, void(OffhandMageTeleport this, entity player, bool key_pressed))
74 {
76 if (key_pressed && !player.OffhandMageTeleport_key_pressed)
77 M_Mage_Attack_Teleport(player, player.enemy);
78 player.OffhandMageTeleport_key_pressed = key_pressed;
79 }
81
87
88void M_Mage_Defend_Heal(entity this);
90
91.entity mage_spike;
93
95{
96 // TODO: mutator hook to choose valid healing targets?
97 if (!targ)
98 return false;
99 if (DIFF_TEAM(targ, this) && targ != this.monster_follow)
100 return false;
101 if (GetResource(targ, RES_HEALTH) <= 0 || STAT(FROZEN, targ))
102 return false;
103 if (!IS_PLAYER(targ))
104 return IS_MONSTER(targ) && GetResource(targ, RES_HEALTH) < targ.max_health;
105 if (StatusEffects_active(STATUSEFFECT_Shield, targ))
106 return false;
107
108 switch (this.skin)
109 {
110 case 0:
111 return GetResource(targ, RES_HEALTH) < autocvar_g_balance_health_regenstable;
112 case 1:
113 return ((GetResource(targ, RES_CELLS) && GetResource(targ, RES_CELLS) < autocvar_g_pickup_cells_max)
114 || (GetResource(targ, RES_ROCKETS) && GetResource(targ, RES_ROCKETS) < autocvar_g_pickup_rockets_max)
115 || (GetResource(targ, RES_BULLETS) && GetResource(targ, RES_BULLETS) < autocvar_g_pickup_nails_max)
116 || (GetResource(targ, RES_SHELLS) && GetResource(targ, RES_SHELLS) < autocvar_g_pickup_shells_max)
117 );
118 case 2:
120 }
121
122 return false;
123}
124
125void M_Mage_Attack_Spike_Explode(entity this, entity directhitentity)
126{
127 this.event_damage = func_null;
128
129 sound(this, CH_SHOTS, SND_MageSpike_IMPACT, VOL_BASE, ATTEN_NORM);
130
131 this.realowner.mage_spike = NULL;
132
133 Send_Effect(EFFECT_EXPLOSION_SMALL, this.origin, '0 0 0', 1);
134 RadiusDamage(this, this.realowner,
138 NULL,
139 NULL,
140 0,
141 DEATH_MONSTER_MAGE.m_id,
142 DMG_NOWEP,
143 directhitentity
144 );
145
146 delete(this);
147}
148
155
156// copied from W_Seeker_Think
158{
159 if (time > this.ltime
160 || (this.enemy && GetResource(this.enemy, RES_HEALTH) <= 0)
161 || !this.owner || GetResource(this.owner, RES_HEALTH) <= 0)
162 {
165 }
166
167 W_SeekOutEnemy(this,
176
177 //this.angles = vectoangles(this.velocity); // turn model in the new flight direction
178 this.nextthink = time;// + 0.05; // csqc projectiles
180}
181
183{
184 makevectors(this.angles);
185
186 entity missile = new(M_Mage_Attack_Spike);
187 WarpZone_RefSys_Copy(missile, this);
188 missile.owner = missile.realowner = this;
190 missile.ltime = time + 7;
191 missile.nextthink = time;
192 missile.solid = SOLID_BBOX;
194 missile.flags = FL_PROJECTILE;
195 IL_PUSH(g_projectiles, missile);
196 IL_PUSH(g_bot_dodge, missile);
197 setorigin(missile, this.origin + v_forward * 14 + '0 0 30' + v_right * -14);
198 setsize(missile, '0 0 0', '0 0 0');
199 missile.velocity = dir * 400;
200 missile.avelocity = '300 300 300';
201 missile.enemy = this.enemy;
203
204 this.mage_spike = missile;
205
206 CSQCProjectile(missile, true, PROJECTILE_MAGE_SPIKE, true);
207}
208
209
218{
222 bool was_healed = (head != NULL);
223 for (; head; head = head.chain)
224 {
225 if (IS_PLAYER(head))
226 {
227 fx = EFFECT_Null;
228 switch (this.skin)
229 {
230 case 0:
232 fx = EFFECT_HEALING;
233 break;
234 case 1:
235 if (GetResource(head, RES_CELLS)) GiveResourceWithLimit(head, RES_CELLS, 1, autocvar_g_pickup_cells_max);
236 if (GetResource(head, RES_ROCKETS)) GiveResourceWithLimit(head, RES_ROCKETS, 1, autocvar_g_pickup_rockets_max);
237 if (GetResource(head, RES_SHELLS)) GiveResourceWithLimit(head, RES_SHELLS, 2, autocvar_g_pickup_shells_max);
238 if (GetResource(head, RES_BULLETS)) GiveResourceWithLimit(head, RES_BULLETS, 5, autocvar_g_pickup_nails_max);
239 // TODO: fuel?
240 fx = EFFECT_AMMO_REGEN;
241 break;
242 case 2:
244 {
246 fx = EFFECT_ARMOR_REPAIR;
247 }
248 break;
249 }
250
251 float pl_alpha = (!head.alpha ? 1 : head.alpha);
252 if (pl_alpha > 0)
253 Send_Effect_Core(fx, head.origin, vec2(head.velocity), 5, '0 0 0', '0 0 0', pl_alpha, pl_alpha, -1, NULL);
254 }
255 else
256 {
257 Send_Effect(EFFECT_HEALING, head.origin, vec2(head.velocity), 5);
259 if (!(head.spawnflags & MONSTERFLAG_INVINCIBLE) && head.sprite)
260 WaypointSprite_UpdateHealth(head.sprite, GetResource(head, RES_HEALTH));
261 }
262 }
263
264 if (was_healed)
265 {
266 setanim(this, this.anim_melee, true, true, true);
269 this.anim_finished = time + 1.5;
270 }
271}
272
274{
275 sound(this, CH_SHOTS, SND_MageSpike_PUSH, 1, ATTEN_NORM);
276 RadiusDamage(this, this,
280 NULL,
281 NULL,
283 DEATH_MONSTER_MAGE.m_id,
284 DMG_NOWEP,
285 this.enemy
286 );
287 Send_Effect(EFFECT_TE_EXPLOSION, this.origin, '0 0 0', 1);
288
289 setanim(this, this.anim_duckjump, true, true, true);
291 this.anim_finished = time + 1;
292 this.state = MONSTER_ATTACK_MELEE; // prevent moving while firing spike
293}
294
296{
297 if (!targ || vdist(targ.origin - this.origin, >, autocvar_g_monster_mage_attack_teleport_random_range))
298 return;
299
300 vector a;
302 {
303 vector oldpos = this.origin;
305 if (MoveToRandomLocationWithinBounds(this, this.absmin - extrasize, this.absmax + extrasize,
307 Q3SURFACEFLAG_SKY, 10, 64, 256, true))
308 {
309 a = vectoangles(targ.origin - this.origin);
310 this.angles = '0 1 0' * a.y;
311 this.fixangle = true;
312 Send_Effect(EFFECT_SPAWN, oldpos, '0 0 0', 1);
313 Send_Effect(EFFECT_SPAWN, this.origin, '0 0 0', 1);
315 return;
316 }
317 }
318
319 if (!IS_ONGROUND(targ))
320 return;
321
322 makevectors(targ.angles);
323 tracebox(CENTER_OR_VIEWOFS(targ), this.mins, this.maxs, CENTER_OR_VIEWOFS(targ) + (v_forward * -200), MOVE_NOMONSTERS, this);
324
325 if (trace_fraction < 1)
326 return;
327
328 vector newpos = trace_endpos;
329
330 Send_Effect(EFFECT_SPAWN, this.origin, '0 0 0', 1);
331 Send_Effect(EFFECT_SPAWN, newpos, '0 0 0', 1);
332
333 setorigin(this, newpos);
334
335 a = vectoangles(targ.origin - this.origin);
336 a.x = -a.x;
337 this.angles.x = a.x;
338 this.angles.y = a.y;
339 this.fixangle = true;
340 this.velocity *= 0.5;
341
343}
344
346{
347 StatusEffects_apply(STATUSEFFECT_Shield, this, time + autocvar_g_monster_mage_shield_time, 0);
350 setanim(this, this.anim_shoot, true, true, true);
351 this.attack_finished_single[0] = this.anim_finished = time + 1; // give just a short cooldown on attacking
352}
353
354bool M_Mage_Attack(int attack_type, entity actor, entity targ, .entity weaponentity)
355{
356 switch (attack_type)
357 {
359 {
361 {
362 Weapon wep = WEP_MAGE_SPIKE;
363
364 wep.wr_think(wep, actor, weaponentity, 2);
365 return true;
366 }
367 return false;
368 }
370 {
372 {
374 actor.OffhandMageTeleport_key_pressed = 0;
375 off.offhand_think(off, actor, 1);
376 return true;
377 }
378 else if (!actor.mage_spike && random() <= autocvar_g_monster_mage_attack_spike_chance)
379 {
380 setanim(actor, actor.anim_shoot, true, true, true);
381 actor.attack_finished_single[0] = time + autocvar_g_monster_mage_attack_spike_delay;
382 actor.anim_finished = time + 1;
383 actor.state = MONSTER_ATTACK_MELEE; // prevent moving while firing spike
384 Weapon wep = WEP_MAGE_SPIKE;
385 wep.wr_think(wep, actor, weaponentity, 1);
386 return true;
387 }
388 return false;
389 }
390 }
391
392 return false;
393}
394
395spawnfunc(monster_mage)
396{
397 Monster_Spawn(this, true, MON_MAGE);
398}
399
400METHOD(Mage, mr_think, bool(Mage thismon, entity actor))
401{
402 TC(Mage, thismon);
403
407 bool should_heal = (head != NULL); // TODO: this could be optimized by changing the WarpZone_SearchInRadius to return as soon as it finds one entity, somehow
408 // heal ourself if it'd also help a nearby friend, even if we don't need healing
409
410 if (random() < 0.5
411 && time >= actor.attack_finished_single[0]
412 && (GetResource(actor, RES_HEALTH) < autocvar_g_monster_mage_heal_minhealth || should_heal))
413 M_Mage_Defend_Heal(actor);
414
415 if (random() < 0.5
416 && actor.enemy && time >= actor.mage_shield_delay
417 && GetResource(actor, RES_HEALTH) < actor.max_health && !StatusEffects_active(STATUSEFFECT_Shield, actor))
419
420 return true;
421}
422
423METHOD(Mage, mr_pain, float(Mage this, entity actor, float damage_take, entity attacker, float deathtype))
424{
425 TC(Mage, this);
426 return damage_take;
427}
428
429METHOD(Mage, mr_death, bool(Mage this, entity actor))
430{
431 TC(Mage, this);
432 setanim(actor, ((random() > 0.5) ? actor.anim_die2 : actor.anim_die1), false, true, true);
433 return true;
434}
435#endif // SVQC
436#ifdef GAMEQC
437METHOD(Mage, mr_anim, bool(Mage this, entity actor))
438{
439 TC(Mage, this);
440 vector none = '0 0 0';
441 actor.anim_idle = animfixfps(actor, '0 1 1', none);
442 actor.anim_walk = animfixfps(actor, '1 1 1', none);
443 actor.anim_run = animfixfps(actor, '1 1 1', none);
444 actor.anim_shoot = animfixfps(actor, '2 1 5', none); // analyze models and set framerate
445 actor.anim_duckjump = animfixfps(actor, '4 1 5', none); // analyze models and set framerate
446 actor.anim_melee = animfixfps(actor, '5 1 5', none); // analyze models and set framerate
447 //actor.anim_fire1 = animfixfps(actor, '3 1 5', none); // analyze models and set framerate
448 //actor.anim_fire2 = animfixfps(actor, '4 1 5', none); // analyze models and set framerate
449 //actor.anim_fire3 = animfixfps(actor, '5 1 5', none); // analyze models and set framerate
450 actor.anim_pain1 = animfixfps(actor, '6 1 2', none); // 0.5 seconds
451 actor.anim_pain2 = animfixfps(actor, '7 1 2', none); // 0.5 seconds
452 //actor.anim_pain3 = animfixfps(actor, '8 1 2', none); // 0.5 seconds
453 actor.anim_die1 = animfixfps(actor, '9 1 0.5', none); // 2 seconds
454 actor.anim_die2 = animfixfps(actor, '10 1 0.5', none); // 2 seconds
455 //actor.anim_dead1 = animfixfps(actor, '11 1 0.5', none); // 2 seconds
456 //actor.anim_dead2 = animfixfps(actor, '12 1 0.5', none); // 2 seconds
457 return true;
458}
459#endif // GAMEQC
460#ifdef SVQC
461METHOD(Mage, mr_setup, bool(Mage this, entity actor))
462{
463 TC(Mage, this);
464 if (!GetResource(this, RES_HEALTH))
466 if (!actor.speed) actor.speed = autocvar_g_monster_mage_speed_walk;
467 if (!actor.speed2) actor.speed2 = autocvar_g_monster_mage_speed_run;
468 if (!actor.stopspeed) actor.stopspeed = autocvar_g_monster_mage_speed_stop;
469 if (!actor.damageforcescale) actor.damageforcescale = autocvar_g_monster_mage_damageforcescale;
470
471 actor.monster_loot = autocvar_g_monster_mage_loot;
472 actor.monster_attackfunc = M_Mage_Attack;
473
474 return true;
475}
476#endif // SVQC
477#ifdef MENUQC
478METHOD(Mage, describe, string(Mage this))
479{
480 TC(Mage, this);
482 PAR(_("Wielding nanotechnology as if it were sorcery, the Mage employs a range of unique abilities of its own creation in combat."));
483 PAR(_("As a primary attack, the Mage throws a homing electric sphere towards the player. "
484 "This sphere will track its target at high speed, exploding on impact or if it does not reach its target in time."));
485 PAR(_("When threatened, the Mage may deploy an energy shield to protect itself from damage briefly. "
486 "Enemies approaching too closely during this time may be pushed away with explosive force!"));
487 PAR(_("Defensively the Mage is capable of healing itself and nearby allies, with some variants also providing armor and ammunition."));
488 PAR(_("The Mage may sometimes appear to blink out of existence as it teleports behind its target for a sneak attack."));
489 return PAGE_TEXT;
490}
491#endif // MENUQC
#define setanim(...)
Definition anim.qh:45
IntrusiveList g_bot_dodge
Definition api.qh:150
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition mage.qh:9
bool OffhandMageTeleport_key_pressed
Definition mage.qc:72
virtual void offhand_think()
Definition mage.qc:73
virtual void offhand_think()
Definition weapon.qh:238
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:42
virtual void wr_think()
(SERVER) logic to run every frame
Definition weapon.qh:98
entity owner
Definition main.qh:87
int autocvar_g_pickup_rockets_max
Definition ammo.qh:116
int autocvar_g_pickup_shells_max
Definition ammo.qh:44
int autocvar_g_pickup_cells_max
Definition ammo.qh:152
int autocvar_g_pickup_nails_max
Definition ammo.qh:80
float ltime
Definition net.qh:10
#define IS_PLAYER(s)
Definition player.qh:242
const int FL_PROJECTILE
Definition constants.qh:77
float Q3SURFACEFLAG_SKY
float DPCONTENTS_SKY
const float MOVE_NOMONSTERS
float DPCONTENTS_DONOTENTER
float DPCONTENTS_SOLID
float DPCONTENTS_CORPSE
vector mins
vector velocity
float DPCONTENTS_BODY
const float SOLID_BBOX
float DPCONTENTS_PLAYERCLIP
float DPCONTENTS_SLIME
float time
vector v_right
vector trace_endpos
vector maxs
float nextthink
vector absmax
vector v_forward
vector origin
float trace_fraction
float DPCONTENTS_LAVA
vector absmin
void UpdateCSQCProjectile(entity e)
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
bool Heal(entity targ, entity inflictor, float amount, float limit)
Definition damage.qc:951
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
#define DMG_NOWEP
Definition damage.qh:104
int state
const int HITTYPE_SPLASH
automatically set by RadiusDamage
Definition all.qh:32
void Send_Effect_Core(entity eff, vector eff_loc, vector eff_vel, int eff_cnt, vector eff_col_min, vector eff_col_max, float eff_alpha_min, float eff_alpha_max, float eff_alpha_fade, entity ignore)
Definition all.qc:74
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:155
RES_ARMOR
Definition ent_cs.qc:155
ent angles
Definition ent_cs.qc:146
SetResourceExplicit(ent, RES_ARMOR, ReadByte() *DEC_FACTOR)) ENTCS_PROP(NAME
skin
Definition ent_cs.qc:168
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define TC(T, sym)
Definition _all.inc:82
#define STAT(...)
Definition stats.qh:94
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
void WarpZone_RefSys_Copy(entity me, entity from)
Copies the warpzone reference of from onto me.
Definition common.qc:824
noref entity WarpZone_SearchInRadius_otherent
Free to use in the callback.
Definition common.qh:71
#define MOVE_NOTHING
Definition common.qh:35
void M_Mage_Defend_Shield(entity this)
Definition mage.qc:345
void M_Mage_Defend_Heal(entity this)
Definition mage.qc:217
float autocvar_g_monster_mage_attack_push_force
Definition mage.qc:23
float autocvar_g_monster_mage_shield_time
Definition mage.qc:32
float autocvar_g_monster_mage_attack_spike_chance
Definition mage.qc:12
float autocvar_g_monster_mage_attack_push_radius
Definition mage.qc:21
float autocvar_g_monster_mage_heal_delay
Definition mage.qc:31
float autocvar_g_monster_mage_attack_spike_delay
Definition mage.qc:9
float autocvar_g_monster_mage_attack_teleport_random
Definition mage.qc:26
string autocvar_g_monster_mage_loot
Definition mage.qc:5
float autocvar_g_monster_mage_attack_spike_smart_mindist
Definition mage.qc:18
float autocvar_g_monster_mage_speed_run
Definition mage.qc:36
float autocvar_g_monster_mage_speed_stop
Definition mage.qc:35
float autocvar_g_monster_mage_attack_spike_radius
Definition mage.qc:8
void M_Mage_Attack_Spike_Think(entity this)
Definition mage.qc:157
float autocvar_g_monster_mage_attack_spike_smart_trace_min
Definition mage.qc:16
void M_Mage_Attack_Spike_Explode(entity this, entity directhitentity)
Definition mage.qc:125
float autocvar_g_monster_mage_heal_minhealth
Definition mage.qc:29
float autocvar_g_monster_mage_attack_spike_smart
Definition mage.qc:15
float autocvar_g_monster_mage_attack_spike_accel
Definition mage.qc:10
float autocvar_g_monster_mage_attack_spike_smart_trace_max
Definition mage.qc:17
float autocvar_g_monster_mage_health
Definition mage.qc:4
float autocvar_g_monster_mage_attack_spike_decel
Definition mage.qc:11
float autocvar_g_monster_mage_heal_range
Definition mage.qc:30
float autocvar_g_monster_mage_attack_spike_turnrate
Definition mage.qc:13
float autocvar_g_monster_mage_shield_delay
Definition mage.qc:33
float autocvar_g_monster_mage_attack_spike_damage
Definition mage.qc:7
void M_Mage_Attack_Teleport(entity this, entity targ)
Definition mage.qc:295
float autocvar_g_monster_mage_speed_walk
Definition mage.qc:37
float autocvar_g_monster_mage_attack_spike_speed_max
Definition mage.qc:14
void M_Mage_Attack_Push(entity this)
Definition mage.qc:273
float autocvar_g_monster_mage_attack_push_delay
Definition mage.qc:22
float autocvar_g_monster_mage_attack_push_damage
Definition mage.qc:20
float autocvar_g_monster_mage_shield_blockpercent
Definition mage.qc:34
OffhandMageTeleport OFFHAND_MAGE_TELEPORT
Definition mage.qc:82
bool M_Mage_Attack(int attack_type, entity actor, entity targ,.entity weaponentity)
Definition mage.qc:354
entity mage_spike
Definition mage.qc:91
bool M_Mage_Defend_Heal_Check(entity this, entity targ)
Definition mage.qc:94
void M_Mage_Attack_Spike(entity this, vector dir)
Definition mage.qc:182
float autocvar_g_monster_mage_attack_teleport_random_range
Definition mage.qc:27
float autocvar_g_monster_mage_heal_allies
Definition mage.qc:28
float autocvar_g_monster_mage_attack_teleport_delay
Definition mage.qc:25
float autocvar_g_monster_mage_damageforcescale
Definition mage.qc:6
bool M_Mage_Defend_Heal_cond(entity e)
Definition mage.qc:211
void M_Mage_Attack_Spike_Touch(entity this, entity toucher)
Definition mage.qc:149
float mage_shield_delay
Definition mage.qc:92
bool M_Mage_Defend_Heal_cond_checkvalid
Definition mage.qc:210
float autocvar_g_monster_mage_attack_teleport_chance
Definition mage.qc:24
float autocvar_g_monster_mage_attack_push_chance
Definition mage.qc:19
float random(void)
vector vectoangles(vector v)
vector normalize(vector v)
vector animfixfps(entity e, vector a, vector b)
Definition util.qc:1917
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_FLYMISSILE
Definition movetypes.qh:142
#define IS_ONGROUND(s)
Definition movetypes.qh:16
var void func_null()
#define NEW(cname,...)
Definition oo.qh:120
#define CLASS(...)
Definition oo.qh:149
#define ENDCLASS(cname)
Definition oo.qh:286
#define METHOD(cname, name, prototype)
Definition oo.qh:274
#define NULL
Definition post.qh:14
#define makevectors
Definition post.qh:21
float fixangle
Definition progsdefs.qc:160
const int PROJECTILE_MAGE_SPIKE
const int RES_LIMIT_NONE
Definition resources.qh:60
#define setthink(e, f)
vector
Definition self.qh:96
entity entity toucher
Definition self.qh:76
#define settouch(e, f)
Definition self.qh:77
int dir
Definition impulse.qc:89
float W_SeekOutEnemy(entity this, float speed_decel, float speed_accel, float speed_max, float turn_rate, bool smart, float smart_mindist, float smart_trace_min, float smart_trace_max)
Automatically guides a projectile towards its enemy.
Definition common.qc:239
int projectiledeathtype
Definition common.qh:33
#define PROJECTILE_TOUCH(e, t)
Definition common.qh:40
IntrusiveList g_projectiles
Definition common.qh:70
const float VOL_BASE
Definition sound.qh:36
const int CH_SHOTS
Definition sound.qh:14
const float ATTEN_NORM
Definition sound.qh:30
#define sound(e, c, s, v, a)
Definition sound.qh:52
const int CH_WEAPON_B
Definition sound.qh:8
string W_Sound(string w_snd)
Definition all.qc:226
#define SOUND(name, path)
Definition all.qh:30
#define spawnfunc(id)
Definition spawnfunc.qh:107
#define STATIC_INIT(func)
during worldspawn
Definition static.qh:33
bool StatusEffects_active(StatusEffect this, entity actor)
void StatusEffects_apply(StatusEffect this, entity actor, float eff_time, int eff_flags)
#define PAGE_TEXT
Definition string.qh:651
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
Definition string.qh:657
#define PAGE_TEXT_INIT()
Definition string.qh:650
entity enemy
Definition sv_ctf.qh:152
bool Monster_Spawn(entity this, bool check_appear, Monster mon)
Setup the basic required properties for a monster.
entity Monster_FindTarget(entity this)
void monster_makevectors(entity this, entity targ)
float anim_finished
will be phased out when we have proper animations system
entity monster_follow
monster follow target
float autocvar_g_monsters_target_range
const int MONSTER_ATTACK_MELEE
const int MONSTERFLAG_INVINCIBLE
monster doesn't take damage (may be used for map objects & temporary monsters)
const int MONSTER_ATTACK_RANGED
void GiveResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
Gives an entity some resource but not more than a limit.
float autocvar_g_balance_health_regenstable
int autocvar_g_balance_armor_regenstable
#define DIFF_TEAM(a, b)
Definition teams.qh:242
entity realowner
vector w_shotdir
Definition tracing.qh:20
#define W_SetupShot_Dir(ent, wepent, s_forward, antilag, recoil, snd, chan, maxdamage, deathtype)
Definition tracing.qh:32
#define IS_MONSTER(v)
Definition utils.qh:23
#define CENTER_OR_VIEWOFS(ent)
Definition utils.qh:31
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt().
Definition vector.qh:8
#define vec2(...)
Definition vector.qh:95
void WaypointSprite_UpdateHealth(entity e, float f)
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)
float attack_finished_single[MAX_WEAPONSLOTS]
bool MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundmax, float goodcontents, float badcontents, float badsurfaceflags, int attempts, float maxaboveground, float minviewdistance, bool frompos)
Definition world.qc:1117