diff --git a/data/json/construction.json b/data/json/construction.json
index bb0710981bb5..33aa6cb794d3 100644
--- a/data/json/construction.json
+++ b/data/json/construction.json
@@ -4204,25 +4204,16 @@
},
{
"type": "construction",
- "id": "constr_gridfridge_switch_off",
- "group": "toggle_refrigerator_freezer",
- "required_skills": [ ],
+ "id": "constr_gridglass_fridge",
+ "group": "install_glass_refrigerator",
"category": "FURN",
- "time": "1 m",
- "dark_craftable": true,
- "pre_furniture": "f_fridge_on",
- "post_furniture": "f_fridge_off"
- },
- {
- "type": "construction",
- "id": "constr_gridfridge_switch_on",
- "group": "toggle_refrigerator_freezer",
"required_skills": [ ],
- "category": "FURN",
- "time": "1 m",
- "dark_craftable": true,
- "pre_furniture": "f_fridge_off",
- "post_furniture": "f_fridge_on"
+ "time": "10 m",
+ "qualities": [ ],
+ "components": [ [ [ "glass_fridge", 1 ] ] ],
+ "pre_note": "Will only work if constructed in/on a building that has an electric grid with a mounted battery.",
+ "pre_special": "check_empty",
+ "post_furniture": "f_glass_fridge"
},
{
"type": "construction",
@@ -4239,25 +4230,29 @@
},
{
"type": "construction",
- "id": "constr_gridminifreezer_switch_off",
- "group": "toggle_refrigerator_freezer",
- "required_skills": [ ],
+ "id": "constr_gridfreezer",
+ "group": "install_freezer",
"category": "FURN",
- "time": "1 m",
- "dark_craftable": true,
- "pre_furniture": "f_minifreezer_on",
- "post_furniture": "f_minifreezer_off"
+ "required_skills": [ ],
+ "time": "10 m",
+ "qualities": [ ],
+ "components": [ [ [ "fridge", 1 ] ] ],
+ "pre_note": "Will only work if constructed in/on a building that has an electric grid with a mounted battery.",
+ "pre_special": "check_empty",
+ "post_furniture": "f_freezer"
},
{
"type": "construction",
- "id": "constr_gridminifreezer_switch_on",
- "group": "toggle_refrigerator_freezer",
- "required_skills": [ ],
+ "id": "constr_gridglass_freezer",
+ "group": "install_glass_freezer",
"category": "FURN",
- "time": "1 m",
- "dark_craftable": true,
- "pre_furniture": "f_minifreezer_off",
- "post_furniture": "f_minifreezer_on"
+ "required_skills": [ ],
+ "time": "10 m",
+ "qualities": [ ],
+ "components": [ [ [ "glass_freezer", 1 ] ] ],
+ "pre_note": "Will only work if constructed in/on a building that has an electric grid with a mounted battery.",
+ "pre_special": "check_empty",
+ "post_furniture": "f_glass_freezer"
},
{
"type": "construction",
@@ -4413,6 +4408,20 @@
"pre_special": "check_empty",
"post_furniture": "f_gridvac_sealer"
},
+ {
+ "type": "construction",
+ "id": "constr_gridcraftrig",
+ "group": "place_craftrig",
+ "category": "OTHER",
+ "required_skills": [ [ "electronics", 1 ] ],
+ "time": "30 m",
+ "qualities": [ [ { "id": "SCREW", "level": 1 } ] ],
+ "using": [ [ "soldering_standard", 20 ] ],
+ "components": [ [ [ "craftrig", 1 ] ], [ [ "cable", 5 ] ], [ [ "solder_wire", 10 ] ] ],
+ "pre_note": "Will only work if constructed in/on a building that has an electric grid with a mounted battery.",
+ "pre_special": "check_empty",
+ "post_furniture": "f_craftrig"
+ },
{
"type": "construction",
"id": "constr_gridrvkitchen",
diff --git a/data/json/construction_group.json b/data/json/construction_group.json
index db3a82667da1..eeb7619559aa 100644
--- a/data/json/construction_group.json
+++ b/data/json/construction_group.json
@@ -914,6 +914,16 @@
"id": "install_large_storage_battery",
"name": "Install Large Storage Battery"
},
+ {
+ "type": "construction_group",
+ "id": "install_freezer",
+ "name": "Install Freezer"
+ },
+ {
+ "type": "construction_group",
+ "id": "install_glass_freezer",
+ "name": "Install Glass Freezer"
+ },
{
"type": "construction_group",
"id": "install_minifreezer",
@@ -929,6 +939,11 @@
"id": "install_refrigerator",
"name": "Install Refrigerator"
},
+ {
+ "type": "construction_group",
+ "id": "install_glass_refrigerator",
+ "name": "Install Glass Refrigerator"
+ },
{
"type": "construction_group",
"id": "place_small_space_heater",
@@ -1104,6 +1119,11 @@
"id": "place_vaccuum_sealer",
"name": "Place Vaccuum Sealer"
},
+ {
+ "type": "construction_group",
+ "id": "place_craftrig",
+ "name": "Place FOODCO Kitchen Buddy"
+ },
{
"type": "construction_group",
"id": "place_water_mill",
@@ -1314,11 +1334,6 @@
"id": "tape_up_window",
"name": "Tape Up Window"
},
- {
- "type": "construction_group",
- "id": "toggle_refrigerator_freezer",
- "name": "Toggle Refrigerator/Freezer"
- },
{
"type": "construction_group",
"id": "wax_floor",
diff --git a/data/json/furniture_and_terrain/furniture-appliances.json b/data/json/furniture_and_terrain/furniture-appliances.json
index 1a71daa0e612..b22f46995138 100644
--- a/data/json/furniture_and_terrain/furniture-appliances.json
+++ b/data/json/furniture_and_terrain/furniture-appliances.json
@@ -166,29 +166,101 @@
},
{
"type": "furniture",
- "id": "f_glass_fridge",
- "name": "glass door fridge",
+ "abstract": "f_floor_lamp_base",
+ "symbol": "T",
+ "color": "light_gray",
+ "name": "abstract floor lamp",
+ "description": "Abstract furniture. If you see this, something went wrong.",
+ "move_cost_mod": 2,
+ "required_str": 1,
+ "flags": [ "TRANSPARENT", "PLACE_ITEM", "EASY_DECONSTRUCT" ],
+ "deconstruct": {
+ "items": [
+ { "item": "cable", "charges": 2 },
+ { "item": "power_supply", "count": 1 },
+ { "item": "light_bulb", "count": 1 },
+ { "item": "steel_lump", "count": 1 },
+ { "item": "pipe", "count": 1 }
+ ]
+ },
+ "bash": {
+ "str_min": 12,
+ "str_max": 40,
+ "sound": "metal screeching!",
+ "sound_fail": "bonk!",
+ "items": [
+ { "item": "scrap", "count": [ 1, 2 ] },
+ { "item": "cable", "charges": [ 0, 1 ] },
+ { "item": "e_scrap", "count": [ 0, 1 ] },
+ { "item": "glass_shard", "count": [ 0, 2 ] },
+ { "item": "pipe", "count": [ 0, 1 ] }
+ ]
+ }
+ },
+ {
+ "type": "furniture",
+ "id": "f_floor_lamp_off",
+ "symbol": "T",
+ "color": "light_gray",
+ "copy-from": "f_floor_lamp_base",
+ "looks_like": "f_floor_lamp",
+ "name": "floor lamp (off)",
+ "description": "A tall standing lamp, meant to plug into a wall and light up a room.",
+ "examine_action": "transform",
+ "transforms_into": "f_floor_lamp",
+ "prompt": "Switch on the floor lamp.",
+ "message": "You switch on the floor lamp."
+ },
+ {
+ "type": "furniture",
+ "id": "f_floor_lamp",
+ "symbol": "T",
+ "color": "light_gray",
+ "copy-from": "f_floor_lamp_base",
+ "name": "floor lamp (no power)",
+ "description": "A tall standing lamp, plugged into a wall. This one has no power.",
+ "examine_action": "transform",
+ "transforms_into": "f_floor_lamp_off",
+ "prompt": "Switch off the floor lamp.",
+ "message": "You switch off the floor lamp.",
+ "active": [ "charge_watcher", { "min_power": 5, "transform": { "id": "f_floor_lamp_on", "msg": "The lamp lights up." } } ]
+ },
+ {
+ "type": "furniture",
+ "id": "f_floor_lamp_on",
+ "symbol": "T",
+ "color": "yellow",
+ "copy-from": "f_floor_lamp_base",
+ "looks_like": "f_floor_lamp",
+ "name": "floor lamp (on)",
+ "description": "A tall standing lamp, plugged into a wall.",
+ "examine_action": "transform",
+ "transforms_into": "f_floor_lamp_off",
+ "prompt": "Switch off the floor lamp.",
+ "message": "You switch off the floor lamp.",
+ "light_emitted": 160,
+ "active": [
+ "steady_consumer",
+ {
+ "power": 1,
+ "consume_every": "100 s",
+ "transform": { "id": "f_floor_lamp", "msg": "The lamp flickers and dies." }
+ }
+ ]
+ },
+ {
+ "type": "furniture",
+ "abstract": "f_glass_fridge_base",
+ "name": "abstract glass fridge",
+ "looks_like": "f_glass_fridge",
"symbol": "{",
"color": "light_cyan",
- "description": "Wow! See INTO your fridge before you open it and discover it's not working!",
+ "description": "Abstract furniture. If you see this, something went wrong.",
"move_cost_mod": -1,
"coverage": 90,
"required_str": 10,
- "flags": [ "PLACE_ITEM", "BLOCKSDOOR" ],
- "deconstruct": {
- "items": [
- { "item": "sheet_metal", "count": [ 2, 5 ] },
- { "item": "sheet_metal_small", "count": [ 0, 3 ] },
- { "item": "steel_chunk", "count": [ 2, 3 ] },
- { "item": "scrap", "count": [ 2, 6 ] },
- { "item": "cable", "charges": [ 1, 3 ] },
- { "item": "hose", "count": 1 },
- { "item": "glass_sheet", "count": 1 },
- { "item": "cu_pipe", "count": [ 3, 6 ] },
- { "item": "refrigerant_tank", "count": 1 },
- { "item": "motor_tiny", "count": 1 }
- ]
- },
+ "flags": [ "PLACE_ITEM", "BLOCKSDOOR", "MINEABLE", "EASY_DECONSTRUCT" ],
+ "deconstruct": { "items": [ { "item": "glass_fridge", "count": 1 } ] },
"max_volume": "250 L",
"bash": {
"str_min": 12,
@@ -209,6 +281,109 @@
]
}
},
+ {
+ "type": "furniture",
+ "id": "f_glass_fridge_off",
+ "copy-from": "f_glass_fridge_base",
+ "name": "glass door fridge (off)",
+ "symbol": "{",
+ "description": "There's something tantalizing about seeing the contents of a glass fridge on display. It is switched off.",
+ "examine_action": "transform",
+ "transforms_into": "f_glass_fridge",
+ "prompt": "Switch on the glass fridge.",
+ "message": "You switch on the glass fridge.",
+ "color": "light_cyan"
+ },
+ {
+ "type": "furniture",
+ "id": "f_glass_fridge",
+ "name": "glass door fridge",
+ "copy-from": "f_glass_fridge_base",
+ "symbol": "{",
+ "description": "There's something tantalizing about seeing the contents of a glass fridge on display. It has no power.",
+ "examine_action": "transform",
+ "transforms_into": "f_glass_fridge_off",
+ "prompt": "Switch off the glass fridge.",
+ "message": "You switch off the glass fridge.",
+ "active": [ "charge_watcher", { "min_power": 40, "transform": { "id": "f_glass_fridge_on", "msg": "The fridge starts up." } } ],
+ "color": "light_cyan"
+ },
+ {
+ "type": "furniture",
+ "id": "f_glass_fridge_on",
+ "name": "glass door fridge (on)",
+ "copy-from": "f_glass_fridge_base",
+ "symbol": "{",
+ "description": "There's something tantalizing about seeing the contents of a glass fridge on display. It is switched on.",
+ "examine_action": "transform",
+ "transforms_into": "f_glass_fridge_off",
+ "prompt": "Switch off the glass fridge.",
+ "message": "You switch off the glass fridge.",
+ "color": "light_cyan",
+ "extend": { "flags": [ "FRIDGE" ] },
+ "//": "Consumes more power due to worse insulation.",
+ "active": [
+ "steady_consumer",
+ {
+ "power": 25,
+ "consume_every": "600 s",
+ "transform": { "id": "f_glass_fridge", "msg": "The fridge shuts down." }
+ }
+ ]
+ },
+ {
+ "type": "furniture",
+ "id": "f_glass_freezer_off",
+ "name": "glass door freezer (off)",
+ "copy-from": "f_glass_fridge_base",
+ "symbol": "{",
+ "description": "A glass door freezer! Maybe there's some ice cream inside. It is switched off.",
+ "examine_action": "transform",
+ "transforms_into": "f_glass_freezer",
+ "prompt": "Switch on the glass freezer.",
+ "message": "You switch on the glass freezer.",
+ "color": "blue",
+ "deconstruct": { "items": [ { "item": "glass_freezer", "count": 1 } ] }
+ },
+ {
+ "type": "furniture",
+ "id": "f_glass_freezer",
+ "name": "glass door freezer",
+ "copy-from": "f_glass_fridge_base",
+ "symbol": "{",
+ "description": "A glass door freezer! Maybe there's some ice cream inside. It has no power.",
+ "examine_action": "transform",
+ "transforms_into": "f_glass_freezer_off",
+ "prompt": "Switch off the glass freezer.",
+ "message": "You switch off the glass freezer.",
+ "active": [ "charge_watcher", { "min_power": 50, "transform": { "id": "f_glass_freezer_on", "msg": "The freezer starts up." } } ],
+ "color": "blue",
+ "deconstruct": { "items": [ { "item": "glass_freezer", "count": 1 } ] }
+ },
+ {
+ "type": "furniture",
+ "id": "f_glass_freezer_on",
+ "name": "glass freezer (on)",
+ "copy-from": "f_glass_fridge_base",
+ "symbol": "{",
+ "description": "A glass door freezer! Maybe there's some ice cream inside. It is switched on.",
+ "examine_action": "transform",
+ "transforms_into": "f_glass_freezer_off",
+ "prompt": "Switch off the glass freezer.",
+ "message": "You switch off the glass freezer.",
+ "color": "blue",
+ "extend": { "flags": [ "FREEZER" ] },
+ "//": "Consumes more power due to worse insulation.",
+ "deconstruct": { "items": [ { "item": "glass_freezer", "count": 1 } ] },
+ "active": [
+ "steady_consumer",
+ {
+ "power": 30,
+ "consume_every": "600 s",
+ "transform": { "id": "f_glass_freezer", "msg": "The freezer shuts down." }
+ }
+ ]
+ },
{
"type": "furniture",
"id": "f_home_furnace",
@@ -824,17 +999,13 @@
{
"type": "furniture",
"id": "f_welderrig",
+ "copy-from": "f_gridwelder",
"looks_like": "weldrig",
"name": "grid welder rig",
"symbol": "#",
- "description": "A vehicle welding rig connected to a electrical grid.",
"color": "red",
- "move_cost_mod": -1,
- "coverage": 10,
- "required_str": -1,
- "crafting_pseudo_item": "fake_gridwelder",
- "examine_action": "use_furn_fake_item",
- "flags": [ "TRANSPARENT", "MOUNTABLE", "EASY_DECONSTRUCT" ],
+ "description": "A vehicle welding rig connected to a electrical grid. Has a soldering iron attached.",
+ "extend": { "crafting_pseudo_item": [ "fake_gridsolderingiron" ] },
"deconstruct": {
"items": [ { "item": "weldrig", "count": 1 }, { "item": "cable", "charges": 5 }, { "item": "power_supply", "count": 1 } ]
},
@@ -1000,6 +1171,37 @@
]
}
},
+ {
+ "type": "furniture",
+ "id": "f_craftrig",
+ "looks_like": "craftrig",
+ "name": "grid FOODCO kitchen buddy",
+ "symbol": "&",
+ "description": "A multi-function crafting station, with a water purifier, food processor, food dehydrator, vacuum sealer, and hand press for making ammo. Draws power from the electrical grid. If you attempt to craft an item that needs one of the kitchen buddy's functions, it will automatically be selected as a tool.",
+ "color": "blue",
+ "move_cost_mod": -1,
+ "coverage": 80,
+ "required_str": 10,
+ "crafting_pseudo_item": [ "fake_gridfood_processor", "fake_griddehydrator", "fake_gridvac_sealer", "fake_gridwater_purifier", "press" ],
+ "flags": [ "BLOCKSDOOR", "MINEABLE", "EASY_DECONSTRUCT" ],
+ "deconstruct": { "items": [ { "item": "craftrig", "count": 1 }, { "item": "cable", "charges": 5 } ] },
+ "bash": {
+ "str_min": 18,
+ "str_max": 50,
+ "sound": "metal screeching!",
+ "sound_fail": "clang!",
+ "items": [
+ { "count": [ 4, 7 ], "item": "steel_lump" },
+ { "count": [ 4, 7 ], "item": "steel_chunk" },
+ { "count": [ 4, 7 ], "item": "scrap" },
+ { "charges": 0, "item": "water_purifier", "prob": 50 },
+ { "charges": 0, "item": "vac_sealer", "prob": 50 },
+ { "charges": 0, "item": "dehydrator", "prob": 50 },
+ { "charges": 0, "item": "food_processor", "prob": 50 },
+ { "charges": 0, "item": "press", "prob": 50 }
+ ]
+ }
+ },
{
"type": "furniture",
"id": "f_gridelectrolysis_kit",
@@ -1056,10 +1258,10 @@
{
"type": "furniture",
"abstract": "f_fridge_base",
- "name": "-",
+ "name": "abstract fridge",
"looks_like": "f_fridge",
"symbol": "{",
- "description": "-",
+ "description": "Abstract furniture. If you see this, something went wrong.",
"color": "light_cyan",
"move_cost_mod": -1,
"coverage": 90,
@@ -1092,6 +1294,10 @@
"name": "refrigerator (off)",
"symbol": "{",
"description": "Refrigerate your food with the amazing science of electricity! It is switched off.",
+ "examine_action": "transform",
+ "transforms_into": "f_fridge",
+ "prompt": "Switch on the fridge.",
+ "message": "You switch on the fridge.",
"color": "light_cyan"
},
{
@@ -1101,6 +1307,10 @@
"copy-from": "f_fridge_base",
"symbol": "{",
"description": "Refrigerate your food with the amazing science of electricity! It has no power.",
+ "examine_action": "transform",
+ "transforms_into": "f_fridge_off",
+ "prompt": "Switch off the fridge.",
+ "message": "You switch off the fridge.",
"active": [ "charge_watcher", { "min_power": 30, "transform": { "id": "f_fridge_on", "msg": "The fridge starts up." } } ],
"color": "light_cyan"
},
@@ -1111,19 +1321,72 @@
"copy-from": "f_fridge_base",
"symbol": "{",
"description": "Refrigerate your food with the amazing science of electricity! It is switched on.",
+ "examine_action": "transform",
+ "transforms_into": "f_fridge_off",
+ "prompt": "Switch off the fridge.",
+ "message": "You switch off the fridge.",
"color": "light_cyan",
+ "extend": { "flags": [ "FRIDGE" ] },
"active": [
"steady_consumer",
{ "power": 20, "consume_every": "600 s", "transform": { "id": "f_fridge", "msg": "The fridge shuts down." } }
]
},
+ {
+ "type": "furniture",
+ "id": "f_freezer_off",
+ "name": "freezer (off)",
+ "copy-from": "f_fridge_base",
+ "symbol": "{",
+ "description": "Freeze your food with the amazing science of electricity! It is switched off.",
+ "examine_action": "transform",
+ "transforms_into": "f_freezer",
+ "prompt": "Switch on the freezer.",
+ "message": "You switch on the freezer.",
+ "color": "blue",
+ "deconstruct": { "items": [ { "item": "freezer", "count": 1 } ] }
+ },
+ {
+ "type": "furniture",
+ "id": "f_freezer",
+ "name": "freezer",
+ "copy-from": "f_fridge_base",
+ "symbol": "{",
+ "description": "Freeze your food with the amazing science of electricity! It has no power.",
+ "examine_action": "transform",
+ "transforms_into": "f_freezer_off",
+ "prompt": "Switch off the freezer.",
+ "message": "You switch off the freezer.",
+ "active": [ "charge_watcher", { "min_power": 40, "transform": { "id": "f_freezer_on", "msg": "The freezer starts up." } } ],
+ "color": "blue",
+ "deconstruct": { "items": [ { "item": "freezer", "count": 1 } ] }
+ },
+ {
+ "type": "furniture",
+ "id": "f_freezer_on",
+ "name": "freezer (on)",
+ "copy-from": "f_fridge_base",
+ "symbol": "{",
+ "description": "Freeze your food with the amazing science of electricity! It is switched on.",
+ "examine_action": "transform",
+ "transforms_into": "f_freezer_off",
+ "prompt": "Switch off the freezer.",
+ "message": "You switch off the freezer.",
+ "color": "blue",
+ "extend": { "flags": [ "FREEZER" ] },
+ "deconstruct": { "items": [ { "item": "freezer", "count": 1 } ] },
+ "active": [
+ "steady_consumer",
+ { "power": 25, "consume_every": "600 s", "transform": { "id": "f_freezer", "msg": "The freezer shuts down." } }
+ ]
+ },
{
"type": "furniture",
"abstract": "f_minifreezer_base",
- "name": "-",
+ "name": "abstract minifreezer",
"looks_like": "minifreezer",
"symbol": "H",
- "description": "-",
+ "description": "Abstract furniture. If you see this, something went wrong.",
"color": "blue",
"move_cost_mod": -1,
"coverage": 50,
@@ -1152,6 +1415,10 @@
"name": "minifreezer (off)",
"symbol": "H",
"description": "Freeze your food with the amazing science of electricity! It is switched off.",
+ "examine_action": "transform",
+ "transforms_into": "f_minifreezer",
+ "prompt": "Switch on the minfreezer.",
+ "message": "You switch on the minifreezer.",
"color": "blue"
},
{
@@ -1161,6 +1428,10 @@
"copy-from": "f_minifreezer_base",
"symbol": "H",
"description": "Freeze your food with the amazing science of electricity! It has no power.",
+ "examine_action": "transform",
+ "transforms_into": "f_minifreezer_off",
+ "prompt": "Switch off the minifreezer.",
+ "message": "You switch off the minifreezer.",
"active": [
"charge_watcher",
{ "min_power": 60, "transform": { "id": "f_minifreezer_on", "msg": "The minifreezer starts up." } }
@@ -1174,7 +1445,12 @@
"copy-from": "f_minifreezer_base",
"symbol": "H",
"description": "Freeze your food with the amazing science of electricity! It is switched on.",
+ "examine_action": "transform",
+ "transforms_into": "f_minifreezer_off",
+ "prompt": "Switch off the minifreezer.",
+ "message": "You switch off the minifreezer.",
"color": "blue",
+ "extend": { "flags": [ "FREEZER" ] },
"active": [
"steady_consumer",
{
@@ -1221,8 +1497,8 @@
"looks_like": "small_space_heater",
"symbol": ";",
"color": "light_gray",
- "name": "-",
- "description": "-",
+ "name": "abstract space heater",
+ "description": "Abstract furniture. If you see this, something went wrong.",
"move_cost_mod": 2,
"required_str": 1,
"flags": [ "TRANSPARENT", "EASY_DECONSTRUCT" ],
diff --git a/data/json/furniture_and_terrain/furniture-decorative.json b/data/json/furniture_and_terrain/furniture-decorative.json
index f08aac663e1f..a116a55c40d5 100644
--- a/data/json/furniture_and_terrain/furniture-decorative.json
+++ b/data/json/furniture_and_terrain/furniture-decorative.json
@@ -153,40 +153,6 @@
"items": [ { "item": "pipe", "count": [ 1, 6 ] }, { "item": "wire", "count": [ 1, 2 ] }, { "item": "scrap", "count": [ 1, 6 ] } ]
}
},
- {
- "type": "furniture",
- "id": "f_floor_lamp",
- "name": "floor lamp",
- "symbol": "T",
- "looks_like": "f_rack_coat",
- "description": "A tall standing lamp, meant to plug into a wall and light up a room.",
- "color": "light_gray",
- "move_cost_mod": 2,
- "required_str": 1,
- "flags": [ "BLOCKSDOOR", "PLACE_ITEM", "EASY_DECONSTRUCT" ],
- "deconstruct": {
- "items": [
- { "item": "cable", "charges": [ 1, 2 ] },
- { "item": "amplifier", "count": [ 1, 4 ] },
- { "item": "light_bulb", "count": [ 1, 4 ] },
- { "item": "steel_lump", "count": 1 },
- { "item": "pipe", "count": 1 }
- ]
- },
- "bash": {
- "str_min": 12,
- "str_max": 40,
- "sound": "metal screeching!",
- "sound_fail": "bonk!",
- "items": [
- { "item": "scrap", "count": [ 1, 2 ] },
- { "item": "cable", "charges": [ 0, 1 ] },
- { "item": "e_scrap", "count": [ 0, 1 ] },
- { "item": "glass_shard", "count": [ 0, 1 ] },
- { "item": "pipe", "count": [ 0, 1 ] }
- ]
- }
- },
{
"type": "furniture",
"id": "f_winter_wreath",
diff --git a/data/json/furniture_and_terrain/furniture-zztesting.json b/data/json/furniture_and_terrain/furniture-zztesting.json
deleted file mode 100644
index 974a791c79c1..000000000000
--- a/data/json/furniture_and_terrain/furniture-zztesting.json
+++ /dev/null
@@ -1,83 +0,0 @@
-[
- {
- "type": "furniture",
- "abstract": "f_floor_lamp_base",
- "symbol": "T",
- "color": "light_gray",
- "name": "-",
- "description": "-",
- "move_cost_mod": 2,
- "required_str": 1,
- "flags": [ "TRANSPARENT", "PLACE_ITEM", "EASY_DECONSTRUCT" ],
- "deconstruct": {
- "items": [
- { "item": "cable", "charges": 2 },
- { "item": "power_supply", "count": 1 },
- { "item": "light_bulb", "count": 1 },
- { "item": "steel_lump", "count": 1 },
- { "item": "pipe", "count": 1 }
- ]
- },
- "bash": {
- "str_min": 12,
- "str_max": 40,
- "sound": "metal screeching!",
- "sound_fail": "bonk!",
- "items": [
- { "item": "scrap", "count": [ 1, 2 ] },
- { "item": "cable", "charges": [ 0, 1 ] },
- { "item": "e_scrap", "count": [ 0, 1 ] },
- { "item": "glass_shard", "count": [ 0, 2 ] },
- { "item": "pipe", "count": [ 0, 1 ] }
- ]
- }
- },
- {
- "type": "furniture",
- "id": "f_floor_lamp",
- "symbol": "T",
- "color": "light_gray",
- "copy-from": "f_floor_lamp_base",
- "name": "floor lamp (no power)",
- "description": "A tall standing lamp, plugged into a wall. This one has no power.",
- "examine_action": "transform",
- "transforms_into": "f_floor_lamp_off",
- "message": "You turn the lamp off.",
- "active": [ "charge_watcher", { "min_power": 5, "transform": { "id": "f_floor_lamp_on", "msg": "The lamp lights up." } } ]
- },
- {
- "type": "furniture",
- "id": "f_floor_lamp_off",
- "symbol": "T",
- "color": "light_gray",
- "copy-from": "f_floor_lamp_base",
- "looks_like": "f_floor_lamp",
- "name": "floor lamp (off)",
- "description": "A tall standing lamp, meant to plug into a wall and light up a room.",
- "examine_action": "transform",
- "transforms_into": "f_floor_lamp",
- "message": "You turn the lamp on."
- },
- {
- "type": "furniture",
- "id": "f_floor_lamp_on",
- "symbol": "T",
- "color": "yellow",
- "copy-from": "f_floor_lamp_base",
- "looks_like": "f_floor_lamp",
- "name": "floor lamp (on)",
- "description": "A tall standing lamp, plugged into a wall.",
- "examine_action": "transform",
- "transforms_into": "f_floor_lamp_off",
- "message": "You turn the lamp off.",
- "light_emitted": 160,
- "active": [
- "steady_consumer",
- {
- "power": 1,
- "consume_every": "100 s",
- "transform": { "id": "f_floor_lamp", "msg": "The lamp flickers and dies." }
- }
- ]
- }
-]
diff --git a/data/json/itemgroups/collections_domestic.json b/data/json/itemgroups/collections_domestic.json
index 19668a39f7f0..f8655823add5 100644
--- a/data/json/itemgroups/collections_domestic.json
+++ b/data/json/itemgroups/collections_domestic.json
@@ -730,6 +730,32 @@
{ "item": "icecream_candy", "prob": 3 }
]
},
+ {
+ "type": "item_group",
+ "id": "kitchen_freezer",
+ "ammo": 75,
+ "magazine": 100,
+ "subtype": "distribution",
+ "entries": [
+ { "item": "sweet_sausage", "prob": 2 },
+ { "item": "bacon", "prob": 25 },
+ { "item": "fchicken", "prob": 25 },
+ { "item": "lunchmeat", "prob": 10 },
+ { "item": "bologna", "prob": 10 },
+ { "item": "pizza_veggy", "prob": 8 },
+ { "item": "pizza_meat", "prob": 8 },
+ { "item": "pizza_cheese", "prob": 8 },
+ { "item": "hotdogs_frozen", "prob": 8 },
+ { "item": "corndogs_frozen", "prob": 8 },
+ { "item": "meat_smoked", "prob": 8 },
+ { "item": "fish_smoked", "prob": 8 },
+ { "item": "bologna", "prob": 6 },
+ { "item": "sausage", "prob": 6 },
+ { "item": "bratwurst_sausage", "prob": 5 },
+ { "item": "lunchmeat", "prob": 10 },
+ { "item": "meat", "prob": 15 }
+ ]
+ },
{
"type": "item_group",
"id": "bedroom",
diff --git a/data/json/itemgroups/food_service.json b/data/json/itemgroups/food_service.json
index 784a220a5fcc..4f0019fa1d43 100644
--- a/data/json/itemgroups/food_service.json
+++ b/data/json/itemgroups/food_service.json
@@ -12,6 +12,17 @@
{ "item": "brownie", "prob": 20 }
]
},
+ {
+ "id": "frozen_baked_goods",
+ "type": "item_group",
+ "subtype": "distribution",
+ "entries": [
+ { "item": "cake2", "prob": 15 },
+ { "item": "cake3", "prob": 10 },
+ { "item": "jihelucake", "prob": 10 },
+ { "item": "brownie", "prob": 20 }
+ ]
+ },
{
"id": "tea_dishes",
"type": "item_group",
@@ -810,6 +821,19 @@
[ "soup_meat", 10 ]
]
},
+ {
+ "id": "restaur_freezer",
+ "type": "item_group",
+ "items": [
+ [ "fish_smoked", 5 ],
+ [ "meat_smoked", 5 ],
+ [ "bologna", 5 ],
+ [ "sausage", 5 ],
+ [ "bratwurst_sausage", 5 ],
+ [ "lunchmeat", 5 ],
+ [ "meat", 10 ]
+ ]
+ },
{
"id": "restaur_kitchen",
"type": "item_group",
diff --git a/data/json/items/fake.json b/data/json/items/fake.json
index 4029000b69ed..9ef27f3045d5 100644
--- a/data/json/items/fake.json
+++ b/data/json/items/fake.json
@@ -278,6 +278,15 @@
"max_charges": 2500,
"flags": [ "USES_GRID_POWER" ]
},
+ {
+ "id": "fake_gridwater_purifier",
+ "copy-from": "fake_item",
+ "type": "TOOL",
+ "name": { "str": "grid water purifier" },
+ "sub": "water_purifier",
+ "max_charges": 2500,
+ "flags": [ "USES_GRID_POWER" ]
+ },
{
"id": "fake_gridelectrolysis_kit",
"copy-from": "fake_item",
diff --git a/data/json/items/furniture.json b/data/json/items/furniture.json
index 17494349083b..ab39f7d517c9 100644
--- a/data/json/items/furniture.json
+++ b/data/json/items/furniture.json
@@ -13,6 +13,49 @@
"symbol": "{",
"color": "light_cyan"
},
+ {
+ "id": "freezer",
+ "type": "TOOL",
+ "looks_like": "f_fridge",
+ "name": "freezer",
+ "description": "A large and heavy freezer, used in restaurants, megastores and other environments where you need a large volume of things frozen.",
+ "weight": "80 kg",
+ "volume": "210000 ml",
+ "price": 1000,
+ "price_postapoc": 150,
+ "material": "steel",
+ "symbol": "{",
+ "color": "blue"
+ },
+ {
+ "id": "glass_fridge",
+ "type": "TOOL",
+ "looks_like": "f_glass_fridge",
+ "name": "glass refrigerator",
+ "description": "A glass refrigerator. Used to display chilled goods in shops.",
+ "//": "Glass fridges are lighter than steel, but the volume is larger because of the furniture item.",
+ "weight": "77 kg",
+ "volume": "260000 ml",
+ "price": 1000,
+ "price_postapoc": 150,
+ "material": [ "steel", "glass" ],
+ "symbol": "{",
+ "color": "light_cyan"
+ },
+ {
+ "id": "glass_freezer",
+ "type": "TOOL",
+ "looks_like": "f_glass_fridge",
+ "name": "glass freezer",
+ "description": "A glass freezer. Used to display frozen goods in shops.",
+ "weight": "77 kg",
+ "volume": "260000 ml",
+ "price": 1000,
+ "price_postapoc": 150,
+ "material": [ "steel", "glass" ],
+ "symbol": "{",
+ "color": "blue"
+ },
{
"id": "oven",
"type": "TOOL",
diff --git a/data/json/mapgen/bakery.json b/data/json/mapgen/bakery.json
index aa3d235b8316..c57de84a2757 100644
--- a/data/json/mapgen/bakery.json
+++ b/data/json/mapgen/bakery.json
@@ -23,7 +23,7 @@
"_|S.....#.t.o-.........|",
"_|c.......t.r-..gg^gg..|",
"_|c.........r--+-----+-|",
- "_|ccc{{.....r-...&-&...|",
+ "_|ccc{{[[...r-...&-&...|",
"_||||||||-+---....-....|",
"_pppaaps|b..l-c.-----.c|",
"_pppppps|b..l-S.dT-Td.S|",
@@ -64,7 +64,8 @@
"t": "f_table",
"r": "f_rack",
"g": "f_glass_cabinet",
- "{": "f_fridge"
+ "{": "f_fridge",
+ "[": "f_freezer"
},
"toilets": { "T": { } },
"place_items": [
@@ -74,6 +75,7 @@
{ "item": "groce_ingredient", "x": 12, "y": [ 14, 16 ], "chance": 50, "repeat": [ 1, 3 ] },
{ "item": "groce_ingredient", "x": [ 9, 11 ], "y": 21, "chance": 50, "repeat": [ 1, 3 ] },
{ "item": "groce_dairyegg", "x": [ 5, 6 ], "y": 16, "chance": 75 },
+ { "item": "frozen_baked_goods", "x": [ 7, 8 ], "y": 16, "chance": 75, "repeat": [ 1, 3 ] },
{ "item": "groce_bread", "x": 2, "y": 16, "chance": 50 },
{ "item": "groce_bread", "x": 2, "y": 14, "chance": 50 },
{ "item": "groce_bread", "x": 16, "y": 5, "chance": 50 },
diff --git a/data/json/mapgen/city_blocks/urban_14_dense_house_mart_food.json b/data/json/mapgen/city_blocks/urban_14_dense_house_mart_food.json
index 8db281364fe6..c0729a3f1f01 100644
--- a/data/json/mapgen/city_blocks/urban_14_dense_house_mart_food.json
+++ b/data/json/mapgen/city_blocks/urban_14_dense_house_mart_food.json
@@ -119,7 +119,7 @@
"7": "f_rack",
"9": "f_rack",
"z": "f_cardboard_box",
- "8": "f_glass_fridge",
+ "8": "f_glass_freezer",
"m": "f_glass_fridge",
"0": "f_table"
},
diff --git a/data/json/mapgen/homeimprovement_superstore.json b/data/json/mapgen/homeimprovement_superstore.json
index bcbca3124aa5..8db8b3f69ab1 100644
--- a/data/json/mapgen/homeimprovement_superstore.json
+++ b/data/json/mapgen/homeimprovement_superstore.json
@@ -92,13 +92,13 @@
"object": {
"rows": [
"|rrrrrrr...........F|s..",
- "|..................F|t..",
+ "|..................f|t..",
"|rrrrrrr................",
"|.......................",
"|...................---.",
"|..ccc.............O|CT.",
"|..................O|s..",
- "|..ccc.............O|t..",
+ "|..ccc.............f|t..",
"|........|..............",
"|..ccc...|.CT.CT........",
"|........|$.......|.....",
@@ -133,6 +133,7 @@
"s": "t_floor",
"O": "t_floor",
"F": "t_floor",
+ "f": "t_floor",
"t": "t_floor",
"|": "t_wall"
},
@@ -146,6 +147,7 @@
"r": "f_rack",
"s": "f_sink",
"O": "f_oven",
+ "f": "f_freezer",
"F": "f_fridge",
"t": "f_toilet"
},
diff --git a/data/json/mapgen/irradiator_1.json b/data/json/mapgen/irradiator_1.json
index 200167a4794e..b256af5d2024 100644
--- a/data/json/mapgen/irradiator_1.json
+++ b/data/json/mapgen/irradiator_1.json
@@ -251,7 +251,7 @@
"]": [ "f_bookcase", "f_filing_cabinet" ],
"?": [ "f_toilet" ],
">": [ "f_vent_pipe" ],
- ".": [ "f_oven", "f_counter", "f_fridge", "f_trashcan", "f_cupboard" ],
+ ".": [ "f_oven", "f_counter", "f_fridge", "f_freezer", "f_trashcan", "f_cupboard" ],
"{": [ "f_washer", "f_dryer" ]
},
"computers": {
diff --git a/data/json/mapgen/mall/mall_second_floor.json b/data/json/mapgen/mall/mall_second_floor.json
index 19da9ae0bbac..f792d1344094 100644
--- a/data/json/mapgen/mall/mall_second_floor.json
+++ b/data/json/mapgen/mall/mall_second_floor.json
@@ -399,7 +399,7 @@
"...........| ",
"yFFy......yH ",
"#####.....YH ",
- " #y..JmmH ",
+ " #y..J[[H ",
" #F..J.BH ",
" #F..J..H ",
" #y..JJ.H ",
@@ -417,7 +417,7 @@
"z": "t_thconc_floor",
"^": "t_linoleum_white"
},
- "furniture": { "%": [ "f_indoor_plant_y", "f_indoor_plant" ], "^": "f_sink", "!": "f_counter" },
+ "furniture": { "%": [ "f_indoor_plant_y", "f_indoor_plant" ], "^": "f_sink", "!": "f_counter", "[": "f_glass_freezer" },
"items": {
"u": [
{ "item": "vending_food_items", "chance": 20, "repeat": [ 4, 10 ] },
@@ -441,7 +441,7 @@
{ "item": "hatstore_accessories", "chance": 40, "repeat": [ 1, 2 ] },
{ "item": "shoestore_shoes", "chance": 10, "repeat": [ 1, 2 ] }
],
- "m": { "item": "dessert", "chance": 50, "repeat": [ 1, 2 ] },
+ "[": { "item": "dessert", "chance": 50, "repeat": [ 1, 2 ] },
"J": [
{ "item": "baked_goods", "chance": 40, "repeat": [ 1, 2 ] },
{ "item": "coffee_display_2", "chance": 50, "repeat": [ 1, 2 ] },
diff --git a/data/json/mapgen/megastore.json b/data/json/mapgen/megastore.json
index 35e6df2012a6..d147f8e6fe7c 100644
--- a/data/json/mapgen/megastore.json
+++ b/data/json/mapgen/megastore.json
@@ -62,6 +62,7 @@
"U": "f_cupboard",
"x": "f_crate_o",
"X": "f_crate_c",
+ "[": "f_glass_freezer",
":": "f_shredder"
},
"toilets": { "&": { "amount": [ 0, 50 ] } },
@@ -87,7 +88,8 @@
"r": { "item": "pants", "chance": 65, "repeat": [ 1, 4 ] },
"R": { "item": "jackets", "chance": 65, "repeat": [ 1, 4 ] },
"x": { "item": "child_items", "chance": 65, "repeat": [ 1, 8 ] },
- "X": { "item": "construction_worker", "chance": 65, "repeat": [ 1, 4 ] }
+ "X": { "item": "construction_worker", "chance": 65, "repeat": [ 1, 4 ] },
+ "[": { "item": "kitchen_freezer", "chance": 65, "repeat": [ 2, 6 ] }
}
},
{
@@ -102,7 +104,8 @@
"r": { "item": "hardware", "chance": 65, "repeat": [ 1, 4 ] },
"R": { "item": "mischw", "chance": 65, "repeat": [ 1, 6 ] },
"x": { "item": "shelter", "chance": 65, "repeat": [ 1, 4 ] },
- "X": { "item": "cannedfood", "chance": 65, "repeat": [ 2, 10 ] }
+ "X": { "item": "cannedfood", "chance": 65, "repeat": [ 2, 10 ] },
+ "[": { "item": "kitchen_freezer", "chance": 65, "repeat": [ 2, 6 ] }
}
},
{
@@ -117,7 +120,8 @@
"r": { "item": "hardware", "chance": 65, "repeat": [ 1, 4 ] },
"R": { "item": "cleaning", "chance": 65, "repeat": [ 1, 4 ] },
"x": { "item": "shoes", "chance": 65, "repeat": [ 1, 8 ] },
- "X": { "item": "dresser", "chance": 65, "repeat": [ 1, 4 ] }
+ "X": { "item": "dresser", "chance": 65, "repeat": [ 1, 4 ] },
+ "[": { "item": "kitchen_freezer", "chance": 65, "repeat": [ 2, 6 ] }
}
},
{
@@ -492,7 +496,7 @@
"RRRRRIRRRRR..RRRRRIRRRRR",
"........................",
"........................",
- ".fffffffffff..FFFFFFFFF.",
+ ".[[[[[[[[[[[..FFFFFFFFF.",
".fffffffffff..FFFFFFFFF.",
"........................"
],
@@ -921,8 +925,8 @@
"..FFFFFFFF...KK..KK.....",
"..FFFFFFFF...KK..KK.....",
".............KK..KK.....",
- "..FFIFFFFF...KK..KI.....",
- "..ffffffff...KK..KK.....",
+ "..[[I[[[[[...KK..KI.....",
+ "..[[[[[[[[...KK..KK.....",
".............KK..KK.....",
"..ffffffff...KK..KK.....",
"..ffffffff...KK..KK.....",
@@ -1119,7 +1123,7 @@
"..fffIffffffffffffIfff..",
"........................",
"........................",
- "..ffffffffffffffffffff..",
+ "..[[[[[[[[[[[[[[[[[[[[..",
"..KKKKKKKKKKKKKKKKKKKK..",
"........................"
],
diff --git a/data/json/mapgen/nested/retail_nested.json b/data/json/mapgen/nested/retail_nested.json
index 557d04e87ccb..6b0901bf5e7e 100644
--- a/data/json/mapgen/nested/retail_nested.json
+++ b/data/json/mapgen/nested/retail_nested.json
@@ -1247,7 +1247,7 @@
"JJiRiJJ| || ",
"F n| |t ",
"F RRR l| * ",
- "F * | ",
+ "f * | ",
"YPPQQSY| |j "
],
"terrain": { "?": "t_console_broken", "|": "t_brick_wall", "*": "t_door_c" },
@@ -1263,6 +1263,7 @@
"Y": "f_trashcan",
"A": "f_stool",
"i": "f_oven",
+ "f": "f_freezer",
"F": "f_fridge",
"n": "f_sink",
"l": "f_dishwasher",
diff --git a/data/json/mapgen/pizza_parlor.json b/data/json/mapgen/pizza_parlor.json
index d27cc8238a5e..d402e79407d8 100644
--- a/data/json/mapgen/pizza_parlor.json
+++ b/data/json/mapgen/pizza_parlor.json
@@ -11,7 +11,7 @@
"-||||||||||||||- ",
"-FwlwL-P#######-4 Y",
"-Flwlw#..U.U.U.g ",
- "-#wlwl@........g ",
+ "-fwlwl@........g ",
"-#lwlw#........g ",
"-#wlwl{........g ",
"-Olwlw{........g ",
@@ -70,6 +70,7 @@
"#": "f_counter",
"B": "f_bench",
"C": "f_trashcan",
+ "f": "f_freezer",
"F": "f_fridge",
"H": "f_chair",
"L": "f_locker",
@@ -84,9 +85,10 @@
"toilets": { "t": { } },
"place_items": [
{ "item": "pizza_display", "x": 6, "y": [ 5, 8 ], "chance": 65, "repeat": [ 3, 4 ] },
- { "item": "pizza_kitchen", "x": 1, "y": [ 3, 5 ], "chance": 80, "repeat": [ 7, 10 ] },
+ { "item": "pizza_kitchen", "x": 1, "y": [ 4, 5 ], "chance": 80, "repeat": [ 7, 10 ] },
{ "item": "pizza_kitchen", "x": 1, "y": [ 8, 9 ], "chance": 82, "repeat": [ 7, 9 ] },
{ "item": "pizza_fridge", "x": 1, "y": [ 1, 2 ], "chance": 80, "repeat": [ 9, 10 ] },
+ { "item": "restaur_freezer", "x": 1, "y": 3, "chance": 80, "repeat": [ 5, 6 ] },
{ "item": "pizza_beer", "x": [ 9, 13 ], "y": 1, "chance": 70, "repeat": [ 2, 3 ] },
{ "item": "pizza_soda", "x": 6, "y": [ 9, 12 ], "chance": 70, "repeat": [ 2, 5 ] },
{ "item": "pizza_table", "x": [ 11, 12 ], "y": 11, "chance": 25 },
diff --git a/data/json/mapgen/restaurant.json b/data/json/mapgen/restaurant.json
index 3c877d7ef31e..033ac5d80315 100644
--- a/data/json/mapgen/restaurant.json
+++ b/data/json/mapgen/restaurant.json
@@ -173,7 +173,7 @@
"ssssssssssssssssssssssss",
"ssssssssssssssssssssssss",
"ssss|-------------|sssss",
- "____|&wlwF|.......|sssss",
+ "____|&wlfF|.......|sssss",
"____DwlwlF|A...@2^gsssss",
"____|lwlw#|.......+sssss",
"____|#lwlS|A......+sssss",
@@ -233,6 +233,7 @@
"&": "f_trashcan",
"A": "f_statue",
"B": "f_bench",
+ "f": "f_freezer",
"F": "f_fridge",
"O": "f_oven",
"R": "f_woodstove",
@@ -253,6 +254,7 @@
{ "item": "restaur_bath", "x": [ 2, 3 ], "y": [ 3, 18 ], "chance": 25 },
{ "item": "restaur_trash", "x": 5, "y": 3, "chance": 75, "repeat": [ 1, 3 ] },
{ "item": "restaur_fridge", "x": 9, "y": [ 3, 4 ], "chance": 80, "repeat": [ 2, 8 ] },
+ { "item": "restaur_freezer", "x": 8, "y": 3, "chance": 80, "repeat": [ 2, 8 ] },
{ "item": "restaur_sink", "x": 9, "y": [ 6, 7 ], "chance": 75, "repeat": [ 2, 3 ] },
{ "item": "restaur_kitchen", "x": 9, "y": 5, "chance": 75, "repeat": [ 1, 8 ] },
{ "item": "restaur_kitchen", "x": 9, "y": [ 8, 9 ], "chance": 75, "repeat": [ 1, 8 ] },
@@ -356,7 +358,7 @@
"=| HtHHtH tt|=",
"=| HtHHtH HH|=",
"=|-+----- -----------|=",
- "=|S T|< | ###ffff|xxx|=",
+ "=|S T|< | ###Ffff|xxx|=",
"=|r -|L + c 7|=",
"=|S T|L |r ##GGGxx|xxx|=",
"=|--------+-----------|=",
@@ -399,6 +401,7 @@
"S": "f_sink",
"Y": "f_rack_coat",
"f": "f_fridge",
+ "F": "f_freezer",
"L": "f_locker",
"r": "f_trashcan",
"t": "f_table"
@@ -422,7 +425,8 @@
{ "item": "soup_bar", "x": 10, "y": 10, "chance": 75, "repeat": [ 1, 6 ] },
{ "item": "soup_bar", "x": 11, "y": 10, "chance": 75, "repeat": [ 1, 6 ] },
{ "item": "coat_rack", "x": 6, "y": [ 17, 18 ], "chance": 60, "repeat": [ 2, 4 ] },
- { "item": "restaur_fridge", "x": [ 14, 17 ], "y": 16, "chance": 60, "repeat": [ 1, 8 ] },
+ { "item": "restaur_fridge", "x": [ 15, 17 ], "y": 16, "chance": 60, "repeat": [ 1, 8 ] },
+ { "item": "restaur_freezer", "x": 14, "y": 16, "chance": 60, "repeat": [ 1, 8 ] },
{ "item": "restaur_kitchen", "x": [ 16, 17 ], "y": 18, "chance": 60, "repeat": [ 1, 8 ] }
],
"place_monsters": [
diff --git a/data/json/mapgen/restaurant_fast.json b/data/json/mapgen/restaurant_fast.json
index 0a7ca0dbebb1..5dc4d3f73fd1 100644
--- a/data/json/mapgen/restaurant_fast.json
+++ b/data/json/mapgen/restaurant_fast.json
@@ -23,7 +23,7 @@
",_____ow=w=w=w+..|_____,",
",_____|ewccOwc|t-|_____,",
",_____|l=w=w=S|=S|_____,",
- ",_____||eercwx|P||_____,",
+ ",_____||ffrcwx|P||_____,",
",_____#|----o---|4_____,",
",________,_____________,",
",________,_____________,",
@@ -73,6 +73,7 @@
"c": "f_counter",
"d": "f_dumpster",
"e": "f_fridge",
+ "f": "f_freezer",
"g": "f_trashcan",
"l": "f_locker",
"r": "f_oven"
diff --git a/data/json/mapgen/s_furniture.json b/data/json/mapgen/s_furniture.json
index 54a55ea410da..85599da1ad50 100644
--- a/data/json/mapgen/s_furniture.json
+++ b/data/json/mapgen/s_furniture.json
@@ -9,7 +9,7 @@
"rows": [
" ",
" |ggggggggg++ggggggggg| ",
- " |.CphpH.c....O.O.&.&.| ",
+ " |.CphpH.c....O.O.&F&.| ",
" |B.....kc...........y| ",
" |B....ccc...........f| ",
" |v..........#.m..e..B| ",
@@ -60,6 +60,7 @@
"h": "f_chair",
"m": "f_sofa",
"f": "f_filing_cabinet",
+ "F": "f_freezer",
"o": "f_toilet",
"p": "f_rack_coat",
"q": "f_displaycase",
diff --git a/data/json/mapgen/s_grocery.json b/data/json/mapgen/s_grocery.json
index a618880db0e2..8fc7ac2924ba 100644
--- a/data/json/mapgen/s_grocery.json
+++ b/data/json/mapgen/s_grocery.json
@@ -26,7 +26,7 @@
"|TS|^ A|r r|t t|r r|_",
"|ll+ A|r r|t t|r r|_",
"|--|-I-- |_",
- "__4|**C|[[[[-[[[[-[[[[|_",
+ "__4|**C| |_",
"___|**C|]]]]]]]]]]]]]]|_",
"___L***+**************|_",
"___|------------------|_"
@@ -67,7 +67,7 @@
"7": "f_bookcase",
"C": "f_crate_c",
"S": "f_sink",
- "]": "f_rack",
+ "]": "f_glass_freezer",
"^": "f_indoor_plant",
"b": "f_stool",
"f": "f_glass_fridge",
diff --git a/data/json/mapgen/s_icecream.json b/data/json/mapgen/s_icecream.json
index 4ff2a90ee4d8..d080aec2899e 100644
--- a/data/json/mapgen/s_icecream.json
+++ b/data/json/mapgen/s_icecream.json
@@ -21,7 +21,7 @@
"..|cc-ff+___tt__tt__v|..",
"..|ffcff+___##__##__v|..",
"..|efcff||||||||||||||..",
- "..|ff-ff-T&-j{{{c&ccc|..",
+ "..|ff-ff-T&-j{{[c&ccc|..",
"..|ff-ffgfc-fffffffff|..",
"..|ff-k-----offfffffh|..",
"..|fffffffffffffffffh|..",
@@ -62,6 +62,7 @@
"v": "t_sidewalk",
"w": "t_window",
"{": "t_floor",
+ "[": "t_floor",
"|": "t_brick_wall",
"4": "t_gutter_downspout"
},
@@ -83,7 +84,8 @@
"o": "f_oven",
"t": "f_table",
"v": "f_vending_c",
- "{": "f_fridge"
+ "{": "f_fridge",
+ "[": "f_freezer"
},
"toilets": { "T": { } },
"place_items": [
diff --git a/data/json/recipes/other/other.json b/data/json/recipes/other/other.json
index 4df1fc656fc7..5e41894eced0 100644
--- a/data/json/recipes/other/other.json
+++ b/data/json/recipes/other/other.json
@@ -373,6 +373,72 @@
[ [ "motor_tiny", 1 ] ]
]
},
+ {
+ "type": "recipe",
+ "result": "freezer",
+ "copy-from": "fridge",
+ "qualities": [ { "id": "HAMMER", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ],
+ "components": [
+ [ [ "sheet_metal", 6 ] ],
+ [ [ "sheet_metal_small", 4 ] ],
+ [ [ "steel_chunk", 4 ] ],
+ [ [ "cable", 3 ] ],
+ [ [ "hose", 1 ] ],
+ [ [ "condensor_coil", 1 ] ],
+ [ [ "evaporator_coil", 1 ] ],
+ [ [ "refrigerant_tank", 1 ] ],
+ [ [ "thermostat", 1 ] ],
+ [ [ "light_bulb", 1 ] ],
+ [ [ "motor_tiny", 1 ] ]
+ ]
+ },
+ {
+ "type": "recipe",
+ "result": "glass_fridge",
+ "category": "CC_OTHER",
+ "subcategory": "CSC_OTHER_OTHER",
+ "skill_used": "fabrication",
+ "difficulty": 5,
+ "time": "40 m",
+ "reversible": true,
+ "decomp_learn": 5,
+ "using": [ [ "soldering_standard", 20 ], [ "welding_standard", 5 ] ],
+ "qualities": [ { "id": "HAMMER", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ],
+ "components": [
+ [ [ "sheet_metal", 4 ] ],
+ [ [ "sheet_metal_small", 3 ] ],
+ [ [ "steel_chunk", 3 ] ],
+ [ [ "cable", 3 ] ],
+ [ [ "hose", 1 ] ],
+ [ [ "reinforced_glass_pane", 1 ] ],
+ [ [ "condensor_coil", 1 ] ],
+ [ [ "evaporator_coil", 1 ] ],
+ [ [ "refrigerant_tank", 1 ] ],
+ [ [ "thermostat", 1 ] ],
+ [ [ "light_bulb", 1 ] ],
+ [ [ "motor_tiny", 1 ] ]
+ ]
+ },
+ {
+ "type": "recipe",
+ "result": "glass_freezer",
+ "copy-from": "glass_fridge",
+ "qualities": [ { "id": "HAMMER", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ],
+ "components": [
+ [ [ "sheet_metal", 4 ] ],
+ [ [ "sheet_metal_small", 3 ] ],
+ [ [ "steel_chunk", 3 ] ],
+ [ [ "cable", 3 ] ],
+ [ [ "hose", 1 ] ],
+ [ [ "reinforced_glass_pane", 1 ] ],
+ [ [ "condensor_coil", 1 ] ],
+ [ [ "evaporator_coil", 1 ] ],
+ [ [ "refrigerant_tank", 1 ] ],
+ [ [ "thermostat", 1 ] ],
+ [ [ "light_bulb", 1 ] ],
+ [ [ "motor_tiny", 1 ] ]
+ ]
+ },
{
"type": "recipe",
"result": "oven",
diff --git a/data/json/vehicleparts/utilities.json b/data/json/vehicleparts/utilities.json
index 001aa4846438..c03ef4c826f2 100644
--- a/data/json/vehicleparts/utilities.json
+++ b/data/json/vehicleparts/utilities.json
@@ -63,8 +63,6 @@
{ "count": [ 4, 7 ], "item": "steel_lump" },
{ "count": [ 4, 7 ], "item": "steel_chunk" },
{ "count": [ 4, 7 ], "item": "scrap" },
- { "item": "pan", "prob": 50 },
- { "item": "pot", "prob": 50 },
{ "charges": 0, "item": "water_purifier", "prob": 50 },
{ "charges": 0, "item": "vac_sealer", "prob": 50 },
{ "charges": 0, "item": "dehydrator", "prob": 50 },
@@ -76,7 +74,7 @@
"color": "light_green",
"damage_modifier": 10,
"damage_reduction": { "all": 20 },
- "description": "A multi-function crafting station, with a water purifier, food dehydrator, vacuum sealer, and hand press for making ammo. Draws power from the vehicle's batteries. 'e'xamine the tile with the kitchen buddy to access the water faucet or to purify water in a vehicle tank or in a container in your inventory. If you attempt craft an item that needs one of the kitchen buddy's functions, it will automatically be selected as a tool.",
+ "description": "A multi-function crafting station, with a water purifier, food processor, food dehydrator, vacuum sealer, and hand press for making ammo. Draws power from the vehicle's batteries. 'e'xamine the tile with the kitchen buddy to access the water faucet or to purify water in a vehicle tank or in a container in your inventory. If you attempt to craft an item that needs one of the kitchen buddy's functions, it will automatically be selected as a tool.",
"durability": 80,
"flags": [ "CARGO", "OBSTACLE", "CRAFTRIG", "WATER_PURIFIER", "COVERED" ],
"item": "craftrig",
diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md
index 9067af20c1a7..57b2571183e7 100644
--- a/doc/JSON_FLAGS.md
+++ b/doc/JSON_FLAGS.md
@@ -550,6 +550,8 @@ List of known flags, used in both `terrain.json` and `furniture.json`.
- ```FLAT``` Player can build and move furniture on.
- ```FORAGE_HALLU``` This item can be found with the `HIDDEN_HALLU` flag when found through foraging.
- ```FORAGE_POISION``` This item can be found with the `HIDDEN_POISON` flag when found through foraging.
+- ```FRIDGE``` This item refrigerates items inside. Preserving them. Unlike vehicle parts, any furniture with this flag constantly functions.
+- ```FREEZER``` This item freezes items inside. Preserving them extremely well. Unlike vehicle parts, any furniture with this flag constantly functions.
- ```GOES_DOWN``` Can use > to go down a level.
- ```GOES_UP``` Can use < to go up a level.
- ```GROWTH_SEED``` This plant is in its seed stage of growth.
diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md
index 2cb2665724a1..c437e750d8d2 100644
--- a/doc/JSON_INFO.md
+++ b/doc/JSON_INFO.md
@@ -2706,7 +2706,8 @@ Strength required to move the furniture around. Negative values indicate an unmo
#### `crafting_pseudo_item`
-(Optional) Id of an item (tool) that will be available for crafting when this furniture is range (the furniture acts as an item of that type).
+(Optional) Id of an item (tool) that will be available for crafting when this furniture is range (the furniture acts as an item of that type). Can be made into an array.
+Example: `"crafting_pseudo_item": [ "fake_gridwelder", "fake_gridsolderingiron" ],`
#### `workbench`
diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp
index adf9722b21ce..0ffebed06a6b 100644
--- a/src/activity_handlers.cpp
+++ b/src/activity_handlers.cpp
@@ -2684,20 +2684,25 @@ item get_fake_tool( hack_type_t hack_type, const player_activity &activity )
return fake_item;
}
const furn_t &furniture = m.furn( position ).obj();
- const itype *item_type = furniture.crafting_pseudo_item_type();
- if( item_type == nullptr ) {
- return fake_item;
- }
- if( !item_type->has_flag( "USES_GRID_POWER" ) ) {
- debugmsg( "Non grid powered furniture for long repairs is not supported yet." );
+ const std::vector item_type_list = furniture.crafting_pseudo_item_types();
+
+ if( item_type_list.empty() ) {
return fake_item;
}
- const tripoint_abs_ms abspos( m.getabs( position ) );
- const distribution_grid &grid = get_distribution_grid_tracker().grid_at( abspos );
-
- fake_item = item( item_type, calendar::turn, 0 );
- fake_item.charges = grid.get_resource( true );
+ for( const itype &item_type : item_type_list ) {
+ if( item_type.get_id() == static_cast( activity.str_values[1] ) ) {
+ if( !item_type.has_flag( "USES_GRID_POWER" ) ) {
+ debugmsg( "Non grid powered furniture for long repairs is not supported yet." );
+ return fake_item;
+ }
+ const tripoint_abs_ms abspos( m.getabs( position ) );
+ const distribution_grid &grid = get_distribution_grid_tracker().grid_at( abspos );
+ fake_item = item( item_type.get_id(), calendar::turn, 0 );
+ fake_item.charges = grid.get_resource( true );
+ break;
+ }
+ }
break;
}
}
@@ -2777,7 +2782,8 @@ void patch_activity_for_vehicle_welder(
}
void patch_activity_for_furniture( player_activity &activity,
- const tripoint &furniture_position )
+ const tripoint &furniture_position,
+ const itype_id &itt )
{
// Player may start another activity on welder/soldering iron
// Check it here instead of furniture interaction code
@@ -2796,6 +2802,7 @@ void patch_activity_for_furniture( player_activity &activity,
0, // Useless for us, set only to be compatible with vehicle
static_cast( hack_type_t::furniture )
};
+ activity.str_values.emplace_back( static_cast( itt ) );
}
} // namespace repair_activity_hack
diff --git a/src/activity_handlers.h b/src/activity_handlers.h
index 62e12e9a3497..d7be822d5f15 100644
--- a/src/activity_handlers.h
+++ b/src/activity_handlers.h
@@ -285,7 +285,8 @@ void patch_activity_for_vehicle_welder(
int interact_part_idx
);
void patch_activity_for_furniture( player_activity &activity,
- const tripoint &furniture_position );
+ const tripoint &furniture_position,
+ const itype_id &itt );
} // namespace repair_activity_hack
diff --git a/src/game.cpp b/src/game.cpp
index 72cd1e8e093d..5b35e051b1e0 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -5731,7 +5731,8 @@ void game::examine( const tripoint &examp )
add_msg( _( "It is empty." ) );
} else if( ( m.has_flag( TFLAG_FIRE_CONTAINER, examp ) &&
xfurn_t.examine == &iexamine::fireplace ) ||
- xfurn_t.examine == &iexamine::workbench ) {
+ xfurn_t.examine == &iexamine::workbench ||
+ xfurn_t.examine == &iexamine::transform ) {
return;
} else {
sounds::process_sound_markers( &u );
diff --git a/src/iexamine.cpp b/src/iexamine.cpp
index fa5c3274f002..e7c3cc43004b 100644
--- a/src/iexamine.cpp
+++ b/src/iexamine.cpp
@@ -87,6 +87,7 @@
#include "pldata.h"
#include "point.h"
#include "recipe.h"
+#include "relic.h"
#include "requirements.h"
#include "rng.h"
#include "sounds.h"
@@ -129,6 +130,7 @@ static const efftype_id effect_weak_antibiotic( "weak_antibiotic" );
static const itype_id itype_2x4( "2x4" );
static const itype_id itype_arm_splint( "arm_splint" );
+static const itype_id itype_battery( "battery" );
static const itype_id itype_bot_broken_cyborg( "bot_broken_cyborg" );
static const itype_id itype_bot_prototype_cyborg( "bot_prototype_cyborg" );
static const itype_id itype_cash_card( "cash_card" );
@@ -1633,22 +1635,47 @@ void iexamine::notify( player &, const tripoint &pos )
* Transform the examined object into the object specified by its transforms_into property. If the new object has a message property,
* it is displayed as if the notify examine_action was used.
*/
-void iexamine::transform( player &, const tripoint &pos )
+void iexamine::transform( player &p, const tripoint &pos )
{
std::string message;
+ std::string prompt;
if( g->m.has_furn( pos ) ) {
message = g->m.furn( pos ).obj().message;
- if( !message.empty() ) {
- add_msg( _( message ) );
- }
- g->m.furn_set( pos, g->m.get_furn_transforms_into( pos ) );
+ prompt = g->m.furn( pos ).obj().prompt;
} else {
message = g->m.ter( pos ).obj().message;
- if( !message.empty() ) {
- add_msg( _( message ) );
+ prompt = g->m.ter( pos ).obj().prompt;
+ }
+
+ uilist selection_menu;
+ selection_menu.text = _( "Select an action" );
+ selection_menu.addentry( 0, true, 'g', _( "Get items" ) );
+ selection_menu.addentry( 1, true, 't', !prompt.empty() ? _( prompt ) : _( "Transform furniture" ) );
+ selection_menu.query();
+
+ switch( selection_menu.ret ) {
+ case 0:
+ none( p, pos );
+ pickup::pick_up( pos, 0 );
+ return;
+ case 1: {
+ if( g->m.has_furn( pos ) ) {
+ if( !message.empty() ) {
+ add_msg( _( message ) );
+ }
+ g->m.furn_set( pos, g->m.get_furn_transforms_into( pos ) );
+ } else {
+ if( !message.empty() ) {
+ add_msg( _( message ) );
+ }
+ g->m.ter_set( pos, g->m.get_ter_transforms_into( pos ) );
+ }
+ return;
}
- g->m.ter_set( pos, g->m.get_ter_transforms_into( pos ) );
+ default:
+ none( p, pos );
+ return;
}
}
@@ -3853,22 +3880,29 @@ void iexamine::clean_water_source( player &, const tripoint &examp )
liquid_handler::handle_liquid( water, nullptr, 0, &examp );
}
-const itype *furn_t::crafting_pseudo_item_type() const
+std::vector furn_t::crafting_pseudo_item_types() const
{
- if( crafting_pseudo_item.is_empty() ) {
- return nullptr;
+ std::vector conversion;
+ for( const itype_id &itid : crafting_pseudo_items ) {
+ conversion.push_back( *itid );
}
- return &*crafting_pseudo_item;
+ return conversion;
}
-const itype *furn_t::crafting_ammo_item_type() const
+std::vector furn_t::crafting_ammo_item_types() const
{
- const itype *pseudo = crafting_pseudo_item_type();
- if( pseudo->tool && !pseudo->tool->ammo_id.empty() ) {
- const itype_id &iid = ammotype( *pseudo->tool->ammo_id.begin() )->default_ammotype();
- return &*iid;
+ const std::vector pseudo_list = crafting_pseudo_item_types();
+
+ std::vector pseudo_ammo_list;
+ if( !pseudo_list.empty() ) {
+ for( const itype &pseudo : pseudo_list ) {
+ if( pseudo.tool && !pseudo.tool->ammo_id.empty() ) {
+ const itype_id &iid = ammotype( *pseudo.tool->ammo_id.begin() )->default_ammotype();
+ pseudo_ammo_list.push_back( *iid );
+ }
+ }
}
- return nullptr;
+ return pseudo_ammo_list;
}
static int count_charges_in_list( const itype *type, const map_stack &items )
@@ -3885,21 +3919,51 @@ void iexamine::reload_furniture( player &p, const tripoint &examp )
{
map &here = get_map();
const furn_t &f = here.furn( examp ).obj();
- const itype *type = f.crafting_pseudo_item_type();
- const itype *ammo = f.crafting_ammo_item_type();
- if( type == nullptr || ammo == nullptr ) {
- add_msg( m_info, _( "This %s can not be reloaded!" ), f.name() );
+ const std::vector ammo_types = f.crafting_ammo_item_types();
+
+ // No fake item, no ammo, something is wrong here.
+ if( ammo_types.empty() ) {
+ debugmsg( ( "The %s has no crafting_pseudo_items or no defined ammo!" ), f.name() );
return;
}
+
map_stack items_here = here.i_at( examp );
- const int amount_in_furn = count_charges_in_list( ammo, items_here );
- const int amount_in_inv = p.charges_of( ammo->get_id() );
+ std::vector ammo_names;
+ std::vector ammo_filtered;
+ int ammo_index = 0;
+
+ for( const itype &at : ammo_types ) {
+ if( at.get_id() != itype_battery ) {
+ ammo_names.emplace_back( at.nname( 1 ) );
+ ammo_filtered.emplace_back( at );
+ }
+ }
+
+ if( ammo_filtered.empty() ) {
+ debugmsg( "Furniture %s has no valid ammo to reload!", f.name() );
+ return;
+ } else if( ammo_names.size() > 1 ) {
+ ammo_index = uilist( _( "What would you like to change?" ), ammo_names );
+ if( ammo_index < 0 || static_cast( ammo_index ) >= ammo_names.size() ) {
+ ammo_index = -1;
+ }
+ }
+ if( ammo_index < 0 ) {
+ return;
+ }
+
+ // HACK: Yes I know I'm converting from itype to itype_id and back again into a pointer.
+ // It seems to be needed to make the appropriate connections?
+ // Otherwise the part where it queries for the amount doesn't seem to work right.
+ const itype *cur_ammo = &*ammo_types.at( ammo_index ).get_id();
+ const int amount_in_furn = count_charges_in_list( cur_ammo, items_here );
+ const int amount_in_inv = p.charges_of( cur_ammo->get_id() );
if( amount_in_furn > 0 ) {
if( p.query_yn( _( "The %1$s contains %2$d %3$s. Unload?" ), f.name(), amount_in_furn,
- ammo->nname( amount_in_furn ) ) ) {
+ cur_ammo->nname( amount_in_furn ) ) ) {
auto items = here.i_at( examp );
for( auto &itm : items ) {
- if( itm.type == ammo ) {
+ if( itm.type == cur_ammo ) {
g->u.assign_activity( player_activity( pickup_activity_actor(
{ { item_location( map_cursor( examp ), &itm ), cata::nullopt, {} } }, g->u.pos() ) ) );
return;
@@ -3908,21 +3972,23 @@ void iexamine::reload_furniture( player &p, const tripoint &examp )
}
}
- const int max_amount_in_furn = ammo->charges_per_volume( f.max_volume );
+ // Note that this can lead to hammerspace as each ammo type doesn't take other items on the tile into account.
+ const int max_amount_in_furn = cur_ammo->charges_per_volume( f.max_volume );
const int max_reload_amount = max_amount_in_furn - amount_in_furn;
if( max_reload_amount <= 0 ) {
return;
}
if( amount_in_inv == 0 ) {
//~ Reloading or restocking a piece of furniture, for example a forge.
- add_msg( m_info, _( "You need some %1$s to reload this %2$s." ), ammo->nname( 2 ),
+ add_msg( m_info, _( "You need some %1$s to reload this %2$s." ),
+ cur_ammo->nname( 2 ),
f.name() );
return;
}
const int max_amount = std::min( amount_in_inv, max_reload_amount );
//~ Loading fuel or other items into a piece of furniture.
const std::string popupmsg = string_format( _( "Put how many of the %1$s into the %2$s?" ),
- ammo->nname( max_amount ), f.name() );
+ cur_ammo->nname( max_amount ), f.name() );
int amount = string_input_popup()
.title( popupmsg )
.width( 20 )
@@ -3932,24 +3998,25 @@ void iexamine::reload_furniture( player &p, const tripoint &examp )
if( amount <= 0 || amount > max_amount ) {
return;
}
- p.use_charges( ammo->get_id(), amount );
+ p.use_charges( cur_ammo->get_id(), amount );
auto items = here.i_at( examp );
for( auto &itm : items ) {
- if( itm.type == ammo ) {
+ if( itm.type == cur_ammo ) {
itm.charges += amount;
amount = 0;
break;
}
}
if( amount != 0 ) {
- item it( ammo, calendar::turn, amount );
+ item it( cur_ammo->get_id(), calendar::turn, amount );
here.add_item( examp, it );
}
- const int amount_in_furn_after_placing = count_charges_in_list( ammo, items );
+ const int amount_in_furn_after_placing = count_charges_in_list( &ammo_types.at( ammo_index ),
+ items );
//~ %1$s - furniture, %2$d - number, %3$s items.
add_msg( _( "The %1$s contains %2$d %3$s." ), f.name(), amount_in_furn_after_placing,
- ammo->nname( amount_in_furn_after_placing ) );
+ cur_ammo->nname( amount_in_furn_after_placing ) );
add_msg( _( "You reload the %s." ), here.furnname( examp ) );
p.moves -= to_moves( 5_seconds );
@@ -3966,24 +4033,44 @@ void iexamine::use_furn_fake_item( player &p, const tripoint &examp )
return;
}
const furn_t &furniture = m.furn( examp ).obj();
- const itype *item_type = furniture.crafting_pseudo_item_type();
- if( item_type == nullptr ) {
+ const std::vector item_type_list = furniture.crafting_pseudo_item_types();
+ std::vector usable_item_types;
+ std::vector usable_item_names;
+ if( item_type_list.empty() ) {
debugmsg(
- "Got furniture ( %s ) with use_furn_fake_item",
+ "Furniture ( %s ) with use_furn_fake_item does not have fake item to use.",
furniture.id.c_str()
);
return;
}
- if( !item_type->has_use() ) {
+ for( const itype &itt : item_type_list ) {
+ if( !itt.has_use() ) {
+ continue;
+ }
+ usable_item_types.push_back( itt );
+ usable_item_names.push_back( itt.nname( 1 ) );
+ }
+ if( usable_item_types.empty() ) {
debugmsg(
- "Got furniture ( %s ) with use_furn_fake_item but fake item %s doesn't have uses",
- furniture.id.c_str(), item_type->get_id().c_str()
- );
+ "Furniture ( %s ) with use_furn_fake_item has no fake item with uses",
+ furniture.id.c_str() );
+ return;
+ }
+
+ int tool_index = 0;
+ if( usable_item_types.size() > 1 ) {
+ tool_index = uilist( _( "Which tool do you want to use?" ), usable_item_names );
+ if( tool_index < 0 || static_cast( tool_index ) >= usable_item_types.size() ) {
+ tool_index = -1;
+ }
+ }
+ if( tool_index < 0 ) {
return;
}
- const itype *ammo = furniture.crafting_ammo_item_type();
- item fake_item( item_type, calendar::turn, 0 );
+ const itype &cur_tool = usable_item_types.at( tool_index );
+ item fake_item( cur_tool.get_id(), calendar::turn, 0 );
+ const itype_id ammo = fake_item.ammo_default();
fake_item.set_flag( "PSEUDO" );
enum class charges_type {
@@ -3997,8 +4084,8 @@ void iexamine::use_furn_fake_item( player &p, const tripoint &examp )
const distribution_grid &grid = get_distribution_grid_tracker().grid_at( abspos );
fake_item.charges = grid.get_resource();
charge_type = charges_type::grid;
- } else if( ammo != nullptr ) {
- fake_item.charges = count_charges_in_list( ammo, m.i_at( examp ) );
+ } else if( ammo != itype_id::NULL_ID() ) {
+ fake_item.charges = count_charges_in_list( &*ammo, m.i_at( examp ) );
charge_type = charges_type::ammo_from_map;
}
@@ -4006,7 +4093,8 @@ void iexamine::use_furn_fake_item( player &p, const tripoint &examp )
p.invoke_item( &fake_item );
// HACK: Evil hack incoming
- activity_handlers::repair_activity_hack::patch_activity_for_furniture( g->u.activity, examp );
+ activity_handlers::repair_activity_hack::patch_activity_for_furniture( g->u.activity, examp,
+ cur_tool.get_id() );
const int discharged_ammo = original_charges - fake_item.charges;
@@ -4020,7 +4108,7 @@ void iexamine::use_furn_fake_item( player &p, const tripoint &examp )
const int remainder = grid.mod_resource( -discharged_ammo );
if( remainder != 0 ) {
debugmsg( "Fake item %s discharged more charges than have in grid at %s.",
- item_type->get_id().c_str(), abspos.to_string() );
+ cur_tool.get_id().c_str(), abspos.to_string() );
}
return;
}
@@ -4029,7 +4117,7 @@ void iexamine::use_furn_fake_item( player &p, const tripoint &examp )
m.use_charges( examp, 0, ammo->get_id(), by_ref );
if( by_ref != 0 ) {
debugmsg( "Discharged fake item %s more ammo than %s has at %s.",
- item_type->get_id().c_str(),
+ cur_tool.get_id().c_str(),
furniture.id.c_str(),
examp.to_string()
);
@@ -4038,7 +4126,7 @@ void iexamine::use_furn_fake_item( player &p, const tripoint &examp )
}
case charges_type::none:
debugmsg( "Somehow changed charges of fake item %s without ammo type to %d.",
- item_type->get_id().c_str(),
+ cur_tool.get_id().c_str(),
fake_item.charges
);
return;
diff --git a/src/inventory.cpp b/src/inventory.cpp
index 06a93a5acf27..4bd894d56045 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -515,19 +515,21 @@ void inventory::form_from_map( map &m, std::vector pts, const Characte
for( const tripoint &p : pts ) {
if( m.has_furn( p ) ) {
const furn_t &f = m.furn( p ).obj();
- const itype *type = f.crafting_pseudo_item_type();
- if( type != nullptr ) {
- const itype *ammo = f.crafting_ammo_item_type();
- item furn_item( type, calendar::turn, 0 );
- furn_item.set_flag( "PSEUDO" );
- if( furn_item.has_flag( "USES_GRID_POWER" ) ) {
- // TODO: The grid tracker should correspond to map!
- auto &grid = get_distribution_grid_tracker().grid_at( tripoint_abs_ms( m.getabs( p ) ) );
- furn_item.charges = grid.get_resource();
- } else {
- furn_item.charges = ammo ? count_charges_in_list( ammo, m.i_at( p ) ) : 0;
+ const std::vector tool_list = f.crafting_pseudo_item_types();
+ if( !tool_list.empty() ) {
+ for( const itype &type : tool_list ) {
+ item furn_item( type.get_id(), calendar::turn, 0 );
+ furn_item.set_flag( "PSEUDO" );
+ const itype_id &ammo = furn_item.ammo_default();
+ if( furn_item.has_flag( "USES_GRID_POWER" ) ) {
+ // TODO: The grid tracker should correspond to map!
+ auto &grid = get_distribution_grid_tracker().grid_at( tripoint_abs_ms( m.getabs( p ) ) );
+ furn_item.charges = grid.get_resource();
+ } else {
+ furn_item.charges = ammo ? count_charges_in_list( &*ammo, m.i_at( p ) ) : 0;
+ }
+ add_item_by_items_type_cache( furn_item );
}
- add_item_by_items_type_cache( furn_item );
}
}
if( m.has_items( p ) && m.accessible_items( p ) ) {
diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp
index eaa2c9109788..5ea7f1241915 100644
--- a/src/iuse_actor.cpp
+++ b/src/iuse_actor.cpp
@@ -1212,6 +1212,7 @@ void deploy_furn_actor::info( const item &, std::vector &dump ) const
std::vector can_function_as;
const furn_t &the_furn = furn_type.obj();
const std::string furn_name = the_furn.name();
+ const std::set &pseudo_list = the_furn.crafting_pseudo_items;
if( the_furn.workbench ) {
can_function_as.emplace_back( _( "a crafting station" ) );
@@ -1233,7 +1234,7 @@ void deploy_furn_actor::info( const item &, std::vector &dump ) const
if( the_furn.has_flag( "FIRE_CONTAINER" ) ) {
can_function_as.emplace_back( _( "a safe place to contain a fire" ) );
}
- if( the_furn.crafting_pseudo_item == itype_char_smoker ) {
+ if( pseudo_list.count( itype_char_smoker ) > 0 ) {
can_function_as.emplace_back( _( "a place to smoke or dry food for preservation" ) );
}
diff --git a/src/map.cpp b/src/map.cpp
index 7811f6e74f3e..fcce05702060 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -4624,10 +4624,10 @@ void map::process_items_in_submap( submap ¤t_submap, const tripoint &gridp
if( ter( map_location ) == t_rootcellar ) {
flag = temperature_flag::TEMP_ROOT_CELLAR;
}
- if( furn( map_location ) == f_fridge_on ) {
+ if( has_flag_furn( TFLAG_FRIDGE, map_location ) ) {
flag = temperature_flag::TEMP_FRIDGE;
}
- if( furn( map_location ) == f_minifreezer_on ) {
+ if( has_flag_furn( TFLAG_FREEZER, map_location ) ) {
flag = temperature_flag::TEMP_FREEZER;
}
map_stack items = i_at( map_location );
@@ -4877,37 +4877,39 @@ static void use_charges_from_furn( const furn_t &f, const itype_id &type, int &q
}
}
- const itype *itt = f.crafting_pseudo_item_type();
- if( itt != nullptr && itt->item_tags.count( flag_USES_GRID_POWER ) > 0 ) {
- const tripoint_abs_ms abspos( m->getabs( p ) );
- auto &grid = get_distribution_grid_tracker().grid_at( abspos );
- item furn_item( itt, calendar::start_of_cataclysm, grid.get_resource() );
- int initial_quantity = quantity;
- if( filter( furn_item ) ) {
- furn_item.use_charges( type, quantity, ret, p );
- // That quantity math thing is atrocious. Punishment for the int& "argument".
- grid.mod_resource( quantity - initial_quantity );
- }
- } else if( itt != nullptr && itt->tool && !itt->tool->ammo_id.empty() ) {
- const itype_id ammo = ammotype( *itt->tool->ammo_id.begin() )->default_ammotype();
- auto stack = m->i_at( p );
- auto iter = std::find_if( stack.begin(), stack.end(),
- [ammo]( const item & i ) {
- return i.typeId() == ammo;
- } );
- if( iter != stack.end() ) {
- item furn_item( itt, calendar::start_of_cataclysm, iter->charges );
- if( !filter( furn_item ) ) {
- return;
+ const std::vector item_list = f.crafting_pseudo_item_types();
+ for( const itype &itt : item_list ) {
+ if( itt.item_tags.count( flag_USES_GRID_POWER ) > 0 ) {
+ const tripoint_abs_ms abspos( m->getabs( p ) );
+ auto &grid = get_distribution_grid_tracker().grid_at( abspos );
+ item furn_item( itt.get_id(), calendar::start_of_cataclysm, grid.get_resource() );
+ int initial_quantity = quantity;
+ if( filter( furn_item ) ) {
+ furn_item.use_charges( type, quantity, ret, p );
+ // That quantity math thing is atrocious. Punishment for the int& "argument".
+ grid.mod_resource( quantity - initial_quantity );
}
- // The item constructor limits the charges to the (type specific) maximum.
- // Setting it separately circumvents that it is synchronized with the code that creates
- // the pseudo item (and fills its charges) in inventory.cpp
- furn_item.charges = iter->charges;
- if( furn_item.use_charges( type, quantity, ret, p ) ) {
- stack.erase( iter );
- } else {
- iter->charges = furn_item.charges;
+ } else if( itt.tool && !itt.tool->ammo_id.empty() ) {
+ const itype_id ammo = ammotype( *itt.tool->ammo_id.begin() )->default_ammotype();
+ auto stack = m->i_at( p );
+ auto iter = std::find_if( stack.begin(), stack.end(),
+ [ammo]( const item & i ) {
+ return i.typeId() == ammo;
+ } );
+ if( iter != stack.end() ) {
+ item furn_item( itt.get_id(), calendar::start_of_cataclysm, iter->charges );
+ if( !filter( furn_item ) ) {
+ return;
+ }
+ // The item constructor limits the charges to the (type specific) maximum.
+ // Setting it separately circumvents that it is synchronized with the code that creates
+ // the pseudo item (and fills its charges) in inventory.cpp
+ furn_item.charges = iter->charges;
+ if( furn_item.use_charges( type, quantity, ret, p ) ) {
+ stack.erase( iter );
+ } else {
+ iter->charges = furn_item.charges;
+ }
}
}
}
diff --git a/src/mapdata.cpp b/src/mapdata.cpp
index ebb5abda1603..3700be966d43 100644
--- a/src/mapdata.cpp
+++ b/src/mapdata.cpp
@@ -190,8 +190,10 @@ static const std::unordered_map ter_bitflags_map = {
{ "THIN_OBSTACLE", TFLAG_THIN_OBSTACLE }, // Passable by players and monsters. Vehicles destroy it.
{ "SMALL_PASSAGE", TFLAG_SMALL_PASSAGE }, // A small passage, that large or huge things cannot pass through
{ "Z_TRANSPARENT", TFLAG_Z_TRANSPARENT }, // Doesn't block vision passing through the z-level
- { "SUN_ROOF_ABOVE", TFLAG_SUN_ROOF_ABOVE }, // This furniture has a "fake roof" above, that blocks sunlight (see #44421).
- { "SUSPENDED", TFLAG_SUSPENDED } // This furniture is suspended between other terrain, and will cause a cascading failure on break.
+ { "SUN_ROOF_ABOVE", TFLAG_SUN_ROOF_ABOVE }, // This furniture has a "fake roof" above, that blocks sunlight (see #44421).
+ { "SUSPENDED", TFLAG_SUSPENDED }, // This furniture is suspended between other terrain, and will cause a cascading failure on break.
+ { "FRIDGE", TFLAG_FRIDGE }, // This is an active fridge.
+ { "FREEZER", TFLAG_FREEZER }, // This is an active freezer.
}
};
@@ -1103,7 +1105,7 @@ furn_id f_null,
f_chair, f_armchair, f_sofa, f_cupboard, f_trashcan, f_desk, f_exercise,
f_ball_mach, f_bench, f_lane, f_table, f_pool_table,
f_counter,
- f_fridge, f_fridge_on, f_minifreezer_on, f_glass_fridge, f_dresser, f_locker,
+ f_fridge, f_fridge_on, f_minifreezer_on, f_glass_fridge, f_freezer, f_dresser, f_locker,
f_rack, f_bookcase,
f_washer, f_dryer,
f_vending_c, f_vending_o, f_dumpster, f_dive_block,
@@ -1176,6 +1178,7 @@ void set_furn_ids()
f_fridge_on = furn_id( "f_fridge_on" );
f_minifreezer_on = furn_id( "f_minifreezer_on" );
f_glass_fridge = furn_id( "f_glass_fridge" );
+ f_freezer = furn_id( "f_freezer" );
f_dresser = furn_id( "f_dresser" );
f_locker = furn_id( "f_locker" );
f_rack = furn_id( "f_rack" );
@@ -1316,6 +1319,7 @@ void map_data_common_t::load( const JsonObject &jo, const std::string &src )
mandatory( jo, was_loaded, "description", description );
optional( jo, was_loaded, "message", message );
+ optional( jo, was_loaded, "prompt", prompt );
assign( jo, "flags", flags );
bitflags.reset();
@@ -1531,7 +1535,6 @@ void furn_t::load( const JsonObject &jo, const std::string &src )
optional( jo, was_loaded, "keg_capacity", keg_capacity, legacy_volume_reader, 0_ml );
mandatory( jo, was_loaded, "required_str", move_str_req );
optional( jo, was_loaded, "max_volume", max_volume, volume_reader(), DEFAULT_MAX_VOLUME_IN_SQUARE );
- optional( jo, was_loaded, "crafting_pseudo_item", crafting_pseudo_item, itype_id() );
optional( jo, was_loaded, "deployed_item", deployed_item );
load_symbol( jo );
@@ -1554,6 +1557,9 @@ void furn_t::load( const JsonObject &jo, const std::string &src )
JsonIn &jsin = *jo.get_raw( "active" );
active.deserialize( jsin );
}
+
+ assign( jo, "crafting_pseudo_item", crafting_pseudo_items );
+
}
void map_data_common_t::check() const
diff --git a/src/mapdata.h b/src/mapdata.h
index 15ae0b7da2ff..6bcce1467625 100644
--- a/src/mapdata.h
+++ b/src/mapdata.h
@@ -321,6 +321,8 @@ enum ter_bitflags : int {
TFLAG_Z_TRANSPARENT,
TFLAG_SUN_ROOF_ABOVE,
TFLAG_SUSPENDED,
+ TFLAG_FRIDGE,
+ TFLAG_FREEZER,
NUM_TERFLAGS
};
@@ -394,6 +396,8 @@ struct map_data_common_t {
// Message text for notify and transform examine actions
std::string message;
+ // Prompt text for transform_examine actions
+ std::string prompt;
iexamine_function examine; // What happens when the terrain/furniture is examined
@@ -498,7 +502,7 @@ struct furn_t : map_data_common_t {
furn_str_id close; // Close action: transform into furniture with matching id
furn_str_id transforms_into; // Transform into what furniture?
- itype_id crafting_pseudo_item;
+ std::set crafting_pseudo_items;
units::volume keg_capacity = 0_ml;
int comfort = 0;
int floor_bedding_warmth = 0;
@@ -518,10 +522,8 @@ struct furn_t : map_data_common_t {
cata::poly_serialized active;
- // May return NULL
- const itype *crafting_pseudo_item_type() const;
- // May return NULL
- const itype *crafting_ammo_item_type() const;
+ std::vector crafting_pseudo_item_types() const;
+ std::vector crafting_ammo_item_types() const;
furn_t();
@@ -679,7 +681,7 @@ extern furn_id f_null,
f_chair, f_armchair, f_sofa, f_cupboard, f_trashcan, f_desk, f_exercise,
f_bench, f_table, f_pool_table,
f_counter,
- f_fridge, f_fridge_on, f_minifreezer_on, f_glass_fridge, f_dresser, f_locker,
+ f_fridge, f_fridge_on, f_minifreezer_on, f_glass_fridge, f_freezer, f_dresser, f_locker,
f_rack, f_bookcase,
f_washer, f_dryer,
f_vending_c, f_vending_o, f_dumpster, f_dive_block,
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index b73f73a86e7c..66046af5c181 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -6097,7 +6097,7 @@ void science_room( map *m, const point &p1, const point &p2, int z, int rotate )
} while( !one_in( 5 ) );
if( rotate == 0 ) {
mremove_trap( m, point( p1.x, p2.y ) );
- m->furn_set( point( p1.x, p2.y ), f_fridge );
+ m->furn_set( point( p1.x, p2.y ), f_freezer );
m->place_items( item_group_id( "goo" ), 60, point( p1.x, p2.y ), point( p1.x, p2.y ), false,
calendar::start_of_cataclysm );
} else if( rotate == 1 ) {
@@ -6107,7 +6107,7 @@ void science_room( map *m, const point &p1, const point &p2, int z, int rotate )
calendar::start_of_cataclysm );
} else if( rotate == 2 ) {
mremove_trap( m, point( p2.x, p1.y ) );
- m->furn_set( point( p2.x, p1.y ), f_fridge );
+ m->furn_set( point( p2.x, p1.y ), f_freezer );
m->place_items( item_group_id( "goo" ), 60, point( p2.x, p1.y ), point( p2.x, p1.y ), false,
calendar::start_of_cataclysm );
} else {