Begins #42 Add boss 2 & 3

- Added "The cleric" for level 10.
This commit is contained in:
Linus Probert 2018-08-22 13:13:54 +02:00
parent f1b0045829
commit 6326a64111
9 changed files with 101 additions and 29 deletions

View File

@ -45,7 +45,8 @@ local behaviour = {
guerilla = 3,
coward = 4,
sentinel = 5,
fire_demon = 6
fire_demon = 6,
sorcerer = 7
}
local stats = {
@ -93,17 +94,17 @@ local stats = {
},
boss = {
hp = 60,
dmg = 4,
dmg = 3,
atk = 1,
def = 0,
speed = 1
},
platino = {
hp = 60,
dmg = 60,
atk = 60,
def = 60,
speed = 3
hp = 30,
dmg = 0,
atk = 0,
def = 0,
speed = 2
}
}
@ -212,7 +213,7 @@ local orcs = {
{ stats.orc, 48, 4*16, "An Orc Sentry", behaviour.sentinel },
{ stats.orc, 64, 4*16, "An Orc Brute", behaviour.guerilla },
{ stats.orc, 80, 4*16, "An Orc Captain", behaviour.hostile },
{ stats.orc, 80, 4*16, "An Orc Pyro", behaviour.fire_demon },
{ stats.orc, 96, 4*16, "An Orc Pyro", behaviour.fire_demon },
}
for i=1,#orcs do
orcs[i] = concat({ texturePaths.humanoid0, texturePaths.humanoid1 }, orcs[i])
@ -220,7 +221,7 @@ end
local bosses = {
{ stats.boss, 16, 5*16, "The Hell Hound", behaviour.fire_demon, true },
{ stats.boss, 32, 23*16, "The Cleric", behaviour.sentinel, true },
{ stats.boss, 16, 23*16, "The Cleric", behaviour.sorcerer, true },
}
bosses[1] = concat({ texturePaths.dog0, texturePaths.dog1 }, bosses[1])
bosses[2] = concat({ texturePaths.humanoid0, texturePaths.humanoid1 }, bosses[2])
@ -233,7 +234,8 @@ local platino = {
48,
12*16,
"Platino",
behaviour.sentinel
behaviour.sentinel,
true
}
}
@ -303,7 +305,7 @@ function module.add_monsters_to_room(room, roomx, roomy)
end
function module.add_boss_to_room(room, roomx, roomy)
local boss = bosses[1]
local boss = bosses[CURRENT_LEVEL / 5]
local success = false
while not success do
local rx = random(13) + 1

View File

@ -304,7 +304,7 @@ static void
startGame(void *unused)
{
UNUSED(unused);
cLevel = 1;
cLevel = 5;
gGameState = PLAYING;
if (gPlayer)
player_destroy(gPlayer);
@ -626,10 +626,13 @@ check_next_level(void)
if (tile->levelExit) {
mixer_play_effect(NEXT_LEVEL);
++cLevel;
if (cLevel % 5 == 0)
if (cLevel % 5 == 0) {
gui_log("You sense something powerful in the vicinity");
gui_event_message("Something powerful lurks in the dark");
mixer_play_music(BOSS_MUSIC0);
else
} else {
mixer_play_music(GAME_MUSIC0 + get_random(2));
}
resetGame();
}
}

View File

@ -106,6 +106,7 @@ monster_behaviour_check_post_hit(Monster *m)
monster_state_change(m, SCARED);
break;
case GUERILLA:
case SORCERER:
case FIRE_DEMON:
break;
default:
@ -119,6 +120,7 @@ monster_behaviour_check_post_attack(Monster *m)
{
switch (m->behaviour) {
case GUERILLA:
case SORCERER:
case FIRE_DEMON:
monster_state_change(m, SCARED);
break;
@ -154,6 +156,7 @@ monster_behaviour_check(Monster *m, RoomMatrix *rm)
{
switch (m->behaviour) {
case GUERILLA:
case SORCERER:
case FIRE_DEMON:
if (m->state.stepsSinceChange > 8
&& m->state.current == SCARED) {
@ -379,6 +382,33 @@ 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);
r->monster->stats.hp -= 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);
r->player->stats.hp -= dmg;
gui_log("You take %d damage from the explosion", dmg);
}
}
}
}
bool
monster_move(Monster *m, RoomMatrix *rm, Map *map)
{
@ -395,10 +425,18 @@ monster_move(Monster *m, RoomMatrix *rm, Map *map)
}
monster_behaviour_check(m, rm);
Position origPos = m->sprite->pos;
Position originalMPos =
position_to_matrix_coords(&m->sprite->pos);
if (m->state.current == AGRESSIVE && m->behaviour == SORCERER) {
if (position_proximity(1, &originalMPos, &rm->playerRoomPos)) {
sorcerer_blast(m, rm);
monster_behaviour_check_post_attack(m);
return true;
}
}
rm->spaces[originalMPos.x][originalMPos.y].occupied = false;
rm->spaces[originalMPos.x][originalMPos.y].monster = NULL;
@ -442,13 +480,20 @@ monster_move(Monster *m, RoomMatrix *rm, Map *map)
}
if (!position_equals(&origPos, &m->sprite->pos)
&& (rm->modifier->type == RMOD_TYPE_FIRE || m->behaviour == FIRE_DEMON)) {
if (!position_equals(&origPos, &m->sprite->pos)) {
if (rm->modifier->type == RMOD_TYPE_FIRE || m->behaviour == FIRE_DEMON) {
Object *o = object_create_fire();
o->sprite->pos = origPos;
o->damage *= m->stats.lvl;
linkedlist_push(&map->objects, o);
}
if (m->behaviour == SORCERER) {
Object *o = object_create_green_gas();
o->sprite->pos = origPos;
o->damage *= m->stats.lvl;
linkedlist_push(&map->objects, o);
}
}
m->steps++;
if (m->steps >= m->stats.speed) {
@ -542,7 +587,7 @@ monster_drop_loot(Monster *monster, Map *map, Player *player)
linkedlist_append(&map->items, treasure);
}
if (monster->stats.lvl > 2 && get_random(19) == 0) {
if (monster->stats.lvl > 2 && get_random(29) == 0) {
Artifact *a = artifact_create_random(player, 1);
a->sprite->pos = monster->sprite->pos;
linkedlist_append(&map->artifacts, a);
@ -613,6 +658,7 @@ monster_set_behaviour(Monster *m, MonsterBehaviour behaviour)
switch (behaviour) {
case HOSTILE:
case GUERILLA:
case SORCERER:
case COWARD:
case FIRE_DEMON:
m->state.current = AGRESSIVE;

View File

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

View File

@ -49,6 +49,21 @@ object_create_fire()
return o;
}
Object *
object_create_green_gas()
{
Object *o = object_create();
Texture *t0 = texturecache_add("Objects/Effect0.png");
Texture *t1 = texturecache_add("Objects/Effect1.png");
sprite_set_texture(o->sprite, t0, 0);
sprite_set_texture(o->sprite, t1, 1);
o->sprite->dim = GAME_DIMENSION;
o->sprite->clip = CLIP16(32, 24*16);
o->damage = 3;
o->timeout = 3;
return o;
}
void
object_render(Object *o, Camera *cam)
{

View File

@ -38,6 +38,9 @@ object_create(void);
Object *
object_create_fire(void);
Object *
object_create_green_gas(void);
void
object_render(Object*, Camera*);

View File

@ -156,10 +156,10 @@ create_explosion(Position pos, Dimension dim, unsigned int c_count, ...)
x = get_random(dim.width) + pos.x;
y = get_random(dim.height) + pos.y;
xv = get_random(600) - 300;
yv = get_random(600) - 300;
xv = get_random(500) - 300;
yv = get_random(500) - 300;
lt = get_random(10);
lt = get_random(20);
p = create_rect_particle();
p->particle.rect.pos = (Position) { x, y };
@ -167,6 +167,7 @@ create_explosion(Position pos, Dimension dim, unsigned int c_count, ...)
p->velocity = (Vector2d) { (float) xv, (float) yv };
p->movetime = lt;
p->lifetime = lt;
p->blend_mode = SDL_BLENDMODE_BLEND;
p->color = colors[get_random((unsigned int) c_count-1)];
linkedlist_append(&engine->game_particles, p);
}

View File

@ -531,7 +531,7 @@ player_hit(Player *p, unsigned int dmg)
Position pos = p->sprite->pos;
pos.x += 8;
pos.y += 8;
particle_engine_bloodspray(pos, (Dimension) { 8, 8 }, dmg);
particle_engine_bloodspray(pos, DIM(8, 8), dmg);
mixer_play_effect(PLAYER_HIT0 + get_random(2));
char msg[5];
m_sprintf(msg, 5, "-%d", dmg);

View File

@ -67,10 +67,11 @@ stats_fight(Stats *attacker, Stats *defender)
bool critical = false;
int atkRoll = get_attack_roll(attacker);
if (atkRoll - attacker->atk == 20)
critical = true;
int defRoll = get_defence_roll(defender);
if (atkRoll - attacker->atk == 20)
critical = get_attack_roll(attacker) > defRoll;
int dmgRoll = 0;
if (atkRoll >= defRoll) {
if (attacker->dmg > 0)