From: Mario Date: Sat, 12 Oct 2013 17:55:11 +0000 (+1100) Subject: Begin working on a new mage attack X-Git-Tag: xonotic-v0.8.0~241^2^2~53 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=71c012ba7810a42b948ef0b0db35ed2fed7eacb1;p=xonotic%2Fxonotic-data.pk3dir.git Begin working on a new mage attack --- diff --git a/monsters.cfg b/monsters.cfg index 99e1fcf55..b3b5ab1b8 100644 --- a/monsters.cfg +++ b/monsters.cfg @@ -99,16 +99,6 @@ set g_monster_stingray_speed_stop 10 set g_monster_stingray_speed_walk 40 // }}} // {{{ #10: Mage -set g_monster_mage_attack_grenade_chance 30 -set g_monster_mage_attack_grenade_damage 25 -set g_monster_mage_attack_grenade_edgedamage 20 -set g_monster_mage_attack_grenade_force 170 -set g_monster_mage_attack_grenade_lifetime 5 -set g_monster_mage_attack_grenade_radius 100 -set g_monster_mage_attack_grenade_speed 150 -set g_monster_mage_attack_grenade_speed_up 95 -set g_monster_mage_attack_melee_damage 30 -set g_monster_mage_attack_melee_delay 0.7 set g_monster_mage_attack_spike_accel 400 set g_monster_mage_attack_spike_damage 30 set g_monster_mage_attack_spike_decel 400 diff --git a/qcsrc/common/monsters/monster/mage.qc b/qcsrc/common/monsters/monster/mage.qc index 597d27525..82173b731 100644 --- a/qcsrc/common/monsters/monster/mage.qc +++ b/qcsrc/common/monsters/monster/mage.qc @@ -22,16 +22,6 @@ REGISTER_MONSTER( MON_ADD_CVAR(monster, attack_spike_smart_trace_min) \ MON_ADD_CVAR(monster, attack_spike_smart_trace_max) \ MON_ADD_CVAR(monster, attack_spike_smart_mindist) \ - MON_ADD_CVAR(monster, attack_melee_damage) \ - MON_ADD_CVAR(monster, attack_melee_delay) \ - MON_ADD_CVAR(monster, attack_grenade_damage) \ - MON_ADD_CVAR(monster, attack_grenade_edgedamage) \ - MON_ADD_CVAR(monster, attack_grenade_force) \ - MON_ADD_CVAR(monster, attack_grenade_radius) \ - MON_ADD_CVAR(monster, attack_grenade_lifetime) \ - MON_ADD_CVAR(monster, attack_grenade_chance) \ - MON_ADD_CVAR(monster, attack_grenade_speed) \ - MON_ADD_CVAR(monster, attack_grenade_speed_up) \ MON_ADD_CVAR(monster, heal_self) \ MON_ADD_CVAR(monster, heal_allies) \ MON_ADD_CVAR(monster, heal_minhealth) \ @@ -59,20 +49,20 @@ const float mage_anim_run = 5; void() mage_heal; void() mage_shield; +.entity mage_spike; + float friend_needshelp(entity e) { if(e == world) return FALSE; if(e.health <= 0) return FALSE; - if(vlen(e.origin - self.origin) > MON_CVAR(mage, heal_range)) - return FALSE; if(DIFF_TEAM(e, self) && e != self.monster_owner) return FALSE; if(e.frozen) return FALSE; if(!IS_PLAYER(e)) - return (e.health < e.max_health); + return (e.flags & FL_MONSTER && e.health < e.max_health); if(e.items & IT_INVINCIBLE) return FALSE; @@ -87,65 +77,14 @@ float friend_needshelp(entity e) return FALSE; } -void mageattack_melee() -{ - monster_melee(self.enemy, MON_CVAR(mage, attack_melee_damage), mage_anim_attack, self.attack_range, MON_CVAR(mage, attack_melee_delay) - 0.2, DEATH_MONSTER_MAGE, TRUE); -} - -void mage_grenade_explode() -{ - pointparticles(particleeffectnum("explosion_small"), self.origin, '0 0 0', 1); - - sound(self, CH_SHOTS, "weapons/grenade_impact.wav", VOL_BASE, ATTEN_NORM); - RadiusDamage (self, self.realowner, MON_CVAR(mage, attack_grenade_damage), MON_CVAR(mage, attack_grenade_edgedamage), MON_CVAR(mage, attack_grenade_radius), world, MON_CVAR(mage, attack_grenade_force), DEATH_MONSTER_MAGE, other); - remove(self); -} - -void mage_grenade_touch() -{ - if(IS_PLAYER(other)) - { - PROJECTILE_TOUCH; - mage_grenade_explode(); - return; - } -} - -void mage_throw_itemgrenade() -{ - makevectors(self.angles); - - entity gren = spawn (); - gren.owner = gren.realowner = self; - gren.classname = "grenade"; - gren.bot_dodge = FALSE; - gren.movetype = MOVETYPE_BOUNCE; - gren.solid = SOLID_TRIGGER; - gren.projectiledeathtype = DEATH_MONSTER_MAGE; - setorigin(gren, CENTER_OR_VIEWOFS(self)); - setsize(gren, '-64 -64 -64', '64 64 64'); - - gren.nextthink = time + MON_CVAR(mage, attack_grenade_lifetime); - gren.think = mage_grenade_explode; - gren.use = mage_grenade_explode; - gren.touch = mage_grenade_touch; - - gren.missile_flags = MIF_SPLASH | MIF_ARC; - W_SetupProjectileVelocityEx(gren, v_forward, v_up, MON_CVAR(mage, attack_grenade_speed), MON_CVAR(mage, attack_grenade_speed_up), 0, 0, FALSE); - - gren.flags = FL_PROJECTILE; - - setmodel(gren, "models/items/g_h50.md3"); - - self.attack_finished_single = time + 1.5; -} - void mage_spike_explode() { self.event_damage = func_null; sound(self, CH_SHOTS, "weapons/grenade_impact.wav", VOL_BASE, ATTEN_NORM); + self.realowner.mage_spike = world; + pointparticles(particleeffectnum("explosion_small"), self.origin, '0 0 0', 1); RadiusDamage (self, self.realowner, MON_CVAR(mage, attack_spike_damage), MON_CVAR(mage, attack_spike_damage) * 0.5, MON_CVAR(mage, attack_spike_radius), world, 0, DEATH_MONSTER_MAGE, other); @@ -223,7 +162,7 @@ void mage_spike_think() UpdateCSQCProjectile(self); } -void mage_spike() +void mage_attack_spike() { entity missile; vector dir = normalize((self.enemy.origin + '0 0 10') - self.origin); @@ -245,15 +184,39 @@ void mage_spike() missile.enemy = self.enemy; missile.touch = mage_spike_touch; + self.mage_spike = missile; + CSQCProjectile(missile, TRUE, PROJECTILE_MAGE_SPIKE, TRUE); } +void mage_attack_beam() +{ + if(self.health <= 0 || self.enemy.health <= 0) + return; + + traceline(self.origin + self.view_ofs, self.enemy.origin, FALSE, self); + + if(vlen(self.origin - trace_endpos) > 500) + { + self.attack_finished_single = time; + return; + } + + if(trace_ent) + Damage(trace_ent, self, self, 10, DEATH_MONSTER_MAGE, trace_ent.origin, '0 0 0'); + + trailparticles(self, particleeffectnum("TE_TEI_G3RED_HIT"), self.origin + self.view_ofs, trace_ent.origin); + + if(time < self.attack_finished_single) + defer(0.1, mage_attack_beam); +} + void mage_heal() { entity head; float washealed = FALSE; - for(head = world; (head = findfloat(head, monster_attack, TRUE)); ) if(friend_needshelp(head)) + for(head = findradius(self.origin, MON_CVAR(mage, heal_range)); head; head = head.chain) if(friend_needshelp(head)) { washealed = TRUE; string fx = ""; @@ -352,26 +315,32 @@ float mage_attack(float attack_type) switch(attack_type) { case MONSTER_ATTACK_MELEE: - { - self.frame = mage_anim_attack; - self.attack_finished_single = time + MON_CVAR(mage, attack_melee_delay); - defer(0.2, mageattack_melee); - - return TRUE; - } case MONSTER_ATTACK_RANGED: { - if(random() < MON_CVAR(mage, attack_grenade_chance) / 100) + if not(self.mage_spike) { - mage_throw_itemgrenade(); - return TRUE; + if(random() <= 0.5) + { + self.frame = mage_anim_attack; + self.attack_finished_single = time + 1.5; // 0.3 seconds of beam + defer(1.2, mage_attack_beam); + + return TRUE; + } + else + { + self.frame = mage_anim_attack; + self.attack_finished_single = time + MON_CVAR(mage, attack_spike_delay); + defer(0.2, mage_attack_spike); + + return TRUE; + } } - - self.frame = mage_anim_attack; - self.attack_finished_single = time + MON_CVAR(mage, attack_spike_delay); - defer(0.2, mage_spike); - return TRUE; + if(self.mage_spike) + return TRUE; + else + return FALSE; } } @@ -402,19 +371,12 @@ float m_mage(float req) entity head; float need_help = FALSE; - FOR_EACH_PLAYER(head) - if(friend_needshelp(head)) - { - need_help = TRUE; - break; // found 1 player near us who is low on health - } - if(!need_help) - FOR_EACH_MONSTER(head) + for(head = findradius(self.origin, MON_CVAR(mage, heal_range)); head; head = head.chain) if(head != self) if(friend_needshelp(head)) { need_help = TRUE; - break; // found 1 player near us who is low on health + break; } if(self.health < MON_CVAR(mage, heal_minhealth) || need_help) @@ -449,7 +411,6 @@ float m_mage(float req) case MR_PRECACHE: { precache_model ("models/monsters/mage.dpm"); - precache_model ("models/items/g_h50.md3"); precache_model ("models/ctf/shield.md3"); precache_sound ("weapons/grenade_impact.wav"); return TRUE;