parent
f1b0045829
commit
6326a64111
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -35,7 +35,8 @@ typedef enum {
|
|||
GUERILLA,
|
||||
COWARD,
|
||||
SENTINEL,
|
||||
FIRE_DEMON
|
||||
FIRE_DEMON,
|
||||
SORCERER
|
||||
} MonsterBehaviour;
|
||||
|
||||
typedef enum {
|
||||
|
|
15
src/object.c
15
src/object.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,9 @@ object_create(void);
|
|||
Object *
|
||||
object_create_fire(void);
|
||||
|
||||
Object *
|
||||
object_create_green_gas(void);
|
||||
|
||||
void
|
||||
object_render(Object*, Camera*);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue