Fixes: #4 Room stuff: Traps
- Adds traps - Adds lua hooks for traps - Fixes level exit in pit bug
This commit is contained in:
parent
a3c3c634d6
commit
ffde0793e5
|
@ -172,6 +172,7 @@ add_executable(breakhack
|
|||
src/settings
|
||||
src/actiontextbuilder
|
||||
src/animation
|
||||
src/trap
|
||||
)
|
||||
|
||||
# Sqlite has some warnings that I we don't need to see
|
||||
|
@ -261,6 +262,7 @@ if (NOT DEBUG_BUILD)
|
|||
"maproombuilder.lua"
|
||||
"menumapgen.lua"
|
||||
"monstergen.lua"
|
||||
"trapgen.lua"
|
||||
"pitlayouts.dat"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
local room_builder = require "maproombuilder"
|
||||
local monster_gen = require "monstergen"
|
||||
local trap_gen = require "trapgen"
|
||||
|
||||
-- Setting up some functions
|
||||
local time = os.time
|
||||
|
@ -115,6 +116,7 @@ local function generate_path ()
|
|||
if room then
|
||||
room_builder.build_room(room)
|
||||
monster_gen.add_monsters_to_room(room, i-1, j-1)
|
||||
trap_gen.add_traps_to_room(room, i-1, j-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -138,6 +140,7 @@ for i=1,10 do
|
|||
set_current_room(map, i-1, j-1);
|
||||
room_builder.load_room(map, room)
|
||||
monster_gen.load_monsters(map, room.monsters)
|
||||
trap_gen.load_traps(map, room.traps)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -294,7 +294,6 @@ local function build_vert_center_coridoor(room, offset)
|
|||
end
|
||||
|
||||
local function build_horiz_center_coridoor(room, offset)
|
||||
info("Building horizontal corrdior: " .. offset)
|
||||
for i=0,6 do
|
||||
room.tiles[offset+i][4] = wall.horizontal
|
||||
room.tiles[offset+i][5] = floor.center
|
||||
|
@ -412,7 +411,12 @@ local function add_level_exit(room)
|
|||
while not success do
|
||||
x = random(14)
|
||||
y = random(10)
|
||||
if not room.decor[x][y] then
|
||||
if not room.decor[x][y]
|
||||
and not room.traps[x][y]
|
||||
and (room.tiles[x][y]
|
||||
and not room.tiles[x][y][5]
|
||||
and not room.tiles[x][y][8])
|
||||
then
|
||||
success = true
|
||||
room.tiles[x][y] = special.level_exit
|
||||
end
|
||||
|
@ -469,16 +473,19 @@ function module.create_empty_room()
|
|||
type = nil,
|
||||
arg = nil
|
||||
},
|
||||
monsters = {}
|
||||
monsters = {},
|
||||
traps = {}
|
||||
}
|
||||
for i=0,15 do
|
||||
room.tiles[i] = {}
|
||||
room.decor[i] = {}
|
||||
room.monsters[i] = {}
|
||||
room.traps[i] = {}
|
||||
for j=0,11 do
|
||||
room.tiles[i][j] = nil
|
||||
room.decor[i][j] = nil
|
||||
room.monsters[i][j] = nil
|
||||
room.traps[i][j] = nil
|
||||
end
|
||||
end
|
||||
return room
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
local module = {}
|
||||
local random = math.random
|
||||
|
||||
local textures = {
|
||||
"Objects/Trap1.png",
|
||||
"Objects/Trap0.png"
|
||||
}
|
||||
|
||||
local traps = {}
|
||||
for i=1,7 do
|
||||
trap = { textures[1], textures[2], i*16, 3*16, CURRENT_LEVEL * 4 }
|
||||
table.insert(traps, trap)
|
||||
end
|
||||
|
||||
local function repack(data)
|
||||
return {
|
||||
texturePath1 = data[1],
|
||||
texturePath2 = data[2],
|
||||
clipX = data[3],
|
||||
clipY = data[4],
|
||||
damage = data[5]
|
||||
}
|
||||
end
|
||||
|
||||
function module.add_traps_to_room(room)
|
||||
if room.type == "coridoor" then
|
||||
if random(2) ~= 1 then return end
|
||||
else
|
||||
if random(4) ~= 1 then return end
|
||||
end
|
||||
|
||||
local count = random(4)
|
||||
local i = 0
|
||||
while i < count do
|
||||
local rx = random(13) + 1
|
||||
local ry = random(9) + 1
|
||||
if not room.decor[rx][ry]
|
||||
and not room.monsters[rx][ry]
|
||||
and (room.tiles[rx][ry]
|
||||
and not room.tiles[rx][ry][5]
|
||||
and not room.tiles[rx][ry][8])
|
||||
then
|
||||
|
||||
room.traps[rx][ry] = traps[random(#traps)]
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function module.load_traps(map, traps)
|
||||
for i=0,15 do
|
||||
for j=0,11 do
|
||||
trap = traps[i][j]
|
||||
if trap then
|
||||
add_trap(map, i, j, repack(trap))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return module
|
18
src/map.c
18
src/map.c
|
@ -25,6 +25,7 @@
|
|||
#include "gui.h"
|
||||
#include "particle_engine.h"
|
||||
#include "update_data.h"
|
||||
#include "trap.h"
|
||||
|
||||
static
|
||||
Room* create_room(void)
|
||||
|
@ -38,6 +39,7 @@ Room* create_room(void)
|
|||
for (j=0; j < MAP_ROOM_HEIGHT; ++j) {
|
||||
room->tiles[i][j] = NULL;
|
||||
room->decorations[i][j] = NULL;
|
||||
room->traps[i][j] = NULL;
|
||||
}
|
||||
}
|
||||
return room;
|
||||
|
@ -113,6 +115,17 @@ void map_add_decoration(Map *map, Position *tile_pos, MapTile *tile)
|
|||
*oldTile = tile;
|
||||
}
|
||||
|
||||
void
|
||||
map_add_trap(Map *map, Position *pos, Trap *trap)
|
||||
{
|
||||
const Position *cr = &map->currentRoom;
|
||||
Trap **oldTrap = &map->rooms[cr->x][cr->y]->traps[pos->x][pos->y];
|
||||
if (*oldTrap)
|
||||
trap_destroy(*oldTrap);
|
||||
|
||||
*oldTrap = trap;
|
||||
}
|
||||
|
||||
void
|
||||
map_clear_dead_monsters(Map *map, Player *player)
|
||||
{
|
||||
|
@ -270,6 +283,8 @@ void map_render(Map *map, Camera *cam)
|
|||
room->decorations[i][j],
|
||||
&tilePos,
|
||||
cam);
|
||||
if (room->traps[i][j])
|
||||
trap_render(room->traps[i][j], cam);
|
||||
}
|
||||
}
|
||||
if (room->modifier.type == RMOD_TYPE_WINDY) {
|
||||
|
@ -335,6 +350,9 @@ void map_room_destroy(Room *room)
|
|||
if (room->decorations[i][j]) {
|
||||
free(room->decorations[i][j]);
|
||||
}
|
||||
if (room->traps[i][j]) {
|
||||
trap_destroy(room->traps[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(room);
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
#include "player.h"
|
||||
#include "map_room_modifiers.h"
|
||||
|
||||
struct UpdateData;
|
||||
typedef struct UpdateData UpdateData;
|
||||
typedef struct Trap Trap;
|
||||
|
||||
typedef struct MapTile_t {
|
||||
int textureIndex0;
|
||||
|
@ -47,6 +48,7 @@ typedef struct MapTile_t {
|
|||
typedef struct Room_t {
|
||||
MapTile* tiles[MAP_ROOM_WIDTH][MAP_ROOM_HEIGHT];
|
||||
MapTile* decorations[MAP_ROOM_WIDTH][MAP_ROOM_HEIGHT];
|
||||
Trap* traps[MAP_ROOM_WIDTH][MAP_ROOM_HEIGHT];
|
||||
RoomModifierData modifier;
|
||||
} Room;
|
||||
|
||||
|
@ -76,6 +78,9 @@ map_add_tile(Map *map, Position *tile_pos, MapTile*);
|
|||
void
|
||||
map_add_decoration(Map *map, Position *tile_pos, MapTile*);
|
||||
|
||||
void
|
||||
map_add_trap(Map*, Position*, Trap*);
|
||||
|
||||
void
|
||||
map_add_monster(Map*, Monster*);
|
||||
|
||||
|
@ -89,7 +94,7 @@ void
|
|||
map_clear_collected_items(Map*);
|
||||
|
||||
void
|
||||
map_update(struct UpdateData*);
|
||||
map_update(UpdateData*);
|
||||
|
||||
void
|
||||
map_render(Map*, Camera*);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "stats.h"
|
||||
#include "io_util.h"
|
||||
#include "texturecache.h"
|
||||
#include "trap.h"
|
||||
|
||||
static
|
||||
lua_State* load_lua_state(void)
|
||||
|
@ -235,47 +236,67 @@ lua_checkstats(lua_State *L, int index)
|
|||
return stats;
|
||||
}
|
||||
|
||||
static
|
||||
int l_tile_occupied(lua_State *L)
|
||||
{
|
||||
Map *map;
|
||||
Room *room;
|
||||
MapTile *tile, *decor;
|
||||
Position *rPos;
|
||||
int x, y;
|
||||
bool response = false;
|
||||
|
||||
map = luaL_checkmap(L, 1);
|
||||
x = (int) luaL_checkinteger(L, 2);
|
||||
y = (int) luaL_checkinteger(L, 3);
|
||||
|
||||
rPos = &map->currentRoom;
|
||||
room = map->rooms[rPos->x][rPos->y];
|
||||
|
||||
tile = room->tiles[x][y];
|
||||
decor = room->decorations[x][y];
|
||||
|
||||
response = response || (tile && (tile->collider || tile->levelExit || tile->lethal));
|
||||
response = response || (decor && (decor->collider || decor->levelExit));
|
||||
|
||||
lua_pushboolean(L, response);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int l_add_tile(lua_State *L)
|
||||
static int
|
||||
l_add_tile(lua_State *L)
|
||||
{
|
||||
extract_tile_data(L, &map_add_tile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int l_add_decoration(lua_State *L)
|
||||
static int
|
||||
l_add_decoration(lua_State *L)
|
||||
{
|
||||
extract_tile_data(L, &map_add_decoration);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_add_trap(lua_State *L)
|
||||
{
|
||||
Map *map = luaL_checkmap(L, 1);
|
||||
int xpos = (int) luaL_checkinteger(L, 2);
|
||||
int ypos = (int) luaL_checkinteger(L, 3);
|
||||
|
||||
// Read the table
|
||||
lua_settop(L, 4);
|
||||
luaL_checktype(L, 4, LUA_TTABLE);
|
||||
|
||||
// Get the fields from the table
|
||||
lua_getfield(L, 4, "texturePath1");
|
||||
lua_getfield(L, 4, "texturePath2");
|
||||
lua_getfield(L, 4, "clipX");
|
||||
lua_getfield(L, 4, "clipY");
|
||||
lua_getfield(L, 4, "damage");
|
||||
|
||||
const char *texturePath1 = luaL_checkstring(L, -5);
|
||||
const char *texturePath2 = luaL_checkstring(L, -4);
|
||||
int clipx = (int) luaL_checkinteger(L, -3);
|
||||
int clipy = (int) luaL_checkinteger(L, -2);
|
||||
int damage = (int) luaL_checkinteger(L, -1);
|
||||
|
||||
Texture *t0 = texturecache_add(texturePath1);
|
||||
Texture *t1 = texturecache_add(texturePath2);
|
||||
|
||||
lua_pop(L, 5);
|
||||
|
||||
const Position *cr = &map->currentRoom;
|
||||
|
||||
Trap *trap = trap_create();
|
||||
sprite_set_texture(trap->sprite, t0, 0);
|
||||
sprite_set_texture(trap->sprite, t1, 1);
|
||||
trap->sprite->clip = CLIP16(clipx, clipy);
|
||||
trap->sprite->pos = (Position) {
|
||||
cr->x * MAP_ROOM_WIDTH * TILE_DIMENSION + xpos * TILE_DIMENSION,
|
||||
cr->y * MAP_ROOM_HEIGHT * TILE_DIMENSION + ypos * TILE_DIMENSION
|
||||
};
|
||||
trap->damage = damage;
|
||||
|
||||
Position trapPos = { xpos, ypos };
|
||||
map_add_trap(map, &trapPos, trap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_add_monster(lua_State *L)
|
||||
{
|
||||
|
@ -316,9 +337,6 @@ l_add_monster(lua_State *L)
|
|||
|
||||
label = strdup(tmp_label);
|
||||
|
||||
texture1->dim = GAME_DIMENSION;
|
||||
texture2->dim = GAME_DIMENSION;
|
||||
|
||||
lua_pop(L, 8);
|
||||
|
||||
monster = monster_create();
|
||||
|
@ -419,6 +437,9 @@ generate_map(unsigned int level, const char *file, SDL_Renderer *renderer)
|
|||
lua_pushcfunction(L, l_add_decoration);
|
||||
lua_setglobal(L, "add_decoration");
|
||||
|
||||
lua_pushcfunction(L, l_add_trap);
|
||||
lua_setglobal(L, "add_trap");
|
||||
|
||||
lua_pushcfunction(L, l_add_texture);
|
||||
lua_setglobal(L, "add_texture");
|
||||
|
||||
|
@ -434,9 +455,6 @@ generate_map(unsigned int level, const char *file, SDL_Renderer *renderer)
|
|||
lua_pushcfunction(L, l_add_monster);
|
||||
lua_setglobal(L, "add_monster");
|
||||
|
||||
lua_pushcfunction(L, l_tile_occupied);
|
||||
lua_setglobal(L, "tile_occupied");
|
||||
|
||||
lua_pushinteger(L, level);
|
||||
lua_setglobal(L, "CURRENT_LEVEL");
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ has_collided(Monster *monster, RoomMatrix *matrix, Vector2d direction)
|
|||
monster_behaviour_check_post_attack(monster);
|
||||
}
|
||||
|
||||
return space->occupied || space->lethal;
|
||||
return space->occupied || space->lethal || space->trap;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -299,7 +299,9 @@ get_optimal_move_towards(Monster *m, RoomMatrix *rm, const Position *dest)
|
|||
x_dist = abs(next.x - dest->x);
|
||||
y_dist = abs(next.y - dest->y);
|
||||
|
||||
if (rm->spaces[next.x][next.y].occupied || rm->spaces[next.x][next.y].lethal) {
|
||||
if (rm->spaces[next.x][next.y].occupied
|
||||
|| rm->spaces[next.x][next.y].lethal
|
||||
|| rm->spaces[next.x][next.y].trap) {
|
||||
nextScore += 50;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "vector2d.h"
|
||||
#include "actiontextbuilder.h"
|
||||
#include "animation.h"
|
||||
#include "trap.h"
|
||||
|
||||
#define ENGINEER_STATS { 12, 12, 5, 7, 2, 2, 1, false, false }
|
||||
#define MAGE_STATS { 12, 12, 5, 7, 1, 2, 1, false, false }
|
||||
|
@ -169,6 +170,10 @@ has_collided(Player *player, RoomMatrix *matrix, Vector2d direction)
|
|||
player->state = FALLING;
|
||||
}
|
||||
|
||||
if (space->trap && !collided) {
|
||||
trap_activate(space->trap, player);
|
||||
}
|
||||
|
||||
return collided;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "item.h"
|
||||
#include "update_data.h"
|
||||
#include "defines.h"
|
||||
#include "trap.h"
|
||||
|
||||
static void
|
||||
roommatrix_reset(RoomMatrix *m)
|
||||
|
@ -42,6 +43,7 @@ roommatrix_reset(RoomMatrix *m)
|
|||
space->light = 0;
|
||||
space->monster = NULL;
|
||||
space->player = NULL;
|
||||
space->trap = NULL;
|
||||
while (space->items != NULL)
|
||||
linkedlist_pop(&space->items);
|
||||
}
|
||||
|
@ -120,6 +122,7 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m)
|
|||
space->lightsource |=
|
||||
r->decorations[i][j]->lightsource;
|
||||
}
|
||||
space->trap = r->traps[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef struct Monster_t Monster;
|
|||
typedef struct Player_t Player;
|
||||
typedef struct Item_t Item;
|
||||
typedef struct Node LinkedList;
|
||||
typedef struct Trap Trap;
|
||||
|
||||
struct UpdateData;
|
||||
|
||||
|
@ -42,6 +43,7 @@ typedef struct {
|
|||
int light;
|
||||
Monster *monster;
|
||||
Player *player;
|
||||
Trap *trap;
|
||||
LinkedList *items;
|
||||
} RoomSpace;
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 <SDL.h>
|
||||
#include "trap.h"
|
||||
#include "util.h"
|
||||
#include "gui.h"
|
||||
|
||||
Trap *
|
||||
trap_create()
|
||||
{
|
||||
Trap *trap = ec_malloc(sizeof(Trap));
|
||||
trap->sprite = sprite_create();
|
||||
trap->sprite->animate = false;
|
||||
trap->sprite->dim = GAME_DIMENSION;
|
||||
trap->damage = 10;
|
||||
return trap;
|
||||
}
|
||||
|
||||
void
|
||||
trap_activate(Trap *trap, Player *player)
|
||||
{
|
||||
player->stats.hp -= trap->damage;
|
||||
player_hit(player, trap->damage);
|
||||
if (!trap->sprite->animate) {
|
||||
gui_log("A trap is sprung!");
|
||||
trap->sprite->animate = true;
|
||||
} else {
|
||||
gui_log("You step in a trap!");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
trap_render(Trap *trap, Camera *cam)
|
||||
{
|
||||
sprite_render(trap->sprite, cam);
|
||||
}
|
||||
|
||||
void
|
||||
trap_destroy(Trap *trap)
|
||||
{
|
||||
sprite_destroy(trap->sprite);
|
||||
free(trap);
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 "sprite.h"
|
||||
#include "player.h"
|
||||
#include "update_data.h"
|
||||
#include "camera.h"
|
||||
|
||||
typedef struct Trap {
|
||||
Sprite *sprite;
|
||||
Uint32 damage;
|
||||
} Trap;
|
||||
|
||||
Trap *
|
||||
trap_create(void);
|
||||
|
||||
void
|
||||
trap_activate(Trap*, Player*);
|
||||
|
||||
void
|
||||
trap_render(Trap*, Camera*);
|
||||
|
||||
void
|
||||
trap_destroy(Trap*);
|
Loading…
Reference in New Issue