Adds monster bloodlust
- Introduces the beginning of an event listener system - Introduces fairies. When they are killed monsters in the room rage!
This commit is contained in:
parent
d749861477
commit
fd3a625249
|
@ -181,6 +181,7 @@ add_executable(breakhack
|
|||
src/sprite
|
||||
src/sprite_util
|
||||
src/util
|
||||
src/event
|
||||
src/player
|
||||
src/map
|
||||
src/map_lua
|
||||
|
|
|
@ -169,6 +169,18 @@ for i=1,#misc do
|
|||
misc[i] = concat({ texturePaths.misc0, texturePaths.misc1 }, misc[i])
|
||||
end
|
||||
|
||||
local fairies = {
|
||||
{ stats.misc, 0, 48, "A Fairy", behaviour.pacifist },
|
||||
{ stats.misc, 16, 48, "A Fairy", behaviour.pacifist },
|
||||
{ stats.misc, 32, 48, "A Fairy", behaviour.pacifist },
|
||||
{ stats.misc, 48, 48, "A Fairy", behaviour.pacifist },
|
||||
{ stats.misc, 64, 48, "A Fairy", behaviour.pacifist },
|
||||
{ stats.misc, 80, 48, "A Fairy", behaviour.pacifist },
|
||||
}
|
||||
for i=1,#fairies do
|
||||
fairies[i] = concat({ texturePaths.humanoid0, texturePaths.humanoid1 }, fairies[i])
|
||||
end
|
||||
|
||||
local reanimated = {
|
||||
{ stats.undead, 0, 32, "A Skeleton", behaviour.normal },
|
||||
{ stats.undead, 48, 32, "A Black Skeleton", behaviour.normal },
|
||||
|
@ -273,7 +285,6 @@ local eastereggs = {
|
|||
{ stats.misc, 0*16, 7*16, "Adnis, the Ranger", behaviour.passive },
|
||||
{ stats.misc, 7*16, 8*16, "Ti, the Mage", behaviour.passive },
|
||||
}
|
||||
|
||||
for i=1,#eastereggs do
|
||||
eastereggs[i] = concat({ texturePaths.player0, texturePaths.player1 }, eastereggs[i])
|
||||
end
|
||||
|
@ -360,6 +371,7 @@ if(CURRENT_LEVEL > 0) then
|
|||
end
|
||||
|
||||
local addSpecialInLevel = random(100) == 1
|
||||
local addFairyToLevel = random(3) == 1;
|
||||
|
||||
local function add_monster_to_tile(room, roomx, roomy, rx, ry, monster)
|
||||
local x = (roomx * 512) + rx * 32
|
||||
|
@ -372,7 +384,8 @@ local function add_monster_to_tile(room, roomx, roomy, rx, ry, monster)
|
|||
end
|
||||
|
||||
function module.add_monsters_to_room(room, roomx, roomy)
|
||||
local addSpecial = addSpecialInLevel and random(5) == 1
|
||||
local addSpecial = addSpecialInLevel and random(2) == 1
|
||||
local addFairy = random(2) == 1
|
||||
local count = random(3)
|
||||
if (CURRENT_LEVEL > 3) then
|
||||
count = random(4)
|
||||
|
@ -387,6 +400,9 @@ function module.add_monsters_to_room(room, roomx, roomy)
|
|||
addSpecialInLevel = false
|
||||
addSpecial = false
|
||||
add_monster_to_tile(room, roomx, roomy, rx, ry, eastereggs[random(#eastereggs)])
|
||||
elseif addFairyToLevel and addFairy then
|
||||
addFairyToLevel = false
|
||||
add_monster_to_tile(room, roomx, roomy, rx, ry, fairies[random(#fairies)])
|
||||
else
|
||||
add_monster_to_tile(room, roomx, roomy, rx, ry, enemies[random(#enemies)])
|
||||
end
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* BreakHack - A dungeone crawler RPG
|
||||
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "event.h"
|
||||
#include "util.h"
|
||||
#include "linkedlist.h"
|
||||
|
||||
static LinkedList *callbacks = NULL;
|
||||
|
||||
void
|
||||
event_register_listener(EventCallback cb)
|
||||
{
|
||||
linkedlist_append(&callbacks, cb);
|
||||
}
|
||||
|
||||
void
|
||||
event_clear_listeners(void)
|
||||
{
|
||||
while (callbacks)
|
||||
linkedlist_pop(&callbacks);
|
||||
}
|
||||
|
||||
void
|
||||
event_trigger(Event *event)
|
||||
{
|
||||
LinkedList *cbs = callbacks;
|
||||
while (cbs) {
|
||||
((EventCallback) cbs->data)(event);
|
||||
cbs = cbs->next;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* BreakHack - A dungeone crawler RPG
|
||||
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "player.h"
|
||||
|
||||
typedef enum EventType {
|
||||
MONSTER_KILLED_EVENT
|
||||
} EventType;
|
||||
|
||||
typedef struct MonsterKilledEvent {
|
||||
EventType *type;
|
||||
Player *player;
|
||||
Monster *monster;
|
||||
} MonsterKilledEvent;
|
||||
|
||||
typedef union Event {
|
||||
EventType type;
|
||||
MonsterKilledEvent monsterKilled;
|
||||
} Event;
|
||||
|
||||
typedef void (*EventCallback)(Event*);
|
||||
|
||||
void
|
||||
event_register_listener(EventCallback cb);
|
||||
|
||||
void
|
||||
event_clear_listeners(void);
|
||||
|
||||
void
|
||||
event_trigger(Event *event);
|
20
src/main.c
20
src/main.c
|
@ -56,6 +56,7 @@
|
|||
#include "gamecontroller.h"
|
||||
#include "time.h"
|
||||
#include "sprite_util.h"
|
||||
#include "event.h"
|
||||
|
||||
#ifdef STEAM_BUILD
|
||||
#include "steam/steamworks_api_wrapper.h"
|
||||
|
@ -646,6 +647,22 @@ resetGame(void)
|
|||
repopulate_roommatrix();
|
||||
}
|
||||
|
||||
static void
|
||||
on_event_callback(Event *event)
|
||||
{
|
||||
if (event->type == MONSTER_KILLED_EVENT) {
|
||||
if (strcmp(event->monsterKilled.monster->label, "A Fairy") == 0) {
|
||||
LinkedList *monsters = gMap->monsters;
|
||||
while (monsters) {
|
||||
Monster *monster = monsters->data;
|
||||
monsters = monsters->next;
|
||||
if (position_in_room(&monster->sprite->pos, &gMap->currentRoom))
|
||||
monster_set_bloodlust(monster, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
init(void)
|
||||
{
|
||||
|
@ -668,6 +685,8 @@ init(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
event_register_listener(on_event_callback);
|
||||
|
||||
settings_init();
|
||||
hiscore_init();
|
||||
initMainMenu();
|
||||
|
@ -1333,6 +1352,7 @@ void close(void)
|
|||
#endif // STEAM_BUILD
|
||||
|
||||
gamecontroller_close();
|
||||
event_clear_listeners();
|
||||
SDL_DestroyRenderer(gRenderer);
|
||||
SDL_DestroyWindow(gWindow);
|
||||
gWindow = NULL;
|
||||
|
|
|
@ -265,6 +265,7 @@ monster_create(void)
|
|||
m->stateIndicator.shownOnPlayerRoomEnter = false;
|
||||
m->state.forceCount = 0;
|
||||
m->boss = false;
|
||||
m->bloodlust = false;
|
||||
monster_set_behaviour(m, NORMAL);
|
||||
|
||||
return m;
|
||||
|
@ -697,6 +698,12 @@ monster_drop_loot(Monster *monster, Map *map, Player *player)
|
|||
linkedlist_append(&map->items, treasure);
|
||||
}
|
||||
|
||||
if (strcmp(monster->label, "A Fairy") == 0) {
|
||||
Item *treasure = item_builder_build_treasure(PLATINUM, 3 * monster->stats.lvl);
|
||||
treasure->sprite->pos = monsterTilePos;
|
||||
linkedlist_append(&map->items, treasure);
|
||||
}
|
||||
|
||||
if (monster->stats.lvl > 2 && get_random(29) == 0) {
|
||||
Artifact *a = artifact_create_random(player, 1);
|
||||
a->sprite->pos = monsterTilePos;
|
||||
|
@ -748,6 +755,13 @@ monster_render(Monster *m, Camera *cam)
|
|||
if (m->stats.hp <= 0)
|
||||
return;
|
||||
|
||||
if (m->bloodlust) {
|
||||
Position pos = m->sprite->pos;
|
||||
pos.x += 6;
|
||||
pos.y += 6;
|
||||
particle_engine_sparkle(pos, DIM(20, 20), C_RED, false);
|
||||
}
|
||||
|
||||
sprite_render(m->sprite, cam);
|
||||
}
|
||||
|
||||
|
@ -832,6 +846,35 @@ monster_push(Monster *m, Player *p, RoomMatrix *rm, Vector2d direction)
|
|||
player_monster_kill_check(p, m);
|
||||
}
|
||||
|
||||
void
|
||||
monster_set_bloodlust(Monster *m, bool bloodlust)
|
||||
{
|
||||
if (m->bloodlust == bloodlust || m->stats.hp <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m->bloodlust = bloodlust;
|
||||
if (bloodlust) {
|
||||
gui_log("%s rages with bloodlust", m->label);
|
||||
monster_set_behaviour(m, HOSTILE);
|
||||
m->stats.advantage = true;
|
||||
m->stats.atk += 2;
|
||||
m->stats.def += 2;
|
||||
m->stats.dmg += 2;
|
||||
m->stats.hp += 10;
|
||||
m->stats.maxhp += 10;
|
||||
} else {
|
||||
gui_log("%s calms down from it's bloodlust", m->label);
|
||||
monster_set_behaviour(m, NORMAL);
|
||||
m->stats.advantage = false;
|
||||
m->stats.atk -= 2;
|
||||
m->stats.def -= 2;
|
||||
m->stats.dmg -= 2;
|
||||
m->stats.hp -= 10;
|
||||
m->stats.maxhp -= 10;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
monster_destroy(Monster *m)
|
||||
{
|
||||
|
|
|
@ -73,6 +73,7 @@ typedef struct Monster {
|
|||
MonsterBehaviour behaviour;
|
||||
unsigned int steps;
|
||||
bool boss;
|
||||
bool bloodlust;
|
||||
} Monster;
|
||||
|
||||
Monster* monster_create(void);
|
||||
|
@ -113,6 +114,9 @@ monster_push(Monster *, Player *, RoomMatrix*, Vector2d dir);
|
|||
void
|
||||
monster_reset_steps(Monster *m);
|
||||
|
||||
void
|
||||
monster_set_bloodlust(Monster*, bool bloodlust);
|
||||
|
||||
void
|
||||
monster_destroy(Monster*);
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "animation.h"
|
||||
#include "trap.h"
|
||||
#include "gamecontroller.h"
|
||||
#include "event.h"
|
||||
|
||||
#ifdef STEAM_BUILD
|
||||
#include "steam/steamworks_api_wrapper.h"
|
||||
|
@ -610,6 +611,12 @@ player_monster_kill_check(Player *player, Monster *monster)
|
|||
if (strcmp("The Trader", monster->label) == 0) {
|
||||
player->stateData.shopOwnerKiller = true;
|
||||
}
|
||||
|
||||
Event event;
|
||||
event.type = MONSTER_KILLED_EVENT;
|
||||
event.monsterKilled.monster = monster;
|
||||
event.monsterKilled.player = player;
|
||||
event_trigger(&event);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue