]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/monsters/monster/mage.qc
Adjust frequency of mage's teleportation attack, update monster configuration to...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / monsters / monster / mage.qc
index b2dba6a99cebf1ad63f21cfcec641fcb3414ebd2..8cfa77e6535aa7dfe70925d12a58cb02b9bb4537 100644 (file)
@@ -1,43 +1,6 @@
 #include "mage.qh"
 
 #ifdef SVQC
-
-SOUND(MageSpike_FIRE, W_Sound("electro_fire"));
-void M_Mage_Attack_Spike(entity this, vector dir);
-void M_Mage_Attack_Push(entity this);
-METHOD(MageSpike, wr_think, void(MageSpike thiswep, entity actor, .entity weaponentity, int fire))
-{
-    TC(MageSpike, thiswep);
-    if (fire & 1)
-    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);
-        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);
-        weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, w_ready);
-    }
-    if (fire & 2)
-    if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, weaponentity, true, 0.5)) {
-        M_Mage_Attack_Push(actor);
-        weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, 0, w_ready);
-    }
-}
-
-void M_Mage_Attack_Teleport(entity this, entity targ);
-
-CLASS(OffhandMageTeleport, OffhandWeapon)
-    .bool OffhandMageTeleport_key_pressed;
-    METHOD(OffhandMageTeleport, offhand_think, void(OffhandMageTeleport this, entity player, bool key_pressed))
-    {
-        TC(OffhandMageTeleport, this);
-        if (key_pressed && !player.OffhandMageTeleport_key_pressed)
-               M_Mage_Attack_Teleport(player, player.enemy);
-        player.OffhandMageTeleport_key_pressed = key_pressed;
-    }
-ENDCLASS(OffhandMageTeleport)
-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;
@@ -73,21 +36,49 @@ 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;
-*/
+SOUND(MageSpike_FIRE, W_Sound("electro_fire"));
+void M_Mage_Attack_Spike(entity this, vector dir);
+void M_Mage_Attack_Push(entity this);
+METHOD(MageSpike, wr_think, void(MageSpike thiswep, entity actor, .entity weaponentity, int fire))
+{
+    TC(MageSpike, thiswep);
+    if (fire & 1)
+    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);
+        weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, 0, w_ready);
+    }
+    if (fire & 2)
+    if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, weaponentity, true, 0.5)) {
+        M_Mage_Attack_Push(actor);
+        weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, 0, w_ready);
+    }
+}
+
+void M_Mage_Attack_Teleport(entity this, entity targ);
+
+CLASS(OffhandMageTeleport, OffhandWeapon)
+    .bool OffhandMageTeleport_key_pressed;
+    METHOD(OffhandMageTeleport, offhand_think, void(OffhandMageTeleport this, entity player, bool key_pressed))
+    {
+        TC(OffhandMageTeleport, this);
+        if (key_pressed && !player.OffhandMageTeleport_key_pressed)
+               M_Mage_Attack_Teleport(player, player.enemy);
+        player.OffhandMageTeleport_key_pressed = key_pressed;
+    }
+ENDCLASS(OffhandMageTeleport)
+OffhandMageTeleport OFFHAND_MAGE_TELEPORT;
+STATIC_INIT(OFFHAND_MAGE_TELEPORT) { OFFHAND_MAGE_TELEPORT = NEW(OffhandMageTeleport); }
 
 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)
 {
@@ -101,7 +92,7 @@ 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)
@@ -150,7 +141,7 @@ void M_Mage_Attack_Spike_Touch(entity this, entity toucher)
 // 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);
        }
@@ -205,7 +196,7 @@ void M_Mage_Attack_Spike(entity this, vector dir)
 {
        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;
@@ -306,7 +297,7 @@ void M_Mage_Attack_Push(entity this)
 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)
        {
@@ -351,18 +342,11 @@ void M_Mage_Attack_Teleport(entity this, entity targ)
        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;
@@ -411,7 +395,7 @@ bool M_Mage_Attack(int attack_type, entity actor, entity targ, .entity weaponent
        return false;
 }
 
-spawnfunc(monster_mage) { Monster_Spawn(this, true, MON_MAGE.monsterid); }
+spawnfunc(monster_mage) { Monster_Spawn(this, true, MON_MAGE); }
 
 #endif // SVQC
 
@@ -449,13 +433,8 @@ METHOD(Mage, mr_think, bool(Mage thismon, entity actor))
     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;