void monster_die()
{
MON_ACTION(self.monsterid, MR_DEATH);
-
+
self.solid = SOLID_CORPSE;
}
void monster_draw()
-{
+{
float dt;
-
+
dt = time - self.move_time;
self.move_time = time;
if(dt <= 0)
void monster_construct()
{
- vector min_s, max_s;
entity mon = get_monsterinfo(self.monsterid);
- min_s = mon.mins;
- max_s = mon.maxs;
-
if(mon.spawnflags & MONSTER_SIZE_BROKEN)
self.scale = 1.3;
self.netname = M_NAME(self.monsterid);
-
+
setorigin(self, self.origin);
setmodel(self, mon.model);
- setsize(self, min_s, max_s);
+ setsize(self, mon.mins, mon.maxs);
self.move_movetype = MOVETYPE_BOUNCE;
self.health = 255;
self.solid = SOLID_BBOX;
- self.movetype = MOVETYPE_BOUNCE;
+ self.movetype = MOVETYPE_BOUNCE;
self.move_origin = self.origin;
self.move_time = time;
- self.drawmask = MASK_NORMAL;
+ self.drawmask = MASK_NORMAL;
self.alpha = 1;
self.draw = monster_draw;
}
{
float sf;
sf = ReadByte();
-
+
if(sf & MSF_SETUP)
{
self.monsterid = ReadByte();
-
+
self.origin_x = ReadCoord();
self.origin_y = ReadCoord();
self.origin_z = ReadCoord();
self.velocity_z = ReadShort();
self.move_angles_y = ReadShort();
-
- self.move_time = time;
+
+ self.move_time = time;
self.move_velocity = self.velocity;
- self.move_origin = self.origin;
+ self.move_origin = self.origin;
}
if(sf & MSF_ANIM)
{
self.frame1time = ReadCoord();
- self.frame = ReadByte();
+ self.frame = ReadByte();
}
-
+
if(sf & MSF_STATUS)
{
self.skin = ReadByte();
float _tmp;
_tmp = ReadByte();
if(_tmp != self.team)
- {
- self.team = _tmp;
+ {
+ self.team = _tmp;
monster_changeteam();
}
{
case MONSTER_ATTACK_MELEE:
{
- monsters_setframe(animus_anim_attack);
- self.attack_finished_single = time + 1;
- monster_melee(self.enemy, MON_CVAR(animus, attack_melee_damage), self.attack_range, DEATH_MONSTER_ANIMUS, TRUE);
+ if(monster_melee(self.enemy, MON_CVAR(animus, attack_melee_damage), animus_anim_attack, self.attack_range, 1, DEATH_MONSTER_ANIMUS, TRUE))
+ return TRUE;
- return TRUE;
+ return FALSE;
}
case MONSTER_ATTACK_RANGED:
{
makevectors(self.angles);
if(monster_leap(animus_anim_leap, animus_touch_jump, v_forward * 700 + '0 0 300', 0.8))
return TRUE;
+
+ return FALSE;
}
}
case MONSTER_ATTACK_MELEE:
{
float len = vlen(self.velocity);
- monsters_setframe((len < 50) ? bruiser_anim_attack : bruiser_anim_runattack);
- self.attack_finished_single = time + 1.25;
- monster_melee(self.enemy, MON_CVAR(bruiser, attack_melee_damage), self.attack_range, DEATH_MONSTER_BRUISER, FALSE);
+ if(monster_melee(self.enemy, MON_CVAR(bruiser, attack_melee_damage), ((len < 50) ? bruiser_anim_attack : bruiser_anim_runattack), self.attack_range, 1.25, DEATH_MONSTER_BRUISER, FALSE))
+ return TRUE;
- return TRUE;
+ return FALSE;
}
case MONSTER_ATTACK_RANGED:
{
self.brute_cycles += 1;
self.angles_y = self.angles_y + random()* 25;
- monster_melee(self.enemy, MON_CVAR(brute, attack_chainsaw_damage), self.attack_range, DEATH_MONSTER_BRUTE_BLADE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(brute, attack_chainsaw_damage), brute_anim_swing, self.attack_range, 0, DEATH_MONSTER_BRUTE_BLADE, TRUE);
if(self.brute_cycles <= 4)
defer(0.2, brute_blade);
case MONSTER_ATTACK_MELEE:
{
self.brute_cycles = 0;
- monsters_setframe(brute_anim_swing);
self.attack_finished_single = time + 1.3;
brute_blade();
{
case MONSTER_ATTACK_MELEE:
{
- monsters_setframe(cerberus_anim_attack);
- self.attack_finished_single = time + 0.7;
- monster_melee(self.enemy, MON_CVAR(cerberus, attack_bite_damage), self.attack_range, DEATH_MONSTER_CERBERUS_BITE, TRUE);
-
- return TRUE;
+ if(monster_melee(self.enemy, MON_CVAR(cerberus, attack_bite_damage), cerberus_anim_attack, self.attack_range, 0.7, DEATH_MONSTER_CERBERUS_BITE, TRUE))
+ return TRUE;
+
+ return FALSE;
}
case MONSTER_ATTACK_RANGED:
{
makevectors(self.angles);
if(monster_leap(cerberus_anim_attack, cerberus_touch_jump, v_forward * 300 + '0 0 200', 0.8))
return TRUE;
+
+ return FALSE;
}
}
anim = knight_anim_smash;
else
anim = knight_anim_wattack;
-
- monsters_setframe(anim);
- self.attack_finished_single = time + 0.7;
- monster_melee(self.enemy, MON_CVAR(knight, attack_melee_damage), self.attack_range, DEATH_MONSTER_KNIGHT_MELEE, TRUE);
-
- return TRUE;
+
+ if(monster_melee(self.enemy, MON_CVAR(knight, attack_melee_damage), anim, self.attack_range, 0.7, DEATH_MONSTER_KNIGHT_MELEE, TRUE))
+ return TRUE;
+
+ return FALSE;
}
case MONSTER_ATTACK_RANGED:
{
if(knight_attack_ranged())
return TRUE;
+
+ return FALSE;
}
}
void mageattack_melee()
{
- monster_melee(self.enemy, MON_CVAR(mage, attack_melee_damage), self.attack_range, DEATH_MONSTER_MAGE, TRUE);
+ 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()
void shambler_smash()
{
- monster_melee(self.enemy, MON_CVAR(shambler, attack_smash_damage), self.attack_range, DEATH_MONSTER_SHAMBLER_SMASH, TRUE);
+ monster_melee(self.enemy, MON_CVAR(shambler, attack_smash_damage), shambler_anim_smash, self.attack_range, 0.4, DEATH_MONSTER_SHAMBLER_SMASH, TRUE);
}
void shambler_delayedsmash()
void shambler_swing()
{
float r = (random() < 0.5);
- monsters_setframe((r) ? shambler_anim_swingr : shambler_anim_swingl);
- monster_melee(self.enemy, MON_CVAR(shambler, attack_claw_damage), self.attack_range, DEATH_MONSTER_SHAMBLER_CLAW, TRUE);
- self.attack_finished_single = time + 0.8;
+ monster_melee(self.enemy, MON_CVAR(shambler, attack_claw_damage), ((r) ? shambler_anim_swingr : shambler_anim_swingl), self.attack_range, 0.8, DEATH_MONSTER_SHAMBLER_CLAW, TRUE);
if(r)
defer(0.5, shambler_swing);
}
{
case MONSTER_ATTACK_MELEE:
{
- monster_melee(self.enemy, MON_CVAR(spider, attack_bite_damage), self.attack_range, DEATH_MONSTER_SPIDER, TRUE);
- monsters_setframe((random() > 0.5) ? spider_anim_attack : spider_anim_attack2);
- self.attack_finished_single = time + MON_CVAR(spider, attack_bite_delay);
-
- return TRUE;
+ if(monster_melee(self.enemy, MON_CVAR(spider, attack_bite_damage), ((random() > 0.5) ? spider_anim_attack : spider_anim_attack2), self.attack_range, MON_CVAR(spider, attack_bite_delay), DEATH_MONSTER_SPIDER, TRUE))
+ return TRUE;
+
+ return FALSE;
}
case MONSTER_ATTACK_RANGED:
{
{
case MONSTER_ATTACK_MELEE:
{
- monsters_setframe(stingray_anim_attack);
- self.attack_finished_single = time + MON_CVAR(stingray, attack_bite_delay);
- monster_melee(self.enemy, MON_CVAR(stingray, attack_bite_damage), self.attack_range, DEATH_MONSTER_STINGRAY, FALSE);
-
- return TRUE;
+ if(monster_melee(self.enemy, MON_CVAR(stingray, attack_bite_damage), stingray_anim_attack, self.attack_range, MON_CVAR(stingray, attack_bite_delay), DEATH_MONSTER_STINGRAY, FALSE))
+ return TRUE;
+
+ return FALSE;
}
case MONSTER_ATTACK_RANGED:
+ {
+ // no ranged attack for stingray (yet?)
+ return FALSE;
+ }
}
return FALSE;
chosen_anim = zombie_anim_attackstanding2;
else
chosen_anim = zombie_anim_attackstanding3;
-
- monsters_setframe(chosen_anim);
-
- self.attack_finished_single = time + MON_CVAR(zombie, attack_melee_delay);
- monster_melee(self.enemy, MON_CVAR(zombie, attack_melee_damage), self.attack_range, DEATH_MONSTER_ZOMBIE_MELEE, TRUE);
-
- return TRUE;
+ if(monster_melee(self.enemy, MON_CVAR(zombie, attack_melee_damage), chosen_anim, self.attack_range, MON_CVAR(zombie, attack_melee_delay), DEATH_MONSTER_ZOMBIE_MELEE, TRUE))
+ return TRUE;
+
+ return FALSE;
}
case MONSTER_ATTACK_RANGED:
{
makevectors(self.angles);
if(monster_leap(zombie_anim_attackleap, zombie_attack_leap_touch, v_forward * MON_CVAR(zombie, attack_leap_speed) + '0 0 200', MON_CVAR(zombie, attack_leap_delay)))
return TRUE;
+
+ return FALSE;
}
}
makevectors(self.v_angle);
}
-float monster_melee(entity targ, float damg, float er, float deathtype, float dostop)
+float monster_melee(entity targ, float damg, float anim, float er, float anim_finished, float deathtype, float dostop)
{
float rdmg = damg * random();
self.state = MONSTER_STATE_ATTACK_MELEE;
self.SendFlags |= MSF_MOVE;
}
+
+ monsters_setframe(anim);
+
+ if(anim_finished != 0)
+ self.attack_finished_single = time + anim_finished;
monster_makevectors(targ);