Completes #42 Add boss 2 & 3

- Adds "The Shadow"
- Adds the "assassin" behaviour
- Adds some assassins to levels > 15
This commit is contained in:
Linus Probert 2018-08-23 09:11:13 +02:00
parent 449cc362a0
commit 52913af237
3 changed files with 77 additions and 27 deletions

View File

@ -46,7 +46,8 @@ local behaviour = {
coward = 4,
sentinel = 5,
fire_demon = 6,
sorcerer = 7
sorcerer = 7,
assassin = 8
}
local stats = {
@ -239,12 +240,23 @@ for i=1,#orcs do
orcs[i] = concat({ texturePaths.humanoid0, texturePaths.humanoid1 }, orcs[i])
end
local assassins = {
{ stats.misc, 1*16, 6*16, "A Reaper", behaviour.assassin },
{ stats.misc, 0*16, 7*16, "An Assassin", behaviour.assassin },
{ stats.misc, 1*16, 7*16, "A Royal Assassin", behaviour.assassin },
}
for i=1,#assassins do
assassins[i] = concat({ texturePaths.undead0, texturePaths.undead1 }, assassins[i])
end
local bosses = {
{ stats.boss, 16, 5*16, "The Hell Hound", behaviour.fire_demon, true },
{ stats.boss, 16, 23*16, "The Cleric", behaviour.sorcerer, true },
{ stats.boss, 16, 8*16, "The Shadow", behaviour.assassin, true },
}
bosses[1] = concat({ texturePaths.dog0, texturePaths.dog1 }, bosses[1])
bosses[2] = concat({ texturePaths.humanoid0, texturePaths.humanoid1 }, bosses[2])
bosses[3] = concat({ texturePaths.undead0, texturePaths.undead1 }, bosses[3])
local platino = {
{
@ -282,6 +294,7 @@ if(CURRENT_LEVEL > 0) then
enemies = {}
enemies = concat(enemies, undead)
enemies = concat(enemies, orcs)
enemies = concat(enemies, assassins)
elseif (CURRENT_LEVEL > 10) then
enemies = {}
enemies = concat(enemies, undead)

View File

@ -106,6 +106,7 @@ monster_behaviour_check_post_hit(Monster *m)
monster_state_change(m, SCARED);
break;
case GUERILLA:
case ASSASSIN:
case SORCERER:
case FIRE_DEMON:
break;
@ -115,6 +116,48 @@ monster_behaviour_check_post_hit(Monster *m)
}
}
static void
damage_surroundings(Monster *m, RoomMatrix *rm)
{
Position roomPos = position_to_matrix_coords(&m->sprite->pos);
for (Sint32 i = -1; i <= 1; ++i) {
for (Sint32 j = -1; j <= 1; ++j) {
if (i == 0 && j == 0)
continue;
RoomSpace *r = &rm->spaces[roomPos.x + i][roomPos.y + j];
if (r->monster) {
int dmg = stats_fight(&m->stats, &r->monster->stats);
monster_hit(r->monster, dmg);
gui_log("%s takes %d damage from the explosion", r->monster->label, dmg);
} else if (r->player) {
int dmg = stats_fight(&m->stats, &r->player->stats);
player_hit(r->player, dmg);
gui_log("You take %d damage from the explosion", dmg);
}
}
}
}
static void
sorcerer_blast(Monster *m, RoomMatrix *rm)
{
gui_log("%s creates a magical explosion", m->label);
particle_engine_eldritch_explosion(m->sprite->pos, DIM(TILE_DIMENSION, TILE_DIMENSION));
damage_surroundings(m, rm);
}
static void
assassin_cloak_effect(Monster *m, bool cloak)
{
if (cloak)
gui_log("%s dissappears from sight", m->label);
else
gui_log("%s reappears, filled with rage", m->label);
particle_engine_fire_explosion(m->sprite->pos, DIM(TILE_DIMENSION, TILE_DIMENSION));
}
static void
monster_behaviour_check_post_attack(Monster *m)
{
@ -124,6 +167,10 @@ monster_behaviour_check_post_attack(Monster *m)
case FIRE_DEMON:
monster_state_change(m, SCARED);
break;
case ASSASSIN:
assassin_cloak_effect(m, true);
monster_state_change(m, SCARED);
break;
default:
break;
}
@ -163,6 +210,13 @@ monster_behaviour_check(Monster *m, RoomMatrix *rm)
monster_state_change(m, AGRESSIVE);
}
break;
case ASSASSIN:
if (m->state.stepsSinceChange > 5
&& m->state.current == SCARED) {
assassin_cloak_effect(m, false);
monster_state_change(m, AGRESSIVE);
}
break;
case SENTINEL:
handle_sentinel_behaviour(m, rm);
break;
@ -382,31 +436,6 @@ monster_coward_walk(Monster *m, RoomMatrix *rm)
}
}
static void
sorcerer_blast(Monster *m, RoomMatrix *rm)
{
gui_log("%s creates a magical explosion", m->label);
particle_engine_eldritch_explosion(m->sprite->pos, DIM(TILE_DIMENSION, TILE_DIMENSION));
Position roomPos = position_to_matrix_coords(&m->sprite->pos);
for (Sint32 i = -1; i <= 1; ++i) {
for (Sint32 j = -1; j <= 1; ++j) {
if (i == 0 && j == 0)
continue;
RoomSpace *r = &rm->spaces[roomPos.x + i][roomPos.y + j];
if (r->monster) {
int dmg = stats_fight(&m->stats, &r->monster->stats);
monster_hit(r->monster, dmg);
gui_log("%s takes %d damage from the explosion", r->monster->label, dmg);
} else if (r->player) {
int dmg = stats_fight(&m->stats, &r->player->stats);
player_hit(r->player, dmg);
gui_log("You take %d damage from the explosion", dmg);
}
}
}
}
bool
monster_move(Monster *m, RoomMatrix *rm, Map *map)
{
@ -644,6 +673,9 @@ monster_render(Monster *m, Camera *cam)
if (m->stats.hp <= 0)
return;
if (m->behaviour == ASSASSIN && m->state.current != AGRESSIVE)
return;
sprite_render(m->sprite, cam);
}
@ -653,6 +685,9 @@ monster_render_top_layer(Monster *m, Camera *cam)
if (m->stats.hp <= 0)
return;
if (m->behaviour == ASSASSIN && m->state.current != AGRESSIVE)
return;
if (m->stateIndicator.displayCount != 0)
sprite_render(m->stateIndicator.sprite, cam);
}
@ -664,6 +699,7 @@ monster_set_behaviour(Monster *m, MonsterBehaviour behaviour)
switch (behaviour) {
case HOSTILE:
case GUERILLA:
case ASSASSIN:
case SORCERER:
case COWARD:
case FIRE_DEMON:

View File

@ -36,7 +36,8 @@ typedef enum {
COWARD,
SENTINEL,
FIRE_DEMON,
SORCERER
SORCERER,
ASSASSIN
} MonsterBehaviour;
typedef enum {