From 2ae6ada297ede308cacb7b7d8e198ab557c3250f Mon Sep 17 00:00:00 2001 From: Linus Probert Date: Wed, 20 Mar 2019 09:53:35 +0100 Subject: [PATCH] Completes locked room generation --- data/lockedroomlayouts.dat | 80 +++++++++++++++++++++++++++++++++++++- data/mapgen.lua | 12 +++++- src/item_builder.c | 8 ++-- src/map.c | 5 +++ src/map.h | 2 + src/map_lua.c | 53 +++++++++++++++++++------ src/monster.c | 28 ++++++------- 7 files changed, 156 insertions(+), 32 deletions(-) diff --git a/data/lockedroomlayouts.dat b/data/lockedroomlayouts.dat index 9b34415..30dab93 100644 --- a/data/lockedroomlayouts.dat +++ b/data/lockedroomlayouts.dat @@ -4,9 +4,87 @@ ++#-c--c--c--#++ ++#----------#++ ++#-c--c--c--#++ -++G----------S++ +++G----------G++ +++#-c--c--c--#++ +++#----------#++ +++"#####G####"++ +++++++++++++++++ +++++++++++++++++ + +++++++++++++++++ +++++++++++++++++ +++"#####S####"++ +++#-c--c--c--#++ +++#----------#++ +++#-c--c--c--#++ +++S----------S++ ++#-c--c--c--#++ ++#----------#++ ++"#####S####"++ ++++++++++++++++ +++++++++++++++++ + +++++++++++++++++ +++++++++++++++++ +++/####-#####/++ +++#--c#-#c---#++ +++S---#-#----G++ +++#####-######++ +++------------++ +++#####-######++ +++S--c#-#c---G++ +++/####-#####/++ +++++++++++++++++ +++++++++++++++++ + +++++++++++++++++ +++++++++++++++++ +++----#S#-----++ +++----#c#-----++ +++----#c#-----++ +++----#c#-----++ +++----###-----++ +++------------++ +++------------++ +++------------++ +++++++++++++++++ +++++++++++++++++ + +++++++++++++++++ +++++++++++++++++ +++------------++ +++------------++ +++------------++ +++---###S##---++ +++---#cccc#---++ +++---######---++ +++------------++ +++------------++ +++++++++++++++++ +++++++++++++++++ + +++++++++++++++++ +++++++++++++++++ +++----#G#-----++ +++----#c#-----++ +++----#c#-----++ +++----#c#-----++ +++----###-----++ +++------------++ +++------------++ +++------------++ +++++++++++++++++ +++++++++++++++++ + +++++++++++++++++ +++++++++++++++++ +++------------++ +++------------++ +++------------++ +++---###G##---++ +++---#cccc#---++ +++---######---++ +++------------++ +++------------++ +++++++++++++++++ ++++++++++++++++ \ No newline at end of file diff --git a/data/mapgen.lua b/data/mapgen.lua index 525a65d..59b87cb 100644 --- a/data/mapgen.lua +++ b/data/mapgen.lua @@ -14,6 +14,8 @@ local LEFT = 2 local RIGHT = 3 local DOWN = 4 +local lockedDoorsAdded = false + -- BEGIN FUNCTIONS local function matrix_coverage (matrix) local cov = 0 @@ -128,11 +130,13 @@ local function generate_path () for j=1,10 do room = map_matrix[i][j] if room then - if roomCount > 4 and shopLevel and not shopAdded then + if roomCount > 4 and shopLevel and not shopAdded and not room.goal then room.type = "shop" shopAdded = true + elseif random(8) == 1 and not room.goal then + room.type = "locked" + lockedDoorsAdded = true end - room.type = "locked" roomCount = roomCount + 1 room_builder.build_room(room, i-1, j-1) if room.type ~= "shop" then @@ -178,4 +182,8 @@ for i=1,10 do end end end + +if lockedDoorsAdded then + add_keybearers(map) +end -- END SCRIPT diff --git a/src/item_builder.c b/src/item_builder.c index 12e60ed..8ec2e7a 100644 --- a/src/item_builder.c +++ b/src/item_builder.c @@ -155,15 +155,15 @@ item_builder_build_treasure(Treasure type, double goldAmt) static void pickup_silver_key(Item *item, Player *player) { - UNUSED(item); - player->equipment.keys &= LOCK_SILVER; + gui_log("You pickup %s", item->label); + player->equipment.keys |= LOCK_SILVER; } static void pickup_gold_key(Item *item, Player *player) { - UNUSED(item); - player->equipment.keys &= LOCK_GOLD; + gui_log("You pickup %s", item->label); + player->equipment.keys |= LOCK_GOLD; } Item * diff --git a/src/map.c b/src/map.c index 9d40813..77d8a48 100644 --- a/src/map.c +++ b/src/map.c @@ -37,6 +37,7 @@ create_room(void) room = ec_malloc(sizeof(Room)); room->modifier.type = RMOD_TYPE_NONE; room->visited = false; + room->lockTypes = 0; for (i=0; i < MAP_ROOM_WIDTH; ++i) { for (j=0; j < MAP_ROOM_HEIGHT; ++j) { room->tiles[i][j] = NULL; @@ -63,6 +64,7 @@ map_create(void) map->currentRoom = (Position) { 0, 0 }; map->monsterMoveTimer = _timer_create(); map->level = 1; + map->lockTypes = 0; for (i=0; i < MAP_H_ROOM_COUNT; ++i) { for (j=0; j < MAP_V_ROOM_COUNT; ++j) { @@ -150,6 +152,9 @@ map_add_door(Map *map, Position *tile_pos, MapTile *tile) tile->door = true; tile->sprite->texture_index = 0; tile->sprite->animate = false; + + map->lockTypes |= tile->lockType; + room->lockTypes |= tile->lockType; } void diff --git a/src/map.h b/src/map.h index ad0524c..6b712d2 100644 --- a/src/map.h +++ b/src/map.h @@ -60,6 +60,7 @@ typedef struct Room_t { Trap* traps[MAP_ROOM_WIDTH][MAP_ROOM_HEIGHT]; RoomModifierData modifier; bool visited; + unsigned int lockTypes; } Room; typedef struct Map_t { @@ -72,6 +73,7 @@ typedef struct Map_t { Position currentRoom; Timer *monsterMoveTimer; int level; + unsigned int lockTypes; } Map; Map* diff --git a/src/map_lua.c b/src/map_lua.c index 4eb8ad6..7db1ad2 100644 --- a/src/map_lua.c +++ b/src/map_lua.c @@ -390,20 +390,48 @@ l_add_chest(lua_State *L) return 0; } -static int -l_add_key_to_random_monster(lua_State *L) +static bool +monster_is_in_room_with_locktype(Map *map, Monster *m, DoorLockType lockType) { - Map *map = luaL_checkmap(L, 0); - int keytype = (int) luaL_checkinteger(L, 1); + Position roomPos = position_to_room_coords(&m->sprite->pos); + Room *room = map->rooms[roomPos.x][roomPos.y]; + return room->lockTypes & lockType; +} - unsigned int max = linkedlist_size(&map->monsters); - unsigned int index = bh_map_rand(max - 1); +static void +add_keybearer_to_map(Map *map, int keyType) +{ + for (size_t tries = 0; tries < 10; tries++) { + unsigned int max = linkedlist_size(map->monsters); + unsigned int index = bh_map_rand() % max; - Monster *m = linkedlist_get(&map->monsters, index); - if (!m) - return 0; - - m->items.keyType = keytype; + Monster *m = linkedlist_get(&map->monsters, index); + if (!m) + continue; + + if (m->items.keyType != LOCK_NONE) + continue; + + if (!monster_is_in_room_with_locktype(map, m, keyType)) { + debug("Adding key %d to monster '%s' (%u)", keyType, m->label, index); + m->items.keyType = keyType; + return; + } else { + debug("Looking for another monster to be the keybearer"); + } + } + + error("Failed to find a suitable keybearer (%d)", keyType); +} + +static int +l_add_key_to_random_monsters(lua_State *L) +{ + Map *map = luaL_checkmap(L, 1); + if (map->lockTypes & LOCK_GOLD) + add_keybearer_to_map(map, LOCK_GOLD); + if (map->lockTypes & LOCK_SILVER) + add_keybearer_to_map(map, LOCK_SILVER); return 0; } @@ -644,6 +672,9 @@ generate_map(unsigned int level, const char *file, GameMode gameMode, Player *pl lua_pushcfunction(L, l_add_monster); lua_setglobal(L, "add_monster"); + lua_pushcfunction(L, l_add_key_to_random_monsters); + lua_setglobal(L, "add_keybearers"); + lua_pushcfunction(L, l_get_random_seed); lua_setglobal(L, "get_random_seed"); diff --git a/src/monster.c b/src/monster.c index eee036f..e0fef76 100644 --- a/src/monster.c +++ b/src/monster.c @@ -690,25 +690,25 @@ monster_drop_loot(Monster *monster, Map *map, Player *player) linkedlist_append(&map->artifacts, a); Item *treasure = item_builder_build_item(TREASURE, map->level*2); treasure->sprite->pos = monsterTilePos; - linkedlist_append(&map->items, treasure); - } - - if (strcmp(monster->label, "The Trader") == 0) { - Item *treasure = item_builder_build_treasure(PLATINUM, 10 * monster->stats.lvl); - treasure->sprite->pos = monsterTilePos; - 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); + linkedlist_push(&map->items, treasure); } if (monster->items.keyType != LOCK_NONE) { Item *key = item_builder_build_key(monster->items.keyType); key->sprite->pos = monsterTilePos; - linkedlist_append(&map->items, key); + linkedlist_push(&map->items, key); + } + + if (strcmp(monster->label, "The Trader") == 0) { + Item *treasure = item_builder_build_treasure(PLATINUM, 10 * monster->stats.lvl); + treasure->sprite->pos = monsterTilePos; + linkedlist_push(&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_push(&map->items, treasure); } if (monster->stats.lvl > 2 && get_random(29) == 0) {