#include "mage.qh"
#ifdef SVQC
+float autocvar_g_monster_mage_health;
+float autocvar_g_monster_mage_damageforcescale = 0.5;
+float autocvar_g_monster_mage_attack_spike_damage;
+float autocvar_g_monster_mage_attack_spike_radius;
+float autocvar_g_monster_mage_attack_spike_delay;
+float autocvar_g_monster_mage_attack_spike_accel;
+float autocvar_g_monster_mage_attack_spike_decel;
+float autocvar_g_monster_mage_attack_spike_chance = 0.45;
+float autocvar_g_monster_mage_attack_spike_turnrate;
+float autocvar_g_monster_mage_attack_spike_speed_max;
+float autocvar_g_monster_mage_attack_spike_smart;
+float autocvar_g_monster_mage_attack_spike_smart_trace_min;
+float autocvar_g_monster_mage_attack_spike_smart_trace_max;
+float autocvar_g_monster_mage_attack_spike_smart_mindist;
+float autocvar_g_monster_mage_attack_push_chance = 0.7;
+float autocvar_g_monster_mage_attack_push_damage;
+float autocvar_g_monster_mage_attack_push_radius;
+float autocvar_g_monster_mage_attack_push_delay;
+float autocvar_g_monster_mage_attack_push_force;
+float autocvar_g_monster_mage_attack_teleport_chance = 0.2;
+float autocvar_g_monster_mage_attack_teleport_delay = 2;
+float autocvar_g_monster_mage_attack_teleport_random = 0.4;
+float autocvar_g_monster_mage_attack_teleport_random_range = 1200;
+float autocvar_g_monster_mage_heal_self;
+float autocvar_g_monster_mage_heal_allies;
+float autocvar_g_monster_mage_heal_minhealth;
+float autocvar_g_monster_mage_heal_range;
+float autocvar_g_monster_mage_heal_delay;
+float autocvar_g_monster_mage_shield_time;
+float autocvar_g_monster_mage_shield_delay;
+float autocvar_g_monster_mage_shield_blockpercent;
+float autocvar_g_monster_mage_speed_stop;
+float autocvar_g_monster_mage_speed_run;
+float autocvar_g_monster_mage_speed_walk;
SOUND(MageSpike_FIRE, W_Sound("electro_fire"));
void M_Mage_Attack_Spike(entity this, vector dir);
if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, weaponentity, false, 0.2)) {
if (!actor.target_range) actor.target_range = autocvar_g_monsters_target_range;
actor.enemy = Monster_FindTarget(actor);
+ monster_makevectors(actor, actor.enemy);
W_SetupShot_Dir(actor, weaponentity, v_forward, false, 0, SND_MageSpike_FIRE, CH_WEAPON_B, 0, DEATH_MONSTER_MAGE.m_id);
if (!IS_PLAYER(actor)) w_shotdir = normalize((actor.enemy.origin + '0 0 10') - actor.origin);
M_Mage_Attack_Spike(actor, w_shotdir);
OffhandMageTeleport OFFHAND_MAGE_TELEPORT;
STATIC_INIT(OFFHAND_MAGE_TELEPORT) { OFFHAND_MAGE_TELEPORT = NEW(OffhandMageTeleport); }
-float autocvar_g_monster_mage_health;
-float autocvar_g_monster_mage_damageforcescale = 0.5;
-float autocvar_g_monster_mage_attack_spike_damage;
-float autocvar_g_monster_mage_attack_spike_radius;
-float autocvar_g_monster_mage_attack_spike_delay;
-float autocvar_g_monster_mage_attack_spike_accel;
-float autocvar_g_monster_mage_attack_spike_decel;
-float autocvar_g_monster_mage_attack_spike_chance = 0.45;
-float autocvar_g_monster_mage_attack_spike_turnrate;
-float autocvar_g_monster_mage_attack_spike_speed_max;
-float autocvar_g_monster_mage_attack_spike_smart;
-float autocvar_g_monster_mage_attack_spike_smart_trace_min;
-float autocvar_g_monster_mage_attack_spike_smart_trace_max;
-float autocvar_g_monster_mage_attack_spike_smart_mindist;
-float autocvar_g_monster_mage_attack_push_chance = 0.7;
-float autocvar_g_monster_mage_attack_push_damage;
-float autocvar_g_monster_mage_attack_push_radius;
-float autocvar_g_monster_mage_attack_push_delay;
-float autocvar_g_monster_mage_attack_push_force;
-float autocvar_g_monster_mage_attack_teleport_chance = 0.2;
-float autocvar_g_monster_mage_attack_teleport_delay = 2;
-float autocvar_g_monster_mage_attack_teleport_random = 0.4;
-float autocvar_g_monster_mage_attack_teleport_random_range = 1200;
-float autocvar_g_monster_mage_heal_self;
-float autocvar_g_monster_mage_heal_allies;
-float autocvar_g_monster_mage_heal_minhealth;
-float autocvar_g_monster_mage_heal_range;
-float autocvar_g_monster_mage_heal_delay;
-float autocvar_g_monster_mage_shield_time;
-float autocvar_g_monster_mage_shield_delay;
-float autocvar_g_monster_mage_shield_blockpercent;
-float autocvar_g_monster_mage_speed_stop;
-float autocvar_g_monster_mage_speed_run;
-float autocvar_g_monster_mage_speed_walk;
-
-/*
-const float mage_anim_idle = 0;
-const float mage_anim_walk = 1;
-const float mage_anim_attack = 2;
-const float mage_anim_pain = 3;
-const float mage_anim_death = 4;
-const float mage_anim_run = 5;
-*/
-
void M_Mage_Defend_Heal(entity this);
void M_Mage_Defend_Shield(entity this);
.entity mage_spike;
.float mage_shield_delay;
-.float mage_shield_time;
bool M_Mage_Defend_Heal_Check(entity this, entity targ)
{
return false;
if(!IS_PLAYER(targ))
return (IS_MONSTER(targ) && GetResource(targ, RES_HEALTH) < targ.max_health);
- if(targ.items & ITEM_Shield.m_itemid)
+ if(StatusEffects_active(STATUSEFFECT_Shield, targ))
return false;
switch(this.skin)
// copied from W_Seeker_Think
void M_Mage_Attack_Spike_Think(entity this)
{
- if (time > this.ltime || (this.enemy && GetResource(this.enemy, RES_HEALTH) <= 0) || GetResource(this.owner, RES_HEALTH) <= 0) {
+ if (time > this.ltime || (this.enemy && GetResource(this.enemy, RES_HEALTH) <= 0) || !this.owner || GetResource(this.owner, RES_HEALTH) <= 0) {
this.projectiledeathtype |= HITTYPE_SPLASH;
M_Mage_Attack_Spike_Explode(this, NULL);
}
{
makevectors(this.angles);
- entity missile = spawn();
+ entity missile = new(M_Mage_Attack_Spike);
missile.owner = missile.realowner = this;
setthink(missile, M_Mage_Attack_Spike_Think);
missile.ltime = time + 7;
void M_Mage_Attack_Teleport(entity this, entity targ)
{
if(!targ) return;
- if(vdist(targ.origin - this.origin, >, 1500)) return;
+ if(vdist(targ.origin - this.origin, >, autocvar_g_monster_mage_attack_teleport_random_range)) return;
if(autocvar_g_monster_mage_attack_teleport_random && random() <= autocvar_g_monster_mage_attack_teleport_random)
{
this.attack_finished_single[0] = time + autocvar_g_monster_mage_attack_teleport_delay;
}
-void M_Mage_Defend_Shield_Remove(entity this)
-{
- this.effects &= ~(EF_ADDITIVE | EF_BLUE);
- SetResourceExplicit(this, RES_ARMOR, autocvar_g_monsters_armor_blockpercent);
-}
-
void M_Mage_Defend_Shield(entity this)
{
- this.effects |= (EF_ADDITIVE | EF_BLUE);
+ StatusEffects_apply(STATUSEFFECT_Shield, this, time + autocvar_g_monster_mage_shield_time, 0);
this.mage_shield_delay = time + (autocvar_g_monster_mage_shield_delay);
SetResourceExplicit(this, RES_ARMOR, autocvar_g_monster_mage_shield_blockpercent);
- this.mage_shield_time = time + (autocvar_g_monster_mage_shield_time);
setanim(this, this.anim_shoot, true, true, true);
this.attack_finished_single[0] = time + 1; // give just a short cooldown on attacking
this.anim_finished = time + 1;
return false;
}
-spawnfunc(monster_mage) { Monster_Spawn(this, true, MON_MAGE.monsterid); }
+spawnfunc(monster_mage) { Monster_Spawn(this, true, MON_MAGE); }
#endif // SVQC
if(random() < 0.5)
M_Mage_Defend_Heal(actor);
- if(time >= actor.mage_shield_time && GetResource(actor, RES_ARMOR))
- M_Mage_Defend_Shield_Remove(actor);
-
- if(actor.enemy)
- if(GetResource(actor, RES_HEALTH) < actor.max_health)
- if(time >= actor.mage_shield_delay)
- if(random() < 0.5)
+ if(actor.enemy && time >= actor.mage_shield_delay && random() < 0.5)
+ if(GetResource(actor, RES_HEALTH) < actor.max_health && !StatusEffects_active(STATUSEFFECT_Shield, actor))
M_Mage_Defend_Shield(actor);
return true;