diff --git a/data/json/construction.json b/data/json/construction.json index 86a0ff56b1cf..2e01e281b523 100644 --- a/data/json/construction.json +++ b/data/json/construction.json @@ -7,6 +7,7 @@ "required_skills": [ [ "fabrication", 0 ] ], "time": "20 m", "qualities": [ [ { "id": "PRY", "level": 1 } ], [ { "id": "SCREW", "level": 1 } ] ], + "deny_flags": [ "ADV_DECONSTRUCT" ], "pre_special": "check_deconstruct", "post_flags": [ "keep_items" ], "post_special": "done_deconstruct" @@ -20,6 +21,7 @@ "time": "10 s", "pre_note": "Certain terrain and furniture can be deconstructed without any tools.", "pre_flags": "EASY_DECONSTRUCT", + "deny_flags": [ "ADV_DECONSTRUCT" ], "pre_special": "check_deconstruct", "post_flags": [ "keep_items" ], "dark_craftable": true, diff --git a/data/json/deconstruction.json b/data/json/deconstruction.json index 36cd1925d542..b16ac7aa2843 100644 --- a/data/json/deconstruction.json +++ b/data/json/deconstruction.json @@ -782,342 +782,227 @@ "type": "construction", "id": "constr_remove_object_fireplace", "//": "Breaks a fireplace apart giving you back most of the rocks used in its construction.", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "fabrication", 2 ] ], "time": "90 m", "using": [ [ "object_deconstruction_advanced", 1 ] ], - "byproducts": [ { "item": "rock", "count": [ 35, 40 ] } ], "pre_furniture": "f_fireplace", - "post_furniture": "f_null", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_electrical_conduit", "//": "Breaks an electrical conduit.", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "fabrication", 2 ], [ "electronics", 3 ] ], "time": "90 m", "using": [ [ "advanced_electronics_high_voltage", 1 ] ], - "byproducts": [ - { "item": "scrap", "count": [ 1, 4 ] }, - { "item": "scrap_copper", "count": [ 10, 20 ] }, - { "item": "cable", "charges": [ 20, 100 ] }, - { "item": "pipe", "count": [ 1, 2 ] } - ], "pre_furniture": "f_electrical_conduit", - "post_furniture": "f_null", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_capacitor_bank", "//": "Removes a capacitor bank", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "fabrication", 3 ], [ "electronics", 8 ] ], "time": "120 m", "using": [ [ "advanced_electronics_high_voltage", 1 ] ], - "byproducts": [ - { "item": "scrap", "count": [ 1, 4 ] }, - { "item": "cable", "charges": [ 100, 800 ] }, - { "item": "pipe", "count": [ 0, 4 ] }, - { "item": "circuit", "count": [ 0, 5 ] }, - { "item": "e_scrap", "count": [ 2, 8 ] }, - { "item": "amplifier", "count": [ 0, 4 ] }, - { "item": "power_supply", "count": [ 0, 2 ] }, - { "item": "metal_tank_little", "count": [ 0, 6 ] } - ], "pre_furniture": "f_capacitor", - "post_furniture": "f_null", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_t_console_broken", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 0 ] ], "time": "20 m", "qualities": [ { "id": "SCREW", "level": 1 } ], - "byproducts": [ - { "item": "processor", "count": [ 1, 2 ] }, - { "item": "RAM", "count": [ 4, 8 ] }, - { "item": "cable", "charges": [ 4, 6 ] }, - { "item": "large_lcd_screen", "count": 1 }, - { "item": "e_scrap", "count": [ 10, 16 ] }, - { "item": "circuit", "count": [ 6, 10 ] }, - { "item": "power_supply", "count": [ 2, 4 ] }, - { "item": "amplifier", "count": [ 2, 4 ] }, - { "item": "plastic_chunk", "count": [ 10, 12 ] }, - { "item": "scrap", "count": [ 6, 8 ] } - ], "pre_terrain": "t_console_broken", - "post_terrain": "t_floor", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_t_console", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 0 ] ], "time": "20 m", "qualities": [ { "id": "SCREW", "level": 1 } ], - "byproducts": [ - { "item": "processor", "count": [ 1, 2 ] }, - { "item": "RAM", "count": [ 4, 8 ] }, - { "item": "cable", "charges": [ 4, 6 ] }, - { "item": "large_lcd_screen", "count": 1 }, - { "item": "e_scrap", "count": [ 10, 16 ] }, - { "item": "circuit", "count": [ 6, 10 ] }, - { "item": "power_supply", "count": [ 2, 4 ] }, - { "item": "amplifier", "count": [ 2, 4 ] }, - { "item": "plastic_chunk", "count": [ 10, 12 ] }, - { "item": "scrap", "count": [ 6, 8 ] } - ], "pre_terrain": "t_console", - "post_terrain": "t_floor", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_plut_generator", "//": "Removes a Plut Gen.", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "fabrication", 2 ], [ "electronics", 6 ] ], "time": "90 m", "using": [ [ "advanced_electronics_high_voltage", 1 ] ], - "byproducts": [ - { "item": "plut_generator_item", "charges": [ 1, 1 ] }, - { "item": "power_supply", "charges": [ 3, 3 ] }, - { "item": "cable", "charges": [ 15, 15 ] } - ], "pre_terrain": "t_plut_generator", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_grid_plut_generator", "//": "Removes a Plut Gen from grid.", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "fabrication", 2 ], [ "electronics", 6 ] ], "time": "30 m", "using": [ [ "advanced_electronics_high_voltage", 1 ] ], - "byproducts": [ - { "item": "plut_generator_item", "charges": [ 1, 1 ] }, - { "item": "power_supply", "charges": [ 3, 3 ] }, - { "item": "cable", "charges": [ 15, 15 ] } - ], "pre_furniture": "f_grid_plut_generator", - "post_furniture": "f_null", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_sai_box", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 1 ] ], "time": "30 m", "using": [ [ "advanced_electronics_low_voltage", 1 ] ], - "byproducts": [ - { "item": "RAM", "count": [ 4, 8 ] }, - { "item": "cable", "charges": [ 16, 40 ] }, - { "item": "small_lcd_screen", "count": [ 2, 4 ] }, - { "item": "e_scrap", "count": [ 12, 24 ] }, - { "item": "circuit", "count": [ 6, 30 ] }, - { "item": "power_supply", "count": [ 4, 8 ] }, - { "item": "amplifier", "count": [ 3, 6 ] }, - { "item": "plastic_chunk", "count": [ 4, 8 ] }, - { "item": "scrap", "count": [ 8, 16 ] } - ], "pre_terrain": "t_sai_box", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_sai_box_damaged", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 1 ] ], "time": "35 m", "using": [ [ "advanced_electronics_low_voltage", 1 ] ], - "byproducts": [ - { "item": "RAM", "count": [ 1, 2 ] }, - { "item": "cable", "charges": [ 4, 24 ] }, - { "item": "e_scrap", "count": [ 4, 12 ] }, - { "item": "circuit", "count": [ 2, 12 ] }, - { "item": "power_supply", "count": [ 1, 4 ] }, - { "item": "amplifier", "count": [ 1, 3 ] }, - { "item": "plastic_chunk", "count": [ 2, 6 ] }, - { "item": "scrap", "count": [ 6, 12 ] } - ], "pre_terrain": "t_sai_box_damaged", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_t_oil_circ_brkr_l", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 5 ] ], "time": "60 m", "using": [ [ "advanced_electronics_high_voltage", 1 ] ], - "byproducts": [ - { "item": "cable", "charges": [ 8, 24 ] }, - { "item": "power_supply", "count": [ 4, 8 ] }, - { "item": "amplifier", "count": [ 8, 16 ] }, - { "item": "steel_chunk", "count": [ 4, 16 ] }, - { "item": "scrap", "count": [ 12, 24 ] }, - { "item": "sheet_metal", "count": [ 6, 12 ] }, - { "item": "ceramic_shard", "count": [ 2, 6 ] } - ], "pre_terrain": "t_oil_circ_brkr_l", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_t_oil_circ_brkr_s", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 5 ] ], "time": "45 m", "using": [ [ "advanced_electronics_high_voltage", 1 ] ], - "byproducts": [ - { "item": "cable", "charges": [ 4, 12 ] }, - { "item": "power_supply", "count": [ 3, 6 ] }, - { "item": "amplifier", "count": [ 6, 12 ] }, - { "item": "steel_chunk", "count": [ 2, 12 ] }, - { "item": "scrap", "count": [ 8, 18 ] }, - { "item": "sheet_metal", "count": [ 4, 8 ] }, - { "item": "ceramic_shard", "count": [ 1, 4 ] } - ], "pre_terrain": "t_oil_circ_brkr_s", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_t_switchgear_l", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 1 ] ], "time": "45 m", "using": [ [ "advanced_electronics_low_voltage", 1 ] ], - "byproducts": [ - { "item": "RAM", "count": [ 2, 6 ] }, - { "item": "cable", "charges": [ 4, 24 ] }, - { "item": "small_lcd_screen", "count": [ 6, 12 ] }, - { "item": "e_scrap", "count": [ 16, 24 ] }, - { "item": "circuit", "count": [ 12, 30 ] }, - { "item": "power_supply", "count": [ 6, 8 ] }, - { "item": "amplifier", "count": [ 6, 8 ] }, - { "item": "plastic_chunk", "count": [ 2, 4 ] }, - { "item": "scrap", "count": [ 8, 16 ] }, - { "item": "sheet_metal", "count": [ 2, 4 ] } - ], "pre_terrain": "t_switchgear_l", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_t_switchgear_s", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 1 ] ], "time": "35 m", "using": [ [ "advanced_electronics_low_voltage", 1 ] ], - "byproducts": [ - { "item": "RAM", "count": [ 1, 2 ] }, - { "item": "cable", "charges": [ 2, 8 ] }, - { "item": "small_lcd_screen", "count": [ 2, 6 ] }, - { "item": "e_scrap", "count": [ 6, 12 ] }, - { "item": "circuit", "count": [ 8, 24 ] }, - { "item": "power_supply", "count": [ 2, 6 ] }, - { "item": "amplifier", "count": [ 1, 4 ] }, - { "item": "plastic_chunk", "count": [ 1, 2 ] }, - { "item": "scrap", "count": [ 4, 8 ] }, - { "item": "sheet_metal", "count": [ 1, 2 ] } - ], "pre_terrain": "t_switchgear_s", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_t_lgtn_arrest", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 0 ] ], "time": "20 m", "using": [ [ "advanced_electronics_low_voltage", 1 ] ], - "byproducts": [ - { "item": "cable", "charges": [ 0, 4 ] }, - { "item": "scrap", "count": [ 8, 12 ] }, - { "item": "steel_chunk", "count": [ 2, 4 ] }, - { "item": "ceramic_shard", "count": [ 8, 16 ] } - ], "pre_terrain": "t_lgtn_arrest", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_t_station_disc", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 2 ] ], "time": "35 m", "using": [ [ "advanced_electronics_high_voltage", 1 ] ], - "byproducts": [ - { "item": "RAM", "count": [ 12, 24 ] }, - { "item": "cable", "charges": [ 6, 12 ] }, - { "item": "small_lcd_screen", "count": [ 8, 16 ] }, - { "item": "e_scrap", "count": [ 8, 12 ] }, - { "item": "circuit", "count": [ 6, 18 ] }, - { "item": "power_supply", "count": [ 8, 12 ] }, - { "item": "amplifier", "count": [ 2, 4 ] }, - { "item": "plastic_chunk", "count": [ 4, 8 ] }, - { "item": "scrap", "count": [ 2, 6 ] }, - { "item": "sheet_metal", "count": [ 1, 2 ] }, - { "item": "lead", "charges": [ 1, 2 ] }, - { "item": "ceramic_shard", "count": [ 2, 6 ] } - ], "pre_terrain": "t_station_disc", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_t_current_trans", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 3 ] ], "time": "45 m", "using": [ [ "advanced_electronics_high_voltage", 1 ] ], - "byproducts": [ - { "item": "scrap", "count": [ 12, 16 ] }, - { "item": "steel_chunk", "count": [ 4, 6 ] }, - { "item": "lead", "charges": [ 4, 16 ] }, - { "item": "cable", "charges": [ 60, 120 ] }, - { "item": "sheet_metal", "count": [ 2, 6 ] }, - { "item": "ceramic_shard", "count": [ 4, 12 ] } - ], "pre_terrain": "t_current_trans", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" }, { "type": "construction", "id": "constr_remove_t_potential_trans", - "category": "CONSTRUCT", + "category": "OTHER", "required_skills": [ [ "electronics", 4 ] ], "time": "55 m", "using": [ [ "advanced_electronics_high_voltage", 1 ] ], - "byproducts": [ - { "item": "scrap", "count": [ 12, 16 ] }, - { "item": "steel_chunk", "count": [ 4, 6 ] }, - { "item": "lead", "charges": [ 12, 32 ] }, - { "item": "cable", "charges": [ 20, 40 ] }, - { "item": "sheet_metal", "count": [ 2, 6 ] }, - { "item": "ceramic_shard", "count": [ 4, 12 ] } - ], + "byproducts": [ ], "pre_terrain": "t_potential_trans", - "post_terrain": "t_concrete", + "pre_special": "check_deconstruct", + "post_flags": [ "keep_items" ], + "post_special": "done_deconstruct", "group": "advanced_object_deconstruction" } ] diff --git a/data/json/furniture_and_terrain/furniture-appliances.json b/data/json/furniture_and_terrain/furniture-appliances.json index 42f1f2a45d9e..d3fcb21f80ba 100644 --- a/data/json/furniture_and_terrain/furniture-appliances.json +++ b/data/json/furniture_and_terrain/furniture-appliances.json @@ -2508,7 +2508,14 @@ "move_cost_mod": -1, "coverage": 60, "required_str": -1, - "flags": [ "TRANSPARENT", "NOITEM", "REDUCE_SCENT", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "NOITEM", "REDUCE_SCENT", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "items": [ + { "item": "plut_generator_item", "count": 1 }, + { "item": "cable", "charges": 15 }, + { "item": "power_supply", "count": 3 } + ] + }, "bash": { "str_min": 50, "str_max": 400, @@ -2524,13 +2531,6 @@ "//": "Variable reduction, destroy_threshold equal to str_min instead of str_max due to delicate electronics", "ranged": { "reduction": [ 25, 50 ], "destroy_threshold": 50, "block_unaimed_chance": "50%" } }, - "deconstruct": { - "items": [ - { "item": "plut_generator_item", "count": 1 }, - { "item": "cable", "charges": 15 }, - { "item": "power_supply", "count": 3 } - ] - }, "//2": "Please keep steady_consumer to 300 s or more to avoid lag.", "active": [ "steady_consumer", { "power": -100, "consume_every": "300 s" } ] }, diff --git a/data/json/furniture_and_terrain/furniture-fireplaces.json b/data/json/furniture_and_terrain/furniture-fireplaces.json index ed8c4c521b9e..4f3a637c5e78 100644 --- a/data/json/furniture_and_terrain/furniture-fireplaces.json +++ b/data/json/furniture_and_terrain/furniture-fireplaces.json @@ -9,7 +9,8 @@ "move_cost_mod": 2, "coverage": 90, "required_str": -1, - "flags": [ "TRANSPARENT", "CONTAINER", "FIRE_CONTAINER", "SUPPRESS_SMOKE", "PLACE_ITEM", "MINEABLE" ], + "flags": [ "TRANSPARENT", "CONTAINER", "FIRE_CONTAINER", "SUPPRESS_SMOKE", "PLACE_ITEM", "MINEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { "items": [ { "item": "rock", "count": [ 35, 40 ] } ] }, "examine_action": "fireplace", "bash": { "str_min": 50, diff --git a/data/json/furniture_and_terrain/furniture-industrial.json b/data/json/furniture_and_terrain/furniture-industrial.json index a85dd8e1451d..ce7767fcf3a5 100644 --- a/data/json/furniture_and_terrain/furniture-industrial.json +++ b/data/json/furniture_and_terrain/furniture-industrial.json @@ -227,7 +227,15 @@ "move_cost_mod": 1, "coverage": 30, "required_str": -1, - "flags": [ "TRANSPARENT", "NOCOLLIDE" ], + "flags": [ "TRANSPARENT", "NOCOLLIDE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "items": [ + { "item": "scrap", "count": [ 1, 4 ] }, + { "item": "scrap_copper", "count": [ 10, 20 ] }, + { "item": "cable", "charges": [ 20, 100 ] }, + { "item": "pipe", "count": [ 1, 2 ] } + ] + }, "bash": { "str_min": 10, "str_max": 100, @@ -254,7 +262,19 @@ "move_cost_mod": 4, "coverage": 40, "required_str": -1, - "flags": [ "TRANSPARENT", "MOUNTABLE" ], + "flags": [ "TRANSPARENT", "MOUNTABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "items": [ + { "item": "scrap", "count": [ 1, 4 ] }, + { "item": "cable", "charges": [ 100, 800 ] }, + { "item": "pipe", "count": [ 0, 4 ] }, + { "item": "circuit", "count": [ 0, 5 ] }, + { "item": "e_scrap", "count": [ 2, 8 ] }, + { "item": "amplifier", "count": [ 0, 4 ] }, + { "item": "power_supply", "count": [ 0, 2 ] }, + { "item": "metal_tank_little", "count": [ 0, 6 ] } + ] + }, "bash": { "str_min": 25, "str_max": 200, diff --git a/data/json/furniture_and_terrain/terrain-manufactured.json b/data/json/furniture_and_terrain/terrain-manufactured.json index a7473da10f5c..0357ef14b819 100644 --- a/data/json/furniture_and_terrain/terrain-manufactured.json +++ b/data/json/furniture_and_terrain/terrain-manufactured.json @@ -713,7 +713,15 @@ "color": "light_green", "looks_like": "t_machinery_electronic", "move_cost": 0, - "flags": [ "TRANSPARENT", "NOITEM", "REDUCE_SCENT", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "NOITEM", "REDUCE_SCENT", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "plut_generator_item", "charges": [ 1, 1 ] }, + { "item": "power_supply", "charges": [ 3, 3 ] }, + { "item": "cable", "charges": [ 15, 15 ] } + ] + }, "bash": { "str_min": 50, "str_max": 400, @@ -742,7 +750,21 @@ "looks_like": "t_machinery_electronic", "move_cost": 0, "coverage": 90, - "flags": [ "NOITEM", "WALL" ], + "flags": [ "NOITEM", "WALL", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "RAM", "count": [ 4, 8 ] }, + { "item": "cable", "charges": [ 16, 40 ] }, + { "item": "small_lcd_screen", "count": [ 2, 4 ] }, + { "item": "e_scrap", "count": [ 12, 24 ] }, + { "item": "circuit", "count": [ 6, 30 ] }, + { "item": "power_supply", "count": [ 4, 8 ] }, + { "item": "amplifier", "count": [ 3, 6 ] }, + { "item": "plastic_chunk", "count": [ 4, 8 ] }, + { "item": "scrap", "count": [ 8, 16 ] } + ] + }, "bash": { "str_min": 8, "str_max": 80, @@ -763,7 +785,20 @@ "looks_like": "f_wreckage", "move_cost": 0, "coverage": 90, - "flags": [ "NOITEM", "WALL" ], + "flags": [ "NOITEM", "WALL", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "RAM", "count": [ 1, 2 ] }, + { "item": "cable", "charges": [ 4, 24 ] }, + { "item": "e_scrap", "count": [ 4, 12 ] }, + { "item": "circuit", "count": [ 2, 12 ] }, + { "item": "power_supply", "count": [ 1, 4 ] }, + { "item": "amplifier", "count": [ 1, 3 ] }, + { "item": "plastic_chunk", "count": [ 2, 6 ] }, + { "item": "scrap", "count": [ 6, 12 ] } + ] + }, "bash": { "str_min": 6, "str_max": 80, @@ -791,7 +826,19 @@ "looks_like": "t_machinery_electronic", "move_cost": 0, "coverage": 90, - "flags": [ "TRANSPARENT", "FLAMMABLE", "NOITEM", "WALL", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "FLAMMABLE", "NOITEM", "WALL", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "cable", "charges": [ 8, 24 ] }, + { "item": "power_supply", "count": [ 4, 8 ] }, + { "item": "amplifier", "count": [ 8, 16 ] }, + { "item": "steel_chunk", "count": [ 4, 16 ] }, + { "item": "scrap", "count": [ 12, 24 ] }, + { "item": "sheet_metal", "count": [ 6, 12 ] }, + { "item": "ceramic_shard", "count": [ 2, 6 ] } + ] + }, "bash": { "str_min": 20, "str_max": 150, @@ -818,7 +865,19 @@ "looks_like": "t_machinery_electronic", "move_cost": 0, "coverage": 65, - "flags": [ "TRANSPARENT", "FLAMMABLE", "NOITEM", "WALL", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "FLAMMABLE", "NOITEM", "WALL", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "cable", "charges": [ 4, 12 ] }, + { "item": "power_supply", "count": [ 3, 6 ] }, + { "item": "amplifier", "count": [ 6, 12 ] }, + { "item": "steel_chunk", "count": [ 2, 12 ] }, + { "item": "scrap", "count": [ 8, 18 ] }, + { "item": "sheet_metal", "count": [ 4, 8 ] }, + { "item": "ceramic_shard", "count": [ 1, 4 ] } + ] + }, "bash": { "str_min": 20, "str_max": 150, @@ -845,7 +904,22 @@ "looks_like": "t_machinery_electronic", "move_cost": 0, "coverage": 90, - "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "RAM", "count": [ 2, 6 ] }, + { "item": "cable", "charges": [ 4, 24 ] }, + { "item": "small_lcd_screen", "count": [ 6, 12 ] }, + { "item": "e_scrap", "count": [ 16, 24 ] }, + { "item": "circuit", "count": [ 12, 30 ] }, + { "item": "power_supply", "count": [ 6, 8 ] }, + { "item": "amplifier", "count": [ 6, 8 ] }, + { "item": "plastic_chunk", "count": [ 2, 4 ] }, + { "item": "scrap", "count": [ 8, 16 ] }, + { "item": "sheet_metal", "count": [ 2, 4 ] } + ] + }, "bash": { "str_min": 20, "str_max": 150, @@ -871,7 +945,22 @@ "looks_like": "t_machinery_electronic", "move_cost": 0, "coverage": 65, - "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "RAM", "count": [ 1, 2 ] }, + { "item": "cable", "charges": [ 2, 8 ] }, + { "item": "small_lcd_screen", "count": [ 2, 6 ] }, + { "item": "e_scrap", "count": [ 6, 12 ] }, + { "item": "circuit", "count": [ 8, 24 ] }, + { "item": "power_supply", "count": [ 2, 6 ] }, + { "item": "amplifier", "count": [ 1, 4 ] }, + { "item": "plastic_chunk", "count": [ 1, 2 ] }, + { "item": "scrap", "count": [ 4, 8 ] }, + { "item": "sheet_metal", "count": [ 1, 2 ] } + ] + }, "bash": { "str_min": 20, "str_max": 150, @@ -900,7 +989,16 @@ "color": "i_light_gray", "looks_like": "t_machinery_electronic", "move_cost": 0, - "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "cable", "charges": [ 0, 4 ] }, + { "item": "scrap", "count": [ 8, 12 ] }, + { "item": "steel_chunk", "count": [ 2, 4 ] }, + { "item": "ceramic_shard", "count": [ 8, 16 ] } + ] + }, "bash": { "str_min": 20, "str_max": 150, @@ -924,7 +1022,24 @@ "color": "light_gray", "looks_like": "t_machinery_electronic", "move_cost": 0, - "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "RAM", "count": [ 12, 24 ] }, + { "item": "cable", "charges": [ 6, 12 ] }, + { "item": "small_lcd_screen", "count": [ 8, 16 ] }, + { "item": "e_scrap", "count": [ 8, 12 ] }, + { "item": "circuit", "count": [ 6, 18 ] }, + { "item": "power_supply", "count": [ 8, 12 ] }, + { "item": "amplifier", "count": [ 2, 4 ] }, + { "item": "plastic_chunk", "count": [ 4, 8 ] }, + { "item": "scrap", "count": [ 2, 6 ] }, + { "item": "sheet_metal", "count": [ 1, 2 ] }, + { "item": "lead", "charges": [ 1, 2 ] }, + { "item": "ceramic_shard", "count": [ 2, 6 ] } + ] + }, "bash": { "str_min": 20, "str_max": 150, @@ -950,7 +1065,18 @@ "looks_like": "t_machinery_electronic", "move_cost": 0, "coverage": 50, - "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "scrap", "count": [ 12, 16 ] }, + { "item": "steel_chunk", "count": [ 4, 6 ] }, + { "item": "lead", "charges": [ 4, 16 ] }, + { "item": "cable", "charges": [ 60, 120 ] }, + { "item": "sheet_metal", "count": [ 2, 6 ] }, + { "item": "ceramic_shard", "count": [ 4, 12 ] } + ] + }, "bash": { "str_min": 20, "str_max": 150, @@ -979,7 +1105,18 @@ "looks_like": "t_machinery_electronic", "move_cost": 0, "coverage": 50, - "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "NOITEM", "WALL", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_concrete", + "items": [ + { "item": "scrap", "count": [ 12, 16 ] }, + { "item": "steel_chunk", "count": [ 4, 6 ] }, + { "item": "lead", "charges": [ 12, 32 ] }, + { "item": "cable", "charges": [ 20, 40 ] }, + { "item": "sheet_metal", "count": [ 2, 6 ] }, + { "item": "ceramic_shard", "count": [ 4, 12 ] } + ] + }, "bash": { "str_min": 20, "str_max": 150, diff --git a/data/json/furniture_and_terrain/terrain-mechanisms.json b/data/json/furniture_and_terrain/terrain-mechanisms.json index b5bd2c68b290..6768342680bd 100644 --- a/data/json/furniture_and_terrain/terrain-mechanisms.json +++ b/data/json/furniture_and_terrain/terrain-mechanisms.json @@ -9,7 +9,22 @@ "move_cost": 0, "coverage": 50, "roof": "t_flat_roof", - "flags": [ "TRANSPARENT", "NOITEM", "INDOORS", "SHORT", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "NOITEM", "INDOORS", "SHORT", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_floor", + "items": [ + { "item": "processor", "count": [ 1, 2 ] }, + { "item": "RAM", "count": [ 4, 8 ] }, + { "item": "cable", "charges": [ 4, 6 ] }, + { "item": "large_lcd_screen", "count": 1 }, + { "item": "e_scrap", "count": [ 10, 16 ] }, + { "item": "circuit", "count": [ 6, 10 ] }, + { "item": "power_supply", "count": [ 2, 4 ] }, + { "item": "amplifier", "count": [ 2, 4 ] }, + { "item": "plastic_chunk", "count": [ 10, 12 ] }, + { "item": "scrap", "count": [ 6, 8 ] } + ] + }, "bash": { "str_min": 16, "str_max": 150, @@ -43,7 +58,22 @@ "coverage": 50, "light_emitted": 10, "roof": "t_flat_roof", - "flags": [ "TRANSPARENT", "CONSOLE", "NOITEM", "INDOORS", "SHORT", "PERMEABLE" ], + "flags": [ "TRANSPARENT", "CONSOLE", "NOITEM", "INDOORS", "SHORT", "PERMEABLE", "ADV_DECONSTRUCT" ], + "deconstruct": { + "ter_set": "t_floor", + "items": [ + { "item": "processor", "count": [ 1, 2 ] }, + { "item": "RAM", "count": [ 4, 8 ] }, + { "item": "cable", "charges": [ 4, 6 ] }, + { "item": "large_lcd_screen", "count": 1 }, + { "item": "e_scrap", "count": [ 10, 16 ] }, + { "item": "circuit", "count": [ 6, 10 ] }, + { "item": "power_supply", "count": [ 2, 4 ] }, + { "item": "amplifier", "count": [ 2, 4 ] }, + { "item": "plastic_chunk", "count": [ 10, 12 ] }, + { "item": "scrap", "count": [ 6, 8 ] } + ] + }, "bash": { "str_min": 8, "str_max": 150, diff --git a/data/json/items/armor/power_armor.json b/data/json/items/armor/power_armor.json index 7565dd64977e..a65fa8c64cd8 100644 --- a/data/json/items/armor/power_armor.json +++ b/data/json/items/armor/power_armor.json @@ -670,6 +670,7 @@ }, { "id": "exosuit_industrial", + "sub": "gloves_rubber", "type": "TOOL_ARMOR", "category": "armor", "name": { "str": "industrial exo-suit" }, diff --git a/data/json/items/comestibles/drink_other.json b/data/json/items/comestibles/drink_other.json index e2dde1660fee..04fc48e7dbd6 100644 --- a/data/json/items/comestibles/drink_other.json +++ b/data/json/items/comestibles/drink_other.json @@ -208,9 +208,24 @@ "type": "COMESTIBLE", "id": "cooking_oil2", "name": { "str_sp": "animal cooking oil" }, - "copy-from": "cooking_oil", + "//": "Can't copy-from the vegetable oil because it extends vitamins instead of overwriting them", + "weight": "15 g", + "color": "yellow", + "container": "jug_plastic", + "comestible_type": "DRINK", + "symbol": "~", + "quench": -1, + "healthy": -2, + "calories": 127, "description": "Thin yellow animal oil used for cooking.", + "price": "40 cent", + "price_postapoc": "5 USD", "material": [ "flesh", "oil" ], + "volume": "250 ml", + "charges": 16, + "phase": "liquid", + "fun": -25, + "flags": [ "NUTRIENT_OVERRIDE" ], "vitamins": [ [ "meat_allergen", 1 ] ] }, { diff --git a/data/json/items/comestibles/sandwich.json b/data/json/items/comestibles/sandwich.json index 6ebbcb33741e..a210bf623bb3 100644 --- a/data/json/items/comestibles/sandwich.json +++ b/data/json/items/comestibles/sandwich.json @@ -1,7 +1,29 @@ [ + { + "type": "COMESTIBLE", + "id": "sandwich_generic", + "name": { "str": "GENERIC SANDWICH", "str_pl": "GENERIC SANDWICHES" }, + "weight": "300 g", + "healthy": 1, + "calories": 300, + "color": "brown", + "spoils_in": "1 day 12 hours", + "container": "wrapper", + "comestible_type": "FOOD", + "symbol": "%", + "description": "If you can see this, you shouldn't be able to. This is to solve dumb copy-from issues.", + "price": "2 USD", + "price_postapoc": "2 USD", + "primary_material": "wheat", + "volume": "500 ml", + "material": [ "wheat" ], + "fun": 12, + "charges": 4 + }, { "type": "COMESTIBLE", "id": "sandwich_deluxe", + "copy-from": "sandwich_generic", "name": { "str": "deluxe sandwich", "str_pl": "deluxe sandwiches" }, "conditional_names": [ { @@ -23,21 +45,11 @@ { "type": "COMPONENT_ID", "condition": "soysauce", "name": "%s with soy sauce" }, { "type": "COMPONENT_ID", "condition": "seasoning_salt", "name": "%s with seasoned salt" } ], - "weight": "300 g", - "healthy": 1, - "calories": 300, - "color": "brown", - "spoils_in": "1 day 12 hours", - "container": "wrapper", - "comestible_type": "FOOD", - "symbol": "%", "description": "A sandwich of meat, vegetables, and cheese with condiments. Tasty and nutritious!", "price": "12 USD", "price_postapoc": "3 USD", "primary_material": "wheat", - "volume": "500 ml", "material": [ "flesh", "veggy", "wheat", "milk" ], - "fun": 12, "vitamins": [ [ "vitA", 8 ], [ "vitC", 26 ], @@ -48,13 +60,12 @@ [ "veggy_allergen", 1 ], [ "wheat_allergen", 1 ], [ "milk_allergen", 1 ] - ], - "charges": 4 + ] }, { "type": "COMESTIBLE", "id": "sandwich_cheese_grilled", - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "name": { "str": "grilled cheese sandwich", "str_pl": "grilled cheese sandwiches" }, "calories": 160, "description": "A delicious grilled cheese sandwich, because everything is better with melted cheese.", @@ -68,7 +79,7 @@ { "type": "COMESTIBLE", "id": "sandwich_cheese", - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "name": { "str": "cheese sandwich", "str_pl": "cheese sandwiches" }, "calories": 160, "description": "A simple cheese sandwich.", @@ -81,7 +92,7 @@ { "type": "COMESTIBLE", "id": "sandwich_jam", - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "name": { "str": "jam sandwich", "str_pl": "jam sandwiches" }, "conditional_names": [ { "type": "COMPONENT_ID", "condition": "apple", "name": "apple %s" }, @@ -122,7 +133,7 @@ { "type": "COMESTIBLE", "id": "sandwich_fairy", - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "name": { "str_sp": "fairy bread" }, "calories": 200, "description": "An 'open-faced sandwich' consisting of sliced white bread, a healthy crust-to-crust slathering of butter, and sprinkles. Supposedly a staple of birthday parties in Australia.", @@ -135,7 +146,7 @@ { "type": "COMESTIBLE", "id": "sandwich_honey", - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "name": { "str": "honey sandwich", "str_pl": "honey sandwiches" }, "calories": 200, "description": "A delicious honey sandwich.", @@ -148,7 +159,7 @@ { "type": "COMESTIBLE", "id": "sandwich_sauce", - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "name": { "str": "sauce sandwich", "str_pl": "sauce sandwiches" }, "conditional_names": [ { @@ -208,7 +219,7 @@ { "type": "COMESTIBLE", "id": "sandwich_veggy", - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "name": { "str": "vegetable sandwich", "str_pl": "vegetable sandwiches" }, "calories": 180, "description": "Bread and vegetables, that's it.", @@ -222,7 +233,7 @@ { "type": "COMESTIBLE", "id": "sandwich_t", - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "name": { "str": "meat sandwich", "str_pl": "meat sandwiches" }, "conditional_names": [ { @@ -295,7 +306,7 @@ { "type": "COMESTIBLE", "id": "fish_sandwich", - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "name": { "str": "fish sandwich", "str_pl": "fish sandwiches" }, "calories": 200, "description": "A delicious fish sandwich.", @@ -309,7 +320,7 @@ "type": "COMESTIBLE", "id": "sandwich_okay", "name": { "str": "okay sandwich", "str_pl": "okay sandwiches" }, - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "looks_like": "sandwich_deluxe", "description": "A simple sandwich, little more than meat and veggies on bread. Rather dry.", "price": "2 USD", @@ -322,7 +333,7 @@ "type": "COMESTIBLE", "id": "sandwich_deluxe_nocheese", "name": { "str": "dairy-free deluxe sandwich", "str_pl": "dairy-free deluxe sandwiches" }, - "copy-from": "sandwich_deluxe", + "copy-from": "sandwich_generic", "looks_like": "sandwich_deluxe", "conditional_names": [ { diff --git a/data/json/items/comestibles/veggy_dishes.json b/data/json/items/comestibles/veggy_dishes.json index 15e880c41080..738d88e3ebbb 100644 --- a/data/json/items/comestibles/veggy_dishes.json +++ b/data/json/items/comestibles/veggy_dishes.json @@ -908,12 +908,19 @@ "type": "COMESTIBLE", "id": "veggy_sausage", "name": "smoked veggy sausage", - "copy-from": "sausage", + "weight": "148 g", + "comestible_type": "FOOD", + "symbol": "%", + "quench": -1, "calories": 56, "healthy": 1, "material": [ "veggy" ], "description": "A plant based sausage that has been cured and smoked for long term storage.", + "price": "16 USD", + "volume": "250 ml", + "price_postapoc": "3 USD", "fun": 4, + "flags": [ "EATEN_HOT", "SMOKED" ], "vitamins": [ [ "veggy_allergen", 1 ] ] }, { diff --git a/data/json/mapgen/cs_tire_shop.json b/data/json/mapgen/cs_tire_shop.json index dd68efde6ebd..4d8219f9ee35 100644 --- a/data/json/mapgen/cs_tire_shop.json +++ b/data/json/mapgen/cs_tire_shop.json @@ -5,46 +5,45 @@ "method": "json", "weight": 1000, "object": { - "fill_ter": "t_floor", + "fill_ter": "t_thconc_floor", "rows": [ - ",..~~y''''y~~''''''~~.,`", - ".,.~~y''''y~~''''''~~..,", - "..,~~y''''y~~''''''~~,..", - ",..~~y''''y~~''''''~~.,.", - "...~~y''''y~~''''''~~...", - ",..~~y''''y~e''''''~~.,.", - "...~-ggggggg-======-g-.,", - "..,~| rrrrr eM#MM#M |..", - "...~| M#MM#M t|.,", - ".,.~| rrrrr M#MM#M t|..", - "...~| M#MM#M t|,.", - ".,.~| rrrrr M#MM#M t|..", - "...~| M#MM#M t|,.", - "..,~| rrrrr M#MM#M t|.,", - "...~| M#MM#M t|..", - ",..~| rrrrr MMMMMM |.,", - "...~D |,.", - ".,..| cc--l---- -- Sg..", - "...,| ch|L C|Vv c| Sg,.", - ".,..| |L C| c|-D-|..", - "..,.|rrr|L C|hhhh|T S|4,", - "...,-ggg-----gggg-----..", - ".,..,..,.u 0_kJ ) { json.member( "energy_stored", energy_stored ); } + json.member( "show_sprite", show_sprite ); json.end_object(); } @@ -2955,6 +2956,9 @@ void bionic::deserialize( JsonIn &jsin ) if( jo.has_float( "auto_start_threshold" ) ) { auto_start_threshold = jo.get_float( "auto_start_threshold" ); } + if( jo.has_bool( "show_sprite" ) ) { + show_sprite = jo.get_bool( "show_sprite" ); + } if( jo.has_array( "bionic_tags" ) ) { for( const std::string line : jo.get_array( "bionic_tags" ) ) { bionic_tags.insert( line ); diff --git a/src/bionics.h b/src/bionics.h index 6418f4d475cc..0c716841dcf4 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -165,6 +165,7 @@ struct bionic { int charge_timer = 0; char invlet = 'a'; bool powered = false; + bool show_sprite = true; /* Ammunition actually loaded in this bionic gun in deactivated state */ itype_id ammo_loaded = itype_id::NULL_ID(); /* Ammount of ammo actually held inside by this bionic gun in deactivated state */ diff --git a/src/bionics_ui.cpp b/src/bionics_ui.cpp index c4e8ef20e9ae..9b5f6c5889a8 100644 --- a/src/bionics_ui.cpp +++ b/src/bionics_ui.cpp @@ -258,8 +258,10 @@ static void draw_bionics_titlebar( const catacurses::window &window, Character * std::string desc_append = string_format( _( "[%s] Reassign, [%s] Switch tabs, " "[%s] Toggle fuel saving mode, " + "[%s] Toggle sprite visibility, " "[%s] Toggle auto start mode." ), ctxt.get_desc( "REASSIGN" ), ctxt.get_desc( "NEXT_TAB" ), ctxt.get_desc( "TOGGLE_SAFE_FUEL" ), + ctxt.get_desc( "TOGGLE_SPRITE" ), ctxt.get_desc( "TOGGLE_AUTO_START" ) ); desc_append += string_format( _( " [%s] Sort: %s" ), ctxt.get_desc( "SORT" ), sort_mode_str( uistate.bionic_sort_mode ) ); @@ -317,6 +319,9 @@ static std::string build_bionic_poweronly_string( const bionic &bio ) if( bio.incapacitated_time > 0_turns ) { properties.emplace_back( _( "(incapacitated)" ) ); } + if( !bio.show_sprite ) { + properties.emplace_back( _( "(hidden)" ) ); + } if( !bio.has_flag( flag_SAFE_FUEL_OFF ) && ( !bio.info().fuel_opts.empty() || bio.info().is_remote_fueled ) ) { properties.emplace_back( _( "(fuel saving ON)" ) ); @@ -630,6 +635,7 @@ void show_bionics_ui( Character &who ) ctxt.register_action( "QUIT" ); ctxt.register_action( "HELP_KEYBINDINGS" ); ctxt.register_action( "TOGGLE_SAFE_FUEL" ); + ctxt.register_action( "TOGGLE_SPRITE" ); ctxt.register_action( "TOGGLE_AUTO_START" ); ctxt.register_action( "SORT" ); @@ -840,6 +846,13 @@ void show_bionics_ui( Character &who ) popup( _( "You can't toggle auto start mode on a non-fueled CBM." ) ); } } + + } else if( action == "TOGGLE_SPRITE" ) { + auto &bio_list = tab_mode == TAB_ACTIVE ? active : passive; + if( !current_bionic_list->empty() ) { + tmp = bio_list[cursor]; + tmp->show_sprite = !tmp->show_sprite; + } } else if( action == "SORT" ) { uistate.bionic_sort_mode = pick_sort_mode(); // FIXME: is there a better way to resort? diff --git a/src/catalua_bindings.cpp b/src/catalua_bindings.cpp index a56f8c19eaaa..eb23cce4958b 100644 --- a/src/catalua_bindings.cpp +++ b/src/catalua_bindings.cpp @@ -1012,6 +1012,7 @@ void cata::reg_all_bindings( sol::state &lua ) reg_enums( lua ); reg_game_ids( lua ); mod_mutation_branch( lua ); + reg_magic( lua ); reg_coords_library( lua ); reg_constants( lua ); reg_hooks_examples( lua ); diff --git a/src/catalua_bindings.h b/src/catalua_bindings.h index 6b910d8d70f6..b34b6b8ff98c 100644 --- a/src/catalua_bindings.h +++ b/src/catalua_bindings.h @@ -33,10 +33,14 @@ void reg_locale_api( sol::state &lua ); void reg_map( sol::state &lua ); void reg_monster( sol::state &lua ); void mod_mutation_branch( sol::state &lua ); +void reg_magic( sol::state &lua ); void reg_npc( sol::state &lua ); void reg_player( sol::state &lua ); void reg_point_tripoint( sol::state &lua ); void reg_skill_level_map( sol::state &lua ); +void reg_spell_type( sol::state &lua ); +void reg_spell_fake( sol::state &lua ); +void reg_spell( sol::state &lua ); void reg_testing_library( sol::state &lua ); void reg_time_types( sol::state &lua ); void reg_types( sol::state &lua ); diff --git a/src/catalua_bindings_ids.cpp b/src/catalua_bindings_ids.cpp index 10240c6c67b3..9219f913f3f7 100644 --- a/src/catalua_bindings_ids.cpp +++ b/src/catalua_bindings_ids.cpp @@ -14,6 +14,7 @@ #include "flag_trait.h" #include "itype.h" #include "json.h" +#include "magic.h" #include "mapdata.h" #include "martialarts.h" #include "monfaction.h" @@ -123,6 +124,7 @@ void cata::detail::reg_game_ids( sol::state &lua ) reg_id( lua ); reg_id( lua ); reg_id( lua ); + reg_id( lua ); reg_id( lua ); } diff --git a/src/catalua_bindings_magic.cpp b/src/catalua_bindings_magic.cpp new file mode 100644 index 000000000000..f0434351ba19 --- /dev/null +++ b/src/catalua_bindings_magic.cpp @@ -0,0 +1,229 @@ +#ifdef LUA +#include "catalua_bindings.h" + +#include "catalua.h" +// Thx Almantuxas +#include "catalua_bindings_utils.h" +#include "catalua_impl.h" +#include "catalua_log.h" +#include "catalua_luna.h" +#include "catalua_luna_doc.h" + +#include "avatar.h" +#include "creature.h" +#include "magic.h" + +// IN WAITING: enchantment_id, enchantments in general +void cata::detail::reg_magic( sol::state &lua ) +{ + reg_spell_type( lua ); + reg_spell_fake( lua ); + reg_spell( lua ); +} + +void cata::detail::reg_spell_type( sol::state &lua ) +{ +#define UT_CLASS spell_type + { + /* NOTE: These changes are applied to the "SpellTypeRaw" Lua obj. + * Because spell_type is bound as an ID, the actual object is + * shoved into a 'Raw' binding. + */ + DOC( "The 'raw' type for storing the information defining every spell in the game. It's not possible to cast directly from this type; check SpellSimple and Spell." ); + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::no_constructor + ); + + // The string conversion function references this object's str_id. + luna::set_fx( ut, sol::meta_function::to_string, + []( const UT_CLASS & id ) -> std::string { + return string_format( "%s[%s]", luna::detail::luna_traits::name, id.id.c_str() ); + } ); + + SET_MEMB_RO( id ); + DOC( "The name of the primary effect this spell will enact." ); + SET_MEMB_RO( effect_name ); + DOC( "Specifics about the effect this spell will enact." ); + SET_MEMB_RO( effect_str ); + + // Currently unclear on how to implement 'field'; it's std::optional, + // while we want to return sol::optional. + SET_MEMB_RO( field_chance ); + SET_MEMB_RO( min_field_intensity ); + SET_MEMB_RO( field_intensity_increment ); + SET_MEMB_RO( max_field_intensity ); + SET_MEMB_RO( field_intensity_variance ); + + SET_MEMB_RO( min_damage ); + SET_MEMB_RO( damage_increment ); + SET_MEMB_RO( max_damage ); + + SET_MEMB_RO( min_range ); + SET_MEMB_RO( range_increment ); + SET_MEMB_RO( max_range ); + + SET_MEMB_RO( min_aoe ); + SET_MEMB_RO( aoe_increment ); + SET_MEMB_RO( max_aoe ); + + SET_MEMB_RO( min_dot ); + SET_MEMB_RO( dot_increment ); + SET_MEMB_RO( max_dot ); + + SET_MEMB_RO( min_duration ); + SET_MEMB_RO( duration_increment ); + SET_MEMB_RO( max_duration ); + + // Ignoring pierce damage for now, amongst other things. + + SET_MEMB_RO( base_energy_cost ); + SET_MEMB_RO( energy_increment ); + SET_MEMB_RO( final_energy_cost ); + + SET_MEMB_RO( difficulty ); + SET_MEMB_RO( max_level ); + SET_MEMB_RO( base_casting_time ); + SET_MEMB_RO( casting_time_increment ); + SET_MEMB_RO( final_casting_time ); + + DOC( "Other spells cast by this spell." ); + luna::set_fx( ut, "additional_spells", + []( const UT_CLASS & spid ) -> std::vector { + std::vector rv = spid.additional_spells; return rv; + } ); + + DOC( "Returns a (long) list of every spell in the game." ); + SET_FX_T( get_all, const std::vector &() ); + + } +#undef UT_CLASS // #define UT_CLASS spell_type +} + +void cata::detail::reg_spell_fake( sol::state &lua ) +{ +#define UT_CLASS fake_spell + { + DOC( "The type for basic spells. If you don't need to track XP from casting (e.g., if a spell is intended to be cast by anything *other than* a player), this is likely the appropriate type. Otherwise, see the Spell type." ); + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::constructors < + UT_CLASS( spell_id sp, bool hit_self ), + UT_CLASS( spell_id sp, bool hit_self, int max_level ) + > () + ); + + luna::set_fx( ut, sol::meta_function::to_string, + []( const UT_CLASS & id ) -> std::string { + return string_format( "%s[%s]", luna::detail::luna_traits::name, id.id.c_str() ); + } ); + + SET_MEMB_RO( id ); + + DOC( "Returns the defined maximum level of this SpellSimple instance, if defined. Otherwise, returns 0." ); + luna::set_fx( ut, "max_level", []( UT_CLASS & sp ) -> int { + return sp.max_level.has_value() ? *sp.max_level : 0; + } ); + + // Perhaps this should be writeable? + SET_MEMB_RO( level ); + DOC( "Whether or not the target point is *locked* to the source's location." ); + SET_MEMB_N_RO( self, "force_target_source" ); + DOC( "Used for enchantments; the spell's *chance* to trigger every turn." ); + SET_MEMB_RO( trigger_once_in ); + + // TODO: Support min_level_override + luna::set_fx( ut, "cast", + []( UT_CLASS & sp, + Creature & source, + const tripoint & target, + sol::optional min_lvl_override ) + { + int mlo = min_lvl_override.has_value() ? *min_lvl_override : 0; + sp.get_spell( mlo ).cast_all_effects( source, target ); + } + ); + + DOC( "Static function: Creates and immediately casts a SimpleSpell, then returns the new spell for potential reuse. If the given tripoint is the player's location, the spell will be locked to the player. (This does not necessarily cause friendly fire!) If an integer is specified, the spell will be cast at that level." ); + luna::set_fx( ut, "prompt_cast", + []( spell_id spid, + tripoint & target, + sol::optional level ) -> fake_spell + { + // This will be our return value, as well as the spell we cast. + fake_spell sp; + /* Without a specified Creature, we assume the player is the + * source. + * I'd prefer to call gapi.get_avatar, but this will do for now. + */ + avatar &avvy = get_avatar(); + // If target is avatar's location, assume we want to hit self + bool hit_self = avvy.pos() == target; + sp = fake_spell( spid, hit_self ); + + // If a level is given, forcefully clamp to that level. + if( level.has_value() ) + { + sp.level = *level; + sp.max_level = *level; + } + + // Now that the spell is configured, we cast it as usual... + sp.get_spell().cast_all_effects( avvy, target ); + // ...and return the spell we made for reuse. + return sp; + } + ); + } +#undef UT_CLASS // #define UT_CLASS fake_spell +} + +void cata::detail::reg_spell( sol::state &lua ) +{ +#define UT_CLASS spell + { + /* NOTE: This is the actual 'spell type', which is fully-featured and + * intended for use with players. As such, it tracks things like xp + * and level, which you may not care about. + * This functionality isn't presently important, particularly since + * there are currently no methods to access the spells in a player's + * spellbook (known_magic). + */ + DOC( "The class used for spells that *a player* knows, casts, and gains experience for using. If a given spell is not supposed to be directly cast by a player, consider using SpellSimple instead." ); + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::constructors < + UT_CLASS( spell_id, int ) + > () + ); + + // Lets us grab the ID from the object. + SET_MEMB_N_RO( type, "id" ); + + SET_FX_T( xp, int() const ); + SET_FX_T( gain_exp, void( int ) ); + SET_FX_T( set_exp, void( int ) ); + SET_FX_T( gain_levels, void( int ) ); + SET_FX_T( set_level, void( int ) ); + SET_FX_T( get_level, int() const ); + + SET_FX_T( name, std::string() const ); + SET_FX_N_T( description, "desc", std::string() const ); + + // Present priority is basic functionality. + + DOC( "Cast this spell, as well as any sub-spells." ); + SET_FX_N_T( cast_all_effects, "cast", void( Creature & source, const tripoint & target ) const ); + DOC( "Cast *only* this spell's main effects. Generally, cast() should be used instead." ); + SET_FX_N_T( cast_spell_effect, "cast_single_effect", void( Creature & source, const tripoint & target ) const ); + } +#undef UT_CLASS // #define UT_CLASS spell +} + +#endif // #ifdef LUA diff --git a/src/catalua_luna.h b/src/catalua_luna.h index 3c7fb8c945b8..fa759d632830 100644 --- a/src/catalua_luna.h +++ b/src/catalua_luna.h @@ -288,6 +288,24 @@ void doc_member( sol::table &dt, sol::types && ) } // Olanti! Curse thee for what I must do! +// NOTE: This only works with read-only properties (for now). +// It also has some pretty significant issues with intuiting the type of the +// property it's working with. +// TODO: Resolve these issues. +template +void doc_member( sol::table &dt, + sol::types> && ) +{ + dt[KEY_MEMBER_TYPE] = MEMBER_IS_VAR; + add_comment( dt, KEY_MEMBER_COMMENT ); + /* TODO: Why does this work HERE but not when it's run in doc_value_impl?! + * This may prove problematic in the future. Implementing luna_traits might + * help avert it for certain types, but I would much prefer the root problem + * solved. + */ + dt[KEY_MEMBER_VARIABLE_TYPE] = doc_value( sol::types>() ); +} + template void doc_member( sol::table &dt, sol::types> && ) { diff --git a/src/catalua_luna_doc.h b/src/catalua_luna_doc.h index 85be3ff13dfb..eec142e19108 100644 --- a/src/catalua_luna_doc.h +++ b/src/catalua_luna_doc.h @@ -44,6 +44,8 @@ class recipe; class Skill; class SkillLevel; class SkillLevelMap; +class spell_type; +class spell; class time_duration; class time_point; class tinymap; @@ -52,6 +54,7 @@ struct body_part_type; struct damage_instance; struct damage_unit; struct dealt_damage_instance; +struct fake_spell; struct field_type; struct mutation_branch; struct npc_opinion; @@ -123,6 +126,8 @@ LUNA_VAL( point, "Point" ); LUNA_VAL( query_popup, "QueryPopup" ); LUNA_VAL( SkillLevelMap, "SkillLevelMap" ); LUNA_VAL( SkillLevel, "SkillLevel" ); +LUNA_VAL( fake_spell, "SpellSimple" ) +LUNA_VAL( spell, "Spell" ) LUNA_VAL( time_duration, "TimeDuration" ); LUNA_VAL( time_point, "TimePoint" ); LUNA_VAL( tinymap, "Tinymap" ); @@ -154,6 +159,7 @@ LUNA_ID( mutation_category_trait, "MutationCategoryTrait" ) LUNA_ID( recipe, "Recipe" ) LUNA_ID( Skill, "Skill" ) LUNA_ID( species_type, "SpeciesType" ) +LUNA_ID( spell_type, "SpellType" ) LUNA_ID( ter_t, "Ter" ) // Enums diff --git a/src/character.cpp b/src/character.cpp index 631bc060878f..3cf091b1f8ca 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -3664,6 +3664,9 @@ std::vector Character::get_overlay_ids() const // then get bionics for( const bionic &bio : *my_bionics ) { + if( !bio.show_sprite ) { + continue; + } overlay_id = ( bio.powered ? "active_" : "" ) + bio.id.str(); order = get_overlay_order_of_mutation( overlay_id ); mutation_sorting.insert( std::pair( order, overlay_id ) ); diff --git a/src/construction.cpp b/src/construction.cpp index e0a52c5ec599..d0a21f6bd49e 100644 --- a/src/construction.cpp +++ b/src/construction.cpp @@ -983,6 +983,13 @@ bool can_construct( const construction &con, const tripoint &p ) bool place_okay = con.pre_special( p ); // see if the terrain type checks out place_okay &= has_pre_terrain( con, p ); + // see if the (deny) flags check out + place_okay &= std::none_of( con.deny_flags.begin(), con.deny_flags.end(), + [&p, &here]( const std::string & flag ) -> bool { + const furn_id &furn = here.furn( p ); + const ter_id &ter = here.ter( p ); + return furn == f_null ? ter->has_flag( flag ) : furn->has_flag( flag ); + } ); // see if the flags check out place_okay &= std::all_of( con.pre_flags.begin(), con.pre_flags.end(), [&p, &here]( const std::string & flag ) -> bool { @@ -1658,6 +1665,7 @@ void construction::load( const JsonObject &jo, const std::string &/*src*/ ) optional( jo, was_loaded, "post_terrain", post_terrain ); optional( jo, was_loaded, "post_furniture", post_furniture ); assign( jo, "pre_flags", pre_flags ); + optional( jo, was_loaded, "deny_flags", deny_flags ); optional( jo, was_loaded, "post_flags", post_flags ); if( jo.has_member( "byproducts" ) ) { @@ -1728,7 +1736,12 @@ void construction::load( const JsonObject &jo, const std::string &/*src*/ ) if( !post_special || !s.empty() ) { auto it = post_special_map.find( s ); if( it != post_special_map.end() ) { - post_special = it->second; + if( s == "done_deconstruct" && ( !post_terrain.is_empty() || !post_furniture.is_empty() ) ) { + jo.throw_error( "Can't use post_special function \"done_deconstruct\" alongside post_terrain/post_furniture fields", + s ); + } else { + post_special = it->second; + } } else { debugmsg( "Unknown post_special function \"%s\"", s ); } @@ -1783,7 +1796,7 @@ void construction::check() const void construction::finalize() { if( !group.is_valid() ) { - debugmsg( "Invalid construction group (%s) defiend for construction (%s)", group, id ); + debugmsg( "Invalid construction group (%s) defined for construction (%s)", group, id ); } if( vehicle_start ) { std::vector frame_items; diff --git a/src/construction.h b/src/construction.h index 64b09ef00174..d310349ff181 100644 --- a/src/construction.h +++ b/src/construction.h @@ -65,6 +65,9 @@ struct construction { // Flags beginning terrain must have std::set pre_flags; + // Flags that exclude a given terrain tile + std::set deny_flags; + // Post construction flags std::set post_flags; diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index abed5e974ee4..495195765585 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -2273,6 +2273,7 @@ int fireweapon_on_actor::use( player &p, item &it, bool t, const tripoint & ) co if( extinguish ) { it.revert( &p, false ); it.deactivate(); + return 0; } else if( one_in( noise_chance ) ) { if( noise > 0 ) { diff --git a/src/magic.h b/src/magic.h index 7d122c3750af..fe4de0efa113 100644 --- a/src/magic.h +++ b/src/magic.h @@ -12,6 +12,7 @@ #include #include "bodypart.h" +#include "catalua_type_operators.h" #include "damage.h" #include "enum_bitset.h" #include "event_bus.h" @@ -118,6 +119,11 @@ struct fake_spell { bool operator==( const fake_spell &rhs )const; + // Borrowed from LUA_TYPE_OPS, catalua_type_operators.h + inline bool operator<( const fake_spell &rhs ) const { + return ( id ) < rhs.id; + } + void load( const JsonObject &jo ); void serialize( JsonOut &json ) const; void deserialize( JsonIn &jsin ); @@ -284,14 +290,19 @@ class spell_type static void check_consistency(); static void reset_all(); bool is_valid() const; + + LUA_TYPE_OPS( spell_type, id ); }; class spell { + public: + // Here for Lua reasons. + spell_id type; + private: friend class spell_events; // basic spell data - spell_id type; // once you accumulate enough exp you level the spell int experience = 0; @@ -448,6 +459,8 @@ class spell // picks a random valid tripoint from @area std::optional random_valid_target( const Creature &caster, const tripoint &caster_pos ) const; + + LUA_TYPE_OPS( spell, type ); }; class known_magic diff --git a/src/mapdata.h b/src/mapdata.h index cc96c6b637e9..1dfde25ae0b9 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -224,6 +224,7 @@ struct pry_result { * OPENCLOSE_INSIDE - If it's a door (with an 'open' or 'close' field), it can only be opened or closed if you're inside. * PERMEABLE - Allows gases to flow through unimpeded. * RAMP - Higher z-levels can be accessed from this tile + * ADV_DECONSTRUCT - Player cannot use "Deconstruct (Simple) Furniture"; alternative means are required * EASY_DECONSTRUCT - Player can deconstruct this without tools * HIDE_PLACE - Creature on this tile can't be seen by other creature not standing on adjacent tiles * BLOCK_WIND - This tile will partially block wind diff --git a/src/string_id_null_ids.cpp b/src/string_id_null_ids.cpp index 4d4cf454d525..6176747722d4 100644 --- a/src/string_id_null_ids.cpp +++ b/src/string_id_null_ids.cpp @@ -35,6 +35,7 @@ MAKE_CLASS_NULL_ID( overmap_special, "" ) MAKE_CLASS_NULL_ID( recipe, "null" ) MAKE_CLASS_NULL_ID( SkillDisplayType, "none" ) MAKE_CLASS_NULL_ID( Skill, "none" ) +MAKE_CLASS_NULL_ID( spell_type, "spell_none" ) MAKE_CLASS_NULL_ID( ter_furn_transform, "null" ) MAKE_CLASS_NULL_ID( translation, "null" ) MAKE_CLASS_NULL_ID( VehicleGroup, "null" )