parent
f1b0045829
commit
6326a64111
|
@ -45,7 +45,8 @@ local behaviour = {
|
||||||
guerilla = 3,
|
guerilla = 3,
|
||||||
coward = 4,
|
coward = 4,
|
||||||
sentinel = 5,
|
sentinel = 5,
|
||||||
fire_demon = 6
|
fire_demon = 6,
|
||||||
|
sorcerer = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
local stats = {
|
local stats = {
|
||||||
|
@ -93,17 +94,17 @@ local stats = {
|
||||||
},
|
},
|
||||||
boss = {
|
boss = {
|
||||||
hp = 60,
|
hp = 60,
|
||||||
dmg = 4,
|
dmg = 3,
|
||||||
atk = 1,
|
atk = 1,
|
||||||
def = 0,
|
def = 0,
|
||||||
speed = 1
|
speed = 1
|
||||||
},
|
},
|
||||||
platino = {
|
platino = {
|
||||||
hp = 60,
|
hp = 30,
|
||||||
dmg = 60,
|
dmg = 0,
|
||||||
atk = 60,
|
atk = 0,
|
||||||
def = 60,
|
def = 0,
|
||||||
speed = 3
|
speed = 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ local orcs = {
|
||||||
{ stats.orc, 48, 4*16, "An Orc Sentry", behaviour.sentinel },
|
{ stats.orc, 48, 4*16, "An Orc Sentry", behaviour.sentinel },
|
||||||
{ stats.orc, 64, 4*16, "An Orc Brute", behaviour.guerilla },
|
{ 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 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
|
for i=1,#orcs do
|
||||||
orcs[i] = concat({ texturePaths.humanoid0, texturePaths.humanoid1 }, orcs[i])
|
orcs[i] = concat({ texturePaths.humanoid0, texturePaths.humanoid1 }, orcs[i])
|
||||||
|
@ -220,7 +221,7 @@ end
|
||||||
|
|
||||||
local bosses = {
|
local bosses = {
|
||||||
{ stats.boss, 16, 5*16, "The Hell Hound", behaviour.fire_demon, true },
|
{ 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[1] = concat({ texturePaths.dog0, texturePaths.dog1 }, bosses[1])
|
||||||
bosses[2] = concat({ texturePaths.humanoid0, texturePaths.humanoid1 }, bosses[2])
|
bosses[2] = concat({ texturePaths.humanoid0, texturePaths.humanoid1 }, bosses[2])
|
||||||
|
@ -233,7 +234,8 @@ local platino = {
|
||||||
48,
|
48,
|
||||||
12*16,
|
12*16,
|
||||||
"Platino",
|
"Platino",
|
||||||
behaviour.sentinel
|
behaviour.sentinel,
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +305,7 @@ function module.add_monsters_to_room(room, roomx, roomy)
|
||||||
end
|
end
|
||||||
|
|
||||||
function module.add_boss_to_room(room, roomx, roomy)
|
function module.add_boss_to_room(room, roomx, roomy)
|
||||||
local boss = bosses[1]
|
local boss = bosses[CURRENT_LEVEL / 5]
|
||||||
local success = false
|
local success = false
|
||||||
while not success do
|
while not success do
|
||||||
local rx = random(13) + 1
|
local rx = random(13) + 1
|
||||||
|
|
|
@ -304,7 +304,7 @@ static void
|
||||||
startGame(void *unused)
|
startGame(void *unused)
|
||||||
{
|
{
|
||||||
UNUSED(unused);
|
UNUSED(unused);
|
||||||
cLevel = 1;
|
cLevel = 5;
|
||||||
gGameState = PLAYING;
|
gGameState = PLAYING;
|
||||||
if (gPlayer)
|
if (gPlayer)
|
||||||
player_destroy(gPlayer);
|
player_destroy(gPlayer);
|
||||||
|
@ -626,10 +626,13 @@ check_next_level(void)
|
||||||
if (tile->levelExit) {
|
if (tile->levelExit) {
|
||||||
mixer_play_effect(NEXT_LEVEL);
|
mixer_play_effect(NEXT_LEVEL);
|
||||||
++cLevel;
|
++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);
|
mixer_play_music(BOSS_MUSIC0);
|
||||||
else
|
} else {
|
||||||
mixer_play_music(GAME_MUSIC0 + get_random(2));
|
mixer_play_music(GAME_MUSIC0 + get_random(2));
|
||||||
|
}
|
||||||
resetGame();
|
resetGame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,7 @@ monster_behaviour_check_post_hit(Monster *m)
|
||||||
monster_state_change(m, SCARED);
|
monster_state_change(m, SCARED);
|
||||||
break;
|
break;
|
||||||
case GUERILLA:
|
case GUERILLA:
|
||||||
|
case SORCERER:
|
||||||
case FIRE_DEMON:
|
case FIRE_DEMON:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -119,6 +120,7 @@ monster_behaviour_check_post_attack(Monster *m)
|
||||||
{
|
{
|
||||||
switch (m->behaviour) {
|
switch (m->behaviour) {
|
||||||
case GUERILLA:
|
case GUERILLA:
|
||||||
|
case SORCERER:
|
||||||
case FIRE_DEMON:
|
case FIRE_DEMON:
|
||||||
monster_state_change(m, SCARED);
|
monster_state_change(m, SCARED);
|
||||||
break;
|
break;
|
||||||
|
@ -154,6 +156,7 @@ monster_behaviour_check(Monster *m, RoomMatrix *rm)
|
||||||
{
|
{
|
||||||
switch (m->behaviour) {
|
switch (m->behaviour) {
|
||||||
case GUERILLA:
|
case GUERILLA:
|
||||||
|
case SORCERER:
|
||||||
case FIRE_DEMON:
|
case FIRE_DEMON:
|
||||||
if (m->state.stepsSinceChange > 8
|
if (m->state.stepsSinceChange > 8
|
||||||
&& m->state.current == SCARED) {
|
&& 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
|
bool
|
||||||
monster_move(Monster *m, RoomMatrix *rm, Map *map)
|
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);
|
monster_behaviour_check(m, rm);
|
||||||
|
|
||||||
Position origPos = m->sprite->pos;
|
Position origPos = m->sprite->pos;
|
||||||
Position originalMPos =
|
Position originalMPos =
|
||||||
position_to_matrix_coords(&m->sprite->pos);
|
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].occupied = false;
|
||||||
rm->spaces[originalMPos.x][originalMPos.y].monster = NULL;
|
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)
|
if (!position_equals(&origPos, &m->sprite->pos)) {
|
||||||
&& (rm->modifier->type == RMOD_TYPE_FIRE || m->behaviour == FIRE_DEMON)) {
|
if (rm->modifier->type == RMOD_TYPE_FIRE || m->behaviour == FIRE_DEMON) {
|
||||||
Object *o = object_create_fire();
|
Object *o = object_create_fire();
|
||||||
o->sprite->pos = origPos;
|
o->sprite->pos = origPos;
|
||||||
o->damage *= m->stats.lvl;
|
o->damage *= m->stats.lvl;
|
||||||
linkedlist_push(&map->objects, o);
|
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++;
|
m->steps++;
|
||||||
if (m->steps >= m->stats.speed) {
|
if (m->steps >= m->stats.speed) {
|
||||||
|
@ -542,7 +587,7 @@ monster_drop_loot(Monster *monster, Map *map, Player *player)
|
||||||
linkedlist_append(&map->items, treasure);
|
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);
|
Artifact *a = artifact_create_random(player, 1);
|
||||||
a->sprite->pos = monster->sprite->pos;
|
a->sprite->pos = monster->sprite->pos;
|
||||||
linkedlist_append(&map->artifacts, a);
|
linkedlist_append(&map->artifacts, a);
|
||||||
|
@ -613,6 +658,7 @@ monster_set_behaviour(Monster *m, MonsterBehaviour behaviour)
|
||||||
switch (behaviour) {
|
switch (behaviour) {
|
||||||
case HOSTILE:
|
case HOSTILE:
|
||||||
case GUERILLA:
|
case GUERILLA:
|
||||||
|
case SORCERER:
|
||||||
case COWARD:
|
case COWARD:
|
||||||
case FIRE_DEMON:
|
case FIRE_DEMON:
|
||||||
m->state.current = AGRESSIVE;
|
m->state.current = AGRESSIVE;
|
||||||
|
|
|
@ -35,7 +35,8 @@ typedef enum {
|
||||||
GUERILLA,
|
GUERILLA,
|
||||||
COWARD,
|
COWARD,
|
||||||
SENTINEL,
|
SENTINEL,
|
||||||
FIRE_DEMON
|
FIRE_DEMON,
|
||||||
|
SORCERER
|
||||||
} MonsterBehaviour;
|
} MonsterBehaviour;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
15
src/object.c
15
src/object.c
|
@ -49,6 +49,21 @@ object_create_fire()
|
||||||
return o;
|
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
|
void
|
||||||
object_render(Object *o, Camera *cam)
|
object_render(Object *o, Camera *cam)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,9 @@ object_create(void);
|
||||||
Object *
|
Object *
|
||||||
object_create_fire(void);
|
object_create_fire(void);
|
||||||
|
|
||||||
|
Object *
|
||||||
|
object_create_green_gas(void);
|
||||||
|
|
||||||
void
|
void
|
||||||
object_render(Object*, Camera*);
|
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;
|
x = get_random(dim.width) + pos.x;
|
||||||
y = get_random(dim.height) + pos.y;
|
y = get_random(dim.height) + pos.y;
|
||||||
|
|
||||||
xv = get_random(600) - 300;
|
xv = get_random(500) - 300;
|
||||||
yv = get_random(600) - 300;
|
yv = get_random(500) - 300;
|
||||||
|
|
||||||
lt = get_random(10);
|
lt = get_random(20);
|
||||||
|
|
||||||
p = create_rect_particle();
|
p = create_rect_particle();
|
||||||
p->particle.rect.pos = (Position) { x, y };
|
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->velocity = (Vector2d) { (float) xv, (float) yv };
|
||||||
p->movetime = lt;
|
p->movetime = lt;
|
||||||
p->lifetime = lt;
|
p->lifetime = lt;
|
||||||
|
p->blend_mode = SDL_BLENDMODE_BLEND;
|
||||||
p->color = colors[get_random((unsigned int) c_count-1)];
|
p->color = colors[get_random((unsigned int) c_count-1)];
|
||||||
linkedlist_append(&engine->game_particles, p);
|
linkedlist_append(&engine->game_particles, p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -531,7 +531,7 @@ player_hit(Player *p, unsigned int dmg)
|
||||||
Position pos = p->sprite->pos;
|
Position pos = p->sprite->pos;
|
||||||
pos.x += 8;
|
pos.x += 8;
|
||||||
pos.y += 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));
|
mixer_play_effect(PLAYER_HIT0 + get_random(2));
|
||||||
char msg[5];
|
char msg[5];
|
||||||
m_sprintf(msg, 5, "-%d", dmg);
|
m_sprintf(msg, 5, "-%d", dmg);
|
||||||
|
|
|
@ -67,10 +67,11 @@ stats_fight(Stats *attacker, Stats *defender)
|
||||||
bool critical = false;
|
bool critical = false;
|
||||||
|
|
||||||
int atkRoll = get_attack_roll(attacker);
|
int atkRoll = get_attack_roll(attacker);
|
||||||
if (atkRoll - attacker->atk == 20)
|
|
||||||
critical = true;
|
|
||||||
int defRoll = get_defence_roll(defender);
|
int defRoll = get_defence_roll(defender);
|
||||||
|
|
||||||
|
if (atkRoll - attacker->atk == 20)
|
||||||
|
critical = get_attack_roll(attacker) > defRoll;
|
||||||
|
|
||||||
int dmgRoll = 0;
|
int dmgRoll = 0;
|
||||||
if (atkRoll >= defRoll) {
|
if (atkRoll >= defRoll) {
|
||||||
if (attacker->dmg > 0)
|
if (attacker->dmg > 0)
|
||||||
|
|
Loading…
Reference in New Issue