From 8f20f36db74ebf8b2216aaec6610fae656fa5f03 Mon Sep 17 00:00:00 2001 From: Linus Probert Date: Fri, 8 Mar 2019 10:16:15 +0100 Subject: [PATCH] Lighting on wall layouts and aggro shopkeepers --- data/layoutparser.lua | 14 +++- data/maproombuilder.lua | 174 ++++++++++++++++++++++++---------------- data/monstergen.lua | 2 +- data/walllayouts.dat | 20 ++--- src/item_builder.c | 46 ++++++----- src/item_builder.h | 3 + src/map_lua.c | 6 ++ src/monster.c | 6 ++ src/player.c | 3 + 9 files changed, 171 insertions(+), 103 deletions(-) diff --git a/data/layoutparser.lua b/data/layoutparser.lua index 2704930..8b2e2f4 100644 --- a/data/layoutparser.lua +++ b/data/layoutparser.lua @@ -184,7 +184,8 @@ function module.load_textures(map, wall_xoffset, wall_yoffset) lights = { candle0 = { t_decor0, t_decor1, 3 * 16, 8 * 16, true, true }, - candle1 = { t_decor0, t_decor1, 1 * 16, 8 * 16, true, true } + candle1 = { t_decor0, t_decor1, 1 * 16, 8 * 16, true, true }, + candle2 = { t_decor0, t_decor1, 5 * 16, 8 * 16, true, false }, } end @@ -196,10 +197,17 @@ function draw_layout_to_room(room, matrix, roomx, roomy) if matrix[i][j] == "p" then setPitTile(room, matrix, i, j); elseif matrix[i][j] == "#" then - setBlockTile(room, matrix, i, j, walls, {"#", "\""}, false) + setBlockTile(room, matrix, i, j, walls, {"#", "\"", "/"}, false) elseif matrix[i][j] == "\"" then - setBlockTile(room, matrix, i, j, walls, {"#", "\""}, false) + setBlockTile(room, matrix, i, j, walls, {"#", "\"", "/"}, false) room.decor[i][j] = lights.candle1 + elseif matrix[i][j] == "/" then + setBlockTile(room, matrix, i, j, walls, {"#", "\"", "/"}, false) + if random(2) == 1 then + room.decor[i][j] = lights.candle1 + else + room.decor[i][j] = lights.candle2 + end elseif matrix[i][j] == "f" then setBlockTile(room, matrix, i, j, fences, "f", true) elseif matrix[i][j] == "a" then diff --git a/data/maproombuilder.lua b/data/maproombuilder.lua index eb60d9c..ed6b314 100644 --- a/data/maproombuilder.lua +++ b/data/maproombuilder.lua @@ -32,6 +32,7 @@ local wall = { local special = { level_exit = nil } local floorDecor = { } +local blockingFloorDecor = { } local lightDecor = { } local function load_decor_textures() @@ -41,9 +42,9 @@ local function load_decor_textures() -- Skulls table.insert(floorDecor, { td0, td1, 0, 12 * 16, false, false }) table.insert(floorDecor, { td0, td1, 32, 12 * 16, false, false }) - table.insert(floorDecor, { td0, td1, 64, 12 * 16, false, true }) table.insert(floorDecor, { td0, td1, 0, 13 * 16, false, false }) table.insert(floorDecor, { td0, td1, 32, 13 * 16, false, false }) + table.insert(floorDecor, { td0, td1, 64, 12 * 16, false, true }) table.insert(floorDecor, { td0, td1, 64, 13 * 16, false, true }) -- Bones @@ -52,52 +53,54 @@ local function load_decor_textures() table.insert(floorDecor, { td0, td1, 16, 13 * 16, false, false }) table.insert(floorDecor, { td0, td1, 48, 13 * 16, false, false }) + -- Webs + table.insert(floorDecor, { td0, td1, 0 * 16, 19 * 16, false }) + table.insert(floorDecor, { td0, td1, 1 * 16, 19 * 16, false }) + table.insert(floorDecor, { td0, td1, 2 * 16, 19 * 16, false }) + table.insert(floorDecor, { td0, td1, 3 * 16, 19 * 16, false }) + table.insert(floorDecor, { td0, td1, 4 * 16, 19 * 16, false }) + -- Urns - --table.insert(floorDecor, { td0, td1, 0 * 16, 48, true, false }) - --table.insert(floorDecor, { td0, td1, 1 * 16, 48, true, false }) - --table.insert(floorDecor, { td0, td1, 2 * 16, 48, true, false }) - --table.insert(floorDecor, { td0, td1, 3 * 16, 48, true, false }) - --table.insert(floorDecor, { td0, td1, 4 * 16, 48, true, false }) - --table.insert(floorDecor, { td0, td1, 5 * 16, 48, true, false }) - --table.insert(floorDecor, { td0, td1, 6 * 16, 48, false, false }) - --table.insert(floorDecor, { td0, td1, 7 * 16, 48, false, false }) + table.insert(floorDecor, { td0, td1, 6 * 16, 48, false, false }) + table.insert(floorDecor, { td0, td1, 7 * 16, 48, false, false }) + + -- Urns + --table.insert(blockingFloorDecor, { td0, td1, 0 * 16, 48, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 1 * 16, 48, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 2 * 16, 48, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 3 * 16, 48, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 4 * 16, 48, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 5 * 16, 48, true, false }) -- Racks - --table.insert(floorDecor, { td0, td1, 0 * 16, 11 * 16, true, false }) - --table.insert(floorDecor, { td0, td1, 1 * 16, 11 * 16, true, false }) - --table.insert(floorDecor, { td0, td1, 2 * 16, 11 * 16, true, false }) - --table.insert(floorDecor, { td0, td1, 3 * 16, 11 * 16, true, false }) - --table.insert(floorDecor, { td0, td1, 4 * 16, 11 * 16, true, false }) - --table.insert(floorDecor, { td0, td1, 5 * 16, 11 * 16, true, false }) - --table.insert(floorDecor, { td0, td1, 6 * 16, 11 * 16, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 0 * 16, 11 * 16, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 1 * 16, 11 * 16, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 2 * 16, 11 * 16, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 3 * 16, 11 * 16, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 4 * 16, 11 * 16, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 5 * 16, 11 * 16, true, false }) + --table.insert(blockingFloorDecor, { td0, td1, 6 * 16, 11 * 16, true, false }) -- Headstones - table.insert(floorDecor, { td0, td1, 0 * 16, 17 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 1 * 16, 17 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 2 * 16, 17 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 3 * 16, 17 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 4 * 16, 17 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 0 * 16, 18 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 1 * 16, 18 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 2 * 16, 18 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 3 * 16, 18 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 4 * 16, 18 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 0 * 16, 17 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 1 * 16, 17 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 2 * 16, 17 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 3 * 16, 17 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 4 * 16, 17 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 0 * 16, 18 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 1 * 16, 18 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 2 * 16, 18 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 3 * 16, 18 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 4 * 16, 18 * 16, true, false }) -- Altars - table.insert(floorDecor, { td0, td1, 0 * 16, 20 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 1 * 16, 20 * 16, true, false }) - table.insert(floorDecor, { td0, td1, 2 * 16, 20 * 16, true, false }) - - -- Webs - --table.insert(floorDecor, { td0, td1, 0 * 16, 19 * 16, false }) - --table.insert(floorDecor, { td0, td1, 1 * 16, 19 * 16, false }) - --table.insert(floorDecor, { td0, td1, 2 * 16, 19 * 16, false }) - --table.insert(floorDecor, { td0, td1, 3 * 16, 19 * 16, false }) - --table.insert(floorDecor, { td0, td1, 4 * 16, 19 * 16, false }) + table.insert(blockingFloorDecor, { td0, td1, 0 * 16, 20 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 1 * 16, 20 * 16, true, false }) + table.insert(blockingFloorDecor, { td0, td1, 2 * 16, 20 * 16, true, false }) -- Statues - --table.insert(floorDecor, { td0, td1, 3 * 16, 20 * 16, true }) - --table.insert(floorDecor, { td0, td1, 4 * 16, 20 * 16, true }) + --table.insert(blockingFloorDecor, { td0, td1, 3 * 16, 20 * 16, true }) + --table.insert(blockingFloorDecor, { td0, td1, 4 * 16, 20 * 16, true }) lightDecor.candle0 = { td0, td1, 0, 8 * 16, false, true } lightDecor.candle1 = { td0, td1, 16, 8 * 16, false, true } @@ -122,27 +125,63 @@ local function repack(data) } end -local function add_random_decor_to_room(room) +local function room_tile_available(room, rx, ry) + return not room.chests[rx][ry] + and not room.traps[rx][ry] + and not room.monsters[rx][ry] + and not room.decor[rx][ry] + and (room.tiles[rx][ry] + and not room.tiles[rx][ry][5] + and not room.tiles[rx][ry][7] + and not room.tiles[rx][ry][8]) +end + + +local function add_random_decor_to_room(room, blockingDecor) local decor_count = random(8) + if blockingDecor then + decor_count = random(4) + end for i=1,decor_count do - x = random(11) + 1 - y = random(8) + 1 - if not room.decor[x][y] then - room.decor[x][y] = floorDecor[random(#floorDecor)] + local success = false + while not success do + x = random(11) + 1 + y = random(8) + 1 + if room_tile_available(room, x, y) then + room.decor[x][y] = floorDecor[random(#floorDecor)] + success = true + end end end - if random(2) == 1 then - room.decor[4][3] = lightDecor.candle2 + if blockingDecor then + decor_count = random(4) + for i=1,decor_count do + local success = false + while not success do + x = random(11) + 1 + y = random(8) + 1 + if room_tile_available(room, x, y) then + room.decor[x][y] = blockingFloorDecor[random(#blockingFloorDecor)] + success = true + end + end + end end - if random(2) == 1 then - room.decor[11][3] = lightDecor.candle2 - end - if random(2) == 1 then - room.decor[4][9] = lightDecor.candle2 - end - if random(2) == 1 then - room.decor[11][9] = lightDecor.candle2 + + if blockingDecor then + if random(2) == 1 and room_tile_available(room, 4, 3) then + room.decor[4][3] = lightDecor.candle2 + end + if random(2) == 1 and room_tile_available(room, 11, 3) then + room.decor[11][3] = lightDecor.candle2 + end + if random(2) == 1 and room_tile_available(room, 4, 9) then + room.decor[4][9] = lightDecor.candle2 + end + if random(2) == 1 and room_tile_available(room, 11, 9) then + room.decor[11][9] = lightDecor.candle2 + end end end @@ -322,19 +361,8 @@ local function build_coridoor_room(room) build_center_corner_walls(room, exits) end -local function room_tile_available(room, rx, ry) - return not room.chests[rx][ry] - and not room.traps[rx][ry] - and not room.monsters[rx][ry] - and not room.decor[rx][ry] - and (room.tiles[rx][ry] - and not room.tiles[rx][ry][5] - and not room.tiles[rx][ry][7] - and not room.tiles[rx][ry][8]) -end - local function add_level_exit(room) - success = false + local success = false while not success do x = random(14) y = random(10) @@ -355,13 +383,21 @@ end local function build_normal_room(room) local crumbling = (CURRENT_LEVEL > 3 or QUICK_MODE) and random(8) == 1 + local pitsAdded = false; + local interiorWallsAdded = false add_tiles_to_room(room, crumbling) - add_random_decor_to_room(room) add_walls_to_room(room) add_exits_to_room(room) - local pitsAdded = crumbling or layoutparser.add_pits_to_room(room) - layoutparser.add_walls_to_room(room) + + if not crumbling then + pitsAdded = layoutparser.add_pits_to_room(room) + end + if not pitsAdded then + interiorWallsAdded = layoutparser.add_walls_to_room(room) + end + + add_random_decor_to_room(room, not interiorWallsAdded) if room.goal then add_level_exit(room) @@ -373,7 +409,7 @@ local function build_normal_room(room) elseif (CURRENT_LEVEL > 3 or QUICK_MODE) and random(8) == 1 then room.modifier.type = "FIRE" room.modifier.arg = "" - elseif ((not pitsAdded and (CURRENT_LEVEL > 1 or QUICK_MODE)) or CURRENT_LEVEL > 3) and random(8) == 1 then + elseif ((not pitsAdded and not crumbling and (CURRENT_LEVEL > 1 or QUICK_MODE)) or CURRENT_LEVEL > 3) and random(8) == 1 then directions = { "LEFT", "RIGHT", "UP", "DOWN" } room.modifier.type = "WINDY" room.modifier.arg = directions[random(#directions)] diff --git a/data/monstergen.lua b/data/monstergen.lua index 2d28ee8..56aaee2 100644 --- a/data/monstergen.lua +++ b/data/monstergen.lua @@ -108,7 +108,7 @@ local stats = { speed = 1 }, shopkeeper = { - hp = 100, + hp = 200, dmg = 10, atk = 2, def = 0, diff --git a/data/walllayouts.dat b/data/walllayouts.dat index 25bdf10..27f7855 100644 --- a/data/walllayouts.dat +++ b/data/walllayouts.dat @@ -1,13 +1,13 @@ ++++++++++++++++ ++++++++++++++++ -++##--------##++ +++/#--------#/++ ++##--------##++ ++------------++ ++------------++ ++------------++ ++------------++ ++##--------##++ -++##--------##++ +++/#--------#/++ ++++++++++++++++ ++++++++++++++++ @@ -15,9 +15,9 @@ ++++++++++++++++ ++#--#-#-#-#-#++ ++------------++ -++#-#-#-#-#--#++ +++/-#-#-#-#--/++ ++------------++ -++#--#-#-#-#-#++ +++/--#-#-#-#-/++ ++------------++ ++--#-#-#-#---++ ++#-########-#++ @@ -28,10 +28,10 @@ ++++++++++++++++ ++############++ ++#----------#++ -++#-########-#++ +++#-/#######-#++ ++--#------#-#++ ++--#--------#++ -++#-########-#++ +++#-/#######-#++ ++#----------#++ ++############++ ++++++++++++++++ @@ -39,26 +39,26 @@ ++++++++++++++++ ++++++++++++++++ -++##--------##++ +++/#--------#/++ ++##-ffffff-##++ ++---f----f---++ ++--------f---++ ++--------f---++ ++---f----f---++ ++##-ffffff-##++ -++##--------##++ +++/#--------#/++ ++++++++++++++++ ++++++++++++++++ ++++++++++++++++ ++++++++++++++++ -++##ffffffff##++ +++/#ffffffff#/++ ++##--------##++ ++------------++ ++---######---++ ++---######---++ ++------------++ ++##--------##++ -++##ffffffff##++ +++/#ffffffff#/++ ++++++++++++++++ ++++++++++++++++ diff --git a/src/item_builder.c b/src/item_builder.c index d779b60..f49703b 100644 --- a/src/item_builder.c +++ b/src/item_builder.c @@ -109,29 +109,13 @@ pickup_gold(Item *item, Player *player) gui_log("You pick up %s", &item->label); } -static Item * -create_treasure(int current_level) +Item * +item_builder_build_treasure(Treasure type, double goldAmt) { - double amt; + double amt = goldAmt; char label[50] = ""; - unsigned int highest_treasure; - unsigned int value; - - amt = (unsigned int) 1 + get_random(5*current_level) % 40; - amt = amt == 0 ? 1 : amt; - - if (current_level > 9) { - highest_treasure = PLATINUM; - } else if (current_level > 3) { - highest_treasure = GOLD; - } else { - highest_treasure = SILVER; - } - - value = get_random(highest_treasure); - SDL_Rect clip = CLIP16(0, 0); - switch (value) { + switch (type) { case COPPER: m_sprintf(label, 50, "%.0f copper", amt); amt /= 100; @@ -166,6 +150,28 @@ create_treasure(int current_level) return item; } +static Item * +create_treasure(int current_level) +{ + double amt; + unsigned int highest_treasure; + unsigned int value; + + amt = (unsigned int) 1 + get_random(5*current_level) % 40; + amt = amt == 0 ? 1 : amt; + + if (current_level > 9) { + highest_treasure = PLATINUM; + } else if (current_level > 3) { + highest_treasure = GOLD; + } else { + highest_treasure = SILVER; + } + + value = get_random(highest_treasure); + return item_builder_build_treasure((Treasure) value, amt); +} + Item * item_builder_build_item(ItemKey key, int level) { diff --git a/src/item_builder.h b/src/item_builder.h index 0a3f670..38cff4a 100644 --- a/src/item_builder.h +++ b/src/item_builder.h @@ -53,6 +53,9 @@ item_builder_build_sack(void); Item * item_builder_build_container(const char *path0, const char *path1, SDL_Rect clip); +Item * +item_builder_build_treasure(Treasure type, double goldAmt); + void item_builder_close(void); diff --git a/src/map_lua.c b/src/map_lua.c index 65ae4dc..6cd6fae 100644 --- a/src/map_lua.c +++ b/src/map_lua.c @@ -375,6 +375,7 @@ l_add_chest(lua_State *L) static int l_add_monster(lua_State *L) { + Player *player = luaL_checkplayer(L); Monster *monster; Map *map; int x, y, clip_x, clip_y, behaviour; @@ -417,6 +418,11 @@ l_add_monster(lua_State *L) lua_pop(L, 8); + // Make sure traders stay hostile if you've killed one + if (strcmp(label, "The Trader") == 0 && player->stateData.shopOwnerKiller) { + behaviour = HOSTILE; + } + monster = monster_create(); monster->sprite->clip = (SDL_Rect) { clip_x, clip_y, 16, 16 }; monster_update_pos(monster, (Position) { x, y }); diff --git a/src/monster.c b/src/monster.c index 904ed64..c14c62f 100644 --- a/src/monster.c +++ b/src/monster.c @@ -690,6 +690,12 @@ monster_drop_loot(Monster *monster, Map *map, Player *player) linkedlist_append(&map->items, treasure); } + if (strcmp(monster->label, "The Trader") == 0) { + Item *treasure = item_builder_build_treasure(PLATINUM, 25 * 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; diff --git a/src/player.c b/src/player.c index c6acd29..3ee1c0f 100644 --- a/src/player.c +++ b/src/player.c @@ -607,6 +607,9 @@ player_monster_kill_check(Player *player, Monster *monster) else if (strcmp("Ti, the Mage", monster->label) == 0) steam_set_achievement(BUGGCREATOR); #endif // STEAM_BUILD + if (strcmp("The Trader", monster->label) == 0) { + player->stateData.shopOwnerKiller = true; + } } }