From 3f3975061cfbf24d792b2eecdbb893cc5a5f61d6 Mon Sep 17 00:00:00 2001 From: curstwist <39442864+curstwist@users.noreply.github.com> Date: Thu, 3 Oct 2019 14:21:17 -0400 Subject: [PATCH 01/21] add faction base to 1st shelter includes palettes for rock, log, wood, wattle and daub, and standard t_wall. --- .../modular_shelter_common.json | 437 ++++++++++++++++++ .../modular_shelter/modular_shelter_log.json | 126 +++++ .../modular_shelter/modular_shelter_rock.json | 126 +++++ .../modular_shelter_standard.json | 126 +++++ .../modular_shelter/modular_shelter_wad.json | 126 +++++ .../modular_shelter/modular_shelter_wood.json | 126 +++++ .../json/recipes/basecamps/recipe_groups.json | 3 +- .../recipe_modular_shelter_common.json | 412 +++++++++++++++++ .../recipe_modular_shelter_log.json | 77 +++ .../recipe_modular_shelter_rock.json | 77 +++ .../recipe_modular_shelter_standard.json | 77 +++ .../recipe_modular_shelter_wad.json | 77 +++ .../recipe_modular_shelter_wood.json | 77 +++ 13 files changed, 1866 insertions(+), 1 deletion(-) create mode 100644 data/json/mapgen/basecamps/modular_shelter/modular_shelter_common.json create mode 100644 data/json/mapgen/basecamps/modular_shelter/modular_shelter_log.json create mode 100644 data/json/mapgen/basecamps/modular_shelter/modular_shelter_rock.json create mode 100644 data/json/mapgen/basecamps/modular_shelter/modular_shelter_standard.json create mode 100644 data/json/mapgen/basecamps/modular_shelter/modular_shelter_wad.json create mode 100644 data/json/mapgen/basecamps/modular_shelter/modular_shelter_wood.json create mode 100644 data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_common.json create mode 100644 data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_log.json create mode 100644 data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_rock.json create mode 100644 data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_standard.json create mode 100644 data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_wad.json create mode 100644 data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_wood.json diff --git a/data/json/mapgen/basecamps/modular_shelter/modular_shelter_common.json b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_common.json new file mode 100644 index 0000000000000..b57a89a18abc4 --- /dev/null +++ b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_common.json @@ -0,0 +1,437 @@ +[ + { + "type": "palette", + "id": "fbmc_shelter_palette", + "terrain": { "w": "t_wall", "d": "t_door_c" }, + "furniture": { + "h": "f_chair", + "t": "f_table", + "c": "f_workbench", + "r": "f_rack", + "b": "f_bed", + "m": "f_straw_bed", + "n": "f_makeshift_bed", + "L": "f_locker", + "s": "f_sofa", + "C": "f_armchair", + "B": "f_bookcase" + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_0", + "method": "json", + "object": { + "set": [ + { "point": "terrain", "id": "t_floor", "x": 9, "y": 9 }, + { "point": "furniture", "id": "f_bulletin", "x": 9, "y": 9 } + ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_fireplace", + "method": "json", + "object": { + "set": [ + { "point": "furniture", "id": "f_fireplace", "x": 18, "y": 11 }, + { "point": "furniture", "id": "f_table", "x": 18, "y": 12 } + ], + "place_loot": [ { "item": "pot", "x": 18, "y": 12, "chance": 100 } ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_brazier", + "method": "json", + "object": { + "set": [ + { "point": "furniture", "id": "f_brazier", "x": 18, "y": 11 }, + { "point": "furniture", "id": "f_table", "x": 18, "y": 12 } + ], + "place_loot": [ { "item": "pot", "x": 18, "y": 12, "chance": 100 } ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_stove", + "method": "json", + "object": { + "set": [ + { "point": "furniture", "id": "f_woodstove", "x": 18, "y": 11 }, + { "point": "furniture", "id": "f_table", "x": 18, "y": 12 } + ], + "place_loot": [ { "item": "pot", "x": 18, "y": 12, "chance": 100 } ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_well", + "method": "json", + "object": { "set": [ { "point": "terrain", "id": "t_water_pump", "x": 16, "y": 9 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SE", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_se", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SE" ], "x": 15, "y": 19 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_E", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_e", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_E" ], "x": 15, "y": 15 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SW", + "object": { + "mapgensize": [ 5, 5 ], + "rows": [ + " wwww", + " w", + " d", + " w", + " www" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_SW", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SW" ], "x": 4, "y": 16 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_W", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_W", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_W" ], "x": 5, "y": 12 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_NW", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + " ", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_NW", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_NW" ], "x": 5, "y": 8 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bed_standard_east_wall", + "object": { + "mapgensize": [ 3, 3 ], + "rows": [ + "Lbb", + " t", + "Lbb" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_standard_SE", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_standard_east_wall" ], "x": 16, "y": 20 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_standard_E", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_standard_east_wall" ], "x": 16, "y": 16 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bed_straw_east_wall", + "object": { + "mapgensize": [ 3, 3 ], + "rows": [ + "Lmm", + " t", + "Lmm" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_straw_SE", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_straw_east_wall" ], "x": 16, "y": 20 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_straw_E", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_straw_east_wall" ], "x": 16, "y": 16 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bed_makeshift_east_wall", + "object": { + "mapgensize": [ 3, 3 ], + "rows": [ + "Lnn", + " t", + "Lnn" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_makeshift_SE", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_makeshift_east_wall" ], "x": 16, "y": 20 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_makeshift_E", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_makeshift_east_wall" ], "x": 16, "y": 16 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bed_standard_west_wall", + "object": { + "mapgensize": [ 3, 3 ], + "rows": [ + "bbL", + "t ", + "bbL" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_standard_SW", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_standard_west_wall" ], "x": 5, "y": 17 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_standard_W", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_standard_west_wall" ], "x": 5, "y": 13 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_standard_NW", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_standard_west_wall" ], "x": 5, "y": 9 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bed_straw_west_wall", + "object": { + "mapgensize": [ 3, 3 ], + "rows": [ + "mmL", + "t ", + "mmL" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_straw_SW", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_straw_west_wall" ], "x": 5, "y": 17 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_straw_W", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_straw_west_wall" ], "x": 5, "y": 13 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_straw_NW", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_straw_west_wall" ], "x": 5, "y": 9 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bed_makeshift_west_wall", + "object": { + "mapgensize": [ 3, 3 ], + "rows": [ + "nnL", + "t ", + "nnL" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_makeshift_SW", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_makeshift_west_wall" ], "x": 5, "y": 17 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_makeshift_W", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_makeshift_west_wall" ], "x": 5, "y": 13 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_beds_makeshift_NW", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bed_makeshift_west_wall" ], "x": 5, "y": 9 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_dining_room", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + " hth", + " hth", + " hth", + " hth" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_dining", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_dining_room" ], "x": 10, "y": 10 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_living_room", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "tsss", + " ", + " ", + " CtC" + ], + "palettes": [ "fbmc_shelter_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_livingroom", + "method": "json", + "object": { + "place_nested": [ { "chunks": [ "fbmc_shelter_living_room" ], "x": 10, "y": 18 } ], + "set": [ + { "point": "furniture", "id": "f_bookcase", "x": 7, "y": 21 }, + { "point": "furniture", "id": "f_bookcase", "x": 8, "y": 21 } + ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_pantry", + "method": "json", + "object": { + "set": [ + { "point": "furniture", "id": "f_rack_wood", "x": 15, "y": 9 }, + { "point": "furniture", "id": "f_rack_wood", "x": 15, "y": 14 }, + { "point": "furniture", "id": "f_rack_wood", "x": 16, "y": 14 }, + { "point": "furniture", "id": "f_rack_wood", "x": 17, "y": 14 }, + { "point": "furniture", "id": "f_rack_wood", "x": 18, "y": 14 } + ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_craftspot", + "method": "json", + "object": { + "set": [ + { "point": "furniture", "id": "f_workbench", "x": 16, "y": 11 }, + { "point": "furniture", "id": "f_workbench", "x": 16, "y": 12 } + ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_radio_console", + "method": "json", + "object": { + "set": [ + { "point": "terrain", "id": "t_radio_tower", "x": 5, "y": 7 }, + { "point": "terrain", "id": "t_radio_controls", "x": 6, "y": 7 } + ] + } + } +] diff --git a/data/json/mapgen/basecamps/modular_shelter/modular_shelter_log.json b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_log.json new file mode 100644 index 0000000000000..41a7e38909c8a --- /dev/null +++ b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_log.json @@ -0,0 +1,126 @@ +[ + { + "type": "palette", + "id": "fbmc_shelter_palette_log", + "terrain": { "w": "t_wall_log", "d": "t_door_c" }, + "furniture": { + "h": "f_chair", + "t": "f_table", + "c": "f_workbench", + "r": "f_rack", + "b": "f_bed", + "m": "f_straw_bed", + "n": "f_makeshift_bed", + "L": "f_locker", + "s": "f_sofa", + "C": "f_armchair", + "B": "f_bookcase" + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SE_log", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette_log" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_se_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SE_log" ], "x": 15, "y": 19 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_E_log", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette_log" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_e_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_E_log" ], "x": 15, "y": 15 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SW_log", + "object": { + "mapgensize": [ 5, 5 ], + "rows": [ + " wwww", + " w", + " d", + " w", + " www" + ], + "palettes": [ "fbmc_shelter_palette_log" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_SW_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SW_log" ], "x": 4, "y": 16 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_W_log", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette_log" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_W_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_W_log" ], "x": 5, "y": 12 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_NW_log", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + " ", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette_log" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_NW_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_NW_log" ], "x": 5, "y": 8 } ] } + } +] diff --git a/data/json/mapgen/basecamps/modular_shelter/modular_shelter_rock.json b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_rock.json new file mode 100644 index 0000000000000..d0ea3612852bc --- /dev/null +++ b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_rock.json @@ -0,0 +1,126 @@ +[ + { + "type": "palette", + "id": "fbmc_shelter_palette_rock", + "terrain": { "w": "t_rock_wall", "d": "t_door_c" }, + "furniture": { + "h": "f_chair", + "t": "f_table", + "c": "f_workbench", + "r": "f_rack", + "b": "f_bed", + "m": "f_straw_bed", + "n": "f_makeshift_bed", + "L": "f_locker", + "s": "f_sofa", + "C": "f_armchair", + "B": "f_bookcase" + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SE_rock", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette_rock" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_se_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SE_rock" ], "x": 15, "y": 19 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_E_rock", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette_rock" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_e_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_E_rock" ], "x": 15, "y": 15 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SW_rock", + "object": { + "mapgensize": [ 5, 5 ], + "rows": [ + " wwww", + " w", + " d", + " w", + " www" + ], + "palettes": [ "fbmc_shelter_palette_rock" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_SW_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SW_rock" ], "x": 4, "y": 16 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_W_rock", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette_rock" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_W_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_W_rock" ], "x": 5, "y": 12 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_NW_rock", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + " ", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette_rock" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_NW_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_NW_rock" ], "x": 5, "y": 8 } ] } + } +] diff --git a/data/json/mapgen/basecamps/modular_shelter/modular_shelter_standard.json b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_standard.json new file mode 100644 index 0000000000000..d0ea3612852bc --- /dev/null +++ b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_standard.json @@ -0,0 +1,126 @@ +[ + { + "type": "palette", + "id": "fbmc_shelter_palette_rock", + "terrain": { "w": "t_rock_wall", "d": "t_door_c" }, + "furniture": { + "h": "f_chair", + "t": "f_table", + "c": "f_workbench", + "r": "f_rack", + "b": "f_bed", + "m": "f_straw_bed", + "n": "f_makeshift_bed", + "L": "f_locker", + "s": "f_sofa", + "C": "f_armchair", + "B": "f_bookcase" + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SE_rock", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette_rock" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_se_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SE_rock" ], "x": 15, "y": 19 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_E_rock", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette_rock" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_e_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_E_rock" ], "x": 15, "y": 15 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SW_rock", + "object": { + "mapgensize": [ 5, 5 ], + "rows": [ + " wwww", + " w", + " d", + " w", + " www" + ], + "palettes": [ "fbmc_shelter_palette_rock" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_SW_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SW_rock" ], "x": 4, "y": 16 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_W_rock", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette_rock" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_W_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_W_rock" ], "x": 5, "y": 12 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_NW_rock", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + " ", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette_rock" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_NW_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_NW_rock" ], "x": 5, "y": 8 } ] } + } +] diff --git a/data/json/mapgen/basecamps/modular_shelter/modular_shelter_wad.json b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_wad.json new file mode 100644 index 0000000000000..d540afb4fe26a --- /dev/null +++ b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_wad.json @@ -0,0 +1,126 @@ +[ + { + "type": "palette", + "id": "fbmc_shelter_palette_wad", + "terrain": { "w": "t_wall_wattle", "d": "t_door_makeshift_c" }, + "furniture": { + "h": "f_chair", + "t": "f_table", + "c": "f_workbench", + "r": "f_rack", + "b": "f_bed", + "m": "f_straw_bed", + "n": "f_makeshift_bed", + "L": "f_locker", + "s": "f_sofa", + "C": "f_armchair", + "B": "f_bookcase" + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SE_wad", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette_wad" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_se_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SE_wad" ], "x": 15, "y": 19 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_E_wad", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette_wad" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_e_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_E_wad" ], "x": 15, "y": 15 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SW_wad", + "object": { + "mapgensize": [ 5, 5 ], + "rows": [ + " wwww", + " w", + " d", + " w", + " www" + ], + "palettes": [ "fbmc_shelter_palette_wad" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_SW_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SW_wad" ], "x": 4, "y": 16 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_W_wad", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette_wad" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_W_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_W_wad" ], "x": 5, "y": 12 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_NW_wad", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + " ", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette_wad" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_NW_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_NW_wad" ], "x": 5, "y": 8 } ] } + } +] diff --git a/data/json/mapgen/basecamps/modular_shelter/modular_shelter_wood.json b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_wood.json new file mode 100644 index 0000000000000..3ae2a13a2785b --- /dev/null +++ b/data/json/mapgen/basecamps/modular_shelter/modular_shelter_wood.json @@ -0,0 +1,126 @@ +[ + { + "type": "palette", + "id": "fbmc_shelter_palette_wood", + "terrain": { "w": "t_wall_wood", "d": "t_door_c" }, + "furniture": { + "h": "f_chair", + "t": "f_table", + "c": "f_workbench", + "r": "f_rack", + "b": "f_bed", + "m": "f_straw_bed", + "n": "f_makeshift_bed", + "L": "f_locker", + "s": "f_sofa", + "C": "f_armchair", + "B": "f_bookcase" + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SE_wood", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette_wood" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_se_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SE_wood" ], "x": 15, "y": 19 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_E_wood", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + "w ", + "d ", + "w " + ], + "palettes": [ "fbmc_shelter_palette_wood" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_e_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_E_wood" ], "x": 15, "y": 15 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_SW_wood", + "object": { + "mapgensize": [ 5, 5 ], + "rows": [ + " wwww", + " w", + " d", + " w", + " www" + ], + "palettes": [ "fbmc_shelter_palette_wood" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_SW_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_SW_wood" ], "x": 4, "y": 16 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_W_wood", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + "wwww", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette_wood" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_W_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_W_wood" ], "x": 5, "y": 12 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmc_shelter_bedroom_NW_wood", + "object": { + "mapgensize": [ 4, 4 ], + "rows": [ + " ", + " w", + " d", + " w" + ], + "palettes": [ "fbmc_shelter_palette_wood" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmc_shelter_bedroom_NW_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmc_shelter_bedroom_NW_wood" ], "x": 5, "y": 8 } ] } + } +] diff --git a/data/json/recipes/basecamps/recipe_groups.json b/data/json/recipes/basecamps/recipe_groups.json index 2dfa2c1287c76..1fc3917ccdc57 100644 --- a/data/json/recipes/basecamps/recipe_groups.json +++ b/data/json/recipes/basecamps/recipe_groups.json @@ -5,7 +5,8 @@ "building_type": "NONE", "recipes": [ { "id": "faction_base_modular_hub_field_0", "description": "Field Camp", "om_terrains": [ "field" ] }, - { "id": "faction_base_firestation_0", "description": "Firestation Base", "om_terrains": [ "fire_station" ] } + { "id": "faction_base_firestation_0", "description": "Firestation Base", "om_terrains": [ "fire_station" ] }, + { "id": "faction_base_shelter_0", "description": "Evac Shelter Base", "om_terrains": [ "shelter" ] } ] }, { diff --git a/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_common.json b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_common.json new file mode 100644 index 0000000000000..a1c49a9ab359c --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_common.json @@ -0,0 +1,412 @@ +[ + { + "type": "recipe", + "result": "faction_base_shelter_0", + "description": "We should survey the base site and set up a bulletin board.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "time": "1 h", + "construction_blueprint": "fbmc_shelter_0", + "blueprint_provides": [ + { "id": "gathering" }, + { "id": "primitive_camp_recipes_1" }, + { "id": "fbmc_shelter_0" }, + { "id": "firewood" }, + { "id": "foraging" }, + { "id": "sorting" }, + { "id": "logging" } + ], + "blueprint_requires": [ { "id": "not_an_upgrade" } ], + "blueprint_name": "basic survey" + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_fireplace", + "description": "We should build a fireplace for cooking and grab a pot. Let's set up near the working terminal.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_fireplace", + "blueprint_name": "build a fireplace", + "blueprint_requires": [ { "id": "fbmc_shelter_0" } ], + "blueprint_provides": [ + { "id": "fbmc_shelter_fire" }, + { "id": "trapping" }, + { "id": "hunting" }, + { "id": "kitchen" }, + { "id": "kitchen_recipes_1" } + ], + "blueprint_excludes": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_resources": [ "fake_fireplace", "pot" ], + "blueprint_autocalc": true, + "components": [ [ [ "pot", 1 ], [ "rock_pot", 1 ], [ "pot_copper", 1 ], [ "clay_pot", 1 ] ] ] + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_brazier", + "description": "We should build a brazier for cooking and grab a pot. Let's set up near the working terminal.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "time": "5 m", + "construction_blueprint": "fbmc_shelter_brazier", + "blueprint_name": "build a brazier", + "blueprint_requires": [ { "id": "fbmc_shelter_0" } ], + "blueprint_provides": [ + { "id": "fbmc_shelter_fire" }, + { "id": "trapping" }, + { "id": "hunting" }, + { "id": "kitchen" }, + { "id": "kitchen_recipes_1" } + ], + "blueprint_excludes": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_resources": [ "fake_fireplace", "pot" ], + "blueprint_autocalc": true, + "components": [ [ [ "brazier", 1 ] ], [ [ "pot", 1 ], [ "rock_pot", 1 ], [ "pot_copper", 1 ], [ "clay_pot", 1 ] ] ] + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_stove", + "description": "We should build a wood stove for cooking and grab a pot. Let's set up near the working terminal.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_stove", + "blueprint_name": "build a wood stove", + "blueprint_requires": [ { "id": "fbmc_shelter_0" } ], + "blueprint_provides": [ + { "id": "fbmc_shelter_fire" }, + { "id": "trapping" }, + { "id": "hunting" }, + { "id": "kitchen" }, + { "id": "kitchen_recipes_1" } + ], + "blueprint_excludes": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_resources": [ "fake_fireplace", "pot" ], + "blueprint_autocalc": true, + "components": [ [ [ "pot", 1 ], [ "rock_pot", 1 ], [ "pot_copper", 1 ], [ "clay_pot", 1 ] ] ] + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_well", + "description": "We should build a well, put it near the terminal. This will make our future here more secure.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_well", + "blueprint_name": "build a well", + "blueprint_requires": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_well" }, { "id": "relaying" }, { "id": "scouting" }, { "id": "patrolling" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_well" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_standard_SE", + "description": "Let's furnish the southeast bedroom with regular beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_standard_SE", + "blueprint_name": "furnish the SE bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_se" }, { "id": "bed", "amount": 3 } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_se" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_standard_E", + "description": "Let's furnish the east bedroom with regular beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_standard_E", + "blueprint_name": "furnish the E bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom2" }, { "id": "fbmc_shelter_beds_se" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_e" }, { "id": "bed", "amount": 4 } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_e" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_straw_SE", + "description": "Let's furnish the southeast bedroom with straw beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_straw_SE", + "blueprint_name": "furnish the SE bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_se" }, { "id": "bed", "amount": 3 } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_se" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_straw_E", + "description": "Let's furnish the east bedroom with straw beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_straw_E", + "blueprint_name": "furnish the E bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom2" }, { "id": "fbmc_shelter_beds_se" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_e" }, { "id": "bed", "amount": 4 } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_e" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_makeshift_SE", + "description": "Let's furnish the southeast bedroom with makeshift beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_makeshift_SE", + "blueprint_name": "furnish the SE bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_se" }, { "id": "bed", "amount": 3 } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_se" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_makeshift_E", + "description": "Let's furnish the east bedroom with makeshift beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_makeshift_E", + "blueprint_name": "furnish the E bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom2" }, { "id": "fbmc_shelter_beds_se" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_e" }, { "id": "bed", "amount": 4 } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_e" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_standard_SW", + "description": "Let's furnish the southwest bedroom with regular beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_standard_SW", + "blueprint_name": "furnish the SW bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom3" }, { "id": "fbmc_shelter_beds_e" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_sw" }, { "id": "bed", "amount": 5 } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_sw" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_standard_W", + "description": "Let's furnish the west bedroom with regular beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_standard_W", + "blueprint_name": "furnish the W bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom4" }, { "id": "fbmc_shelter_beds_sw" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_w" }, { "id": "bed" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_w" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_standard_NW", + "description": "Let's furnish the north west bedroom with regular beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_standard_NW", + "blueprint_name": "furnish the NW bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom5" }, { "id": "fbmc_shelter_beds_w" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_nw" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_nw" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_straw_SW", + "description": "Let's furnish the southwest bedroom with straw beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_straw_SW", + "blueprint_name": "furnish the SW bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom3" }, { "id": "fbmc_shelter_beds_e" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_sw" }, { "id": "bed", "amount": 5 } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_sw" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_straw_W", + "description": "Let's furnish the west bedroom with straw beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_straw_W", + "blueprint_name": "furnish the W bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom4" }, { "id": "fbmc_shelter_beds_sw" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_w" }, { "id": "bed" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_w" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_beds_straw_NW", + "description": "Let's furnish the north west bedroom with straw beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_shelter_beds_straw_NW", + "blueprint_name": "furnish the NW bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom5" }, { "id": "fbmc_shelter_beds_w" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_nw" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_nw" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_makeshift_SW", + "description": "Let's furnish the southwest bedroom with makeshift beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_shelter_beds_makeshift_SW", + "blueprint_name": "furnish the SW bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom3" }, { "id": "fbmc_shelter_beds_e" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_sw" }, { "id": "bed", "amount": 5 } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_sw" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_makeshift_W", + "description": "Let's furnish the west bedroom with makeshift beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_makeshift_W", + "blueprint_name": "furnish the W bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom4" }, { "id": "fbmc_shelter_beds_sw" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_w" }, { "id": "bed" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_w" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_beds_makeshift_NW", + "description": "Let's furnish the north west bedroom with makeshift beds.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_beds_makeshift_NW", + "blueprint_name": "furnish the NW bedroom", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom5" }, { "id": "fbmc_shelter_beds_w" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_beds_nw" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_beds_nw" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_diningroom", + "description": "Let's make a dining area.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_dining", + "blueprint_name": "furnish the dining room", + "blueprint_requires": [ { "id": "fbmc_shelter_beds_se" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_dining" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_dining" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_livingroom", + "description": "Let's make a living room area.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_livingroom", + "blueprint_name": "furnish the living room", + "blueprint_requires": [ { "id": "fbmc_shelter_beds_se" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_livingroom" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_livingroom" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_pantry", + "description": "Let's build some pantry storage.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_pantry", + "blueprint_name": "build some wooden racks", + "blueprint_requires": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_pantry" }, { "id": "pantry" }, { "id": "sorting" }, { "id": "tool_storage" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_pantry" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_craftspot", + "description": "Let's build a work bench.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_craftspot", + "blueprint_name": "build a work bench", + "blueprint_requires": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_craftspot" }, { "id": "tool_storage" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_craftspot" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_radio", + "description": "Let's set up a radio tower to improve our recruitment efforts.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_radio_console", + "blueprint_name": "build a radio tower and console", + "blueprint_requires": [ { "id": "fbmc_shelter_well" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_radio" }, { "id": "recruiting" }, { "id": "radio" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_radio" } ], + "blueprint_autocalc": true + } +] diff --git a/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_log.json b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_log.json new file mode 100644 index 0000000000000..9dba04796cec7 --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_log.json @@ -0,0 +1,77 @@ +[ + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom1_log", + "description": "Let's build some living quarters so we can expand. We will start in the southeast corner.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_se_log", + "blueprint_name": "build SE log bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom2_log", + "description": "Let's build some living quarters so we can expand. We will continue along the same wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_e_log", + "blueprint_name": "build E log bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom3_log", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_SW_log", + "blueprint_name": "build SW log bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom4_log", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_W_log", + "blueprint_name": "build W log bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom5_log", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_NW_log", + "blueprint_name": "build NW log bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom5" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom5" } ], + "blueprint_autocalc": true + } +] diff --git a/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_rock.json b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_rock.json new file mode 100644 index 0000000000000..de9b124b65bf4 --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_rock.json @@ -0,0 +1,77 @@ +[ + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom1_rock", + "description": "Let's build some living quarters so we can expand. We will start in the southeast corner.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_se_rock", + "blueprint_name": "build SE rock bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom2_rock", + "description": "Let's build some living quarters so we can expand. We will continue along the same wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_e_rock", + "blueprint_name": "build E rock bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom3_rock", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_SW_rock", + "blueprint_name": "build SW rock bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom4_rock", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_W_rock", + "blueprint_name": "build W rock bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom5_rock", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_NW_rock", + "blueprint_name": "build NW rock bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom5" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom5" } ], + "blueprint_autocalc": true + } +] diff --git a/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_standard.json b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_standard.json new file mode 100644 index 0000000000000..cb5d72b15cdff --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_standard.json @@ -0,0 +1,77 @@ +[ + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom1", + "description": "Let's build some living quarters so we can expand. We will start in the southeast corner.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_se", + "blueprint_name": "build SE standard bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom2", + "description": "Let's build some living quarters so we can expand. We will continue along the same wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_e", + "blueprint_name": "build E standard bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom3", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_SW", + "blueprint_name": "build SW standard bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom4", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_W", + "blueprint_name": "build W standard bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom5", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_NW", + "blueprint_name": "build NW standard bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom5" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom5" } ], + "blueprint_autocalc": true + } +] diff --git a/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_wad.json b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_wad.json new file mode 100644 index 0000000000000..a2d39a505feb3 --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_wad.json @@ -0,0 +1,77 @@ +[ + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom1_wad", + "description": "Let's build some living quarters so we can expand. We will start in the southeast corner.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_se_wad", + "blueprint_name": "build SE wattle and daub bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom2_wad", + "description": "Let's build some living quarters so we can expand. We will continue along the same wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_e_wad", + "blueprint_name": "build E wattle and daub bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom3_wad", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_SW_wad", + "blueprint_name": "build SW wattle and daub bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom4_wad", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_W_wad", + "blueprint_name": "build W wattle and daub bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom5_wad", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_NW_wad", + "blueprint_name": "build NW wattle and daub bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom5" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom5" } ], + "blueprint_autocalc": true + } +] diff --git a/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_wood.json b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_wood.json new file mode 100644 index 0000000000000..0767d7af71c74 --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_shelter/recipe_modular_shelter_wood.json @@ -0,0 +1,77 @@ +[ + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom1_wood", + "description": "Let's build some living quarters so we can expand. We will start in the southeast corner.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_se_wood", + "blueprint_name": "build SE wood panel bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_fire" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom2_wood", + "description": "Let's build some living quarters so we can expand. We will continue along the same wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_e_wood", + "blueprint_name": "build E wood panel bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom1" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom3_wood", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_SW_wood", + "blueprint_name": "build SW wood panel bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom2" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom4_wood", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_W_wood", + "blueprint_name": "build W wood panel bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom3" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_shelter_bedroom5_wood", + "description": "Let's build some living quarters so we can expand. We will continue along the other wall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmc_shelter_bedroom_NW_wood", + "blueprint_name": "build NW wood panel bedroom walls", + "blueprint_requires": [ { "id": "fbmc_shelter_bedroom4" } ], + "blueprint_provides": [ { "id": "fbmc_shelter_bedroom5" } ], + "blueprint_excludes": [ { "id": "fbmc_shelter_bedroom5" } ], + "blueprint_autocalc": true + } +] From fb0dfe67c59ec1ceb7dd4669d85e504d32c6a9f4 Mon Sep 17 00:00:00 2001 From: curstwist <39442864+curstwist@users.noreply.github.com> Date: Sat, 5 Oct 2019 20:02:04 -0400 Subject: [PATCH 02/21] add new faction kitchen --- .../modular_canteen_common.json | 222 ++++++++++++++++++ .../modular_canteen/modular_canteen_log.json | 200 ++++++++++++++++ .../modular_canteen_metal.json | 199 ++++++++++++++++ .../modular_canteen/modular_canteen_rock.json | 200 ++++++++++++++++ .../modular_canteen/modular_canteen_wad.json | 200 ++++++++++++++++ .../modular_canteen/modular_canteen_wood.json | 170 ++++++++++++++ data/json/mapgen/faction_buildings.json | 37 +++ .../overmap_terrain_faction_base.json | 9 + .../json/recipes/basecamps/recipe_groups.json | 5 +- .../recipe_modular_canteen_common.json | 211 +++++++++++++++++ .../recipe_modular_canteen_log.json | 107 +++++++++ .../recipe_modular_canteen_metal.json | 107 +++++++++ .../recipe_modular_canteen_rock.json | 107 +++++++++ .../recipe_modular_canteen_wad.json | 107 +++++++++ .../recipe_modular_canteen_wood.json | 107 +++++++++ 15 files changed, 1986 insertions(+), 2 deletions(-) create mode 100644 data/json/mapgen/basecamps/modular_canteen/modular_canteen_common.json create mode 100644 data/json/mapgen/basecamps/modular_canteen/modular_canteen_log.json create mode 100644 data/json/mapgen/basecamps/modular_canteen/modular_canteen_metal.json create mode 100644 data/json/mapgen/basecamps/modular_canteen/modular_canteen_rock.json create mode 100644 data/json/mapgen/basecamps/modular_canteen/modular_canteen_wad.json create mode 100644 data/json/mapgen/basecamps/modular_canteen/modular_canteen_wood.json create mode 100644 data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_common.json create mode 100644 data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_log.json create mode 100644 data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_metal.json create mode 100644 data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rock.json create mode 100644 data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wad.json create mode 100644 data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wood.json diff --git a/data/json/mapgen/basecamps/modular_canteen/modular_canteen_common.json b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_common.json new file mode 100644 index 0000000000000..e62767c8f8635 --- /dev/null +++ b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_common.json @@ -0,0 +1,222 @@ +[ + { + "type": "palette", + "id": "fbmk_common_palette", + "terrain": { + "d": "t_door_c", + "B": "t_grass", + "o": "t_window_no_curtains", + "w": "t_wall_wood", + ".": "t_floor", + ",": "t_dirtfloor", + "S": "t_dirtfloor", + "a": "t_dirtfloor", + "U": "t_rootcellar" + }, + "furniture": { + "b": "f_bench", + "t": "f_table", + "K": "f_kiln_empty", + "a": "f_stool", + "r": "f_rack_wood", + "R": "f_rack", + "h": "f_chair", + "S": "f_smoking_rack", + "V": "f_fvat_empty", + "B": "f_birdbath", + "H": "f_butcher_rack", + "c": "f_counter", + "p": "f_planter" + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_0", + "object": { + "mapgensize": [ 6, 6 ], + "rows": [ + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen_0", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_0" ], "x": 10, "y": 10 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_fireplace", + "method": "json", + "object": { + "set": [ + { "point": "furniture", "id": "f_fireplace", "x": 11, "y": 8 }, + { "point": "furniture", "id": "f_fireplace", "x": 13, "y": 8 }, + { "point": "furniture", "id": "f_counter", "x": 10, "y": 8 } + ], + "place_loot": [ { "item": "pot", "x": 10, "y": 8 } ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_stove", + "method": "json", + "object": { + "set": [ + { "point": "furniture", "id": "f_woodstove", "x": 11, "y": 8 }, + { "point": "furniture", "id": "f_woodstove", "x": 13, "y": 8 }, + { "point": "furniture", "id": "f_counter", "x": 10, "y": 8 } + ], + "place_loot": [ { "item": "pot", "x": 10, "y": 8 }, { "item": "pan", "x": 10, "y": 8 } ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_well", + "method": "json", + "object": { "set": [ { "point": "terrain", "id": "t_water_pump", "x": 12, "y": 5 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_counters", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " ", + " c ", + " ", + " ccc ", + " ", + " rr rr ", + " " + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen_counters", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_counters" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_smoking_kiln", + "method": "json", + "object": { + "set": [ + { "point": "furniture", "id": "f_smoking_rack", "x": 17, "y": 8 }, + { "point": "furniture", "id": "f_smoking_rack", "x": 18, "y": 8 }, + { "point": "furniture", "id": "f_smoking_rack", "x": 19, "y": 8 }, + { "point": "furniture", "id": "f_kiln_empty", "x": 19, "y": 12 } + ] + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_pantry", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " ", + " rrrrU ", + " V ", + " rrrr ", + " V ", + " rrrrU ", + " " + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_pantry_furniture", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_pantry" ], "x": 3, "y": 7 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_butchery_rack", + "method": "json", + "object": { + "set": [ + { "point": "furniture", "id": "f_butcher_rack", "x": 17, "y": 12 }, + { "point": "furniture", "id": "f_table", "x": 16, "y": 12 } + ], + "place_loot": [ { "item": "knife_butcher", "x": 16, "y": 12 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_furniture", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "hth hth", + "hth hth", + "hth hth", + "hth hth", + " ", + " ", + " " + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_furniture", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_furniture" ], "x": 9, "y": 15 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_planters", + "object": { + "mapgensize": [ 3, 3 ], + "rows": [ + "ppp", + "ppp", + " " + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_planters_1", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_planters" ], "x": 4, "y": 4 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_planters_2", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_planters" ], "x": 8, "y": 4 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_planters_3", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_planters" ], "x": 14, "y": 4 } ] } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_planters_4", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_planters" ], "x": 18, "y": 4 } ] } + } +] diff --git a/data/json/mapgen/basecamps/modular_canteen/modular_canteen_log.json b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_log.json new file mode 100644 index 0000000000000..6935ddc92d80d --- /dev/null +++ b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_log.json @@ -0,0 +1,200 @@ +[ + { + "type": "palette", + "id": "fbmk_log_palette", + "terrain": { + "d": "t_door_c", + "B": "t_grass", + "o": "t_window_no_curtains", + "w": "t_wall_log", + ".": "t_floor", + ",": "t_dirtfloor", + "S": "t_dirtfloor", + "a": "t_dirtfloor", + "U": "t_rootcellar" + }, + "furniture": { + "b": "f_bench", + "t": "f_table", + "K": "f_kiln_empty", + "a": "f_stool", + "r": "f_rack_wood", + "R": "f_rack", + "h": "f_chair", + "S": "f_smoking_rack", + "V": "f_fvat_empty", + "B": "f_birdbath", + "H": "f_butcher_rack", + "c": "f_counter", + "p": "f_planter" + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_kitchen_room_log", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "wowdwow", + "w.....w", + "......o", + " ", + " ", + " ", + " " + ], + "palettes": [ "fbmk_log_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_kitchen_room_log" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_kitchen_room2_log", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " ", + " ", + " ", + "w.....d", + "......o", + "w.....w", + "wwwdwww" + ], + "palettes": [ "fbmk_log_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen2_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_kitchen_room2_log" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_smoking_area_log", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + ",w,w ", + ",,,, ", + ",,,, ", + ",,aw ", + ",,,, ", + ",,,, ", + "ww,w " + ], + "palettes": [ "fbmk_log_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_smoking_area_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_smoking_area_log" ], "x": 16, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_pantry_log", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "wwwwww ", + "w..... ", + "o..... ", + "w..... ", + "o..... ", + "w..... ", + "wwwwww " + ], + "palettes": [ "fbmk_log_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_pantry_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_pantry_log" ], "x": 3, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_west_log", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " bbbw..", + " w..", + " B o..", + " d..", + " o..", + " ww.", + " ww" + ], + "palettes": [ "fbmk_log_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_west_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_west_log" ], "x": 3, "y": 14 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_east_log", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "...w ", + "...w ", + "...ob ", + "...wb ", + "...ob ", + "..ww ", + "oww " + ], + "palettes": [ "fbmk_log_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_east_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_east_log" ], "x": 14, "y": 14 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_center_log", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " .... ", + " .... ", + " .... ", + " .... ", + " .... ", + " .... ", + " owdw " + ], + "palettes": [ "fbmk_log_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_center_log", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_center_log" ], "x": 8, "y": 14 } ] } + } +] diff --git a/data/json/mapgen/basecamps/modular_canteen/modular_canteen_metal.json b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_metal.json new file mode 100644 index 0000000000000..d299b18d0777f --- /dev/null +++ b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_metal.json @@ -0,0 +1,199 @@ +[ + { + "type": "palette", + "id": "fbmk_metal_palette", + "terrain": { + "d": "t_door_metal_c", + "B": "t_grass", + "o": "t_window_no_curtains", + "w": "t_junk_wall", + ".": "t_floor", + ",": "t_dirtfloor", + "S": "t_dirtfloor", + "a": "t_dirtfloor", + "U": "t_rootcellar" + }, + "furniture": { + "b": "f_bench", + "t": "f_table", + "K": "f_kiln_empty", + "a": "f_stool", + "r": "f_rack_wood", + "h": "f_chair", + "S": "f_smoking_rack", + "V": "f_fvat_empty", + "B": "f_birdbath", + "H": "f_butcher_rack", + "c": "f_counter", + "p": "f_planter" + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_kitchen_room_metal", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "wowdwow", + "w.....w", + "......o", + " ", + " ", + " ", + " " + ], + "palettes": [ "fbmk_metal_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen_metal", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_kitchen_room_metal" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_kitchen_room2_metal", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " ", + " ", + " ", + "w.....d", + "......o", + "w.....w", + "wwwdwww" + ], + "palettes": [ "fbmk_metal_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen2_metal", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_kitchen_room2_metal" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_smoking_area_metal", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + ",w,w ", + ",,,, ", + ",,,, ", + ",,aw ", + ",,,, ", + ",,,, ", + "ww,w " + ], + "palettes": [ "fbmk_metal_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_smoking_area_metal", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_smoking_area_metal" ], "x": 16, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_pantry_metal", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "wwwwww ", + "w..... ", + "o..... ", + "w..... ", + "o..... ", + "w..... ", + "wwwwww " + ], + "palettes": [ "fbmk_metal_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_pantry_metal", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_pantry_metal" ], "x": 3, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_west_metal", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " bbbw..", + " w..", + " B o..", + " d..", + " o..", + " ww.", + " ww" + ], + "palettes": [ "fbmk_metal_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_west_metal", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_west_metal" ], "x": 3, "y": 14 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_east_metal", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "...w ", + "...w ", + "...ob ", + "...wb ", + "...ob ", + "..ww ", + "oww " + ], + "palettes": [ "fbmk_metal_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_east_metal", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_east_metal" ], "x": 14, "y": 14 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_center_metal", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " .... ", + " .... ", + " .... ", + " .... ", + " .... ", + " .... ", + " owdw " + ], + "palettes": [ "fbmk_metal_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_center_metal", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_center_metal" ], "x": 8, "y": 14 } ] } + } +] diff --git a/data/json/mapgen/basecamps/modular_canteen/modular_canteen_rock.json b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_rock.json new file mode 100644 index 0000000000000..30e47ad802be1 --- /dev/null +++ b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_rock.json @@ -0,0 +1,200 @@ +[ + { + "type": "palette", + "id": "fbmk_rock_palette", + "terrain": { + "d": "t_door_c", + "B": "t_grass", + "o": "t_window_no_curtains", + "w": "t_rock_wall", + ".": "t_floor", + ",": "t_dirtfloor", + "S": "t_dirtfloor", + "a": "t_dirtfloor", + "U": "t_rootcellar" + }, + "furniture": { + "b": "f_bench", + "t": "f_table", + "K": "f_kiln_empty", + "a": "f_stool", + "r": "f_rack_wood", + "R": "f_rack", + "h": "f_chair", + "S": "f_smoking_rack", + "V": "f_fvat_empty", + "B": "f_birdbath", + "H": "f_butcher_rack", + "c": "f_counter", + "p": "f_planter" + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_kitchen_room_rock", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "wowdwow", + "w.....w", + "......o", + " ", + " ", + " ", + " " + ], + "palettes": [ "fbmk_rock_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_kitchen_room_rock" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_kitchen_room2_rock", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " ", + " ", + " ", + "w.....d", + "......o", + "w.....w", + "wwwdwww" + ], + "palettes": [ "fbmk_rock_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen2_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_kitchen_room2_rock" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_smoking_area_rock", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + ",w,w ", + ",,,, ", + ",,,, ", + ",,aw ", + ",,,, ", + ",,,, ", + "ww,w " + ], + "palettes": [ "fbmk_rock_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_smoking_area_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_smoking_area_rock" ], "x": 16, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_pantry_rock", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "wwwwww ", + "w..... ", + "o..... ", + "w..... ", + "o..... ", + "w..... ", + "wwwwww " + ], + "palettes": [ "fbmk_rock_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_pantry_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_pantry_rock" ], "x": 3, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_west_rock", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " bbbw..", + " w..", + " B o..", + " d..", + " o..", + " ww.", + " ww" + ], + "palettes": [ "fbmk_rock_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_west_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_west_rock" ], "x": 3, "y": 14 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_east_rock", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "...w ", + "...w ", + "...ob ", + "...wb ", + "...ob ", + "..ww ", + "oww " + ], + "palettes": [ "fbmk_rock_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_east_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_east_rock" ], "x": 14, "y": 14 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_center_rock", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " .... ", + " .... ", + " .... ", + " .... ", + " .... ", + " .... ", + " owdw " + ], + "palettes": [ "fbmk_rock_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_center_rock", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_center_rock" ], "x": 8, "y": 14 } ] } + } +] diff --git a/data/json/mapgen/basecamps/modular_canteen/modular_canteen_wad.json b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_wad.json new file mode 100644 index 0000000000000..0caac47fc4026 --- /dev/null +++ b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_wad.json @@ -0,0 +1,200 @@ +[ + { + "type": "palette", + "id": "fbmk_wad_palette", + "terrain": { + "d": "t_door_makeshift_c", + "B": "t_grass", + "o": "t_wall_wattle_half", + "w": "t_wall_wattle", + ".": "t_floor", + ",": "t_dirtfloor", + "S": "t_dirtfloor", + "a": "t_dirtfloor", + "U": "t_rootcellar" + }, + "furniture": { + "b": "f_bench", + "t": "f_table", + "K": "f_kiln_empty", + "a": "f_stool", + "r": "f_rack_wood", + "R": "f_rack", + "h": "f_chair", + "S": "f_smoking_rack", + "V": "f_fvat_empty", + "B": "f_birdbath", + "H": "f_butcher_rack", + "c": "f_counter", + "p": "f_planter" + } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_kitchen_room_wad", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "wowdwow", + "w.....w", + "......o", + " ", + " ", + " ", + " " + ], + "palettes": [ "fbmk_wad_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_kitchen_room_wad" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_kitchen_room2_wad", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " ", + " ", + " ", + "w.....d", + "......o", + "w.....w", + "wwwdwww" + ], + "palettes": [ "fbmk_wad_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen2_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_kitchen_room2_wad" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_smoking_area_wad", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + ",w,w ", + ",,,, ", + ",,,, ", + ",,aw ", + ",,,, ", + ",,,, ", + "ww,w " + ], + "palettes": [ "fbmk_wad_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_smoking_area_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_smoking_area_wad" ], "x": 16, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_pantry_wad", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "wwwwww ", + "w..... ", + "o..... ", + "w..... ", + "o..... ", + "w..... ", + "wwwwww " + ], + "palettes": [ "fbmk_wad_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_pantry_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_pantry_wad" ], "x": 3, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_west_wad", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " bbbw..", + " w..", + " B o..", + " d..", + " o..", + " ww.", + " ww" + ], + "palettes": [ "fbmk_wad_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_west_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_west_wad" ], "x": 3, "y": 14 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_east_wad", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "...w ", + "...w ", + "...ob ", + "...wb ", + "...ob ", + "..ww ", + "oww " + ], + "palettes": [ "fbmk_wad_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_east_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_east_wad" ], "x": 14, "y": 14 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_center_wad", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " .... ", + " .... ", + " .... ", + " .... ", + " .... ", + " .... ", + " owdw " + ], + "palettes": [ "fbmk_wad_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_center_wad", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_center_wad" ], "x": 8, "y": 14 } ] } + } +] diff --git a/data/json/mapgen/basecamps/modular_canteen/modular_canteen_wood.json b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_wood.json new file mode 100644 index 0000000000000..69001ba90615a --- /dev/null +++ b/data/json/mapgen/basecamps/modular_canteen/modular_canteen_wood.json @@ -0,0 +1,170 @@ +[ + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_kitchen_room_wood", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "wowdwow", + "w.....w", + "......o", + " ", + " ", + " ", + " " + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_kitchen_room_wood" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_kitchen_room2_wood", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " ", + " ", + " ", + "w.....d", + "......o", + "w.....w", + "wwwdwww" + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_canteen2_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_kitchen_room2_wood" ], "x": 9, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_smoking_area_wood", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + ",w,w ", + ",,,, ", + ",,,, ", + ",,aw ", + ",,,, ", + ",,,, ", + "ww,w " + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "faction_base_smoking_area_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_smoking_area_wood" ], "x": 16, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_pantry_wood", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "wwwwww ", + "w..... ", + "o..... ", + "w..... ", + "o..... ", + "w..... ", + "wwwwww " + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_pantry_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_pantry_wood" ], "x": 3, "y": 7 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_west_wood", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " bbbw..", + " w..", + " B o..", + " d..", + " o..", + " ww.", + " ww" + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_west_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_west_wood" ], "x": 3, "y": 14 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_east_wood", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + "...w ", + "...w ", + "...ob ", + "...wb ", + "...ob ", + "..ww ", + "oww " + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_east_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_east_wood" ], "x": 14, "y": 14 } ] } + }, + { + "type": "mapgen", + "method": "json", + "nested_mapgen_id": "fbmk_canteen_dining_center_wood", + "object": { + "mapgensize": [ 7, 7 ], + "rows": [ + " .... ", + " .... ", + " .... ", + " .... ", + " .... ", + " .... ", + " owdw " + ], + "palettes": [ "fbmk_common_palette" ] + } + }, + { + "type": "mapgen", + "update_mapgen_id": "fbmk_canteen_dining_center_wood", + "method": "json", + "object": { "place_nested": [ { "chunks": [ "fbmk_canteen_dining_center_wood" ], "x": 8, "y": 14 } ] } + } +] diff --git a/data/json/mapgen/faction_buildings.json b/data/json/mapgen/faction_buildings.json index 9b24b858ac8b8..06942a9c93f58 100644 --- a/data/json/mapgen/faction_buildings.json +++ b/data/json/mapgen/faction_buildings.json @@ -2477,5 +2477,42 @@ ], "palettes": [ "acidia_camp_palette" ] } + }, + { + "type": "mapgen", + "om_terrain": "faction_base_canteen_0", + "method": "json", + "weight": 250, + "object": { + "faction_owner": [ { "id": "your_followers", "x": [ 0, 23 ], "y": [ 0, 23 ] } ], + "fill_ter": "t_grass", + "rows": [ + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,,", + ",,,,,,,,,,,,,,,,,,,,,,,," + ], + "palettes": [ "acidia_camp_palette" ] + } } ] diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json b/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json index c0ef24fd63dac..4eb7af736282c 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_faction_base.json @@ -601,5 +601,14 @@ "color": "cyan", "see_cost": 5, "flags": [ "NO_ROTATE" ] + }, + { + "type": "overmap_terrain", + "id": "faction_base_canteen_0", + "name": "canteen survey", + "sym": "+", + "color": "i_green", + "see_cost": 5, + "flags": [ "NO_ROTATE" ] } ] diff --git a/data/json/recipes/basecamps/recipe_groups.json b/data/json/recipes/basecamps/recipe_groups.json index 2dfa2c1287c76..45778feefa52f 100644 --- a/data/json/recipes/basecamps/recipe_groups.json +++ b/data/json/recipes/basecamps/recipe_groups.json @@ -15,7 +15,7 @@ "recipes": [ { "id": "faction_base_farm_0", "description": "Farm", "om_terrains": [ "field" ] }, { "id": "faction_base_garage_0", "description": "Garage", "om_terrains": [ "field" ] }, - { "id": "faction_base_kitchen_0", "description": "Kitchen", "om_terrains": [ "field" ] }, + { "id": "faction_base_canteen_0", "description": "Kitchen", "om_terrains": [ "field" ] }, { "id": "faction_base_livestock_0", "description": "Livestock Area", "om_terrains": [ "field" ] }, { "id": "faction_base_storehouse_0", "description": "Central Storage Building", "om_terrains": [ "field" ] }, { "id": "faction_base_workshop_0", "description": "Fabrication workshop", "om_terrains": [ "field" ] } @@ -71,7 +71,8 @@ { "id": "pemmican", "description": " Cook: Pemmican" }, { "id": "veggy_aspic", "description": " Cook: Veggy Aspic" }, { "id": "meat_canned_jarred", "description": " Cook: Meat, Canned" }, - { "id": "meat_aspic", "description": " Cook: Meat Aspic" } + { "id": "meat_aspic", "description": " Cook: Meat Aspic" }, + { "id": "kompot", "description": " Cook: Kompot" } ] }, { diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_common.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_common.json new file mode 100644 index 0000000000000..f23e4983cf906 --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_common.json @@ -0,0 +1,211 @@ +[ + { + "type": "recipe", + "result": "faction_base_canteen_0", + "description": "Survey land for a kitchen and dining area.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen_0", + "blueprint_name": "kitchen survey", + "time": "180 m", + "blueprint_requires": [ { "id": "not_an_upgrade" } ], + "blueprint_provides": [ { "id": "fbmk_0" } ] + }, + { + "type": "recipe", + "result": "faction_base_modular_canteen_fireplace", + "description": "Now that we have some cover, we should build 2 fireplaces for cooking and grab a pot.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_fireplace", + "blueprint_name": "build 2 fireplaces", + "blueprint_requires": [ { "id": "fbmk_center" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_fire" }, { "id": "trapping" }, { "id": "kitchen" }, { "id": "kitchen_recipes_1" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_fire" } ], + "blueprint_resources": [ "fake_fireplace", "pot" ], + "blueprint_autocalc": true, + "components": [ [ [ "pot", 1 ], [ "rock_pot", 1 ], [ "pot_copper", 1 ], [ "clay_pot", 1 ] ], [ [ "pan", 1 ] ] ] + }, + { + "type": "recipe", + "result": "faction_base_modular_canteen_stove", + "description": "Now that we have some cover, we should build 2 stoves for cooking and grab a pot.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_stove", + "blueprint_name": "build 2 wood stoves", + "blueprint_requires": [ { "id": "fbmk_center" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_fire" }, { "id": "trapping" }, { "id": "kitchen" }, { "id": "kitchen_recipes_1" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_fire" } ], + "blueprint_resources": [ "fake_fireplace", "pot" ], + "blueprint_autocalc": true, + "components": [ [ [ "pot", 1 ], [ "rock_pot", 1 ], [ "pot_copper", 1 ], [ "clay_pot", 1 ] ], [ [ "pan", 1 ] ] ] + }, + { + "type": "recipe", + "result": "faction_base_modular_canteen_well", + "description": "We should build a well. This will make cooking more convenient.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_well", + "blueprint_name": "build a well", + "blueprint_requires": [ { "id": "fbmk_canteen_fire" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_well" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_well" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_canteen_counters", + "description": "Lets build some counters and shelves.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen_counters", + "blueprint_name": "build kitchen counters", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_counters" } ], + "blueprint_excludes": [ { "id": "fbmk_counters" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_modular_canteen_smoking", + "description": "Let's build some smokers and a charcoal kiln for food preservation.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_smoking_kiln", + "blueprint_name": "build 3 smoking racks and a charcoal kiln", + "blueprint_requires": [ { "id": "fbmk_canteen_fire" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_smoking" }, { "id": "kitchen_recipes_2" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_smoking" } ], + "blueprint_resources": [ "fake_char_smoker", "fake_char_kiln" ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_pantry_furniture", + "description": "Lets furnish the pantry and build 2 root cellars.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_pantry_furniture", + "blueprint_name": "furnish the pantry", + "blueprint_requires": [ { "id": "fbmk_pantry_room" } ], + "blueprint_provides": [ { "id": "fbmk_pantry_furniture" }, { "id": "pantry" } ], + "blueprint_excludes": [ { "id": "fbmk_pantry_furniture" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_butchery", + "description": "Let's make a butchery area.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_butchery_rack", + "blueprint_name": "build butchery area", + "blueprint_requires": [ { "id": "fbmk_canteen_smoking" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_butchery" }, { "id": "kitchen_recipes_3" }, { "id": "trapping" }, { "id": "hunting" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_butchery" } ], + "blueprint_autocalc": true, + "components": [ [ [ "knife_butcher", 1 ], [ "knife_steak", 1 ], [ "knife_chef", 1 ], [ "knife_carving", 1 ] ] ] + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_furniture", + "description": "Let's make some furniture for the dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_furniture", + "blueprint_name": "furnish the dining room", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_furniture" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_furniture" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_planters_1", + "description": "Let's build some planters to the north for a chef's garden.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_planters_1", + "blueprint_name": "build some planters", + "blueprint_requires": [ { "id": "fbmk_canteen_well" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_planterA" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_planterA" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_planters_2", + "description": "Let's build some planters to the north for a chef's garden.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_planters_2", + "blueprint_name": "build some planters", + "blueprint_requires": [ { "id": "fbmk_canteen_planterA" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_planterB" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_planterB" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_planters_3", + "description": "Let's build some planters to the north for a chef's garden.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_planters_3", + "blueprint_name": "build some planters", + "blueprint_requires": [ { "id": "fbmk_canteen_planterB" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_planterC" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_planterC" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_planters_4", + "description": "Let's build some planters to the north for a chef's garden.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "skill_used": "fabrication", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_planters_4", + "blueprint_name": "build some planters", + "blueprint_requires": [ { "id": "fbmk_canteen_planterC" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_planterD" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_planterD" } ], + "blueprint_autocalc": true + } +] diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_log.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_log.json new file mode 100644 index 0000000000000..9a2bdb1ac5636 --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_log.json @@ -0,0 +1,107 @@ +[ + { + "type": "recipe", + "result": "faction_base_canteen_room_center_log", + "description": "Lets start building the central kitchen log walls.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen_log", + "blueprint_name": "build the log wall central kitchen room", + "blueprint_requires": [ { "id": "fbmk_0" } ], + "blueprint_provides": [ { "id": "fbmk_center" } ], + "blueprint_excludes": [ { "id": "fbmk_center" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_room2_center_log", + "description": "Lets finish the central kitchen log walls.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen2_log", + "blueprint_name": "finish the log wall central kitchen room", + "blueprint_requires": [ { "id": "fbmk_center" } ], + "blueprint_provides": [ { "id": "fbmk_center2" } ], + "blueprint_excludes": [ { "id": "fbmk_center2" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_smoking_area_log", + "description": "Lets get this log wall smoking area covered to protect the workers from the weather.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_smoking_area_log", + "blueprint_name": "build a log wall roofed area for smoking racks", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_smoking_area" } ], + "blueprint_excludes": [ { "id": "fbmk_smoking_area" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_pantry_log", + "description": "Lets build a log wall pantry west of the kitchen.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_pantry_log", + "blueprint_name": "build a log wall pantry", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_pantry_room" } ], + "blueprint_excludes": [ { "id": "fbmk_pantry_room" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_west_log", + "description": "Lets build the west log wall of the dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_west_log", + "blueprint_name": "build W log wall", + "blueprint_requires": [ { "id": "fbmk_pantry_room" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_west" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_west" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_east_log", + "description": "Lets build the east log wall of the dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_east_log", + "blueprint_name": "build E log wall", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_west" }, { "id": "fbmk_smoking_area" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_center_log", + "description": "Lets build the center of the log wall dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_center_log", + "blueprint_name": "build center of the log wall dining hall", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_autocalc": true + } +] diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_metal.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_metal.json new file mode 100644 index 0000000000000..a1d7b2ab3211c --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_metal.json @@ -0,0 +1,107 @@ +[ + { + "type": "recipe", + "result": "faction_base_canteen_room_center_metal", + "description": "Lets start building the central kitchen metal walls.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen_metal", + "blueprint_name": "build the metal wall central kitchen room", + "blueprint_requires": [ { "id": "fbmk_0" } ], + "blueprint_provides": [ { "id": "fbmk_center" } ], + "blueprint_excludes": [ { "id": "fbmk_center" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_room2_center_metal", + "description": "Lets finish the central kitchen metal walls.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen2_metal", + "blueprint_name": "finish the metal wall central kitchen room", + "blueprint_requires": [ { "id": "fbmk_center" } ], + "blueprint_provides": [ { "id": "fbmk_center2" } ], + "blueprint_excludes": [ { "id": "fbmk_center2" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_smoking_area_metal", + "description": "Lets get this metal wall smoking area covered to protect the workers from the weather.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_smoking_area_metal", + "blueprint_name": "build a metal wall roofed area for smoking racks", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_smoking_area" } ], + "blueprint_excludes": [ { "id": "fbmk_smoking_area" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_pantry_metal", + "description": "Lets build a metal wall pantry west of the kitchen.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_pantry_metal", + "blueprint_name": "build a metal wall pantry", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_pantry_room" } ], + "blueprint_excludes": [ { "id": "fbmk_pantry_room" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_west_metal", + "description": "Lets build the west metal wall of the dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_west_metal", + "blueprint_name": "build W metal wall", + "blueprint_requires": [ { "id": "fbmk_pantry_room" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_west" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_west" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_east_metal", + "description": "Lets build the east metal wall of the dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_east_metal", + "blueprint_name": "build E metal wall", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_west" }, { "id": "fbmk_smoking_area" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_center_metal", + "description": "Lets build the center of the metal wall dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_center_metal", + "blueprint_name": "build center of the metal wall dining hall", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_autocalc": true + } +] diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rock.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rock.json new file mode 100644 index 0000000000000..a6e3626078838 --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_rock.json @@ -0,0 +1,107 @@ +[ + { + "type": "recipe", + "result": "faction_base_canteen_room_center_rock", + "description": "Lets start building the central kitchen rock walls.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen_rock", + "blueprint_name": "build the central kitchen room", + "blueprint_requires": [ { "id": "fbmk_0" } ], + "blueprint_provides": [ { "id": "fbmk_center" } ], + "blueprint_excludes": [ { "id": "fbmk_center" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_room2_center_rock", + "description": "Lets finish the central kitchen rock walls.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen2_rock", + "blueprint_name": "finish the rock wall central kitchen room", + "blueprint_requires": [ { "id": "fbmk_center" } ], + "blueprint_provides": [ { "id": "fbmk_center2" } ], + "blueprint_excludes": [ { "id": "fbmk_center2" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_smoking_area_rock", + "description": "Lets get this rock wall smoking area covered to protect the workers from the weather.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_smoking_area_rock", + "blueprint_name": "build a rock wall roofed area for smoking racks", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_smoking_area" } ], + "blueprint_excludes": [ { "id": "fbmk_smoking_area" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_pantry_rock", + "description": "Lets build a rock wall pantry west of the kitchen.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_pantry_rock", + "blueprint_name": "build a rock wall pantry", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_pantry_room" } ], + "blueprint_excludes": [ { "id": "fbmk_pantry_room" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_west_rock", + "description": "Lets build the west rock wall of the rock wall dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_west_rock", + "blueprint_name": "build W rock wall", + "blueprint_requires": [ { "id": "fbmk_pantry_room" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_west" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_west" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_east_rock", + "description": "Lets build the east rock wall of the rock wall dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_east_rock", + "blueprint_name": "build E rock wall", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_west" }, { "id": "fbmk_smoking_area" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_center_rock", + "description": "Lets build the center of the rock wall dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_center_rock", + "blueprint_name": "build center of the rock dining hall", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_autocalc": true + } +] diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wad.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wad.json new file mode 100644 index 0000000000000..766305cf4b2db --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wad.json @@ -0,0 +1,107 @@ +[ + { + "type": "recipe", + "result": "faction_base_canteen_room_center_wad", + "description": "Lets start building the central kitchen wattle and daub walls.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen_wad", + "blueprint_name": "build the wattle and daub central kitchen room", + "blueprint_requires": [ { "id": "fbmk_0" } ], + "blueprint_provides": [ { "id": "fbmk_center" } ], + "blueprint_excludes": [ { "id": "fbmk_center" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_room2_center_wad", + "description": "Lets finish the central kitchen wattle and daub walls.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen2_wad", + "blueprint_name": "finish the wattle and daub central kitchen room", + "blueprint_requires": [ { "id": "fbmk_center" } ], + "blueprint_provides": [ { "id": "fbmk_center2" } ], + "blueprint_excludes": [ { "id": "fbmk_center2" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_smoking_area_wad", + "description": "Lets get this wattle and daub smoking area covered to protect the workers from the weather.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_smoking_area_wad", + "blueprint_name": "build a wattle and daub roofed area for smoking racks", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_smoking_area" } ], + "blueprint_excludes": [ { "id": "fbmk_smoking_area" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_pantry_wad", + "description": "Lets build a wattle and daub wall pantry west of the kitchen.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_pantry_wad", + "blueprint_name": "build a wattle and daub pantry", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_pantry_room" } ], + "blueprint_excludes": [ { "id": "fbmk_pantry_room" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_west_wad", + "description": "Lets build the west wattle and daub wall of the dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_west_wad", + "blueprint_name": "build W wattle and daub wall", + "blueprint_requires": [ { "id": "fbmk_pantry_room" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_west" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_west" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_east_wad", + "description": "Lets build the east wattle and daub wall of the dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_east_wad", + "blueprint_name": "build E wattle and daub wall", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_west" }, { "id": "fbmk_smoking_area" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_center_wad", + "description": "Lets build the center of the wattle and daub dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_center_wad", + "blueprint_name": "build center of the wattle and daub dining hall", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_autocalc": true + } +] diff --git a/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wood.json b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wood.json new file mode 100644 index 0000000000000..37699de3ea5e5 --- /dev/null +++ b/data/json/recipes/basecamps/recipe_modular_canteen/recipe_modular_canteen_wood.json @@ -0,0 +1,107 @@ +[ + { + "type": "recipe", + "result": "faction_base_canteen_room_center_wood", + "description": "Lets start building the central kitchen wood panel walls.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen_wood", + "blueprint_name": "build the wood panel central kitchen room", + "blueprint_requires": [ { "id": "fbmk_0" } ], + "blueprint_provides": [ { "id": "fbmk_center" } ], + "blueprint_excludes": [ { "id": "fbmk_center" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_room2_center_wood", + "description": "Lets finish the central kitchen wood panel walls.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_canteen2_wood", + "blueprint_name": "finish the wood panel central kitchen room", + "blueprint_requires": [ { "id": "fbmk_center" } ], + "blueprint_provides": [ { "id": "fbmk_center2" } ], + "blueprint_excludes": [ { "id": "fbmk_center2" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_smoking_area_wood", + "description": "Lets get this wood panel smoking area covered to protect the workers from the weather.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "faction_base_smoking_area_wood", + "blueprint_name": "build a wood panel roofed area for smoking racks", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_smoking_area" } ], + "blueprint_excludes": [ { "id": "fbmk_smoking_area" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_pantry_wood", + "description": "Lets build a wood panel pantry west of the kitchen.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_pantry_wood", + "blueprint_name": "build a wood panel pantry", + "blueprint_requires": [ { "id": "fbmk_center2" } ], + "blueprint_provides": [ { "id": "fbmk_pantry_room" } ], + "blueprint_excludes": [ { "id": "fbmk_pantry_room" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_west_wood", + "description": "Lets build the west wood panel wall of the dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_west_wood", + "blueprint_name": "build W wood wall", + "blueprint_requires": [ { "id": "fbmk_pantry_room" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_west" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_west" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_east_wood", + "description": "Lets build the east wood panel wall of the dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_east_wood", + "blueprint_name": "build E wood wall", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_west" }, { "id": "fbmk_smoking_area" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_autocalc": true + }, + { + "type": "recipe", + "result": "faction_base_canteen_dining_center_wood", + "description": "Lets build the center of the wood panel dining hall.", + "category": "CC_BUILDING", + "subcategory": "CSC_BUILDING_BASES", + "autolearn": false, + "never_learn": true, + "construction_blueprint": "fbmk_canteen_dining_center_wood", + "blueprint_name": "build center of the dining hall", + "blueprint_requires": [ { "id": "fbmk_canteen_dining_east" } ], + "blueprint_provides": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_excludes": [ { "id": "fbmk_canteen_dining_center" } ], + "blueprint_autocalc": true + } +] From 4c1a279fc423f843f9fe944629ae02c604cb2b4a Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Sun, 6 Oct 2019 01:59:29 +0000 Subject: [PATCH 03/21] Make linting failure message more clear Right now when a json file is not linted, the program just says 'Formatted $FILENAME' and exits - this doesn't make it particularly clear what is wrong when a file is not linted. This aims to make it more clear for new contributors. --- tools/format/format.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/format/format.cpp b/tools/format/format.cpp index 7b469627e819a..0319c4f9246ef 100644 --- a/tools/format/format.cpp +++ b/tools/format/format.cpp @@ -203,7 +203,7 @@ int main( int argc, char *argv[] ) std::ofstream fout( filename, std::ios::binary | std::ios::trunc ); fout << out.str(); fout.close(); - std::cout << "Formatted " << filename << std::endl; + std::cout << filename << " needs to be linted" << std::endl; exit( EXIT_FAILURE ); } } From af14cb222a77fd95be63acdf076ff84bd39f9252 Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Mon, 7 Oct 2019 19:44:15 -0400 Subject: [PATCH 04/21] AEA_PULSE --- data/json/legacy_artifact_active.json | 29 +++++++++++++++++++++++++++ doc/MAGIC.md | 2 ++ src/magic.cpp | 1 + src/magic.h | 1 + src/magic_spell_effect.cpp | 12 +++++++++++ 5 files changed, 45 insertions(+) diff --git a/data/json/legacy_artifact_active.json b/data/json/legacy_artifact_active.json index 586456f220246..0689a8e1a06f4 100644 --- a/data/json/legacy_artifact_active.json +++ b/data/json/legacy_artifact_active.json @@ -523,5 +523,34 @@ "max_damage": 40, "valid_targets": [ "self" ], "extra_effects": [ { "id": "AEA_SCREAM_morale" } ] + }, + { + "type": "SPELL", + "id": "AEA_PULSE_bash_terrain", + "name": "Bash Terrain", + "description": "Damages the terrain", + "valid_targets": [ "self", "ally", "hostile", "ground" ], + "effect": "bash", + "min_damage": 40, + "max_damage": 40, + "min_aoe": 2, + "max_aoe": 2 + }, + { + "type": "SPELL", + "id": "AEA_PULSE", + "name": "Artifact Pulse", + "description": "Damages the terrain", + "message": "", + "sound_description": "The earth shakes!", + "sound_id": "misc", + "sound_variant": "earthquake", + "sound_ambient": true, + "sound_type": "combat", + "valid_targets": [ "self" ], + "min_damage": 30, + "max_damage": 30, + "effect": "noise", + "extra_effects": [ { "id": "AEA_PULSE_bash_terrain" }, { "id": "AEA_PULSE_bash_terrain" }, { "id": "AEA_PULSE_bash_terrain" } ] } ] diff --git a/doc/MAGIC.md b/doc/MAGIC.md index 4c27caf051ae6..42344b20dca01 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -111,6 +111,8 @@ Any aoe will manifest as a circular area centered on the target, and will only d * "mutate" - mutates the target(s). if effect_str is defined, mutates toward that category instead of picking at random. the "MUTATE_TRAIT" flag allows effect_str to be a specific trait instead of a category. damage() / 100 is the percent chance the mutation will be successful (a value of 10000 represents 100.00%) +* "bash" - bashes the terrain at the target. uses damage() as the strength of the bash. + * "WONDER" - Unlike the above, this is not an "effect" but a "flag". This alters the behavior of the parent spell drastically: The spell itself doesn't cast, but its damage and range information is used in order to cast the extra_effects. N of the extra_effects will be chosen at random to be cast, where N is the current damage of the spell (stacks with RANDOM_DAMAGE flag) and the message of the spell cast by this spell will also be displayed. If this spell's message is not wanted to be displayed, make sure the message is an empty string. * "RANDOM_TARGET" - A special spell flag (like wonder) that forces the spell to choose a random valid target within range instead of the caster choosing the target. This also affects extra_effects. diff --git a/src/magic.cpp b/src/magic.cpp index cea183f96023c..14f98ed5c929d 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -219,6 +219,7 @@ void spell_type::load( JsonObject &jo, const std::string & ) { "map", spell_effect::map }, { "morale", spell_effect::morale }, { "mutate", spell_effect::mutate }, + { "bash", spell_effect::bash }, { "none", spell_effect::none } }; diff --git a/src/magic.h b/src/magic.h index 8876aa7128aa2..6d557c8aa8bce 100644 --- a/src/magic.h +++ b/src/magic.h @@ -507,6 +507,7 @@ void mod_moves( const spell &sp, Creature &caster, const tripoint &target ); void map( const spell &sp, Creature &caster, const tripoint & ); void morale( const spell &sp, Creature &caster, const tripoint &target ); void mutate( const spell &sp, Creature &caster, const tripoint &target ); +void bash( const spell &sp, Creature &caster, const tripoint &target ); void none( const spell &sp, Creature &, const tripoint &target ); } // namespace spell_effect diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index e91e1d3aa9430..651d07c867120 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -810,3 +810,15 @@ void spell_effect::mutate( const spell &sp, Creature &caster, const tripoint &ta sp.make_sound( potential_target ); } } + +void spell_effect::bash( const spell &sp, Creature &caster, const tripoint &target ) +{ + const std::set area = spell_effect_blast( sp, caster.pos(), target, sp.aoe(), false ); + for( const tripoint &potential_target : area ) { + if( !sp.is_valid_target( caster, potential_target ) ) { + continue; + } + // the bash already makes noise, so no need for spell::make_sound() + g->m.bash( potential_target, sp.damage(), sp.has_flag( spell_flag::SILENT ) ); + } +} From a75b6cbda287e2ee989077bb274c585f8526c818 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Mon, 7 Oct 2019 19:38:00 -0500 Subject: [PATCH 05/21] faction camp: Clean up the line lengths Bring all the lines that can be under 100 characters back under 100 characters because I'm a touch obsessive on this topic. --- src/faction_camp.cpp | 327 ++++++++++++++++++++++++------------------- 1 file changed, 183 insertions(+), 144 deletions(-) diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index 7f3612c49af3c..7b287ea1a8d88 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -116,19 +116,22 @@ recipe_id select_camp_option( const std::map &pos_option std::map miss_info = {{ { "_faction_upgrade_camp", { - "Upgrade Camp", to_translation( "Upgrade camp" ), to_translation( "Working to expand your camp!\n" ), + "Upgrade Camp", to_translation( "Upgrade camp" ), + to_translation( "Working to expand your camp!\n" ), "Recover Ally from Upgrading", to_translation( "Recover Ally from Upgrading" ) } }, { "_faction_camp_crafting_", { - "Craft Item", to_translation( "Craft Item" ), to_translation( "Busy crafting!\n" ), + "Craft Item", to_translation( "Craft Item" ), + to_translation( "Busy crafting!\n" ), " (Finish) Crafting", to_translation( " (Finish) Crafting" ) } }, { "travelling", { - "Travelling", to_translation( "Travelling" ), to_translation( "Busy travelling!\n" ), + "Travelling", to_translation( "Travelling" ), + to_translation( "Busy travelling!\n" ), "Recall ally from travelling", to_translation( "Recall ally from travelling" ) } }, @@ -141,37 +144,43 @@ std::map miss_info = {{ }, { "_faction_camp_firewood", { - "Collect Firewood", to_translation( "Collect Firewood" ), to_translation( "Searching for firewood.\n" ), + "Collect Firewood", to_translation( "Collect Firewood" ), + to_translation( "Searching for firewood.\n" ), "Recover Firewood Gatherers", to_translation( "Recover Firewood Gatherers" ) } }, { "_faction_camp_menial", { - "Menial Labor", to_translation( "Menial Labor" ), to_translation( "Performing menial labor...\n" ), + "Menial Labor", to_translation( "Menial Labor" ), + to_translation( "Performing menial labor...\n" ), "Recover Menial Laborer", to_translation( "Recover Menial Laborer" ) } }, { "_faction_camp_expansion", { - "Expand Base", to_translation( "Expand Base" ), to_translation( "Surveying for expansion...\n" ), + "Expand Base", to_translation( "Expand Base" ), + to_translation( "Surveying for expansion...\n" ), "Recover Surveyor", to_translation( "Recover Surveyor" ) } }, { "_faction_camp_cut_log", { - "Cut Logs", to_translation( "Cut Logs" ), to_translation( "Cutting logs in the woods...\n" ), + "Cut Logs", to_translation( "Cut Logs" ), + to_translation( "Cutting logs in the woods...\n" ), "Recover Log Cutter", to_translation( "Recover Log Cutter" ) } }, { "_faction_camp_clearcut", { - "Clearcut", to_translation( "Clear a forest" ), to_translation( "Clearing a forest...\n" ), + "Clearcut", to_translation( "Clear a forest" ), + to_translation( "Clearing a forest...\n" ), "Recover Clearcutter", to_translation( "Recover Clearcutter" ) } }, { "_faction_camp_hide_site", { - "Setup Hide Site", to_translation( "Setup Hide Site" ), to_translation( "Setting up a hide site...\n" ), + "Setup Hide Site", to_translation( "Setup Hide Site" ), + to_translation( "Setting up a hide site...\n" ), "Recover Hide Setup", to_translation( "Recover Hide Setup" ) } }, @@ -184,19 +193,22 @@ std::map miss_info = {{ }, { "_faction_camp_foraging", { - "Camp Forage", to_translation( "Forage for plants" ), to_translation( "Foraging for edible plants.\n" ), + "Camp Forage", to_translation( "Forage for plants" ), + to_translation( "Foraging for edible plants.\n" ), "Recover Foragers", to_translation( "Recover Foragers" ) } }, { "_faction_camp_trapping", { - "Trap Small Game", to_translation( "Trap Small Game" ), to_translation( "Trapping Small Game.\n" ), + "Trap Small Game", to_translation( "Trap Small Game" ), + to_translation( "Trapping Small Game.\n" ), "Recover Trappers", to_translation( "Recover Trappers" ) } }, { "_faction_camp_hunting", { - "Hunt Large Animals", to_translation( "Hunt Large Animals" ), to_translation( "Hunting large animals.\n" ), + "Hunt Large Animals", to_translation( "Hunt Large Animals" ), + to_translation( "Hunting large animals.\n" ), "Recover Hunter", to_translation( "Recover Hunter" ) } }, @@ -209,19 +221,22 @@ std::map miss_info = {{ }, { "_faction_camp_recruit_0", { - "Recruit Companions", to_translation( "Recruit Companions" ), to_translation( "Searching for recruits.\n" ), + "Recruit Companions", to_translation( "Recruit Companions" ), + to_translation( "Searching for recruits.\n" ), "Recover Recruiter", to_translation( "Recover Recruiter" ) } }, { "_faction_camp_scout_0", { - "Scout Mission", to_translation( "Scout Mission" ), to_translation( "Scouting the region.\n" ), + "Scout Mission", to_translation( "Scout Mission" ), + to_translation( "Scouting the region.\n" ), "Recover Scout", to_translation( "Recover Scout" ) } }, { "_faction_camp_combat_0", { - "Combat Patrol", to_translation( "Combat Patrol" ), to_translation( "Patrolling the region.\n" ), + "Combat Patrol", to_translation( "Combat Patrol" ), + to_translation( "Patrolling the region.\n" ), "Recover Combat Patrol", to_translation( "Recover Combat Patrol" ) } }, @@ -234,13 +249,15 @@ std::map miss_info = {{ }, { "_faction_exp_chop_shop_", { - " Chop Shop", to_translation( " Chop Shop" ), to_translation( "Working at the chop shop...\n" ), + " Chop Shop", to_translation( " Chop Shop" ), + to_translation( "Working at the chop shop...\n" ), " (Finish) Chop Shop", to_translation( " (Finish) Chop Shop" ) } }, { "_faction_exp_kitchen_cooking_", { - " Kitchen Cooking", to_translation( " Kitchen Cooking" ), to_translation( "Working in your kitchen!\n" ), + " Kitchen Cooking", to_translation( " Kitchen Cooking" ), + to_translation( "Working in your kitchen!\n" ), " (Finish) Cooking", to_translation( " (Finish) Cooking" ) } }, @@ -253,13 +270,15 @@ std::map miss_info = {{ }, { "_faction_exp_plow_", { - " Plow Fields", to_translation( " Plow Fields" ), to_translation( "Working to plow your fields!\n" ), + " Plow Fields", to_translation( " Plow Fields" ), + to_translation( "Working to plow your fields!\n" ), " (Finish) Plow Fields", to_translation( " (Finish) Plow fields" ) } }, { "_faction_exp_plant_", { - " Plant Fields", to_translation( " Plant Fields" ), to_translation( "Working to plant your fields!\n" ), + " Plant Fields", to_translation( " Plant Fields" ), + to_translation( "Working to plant your fields!\n" ), " (Finish) Plant Fields", to_translation( " (Finish) Plant Fields" ) } }, @@ -272,7 +291,8 @@ std::map miss_info = {{ }, { "_faction_exp_farm_crafting_", { - " Farm Crafting", to_translation( " Farm Crafting" ), to_translation( "Working on your farm!\n" ), + " Farm Crafting", to_translation( " Farm Crafting" ), + to_translation( "Working on your farm!\n" ), " (Finish) Crafting", to_translation( " (Finish) Crafting" ) } } @@ -627,8 +647,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio const base_camps::miss_data &miss_info = base_camps::miss_info[ "_faction_upgrade_camp" ]; entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } for( const basecamp_upgrade &upgrade : available_upgrades( base_dir ) ) { @@ -677,27 +697,27 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Time: 3 Hours, Repeated\n" "Positions: %d/3\n" ), gathering_description( gather_bldg ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.size() < 3 ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.size() < 3 ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_fixed( entry, npc_list, 3_hours ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } if( !by_radio ) { entry = string_format( _( "Notes:\n" - "Distribute food to your follower and fill you larders. Place " - "the food you wish to distribute in the camp food zone. You " - "must have a camp food zone, an unsorted loot zone, and at " - "least one loot destination zone or you will be prompted to " - "create them using the zone manager.\n" + "Distribute food to your follower and fill you larders. " + "Place the food you wish to distribute in the camp food " + "zone. You must have a camp food zone, an unsorted loot " + "zone, and at least one loot destination zone or you will " + "be prompted to create them using the zone manager.\n" "Effects:\n" - "> Increases your faction's food supply value which in turn is " - "used to pay laborers for their time\n\n" + "> Increases your faction's food supply value which in " + "turn is used to pay laborers for their time\n\n" "Must have enjoyability >= -6\n" - "Perishable food liquidated at penalty depending on upgrades " - "and rot time:\n" + "Perishable food liquidated at penalty depending on " + "upgrades and rot time:\n" "> Rotten: 0%%\n" "> Rots in < 2 days: 60%%\n" "> Rots in < 5 days: 80%%\n\n" @@ -706,16 +726,17 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio mission_key.add( "Distribute Food", _( "Distribute Food" ), entry ); entry = string_format( _( "Notes:\n" - "Reset the zones that items are sorted to using the [ Menial " - "Labor ] mission.\n\n" + "Reset the zones that items are sorted to using the " + "[ Menial Labor ] mission.\n\n" "Effects:\n" - "> Assign sort zones using the zone manager. You must have a " - "camp food zone, an unsorted loot zone, and at least one loot " - "destination zone.\n" - "> Only items that are in the unsorted loot zone and not in " - "any other zone will be sorted.\n" - "Items that do not have a loot destination zone will be sorted " - "using the normal rules for automatic zone sorting." ) ); + "> Assign sort zones using the zone manager. You must " + "have a camp food zone, an unsorted loot zone, and at " + "least one loot destination zone.\n" + "> Only items that are in the unsorted loot zone and not " + "in any other zone will be sorted.\n" + "Items that do not have a loot destination zone will be " + "sorted using the normal rules for automatic zone " + "sorting." ) ); mission_key.add( "Reset Sort Points", _( "Reset Sort Points" ), entry ); } } @@ -734,13 +755,13 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: Very Low\n" "Time: 3 Hours, Repeated\n" "Positions: %d/3\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.size() < 3 ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.size() < 3 ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_fixed( entry, npc_list, 3_hours ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -759,13 +780,13 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "\n\nRisk: None\n" "Time: 3 Hours\n" "Positions: %d/1\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.empty() ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.empty() ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } } @@ -780,8 +801,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "each camp.\n\n" "Skill used: N/A \n" "Effects:\n" - "> Choose any one of the available expansions. Starting with a " - "farm is always a solid choice since food is used to support " + "> Choose any one of the available expansions. Starting with " + "a farm is always a solid choice since food is used to support " "companion missions and little is needed to get it going. " "With minimal investment, a mechanic can be useful as a " "chop-shop to rapidly dismantle large vehicles, and a forge " @@ -791,13 +812,13 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: None\n" "Time: 3 Hours \n" "Positions: %d/1\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.empty() ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.empty() ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -809,20 +830,21 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Skill used: fabrication\n" "Difficulty: 1 \n" "Effects:\n" - "> 50%% of trees/trunks at the forest position will be cut down.\n" + "> 50%% of trees/trunks at the forest position will be " + "cut down.\n" "> 100%% of total material will be brought back.\n" "> Repeatable with diminishing returns.\n" "> Will eventually turn forests into fields.\n" "Risk: None\n" "Time: 6 Hour Base + Travel Time + Cutting Time\n" "Positions: %d/1\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.empty() ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.empty() ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -842,13 +864,13 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: None\n" "Time: 6 Hour Base + Travel Time + Cutting Time\n" "Positions: %d/1\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.empty() ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.empty() ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -867,13 +889,13 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: Medium\n" "Time: 6 Hour Construction + Travel\n" "Positions: %d/1\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.empty() ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.empty() ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -898,8 +920,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -917,13 +939,13 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: Very Low\n" "Time: 4 Hours, Repeated\n" "Positions: %d/3\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.size() < 3 ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.size() < 3 ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_fixed( entry, npc_list, 4_hours ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -940,13 +962,13 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: Low\n" "Time: 6 Hours, Repeated\n" "Positions: %d/2\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.size() < 2 ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.size() < 2 ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_fixed( entry, npc_list, 6_hours ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -963,13 +985,13 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: Medium\n" "Time: 6 Hours, Repeated\n" "Positions: %d/1\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.empty() ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.empty() ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_fixed( entry, npc_list, 6_hours ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -977,16 +999,16 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio comp_list npc_list = get_mission_workers( "_faction_camp_om_fortifications" ); const base_camps::miss_data &miss_info = base_camps::miss_info[ "_faction_camp_om_fortifications" ]; entry = om_upgrade_description( "faction_wall_level_N_0" ); - mission_key.add_start( "Construct Map Fort", _( "Construct Map Fortifications" ), cata::nullopt, - entry, npc_list.empty() ); + mission_key.add_start( "Construct Map Fort", _( "Construct Map Fortifications" ), + cata::nullopt, entry, npc_list.empty() ); entry = om_upgrade_description( "faction_wall_level_N_1" ); mission_key.add_start( "Construct Trench", _( "Construct Spiked Trench" ), cata::nullopt, entry, npc_list.empty() ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -999,8 +1021,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -1020,13 +1042,13 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: High\n" "Time: Travel\n" "Positions: %d/3\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.size() < 3 ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.size() < 3 ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), cata::nullopt, - entry, avail ); + mission_key.add_return( miss_info.ret_miss_id, miss_info.ret_desc.translated(), + cata::nullopt, entry, avail ); } } @@ -1048,8 +1070,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: Very High\n" "Time: Travel\n" "Positions: %d/3\n" ), npc_list.size() ); - mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, entry, - npc_list.size() < 3 ); + mission_key.add_start( miss_info.miss_id, miss_info.desc.translated(), cata::nullopt, + entry, npc_list.size() < 3 ); if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); @@ -1077,7 +1099,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio for( const basecamp_upgrade &upgrade : available_upgrades( dir ) ) { const base_camps::miss_data &miss_info = base_camps::miss_info[ "_faction_upgrade_exp_" ]; - comp_list npc_list = get_mission_workers( upgrade.bldg + "_faction_upgrade_exp_" + dir_id ); + comp_list npc_list = get_mission_workers( upgrade.bldg + "_faction_upgrade_exp_" + + dir_id ); if( npc_list.empty() ) { entry = om_upgrade_description( upgrade.bldg ); mission_key.add_start( dir_id + miss_info.miss_id + upgrade.bldg, @@ -1087,8 +1110,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); mission_key.add_return( "Recover Ally, " + dir_id + " Expansion" + upgrade.bldg, - _( "Recover Ally, " ) + dir_abbr + _( " Expansion" ) + " " + - upgrade.name, dir, entry, avail ); + _( "Recover Ally, " ) + dir_abbr + _( " Expansion" ) + + " " + upgrade.name, dir, entry, avail ); } } @@ -1110,8 +1133,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio if( !npc_list.empty() ) { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( dir_id + miss_info.ret_miss_id, dir_abbr + miss_info.ret_desc, dir, - entry, avail ); + mission_key.add_return( dir_id + miss_info.ret_miss_id, + dir_abbr + miss_info.ret_desc, dir, entry, avail ); } } @@ -1124,8 +1147,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio } else { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( dir_id + miss_info.ret_miss_id, dir_abbr + miss_info.ret_desc, dir, - entry, avail ); + mission_key.add_return( dir_id + miss_info.ret_miss_id, + dir_abbr + miss_info.ret_desc, dir, entry, avail ); } } @@ -1138,8 +1161,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio } else { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( dir_id + miss_info.ret_miss_id, dir_abbr + miss_info.ret_desc, dir, - entry, avail ); + mission_key.add_return( dir_id + miss_info.ret_miss_id, + dir_abbr + miss_info.ret_desc, dir, entry, avail ); } } @@ -1165,8 +1188,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio } else { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( dir_id + miss_info.ret_miss_id, dir_abbr + miss_info.ret_desc, dir, - entry, avail ); + mission_key.add_return( dir_id + miss_info.ret_miss_id, + dir_abbr + miss_info.ret_desc, dir, entry, avail ); } } if( has_provides( "farming", dir ) ) { @@ -1188,13 +1211,14 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: None\n" "Time: 1 Min / Plot \n" "Positions: 0/1 \n" ); - mission_key.add_start( dir_id + miss_info.miss_id, dir_abbr + miss_info.desc, dir, entry, + mission_key.add_start( dir_id + miss_info.miss_id, + dir_abbr + miss_info.desc, dir, entry, plots > 0 && warm_enough_to_plant( omt_trg ) ); } else { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( dir_id + miss_info.ret_miss_id, dir_abbr + miss_info.ret_desc, dir, - entry, avail ); + mission_key.add_return( dir_id + miss_info.ret_miss_id, + dir_abbr + miss_info.ret_desc, dir, entry, avail ); } } if( has_provides( "farming", dir ) ) { @@ -1213,13 +1237,14 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio "Risk: None\n" "Time: 3 Min / Plot \n" "Positions: 0/1 \n" ); - mission_key.add_start( dir_id + miss_info.miss_id, dir_abbr + miss_info.desc, dir, entry, + mission_key.add_start( dir_id + miss_info.miss_id, + dir_abbr + miss_info.desc, dir, entry, plots > 0 ); } else { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( dir_id + miss_info.ret_miss_id, dir_abbr + miss_info.ret_desc, dir, - entry, avail ); + mission_key.add_return( dir_id + miss_info.ret_miss_id, + dir_abbr + miss_info.ret_desc, dir, entry, avail ); } } @@ -1231,8 +1256,8 @@ void basecamp::get_available_missions( mission_data &mission_key, bool by_radio } else { entry = miss_info.action.translated(); bool avail = update_time_left( entry, npc_list ); - mission_key.add_return( dir_id + miss_info.ret_miss_id, dir_abbr + miss_info.ret_desc, dir, - entry, avail ); + mission_key.add_return( dir_id + miss_info.ret_miss_id, + dir_abbr + miss_info.ret_desc, dir, entry, avail ); } } } @@ -1384,7 +1409,8 @@ bool basecamp::handle_mission( const std::string &miss_id, const cata::optional< const tripoint omt_trg = expansions[dir].pos; if( miss_id.substr( 0, 18 + miss_dir_id.size() ) == miss_dir_id + " Expansion Upgrade" ) { const std::string bldg = miss_id.substr( 18 + miss_dir_id.size() ); - start_upgrade( bldg, dir, bldg + "_faction_upgrade_exp_" + miss_dir_id, by_radio ); + start_upgrade( bldg, dir, bldg + "_faction_upgrade_exp_" + miss_dir_id, + by_radio ); } else if( miss_id == "Recover Ally, " + miss_dir_id + " Expansion" ) { upgrade_return( dir, "_faction_upgrade_exp_" + miss_dir_id ); } else { @@ -1415,7 +1441,8 @@ bool basecamp::handle_mission( const std::string &miss_id, const cata::optional< start_crafting( miss_id, *miss_dir, "SMITH", "_faction_exp_blacksmith_crafting_", by_radio ); if( miss_id == miss_dir_id + " (Finish) Smithing" ) { - const std::string msg = _( "returns from your blacksmith shop with something..." ); + const std::string msg = _( "returns from your blacksmith shop with " + "something..." ); mission_return( "_faction_exp_blacksmith_crafting_" + miss_dir_id, 1_minutes, true, msg, "fabrication", 2 ); } @@ -1466,8 +1493,9 @@ npc_ptr basecamp::start_mission( const std::string &miss_id, time_duration durat popup( _( "You don't have enough food stored to feed your companion." ) ); return nullptr; } - npc_ptr comp = talk_function::individual_mission( omt_pos, base_camps::id, desc, miss_id, false, - equipment, skill_tested, skill_level ); + npc_ptr comp = talk_function::individual_mission( omt_pos, base_camps::id, desc, miss_id, + false, equipment, skill_tested, + skill_level ); if( comp != nullptr ) { comp->companion_mission_time_ret = calendar::turn + duration; if( must_feed ) { @@ -1526,7 +1554,8 @@ void basecamp::start_cut_logs() standard_npc sample_npc( "Temp" ); sample_npc.set_fake( true ); int tree_est = om_cutdown_trees_est( forest, 50 ); - int tree_young_est = om_harvest_ter_est( sample_npc, forest, ter_id( "t_tree_young" ), 50 ); + int tree_young_est = om_harvest_ter_est( sample_npc, forest, + ter_id( "t_tree_young" ), 50 ); int dist = rl_dist( forest.xy(), omt_pos.xy() ); //Very roughly what the player does + 6 hours for prep, clean up, breaks time_duration chop_time = 6_hours + 1_hours * tree_est + 7_minutes * tree_young_est; @@ -1583,7 +1612,8 @@ void basecamp::start_clearcut() standard_npc sample_npc( "Temp" ); sample_npc.set_fake( true ); int tree_est = om_cutdown_trees_est( forest, 95 ); - int tree_young_est = om_harvest_ter_est( sample_npc, forest, ter_id( "t_tree_young" ), 95 ); + int tree_young_est = om_harvest_ter_est( sample_npc, forest, + ter_id( "t_tree_young" ), 95 ); int dist = rl_dist( forest.xy(), omt_pos.xy() ); //Very roughly what the player does + 6 hours for prep, clean up, breaks time_duration chop_time = 6_hours + 1_hours * tree_est + 7_minutes * tree_young_est; @@ -1615,7 +1645,8 @@ void basecamp::start_setup_hide_site() "field" }; popup( _( "Forests, swamps, and fields are valid hide site locations." ) ); - tripoint forest = om_target_tile( omt_pos, 10, 90, hide_locations, true, true, omt_pos, true ); + tripoint forest = om_target_tile( omt_pos, 10, 90, hide_locations, true, true, + omt_pos, true ); if( forest != tripoint( -999, -999, -999 ) ) { int dist = rl_dist( forest.xy(), omt_pos.xy() ); inventory tgt_inv = g->u.inv; @@ -1624,7 +1655,8 @@ void basecamp::start_setup_hide_site() } ); if( !pos_inv.empty() ) { std::vector losing_equipment = give_equipment( pos_inv, - _( "Do you wish to give your companion additional items?" ) ); + _( "Do you wish to give your companion " + "additional items?" ) ); int trips = om_carry_weight_to_trips( losing_equipment ); time_duration build_time = 6_hours; time_duration travel_time = companion_travel_time_calc( forest, omt_pos, 0_minutes, @@ -1654,7 +1686,8 @@ void basecamp::start_relay_hide_site() { std::vector hide_locations = { "faction_hide_site_0" }; popup( _( "You must select an existing hide site." ) ); - tripoint forest = om_target_tile( omt_pos, 10, 90, hide_locations, true, true, omt_pos, true ); + tripoint forest = om_target_tile( omt_pos, 10, 90, hide_locations, true, true, + omt_pos, true ); if( forest != tripoint( -999, -999, -999 ) ) { int dist = rl_dist( forest.xy(), omt_pos.xy() ); inventory tgt_inv = g->u.inv; @@ -1664,7 +1697,8 @@ void basecamp::start_relay_hide_site() std::vector losing_equipment; if( !pos_inv.empty() ) { losing_equipment = give_equipment( pos_inv, - _( "Do you wish to give your companion additional items?" ) ); + _( "Do you wish to give your companion " + "additional items?" ) ); } //Check items in improvised shelters at hide site tinymap target_bay; @@ -1828,7 +1862,8 @@ void basecamp::start_combat_mission( const std::string &miss ) // and then search for the mission id without direction prefix in the recipes // if there's a match, the player has selected a crafting mission void basecamp::start_crafting( const std::string &cur_id, const point &cur_dir, - const std::string &type, const std::string &miss_id, bool by_radio ) + const std::string &type, const std::string &miss_id, + bool by_radio ) { const std::string cur_dir_id = base_camps::all_directions.at( cur_dir ).id; const std::map &recipes = recipe_deck( type ); @@ -1861,8 +1896,9 @@ void basecamp::start_crafting( const std::string &cur_id, const point &cur_dir, return; } time_duration work_days = base_camps::to_workdays( making.batch_duration( batch_size ) ); - npc_ptr comp = start_mission( miss_id + cur_dir_id, work_days, true, _( "begins to work..." ), - false, {}, making.skill_used.str(), making.difficulty ); + npc_ptr comp = start_mission( miss_id + cur_dir_id, work_days, true, + _( "begins to work..." ), false, {}, + making.skill_used.str(), making.difficulty ); if( comp != nullptr ) { consume_components( making, batch_size, by_radio ); for( const item &results : making.create_results( batch_size ) ) { @@ -2115,7 +2151,8 @@ bool basecamp::start_garage_chop( const point &dir, const tripoint &omt_tgt ) } // camp faction companion mission recovery functions -npc_ptr basecamp::companion_choose_return( const std::string &miss_id, time_duration min_duration ) +npc_ptr basecamp::companion_choose_return( const std::string &miss_id, + time_duration min_duration ) { return talk_function::companion_choose_return( omt_pos, base_camps::id, miss_id, calendar::turn - min_duration ); @@ -2299,7 +2336,8 @@ bool basecamp::gathering_return( const std::string &task, time_duration min_time if( task == "_faction_camp_trapping" || task == "_faction_camp_hunting" ) { hunting_results( skill, task, checks_per_cycle * mission_time / min_time, 30, by_radio ); } else { - search_results( skill, itemlist, checks_per_cycle * mission_time / min_time, 15, by_radio ); + search_results( skill, itemlist, checks_per_cycle * mission_time / min_time, 15, + by_radio ); } return true; @@ -2351,7 +2389,8 @@ void basecamp::fortifications_return() void basecamp::recruit_return( const std::string &task, int score ) { - const std::string msg = _( "returns from searching for recruits with a bit more experience..." ); + const std::string msg = _( "returns from searching for recruits with " + "a bit more experience..." ); npc_ptr comp = mission_return( task, 4_days, true, msg, "recruiting", 2 ); if( comp == nullptr ) { return; @@ -3321,8 +3360,8 @@ std::string basecamp::recruit_description( int npc_count ) std::string desc = string_format( _( "Notes:\n" "Recruiting additional followers is very dangerous and " "expensive. The outcome is heavily dependent on the " - "skill of the companion you send and the appeal of your " - "base.\n\n" + "skill of the companion you send and the appeal of " + "your base.\n\n" "Skill used: speech\n" "Difficulty: 2 \n" "Base Score: +%3d%%\n" @@ -3599,8 +3638,8 @@ bool survive_random_encounter( npc &comp, std::string &situation, int favor, int talk_function::companion_skill_trainer( comp, "gathering", 10_minutes, 10 - favor ); } else if( skill_2 + favor > rng( 0, 10 ) ) { popup( _( "Another survivor approaches %s asking for directions." ), comp.name ); - popup( _( "Fearful that he may be an agent of some hostile faction, %s doesn't mention the camp." ), - comp.name ); + popup( _( "Fearful that he may be an agent of some hostile faction, " + "%s doesn't mention the camp." ), comp.name ); popup( _( "The two part on friendly terms and the survivor isn't seen again." ) ); talk_function::companion_skill_trainer( comp, "recruiting", 10_minutes, 10 - favor ); } else { @@ -3615,13 +3654,13 @@ bool survive_random_encounter( npc &comp, std::string &situation, int favor, int if( skill * rng( 8, 12 ) > ( monsters * rng( 8, 12 ) ) ) { if( one_in( 2 ) ) { popup( _( "The bull moose charged %s from the tree line..." ), comp.name ); - popup( _( "Despite being caught off guard %s was able to run away until the moose gave up pursuit." ), - comp.name ); + popup( _( "Despite being caught off guard %s was able to run away until the " + "moose gave up pursuit." ), comp.name ); } else { - popup( _( "The jabberwock grabbed %s by the arm from behind and began to scream." ), - comp.name ); - popup( _( "Terrified, %s spun around and delivered a massive kick to the creature's torso..." ), - comp.name ); + popup( _( "The jabberwock grabbed %s by the arm from behind and " + "began to scream." ), comp.name ); + popup( _( "Terrified, %s spun around and delivered a massive kick " + "to the creature's torso..." ), comp.name ); popup( _( "Collapsing into a pile of gore, %s walked away unscathed..." ), comp.name ); popup( _( "(Sounds like bullshit, you wonder what really happened.)" ) ); @@ -3629,8 +3668,8 @@ bool survive_random_encounter( npc &comp, std::string &situation, int favor, int talk_function::companion_skill_trainer( comp, "combat", 10_minutes, 10 - favor ); } else { if( one_in( 2 ) ) { - popup( _( "%s turned to find the hideous black eyes of a giant wasp staring back from only a few feet away..." ), - comp.name ); + popup( _( "%s turned to find the hideous black eyes of a giant wasp " + "staring back from only a few feet away..." ), comp.name ); popup( _( "The screams were terrifying, there was nothing anyone could do." ) ); } else { popup( _( "Pieces of %s were found strewn across a few bushes." ), comp.name ); From 72074becedc99194338b081552f4848a246b85e3 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Mon, 7 Oct 2019 20:41:52 -0500 Subject: [PATCH 06/21] basecamps: faster travel, faster carrying, faster logging companions now walk across overmap tiles in roughly 30 seconds, and will haul stuff on the ground at 30 seconds per overmap tiles (or 150 seconds for water tiles). NPCs will not haul items if they can carry them instead. Logging missions will be remarkable faster, since NPCs used to spend an enormous amount of time walking back and forth carrying logs. --- src/faction_camp.cpp | 85 ++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index 7b287ea1a8d88..8ffd3404b02df 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -96,7 +96,11 @@ const zone_type_id z_loot_unsorted( "LOOT_UNSORTED" ); const zone_type_id z_loot_ignore( "LOOT_IGNORE" ); const zone_type_id z_camp_food( "CAMP_FOOD" ); -using mass_volume = std::pair; +struct mass_volume { + units::mass wgt; + units::volume vol; + int count; +}; namespace base_camps { @@ -375,9 +379,9 @@ std::vector om_companion_path( const tripoint &start, int range_start * @param trips how many trips back and forth the NPC will make */ time_duration companion_travel_time_calc( const tripoint &omt_pos, const tripoint &omt_tgt, - time_duration work, int trips = 1 ); + time_duration work, int trips = 1, int haulage = 0 ); time_duration companion_travel_time_calc( const std::vector &journey, time_duration work, - int trips = 1 ); + int trips = 1, int haulauge = 0 ); /// Determines how many round trips a given NPC @ref comp will take to move all of the /// items @ref itms int om_carry_weight_to_trips( const std::vector &itms, npc_ptr comp = nullptr ); @@ -1559,19 +1563,12 @@ void basecamp::start_cut_logs() int dist = rl_dist( forest.xy(), omt_pos.xy() ); //Very roughly what the player does + 6 hours for prep, clean up, breaks time_duration chop_time = 6_hours + 1_hours * tree_est + 7_minutes * tree_young_est; - //Generous to believe the NPC can move ~ 2 logs or ~8 heavy sticks (3 per young tree?) - //per trip, each way is 1 trip - //20 young trees => ~60 sticks which can be carried 8 at a time, so 8 round trips or - //16 trips total - //This all needs to be in an om_carry_weight_over_distance function eventually... - int trips = tree_est + tree_young_est * 3 / 4; - //Always have to come back so no odd number of trips - trips += trips & 1 ? 1 : 0; + int haul_items = 2 * tree_est + 3 * tree_young_est; time_duration travel_time = companion_travel_time_calc( forest, omt_pos, 0_minutes, - trips ); + 2, haul_items ); time_duration work_time = travel_time + chop_time; if( !query_yn( _( "Trip Estimate:\n%s" ), camp_trip_description( work_time, - chop_time, travel_time, dist, trips, time_to_food( work_time ) ) ) ) { + chop_time, travel_time, dist, 2, time_to_food( work_time ) ) ) ) { return; } g->draw_ter(); @@ -1579,16 +1576,12 @@ void basecamp::start_cut_logs() npc_ptr comp = start_mission( "_faction_camp_cut_log", work_time, true, _( "departs to cut logs..." ), false, {}, "fabrication", 2 ); if( comp != nullptr ) { - units::mass carry_m = comp->weight_capacity() - comp->weight_carried(); - // everyone gets at least a makeshift sling of storage - units::volume carry_v = comp->volume_capacity() - comp->volume_carried() + - item( itype_id( "makeshift_sling" ) ).get_storage(); om_cutdown_trees_logs( forest, 50 ); om_harvest_ter( *comp, forest, ter_id( "t_tree_young" ), 50 ); mass_volume harvest = om_harvest_itm( comp, forest, 95 ); // recalculate trips based on actual load and capacity - trips = om_carry_weight_to_trips( harvest.first, harvest.second, carry_m, carry_v ); - travel_time = companion_travel_time_calc( forest, omt_pos, 0_minutes, trips ); + travel_time = companion_travel_time_calc( forest, omt_pos, 0_minutes, 2, + harvest.count ); work_time = travel_time + chop_time; comp->companion_mission_time_ret = calendar::turn + work_time; //If we cleared a forest... @@ -1658,9 +1651,10 @@ void basecamp::start_setup_hide_site() _( "Do you wish to give your companion " "additional items?" ) ); int trips = om_carry_weight_to_trips( losing_equipment ); + int haulage = trips <= 2 ? 0 : losing_equipment.size(); time_duration build_time = 6_hours; time_duration travel_time = companion_travel_time_calc( forest, omt_pos, 0_minutes, - trips ); + 2, haulage ); time_duration work_time = travel_time + build_time; if( !query_yn( _( "Trip Estimate:\n%s" ), camp_trip_description( work_time, build_time, travel_time, dist, trips, time_to_food( work_time ) ) ) ) { @@ -1671,7 +1665,8 @@ void basecamp::start_setup_hide_site() "survival", 3 ); if( comp != nullptr ) { trips = om_carry_weight_to_trips( losing_equipment, comp ); - work_time = companion_travel_time_calc( forest, omt_pos, 0_minutes, trips ) + + haulage = trips <= 2 ? 0 : losing_equipment.size(); + work_time = companion_travel_time_calc( forest, omt_pos, 0_minutes, 2, haulage ) + build_time; comp->companion_mission_time_ret = calendar::turn + work_time; om_set_hide_site( *comp, forest, losing_equipment ); @@ -1715,9 +1710,11 @@ void basecamp::start_relay_hide_site() //Only get charged the greater trips since return is free for both int trips = std::max( om_carry_weight_to_trips( gaining_equipment ), om_carry_weight_to_trips( losing_equipment ) ); + int haulage = trips <= 2 ? 0 : std::max( gaining_equipment.size(), + losing_equipment.size() ); time_duration build_time = 6_hours; time_duration travel_time = companion_travel_time_calc( forest, omt_pos, 0_minutes, - trips ); + trips, haulage ); time_duration work_time = travel_time + build_time; if( !query_yn( _( "Trip Estimate:\n%s" ), camp_trip_description( work_time, build_time, travel_time, dist, trips, time_to_food( work_time ) ) ) ) { @@ -1731,8 +1728,10 @@ void basecamp::start_relay_hide_site() // recalculate trips based on actual load trips = std::max( om_carry_weight_to_trips( gaining_equipment, comp ), om_carry_weight_to_trips( losing_equipment, comp ) ); - work_time = companion_travel_time_calc( forest, omt_pos, 0_minutes, trips ) + - build_time; + int haulage = trips <= 2 ? 0 : std::max( gaining_equipment.size(), + losing_equipment.size() ); + work_time = companion_travel_time_calc( forest, omt_pos, 0_minutes, trips, + haulage ) + build_time; comp->companion_mission_time_ret = calendar::turn + work_time; om_set_hide_site( *comp, forest, losing_equipment, gaining_equipment ); } @@ -2895,18 +2894,22 @@ mass_volume om_harvest_itm( npc_ptr comp, const tripoint &omt_tgt, int chance, b units::volume harvested_v = 0_ml; units::mass total_m = 0_gram; units::volume total_v = 0_ml; + int total_num = 0; + int harvested_num = 0; tripoint mapmin = tripoint( 0, 0, omt_tgt.z ); tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, omt_tgt.z ); for( const tripoint &p : target_bay.points_in_rectangle( mapmin, mapmax ) ) { for( const item &i : target_bay.i_at( p ) ) { total_m += i.weight( true ); total_v += i.volume( true ); + total_num += 1; if( take && x_in_y( chance, 100 ) ) { if( comp ) { comp->companion_mission_inv.push_back( i ); } harvested_m += i.weight( true ); harvested_v += i.volume( true ); + harvested_num += 1; } } if( take ) { @@ -2914,9 +2917,15 @@ mass_volume om_harvest_itm( npc_ptr comp, const tripoint &omt_tgt, int chance, b } } target_bay.save(); - mass_volume results = { total_m, total_v }; + mass_volume results; if( take ) { - results = { harvested_m, harvested_v }; + results.wgt = harvested_m; + results.vol = harvested_v; + results.count = harvested_num; + } else { + results.wgt = total_m; + results.vol = total_v; + results.count = total_num; } return results; } @@ -3073,36 +3082,36 @@ bool om_set_hide_site( npc &comp, const tripoint &omt_tgt, // path and travel time time_duration companion_travel_time_calc( const tripoint &omt_pos, - const tripoint &omt_tgt, time_duration work, - int trips ) + const tripoint &omt_tgt, time_duration work, int trips, int haulage ) { std::vector journey = line_to( omt_pos, omt_tgt ); - return companion_travel_time_calc( journey, work, trips ); + return companion_travel_time_calc( journey, work, trips, haulage ); } time_duration companion_travel_time_calc( const std::vector &journey, - time_duration work, int trips ) + time_duration work, int trips, int haulage ) { int one_way = 0; for( auto &om : journey ) { const oter_id &omt_ref = overmap_buffer.ter( om ); std::string om_id = omt_ref.id().c_str(); - //Player walks 1 om is roughly 2.5 min + //Player walks 1 om is roughly 30 seconds if( om_id == "field" ) { - one_way += 3; + one_way += 30 + 30 * haulage; } else if( om_id == "forest" ) { - one_way += 4; + one_way += 40 + 30 * haulage; } else if( om_id == "forest_thick" ) { - one_way += 5; + one_way += 50 + 30 * haulage; } else if( om_id == "forest_water" ) { - one_way += 6; + one_way += 60 + 30 * haulage; } else if( is_river( omt_ref ) ) { - one_way += 20; + // hauling stuff over a river is slow, because you have to portage most items + one_way += 200 + 40 * haulage; } else { - one_way += 4; + one_way += 40 + 30 * haulage; } } - return work + one_way * trips * 1_minutes; + return work + one_way * trips * 1_seconds; } int om_carry_weight_to_trips( units::mass mass, units::volume volume, From da1e6d10ad0eb83be4380e10964ec4e841e4e6d2 Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Mon, 7 Oct 2019 21:06:06 -0400 Subject: [PATCH 07/21] AEA_ENTRANCE --- data/json/legacy_artifact_active.json | 16 ++++++++++++++++ doc/MAGIC.md | 2 ++ src/magic.cpp | 1 + src/magic.h | 1 + src/magic_spell_effect.cpp | 19 +++++++++++++++++++ 5 files changed, 39 insertions(+) diff --git a/data/json/legacy_artifact_active.json b/data/json/legacy_artifact_active.json index 586456f220246..2bab9a56eebca 100644 --- a/data/json/legacy_artifact_active.json +++ b/data/json/legacy_artifact_active.json @@ -507,6 +507,22 @@ "min_duration": 180000, "max_duration": 180000 }, + { + "type": "SPELL", + "id": "AEA_ENTRANCE", + "name": "Artifact Entrance", + "description": "Entrances surrounding monsters", + "effect": "charm_monster", + "message": "", + "min_damage": 0, + "max_damage": 600, + "min_duration": 500, + "max_duration": 5000, + "min_aoe": 8, + "max_aoe": 8, + "valid_targets": [ "self", "hostile" ], + "flags": [ "RANDOM_DAMAGE", "RANDOM_DURATION" ] + }, { "type": "SPELL", "id": "AEA_SCREAM", diff --git a/doc/MAGIC.md b/doc/MAGIC.md index 4c27caf051ae6..7cfc8125e13bf 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -109,6 +109,8 @@ Any aoe will manifest as a circular area centered on the target, and will only d * "morale" - gives a morale effect to all npcs or avatar within aoe, with value damage(). decay_start is duration() / 10. +* "charm_monster" - charms a monster that has less hp than damage() for approximately duration() + * "mutate" - mutates the target(s). if effect_str is defined, mutates toward that category instead of picking at random. the "MUTATE_TRAIT" flag allows effect_str to be a specific trait instead of a category. damage() / 100 is the percent chance the mutation will be successful (a value of 10000 represents 100.00%) * "WONDER" - Unlike the above, this is not an "effect" but a "flag". This alters the behavior of the parent spell drastically: The spell itself doesn't cast, but its damage and range information is used in order to cast the extra_effects. N of the extra_effects will be chosen at random to be cast, where N is the current damage of the spell (stacks with RANDOM_DAMAGE flag) and the message of the spell cast by this spell will also be displayed. If this spell's message is not wanted to be displayed, make sure the message is an empty string. diff --git a/src/magic.cpp b/src/magic.cpp index cea183f96023c..ca26861f85360 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -218,6 +218,7 @@ void spell_type::load( JsonObject &jo, const std::string & ) { "mod_moves", spell_effect::mod_moves }, { "map", spell_effect::map }, { "morale", spell_effect::morale }, + { "charm_monster", spell_effect::charm_monster }, { "mutate", spell_effect::mutate }, { "none", spell_effect::none } }; diff --git a/src/magic.h b/src/magic.h index 8876aa7128aa2..96ba5c6674cb7 100644 --- a/src/magic.h +++ b/src/magic.h @@ -506,6 +506,7 @@ void flashbang( const spell &sp, Creature &caster, const tripoint &target ); void mod_moves( const spell &sp, Creature &caster, const tripoint &target ); void map( const spell &sp, Creature &caster, const tripoint & ); void morale( const spell &sp, Creature &caster, const tripoint &target ); +void charm_monster( const spell &sp, Creature &caster, const tripoint &target ); void mutate( const spell &sp, Creature &caster, const tripoint &target ); void none( const spell &sp, Creature &, const tripoint &target ); } // namespace spell_effect diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index e91e1d3aa9430..c99ef3a565654 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -782,6 +782,25 @@ void spell_effect::morale( const spell &sp, Creature &caster, const tripoint &ta } } +void spell_effect::charm_monster( const spell &sp, Creature &caster, const tripoint &target ) +{ + const std::set area = spell_effect_blast( sp, caster.pos(), target, sp.aoe(), false ); + for( const tripoint &potential_target : area ) { + if( !sp.is_valid_target( caster, potential_target ) ) { + continue; + } + monster *mon = g->critter_at( potential_target ); + if( !mon ) { + continue; + } + sp.make_sound( potential_target ); + if( mon->friendly == 0 && mon->get_hp() <= sp.damage() ) { + mon->unset_dest(); + mon->friendly += sp.duration() / 100; + } + } +} + void spell_effect::mutate( const spell &sp, Creature &caster, const tripoint &target ) { const std::set area = spell_effect_blast( sp, caster.pos(), target, sp.aoe(), false ); From f48547ba8067b6a944ff2500ce2e5690d20c60c7 Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Mon, 7 Oct 2019 23:18:37 -0400 Subject: [PATCH 08/21] Magiclysm: Lava Bomb Spell --- data/mods/Magiclysm/Spells/earthshaper.json | 68 +++++++++++++++++++ .../mods/Magiclysm/itemgroups/spellbooks.json | 7 +- data/mods/Magiclysm/items/spell_scrolls.json | 8 +++ .../ter_fur_transform/ter_fur_transform.json | 5 ++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/data/mods/Magiclysm/Spells/earthshaper.json b/data/mods/Magiclysm/Spells/earthshaper.json index 72fc92a43d34e..008c0965a6060 100644 --- a/data/mods/Magiclysm/Spells/earthshaper.json +++ b/data/mods/Magiclysm/Spells/earthshaper.json @@ -204,5 +204,73 @@ "spell_class": "EARTHSHAPER", "energy_source": "MANA", "flags": [ "PERMANENT", "NO_LEGS", "CONCENTRATE" ] + }, + { + "id": "lava_bomb_shrapnel", + "type": "SPELL", + "name": "Lava Bomb Shrapnel", + "description": "This is a sub spell for the Lava Bomb spell.", + "effect": "projectile_attack", + "valid_targets": [ "hostile", "ally", "self", "ground" ], + "damage_type": "cut", + "max_level": 30, + "min_damage": 5, + "max_damage": 65, + "damage_increment": 2, + "min_aoe": 1, + "max_aoe": 3, + "aoe_increment": 0.1 + }, + { + "id": "lava_bomb_heat", + "type": "SPELL", + "name": "Lava Bomb Heat", + "description": "This is a sub spell for the Lava Bomb spell.", + "effect": "projectile_attack", + "valid_targets": [ "hostile", "ally", "self", "ground" ], + "damage_type": "fire", + "max_level": 30, + "min_damage": 10, + "max_damage": 90, + "damage_increment": 2.25, + "min_aoe": 3, + "max_aoe": 5, + "aoe_increment": 0.1 + }, + { + "id": "lava_bomb_ter", + "type": "SPELL", + "name": "Lava Bomb Terrain", + "description": "This is a sub spell for the Lava Bomb spell.", + "effect": "ter_transform", + "effect_str": "lava_bomb", + "max_level": 30, + "min_aoe": 0, + "max_aoe": 2, + "aoe_increment": 0.15, + "valid_targets": [ "hostile", "ally", "self", "ground" ] + }, + { + "id": "lava_bomb_main", + "//": "The main part of the spell that causes all of the side effects.", + "type": "SPELL", + "name": "Lava Bomb", + "description": "You tear up the ground beneath you to fire a lava bomb: a globe of lava surrounded by hot, solid rock. It shatters upon impact, spraying shards of rock and lava everywhere.", + "effect": "projectile_attack", + "valid_targets": [ "hostile", "ground", "ally" ], + "damage_type": "bash", + "max_level": 30, + "difficulty": 12, + "min_damage": 20, + "max_damage": 140, + "damage_increment": 4, + "min_range": 6, + "max_range": 10, + "range_increment": 0.2, + "base_casting_time": 350, + "base_energy_cost": 1000, + "energy_source": "MANA", + "flags": [ "VERBAL", "SOMATIC", "LOUD" ], + "extra_effects": [ { "id": "lava_bomb_shrapnel" }, { "id": "lava_bomb_heat" }, { "id": "lava_bomb_ter" } ] } ] diff --git a/data/mods/Magiclysm/itemgroups/spellbooks.json b/data/mods/Magiclysm/itemgroups/spellbooks.json index 719ae6e0abe64..74e0dc4d40062 100644 --- a/data/mods/Magiclysm/itemgroups/spellbooks.json +++ b/data/mods/Magiclysm/itemgroups/spellbooks.json @@ -95,7 +95,12 @@ { "id": "spell_scroll_tier_3", "type": "item_group", - "items": [ [ "spell_scroll_magus_mana_blast", 50 ], [ "lightning_storm_scroll", 50 ], [ "spell_scroll_invisibility", 10 ] ] + "items": [ + [ "spell_scroll_magus_mana_blast", 50 ], + [ "lightning_storm_scroll", 50 ], + [ "spell_scroll_invisibility", 10 ], + [ "spell_scroll_lava_bomb", 5 ] + ] }, { "id": "spellbook_tier_0", diff --git a/data/mods/Magiclysm/items/spell_scrolls.json b/data/mods/Magiclysm/items/spell_scrolls.json index 316a60b51db82..671854bd9c9d6 100644 --- a/data/mods/Magiclysm/items/spell_scrolls.json +++ b/data/mods/Magiclysm/items/spell_scrolls.json @@ -617,5 +617,13 @@ "name": "Scroll of Purification Seed", "description": "You summon a gift of the earth which will purify water. Greater levels yield greater numbers of seeds.", "use_action": { "type": "learn_spell", "spells": [ "purify_seed" ] } + }, + { + "type": "GENERIC", + "copy-from": "spell_scroll", + "id": "spell_scroll_lava_bomb", + "name": "Scroll of Lava Bomb", + "description": "You tear up the ground beneath you to fire a lava bomb: a globe of lava surrounded by hot, solid rock. It shatters upon impact, spraying shards of rock and lava everywhere.", + "use_action": { "type": "learn_spell", "spell": [ "lava_bomb" ] } } ] diff --git a/data/mods/Magiclysm/ter_fur_transform/ter_fur_transform.json b/data/mods/Magiclysm/ter_fur_transform/ter_fur_transform.json index 1841135172a0a..8bcfe3aefdd04 100644 --- a/data/mods/Magiclysm/ter_fur_transform/ter_fur_transform.json +++ b/data/mods/Magiclysm/ter_fur_transform/ter_fur_transform.json @@ -84,5 +84,10 @@ "id": "fungicide", "terrain": [ { "result": "t_dirt_barren", "valid_flags": [ "FUNGUS" ], "message": "The fungus here dies back." } ], "furniture": [ { "result": "f_null", "valid_flags": [ "FUNGUS" ], "message": "The fungus here dies back." } ] + }, + { + "type": "ter_furn_transform", + "id": "lava_bomb", + "terrain": [ { "result": "t_lava", "valid_flags": [ "DIGGABLE" ] } ] } ] From 9f71965d4af610f67c51ed6fc884dfc43e45b22b Mon Sep 17 00:00:00 2001 From: Fris0uman <41293484+Fris0uman@users.noreply.github.com> Date: Tue, 8 Oct 2019 09:26:19 +0200 Subject: [PATCH 09/21] Solar panels are not repairable (#34546) * can't repair any solar panel item * can't repair solar panel vehicle part * NO_REPAIR flag is valid even for vehicle with TOOL_WRENCH flag --- data/json/items/vehicle/solar.json | 1 + data/json/vehicleparts/vehicle_parts.json | 2 +- src/veh_type.cpp | 15 +++++++++------ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/data/json/items/vehicle/solar.json b/data/json/items/vehicle/solar.json index 925119485e0e5..b01b4c53e3d35 100644 --- a/data/json/items/vehicle/solar.json +++ b/data/json/items/vehicle/solar.json @@ -11,6 +11,7 @@ "material": [ "glass" ], "volume": "3 L", "bashing": 1, + "flags": [ "NO_REPAIR" ], "category": "veh_parts", "price": 90000 }, diff --git a/data/json/vehicleparts/vehicle_parts.json b/data/json/vehicleparts/vehicle_parts.json index 16f8fc2cb33dd..a97fe8adb7a9c 100644 --- a/data/json/vehicleparts/vehicle_parts.json +++ b/data/json/vehicleparts/vehicle_parts.json @@ -1737,7 +1737,7 @@ "item": "solar_panel", "difficulty": 4, "location": "on_roof", - "flags": [ "SOLAR_PANEL", "TOOL_WRENCH" ], + "flags": [ "SOLAR_PANEL", "TOOL_WRENCH", "NO_REPAIR" ], "breaks_into": [ { "item": "steel_lump", "count": [ 2, 4 ] }, { "item": "steel_chunk", "count": [ 2, 4 ] }, diff --git a/src/veh_type.cpp b/src/veh_type.cpp index 2dfdad49f69fa..dd665e618ed36 100644 --- a/src/veh_type.cpp +++ b/src/veh_type.cpp @@ -520,18 +520,21 @@ void vpart_info::check() if( part.has_flag( "TOOL_WRENCH" ) || part.has_flag( "WHEEL" ) ) { part.install_reqs = { { requirement_id( "vehicle_bolt" ), 1 } }; part.removal_reqs = { { requirement_id( "vehicle_bolt" ), 1 } }; - part.repair_reqs = { { requirement_id( "welding_standard" ), 5 } }; - + if( !part.has_flag( "NO_REPAIR" ) ) { + part.repair_reqs = { { requirement_id( "welding_standard" ), 5 } }; + } } else if( part.has_flag( "TOOL_SCREWDRIVER" ) ) { part.install_reqs = { { requirement_id( "vehicle_screw" ), 1 } }; part.removal_reqs = { { requirement_id( "vehicle_screw" ), 1 } }; - part.repair_reqs = { { requirement_id( "adhesive" ), 1 } }; - + if( !part.has_flag( "NO_REPAIR" ) ) { + part.repair_reqs = { { requirement_id( "adhesive" ), 1 } }; + } } else if( part.has_flag( "NAILABLE" ) ) { part.install_reqs = { { requirement_id( "vehicle_nail_install" ), 1 } }; part.removal_reqs = { { requirement_id( "vehicle_nail_removal" ), 1 } }; - part.repair_reqs = { { requirement_id( "adhesive" ), 2 } }; - + if( !part.has_flag( "NO_REPAIR" ) ) { + part.repair_reqs = { { requirement_id( "adhesive" ), 2 } }; + } } else if( part.has_flag( "TOOL_NONE" ) ) { // no-op From 3ece2826bc3bfaa1de2d724e9d0e3d8c384deed5 Mon Sep 17 00:00:00 2001 From: Curtis Merrill Date: Tue, 8 Oct 2019 03:26:44 -0400 Subject: [PATCH 10/21] Encapsulate bionic power (#34517) * make power_level and max_power_level private adds setters, getters, and some other helper functions for use as well * change charge_poewr to mod_poewr_level * update tests to use power level getters and setters * reviewer suggestion --- src/activity_handlers.cpp | 2 +- src/avatar_action.cpp | 4 +- src/bionics.cpp | 96 ++++++++++++++++---------------- src/bionics_ui.cpp | 2 +- src/character.cpp | 50 +++++++++++++++++ src/character.h | 16 +++++- src/condition.cpp | 2 +- src/consumption.cpp | 22 ++++---- src/crafting.cpp | 2 +- src/explosion.cpp | 7 ++- src/game.cpp | 28 +++++----- src/game_inventory.cpp | 4 +- src/iexamine.cpp | 15 ++--- src/item.cpp | 6 +- src/iuse.cpp | 9 +-- src/iuse_actor.cpp | 4 +- src/magic.cpp | 8 +-- src/magic_spell_effect.cpp | 3 +- src/melee.cpp | 6 +- src/memorial_logger.cpp | 2 +- src/monattack.cpp | 4 +- src/mutation.cpp | 2 +- src/newcharacter.cpp | 2 +- src/npcmove.cpp | 8 +-- src/panels.cpp | 12 ++-- src/player.cpp | 111 ++++++++++++++++++------------------- src/player.h | 2 - src/player_display.cpp | 6 +- src/vehicle.cpp | 10 ++-- src/visitable.cpp | 4 +- tests/bionics_test.cpp | 10 ++-- tests/mondefense_test.cpp | 2 +- 32 files changed, 259 insertions(+), 202 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index a4b95fad00165..ea57983cb1037 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -4355,7 +4355,7 @@ void activity_handlers::spellcasting_finish( player_activity *act, player *p ) p->mod_stat( "stamina", -cost ); break; case bionic_energy: - p->power_level -= units::from_kilojoule( cost ); + p->mod_power_level( -units::from_kilojoule( cost ) ); break; case hp_energy: blood_magic( p, cost ); diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index 9dc1abc94c820..870f1fe09a7d9 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -664,7 +664,7 @@ bool avatar_action::fire_check( avatar &you, const map &m, const targeting_data if( !( you.has_charges( "UPS_off", ups_drain ) || you.has_charges( "adv_UPS_off", adv_ups_drain ) || ( you.has_active_bionic( bionic_id( "bio_ups" ) ) && - you.power_level >= units::from_kilojoule( ups_drain ) ) ) ) { + you.get_power_level() >= units::from_kilojoule( ups_drain ) ) ) ) { add_msg( m_info, _( "You need a UPS with at least %d charges or an advanced UPS with at least %d charges to fire that!" ), ups_drain, adv_ups_drain ); @@ -798,7 +798,7 @@ bool avatar_action::fire( avatar &you, map &m ) } if( shots && args.power_cost ) { - you.charge_power( units::from_kilojoule( -args.power_cost ) * shots ); + you.mod_power_level( units::from_kilojoule( -args.power_cost ) * shots ); } g->reenter_fullscreen(); return shots != 0; diff --git a/src/bionics.cpp b/src/bionics.cpp index cc48aa64fd3bd..54f8c1da0f2f2 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -183,7 +183,7 @@ void npc::discharge_cbm_weapon() return; } bionic &bio = ( *my_bionics )[cbm_weapon_index]; - charge_power( -bionics[bio.id].power_activate ); + mod_power_level( -bionics[bio.id].power_activate ); weapon = real_weapon; cbm_weapon_index = -1; } @@ -195,7 +195,7 @@ void npc::check_or_use_weapon_cbm( const bionic_id &cbm_id ) return; } - int free_power = std::max( 0, units::to_kilojoule( power_level - max_power_level ) * + int free_power = std::max( 0, units::to_kilojoule( get_power_level() - get_max_power_level() ) * static_cast( rules.cbm_reserve ) / 100 ); if( free_power == 0 ) { return; @@ -246,7 +246,7 @@ void npc::check_or_use_weapon_cbm( const bionic_id &cbm_id ) } weapon = item( bionics[bio.id].fake_item ); - charge_power( -bionics[bio.id].power_activate ); + mod_power_level( -bionics[bio.id].power_activate ); bio.powered = true; cbm_weapon_index = index; } @@ -282,7 +282,7 @@ bool player::activate_bionic( int b, bool eff_only ) // It's already on! return false; } - if( power_level < bionics[bio.id].power_activate ) { + if( !enough_power_for( bio.id ) ) { add_msg_if_player( m_info, _( "You don't have the power to activate your %s." ), bionics[bio.id].name ); return false; @@ -293,7 +293,7 @@ bool player::activate_bionic( int b, bool eff_only ) } //We can actually activate now, do activation-y things - charge_power( -bionics[bio.id].power_activate ); + mod_power_level( -bionics[bio.id].power_activate ); if( bionics[bio.id].toggled || bionics[bio.id].charge_time > 0 ) { bio.powered = true; } @@ -308,14 +308,14 @@ bool player::activate_bionic( int b, bool eff_only ) // On activation effects go here if( bionics[bio.id].gun_bionic ) { - charge_power( bionics[bio.id].power_activate ); + mod_power_level( bionics[bio.id].power_activate ); bio_gun = item( bionics[bio.id].fake_item ); g->refresh_all(); avatar_action::fire( g->u, g->m, bio_gun, units::to_kilojoule( bionics[bio.id].power_activate ) ); } else if( bionics[ bio.id ].weapon_bionic ) { if( weapon.has_flag( "NO_UNWIELD" ) ) { add_msg_if_player( m_info, _( "Deactivate your %s first!" ), weapon.tname() ); - charge_power( bionics[bio.id].power_activate ); + mod_power_level( bionics[bio.id].power_activate ); bio.powered = false; return false; } @@ -323,7 +323,7 @@ bool player::activate_bionic( int b, bool eff_only ) if( !weapon.is_null() ) { const std::string query = string_format( _( "Stop wielding %s?" ), weapon.tname() ); if( !dispose_item( item_location( *this, &weapon ), query ) ) { - charge_power( bionics[bio.id].power_activate ); + mod_power_level( bionics[bio.id].power_activate ); bio.powered = false; return false; } @@ -376,8 +376,8 @@ bool player::activate_bionic( int b, bool eff_only ) add_msg_if_player( m_info, _( "You cannot activate that while mounted." ) ); return false; } - mod_moves( units::to_kilojoule( power_level ) ); - power_level = 0_kJ; + mod_moves( units::to_kilojoule( get_power_level() ) ); + set_power_level( 0_kJ ); add_msg_if_player( m_good, _( "Your speed suddenly increases!" ) ); if( one_in( 3 ) ) { add_msg_if_player( m_bad, _( "Your muscles tear with the strain." ) ); @@ -517,7 +517,7 @@ bool player::activate_bionic( int b, bool eff_only ) add_msg_if_player( m_bad, _( "There was not enough moisture in the air from which to draw water!" ) ); } else if( !liquid_handler::consume_liquid( water ) ) { - charge_power( bionics[bionic_id( "bio_evap" )].power_activate ); + mod_power_level( bionics[bionic_id( "bio_evap" )].power_activate ); } } else if( bio.id == "bio_torsionratchet" ) { add_msg_if_player( m_info, _( "Your torsion ratchet locks onto your joints." ) ); @@ -530,7 +530,7 @@ bool player::activate_bionic( int b, bool eff_only ) mod_moves( -100 ); } else { add_msg_if_player( m_info, _( "You can't light a fire there." ) ); - charge_power( bionics[bionic_id( "bio_lighter" )].power_activate ); + mod_power_level( bionics[bionic_id( "bio_lighter" )].power_activate ); } } else if( bio.id == "bio_geiger" ) { add_msg_if_player( m_info, _( "Your radiation level: %d" ), radiation ); @@ -544,7 +544,7 @@ bool player::activate_bionic( int b, bool eff_only ) if( has_effect( effect_adrenaline ) ) { // Safety add_msg_if_player( m_bad, _( "The bionic refuses to activate!" ) ); - charge_power( bionics[bio.id].power_activate ); + mod_power_level( bionics[bio.id].power_activate ); } else { add_effect( effect_adrenaline, 20_minutes ); } @@ -555,7 +555,7 @@ bool player::activate_bionic( int b, bool eff_only ) explosion_handler::emp_blast( *pnt ); mod_moves( -100 ); } else { - charge_power( bionics[bionic_id( "bio_emp" )].power_activate ); + mod_power_level( bionics[bionic_id( "bio_emp" )].power_activate ); } } else if( bio.id == "bio_hydraulics" ) { add_msg_if_player( m_good, _( "Your muscles hiss as hydraulic strength fills them!" ) ); @@ -582,7 +582,7 @@ bool player::activate_bionic( int b, bool eff_only ) } } if( !extracted ) { - charge_power( bionics[bionic_id( "bio_water_extractor" )].power_activate ); + mod_power_level( bionics[bionic_id( "bio_water_extractor" )].power_activate ); } } else if( bio.id == "bio_magnet" ) { static const std::set affected_materials = @@ -627,7 +627,7 @@ bool player::activate_bionic( int b, bool eff_only ) if( invoke_item( &tmp_item ) == 0 ) { if( tmp_item.charges > 0 ) { // restore the energy since CBM wasn't used - charge_power( bionics[bio.id].power_activate ); + mod_power_level( bionics[bio.id].power_activate ); } return true; } @@ -679,9 +679,9 @@ bool player::activate_bionic( int b, bool eff_only ) } else { ctr = item( "radiocontrol", 0 ); } - ctr.charges = units::to_kilojoule( power_level ); + ctr.charges = units::to_kilojoule( get_power_level() ); int power_use = invoke_item( &ctr ); - charge_power( units::from_kilojoule( -power_use ) ); + mod_power_level( units::from_kilojoule( -power_use ) ); bio.powered = ctr.active; } else { bio.powered = g->remoteveh() != nullptr || !get_value( "remote_controlling" ).empty(); @@ -778,14 +778,14 @@ bool player::deactivate_bionic( int b, bool eff_only ) bionics[bio.id].name ); return false; } - if( power_level < bionics[bio.id].power_deactivate ) { + if( get_power_level() < bionics[bio.id].power_deactivate ) { add_msg( m_info, _( "You don't have the power to deactivate your %s." ), bionics[bio.id].name ); return false; } //We can actually deactivate now, do deactivation-y things - charge_power( -bionics[bio.id].power_deactivate ); + mod_power_level( -bionics[bio.id].power_deactivate ); bio.powered = false; add_msg_if_player( m_neutral, _( "You deactivate your %s." ), bionics[bio.id].name ); } @@ -854,20 +854,17 @@ bool player::burn_fuel( int b, bool start ) for( const itype_id &fuel : get_fuel_available( bio.id ) ) { const item tmp_fuel( fuel ); int temp = std::stoi( get_value( fuel ) ); - if( power_level + units::from_kilojoule( tmp_fuel.fuel_energy() ) *bio.info().fuel_efficiency > - max_power_level ) { - + if( get_power_level() + units::from_kilojoule( tmp_fuel.fuel_energy() ) *bio.info().fuel_efficiency + > get_max_power_level() ) { add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste fuel." ), _( "'s %s turns off to not waste fuel." ), bio.info().name ); - bio.powered = false; deactivate_bionic( b, true ); return false; - } else { if( temp > 0 ) { temp -= 1; - charge_power( units::from_kilojoule( tmp_fuel.fuel_energy() ) *bio.info().fuel_efficiency ); + mod_power_level( units::from_kilojoule( tmp_fuel.fuel_energy() ) *bio.info().fuel_efficiency ); set_value( fuel, std::to_string( temp ) ); update_fuel_storage( fuel ); if( bio.info().exothermic_power_gen ) { @@ -921,7 +918,7 @@ static bool attempt_recharge( player &p, bionic &bio, int &amount, int factor = power_cost -= units::from_kilojoule( armor_power_cost ) * factor; } } - if( p.power_level >= power_cost ) { + if( p.get_power_level() >= power_cost ) { // Set the recharging cost and charge the bionic. amount = units::to_kilojoule( power_cost ); // This is our first turn of charging, so subtract a turn from the recharge delay. @@ -967,7 +964,7 @@ void player::process_bionic( int b ) return; } if( cost ) { - charge_power( units::from_kilojoule( -cost ) ); + mod_power_level( units::from_kilojoule( -cost ) ); } } } @@ -990,14 +987,14 @@ void player::process_bionic( int b ) "bio_hydraulics" ); } else if( bio.id == "bio_nanobots" ) { for( int i = 0; i < num_hp_parts; i++ ) { - if( power_level >= 5_kJ && hp_cur[i] > 0 && hp_cur[i] < hp_max[i] ) { + if( get_power_level() >= 5_kJ && hp_cur[i] > 0 && hp_cur[i] < hp_max[i] ) { heal( static_cast( i ), 1 ); - charge_power( -5_kJ ); + mod_power_level( -5_kJ ); } } for( const body_part bp : all_body_parts ) { - if( power_level >= 2_kJ && remove_effect( effect_bleed, bp ) ) { - charge_power( -2_kJ ); + if( get_power_level() >= 2_kJ && remove_effect( effect_bleed, bp ) ) { + mod_power_level( -2_kJ ); } } } else if( bio.id == "bio_painkiller" ) { @@ -1006,7 +1003,7 @@ void player::process_bionic( int b ) int max_pkill = std::min( 150, pain ); if( pkill < max_pkill ) { mod_painkiller( 1 ); - charge_power( -2_kJ ); + mod_power_level( -2_kJ ); } // Only dull pain so extreme that we can't pkill it safely @@ -1014,10 +1011,10 @@ void player::process_bionic( int b ) mod_pain( -1 ); // Negative side effect: negative stim stim--; - charge_power( -2_kJ ); + mod_power_level( -2_kJ ); } } else if( bio.id == "bio_cable" ) { - if( power_level >= max_power_level ) { + if( is_max_power() ) { return; } @@ -1035,11 +1032,11 @@ void player::process_bionic( int b ) double modifier = g->natural_light_level( pos().z ) / default_daylight_level(); // basic solar panel produces 50W = 1 charge/20_seconds = 180 charges/hour(3600) if( is_wearing( "solarpack_on" ) && x_in_y( 180 * modifier, 3600 ) ) { - charge_power( 1_kJ ); + mod_power_level( 1_kJ ); } // quantum solar backpack = solar panel x6 if( is_wearing( "q_solarpack_on" ) && x_in_y( 6 * 180 * modifier, 3600 ) ) { - charge_power( 1_kJ ); + mod_power_level( 1_kJ ); } } if( cable->get_var( "state" ) == "UPS_link" ) { @@ -1048,10 +1045,10 @@ void player::process_bionic( int b ) }; if( has_charges( "UPS_off", 1, used_ups ) ) { use_charges( "UPS_off", 1, used_ups ); - charge_power( 1_kJ ); + mod_power_level( 1_kJ ); } else if( has_charges( "adv_UPS_off", 1, used_ups ) ) { use_charges( "adv_UPS_off", roll_remainder( 0.6 ), used_ups ); - charge_power( 1_kJ ); + mod_power_level( 1_kJ ); } } continue; @@ -1063,7 +1060,7 @@ void player::process_bionic( int b ) wants_power_amt = vp->vehicle().discharge_battery( wants_power_amt ); if( wants_power_amt == 0 ) { - charge_power( 1_kJ ); + mod_power_level( 1_kJ ); break; } } @@ -1071,7 +1068,7 @@ void player::process_bionic( int b ) if( wants_power_amt < battery_per_power && wants_power_amt > 0 && x_in_y( battery_per_power - wants_power_amt, battery_per_power ) ) { - charge_power( 1_kJ ); + mod_power_level( 1_kJ ); } } else if( bio.id == "bio_gills" ) { if( has_effect( effect_asthma ) ) { @@ -1477,7 +1474,7 @@ void player::perform_uninstall( bionic_id bid, int difficulty, int success, int remove_bionic( bid ); // remove power bank provided by bionic - max_power_level -= units::from_kilojoule( power_lvl ); + mod_max_power_level( -units::from_kilojoule( power_lvl ) ); item cbm( "burnt_out_bionic" ); if( item::type_is_defined( bid.c_str() ) ) { @@ -1557,7 +1554,7 @@ bool player::uninstall_bionic( const bionic &target_cbm, monster &installer, pla } // remove power bank provided by bionic - patient.max_power_level -= target_cbm.info().capacity; + patient.mod_max_power_level( -target_cbm.info().capacity ); patient.remove_bionic( target_cbm.id ); item cbm( "burnt_out_bionic" ); if( item::type_is_defined( target_cbm.id.c_str() ) ) { @@ -1822,15 +1819,16 @@ void player::bionics_install_failure( bionic_id bid, std::string installer, int } ); if( valid.empty() ) { // We've got all the bad bionics! - if( max_power_level > 0_kJ ) { - units::energy old_power = max_power_level; + if( has_max_power() ) { + units::energy old_power = get_max_power_level(); add_msg( m_bad, _( "%s lose power capacity!" ), disp_name() ); - max_power_level = units::from_kilojoule( rng( 0, units::to_kilojoule( max_power_level ) - 25 ) ); + set_max_power_level( units::from_kilojoule( rng( 0, + units::to_kilojoule( get_max_power_level() ) - 25 ) ) ); if( is_player() ) { g->memorial().add( pgettext( "memorial_male", "Lost %d units of power capacity." ), pgettext( "memorial_female", "Lost %d units of power capacity." ), - units::to_kilojoule( old_power - max_power_level ) ); + units::to_kilojoule( old_power - get_max_power_level() ) ); } } // TODO: What if we can't lose power capacity? No penalty? @@ -1947,7 +1945,7 @@ void player::add_bionic( const bionic_id &b ) } units::energy pow_up = bionics[b].capacity; - max_power_level += pow_up; + mod_max_power_level( pow_up ); if( b == "bio_power_storage" || b == "bio_power_storage_mkII" ) { add_msg_if_player( m_good, _( "Increased storage capacity by %i." ), units::to_kilojoule( pow_up ) ); @@ -1995,7 +1993,7 @@ int player::num_bionics() const std::pair player::amount_of_storage_bionics() const { - units::energy lvl = max_power_level; + units::energy lvl = get_max_power_level(); // exclude amount of power capacity obtained via non-power-storage CBMs for( const auto &it : *my_bionics ) { diff --git a/src/bionics_ui.cpp b/src/bionics_ui.cpp index 69fa2715053e4..745c2bb1bdffc 100644 --- a/src/bionics_ui.cpp +++ b/src/bionics_ui.cpp @@ -69,7 +69,7 @@ static void draw_bionics_titlebar( const catacurses::window &window, player *p, } const int pwr_str_pos = right_print( window, 0, 1, c_white, string_format( _( "Bionic Power: %i/%i" ), - units::to_kilojoule( p->power_level ), units::to_kilojoule( p->max_power_level ) ) ); + units::to_kilojoule( p->get_power_level() ), units::to_kilojoule( p->get_max_power_level() ) ) ); std::string desc; if( mode == REASSIGNING ) { desc = _( "Reassigning.\nSelect a bionic to reassign or press SPACE to cancel." ); diff --git a/src/character.cpp b/src/character.cpp index b9e71171e1bc8..1d674228d665a 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -939,6 +939,56 @@ bionic_id Character::get_most_efficient_bionic( const std::vector &bi return bio; } +units::energy Character::get_power_level() const +{ + return power_level; +} + +units::energy Character::get_max_power_level() const +{ + return max_power_level; +} + +void Character::set_power_level( units::energy npower ) +{ + power_level = std::min( npower, max_power_level ); +} + +void Character::set_max_power_level( units::energy npower_max ) +{ + max_power_level = npower_max; +} + +void Character::mod_power_level( units::energy npower ) +{ + power_level = clamp( power_level + npower, 0_kJ, max_power_level ); +} + +void Character::mod_max_power_level( units::energy npower_max ) +{ + max_power_level += npower_max; +} + +bool Character::is_max_power() const +{ + return power_level >= max_power_level; +} + +bool Character::has_power() const +{ + return power_level > 0_kJ; +} + +bool Character::has_max_power() const +{ + return max_power_level > 0_kJ; +} + +bool Character::enough_power_for( const bionic_id &bid ) const +{ + return power_level >= bid->power_activate; +} + std::vector Character::get_fuel_available( const bionic_id &bio ) const { std::vector stored_fuels; diff --git a/src/character.h b/src/character.h index 343343ed87297..62d63a34b135a 100644 --- a/src/character.h +++ b/src/character.h @@ -578,6 +578,17 @@ class Character : public Creature, public visitable int get_mod_stat_from_bionic( const Character::stat &Stat ) const; // route for overmap-scale travelling std::vector omt_path; + + units::energy get_power_level() const; + units::energy get_max_power_level() const; + void mod_power_level( units::energy npower ); + void mod_max_power_level( units::energy npower_max ); + void set_power_level( units::energy npower ); + void set_max_power_level( units::energy npower_max ); + bool is_max_power() const; + bool has_power() const; + bool has_max_power() const; + bool enough_power_for( const bionic_id &bid ) const; // --------------- Generic Item Stuff --------------- struct has_mission_item_filter { @@ -930,8 +941,6 @@ class Character : public Creature, public visitable stomach_contents stomach; stomach_contents guts; - units::energy power_level; - units::energy max_power_level; int oxygen; int stamina; int radiation; @@ -1090,6 +1099,9 @@ class Character : public Creature, public visitable // A unique ID number, assigned by the game class. Values should never be reused. character_id id; + units::energy power_level; + units::energy max_power_level; + /** Needs (hunger, starvation, thirst, fatigue, etc.) */ int stored_calories; int healthy_calories; diff --git a/src/condition.cpp b/src/condition.cpp index 844607b0e65de..ab7059a992b89 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -304,7 +304,7 @@ void conditional_t::set_has_bionics( JsonObject &jo, const std::string &membe actor = dynamic_cast( d.beta ); } if( bionics_id == "ANY" ) { - return actor->num_bionics() > 0 || actor->max_power_level > 0_kJ; + return actor->num_bionics() > 0 || actor->has_max_power(); } return actor->has_bionic( bionic_id( bionics_id ) ); }; diff --git a/src/consumption.cpp b/src/consumption.cpp index 332cdb0b9381c..af4c8fa928d0f 100644 --- a/src/consumption.cpp +++ b/src/consumption.cpp @@ -242,7 +242,7 @@ std::pair player::fun_for( const item &comest ) const } if( has_active_bionic( bio_taste_blocker ) && - power_level > units::from_kilojoule( abs( comest.get_comestible()->fun ) ) && + get_power_level() > units::from_kilojoule( abs( comest.get_comestible()->fun ) ) && fun < 0 ) { fun = 0; } @@ -811,17 +811,17 @@ bool player::eat( item &food, bool force ) } if( has_bionic( bio_ethanol ) && food.type->can_use( "ALCOHOL" ) ) { - charge_power( units::from_kilojoule( rng( 50, 200 ) ) ); + mod_power_level( units::from_kilojoule( rng( 50, 200 ) ) ); } if( has_bionic( bio_ethanol ) && food.type->can_use( "ALCOHOL_WEAK" ) ) { - charge_power( units::from_kilojoule( rng( 25, 100 ) ) ); + mod_power_level( units::from_kilojoule( rng( 25, 100 ) ) ); } if( has_bionic( bio_ethanol ) && food.type->can_use( "ALCOHOL_STRONG" ) ) { - charge_power( units::from_kilojoule( rng( 75, 300 ) ) ); + mod_power_level( units::from_kilojoule( rng( 75, 300 ) ) ); } if( has_active_bionic( bio_taste_blocker ) ) { - charge_power( units::from_kilojoule( -abs( food.get_comestible()->fun ) ) ); + mod_power_level( units::from_kilojoule( -abs( food.get_comestible()->fun ) ) ); } if( food.has_flag( "CANNIBALISM" ) ) { @@ -1175,7 +1175,7 @@ bool player::feed_battery_with( item &it ) const int energy = get_acquirable_energy( it, rechargeable_cbm::battery ); const int profitable_energy = std::min( energy, - units::to_kilojoule( max_power_level - power_level ) ); + units::to_kilojoule( get_max_power_level() - get_power_level() ) ); if( profitable_energy <= 0 ) { add_msg_player_or_npc( m_info, @@ -1184,7 +1184,7 @@ bool player::feed_battery_with( item &it ) return false; } - charge_power( units::from_kilojoule( it.charges ) ); + mod_power_level( units::from_kilojoule( it.charges ) ); it.charges -= profitable_energy; add_msg_player_or_npc( m_info, @@ -1276,14 +1276,14 @@ bool player::feed_furnace_with( item &it ) _( "You digest your %s, but fail to acquire energy from it." ), _( " digests their %s for energy, but fails to acquire energy from it." ), it.tname() ); - } else if( power_level >= max_power_level ) { + } else if( is_max_power() ) { add_msg_player_or_npc( _( "You digest your %s, but you're fully powered already, so the energy is wasted." ), _( " digests a %s for energy, they're fully powered already, so the energy is wasted." ), it.tname() ); } else { const int profitable_energy = std::min( energy, - units::to_kilojoule( max_power_level - power_level ) ); + units::to_kilojoule( get_max_power_level() - get_power_level() ) ); if( it.count_by_charges() ) { add_msg_player_or_npc( m_info, ngettext( "You digest %d %s and recharge %d point of energy.", @@ -1307,7 +1307,7 @@ bool player::feed_furnace_with( item &it ) ), it.tname(), profitable_energy ); } - charge_power( units::from_kilojoule( profitable_energy ) ); + mod_power_level( units::from_kilojoule( profitable_energy ) ); } it.charges -= consumed_charges; @@ -1410,7 +1410,7 @@ int player::get_acquirable_energy( const item &it, rechargeable_cbm cbm ) const case rechargeable_cbm::other: const int to_consume = std::min( it.charges, std::numeric_limits::max() ); const int to_charge = std::min( static_cast( it.fuel_energy() * to_consume ), - units::to_kilojoule( max_power_level - power_level ) ); + units::to_kilojoule( get_max_power_level() - get_power_level() ) ); return to_charge; break; } diff --git a/src/crafting.cpp b/src/crafting.cpp index 046b356a64923..1db635b39334c 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -548,7 +548,7 @@ const inventory &player::crafting_inventory( const tripoint &src_pos, int radius if( ( !bio_data.activated || bio.powered ) && !bio_data.fake_item.empty() ) { cached_crafting_inventory += item( bio.info().fake_item, - calendar::turn, units::to_kilojoule( power_level ) ); + calendar::turn, units::to_kilojoule( get_power_level() ) ); } } if( has_trait( trait_BURROW ) ) { diff --git a/src/explosion.cpp b/src/explosion.cpp index a49caa0df9942..2615e07576217 100644 --- a/src/explosion.cpp +++ b/src/explosion.cpp @@ -708,10 +708,11 @@ void emp_blast( const tripoint &p ) } } if( g->u.posx() == x && g->u.posy() == y ) { - if( g->u.power_level > 0_kJ ) { + if( g->u.get_power_level() > 0_kJ ) { add_msg( m_bad, _( "The EMP blast drains your power." ) ); - int max_drain = ( g->u.power_level > 1000_kJ ? 1000 : units::to_kilojoule( g->u.power_level ) ); - g->u.charge_power( units::from_kilojoule( -rng( 1 + max_drain / 3, max_drain ) ) ); + int max_drain = ( g->u.get_power_level() > 1000_kJ ? 1000 : units::to_kilojoule( + g->u.get_power_level() ) ); + g->u.mod_power_level( units::from_kilojoule( -rng( 1 + max_drain / 3, max_drain ) ) ); } // TODO: More effects? //e-handcuffs effects diff --git a/src/game.cpp b/src/game.cpp index 0f801ea4855e5..05af7b72956dc 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -4190,10 +4190,10 @@ void game::monmove() if( !critter.is_dead() && u.has_active_bionic( bionic_id( "bio_alarm" ) ) && - u.power_level >= 25_kJ && + u.get_power_level() >= 25_kJ && rl_dist( u.pos(), critter.pos() ) <= 5 && !critter.is_hallucination() ) { - u.charge_power( -25_kJ ); + u.mod_power_level( -25_kJ ); add_msg( m_warning, _( "Your motion alarm goes off!" ) ); cancel_activity_or_ignore_query( distraction_type::motion_alarm, _( "Your motion alarm goes off!" ) ); @@ -9637,7 +9637,8 @@ void game::place_player_overmap( const tripoint &om_dest ) bool game::phasing_move( const tripoint &dest_loc ) { - if( !u.has_active_bionic( bionic_id( "bio_probability_travel" ) ) || u.power_level < 250_kJ ) { + if( !u.has_active_bionic( bionic_id( "bio_probability_travel" ) ) || + u.get_power_level() < 250_kJ ) { return false; } @@ -9657,15 +9658,15 @@ bool game::phasing_move( const tripoint &dest_loc ) //add 1 to tunnel distance for each impassable tile in the line tunneldist += 1; if( tunneldist * 250_kJ > - u.power_level ) { //oops, not enough energy! Tunneling costs 250 bionic power per impassable tile + u.get_power_level() ) { //oops, not enough energy! Tunneling costs 250 bionic power per impassable tile add_msg( _( "You try to quantum tunnel through the barrier but are reflected! Try again with more energy!" ) ); - u.charge_power( -250_kJ ); + u.mod_power_level( -250_kJ ); return false; } if( tunneldist > 24 ) { add_msg( m_info, _( "It's too dangerous to tunnel that far!" ) ); - u.charge_power( -250_kJ ); + u.mod_power_level( -250_kJ ); return false; } @@ -9679,7 +9680,8 @@ bool game::phasing_move( const tripoint &dest_loc ) } add_msg( _( "You quantum tunnel through the %d-tile wide barrier!" ), tunneldist ); - u.charge_power( -( tunneldist * 250_kJ ) ); //tunneling costs 250 bionic power per impassable tile + //tunneling costs 250 bionic power per impassable tile + u.mod_power_level( -( tunneldist * 250_kJ ) ); u.moves -= 100; //tunneling costs 100 moves u.setpos( dest ); @@ -9892,29 +9894,29 @@ void game::on_move_effects() const item muscle( "muscle" ); if( one_in( 8 ) ) {// active power gen if( u.has_active_bionic( bionic_id( "bio_torsionratchet" ) ) ) { - u.charge_power( 1_kJ ); + u.mod_power_level( 1_kJ ); } for( const bionic_id &bid : u.get_bionic_fueled_with( muscle ) ) { if( u.has_active_bionic( bid ) ) { - u.charge_power( units::from_kilojoule( muscle.fuel_energy() ) * bid->fuel_efficiency ); + u.mod_power_level( units::from_kilojoule( muscle.fuel_energy() ) * bid->fuel_efficiency ); } } } if( one_in( 160 ) ) {// passive power gen if( u.has_bionic( bionic_id( "bio_torsionratchet" ) ) ) { - u.charge_power( 1_kJ ); + u.mod_power_level( 1_kJ ); } for( const bionic_id &bid : u.get_bionic_fueled_with( muscle ) ) { if( u.has_bionic( bid ) ) { - u.charge_power( units::from_kilojoule( muscle.fuel_energy() ) * bid->fuel_efficiency ); + u.mod_power_level( units::from_kilojoule( muscle.fuel_energy() ) * bid->fuel_efficiency ); } } } if( u.has_active_bionic( bionic_id( "bio_jointservo" ) ) ) { if( u.movement_mode_is( PMM_RUN ) ) { - u.charge_power( -20_kJ ); + u.mod_power_level( -20_kJ ); } else { - u.charge_power( -10_kJ ); + u.mod_power_level( -10_kJ ); } } } diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index a7a651aa11c80..e79843d385501 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -563,7 +563,7 @@ class comestible_inventory_preset : public inventory_selector_preset if( !res.success() && cbm == rechargeable_cbm::none ) { return res.str(); - } else if( cbm == rechargeable_cbm::battery && p.power_level >= p.max_power_level ) { + } else if( cbm == rechargeable_cbm::battery && p.is_max_power() ) { return _( "You're fully charged" ); } else if( cbm == rechargeable_cbm::other && ( p.get_fuel_capacity( it.typeId() ) <= 0 ) ) { return string_format( _( "No space to store more %s" ), it.tname() ); @@ -1622,7 +1622,7 @@ class bionic_install_preset: public inventory_selector_preset return _( "Superior version installed" ); } else if( pa.is_npc() && !bid->npc_usable ) { return _( "CBM not compatible with patient" ); - } else if( units::energy_max - pa.max_power_level < bid->capacity ) { + } else if( units::energy_max - pa.get_max_power_level() < bid->capacity ) { return _( "Max power capacity already reached" ); } else if( !p.has_enough_anesth( itemtype, pa ) ) { const int weight = units::to_kilogram( pa.bodyweight() ) / 10; diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 9fa0178729f7b..6812c2d95c4cb 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -2577,7 +2577,7 @@ void iexamine::fireplace( player &p, const tripoint &examp ) const bool has_firestarter = !firestarters.empty(); const bool has_bionic_firestarter = p.has_bionic( bionic_id( "bio_lighter" ) ) && - p.power_level >= bionic_id( "bio_lighter" )->power_activate; + p.enough_power_for( bionic_id( "bio_lighter" ) ); auto firequenchers = p.items_with( []( const item & it ) { return it.damage_melee( DT_BASH ); @@ -2627,7 +2627,7 @@ void iexamine::fireplace( player &p, const tripoint &examp ) } case 2: { if( g->m.add_field( examp, fd_fire, 1 ) ) { - p.charge_power( -bionic_id( "bio_lighter" )->power_activate ); + p.mod_power_level( -bionic_id( "bio_lighter" )->power_activate ); p.mod_moves( -to_moves( 1_seconds ) ); } else { p.add_msg_if_player( m_info, _( "You can't light a fire there." ) ); @@ -3944,7 +3944,7 @@ void iexamine::pay_gas( player &p, const tripoint &examp ) int pricePerUnit = getGasPricePerLiter( discount ); bool can_hack = ( !p.has_trait( trait_ILLITERATE ) && ( ( p.has_charges( "electrohack", 25 ) ) || - ( p.has_bionic( bionic_id( "bio_fingerhack" ) ) && p.power_level > 24_kJ ) ) ); + ( p.has_bionic( bionic_id( "bio_fingerhack" ) ) && p.get_power_level() > 24_kJ ) ) ); uilist amenu; amenu.selected = 1; @@ -5686,7 +5686,7 @@ hack_result iexamine::hack_attempt( player &p ) bool using_electrohack = p.has_charges( "electrohack", 25 ) && query_yn( _( "Use electrohack?" ) ); bool using_fingerhack = !using_electrohack && p.has_bionic( bionic_id( "bio_fingerhack" ) ) && - p.power_level > 24_kJ && query_yn( _( "Use fingerhack?" ) ); + p.get_power_level() > 24_kJ && query_yn( _( "Use fingerhack?" ) ); if( !( using_electrohack || using_fingerhack ) ) { return HACK_UNABLE; @@ -5695,7 +5695,7 @@ hack_result iexamine::hack_attempt( player &p ) p.moves -= to_moves( 5_minutes ); p.practice( skill_computer, 20 ); if( using_fingerhack ) { - p.charge_power( -25_kJ ); + p.mod_power_level( -25_kJ ); } else { p.use_charges( "electrohack", 25 ); } @@ -5707,7 +5707,7 @@ hack_result iexamine::hack_attempt( player &p ) if( success < 0 ) { add_msg( _( "You cause a short circuit!" ) ); if( using_fingerhack ) { - p.charge_power( -25_kJ ); + p.mod_power_level( -25_kJ ); } else { p.use_charges( "electrohack", 25 ); } @@ -5718,7 +5718,8 @@ hack_result iexamine::hack_attempt( player &p ) p.use_amount( "electrohack", 1 ); } else { add_msg( m_bad, _( "Your power is drained!" ) ); - p.charge_power( units::from_kilojoule( -rng( 25, units::to_kilojoule( p.power_level ) ) ) ); + p.mod_power_level( units::from_kilojoule( -rng( 25, + units::to_kilojoule( p.get_power_level() ) ) ) ); } } return HACK_FAIL; diff --git a/src/item.cpp b/src/item.cpp index 3505e64b3a3a5..4851caf6d11ad 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -6180,7 +6180,7 @@ int item::ammo_remaining() const if( is_tool() || is_gun() ) { // includes auxiliary gunmods if( has_flag( "USES_BIONIC_POWER" ) ) { - int power = units::to_kilojoule( g->u.power_level ); + int power = units::to_kilojoule( g->u.get_power_level() ); return power; } return charges; @@ -6311,8 +6311,8 @@ int item::ammo_consume( int qty, const tripoint &pos ) } else if( is_tool() || is_gun() ) { qty = std::min( qty, charges ); if( has_flag( "USES_BIONIC_POWER" ) ) { - charges = units::to_kilojoule( g->u.power_level ); - g->u.charge_power( units::from_kilojoule( -qty ) ); + charges = units::to_kilojoule( g->u.get_power_level() ); + g->u.mod_power_level( units::from_kilojoule( -qty ) ); } charges -= qty; if( charges == 0 ) { diff --git a/src/iuse.cpp b/src/iuse.cpp index c4a3719140c15..c085a5d2258e7 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -5526,10 +5526,10 @@ int iuse::heat_food( player *p, item *it, bool, const tripoint & ) { if( g->m.has_nearby_fire( p->pos() ) ) { heat_item( *p ); - } else if( p->has_active_bionic( bionic_id( "bio_tools" ) ) && p->power_level > 10_kJ && + } else if( p->has_active_bionic( bionic_id( "bio_tools" ) ) && p->get_power_level() > 10_kJ && query_yn( _( "There is no fire around, use your integrated toolset instead?" ) ) ) { if( heat_item( *p ) ) { - p->charge_power( -10_kJ ); + p->mod_power_level( -10_kJ ); } } else { p->add_msg_if_player( m_info, _( "You need to be next to fire to heat something up with the %s." ), @@ -7891,8 +7891,9 @@ int iuse::ehandcuffs( player *p, item *it, bool t, const tripoint &pos ) } if( p->has_item( *it ) ) { - if( p->has_active_bionic( bionic_id( "bio_shock" ) ) && p->power_level >= 2_kJ && one_in( 5 ) ) { - p->charge_power( -2_kJ ); + if( p->has_active_bionic( bionic_id( "bio_shock" ) ) && p->get_power_level() >= 2_kJ && + one_in( 5 ) ) { + p->mod_power_level( -2_kJ ); it->item_tags.erase( "NO_UNWIELD" ); it->ammo_unset(); diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 09966b88b1199..4e8e53eff3bde 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -871,7 +871,7 @@ void ups_based_armor_actor::load( JsonObject &obj ) static bool has_powersource( const item &i, const player &p ) { - if( i.is_power_armor() && p.can_interface_armor() && p.power_level > 0_kJ ) { + if( i.is_power_armor() && p.can_interface_armor() && p.has_power() ) { return true; } return p.has_charges( "UPS", 1 ); @@ -4090,7 +4090,7 @@ ret_val install_bionic_actor::can_use( const player &p, const item &it, bo } else if( it.has_fault( fault_id( "fault_bionic_salvaged" ) ) ) { return ret_val::make_failure( _( "This CBM is already deployed. You need to reset it to factory state." ) ); - } else if( units::energy_max - p.max_power_level < bid->capacity ) { + } else if( units::energy_max - p.get_max_power_level() < bid->capacity ) { return ret_val::make_failure( _( "Max power capacity already reached" ) ); } } diff --git a/src/magic.cpp b/src/magic.cpp index 7ff91a393038e..b1f77d4639985 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -630,7 +630,7 @@ bool spell::can_cast( const player &p ) const return false; } case bionic_energy: - return p.power_level >= units::from_kilojoule( energy_cost( p ) ); + return p.get_power_level() >= units::from_kilojoule( energy_cost( p ) ); case fatigue_energy: return p.get_fatigue() < EXHAUSTED; case none_energy: @@ -805,7 +805,7 @@ std::string spell::energy_cur_string( const player &p ) const return _( "infinite" ); } if( energy_source() == bionic_energy ) { - return colorize( to_string( units::to_kilojoule( p.power_level ) ), c_light_blue ); + return colorize( to_string( units::to_kilojoule( p.get_power_level() ) ), c_light_blue ); } if( energy_source() == mana_energy ) { return colorize( to_string( p.magic.available_mana() ), c_light_blue ); @@ -1353,7 +1353,7 @@ int known_magic::max_mana( const player &p ) const const float int_bonus = ( ( 0.2f + p.get_int() * 0.1f ) - 1.0f ) * mana_base; const float unaugmented_mana = std::max( 0.0f, ( ( mana_base + int_bonus ) * p.mutation_value( "mana_multiplier" ) ) + - p.mutation_value( "mana_modifier" ) - units::to_kilojoule( p.power_level ) ); + p.mutation_value( "mana_modifier" ) - units::to_kilojoule( p.get_power_level() ) ); return p.calculate_by_enchantment( unaugmented_mana, enchantment::mod::MAX_MANA, true ); } @@ -1383,7 +1383,7 @@ bool known_magic::has_enough_energy( const player &p, spell &sp ) const case mana_energy: return available_mana() >= cost; case bionic_energy: - return p.power_level >= units::from_kilojoule( cost ); + return p.get_power_level() >= units::from_kilojoule( cost ); case stamina_energy: return p.stamina >= cost; case hp_energy: diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index ca1e2371c25c4..1d2deffe6a4a1 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -574,8 +574,7 @@ void spell_effect::recover_energy( const spell &sp, Creature &caster, const trip p->mod_fatigue( -healing ); } else if( energy_source == "BIONIC" ) { if( healing > 0 ) { - p->power_level = units::from_kilojoule( std::min( units::to_kilojoule( p->max_power_level ), - units::to_kilojoule( p->power_level ) + healing ) ); + p->mod_power_level( units::from_kilojoule( healing ) ); } else { p->mod_stat( "stamina", healing ); } diff --git a/src/melee.cpp b/src/melee.cpp index b5413c5808722..6990546be674b 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -1661,9 +1661,9 @@ std::string player::melee_special_effects( Creature &t, damage_instance &d, item std::string target = t.disp_name(); - if( has_active_bionic( bionic_id( "bio_shock" ) ) && power_level >= 2_kJ && + if( has_active_bionic( bionic_id( "bio_shock" ) ) && get_power_level() >= 2_kJ && ( !is_armed() || weapon.conductive() ) ) { - charge_power( -2_kJ ); + mod_power_level( -2_kJ ); d.add_damage( DT_ELECTRIC, rng( 2, 10 ) ); if( is_player() ) { @@ -1674,7 +1674,7 @@ std::string player::melee_special_effects( Creature &t, damage_instance &d, item } if( has_active_bionic( bionic_id( "bio_heat_absorb" ) ) && !is_armed() && t.is_warm() ) { - charge_power( 3_kJ ); + mod_power_level( 3_kJ ); d.add_damage( DT_COLD, 3 ); if( is_player() ) { dump << string_format( _( "You drain %s's body heat." ), target ) << std::endl; diff --git a/src/memorial_logger.cpp b/src/memorial_logger.cpp index 1e4d74b273a98..386d79199be5a 100644 --- a/src/memorial_logger.cpp +++ b/src/memorial_logger.cpp @@ -287,7 +287,7 @@ void memorial_logger::write( std::ostream &file, const std::string &epitaph ) co } file << string_format( _( "Bionic Power: %d/%d" ), - units::to_kilojoule( u.power_level ), units::to_kilojoule( u.max_power_level ) ) << eol; + units::to_kilojoule( u.get_power_level() ), units::to_kilojoule( u.get_max_power_level() ) ) << eol; file << eol; //Equipment diff --git a/src/monattack.cpp b/src/monattack.cpp index f4996c4457f7f..b071220b18cc8 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -4589,7 +4589,7 @@ bool mattack::riotbot( monster *z ) handcuffs.set_var( "HANDCUFFS_Y", foe->posy() ); const bool is_uncanny = foe->has_active_bionic( bionic_id( "bio_uncanny_dodge" ) ) && - foe->power_level > 74_kJ && + foe->get_power_level() > 74_kJ && !one_in( 3 ); ///\EFFECT_DEX >13 allows and increases chance to slip out of riot bot handcuffs const bool is_dex = foe->dex_cur > 13 && !one_in( foe->dex_cur - 11 ); @@ -4597,7 +4597,7 @@ bool mattack::riotbot( monster *z ) if( is_uncanny || is_dex ) { if( is_uncanny ) { - foe->charge_power( -75_kJ ); + foe->mod_power_level( -75_kJ ); } add_msg( m_good, diff --git a/src/mutation.cpp b/src/mutation.cpp index d550a8f3993ae..c20f6b4169379 100644 --- a/src/mutation.cpp +++ b/src/mutation.cpp @@ -547,7 +547,7 @@ void player::activate_mutation( const trait_id &mut ) return; } } else if( mut == trait_DEBUG_BIONIC_POWER ) { - max_power_level += 100_kJ; + mod_max_power_level( 100_kJ ); add_msg_if_player( m_good, _( "Bionic power storage increased by 100." ) ); tdata.powered = false; return; diff --git a/src/newcharacter.cpp b/src/newcharacter.cpp index 0106069caa8b9..fe101c4e2d04f 100644 --- a/src/newcharacter.cpp +++ b/src/newcharacter.cpp @@ -626,7 +626,7 @@ bool avatar::create( character_type type, const std::string &tempname ) add_bionic( bio ); } // Adjust current energy level to maximum - power_level = max_power_level; + set_power_level( get_max_power_level() ); for( auto &t : get_base_traits() ) { std::vector styles; diff --git a/src/npcmove.cpp b/src/npcmove.cpp index 942d1b66c36bb..8f145f1290871 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -1621,16 +1621,16 @@ bool npc::wants_to_recharge_cbm() for( const bionic_id bid : get_fueled_bionics() ) { for( const itype_id fid : bid->fuel_opts ) { return get_fuel_available( bid ).empty() || ( !get_fuel_available( bid ).empty() && - power_level < ( max_power_level * static_cast( rules.cbm_recharge ) / 100 ) && + get_power_level() < ( get_max_power_level() * static_cast( rules.cbm_recharge ) / 100 ) && !use_bionic_by_id( bid ) ); } } - return power_level < ( max_power_level * static_cast( rules.cbm_recharge ) / 100 ); + return get_power_level() < ( get_max_power_level() * static_cast( rules.cbm_recharge ) / 100 ); } bool npc::can_use_offensive_cbm() const { - return power_level > ( max_power_level * static_cast( rules.cbm_reserve ) / 100 ); + return get_power_level() > ( get_max_power_level() * static_cast( rules.cbm_reserve ) / 100 ); } bool npc::consume_cbm_items( const std::function &filter ) @@ -1656,7 +1656,7 @@ bool npc::recharge_cbm() { // non-allied NPCs don't consume resources to recharge if( !is_player_ally() ) { - charge_power( max_power_level ); + mod_power_level( get_max_power_level() ); return true; } diff --git a/src/panels.cpp b/src/panels.cpp index 96c9603ee5435..3f813eed5b026 100644 --- a/src/panels.cpp +++ b/src/panels.cpp @@ -779,19 +779,19 @@ static std::pair power_stat( const avatar &u ) { nc_color c_pwr = c_red; std::string s_pwr; - if( u.max_power_level == 0_kJ ) { + if( !u.has_max_power() ) { s_pwr = "--"; c_pwr = c_light_gray; } else { - if( u.power_level >= u.max_power_level / 2 ) { + if( u.get_power_level() >= u.get_max_power_level() / 2 ) { c_pwr = c_light_blue; - } else if( u.power_level >= u.max_power_level / 3 ) { + } else if( u.get_power_level() >= u.get_max_power_level() / 3 ) { c_pwr = c_yellow; - } else if( u.power_level >= u.max_power_level / 4 ) { + } else if( u.get_power_level() >= u.get_max_power_level() / 4 ) { c_pwr = c_red; } - s_pwr = to_string( units::to_kilojoule( u.power_level ) ) + pgettext( "energy unit: kilojoule", - "kJ" ); + s_pwr = to_string( units::to_kilojoule( u.get_power_level() ) ) + + pgettext( "energy unit: kilojoule", "kJ" ); } return std::make_pair( c_pwr, s_pwr ); } diff --git a/src/player.cpp b/src/player.cpp index 347b55eb86cb1..78f0a9ea02c01 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -480,8 +480,8 @@ player::player() : per_max = 8; dodges_left = 1; blocks_left = 1; - power_level = 0_kJ; - max_power_level = 0_kJ; + set_power_level( 0_kJ ); + set_max_power_level( 0_kJ ); stamina = 10000; //Temporary value for stamina. It will be reset later from external json option. stim = 0; pkill = 0; @@ -584,14 +584,14 @@ void player::process_turn() // Didn't just pick something up last_item = itype_id( "null" ); - if( has_active_bionic( bio_metabolics ) && power_level < max_power_level && + if( has_active_bionic( bio_metabolics ) && !is_max_power() && 0.8f < get_kcal_percent() && calendar::once_every( 3_turns ) ) { // Efficiency is approximately 25%, power output is ~60W mod_stored_kcal( -1 ); - charge_power( 1_kJ ); + mod_power_level( 1_kJ ); } if( has_trait( trait_DEBUG_BIONIC_POWER ) ) { - charge_power( max_power_level ); + mod_power_level( get_max_power_level() ); } visit_items( [this]( item * e ) { @@ -2133,11 +2133,6 @@ bool player::has_active_optcloak() const return false; } -void player::charge_power( units::energy amount ) -{ - power_level = clamp( power_level + amount, 0_kJ, max_power_level ); -} - /* * Calculate player brightness based on the brightest active item, as * per itype tag LIGHT_* and optional CHARGEDIM ( fade starting at 20% charge ) @@ -2709,7 +2704,7 @@ void player::on_hit( Creature *source, body_part bp_hit, } bool u_see = g->u.sees( *this ); - if( has_active_bionic( bionic_id( "bio_ods" ) ) && power_level > 5_kJ ) { + if( has_active_bionic( bionic_id( "bio_ods" ) ) && get_power_level() > 5_kJ ) { if( is_player() ) { add_msg( m_good, _( "Your offensive defense system shocks %s in mid-attack!" ), source->disp_name() ); @@ -2719,7 +2714,7 @@ void player::on_hit( Creature *source, body_part bp_hit, source->disp_name() ); } int shock = rng( 1, 4 ); - charge_power( units::from_kilojoule( -shock ) ); + mod_power_level( units::from_kilojoule( -shock ) ); damage_instance ods_shock_damage; ods_shock_damage.add_damage( DT_ELECTRIC, shock * 5 ); // Should hit body part used for attack @@ -4130,7 +4125,7 @@ void player::update_needs( int rate_multiplier ) if( g->is_in_sunlight( pos() ) ) { if( has_bionic( bn_bio_solar ) ) { - charge_power( units::from_kilojoule( rate_multiplier * 25 ) ); + mod_power_level( units::from_kilojoule( rate_multiplier * 25 ) ); } } @@ -4240,8 +4235,8 @@ void player::update_stamina( int turns ) } const int max_stam = get_stamina_max(); - if( power_level >= 3_kJ && has_active_bionic( bio_gills ) ) { - int bonus = std::min( units::to_kilojoule( power_level ) / 3, + if( get_power_level() >= 3_kJ && has_active_bionic( bio_gills ) ) { + int bonus = std::min( units::to_kilojoule( get_power_level() ) / 3, max_stam - stamina - stamina_recovery * turns ); // so the effective recovery is up to 5x default bonus = std::min( bonus, 4 * static_cast @@ -4250,7 +4245,7 @@ void player::update_stamina( int turns ) stamina_recovery += bonus; bonus /= 10; bonus = std::max( bonus, 1 ); - charge_power( units::from_kilojoule( -bonus ) ); + mod_power_level( units::from_kilojoule( -bonus ) ); } } @@ -4818,9 +4813,9 @@ void player::suffer() oxygen += 12; } if( oxygen <= 5 ) { - if( has_bionic( bio_gills ) && power_level >= 25_kJ ) { + if( has_bionic( bio_gills ) && get_power_level() >= 25_kJ ) { oxygen += 5; - charge_power( -25_kJ ); + mod_power_level( -25_kJ ); } else { add_msg_if_player( m_bad, _( "You're drowning!" ) ); apply_damage( nullptr, bp_torso, rng( 1, 4 ) ); @@ -5195,7 +5190,7 @@ void player::suffer() ( has_effect( effect_sleep ) ? 10 : 1 ) ) ) { bool auto_use = has_charges( "inhaler", 1 ) || has_charges( "oxygen_tank", 1 ) || has_charges( "smoxygen_tank", 1 ); - bool oxygenator = has_bionic( bio_gills ) && power_level >= 3_kJ; + bool oxygenator = has_bionic( bio_gills ) && get_power_level() >= 3_kJ; if( underwater ) { oxygen = oxygen / 2; auto_use = false; @@ -5213,7 +5208,7 @@ void player::suffer() map_inv.has_charges( "smoxygen_tank", 1 ); // check if character has an oxygenator first if( oxygenator ) { - charge_power( -3_kJ ); + mod_power_level( -3_kJ ); add_msg_if_player( m_info, _( "You use your Oxygenator to clear it up, " "then go back to sleep." ) ); } else if( auto_use ) { @@ -5694,10 +5689,10 @@ void player::suffer() apply_damage( nullptr, bp_torso, 1 ); mod_pain( 1 ); add_msg_if_player( m_bad, _( "Your chest burns as your power systems overload!" ) ); - charge_power( 50_kJ ); + mod_power_level( 50_kJ ); power_gen -= 60; // ten units of power lost due to short-circuiting into you } - charge_power( units::from_kilojoule( power_gen ) ); + mod_power_level( units::from_kilojoule( power_gen ) ); } } else { slow_rad += ( ( ( reactor_plut * 0.4 ) + ( tank_plut * 0.4 ) ) * 100 ); @@ -5712,12 +5707,12 @@ void player::suffer() } // Negative bionics effects - if( has_bionic( bio_dis_shock ) && power_level > 9_kJ && one_turn_in( 2_hours ) && + if( has_bionic( bio_dis_shock ) && get_power_level() > 9_kJ && one_turn_in( 2_hours ) && !has_effect( effect_narcosis ) ) { add_msg_if_player( m_bad, _( "You suffer a painful electrical discharge!" ) ); mod_pain( 1 ); moves -= 150; - charge_power( -10_kJ ); + mod_power_level( -10_kJ ); if( weapon.typeId() == "e_handcuffs" && weapon.charges > 0 ) { weapon.charges -= rng( 1, 3 ) * 50; @@ -5736,9 +5731,9 @@ void player::suffer() sfx::play_variant_sound( "bionics", "acid_discharge", 100 ); sfx::do_player_death_hurt( g->u, false ); } - if( has_bionic( bio_drain ) && power_level > 24_kJ && one_turn_in( 1_hours ) ) { + if( has_bionic( bio_drain ) && get_power_level() > 24_kJ && one_turn_in( 1_hours ) ) { add_msg_if_player( m_bad, _( "Your batteries discharge slightly." ) ); - charge_power( -25_kJ ); + mod_power_level( -25_kJ ); sfx::play_variant_sound( "bionics", "elec_crackle_low", 100 ); } if( has_bionic( bio_noise ) && one_turn_in( 50_minutes ) && @@ -5753,8 +5748,8 @@ void player::suffer() } sounds::sound( pos(), 60, sounds::sound_t::movement, _( "Crackle!" ) ); //sfx above } - if( has_bionic( bio_power_weakness ) && max_power_level > 0_kJ && - power_level >= max_power_level * .75 ) { + if( has_bionic( bio_power_weakness ) && has_max_power() && + get_power_level() >= get_max_power_level() * .75 ) { mod_str_bonus( -3 ); } if( has_bionic( bio_trip ) && one_turn_in( 50_minutes ) && @@ -5773,9 +5768,9 @@ void player::suffer() add_effect( effect_downed, 1_turns, num_bp, false, 0, true ); sfx::play_variant_sound( "bionics", "elec_crackle_high", 100 ); } - if( has_bionic( bio_shakes ) && power_level > 24_kJ && one_turn_in( 2_hours ) ) { + if( has_bionic( bio_shakes ) && get_power_level() > 24_kJ && one_turn_in( 2_hours ) ) { add_msg_if_player( m_bad, _( "Your bionics short-circuit, causing you to tremble and shiver." ) ); - charge_power( -25_kJ ); + mod_power_level( -25_kJ ); add_effect( effect_shakes, 5_minutes ); sfx::play_variant_sound( "bionics", "elec_crackle_med", 100 ); } @@ -5792,10 +5787,10 @@ void player::suffer() add_effect( effect_formication, 10_minutes, bp ); } if( has_bionic( bio_glowy ) && !has_effect( effect_glowy_led ) && one_turn_in( 50_minutes ) && - power_level > 1_kJ ) { + get_power_level() > 1_kJ ) { add_msg_if_player( m_bad, _( "Your malfunctioning bionic starts to glow!" ) ); add_effect( effect_glowy_led, 5_minutes ); - charge_power( -1_kJ ); + mod_power_level( -1_kJ ); } // Artifact effects @@ -6533,7 +6528,7 @@ void player::process_active_items() } } if( has_active_bionic( bionic_id( "bio_ups" ) ) ) { - ch_UPS += units::to_kilojoule( power_level ); + ch_UPS += units::to_kilojoule( get_power_level() ); } int ch_UPS_used = 0; if( cloak != nullptr ) { @@ -6558,7 +6553,7 @@ void player::process_active_items() // For powered armor, an armor-powering bionic should always be preferred over UPS usage. if( power_armor != nullptr ) { const int power_cost = 4; - bool bio_powered = can_interface_armor() && power_level > 0_kJ; + bool bio_powered = can_interface_armor() && has_power(); // Bionic power costs are handled elsewhere. if( !bio_powered ) { if( ch_UPS >= power_cost ) { @@ -6729,11 +6724,11 @@ bool player::has_fire( const int quantity ) const return true; } } - } else if( has_active_bionic( bio_tools ) && power_level > quantity * 5_kJ ) { + } else if( has_active_bionic( bio_tools ) && get_power_level() > quantity * 5_kJ ) { return true; - } else if( has_bionic( bio_lighter ) && power_level > quantity * 5_kJ ) { + } else if( has_bionic( bio_lighter ) && get_power_level() > quantity * 5_kJ ) { return true; - } else if( has_bionic( bio_laser ) && power_level > quantity * 5_kJ ) { + } else if( has_bionic( bio_laser ) && get_power_level() > quantity * 5_kJ ) { return true; } else if( is_npc() ) { // A hack to make NPCs use their Molotovs @@ -6763,14 +6758,14 @@ void player::use_fire( const int quantity ) return; } } - } else if( has_active_bionic( bio_tools ) && power_level > quantity * 5_kJ ) { - charge_power( -quantity * 5_kJ ); + } else if( has_active_bionic( bio_tools ) && get_power_level() > quantity * 5_kJ ) { + mod_power_level( -quantity * 5_kJ ); return; - } else if( has_bionic( bio_lighter ) && power_level > quantity * 5_kJ ) { - charge_power( -quantity * 5_kJ ); + } else if( has_bionic( bio_lighter ) && get_power_level() > quantity * 5_kJ ) { + mod_power_level( -quantity * 5_kJ ); return; - } else if( has_bionic( bio_laser ) && power_level > quantity * 5_kJ ) { - charge_power( -quantity * 5_kJ ); + } else if( has_bionic( bio_laser ) && get_power_level() > quantity * 5_kJ ) { + mod_power_level( -quantity * 5_kJ ); return; } } @@ -6784,7 +6779,7 @@ std::list player::use_charges( const itype_id &what, int qty, return res; } else if( what == "toolset" ) { - charge_power( units::from_kilojoule( -qty ) ); + mod_power_level( units::from_kilojoule( -qty ) ); return res; } else if( what == "fire" ) { @@ -6800,9 +6795,9 @@ std::list player::use_charges( const itype_id &what, int qty, qty -= std::min( qty, power_drain ); return res; } - if( power_level > 0_kJ && has_active_bionic( bio_ups ) ) { - int bio = std::min( units::to_kilojoule( power_level ), qty ); - charge_power( units::from_kilojoule( -bio ) ); + if( has_power() && has_active_bionic( bio_ups ) ) { + int bio = std::min( units::to_kilojoule( get_power_level() ), qty ); + mod_power_level( units::from_kilojoule( -bio ) ); qty -= std::min( qty, bio ); } @@ -9381,8 +9376,8 @@ void player::try_to_sleep( const time_duration &dur ) } add_msg_if_player( _( "You start trying to fall asleep." ) ); if( has_active_bionic( bio_soporific ) ) { - bio_soporific_powered_at_last_sleep_check = power_level > 0_kJ; - if( power_level > 0_kJ ) { + bio_soporific_powered_at_last_sleep_check = has_power(); + if( bio_soporific_powered_at_last_sleep_check ) { // The actual bonus is applied in sleep_spot( p ). add_msg_if_player( m_good, _( "Your soporific inducer starts working its magic." ) ); } else { @@ -9591,12 +9586,12 @@ bool player::can_sleep() bool result = sleepy > 0; if( has_active_bionic( bio_soporific ) ) { - if( bio_soporific_powered_at_last_sleep_check && power_level == 0_kJ ) { + if( bio_soporific_powered_at_last_sleep_check && !has_power() ) { add_msg_if_player( m_bad, _( "Your soporific inducer runs out of power!" ) ); - } else if( !bio_soporific_powered_at_last_sleep_check && power_level > 0_kJ ) { + } else if( !bio_soporific_powered_at_last_sleep_check && has_power() ) { add_msg_if_player( m_good, _( "Your soporific inducer starts back up." ) ); } - bio_soporific_powered_at_last_sleep_check = power_level > 0_kJ; + bio_soporific_powered_at_last_sleep_check = has_power(); } return result; @@ -10067,7 +10062,7 @@ void player::absorb_hit( body_part bp, damage_instance &dam ) // The bio_ads CBM absorbs damage before hitting armor if( has_active_bionic( bio_ads ) ) { - if( elem.amount > 0 && power_level > 24_kJ ) { + if( elem.amount > 0 && get_power_level() > 24_kJ ) { if( elem.type == DT_BASH ) { elem.amount -= rng( 1, 8 ); } else if( elem.type == DT_CUT ) { @@ -10075,7 +10070,7 @@ void player::absorb_hit( body_part bp, damage_instance &dam ) } else if( elem.type == DT_STAB ) { elem.amount -= rng( 1, 2 ); } - charge_power( -25_kJ ); + mod_power_level( -25_kJ ); } if( elem.amount < 0 ) { elem.amount = 0; @@ -10674,11 +10669,11 @@ bool player::uncanny_dodge() { bool is_u = this == &g->u; bool seen = g->u.sees( *this ); - if( this->power_level < 74_kJ || !this->has_active_bionic( bio_uncanny_dodge ) ) { + if( this->get_power_level() < 74_kJ || !this->has_active_bionic( bio_uncanny_dodge ) ) { return false; } tripoint adjacent = adjacent_tile(); - charge_power( -75_kJ ); + mod_power_level( -75_kJ ); if( adjacent.x != posx() || adjacent.y != posy() ) { position.x = adjacent.x; position.y = adjacent.y; @@ -11850,12 +11845,12 @@ void player::do_skill_rust() continue; } - const bool charged_bio_mem = power_level > 25_kJ && has_active_bionic( bio_memory ); + const bool charged_bio_mem = get_power_level() > 25_kJ && has_active_bionic( bio_memory ); const int oldSkillLevel = skill_level_obj.level(); if( skill_level_obj.rust( charged_bio_mem ) ) { add_msg_if_player( m_warning, _( "Your knowledge of %s begins to fade, but your memory banks retain it!" ), aSkill.name() ); - charge_power( -25_kJ ); + mod_power_level( -25_kJ ); } const int newSkill = skill_level_obj.level(); if( newSkill < oldSkillLevel ) { diff --git a/src/player.h b/src/player.h index d8198bc3bccf0..d77989d71063c 100644 --- a/src/player.h +++ b/src/player.h @@ -360,8 +360,6 @@ class player : public Character float adjusted_skill ); /**Has enough anesthetic for surgery*/ bool has_enough_anesth( const itype *cbm, player &patient ); - /** Adds the entered amount to the player's bionic power_level */ - void charge_power( units::energy amount ); /** Generates and handles the UI for player interaction with installed bionics */ void power_bionics(); void power_mutations(); diff --git a/src/player_display.cpp b/src/player_display.cpp index 0924ba48c80e0..f930ddfddd85c 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -514,7 +514,7 @@ static void draw_bionics_tab( const catacurses::window &w_bionics, const catacur // NOLINTNEXTLINE(cata-use-named-point-constants) trim_and_print( w_bionics, point( 1, 1 ), getmaxx( w_bionics ) - 1, c_white, string_format( _( "Bionic Power: %1$d / %2$d" ), - units::to_kilojoule( you.power_level ), units::to_kilojoule( you.max_power_level ) ) ); + units::to_kilojoule( you.get_power_level() ), units::to_kilojoule( you.get_max_power_level() ) ) ); const size_t useful_y = bionics_win_size_y - 1; const size_t half_y = useful_y / 2; @@ -561,7 +561,7 @@ static void draw_bionics_tab( const catacurses::window &w_bionics, const catacur // NOLINTNEXTLINE(cata-use-named-point-constants) trim_and_print( w_bionics, point( 1, 1 ), getmaxx( w_bionics ) - 1, c_white, string_format( _( "Bionic Power: %1$d / %2$d" ), - units::to_kilojoule( you.power_level ), units::to_kilojoule( you.max_power_level ) ) ); + units::to_kilojoule( you.get_power_level() ), units::to_kilojoule( you.get_max_power_level() ) ) ); for( size_t i = 0; i < bionicslist.size() && i < bionics_win_size_y - 1; i++ ) { mvwprintz( w_bionics, point( 1, static_cast( i + 2 ) ), c_black, " " ); trim_and_print( w_bionics, point( 1, static_cast( i + 2 ) ), getmaxx( w_bionics ) - 1, @@ -981,7 +981,7 @@ static void draw_initial_windows( const catacurses::window &w_stats, // NOLINTNEXTLINE(cata-use-named-point-constants) trim_and_print( w_bionics, point( 1, 1 ), getmaxx( w_bionics ) - 1, c_white, string_format( _( "Bionic Power: %1$d / %2$d" ), - units::to_kilojoule( you.power_level ), units::to_kilojoule( you.max_power_level ) ) ); + units::to_kilojoule( you.get_power_level() ), units::to_kilojoule( you.get_max_power_level() ) ) ); for( size_t i = 0; i < bionicslist.size() && i < bionics_win_size_y - 1; i++ ) { trim_and_print( w_bionics, point( 1, static_cast( i ) + 2 ), getmaxx( w_bionics ) - 1, c_white, "%s", bionicslist[i].info().name ); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index a1de4452546e1..a918d156a2903 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -4270,31 +4270,31 @@ void vehicle::consume_fuel( int load, const int t_seconds, bool skip_electric ) const item muscle( "muscle" ); if( g->u.has_active_bionic( bionic_id( "bio_torsionratchet" ) ) ) { if( one_in( 1000 / load ) ) { // more pedaling = more power - g->u.charge_power( 1_kJ ); + g->u.mod_power_level( 1_kJ ); } mod += eff_load / 5; } if( g->u.has_bionic( bionic_id( "bio_torsionratchet" ) ) ) { if( one_in( 1000 / load ) && one_in( 20 ) ) { // intentional double chance check - g->u.charge_power( 1_kJ ); + g->u.mod_power_level( 1_kJ ); } mod += eff_load / 10; } for( const bionic_id &bid : g->u.get_bionic_fueled_with( muscle ) ) { if( g->u.has_active_bionic( bid ) ) { if( one_in( 1000 / load ) ) { // more pedaling = more power - g->u.charge_power( units::from_kilojoule( muscle.fuel_energy() ) * bid->fuel_efficiency ); + g->u.mod_power_level( units::from_kilojoule( muscle.fuel_energy() ) * bid->fuel_efficiency ); } mod += eff_load / 5; } if( one_in( 1000 / load ) && one_in( 20 ) ) { // intentional double chance check - g->u.charge_power( units::from_kilojoule( muscle.fuel_energy() ) * bid->fuel_efficiency ); + g->u.mod_power_level( units::from_kilojoule( muscle.fuel_energy() ) * bid->fuel_efficiency ); } mod += eff_load / 10; } // decreased stamina burn scalable with load if( g->u.has_active_bionic( bionic_id( "bio_jointservo" ) ) ) { - g->u.charge_power( units::from_kilojoule( -std::max( eff_load / 20, 1 ) ) ); + g->u.mod_power_level( units::from_kilojoule( -std::max( eff_load / 20, 1 ) ) ); mod -= std::max( eff_load / 5, 5 ); } if( one_in( 1000 / load ) && one_in( 10 ) ) { diff --git a/src/visitable.cpp b/src/visitable.cpp index 359b6c04d0c82..5fb00b3950f61 100644 --- a/src/visitable.cpp +++ b/src/visitable.cpp @@ -847,7 +847,7 @@ int visitable::charges_of( const std::string &what, int limit, if( what == "toolset" ) { if( p && p->has_active_bionic( bionic_id( "bio_tools" ) ) ) { - return std::min( units::to_kilojoule( p->power_level ), limit ); + return std::min( units::to_kilojoule( p->get_power_level() ), limit ); } else { return 0; } @@ -858,7 +858,7 @@ int visitable::charges_of( const std::string &what, int limit, qty = sum_no_wrap( qty, charges_of( "UPS_off" ) ); qty = sum_no_wrap( qty, static_cast( charges_of( "adv_UPS_off" ) / 0.6 ) ); if( p && p->has_active_bionic( bionic_id( "bio_ups" ) ) ) { - qty = sum_no_wrap( qty, units::to_kilojoule( p->power_level ) ); + qty = sum_no_wrap( qty, units::to_kilojoule( p->get_power_level() ) ); } if( p && p->is_mounted() ) { auto mons = p->mounted_creature.get(); diff --git a/tests/bionics_test.cpp b/tests/bionics_test.cpp index 8547792992c33..7db31df6a0710 100644 --- a/tests/bionics_test.cpp +++ b/tests/bionics_test.cpp @@ -19,8 +19,8 @@ static void clear_bionics( player &p ) { p.my_bionics->clear(); - p.power_level = 0_kJ; - p.max_power_level = 0_kJ; + p.set_power_level( 0_kJ ); + p.set_max_power_level( 0_kJ ); } static void give_and_activate( player &p, bionic_id const &bioid ) @@ -93,13 +93,13 @@ TEST_CASE( "bionics", "[bionics] [item]" ) // Could be a SECTION, but prerequisite for many tests. INFO( "no power capacity at first" ); - CHECK( dummy.max_power_level == 0_kJ ); + CHECK( !dummy.has_max_power() ); dummy.add_bionic( bionic_id( "bio_power_storage" ) ); INFO( "adding Power Storage CBM only increases capacity" ); - CHECK( dummy.power_level == 0_kJ ); - REQUIRE( dummy.max_power_level > 0_kJ ); + CHECK( !dummy.has_power() ); + REQUIRE( dummy.has_max_power() ); SECTION( "bio_advreactor" ) { give_and_activate( dummy, bionic_id( "bio_advreactor" ) ); diff --git a/tests/mondefense_test.cpp b/tests/mondefense_test.cpp index a1c38873ae948..f680cbc161008 100644 --- a/tests/mondefense_test.cpp +++ b/tests/mondefense_test.cpp @@ -91,7 +91,7 @@ TEST_CASE( "zapback_npc_electricity_immune", "[mondefense]" ) standard_npc attacker( "Attacker" ); attacker.add_bionic( bionic_id( "bio_power_storage" ) ); attacker.add_bionic( bionic_id( "bio_faraday" ) ); - attacker.charge_power( 100_kJ ); + attacker.mod_power_level( 100_kJ ); // Don't forget to turn it on... test_zapback( attacker, true ); // Wow this is a raw index? From 1d5a82ba720c3d185606a3733b7f3a2c452e14b0 Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Tue, 8 Oct 2019 11:46:01 +0300 Subject: [PATCH 11/21] Obsolete tool_rdx_sand_bomb --- data/json/recipes/recipe_obsolete.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/data/json/recipes/recipe_obsolete.json b/data/json/recipes/recipe_obsolete.json index 441f6535a4eda..de953a60b4a99 100644 --- a/data/json/recipes/recipe_obsolete.json +++ b/data/json/recipes/recipe_obsolete.json @@ -1900,5 +1900,10 @@ "type": "recipe", "result": "tanned_hide_scraped", "obsolete": true + }, + { + "type": "recipe", + "result": "tool_rdx_sand_bomb", + "obsolete": true } ] From d0ef0624180c70ba01dbd7fa2d5ac53558001930 Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Tue, 8 Oct 2019 11:46:38 +0300 Subject: [PATCH 12/21] Obsolete tool_black_powder_bomb --- data/json/itemgroups/item_groups.json | 3 +- data/json/items/migration.json | 5 +++ data/json/items/obsolete.json | 54 ++++++++++++++++++++++++++ data/json/items/tools.json | 54 -------------------------- data/json/recipes/recipe_obsolete.json | 5 +++ 5 files changed, 65 insertions(+), 56 deletions(-) diff --git a/data/json/itemgroups/item_groups.json b/data/json/itemgroups/item_groups.json index ab67455c1c51d..79fd7dff151cb 100644 --- a/data/json/itemgroups/item_groups.json +++ b/data/json/itemgroups/item_groups.json @@ -5860,8 +5860,7 @@ [ "smokebomb", 50 ], [ "dynamite", 50 ], [ "mininuke", 5 ], - [ "c4", 50 ], - [ "tool_black_powder_bomb", 10 ] + [ "c4", 50 ] ] }, { diff --git a/data/json/items/migration.json b/data/json/items/migration.json index 5391d3162a283..28d45850b2ddf 100644 --- a/data/json/items/migration.json +++ b/data/json/items/migration.json @@ -708,5 +708,10 @@ "id": "magbandolier", "type": "MIGRATION", "replace": "chestrig" + }, + { + "id": "tool_black_powder_bomb", + "type": "MIGRATION", + "replace": "can_bomb" } ] diff --git a/data/json/items/obsolete.json b/data/json/items/obsolete.json index 0c8e69db085dc..c00d4be2ca425 100644 --- a/data/json/items/obsolete.json +++ b/data/json/items/obsolete.json @@ -598,5 +598,59 @@ "explosion": { "power": 120 } }, "flags": [ "TRADER_AVOID" ] + }, + { + "id": "tool_black_powder_bomb", + "type": "TOOL", + "category": "weapons", + "name": "black gunpowder bomb", + "description": "This is a tin can filled to the brim with black gunpowder and with a bit of fuse sticking out of it.", + "//": "40g of tin can and 250ml/412g of gunpowder", + "weight": "452 g", + "volume": "250 ml", + "price": 2500, + "to_hit": -2, + "material": [ "steel", "plastic" ], + "symbol": "*", + "color": "red", + "explode_in_fire": true, + "explosion": { "power": 88, "shrapnel": { "casing_mass": 3, "fragment_mass": 0.12 } }, + "use_action": { + "target": "tool_black_powder_bomb_act", + "msg": "You light the fuse on the black gunpowder bomb. Throw it before it blows in your face!", + "target_charges": 3, + "active": true, + "need_fire": 1, + "menu_text": "Light fuse", + "type": "transform" + }, + "flags": [ "RADIO_MODABLE", "RADIO_INVOKE_PROC", "BOMB" ] + }, + { + "id": "tool_black_powder_bomb_act", + "type": "TOOL", + "category": "weapons", + "name": "active black gunpowder bomb", + "description": "This is a tin can filled to the brim with black gunpowder and with a lit fuse stuck inside of it.", + "weight": "452 g", + "volume": "500 ml", + "price": 0, + "to_hit": -2, + "material": [ "steel", "plastic" ], + "symbol": "*", + "color": "light_red", + "initial_charges": 3, + "max_charges": 3, + "turns_per_charge": 1, + "explode_in_fire": true, + "explosion": { "power": 88, "shrapnel": { "casing_mass": 3, "fragment_mass": 0.12 } }, + "use_action": { + "type": "explosion", + "sound_volume": 0, + "sound_msg": "Kshhh.", + "no_deactivate_msg": "You've already lit the fuse - throw it!", + "explosion": { "power": 88, "shrapnel": { "casing_mass": 3, "fragment_mass": 0.12 } } + }, + "flags": [ "BOMB", "TRADER_AVOID" ] } ] diff --git a/data/json/items/tools.json b/data/json/items/tools.json index ef64b430b7d2a..973ae56cb263f 100644 --- a/data/json/items/tools.json +++ b/data/json/items/tools.json @@ -6064,60 +6064,6 @@ }, "flags": [ "BOMB", "TRADER_AVOID" ] }, - { - "id": "tool_black_powder_bomb", - "type": "TOOL", - "category": "weapons", - "name": "black gunpowder bomb", - "description": "This is a tin can filled to the brim with black gunpowder and with a bit of fuse sticking out of it.", - "//": "40g of tin can and 250ml/412g of gunpowder", - "weight": "452 g", - "volume": "250 ml", - "price": 2500, - "to_hit": -2, - "material": [ "steel", "plastic" ], - "symbol": "*", - "color": "red", - "explode_in_fire": true, - "explosion": { "power": 88, "shrapnel": { "casing_mass": 3, "fragment_mass": 0.12 } }, - "use_action": { - "target": "tool_black_powder_bomb_act", - "msg": "You light the fuse on the black gunpowder bomb. Throw it before it blows in your face!", - "target_charges": 3, - "active": true, - "need_fire": 1, - "menu_text": "Light fuse", - "type": "transform" - }, - "flags": [ "RADIO_MODABLE", "RADIO_INVOKE_PROC", "BOMB" ] - }, - { - "id": "tool_black_powder_bomb_act", - "type": "TOOL", - "category": "weapons", - "name": "active black gunpowder bomb", - "description": "This is a tin can filled to the brim with black gunpowder and with a lit fuse stuck inside of it.", - "weight": "452 g", - "volume": "500 ml", - "price": 0, - "to_hit": -2, - "material": [ "steel", "plastic" ], - "symbol": "*", - "color": "light_red", - "initial_charges": 3, - "max_charges": 3, - "turns_per_charge": 1, - "explode_in_fire": true, - "explosion": { "power": 88, "shrapnel": { "casing_mass": 3, "fragment_mass": 0.12 } }, - "use_action": { - "type": "explosion", - "sound_volume": 0, - "sound_msg": "Kshhh.", - "no_deactivate_msg": "You've already lit the fuse - throw it!", - "explosion": { "power": 88, "shrapnel": { "casing_mass": 3, "fragment_mass": 0.12 } } - }, - "flags": [ "BOMB", "TRADER_AVOID" ] - }, { "id": "tool_black_powder_charge", "type": "TOOL", diff --git a/data/json/recipes/recipe_obsolete.json b/data/json/recipes/recipe_obsolete.json index de953a60b4a99..a3cb978f3ee13 100644 --- a/data/json/recipes/recipe_obsolete.json +++ b/data/json/recipes/recipe_obsolete.json @@ -1901,6 +1901,11 @@ "result": "tanned_hide_scraped", "obsolete": true }, + { + "type": "recipe", + "result": "tool_black_powder_bomb", + "obsolete": true + }, { "type": "recipe", "result": "tool_rdx_sand_bomb", From dd0d6eba74573e02f36089ca45f1a7fc3b44c5b9 Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Tue, 8 Oct 2019 11:47:06 +0300 Subject: [PATCH 13/21] Obsolete matchbomb --- data/json/monsterdrops/zombie_survivor.json | 2 +- data/json/npcs/NC_ARSONIST.json | 3 +-- data/json/npcs/NC_JUNK_SHOPKEEP.json | 1 - data/json/npcs/items_generic.json | 1 - .../surface_staff/NPC_free_merchant_shopkeep.json | 1 - data/json/recipes/recipe_obsolete.json | 5 +++++ data/mods/blazemod/blaze_ammo_recipes.json | 3 +-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/data/json/monsterdrops/zombie_survivor.json b/data/json/monsterdrops/zombie_survivor.json index 9bc28a90c4ae8..37c9277360dae 100644 --- a/data/json/monsterdrops/zombie_survivor.json +++ b/data/json/monsterdrops/zombie_survivor.json @@ -64,7 +64,7 @@ { "id": "survivor_grenades", "type": "item_group", - "items": [ [ "gasbomb_makeshift", 30 ], [ "matchbomb", 50 ], [ "molotov", 100 ], [ "nail_bomb", 100 ], [ "pipebomb", 30 ] ] + "items": [ [ "gasbomb_makeshift", 30 ], [ "molotov", 100 ], [ "nail_bomb", 100 ], [ "pipebomb", 30 ], [ "can_bomb", 30 ] ] }, { "id": "survivor_stabbing", diff --git a/data/json/npcs/NC_ARSONIST.json b/data/json/npcs/NC_ARSONIST.json index a54eabcf098d6..b23a2803707b3 100644 --- a/data/json/npcs/NC_ARSONIST.json +++ b/data/json/npcs/NC_ARSONIST.json @@ -165,8 +165,7 @@ [ "firecracker_pack", 50 ], [ "firecracker", 30 ], [ "dynamite", 50 ], - [ "rebar", 100 ], - [ "matchbomb", 50 ] + [ "rebar", 100 ] ] } ] diff --git a/data/json/npcs/NC_JUNK_SHOPKEEP.json b/data/json/npcs/NC_JUNK_SHOPKEEP.json index fc14afa5a7f06..1b8d90406d71a 100644 --- a/data/json/npcs/NC_JUNK_SHOPKEEP.json +++ b/data/json/npcs/NC_JUNK_SHOPKEEP.json @@ -134,7 +134,6 @@ [ "shotgun_d", 5 ], [ "pipebomb", 10 ], [ "molotov", 10 ], - [ "matchbomb", 10 ], [ "longbow", 5 ], [ "compositebow", 15 ], [ "shortbow", 10 ], diff --git a/data/json/npcs/items_generic.json b/data/json/npcs/items_generic.json index 7d6d3bf846c1c..7b45a0aa7fb37 100644 --- a/data/json/npcs/items_generic.json +++ b/data/json/npcs/items_generic.json @@ -768,7 +768,6 @@ [ "mask_bal", 1 ], [ "mask_dust", 4 ], [ "mask_filter", 1 ], - [ "matchbomb", 2 ], [ "maltballs", 1 ], [ "maple_candy", 2 ], [ "marshmallow", 2 ], diff --git a/data/json/npcs/refugee_center/surface_staff/NPC_free_merchant_shopkeep.json b/data/json/npcs/refugee_center/surface_staff/NPC_free_merchant_shopkeep.json index 7e2bfd924d7b1..867e05c2bf345 100644 --- a/data/json/npcs/refugee_center/surface_staff/NPC_free_merchant_shopkeep.json +++ b/data/json/npcs/refugee_center/surface_staff/NPC_free_merchant_shopkeep.json @@ -192,7 +192,6 @@ [ "shotgun_d", 5 ], [ "pipebomb", 10 ], [ "molotov", 10 ], - [ "matchbomb", 10 ], [ "longbow", 5 ], [ "compositebow", 15 ], [ "shortbow", 10 ], diff --git a/data/json/recipes/recipe_obsolete.json b/data/json/recipes/recipe_obsolete.json index a3cb978f3ee13..42944b3d47e87 100644 --- a/data/json/recipes/recipe_obsolete.json +++ b/data/json/recipes/recipe_obsolete.json @@ -1901,6 +1901,11 @@ "result": "tanned_hide_scraped", "obsolete": true }, + { + "type": "recipe", + "result": "matchbomb", + "obsolete": true + }, { "type": "recipe", "result": "tool_black_powder_bomb", diff --git a/data/mods/blazemod/blaze_ammo_recipes.json b/data/mods/blazemod/blaze_ammo_recipes.json index 6eba06ca5247b..59ff7c9fe5a86 100644 --- a/data/mods/blazemod/blaze_ammo_recipes.json +++ b/data/mods/blazemod/blaze_ammo_recipes.json @@ -18,8 +18,7 @@ [ "diesel", 600 ], [ "chem_rdx", 1 ], [ "chem_hmtd", 2 ], - [ "chem_anfo", 5 ], - [ "matchbomb", 3 ] + [ "chem_anfo", 5 ] ], [ [ "smpistol_primer", 1 ], From 45f8b73715eee3617544f7b59c89f8255b4fe113 Mon Sep 17 00:00:00 2001 From: Alexey Mostovoy <1931904+AMurkin@users.noreply.github.com> Date: Tue, 8 Oct 2019 18:13:31 +0400 Subject: [PATCH 14/21] Some player_display.cpp code refactoring (#34559) * coldblood4 variable used once * calc print displacements * join effect name and text * Change make_pair to {} --- src/player_display.cpp | 97 +++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/src/player_display.cpp b/src/player_display.cpp index f930ddfddd85c..b9ce3881bacc1 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -34,8 +34,6 @@ static const std::string title_SKILLS = translate_marker( "SKILLS" ); static const std::string title_BIONICS = translate_marker( "BIONICS" ); static const std::string title_TRAITS = translate_marker( "TRAITS" ); -static const trait_id trait_COLDBLOOD4( "COLDBLOOD4" ); - // use this instead of having to type out 26 spaces like before static const std::string header_spaces( 26, ' ' ); @@ -577,9 +575,8 @@ static void draw_bionics_tab( const catacurses::window &w_bionics, const catacur static void draw_effects_tab( const catacurses::window &w_effects, const catacurses::window &w_info, unsigned int &line, int &curtab, input_context &ctxt, bool &done, - std::string &action, std::vector &effect_name, - const size_t effect_win_size_y, - const std::vector &effect_text ) + std::string &action, std::vector> &effect_name_and_text, + const size_t effect_win_size_y ) { mvwprintz( w_effects, point_zero, h_light_gray, header_spaces ); center_print( w_effects, 0, h_light_gray, _( title_EFFECTS ) ); @@ -589,37 +586,40 @@ static void draw_effects_tab( const catacurses::window &w_effects, const catacur size_t min = 0; size_t max = 0; + const size_t actual_size = effect_name_and_text.size(); + if( line <= half_y ) { min = 0; max = effect_win_size_y; - if( effect_name.size() < max ) { - max = effect_name.size(); + if( actual_size < max ) { + max = actual_size; } - } else if( line >= effect_name.size() - half_y ) { - min = ( effect_name.size() < effect_win_size_y ? 0 : effect_name.size() - effect_win_size_y ); - max = effect_name.size(); + } else if( line >= actual_size - half_y ) { + min = ( actual_size < effect_win_size_y ? 0 : actual_size - effect_win_size_y ); + max = actual_size; } else { min = line - half_y; max = line - half_y + effect_win_size_y; - if( effect_name.size() < max ) { - max = effect_name.size(); + if( actual_size < max ) { + max = actual_size; } } for( size_t i = min; i < max; i++ ) { trim_and_print( w_effects, point( 0, static_cast( 1 + i - min ) ), getmaxx( w_effects ) - 1, - i == line ? h_light_gray : c_light_gray, effect_name[i] ); + i == line ? h_light_gray : c_light_gray, effect_name_and_text[i].first ); } - if( line < effect_text.size() ) { + if( line < actual_size ) { // NOLINTNEXTLINE(cata-use-named-point-constants) - fold_and_print( w_info, point( 1, 0 ), FULL_SCREEN_WIDTH - 2, c_magenta, effect_text[line] ); + fold_and_print( w_info, point( 1, 0 ), FULL_SCREEN_WIDTH - 2, c_magenta, + effect_name_and_text[line].second ); } wrefresh( w_effects ); wrefresh( w_info ); action = ctxt.handle_input(); if( action == "DOWN" ) { - if( line < effect_name.size() - 1 ) { + if( line < actual_size - 1 ) { line++; } return; @@ -630,10 +630,10 @@ static void draw_effects_tab( const catacurses::window &w_effects, const catacur } else if( action == "NEXT_TAB" || action == "PREV_TAB" ) { mvwprintz( w_effects, point_zero, c_light_gray, header_spaces ); center_print( w_effects, 0, c_light_gray, _( title_EFFECTS ) ); - for( size_t i = 0; i < effect_name.size() && i < 7; i++ ) { + for( size_t i = 0; i < actual_size && i < 7; i++ ) { trim_and_print( w_effects, point( 0, static_cast( i ) + 1 ), getmaxx( w_effects ) - 1, c_light_gray, - effect_name[i] ); + effect_name_and_text[i].first ); } wrefresh( w_effects ); line = 0; @@ -921,7 +921,8 @@ static void draw_initial_windows( const catacurses::window &w_stats, const catacurses::window &w_bionics, const catacurses::window &w_effects, const catacurses::window &w_skills, const catacurses::window &w_speed, player &you, unsigned int &line, std::vector &traitslist, std::vector &bionicslist, - std::vector &effect_name, std::vector &skillslist, + std::vector> &effect_name_and_text, + std::vector &skillslist, const size_t bionics_win_size_y, const size_t effect_win_size_y, const size_t trait_win_size_y, const size_t skill_win_size_y ) { @@ -990,10 +991,10 @@ static void draw_initial_windows( const catacurses::window &w_stats, // Next, draw effects. center_print( w_effects, 0, c_light_gray, _( title_EFFECTS ) ); - for( size_t i = 0; i < effect_name.size() && i < effect_win_size_y; i++ ) { + for( size_t i = 0; i < effect_name_and_text.size() && i < effect_win_size_y; i++ ) { trim_and_print( w_effects, point( 0, static_cast( i ) + 1 ), getmaxx( w_effects ) - 1, c_light_gray, - effect_name[i] ); + effect_name_and_text[i].first ); } wrefresh( w_effects ); @@ -1048,7 +1049,7 @@ static void draw_initial_windows( const catacurses::window &w_stats, nc_color pen_color; std::string pen_sign; const auto player_local_temp = g->weather.get_temperature( you.pos() ); - if( you.has_trait( trait_COLDBLOOD4 ) && player_local_temp > 65 ) { + if( you.has_trait( trait_id( "COLDBLOOD4" ) ) && player_local_temp > 65 ) { pen_color = c_green; pen_sign = "+"; } else if( player_local_temp < 65 ) { @@ -1081,10 +1082,10 @@ static void draw_initial_windows( const catacurses::window &w_stats, int runcost = you.run_cost( 100 ); nc_color col = ( runcost <= 100 ? c_green : c_red ); - mvwprintz( w_speed, point( runcost >= 100 ? 21 : ( runcost < 10 ? 23 : 22 ), 1 ), col, + mvwprintz( w_speed, point( 21 + ( runcost >= 100 ? 0 : ( runcost < 10 ? 2 : 1 ) ), 1 ), col, "%d", runcost ); col = ( newmoves >= 100 ? c_green : c_red ); - mvwprintz( w_speed, point( newmoves >= 100 ? 21 : ( newmoves < 10 ? 23 : 22 ), 2 ), col, + mvwprintz( w_speed, point( 21 + ( newmoves >= 100 ? 0 : ( newmoves < 10 ? 2 : 1 ) ), 2 ), col, "%d", newmoves ); wrefresh( w_speed ); } @@ -1092,19 +1093,17 @@ static void draw_initial_windows( const catacurses::window &w_stats, void player::disp_info() { unsigned int line = 0; - std::vector effect_name; - std::vector effect_text; + std::vector> effect_name_and_text; for( auto &elem : *effects ) { for( auto &_effect_it : elem.second ) { const std::string tmp = _effect_it.second.disp_name(); - if( !tmp.empty() ) { - effect_name.push_back( tmp ); - effect_text.push_back( _effect_it.second.disp_desc() ); + if( tmp.empty() ) { + continue; } + effect_name_and_text.push_back( { tmp, _effect_it.second.disp_desc() } ); } } if( get_perceived_pain() > 0 ) { - effect_name.push_back( _( "Pain" ) ); const auto ppen = get_pain_penalty(); std::string pain_text; const auto add_if = [&]( const int amount, const char *const name ) { @@ -1117,20 +1116,21 @@ void player::disp_info() add_if( ppen.intelligence, _( "Intelligence -%d" ) ); add_if( ppen.perception, _( "Perception -%d" ) ); add_if( ppen.speed, _( "Speed -%d %%" ) ); - effect_text.push_back( pain_text ); + effect_name_and_text.push_back( { _( "Pain" ), pain_text } ); } const float bmi = get_bmi(); if( bmi < character_weight_category::underweight ) { + std::string starvation_name; std::stringstream starvation_text; if( bmi < character_weight_category::emaciated ) { - effect_name.push_back( _( "Severely Malnourished" ) ); + starvation_name = _( "Severely Malnourished" ); starvation_text << _( "Your body is severely weakened by starvation. You might die if you don't start eating regular meals!\n\n" ); } else { - effect_name.push_back( _( "Malnourished" ) ); + starvation_name = _( "Malnourished" ); starvation_text << _( "Your body is weakened by starvation. Only time and regular meals will help you recover.\n\n" ); } @@ -1142,36 +1142,35 @@ void player::disp_info() starvation_text << _( "Intelligence" ) << " -" << string_format( "%2.0f%%", str_penalty * 50.0f ); } - effect_text.push_back( starvation_text.str() ); + effect_name_and_text.push_back( { starvation_name, starvation_text.str() } ); } if( ( has_trait( trait_id( "TROGLO" ) ) && g->is_in_sunlight( pos() ) && g->weather.weather == WEATHER_SUNNY ) || ( has_trait( trait_id( "TROGLO2" ) ) && g->is_in_sunlight( pos() ) && g->weather.weather != WEATHER_SUNNY ) ) { - effect_name.push_back( _( "In Sunlight" ) ); - effect_text.push_back( _( "The sunlight irritates you.\n" - "Strength - 1; Dexterity - 1; Intelligence - 1; Perception - 1" ) ); + effect_name_and_text.push_back( { _( "In Sunlight" ), + _( "The sunlight irritates you.\n" + "Strength - 1; Dexterity - 1; Intelligence - 1; Perception - 1" ) } ); } else if( has_trait( trait_id( "TROGLO2" ) ) && g->is_in_sunlight( pos() ) ) { - effect_name.push_back( _( "In Sunlight" ) ); - effect_text.push_back( _( "The sunlight irritates you badly.\n" - "Strength - 2; Dexterity - 2; Intelligence - 2; Perception - 2" ) ); + effect_name_and_text.push_back( { _( "In Sunlight" ), + _( "The sunlight irritates you badly.\n" + "Strength - 2; Dexterity - 2; Intelligence - 2; Perception - 2" ) } ); } else if( has_trait( trait_id( "TROGLO3" ) ) && g->is_in_sunlight( pos() ) ) { - effect_name.push_back( _( "In Sunlight" ) ); - effect_text.push_back( _( "The sunlight irritates you terribly.\n" - "Strength - 4; Dexterity - 4; Intelligence - 4; Perception - 4" ) ); + effect_name_and_text.push_back( { _( "In Sunlight" ), + _( "The sunlight irritates you terribly.\n" + "Strength - 4; Dexterity - 4; Intelligence - 4; Perception - 4" ) } ); } for( auto &elem : addictions ) { if( elem.sated < 0_turns && elem.intensity >= MIN_ADDICTION_LEVEL ) { - effect_name.push_back( addiction_name( elem ) ); - effect_text.push_back( addiction_text( elem ) ); + effect_name_and_text.push_back( { addiction_name( elem ), addiction_text( elem ) } ); } } unsigned int maxy = static_cast( TERMY ); - unsigned int effect_win_size_y = 1 + static_cast( effect_name.size() ); + unsigned int effect_win_size_y = 1 + static_cast( effect_name_and_text.size() ); std::vector traitslist = get_mutations( false ); unsigned int trait_win_size_y = 1 + static_cast( traitslist.size() ); @@ -1316,8 +1315,8 @@ void player::disp_info() wrefresh( w_tip ); draw_initial_windows( w_stats, w_encumb, w_traits, w_bionics, w_effects, w_skills, w_speed, *this, - line, traitslist, bionicslist, effect_name, skillslist, bionics_win_size_y, effect_win_size_y, - trait_win_size_y, skill_win_size_y ); + line, traitslist, bionicslist, effect_name_and_text, skillslist, bionics_win_size_y, + effect_win_size_y, trait_win_size_y, skill_win_size_y ); std::map speed_effects; for( auto &elem : *effects ) { @@ -1371,7 +1370,7 @@ void player::disp_info() case 6: // Effects tab draw_effects_tab( w_effects, w_info, line, curtab, ctxt, done, action, - effect_name, effect_win_size_y, effect_text ); + effect_name_and_text, effect_win_size_y ); break; case 3: // Skills tab From 762b7a1064b320a2dce878409ab9437e84e3602d Mon Sep 17 00:00:00 2001 From: Anton Burmistrov Date: Tue, 8 Oct 2019 17:13:53 +0300 Subject: [PATCH 15/21] Look Around window with or without minimap (#34558) * Added ability to toggle minimap on and off in Look Around Window with corresponding increase/decrease of LA window height * Added Toggle Minimap keybinding to Look Around window Also renamed Toggle Pixel Minimap to Toggle Minimap for brevity --- data/raw/keybindings.json | 3 +-- src/game.cpp | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/data/raw/keybindings.json b/data/raw/keybindings.json index 0ae679e109b35..bd3fc53ba4a80 100644 --- a/data/raw/keybindings.json +++ b/data/raw/keybindings.json @@ -1955,8 +1955,7 @@ }, { "type": "keybinding", - "name": "Toggle Pixel Minimap", - "category": "DEFAULTMODE", + "name": "Toggle Minimap", "id": "toggle_pixel_minimap", "bindings": [ { "input_method": "keyboard", "key": "N" } ] }, diff --git a/src/game.cpp b/src/game.cpp index 05af7b72956dc..75ccda09b5b84 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -6622,7 +6622,7 @@ look_around_result game::look_around( catacurses::window w_info, tripoint ¢e bool bNewWindow = false; if( !w_info ) { int panel_width = panel_manager::get_manager().get_current_layout().begin()->get_width(); - int height = TERMY; + int height = pixel_minimap_option ? TERMY - getmaxy( w_pixel_minimap ) : TERMY; // If particularly small, base height on panel width irrespective of other elements. // Value here is attempting to get a square-ish result assuming 1x2 proportioned font. @@ -6670,6 +6670,7 @@ look_around_result game::look_around( catacurses::window w_info, tripoint ¢e ctxt.register_action( "HELP_KEYBINDINGS" ); ctxt.register_action( "zoom_out" ); ctxt.register_action( "zoom_in" ); + ctxt.register_action( "toggle_pixel_minimap" ); const int old_levz = get_levz(); const int min_levz = std::max( old_levz - fov_3d_z_range, -OVERMAP_DEPTH ); @@ -6699,8 +6700,13 @@ look_around_result game::look_around( catacurses::window w_info, tripoint ¢e std::string fast_scroll_text = string_format( _( "%s - %s" ), ctxt.get_desc( "TOGGLE_FAST_SCROLL" ), ctxt.get_action_name( "TOGGLE_FAST_SCROLL" ) ); - center_print( w_info, getmaxy( w_info ) - 1, fast_scroll ? c_light_green : c_green, - fast_scroll_text ); + std::string pixel_minimap_text = string_format( _( "%s - %s" ), + ctxt.get_desc( "toggle_pixel_minimap" ), + ctxt.get_action_name( "toggle_pixel_minimap" ) ); + mvwprintz( w_info, point( 1, getmaxy( w_info ) - 1 ), fast_scroll ? c_light_green : c_green, + fast_scroll_text ); + mvwprintz( w_info, point( utf8_width( fast_scroll_text ) + 3, getmaxy( w_info ) - 1 ), + pixel_minimap_option ? c_light_green : c_green, pixel_minimap_text ); int first_line = 1; const int last_line = getmaxy( w_info ) - 2; @@ -6758,6 +6764,12 @@ look_around_result game::look_around( catacurses::window w_info, tripoint ¢e list_items_monsters(); } else if( action == "TOGGLE_FAST_SCROLL" ) { fast_scroll = !fast_scroll; + } else if( action == "toggle_pixel_minimap" ) { + toggle_pixel_minimap(); + + int panel_width = panel_manager::get_manager().get_current_layout().begin()->get_width(); + int height = pixel_minimap_option ? TERMY - getmaxy( w_pixel_minimap ) : TERMY; + w_info = catacurses::newwin( height, panel_width, point( TERMX - panel_width, 0 ) ); } else if( action == "LEVEL_UP" || action == "LEVEL_DOWN" ) { if( !allow_zlev_move ) { continue; From 572ffb282d5c42c35acb6dd13d555d9a8d6b76ae Mon Sep 17 00:00:00 2001 From: Anton Burmistrov Date: Tue, 8 Oct 2019 17:17:32 +0300 Subject: [PATCH 16/21] Tweaked turrets' day vision range and firing range (#34426) * Tweaked turrets' day vision range and firing range * Spawn random number of bullets on turrets' death * Revert "Spawn random number of bullets on turrets' death" This reverts commit 10a9cbea4c593ebd89881023bc1f1e3ed1e24846. * Increased .50 BMG range to 110 * Increased .50 BMG weapons range and M2HB turret firing range --- data/json/items/ammo/50.json | 2 +- data/json/items/gun/50.json | 6 +++--- data/json/monsters/turrets.json | 10 +++++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/data/json/items/ammo/50.json b/data/json/items/ammo/50.json index f83f605b96713..5e6822144efe2 100644 --- a/data/json/items/ammo/50.json +++ b/data/json/items/ammo/50.json @@ -25,7 +25,7 @@ "stack_size": 10, "ammo_type": "50", "casing": "50_casing", - "range": 40, + "range": 110, "damage": 131, "pierce": 28, "dispersion": 30, diff --git a/data/json/items/gun/50.json b/data/json/items/gun/50.json index 14e625ba4ab38..34d771db244aa 100644 --- a/data/json/items/gun/50.json +++ b/data/json/items/gun/50.json @@ -14,7 +14,7 @@ "bashing": 12, "material": "steel", "ammo": "50", - "range": 45, + "range": 100, "ranged_damage": -5, "dispersion": 90, "durability": 8, @@ -39,7 +39,7 @@ "material": "steel", "ammo": "50", "skill": "rifle", - "range": 45, + "range": 110, "dispersion": 200, "durability": 8, "reload": 400, @@ -99,7 +99,7 @@ "bashing": 13, "material": "steel", "ammo": "50", - "range": 45, + "range": 115, "ranged_damage": -5, "dispersion": 80, "durability": 7, diff --git a/data/json/monsters/turrets.json b/data/json/monsters/turrets.json index 1152401f4a4e4..f43a39a4926f3 100644 --- a/data/json/monsters/turrets.json +++ b/data/json/monsters/turrets.json @@ -64,6 +64,7 @@ "morale": 100, "armor_bash": 14, "armor_cut": 16, + "vision_day": 50, "revert_to_itype": "bot_laserturret", "special_attacks": [ { @@ -98,6 +99,7 @@ "morale": 100, "armor_bash": 14, "armor_cut": 16, + "vision_day": 50, "vision_night": 3, "revert_to_itype": "bot_antimateriel", "starting_ammo": { "50bmg": 400 }, @@ -110,7 +112,7 @@ "ammo_type": "50bmg", "fake_skills": [ [ "gun", 8 ], [ "rifle", 8 ] ], "fake_dex": 12, - "ranges": [ [ 0, 10, "AUTO" ], [ 11, 40, "DEFAULT" ] ], + "ranges": [ [ 0, 40, "AUTO" ], [ 41, 110, "DEFAULT" ] ], "require_targeting_npc": true, "require_targeting_monster": true, "laser_lock": false, @@ -144,6 +146,7 @@ "morale": 100, "armor_bash": 14, "armor_cut": 16, + "vision_day": 50, "vision_night": 3, "revert_to_itype": "bot_rifleturret", "starting_ammo": { "556": 1600 }, @@ -156,7 +159,7 @@ "ammo_type": "556", "fake_skills": [ [ "gun", 8 ], [ "rifle", 8 ] ], "fake_dex": 12, - "ranges": [ [ 0, 30, "DEFAULT" ] ], + "ranges": [ [ 0, 36, "DEFAULT" ] ], "require_targeting_npc": true, "require_targeting_monster": true, "laser_lock": false, @@ -190,6 +193,7 @@ "morale": 100, "armor_bash": 14, "armor_cut": 16, + "vision_day": 50, "vision_night": 3, "revert_to_itype": "bot_crows_m240", "starting_ammo": { "762_51": 1000 }, @@ -202,7 +206,7 @@ "ammo_type": "762_51", "fake_skills": [ [ "gun", 8 ], [ "rifle", 8 ] ], "fake_dex": 12, - "ranges": [ [ 0, 30, "DEFAULT" ] ], + "ranges": [ [ 0, 60, "DEFAULT" ] ], "require_targeting_npc": true, "require_targeting_monster": true, "laser_lock": false, From 9e4ae2bb96b9967dc369b824aa73c5e0273a3651 Mon Sep 17 00:00:00 2001 From: Azumgi <4zumgi@gmail.com> Date: Tue, 8 Oct 2019 17:21:42 +0300 Subject: [PATCH 17/21] Add overlay indicators for dead zombies that can still revive (#34244) * Draw zombie revival indicators * Prevent rev. indicators from showing on debug mapgen tiles * Update RetroDays tileset - zombie revival indicator --- gfx/RetroDaysTileset/tile_config.json | 31 +++++++++++++------------- gfx/RetroDaysTileset/tiles.png | Bin 76217 -> 106006 bytes src/cata_tiles.cpp | 20 +++++++++++++++-- src/cata_tiles.h | 2 ++ 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/gfx/RetroDaysTileset/tile_config.json b/gfx/RetroDaysTileset/tile_config.json index 10d84f3e1d21e..635d78675fe0c 100644 --- a/gfx/RetroDaysTileset/tile_config.json +++ b/gfx/RetroDaysTileset/tile_config.json @@ -7798,7 +7798,8 @@ { "id": "hinge", "fg": 3036, "rotates": false }, { "id": "wood_sheet", "fg": 3037, "rotates": false }, { "id": "wood_panel", "fg": 3038, "rotates": false }, - { "id": "condom", "fg": 3039, "rotates": false } + { "id": "condom", "fg": 3039, "rotates": false }, + { "id": "zombie_revival_indicator", "fg": 3040 } ] }, { @@ -7808,20 +7809,20 @@ "sprite_offset_x": -5, "sprite_offset_y": -10, "tiles": [ - { "id": "mon_dragon_dummy", "fg": 3040, "rotates": false }, - { "id": "mon_tyrannosaurus", "fg": 3041, "rotates": false }, - { "id": "mon_triceratops", "fg": 3042, "rotates": false }, - { "id": "mon_fungaloid_queen", "fg": 3043 }, - { "id": "mon_fungaloid_seeder", "fg": 3044 }, - { "id": "mon_fungaloid_tower", "fg": 3045 }, - { "id": "mon_skeleton_hulk", "fg": 3046, "rotates": false }, - { "id": "mon_zombie_kevlar_2", "fg": 3047, "rotates": false }, - { "id": "mon_zombie_hulk_pk", "fg": 3048, "rotates": false }, - { "id": "mon_zombie_hulk", "fg": 3048, "rotates": false }, - { "id": "overlay_mutation_THRESH_URSINE", "fg": 3049 }, - { "id": "overlay_mutation_THRESH_CATTLE", "fg": 3050 }, - { "id": "overlay_male_mutation_THRESH_CATTLE", "fg": 3051 }, - { "id": "overlay_mutation_THRESH_LIZARD", "fg": 3052 } + { "id": "mon_dragon_dummy", "fg": 3056, "rotates": false }, + { "id": "mon_tyrannosaurus", "fg": 3057, "rotates": false }, + { "id": "mon_triceratops", "fg": 3058, "rotates": false }, + { "id": "mon_fungaloid_queen", "fg": 3059 }, + { "id": "mon_fungaloid_seeder", "fg": 3060 }, + { "id": "mon_fungaloid_tower", "fg": 3061 }, + { "id": "mon_skeleton_hulk", "fg": 3062, "rotates": false }, + { "id": "mon_zombie_kevlar_2", "fg": 3063, "rotates": false }, + { "id": "mon_zombie_hulk_pk", "fg": 3064, "rotates": false }, + { "id": "mon_zombie_hulk", "fg": 3064, "rotates": false }, + { "id": "overlay_mutation_THRESH_URSINE", "fg": 3065 }, + { "id": "overlay_mutation_THRESH_CATTLE", "fg": 3066 }, + { "id": "overlay_male_mutation_THRESH_CATTLE", "fg": 3067 }, + { "id": "overlay_mutation_THRESH_LIZARD", "fg": 3068 } ] }, { diff --git a/gfx/RetroDaysTileset/tiles.png b/gfx/RetroDaysTileset/tiles.png index 902011653af2a4176b239402e7bacccce501a09b..34e0e7ea2805fa60537d5ebaa4bce664f821afb5 100644 GIT binary patch literal 106006 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%0D0W;k6ZB{Hj+$?#Xj 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

^}rSxj$<1`%;>e?2tQXLQl5AddV0ut?_ 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 Ef~8>q_y7O^ diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index 51eb45621d1cd..f4d020b4132ca 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -67,6 +67,7 @@ #define dbg(x) DebugLog((x),D_SDL) << __FILE__ << ":" << __LINE__ << ": " static const std::string ITEM_HIGHLIGHT( "highlight_item" ); +static const std::string ZOMBIE_REVIVAL_INDICATOR( "zombie_revival_indicator" ); static const std::array multitile_keys = {{ "center", @@ -1243,12 +1244,12 @@ void cata_tiles::draw( const point &dest, const tripoint ¢er, int width, int draw_points.emplace_back( pos, height_3d, ll, invisible ); } - const std::array drawing_layers = {{ + const std::array drawing_layers = {{ &cata_tiles::draw_furniture, &cata_tiles::draw_graffiti, &cata_tiles::draw_trap, &cata_tiles::draw_field_or_item, &cata_tiles::draw_vpart, &cata_tiles::draw_vpart_below, &cata_tiles::draw_critter_at_below, &cata_tiles::draw_terrain_below, &cata_tiles::draw_critter_at, - &cata_tiles::draw_zone_mark + &cata_tiles::draw_zone_mark, &cata_tiles::draw_zombie_revival_indicators } }; // for each of the drawing layers in order, back to front ... @@ -2782,6 +2783,21 @@ bool cata_tiles::draw_zone_mark( const tripoint &p, lit_level ll, int &height_3d return false; } +bool cata_tiles::draw_zombie_revival_indicators( const tripoint &pos, const lit_level /*ll*/, + int &/*height_3d*/, const bool ( &invisible )[5] ) +{ + if( tileset_ptr->find_tile_type( ZOMBIE_REVIVAL_INDICATOR ) && !invisible[0] && + item_override.find( pos ) == item_override.end() && g->m.could_see_items( pos, g->u ) ) { + for( auto &i : g->m.i_at( pos ) ) { + if( i.can_revive() ) { + return draw_from_id_string( ZOMBIE_REVIVAL_INDICATOR, C_NONE, empty_string, pos, 0, 0, LL_LIT, + false ); + } + } + } + return false; +} + void cata_tiles::draw_entity_with_overlays( const player &pl, const tripoint &p, lit_level ll, int &height_3d ) { diff --git a/src/cata_tiles.h b/src/cata_tiles.h index de08172077338..08ea37cfbddef 100644 --- a/src/cata_tiles.h +++ b/src/cata_tiles.h @@ -357,6 +357,8 @@ class cata_tiles const bool ( &invisible )[5] ); bool draw_zone_mark( const tripoint &p, lit_level ll, int &height_3d, const bool ( &invisible )[5] ); + bool draw_zombie_revival_indicators( const tripoint &pos, lit_level ll, int &height_3d, + const bool ( &invisible )[5] ); void draw_entity_with_overlays( const player &pl, const tripoint &p, lit_level ll, int &height_3d ); bool draw_item_highlight( const tripoint &pos ); From 836b8d94e62ec2680869545881a5011dd6c9bf4c Mon Sep 17 00:00:00 2001 From: Valiant Date: Tue, 8 Oct 2019 18:45:19 +0400 Subject: [PATCH 18/21] Replaced free-floating battery charge spawn with heavy battery cell spawn --- src/mapgen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 03496d9a60fef..ed2ac86b7b474 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -4148,7 +4148,7 @@ void map::draw_lab( mapgendata &dat ) furn_set( point( SEEX, SEEY ), f_table ); if( loot_variant <= 67 ) { spawn_item( point( SEEX, SEEY - 1 ), "UPS_off" ); - spawn_item( point( SEEX, SEEY - 1 ), "battery", dice( 4, 3 ) ); + spawn_item( point( SEEX, SEEY - 1 ), "heavy_battery_cell" ); spawn_item( point( SEEX - 1, SEEY ), "v29" ); spawn_item( point( SEEX - 1, SEEY ), "laser_rifle", dice( 1, 0 ) ); spawn_item( point( SEEX, SEEY ), "plasma_gun" ); From 52fc6cd0d380d75b51059eb71be8796f730f80e6 Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Tue, 8 Oct 2019 19:04:41 +0200 Subject: [PATCH 19/21] Removed musicstore itemgroup --- data/json/mapgen/musicstore.json | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/data/json/mapgen/musicstore.json b/data/json/mapgen/musicstore.json index 77e2dc9c844ed..72f93292e6d79 100644 --- a/data/json/mapgen/musicstore.json +++ b/data/json/mapgen/musicstore.json @@ -1,35 +1,4 @@ [ - { - "id": "musicstore_showpiece", - "type": "item_group", - "items": [ - { - "distribution": [ - { "item": "acoustic_guitar", "prob": 100 }, - { "item": "bagpipes", "prob": 25 }, - { "item": "banjo", "prob": 60 }, - { "item": "bone_flute", "prob": 20 }, - { "item": "clarinet", "prob": 50 }, - { "item": "flute", "prob": 50 }, - { "item": "harmonica_holder", "prob": 70 }, - { "item": "jug_clay", "prob": 20 }, - { "item": "saw", "prob": 20 }, - { "item": "saxophone", "prob": 50 }, - { "item": "trumpet", "prob": 50 }, - { "item": "tuba", "prob": 25 }, - { "item": "ukulele", "prob": 50 }, - { "item": "violin", "prob": 90 }, - { "item": "guitar_electric", "prob": 90 }, - { - "collection": [ { "item": "case_violin" }, { "item": "tommygun" }, { "item": "grip" }, { "item": "thompson_drum" } ], - "prob": 15 - }, - { "collection": [ { "item": "case_violin" }, { "item": "violin_golden" } ], "prob": 50 }, - { "collection": [ { "item": "spoon" }, { "item": "washboard" } ], "prob": 15 } - ] - } - ] - }, { "id": "mussto_windinst", "type": "item_group", From 156a2f6aa357b81ab1620125bad8d61b51f6ce65 Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Tue, 8 Oct 2019 20:52:44 +0200 Subject: [PATCH 20/21] Moved bluebell flower to obsolete --- data/json/items/generic.json | 13 ------------- data/json/items/obsolete.json | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/data/json/items/generic.json b/data/json/items/generic.json index 43dc3954c74b0..438dd84937493 100644 --- a/data/json/items/generic.json +++ b/data/json/items/generic.json @@ -1874,19 +1874,6 @@ "volume": 0, "price": 200 }, - { - "type": "GENERIC", - "id": "bluebell_flower", - "name": "bluebell", - "description": "A bluebell stalk with some petals.", - "weight": "40 g", - "to_hit": -3, - "color": "blue", - "symbol": ",", - "material": [ "veggy" ], - "volume": "250 ml", - "price": 0 - }, { "type": "GENERIC", "id": "bluebell_bud", diff --git a/data/json/items/obsolete.json b/data/json/items/obsolete.json index c00d4be2ca425..eb0d0bc578c20 100644 --- a/data/json/items/obsolete.json +++ b/data/json/items/obsolete.json @@ -652,5 +652,18 @@ "explosion": { "power": 88, "shrapnel": { "casing_mass": 3, "fragment_mass": 0.12 } } }, "flags": [ "BOMB", "TRADER_AVOID" ] + }, + { + "type": "GENERIC", + "id": "bluebell_flower", + "name": "bluebell", + "description": "A bluebell stalk with some petals.", + "weight": "40 g", + "to_hit": -3, + "color": "blue", + "symbol": ",", + "material": [ "veggy" ], + "volume": "250 ml", + "price": 0 } ] From 43d5a1c5131bc2fb7d07c02d2ee4b36ecd455b65 Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Tue, 8 Oct 2019 23:37:15 +0300 Subject: [PATCH 21/21] Fix astyle regression (#34570) --- src/player_display.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/player_display.cpp b/src/player_display.cpp index b9ce3881bacc1..8e3a4f173c1f9 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -1151,15 +1151,18 @@ void player::disp_info() g->weather.weather != WEATHER_SUNNY ) ) { effect_name_and_text.push_back( { _( "In Sunlight" ), _( "The sunlight irritates you.\n" - "Strength - 1; Dexterity - 1; Intelligence - 1; Perception - 1" ) } ); + "Strength - 1; Dexterity - 1; Intelligence - 1; Perception - 1" ) + } ); } else if( has_trait( trait_id( "TROGLO2" ) ) && g->is_in_sunlight( pos() ) ) { effect_name_and_text.push_back( { _( "In Sunlight" ), _( "The sunlight irritates you badly.\n" - "Strength - 2; Dexterity - 2; Intelligence - 2; Perception - 2" ) } ); + "Strength - 2; Dexterity - 2; Intelligence - 2; Perception - 2" ) + } ); } else if( has_trait( trait_id( "TROGLO3" ) ) && g->is_in_sunlight( pos() ) ) { effect_name_and_text.push_back( { _( "In Sunlight" ), _( "The sunlight irritates you terribly.\n" - "Strength - 4; Dexterity - 4; Intelligence - 4; Perception - 4" ) } ); + "Strength - 4; Dexterity - 4; Intelligence - 4; Perception - 4" ) + } ); } for( auto &elem : addictions ) {