From 60b9614821158a9647f2ca94ce12868c1e56074f Mon Sep 17 00:00:00 2001 From: Serhiy Zahoriya Date: Mon, 15 Jun 2020 15:27:58 +0300 Subject: [PATCH 001/151] Equalize root cellar and underground spoilage rates --- src/item.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item.cpp b/src/item.cpp index ba63d26045af5..7bf741db91a08 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -8695,7 +8695,7 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, //Use weather if above ground, use map temp if below double env_temperature = 0; - if( pos.z >= 0 ) { + if( pos.z >= 0 && flag != temperature_flag::ROOT_CELLAR ) { double weather_temperature = wgen.get_weather_temperature( pos, time, seed ); env_temperature = weather_temperature + enviroment_mod + local_mod; } else { From 63ee8ad5894994e0defb3364b0791713cd402cc1 Mon Sep 17 00:00:00 2001 From: Duck13Tales <67176313+Duck13Tales@users.noreply.github.com> Date: Sat, 11 Jul 2020 21:02:22 -0300 Subject: [PATCH 002/151] Just some aditions to make possible to disassemble some ordinary tools --- data/json/recipes/other/materials.json | 2 +- data/json/recipes/other/tool.json | 33 ++- data/json/recipes/recipe_deconstruction.json | 234 ++++++++++++++++++- data/json/recipes/recipe_others.json | 9 +- data/json/recipes/recipe_weapon.json | 1 + 5 files changed, 273 insertions(+), 6 deletions(-) diff --git a/data/json/recipes/other/materials.json b/data/json/recipes/other/materials.json index 8a08263852032..d883058421327 100644 --- a/data/json/recipes/other/materials.json +++ b/data/json/recipes/other/materials.json @@ -185,7 +185,7 @@ "components": [ [ [ "acid", 1 ] ], [ [ "water", 3 ], [ "water_clean", 3 ] ], - [ [ "tin_plate", 1 ], [ "tin_cup", 1 ], [ "bowl_pewter", 1 ] ] + [ [ "tin_plate", 1 ], [ "tin_cup", 1 ], [ "bowl_pewter", 1 ], [ "pot_makeshift_copper", 1 ] ] ] }, { diff --git a/data/json/recipes/other/tool.json b/data/json/recipes/other/tool.json index 242f600aa62d5..079378a35cdbc 100644 --- a/data/json/recipes/other/tool.json +++ b/data/json/recipes/other/tool.json @@ -132,6 +132,7 @@ "skill_used": "fabrication", "difficulty": 3, "time": "3 h", + "reversible": true, "autolearn": true, "using": [ [ "blacksmithing_standard", 1 ], [ "steel_tiny", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], @@ -145,6 +146,7 @@ "skill_used": "fabrication", "difficulty": 4, "time": "3 h", + "reversible": true, "autolearn": true, "using": [ [ "blacksmithing_standard", 1 ], [ "steel_tiny", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], @@ -158,6 +160,7 @@ "skill_used": "fabrication", "difficulty": 3, "time": "3 h", + "reversible": true, "autolearn": true, "using": [ [ "blacksmithing_standard", 1 ], [ "steel_tiny", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], @@ -171,6 +174,7 @@ "skill_used": "fabrication", "difficulty": 4, "time": "3 h", + "reversible": true, "autolearn": true, "using": [ [ "blacksmithing_standard", 1 ], [ "steel_tiny", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], @@ -184,6 +188,7 @@ "skill_used": "fabrication", "difficulty": 4, "time": "3 h", + "reversible": true, "autolearn": true, "using": [ [ "blacksmithing_standard", 2 ], [ "steel_tiny", 2 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], @@ -197,6 +202,7 @@ "skill_used": "fabrication", "difficulty": 7, "time": "5 h", + "reversible": true, "autolearn": true, "using": [ [ "blacksmithing_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], @@ -300,6 +306,7 @@ "difficulty": 4, "skills_required": [ "fabrication", 3 ], "time": 300000, + "reversible": true, "book_learn": [ [ "textbook_tailor", 4 ], [ "manual_tailor", 5 ], [ "tailor_portfolio", 4 ] ], "using": [ [ "sewing_standard", 100 ], [ "cordage", 2 ] ], "components": [ [ [ "leather", 30 ], [ "tanned_hide", 5 ], [ "fur", 30 ], [ "tanned_pelt", 5 ] ], [ [ "wire", 2 ] ] ] @@ -313,6 +320,7 @@ "difficulty": 5, "skills_required": [ "mechanics", 3 ], "time": "300 m", + "reversible": true, "book_learn": [ [ "manual_mechanics", 3 ], [ "manual_fabrication", 5 ], [ "textbook_fabrication", 5 ] ], "using": [ [ "forging_standard", 10 ], [ "steel_standard", 5 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], @@ -327,6 +335,7 @@ "difficulty": 2, "skills_required": [ "mechanics", 1 ], "time": "100 m", + "reversible": true, "book_learn": [ [ "manual_mechanics", 1 ], [ "manual_fabrication", 2 ], [ "textbook_fabrication", 2 ] ], "qualities": [ { "id": "SAW_M", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "WRENCH", "level": 1 } ], "components": [ [ [ "pipe", 4 ] ], [ [ "scrap", 2 ] ] ] @@ -340,6 +349,7 @@ "difficulty": 3, "skills_required": [ "mechanics", 2 ], "time": "200 m", + "reversible": true, "book_learn": [ [ "manual_mechanics", 2 ], [ "manual_fabrication", 3 ], [ "textbook_fabrication", 3 ] ], "using": [ [ "welding_standard", 5 ] ], "qualities": [ { "id": "SAW_M_FINE", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "WRENCH", "level": 1 } ], @@ -353,6 +363,7 @@ "skill_used": "fabrication", "difficulty": 7, "time": "420 m", + "reversible": true, "autolearn": true, "book_learn": [ [ "textbook_carpentry", 5 ], [ "textbook_fabrication", 6 ] ], "using": [ [ "forging_standard", 2 ], [ "steel_standard", 2 ] ], @@ -369,6 +380,7 @@ "skills_required": [ "chemistry", 3 ], "difficulty": 4, "time": "200 m", + "reversible": true, "book_learn": [ [ "textbook_chemistry", 4 ], [ "brewing_cookbook", 3 ] ], "qualities": [ { "id": "CUT", "level": 1 }, { "id": "HAMMER", "level": 2 } ], "components": [ [ [ "pot", 1 ], [ "pot_copper", 1 ] ], [ [ "hose", 2 ], [ "makeshift_hose", 2 ] ] ] @@ -452,6 +464,7 @@ "skills_required": [ "fabrication", 1 ], "difficulty": 2, "time": "5 m", + "reversible": true, "autolearn": true, "book_learn": [ [ "mag_survival", 2 ], [ "textbook_survival", 1 ], [ "cookbook", 2 ] ], "qualities": [ { "id": "CUT", "level": 1 } ], @@ -466,6 +479,7 @@ "skills_required": [ "fabrication", 1 ], "difficulty": 3, "time": 54000, + "reversible": true, "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "rock", 1 ], [ "ceramic_shard", 1 ], [ "sharp_rock", 1 ] ] ] @@ -479,6 +493,7 @@ "skills_required": [ "fabrication", 1 ], "difficulty": 3, "time": 60000, + "reversible": true, "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "steel_chunk", 1 ], [ "steel_lump", 1 ] ] ] @@ -532,6 +547,7 @@ "skill_used": "fabrication", "difficulty": 2, "time": 80000, + "reversible": true, "autolearn": true, "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ] }, @@ -543,6 +559,7 @@ "skill_used": "fabrication", "difficulty": 3, "time": "120 m", + "reversible": true, "autolearn": true, "using": [ [ "forging_standard", 8 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], @@ -556,6 +573,7 @@ "skill_used": "fabrication", "difficulty": 8, "time": "420 m", + "reversible": true, "book_learn": [ [ "textbook_fireman", 8 ] ], "using": [ [ "forging_standard", 20 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], @@ -569,6 +587,7 @@ "skill_used": "fabrication", "difficulty": 3, "time": "100 m", + "reversible": true, "autolearn": true, "using": [ [ "forging_standard", 6 ], [ "steel_standard", 2 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], @@ -582,6 +601,7 @@ "skill_used": "fabrication", "difficulty": 5, "time": "240 m", + "reversible": true, "autolearn": true, "using": [ [ "forging_standard", 8 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], @@ -600,6 +620,7 @@ "skill_used": "fabrication", "difficulty": 6, "time": "6 h", + "reversible": true, "book_learn": [ [ "textbook_fireman", 6 ] ], "using": [ [ "blacksmithing_standard", 16 ], [ "steel_standard", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], @@ -612,6 +633,7 @@ "subcategory": "CSC_OTHER_TOOLS", "skill_used": "fabrication", "time": "1 m", + "reversible": true, "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "pipe", 1 ] ] ] @@ -649,6 +671,7 @@ "subcategory": "CSC_OTHER_TOOLS", "skill_used": "fabrication", "time": "2 m", + "reversible": true, "autolearn": true, "components": [ [ [ "colander_steel", 1 ], [ "wire_mesh", 1 ], [ "splatter_guard", 1 ] ] ] }, @@ -942,9 +965,10 @@ "skill_used": "fabrication", "difficulty": 4, "skills_required": [ [ "survival", 3 ], [ "tailor", 4 ] ], - "autolearn": true, "time": "1 h", - "qualities": [ { "id": "SEW", "level": 2 }, { "id": "CUT", "level": 1 } ], + "reversible": true, + "autolearn": true, + "qualities": [ { "id": "CUT", "level": 1 }, { "id": "SEW", "level": 2 } ], "components": [ [ [ "leather", 2 ] ], [ [ "superglue", 1 ] ], [ [ "filament", 40, "LIST" ] ] ] }, { @@ -955,6 +979,7 @@ "skill_used": "fabrication", "difficulty": 2, "time": "1 h", + "reversible": true, "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 2 }, { "id": "HAMMER_FINE", "level": 1 } ], "components": [ [ [ "pipe", 1 ] ], [ [ "nail", 1 ], [ "screwdriver", 1 ] ], [ [ "2x4", 1 ], [ "stick", 1 ], [ "splinter", 3 ] ] ] @@ -967,6 +992,7 @@ "skill_used": "fabrication", "difficulty": 3, "time": "2 h", + "reversible": true, "autolearn": true, "using": [ [ "forging_standard", 8 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER", "level": 3 }, { "id": "CHISEL", "level": 3 } ], @@ -981,6 +1007,7 @@ "skill_used": "fabrication", "difficulty": 2, "time": "1 h", + "reversible": true, "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 1 }, { "id": "CUT", "level": 1 } ], "tools": [ [ [ "surface_heat", 10, "LIST" ] ] ], @@ -994,6 +1021,7 @@ "skill_used": "fabrication", "difficulty": 3, "time": "2 h", + "reversible": true, "autolearn": true, "using": [ [ "forging_standard", 8 ] ], "qualities": [ { "id": "ANVIL", "level": 3 }, { "id": "HAMMER_FINE", "level": 1 }, { "id": "CHISEL", "level": 3 } ], @@ -1008,6 +1036,7 @@ "skill_used": "fabrication", "difficulty": 2, "time": "1 h", + "reversible": true, "autolearn": true, "qualities": [ { "id": "HAMMER", "level": 1 }, { "id": "CUT", "level": 1 } ], "tools": [ [ [ "surface_heat", 10, "LIST" ] ] ], diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index 94344672a5659..5c0c208e19727 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -4,7 +4,7 @@ "type": "uncraft", "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "splinter", 1 ] ] ] + "components": [ [ [ "wooden_bead", 10 ] ] ] }, { "result": "bead_ear", @@ -18,7 +18,14 @@ "type": "uncraft", "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "splinter", 1 ] ] ] + "components": [ [ [ "wooden_bead", 30 ] ] ] + }, + { + "type": "uncraft", + "result": "bottle_opener", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 1 ] ] ] }, { "result": "bracelet_friendship", @@ -48,6 +55,27 @@ "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ] ] }, + { + "type": "uncraft", + "result": "can_opener", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 3 ] ] ] + }, + { + "type": "uncraft", + "result": "carving_fork", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 3 ] ] ] + }, + { + "result": "colander_steel", + "type": "uncraft", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 6 ] ] ] + }, { "result": "copper_hairpin", "type": "uncraft", @@ -69,6 +97,15 @@ "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "copper", 4 ] ] ] }, + { + "result": "copper_pan", + "type": "uncraft", + "skill_used": "fabrication", + "difficulty": 1, + "time": "7 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap_copper", 4 ] ], [ [ "scrap", 1 ] ] ] + }, { "result": "copper_ring", "type": "uncraft", @@ -76,6 +113,13 @@ "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "copper", 3 ] ] ] }, + { + "type": "uncraft", + "result": "corkscrew", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 1 ] ] ] + }, { "result": "cufflinks", "type": "uncraft", @@ -294,6 +338,13 @@ "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "silver_small", 2 ] ], [ [ "diamond", 1 ] ] ] }, + { + "type": "uncraft", + "result": "ladle", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 3 ] ] ] + }, { "result": "leather_collar", "type": "uncraft", @@ -1398,6 +1449,15 @@ "using": [ [ "soldering_standard", 20 ] ], "components": [ [ [ "processor", 4 ] ], [ [ "power_supply", 1 ] ], [ [ "e_scrap", 6 ] ], [ [ "solder_wire", 1 ] ] ] }, + { + "result": "iron_pot", + "type": "uncraft", + "skill_used": "fabrication", + "difficulty": 1, + "time": "2 m", + "qualities": [ { "id": "SAW_M", "level": 1 } ], + "components": [ [ [ "sheet_metal_small", 10 ], [ "steel_chunk", 1 ] ] ] + }, { "result": "pathfinding_module", "type": "uncraft", @@ -1683,6 +1743,13 @@ "qualities": [ { "id": "SCREW", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ], [ [ "small_lcd_screen", 1 ] ], [ [ "RAM", 1 ] ], [ [ "processor", 1 ] ], [ [ "lens_small", 1 ] ] ] }, + { + "result": "splatter_guard", + "type": "uncraft", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 7 ] ] ] + }, { "result": "ceramic_bowl", "type": "uncraft", @@ -1695,6 +1762,12 @@ "time": "1 m", "components": [ [ [ "ceramic_shard", 1 ] ] ] }, + { + "result": "ceramic_mug", + "type": "uncraft", + "time": "1 m", + "components": [ [ [ "ceramic_shard", 1 ] ] ] + }, { "result": "ceramic_plate", "type": "uncraft", @@ -2273,6 +2346,15 @@ "qualities": [ { "id": "SCREW", "level": 1 } ], "components": [ [ [ "e_scrap", 2 ] ], [ [ "amplifier", 1 ] ], [ [ "scrap", 2 ] ] ] }, + { + "result": "kettle", + "type": "uncraft", + "skill_used": "fabrication", + "difficulty": 1, + "time": "1 m 30 s", + "qualities": [ { "id": "SAW_M", "level": 1 } ], + "components": [ [ [ "sheet_metal_small", 3 ] ] ] + }, { "result": "kiln_done", "type": "uncraft", @@ -2281,6 +2363,64 @@ "time": "1 m", "components": [ [ [ "charcoal", 200 ] ], [ [ "char_kiln", 1 ] ] ] }, + { + "type": "uncraft", + "result": "knife_bread", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + }, + { + "type": "uncraft", + "result": "knife_butter", + "time": "2 m", + "components": [ [ [ "spike", 1 ] ] ], + "flags": [ "BLIND_EASY" ] + }, + { + "type": "uncraft", + "result": "knife_butcher", + "time": "10 m", + "qualities": [ { "id": "HAMMER", "level": 1 }, { "id": "CUT", "level": 1 } ], + "components": [ + [ [ "steel_lump", 1 ] , ["steel_chunk", 4] , ["scrap", 20 ] ], + [ [ "leather", 1 ] , ["fur", 1] ] ] + }, + { + "type": "uncraft", + "result": "knife_carving", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + }, + { + "type": "uncraft", + "result": "knife_chef", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + }, + { + "type": "uncraft", + "result": "knife_folding", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "plastic_chunk", 1] ], [ [ "scrap", 4 ] ] ] + }, + { + "type": "uncraft", + "result": "knife_meat_cleaver", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "steel_chunk", 2] , [ "scrap", 10 ] ] ] + }, + { + "type": "uncraft", + "result": "knife_paring", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 2 ] ] ] + }, { "result": "knife_steak", "type": "uncraft", @@ -2288,6 +2428,13 @@ "components": [ [ [ "spike", 1 ] ] ], "flags": [ "BLIND_EASY" ] }, + { + "type": "uncraft", + "result": "knife_vegetable_cleaver", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + }, { "result": "laptop", "type": "uncraft", @@ -2401,6 +2548,13 @@ "qualities": [ { "id": "SCREW", "level": 1 } ], "components": [ [ [ "element", 3 ] ], [ [ "amplifier", 1 ] ], [ [ "scrap", 6 ] ], [ [ "plastic_chunk", 1 ] ], [ [ "cable", 8 ] ] ] }, + { + "result": "mess_tray", + "type": "uncraft", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 5 ] ] ] + }, { "result": "microwave", "type": "uncraft", @@ -2556,6 +2710,20 @@ "qualities": [ { "id": "WRENCH", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ], [ [ "plastic_chunk", 1 ] ], [ [ "metal_tank_little", 1 ] ] ] }, + { + "type": "uncraft", + "result": "peeler", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 1 ] ] ] + }, + { + "type": "uncraft", + "result": "potato_masher", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 3 ] ] ] + }, { "result": "pillow", "type": "uncraft", @@ -2705,6 +2873,13 @@ "components": [ [ [ "paper", 10 ] ] ], "flags": [ "BLIND_EASY" ] }, + { + "type": "uncraft", + "result": "garlic_press", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 3 ] ] ] + }, { "result": "gold_ring", "type": "uncraft", @@ -2837,6 +3012,21 @@ "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "WRENCH", "level": 1 }, { "id": "SAW_M", "level": 1 } ], "components": [ [ [ "motor_tiny", 3 ] ], [ [ "processor", 3 ] ], [ [ "RAM", 2 ] ], [ [ "plastic_chunk", 2 ] ] ] }, + { + "result": "sewing_kit", + "type": "uncraft", + "time": "30 s", + "components": [ [ [ "scrap", 2 ] ], [ [ "plastic_chunk", 1 ] ] ] + }, + { + "result": "steel_pan", + "type": "uncraft", + "skill_used": "fabrication", + "difficulty": 1, + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 10 ] ] ] + }, { "result": "scythe", "type": "uncraft", @@ -3114,6 +3304,15 @@ "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "stick", 2 ] ] ] }, + { + "result": "stock_pot", + "type": "uncraft", + "skill_used": "fabrication", + "difficulty": 1, + "time": "2 m", + "qualities": [ { "id": "SAW_M", "level": 1 } ], + "components": [ [ [ "sheet_metal_small", 8 ], [ "steel_chunk", 1 ] ] ] + }, { "result": "straw_basket", "type": "uncraft", @@ -3278,6 +3477,19 @@ "components": [ [ [ "walnut_unshelled", 1 ] ] ], "flags": [ "BLIND_EASY" ] }, + { + "type": "uncraft", + "result": "whisk", + "time": "1 m 30 s", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "scrap", 3 ] ] ] + }, + { + "result": "wine_glass", + "type": "uncraft", + "time": "30 s", + "components": [ [ [ "glass_shard", 4 ] ] ] + }, { "result": "peanut", "type": "uncraft", @@ -3601,6 +3813,24 @@ "components": [ [ [ "cardboard", 2 ] ], [ [ "plastic_chunk", 2 ] ] ], "flags": [ "BLIND_EASY" ] }, + { + "result": "pan", + "type": "uncraft", + "skill_used": "fabrication", + "difficulty": 1, + "time": "2 m", + "qualities": [ { "id": "SAW_M", "level": 1 } ], + "components": [ [ [ "sheet_metal_small", 8 ], [ "steel_chunk", 1 ] ] ] + }, + { + "result": "pot", + "type": "uncraft", + "skill_used": "fabrication", + "difficulty": 1, + "time": "4 m", + "qualities": [ { "id": "SAW_M", "level": 1 } ], + "components": [ [ [ "scrap", 20 ] ] ] + }, { "result": "pot_canning", "type": "uncraft", diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index d8b49e9b4e897..1034ee0b46de6 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -3437,11 +3437,18 @@ [ "plastic_straw", 3 ], [ "plastic_knife", 2 ], [ "plastic_spoon", 2 ], + [ "plastic_spoon_kids", 2 ], [ "plastic_fork", 2 ], + [ "plastic_plate", 4 ], [ "plastic_six_dice", 11 ], [ "bag_zipper", 25 ], [ "cup_plastic", 25 ], - [ "bag_plastic", 10 ] + [ "bag_plastic", 10 ], + [ "tumbler_plastic", 4 ], + [ "bowl_plastic", 4 ], + [ "plastic_bowl_kids", 4 ], + [ "sippy_cup", 4 ], + [ "gasket_plastic", 1 ] ] ] }, diff --git a/data/json/recipes/recipe_weapon.json b/data/json/recipes/recipe_weapon.json index a7eba09f741dd..172aec4516695 100644 --- a/data/json/recipes/recipe_weapon.json +++ b/data/json/recipes/recipe_weapon.json @@ -1496,6 +1496,7 @@ "skill_used": "fabrication", "difficulty": 4, "time": "4 h", + "reversible": true, "autolearn": true, "using": [ [ "blacksmithing_standard", 4 ], [ "steel_standard", 1 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], From eab8faabdd61a2feaa840a7a81b63d5dbd522d22 Mon Sep 17 00:00:00 2001 From: Duck13Tales <67176313+Duck13Tales@users.noreply.github.com> Date: Sat, 11 Jul 2020 21:52:33 -0300 Subject: [PATCH 003/151] Just some aditions to make possible to disassemble some ordinary tools --- data/json/recipes/recipe_deconstruction.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index 5c0c208e19727..1f68519a37ef5 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -2368,7 +2368,7 @@ "result": "knife_bread", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] }, { "type": "uncraft", @@ -2391,35 +2391,35 @@ "result": "knife_carving", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] }, { "type": "uncraft", "result": "knife_chef", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] }, { "type": "uncraft", "result": "knife_folding", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "plastic_chunk", 1] ], [ [ "scrap", 4 ] ] ] + "components": [ [ [ "plastic_chunk", 1] ], [ [ "scrap", 4 ] ] ] }, { "type": "uncraft", "result": "knife_meat_cleaver", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "steel_chunk", 2] , [ "scrap", 10 ] ] ] + "components": [ [ [ "steel_chunk", 2] , [ "scrap", 10 ] ] ] }, { "type": "uncraft", "result": "knife_paring", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "scrap", 2 ] ] ] + "components": [ [ [ "scrap", 2 ] ] ] }, { "result": "knife_steak", @@ -2433,7 +2433,7 @@ "result": "knife_vegetable_cleaver", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] }, { "result": "laptop", From 80f0d4ead33a5d109a2f7650dfde7fa6b5493730 Mon Sep 17 00:00:00 2001 From: Duck13Tales <67176313+Duck13Tales@users.noreply.github.com> Date: Sat, 11 Jul 2020 22:18:17 -0300 Subject: [PATCH 004/151] Just some aditions to make possible to disassemble some ordinary tools --- data/json/recipes/recipe_deconstruction.json | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index 1f68519a37ef5..d7fb9fbe6df79 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -2368,7 +2368,7 @@ "result": "knife_bread", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + "components": [ [ [ "steel_chunk", 1 ], [ "scrap", 5 ] ] ] }, { "type": "uncraft", @@ -2382,37 +2382,35 @@ "result": "knife_butcher", "time": "10 m", "qualities": [ { "id": "HAMMER", "level": 1 }, { "id": "CUT", "level": 1 } ], - "components": [ - [ [ "steel_lump", 1 ] , ["steel_chunk", 4] , ["scrap", 20 ] ], - [ [ "leather", 1 ] , ["fur", 1] ] ] + "components": [ [ [ "steel_lump", 1 ], [ "steel_chunk", 4 ], [ "scrap", 20 ] ], [ [ "leather", 1 ], [ "fur", 1 ] ] ] }, { "type": "uncraft", "result": "knife_carving", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + "components": [ [ [ "steel_chunk", 1 ], [ "scrap", 5 ] ] ] }, { "type": "uncraft", "result": "knife_chef", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + "components": [ [ [ "steel_chunk", 1 ], [ "scrap", 5 ] ] ] }, { "type": "uncraft", "result": "knife_folding", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "plastic_chunk", 1] ], [ [ "scrap", 4 ] ] ] + "components": [ [ [ "plastic_chunk", 1 ] ], [ [ "scrap", 4 ] ] ] }, { "type": "uncraft", "result": "knife_meat_cleaver", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "steel_chunk", 2] , [ "scrap", 10 ] ] ] + "components": [ [ [ "steel_chunk", 2 ], [ "scrap", 10 ] ] ] }, { "type": "uncraft", @@ -2433,7 +2431,7 @@ "result": "knife_vegetable_cleaver", "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "steel_chunk", 1] , [ "scrap", 5 ] ] ] + "components": [ [ [ "steel_chunk", 1 ], [ "scrap", 5 ] ] ] }, { "result": "laptop", From b29876034ba5c5bdb26810a7149e0fcf7214a1c5 Mon Sep 17 00:00:00 2001 From: Duck13Tales <67176313+Duck13Tales@users.noreply.github.com> Date: Sat, 11 Jul 2020 22:56:41 -0300 Subject: [PATCH 005/151] Just some aditions to make possible to disassemble some ordinary tools --- data/json/recipes/recipe_deconstruction.json | 61 +------------------- data/json/recipes/recipe_food.json | 1 + data/json/recipes/recipe_others.json | 33 +---------- 3 files changed, 4 insertions(+), 91 deletions(-) diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index d7fb9fbe6df79..c076cbfb2d9d5 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -673,26 +673,6 @@ [ [ "steel_chunk", 12 ] ] ] }, - { - "result": "broken_robofac_laserturret_mk1", - "type": "uncraft", - "skill_used": "electronics", - "difficulty": 6, - "time": "3 h", - "using": [ [ "soldering_standard", 10 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ - [ [ "ai_module", 1 ] ], - [ [ "gun_module", 1 ] ], - [ [ "targeting_module", 1 ] ], - [ [ "identification_module", 1 ] ], - [ [ "sensor_module", 1 ] ], - [ [ "medium_storage_battery", 1 ] ], - [ [ "power_supply", 1 ] ], - [ [ "robot_controls", 1 ] ], - [ [ "turret_chassis", 1 ] ] - ] - }, { "result": "broken_eyebot", "type": "uncraft", @@ -3755,31 +3735,12 @@ [ [ "aspirin", 10 ] ], [ [ "disinfectant", 10 ] ], [ [ "saline", 5 ] ], - [ [ "adhesive_bandages", 6 ] ], - [ [ "bandages", 3 ] ], + [ [ "bandages", 6 ] ], [ [ "medical_gauze", 6 ] ], [ [ "booklet_firstaid", 1 ] ] ], "flags": [ "BLIND_EASY", "UNCRAFT_LIQUIDS_CONTAINED" ] }, - { - "result": "ifak", - "type": "uncraft", - "time": "6 s", - "components": [ - [ [ "medical_tape", 20 ] ], - [ [ "tourniquet_upper", 1 ] ], - [ [ "disinfectant", 5 ] ], - [ [ "quikclot", 5 ] ], - [ [ "bandages", 9 ] ], - [ [ "medical_gauze", 3 ] ], - [ [ "adhesive_bandages", 3 ] ], - [ [ "pur_tablets", 3 ] ], - [ [ "gloves_medical", 1 ] ], - [ [ "scissors", 1 ] ] - ], - "flags": [ "BLIND_EASY", "UNCRAFT_LIQUIDS_CONTAINED" ] - }, { "result": "survival_kit", "type": "uncraft", @@ -4016,26 +3977,6 @@ "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "rag", 25 ] ], [ [ "element", 5 ] ], [ [ "cable", 5 ] ] ] }, - { - "result": "wearable_light", - "type": "uncraft", - "skill_used": "fabrication", - "time": "30 s", - "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ [ [ "flashlight", 1 ] ], [ [ "rag", 2 ] ] ] - }, - { - "result": "miner_hat", - "type": "uncraft", - "skill_used": "fabrication", - "time": "30 s", - "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ - [ [ "hat_hard", 1 ], [ "helmet_bike", 1 ] ], - [ [ "flashlight", 1 ] ], - [ [ "rag", 2 ], [ "leather", 2 ], [ "cordage", 1, "LIST" ], [ "duct_tape", 10 ], [ "medical_tape", 20 ] ] - ] - }, { "result": "adobe_pallet_done", "type": "uncraft", diff --git a/data/json/recipes/recipe_food.json b/data/json/recipes/recipe_food.json index 97ed24a17daac..a87d3ceddf43d 100644 --- a/data/json/recipes/recipe_food.json +++ b/data/json/recipes/recipe_food.json @@ -4377,6 +4377,7 @@ [ "onion", 1 ], [ "irradiated_onion", 1 ], [ "broccoli", 1 ], + [ "irradiated_tomato", 1 ], [ "irradiated_broccoli", 1 ], [ "rehydrated_veggy", 1 ], diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index 1034ee0b46de6..1fb39c559af58 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -452,7 +452,7 @@ "subcategory": "CSC_OTHER_TOOLS", "skill_used": "fabrication", "difficulty": 1, - "time": "5 m", + "time": "20 m", "reversible": true, "autolearn": true, "qualities": [ { "id": "CUT", "level": 1 } ], @@ -491,7 +491,6 @@ "difficulty": 2, "time": "25 m", "autolearn": true, - "reversible": true, "using": [ [ "soldering_standard", 10 ] ], "qualities": [ { "id": "CUT", "level": 1 }, { "id": "SCREW", "level": 1 } ], "components": [ @@ -1583,7 +1582,7 @@ "decomp_learn": 2, "autolearn": true, "using": [ [ "cordage", 1 ] ], - "components": [ [ [ "slamfire_shotgun_d", 1 ] ], [ [ "shot_00", 2 ], [ "shot_slug", 2 ], [ "shot_flechette", 2 ] ] ] + "components": [ [ [ "shotgun_d", 1 ] ], [ [ "shot_00", 2 ], [ "shot_slug", 2 ], [ "shot_flechette", 2 ] ] ] }, { "type": "recipe", @@ -4617,33 +4616,5 @@ "autolearn": true, "tools": [ [ [ "tongs", -1 ] ], [ [ "crucible", -1 ], [ "crucible_clay", -1 ] ], [ [ "sheet_metal", -1 ] ], [ [ "forge", 75 ] ] ], "components": [ [ [ "plastic_chunk", 200 ] ] ] - }, - { - "type": "recipe", - "result": "funnel_separation", - "category": "CC_OTHER", - "subcategory": "CSC_OTHER_TOOLS", - "skill_used": "fabrication", - "difficulty": 7, - "time": "1 h", - "book_learn": [ [ "glassblowing_book", 5 ] ], - "qualities": [ { "id": "CHISEL", "level": 3 } ], - "tools": [ [ [ "tongs", -1 ] ], [ [ "pipe", -1 ] ], [ [ "crucible", -1 ], [ "crucible_clay", -1 ] ], [ [ "forge", 75 ] ] ], - "components": [ - [ [ "glass_shard", 3 ], [ "pipe_glass", 1 ], [ "flask_glass", 3 ], [ "test_tube", 6 ], [ "marble", 75 ] ], - [ [ "stopcock", 1 ] ] - ] - }, - { - "type": "recipe", - "result": "stopcock", - "category": "CC_OTHER", - "subcategory": "CSC_OTHER_OTHER", - "skill_used": "fabrication", - "difficulty": 4, - "time": "30 m", - "autolearn": true, - "tools": [ [ [ "mold_plastic", -1 ] ], [ [ "surface_heat", 5, "LIST" ] ] ], - "components": [ [ [ "plastic_chunk", 1 ] ] ] } ] From 3b99e65529de3e41c2fbee4926577b0363e34cfe Mon Sep 17 00:00:00 2001 From: Duck13Tales <67176313+Duck13Tales@users.noreply.github.com> Date: Sat, 11 Jul 2020 23:03:49 -0300 Subject: [PATCH 006/151] Revert "Just some aditions to make possible to disassemble some ordinary tools" This reverts commit b29876034ba5c5bdb26810a7149e0fcf7214a1c5. --- data/json/recipes/recipe_deconstruction.json | 61 +++++++++++++++++++- data/json/recipes/recipe_food.json | 1 - data/json/recipes/recipe_others.json | 33 ++++++++++- 3 files changed, 91 insertions(+), 4 deletions(-) diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index c076cbfb2d9d5..d7fb9fbe6df79 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -673,6 +673,26 @@ [ [ "steel_chunk", 12 ] ] ] }, + { + "result": "broken_robofac_laserturret_mk1", + "type": "uncraft", + "skill_used": "electronics", + "difficulty": 6, + "time": "3 h", + "using": [ [ "soldering_standard", 10 ] ], + "qualities": [ { "id": "SCREW", "level": 1 } ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "gun_module", 1 ] ], + [ [ "targeting_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "medium_storage_battery", 1 ] ], + [ [ "power_supply", 1 ] ], + [ [ "robot_controls", 1 ] ], + [ [ "turret_chassis", 1 ] ] + ] + }, { "result": "broken_eyebot", "type": "uncraft", @@ -3735,12 +3755,31 @@ [ [ "aspirin", 10 ] ], [ [ "disinfectant", 10 ] ], [ [ "saline", 5 ] ], - [ [ "bandages", 6 ] ], + [ [ "adhesive_bandages", 6 ] ], + [ [ "bandages", 3 ] ], [ [ "medical_gauze", 6 ] ], [ [ "booklet_firstaid", 1 ] ] ], "flags": [ "BLIND_EASY", "UNCRAFT_LIQUIDS_CONTAINED" ] }, + { + "result": "ifak", + "type": "uncraft", + "time": "6 s", + "components": [ + [ [ "medical_tape", 20 ] ], + [ [ "tourniquet_upper", 1 ] ], + [ [ "disinfectant", 5 ] ], + [ [ "quikclot", 5 ] ], + [ [ "bandages", 9 ] ], + [ [ "medical_gauze", 3 ] ], + [ [ "adhesive_bandages", 3 ] ], + [ [ "pur_tablets", 3 ] ], + [ [ "gloves_medical", 1 ] ], + [ [ "scissors", 1 ] ] + ], + "flags": [ "BLIND_EASY", "UNCRAFT_LIQUIDS_CONTAINED" ] + }, { "result": "survival_kit", "type": "uncraft", @@ -3977,6 +4016,26 @@ "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "rag", 25 ] ], [ [ "element", 5 ] ], [ [ "cable", 5 ] ] ] }, + { + "result": "wearable_light", + "type": "uncraft", + "skill_used": "fabrication", + "time": "30 s", + "qualities": [ { "id": "CUT", "level": 1 } ], + "components": [ [ [ "flashlight", 1 ] ], [ [ "rag", 2 ] ] ] + }, + { + "result": "miner_hat", + "type": "uncraft", + "skill_used": "fabrication", + "time": "30 s", + "qualities": [ { "id": "CUT", "level": 1 } ], + "components": [ + [ [ "hat_hard", 1 ], [ "helmet_bike", 1 ] ], + [ [ "flashlight", 1 ] ], + [ [ "rag", 2 ], [ "leather", 2 ], [ "cordage", 1, "LIST" ], [ "duct_tape", 10 ], [ "medical_tape", 20 ] ] + ] + }, { "result": "adobe_pallet_done", "type": "uncraft", diff --git a/data/json/recipes/recipe_food.json b/data/json/recipes/recipe_food.json index a87d3ceddf43d..97ed24a17daac 100644 --- a/data/json/recipes/recipe_food.json +++ b/data/json/recipes/recipe_food.json @@ -4377,7 +4377,6 @@ [ "onion", 1 ], [ "irradiated_onion", 1 ], [ "broccoli", 1 ], - [ "irradiated_tomato", 1 ], [ "irradiated_broccoli", 1 ], [ "rehydrated_veggy", 1 ], diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index 1fb39c559af58..1034ee0b46de6 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -452,7 +452,7 @@ "subcategory": "CSC_OTHER_TOOLS", "skill_used": "fabrication", "difficulty": 1, - "time": "20 m", + "time": "5 m", "reversible": true, "autolearn": true, "qualities": [ { "id": "CUT", "level": 1 } ], @@ -491,6 +491,7 @@ "difficulty": 2, "time": "25 m", "autolearn": true, + "reversible": true, "using": [ [ "soldering_standard", 10 ] ], "qualities": [ { "id": "CUT", "level": 1 }, { "id": "SCREW", "level": 1 } ], "components": [ @@ -1582,7 +1583,7 @@ "decomp_learn": 2, "autolearn": true, "using": [ [ "cordage", 1 ] ], - "components": [ [ [ "shotgun_d", 1 ] ], [ [ "shot_00", 2 ], [ "shot_slug", 2 ], [ "shot_flechette", 2 ] ] ] + "components": [ [ [ "slamfire_shotgun_d", 1 ] ], [ [ "shot_00", 2 ], [ "shot_slug", 2 ], [ "shot_flechette", 2 ] ] ] }, { "type": "recipe", @@ -4616,5 +4617,33 @@ "autolearn": true, "tools": [ [ [ "tongs", -1 ] ], [ [ "crucible", -1 ], [ "crucible_clay", -1 ] ], [ [ "sheet_metal", -1 ] ], [ [ "forge", 75 ] ] ], "components": [ [ [ "plastic_chunk", 200 ] ] ] + }, + { + "type": "recipe", + "result": "funnel_separation", + "category": "CC_OTHER", + "subcategory": "CSC_OTHER_TOOLS", + "skill_used": "fabrication", + "difficulty": 7, + "time": "1 h", + "book_learn": [ [ "glassblowing_book", 5 ] ], + "qualities": [ { "id": "CHISEL", "level": 3 } ], + "tools": [ [ [ "tongs", -1 ] ], [ [ "pipe", -1 ] ], [ [ "crucible", -1 ], [ "crucible_clay", -1 ] ], [ [ "forge", 75 ] ] ], + "components": [ + [ [ "glass_shard", 3 ], [ "pipe_glass", 1 ], [ "flask_glass", 3 ], [ "test_tube", 6 ], [ "marble", 75 ] ], + [ [ "stopcock", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "stopcock", + "category": "CC_OTHER", + "subcategory": "CSC_OTHER_OTHER", + "skill_used": "fabrication", + "difficulty": 4, + "time": "30 m", + "autolearn": true, + "tools": [ [ [ "mold_plastic", -1 ] ], [ [ "surface_heat", 5, "LIST" ] ] ], + "components": [ [ [ "plastic_chunk", 1 ] ] ] } ] From df39a8bcb75801a12117102daa6ce18b58243dfb Mon Sep 17 00:00:00 2001 From: Duck13Tales <67176313+Duck13Tales@users.noreply.github.com> Date: Sat, 11 Jul 2020 23:14:02 -0300 Subject: [PATCH 007/151] Just some aditions to make possible to disassemble some ordinary tools --- data/json/recipes/recipe_deconstruction.json | 61 +------------------- 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index d7fb9fbe6df79..c076cbfb2d9d5 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -673,26 +673,6 @@ [ [ "steel_chunk", 12 ] ] ] }, - { - "result": "broken_robofac_laserturret_mk1", - "type": "uncraft", - "skill_used": "electronics", - "difficulty": 6, - "time": "3 h", - "using": [ [ "soldering_standard", 10 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ - [ [ "ai_module", 1 ] ], - [ [ "gun_module", 1 ] ], - [ [ "targeting_module", 1 ] ], - [ [ "identification_module", 1 ] ], - [ [ "sensor_module", 1 ] ], - [ [ "medium_storage_battery", 1 ] ], - [ [ "power_supply", 1 ] ], - [ [ "robot_controls", 1 ] ], - [ [ "turret_chassis", 1 ] ] - ] - }, { "result": "broken_eyebot", "type": "uncraft", @@ -3755,31 +3735,12 @@ [ [ "aspirin", 10 ] ], [ [ "disinfectant", 10 ] ], [ [ "saline", 5 ] ], - [ [ "adhesive_bandages", 6 ] ], - [ [ "bandages", 3 ] ], + [ [ "bandages", 6 ] ], [ [ "medical_gauze", 6 ] ], [ [ "booklet_firstaid", 1 ] ] ], "flags": [ "BLIND_EASY", "UNCRAFT_LIQUIDS_CONTAINED" ] }, - { - "result": "ifak", - "type": "uncraft", - "time": "6 s", - "components": [ - [ [ "medical_tape", 20 ] ], - [ [ "tourniquet_upper", 1 ] ], - [ [ "disinfectant", 5 ] ], - [ [ "quikclot", 5 ] ], - [ [ "bandages", 9 ] ], - [ [ "medical_gauze", 3 ] ], - [ [ "adhesive_bandages", 3 ] ], - [ [ "pur_tablets", 3 ] ], - [ [ "gloves_medical", 1 ] ], - [ [ "scissors", 1 ] ] - ], - "flags": [ "BLIND_EASY", "UNCRAFT_LIQUIDS_CONTAINED" ] - }, { "result": "survival_kit", "type": "uncraft", @@ -4016,26 +3977,6 @@ "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "rag", 25 ] ], [ [ "element", 5 ] ], [ [ "cable", 5 ] ] ] }, - { - "result": "wearable_light", - "type": "uncraft", - "skill_used": "fabrication", - "time": "30 s", - "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ [ [ "flashlight", 1 ] ], [ [ "rag", 2 ] ] ] - }, - { - "result": "miner_hat", - "type": "uncraft", - "skill_used": "fabrication", - "time": "30 s", - "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ - [ [ "hat_hard", 1 ], [ "helmet_bike", 1 ] ], - [ [ "flashlight", 1 ] ], - [ [ "rag", 2 ], [ "leather", 2 ], [ "cordage", 1, "LIST" ], [ "duct_tape", 10 ], [ "medical_tape", 20 ] ] - ] - }, { "result": "adobe_pallet_done", "type": "uncraft", From 5921eb1a52687be22592cf2d5ddb2a4f8b1049e4 Mon Sep 17 00:00:00 2001 From: Duck13Tales <67176313+Duck13Tales@users.noreply.github.com> Date: Sat, 11 Jul 2020 23:14:23 -0300 Subject: [PATCH 008/151] Revert "Just some aditions to make possible to disassemble some ordinary tools" This reverts commit df39a8bcb75801a12117102daa6ce18b58243dfb. --- data/json/recipes/recipe_deconstruction.json | 61 +++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index c076cbfb2d9d5..d7fb9fbe6df79 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -673,6 +673,26 @@ [ [ "steel_chunk", 12 ] ] ] }, + { + "result": "broken_robofac_laserturret_mk1", + "type": "uncraft", + "skill_used": "electronics", + "difficulty": 6, + "time": "3 h", + "using": [ [ "soldering_standard", 10 ] ], + "qualities": [ { "id": "SCREW", "level": 1 } ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "gun_module", 1 ] ], + [ [ "targeting_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "medium_storage_battery", 1 ] ], + [ [ "power_supply", 1 ] ], + [ [ "robot_controls", 1 ] ], + [ [ "turret_chassis", 1 ] ] + ] + }, { "result": "broken_eyebot", "type": "uncraft", @@ -3735,12 +3755,31 @@ [ [ "aspirin", 10 ] ], [ [ "disinfectant", 10 ] ], [ [ "saline", 5 ] ], - [ [ "bandages", 6 ] ], + [ [ "adhesive_bandages", 6 ] ], + [ [ "bandages", 3 ] ], [ [ "medical_gauze", 6 ] ], [ [ "booklet_firstaid", 1 ] ] ], "flags": [ "BLIND_EASY", "UNCRAFT_LIQUIDS_CONTAINED" ] }, + { + "result": "ifak", + "type": "uncraft", + "time": "6 s", + "components": [ + [ [ "medical_tape", 20 ] ], + [ [ "tourniquet_upper", 1 ] ], + [ [ "disinfectant", 5 ] ], + [ [ "quikclot", 5 ] ], + [ [ "bandages", 9 ] ], + [ [ "medical_gauze", 3 ] ], + [ [ "adhesive_bandages", 3 ] ], + [ [ "pur_tablets", 3 ] ], + [ [ "gloves_medical", 1 ] ], + [ [ "scissors", 1 ] ] + ], + "flags": [ "BLIND_EASY", "UNCRAFT_LIQUIDS_CONTAINED" ] + }, { "result": "survival_kit", "type": "uncraft", @@ -3977,6 +4016,26 @@ "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "rag", 25 ] ], [ [ "element", 5 ] ], [ [ "cable", 5 ] ] ] }, + { + "result": "wearable_light", + "type": "uncraft", + "skill_used": "fabrication", + "time": "30 s", + "qualities": [ { "id": "CUT", "level": 1 } ], + "components": [ [ [ "flashlight", 1 ] ], [ [ "rag", 2 ] ] ] + }, + { + "result": "miner_hat", + "type": "uncraft", + "skill_used": "fabrication", + "time": "30 s", + "qualities": [ { "id": "CUT", "level": 1 } ], + "components": [ + [ [ "hat_hard", 1 ], [ "helmet_bike", 1 ] ], + [ [ "flashlight", 1 ] ], + [ [ "rag", 2 ], [ "leather", 2 ], [ "cordage", 1, "LIST" ], [ "duct_tape", 10 ], [ "medical_tape", 20 ] ] + ] + }, { "result": "adobe_pallet_done", "type": "uncraft", From 7d5caeb47a2d503faec7a639df9ae08fd7d4cbab Mon Sep 17 00:00:00 2001 From: Duck13Tales <67176313+Duck13Tales@users.noreply.github.com> Date: Sun, 12 Jul 2020 18:56:31 -0300 Subject: [PATCH 009/151] Just some aditions to make possible to disassemble some ordinary tools --- data/json/items/armor/jewelry.json | 4 +- data/json/items/generic/dining_kitchen.json | 16 ++--- data/json/recipes/other/materials.json | 2 +- data/json/recipes/other/tool.json | 1 + data/json/recipes/recipe_deconstruction.json | 67 +++++++++++--------- data/json/recipes/recipe_others.json | 4 +- 6 files changed, 50 insertions(+), 44 deletions(-) diff --git a/data/json/items/armor/jewelry.json b/data/json/items/armor/jewelry.json index 44428ce2fa0b6..b2d855c81c885 100644 --- a/data/json/items/armor/jewelry.json +++ b/data/json/items/armor/jewelry.json @@ -35,8 +35,8 @@ "name": { "str": "beaded necklace" }, "description": "A simple necklace made of string and wooden beads. You can wear it if you like, but it won't provide any effects. Also doubles as a set of prayer beads, if you're so inclined.", "looks_like": "silver_necklace", - "weight": "15 g", - "volume": "10 ml", + "weight": "36 g", + "volume": "30 ml", "price": 100, "price_postapoc": 10, "material": [ "wood" ], diff --git a/data/json/items/generic/dining_kitchen.json b/data/json/items/generic/dining_kitchen.json index 2b542c6a0738d..c0953495137ce 100644 --- a/data/json/items/generic/dining_kitchen.json +++ b/data/json/items/generic/dining_kitchen.json @@ -57,8 +57,8 @@ "price": 1200, "price_postapoc": 0, "material": [ "ceramic" ], - "weight": "322 g", - "volume": "262 ml", + "weight": "375 g", + "volume": "375 ml", "bashing": 3, "to_hit": -1 }, @@ -125,6 +125,7 @@ "type": "GENERIC", "category": "other", "id": "ceramic_plate", + "volume": "125 ml", "name": { "str": "ceramic plate" }, "symbol": ",", "description": "A ceramic dinner plate, unremarkable in every way.", @@ -138,7 +139,7 @@ "symbol": ")", "description": "A perfectly ordinary ceramic soup bowl.", "copy-from": "base_ceramic_dish", - "volume": "525 ml", + "volume": "625 ml", "pocket_data": [ { "max_contains_volume": "500 ml", @@ -154,12 +155,10 @@ "type": "GENERIC", "category": "other", "id": "ceramic_cup", - "volume": "262 ml", "name": { "str": "ceramic cup" }, "symbol": "u", "description": "A light ceramic teacup. Quite classy.", "copy-from": "base_ceramic_dish", - "proportional": { "weight": 0.6 }, "pocket_data": [ { "max_contains_volume": "250 ml", @@ -179,7 +178,6 @@ "symbol": "u", "description": "A ceramic coffee cup with a logo on the side.", "copy-from": "base_ceramic_dish", - "proportional": { "weight": 0.8 }, "pocket_data": [ { "max_contains_volume": "250 ml", @@ -652,7 +650,7 @@ "type": "GENERIC", "category": "other", "id": "can_opener", - "name": { "str": "can opener" }, + "name": { "str": "can opener", "str_pl": "can openers" }, "description": "It's not hard to open cans without this, but it's way messier.", "looks_like": "hand_crank_charger", "copy-from": "base_utensil" @@ -727,7 +725,7 @@ "material": [ "iron" ], "color": "dark_gray", "weight": "3000 g", - "volume": "2100 ml", + "volume": "2375 ml", "bashing": 10, "pocket_data": [ { @@ -843,7 +841,7 @@ "material": [ "iron" ], "color": "dark_gray", "weight": "2628 g", - "volume": "1050 ml", + "volume": "1335 ml", "bashing": 12, "to_hit": -3, "pocket_data": [ diff --git a/data/json/recipes/other/materials.json b/data/json/recipes/other/materials.json index d883058421327..8a08263852032 100644 --- a/data/json/recipes/other/materials.json +++ b/data/json/recipes/other/materials.json @@ -185,7 +185,7 @@ "components": [ [ [ "acid", 1 ] ], [ [ "water", 3 ], [ "water_clean", 3 ] ], - [ [ "tin_plate", 1 ], [ "tin_cup", 1 ], [ "bowl_pewter", 1 ], [ "pot_makeshift_copper", 1 ] ] + [ [ "tin_plate", 1 ], [ "tin_cup", 1 ], [ "bowl_pewter", 1 ] ] ] }, { diff --git a/data/json/recipes/other/tool.json b/data/json/recipes/other/tool.json index 079378a35cdbc..3798d1cc74fbe 100644 --- a/data/json/recipes/other/tool.json +++ b/data/json/recipes/other/tool.json @@ -217,6 +217,7 @@ "skill_used": "fabrication", "difficulty": 2, "time": "1 h", + "reversible": true, "autolearn": true, "using": [ [ "blacksmithing_standard", 3 ], [ "steel_tiny", 3 ] ], "qualities": [ { "id": "CHISEL", "level": 3 } ], diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index d7fb9fbe6df79..23af20c6dda2a 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -3,7 +3,7 @@ "result": "bead_bracelet", "type": "uncraft", "time": "30 s", - "qualities": [ { "id": "HAMMER", "level": 1 } ], + "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "wooden_bead", 10 ] ] ] }, { @@ -17,13 +17,13 @@ "result": "bead_necklace", "type": "uncraft", "time": "30 s", - "qualities": [ { "id": "HAMMER", "level": 1 } ], + "qualities": [ { "id": "CUT", "level": 1 } ], "components": [ [ [ "wooden_bead", 30 ] ] ] }, { "type": "uncraft", "result": "bottle_opener", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ] ] }, @@ -37,7 +37,7 @@ { "result": "shears", "type": "uncraft", - "time": "2 m", + "time": "1 m", "qualities": [ { "id": "SAW_M", "level": 1 } ], "components": [ [ [ "scrap", 3 ] ], [ [ "plastic_chunk", 1 ] ] ] }, @@ -58,21 +58,21 @@ { "type": "uncraft", "result": "can_opener", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 3 ] ] ] }, { "type": "uncraft", "result": "carving_fork", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 3 ] ] ] }, { "result": "colander_steel", "type": "uncraft", - "time": "1 m 30 s", + "time": "1 m", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 6 ] ] ] }, @@ -102,9 +102,9 @@ "type": "uncraft", "skill_used": "fabrication", "difficulty": 1, - "time": "7 m 30 s", + "time": "5 m", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "scrap_copper", 4 ] ], [ [ "scrap", 1 ] ] ] + "components": [ [ [ "scrap_copper", 10 ] ], [ [ "scrap", 3 ] ] ] }, { "result": "copper_ring", @@ -116,7 +116,7 @@ { "type": "uncraft", "result": "corkscrew", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ] ] }, @@ -341,7 +341,7 @@ { "type": "uncraft", "result": "ladle", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 3 ] ] ] }, @@ -2029,7 +2029,7 @@ { "result": "foon", "type": "uncraft", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ] ] }, @@ -2043,32 +2043,32 @@ { "result": "fork", "type": "uncraft", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ] ] }, { "result": "glass", "type": "uncraft", - "time": "30 s", + "time": "1 s", "components": [ [ [ "glass_shard", 4 ] ] ] }, { "result": "glass_bowl", "type": "uncraft", - "time": "30 s", + "time": "1 s", "components": [ [ [ "glass_shard", 4 ] ] ] }, { "result": "glass_plate", "type": "uncraft", - "time": "30 s", + "time": "1 s", "components": [ [ [ "glass_shard", 4 ] ] ] }, { "result": "glass_sheet", "type": "uncraft", - "time": "2 m", + "time": "1 s", "components": [ [ [ "glass_shard", 182 ] ] ] }, { @@ -2511,7 +2511,7 @@ "result": "makeshift_crowbar", "type": "uncraft", "skill_used": "mechanics", - "time": "5 m", + "time": "1 m 30 s", "qualities": [ { "id": "SAW_M", "level": 1 } ], "components": [ [ [ "scrap", 3 ] ], [ [ "steel_chunk", 1 ] ] ] }, @@ -2711,14 +2711,21 @@ { "type": "uncraft", "result": "peeler", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ] ] }, + { + "type": "uncraft", + "result": "pot_makeshift_copper", + "time": "5 m", + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "components": [ [ [ "copper_scrap_equivalent", 16, "LIST" ] ] ] + }, { "type": "uncraft", "result": "potato_masher", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 3 ] ] ] }, @@ -2759,7 +2766,7 @@ "type": "uncraft", "skill_used": "fabrication", "difficulty": 1, - "time": "7 m 30 s", + "time": "5 m", "qualities": [ { "id": "SAW_M", "level": 1 } ], "components": [ [ [ "scrap_copper", 5 ] ], [ [ "scrap", 1 ] ] ] }, @@ -2874,7 +2881,7 @@ { "type": "uncraft", "result": "garlic_press", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 3 ] ] ] }, @@ -3023,7 +3030,7 @@ "difficulty": 1, "time": "1 m 30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], - "components": [ [ [ "scrap", 10 ] ] ] + "components": [ [ [ "steel_chunk", 3 ], [ "scrap", 15 ] ] ] }, { "result": "scythe", @@ -3277,14 +3284,14 @@ { "result": "spoon", "type": "uncraft", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ] ] }, { "result": "spork", "type": "uncraft", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ] ] }, @@ -3478,15 +3485,15 @@ { "type": "uncraft", "result": "whisk", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 3 ] ] ] }, { "result": "wine_glass", "type": "uncraft", - "time": "30 s", - "components": [ [ [ "glass_shard", 4 ] ] ] + "time": "1 s", + "components": [ [ [ "glass_shard", 2 ] ] ] }, { "result": "peanut", @@ -3586,7 +3593,7 @@ { "result": "wire", "type": "uncraft", - "time": "1 m 30 s", + "time": "30 s", "qualities": [ { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "scrap", 1 ] ] ] }, @@ -3818,7 +3825,7 @@ "difficulty": 1, "time": "2 m", "qualities": [ { "id": "SAW_M", "level": 1 } ], - "components": [ [ [ "sheet_metal_small", 8 ], [ "steel_chunk", 1 ] ] ] + "components": [ [ [ "steel_chunk", 1 ] ], [ [ "sheet_metal_small", 9 ] ], [ [ "scrap", 3 ] ] ] }, { "result": "pot", diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index 1034ee0b46de6..54bf4bea6b480 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -3437,7 +3437,7 @@ [ "plastic_straw", 3 ], [ "plastic_knife", 2 ], [ "plastic_spoon", 2 ], - [ "plastic_spoon_kids", 2 ], + [ "plastic_spoon_kids", 4 ], [ "plastic_fork", 2 ], [ "plastic_plate", 4 ], [ "plastic_six_dice", 11 ], @@ -3446,7 +3446,7 @@ [ "bag_plastic", 10 ], [ "tumbler_plastic", 4 ], [ "bowl_plastic", 4 ], - [ "plastic_bowl_kids", 4 ], + [ "plastic_bowl_kids", 8 ], [ "sippy_cup", 4 ], [ "gasket_plastic", 1 ] ] From 4ab5b9002753b766ab49791281e83f511ef4140d Mon Sep 17 00:00:00 2001 From: Duck13Tales <67176313+Duck13Tales@users.noreply.github.com> Date: Sun, 12 Jul 2020 21:18:38 -0300 Subject: [PATCH 010/151] Just some aditions to make possible to disassemble some ordinary tools --- data/json/items/generic/dining_kitchen.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/items/generic/dining_kitchen.json b/data/json/items/generic/dining_kitchen.json index c0953495137ce..7262ea9ac987c 100644 --- a/data/json/items/generic/dining_kitchen.json +++ b/data/json/items/generic/dining_kitchen.json @@ -283,7 +283,7 @@ "symbol": "U", "description": "A tall drinking glass.", "copy-from": "base_glass_dish", - "volume": "600 ml", + "volume": "620 ml", "pocket_data": [ { "max_contains_volume": "500 ml", @@ -324,7 +324,7 @@ "symbol": "u", "description": "A glass bowl for soup or dessert.", "copy-from": "base_glass_dish", - "volume": "525 ml", + "volume": "620 ml", "pocket_data": [ { "max_contains_volume": "500 ml", From 21138ba6e2bbab30edcdcf4dcc927dc6513029c6 Mon Sep 17 00:00:00 2001 From: olanti-p Date: Tue, 14 Jul 2020 13:02:30 +0300 Subject: [PATCH 011/151] Get rid of game::unload --- src/activity_actor.cpp | 2 +- src/game.cpp | 7 +------ src/game.h | 2 -- src/iuse.cpp | 4 ++-- src/player.cpp | 2 +- src/vehicle_use.cpp | 2 +- tests/reloading_test.cpp | 2 +- 7 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index ecf459b91ca91..ea746e691b848 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -328,7 +328,7 @@ void aim_activity_actor::unload_RAS_weapon() // Note: this code works only for avatar item_location loc = item_location( you, gun.target ); - g->unload( loc ); + you.unload( loc ); // Give back time for unloading as essentially nothing has been done. if( first_turn ) { diff --git a/src/game.cpp b/src/game.cpp index 21b8ed31c44d2..eb2e7aee07dad 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2307,7 +2307,7 @@ int game::inventory_item_menu( item_location locThisItem, handle_contents_changed( locThisItem ); break; case 'U': - unload( locThisItem ); + u.unload( locThisItem ); handle_contents_changed( locThisItem ); break; case 'r': @@ -9004,11 +9004,6 @@ void game::reload_weapon( bool try_everything ) reload_item(); } -bool game::unload( item_location &loc ) -{ - return u.unload( loc ); -} - void game::wield( item_location loc ) { if( !loc ) { diff --git a/src/game.h b/src/game.h index 44d0eaa7f41e3..0d0638a09330d 100644 --- a/src/game.h +++ b/src/game.h @@ -825,8 +825,6 @@ class game point place_player( const tripoint &dest ); void place_player_overmap( const tripoint &om_dest ); - bool unload( item_location &loc ); // Unload a gun/tool 'U' - unsigned int get_seed() const; /** If invoked, NPCs will be reloaded before next turn. */ diff --git a/src/iuse.cpp b/src/iuse.cpp index b8e0482312837..f4299b08e33ee 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -1809,7 +1809,7 @@ int iuse::remove_all_mods( player *p, item *, bool, const tripoint & ) return 0; } - if( !loc->ammo_remaining() || g->unload( loc ) ) { + if( !loc->ammo_remaining() || p->unload( loc ) ) { item *mod = loc->contents.get_item_with( []( const item & e ) { return e.is_toolmod() && !e.is_irremovable(); @@ -6252,7 +6252,7 @@ int iuse::toolmod_attach( player *p, item *it, bool, const tripoint & ) } if( loc->ammo_remaining() ) { - if( !g->unload( loc ) ) { + if( !p->unload( loc ) ) { p->add_msg_if_player( m_info, _( "You cancel unloading the tool." ) ); return 0; } diff --git a/src/player.cpp b/src/player.cpp index 546bb28fd57a3..b1f4abce2b995 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -3144,7 +3144,7 @@ bool player::gunmod_remove( item &gun, item &mod ) } item_location loc = item_location( *this, &mod ); - if( mod.ammo_remaining() && !g->unload( loc ) ) { + if( mod.ammo_remaining() && !unload( loc ) ) { return false; } diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index f4ac178a89eda..55803a8e12e89 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -2148,7 +2148,7 @@ void vehicle::interact_with( const tripoint &pos, int interact_part ) } case UNLOAD_TURRET: { item_location loc = turret.base(); - g->unload( loc ); + player_character.unload( loc ); return; } case RELOAD_TURRET: { diff --git a/tests/reloading_test.cpp b/tests/reloading_test.cpp index deab69b37e401..94051b246b116 100644 --- a/tests/reloading_test.cpp +++ b/tests/reloading_test.cpp @@ -103,7 +103,7 @@ TEST_CASE( "reload_gun_with_swappable_magazine", "[reload],[gun]" ) REQUIRE( glock.magazine_current() != nullptr ); // We're expecting the magazine to end up in the inventory. item_location glock_loc( dummy, &glock ); - REQUIRE( g->unload( glock_loc ) ); + REQUIRE( dummy.unload( glock_loc ) ); const std::vector glock_mags = dummy.items_with( []( const item & it ) { return it.typeId() == itype_id( "glockmag" ); } ); From 30de6ca68982637fd577d9ba34a55e618ab522e0 Mon Sep 17 00:00:00 2001 From: DialoMalison Date: Tue, 14 Jul 2020 08:39:26 -0400 Subject: [PATCH 012/151] Add longest side data to spearguns and spears --- data/json/items/ranged/spearguns.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/data/json/items/ranged/spearguns.json b/data/json/items/ranged/spearguns.json index 8c56203fdb4bb..e624d1101a5bc 100644 --- a/data/json/items/ranged/spearguns.json +++ b/data/json/items/ranged/spearguns.json @@ -11,6 +11,7 @@ "material": [ "wood" ], "volume": "250 ml", "weight": "18 g", + "longest_side": "120 cm", "bashing": 1, "ammo_type": "fishspear", "damage": { "damage_type": "stab", "amount": 12, "armor_penetration": 4 }, @@ -32,6 +33,7 @@ "material": [ "kevlar_rigid" ], "volume": "250 ml", "weight": "12 g", + "longest_side": "120 cm", "bashing": 1, "ammo_type": "fishspear", "damage": { "damage_type": "stab", "amount": 14, "armor_penetration": 12 }, @@ -53,6 +55,7 @@ "material": [ "iron" ], "volume": "250 ml", "weight": "28 g", + "longest_side": "120 cm", "bashing": 1, "ammo_type": "fishspear", "damage": { "damage_type": "stab", "amount": 14, "armor_penetration": 8 }, @@ -79,6 +82,7 @@ "ammo": [ "fishspear" ], "weight": "3460 g", "volume": "2 L", + "longest_side": "90 cm", "bashing": 8, "to_hit": -2, "ranged_damage": { "damage_type": "stab", "amount": 12 }, @@ -116,6 +120,7 @@ "ammo": [ "fishspear" ], "weight": "3060 g", "volume": "2 L", + "longest_side": "90 cm", "bashing": 8, "to_hit": -2, "ranged_damage": { "damage_type": "stab", "amount": 6 }, @@ -152,6 +157,7 @@ "ammo": [ "fishspear" ], "weight": "840 g", "volume": "1 L", + "longest_side": "35 cm", "bashing": 7, "to_hit": -2, "dispersion": 120, @@ -185,6 +191,7 @@ "ammo": [ "fishspear" ], "weight": "2100 g", "volume": "1750 ml", + "longest_side": "90 cm", "bashing": 7, "to_hit": -2, "ranged_damage": { "damage_type": "stab", "amount": 6 }, From 2f5775fda8d10f6dea846fff646eac22866a518e Mon Sep 17 00:00:00 2001 From: olanti-p Date: Tue, 14 Jul 2020 13:03:07 +0300 Subject: [PATCH 013/151] Migrate ACT_UNLOAD_MAG to the activity actor system --- src/activity_actor.cpp | 69 +++++++++++++++++++++++++++++++++++++++ src/activity_actor.h | 32 ++++++++++++++++++ src/activity_handlers.cpp | 38 --------------------- src/activity_handlers.h | 1 - src/player.cpp | 18 ++++------ 5 files changed, 107 insertions(+), 51 deletions(-) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index ea746e691b848..2b4a689c143be 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -48,6 +48,7 @@ static const skill_id skill_mechanics( "mechanics" ); static const trait_id trait_ILLITERATE( "ILLITERATE" ); +static const std::string flag_MAG_DESTROY( "MAG_DESTROY" ); static const std::string flag_PERFECT_LOCKPICK( "PERFECT_LOCKPICK" ); static const std::string flag_RELOAD_AND_SHOOT( "RELOAD_AND_SHOOT" ); @@ -1318,6 +1319,73 @@ std::unique_ptr try_sleep_activity_actor::deserialize( JsonIn &j return actor.clone(); } +void unload_mag_activity_actor::start( player_activity &act, Character & ) +{ + act.moves_left = moves_total; + act.moves_total = moves_total; +} + +void unload_mag_activity_actor::finish( player_activity &act, Character &who ) +{ + act.set_to_null(); + unload( who, target ); +} + +void unload_mag_activity_actor::unload( Character &who, item_location &target ) +{ + int qty = 0; + item &it = *target.get_item(); + + std::vector remove_contained; + for( item *contained : it.contents.all_items_top() ) { + if( who.as_player()->add_or_drop_with_msg( *contained, true ) ) { + qty += contained->charges; + remove_contained.push_back( contained ); + } + } + // remove the ammo leads in the belt + for( item *remove : remove_contained ) { + it.remove_item( *remove ); + } + + // remove the belt linkage + if( it.is_ammo_belt() ) { + if( it.type->magazine->linkage ) { + item link( *it.type->magazine->linkage, calendar::turn, qty ); + who.as_player()->add_or_drop_with_msg( link, true ); + } + who.add_msg_if_player( _( "You disassemble your %s." ), it.tname() ); + } else { + who.add_msg_if_player( _( "You unload your %s." ), it.tname() ); + } + + if( it.has_flag( flag_MAG_DESTROY ) && it.ammo_remaining() == 0 ) { + target.remove_item(); + } +} + +void unload_mag_activity_actor::serialize( JsonOut &jsout ) const +{ + jsout.start_object(); + + jsout.member( "moves_total", moves_total ); + jsout.member( "target", target ); + + jsout.end_object(); +} + +std::unique_ptr unload_mag_activity_actor::deserialize( JsonIn &jsin ) +{ + unload_mag_activity_actor actor = unload_mag_activity_actor( 0, item_location::nowhere ); + + JsonObject data = jsin.get_object(); + + data.read( "moves_total", actor.moves_total ); + data.read( "target", actor.target ); + + return actor.clone(); +} + void workout_activity_actor::start( player_activity &act, Character &who ) { if( who.get_fatigue() > fatigue_levels::DEAD_TIRED ) { @@ -1573,6 +1641,7 @@ deserialize_functions = { { activity_id( "ACT_OPEN_GATE" ), &open_gate_activity_actor::deserialize }, { activity_id( "ACT_PICKUP" ), &pickup_activity_actor::deserialize }, { activity_id( "ACT_TRY_SLEEP" ), &try_sleep_activity_actor::deserialize }, + { activity_id( "ACT_UNLOAD_MAG" ), &unload_mag_activity_actor::deserialize }, { activity_id( "ACT_WORKOUT_HARD" ), &workout_activity_actor::deserialize }, { activity_id( "ACT_WORKOUT_ACTIVE" ), &workout_activity_actor::deserialize }, { activity_id( "ACT_WORKOUT_MODERATE" ), &workout_activity_actor::deserialize }, diff --git a/src/activity_actor.h b/src/activity_actor.h index de7ded2e1afb0..d8406d5ad2ff5 100644 --- a/src/activity_actor.h +++ b/src/activity_actor.h @@ -585,6 +585,38 @@ class try_sleep_activity_actor : public activity_actor static std::unique_ptr deserialize( JsonIn &jsin ); }; +class unload_mag_activity_actor : public activity_actor +{ + private: + int moves_total; + item_location target; + public: + unload_mag_activity_actor( int moves_total, const item_location &target ) : + moves_total( moves_total ), target( target ) {} + activity_id get_type() const override { + return activity_id( "ACT_UNLOAD_MAG" ); + } + + bool can_resume_with_internal( const activity_actor &other, const Character & ) const override { + const unload_mag_activity_actor &act = static_cast( other ); + return target == act.target; + } + + void start( player_activity &act, Character & ) override; + void do_turn( player_activity &, Character & ) override {} + void finish( player_activity &act, Character &who ) override; + + /** Unloads the magazine instantly. Can be called without an activity. May destroy the item. */ + static void unload( Character &who, item_location &target ); + + std::unique_ptr clone() const override { + return std::make_unique( *this ); + } + + void serialize( JsonOut &jsout ) const override; + static std::unique_ptr deserialize( JsonIn &jsin ); +}; + class workout_activity_actor : public activity_actor { private: diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 094d771cc1b92..466160a5a45ae 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -187,7 +187,6 @@ static const activity_id ACT_TOOLMOD_ADD( "ACT_TOOLMOD_ADD" ); static const activity_id ACT_TRAIN( "ACT_TRAIN" ); static const activity_id ACT_TRAVELLING( "ACT_TRAVELLING" ); static const activity_id ACT_TREE_COMMUNION( "ACT_TREE_COMMUNION" ); -static const activity_id ACT_UNLOAD_MAG( "ACT_UNLOAD_MAG" ); static const activity_id ACT_VEHICLE( "ACT_VEHICLE" ); static const activity_id ACT_VEHICLE_DECONSTRUCTION( "ACT_VEHICLE_DECONSTRUCTION" ); static const activity_id ACT_VEHICLE_REPAIR( "ACT_VEHICLE_REPAIR" ); @@ -276,7 +275,6 @@ static const std::string flag_GIBBED( "GIBBED" ); static const std::string flag_HIDDEN_HALLU( "HIDDEN_HALLU" ); static const std::string flag_HIDDEN_ITEM( "HIDDEN_ITEM" ); static const std::string flag_HIDDEN_POISON( "HIDDEN_POISON" ); -static const std::string flag_MAG_DESTROY( "MAG_DESTROY" ); static const std::string flag_MESSY( "MESSY" ); static const std::string flag_PLANTABLE( "PLANTABLE" ); static const std::string flag_PULPED( "PULPED" ); @@ -416,7 +414,6 @@ activity_handlers::finish_functions = { { ACT_PLAY_WITH_PET, play_with_pet_finish }, { ACT_SHAVE, shaving_finish }, { ACT_HAIRCUT, haircut_finish }, - { ACT_UNLOAD_MAG, unload_mag_finish }, { ACT_ROBOT_CONTROL, robot_control_finish }, { ACT_MIND_SPLICER, mind_splicer_finish }, { ACT_SPELLCASTING, spellcasting_finish }, @@ -4098,41 +4095,6 @@ void activity_handlers::haircut_finish( player_activity *act, player *p ) act->set_to_null(); } -void activity_handlers::unload_mag_finish( player_activity *act, player *p ) -{ - int qty = 0; - item &it = *act->targets[ 0 ]; - - std::vector remove_contained; - for( item *contained : it.contents.all_items_top() ) { - if( p->add_or_drop_with_msg( *contained, true ) ) { - qty += contained->charges; - remove_contained.push_back( contained ); - } - } - // remove the ammo leads in the belt - for( item *remove : remove_contained ) { - it.remove_item( *remove ); - } - - // remove the belt linkage - if( it.is_ammo_belt() ) { - if( it.type->magazine->linkage ) { - item link( *it.type->magazine->linkage, calendar::turn, qty ); - p->add_or_drop_with_msg( link, true ); - } - add_msg( _( "You disassemble your %s." ), it.tname() ); - } else { - add_msg( _( "You unload your %s." ), it.tname() ); - } - - if( it.has_flag( flag_MAG_DESTROY ) && it.ammo_remaining() == 0 ) { - act->targets[ 0 ].remove_item(); - } - - act->set_to_null(); -} - std::vector get_sorted_tiles_by_distance( const tripoint &abspos, const std::unordered_set &tiles ) { diff --git a/src/activity_handlers.h b/src/activity_handlers.h index fb59c19eb404b..b6309241fcf18 100644 --- a/src/activity_handlers.h +++ b/src/activity_handlers.h @@ -235,7 +235,6 @@ void fill_pit_finish( player_activity *act, player *p ); void play_with_pet_finish( player_activity *act, player *p ); void shaving_finish( player_activity *act, player *p ); void haircut_finish( player_activity *act, player *p ); -void unload_mag_finish( player_activity *act, player *p ); void robot_control_finish( player_activity *act, player *p ); void mind_splicer_finish( player_activity *act, player *p ); void spellcasting_finish( player_activity *act, player *p ); diff --git a/src/player.cpp b/src/player.cpp index b1f4abce2b995..7898cb7723778 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -2960,23 +2960,17 @@ bool player::unload( item_location &loc ) } ); if( target->is_magazine() ) { - player_activity unload_mag_act( activity_id( "ACT_UNLOAD_MAG" ) ); - assign_activity( unload_mag_act ); - activity.targets.emplace_back( item_location( loc, target ) ); - - // Calculate the time to remove the contained ammo (consuming half as much time as required to load the magazine) int mv = 0; for( const item *content : target->contents.all_items_top() ) { - mv += this->item_reload_cost( it, *content, content->charges ) / 2; + // We use the same cost for both reloading and unloading + mv += this->item_reload_cost( it, *content, content->charges ); } - activity.moves_left += mv; - - // I think this means if unload is not done on ammo-belt, it takes as long as it takes to reload a mag. - if( !it.is_ammo_belt() ) { - activity.moves_left += mv; + if( it.is_ammo_belt() ) { + // Disassembling ammo belts is easier than assembling them + mv /= 2; } - activity.auto_resume = true; + assign_activity( player_activity( unload_mag_activity_actor( mv, item_location( loc, target ) ) ) ); return true; } else if( target->magazine_current() ) { From 3243e3b5543a0c83ab8d202272b99dabf396bc1a Mon Sep 17 00:00:00 2001 From: olanti-p Date: Tue, 14 Jul 2020 13:51:49 +0300 Subject: [PATCH 014/151] Make it possible to skip activity and unload a magazine immediately --- src/activity_actor.cpp | 2 +- src/player.cpp | 28 ++++++++++++++++------------ src/player.h | 6 +++++- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index 2b4a689c143be..5f98da78dbefa 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -329,7 +329,7 @@ void aim_activity_actor::unload_RAS_weapon() // Note: this code works only for avatar item_location loc = item_location( you, gun.target ); - you.unload( loc ); + you.unload( loc, true ); // Give back time for unloading as essentially nothing has been done. if( first_turn ) { diff --git a/src/player.cpp b/src/player.cpp index 7898cb7723778..e9292032b574b 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -2874,7 +2874,7 @@ bool player::add_or_drop_with_msg( item &it, const bool /*unloading*/, const ite return true; } -bool player::unload( item_location &loc ) +bool player::unload( item_location &loc, bool bypass_activity ) { item &it = *loc; // Unload a container consuming moves per item successfully removed @@ -2960,17 +2960,21 @@ bool player::unload( item_location &loc ) } ); if( target->is_magazine() ) { - int mv = 0; - for( const item *content : target->contents.all_items_top() ) { - // We use the same cost for both reloading and unloading - mv += this->item_reload_cost( it, *content, content->charges ); - } - if( it.is_ammo_belt() ) { - // Disassembling ammo belts is easier than assembling them - mv /= 2; + item_location targloc = item_location( loc, target ); + if( bypass_activity ) { + unload_mag_activity_actor::unload( *this, targloc ); + } else { + int mv = 0; + for( const item *content : target->contents.all_items_top() ) { + // We use the same cost for both reloading and unloading + mv += this->item_reload_cost( it, *content, content->charges ); + } + if( it.is_ammo_belt() ) { + // Disassembling ammo belts is easier than assembling them + mv /= 2; + } + assign_activity( player_activity( unload_mag_activity_actor( mv, targloc ) ) ); } - - assign_activity( player_activity( unload_mag_activity_actor( mv, item_location( loc, target ) ) ) ); return true; } else if( target->magazine_current() ) { @@ -3138,7 +3142,7 @@ bool player::gunmod_remove( item &gun, item &mod ) } item_location loc = item_location( *this, &mod ); - if( mod.ammo_remaining() && !unload( loc ) ) { + if( mod.ammo_remaining() && !unload( loc, true ) ) { return false; } diff --git a/src/player.h b/src/player.h index 322d0b825f63e..dde53a1a251d0 100644 --- a/src/player.h +++ b/src/player.h @@ -412,7 +412,11 @@ class player : public Character */ bool add_or_drop_with_msg( item &it, bool unloading = false, const item *avoid = nullptr ); - bool unload( item_location &loc ); + /** + * Unload item. + * @param bypass_activity If item requires an activity for its unloading, unload item immediately instead. + */ + bool unload( item_location &loc, bool bypass_activity = false ); /** * Try to wield a contained item consuming moves proportional to weapon skill and volume. From c826619112af1a5fc17cadb0113d318dd6e00b19 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Wed, 8 Jul 2020 15:37:44 -0500 Subject: [PATCH 015/151] dialogue: make dialogue work with non-character actors create a generic interface class called `talker` which can be inherited by character/avatar/npc/monster/whatever specific interface classes. talker *alpha and talker *beta will replace avatar *alpha and npc *beta inside of the dialogue class. This will hopefully allow any class to be used in fully feature conversations, though only classes that have a native set_value() member will be able to store persistent values. --- src/talker.h | 302 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 src/talker.h diff --git a/src/talker.h b/src/talker.h new file mode 100644 index 0000000000000..16bce5b90040a --- /dev/null +++ b/src/talker.h @@ -0,0 +1,302 @@ +#pragma once +#ifndef CATA_SRC_TALKER_H +#define CATA_SRC_TALKER_H + +class faction; +class item; +class mission; +class npc; +class player; +class recipe; +struct tripoint; +class vehicle; + +/* + * Talker is an entity independent way of providing a participant in a dialogue. + * Talker is a virtual abstract class and should never really be used. Instead, + * entity specific talker child classes such as character_talker should be used. + */ +class talker +{ + public: + virtual ~talker() = default; + // virtual member accessor functions + virtual player *get_character() { + return nullptr; + } + virtual player *get_character() const { + return nullptr; + } + virtual npc *get_npc() { + return nullptr; + } + virtual npc *get_npc() const { + return nullptr; + } + + // identity and location + virtual std::string disp_name() const { + return ""; + } + virtual character_id getID() const { + return character_id( 0 ); + } + virtual bool is_male() const { + return false; + } + virtual std::vector get_grammatical_genders() const { + return {}; + } + virtual int posx() const = 0; + virtual int posy() const = 0; + virtual int posz() const = 0; + virtual tripoint pos() const = 0; + virtual tripoint global_omt_location() const = 0; + virtual std::string distance_to_goal() const { + return ""; + } + + // mandatory functions for starting a dialogue + virtual bool will_talk_to_u( const player &, bool ) { + return false; + } + virtual std::vector get_topics( bool ) { + return {}; + } + virtual void check_missions() {} + virtual void update_missions( const std::vector &, const character_id & ) {} + virtual bool check_hostile_response( int ) const { + return false; + } + virtual int parse_mod( const std::string &, int ) const { + return 0; + } + virtual int trial_chance_mod( const std::string & ) const { + return 0; + } + + // stats, skills, traits, bionics, and magic + virtual int str_cur() const { + return 0; + } + virtual int dex_cur() const { + return 0; + } + virtual int int_cur() const { + return 0; + } + virtual int per_cur() const { + return 0; + } + virtual int get_skill_level( const skill_id & ) const { + return false; + } + virtual bool has_trait( const trait_id & ) const { + return false; + } + virtual void set_mutation( const trait_id & ) {} + virtual void unset_mutation( const trait_id & ) {} + virtual bool has_trait_flag( const std::string & ) const { + return false; + } + virtual bool crossed_threshold() const { + return false; + } + virtual int num_bionics() const { + return 0; + } + virtual bool has_max_power() const { + return false; + } + virtual bool has_bionic( const bionic_id & ) const { + return false; + } + virtual bool knows_spell( const spell_id & ) const { + return false; + } + virtual std::vector skills_offered_to( const talker & ) const { + return {}; + } + virtual std::string skill_training_text( const talker &, const skill_id & ) const { + return {}; + } + virtual std::vector styles_offered_to( const talker & ) const { + return {}; + } + virtual std::string style_training_text( const talker &, const matype_id & ) const { + return {}; + } + virtual std::vector spells_offered_to( talker & ) { + return {}; + } + virtual std::string spell_training_text( talker &, const spell_id & ) { + return {}; + } + virtual void store_chosen_training( const skill_id &, const matype_id &, + const spell_id & ) { + } + + // effects and values + virtual bool has_effect( const efftype_id & ) const { + return false; + } + virtual bool is_deaf() const { + return false; + } + virtual void add_effect( const efftype_id &, const time_duration &, bool ) {} + virtual void remove_effect( const efftype_id & ) {} + virtual std::string get_value( const std::string & ) const { + return ""; + } + virtual void set_value( const std::string &, const std::string & ) {} + virtual void remove_value( const std::string & ) {} + + // inventory, buying, and selling + virtual bool is_wearing( const itype_id & ) const { + return false; + } + virtual int charges_of( const itype_id & ) const { + return 0; + } + virtual bool has_charges( const itype_id &, int ) const { + return false; + } + virtual std::list use_charges( const itype_id &, int ) { + return {}; + } + virtual bool has_amount( const itype_id &, int ) const { + return false; + } + virtual std::list use_amount( const itype_id &, int ) { + return {}; + } + virtual int value( const item & ) { + return 0; + } + virtual int cash() const { + return 0; + } + virtual int debt() const { + return 0; + } + virtual void add_debt( int ) {} + virtual std::vector items_with( const std::function & ) const { + return {}; + }; + virtual void i_add( const item & ) {} + virtual void remove_items_with( const std::function & ) {} + virtual bool unarmed_attack() const { + return false; + } + virtual bool can_stash_weapon() const { + return false; + } + virtual bool has_stolen_item( const talker & ) const { + return false; + } + virtual int cash_to_favor( int ) const { + return 0; + } + virtual std::string give_item_to( bool ) { + return _( "Nope." ); + } + virtual bool buy_from( int ) { + return false; + } + virtual void buy_monster( talker &, const mtype_id &, int, int, bool, + const translation & ) {} + + // missions + virtual std::vector available_missions() const { + return {}; + } + virtual std::vector assigned_missions() const { + return {}; + } + virtual mission *selected_mission() const { + return nullptr; + } + virtual void select_mission( mission * ) { + } + virtual void add_mission( const mission_type_id & ) {} + virtual void set_companion_mission( const std::string & ) {} + + // factions and alliances + virtual faction *get_faction() const { + return nullptr; + } + virtual void set_fac( const faction_id & ) {} + virtual void add_faction_rep( int ) {} + virtual bool is_following() const { + return false; + } + virtual bool is_friendly( const Character & ) const { + return false; + } + virtual bool is_player_ally() const { + return false; + } + virtual bool turned_hostile() const { + return false; + } + virtual bool is_enemy() const { + return false; + } + virtual void make_angry() {} + + // ai rules + virtual bool has_ai_rule( const std::string &, const std::string & ) const { + return false; + } + virtual void toggle_ai_rule( const std::string &, const std::string & ) {} + virtual void set_ai_rule( const std::string &, const std::string & ) {} + virtual void clear_ai_rule( const std::string &, const std::string & ) {} + + // other descriptors + virtual std::string get_job_description() const { + return ""; + } + virtual std::string evaluation_by( const talker & ) const { + return ""; + } + virtual std::string short_description() const { + return ""; + } + virtual bool has_activity() const { + return false; + } + virtual bool is_mounted() const { + return false; + } + virtual bool is_myclass( const npc_class_id & ) const { + return false; + } + virtual void set_class( const npc_class_id & ) {} + virtual int get_fatigue() const { + return 0; + } + virtual int get_hunger() const { + return 0; + } + virtual int get_thirst() const { + return 0; + } + virtual bool is_in_control_of( const vehicle & ) const { + return false; + } + + // speaking + virtual void say( const std::string & ) {} + virtual void shout( const std::string & = "", bool = false ) {} + + // miscellaneous + virtual bool enslave_mind() { + return false; + } + virtual std::string opinion_text() const { + return ""; + } + virtual void add_opinion( int /*trust*/, int /*fear*/, int /*value*/, int /*anger*/, + int /*debt*/ ) {} +}; +#endif // CATA_SRC_TALKER_H From e729b240d2e8c848337c6395a29d84afc953d920 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Mon, 13 Jul 2020 08:32:40 -0500 Subject: [PATCH 016/151] dialogue: add talker_character, talker_avatar, and talker_npc classes add the talker_character, talker_avatar, and talker_npc child classes that build on top of the generic talker interface. --- src/avatar.cpp | 11 + src/avatar.h | 2 + src/npc.cpp | 11 + src/npc.h | 4 +- src/player.h | 1 - src/talker_avatar.cpp | 130 ++++++ src/talker_avatar.h | 29 ++ src/talker_character.cpp | 293 ++++++++++++++ src/talker_character.h | 103 +++++ src/talker_npc.cpp | 832 +++++++++++++++++++++++++++++++++++++++ src/talker_npc.h | 106 +++++ 11 files changed, 1520 insertions(+), 2 deletions(-) create mode 100644 src/talker_avatar.cpp create mode 100644 src/talker_avatar.h create mode 100644 src/talker_character.cpp create mode 100644 src/talker_character.h create mode 100644 src/talker_npc.cpp create mode 100644 src/talker_npc.h diff --git a/src/avatar.cpp b/src/avatar.cpp index d46ec33f52c09..592ad58f0e619 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -62,6 +62,8 @@ #include "stomach.h" #include "string_formatter.h" #include "string_id.h" +#include "talker.h" +#include "talker_avatar.h" #include "translations.h" #include "type_id.h" #include "ui.h" @@ -1667,6 +1669,15 @@ std::string avatar::total_daily_calories_string() const return ret; } +std::unique_ptr get_talker_for( avatar &me ) +{ + return std::make_unique( &me ); +} +std::unique_ptr get_talker_for( avatar *me ) +{ + return std::make_unique( me ); +} + points_left::points_left() { limit = MULTI_POOL; diff --git a/src/avatar.h b/src/avatar.h index 1be14fd49a503..36a4ba4bc6994 100644 --- a/src/avatar.h +++ b/src/avatar.h @@ -300,6 +300,8 @@ class avatar : public player }; avatar &get_avatar(); +std::unique_ptr get_talker_for( avatar &me ); +std::unique_ptr get_talker_for( avatar *me ); struct points_left { int stat_points; diff --git a/src/npc.cpp b/src/npc.cpp index d0c76c456fa4f..a436ac15786ad 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -63,6 +63,8 @@ #include "sounds.h" #include "stomach.h" #include "string_formatter.h" +#include "talker.h" +#include "talker_npc.h" #include "text_snippets.h" #include "tileray.h" #include "trait_group.h" @@ -3389,3 +3391,12 @@ std::string npc::describe_mission() const "mission: %d.", static_cast( mission ) ); } // switch (mission) } + +std::unique_ptr get_talker_for( npc &guy ) +{ + return std::make_unique( &guy ); +} +std::unique_ptr get_talker_for( npc *guy ) +{ + return std::make_unique( guy ); +} diff --git a/src/npc.h b/src/npc.h index 2fd39689e78ab..41103fe58e9f9 100644 --- a/src/npc.h +++ b/src/npc.h @@ -49,6 +49,7 @@ class mission; class monfaction; class monster; class npc_class; +class talker; class vehicle; struct bionic_data; struct mission_type; @@ -1439,5 +1440,6 @@ std::ostream &operator<< ( std::ostream &os, const npc_need &need ); /** Opens a menu and allows player to select a friendly NPC. */ npc *pick_follower(); - +std::unique_ptr get_talker_for( npc &guy ); +std::unique_ptr get_talker_for( npc *guy ); #endif // CATA_SRC_NPC_H diff --git a/src/player.h b/src/player.h index 322d0b825f63e..cc89726a0ebe7 100644 --- a/src/player.h +++ b/src/player.h @@ -763,5 +763,4 @@ class player : public Character /** Stamp of skills. @ref learned_recipes are valid only with this set of skills. */ mutable decltype( _skills ) valid_autolearn_skills; }; - #endif // CATA_SRC_PLAYER_H diff --git a/src/talker_avatar.cpp b/src/talker_avatar.cpp new file mode 100644 index 0000000000000..157547464c3a2 --- /dev/null +++ b/src/talker_avatar.cpp @@ -0,0 +1,130 @@ +#include "avatar.h" +#include "game.h" +#include "game_constants.h" +#include "messages.h" +#include "monster.h" +#include "mtype.h" +#include "npc.h" +#include "npctrade.h" +#include "output.h" +#include "player.h" +#include "talker_avatar.h" + +static const efftype_id effect_pacified( "pacified" ); +static const efftype_id effect_pet( "pet" ); + +static const skill_id skill_speech( "speech" ); + +static const bionic_id bio_armor_eyes( "bio_armor_eyes" ); +static const bionic_id bio_deformity( "bio_deformity" ); +static const bionic_id bio_face_mask( "bio_face_mask" ); +static const bionic_id bio_voice( "bio_voice" ); + +static const trait_id trait_PROF_FOODP( "PROF_FOODP" ); + +std::vector talker_avatar::get_topics( bool ) +{ + std::vector add_topics; + if( has_trait( trait_PROF_FOODP ) && !( is_wearing( itype_id( "foodperson_mask" ) ) || + is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) { + add_topics.push_back( "TALK_NOFACE" ); + } + return add_topics; +} + +int talker_avatar::parse_mod( const std::string &attribute, const int factor ) const +{ + int modifier = 0; + if( attribute == "U_INTIMIDATE" ) { + modifier = me_chr->intimidation(); + } + modifier *= factor; + return modifier; +} + +int talker_avatar::trial_chance_mod( const std::string &trial_type ) const +{ + int chance = 0; + const social_modifiers &me_mods = me_chr->get_mutation_social_mods(); + if( trial_type == "lie" ) { + chance += me_chr->talk_skill() + me_mods.lie; + + //come on, who would suspect a robot of lying? + if( me_chr->has_bionic( bio_voice ) ) { + chance += 10; + } + if( me_chr->has_bionic( bio_face_mask ) ) { + chance += 20; + } + } else if( trial_type == "persuade" ) { + chance += me_chr->talk_skill() + me_mods.persuade; + + if( me_chr->has_bionic( bio_face_mask ) ) { + chance += 10; + } + if( me_chr->has_bionic( bio_deformity ) ) { + chance -= 50; + } + if( me_chr->has_bionic( bio_voice ) ) { + chance -= 20; + } + } else if( trial_type == "intimidate" ) { + chance += me_chr->intimidation() + me_mods.intimidate; + + if( me_chr->has_bionic( bio_face_mask ) ) { + chance += 10; + } + if( me_chr->has_bionic( bio_armor_eyes ) ) { + chance += 10; + } + if( me_chr->has_bionic( bio_deformity ) ) { + chance += 20; + } + if( me_chr->has_bionic( bio_voice ) ) { + chance += 20; + } + } + return chance; +} + +void talker_avatar::buy_monster( talker &seller, const mtype_id &mtype, int cost, + int count, bool pacified, const translation &name ) +{ + npc *seller_guy = seller.get_npc(); + if( !seller_guy ) { + popup( _( "%s can't sell you any %s" ), seller.disp_name(), mtype.obj().nname( 2 ) ); + return; + } + if( !npc_trading::pay_npc( *seller_guy, cost ) ) { + popup( _( "You can't afford it!" ) ); + return; + } + + for( int i = 0; i < count; i++ ) { + monster *const mon_ptr = g->place_critter_around( mtype, me_chr->pos(), 3 ); + if( !mon_ptr ) { + add_msg( m_debug, "Cannot place u_buy_monster, no valid placement locations." ); + break; + } + monster &tmp = *mon_ptr; + // Our monster is always a pet. + tmp.friendly = -1; + tmp.add_effect( effect_pet, 1_turns, num_bp, true ); + + if( pacified ) { + tmp.add_effect( effect_pacified, 1_turns, num_bp, true ); + } + + if( !name.empty() ) { + tmp.unique_name = name.translated(); + } + + } + + if( name.empty() ) { + popup( _( "%1$s gives you %2$d %3$s." ), seller_guy->name, + count, mtype.obj().nname( count ) ); + } else { + popup( _( "%1$s gives you %2$s." ), seller_guy->name, name ); + } +} diff --git a/src/talker_avatar.h b/src/talker_avatar.h new file mode 100644 index 0000000000000..53f7fff71bff7 --- /dev/null +++ b/src/talker_avatar.h @@ -0,0 +1,29 @@ +#pragma once +#ifndef CATA_SRC_TALKER_AVATAR_H +#define CATA_SRC_TALKER_AVATAR_H + +#include "talker.h" +#include "talker_character.h" + +class avatar; +/* + * Talker wrapper class for avatar. + */ +class talker_avatar: public talker_character +{ + public: + talker_avatar( avatar *new_me ) : talker_character( new_me ) { + } + ~talker_avatar() override = default; + + // mandatory functions for starting a dialogue + std::vector get_topics( bool ) override; + int parse_mod( const std::string &attribute, int factor ) const override; + int trial_chance_mod( const std::string &trial_type ) const override; + + // inventory and such + void buy_monster( talker &seller, const mtype_id &mtype, int cost, + int count, bool pacified, const translation &name ) override; +}; +#endif // CATA_SRC_TALKER_AVATAR_H + diff --git a/src/talker_character.cpp b/src/talker_character.cpp new file mode 100644 index 0000000000000..11e71f4291170 --- /dev/null +++ b/src/talker_character.cpp @@ -0,0 +1,293 @@ +#include "game.h" +#include "game_constants.h" +#include "messages.h" +#include "monster.h" +#include "mtype.h" +#include "npc.h" +#include "npctrade.h" +#include "output.h" +#include "player.h" +#include "talker_character.h" +#include "vehicle.h" + +static const efftype_id effect_pacified( "pacified" ); +static const efftype_id effect_pet( "pet" ); + +static const skill_id skill_speech( "speech" ); + +static const bionic_id bio_armor_eyes( "bio_armor_eyes" ); +static const bionic_id bio_deformity( "bio_deformity" ); +static const bionic_id bio_face_mask( "bio_face_mask" ); +static const bionic_id bio_voice( "bio_voice" ); + +static const trait_id trait_PROF_FOODP( "PROF_FOODP" ); + +std::string talker_character::disp_name() const +{ + return me_chr->disp_name(); +} + +character_id talker_character::getID() const +{ + return me_chr->getID(); +} + +bool talker_character::is_male() const +{ + return me_chr->male; +} + +std::vector talker_character::get_grammatical_genders() const +{ + return me_chr->get_grammatical_genders(); +} + +int talker_character::posx() const +{ + return me_chr->posx(); +} + +int talker_character::posy() const +{ + return me_chr->posy(); +} + +int talker_character::posz() const +{ + return me_chr->posz(); +} + +tripoint talker_character::pos() const +{ + return me_chr->pos(); +} + +tripoint talker_character::global_omt_location() const +{ + return me_chr->global_omt_location(); +} + +int talker_character::str_cur() const +{ + return me_chr->str_cur; +} + +int talker_character::dex_cur() const +{ + return me_chr->dex_cur; +} + +int talker_character::int_cur() const +{ + return me_chr->int_cur; +} + +int talker_character::per_cur() const +{ + return me_chr->per_cur; +} + +bool talker_character::has_trait( const trait_id &trait_to_check ) const +{ + return me_chr->has_trait( trait_to_check ); +} + +bool talker_character::is_deaf() const +{ + return me_chr->is_deaf(); +} + +void talker_character::set_mutation( const trait_id &new_trait ) +{ + me_chr->set_mutation( new_trait ); +} + +void talker_character::unset_mutation( const trait_id &old_trait ) +{ + me_chr->unset_mutation( old_trait ); +} + +bool talker_character::has_trait_flag( const std::string &trait_flag_to_check ) const +{ + return me_chr->has_trait_flag( trait_flag_to_check ); +} + +bool talker_character::crossed_threshold() const +{ + return me_chr->crossed_threshold(); +} + +int talker_character::num_bionics() const +{ + return me_chr->num_bionics(); +} + +bool talker_character::has_max_power() const +{ + return me_chr->has_max_power(); +} + +bool talker_character::has_bionic( const bionic_id &bionics_id ) const +{ + return me_chr->has_bionic( bionics_id ); +} + +bool talker_character::knows_spell( const spell_id &sp ) const +{ + return me_chr->magic.knows_spell( sp ); +} + +int talker_character::get_skill_level( const skill_id &skill ) const +{ + return me_chr->get_skill_level( skill ); +} + +bool talker_character::has_effect( const efftype_id &effect_id ) const +{ + return me_chr->has_effect( effect_id ); +} + +void talker_character::add_effect( const efftype_id &new_effect, const time_duration &dur, + bool permanent ) +{ + me_chr->add_effect( new_effect, dur, num_bp, permanent ); +} + +void talker_character::remove_effect( const efftype_id &old_effect ) +{ + me_chr->remove_effect( old_effect, num_bp ); +} + +std::string talker_character:: get_value( const std::string &var_name ) const +{ + return me_chr->get_value( var_name ); +} + +void talker_character::set_value( const std::string &var_name, const std::string &value ) +{ + me_chr->set_value( var_name, value ); +} + +void talker_character::remove_value( const std::string &var_name ) +{ + me_chr->remove_value( var_name ); +} + +bool talker_character::is_wearing( const itype_id &item_id ) const +{ + return me_chr->is_wearing( item_id ); +} + +int talker_character::charges_of( const itype_id &item_id ) const +{ + return me_chr->charges_of( item_id ); +} + +bool talker_character::has_charges( const itype_id &item_id, int count ) const +{ + return me_chr->has_charges( item_id, count ); +} + +std::list talker_character::use_charges( const itype_id &item_name, const int count ) +{ + return me_chr->use_charges( item_name, count ); +} + +std::list talker_character::use_amount( const itype_id &item_name, const int count ) +{ + return me_chr->use_amount( item_name, count ); +} + +bool talker_character::has_amount( const itype_id &item_id, int count ) const +{ + return me_chr->has_amount( item_id, count ); +} + +int talker_character::cash() const +{ + return me_chr->cash; +} + +std::vector talker_character::items_with( const std::function + &filter ) const +{ + return me_chr->items_with( filter ); +} + +void talker_character::i_add( const item &new_item ) +{ + me_chr->i_add( new_item ); +} + +void talker_character::remove_items_with( const std::function &filter ) +{ + me_chr->remove_items_with( filter ); +} + +bool talker_character::unarmed_attack() const +{ + return me_chr->unarmed_attack(); +} + +bool talker_character::can_stash_weapon() const +{ + return me_chr->can_pickVolume( me_chr->weapon ); +} + +bool talker_character::has_stolen_item( const talker &guy ) const +{ + const player *owner = guy.get_character(); + if( owner ) { + for( auto &elem : me_chr->inv_dump() ) { + if( elem->is_old_owner( *owner, true ) ) { + return true; + } + } + } + return false; +} + +faction *talker_character::get_faction() const +{ + return me_chr->get_faction(); +} + +std::string talker_character::short_description() const +{ + return me_chr->short_description(); +} + +bool talker_character::has_activity() const +{ + return !me_chr->activity.is_null(); +} + +bool talker_character::is_mounted() const +{ + return me_chr->is_mounted(); +} + +int talker_character::get_fatigue() const +{ + return me_chr->get_fatigue(); +} + +int talker_character::get_hunger() const +{ + return me_chr->get_hunger(); +} + +int talker_character::get_thirst() const +{ + return me_chr->get_thirst(); +} + +bool talker_character::is_in_control_of( const vehicle &veh ) const +{ + return veh.player_in_control( *me_chr ); +} + +void talker_character::shout( const std::string &speech, bool order ) +{ + me_chr->shout( speech, order ); +} diff --git a/src/talker_character.h b/src/talker_character.h new file mode 100644 index 0000000000000..105c6bc3a979c --- /dev/null +++ b/src/talker_character.h @@ -0,0 +1,103 @@ +#pragma once +#ifndef CATA_SRC_TALKER_CHARACTER_H +#define CATA_SRC_TALKER_CHARACTER_H + +#include "talker.h" + +class player; +class faction; +class item; +class mission; +class npc; +struct tripoint; +class vehicle; +/* + * Talker wrapper class for Character. well, ideally, but since Character is such a mess, + * it's the wrapper class for player + * Should never be invoked directly. Only talker_avatar and talker_npc are really valid. + */ +class talker_character: public talker +{ + public: + talker_character( player *new_me ): me_chr( new_me ) { + } + ~talker_character() override = default; + + // underlying element accessor functions + player *get_character() override { + return me_chr; + } + player *get_character() const override { + return me_chr; + } + // identity and location + std::string disp_name() const override; + character_id getID() const override; + bool is_male() const override; + std::vector get_grammatical_genders() const override; + int posx() const override; + int posy() const override; + int posz() const override; + tripoint pos() const override; + tripoint global_omt_location() const override; + + // stats, skills, traits, bionics, and magic + int str_cur() const override; + int dex_cur() const override; + int int_cur() const override; + int per_cur() const override; + bool has_trait( const trait_id &trait_to_check ) const override; + void set_mutation( const trait_id &new_trait ) override; + void unset_mutation( const trait_id &old_trait ) override; + bool has_trait_flag( const std::string &trait_flag_to_check ) const override; + bool crossed_threshold() const override; + int num_bionics() const override; + bool has_max_power() const override; + bool has_bionic( const bionic_id &bionics_id ) const override; + bool knows_spell( const spell_id &sp ) const override; + int get_skill_level( const skill_id &skill ) const override; + + // effects and values + bool has_effect( const efftype_id &effect_id ) const override; + bool is_deaf() const override; + void add_effect( const efftype_id &new_effect, const time_duration &dur, + bool permanent ) override; + void remove_effect( const efftype_id &old_effect ) override; + std::string get_value( const std::string &var_name ) const override; + void set_value( const std::string &var_name, const std::string &value ) override; + void remove_value( const std::string &var_name ) override; + + // inventory, buying, and selling + bool is_wearing( const itype_id &item_id ) const override; + int charges_of( const itype_id &item_id ) const override; + bool has_charges( const itype_id &item_id, int count ) const override; + std::list use_charges( const itype_id &item_name, int count ) override; + bool has_amount( const itype_id &item_id, int count ) const override; + std::list use_amount( const itype_id &item_name, int count ) override; + int cash() const override; + std::vector items_with( const std::function &filter ) const override; + void i_add( const item &new_item ) override; + void remove_items_with( const std::function &filter ) override; + bool unarmed_attack() const override; + bool can_stash_weapon() const override; + bool has_stolen_item( const talker &guy ) const override; + + // factions and alliances + faction *get_faction() const override; + + // other descriptors + std::string short_description() const override; + bool has_activity() const override; + bool is_mounted() const override; + int get_fatigue() const override; + int get_hunger() const override; + int get_thirst() const override; + bool is_in_control_of( const vehicle &veh ) const override; + + // speaking + void shout( const std::string &speech = "", bool order = false ) override; + + protected: + player *me_chr; +}; +#endif // CATA_SRC_TALKER_CHARACTER_H diff --git a/src/talker_npc.cpp b/src/talker_npc.cpp new file mode 100644 index 0000000000000..ca48809c742b7 --- /dev/null +++ b/src/talker_npc.cpp @@ -0,0 +1,832 @@ +#include "avatar.h" +#include "game.h" +#include "game_constants.h" +#include "game_inventory.h" +#include "item.h" +#include "itype.h" +#include "item_location.h" +#include "line.h" +#include "martialarts.h" +#include "messages.h" +#include "mission.h" +#include "mission_companion.h" +#include "player.h" +#include "npc.h" +#include "npctalk.h" +#include "npctrade.h" +#include "skill.h" +#include "talker_npc.h" +#include "talker_character.h" + +class Character; + +static const efftype_id effect_lying_down( "lying_down" ); +static const efftype_id effect_narcosis( "narcosis" ); +static const efftype_id effect_npc_suspend( "npc_suspend" ); +static const efftype_id effect_sleep( "sleep" ); + +static const trait_id trait_DEBUG_MIND_CONTROL( "DEBUG_MIND_CONTROL" ); +static const trait_id trait_PROF_FOODP( "PROF_FOODP" ); + +std::string talker_npc::distance_to_goal() const +{ + // TODO: this ignores the z-component + int dist = rl_dist( me_npc->global_omt_location(), me_npc->goal ); + std::string response; + dist *= 100; + if( dist >= 1300 ) { + int miles = dist / 25; // *100, e.g. quarter mile is "25" + miles -= miles % 25; // Round to nearest quarter-mile + int fullmiles = ( miles - miles % 100 ) / 100; // Left of the decimal point + if( fullmiles < 0 ) { + fullmiles = 0; + } + response = string_format( _( "%d.%d miles." ), fullmiles, miles ); + } else { + response = string_format( ngettext( "%d foot.", "%d feet.", dist ), dist ); + } + return response; +} + +bool talker_npc::will_talk_to_u( const player &u, bool force ) +{ + if( u.is_dead_state() ) { + me_npc->set_attitude( NPCATT_NULL ); + return false; + } + if( g->u.getID() == u.getID() ) { + if( me_npc->get_faction() ) { + me_npc->get_faction()->known_by_u = true; + } + me_npc->set_known_to_u( true ); + } + // This is necessary so that we don't bug the player over and over + if( me_npc->get_attitude() == NPCATT_TALK ) { + me_npc->set_attitude( NPCATT_NULL ); + } else if( !force && ( me_npc->get_attitude() == NPCATT_FLEE || + me_npc-> get_attitude() == NPCATT_FLEE_TEMP ) ) { + add_msg( _( "%s is fleeing from you!" ), disp_name() ); + return false; + } else if( !force && me_npc->get_attitude() == NPCATT_KILL ) { + add_msg( _( "%s is hostile!" ), disp_name() ); + return false; + } + return true; +} + +std::vector talker_npc::get_topics( bool radio_contact ) +{ + std::vector add_topics; + // For each active mission we have, let the mission know we talked to this NPC. + for( auto &mission : g->u.get_active_missions() ) { + mission->on_talk_with_npc( me_npc->getID() ); + } + + add_topics.push_back( me_npc->chatbin.first_topic ); + if( radio_contact ) { + add_topics.push_back( "TALK_RADIO" ); + } else if( me_npc->is_leader() ) { + add_topics.push_back( "TALK_LEADER" ); + } else if( me_npc->is_player_ally() && ( me_npc->is_walking_with() || me_npc->has_activity() ) ) { + add_topics.push_back( "TALK_FRIEND" ); + } else if( me_npc->get_attitude() == NPCATT_RECOVER_GOODS ) { + add_topics.push_back( "TALK_STOLE_ITEM" ); + } + int most_difficult_mission = 0; + for( auto &mission : me_npc->chatbin.missions ) { + const auto &type = mission->get_type(); + if( type.urgent && type.difficulty > most_difficult_mission ) { + add_topics.push_back( "TALK_MISSION_DESCRIBE_URGENT" ); + me_npc->chatbin.mission_selected = mission; + most_difficult_mission = type.difficulty; + } + } + most_difficult_mission = 0; + bool chosen_urgent = false; + for( auto &mission : me_npc->chatbin.missions_assigned ) { + if( mission->get_assigned_player_id() != g->u.getID() ) { + // Not assigned to the player that is currently talking to the npc + continue; + } + const auto &type = mission->get_type(); + if( ( type.urgent && !chosen_urgent ) || ( type.difficulty > most_difficult_mission && + ( type.urgent || !chosen_urgent ) ) ) { + chosen_urgent = type.urgent; + add_topics.push_back( "TALK_MISSION_INQUIRE" ); + me_npc->chatbin.mission_selected = mission; + most_difficult_mission = type.difficulty; + } + } + + // Needs + if( me_npc->has_effect( effect_npc_suspend ) ) { + add_topics.push_back( "TALK_REBOOT" ); + } + if( me_npc->has_effect( effect_sleep ) || me_npc->has_effect( effect_lying_down ) ) { + if( me_npc->has_effect( effect_narcosis ) ) { + add_topics.push_back( "TALK_SEDATED" ); + } else { + add_topics.push_back( "TALK_WAKE_UP" ); + } + } + + if( add_topics.back() == "TALK_NONE" ) { + add_topics.back() = me_npc->pick_talk_topic( g->u ); + } + me_npc->moves -= 100; + + if( g->u.is_deaf() ) { + if( add_topics.back() == "TALK_MUG" || + add_topics.back() == "TALK_STRANGER_AGGRESSIVE" ) { + me_npc->make_angry(); + add_topics.push_back( "TALK_DEAF_ANGRY" ); + } else { + add_topics.push_back( "TALK_DEAF" ); + } + } + + if( me_npc->has_trait( trait_PROF_FOODP ) && + !( me_npc->is_wearing( itype_id( "foodperson_mask_on" ) ) || + me_npc->is_wearing( itype_id( "foodperson_mask" ) ) ) ) { + add_topics.push_back( "TALK_NPC_NOFACE" ); + } + me_npc->decide_needs(); + + return add_topics; +} + +void talker_npc::check_missions() +{ + me_npc->chatbin.check_missions(); +} + +void talker_npc::update_missions( const std::vector &missions_assigned, + const character_id &charID ) +{ + if( me_npc->chatbin.mission_selected != nullptr ) { + if( me_npc->chatbin.mission_selected->get_assigned_player_id() != charID ) { + // Don't talk about a mission that is assigned to someone else. + me_npc->chatbin.mission_selected = nullptr; + } + } + if( me_npc->chatbin.mission_selected == nullptr ) { + // if possible, select a mission to talk about + if( !me_npc->chatbin.missions.empty() ) { + me_npc->chatbin.mission_selected = me_npc->chatbin.missions.front(); + } else if( !missions_assigned.empty() ) { + me_npc->chatbin.mission_selected = missions_assigned.front(); + } + } +} + +bool talker_npc::check_hostile_response( const int anger ) const +{ + return me_npc->op_of_u.anger + anger > me_npc->hostile_anger_level(); +} + +// Every OWED_VAL that the NPC owes you counts as +1 towards convincing +static constexpr int OWED_VAL = 1000; +int talker_npc::parse_mod( const std::string &attribute, const int factor ) const +{ + int modifier = 0; + if( attribute == "ANGER" ) { + modifier = me_npc->op_of_u.anger; + } else if( attribute == "FEAR" ) { + modifier = me_npc->op_of_u.fear; + } else if( attribute == "TRUST" ) { + modifier = me_npc->op_of_u.trust; + } else if( attribute == "VALUE" ) { + modifier = me_npc->op_of_u.value; + } else if( attribute == "POS_FEAR" ) { + modifier = std::max( 0, me_npc->op_of_u.fear ); + } else if( attribute == "AGGRESSION" ) { + modifier = me_npc->personality.aggression; + } else if( attribute == "ALTRUISM" ) { + modifier = me_npc->personality.altruism; + } else if( attribute == "BRAVERY" ) { + modifier = me_npc->personality.bravery; + } else if( attribute == "COLLECTOR" ) { + modifier = me_npc->personality.collector; + } else if( attribute == "MISSIONS" ) { + modifier = me_npc->assigned_missions_value() / OWED_VAL; + } else if( attribute == "NPC_INTIMIDATE" ) { + modifier = me_npc->intimidation(); + } + modifier *= factor; + return modifier; +} + +int talker_npc::trial_chance_mod( const std::string &trial_type ) const +{ + int chance = 0; + if( trial_type == "lie" ) { + chance += - me_npc->talk_skill() + me_npc->op_of_u.trust * 3; + } else if( trial_type == "persuade" ) { + chance += - static_cast( me_npc->talk_skill() * 0.5 ) + + me_npc->op_of_u.trust * 2 + me_npc->op_of_u.value; + } else if( trial_type == "intimidate" ) { + chance += - me_npc->intimidation() + me_npc->op_of_u.fear * 2 - + me_npc->personality.bravery * 2; + } + return chance; +} + +std::vector talker_npc::skills_offered_to( const talker &student ) const +{ + if( student.get_character() ) { + return me_npc->skills_offered_to( *student.get_character() ); + } else { + return {}; + } +} + +std::string talker_npc::skill_training_text( const talker &student, + const skill_id &skill ) const +{ + const player *pupil = student.get_character(); + if( !pupil ) { + return ""; + } + const int cost = me_npc->is_ally( *pupil ) ? 0 : 1000 * + ( 1 + pupil->get_skill_level( skill ) ) * + ( 1 + pupil->get_skill_level( skill ) ); + SkillLevel skill_level_obj = pupil->get_skill_level_object( skill ); + const int cur_level = skill_level_obj.level(); + const int cur_level_exercise = skill_level_obj.exercise(); + skill_level_obj.train( 100 ); + const int next_level = skill_level_obj.level(); + const int next_level_exercise = skill_level_obj.exercise(); + + //~Skill name: current level (exercise) -> next level (exercise) (cost in dollars) + return string_format( cost > 0 ? _( "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" ) : + _( "%s: %d (%d%%) -> %d (%d%%)" ), skill.obj().name(), cur_level, + cur_level_exercise, next_level, next_level_exercise, cost / 100 ); +} + +std::vector talker_npc::styles_offered_to( const talker &student ) const +{ + if( student.get_character() ) { + return me_npc->styles_offered_to( *student.get_character() ); + } else { + return {}; + } +} + +std::string talker_npc::style_training_text( const talker &student, + const matype_id &style ) const +{ + if( !student.get_character() ) { + return ""; + } else if( me_npc->is_ally( *student.get_character() ) ) { + return string_format( "%s", style.obj().name ); + } else { + return string_format( _( "%s ( cost $%d )" ), style.obj().name, 8 ); + } +} + +std::vector talker_npc::spells_offered_to( talker &student ) +{ + if( student.get_character() ) { + return me_npc->spells_offered_to( *student.get_character() ); + } else { + return {}; + } +} + +std::string talker_npc::spell_training_text( talker &student, const spell_id &sp ) +{ + player *pupil = student.get_character(); + if( !pupil ) { + return ""; + } + const spell &temp_spell = me_npc->magic.get_spell( sp ); + const bool knows = pupil->magic.knows_spell( sp ); + const int cost = me_npc->calc_spell_training_cost( knows, temp_spell.get_difficulty(), + temp_spell.get_level() ); + std::string text; + if( knows ) { + text = string_format( _( "%s: 1 hour lesson (cost %s)" ), temp_spell.name(), + format_money( cost ) ); + } else { + text = string_format( _( "%s: teaching spell knowledge (cost %s)" ), + temp_spell.name(), format_money( cost ) ); + } + return text; +} + +void talker_npc::store_chosen_training( const skill_id &c_skill, const matype_id &c_style, + const spell_id &c_spell ) +{ + if( c_skill ) { + me_npc->chatbin.skill = c_skill; + me_npc->chatbin.style = matype_id::NULL_ID(); + me_npc->chatbin.dialogue_spell = spell_id(); + } else if( c_style ) { + me_npc->chatbin.style = c_style; + me_npc->chatbin.skill = skill_id::NULL_ID(); + me_npc->chatbin.dialogue_spell = spell_id(); + } else if( c_spell != spell_id() ) { + me_npc->chatbin.style = matype_id::NULL_ID(); + me_npc->chatbin.skill = skill_id::NULL_ID(); + me_npc->chatbin.dialogue_spell = c_spell; + } +} + +int talker_npc::debt() const +{ + return me_npc->op_of_u.owed; +} + +void talker_npc::add_debt( const int cost ) +{ + me_npc->op_of_u.owed += cost; +} + +int talker_npc::cash_to_favor( const int value ) const +{ + return npc_trading::cash_to_favor( *me_npc, value ); +} + +enum consumption_result { + REFUSED = 0, + CONSUMED_SOME, // Consumption didn't fail, but don't delete the item + CONSUMED_ALL // Consumption succeeded, delete the item +}; + +// Returns true if we destroyed the item through consumption +// does not try to consume contents +static consumption_result try_consume( npc &p, item &it, std::string &reason ) +{ + // TODO: Unify this with 'player::consume_item()' + item &to_eat = it; + if( to_eat.is_null() ) { + debugmsg( "Null item to try_consume." ); + return REFUSED; + } + const auto &comest = to_eat.get_comestible(); + if( !comest ) { + // Don't inform the player that we don't want to eat the lighter + return REFUSED; + } + + if( !p.will_accept_from_player( it ) ) { + reason = _( "I don't trust you enough to eat THISā€¦" ); + return REFUSED; + } + + // TODO: Make it not a copy+paste from player::consume_item + int amount_used = 1; + if( to_eat.is_food() ) { + if( !p.can_consume( to_eat ) ) { + reason = _( "It doesn't look like a good idea to consume thisā€¦" ); + return REFUSED; + } else { + const time_duration &consume_time = p.get_consume_time( to_eat ); + p.moves -= to_moves( consume_time ); + p.consume( to_eat ); + reason = _( "Thanks, that hit the spot." ); + + } + } else if( to_eat.is_medication() ) { + if( !comest->tool.is_null() ) { + bool has = p.has_amount( comest->tool, 1 ); + if( item::count_by_charges( comest->tool ) ) { + has = p.has_charges( comest->tool, 1 ); + } + if( !has ) { + reason = string_format( _( "I need a %s to consume that!" ), + item::nname( comest->tool ) ); + return REFUSED; + } + p.use_charges( comest->tool, 1 ); + reason = _( "Thanks, I feel better already." ); + } + if( to_eat.type->has_use() ) { + amount_used = to_eat.type->invoke( p, to_eat, p.pos() ); + if( amount_used <= 0 ) { + reason = _( "It doesn't look like a good idea to consume thisā€¦" ); + return REFUSED; + } + reason = _( "Thanks, I used it." ); + } + + to_eat.charges -= amount_used; + p.consume_effects( to_eat ); + p.moves -= 250; + } else { + debugmsg( "Unknown comestible type of item: %s\n", to_eat.tname() ); + } + + if( to_eat.charges > 0 ) { + return CONSUMED_SOME; + } + + // If not consuming contents and charge <= 0, we just ate the last charge from the stack + return CONSUMED_ALL; +} + +std::string talker_npc::give_item_to( const bool to_use ) +{ + avatar &u = get_avatar(); + if( me_npc->is_hallucination() ) { + return _( "No thanks, I'm good." ); + } + item_location loc = game_menus::inv::titled_menu( g->u, _( "Offer what?" ), + _( "You have no items to offer." ) ); + if( !loc ) { + return _( "Changed your mind?" ); + } + item &given = *loc; + + if( ( &given == &u.weapon && given.has_flag( "NO_UNWIELD" ) ) || + ( u.is_worn( given ) && given.has_flag( "NO_TAKEOFF" ) ) ) { + // Bionic weapon or shackles + return _( "How?" ); + } + + if( given.is_dangerous() && !u.has_trait( trait_DEBUG_MIND_CONTROL ) ) { + return _( "Are you insane!?" ); + } + + bool taken = false; + std::string reason = _( "Nope." ); + int our_ammo = me_npc->ammo_count_for( me_npc->weapon ); + int new_ammo = me_npc->ammo_count_for( given ); + const double new_weapon_value = me_npc->weapon_value( given, new_ammo ); + const double cur_weapon_value = me_npc->weapon_value( me_npc->weapon, our_ammo ); + add_msg( m_debug, "NPC evaluates own %s (%d ammo): %0.1f", + me_npc->weapon.typeId().str(), our_ammo, cur_weapon_value ); + add_msg( m_debug, "NPC evaluates your %s (%d ammo): %0.1f", + given.typeId().str(), new_ammo, new_weapon_value ); + if( to_use ) { + // Eating first, to avoid evaluating bread as a weapon + const consumption_result consume_res = try_consume( *me_npc, given, reason ); + if( consume_res != REFUSED ) { + if( consume_res == CONSUMED_ALL ) { + u.i_rem( &given ); + } + u.moves -= 100; + if( given.is_container() ) { + given.on_contents_changed(); + } + }// wield it if its a weapon + else if( new_weapon_value > cur_weapon_value ) { + me_npc->wield( given ); + reason = _( "Thanks, I'll wield that now." ); + taken = true; + }// HACK: is_gun here is a hack to prevent NPCs wearing guns if they don't want to use them + else if( !given.is_gun() && given.is_armor() ) { + //if it is impossible to wear return why + ret_val can_wear = me_npc->can_wear( given, true ); + if( !can_wear.success() ) { + reason = can_wear.str(); + } else { + //if we can wear it with equip changes prompt first + can_wear = me_npc->can_wear( given ); + if( ( can_wear.success() || + query_yn( can_wear.str() + _( " Should I take something off?" ) ) ) + && me_npc->wear_if_wanted( given, reason ) ) { + taken = true; + } else { + reason = can_wear.str(); + } + } + } else { + reason += string_format( _( "My current weapon is better than this.\n" + "(new weapon value: %.1f vs %.1f)." ), new_weapon_value, + cur_weapon_value ); + } + } else {//allow_use is false so try to carry instead + if( me_npc->can_pickVolume( given ) && me_npc->can_pickWeight( given ) ) { + reason = _( "Thanks, I'll carry that now." ); + taken = true; + me_npc->i_add( given ); + } else { + if( !me_npc->can_pickVolume( given ) ) { + const units::volume free_space = me_npc->volume_capacity() - + me_npc->volume_carried(); + reason += "\n" + std::string( _( "I have no space to store it." ) ) + "\n"; + if( free_space > 0_ml ) { + reason += string_format( _( "I can only store %s %s more." ), + format_volume( free_space ), volume_units_long() ); + } else { + reason += _( "ā€¦or to store anything else for that matter." ); + } + } + if( !me_npc->can_pickWeight( given ) ) { + reason += std::string( "\n" ) + _( "It is too heavy for me to carry." ); + } + } + } + + + if( taken ) { + u.i_rem( &given ); + u.moves -= 100; + me_npc->has_new_items = true; + } + + return reason; +} + +bool talker_npc::buy_from( const int amount ) +{ + return npc_trading::pay_npc( *me_npc, amount ); +} + +std::vector talker_npc::available_missions() const +{ + return me_npc->chatbin.missions; +} + +std::vector talker_npc::assigned_missions() const +{ + return me_npc->chatbin.missions_assigned; +} + +mission *talker_npc::selected_mission() const +{ + return me_npc->chatbin.mission_selected; +} + +void talker_npc::select_mission( mission *selected ) +{ + me_npc->chatbin.mission_selected = selected; +} + +void talker_npc::add_mission( const mission_type_id &mission_id ) +{ + mission *miss = mission::reserve_new( mission_id, me_npc->getID() ); + miss->assign( get_avatar() ); + me_npc->chatbin.missions_assigned.push_back( miss ); +} + +void talker_npc::set_companion_mission( const std::string &role_id ) +{ + me_npc->companion_mission_role_id = role_id; + talk_function::companion_mission( *me_npc ); +} + +void talker_npc::set_fac( const faction_id &new_fac_name ) +{ + me_npc->set_fac( new_fac_name ); +} + +void talker_npc::add_faction_rep( const int rep_change ) +{ + if( me_npc->get_faction()-> id != faction_id( "no_faction" ) ) { + me_npc->get_faction()->likes_u += rep_change; + me_npc->get_faction()->respects_u += rep_change; + } +} + +bool talker_npc::is_following() const +{ + return me_npc->is_following(); +} + +bool talker_npc::is_friendly( const Character &guy ) const +{ + return me_npc->is_friendly( guy ); +} + +bool talker_npc::is_enemy() const +{ + return me_npc->is_enemy(); +} + +bool talker_npc::is_player_ally() const +{ + return me_npc->is_player_ally(); +} + +bool talker_npc::turned_hostile() const +{ + return me_npc->turned_hostile(); +} + +void talker_npc::make_angry() +{ + me_npc->make_angry(); +} + +bool talker_npc::has_ai_rule( const std::string &type, + const std::string &rule ) const +{ + if( type == "aim_rule" ) { + auto rule_val = aim_rule_strs.find( rule ); + if( rule_val != aim_rule_strs.end() ) { + return me_npc->rules.aim == rule_val->second; + } + } else if( type == "engagement_rule" ) { + auto rule_val = combat_engagement_strs.find( rule ); + if( rule_val != combat_engagement_strs.end() ) { + return me_npc->rules.engagement == rule_val->second; + } + } else if( type == "cbm_reserve_rule" ) { + auto rule_val = cbm_reserve_strs.find( rule ); + if( rule_val != cbm_reserve_strs.end() ) { + return me_npc->rules.cbm_reserve == rule_val->second; + } + } else if( type == "cbm_recharge_rule" ) { + auto rule_val = cbm_recharge_strs.find( rule ); + if( rule_val != cbm_recharge_strs.end() ) { + return me_npc->rules.cbm_recharge == rule_val->second; + } + } else if( type == "ally_rule" ) { + auto rule_val = ally_rule_strs.find( rule ); + if( rule_val != ally_rule_strs.end() ) { + return me_npc->rules.has_flag( rule_val->second.rule ); + } + } else if( type == "ally_override" ) { + auto rule_val = ally_rule_strs.find( rule ); + if( rule_val != ally_rule_strs.end() ) { + return me_npc->rules.has_override_enable( rule_val->second.rule ); + } + } else if( type == "pickup_rule" ) { + if( rule == "any" ) { + return !me_npc->rules.pickup_whitelist->empty(); + } + } + + return false; +} + +void talker_npc::toggle_ai_rule( const std::string &, const std::string &rule ) +{ + auto toggle = ally_rule_strs.find( rule ); + if( toggle == ally_rule_strs.end() ) { + return; + } + me_npc->rules.toggle_flag( toggle->second.rule ); + me_npc->invalidate_range_cache(); + me_npc->wield_better_weapon(); +} + +void talker_npc::set_ai_rule( const std::string &type, const std::string &rule ) +{ + if( type == "aim_rule" ) { + auto rule_val = aim_rule_strs.find( rule ); + if( rule_val != aim_rule_strs.end() ) { + me_npc->rules.aim = rule_val->second; + me_npc->invalidate_range_cache(); + } + } else if( type == "engagement_rule" ) { + auto rule_val = combat_engagement_strs.find( rule ); + if( rule_val != combat_engagement_strs.end() ) { + me_npc->rules.engagement = rule_val->second; + me_npc->invalidate_range_cache(); + me_npc->wield_better_weapon(); + } + } else if( type == "cbm_reserve_rule" ) { + auto rule_val = cbm_reserve_strs.find( rule ); + if( rule_val != cbm_reserve_strs.end() ) { + me_npc->rules.cbm_reserve = rule_val->second; + } + } else if( type == "cbm_recharge_rule" ) { + auto rule_val = cbm_recharge_strs.find( rule ); + if( rule_val != cbm_recharge_strs.end() ) { + me_npc->rules.cbm_recharge = rule_val->second; + } + } else if( type == "ally_rule" ) { + auto toggle = ally_rule_strs.find( rule ); + if( toggle == ally_rule_strs.end() ) { + return; + } + me_npc->rules.set_flag( toggle->second.rule ); + me_npc->invalidate_range_cache(); + me_npc->wield_better_weapon(); + } +} + +void talker_npc::clear_ai_rule( const std::string &, const std::string &rule ) +{ + auto toggle = ally_rule_strs.find( rule ); + if( toggle == ally_rule_strs.end() ) { + return; + } + me_npc->rules.clear_flag( toggle->second.rule ); + me_npc->invalidate_range_cache(); + me_npc->wield_better_weapon(); +} + +std::string talker_npc::get_job_description() const +{ + return me_npc->describe_mission(); +} + +std::string talker_npc::evaluation_by( const talker &alpha ) const +{ + ///\EFFECT_PER affects whether player can size up NPCs + + ///\EFFECT_INT slightly affects whether player can size up NPCs + int ability = alpha.per_cur() * 3 + alpha.int_cur(); + if( ability <= 10 ) { + return _( "&You can't make anything out." ); + } + + if( is_player_ally() || ability > 100 ) { + ability = 100; + } + + std::string info = "&"; + int str_range = static_cast( 100 / ability ); + int str_min = static_cast( me_npc->str_max / str_range ) * str_range; + info += string_format( _( "Str %d - %d" ), str_min, str_min + str_range ); + + if( ability >= 40 ) { + int dex_range = static_cast( 160 / ability ); + int dex_min = static_cast( me_npc->dex_max / dex_range ) * dex_range; + info += string_format( _( " Dex %d - %d" ), dex_min, dex_min + dex_range ); + } + + if( ability >= 50 ) { + int int_range = static_cast( 200 / ability ); + int int_min = static_cast( me_npc->int_max / int_range ) * int_range; + info += string_format( _( " Int %d - %d" ), int_min, int_min + int_range ); + } + + if( ability >= 60 ) { + int per_range = static_cast( 240 / ability ); + int per_min = static_cast( me_npc->per_max / per_range ) * per_range; + info += string_format( _( " Per %d - %d" ), per_min, per_min + per_range ); + } + needs_rates rates = me_npc->calc_needs_rates(); + if( ability >= 100 - ( get_fatigue() / 10 ) ) { + std::string how_tired; + if( get_fatigue() > fatigue_levels::EXHAUSTED ) { + how_tired = _( "Exhausted" ); + } else if( get_fatigue() > fatigue_levels::DEAD_TIRED ) { + how_tired = _( "Dead tired" ); + } else if( get_fatigue() > fatigue_levels::TIRED ) { + how_tired = _( "Tired" ); + } else { + how_tired = _( "Not tired" ); + if( ability >= 100 ) { + time_duration sleep_at = 5_minutes * ( fatigue_levels::TIRED - + get_fatigue() ) / rates.fatigue; + how_tired += _( ". Will need sleep in " ) + to_string_approx( sleep_at ); + } + } + info += "\n" + how_tired; + } + if( ability >= 100 ) { + if( get_thirst() < 100 ) { + time_duration thirst_at = 5_minutes * ( 100 - get_thirst() ) / rates.thirst; + if( thirst_at > 1_hours ) { + info += _( "\nWill need water in " ) + to_string_approx( thirst_at ); + } + } else { + info += _( "\nThirsty" ); + } + if( get_hunger() < 100 ) { + time_duration hunger_at = 5_minutes * ( 100 - get_hunger() ) / rates.hunger; + if( hunger_at > 1_hours ) { + info += _( "\nWill need food in " ) + to_string_approx( hunger_at ); + } + } else { + info += _( "\nHungry" ); + } + } + return info; + +} + +bool talker_npc::has_activity() const +{ + return !me_npc->activity.is_null(); +} + +bool talker_npc::is_myclass( const npc_class_id &class_to_check ) const +{ + return me_npc->myclass == class_to_check; +} + +void talker_npc::set_class( const npc_class_id &new_class ) +{ + me_npc->myclass = new_class; +} + +void talker_npc::say( const std::string &speech ) +{ + me_npc->say( speech ); +} + +std::string talker_npc::opinion_text() const +{ + return me_npc->opinion_text(); +} + +void talker_npc::add_opinion( const int trust, const int fear, const int value, + const int anger, const int debt ) +{ + me_npc->op_of_u += npc_opinion( trust, fear, value, anger, debt ); +} + +bool talker_npc::enslave_mind() +{ + bool not_following = g->get_follower_list().count( me_npc->getID() ) == 0; + me_npc->companion_mission_role_id.clear(); + talk_function::follow( *me_npc ); + return not_following; +} diff --git a/src/talker_npc.h b/src/talker_npc.h new file mode 100644 index 0000000000000..6b90de18b340d --- /dev/null +++ b/src/talker_npc.h @@ -0,0 +1,106 @@ +#pragma once +#ifndef CATA_SRC_TALKER_NPC_H +#define CATA_SRC_TALKER_NPC_H + +#include "talker.h" +#include "talker_character.h" + +class Character; +class faction; +class item; +class mission; +class npc; +class player; +class recipe; +struct tripoint; +class vehicle; + +/* + */ +class talker_npc : public talker_character +{ + public: + talker_npc( npc *new_me ): talker_character( new_me ), me_npc( new_me ) { + } + ~talker_npc() override = default; + + npc *get_npc() override { + return me_npc; + } + npc *get_npc() const override { + return me_npc; + } + + // identity and location + std::string distance_to_goal() const override; + + // mandatory functions for starting a dialogue + bool will_talk_to_u( const player &u, bool force ) override; + std::vector get_topics( bool radio_contact ) override; + void check_missions() override; + void update_missions( const std::vector &missions_assigned, + const character_id &charID ) override; + bool check_hostile_response( int anger ) const override; + int parse_mod( const std::string &attribute, int factor ) const override; + int trial_chance_mod( const std::string &trial_type ) const override; + + // stats, skills, traits, bionics, and magic + std::vector skills_offered_to( const talker &student ) const override; + std::string skill_training_text( const talker &, const skill_id & ) const override; + std::vector styles_offered_to( const talker &student ) const override; + std::string style_training_text( const talker &, const matype_id & ) const override; + std::vector spells_offered_to( talker &student ) override; + std::string spell_training_text( talker &, const spell_id & ) override; + void store_chosen_training( const skill_id &c_skill, const matype_id &c_style, + const spell_id &c_spell ) override; + + // inventory, buying, and selling + void add_debt( int cost ) override; + int debt() const override; + int cash_to_favor( int value ) const override; + std::string give_item_to( bool to_use ) override; + bool buy_from( int amount ) override; + + // missions + std::vector available_missions() const override; + std::vector assigned_missions() const override; + mission *selected_mission() const override; + void select_mission( mission *selected ) override; + void add_mission( const mission_type_id &mission_id ) override; + void set_companion_mission( const std::string &role_id ) override; + + // factions and alliances + void set_fac( const faction_id &new_fac_name ) override; + void add_faction_rep( int rep_change ) override; + bool is_following() const override; + bool is_friendly( const Character &guy ) const override; + bool is_enemy() const override; + bool is_player_ally() const override; + bool turned_hostile() const override; + void make_angry() override; + + // ai rules + bool has_ai_rule( const std::string &type, const std::string &rule ) const override; + void toggle_ai_rule( const std::string &type, const std::string &rule ) override; + void set_ai_rule( const std::string &type, const std::string &rule ) override; + void clear_ai_rule( const std::string &type, const std::string &rule ) override; + + // other descriptors + std::string get_job_description() const override; + std::string evaluation_by( const talker &alpha ) const override; + bool has_activity() const override; + bool is_myclass( const npc_class_id &class_to_check ) const override; + void set_class( const npc_class_id &new_class ) override; + + // speaking + void say( const std::string &speech ) override; + + // miscellaneous + std::string opinion_text() const override; + void add_opinion( int trust, int fear, int value, int anger, int debt ) override; + bool enslave_mind() override; + + protected: + npc *me_npc; +}; +#endif // CATA_SRC_TALKER_NPC_H From 3619b854f6ec24653c81fa65651c20dc6579cb4a Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Mon, 13 Jul 2020 08:39:36 -0500 Subject: [PATCH 017/151] dialogue: convert to using talker shift npc::talk_to_u() to avatar::talk_to( std::unique_ptr talk_with) and adjust callers to match. change dialogue:: from having a player *alpha and a player *beta to having std::unique_ptr alpha and beta, and adjust the other dialogue:: like classes to match. redo condition.cpp and the dialogue effects in npctalk.cpp to use the talker interface. update tests/npc_talk_test.cpp to reflect these changes. --- src/avatar.h | 5 + src/condition.cpp | 247 +++-------- src/condition.h | 3 +- src/dialogue.h | 15 +- src/faction.cpp | 3 +- src/game.cpp | 3 +- src/iexamine.cpp | 4 +- src/mission.cpp | 4 +- src/mission.h | 9 +- src/mission_util.cpp | 10 +- src/npc.h | 6 +- src/npcmove.cpp | 5 +- src/npctalk.cpp | 957 ++++++++-------------------------------- tests/npc_talk_test.cpp | 19 +- 14 files changed, 294 insertions(+), 996 deletions(-) diff --git a/src/avatar.h b/src/avatar.h index 36a4ba4bc6994..76a25872284a0 100644 --- a/src/avatar.h +++ b/src/avatar.h @@ -29,6 +29,7 @@ class JsonOut; class mission; class monster; class npc; +class talker; namespace debug_menu { @@ -139,6 +140,10 @@ class avatar : public player */ void on_mission_finished( mission &cur_mission ); + // Dialogue and bartering--see npctalk.cpp + void talk_to( std::unique_ptr talk_with, bool text_only = false, + bool radio_contact = false ); + /** * Helper function for player::read. * diff --git a/src/condition.cpp b/src/condition.cpp index 29f2756bf4eb1..46e93270b7fcc 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -37,6 +37,7 @@ #include "point.h" #include "recipe_groups.h" #include "string_id.h" +#include "talker.h" #include "type_id.h" #include "vehicle.h" #include "vpart_position.h" @@ -95,10 +96,7 @@ void conditional_t::set_has_any_trait( const JsonObject &jo, const std::strin traits_to_check.emplace_back( f ); } condition = [traits_to_check, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } + const talker *actor = d.actor( is_npc ); for( const auto &trait : traits_to_check ) { if( actor->has_trait( trait ) ) { return true; @@ -113,11 +111,7 @@ void conditional_t::set_has_trait( const JsonObject &jo, const std::string &m { const std::string &trait_to_check = jo.get_string( member ); condition = [trait_to_check, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return actor->has_trait( trait_id( trait_to_check ) ); + return d.actor( is_npc )->has_trait( trait_id( trait_to_check ) ); }; } @@ -127,10 +121,7 @@ void conditional_t::set_has_trait_flag( const JsonObject &jo, const std::stri { const std::string &trait_flag_to_check = jo.get_string( member ); condition = [trait_flag_to_check, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } + const talker *actor = d.actor( is_npc ); if( trait_flag_to_check == "MUTATION_THRESHOLD" ) { return actor->crossed_threshold(); } @@ -142,15 +133,7 @@ template void conditional_t::set_has_activity( bool is_npc ) { condition = [is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - return d.beta->has_activity(); - } else { - if( !actor->activity.is_null() ) { - return true; - } - } - return false; + return d.actor( is_npc )->has_activity(); }; } @@ -158,7 +141,7 @@ template void conditional_t::set_is_riding( bool is_npc ) { condition = [is_npc]( const T & d ) { - return ( is_npc ? d.beta : d.alpha )->is_mounted(); + return d.actor( is_npc )->is_mounted(); }; } @@ -167,7 +150,7 @@ void conditional_t::set_npc_has_class( const JsonObject &jo ) { const std::string &class_to_check = jo.get_string( "npc_has_class" ); condition = [class_to_check]( const T & d ) { - return d.beta->myclass == npc_class_id( class_to_check ); + return d.beta->is_myclass( npc_class_id( class_to_check ) ); }; } @@ -191,11 +174,7 @@ void conditional_t::set_has_strength( const JsonObject &jo, const std::string { const int min_strength = jo.get_int( member ); condition = [min_strength, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return actor->str_cur >= min_strength; + return d.actor( is_npc )->str_cur() >= min_strength; }; } @@ -205,11 +184,7 @@ void conditional_t::set_has_dexterity( const JsonObject &jo, const std::strin { const int min_dexterity = jo.get_int( member ); condition = [min_dexterity, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return actor->dex_cur >= min_dexterity; + return d.actor( is_npc )->dex_cur() >= min_dexterity; }; } @@ -219,11 +194,7 @@ void conditional_t::set_has_intelligence( const JsonObject &jo, const std::st { const int min_intelligence = jo.get_int( member ); condition = [min_intelligence, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return actor->int_cur >= min_intelligence; + return d.actor( is_npc )->int_cur() >= min_intelligence; }; } @@ -233,11 +204,7 @@ void conditional_t::set_has_perception( const JsonObject &jo, const std::stri { const int min_perception = jo.get_int( member ); condition = [min_perception, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return actor->per_cur >= min_perception; + return d.actor( is_npc )->per_cur() >= min_perception; }; } @@ -247,11 +214,7 @@ void conditional_t::set_is_wearing( const JsonObject &jo, const std::string & { const itype_id item_id( jo.get_string( member ) ); condition = [item_id, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return actor->is_wearing( item_id ); + return d.actor( is_npc )->is_wearing( item_id ); }; } @@ -260,10 +223,7 @@ void conditional_t::set_has_item( const JsonObject &jo, const std::string &me { const itype_id item_id( jo.get_string( member ) ); condition = [item_id, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } + const talker *actor = d.actor( is_npc ); return actor->charges_of( item_id ) > 0 || actor->has_amount( item_id, 1 ); }; } @@ -280,10 +240,7 @@ void conditional_t::set_has_items( const JsonObject &jo, const std::string &m const itype_id item_id( has_items.get_string( "item" ) ); int count = has_items.get_int( "count" ); condition = [item_id, count, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } + const talker *actor = d.actor( is_npc ); return actor->has_charges( item_id, count ) || actor->has_amount( item_id, count ); }; } @@ -304,10 +261,7 @@ void conditional_t::set_has_item_category( const JsonObject &jo, const std::s } condition = [category_id, count, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } + const talker *actor = d.actor( is_npc ); const auto items_with = actor->items_with( [category_id]( const item & it ) { return it.get_category().get_id() == category_id; } ); @@ -321,10 +275,7 @@ void conditional_t::set_has_bionics( const JsonObject &jo, const std::string { const std::string bionics_id = jo.get_string( member ); condition = [bionics_id, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } + const talker *actor = d.actor( is_npc ); if( bionics_id == "ANY" ) { return actor->num_bionics() > 0 || actor->has_max_power(); } @@ -338,11 +289,7 @@ void conditional_t::set_has_effect( const JsonObject &jo, const std::string & { const std::string &effect_id = jo.get_string( member ); condition = [effect_id, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return actor->has_effect( efftype_id( effect_id ) ); + return d.actor( is_npc )->has_effect( efftype_id( effect_id ) ); }; } @@ -361,10 +308,7 @@ void conditional_t::set_need( const JsonObject &jo, const std::string &member } } condition = [need, amount, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } + const talker *actor = d.actor( is_npc ); return ( actor->get_fatigue() > amount && need == "fatigue" ) || ( actor->get_hunger() > amount && need == "hunger" ) || ( actor->get_thirst() > amount && need == "thirst" ); @@ -377,11 +321,7 @@ void conditional_t::set_at_om_location( const JsonObject &jo, const std::stri { const std::string &location = jo.get_string( member ); condition = [location, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - const tripoint omt_pos = actor->global_omt_location(); + const tripoint omt_pos = d.actor( is_npc )->global_omt_location(); const oter_id &omt_ref = overmap_buffer.ter( omt_pos ); if( location == "FACTION_CAMP_ANY" ) { @@ -408,10 +348,7 @@ void conditional_t::set_has_var( const JsonObject &jo, const std::string &mem const std::string &value = jo.has_member( "value" ) ? jo.get_string( "value" ) : std::string(); const bool time_check = jo.has_member( "time" ) && jo.get_bool( "time" ); condition = [var_name, value, time_check, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } + const talker *actor = d.actor( is_npc ); if( time_check ) { return !actor->get_value( var_name ).empty(); } @@ -427,13 +364,8 @@ void conditional_t::set_compare_var( const JsonObject &jo, const std::string const std::string &op = jo.get_string( "op" ); const int value = jo.get_int( "value" ); condition = [var_name, op, value, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - int stored_value = 0; - const std::string &var = actor->get_value( var_name ); + const std::string &var = d.actor( is_npc )->get_value( var_name ); if( !var.empty() ) { stored_value = std::stoi( var ); } @@ -470,13 +402,8 @@ void conditional_t::set_compare_time_since_var( const JsonObject &jo, const s const int value = to_turns( read_from_json_string( *jo.get_raw( "time" ), time_duration::units ) ); condition = [var_name, op, value, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - int stored_value = 0; - const std::string &var = actor->get_value( var_name ); + const std::string &var = d.actor( is_npc )->get_value( var_name ); if( var.empty() ) { return false; } else { @@ -535,7 +462,7 @@ void conditional_t::set_u_has_cash( const JsonObject &jo ) { const int min_cash = jo.get_int( "u_has_cash" ); condition = [min_cash]( const T & d ) { - return d.alpha->cash >= min_cash; + return d.alpha->cash() >= min_cash; }; } @@ -544,7 +471,7 @@ void conditional_t::set_u_are_owed( const JsonObject &jo ) { const int min_debt = jo.get_int( "u_are_owed" ); condition = [min_debt]( const T & d ) { - return d.beta->op_of_u.owed >= min_debt; + return d.beta->debt() >= min_debt; }; } @@ -553,11 +480,7 @@ void conditional_t::set_npc_aim_rule( const JsonObject &jo ) { const std::string &setting = jo.get_string( "npc_aim_rule" ); condition = [setting]( const T & d ) { - auto rule = aim_rule_strs.find( setting ); - if( rule != aim_rule_strs.end() ) { - return d.beta->rules.aim == rule->second; - } - return false; + return d.beta->has_ai_rule( "aim_rule", setting ); }; } @@ -566,11 +489,7 @@ void conditional_t::set_npc_engagement_rule( const JsonObject &jo ) { const std::string &setting = jo.get_string( "npc_engagement_rule" ); condition = [setting]( const T & d ) { - auto rule = combat_engagement_strs.find( setting ); - if( rule != combat_engagement_strs.end() ) { - return d.beta->rules.engagement == rule->second; - } - return false; + return d.beta->has_ai_rule( "engagement_rule", setting ); }; } @@ -579,11 +498,7 @@ void conditional_t::set_npc_cbm_reserve_rule( const JsonObject &jo ) { const std::string &setting = jo.get_string( "npc_cbm_reserve_rule" ); condition = [setting]( const T & d ) { - auto rule = cbm_reserve_strs.find( setting ); - if( rule != cbm_reserve_strs.end() ) { - return d.beta->rules.cbm_reserve == rule->second; - } - return false; + return d.beta->has_ai_rule( "cbm_reserve_rule", setting ); }; } @@ -592,11 +507,7 @@ void conditional_t::set_npc_cbm_recharge_rule( const JsonObject &jo ) { const std::string &setting = jo.get_string( "npc_cbm_recharge_rule" ); condition = [setting]( const T & d ) { - auto rule = cbm_recharge_strs.find( setting ); - if( rule != cbm_recharge_strs.end() ) { - return d.beta->rules.cbm_recharge == rule->second; - } - return false; + return d.beta->has_ai_rule( "cbm_recharge_rule", setting ); }; } @@ -605,11 +516,7 @@ void conditional_t::set_npc_rule( const JsonObject &jo ) { std::string rule = jo.get_string( "npc_rule" ); condition = [rule]( const T & d ) { - auto flag = ally_rule_strs.find( rule ); - if( flag != ally_rule_strs.end() ) { - return d.beta->rules.has_flag( flag->second.rule ); - } - return false; + return d.beta->has_ai_rule( "ally_rule", rule ); }; } @@ -618,11 +525,7 @@ void conditional_t::set_npc_override( const JsonObject &jo ) { std::string rule = jo.get_string( "npc_override" ); condition = [rule]( const T & d ) { - auto flag = ally_rule_strs.find( rule ); - if( flag != ally_rule_strs.end() ) { - return d.beta->rules.has_override_enable( flag->second.rule ); - } - return false; + return d.beta->has_ai_rule( "ally_override", rule ); }; } @@ -653,7 +556,7 @@ void conditional_t::set_mission_goal( const JsonObject &jo ) { std::string mission_goal_str = jo.get_string( "mission_goal" ); condition = [mission_goal_str]( const T & d ) { - mission *miss = d.beta->chatbin.mission_selected; + mission *miss = d.beta->selected_mission(); if( !miss ) { return false; } @@ -666,11 +569,7 @@ template void conditional_t::set_is_gender( bool is_male, bool is_npc ) { condition = [is_male, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return actor->male == is_male; + return d.actor( is_npc )->is_male() == is_male; }; } @@ -702,7 +601,7 @@ template void conditional_t::set_no_available_mission() { condition = []( const T & d ) { - return d.beta->chatbin.missions.empty(); + return d.beta->available_missions().empty(); }; } @@ -710,7 +609,7 @@ template void conditional_t::set_has_available_mission() { condition = []( const T & d ) { - return d.beta->chatbin.missions.size() == 1; + return d.beta->available_missions().size() == 1; }; } @@ -718,7 +617,7 @@ template void conditional_t::set_has_many_available_missions() { condition = []( const T & d ) { - return d.beta->chatbin.missions.size() >= 2; + return d.beta->available_missions().size() >= 2; }; } @@ -726,11 +625,8 @@ template void conditional_t::set_mission_complete() { condition = []( const T & d ) { - mission *miss = d.beta->chatbin.mission_selected; - if( !miss ) { - return false; - } - return miss->is_complete( d.beta->getID() ); + mission *miss = d.beta->selected_mission(); + return miss && miss->is_complete( d.beta->getID() ); }; } @@ -738,11 +634,8 @@ template void conditional_t::set_mission_incomplete() { condition = []( const T & d ) { - mission *miss = d.beta->chatbin.mission_selected; - if( !miss ) { - return false; - } - return !miss->is_complete( d.beta->getID() ); + mission *miss = d.beta->selected_mission(); + return miss && !miss->is_complete( d.beta->getID() ); }; } @@ -794,6 +687,14 @@ void conditional_t::set_npc_train_styles() }; } +template +void conditional_t::set_npc_train_spells() +{ + condition = []( const T & d ) { + return !d.beta->spells_offered_to( *d.alpha ).empty(); + }; +} + template void conditional_t::set_at_safe_space() { @@ -806,11 +707,8 @@ template void conditional_t::set_can_stow_weapon( bool is_npc ) { condition = [is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return !actor->unarmed_attack() && actor->can_pickVolume( actor->weapon ); + const talker *actor = d.actor( is_npc ); + return !actor->unarmed_attack() && actor->can_stash_weapon(); }; } @@ -818,11 +716,7 @@ template void conditional_t::set_has_weapon( bool is_npc ) { condition = [is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return !actor->unarmed_attack(); + return !d.actor( is_npc )->unarmed_attack(); }; } @@ -830,12 +724,9 @@ template void conditional_t::set_is_driving( bool is_npc ) { condition = [is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } + const talker *actor = d.actor( is_npc ); if( const optional_vpart_position vp = get_map().veh_at( actor->pos() ) ) { - return vp->vehicle().is_moving() && vp->vehicle().player_in_control( *actor ); + return vp->vehicle().is_moving() && actor->is_in_control_of( vp->vehicle() ); } return false; }; @@ -845,15 +736,7 @@ template void conditional_t::set_has_stolen_item( bool /*is_npc*/ ) { condition = []( const T & d ) { - player *actor = d.alpha; - npc &p = *d.beta; - bool found_in_inv = false; - for( auto &elem : actor->inv_dump() ) { - if( elem->is_old_owner( p, true ) ) { - found_in_inv = true; - } - } - return found_in_inv; + return d.alpha->has_stolen_item( *d.beta ); }; } @@ -869,8 +752,8 @@ template void conditional_t::set_is_outside() { condition = []( const T & d ) { - map &here = get_map(); - const tripoint pos = here.getabs( d.beta->pos() ); + const map &here = get_map(); + const tripoint &pos = here.getabs( d.beta->pos() ); return !here.has_flag( TFLAG_INDOORS, pos ); }; } @@ -887,7 +770,7 @@ template void conditional_t::set_has_pickup_list() { condition = []( const T & d ) { - return !d.beta->rules.pickup_whitelist->empty(); + return d.beta->has_ai_rule( "pickup_rule", "any" ); }; } @@ -919,11 +802,7 @@ void conditional_t::set_has_skill( const JsonObject &jo, const std::string &m const skill_id skill( has_skill.get_string( "skill" ) ); int level = has_skill.get_int( "level" ); condition = [skill, level, is_npc]( const T & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - return actor->get_skill_level( skill ) >= level; + return d.actor( is_npc )->get_skill_level( skill ) >= level; }; } } @@ -932,10 +811,10 @@ template void conditional_t::set_u_know_recipe( const JsonObject &jo, const std::string &member ) { const std::string &known_recipe_id = jo.get_string( member ); - condition = [known_recipe_id]( const T & d ) { - player *actor = d.alpha; - const recipe &r = recipe_id( known_recipe_id ).obj(); - return actor->knows_recipe( &r ); + condition = [known_recipe_id]( const T & ) { + const recipe &rep = recipe_id( known_recipe_id ).obj(); + // should be a talker function but recipes aren't in Character:: yet + return g->u.knows_recipe( &rep ); }; } @@ -943,7 +822,7 @@ template void conditional_t::set_mission_has_generic_rewards() { condition = []( const T & d ) { - mission *miss = d.beta->chatbin.mission_selected; + mission *miss = d.beta->selected_mission(); if( miss == nullptr ) { debugmsg( "mission_has_generic_rewards: mission_selected == nullptr" ); return true; @@ -1187,6 +1066,8 @@ conditional_t::conditional_t( const std::string &type ) set_npc_train_skills(); } else if( type == "npc_train_styles" ) { set_npc_train_styles(); + } else if( type == "npc_train_spells" ) { + set_npc_train_spells(); } else if( type == "at_safe_space" ) { set_at_safe_space(); } else if( type == "u_can_stow_weapon" ) { diff --git a/src/condition.h b/src/condition.h index 49d53def09611..1460457222ff0 100644 --- a/src/condition.h +++ b/src/condition.h @@ -20,7 +20,7 @@ const std::unordered_set simple_string_conds = { { "has_no_available_mission", "has_available_mission", "has_many_available_missions", "mission_complete", "mission_incomplete", "mission_has_generic_rewards", "npc_available", "npc_following", "npc_friend", "npc_hostile", - "npc_train_skills", "npc_train_styles", + "npc_train_skills", "npc_train_styles", "npc_train_spells", "at_safe_space", "is_day", "npc_has_activity", "is_outside", "u_has_camp", "u_can_stow_weapon", "npc_can_stow_weapon", "u_has_weapon", "npc_has_weapon", "u_driving", "npc_driving", @@ -121,6 +121,7 @@ struct conditional_t { void set_npc_hostile(); void set_npc_train_skills(); void set_npc_train_styles(); + void set_npc_train_spells(); void set_at_safe_space(); void set_can_stow_weapon( bool is_npc = false ); void set_has_weapon( bool is_npc = false ); diff --git a/src/dialogue.h b/src/dialogue.h index 401c02459990b..a317292b107e7 100644 --- a/src/dialogue.h +++ b/src/dialogue.h @@ -12,12 +12,12 @@ #include "dialogue_win.h" #include "json.h" #include "npc.h" -#include "player.h" #include "translations.h" #include "type_id.h" class martialart; class mission; +class talker; struct dialogue; enum talk_trial_type : unsigned char { @@ -219,15 +219,13 @@ struct talk_response { struct dialogue { /** - * The player character that speaks (always g->u). - * TODO: make it a reference, not a pointer. + * The talker that speaks (almost certainly representing the avatar, ie get_avatar() ) */ - player *alpha = nullptr; + std::unique_ptr alpha; /** - * The NPC we talk to. Never null. - * TODO: make it a reference, not a pointer. + * The talker responded to alpha, usually a talker_npc. */ - npc *beta = nullptr; + std::unique_ptr beta; /** * If true, we are done talking and the dialog ends. */ @@ -240,6 +238,9 @@ struct dialogue { talk_topic opt( dialogue_window &d_win, const std::string &npc_name, const talk_topic &topic ); dialogue() = default; + talker *actor( const bool is_beta ) const { + return ( is_beta ? beta : alpha ).get(); + } mutable itype_id cur_item; mutable std::string reason; diff --git a/src/faction.cpp b/src/faction.cpp index 2b4b99502ab02..d135375e5a66b 100644 --- a/src/faction.cpp +++ b/src/faction.cpp @@ -30,6 +30,7 @@ #include "point.h" #include "skill.h" #include "string_formatter.h" +#include "talker.h" #include "translations.h" #include "type_id.h" #include "ui_manager.h" @@ -899,7 +900,7 @@ void faction_manager::display() const popup( _( "%s returns from their mission" ), guy->disp_name() ); } else { if( tab == tab_mode::TAB_FOLLOWERS && guy && ( interactable || radio_interactable ) ) { - guy->talk_to_u( false, radio_interactable ); + g->u.talk_to( get_talker_for( *guy ), false, radio_interactable ); } else if( tab == tab_mode::TAB_MYFACTION && camp ) { camp->query_new_name(); } diff --git a/src/game.cpp b/src/game.cpp index 434dde4b9a16a..16891faee79ef 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -141,6 +141,7 @@ #include "string_id.h" #include "string_input_popup.h" #include "submap.h" +#include "talker.h" #include "tileray.h" #include "timed_event.h" #include "translations.h" @@ -5669,7 +5670,7 @@ bool game::npc_menu( npc &who ) const int choice = amenu.ret; if( choice == talk ) { - who.talk_to_u(); + u.talk_to( get_talker_for( who ) ); } else if( choice == swap_pos ) { if( !prompt_dangerous_tile( who.pos() ) ) { return true; diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 667b4ff8d0a16..ddcc070149607 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -82,6 +82,7 @@ #include "string_formatter.h" #include "string_id.h" #include "string_input_popup.h" +#include "talker.h" #include "timed_event.h" #include "translations.h" #include "trap.h" @@ -1057,7 +1058,8 @@ void iexamine::intercom( player &p, const tripoint &examp ) if( intercom_npcs.empty() ) { p.add_msg_if_player( m_info, _( "No one responds." ) ); } else { - intercom_npcs.front()->talk_to_u( false, false ); + // TODO: This needs to be converted a talker_console or something + g->u.talk_to( get_talker_for( *intercom_npcs.front() ), false, false ); } } diff --git a/src/mission.cpp b/src/mission.cpp index 0fd633679f6d4..094def531af1c 100644 --- a/src/mission.cpp +++ b/src/mission.cpp @@ -448,8 +448,8 @@ bool mission::is_complete( const character_id &_npc_id ) const } mission_goal_condition_context cc; - cc.alpha = &u; - cc.beta = n; + cc.alpha = get_talker_for( g->u ); + cc.beta = get_talker_for( *n ); for( auto &mission : n->chatbin.missions_assigned ) { if( mission->get_assigned_player_id() == g->u.getID() ) { diff --git a/src/mission.h b/src/mission.h index d22069632527d..555ecf2d2b490 100644 --- a/src/mission.h +++ b/src/mission.h @@ -20,6 +20,7 @@ #include "overmap.h" #include "point.h" #include "string_id.h" +#include "talker.h" #include "translations.h" #include "type_id.h" @@ -31,7 +32,6 @@ class JsonOut; class avatar; class item; class mission; -class npc; class overmapbuffer; class player; template struct enum_traits; @@ -187,11 +187,14 @@ bool load_funcs( const JsonObject &jo, std::vector alpha; + std::unique_ptr beta; std::vector missions_assigned; mutable std::string reason; bool by_radio = false; + talker *actor( const bool is_beta ) const { + return ( is_beta ? beta : alpha ).get(); + } }; struct mission_type { diff --git a/src/mission_util.cpp b/src/mission_util.cpp index 1ab66e3dcde99..2e0fd87880f58 100644 --- a/src/mission_util.cpp +++ b/src/mission_util.cpp @@ -26,6 +26,7 @@ #include "overmapbuffer.h" #include "point.h" #include "rng.h" +#include "talker.h" #include "translations.h" #include "type_id.h" @@ -520,12 +521,13 @@ bool mission_type::parse_funcs( const JsonObject &jo, std::functionfind_npc( miss->get_npc_id() ); + npc *beta = g->find_npc( miss->get_npc_id() ); standard_npc default_npc( "Default" ); - if( d.beta == nullptr ) { - d.beta = &default_npc; + if( beta == nullptr ) { + beta = &default_npc; } - d.alpha = &g->u; + d.alpha = get_talker_for( g->u ); + d.beta = get_talker_for( beta ); for( const talk_effect_fun_t &effect : talk_effects.effects ) { effect( d ); } diff --git a/src/npc.h b/src/npc.h index 41103fe58e9f9..cb227e10d2502 100644 --- a/src/npc.h +++ b/src/npc.h @@ -886,8 +886,8 @@ class npc : public player std::vector styles_offered_to( const player &p ) const; /** * Spells that the NPC knows but that the player p doesn't. - * not const because get_spell isn't const and both this and p call it - */ + * not const because get_spell isn't const and both this and p call it + */ std::vector spells_offered_to( player &p ); // State checks // We want to kill/mug/etc the player @@ -932,8 +932,6 @@ class npc : public player // How closely do we follow the player? int follow_distance() const; - // Dialogue and bartering--see npctalk.cpp - void talk_to_u( bool text_only = false, bool radio_contact = false ); // Re-roll the inventory of a shopkeeper void shop_restock(); // Use and assessment of items diff --git a/src/npcmove.cpp b/src/npcmove.cpp index 56da28364fb27..f2991248fb914 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -13,6 +13,7 @@ #include "active_item_cache.h" #include "activity_handlers.h" +#include "avatar.h" #include "basecamp.h" #include "bionics.h" #include "bodypart.h" @@ -69,6 +70,8 @@ #include "vpart_position.h" #include "vpart_range.h" +class talker; + static const activity_id ACT_OPERATION( "ACT_OPERATION" ); static const activity_id ACT_PULP( "ACT_PULP" ); @@ -1235,7 +1238,7 @@ void npc::execute_action( npc_action action ) break; case npc_talk_to_player: - talk_to_u(); + g->u.talk_to( get_talker_for( this ) ); moves = 0; break; diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 1a9985fa8ac37..3877d2a1ccfe0 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -69,6 +69,7 @@ #include "string_formatter.h" #include "string_id.h" #include "string_input_popup.h" +#include "talker.h" #include "text_snippets.h" #include "translations.h" #include "ui.h" @@ -87,11 +88,7 @@ static const activity_id ACT_WAIT_NPC( "ACT_WAIT_NPC" ); static const efftype_id effect_lying_down( "lying_down" ); static const efftype_id effect_narcosis( "narcosis" ); -static const efftype_id effect_npc_suspend( "npc_suspend" ); -static const efftype_id effect_pacified( "pacified" ); -static const efftype_id effect_pet( "pet" ); static const efftype_id effect_riding( "riding" ); -static const efftype_id effect_sleep( "sleep" ); static const efftype_id effect_under_operation( "under_operation" ); static const itype_id fuel_type_animal( "animal" ); @@ -101,19 +98,11 @@ static const zone_type_id zone_type_NPC_NO_INVESTIGATE( "NPC_NO_INVESTIGATE" ); static const skill_id skill_speech( "speech" ); -static const bionic_id bio_armor_eyes( "bio_armor_eyes" ); -static const bionic_id bio_deformity( "bio_deformity" ); -static const bionic_id bio_face_mask( "bio_face_mask" ); -static const bionic_id bio_voice( "bio_voice" ); - static const trait_id trait_DEBUG_MIND_CONTROL( "DEBUG_MIND_CONTROL" ); static const trait_id trait_PROF_FOODP( "PROF_FOODP" ); static std::map json_talk_topics; -// Every OWED_VAL that the NPC owes you counts as +1 towards convincing -static constexpr int OWED_VAL = 1000; - #define dbg(x) DebugLog((x),D_GAME) << __FILE__ << ":" << __LINE__ << ": " int topic_category( const talk_topic &the_topic ); @@ -506,7 +495,7 @@ void game::chat() if( npcselect < 0 ) { return; } - available[npcselect]->talk_to_u(); + g->u.talk_to( get_talker_for( *available[npcselect] ) ); break; } case NPC_CHAT_YELL: @@ -730,140 +719,34 @@ void npc_chatbin::check_missions() ma.erase( last, ma.end() ); } -void npc::talk_to_u( bool text_only, bool radio_contact ) +void avatar::talk_to( std::unique_ptr talk_with, bool text_only, bool radio_contact ) { - if( g->u.is_dead_state() ) { - set_attitude( NPCATT_NULL ); + const bool has_mind_control = has_trait( trait_DEBUG_MIND_CONTROL ); + if( !talk_with->will_talk_to_u( *this, has_mind_control ) ) { return; } - const bool has_mind_control = g->u.has_trait( trait_DEBUG_MIND_CONTROL ); - // This is necessary so that we don't bug the player over and over - if( get_attitude() == NPCATT_TALK ) { - set_attitude( NPCATT_NULL ); - } else if( !has_mind_control && ( get_attitude() == NPCATT_FLEE || - get_attitude() == NPCATT_FLEE_TEMP ) ) { - add_msg( _( "%s is fleeing from you!" ), name ); - return; - } else if( !has_mind_control && get_attitude() == NPCATT_KILL ) { - add_msg( _( "%s is hostile!" ), name ); - return; - } - if( get_faction() ) { - get_faction()->known_by_u = true; - } - set_known_to_u( true ); dialogue d; - d.alpha = &g->u; - d.beta = this; - - chatbin.check_missions(); - - // For each active mission we have, let the mission know we talked to this NPC. - for( auto &mission : g->u.get_active_missions() ) { - mission->on_talk_with_npc( this->getID() ); - } - - for( auto &mission : chatbin.missions_assigned ) { - if( mission->get_assigned_player_id() == g->u.getID() ) { + d.alpha = get_talker_for( *this ); + d.beta = std::move( talk_with ); + d.by_radio = radio_contact; + dialogue_by_radio = radio_contact; + d.beta->check_missions(); + for( auto &mission : d.beta->assigned_missions() ) { + if( mission->get_assigned_player_id() == getID() ) { d.missions_assigned.push_back( mission ); } } - d.add_topic( chatbin.first_topic ); - if( radio_contact ) { - d.add_topic( "TALK_RADIO" ); - d.by_radio = true; - } else if( is_leader() ) { - d.add_topic( "TALK_LEADER" ); - } else if( is_player_ally() && ( is_walking_with() || has_activity() ) ) { - d.add_topic( "TALK_FRIEND" ); - } else if( get_attitude() == NPCATT_RECOVER_GOODS ) { - d.add_topic( "TALK_STOLE_ITEM" ); - } - g->u.dialogue_by_radio = d.by_radio; - int most_difficult_mission = 0; - for( auto &mission : chatbin.missions ) { - const auto &type = mission->get_type(); - if( type.urgent && type.difficulty > most_difficult_mission ) { - d.add_topic( "TALK_MISSION_DESCRIBE_URGENT" ); - chatbin.mission_selected = mission; - most_difficult_mission = type.difficulty; - } - } - most_difficult_mission = 0; - bool chosen_urgent = false; - for( auto &mission : chatbin.missions_assigned ) { - if( mission->get_assigned_player_id() != g->u.getID() ) { - // Not assigned to the player that is currently talking to the npc - continue; - } - const auto &type = mission->get_type(); - if( ( type.urgent && !chosen_urgent ) || ( type.difficulty > most_difficult_mission && - ( type.urgent || !chosen_urgent ) ) ) { - chosen_urgent = type.urgent; - d.add_topic( "TALK_MISSION_INQUIRE" ); - chatbin.mission_selected = mission; - most_difficult_mission = type.difficulty; - } - } - - // Needs - if( has_effect( effect_npc_suspend ) ) { - d.add_topic( "TALK_REBOOT" ); - } - if( has_effect( effect_sleep ) || has_effect( effect_lying_down ) ) { - if( has_effect( effect_narcosis ) ) { - d.add_topic( "TALK_SEDATED" ); - } else { - d.add_topic( "TALK_WAKE_UP" ); - } + for( const std::string &topic_id : d.beta->get_topics( radio_contact ) ) { + d.add_topic( topic_id ); } - - if( d.topic_stack.back().id == "TALK_NONE" ) { - d.topic_stack.back() = talk_topic( pick_talk_topic( g->u ) ); + for( const std::string &topic_id : d.alpha->get_topics( radio_contact ) ) { + d.add_topic( topic_id ); } - - moves -= 100; - - if( g->u.is_deaf() ) { - if( d.topic_stack.back().id == "TALK_MUG" || - d.topic_stack.back().id == "TALK_STRANGER_AGGRESSIVE" ) { - make_angry(); - d.add_topic( "TALK_DEAF_ANGRY" ); - } else { - d.add_topic( "TALK_DEAF" ); - } - } - - if( g->u.has_trait( trait_PROF_FOODP ) && !( g->u.is_wearing( itype_id( "foodperson_mask" ) ) || - g->u.is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) { - d.add_topic( "TALK_NOFACE" ); - } - - if( has_trait( trait_PROF_FOODP ) && !( is_wearing( itype_id( "foodperson_mask" ) ) || - is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) { - d.add_topic( "TALK_NPC_NOFACE" ); - } - - decide_needs(); - dialogue_window d_win; d_win.open_dialogue( text_only ); // Main dialogue loop do { - if( chatbin.mission_selected != nullptr ) { - if( chatbin.mission_selected->get_assigned_player_id() != g->u.getID() ) { - // Don't talk about a mission that is assigned to someone else. - chatbin.mission_selected = nullptr; - } - } - if( chatbin.mission_selected == nullptr ) { - // if possible, select a mission to talk about - if( !chatbin.missions.empty() ) { - chatbin.mission_selected = chatbin.missions.front(); - } else if( !d.missions_assigned.empty() ) { - chatbin.mission_selected = d.missions_assigned.front(); - } - } + d.beta->update_missions( d.missions_assigned, getID() ); const talk_topic next = d.opt( d_win, name, d.topic_stack.back() ); if( next.id == "TALK_NONE" ) { int cat = topic_category( d.topic_stack.back() ); @@ -879,19 +762,18 @@ void npc::talk_to_u( bool text_only, bool radio_contact ) } } while( !d.done ); - if( g->u.activity.id() == ACT_AIM && !g->u.has_weapon() ) { - g->u.cancel_activity(); + if( activity.id() == ACT_AIM && !has_weapon() ) { + cancel_activity(); // don't query certain activities that are started from dialogue - } else if( g->u.activity.id() == ACT_TRAIN || - g->u.activity.id() == ACT_WAIT_NPC || - g->u.activity.id() == ACT_SOCIALIZE || - g->u.activity.index == getID().get_value() ) { + } else if( activity.id() == ACT_TRAIN || activity.id() == ACT_WAIT_NPC || + activity.id() == ACT_SOCIALIZE || activity.index == d.beta->getID().get_value() ) { return; } - if( !g->u.has_effect( effect_under_operation ) ) { + if( !d.beta->has_effect( effect_under_operation ) ) { g->cancel_activity_or_ignore_query( distraction_type::talked_to, - string_format( _( "%s talked to you." ), name ) ); + string_format( _( "%s talked to you." ), + d.beta->disp_name() ) ); } } @@ -912,7 +794,7 @@ std::string dialogue::dynamic_line( const talk_topic &the_topic ) const } if( topic == "TALK_NPC_NOFACE" ) { - return string_format( _( "&%s stays silent." ), beta->name ); + return string_format( _( "&%s stays silent." ), beta->disp_name() ); } if( topic == "TALK_NOFACE" ) { @@ -923,16 +805,18 @@ std::string dialogue::dynamic_line( const talk_topic &the_topic ) const } else if( topic == "TALK_DEAF_ANGRY" ) { return string_format( _( "&You are deaf and can't talk. When you don't respond, %s becomes angry!" ), - beta->name ); + beta->disp_name() ); } if( topic == "TALK_SEDATED" ) { - return string_format( - _( "%1$s is sedated and can't be moved or woken up until the medication or sedation wears off.\nYou estimate it will wear off in %2$s." ), - beta->name, to_string_approx( g->u.estimate_effect_dur( skill_id( "firstaid" ), effect_narcosis, - 15_minutes, 6, *beta ) ) ); + return string_format( _( "%1$s is sedated and can't be moved or woken up until the " + "medication or sedation wears off.\nYou estimate it will wear " + "off in %2$s." ), + beta->disp_name(), + to_string_approx( g->u.estimate_effect_dur( skill_id( "firstaid" ), + effect_narcosis, 15_minutes, 6, + *beta->get_npc() ) ) ); } - const auto &p = beta; // for compatibility, later replace it in the code below // Those topics are handled by the mission system, see there. static const std::unordered_set mission_topics = { { "TALK_MISSION_DESCRIBE", "TALK_MISSION_DESCRIBE_URGENT", @@ -942,10 +826,10 @@ std::string dialogue::dynamic_line( const talk_topic &the_topic ) const } }; if( mission_topics.count( topic ) > 0 ) { - if( p->chatbin.mission_selected == nullptr ) { + mission *miss = beta->selected_mission(); + if( miss == nullptr ) { return "mission_selected == nullptr; BUG! (npctalk.cpp:dynamic_line)"; } - mission *miss = p->chatbin.mission_selected; const auto &type = miss->get_type(); // TODO: make it a member of the mission class, maybe at mission instance specific data const std::string &ret = miss->dialogue_for_topic( topic ); @@ -974,35 +858,17 @@ std::string dialogue::dynamic_line( const talk_topic &the_topic ) const } else if( topic == "TALK_TRAIN" ) { if( !g->u.backlog.empty() && g->u.backlog.front().id() == ACT_TRAIN ) { return _( "Shall we resume?" ); - } - std::vector trainable = p->skills_offered_to( g->u ); - std::vector styles = p->styles_offered_to( g->u ); - std::vector teachable = p->spells_offered_to( g->u ); - if( trainable.empty() && styles.empty() && teachable.empty() ) { + } else if( beta->skills_offered_to( *alpha ).empty() && + beta->styles_offered_to( *alpha ).empty() && + beta->spells_offered_to( *alpha ).empty() ) { return _( "Sorry, but it doesn't seem I have anything to teach you." ); } else { return _( "Here's what I can teach youā€¦" ); } } else if( topic == "TALK_HOW_MUCH_FURTHER" ) { - // TODO: this ignores the z-component - const tripoint player_pos = p->global_omt_location(); - int dist = rl_dist( player_pos, p->goal ); - std::string response; - dist *= 100; - if( dist >= 1300 ) { - int miles = dist / 25; // *100, e.g. quarter mile is "25" - miles -= miles % 25; // Round to nearest quarter-mile - int fullmiles = ( miles - miles % 100 ) / 100; // Left of the decimal point - if( fullmiles < 0 ) { - fullmiles = 0; - } - response = string_format( _( "%d.%d miles." ), fullmiles, miles ); - } else { - response = string_format( ngettext( "%d foot.", "%d feet.", dist ), dist ); - } - return response; + return beta->distance_to_goal(); } else if( topic == "TALK_DESCRIBE_MISSION" ) { - return p->describe_mission(); + return beta->get_job_description(); } else if( topic == "TALK_SHOUT" ) { alpha->shout(); if( alpha->is_deaf() ) { @@ -1011,88 +877,13 @@ std::string dialogue::dynamic_line( const talk_topic &the_topic ) const return _( "&You yell." ); } } else if( topic == "TALK_SIZE_UP" ) { - ///\EFFECT_PER affects whether player can size up NPCs - - ///\EFFECT_INT slightly affects whether player can size up NPCs - int ability = g->u.per_cur * 3 + g->u.int_cur; - if( ability <= 10 ) { - return _( "&You can't make anything out." ); - } - - if( p->is_player_ally() || ability > 100 ) { - ability = 100; - } - - std::string info = "&"; - int str_range = static_cast( 100 / ability ); - int str_min = static_cast( p->str_max / str_range ) * str_range; - info += string_format( _( "Str %d - %d" ), str_min, str_min + str_range ); - - if( ability >= 40 ) { - int dex_range = static_cast( 160 / ability ); - int dex_min = static_cast( p->dex_max / dex_range ) * dex_range; - info += string_format( _( " Dex %d - %d" ), dex_min, dex_min + dex_range ); - } - - if( ability >= 50 ) { - int int_range = static_cast( 200 / ability ); - int int_min = static_cast( p->int_max / int_range ) * int_range; - info += string_format( _( " Int %d - %d" ), int_min, int_min + int_range ); - } - - if( ability >= 60 ) { - int per_range = static_cast( 240 / ability ); - int per_min = static_cast( p->per_max / per_range ) * per_range; - info += string_format( _( " Per %d - %d" ), per_min, per_min + per_range ); - } - - needs_rates rates = p->calc_needs_rates(); - if( ability >= 100 - ( p->get_fatigue() / 10 ) ) { - std::string how_tired; - if( p->get_fatigue() > fatigue_levels::EXHAUSTED ) { - how_tired = _( "Exhausted" ); - } else if( p->get_fatigue() > fatigue_levels::DEAD_TIRED ) { - how_tired = _( "Dead tired" ); - } else if( p->get_fatigue() > fatigue_levels::TIRED ) { - how_tired = _( "Tired" ); - } else { - how_tired = _( "Not tired" ); - if( ability >= 100 ) { - time_duration sleep_at = 5_minutes * ( fatigue_levels::TIRED - p->get_fatigue() ) / - rates.fatigue; - how_tired += _( ". Will need sleep in " ) + to_string_approx( sleep_at ); - } - } - info += "\n" + how_tired; - } - if( ability >= 100 ) { - if( p->get_thirst() < 100 ) { - time_duration thirst_at = 5_minutes * ( 100 - p->get_thirst() ) / rates.thirst; - if( thirst_at > 1_hours ) { - info += _( "\nWill need water in " ) + to_string_approx( thirst_at ); - } - } else { - info += _( "\nThirsty" ); - } - if( p->get_hunger() < 100 ) { - time_duration hunger_at = 5_minutes * ( 100 - p->get_hunger() ) / rates.hunger; - if( hunger_at > 1_hours ) { - info += _( "\nWill need food in " ) + to_string_approx( hunger_at ); - } - } else { - info += _( "\nHungry" ); - } - } - return info; + return beta->evaluation_by( *alpha ); } else if( topic == "TALK_LOOK_AT" ) { - return "&" + p->short_description(); + return "&" + beta->short_description(); } else if( topic == "TALK_OPINION" ) { - return "&" + p->opinion_text(); + return "&" + beta->opinion_text(); } else if( topic == "TALK_MIND_CONTROL" ) { - bool not_following = g->get_follower_list().count( p->getID() ) == 0; - p->companion_mission_role_id.clear(); - talk_function::follow( *p ); - if( not_following ) { + if( beta->enslave_mind() ) { return _( "YES, MASTER!" ); } } @@ -1209,11 +1000,8 @@ talk_response &dialogue::add_response( const std::string &text, const std::strin void dialogue::gen_responses( const talk_topic &the_topic ) { - const auto &topic = the_topic.id; // for compatibility, later replace it in the code below - const auto p = beta; // for compatibility, later replace it in the code below - auto &ret = responses; // for compatibility, later replace it in the code below - ret.clear(); - const auto iter = json_talk_topics.find( topic ); + responses.clear(); + const auto iter = json_talk_topics.find( the_topic.id ); if( iter != json_talk_topics.end() ) { json_talk_topic &jtt = iter->second; if( jtt.gen_responses( *this ) ) { @@ -1221,16 +1009,16 @@ void dialogue::gen_responses( const talk_topic &the_topic ) } } - if( topic == "TALK_MISSION_LIST" ) { - if( p->chatbin.missions.size() == 1 ) { + if( the_topic.id == "TALK_MISSION_LIST" ) { + if( beta->available_missions().size() == 1 ) { add_response( _( "Tell me about it." ), "TALK_MISSION_OFFER", - p->chatbin.missions.front(), true ); + beta->available_missions().front(), true ); } else { - for( auto &mission : p->chatbin.missions ) { + for( auto &mission : beta->available_missions() ) { add_response( mission->get_type().tname(), "TALK_MISSION_OFFER", mission, true ); } } - } else if( topic == "TALK_MISSION_LIST_ASSIGNED" ) { + } else if( the_topic.id == "TALK_MISSION_LIST_ASSIGNED" ) { if( missions_assigned.size() == 1 ) { add_response( _( "I have news." ), "TALK_MISSION_INQUIRE", missions_assigned.front() ); } else { @@ -1238,9 +1026,9 @@ void dialogue::gen_responses( const talk_topic &the_topic ) add_response( miss_it->get_type().tname(), "TALK_MISSION_INQUIRE", miss_it ); } } - } else if( topic == "TALK_TRAIN" ) { + } else if( the_topic.id == "TALK_TRAIN" ) { if( !g->u.backlog.empty() && g->u.backlog.front().id() == ACT_TRAIN && - g->u.backlog.front().index == p->getID().get_value() ) { + g->u.backlog.front().index == beta->getID().get_value() ) { player_activity &backlog = g->u.backlog.front(); const skill_id skillt( backlog.name ); // TODO: This is potentially dangerous. A skill and a martial art @@ -1249,7 +1037,7 @@ void dialogue::gen_responses( const talk_topic &the_topic ) const matype_id styleid = matype_id( backlog.name ); if( !styleid.is_valid() ) { const spell_id &sp_id = spell_id( backlog.name ); - if( p->magic.knows_spell( sp_id ) ) { + if( beta->knows_spell( sp_id ) ) { add_response( string_format( _( "Yes, let's resume training %s" ), sp_id->name ), "TALK_TRAIN_START", sp_id ); } @@ -1263,167 +1051,79 @@ void dialogue::gen_responses( const talk_topic &the_topic ) "TALK_TRAIN_START", skillt ); } } - std::vector styles = p->styles_offered_to( g->u ); - std::vector trainable = p->skills_offered_to( g->u ); - std::vector teachable = p->spells_offered_to( g->u ); + const std::vector &styles = beta->styles_offered_to( *alpha ); + const std::vector &trainable = beta->skills_offered_to( *alpha ); + const std::vector &teachable = beta->spells_offered_to( *alpha ); if( trainable.empty() && styles.empty() && teachable.empty() ) { add_response_none( _( "Oh, okay." ) ); return; } for( const spell_id &sp : teachable ) { - const spell &temp_spell = p->magic.get_spell( sp ); - const bool knows = g->u.magic.knows_spell( sp ); - const int cost = p->calc_spell_training_cost( knows, temp_spell.get_difficulty(), - temp_spell.get_level() ); - std::string text; - if( knows ) { - text = string_format( _( "%s: 1 hour lesson (cost %s)" ), temp_spell.name(), - format_money( cost ) ); - } else { - text = string_format( _( "%s: teaching spell knowledge (cost %s)" ), - temp_spell.name(), format_money( cost ) ); + const std::string &text = beta->spell_training_text( *alpha, sp ); + if( !text.empty() ) { + add_response( text, "TALK_TRAIN_START", sp ); + } + } + for( const matype_id &style_id : styles ) { + const std::string &text = beta->style_training_text( *alpha, style_id ); + if( !text.empty() ) { + add_response( text, "TALK_TRAIN_START", style_id.obj() ); + } + } + for( const skill_id &trained : trainable ) { + const std::string &text = beta->skill_training_text( *alpha, trained ); + if( !text.empty() ) { + add_response( text, "TALK_TRAIN_START", trained ); } - add_response( text, "TALK_TRAIN_START", sp ); - } - for( auto &style_id : styles ) { - auto &style = style_id.obj(); - const int cost = calc_ma_style_training_cost( *p, style.id ); - //~Martial art style (cost in dollars) - const std::string text = string_format( cost > 0 ? _( "%s ( cost $%d )" ) : "%s", - style.name, cost / 100 ); - add_response( text, "TALK_TRAIN_START", style ); - } - for( auto &trained : trainable ) { - const int cost = calc_skill_training_cost( *p, trained ); - SkillLevel skill_level_obj = g->u.get_skill_level_object( trained ); - const int cur_level = skill_level_obj.level(); - const int cur_level_exercise = skill_level_obj.exercise(); - skill_level_obj.train( 100 ); - const int next_level = skill_level_obj.level(); - const int next_level_exercise = skill_level_obj.exercise(); - - //~Skill name: current level (exercise) -> next level (exercise) (cost in dollars) - std::string text = string_format( cost > 0 ? _( "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" ) : - _( "%s: %d (%d%%) -> %d (%d%%)" ), - trained.obj().name(), cur_level, cur_level_exercise, - next_level, next_level_exercise, cost / 100 ); - add_response( text, "TALK_TRAIN_START", trained ); } add_response_none( _( "Eh, never mind." ) ); - } else if( topic == "TALK_HOW_MUCH_FURTHER" ) { + } else if( the_topic.id == "TALK_HOW_MUCH_FURTHER" ) { add_response_none( _( "Okay, thanks." ) ); add_response_done( _( "Let's keep moving." ) ); } - if( g->u.has_trait( trait_DEBUG_MIND_CONTROL ) && !p->is_player_ally() ) { + if( alpha->has_trait( trait_DEBUG_MIND_CONTROL ) && !beta->is_player_ally() ) { add_response( _( "OBEY ME!" ), "TALK_MIND_CONTROL" ); add_response_done( _( "Bye." ) ); } - if( ret.empty() ) { + if( responses.empty() ) { add_response_done( _( "Bye." ) ); } } static int parse_mod( const dialogue &d, const std::string &attribute, const int factor ) { - player &u = *d.alpha; - npc &p = *d.beta; - int modifier = 0; - if( attribute == "ANGER" ) { - modifier = p.op_of_u.anger; - } else if( attribute == "FEAR" ) { - modifier = p.op_of_u.fear; - } else if( attribute == "TRUST" ) { - modifier = p.op_of_u.trust; - } else if( attribute == "VALUE" ) { - modifier = p.op_of_u.value; - } else if( attribute == "POS_FEAR" ) { - modifier = std::max( 0, p.op_of_u.fear ); - } else if( attribute == "AGGRESSION" ) { - modifier = p.personality.aggression; - } else if( attribute == "ALTRUISM" ) { - modifier = p.personality.altruism; - } else if( attribute == "BRAVERY" ) { - modifier = p.personality.bravery; - } else if( attribute == "COLLECTOR" ) { - modifier = p.personality.collector; - } else if( attribute == "MISSIONS" ) { - modifier = p.assigned_missions_value() / OWED_VAL; - } else if( attribute == "U_INTIMIDATE" ) { - modifier = u.intimidation(); - } else if( attribute == "NPC_INTIMIDATE" ) { - modifier = p.intimidation(); - } - modifier *= factor; - return modifier; + return d.beta->parse_mod( attribute, factor ) + d.alpha->parse_mod( attribute, factor ); } int talk_trial::calc_chance( const dialogue &d ) const { - player &u = *d.alpha; - if( u.has_trait( trait_DEBUG_MIND_CONTROL ) ) { + if( d.alpha->has_trait( trait_DEBUG_MIND_CONTROL ) ) { return 100; } - const social_modifiers &u_mods = u.get_mutation_social_mods(); - - npc &p = *d.beta; int chance = difficulty; switch( type ) { case NUM_TALK_TRIALS: dbg( D_ERROR ) << "called calc_chance with invalid talk_trial value: " << type; break; - case TALK_TRIAL_LIE: - chance += u.talk_skill() - p.talk_skill() + p.op_of_u.trust * 3; - chance += u_mods.lie; - - //come on, who would suspect a robot of lying? - if( u.has_bionic( bio_voice ) ) { - chance += 10; - } - if( u.has_bionic( bio_face_mask ) ) { - chance += 20; - } - break; - case TALK_TRIAL_PERSUADE: - chance += u.talk_skill() - static_cast( p.talk_skill() / 2 ) + - p.op_of_u.trust * 2 + p.op_of_u.value; - chance += u_mods.persuade; - - if( u.has_bionic( bio_face_mask ) ) { - chance += 10; - } - if( u.has_bionic( bio_deformity ) ) { - chance -= 50; - } - if( u.has_bionic( bio_voice ) ) { - chance -= 20; - } - break; - case TALK_TRIAL_INTIMIDATE: - chance += u.intimidation() - p.intimidation() + p.op_of_u.fear * 2 - - p.personality.bravery * 2; - chance += u_mods.intimidate; - - if( u.has_bionic( bio_face_mask ) ) { - chance += 10; - } - if( u.has_bionic( bio_armor_eyes ) ) { - chance += 10; - } - if( u.has_bionic( bio_deformity ) ) { - chance += 20; - } - if( u.has_bionic( bio_voice ) ) { - chance += 20; - } - break; case TALK_TRIAL_NONE: chance = 100; break; case TALK_TRIAL_CONDITION: chance = condition( d ) ? 100 : 0; break; + case TALK_TRIAL_LIE: + chance += d.alpha->trial_chance_mod( "lie" ) + d.beta->trial_chance_mod( "lie" ); + break; + case TALK_TRIAL_PERSUADE: + chance += d.alpha->trial_chance_mod( "persuade" ) + + d.beta->trial_chance_mod( "persuade" ); + break; + case TALK_TRIAL_INTIMIDATE: + chance += d.alpha->trial_chance_mod( "intimidate" ) + + d.beta->trial_chance_mod( "intimidate" ); + break; } for( const auto &this_mod : modifiers ) { chance += parse_mod( d, this_mod.first, this_mod.second ); @@ -1434,16 +1134,18 @@ int talk_trial::calc_chance( const dialogue &d ) const bool talk_trial::roll( dialogue &d ) const { - player &u = *d.alpha; - if( type == TALK_TRIAL_NONE || u.has_trait( trait_DEBUG_MIND_CONTROL ) ) { + if( type == TALK_TRIAL_NONE || d.alpha->has_trait( trait_DEBUG_MIND_CONTROL ) ) { return true; } const int chance = calc_chance( d ); const bool success = rng( 0, 99 ) < chance; - if( success ) { - u.practice( skill_speech, ( 100 - chance ) / 10 ); - } else { - u.practice( skill_speech, ( 100 - chance ) / 7 ); + if( d.alpha->get_character() ) { + player &u = *d.alpha->get_character(); + if( success ) { + u.practice( skill_speech, ( 100 - chance ) / 10 ); + } else { + u.practice( skill_speech, ( 100 - chance ) / 7 ); + } } return success; } @@ -1633,7 +1335,8 @@ talk_data talk_response::create_option_line( const dialogue &d, const char lette ftext = string_format( pgettext( "talk option", "%1$c: [%2$s %3$d%%] %4$s" ), letter, trial.name(), trial.calc_chance( d ), text ); } - parse_tags( ftext, *d.alpha, *d.beta, success.next_topic.item_type ); + parse_tags( ftext, *d.alpha->get_character(), *d.beta->get_npc(), + success.next_topic.item_type ); nc_color color; std::set consequences = get_consequences( d ); @@ -1666,7 +1369,7 @@ std::set talk_response::get_consequences( const dialogue & dialogue_consequence talk_effect_t::get_consequence( const dialogue &d ) const { - if( d.beta->op_of_u.anger + opinion.anger >= d.beta->hostile_anger_level() ) { + if( d.beta->check_hostile_response( opinion.anger ) ) { return dialogue_consequence::hostile; } return guaranteed_consequence; @@ -1703,7 +1406,7 @@ talk_topic dialogue::opt( dialogue_window &d_win, const std::string &npc_name, } // Parse any tags in challenge - parse_tags( challenge, *alpha, *beta, topic.item_type ); + parse_tags( challenge, *alpha->get_character(), *beta->get_npc(), topic.item_type ); capitalize_letter( challenge ); // Prepend "My Name: " @@ -1711,10 +1414,10 @@ talk_topic dialogue::opt( dialogue_window &d_win, const std::string &npc_name, // No name prepended! challenge = challenge.substr( 1 ); } else if( challenge[0] == '*' ) { - challenge = string_format( pgettext( "npc does something", "%s %s" ), beta->name, + challenge = string_format( pgettext( "npc does something", "%s %s" ), beta->disp_name(), challenge.substr( 1 ) ); } else { - challenge = string_format( pgettext( "npc says something", "%s: %s" ), beta->name, + challenge = string_format( pgettext( "npc says something", "%s: %s" ), beta->disp_name(), challenge ); } @@ -1794,24 +1497,12 @@ talk_topic dialogue::opt( dialogue_window &d_win, const std::string &npc_name, d_win.add_to_history( response_printed ); if( chosen.mission_selected != nullptr ) { - beta->chatbin.mission_selected = chosen.mission_selected; + beta->select_mission( chosen.mission_selected ); } // We can't set both skill and style or training will bug out // TODO: Allow setting both skill and style - if( chosen.skill ) { - beta->chatbin.skill = chosen.skill; - beta->chatbin.style = matype_id::NULL_ID(); - beta->chatbin.dialogue_spell = spell_id(); - } else if( chosen.style ) { - beta->chatbin.style = chosen.style; - beta->chatbin.skill = skill_id::NULL_ID(); - beta->chatbin.dialogue_spell = spell_id(); - } else if( chosen.dialogue_spell != spell_id() ) { - beta->chatbin.style = matype_id::NULL_ID(); - beta->chatbin.skill = skill_id::NULL_ID(); - beta->chatbin.dialogue_spell = chosen.dialogue_spell; - } + beta->store_chosen_training( chosen.skill, chosen.style, chosen.dialogue_spell ); const bool success = chosen.trial.roll( *this ); const auto &effects = success ? chosen.success : chosen.failure; return effects.apply( *this ); @@ -1860,16 +1551,18 @@ static talk_topic load_inline_topic( const JsonObject &jo ) talk_effect_fun_t::talk_effect_fun_t( const talkfunction_ptr &ptr ) { function = [ptr]( const dialogue & d ) { - npc &p = *d.beta; - ptr( p ); + if( d.beta->get_npc() ) { + ptr( *d.beta->get_npc() ); + } }; } talk_effect_fun_t::talk_effect_fun_t( const std::function &ptr ) { function = [ptr]( const dialogue & d ) { - npc &p = *d.beta; - ptr( p ); + if( d.beta->get_npc() ) { + ptr( *d.beta->get_npc() ); + } }; } @@ -1883,9 +1576,7 @@ talk_effect_fun_t::talk_effect_fun_t( const std::functionset_companion_mission( role_id ); }; } @@ -1906,11 +1597,7 @@ void talk_effect_fun_t::set_add_effect( const JsonObject &jo, const std::string duration = time_duration::from_turns( jo.get_int( "duration" ) ); } function = [is_npc, new_effect, duration, permanent]( const dialogue & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - actor->add_effect( efftype_id( new_effect ), duration, num_bp, permanent ); + d.actor( is_npc )->add_effect( efftype_id( new_effect ), duration, permanent ); }; } @@ -1919,11 +1606,7 @@ void talk_effect_fun_t::set_remove_effect( const JsonObject &jo, const std::stri { std::string old_effect = jo.get_string( member ); function = [is_npc, old_effect]( const dialogue & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - actor->remove_effect( efftype_id( old_effect ), num_bp ); + d.actor( is_npc )->remove_effect( efftype_id( old_effect ) ); }; } @@ -1932,11 +1615,7 @@ void talk_effect_fun_t::set_add_trait( const JsonObject &jo, const std::string & { std::string new_trait = jo.get_string( member ); function = [is_npc, new_trait]( const dialogue & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - actor->set_mutation( trait_id( new_trait ) ); + d.actor( is_npc )->set_mutation( trait_id( new_trait ) ); }; } @@ -1945,11 +1624,7 @@ void talk_effect_fun_t::set_remove_trait( const JsonObject &jo, const std::strin { std::string old_trait = jo.get_string( member ); function = [is_npc, old_trait]( const dialogue & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - actor->unset_mutation( trait_id( old_trait ) ); + d.actor( is_npc )->unset_mutation( trait_id( old_trait ) ); }; } @@ -1959,10 +1634,7 @@ void talk_effect_fun_t::set_add_var( const JsonObject &jo, const std::string &me const bool time_check = jo.has_member( "time" ) && jo.get_bool( "time" ); const std::string &value = time_check ? "" : jo.get_string( "value" ); function = [is_npc, var_name, value, time_check]( const dialogue & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } + talker *actor = d.actor( is_npc ); if( time_check ) { actor->set_value( var_name, string_format( "%d", to_turn( calendar::turn ) ) ); } else { @@ -1976,11 +1648,7 @@ void talk_effect_fun_t::set_remove_var( const JsonObject &jo, const std::string { const std::string var_name = get_talk_varname( jo, member, false ); function = [is_npc, var_name]( const dialogue & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - actor->remove_value( var_name ); + d.actor( is_npc )->remove_value( var_name ); }; } @@ -1990,19 +1658,14 @@ void talk_effect_fun_t::set_adjust_var( const JsonObject &jo, const std::string const std::string var_name = get_talk_varname( jo, member, false ); const int value = jo.get_int( "adjustment" ); function = [is_npc, var_name, value]( const dialogue & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } - int adjusted_value = value; - const std::string &var = actor->get_value( var_name ); + const std::string &var = d.actor( is_npc )->get_value( var_name ); if( !var.empty() ) { adjusted_value += std::stoi( var ); } - actor->set_value( var_name, std::to_string( adjusted_value ) ); + d.actor( is_npc )->set_value( var_name, std::to_string( adjusted_value ) ); }; } @@ -2010,9 +1673,7 @@ void talk_effect_fun_t::set_u_buy_item( const itype_id &item_name, int cost, int const std::string &container_name ) { function = [item_name, cost, count, container_name]( const dialogue & d ) { - npc &p = *d.beta; - player &u = *d.alpha; - if( !npc_trading::pay_npc( p, cost ) ) { + if( !d.beta->buy_from( cost ) ) { popup( _( "You can't afford it!" ) ); return; } @@ -2020,25 +1681,27 @@ void talk_effect_fun_t::set_u_buy_item( const itype_id &item_name, int cost, int item new_item = item( item_name, calendar::turn ); if( new_item.count_by_charges() ) { new_item.mod_charges( count - 1 ); - u.i_add( new_item ); + d.alpha->i_add( new_item ); } else { for( int i_cnt = 0; i_cnt < count; i_cnt++ ) { - u.i_add( new_item ); + d.alpha->i_add( new_item ); } } if( count == 1 ) { //~ %1%s is the NPC name, %2$s is an item - popup( _( "%1$s gives you a %2$s." ), p.name, new_item.tname() ); + popup( _( "%1$s gives you a %2$s." ), d.beta->disp_name(), new_item.tname() ); } else { //~ %1%s is the NPC name, %2$d is a number of items, %3$s are items - popup( _( "%1$s gives you %2$d %3$s." ), p.name, count, new_item.tname() ); + popup( _( "%1$s gives you %2$d %3$s." ), d.beta->disp_name(), count, + new_item.tname() ); } } else { item container( container_name, calendar::turn ); - container.put_in( item( item_name, calendar::turn, count ), item_pocket::pocket_type::CONTAINER ); - u.i_add( container ); + container.put_in( item( item_name, calendar::turn, count ), + item_pocket::pocket_type::CONTAINER ); + d.alpha->i_add( container ); //~ %1%s is the NPC name, %2$s is an item - popup( _( "%1$s gives you a %2$s." ), p.name, container.tname() ); + popup( _( "%1$s gives you a %2$s." ), d.beta->disp_name(), container.tname() ); } }; @@ -2051,15 +1714,13 @@ void talk_effect_fun_t::set_u_buy_item( const itype_id &item_name, int cost, int void talk_effect_fun_t::set_u_sell_item( const itype_id &item_name, int cost, int count ) { function = [item_name, cost, count]( const dialogue & d ) { - npc &p = *d.beta; - player &u = *d.alpha; - if( item::count_by_charges( item_name ) && u.has_charges( item_name, count ) ) { - for( const item &it : u.use_charges( item_name, count ) ) { - p.i_add( it ); + if( item::count_by_charges( item_name ) && d.alpha->has_charges( item_name, count ) ) { + for( const item &it : d.alpha->use_charges( item_name, count ) ) { + d.beta->i_add( it ); } - } else if( u.has_amount( item_name, count ) ) { - for( const item &it : u.use_amount( item_name, count ) ) { - p.i_add( it ); + } else if( d.alpha->has_amount( item_name, count ) ) { + for( const item &it : d.alpha->use_amount( item_name, count ) ) { + d.beta->i_add( it ); } } else { //~ %1$s is a translated item name @@ -2068,12 +1729,13 @@ void talk_effect_fun_t::set_u_sell_item( const itype_id &item_name, int cost, in } if( count == 1 ) { //~ %1%s is the NPC name, %2$s is an item - popup( _( "You give %1$s a %2$s." ), p.name, item::nname( item_name ) ); + popup( _( "You give %1$s a %2$s." ), d.beta->disp_name(), item::nname( item_name ) ); } else { //~ %1%s is the NPC name, %2$d is a number of items, %3$s are items - popup( _( "You give %1$s %2$d %3$s." ), p.name, count, item::nname( item_name, count ) ); + popup( _( "You give %1$s %2$d %3$s." ), d.beta->disp_name(), count, + item::nname( item_name, count ) ); } - p.op_of_u.owed += cost; + d.beta->add_debt( cost ); }; } @@ -2085,7 +1747,7 @@ void talk_effect_fun_t::set_consume_item( const JsonObject &jo, const std::strin jo.read( member, item_name, true ); function = [is_npc, item_name, count]( const dialogue & d ) { // this is stupid, but I couldn't get the assignment to work - const auto consume_item = [&]( player & p, const itype_id & item_name, int count ) { + const auto consume_item = [&]( talker & p, const itype_id & item_name, int count ) { item old_item( item_name ); if( p.has_charges( item_name, count ) ) { p.use_charges( item_name, count ); @@ -2109,12 +1771,8 @@ void talk_effect_fun_t::set_remove_item_with( const JsonObject &jo, const std::s { const std::string &item_name = jo.get_string( member ); function = [is_npc, item_name]( const dialogue & d ) { - player *actor = d.alpha; - if( is_npc ) { - actor = dynamic_cast( d.beta ); - } itype_id item_id = itype_id( item_name ); - actor->remove_items_with( [item_id]( const item & it ) { + d.actor( is_npc )->remove_items_with( [item_id]( const item & it ) { return it.typeId() == item_id; } ); }; @@ -2123,35 +1781,28 @@ void talk_effect_fun_t::set_remove_item_with( const JsonObject &jo, const std::s void talk_effect_fun_t::set_u_spend_cash( int amount ) { function = [amount]( const dialogue & d ) { - npc &np = *d.beta; - npc_trading::pay_npc( np, amount ); + d.beta->buy_from( amount ); }; } void talk_effect_fun_t::set_npc_change_faction( const std::string &faction_name ) { function = [faction_name]( const dialogue & d ) { - npc &p = *d.beta; - p.set_fac( faction_id( faction_name ) ); + d.beta->set_fac( faction_id( faction_name ) ); }; } void talk_effect_fun_t::set_npc_change_class( const std::string &class_name ) { function = [class_name]( const dialogue & d ) { - npc &p = *d.beta; - p.myclass = npc_class_id( class_name ); + d.beta->set_class( npc_class_id( class_name ) ); }; } void talk_effect_fun_t::set_change_faction_rep( int rep_change ) { function = [rep_change]( const dialogue & d ) { - npc &p = *d.beta; - if( p.get_faction()->id != faction_id( "no_faction" ) ) { - p.get_faction()->likes_u += rep_change; - p.get_faction()->respects_u += rep_change; - } + d.beta->add_faction_rep( rep_change ); }; } @@ -2166,85 +1817,56 @@ void talk_effect_fun_t::set_add_debt( const std::vector &debt_modifie debt += parse_mod( d, this_mod.first, this_mod.second ); } } - d.beta->op_of_u += npc_opinion( 0, 0, 0, 0, debt ); + d.beta->add_debt( debt ); }; } void talk_effect_fun_t::set_toggle_npc_rule( const std::string &rule ) { function = [rule]( const dialogue & d ) { - auto toggle = ally_rule_strs.find( rule ); - if( toggle == ally_rule_strs.end() ) { - return; - } - d.beta->rules.toggle_flag( toggle->second.rule ); - d.beta->wield_better_weapon(); + d.beta->toggle_ai_rule( "ally_rule", rule ); }; } void talk_effect_fun_t::set_set_npc_rule( const std::string &rule ) { function = [rule]( const dialogue & d ) { - auto flag = ally_rule_strs.find( rule ); - if( flag == ally_rule_strs.end() ) { - return; - } - d.beta->rules.set_flag( flag->second.rule ); - d.beta->wield_better_weapon(); + d.beta->set_ai_rule( "ally_rule", rule ); }; } void talk_effect_fun_t::set_clear_npc_rule( const std::string &rule ) { function = [rule]( const dialogue & d ) { - auto flag = ally_rule_strs.find( rule ); - if( flag == ally_rule_strs.end() ) { - return; - } - d.beta->rules.clear_flag( flag->second.rule ); - d.beta->wield_better_weapon(); + d.beta->clear_ai_rule( "ally_rule", rule ); }; } void talk_effect_fun_t::set_npc_engagement_rule( const std::string &setting ) { function = [setting]( const dialogue & d ) { - auto rule = combat_engagement_strs.find( setting ); - if( rule != combat_engagement_strs.end() ) { - d.beta->rules.engagement = rule->second; - d.beta->invalidate_range_cache(); - } + d.beta->set_ai_rule( "engagement_rule", setting ); }; } void talk_effect_fun_t::set_npc_aim_rule( const std::string &setting ) { function = [setting]( const dialogue & d ) { - auto rule = aim_rule_strs.find( setting ); - if( rule != aim_rule_strs.end() ) { - d.beta->rules.aim = rule->second; - d.beta->invalidate_range_cache(); - } + d.beta->set_ai_rule( "aim_rule", setting ); }; } void talk_effect_fun_t::set_npc_cbm_reserve_rule( const std::string &setting ) { function = [setting]( const dialogue & d ) { - auto rule = cbm_reserve_strs.find( setting ); - if( rule != cbm_reserve_strs.end() ) { - d.beta->rules.cbm_reserve = rule->second; - } + d.beta->set_ai_rule( "cbm_reserve_rule", setting ); }; } void talk_effect_fun_t::set_npc_cbm_recharge_rule( const std::string &setting ) { function = [setting]( const dialogue & d ) { - auto rule = cbm_recharge_strs.find( setting ); - if( rule != cbm_recharge_strs.end() ) { - d.beta->rules.cbm_recharge = rule->second; - } + d.beta->set_ai_rule( "cbm_recharge_rule", setting ); }; } @@ -2263,10 +1885,10 @@ void talk_effect_fun_t::set_mapgen_update( const JsonObject &jo, const std::stri function = [target_params, update_ids]( const dialogue & d ) { mission_target_params update_params = target_params; - update_params.guy = d.beta; + update_params.guy = d.beta->get_npc(); const tripoint omt_pos = mission_util::get_om_terrain_pos( update_params ); for( const std::string &mapgen_update_id : update_ids ) { - run_mapgen_update_func( mapgen_update_id, omt_pos, d.beta->chatbin.mission_selected ); + run_mapgen_update_func( mapgen_update_id, omt_pos, d.beta->selected_mission() ); } }; } @@ -2274,17 +1896,13 @@ void talk_effect_fun_t::set_mapgen_update( const JsonObject &jo, const std::stri void talk_effect_fun_t::set_bulk_trade_accept( bool is_trade, bool is_npc ) { function = [is_trade, is_npc]( const dialogue & d ) { - player *seller = d.alpha; - player *buyer = dynamic_cast( d.beta ); - if( is_npc ) { - seller = dynamic_cast( d.beta ); - buyer = d.alpha; - } + const std::unique_ptr &seller = is_npc ? d.beta : d.alpha; + const std::unique_ptr &buyer = is_npc ? d.alpha : d.beta; int seller_has = seller->charges_of( d.cur_item ); item tmp( d.cur_item ); tmp.charges = seller_has; if( is_trade ) { - int price = tmp.price( true ) * ( is_npc ? -1 : 1 ) + d.beta->op_of_u.owed; + int price = tmp.price( true ) * ( is_npc ? -1 : 1 ) + d.beta->debt(); if( d.beta->get_faction() && !d.beta->get_faction()->currency.is_empty() ) { const itype_id &pay_in = d.beta->get_faction()->currency; item pay( pay_in ); @@ -2297,11 +1915,11 @@ void talk_effect_fun_t::set_bulk_trade_accept( bool is_trade, bool is_npc ) } else { if( buyer_has == 1 ) { //~ %1%s is the NPC name, %2$s is an item - popup( _( "%1$s gives you a %2$s." ), d.beta->disp_name(), + popup( _( "%1$s gives you a %2$s." ), seller->disp_name(), pay.tname() ); } else if( buyer_has > 1 ) { //~ %1%s is the NPC name, %2$d is a number of items, %3$s are items - popup( _( "%1$s gives you %2$d %3$s." ), d.beta->disp_name(), buyer_has, + popup( _( "%1$s gives you %2$d %3$s." ), seller->disp_name(), buyer_has, pay.tname() ); } } @@ -2310,7 +1928,7 @@ void talk_effect_fun_t::set_bulk_trade_accept( bool is_trade, bool is_npc ) price -= d.beta->value( pay ); } } - d.beta->op_of_u.owed += price; + d.beta->add_debt( price ); } } seller->use_charges( d.cur_item, seller_has ); @@ -2321,17 +1939,14 @@ void talk_effect_fun_t::set_bulk_trade_accept( bool is_trade, bool is_npc ) void talk_effect_fun_t::set_npc_gets_item( bool to_use ) { function = [to_use]( const dialogue & d ) { - d.reason = give_item_to( *( d.beta ), to_use ); + d.reason = d.beta->give_item_to( to_use ); }; } void talk_effect_fun_t::set_add_mission( const std::string &mission_id ) { function = [mission_id]( const dialogue & d ) { - npc &p = *d.beta; - mission *miss = mission::reserve_new( mission_type_id( mission_id ), p.getID() ); - miss->assign( get_avatar() ); - p.chatbin.missions_assigned.push_back( miss ); + d.beta->add_mission( mission_type_id( mission_id ) ); }; } @@ -2343,50 +1958,18 @@ const std::vector> &talk_effect_fun_t::get_likely_rewar void talk_effect_fun_t::set_u_buy_monster( const std::string &monster_type_id, int cost, int count, bool pacified, const translation &name ) { - function = [monster_type_id, cost, count, pacified, name]( const dialogue & d ) { - npc &p = *d.beta; - player &u = *d.alpha; - if( !npc_trading::pay_npc( p, cost ) ) { - popup( _( "You can't afford it!" ) ); - return; - } + function = [monster_type_id, cost, count, pacified, name]( const dialogue & d ) { const mtype_id mtype( monster_type_id ); - - for( int i = 0; i < count; i++ ) { - monster *const mon_ptr = g->place_critter_around( mtype, u.pos(), 3 ); - if( !mon_ptr ) { - add_msg( m_debug, "Cannot place u_buy_monster, no valid placement locations." ); - break; - } - monster &tmp = *mon_ptr; - // Our monster is always a pet. - tmp.friendly = -1; - tmp.add_effect( effect_pet, 1_turns, num_bp, true ); - - if( pacified ) { - tmp.add_effect( effect_pacified, 1_turns, num_bp, true ); - } - - if( !name.empty() ) { - tmp.unique_name = name.translated(); - } - - } - - if( name.empty() ) { - popup( _( "%1$s gives you %2$d %3$s." ), p.name, count, mtype.obj().nname( count ) ); - } else { - popup( _( "%1$s gives you %2$s." ), p.name, name ); - } + d.alpha->buy_monster( *d.beta, mtype, cost, count, pacified, name ); }; } void talk_effect_fun_t::set_u_learn_recipe( const std::string &learned_recipe_id ) { - function = [learned_recipe_id]( const dialogue & d ) { + function = [learned_recipe_id]( const dialogue & ) { const recipe &r = recipe_id( learned_recipe_id ).obj(); - d.alpha->learn_recipe( &r ); + g->u.learn_recipe( &r ); popup( _( "You learn how to craft %s." ), r.result_name() ); }; } @@ -2429,24 +2012,20 @@ void talk_effect_t::set_effect( talkfunction_ptr ptr ) talk_topic talk_effect_t::apply( dialogue &d ) const { // Need to get a reference to the mission before effects are applied, because effects can remove the mission - mission *miss = d.beta->chatbin.mission_selected; + mission *miss = d.beta->selected_mission(); for( const talk_effect_fun_t &effect : effects ) { effect( d ); } - d.beta->op_of_u += opinion; + d.beta->add_opinion( opinion.trust, opinion.fear, opinion.value, opinion.anger, opinion.owed ); if( miss && ( mission_opinion.trust || mission_opinion.fear || mission_opinion.value || mission_opinion.anger ) ) { - int m_value = npc_trading::cash_to_favor( *d.beta, miss->get_value() ); - npc_opinion mod = npc_opinion( mission_opinion.trust ? - m_value / mission_opinion.trust : 0, - mission_opinion.fear ? - m_value / mission_opinion.fear : 0, - mission_opinion.value ? - m_value / mission_opinion.value : 0, - mission_opinion.anger ? - m_value / mission_opinion.anger : 0, 0 ); - d.beta->op_of_u += mod; + int m_value = d.beta->cash_to_favor( miss->get_value() ); + d.beta->add_opinion( mission_opinion.trust ? m_value / mission_opinion.trust : 0, + mission_opinion.fear ? m_value / mission_opinion.fear : 0, + mission_opinion.value ? m_value / mission_opinion.value : 0, + mission_opinion.anger ? m_value / mission_opinion.anger : 0, + 0 ); } if( d.beta->turned_hostile() ) { d.beta->make_angry(); @@ -2458,7 +2037,7 @@ talk_topic talk_effect_t::apply( dialogue &d ) const auto &ma = d.missions_assigned; ma.clear(); // Update the missions we can talk about (must only be current, non-complete ones) - for( auto &mission : d.beta->chatbin.missions_assigned ) { + for( auto &mission : d.beta->assigned_missions() ) { if( mission->get_assigned_player_id() == d.alpha->getID() ) { ma.push_back( mission ); } @@ -3126,10 +2705,7 @@ bool json_talk_topic::gen_responses( dialogue &d ) const switch_done |= r.gen_responses( d, switch_done ); } for( const json_talk_repeat_response &repeat : repeat_responses ) { - player *actor = d.alpha; - if( repeat.is_npc ) { - actor = dynamic_cast( d.beta ); - } + std::unique_ptr &actor = repeat.is_npc ? d.beta : d.alpha; std::function filter = return_true; for( const itype_id &item_id : repeat.for_item ) { if( actor->charges_of( item_id ) > 0 || actor->has_amount( item_id, 1 ) ) { @@ -3217,185 +2793,6 @@ std::string npc::pick_talk_topic( const player &/*u*/ ) return "TALK_STRANGER_NEUTRAL"; } -enum consumption_result { - REFUSED = 0, - CONSUMED_SOME, // Consumption didn't fail, but don't delete the item - CONSUMED_ALL // Consumption succeeded, delete the item -}; - -// Returns true if we destroyed the item through consumption -// does not try to consume contents -static consumption_result try_consume( npc &p, item &it, std::string &reason ) -{ - // TODO: Unify this with 'player::consume_item()' - item &to_eat = it; - if( to_eat.is_null() ) { - debugmsg( "Null item to try_consume." ); - return REFUSED; - } - const auto &comest = to_eat.get_comestible(); - if( !comest ) { - // Don't inform the player that we don't want to eat the lighter - return REFUSED; - } - - if( !p.will_accept_from_player( it ) ) { - reason = _( "I don't trust you enough to eat THISā€¦" ); - return REFUSED; - } - - // TODO: Make it not a copy+paste from player::consume_item - int amount_used = 1; - if( to_eat.is_food() ) { - if( !p.can_consume( to_eat ) ) { - reason = _( "It doesn't look like a good idea to consume thisā€¦" ); - return REFUSED; - } else { - const time_duration &consume_time = p.get_consume_time( to_eat ); - p.moves -= to_moves( consume_time ); - p.consume( to_eat ); - reason = _( "Thanks, that hit the spot." ); - - } - } else if( to_eat.is_medication() ) { - if( !comest->tool.is_null() ) { - bool has = p.has_amount( comest->tool, 1 ); - if( item::count_by_charges( comest->tool ) ) { - has = p.has_charges( comest->tool, 1 ); - } - if( !has ) { - reason = string_format( _( "I need a %s to consume that!" ), - item::nname( comest->tool ) ); - return REFUSED; - } - p.use_charges( comest->tool, 1 ); - reason = _( "Thanks, I feel better already." ); - } - if( to_eat.type->has_use() ) { - amount_used = to_eat.type->invoke( p, to_eat, p.pos() ); - if( amount_used <= 0 ) { - reason = _( "It doesn't look like a good idea to consume thisā€¦" ); - return REFUSED; - } - reason = _( "Thanks, I used it." ); - } - - to_eat.charges -= amount_used; - p.consume_effects( to_eat ); - p.moves -= 250; - } else { - debugmsg( "Unknown comestible type of item: %s\n", to_eat.tname() ); - } - - if( to_eat.charges > 0 ) { - return CONSUMED_SOME; - } - - // If not consuming contents and charge <= 0, we just ate the last charge from the stack - return CONSUMED_ALL; -} - -std::string give_item_to( npc &p, bool allow_use ) -{ - if( p.is_hallucination() ) { - return _( "No thanks, I'm good." ); - } - item_location loc = game_menus::inv::titled_menu( g->u, _( "Offer what?" ), - _( "You have no items to offer." ) ); - if( !loc ) { - return _( "Changed your mind?" ); - } - item &given = *loc; - - if( ( &given == &g->u.weapon && given.has_flag( "NO_UNWIELD" ) ) || ( g->u.is_worn( given ) && - given.has_flag( "NO_TAKEOFF" ) ) ) { - // Bionic weapon or shackles - return _( "How?" ); - } - - if( given.is_dangerous() && !g->u.has_trait( trait_DEBUG_MIND_CONTROL ) ) { - return _( "Are you insane!?" ); - } - - bool taken = false; - std::string reason = _( "Nope." ); - int our_ammo = p.ammo_count_for( p.weapon ); - int new_ammo = p.ammo_count_for( given ); - const double new_weapon_value = p.weapon_value( given, new_ammo ); - const double cur_weapon_value = p.weapon_value( p.weapon, our_ammo ); - add_msg( m_debug, "NPC evaluates own %s (%d ammo): %0.1f", - p.weapon.typeId().str(), our_ammo, cur_weapon_value ); - add_msg( m_debug, "NPC evaluates your %s (%d ammo): %0.1f", - given.typeId().str(), new_ammo, new_weapon_value ); - if( allow_use ) { - // Eating first, to avoid evaluating bread as a weapon - const auto consume_res = try_consume( p, given, reason ); - if( consume_res != REFUSED ) { - if( consume_res == CONSUMED_ALL ) { - g->u.i_rem( &given ); - } - g->u.moves -= 100; - if( given.is_container() ) { - given.on_contents_changed(); - } - }// wield it if its a weapon - else if( new_weapon_value > cur_weapon_value ) { - p.wield( given ); - reason = _( "Thanks, I'll wield that now." ); - taken = true; - }// HACK: is_gun here is a hack to prevent NPCs wearing guns if they don't want to use them - else if( !given.is_gun() && given.is_armor() ) { - //if it is impossible to wear return why - ret_val can_wear = p.can_wear( given, true ); - if( !can_wear.success() ) { - reason = can_wear.str(); - } else { - //if we can wear it with equip changes prompt first - can_wear = p.can_wear( given ); - if( ( can_wear.success() || - query_yn( can_wear.str() + _( " Should I take something off?" ) ) ) - && p.wear_if_wanted( given, reason ) ) { - taken = true; - } else { - reason = can_wear.str(); - } - } - } else { - reason += string_format( - _( "My current weapon is better than this.\n(new weapon value: %.1f vs %.1f)." ), new_weapon_value, - cur_weapon_value ); - } - } else {//allow_use is false so try to carry instead - if( p.can_pickVolume( given ) && p.can_pickWeight( given ) ) { - reason = _( "Thanks, I'll carry that now." ); - taken = true; - p.i_add( given ); - } else { - if( !p.can_pickVolume( given ) ) { - const units::volume free_space = p.volume_capacity() - p.volume_carried(); - reason += "\n" + std::string( _( "I have no space to store it." ) ) + "\n"; - if( free_space > 0_ml ) { - reason += string_format( _( "I can only store %s %s more." ), - format_volume( free_space ), volume_units_long() ); - } else { - reason += _( "ā€¦or to store anything else for that matter." ); - } - } - if( !p.can_pickWeight( given ) ) { - reason += std::string( "\n" ) + _( "It is too heavy for me to carry." ); - } - } - } - - if( taken ) { - g->u.i_rem( &given ); - g->u.moves -= 100; - p.has_new_items = true; - } - - return reason; -} - bool npc::has_item_whitelist() const { return is_player_ally() && !rules.pickup_whitelist->empty(); diff --git a/tests/npc_talk_test.cpp b/tests/npc_talk_test.cpp index 2d519730557b2..3318b0bdf545b 100644 --- a/tests/npc_talk_test.cpp +++ b/tests/npc_talk_test.cpp @@ -29,6 +29,7 @@ #include "point.h" #include "string_id.h" #include "stringmaker.h" +#include "talker.h" #include "type_id.h" static const efftype_id effect_gave_quest_item( "gave_quest_item" ); @@ -51,6 +52,7 @@ static npc &create_test_talker() for( const trait_id &tr : model_npc->get_mutations() ) { model_npc->unset_mutation( tr ); } + model_npc->name = "Beta NPC"; model_npc->set_hunger( 0 ); model_npc->set_thirst( 0 ); model_npc->set_fatigue( 0 ); @@ -93,7 +95,8 @@ static npc &prep_test( dialogue &d ) { clear_avatar(); clear_vehicles(); - player &player_character = get_avatar(); + avatar &player_character = get_avatar(); + player_character.name = "Alpha Avatar"; REQUIRE_FALSE( player_character.in_vehicle ); const tripoint test_origin( 15, 15, 0 ); @@ -101,12 +104,12 @@ static npc &prep_test( dialogue &d ) g->faction_manager_ptr->create_if_needed(); - npc &talker_npc = create_test_talker(); + npc &beta = create_test_talker(); - d.alpha = &player_character; - d.beta = &talker_npc; + d.alpha = get_talker_for( player_character ); + d.beta = get_talker_for( beta ); - return talker_npc; + return beta; } TEST_CASE( "npc_talk_start", "[npc_talk]" ) @@ -884,16 +887,16 @@ TEST_CASE( "npc_talk_vars_time", "[npc_talk]" ) TEST_CASE( "npc_talk_bionics", "[npc_talk]" ) { dialogue d; - npc &talker_npc = prep_test( d ); + npc &beta = prep_test( d ); player &player_character = get_avatar(); player_character.clear_bionics(); - talker_npc.clear_bionics(); + beta.clear_bionics(); d.add_topic( "TALK_TEST_BIONICS" ); gen_response_lines( d, 1 ); CHECK( d.responses[0].text == "This is a basic test response." ); player_character.add_bionic( bionic_id( "bio_ads" ) ); - talker_npc.add_bionic( bionic_id( "bio_power_storage" ) ); + beta.add_bionic( bionic_id( "bio_power_storage" ) ); gen_response_lines( d, 3 ); CHECK( d.responses[0].text == "This is a basic test response." ); CHECK( d.responses[1].text == "This is a u_has_bionics bio_ads test response." ); From 91ff71168bc93c287707fc08da6b5aec20878e14 Mon Sep 17 00:00:00 2001 From: Meladath Date: Tue, 14 Jul 2020 17:24:43 +0100 Subject: [PATCH 018/151] Fix cotton ball volume --- data/json/items/comestibles/med.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/items/comestibles/med.json b/data/json/items/comestibles/med.json index b65fc0df3abf6..f08a860f4cef3 100644 --- a/data/json/items/comestibles/med.json +++ b/data/json/items/comestibles/med.json @@ -495,10 +495,10 @@ "description": "Fluffy balls of clean white cotton. Can serve as makeshift bandages in an emergency.", "category": "spare_parts", "weight": "22 g", - "volume": "250 ml", + "volume": "200 ml", "price": 500, "price_postapoc": 50, - "charges": 2, + "charges": 10, "material": [ "cotton" ], "symbol": "*", "color": "white", From 3f6d0c9b5b39b7f84a76283ddd48b9efcc3235fa Mon Sep 17 00:00:00 2001 From: Meladath Date: Tue, 14 Jul 2020 17:28:55 +0100 Subject: [PATCH 019/151] Better sizes for legacy craftables support --- data/json/items/comestibles/med.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/items/comestibles/med.json b/data/json/items/comestibles/med.json index f08a860f4cef3..49e38605255d2 100644 --- a/data/json/items/comestibles/med.json +++ b/data/json/items/comestibles/med.json @@ -495,10 +495,10 @@ "description": "Fluffy balls of clean white cotton. Can serve as makeshift bandages in an emergency.", "category": "spare_parts", "weight": "22 g", - "volume": "200 ml", + "volume": "250 ml", "price": 500, "price_postapoc": 50, - "charges": 10, + "charges": 12, "material": [ "cotton" ], "symbol": "*", "color": "white", From 7050a0d15b40e73e8ae452fc4c3cbf08218cbbcb Mon Sep 17 00:00:00 2001 From: Meladath Date: Tue, 14 Jul 2020 18:58:38 +0100 Subject: [PATCH 020/151] Better volume and fix disinfectant soaked ball --- data/json/items/comestibles/med.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/json/items/comestibles/med.json b/data/json/items/comestibles/med.json index 49e38605255d2..7c0d48dfa3ea4 100644 --- a/data/json/items/comestibles/med.json +++ b/data/json/items/comestibles/med.json @@ -498,7 +498,7 @@ "volume": "250 ml", "price": 500, "price_postapoc": 50, - "charges": 12, + "charges": 10, "material": [ "cotton" ], "symbol": "*", "color": "white", @@ -1823,7 +1823,7 @@ "description": "Fluffy balls of clean white cotton. Now soaked with antiseptic, they are somewhat useful to disinfect a wound.", "weight": "25 g", "//": "Can't copy-from cotton_ball, breaks volume", - "volume": "125 ml", + "volume": "30 ml", "price": 250, "price_postapoc": 50, "material": [ "cotton" ], From d43fcc0273926eb72db77cf1564f478b6947b26c Mon Sep 17 00:00:00 2001 From: Meladath Date: Tue, 14 Jul 2020 19:05:45 +0100 Subject: [PATCH 021/151] Description change and pillow fix --- data/json/items/comestibles/med.json | 8 ++++---- data/json/recipes/recipe_deconstruction.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/data/json/items/comestibles/med.json b/data/json/items/comestibles/med.json index 7c0d48dfa3ea4..3abed3684cf47 100644 --- a/data/json/items/comestibles/med.json +++ b/data/json/items/comestibles/med.json @@ -491,8 +491,8 @@ "id": "cotton_ball", "type": "COMESTIBLE", "comestible_type": "MED", - "name": { "str_sp": "cotton balls" }, - "description": "Fluffy balls of clean white cotton. Can serve as makeshift bandages in an emergency.", + "name": { "str_sp": "cotton ball" }, + "description": "A fluffy ball of clean white cotton. Can serve as a makeshift bandage in an emergency.", "category": "spare_parts", "weight": "22 g", "volume": "250 ml", @@ -1819,8 +1819,8 @@ "id": "disincotton_ball", "type": "COMESTIBLE", "comestible_type": "MED", - "name": { "str_sp": "antiseptic soaked cotton balls" }, - "description": "Fluffy balls of clean white cotton. Now soaked with antiseptic, they are somewhat useful to disinfect a wound.", + "name": { "str_sp": "antiseptic soaked cotton ball" }, + "description": "A fluffy ball of clean white cotton. Now soaked with antiseptic, it is somewhat useful to disinfect a wound.", "weight": "25 g", "//": "Can't copy-from cotton_ball, breaks volume", "volume": "30 ml", diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index 94344672a5659..80e3ae3691157 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -2561,7 +2561,7 @@ "type": "uncraft", "time": "1 m", "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ [ [ "rag", 4 ] ], [ [ "cotton_ball", 8 ] ] ] + "components": [ [ [ "rag", 4 ] ], [ [ "cotton_ball", 40 ] ] ] }, { "result": "pipe", From 996654f553943f8818318ed6cd79e9346d188fab Mon Sep 17 00:00:00 2001 From: olanti-p Date: Tue, 14 Jul 2020 21:28:26 +0300 Subject: [PATCH 022/151] Reset vehicle cache when (un-)mounting vehicles --- src/vehicle_use.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index f4ac178a89eda..f3360d20e6e93 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -1878,6 +1878,7 @@ void vehicle::use_bike_rack( int part ) } if( success ) { get_map().invalidate_map_cache( g->get_levz() ); + get_map().reset_vehicle_cache( g->get_levz() ); } } From 9ebce5b1d99a4668c76451d345ad67b6775c9ead Mon Sep 17 00:00:00 2001 From: Meladath Date: Tue, 14 Jul 2020 19:47:50 +0100 Subject: [PATCH 023/151] Revert plurality change --- data/json/items/comestibles/med.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/json/items/comestibles/med.json b/data/json/items/comestibles/med.json index 3abed3684cf47..7c0d48dfa3ea4 100644 --- a/data/json/items/comestibles/med.json +++ b/data/json/items/comestibles/med.json @@ -491,8 +491,8 @@ "id": "cotton_ball", "type": "COMESTIBLE", "comestible_type": "MED", - "name": { "str_sp": "cotton ball" }, - "description": "A fluffy ball of clean white cotton. Can serve as a makeshift bandage in an emergency.", + "name": { "str_sp": "cotton balls" }, + "description": "Fluffy balls of clean white cotton. Can serve as makeshift bandages in an emergency.", "category": "spare_parts", "weight": "22 g", "volume": "250 ml", @@ -1819,8 +1819,8 @@ "id": "disincotton_ball", "type": "COMESTIBLE", "comestible_type": "MED", - "name": { "str_sp": "antiseptic soaked cotton ball" }, - "description": "A fluffy ball of clean white cotton. Now soaked with antiseptic, it is somewhat useful to disinfect a wound.", + "name": { "str_sp": "antiseptic soaked cotton balls" }, + "description": "Fluffy balls of clean white cotton. Now soaked with antiseptic, they are somewhat useful to disinfect a wound.", "weight": "25 g", "//": "Can't copy-from cotton_ball, breaks volume", "volume": "30 ml", From 20960763678efc225994b75bf05355c889503bca Mon Sep 17 00:00:00 2001 From: meladath Date: Tue, 14 Jul 2020 19:50:41 +0100 Subject: [PATCH 024/151] Update recipe_deconstruction.json --- data/json/recipes/recipe_deconstruction.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index 80e3ae3691157..94344672a5659 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -2561,7 +2561,7 @@ "type": "uncraft", "time": "1 m", "qualities": [ { "id": "CUT", "level": 1 } ], - "components": [ [ [ "rag", 4 ] ], [ [ "cotton_ball", 40 ] ] ] + "components": [ [ [ "rag", 4 ] ], [ [ "cotton_ball", 8 ] ] ] }, { "result": "pipe", From ed4d22fa079ae514c6482228ab7bc7de05eb73e8 Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Mon, 13 Jul 2020 09:07:45 -0400 Subject: [PATCH 025/151] Factor command line parsing out of main main is an overlarge function. This is an easy chunk to pull out. --- src/main.cpp | 758 ++++++++++++++++++++++++++------------------------- 1 file changed, 385 insertions(+), 373 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a2073d9126148..39aa116da8499 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -122,6 +122,381 @@ struct arg_handler { void printHelpMessage( const arg_handler *first_pass_arguments, size_t num_first_pass_arguments, const arg_handler *second_pass_arguments, size_t num_second_pass_arguments ); + +struct cli_opts { + int seed = time( nullptr ); + bool verifyexit = false; + bool check_mods = false; + std::string dump; + dump_mode dmode = dump_mode::TSV; + std::vector opts; + std::string world; /** if set try to load first save in this world on startup */ +}; + +cli_opts parse_commandline( int argc, char **argv ) +{ + cli_opts result; + + const char *section_default = nullptr; + const char *section_map_sharing = "Map sharing"; + const char *section_user_directory = "User directories"; + const std::array first_pass_arguments = {{ + { + "--seed", "", + "Sets the random number generator's seed value", + section_default, + [&result]( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + const unsigned char *hash_input = reinterpret_cast( params[0] ); + result.seed = djb2_hash( hash_input ); + return 1; + } + }, + { + "--jsonverify", nullptr, + "Checks the CDDA json files", + section_default, + [&result]( int, const char ** ) -> int { + result.verifyexit = true; + return 0; + } + }, + { + "--check-mods", "[modsā€¦]", + "Checks the json files belonging to CDDA mods", + section_default, + [&result]( int n, const char *params[] ) -> int { + result.check_mods = true; + test_mode = true; + for( int i = 0; i < n; ++i ) + { + result.opts.emplace_back( params[ i ] ); + } + return 0; + } + }, + { + "--dump-stats", " [mode = TSV] [optsā€¦]", + "Dumps item stats", + section_default, + [&result]( int n, const char *params[] ) -> int { + if( n < 1 ) + { + return -1; + } + test_mode = true; + result.dump = params[ 0 ]; + for( int i = 2; i < n; ++i ) + { + result.opts.emplace_back( params[ i ] ); + } + if( n >= 2 ) + { + if( !strcmp( params[ 1 ], "TSV" ) ) { + result.dmode = dump_mode::TSV; + return 0; + } else if( !strcmp( params[ 1 ], "HTML" ) ) { + result.dmode = dump_mode::HTML; + return 0; + } else { + return -1; + } + } + return 0; + } + }, + { + "--world", "", + "Load world", + section_default, + [&result]( int n, const char *params[] ) -> int { + if( n < 1 ) + { + return -1; + } + result.world = params[0]; + return 1; + } + }, + { + "--basepath", "", + "Base path for all game data subdirectories", + section_default, + []( int num_args, const char **params ) + { + if( num_args < 1 ) { + return -1; + } + PATH_INFO::init_base_path( params[0] ); + PATH_INFO::set_standard_filenames(); + return 1; + } + }, + { + "--shared", nullptr, + "Activates the map-sharing mode", + section_map_sharing, + []( int, const char ** ) -> int { + MAP_SHARING::setSharing( true ); + MAP_SHARING::setCompetitive( true ); + MAP_SHARING::setWorldmenu( false ); + return 0; + } + }, + { + "--username", "", + "Instructs map-sharing code to use this name for your character.", + section_map_sharing, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + MAP_SHARING::setUsername( params[0] ); + return 1; + } + }, + { + "--addadmin", "", + "Instructs map-sharing code to use this name for your character and give you " + "access to the cheat functions.", + section_map_sharing, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + MAP_SHARING::addAdmin( params[0] ); + return 1; + } + }, + { + "--adddebugger", "", + "Informs map-sharing code that you're running inside a debugger", + section_map_sharing, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + MAP_SHARING::addDebugger( params[0] ); + return 1; + } + }, + { + "--competitive", nullptr, + "Instructs map-sharing code to disable access to the in-game cheat functions", + section_map_sharing, + []( int, const char ** ) -> int { + MAP_SHARING::setCompetitive( true ); + return 0; + } + }, + { + "--userdir", "", + // NOLINTNEXTLINE(cata-text-style): the dot is not a period + "Base path for user-overrides to files from the ./data directory and named below", + section_user_directory, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + PATH_INFO::init_user_dir( params[0] ); + PATH_INFO::set_standard_filenames(); + return 1; + } + } + } + }; + + // The following arguments are dependent on one or more of the previous flags and are run + // in a second pass. + const std::array second_pass_arguments = {{ + { + "--worldmenu", nullptr, + "Enables the world menu in the map-sharing code", + section_map_sharing, + []( int, const char ** ) -> int { + MAP_SHARING::setWorldmenu( true ); + return true; + } + }, + { + "--datadir", "", + "Sub directory from which game data is loaded", + nullptr, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + PATH_INFO::set_datadir( params[0] ); + return 1; + } + }, + { + "--savedir", "", + "Subdirectory for game saves", + section_user_directory, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + PATH_INFO::set_savedir( params[0] ); + return 1; + } + }, + { + "--configdir", "", + "Subdirectory for game configuration", + section_user_directory, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + PATH_INFO::set_config_dir( params[0] ); + return 1; + } + }, + { + "--memorialdir", "", + "Subdirectory for memorials", + section_user_directory, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + PATH_INFO::set_memorialdir( params[0] ); + return 1; + } + }, + { + "--optionfile", "", + "Name of the options file within the configdir", + section_user_directory, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + PATH_INFO::set_options( params[0] ); + return 1; + } + }, + { + "--keymapfile", "", + "Name of the keymap file within the configdir", + section_user_directory, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + PATH_INFO::set_keymap( params[0] ); + return 1; + } + }, + { + "--autopickupfile", "", + "Name of the autopickup options file within the configdir", + nullptr, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + PATH_INFO::set_autopickup( params[0] ); + return 1; + } + }, + { + "--motdfile", "", + "Name of the message of the day file within the motd directory", + nullptr, + []( int num_args, const char **params ) -> int { + if( num_args < 1 ) + { + return -1; + } + PATH_INFO::set_motd( params[0] ); + return 1; + } + }, + } + }; + + // Process CLI arguments. + const size_t num_first_pass_arguments = + sizeof( first_pass_arguments ) / sizeof( first_pass_arguments[0] ); + const size_t num_second_pass_arguments = + sizeof( second_pass_arguments ) / sizeof( second_pass_arguments[0] ); + int saved_argc = --argc; // skip program name + const char **saved_argv = const_cast( ++argv ); + while( argc ) { + if( !strcmp( argv[0], "--help" ) ) { + printHelpMessage( first_pass_arguments.data(), num_first_pass_arguments, + second_pass_arguments.data(), num_second_pass_arguments ); + std::exit( 0 ); + } else { + bool arg_handled = false; + for( size_t i = 0; i < num_first_pass_arguments; ++i ) { + auto &arg_handler = first_pass_arguments[i]; + if( !strcmp( argv[0], arg_handler.flag ) ) { + argc--; + argv++; + int args_consumed = arg_handler.handler( argc, const_cast( argv ) ); + if( args_consumed < 0 ) { + printf( "Failed parsing parameter '%s'\n", *( argv - 1 ) ); + exit( 1 ); + } + argc -= args_consumed; + argv += args_consumed; + arg_handled = true; + break; + } + } + // Skip other options. + if( !arg_handled ) { + --argc; + ++argv; + } + } + } + while( saved_argc ) { + bool arg_handled = false; + for( size_t i = 0; i < num_second_pass_arguments; ++i ) { + auto &arg_handler = second_pass_arguments[i]; + if( !strcmp( saved_argv[0], arg_handler.flag ) ) { + --saved_argc; + ++saved_argv; + int args_consumed = arg_handler.handler( saved_argc, saved_argv ); + if( args_consumed < 0 ) { + printf( "Failed parsing parameter '%s'\n", *( argv - 1 ) ); + exit( 1 ); + } + saved_argc -= args_consumed; + saved_argv += args_consumed; + arg_handled = true; + break; + } + } + // Ignore unknown options. + if( !arg_handled ) { + --saved_argc; + ++saved_argv; + } + } + + return result; +} + } // namespace #if defined(USE_WINMAIN) @@ -137,13 +512,6 @@ int main( int argc, char *argv[] ) { #endif init_crash_handlers(); - int seed = time( nullptr ); - bool verifyexit = false; - bool check_mods = false; - std::string dump; - dump_mode dmode = dump_mode::TSV; - std::vector opts; - std::string world; /** if set try to load first save in this world on startup */ #if defined(__ANDROID__) // Start the standard output logging redirector @@ -180,364 +548,8 @@ int main( int argc, char *argv[] ) PATH_INFO::set_standard_filenames(); MAP_SHARING::setDefaults(); - { - const char *section_default = nullptr; - const char *section_map_sharing = "Map sharing"; - const char *section_user_directory = "User directories"; - const std::array first_pass_arguments = {{ - { - "--seed", "", - "Sets the random number generator's seed value", - section_default, - [&seed]( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - const unsigned char *hash_input = reinterpret_cast( params[0] ); - seed = djb2_hash( hash_input ); - return 1; - } - }, - { - "--jsonverify", nullptr, - "Checks the CDDA json files", - section_default, - [&verifyexit]( int, const char ** ) -> int { - verifyexit = true; - return 0; - } - }, - { - "--check-mods", "[modsā€¦]", - "Checks the json files belonging to CDDA mods", - section_default, - [&check_mods, &opts]( int n, const char *params[] ) -> int { - check_mods = true; - test_mode = true; - for( int i = 0; i < n; ++i ) - { - opts.emplace_back( params[ i ] ); - } - return 0; - } - }, - { - "--dump-stats", " [mode = TSV] [optsā€¦]", - "Dumps item stats", - section_default, - [&dump, &dmode, &opts]( int n, const char *params[] ) -> int { - if( n < 1 ) - { - return -1; - } - test_mode = true; - dump = params[ 0 ]; - for( int i = 2; i < n; ++i ) - { - opts.emplace_back( params[ i ] ); - } - if( n >= 2 ) - { - if( !strcmp( params[ 1 ], "TSV" ) ) { - dmode = dump_mode::TSV; - return 0; - } else if( !strcmp( params[ 1 ], "HTML" ) ) { - dmode = dump_mode::HTML; - return 0; - } else { - return -1; - } - } - return 0; - } - }, - { - "--world", "", - "Load world", - section_default, - [&world]( int n, const char *params[] ) -> int { - if( n < 1 ) - { - return -1; - } - world = params[0]; - return 1; - } - }, - { - "--basepath", "", - "Base path for all game data subdirectories", - section_default, - []( int num_args, const char **params ) - { - if( num_args < 1 ) { - return -1; - } - PATH_INFO::init_base_path( params[0] ); - PATH_INFO::set_standard_filenames(); - return 1; - } - }, - { - "--shared", nullptr, - "Activates the map-sharing mode", - section_map_sharing, - []( int, const char ** ) -> int { - MAP_SHARING::setSharing( true ); - MAP_SHARING::setCompetitive( true ); - MAP_SHARING::setWorldmenu( false ); - return 0; - } - }, - { - "--username", "", - "Instructs map-sharing code to use this name for your character.", - section_map_sharing, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - MAP_SHARING::setUsername( params[0] ); - return 1; - } - }, - { - "--addadmin", "", - "Instructs map-sharing code to use this name for your character and give you " - "access to the cheat functions.", - section_map_sharing, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - MAP_SHARING::addAdmin( params[0] ); - return 1; - } - }, - { - "--adddebugger", "", - "Informs map-sharing code that you're running inside a debugger", - section_map_sharing, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - MAP_SHARING::addDebugger( params[0] ); - return 1; - } - }, - { - "--competitive", nullptr, - "Instructs map-sharing code to disable access to the in-game cheat functions", - section_map_sharing, - []( int, const char ** ) -> int { - MAP_SHARING::setCompetitive( true ); - return 0; - } - }, - { - "--userdir", "", - // NOLINTNEXTLINE(cata-text-style): the dot is not a period - "Base path for user-overrides to files from the ./data directory and named below", - section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - PATH_INFO::init_user_dir( params[0] ); - PATH_INFO::set_standard_filenames(); - return 1; - } - } - } - }; - // The following arguments are dependent on one or more of the previous flags and are run - // in a second pass. - const std::array second_pass_arguments = {{ - { - "--worldmenu", nullptr, - "Enables the world menu in the map-sharing code", - section_map_sharing, - []( int, const char ** ) -> int { - MAP_SHARING::setWorldmenu( true ); - return true; - } - }, - { - "--datadir", "", - "Sub directory from which game data is loaded", - nullptr, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - PATH_INFO::set_datadir( params[0] ); - return 1; - } - }, - { - "--savedir", "", - "Subdirectory for game saves", - section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - PATH_INFO::set_savedir( params[0] ); - return 1; - } - }, - { - "--configdir", "", - "Subdirectory for game configuration", - section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - PATH_INFO::set_config_dir( params[0] ); - return 1; - } - }, - { - "--memorialdir", "", - "Subdirectory for memorials", - section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - PATH_INFO::set_memorialdir( params[0] ); - return 1; - } - }, - { - "--optionfile", "", - "Name of the options file within the configdir", - section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - PATH_INFO::set_options( params[0] ); - return 1; - } - }, - { - "--keymapfile", "", - "Name of the keymap file within the configdir", - section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - PATH_INFO::set_keymap( params[0] ); - return 1; - } - }, - { - "--autopickupfile", "", - "Name of the autopickup options file within the configdir", - nullptr, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - PATH_INFO::set_autopickup( params[0] ); - return 1; - } - }, - { - "--motdfile", "", - "Name of the message of the day file within the motd directory", - nullptr, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } - PATH_INFO::set_motd( params[0] ); - return 1; - } - }, - } - }; - - // Process CLI arguments. - const size_t num_first_pass_arguments = - sizeof( first_pass_arguments ) / sizeof( first_pass_arguments[0] ); - const size_t num_second_pass_arguments = - sizeof( second_pass_arguments ) / sizeof( second_pass_arguments[0] ); - int saved_argc = --argc; // skip program name - const char **saved_argv = const_cast( ++argv ); - while( argc ) { - if( !strcmp( argv[0], "--help" ) ) { - printHelpMessage( first_pass_arguments.data(), num_first_pass_arguments, - second_pass_arguments.data(), num_second_pass_arguments ); - return 0; - } else { - bool arg_handled = false; - for( size_t i = 0; i < num_first_pass_arguments; ++i ) { - auto &arg_handler = first_pass_arguments[i]; - if( !strcmp( argv[0], arg_handler.flag ) ) { - argc--; - argv++; - int args_consumed = arg_handler.handler( argc, const_cast( argv ) ); - if( args_consumed < 0 ) { - printf( "Failed parsing parameter '%s'\n", *( argv - 1 ) ); - exit( 1 ); - } - argc -= args_consumed; - argv += args_consumed; - arg_handled = true; - break; - } - } - // Skip other options. - if( !arg_handled ) { - --argc; - ++argv; - } - } - } - while( saved_argc ) { - bool arg_handled = false; - for( size_t i = 0; i < num_second_pass_arguments; ++i ) { - auto &arg_handler = second_pass_arguments[i]; - if( !strcmp( saved_argv[0], arg_handler.flag ) ) { - --saved_argc; - ++saved_argv; - int args_consumed = arg_handler.handler( saved_argc, saved_argv ); - if( args_consumed < 0 ) { - printf( "Failed parsing parameter '%s'\n", *( argv - 1 ) ); - exit( 1 ); - } - saved_argc -= args_consumed; - saved_argv += args_consumed; - arg_handled = true; - break; - } - } - // Ignore unknown options. - if( !arg_handled ) { - --saved_argc; - ++saved_argv; - } - } - } + cli_opts cli = parse_commandline( argc, argv ); if( !dir_exist( PATH_INFO::datadir() ) ) { printf( "Fatal: Can't find data directory \"%s\"\nPlease ensure the current working directory is correct or specify data directory with --datadir. Perhaps you meant to start \"cataclysm-launcher\"?\n", @@ -619,24 +631,24 @@ int main( int argc, char *argv[] ) set_language(); - rng_set_engine_seed( seed ); + rng_set_engine_seed( cli.seed ); g = std::make_unique(); // First load and initialize everything that does not // depend on the mods. try { g->load_static_data(); - if( verifyexit ) { + if( cli.verifyexit ) { exit_handler( 0 ); } - if( !dump.empty() ) { + if( !cli.dump.empty() ) { init_colors(); - exit( g->dump_stats( dump, dmode, opts ) ? 0 : 1 ); + exit( g->dump_stats( cli.dump, cli.dmode, cli.opts ) ? 0 : 1 ); } - if( check_mods ) { + if( cli.check_mods ) { init_colors(); loading_ui ui( false ); - const std::vector mods( opts.begin(), opts.end() ); + const std::vector mods( cli.opts.begin(), cli.opts.end() ); exit( g->check_mod_data( mods, ui ) && !debug_has_error_been_observed() ? 0 : 1 ); } } catch( const std::exception &err ) { @@ -680,11 +692,11 @@ int main( int argc, char *argv[] ) #endif while( true ) { - if( !world.empty() ) { - if( !g->load( world ) ) { + if( !cli.world.empty() ) { + if( !g->load( cli.world ) ) { break; } - world.clear(); // ensure quit returns to opening screen + cli.world.clear(); // ensure quit returns to opening screen } else { main_menu menu; From 9d6308d321b34cc978029965c43b08ada9b0e062 Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Mon, 13 Jul 2020 09:14:26 -0400 Subject: [PATCH 026/151] Move helper functions to the top of main.cpp Define these functions before use so that we don't need to have separate declarations. Also, make exit_handler static. --- src/main.cpp | 130 ++++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 69 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 39aa116da8499..232ed2f2e939a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -101,11 +101,26 @@ int start_logger( const char *app_name ) #endif //__ANDROID__ -void exit_handler( int s ); - namespace { +void exit_handler( int s ) +{ + const int old_timeout = inp_mngr.get_timeout(); + inp_mngr.reset_timeout(); + if( s != 2 || query_yn( _( "Really Quit? All unsaved changes will be lost." ) ) ) { + deinitDebug(); + + int exit_status = 0; + g.reset(); + + catacurses::endwin(); + + exit( exit_status ); + } + inp_mngr.set_timeout( old_timeout ); +} + struct arg_handler { //! Handler function to be invoked when this argument is encountered. The handler will be //! called with the number of parameters after the flag was encountered, along with the array @@ -120,8 +135,50 @@ struct arg_handler { handler_method handler; //!< The callback to be invoked when this argument is encountered. }; -void printHelpMessage( const arg_handler *first_pass_arguments, size_t num_first_pass_arguments, - const arg_handler *second_pass_arguments, size_t num_second_pass_arguments ); +void printHelpMessage( const arg_handler *first_pass_arguments, + size_t num_first_pass_arguments, + const arg_handler *second_pass_arguments, + size_t num_second_pass_arguments ) +{ + + // Group all arguments by help_group. + std::multimap help_map; + for( size_t i = 0; i < num_first_pass_arguments; ++i ) { + std::string help_group; + if( first_pass_arguments[i].help_group ) { + help_group = first_pass_arguments[i].help_group; + } + help_map.insert( std::make_pair( help_group, &first_pass_arguments[i] ) ); + } + for( size_t i = 0; i < num_second_pass_arguments; ++i ) { + std::string help_group; + if( second_pass_arguments[i].help_group ) { + help_group = second_pass_arguments[i].help_group; + } + help_map.insert( std::make_pair( help_group, &second_pass_arguments[i] ) ); + } + + printf( "Command line parameters:\n" ); + std::string current_help_group; + auto it = help_map.begin(); + auto it_end = help_map.end(); + for( ; it != it_end; ++it ) { + if( it->first != current_help_group ) { + current_help_group = it->first; + printf( "\n%s\n", current_help_group.c_str() ); + } + + const arg_handler *handler = it->second; + printf( "%s", handler->flag ); + if( handler->param_documentation ) { + printf( " %s", handler->param_documentation ); + } + printf( "\n" ); + if( handler->documentation ) { + printf( " %s\n", handler->documentation ); + } + } +} struct cli_opts { int seed = time( nullptr ); @@ -712,68 +769,3 @@ int main( int argc, char *argv[] ) exit_handler( -999 ); return 0; } - -namespace -{ -void printHelpMessage( const arg_handler *first_pass_arguments, - size_t num_first_pass_arguments, - const arg_handler *second_pass_arguments, - size_t num_second_pass_arguments ) -{ - - // Group all arguments by help_group. - std::multimap help_map; - for( size_t i = 0; i < num_first_pass_arguments; ++i ) { - std::string help_group; - if( first_pass_arguments[i].help_group ) { - help_group = first_pass_arguments[i].help_group; - } - help_map.insert( std::make_pair( help_group, &first_pass_arguments[i] ) ); - } - for( size_t i = 0; i < num_second_pass_arguments; ++i ) { - std::string help_group; - if( second_pass_arguments[i].help_group ) { - help_group = second_pass_arguments[i].help_group; - } - help_map.insert( std::make_pair( help_group, &second_pass_arguments[i] ) ); - } - - printf( "Command line parameters:\n" ); - std::string current_help_group; - auto it = help_map.begin(); - auto it_end = help_map.end(); - for( ; it != it_end; ++it ) { - if( it->first != current_help_group ) { - current_help_group = it->first; - printf( "\n%s\n", current_help_group.c_str() ); - } - - const arg_handler *handler = it->second; - printf( "%s", handler->flag ); - if( handler->param_documentation ) { - printf( " %s", handler->param_documentation ); - } - printf( "\n" ); - if( handler->documentation ) { - printf( " %s\n", handler->documentation ); - } - } -} -} // namespace - -void exit_handler( int s ) -{ - const int old_timeout = inp_mngr.get_timeout(); - inp_mngr.reset_timeout(); - if( s != 2 || query_yn( _( "Really Quit? All unsaved changes will be lost." ) ) ) { - deinitDebug(); - - int exit_status = 0; - g.reset(); - - catacurses::endwin(); - - exit( exit_status ); - } - inp_mngr.set_timeout( old_timeout ); -} From 9bbedb371c668636d61dfa25c099971900fb30bb Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Mon, 13 Jul 2020 20:38:07 -0400 Subject: [PATCH 027/151] Refactor command line parsing * Factor out repeated loop. * Modernize. * Make argv be const char**. --- src/main.cpp | 136 +++++++++++++++++++++------------------------------ 1 file changed, 55 insertions(+), 81 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 232ed2f2e939a..45ddea5aa92f3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -135,40 +135,36 @@ struct arg_handler { handler_method handler; //!< The callback to be invoked when this argument is encountered. }; -void printHelpMessage( const arg_handler *first_pass_arguments, - size_t num_first_pass_arguments, - const arg_handler *second_pass_arguments, - size_t num_second_pass_arguments ) +template +void printHelpMessage( const FirstPassArgs &first_pass_arguments, + const SecondPassArgs &second_pass_arguments ) { - // Group all arguments by help_group. std::multimap help_map; - for( size_t i = 0; i < num_first_pass_arguments; ++i ) { + for( const arg_handler &handler : first_pass_arguments ) { std::string help_group; - if( first_pass_arguments[i].help_group ) { - help_group = first_pass_arguments[i].help_group; + if( handler.help_group ) { + help_group = handler.help_group; } - help_map.insert( std::make_pair( help_group, &first_pass_arguments[i] ) ); + help_map.emplace( help_group, &handler ); } - for( size_t i = 0; i < num_second_pass_arguments; ++i ) { + for( const arg_handler &handler : second_pass_arguments ) { std::string help_group; - if( second_pass_arguments[i].help_group ) { - help_group = second_pass_arguments[i].help_group; + if( handler.help_group ) { + help_group = handler.help_group; } - help_map.insert( std::make_pair( help_group, &second_pass_arguments[i] ) ); + help_map.emplace( help_group, &handler ); } printf( "Command line parameters:\n" ); std::string current_help_group; - auto it = help_map.begin(); - auto it_end = help_map.end(); - for( ; it != it_end; ++it ) { - if( it->first != current_help_group ) { - current_help_group = it->first; + for( std::pair &help_entry : help_map ) { + if( help_entry.first != current_help_group ) { + current_help_group = help_entry.first; printf( "\n%s\n", current_help_group.c_str() ); } - const arg_handler *handler = it->second; + const arg_handler *handler = help_entry.second; printf( "%s", handler->flag ); if( handler->param_documentation ) { printf( " %s", handler->param_documentation ); @@ -180,6 +176,34 @@ void printHelpMessage( const arg_handler *first_pass_arguments, } } +template +void process_args( const char **argv, int argc, const ArgHandlerContainer &arg_handlers ) +{ + while( argc ) { + bool arg_handled = false; + for( const arg_handler &handler : arg_handlers ) { + if( !strcmp( argv[0], handler.flag ) ) { + argc--; + argv++; + int args_consumed = handler.handler( argc, argv ); + if( args_consumed < 0 ) { + printf( "Failed parsing parameter '%s'\n", *( argv - 1 ) ); + std::exit( 1 ); + } + argc -= args_consumed; + argv += args_consumed; + arg_handled = true; + break; + } + } + // Skip other options. + if( !arg_handled ) { + --argc; + ++argv; + } + } +} + struct cli_opts { int seed = time( nullptr ); bool verifyexit = false; @@ -190,7 +214,7 @@ struct cli_opts { std::string world; /** if set try to load first save in this world on startup */ }; -cli_opts parse_commandline( int argc, char **argv ) +cli_opts parse_commandline( int argc, const char **argv ) { cli_opts result; @@ -489,68 +513,18 @@ cli_opts parse_commandline( int argc, char **argv ) } }; - // Process CLI arguments. - const size_t num_first_pass_arguments = - sizeof( first_pass_arguments ) / sizeof( first_pass_arguments[0] ); - const size_t num_second_pass_arguments = - sizeof( second_pass_arguments ) / sizeof( second_pass_arguments[0] ); - int saved_argc = --argc; // skip program name - const char **saved_argv = const_cast( ++argv ); - while( argc ) { - if( !strcmp( argv[0], "--help" ) ) { - printHelpMessage( first_pass_arguments.data(), num_first_pass_arguments, - second_pass_arguments.data(), num_second_pass_arguments ); - std::exit( 0 ); - } else { - bool arg_handled = false; - for( size_t i = 0; i < num_first_pass_arguments; ++i ) { - auto &arg_handler = first_pass_arguments[i]; - if( !strcmp( argv[0], arg_handler.flag ) ) { - argc--; - argv++; - int args_consumed = arg_handler.handler( argc, const_cast( argv ) ); - if( args_consumed < 0 ) { - printf( "Failed parsing parameter '%s'\n", *( argv - 1 ) ); - exit( 1 ); - } - argc -= args_consumed; - argv += args_consumed; - arg_handled = true; - break; - } - } - // Skip other options. - if( !arg_handled ) { - --argc; - ++argv; - } - } - } - while( saved_argc ) { - bool arg_handled = false; - for( size_t i = 0; i < num_second_pass_arguments; ++i ) { - auto &arg_handler = second_pass_arguments[i]; - if( !strcmp( saved_argv[0], arg_handler.flag ) ) { - --saved_argc; - ++saved_argv; - int args_consumed = arg_handler.handler( saved_argc, saved_argv ); - if( args_consumed < 0 ) { - printf( "Failed parsing parameter '%s'\n", *( argv - 1 ) ); - exit( 1 ); - } - saved_argc -= args_consumed; - saved_argv += args_consumed; - arg_handled = true; - break; - } - } - // Ignore unknown options. - if( !arg_handled ) { - --saved_argc; - ++saved_argv; - } + if( std::count( argv, argv + argc, std::string( "--help" ) ) ) { + printHelpMessage( first_pass_arguments, second_pass_arguments ); + std::exit( 0 ); } + // skip program name + --argc; + ++argv; + + process_args( argv, argc, first_pass_arguments ); + process_args( argv, argc, second_pass_arguments ); + return result; } @@ -565,7 +539,7 @@ int APIENTRY WinMain( HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, #elif defined(__ANDROID__) extern "C" int SDL_main( int argc, char **argv ) { #else -int main( int argc, char *argv[] ) +int main( int argc, const char *argv[] ) { #endif init_crash_handlers(); From 5e33a15653c764c522df96c4fb8cf09e296b2a27 Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Mon, 13 Jul 2020 20:51:56 -0400 Subject: [PATCH 028/151] Factor out common code checking for num args Allow arg_handler to declare how many arguments it expects, so that the check that there are sufficiently many can be placed in one place, rather than repeated in every arg_handler lambda. --- src/main.cpp | 128 ++++++++++++++++++--------------------------------- 1 file changed, 46 insertions(+), 82 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 45ddea5aa92f3..bcb7869dbe5d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -132,6 +132,7 @@ struct arg_handler { const char *param_documentation; //!< Human readable description of this arguments parameter. const char *documentation; //!< Human readable documentation for this argument. const char *help_group; //!< Section of the help message in which to include this argument. + int num_args; //!< How many further arguments are expected for this parameter (usually 0 or 1). handler_method handler; //!< The callback to be invoked when this argument is encountered. }; @@ -185,6 +186,11 @@ void process_args( const char **argv, int argc, const ArgHandlerContainer &arg_h if( !strcmp( argv[0], handler.flag ) ) { argc--; argv++; + if( argc < handler.num_args ) { + printf( "Missing expected argument to command line parameter %s\n", + handler.flag ); + std::exit( 1 ); + } int args_consumed = handler.handler( argc, argv ); if( args_consumed < 0 ) { printf( "Failed parsing parameter '%s'\n", *( argv - 1 ) ); @@ -226,11 +232,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--seed", "", "Sets the random number generator's seed value", section_default, - [&result]( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + [&result]( int, const char **params ) -> int { const unsigned char *hash_input = reinterpret_cast( params[0] ); result.seed = djb2_hash( hash_input ); return 1; @@ -240,16 +243,18 @@ cli_opts parse_commandline( int argc, const char **argv ) "--jsonverify", nullptr, "Checks the CDDA json files", section_default, + 0, [&result]( int, const char ** ) -> int { result.verifyexit = true; return 0; } }, { - "--check-mods", "[modsā€¦]", - "Checks the json files belonging to CDDA mods", + "--check-mods", "[modā€¦]", + "Checks the json files belonging to given CDDA mod", section_default, - [&result]( int n, const char *params[] ) -> int { + 1, + [&result]( int n, const char **params ) -> int { result.check_mods = true; test_mode = true; for( int i = 0; i < n; ++i ) @@ -263,11 +268,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--dump-stats", " [mode = TSV] [optsā€¦]", "Dumps item stats", section_default, - [&result]( int n, const char *params[] ) -> int { - if( n < 1 ) - { - return -1; - } + 1, + [&result]( int n, const char **params ) -> int { test_mode = true; result.dump = params[ 0 ]; for( int i = 2; i < n; ++i ) @@ -293,11 +295,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--world", "", "Load world", section_default, - [&result]( int n, const char *params[] ) -> int { - if( n < 1 ) - { - return -1; - } + 1, + [&result]( int, const char **params ) -> int { result.world = params[0]; return 1; } @@ -306,11 +305,9 @@ cli_opts parse_commandline( int argc, const char **argv ) "--basepath", "", "Base path for all game data subdirectories", section_default, - []( int num_args, const char **params ) + 1, + []( int, const char **params ) { - if( num_args < 1 ) { - return -1; - } PATH_INFO::init_base_path( params[0] ); PATH_INFO::set_standard_filenames(); return 1; @@ -320,6 +317,7 @@ cli_opts parse_commandline( int argc, const char **argv ) "--shared", nullptr, "Activates the map-sharing mode", section_map_sharing, + 0, []( int, const char ** ) -> int { MAP_SHARING::setSharing( true ); MAP_SHARING::setCompetitive( true ); @@ -331,11 +329,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--username", "", "Instructs map-sharing code to use this name for your character.", section_map_sharing, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { MAP_SHARING::setUsername( params[0] ); return 1; } @@ -345,11 +340,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "Instructs map-sharing code to use this name for your character and give you " "access to the cheat functions.", section_map_sharing, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { MAP_SHARING::addAdmin( params[0] ); return 1; } @@ -358,11 +350,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--adddebugger", "", "Informs map-sharing code that you're running inside a debugger", section_map_sharing, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { MAP_SHARING::addDebugger( params[0] ); return 1; } @@ -371,6 +360,7 @@ cli_opts parse_commandline( int argc, const char **argv ) "--competitive", nullptr, "Instructs map-sharing code to disable access to the in-game cheat functions", section_map_sharing, + 0, []( int, const char ** ) -> int { MAP_SHARING::setCompetitive( true ); return 0; @@ -381,11 +371,8 @@ cli_opts parse_commandline( int argc, const char **argv ) // NOLINTNEXTLINE(cata-text-style): the dot is not a period "Base path for user-overrides to files from the ./data directory and named below", section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { PATH_INFO::init_user_dir( params[0] ); PATH_INFO::set_standard_filenames(); return 1; @@ -401,6 +388,7 @@ cli_opts parse_commandline( int argc, const char **argv ) "--worldmenu", nullptr, "Enables the world menu in the map-sharing code", section_map_sharing, + 0, []( int, const char ** ) -> int { MAP_SHARING::setWorldmenu( true ); return true; @@ -410,11 +398,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--datadir", "", "Sub directory from which game data is loaded", nullptr, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { PATH_INFO::set_datadir( params[0] ); return 1; } @@ -423,11 +408,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--savedir", "", "Subdirectory for game saves", section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { PATH_INFO::set_savedir( params[0] ); return 1; } @@ -436,11 +418,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--configdir", "", "Subdirectory for game configuration", section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { PATH_INFO::set_config_dir( params[0] ); return 1; } @@ -449,11 +428,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--memorialdir", "", "Subdirectory for memorials", section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { PATH_INFO::set_memorialdir( params[0] ); return 1; } @@ -462,11 +438,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--optionfile", "", "Name of the options file within the configdir", section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { PATH_INFO::set_options( params[0] ); return 1; } @@ -475,11 +448,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--keymapfile", "", "Name of the keymap file within the configdir", section_user_directory, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { PATH_INFO::set_keymap( params[0] ); return 1; } @@ -488,11 +458,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--autopickupfile", "", "Name of the autopickup options file within the configdir", nullptr, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { PATH_INFO::set_autopickup( params[0] ); return 1; } @@ -501,11 +468,8 @@ cli_opts parse_commandline( int argc, const char **argv ) "--motdfile", "", "Name of the message of the day file within the motd directory", nullptr, - []( int num_args, const char **params ) -> int { - if( num_args < 1 ) - { - return -1; - } + 1, + []( int, const char **params ) -> int { PATH_INFO::set_motd( params[0] ); return 1; } From c31fac2ea1eecbd76d6a106fe0e6d0cb251d0d87 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Tue, 14 Jul 2020 20:32:45 -0700 Subject: [PATCH 029/151] Update data/json/items/generic/dining_kitchen.json --- data/json/items/generic/dining_kitchen.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/items/generic/dining_kitchen.json b/data/json/items/generic/dining_kitchen.json index 7262ea9ac987c..e5d2670d88c77 100644 --- a/data/json/items/generic/dining_kitchen.json +++ b/data/json/items/generic/dining_kitchen.json @@ -650,7 +650,7 @@ "type": "GENERIC", "category": "other", "id": "can_opener", - "name": { "str": "can opener", "str_pl": "can openers" }, + "name": { "str": "can opener" }, "description": "It's not hard to open cans without this, but it's way messier.", "looks_like": "hand_crank_charger", "copy-from": "base_utensil" From 72b298bec15b833a378d12ec7d26ee812b5df49c Mon Sep 17 00:00:00 2001 From: i-am-erk <45136638+I-am-Erk@users.noreply.github.com> Date: Tue, 14 Jul 2020 21:08:35 -0700 Subject: [PATCH 030/151] Add looks_like to containers.json --- data/json/items/containers.json | 49 +++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/data/json/items/containers.json b/data/json/items/containers.json index 840185e6f264c..f591fcd4e6e52 100644 --- a/data/json/items/containers.json +++ b/data/json/items/containers.json @@ -4,6 +4,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "2.5L canteen" }, + "looks_like": "bottle_plastic", "description": "A large plastic water canteen, with a 2.5 liter capacity and carrying strap.", "weight": "155 g", "volume": "2625 ml", @@ -32,6 +33,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "30 gallon barrel" }, + "looks_like": "55gal_drum", "description": "A huge plastic barrel with a resealable lid.", "weight": "6800 g", "volume": "118125 ml", @@ -57,6 +59,7 @@ "id": "30gal_drum", "type": "GENERIC", "category": "container", + "looks_like": "30gal_barrel", "name": { "str": "steel drum (100L)", "str_pl": "steel drums (100L)" }, "description": "A huge steel barrel with a resealable lid.", "weight": "12000 g", @@ -83,6 +86,7 @@ "id": "55gal_drum", "type": "GENERIC", "category": "container", + "looks_like": "30gal_drum", "name": { "str": "steel drum (200L)", "str_pl": "steel drums (200L)" }, "description": "A massive steel barrel with a resealable lid.", "weight": "20000 g", @@ -110,6 +114,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "canvas sack" }, + "looks_like": "bag_plastic", "description": "A large and sturdy canvas sack. Smells faintly of earth and hard work.", "weight": "415 g", "volume": "1 L", @@ -126,6 +131,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "canvas bag" }, + "looks_like": "bag_canvas", "description": "Small bag made of canvas. Looks fine to store dried herbs in.", "weight": "5 g", "volume": "250 ml", @@ -142,6 +148,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "plastic bag" }, + "looks_like": "bag_canvas", "description": "A small, open plastic bag. Essentially trash.", "weight": "5 g", "volume": "10 ml", @@ -246,6 +253,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "glass bottle" }, + "looks_like": "bottle_plastic", "description": "A resealable glass bottle, holds 750 ml of liquid.", "weight": "200 g", "volume": "787 ml", @@ -302,6 +310,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "condiment bottle" }, + "looks_like": "bottle_plastic", "description": "An inverted plastic bottle for condiments. Still sealed from factory, preserves content from rot until opened.", "weight": "19 g", "volume": "525 ml", @@ -330,6 +339,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "condiment bottle" }, + "looks_like": "condiment_bottle_sealed", "description": "An inverted plastic bottle for condiments.", "weight": "19 g", "volume": "525 ml", @@ -357,6 +367,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "small plastic bottle" }, + "looks_like": "bottle_plastic", "description": "A resealable plastic bottle, holds 250 ml of liquid.", "weight": "7 g", "volume": "251 ml", @@ -383,6 +394,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "large plastic bottle" }, + "looks_like": "bottle_plastic", "description": "It's a two-liter plastic bottle that can hold a lot of soda, or, nowadays, boiled water.", "weight": "13 g", "volume": "2003 ml", @@ -408,6 +420,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "clay bowl" }, + "looks_like": "bowl_plastic", "description": "A clay bowl with a waterproofed hide lid. Can be used as a container or as a tool. Holds 250 ml of liquid.", "weight": "60 g", "volume": "255 ml", @@ -433,6 +446,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "pack" }, + "looks_like": "box_small", "description": "SURGEON GENERAL'S WARNING: Smoking Causes Lung Cancer, Heart Disease, Emphysema And May Complicate Pregnancy.", "weight": "15 g", "volume": "253 ml", @@ -464,6 +478,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "cardboard box", "str_pl": "cardboard boxes" }, + "looks_like": "box_small", "description": "A sturdy cardboard box, about the size of a banana box. Great for packing.", "weight": "850 g", "volume": "2100 ml", @@ -488,6 +503,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "large cardboard box", "str_pl": "large cardboard boxes" }, + "looks_like": "box_medium", "description": "A very large cardboard box, the sort children would have loved to hide in, when there were still children.", "weight": "1250 g", "volume": "3150 ml", @@ -538,6 +554,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "hydration pack" }, + "looks_like": "runner_bag", "description": "A slim and lightweight insulated plastic bladder worn on the back. It has a large pocket and a capped mouth for filling with liquid with a hose that allows the wearer to drink hands-free.", "weight": "286 g", "volume": "2503 ml", @@ -594,6 +611,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "paper carton" }, + "looks_like": "box_small", "description": "A half gallon carton constructed of a paper, aluminum, and plastic laminate. It has a threaded cap for easy resealing.", "weight": "28 g", "volume": "2003 ml", @@ -619,6 +637,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "vacuum-packed bag" }, + "looks_like": "bag_plastic", "description": "This is a bag of vacuum-packed food.", "weight": "2 g", "volume": "10 ml", @@ -642,6 +661,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "small tin can" }, + "looks_like": "can_drink", "description": "A small tin can, like what tuna comes in.", "//": "Represents a 4 cm radius x 5 cm height steel can.", "weight": "40 g", @@ -690,6 +710,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "plastic canteen" }, + "looks_like": "2lcanteen", "description": "A military-style water canteen with a 1.5 liter capacity. Commonly worn at the hip.", "weight": "155 g", "volume": "1503 ml", @@ -717,6 +738,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "thermos", "str_pl": "thermoses" }, + "looks_like": "bottle_plastic", "description": "A Thermos brand vacuum flask. Built for temperature retention, helps keep things hot or cold. Contains 1L of liquid.", "weight": "530 g", "price": 1595, @@ -741,6 +763,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "clay canister" }, + "looks_like": "bowl_clay", "description": "A fragile clay vessel. It can be used to make crude impact grenades or to store liquid.", "weight": "268 g", "volume": "253 ml", @@ -766,6 +789,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "clay hydria" }, + "looks_like": "bowl_clay", "description": "A 15-liter clay pot with three handles for carrying and for pouring.", "weight": "1955 g", "volume": "15003 ml", @@ -792,6 +816,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "large clay pot" }, + "looks_like": "bowl_clay", "description": "A bulky and heavy clay pot with a waterproofed hide lid, meant to store water, but can carry other liquids in a pinch.", "weight": "4887 g", "volume": "37500 ml", @@ -843,6 +868,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "glass flask" }, + "looks_like": "bottle_glass", "description": "A 250 ml laboratory conical flask, with a rubber bung.", "weight": "48 g", "volume": "251 ml", @@ -869,6 +895,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "test tube" }, + "looks_like": "flask_glass", "description": "A 10ml laboratory cylindrical test tube, with a rubber stopper.", "weight": "36 g", "volume": "11ml", @@ -895,6 +922,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "beaker" }, + "looks_like": "flask_glass", "description": "A 250ml laboratory beaker. Basically a cup with delusions of grandeur.", "weight": "150 g", "volume": "251ml", @@ -921,6 +949,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "graduated cylinder" }, + "looks_like": "flask_glass", "description": "A tall, narrow glass cylinder with precise markings for measuring fluid quantities. An important science tool, it is also useful for anal retentive chefs.", "weight": "150 g", "volume": "101ml", @@ -948,6 +977,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "microcentrifuge tube" }, + "looks_like": "test_tube", "description": "These plastic tubes, with little built in snap-caps, are a great way to store a tiny amount of liquid. Great for jello shooters if 1mL is enough for a shot for you. Cool people call these \"eppies\".", "weight": "1 g", "volume": "2ml", @@ -973,6 +1003,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "hip flask" }, + "looks_like": "2lcanteen", "description": "A 250 ml metal flask with a hinged screw-on lid, commonly used to discreetly transport alcohol.", "weight": "120 g", "volume": "251 ml", @@ -1002,6 +1033,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "3L glass jar" }, + "looks_like": "jar_glass", "description": "A three-liter glass jar with a metal screw top lid, used for canning.", "weight": "365 g", "volume": "3003 ml", @@ -1047,6 +1079,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "glass jar" }, + "looks_like": "jar_glass", "description": "A half-liter glass jar with a metal screw top lid, used for canning.", "weight": "150 g", "volume": "502 ml", @@ -1115,6 +1148,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "steel jerrycan" }, + "looks_like": "jerrycan", "description": "A steel jerrycan, meant to carry fuel, but can carry other liquids in a pinch.", "weight": "4815 g", "volume": "20002 ml", @@ -1142,6 +1176,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "clay jug" }, + "looks_like": "bowl_clay", "description": "A clay container with a lid, used to hold and pour liquids.", "weight": "400 g", "volume": "1002 ml", @@ -1167,6 +1202,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "gallon jug" }, + "looks_like": "bottle_plastic", "description": "A standard plastic jug used for milk and household cleaning chemicals.", "weight": "190 g", "volume": "3752 ml", @@ -1192,6 +1228,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "aluminum keg" }, + "looks_like": "30l_barrel", "description": "A reusable lightweight aluminum keg, used for shipping beer. It has a capacity of 50 liters.", "weight": "5040 g", "volume": "50050 ml", @@ -1219,6 +1256,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "steel keg" }, + "looks_like": "keg", "description": "A reusable heavy steel keg, used for shipping beer. It has a capacity of 50 liters.", "weight": "12600 g", "volume": "50050 ml", @@ -1270,6 +1308,7 @@ "id": "metal_tank", "type": "GENERIC", "category": "container", + "looks_like": "keg", "name": { "str": "metal tank (60L)", "str_pl": "metal tanks (60L)" }, "description": "A large metal tank for holding liquids. Useful for crafting.", "weight": "5668 g", @@ -1296,6 +1335,7 @@ "id": "metal_tank_little", "type": "GENERIC", "category": "container", + "looks_like": "keg", "name": { "str": "metal tank (2L)", "str_pl": "metal tanks (2L)" }, "description": "A small metal tank for gas or liquids. Useful for crafting.", "weight": "800 g", @@ -1323,6 +1363,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "wooden canteen" }, + "looks_like": "canteen", "description": "A water canteen made from wood, secured by metal bands and sealed with wax or pitch. Holds 1.5 liters and has a simple carry strap.", "weight": "232 g", "volume": "1750 ml", @@ -1375,6 +1416,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "small waterskin" }, + "looks_like": "canvas_bag", "description": "A small watertight leather bag with a carrying strap, can hold 1.5 liters of water.", "weight": "453 g", "volume": "250 ml", @@ -1402,6 +1444,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "waterskin" }, + "looks_like": "waterskin", "description": "A watertight leather bag with a carrying strap, can hold 3 liters of water.", "weight": "783 g", "volume": "500 ml", @@ -1429,6 +1472,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "large waterskin" }, + "looks_like": "waterskin2", "description": "A large watertight leather bag with a carrying strap, can hold 5 liters of water.", "weight": "990 g", "volume": "750 ml", @@ -1456,6 +1500,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "wooden barrel" }, + "looks_like": "30l_barrel", "description": "Traditionally made of white oak; these vessels are known for delivering delicious whiskey to the future. It has a capacity of 100 liters.", "weight": "42408 g", "volume": "101 L", @@ -1500,6 +1545,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "styrofoam cup" }, + "looks_like": "cup_plastic", "description": "A cheap, disposable cup with a plastic lid and straw.", "weight": "50 g", "volume": "501 ml", @@ -1573,6 +1619,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "large tin can" }, + "looks_like": "can_food", "description": "A large tin can, like what beans come in. Holds a substantial amount of food.", "weight": "350 g", "volume": "3003 ml", @@ -1597,6 +1644,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "survival kit box", "str_pl": "survival kit boxes" }, + "looks_like": "box_small", "description": "An aluminum box that used to contain a small survival kit. Can hold 1 liter of liquid.", "weight": "200 g", "volume": "1002 ml", @@ -1621,6 +1669,7 @@ "type": "GENERIC", "category": "container", "name": { "str": "small cardboard box of tea bags", "str_pl": "small cardboard boxes of tea bags" }, + "looks_like": "box_small", "description": "A very small cardboard box with tea brand written on it.", "weight": "10 g", "volume": "105 ml", From 8e60922d137d89fbcc745f3107500e3ac27131c9 Mon Sep 17 00:00:00 2001 From: meladath Date: Wed, 15 Jul 2020 05:16:56 +0100 Subject: [PATCH 031/151] Decouple encumbrance, max_encumbrance and coverage in armor on a per bodypart_id basis (#41522) --- data/json/items/armor/suits_protection.json | 5 +- data/mods/TEST_DATA/items.json | 84 +++++ src/armor_layers.cpp | 13 +- src/artifact.cpp | 33 +- src/bionics.cpp | 2 +- src/bodypart.cpp | 22 ++ src/bodypart.h | 11 + src/character.cpp | 54 +-- src/character.h | 2 +- src/clothing_mod.cpp | 2 +- src/dump.cpp | 9 +- src/enums.h | 5 + src/game.cpp | 2 +- src/game_inventory.cpp | 8 +- src/gamemode_tutorial.cpp | 2 +- src/handle_action.cpp | 7 +- src/item.cpp | 255 +++++++++++--- src/item.h | 32 +- src/item_factory.cpp | 183 +++++++++- src/itype.h | 45 +-- src/iuse_actor.cpp | 8 +- src/map_field.cpp | 2 +- src/mondefense.cpp | 5 +- src/player.cpp | 2 +- src/suffer.cpp | 2 +- tests/item_tname_test.cpp | 2 +- tests/iteminfo_test.cpp | 370 +++++++++++++++++++- tests/itemname_test.cpp | 6 +- 28 files changed, 980 insertions(+), 193 deletions(-) diff --git a/data/json/items/armor/suits_protection.json b/data/json/items/armor/suits_protection.json index 4d3b7eaacc234..bbdb71035f115 100644 --- a/data/json/items/armor/suits_protection.json +++ b/data/json/items/armor/suits_protection.json @@ -851,10 +851,7 @@ "symbol": "[", "looks_like": "touring_suit", "color": "dark_gray", - "covers": [ "LEGS", "TORSO", "ARMS" ], - "coverage": 95, - "encumbrance": 12, - "max_encumbrance": 25, + "armor_portion_data": [ { "covers": [ "torso", "LEGS", "ARMS" ], "coverage": 95, "encumbrance": [ 12, 25 ] } ], "pocket_data": [ { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, diff --git a/data/mods/TEST_DATA/items.json b/data/mods/TEST_DATA/items.json index 334b13bbe79a7..7e90ae2473225 100644 --- a/data/mods/TEST_DATA/items.json +++ b/data/mods/TEST_DATA/items.json @@ -1219,5 +1219,89 @@ "price": 0, "price_postapoc": 0, "fun": -20 + }, + { + "id": "test_swat_armor", + "repairs_like": "survivor_suit", + "type": "ARMOR", + "category": "armor", + "name": { "str": "SWAT armor" }, + "//": "This is well within the pricing structure I found for ballistic vest, shins, and LBE. LEO gear ain't cheap.", + "description": "A suit of black bulletproof armor with lots of pockets. The word SWAT is emblazoned across the back.", + "weight": "7800 g", + "volume": "13 L", + "price": 285000, + "price_postapoc": 2000, + "to_hit": -3, + "bashing": 6, + "material": [ "kevlar_layered", "cotton" ], + "symbol": "[", + "looks_like": "touring_suit", + "color": "dark_gray", + "armor_portion_data": [ { "covers": [ "torso", "LEGS", "ARMS" ], "coverage": 95, "encumbrance": [ 12, 25 ] } ], + "pocket_data": [ + { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, + { "pocket_type": "CONTAINER", "max_contains_volume": "1 L", "max_contains_weight": "3 kg", "moves": 80 }, + { "pocket_type": "CONTAINER", "max_contains_volume": "1500 ml", "max_contains_weight": "3 kg", "moves": 120 }, + { "pocket_type": "CONTAINER", "max_contains_volume": "1500 ml", "max_contains_weight": "3 kg", "moves": 120 } + ], + "warmth": 35, + "material_thickness": 11, + "valid_mods": [ "steel_padded" ], + "environmental_protection": 4, + "flags": [ "POCKETS", "STURDY" ] + }, + { + "id": "test_pants_fur", + "type": "ARMOR", + "name": { "str_sp": "fur pants" }, + "description": "A hefty pair of fur-lined pants.", + "weight": "920 g", + "volume": "4 L", + "price": 20000, + "price_postapoc": 100, + "to_hit": 1, + "material": [ "cotton", "fur" ], + "symbol": "[", + "looks_like": "pants", + "color": "brown", + "covers": [ "LEGS" ], + "coverage": 95, + "encumbrance": 16, + "max_encumbrance": 20, + "pocket_data": [ + { "pocket_type": "CONTAINER", "max_contains_volume": "350 ml", "max_contains_weight": "1 kg", "moves": 80 }, + { "pocket_type": "CONTAINER", "max_contains_volume": "350 ml", "max_contains_weight": "1 kg", "moves": 80 }, + { "pocket_type": "CONTAINER", "max_contains_volume": "250 ml", "max_contains_weight": "1 kg", "moves": 100 }, + { "pocket_type": "CONTAINER", "max_contains_volume": "250 ml", "max_contains_weight": "1 kg", "moves": 100 } + ], + "warmth": 80, + "material_thickness": 3, + "valid_mods": [ "steel_padded" ], + "environmental_protection": 3, + "flags": [ "VARSIZE", "POCKETS" ] + }, + { + "id": "test_pants_faux_fur", + "type": "ARMOR", + "copy-from": "test_pants_fur", + "name": { "str_sp": "faux fur pants" }, + "description": "A pair of long cotton pants lined with warm imitation fur.", + "material": [ "faux_fur", "cotton" ], + "covers": [ "LEGS" ], + "warmth": 70 + }, + { + "id": "test_portion_faux_fur_pants_suit", + "type": "ARMOR", + "copy-from": "test_pants_fur", + "name": { "str_sp": "faux fur pants suit test thing" }, + "description": "A TEST OBJECT SHOULD NOT BE IN GAME", + "material": [ "faux_fur", "cotton" ], + "armor_portion_data": [ + { "covers": [ "torso", "leg_r", "arm_r" ], "coverage": 100, "encumbrance": [ 10, 25 ] }, + { "covers": [ "arm_l", "leg_l", "head" ], "coverage": 50, "encumbrance": 5 } + ], + "warmth": 5 } ] diff --git a/src/armor_layers.cpp b/src/armor_layers.cpp index 8f8d539ce76b2..69494835eacaf 100644 --- a/src/armor_layers.cpp +++ b/src/armor_layers.cpp @@ -48,7 +48,7 @@ namespace { std::string clothing_layer( const item &worn_item ); std::vector clothing_properties( - const item &worn_item, int width, const Character & ); + const item &worn_item, int width, const Character &, const bodypart_id &bp ); std::vector clothing_protection( const item &worn_item, int width ); std::vector clothing_flags_description( const item &worn_item ); @@ -169,7 +169,8 @@ void draw_mid_pane( const catacurses::window &w_sort_middle, // NOLINTNEXTLINE(cata-use-named-point-constants) size_t i = fold_and_print( w_sort_middle, point( 1, 0 ), win_width - 1, c_white, worn_item_it->type_name( 1 ) ) - 1; - std::vector props = clothing_properties( *worn_item_it, win_width - 3, c ); + std::vector props = clothing_properties( *worn_item_it, win_width - 3, c, + bodypart_id( tabindex ) ); nc_color color = c_light_gray; for( std::string &iter : props ) { print_colored_text( w_sort_middle, point( 2, ++i ), color, c_light_gray, iter ); @@ -289,7 +290,7 @@ std::string clothing_layer( const item &worn_item ) } std::vector clothing_properties( - const item &worn_item, const int width, const Character &c ) + const item &worn_item, const int width, const Character &c, const bodypart_id &bp ) { std::vector props; props.reserve( 5 ); @@ -297,9 +298,9 @@ std::vector clothing_properties( const std::string space = " "; props.push_back( string_format( "[%s]", _( "Properties" ) ) ); props.push_back( name_and_value( space + _( "Coverage:" ), - string_format( "%3d", worn_item.get_coverage() ), width ) ); + string_format( "%3d", worn_item.get_coverage( bp ) ), width ) ); props.push_back( name_and_value( space + _( "Encumbrance:" ), - string_format( "%3d", worn_item.get_encumber( c ) ), + string_format( "%3d", worn_item.get_encumber( c, bp ) ), width ) ); props.push_back( name_and_value( space + _( "Warmth:" ), string_format( "%3d", worn_item.get_warmth() ), width ) ); @@ -398,7 +399,7 @@ static std::vector items_cover_bp( const Character &c, int b for( auto elem_it = c.worn.begin(); elem_it != c.worn.end(); ++elem_it ) { if( elem_it->covers( convert_bp( static_cast( bp ) ).id() ) ) { s.push_back( { get_item_penalties( elem_it, c, bp ), - elem_it->get_encumber( c ), + elem_it->get_encumber( c, convert_bp( static_cast( bp ) ).id() ), elem_it->tname() } ); } diff --git a/src/artifact.cpp b/src/artifact.cpp index 351490a4eda79..9746a4f6cff6d 100644 --- a/src/artifact.cpp +++ b/src/artifact.cpp @@ -833,10 +833,7 @@ itype_id new_artifact() def.melee[DT_BASH] = info.melee_bash; def.melee[DT_CUT] = info.melee_cut; def.m_to_hit = info.melee_hit; - def.armor->covers = info.covers; - def.armor->encumber = info.encumb; - def.armor->max_encumber = info.max_encumb; - def.armor->coverage = info.coverage; + def.armor->data.push_back( { info.encumb, info.max_encumb, info.coverage, info.covers } ); def.armor->thickness = info.thickness; def.armor->env_resist = info.env_resist; def.armor->warmth = info.warmth; @@ -861,13 +858,7 @@ itype_id new_artifact() def.weight = 1_gram; } - def.armor->encumber += modinfo.encumb; - - if( modinfo.coverage > 0 || def.armor->coverage > std::abs( modinfo.coverage ) ) { - def.armor->coverage += modinfo.coverage; - } else { - def.armor->coverage = 0; - } + def.armor->data.push_back( { modinfo.encumb, modinfo.max_encumb, modinfo.coverage, modinfo.covers } ); if( modinfo.thickness > 0 || def.armor->thickness > std::abs( modinfo.thickness ) ) { def.armor->thickness += modinfo.thickness; @@ -1278,11 +1269,12 @@ void it_artifact_armor::deserialize( const JsonObject &jo ) m_to_hit = jo.get_int( "m_to_hit" ); item_tags = jo.get_tags( "item_flags" ); - jo.read( "covers", armor->covers ); - armor->encumber = jo.get_int( "encumber" ); // Old saves don't have max_encumber, so set it to base encumbrance value - armor->max_encumber = jo.get_int( "max_encumber", armor->encumber ); - armor->coverage = jo.get_int( "coverage" ); + armor->data.push_back( { jo.get_int( "encumber" ), jo.get_int( "max_encumber", jo.get_int( "encumber" ) ), jo.get_int( "coverage" ), {} } ); + + // A horrible solution to the required change here, but it works for now + jo.read( "covers", armor->data[0].covers ); + armor->thickness = jo.get_int( "material_thickness" ); armor->env_resist = jo.get_int( "env_resist" ); armor->warmth = jo.get_int( "warmth" ); @@ -1417,10 +1409,13 @@ void it_artifact_armor::serialize( JsonOut &json ) const json.member( "techniques", techniques ); // armor data - json.member( "covers", armor->covers ); - json.member( "encumber", armor->encumber ); - json.member( "max_encumber", armor->max_encumber ); - json.member( "coverage", armor->coverage ); + armor_portion_data tempData; + json.member( "encumber", tempData.encumber ); + json.member( "max_encumber", tempData.max_encumber ); + json.member( "coverage", tempData.coverage ); + json.member( "covers", tempData.covers ); + armor->data.push_back( tempData ); + json.member( "material_thickness", armor->thickness ); json.member( "env_resist", armor->env_resist ); json.member( "warmth", armor->warmth ); diff --git a/src/bionics.cpp b/src/bionics.cpp index 342a50ea14a33..3737a80ea7810 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -1585,7 +1585,7 @@ float Character::get_effective_efficiency( int b, float fuel_efficiency ) if( i.covers( elem.first ) && !i.has_flag( flag_ALLOWS_NATURAL_ATTACKS ) && !i.has_flag( flag_SEMITANGIBLE ) && !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) ) { - coverage += i.get_coverage(); + coverage += i.get_coverage( elem.first.id() ); } } } diff --git a/src/bodypart.cpp b/src/bodypart.cpp index 15f4f7c20e49c..a14ea79334a33 100644 --- a/src/bodypart.cpp +++ b/src/bodypart.cpp @@ -61,6 +61,28 @@ generic_factory body_part_factory( "body part" ); } // namespace +bool is_legacy_bodypart_id( const std::string &id ) +{ + static const std::vector legacy_body_parts = { + "TORSO", + "HEAD", + "EYES", + "MOUTH", + "ARM_L", + "ARM_R", + "HAND_L", + "HAND_R", + "LEG_L", + "LEG_R", + "FOOT_L", + "FOOT_R", + "NUM_BP", + }; + + return std::find( legacy_body_parts.begin(), legacy_body_parts.end(), + id ) != legacy_body_parts.end(); +} + static body_part legacy_id_to_enum( const std::string &legacy_id ) { static const std::unordered_map body_parts = { diff --git a/src/bodypart.h b/src/bodypart.h index 14e8a5bd61f65..d0dff3c1f6f35 100644 --- a/src/bodypart.h +++ b/src/bodypart.h @@ -283,6 +283,14 @@ class body_part_set return parts.size(); } + cata::flat_set::iterator begin() const { + return parts.begin(); + } + + cata::flat_set::iterator end() const { + return parts.end(); + } + template void serialize( Stream &s ) const { s.write( parts ); @@ -293,6 +301,9 @@ class body_part_set } }; +// Returns if passed string is legacy bodypart (i.e "TORSO", not "torso") +bool is_legacy_bodypart_id( const std::string &id ); + /** Returns the new id for old token */ const bodypart_str_id &convert_bp( body_part bp ); diff --git a/src/character.cpp b/src/character.cpp index b8d2ffc15d019..07eb2fe34728a 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -3250,7 +3250,7 @@ ret_val Character::can_wear( const item &it, bool with_equip_change ) cons if( it.covers( bodypart_id( "head" ) ) && !it.has_flag( flag_SEMITANGIBLE ) && ( it.has_flag( flag_SKINTIGHT ) || it.has_flag( flag_HELMET_COMPAT ) ) && - ( head_cloth_encumbrance() + it.get_encumber( *this ) > 40 ) ) { + ( head_cloth_encumbrance() + it.get_encumber( *this, bodypart_id( "head" ) ) > 40 ) ) { return ret_val::make_failure( ( is_player() ? _( "You can't wear that much on your head!" ) : string_format( _( "%s can't wear that much on their head!" ), name ) ) ); } @@ -3786,29 +3786,29 @@ bool Character::change_side( item_location &loc, bool interactive ) static void layer_item( std::map &vals, const item &it, std::map &highest_layer_so_far, bool power_armor, const Character &c ) { - const layer_level item_layer = it.get_layer(); - int encumber_val = it.get_encumber( c ); - // For the purposes of layering penalty, set a min of 2 and a max of 10 per item. - int layering_encumbrance = std::min( 10, std::max( 2, encumber_val ) ); - - /* - * Setting layering_encumbrance to 0 at this point makes the item cease to exist - * for the purposes of the layer penalty system. (normally an item has a minimum - * layering_encumbrance of 2 ) - */ - if( it.has_flag( "SEMITANGIBLE" ) ) { - encumber_val = 0; - layering_encumbrance = 0; - } - - const int armorenc = !power_armor || !it.is_power_armor() ? - encumber_val : std::max( 0, encumber_val - 40 ); - body_part_set covered_parts = it.get_covered_body_parts(); for( const bodypart_id &bp : c.get_all_body_parts() ) { if( !covered_parts.test( bp.id() ) ) { continue; } + + const auto item_layer = it.get_layer(); + int encumber_val = it.get_encumber( c, bp.id() ); + int layering_encumbrance = clamp( encumber_val, 2, 10 ); + + /* + * Setting layering_encumbrance to 0 at this point makes the item cease to exist + * for the purposes of the layer penalty system. (normally an item has a minimum + * layering_encumbrance of 2 ) + */ + if( it.has_flag( "SEMITANGIBLE" ) ) { + encumber_val = 0; + layering_encumbrance = 0; + } + + const int armorenc = !power_armor || !it.is_power_armor() ? + encumber_val : std::max( 0, encumber_val - 40 ); + highest_layer_so_far[bp] = std::max( highest_layer_so_far[bp], item_layer ); // Apply layering penalty to this layer, as well as any layer worn @@ -3926,7 +3926,7 @@ int Character::get_wind_resistance( const bodypart_id &bp ) const penalty = 1; // 99% effective } - coverage = std::max( 0, i.get_coverage() - penalty ); + coverage = std::max( 0, i.get_coverage( bp ) - penalty ); totalExposed *= ( 1.0 - coverage / 100.0 ); // Coverage is between 0 and 1? } } @@ -6725,7 +6725,7 @@ float Character::active_light() const if( i.covers( elem.first.id() ) && !i.has_flag( flag_ALLOWS_NATURAL_ATTACKS ) && !i.has_flag( flag_SEMITANGIBLE ) && !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) ) { - coverage += i.get_coverage(); + coverage += i.get_coverage( elem.first.id() ); } } curr_lum += elem.second * ( 1 - ( coverage / 100.0f ) ); @@ -8010,7 +8010,7 @@ int Character::item_wear_cost( const item &it ) const break; } - mv *= std::max( it.get_encumber( *this ) / 10.0, 1.0 ); + mv *= std::max( it.get_avg_encumber( *this ) / 10.0, 1.0 ); return mv; } @@ -8582,7 +8582,7 @@ void Character::absorb_hit( const bodypart_id &bp, damage_instance &dam ) } if( !destroy ) { - destroy = armor_absorb( elem, armor ); + destroy = armor_absorb( elem, armor, bp ); } if( destroy ) { @@ -8628,9 +8628,9 @@ void Character::absorb_hit( const bodypart_id &bp, damage_instance &dam ) } } -bool Character::armor_absorb( damage_unit &du, item &armor ) +bool Character::armor_absorb( damage_unit &du, item &armor, const bodypart_id &bp ) { - if( rng( 1, 100 ) > armor.get_coverage() ) { + if( rng( 1, 100 ) > armor.get_coverage( bp ) ) { return false; } @@ -8913,7 +8913,7 @@ dealt_damage_instance Character::deal_damage( Creature *source, bodypart_id bp, int sum_cover = 0; for( const item &i : worn ) { if( i.covers( bp ) && i.is_filthy() ) { - sum_cover += i.get_coverage(); + sum_cover += i.get_coverage( bp ); } } @@ -9246,7 +9246,7 @@ int Character::head_cloth_encumbrance() const const item *worn_item = &i; if( i.covers( bodypart_id( "head" ) ) && !i.has_flag( flag_SEMITANGIBLE ) && ( worn_item->has_flag( flag_HELMET_COMPAT ) || worn_item->has_flag( flag_SKINTIGHT ) ) ) { - ret += worn_item->get_encumber( *this ); + ret += worn_item->get_encumber( *this, bodypart_id( "head" ) ); } } return ret; diff --git a/src/character.h b/src/character.h index 7925167545bb2..c83a3e9a0b915 100644 --- a/src/character.h +++ b/src/character.h @@ -762,7 +762,7 @@ class Character : public Creature, public visitable * Reduces and mutates du, prints messages about armor taking damage. * @return true if the armor was completely destroyed (and the item must be deleted). */ - bool armor_absorb( damage_unit &du, item &armor ); + bool armor_absorb( damage_unit &du, item &armor, const bodypart_id &bp ); /** * Check for passive bionics that provide armor, and returns the armor bonus * This is called from player::passive_absorb_hit diff --git a/src/clothing_mod.cpp b/src/clothing_mod.cpp index 98a57dba61f29..c4b06b23977a3 100644 --- a/src/clothing_mod.cpp +++ b/src/clothing_mod.cpp @@ -94,7 +94,7 @@ void clothing_mod::load( const JsonObject &jo, const std::string & ) float clothing_mod::get_mod_val( const clothing_mod_type &type, const item &it ) const { const int thickness = it.get_thickness(); - const int coverage = it.get_coverage(); + const int coverage = it.get_avg_coverage(); float result = 0.0f; for( const mod_value &mv : mod_values ) { if( mv.type == type ) { diff --git a/src/dump.cpp b/src/dump.cpp index 97c55317fe7e3..24f3baaaf5cb0 100644 --- a/src/dump.cpp +++ b/src/dump.cpp @@ -106,13 +106,14 @@ bool game::dump_stats( const std::string &what, dump_mode mode, header = { "Name", "Encumber (fit)", "Warmth", "Weight", "Coverage", "Bash", "Cut", "Bullet", "Acid", "Fire" }; - auto dump = [&rows]( const item & obj ) { + body_part bp = opts.empty() ? num_bp : get_body_part_token( opts.front() ); + auto dump = [&rows, &bp]( const item & obj ) { std::vector r; r.push_back( obj.tname( 1, false ) ); - r.push_back( to_string( obj.get_encumber( get_player_character() ) ) ); + r.push_back( to_string( obj.get_encumber( get_player_character(), convert_bp( bp ).id() ) ) ); r.push_back( to_string( obj.get_warmth() ) ); r.push_back( to_string( to_gram( obj.weight() ) ) ); - r.push_back( to_string( obj.get_coverage() ) ); + r.push_back( to_string( obj.get_coverage( convert_bp( bp ).id() ) ) ); r.push_back( to_string( obj.bash_resist() ) ); r.push_back( to_string( obj.cut_resist() ) ); r.push_back( to_string( obj.bullet_resist() ) ); @@ -121,8 +122,6 @@ bool game::dump_stats( const std::string &what, dump_mode mode, rows.push_back( r ); }; - body_part bp = opts.empty() ? num_bp : get_body_part_token( opts.front() ); - for( const itype *e : item_controller->all() ) { if( e->armor ) { item obj( e ); diff --git a/src/enums.h b/src/enums.h index 2d050befa1919..d4fb6f1e12bcf 100644 --- a/src/enums.h +++ b/src/enums.h @@ -271,6 +271,11 @@ enum class layer_level : int { NUM_LAYER_LEVELS }; +template<> +struct enum_traits { + static constexpr layer_level last = layer_level::NUM_LAYER_LEVELS; +}; + inline layer_level &operator++( layer_level &l ) { l = static_cast( static_cast( l ) + 1 ); diff --git a/src/game.cpp b/src/game.cpp index 21b8ed31c44d2..034c5d53c7457 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -12052,7 +12052,7 @@ bool check_art_charge_req( item &it ) bp == bodypart_id( "hand_l" ) ) ) ) { reqsmet = true; for( const item &i : p.worn ) { - if( i.covers( bp ) && ( &it != &i ) && i.get_coverage() > 50 ) { + if( i.covers( bp ) && ( &it != &i ) && i.get_coverage( bp ) > 50 ) { reqsmet = false; break; //This one's no good, check the next body part } diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index cbd0adc129b3c..49828e2564b33 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -292,12 +292,12 @@ class armor_inventory_preset: public inventory_selector_preset armor_inventory_preset( player &pl, const std::string &color_in ) : p( pl ), color( color_in ) { append_cell( [ this ]( const item_location & loc ) { - return get_number_string( loc->get_encumber( p ) ); - }, _( "ENCUMBRANCE" ) ); + return get_number_string( loc->get_avg_encumber( p ) ); + }, _( "AVG ENCUMBRANCE" ) ); append_cell( [ this ]( const item_location & loc ) { - return string_format( "<%s>%d%%", color, loc->get_coverage() ); - }, _( "COVERAGE" ) ); + return string_format( "<%s>%d%%", color, loc->get_avg_coverage() ); + }, _( "AVG COVERAGE" ) ); append_cell( [ this ]( const item_location & loc ) { return get_number_string( loc->get_warmth() ); diff --git a/src/gamemode_tutorial.cpp b/src/gamemode_tutorial.cpp index 20ee208fdd855..4c77de9204ff5 100644 --- a/src/gamemode_tutorial.cpp +++ b/src/gamemode_tutorial.cpp @@ -277,7 +277,7 @@ void tutorial_game::post_action( action_id act ) case ACTION_WEAR: { item it( g->u.last_item, 0 ); if( it.is_armor() ) { - if( it.get_coverage() >= 2 || it.get_thickness() >= 2 ) { + if( it.get_avg_coverage() >= 2 || it.get_thickness() >= 2 ) { add_message( tut_lesson::LESSON_WORE_ARMOR ); } if( it.get_env_resist() >= 2 ) { diff --git a/src/handle_action.cpp b/src/handle_action.cpp index d896ee2d6917b..86fd2a33b210c 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -784,10 +784,9 @@ static void smash() int glove_coverage = 0; for( const item &i : u.worn ) { if( ( i.covers( bodypart_id( "hand_l" ) ) || i.covers( bodypart_id( "hand_r" ) ) ) ) { - int temp_coverage = i.get_coverage(); - if( glove_coverage < temp_coverage ) { - glove_coverage = temp_coverage; - } + int l_coverage = i.get_coverage( bodypart_id( "hand_l" ) ); + int r_coverage = i.get_coverage( bodypart_id( "hand_r" ) ); + glove_coverage = std::max( l_coverage, r_coverage ); } } diff --git a/src/item.cpp b/src/item.cpp index b2dfec884c567..06b6e01341f61 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -784,8 +784,12 @@ body_part_set item::get_covered_body_parts( const side s ) const if( armor == nullptr ) { return res; } + for( const armor_portion_data &data : armor->data ) { + if( data.covers.has_value() ) { + res.unify_set( data.covers.value() ); + } + } - res.unify_set( armor->covers ); if( !armor->sided ) { return res; // Just ignore the side. @@ -1256,9 +1260,21 @@ static std::string get_freshness_description( const item &food_item ) } } -item::sizing item::get_sizing( const Character &p, bool wearable ) const +item::sizing item::get_sizing( const Character &p ) const { - if( wearable ) { + const islot_armor *armor_data = find_armor_data(); + if( !armor_data ) { + return sizing::ignore; + } + bool to_ignore = true; + for( const armor_portion_data &piece : armor_data->data ) { + if( piece.encumber != 0 ) { + to_ignore = false; + } + } + if( to_ignore ) { + return sizing::ignore; + } else { const bool small = p.has_trait( trait_SMALL2 ) || p.has_trait( trait_SMALL_OK ); @@ -1298,8 +1314,6 @@ item::sizing item::get_sizing( const Character &p, bool wearable ) const } } } - return sizing::not_wearable; - } static int get_base_env_resist( const item &it ) @@ -2541,8 +2555,6 @@ void item::armor_info( std::vector &info, const iteminfo_query *parts, } Character &player_character = get_player_character(); - int encumbrance = get_encumber( player_character ); - const sizing sizing_level = get_sizing( player_character, encumbrance != 0 ); const std::string space = " "; body_part_set covered_parts = get_covered_body_parts(); bool covers_anything = covered_parts.any(); @@ -2615,25 +2627,25 @@ void item::armor_info( std::vector &info, const iteminfo_query *parts, if( has_flag( flag_PERSONAL ) ) { layering += _( "Personal aura. " ); } else if( has_flag( flag_SKINTIGHT ) ) { - layering += _( "Close to skin. " ); + layering += _( "Close to skin. " ); } else if( has_flag( flag_BELTED ) ) { - layering += _( "Strapped. " ); + layering += _( "Strapped. " ); } else if( has_flag( flag_OUTER ) ) { - layering += _( "Outer. " ); + layering += _( "Outer. " ); } else if( has_flag( flag_WAIST ) ) { - layering += _( "Waist. " ); + layering += _( "Waist. " ); } else if( has_flag( flag_AURA ) ) { - layering += _( "Outer aura. " ); + layering += _( "Outer aura. " ); } else { - layering += _( "Normal. " ); + layering += _( "Normal. " ); } info.push_back( iteminfo( "ARMOR", layering ) ); } if( parts->test( iteminfo_parts::ARMOR_COVERAGE ) && covers_anything ) { - info.push_back( iteminfo( "ARMOR", _( "Coverage: " ), "%", - iteminfo::no_newline, get_coverage() ) ); + info.push_back( iteminfo( "ARMOR", _( "Average Coverage: " ), "%", + iteminfo::no_newline, get_avg_coverage() ) ); } if( parts->test( iteminfo_parts::ARMOR_WARMTH ) && covers_anything ) { info.push_back( iteminfo( "ARMOR", space + _( "Warmth: " ), get_warmth() ) ); @@ -2643,35 +2655,99 @@ void item::armor_info( std::vector &info, const iteminfo_query *parts, if( parts->test( iteminfo_parts::ARMOR_ENCUMBRANCE ) && covers_anything ) { std::string format; + const bool sizing_matters = get_sizing( player_character ) != sizing::ignore; if( has_flag( flag_FIT ) ) { - format = _( " (fits)" ); - } else if( has_flag( flag_VARSIZE ) && encumbrance ) { - format = _( " (poor fit)" ); + format = _( " (fits)" ); + } else if( has_flag( flag_VARSIZE ) && sizing_matters ) { + format = _( " (poor fit)" ); } - - //If we have the wrong size, we do not fit so alert the player - if( sizing_level == sizing::human_sized_small_char ) { - format = _( " (too big)" ); - } else if( sizing_level == sizing::big_sized_small_char ) { - format = _( " (huge!)" ); - } else if( sizing_level == sizing::small_sized_human_char || - sizing_level == sizing::human_sized_big_char ) { - format = _( " (too small)" ); - } else if( sizing_level == sizing::small_sized_big_char ) { - format = _( " (tiny!)" ); + if( sizing_matters ) { + const sizing sizing_level = get_sizing( player_character ); + //If we have the wrong size, we do not fit so alert the player + if( sizing_level == sizing::human_sized_small_char ) { + format = _( " (too big)" ); + } else if( sizing_level == sizing::big_sized_small_char ) { + format = _( " (huge!)" ); + } else if( sizing_level == sizing::small_sized_human_char || + sizing_level == sizing::human_sized_big_char ) { + format = _( " (too small)" ); + } else if( sizing_level == sizing::small_sized_big_char ) { + format = _( " (tiny!)" ); + } } - info.push_back( iteminfo( "ARMOR", _( "Encumbrance: " ), format, - iteminfo::no_newline | iteminfo::lower_is_better, - encumbrance ) ); + info.push_back( iteminfo( "ARMOR", _( "Encumbrance:" ) + format ) ); if( const islot_armor *t = find_armor_data() ) { - if( t->max_encumber != t->encumber ) { - const int encumbrance_when_full = - get_encumber( player_character, encumber_flags::assume_full ); - info.push_back( iteminfo( "ARMOR", space + _( "Encumbrance when full: " ), "", - iteminfo::no_newline | iteminfo::lower_is_better, - encumbrance_when_full ) ); + if( !t->data.empty() ) { + struct armor_portion_type { + int encumber; + int max_encumber; + int coverage; + + bool operator==( const armor_portion_type &other ) { + return encumber == other.encumber + && max_encumber == other.max_encumber + && coverage == other.coverage; + }; + }; + struct body_part_display_info { + translation to_display; + armor_portion_type portion; + bool active; + }; + + std::map to_display_data; + + for( const armor_portion_data &piece : t->data ) { + if( piece.covers.has_value() ) { + for( const bodypart_str_id &covering_id : piece.covers.value() ) { + if( covering_id != bodypart_str_id( "num_bp" ) ) { + to_display_data[covering_id] = { covering_id.obj().name_as_heading, { + get_encumber( player_character, covering_id ), + get_encumber( player_character, covering_id, encumber_flags::assume_full ), + piece.coverage + }, true + }; + } + } + } + } + // Handle things that use both sides to avoid showing L. Arm R. Arm etc when both are the same + if( !t->sided ) { + for( const body_part &legacy_part : all_body_parts ) { + bodypart_str_id bp( convert_bp( legacy_part ) ); + bodypart_str_id opposite = bp->opposite_part; + if( opposite != bp && covers( bp ) && covers( opposite ) + && to_display_data.at( bp ).portion == to_display_data.at( opposite ).portion + && to_display_data.at( opposite ).active ) { + to_display_data.at( opposite ).to_display = bp->name_as_heading_multiple; + to_display_data.at( bp ).active = false; + } + } + } + for( auto &piece : to_display_data ) { + if( t->sided ) { + const bodypart_str_id &covering_id = piece.first; + if( !covers( covering_id.id() ) ) { + continue; + } + } + if( piece.second.active ) { + info.push_back( iteminfo( "ARMOR", + string_format( _( "%s:" ), piece.second.to_display.translated() ) + space, "", + iteminfo::no_newline | iteminfo::lower_is_better, + piece.second.portion.encumber ) ); + + info.push_back( iteminfo( "ARMOR", space + _( "When Full:" ) + space, "", + iteminfo::no_newline | iteminfo::lower_is_better, + piece.second.portion.max_encumber ) ); + + info.push_back( iteminfo( "ARMOR", space + _( "Coverage:" ) + space, "", + iteminfo::lower_is_better, + piece.second.portion.coverage ) ); + } + } } } } @@ -2726,8 +2802,7 @@ void item::armor_fit_info( std::vector &info, const iteminfo_query *pa } Character &player_character = get_player_character(); - int encumbrance = get_encumber( player_character ); - const sizing sizing_level = get_sizing( player_character, encumbrance != 0 ); + const sizing sizing_level = get_sizing( player_character ); if( has_flag( flag_HELMET_COMPAT ) && parts->test( iteminfo_parts::DESCRIPTION_FLAGS_HELMETCOMPAT ) ) { @@ -3613,7 +3688,11 @@ void item::final_info( std::vector &info, const iteminfo_query *parts, if( parts->test( iteminfo_parts::BASE_RIGIDITY ) ) { if( const islot_armor *t = find_armor_data() ) { - if( t->max_encumber != t->encumber ) { + bool any_encumb_increase = std::any_of( t->data.begin(), t->data.end(), + []( armor_portion_data data ) { + return data.encumber != data.max_encumber; + } ); + if( any_encumb_increase ) { info.emplace_back( "BASE", _( "* This item is not rigid. Its" " volume and encumbrance increase with contents." ) ); @@ -4525,7 +4604,7 @@ std::string item::tname( unsigned int quantity, bool with_prefix, unsigned int t } } - const sizing sizing_level = get_sizing( player_character, get_encumber( player_character ) != 0 ); + const sizing sizing_level = get_sizing( player_character ); if( sizing_level == sizing::human_sized_small_char ) { tagtext += _( " (too big)" ); @@ -5589,14 +5668,46 @@ bool item::is_power_armor() const return t->power_armor; } -int item::get_encumber( const Character &p, encumber_flags flags ) const +int item::get_avg_encumber( const Character &p, encumber_flags flags ) const { const islot_armor *t = find_armor_data(); - if( t == nullptr ) { + if( !t ) { + // handle wearable guns (e.g. shoulder strap) as special case + return is_gun() ? volume() / 750_ml : 0; + } + + int avg_encumber = 0; + int avg_ctr = 0; + + for( const armor_portion_data &entry : t->data ) { + if( entry.covers.has_value() ) { + for( const bodypart_str_id &limb : entry.covers.value() ) { + int encumber = get_encumber( p, bodypart_id( limb ), flags ); + if( encumber ) { + avg_encumber += encumber; + ++avg_ctr; + } + } + } + } + if( avg_encumber == 0 ) { + return 0; + } else { + avg_encumber /= avg_ctr; + return avg_encumber; + } +} + +int item::get_encumber( const Character &p, const bodypart_id &bodypart, + encumber_flags flags ) const +{ + const islot_armor *t = find_armor_data(); + if( !t ) { // handle wearable guns (e.g. shoulder strap) as special case return is_gun() ? volume() / 750_ml : 0; } - int encumber = t->encumber; + + int encumber = 0; // Additional encumbrance from non-rigid pockets float relative_encumbrance = 1; @@ -5604,7 +5715,11 @@ int item::get_encumber( const Character &p, encumber_flags flags ) const relative_encumbrance = contents.relative_encumbrance(); } - encumber += std::ceil( relative_encumbrance * ( t->max_encumber - t->encumber ) ); + if( cata::optional portion_data = portion_for_bodypart( bodypart ) ) { + encumber = portion_data->encumber; + encumber += std::ceil( relative_encumbrance * ( portion_data->max_encumber - + portion_data->encumber ) ); + } // Fit checked before changes, fitting shouldn't reduce penalties from patching. if( has_flag( flag_FIT ) && has_flag( flag_VARSIZE ) ) { @@ -5612,7 +5727,7 @@ int item::get_encumber( const Character &p, encumber_flags flags ) const } // TODO: Should probably have sizing affect coverage - const sizing sizing_level = get_sizing( p, encumber != 0 ); + const sizing sizing_level = get_sizing( p ); switch( sizing_level ) { case sizing::small_sized_human_char: case sizing::small_sized_big_char: @@ -5658,13 +5773,53 @@ layer_level item::get_layer() const } } -int item::get_coverage() const +int item::get_avg_coverage() const { const islot_armor *t = find_armor_data(); - if( t == nullptr ) { + if( !t ) { + return 0; + } + int avg_coverage = 0; + int avg_ctr = 0; + for( const armor_portion_data &entry : t->data ) { + if( entry.covers.has_value() ) { + for( const bodypart_str_id &limb : entry.covers.value() ) { + int coverage = get_coverage( limb ); + if( coverage ) { + avg_coverage += coverage; + ++avg_ctr; + } + } + } + } + if( avg_coverage == 0 ) { return 0; + } else { + avg_coverage /= avg_ctr; + return avg_coverage; + } +} + +int item::get_coverage( const bodypart_id &bodypart ) const +{ + if( cata::optional portion_data = portion_for_bodypart( bodypart ) ) { + return portion_data->coverage; + } + return 0; +} + +cata::optional item::portion_for_bodypart( const bodypart_id &bodypart ) const +{ + const islot_armor *t = find_armor_data(); + if( !t ) { + return cata::optional(); + } + for( const armor_portion_data &entry : t->data ) { + if( entry.covers.has_value() && entry.covers->test( bodypart.id() ) ) { + return entry; + } } - return t->coverage; + return cata::optional(); } int item::get_thickness() const diff --git a/src/item.h b/src/item.h index bed8e0a9b7dc6..770c159c87939 100644 --- a/src/item.h +++ b/src/item.h @@ -47,6 +47,7 @@ class nc_color; class player; class recipe; class relic; +struct armor_portion_data; struct islot_comestible; struct itype; struct mtype; @@ -1581,24 +1582,39 @@ class item : public visitable * Returns clothing layer for item. */ layer_level get_layer() const; + + /* + * Returns the average coverage of each piece of data this item + */ + int get_avg_coverage() const; /** - * Returns the relative coverage that this item has when worn. - * Values range from 0 (not covering anything, or no armor at all) to - * 100 (covering the whole body part). Items that cover more are more likely to absorb - * damage from attacks. + * Returns the highest coverage that any piece of data that this item has that covers the bodypart. + * Values range from 0 (not covering anything) to 100 (covering the whole body part). + * Items that cover more are more likely to absorb damage from attacks. */ - int get_coverage() const; + int get_coverage( const bodypart_id &bodypart ) const; enum class encumber_flags : int { none = 0, assume_full = 1, }; + + cata::optional portion_for_bodypart( const bodypart_id &bodypart ) const; + + /** + * Returns the average encumbrance value that this item across all portions + * Returns 0 if this is can not be worn at all. + */ + int get_avg_encumber( const Character &, encumber_flags = encumber_flags::none ) const; + /** * Returns the encumbrance value that this item has when worn by given * player. * Returns 0 if this is can not be worn at all. */ - int get_encumber( const Character &, encumber_flags = encumber_flags::none ) const; + int get_encumber( const Character &, const bodypart_id &bodypart, + encumber_flags = encumber_flags::none ) const; + /** * Returns the weight capacity modifier (@ref islot_armor::weight_capacity_modifier) that this item provides when worn. * For non-armor it returns 1. The modifier is multiplied with the weight capacity of the character that wears the item. @@ -2162,10 +2178,10 @@ class item : public visitable small_sized_small_char, human_sized_small_char, big_sized_small_char, - not_wearable + ignore }; - sizing get_sizing( const Character &, bool ) const; + sizing get_sizing( const Character & ) const; protected: // Sub-functions of @ref process, they handle the processing for different diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 9a828c1caa1e7..efd7653583191 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -117,8 +117,14 @@ static bool assign_coverage_from_json( const JsonObject &jo, const std::string & parts.set( bodypart_str_id( "foot_l" ) ); parts.set( bodypart_str_id( "foot_r" ) ); } else { - parts.set( convert_bp( get_body_part_token( val ) ) ); + // Convert from legacy enum to new and apply coverage + if( !is_legacy_bodypart_id( val ) ) { + parts.set( bodypart_str_id( val ) ); + } else { + parts.set( convert_bp( get_body_part_token( val ) ) ); + } } + sided |= val == "ARM_EITHER" || val == "HAND_EITHER" || val == "LEG_EITHER" || val == "FOOT_EITHER"; }; @@ -517,14 +523,16 @@ void Item_factory::finalize_post( itype &obj ) if( obj.armor ) { // Setting max_encumber must be in finalize_post because it relies on // stack_size being set for all ammo, which happens in finalize_pre. - if( obj.armor->max_encumber < 0 ) { - units::volume total_nonrigid_volume = 0_ml; - for( const pocket_data &pocket : obj.pockets ) { - if( !pocket.rigid ) { - total_nonrigid_volume += pocket.max_contains_volume(); + for( armor_portion_data &data : obj.armor->data ) { + if( data.max_encumber == -1 ) { + units::volume total_nonrigid_volume = 0_ml; + for( const pocket_data &pocket : obj.pockets ) { + if( !pocket.rigid ) { + total_nonrigid_volume += pocket.max_contains_volume(); + } } + data.max_encumber = data.encumber + total_nonrigid_volume / 250_ml; } - obj.armor->max_encumber = obj.armor->encumber + total_nonrigid_volume / 250_ml; } } @@ -1092,6 +1100,22 @@ void Item_factory::check_definitions() const msg += "undefined category " + type->category_force.str() + "\n"; } + if( type->armor ) { + cata::flat_set observed_bps; + for( const armor_portion_data &portion : type->armor->data ) { + if( portion.covers.has_value() ) { + for( const body_part &bp : all_body_parts ) { + if( portion.covers->test( convert_bp( bp ) ) ) { + if( observed_bps.count( convert_bp( bp ) ) ) { + msg += "multiple portions with same body_part defined\n"; + } + observed_bps.insert( convert_bp( bp ) ); + } + } + } + } + } + if( type->weight < 0_gram ) { msg += "negative weight\n"; } @@ -1790,13 +1814,147 @@ void Item_factory::load_pet_armor( const JsonObject &jo, const std::string &src } } +namespace io +{ +template<> +std::string enum_to_string( layer_level data ) +{ + switch( data ) { + case layer_level::PERSONAL: + return "Personal"; + case layer_level::UNDERWEAR: + return "Underwear"; + case layer_level::REGULAR: + return "Regular"; + case layer_level::WAIST: + return "Waist"; + case layer_level::OUTER: + return "Outer"; + case layer_level::BELTED: + return "Belted"; + case layer_level::AURA: + return "Aura"; + case layer_level::NUM_LAYER_LEVELS: + break; + } + debugmsg( "Invalid layer_level" ); + abort(); +} +} // namespace io + void islot_armor::load( const JsonObject &jo ) { - optional( jo, was_loaded, "encumbrance", encumber, 0 ); - // Default max_encumbrance will be set to a reasonable value in - // finalize_post - optional( jo, was_loaded, "max_encumbrance", max_encumber, -1 ); - optional( jo, was_loaded, "coverage", coverage, 0 ); + if( jo.has_array( "armor_portion_data" ) ) { + bool dont_add_first = false; + if( !data.empty() ) { // Uses copy-from + dont_add_first = true; + const JsonObject &obj = *jo.get_array( "armor_portion_data" ).begin(); + armor_portion_data tempData; + + if( obj.has_array( "encumbrance" ) ) { + tempData.encumber = obj.get_array( "encumbrance" ).get_int( 0 ); + tempData.max_encumber = obj.get_array( "encumbrance" ).get_int( 1 ); + } else if( obj.has_int( "encumbrance" ) ) { + tempData.encumber = obj.get_int( "encumbrance" ); + tempData.max_encumber = -1; + } + if( obj.has_int( "coverage" ) ) { + tempData.coverage = obj.get_int( "coverage" ); + } + if( tempData.encumber != data[0].encumber ) { + data[0].encumber = tempData.encumber; + } + if( tempData.max_encumber != data[0].max_encumber ) { + data[0].max_encumber = tempData.max_encumber; + } + if( tempData.coverage != data[0].coverage ) { + data[0].coverage = tempData.coverage; + } + body_part_set temp_cover_data; + assign_coverage_from_json( obj, "covers", temp_cover_data, sided ); + if( temp_cover_data.any() ) { + data[0].covers = temp_cover_data; + } + } + + for( const JsonObject &obj : jo.get_array( "armor_portion_data" ) ) { + // If this item used copy-from, data[0] is already set, so skip adding first data + if( dont_add_first ) { + obj.allow_omitted_members(); + dont_add_first = false; + continue; + } + armor_portion_data tempData; + body_part_set temp_cover_data; + assign_coverage_from_json( obj, "covers", temp_cover_data, sided ); + tempData.covers = temp_cover_data; + + if( obj.has_array( "encumbrance" ) ) { + tempData.encumber = obj.get_array( "encumbrance" ).get_int( 0 ); + tempData.max_encumber = obj.get_array( "encumbrance" ).get_int( 1 ); + } else if( obj.has_int( "encumbrance" ) ) { + tempData.encumber = obj.get_int( "encumbrance" ); + tempData.max_encumber = -1; + } + if( obj.has_int( "coverage" ) ) { + tempData.coverage = obj.get_int( "coverage" ); + } + data.push_back( tempData ); + + // TODO: Not currently supported, we still use flags for this + //if( obj.has_string( "layer" ) ) { + // for( auto &piece : data ) { + // layer_level layer; + // obj.read( "layer", layer ); + // } + //} else { + // for( armor_portion_data &piece : data ) { + // piece.layer = layer_level::REGULAR; + // } + //} + } + } else { + if( data.empty() ) { // Loading item does not have copy-from + data.emplace_back(); + optional( jo, was_loaded, "encumbrance", data[0].encumber, 0 ); + // Default max_encumbrance will be set to a reasonable value in finalize_post + optional( jo, was_loaded, "max_encumbrance", data[0].max_encumber, -1 ); + optional( jo, was_loaded, "coverage", data[0].coverage, 0 ); + body_part_set temp_cover_data; + assign_coverage_from_json( jo, "covers", temp_cover_data, sided ); + data[0].covers = temp_cover_data; + } else { // This item has copy-from and already has taken data from parent + armor_portion_data child_data; + if( jo.has_int( "encumbrance" ) ) { + child_data.encumber = jo.get_int( "encumbrance" ); + child_data.max_encumber = -1; + } + if( jo.has_int( "max_encumbrance" ) ) { + child_data.max_encumber = jo.get_int( "max_encumbrance" ); + } else { + child_data.max_encumber = -1; + } + if( jo.has_int( "coverage" ) ) { + child_data.coverage = jo.get_int( "coverage" ); + } + // If child item contains data, use that data, otherwise use parents data + if( child_data.encumber != data[0].encumber && child_data.encumber != 0 ) { + data[0].encumber = child_data.encumber; + } + if( child_data.max_encumber != data[0].max_encumber && child_data.max_encumber != -1 ) { + data[0].max_encumber = child_data.max_encumber; + } + if( child_data.coverage != data[0].coverage && child_data.coverage != 0 ) { + data[0].coverage = child_data.coverage; + } + body_part_set temp_cover_data; + assign_coverage_from_json( jo, "covers", temp_cover_data, sided ); + if( temp_cover_data.any() ) { + data[0].covers = temp_cover_data; + } + } + } + optional( jo, was_loaded, "material_thickness", thickness, 0 ); optional( jo, was_loaded, "environmental_protection", env_resist, 0 ); optional( jo, was_loaded, "environmental_protection_with_filter", env_resist_w_filter, 0 ); @@ -1806,7 +1964,6 @@ void islot_armor::load( const JsonObject &jo ) optional( jo, was_loaded, "weight_capacity_bonus", weight_capacity_bonus, mass_reader{}, 0_gram ); optional( jo, was_loaded, "power_armor", power_armor, false ); optional( jo, was_loaded, "valid_mods", valid_mods ); - assign_coverage_from_json( jo, "covers", covers, sided ); } void islot_armor::deserialize( JsonIn &jsin ) diff --git a/src/itype.h b/src/itype.h index bfa90e749ecf4..2437ac581e3cc 100644 --- a/src/itype.h +++ b/src/itype.h @@ -208,29 +208,31 @@ struct islot_brewable { void deserialize( JsonIn &jsin ); }; -struct islot_armor { - /** - * Bitfield of enum body_part - * TODO: document me. - */ - body_part_set covers; - /** - * Whether this item can be worn on either side of the body - */ - bool sided = false; - /** - * How much this item encumbers the player. - */ +struct armor_portion_data { + + // How much this piece encumbers the player. int encumber = 0; - /** - * When storage is full, how much it encumbers the player. - */ + + // When storage is full, how much it encumbers the player. int max_encumber = 0; - /** - * Percentage of the body part area that this item covers. - * This determines how likely it is to hit the item instead of the player. - */ + + // Percentage of the body part that this item covers. + // This determines how likely it is to hit the item instead of the player. int coverage = 0; + + // Where does this cover if any + cata::optional covers; + + // What layer does it cover if any + // TODO: Not currently supported, we still use flags for this + //cata::optional layer; +}; + +struct islot_armor { + /** + * Whether this item can be worn on either side of the body + */ + bool sided = false; /** * TODO: document me. */ @@ -265,6 +267,9 @@ struct islot_armor { */ std::vector valid_mods; + // Layer, encumbrance and coverage information. + std::vector data; + bool was_loaded = false; void load( const JsonObject &jo ); diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 2b47fa8490fc0..dd654742b8839 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -2765,7 +2765,7 @@ bool repair_item_actor::can_repair_target( player &pl, const item &fix, return true; } - const bool resizing_matters = fix.get_encumber( pl ) != 0; + const bool resizing_matters = fix.get_sizing( pl ) != item::sizing::ignore; const bool small = pl.has_trait( trait_SMALL2 ) || pl.has_trait( trait_SMALL_OK ); const bool can_resize = small != fix.has_flag( "UNDERSIZE" ); if( can_be_refitted && resizing_matters && can_resize ) { @@ -2861,7 +2861,7 @@ repair_item_actor::repair_type repair_item_actor::default_action( const item &fi const bool is_undersized = fix.has_flag( flag_UNDERSIZE ); const bool is_oversized = fix.has_flag( flag_OVERSIZE ); - const bool resizing_matters = fix.get_encumber( player_character ) != 0; + const bool resizing_matters = fix.get_sizing( player_character ) != item::sizing::ignore; const bool too_big_while_smol = smol && !is_undersized && !is_oversized; if( too_big_while_smol && can_be_refitted && resizing_matters ) { @@ -4336,8 +4336,8 @@ int sew_advanced_actor::use( player &p, item &it, bool, const tripoint & ) const desc += format_desc_string( _( "Acid" ), mod.acid_resist(), temp_item.acid_resist(), true ); desc += format_desc_string( _( "Fire" ), mod.fire_resist(), temp_item.fire_resist(), true ); desc += format_desc_string( _( "Warmth" ), mod.get_warmth(), temp_item.get_warmth(), true ); - desc += format_desc_string( _( "Encumbrance" ), mod.get_encumber( p ), temp_item.get_encumber( p ), - false ); + desc += format_desc_string( _( "Encumbrance" ), mod.get_avg_encumber( p ), + temp_item.get_avg_encumber( p ), false ); tmenu.addentry_desc( index++, enab, MENU_AUTOASSIGN, prompt, desc ); } diff --git a/src/map_field.cpp b/src/map_field.cpp index a5e8bb76bd856..ca8733c4f4b00 100644 --- a/src/map_field.cpp +++ b/src/map_field.cpp @@ -1631,7 +1631,7 @@ void map::player_in_field( player &u ) int sum_cover = 0; for( const item &i : u.worn ) { if( i.covers( bp ) ) { - sum_cover += i.get_coverage(); + sum_cover += i.get_coverage( bp ); } } // Get stung if [clothing on a body part isn't thick enough (like t-shirt) OR clothing covers less than 100% of body part] diff --git a/src/mondefense.cpp b/src/mondefense.cpp index e8797d9f9a5b0..f0f3186e6401e 100644 --- a/src/mondefense.cpp +++ b/src/mondefense.cpp @@ -56,8 +56,9 @@ void mdefense::zapback( monster &m, Creature *const source, if( const player *const foe = dynamic_cast( source ) ) { // Players/NPCs can avoid the shock if they wear non-conductive gear on their hands for( const item &i : foe->worn ) { - if( ( i.covers( bodypart_id( "hand_l" ) ) || i.covers( bodypart_id( "hand_r" ) ) ) && - !i.conductive() && i.get_coverage() >= 95 ) { + if( !i.conductive() + && ( ( i.get_coverage( bodypart_id( "hand_l" ) ) >= 95 ) || + i.get_coverage( bodypart_id( "hand_r" ) ) >= 95 ) ) { return; } } diff --git a/src/player.cpp b/src/player.cpp index 546bb28fd57a3..2f66c4c93454b 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1084,7 +1084,7 @@ bool player::immune_to( const bodypart_id &bp, damage_unit dam ) const passive_absorb_hit( bp, dam ); for( const item &cloth : worn ) { - if( cloth.get_coverage() == 100 && cloth.covers( bp ) ) { + if( cloth.get_coverage( bp ) == 100 && cloth.covers( bp ) ) { cloth.mitigate_damage( dam ); } } diff --git a/src/suffer.cpp b/src/suffer.cpp index caefaa6939202..e55970da33e56 100644 --- a/src/suffer.cpp +++ b/src/suffer.cpp @@ -831,7 +831,7 @@ void Character::suffer_from_albinism() continue; } //percent of "not covered skin" - float p = 1.0 - i.get_coverage() / 100.0; + float p = 1.0 - i.get_coverage( bp ) / 100.0; open_percent[bp->token] = open_percent[bp->token] * p; } } diff --git a/tests/item_tname_test.cpp b/tests/item_tname_test.cpp index f97b39c9e68ef..f3d13560e9c28 100644 --- a/tests/item_tname_test.cpp +++ b/tests/item_tname_test.cpp @@ -386,7 +386,7 @@ TEST_CASE( "weapon fouling", "[item][tname][fouling][dirt]" ) // Ensure the player and gun are normal size to prevent "too big" or "too small" suffix in tname g->u.clear_mutations(); - REQUIRE( gun.get_sizing( g-> u, true ) == item::sizing::human_sized_human_char ); + REQUIRE( gun.get_sizing( g-> u ) == item::sizing::ignore ); REQUIRE_FALSE( gun.has_flag( "OVERSIZE" ) ); REQUIRE_FALSE( gun.has_flag( "UNDERSIZE" ) ); diff --git a/tests/iteminfo_test.cpp b/tests/iteminfo_test.cpp index cd4fe8bc327fa..013a4cfb0777f 100644 --- a/tests/iteminfo_test.cpp +++ b/tests/iteminfo_test.cpp @@ -359,6 +359,7 @@ TEST_CASE( "item price and barter value", "[iteminfo][price]" ) // "encumbrance" // "max_encumbrance" // "pocket_data" +// "coverage" // - "rigid" // - "max_contains_volume" // @@ -377,7 +378,19 @@ TEST_CASE( "item rigidity", "[iteminfo][rigidity]" ) REQUIRE( briefcase.contents.all_pockets_rigid() ); CHECK( item_info_str( briefcase, encumbrance ) == "--\n" - "Encumbrance: 30\n" ); + "Encumbrance:\n" + "L. Arm: 30 " + "When Full: 30 " + "Coverage: 10\n" + "R. Arm: 30 " + "When Full: 30 " + "Coverage: 10\n" + "L. Hand: 30 " + "When Full: 30 " + "Coverage: 10\n" + "R. Hand: 30 " + "When Full: 30 " + "Coverage: 10\n" ); } SECTION( "non-rigid items indicate their flexible volume/encumbrance" ) { @@ -412,20 +425,32 @@ TEST_CASE( "item rigidity", "[iteminfo][rigidity]" ) // based on the pocket "max_contains_volume" (1 encumbrance per 250 ml). CHECK( item_info_str( waterskin, encumbrance ) == "--\n" - "Encumbrance: 0" - " Encumbrance when full: 6\n" ); + "Encumbrance:\n" + "L. Leg: 0 " + "When Full: 6 " + "Coverage: 5\n" + "R. Leg: 0 " + "When Full: 6 " + "Coverage: 5\n" ); // test_backpack has an explicit "encumbrance" and "max_encumbrance" CHECK( item_info_str( backpack, encumbrance ) == "--\n" - "Encumbrance: 2" - " Encumbrance when full: 15\n" ); + "Encumbrance:\n" + "Torso: 2 " + "When Full: 15 " + "Coverage: 30\n" ); // quiver has no volume, only an implicit volume via ammo CHECK( item_info_str( quiver, encumbrance ) == "--\n" - "Encumbrance: 3" - " Encumbrance when full: 11\n" ); + "Encumbrance:\n" + "L. Leg: 3 " + "When Full: 11 " + "Coverage: 10\n" + "R. Leg: 3 " + "When Full: 11 " + "Coverage: 10\n" ); } } } @@ -626,6 +651,17 @@ TEST_CASE( "armor coverage, warmth, and encumbrance", "[iteminfo][armor][coverag // Long-sleeved shirt covering torso and arms item longshirt( "test_longshirt" ); REQUIRE( longshirt.get_covered_body_parts().any() ); + REQUIRE( longshirt.get_coverage( bodypart_id( "torso" ) ) == 90 ); + REQUIRE( longshirt.get_coverage( bodypart_id( "arm_l" ) ) == 90 ); + REQUIRE( longshirt.get_coverage( bodypart_id( "arm_r" ) ) == 90 ); + REQUIRE( longshirt.get_coverage( bodypart_id( "leg_l" ) ) == 0 ); + REQUIRE( longshirt.get_coverage( bodypart_id( "leg_r" ) ) == 0 ); + REQUIRE( longshirt.get_coverage( bodypart_id( "hand_l" ) ) == 0 ); + REQUIRE( longshirt.get_coverage( bodypart_id( "hand_r" ) ) == 0 ); + REQUIRE( longshirt.get_coverage( bodypart_id( "head" ) ) == 0 ); + REQUIRE( longshirt.get_coverage( bodypart_id( "mouth" ) ) == 0 ); + REQUIRE( longshirt.get_coverage( bodypart_id( "foot_l" ) ) == 0 ); + REQUIRE( longshirt.get_coverage( bodypart_id( "foot_r" ) ) == 0 ); CHECK( item_info_str( longshirt, { iteminfo_parts::ARMOR_BODYPARTS } ) == "--\n" @@ -638,20 +674,324 @@ TEST_CASE( "armor coverage, warmth, and encumbrance", "[iteminfo][armor][coverag "Layer: Normal. \n" ); // NOLINT(cata-text-style) // Coverage and warmth are displayed together on a single line - std::vector cov_warm = { iteminfo_parts::ARMOR_COVERAGE, iteminfo_parts::ARMOR_WARMTH }; - REQUIRE( longshirt.get_coverage() == 90 ); + std::vector cov_warm_shirt = { iteminfo_parts::ARMOR_COVERAGE, iteminfo_parts::ARMOR_WARMTH }; + REQUIRE( longshirt.get_avg_coverage() == 90 ); REQUIRE( longshirt.get_warmth() == 5 ); - CHECK( item_info_str( longshirt, cov_warm ) + CHECK( item_info_str( longshirt, cov_warm_shirt ) == "--\n" - "Coverage: 90% Warmth: 5\n" ); + "Average Coverage: 90% Warmth: 5\n" ); + + REQUIRE( longshirt.get_avg_encumber( get_player_character() ) == 3 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "torso" ) ) == 3 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "arm_l" ) ) == 3 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "arm_r" ) ) == 3 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "leg_l" ) ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "leg_r" ) ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "hand_l" ) ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "hand_r" ) ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "head" ) ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "mouth" ) ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "foot_l" ) ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "foot_r" ) ) == 0 ); + + REQUIRE( longshirt.get_avg_encumber( get_player_character(), + item::encumber_flags::assume_full ) == 3 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "torso" ), + item::encumber_flags::assume_full ) == 3 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "arm_l" ), + item::encumber_flags::assume_full ) == 3 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "arm_r" ), + item::encumber_flags::assume_full ) == 3 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "leg_l" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "leg_r" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "hand_l" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "hand_r" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "head" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "mouth" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "foot_l" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( longshirt.get_encumber( get_player_character(), bodypart_id( "foot_r" ), + item::encumber_flags::assume_full ) == 0 ); + - REQUIRE( longshirt.get_encumber( get_player_character() ) == 3 ); CHECK( item_info_str( longshirt, { iteminfo_parts::ARMOR_ENCUMBRANCE } ) == "--\n" - "Encumbrance:" - " 3" - " (poor fit)\n" ); + "Encumbrance: (poor fit)\n" + "Arms: 3 " + "When Full: 3 " + "Coverage: 90\n" + "Torso: 3 " + "When Full: 3 " + "Coverage: 90\n" ); + + item swat_armor( "test_swat_armor" ); + REQUIRE( swat_armor.get_covered_body_parts().any() ); + + CHECK( item_info_str( swat_armor, { iteminfo_parts::ARMOR_BODYPARTS } ) == + "--\n" + "Covers:" + " The torso." + " The arms." + " The legs. \n" ); + + CHECK( item_info_str( swat_armor, { iteminfo_parts::ARMOR_LAYER } ) == + "--\n" + "Layer: Normal. \n" ); + + std::vector cov_warm_swat = { iteminfo_parts::ARMOR_COVERAGE, iteminfo_parts::ARMOR_WARMTH }; + REQUIRE( swat_armor.get_avg_coverage() == 95 ); + REQUIRE( swat_armor.get_warmth() == 35 ); + CHECK( item_info_str( swat_armor, cov_warm_swat ) + == + "--\n" + "Average Coverage: 95% Warmth: 35\n" ); + + REQUIRE( swat_armor.get_coverage( bodypart_id( "torso" ) ) == 95 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "leg_l" ) ) == 95 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "leg_r" ) ) == 95 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "arm_l" ) ) == 95 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "arm_r" ) ) == 95 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "head" ) ) == 0 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "foot_l" ) ) == 0 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "foot_r" ) ) == 0 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "eyes" ) ) == 0 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "mouth" ) ) == 0 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "hand_r" ) ) == 0 ); + REQUIRE( swat_armor.get_coverage( bodypart_id( "hand_l" ) ) == 0 ); + + REQUIRE( swat_armor.get_avg_encumber( get_player_character() ) == 12 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "torso" ) ) == 12 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "leg_l" ) ) == 12 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "leg_r" ) ) == 12 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "arm_l" ) ) == 12 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "arm_r" ) ) == 12 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "head" ) ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "foot_l" ) ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "foot_r" ) ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "eyes" ) ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "mouth" ) ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "hand_l" ) ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "hand_r" ) ) == 0 ); + + + REQUIRE( swat_armor.get_avg_encumber( get_player_character(), + item::encumber_flags::assume_full ) == 25 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "torso" ), + item::encumber_flags::assume_full ) == 25 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "leg_l" ), + item::encumber_flags::assume_full ) == 25 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "leg_r" ), + item::encumber_flags::assume_full ) == 25 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "arm_l" ), + item::encumber_flags::assume_full ) == 25 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "arm_r" ), + item::encumber_flags::assume_full ) == 25 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "foot_l" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "foot_r" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "head" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "eyes" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "mouth" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "hand_l" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( swat_armor.get_encumber( get_player_character(), bodypart_id( "hand_r" ), + item::encumber_flags::assume_full ) == 0 ); + + CHECK( item_info_str( swat_armor, { iteminfo_parts::ARMOR_ENCUMBRANCE } ) == + "--\n" + "Encumbrance:\n" + "Arms: 12 " + "When Full: 25 " + "Coverage: 95\n" + "Legs: 12 " + "When Full: 25 " + "Coverage: 95\n" + "Torso: 12 " + "When Full: 25 " + "Coverage: 95\n" ); + + // Test copy-from + item faux_fur_pants( "test_pants_faux_fur" ); + REQUIRE( faux_fur_pants.get_covered_body_parts().any() ); + + CHECK( item_info_str( faux_fur_pants, { iteminfo_parts::ARMOR_BODYPARTS } ) == + "--\n" + "Covers:" + " The legs. \n" ); + + CHECK( item_info_str( faux_fur_pants, { iteminfo_parts::ARMOR_LAYER } ) == + "--\n" + "Layer: Normal. \n" ); + + std::vector cov_warm_pants = { iteminfo_parts::ARMOR_COVERAGE, iteminfo_parts::ARMOR_WARMTH }; + REQUIRE( faux_fur_pants.get_avg_coverage() == 95 ); + REQUIRE( faux_fur_pants.get_warmth() == 70 ); + CHECK( item_info_str( faux_fur_pants, cov_warm_pants ) + == + "--\n" + "Average Coverage: 95% Warmth: 70\n" ); + + REQUIRE( faux_fur_pants.get_avg_coverage() == 95 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "leg_l" ) ) == 95 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "leg_r" ) ) == 95 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "arm_l" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "arm_r" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "foot_r" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "foot_l" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "head" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "eyes" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "mouth" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "hand_l" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_coverage( bodypart_id( "hand_r" ) ) == 0 ); + + REQUIRE( faux_fur_pants.get_avg_encumber( get_player_character() ) == 16 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "leg_l" ) ) == 16 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "leg_r" ) ) == 16 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "arm_l" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "arm_r" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "foot_r" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "foot_l" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "head" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "eyes" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "mouth" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "hand_l" ) ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "hand_r" ) ) == 0 ); + + REQUIRE( faux_fur_pants.get_avg_encumber( get_player_character(), + item::encumber_flags::assume_full ) == 20 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "leg_l" ), + item::encumber_flags::assume_full ) == 20 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "leg_r" ), + item::encumber_flags::assume_full ) == 20 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "arm_l" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "arm_r" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "foot_r" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "foot_l" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "head" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "eyes" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "mouth" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "hand_l" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_pants.get_encumber( get_player_character(), bodypart_id( "hand_r" ), + item::encumber_flags::assume_full ) == 0 ); + + item faux_fur_suit( "test_portion_faux_fur_pants_suit" ); + REQUIRE( faux_fur_suit.get_covered_body_parts().any() ); + + CHECK( item_info_str( faux_fur_suit, { iteminfo_parts::ARMOR_BODYPARTS } ) == + "--\n" + "Covers:" + " The head." + " The torso." + " The arms." + " The legs. \n" ); + + CHECK( item_info_str( faux_fur_suit, { iteminfo_parts::ARMOR_LAYER } ) == + "--\n" + "Layer: Normal. \n" ); + + std::vector cov_warm_suit = { iteminfo_parts::ARMOR_COVERAGE, iteminfo_parts::ARMOR_WARMTH }; + REQUIRE( faux_fur_suit.get_avg_coverage() == 75 ); + REQUIRE( faux_fur_suit.get_warmth() == 5 ); + CHECK( item_info_str( faux_fur_suit, cov_warm_suit ) + == + "--\n" + "Average Coverage: 75% Warmth: 5\n" ); + + REQUIRE( faux_fur_suit.get_avg_coverage() == 75 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "torso" ) ) == 100 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "leg_l" ) ) == 50 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "leg_r" ) ) == 100 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "arm_l" ) ) == 50 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "arm_r" ) ) == 100 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "head" ) ) == 50 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "eyes" ) ) == 0 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "mouth" ) ) == 0 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "hand_l" ) ) == 0 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "hand_r" ) ) == 0 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "foot_l" ) ) == 0 ); + REQUIRE( faux_fur_suit.get_coverage( bodypart_id( "foot_r" ) ) == 0 ); + + REQUIRE( faux_fur_suit.get_avg_encumber( get_player_character() ) == 7 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "torso" ) ) == 10 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "leg_l" ) ) == 5 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "leg_r" ) ) == 10 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "arm_l" ) ) == 5 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "arm_r" ) ) == 10 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "head" ) ) == 5 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "eyes" ) ) == 0 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "mouth" ) ) == 0 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "foot_l" ) ) == 0 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "foot_r" ) ) == 0 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "hand_r" ) ) == 0 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "hand_r" ) ) == 0 ); + + REQUIRE( faux_fur_suit.get_avg_encumber( get_player_character(), + item::encumber_flags::assume_full ) == 17 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "torso" ), + item::encumber_flags::assume_full ) == 25 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "leg_l" ), + item::encumber_flags::assume_full ) == 9 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "leg_r" ), + item::encumber_flags::assume_full ) == 25 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "arm_l" ), + item::encumber_flags::assume_full ) == 9 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "arm_r" ), + item::encumber_flags::assume_full ) == 25 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "head" ), + item::encumber_flags::assume_full ) == 9 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "eyes" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "mouth" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "hand_l" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "hand_r" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "foot_l" ), + item::encumber_flags::assume_full ) == 0 ); + REQUIRE( faux_fur_suit.get_encumber( get_player_character(), bodypart_id( "foot_r" ), + item::encumber_flags::assume_full ) == 0 ); + + CHECK( item_info_str( faux_fur_suit, { iteminfo_parts::ARMOR_ENCUMBRANCE } ) == + "--\n" + "Encumbrance: (poor fit)\n" + "L. Arm: 5 " + "When Full: 9 " + "Coverage: 50\n" + "R. Arm: 10 " + "When Full: 25 " + "Coverage: 100\n" + "Head: 5 " + "When Full: 9 " + "Coverage: 50\n" + "L. Leg: 5 " + "When Full: 9 " + "Coverage: 50\n" + "R. Leg: 10 " + "When Full: 25 " + "Coverage: 100\n" + "Torso: 10 " + "When Full: 25 " + "Coverage: 100\n" ); } SECTION( "armor with no coverage omits irrelevant info" ) { diff --git a/tests/itemname_test.cpp b/tests/itemname_test.cpp index f5c79dbe8540d..728c5fdd5bb86 100644 --- a/tests/itemname_test.cpp +++ b/tests/itemname_test.cpp @@ -35,7 +35,7 @@ TEST_CASE( "item sizing display", "[item][iteminfo][display_name][sizing]" ) std::string name = i.display_name(); THEN( "we have the correct sizing" ) { - const item::sizing sizing_level = i.get_sizing( g->u, true ); + const item::sizing sizing_level = i.get_sizing( g->u ); CHECK( sizing_level == item::sizing::small_sized_human_char ); } @@ -71,7 +71,7 @@ TEST_CASE( "item sizing display", "[item][iteminfo][display_name][sizing]" ) std::string name = i.display_name(); THEN( "we have the correct sizing" ) { - const item::sizing sizing_level = i.get_sizing( g->u, true ); + const item::sizing sizing_level = i.get_sizing( g->u ); CHECK( sizing_level == item::sizing::small_sized_big_char ); } @@ -107,7 +107,7 @@ TEST_CASE( "item sizing display", "[item][iteminfo][display_name][sizing]" ) std::string name = i.display_name(); THEN( "we have the correct sizing" ) { - const item::sizing sizing_level = i.get_sizing( g->u, true ); + const item::sizing sizing_level = i.get_sizing( g->u ); CHECK( sizing_level == item::sizing::small_sized_small_char ); } From 1f1f0dead82dbcea08c9fb213913d97f80a81c89 Mon Sep 17 00:00:00 2001 From: Eric Pierce Date: Sun, 12 Jul 2020 22:40:58 -0600 Subject: [PATCH 032/151] Improve requirements / components docs for recipes Add explanation and examples for defining recipe requirements, and using them in recipe components. Also embellish the recipe components section with more inline comments, and some notes on different ways of listing ingredients. Give examples of all different syntaxes, including single and alternative items, unrecoverable components, and items from a requirement list. --- doc/JSON_INFO.md | 171 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 152 insertions(+), 19 deletions(-) diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index cdb69bbdc2b3c..912ebcf3bf586 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -43,6 +43,8 @@ Use the `Home` key to return to the top. - [`cbms`](#-cbms-) - [`traits`](#-traits-) + [Recipes](#recipes) + - [Recipe components](#recipe-components) + - [Overlapping recipe component requirements](#overlapping-recipe-component-requirements) + [Constructions](#constructions) + [Scent Types](#scent_types) + [Scores, Achievements, and Conducts](#scores-achievements-and-conducts) @@ -288,6 +290,7 @@ See below for specifics on the various items ## `data/json/requirements/` + Standard components and tools for crafting | Filename | Description @@ -300,6 +303,42 @@ Standard components and tools for crafting | uncraft.json | common results of taking stuff apart | vehicle.json | tools to work on vehicles +Recipe requirements are JSON objects with `"type": "requirement"`. They allow re-using common +groups of recipe ingredients, or alternative ingredients. For example, the `bread_sandwich` +requirement includes several alternative breads you could make a sandwich with: + +```json +{ + "id": "bread_sandwich", + "type": "requirement", + "//": "Bread appropriate for sandwiches.", + "components": [ + [ + [ "flatbread", 1 ], + [ "bread", 1 ], + [ "cornbread", 1 ], + [ "wastebread", 1 ], + [ "sourdough_bread", 1 ], + [ "biscuit", 1 ], + [ "brioche", 1 ] + ] + ] +} +``` + +This lets you simplify the "components" of sandwich recipes that could work with any of those breads, ex. + +```json +{ + "type": "recipe", + "result": "sandwich_honey", + "components": [ [ [ "bread_sandwich", 2, "LIST" ] ], [ [ "honeycomb", 1 ], [ "honey_bottled", 1 ] ] ], + "//": "..." +} +``` + +See the [Recipe components](#recipe-components) section for how to use the "components" syntax. + ## `data/json/vehicles/` @@ -985,7 +1024,7 @@ player will start with this as a nearby vehicle. A list of flags. TODO: document those flags here. -- ```NO_BONUS_ITEMS``` Prevent bonus items (such as inhalers with the ASTHMA trait) from being given to this profession +- `NO_BONUS_ITEMS` Prevent bonus items (such as inhalers with the ASTHMA trait) from being given to this profession Mods can modify this via `add:flags` and `remove:flags`. @@ -1007,6 +1046,8 @@ Mods can modify this via `add:traits` and `remove:traits`. ### Recipes +Crafting recipes are defined as a JSON object with the following fields: + ```C++ "result": "javelin", // ID of resulting item "category": "CC_WEAPON", // Category of crafting recipe. CC_NONCRAFT used for disassembly recipes @@ -1055,25 +1096,117 @@ Mods can modify this via `add:traits` and `remove:traits`. [ [ "fire", -1 ] // Charges consumed when tool is used, -1 means no charges are consumed ]], -"components": [ // Equivalent tools or components are surrounded by a single set of brackets -[ - [ "spear_wood", 1 ], // Number of charges/items required - [ "pointy_stick", 1 ] -], -[ - [ "rag", 1 ], - [ "leather", 1 ], - [ "fur", 1 ] -], +"components": [ // Items (or item alternatives) required to craft this recipe + [ + [ "item_a", 5 ] // First ingredient: need 5 of item_a + ], + [ + [ "item_b", 2 ], // Also need 2 of item_b... + [ "item_c", 4 ] // OR 4 of item_c (but do not need both) + ], + [ + // ... any number of other component ingredients (see below) + ] +] +``` + +#### Recipe components + +A recipe's "components" lists all the required items or ingredients needed to craft the finished +item from the recipe. Each ingredient is given as an integer quantity of a specific item id or +requirement id, or as a list of several equivalent item/requirement quantities. + +The syntax of an ingredient in its simplest form is an item id and quantity. Continuing the +"javelin" recipe, let's require a single "spear_wood" item: + +```json +"components": [ + [ [ "spear_wood", 1 ] ] +] +``` + +A single component may also have substitutions; for instance, to allow crafting from one +"spear_wood" *or* one "pointy_stick": + +```json +"components": [ + [ [ "spear_wood", 1 ], [ "pointy_stick", 1 ] ] +] +``` + +Notice that the first example with *only* "spear_wood" was simply the degenerate case - a list of +alternatives with only 1 alternative - which is why it was doubly nested in `[ [ ... ] ]`. + +The javelin would be better with some kind of leather or cloth grip. To require 2 rags, 1 leather, +or 1 fur *in addition to* the wood spear or pointy stick: + +```json +"components": [ + [ [ "spear_wood", 1 ], [ "pointy_stick", 1 ] ], + [ [ "rag", 2 ], [ "leather", 1 ], [ "fur", 1 ] ] +] +``` + +And to bind the grip onto the javelin, some sinew or thread should be required, which can have the +"NO_RECOVER" keyword to indicate they cannot be recovered if the item is deconstructed: + +```json +"components": [ + [ [ "spear_wood", 1 ], [ "pointy_stick", 1 ] ], + [ [ "rag", 2 ], [ "leather", 1 ], [ "fur", 1 ] ], + [ [ "sinew", 20, "NO_RECOVER" ], [ "thread", 20, "NO_RECOVER" ] ] +] +``` + +*Note*: Related to "NO_RECOVER", some items such as "superglue" and "duct_tape" have an +"UNRECOVERABLE" flag on the item itself, indicating they can never be reclaimed when disassembling. +See [JSON_FLAGS.md](JSON_FLAGS.md) for how to use this and other item flags. + +To avoid repeating commonly used sets of ingredient items, instead of an individual item id, +provide the id of a "requirement" type, along with a quantity, and the "LIST" keyword. +Typically these are defined within [`data/json/requirements`](#datajsonrequirements). + +For example if these "grip_patch" and "grip_wrap" requirements were defined: + +```json [ - [ "plant_fibre", 20, false ], // Optional flag for recoverability, default is true. - [ "sinew", 20, false ], - [ "thread", 20, false ], - [ "duct_tape", 20 ] // Certain items are flagged as unrecoverable at the item definition level. + { + "id": "grip_patch", + "type": "requirement", + "components": [ [ [ "rag", 2 ], [ "leather", 1 ], [ "fur", 1 ] ] ] + }, + { + "id": "grip_wrap", + "type": "requirement", + "components": [ [ [ "sinew", 20, "NO_RECOVER" ], [ "thread", 20, "NO_RECOVER" ] ] ] + } +] +``` + +Then javelin recipe components could use 1 grip and 1 wrap, for example: + +```json +"result": "javelin", +"components": [ + [ [ "spear_wood", 1 ], [ "pointy_stick", 1 ] ], + [ [ "grip_patch", 1, "LIST" ] ], + [ [ "grip_wrap", 1, "LIST" ] ] ] +``` + +And other recipes needing two such grips could simply require 2 of each: + +```json +"result": "big_staff", +"components": [ + [ [ "stick_long", 1 ] ], + [ [ "grip_patch", 2, "LIST" ] ], + [ [ "grip_wrap", 2, "LIST" ] ] ] ``` + + #### Overlapping recipe component requirements If recipes have requirements which overlap, this makes it more @@ -1539,7 +1672,7 @@ it is present to help catch errors. "trigger_type": "TIME", // What variable is tracked by this trigger "threshold_low": 20, // Is True if the value is above threshold_low "threshold_high": 2, // Is True if the value is below threshold_high - "msg_on": { "text": "Everything is terrible and this makes you so ANGRY!", "rating": "mixed" } // message displayed when the trigger activates + "msg_on": { "text": "Everything is terrible and this makes you so ANGRY!", "rating": "mixed" } // message displayed when the trigger activates "msg_off": { "text": "Your glow fades." } // message displayed when the trigger deactivates the trait } ] @@ -1559,7 +1692,7 @@ it is present to help catch errors. ### Traps ```C++ - "type": "trap", + "type": "trap", "id": "tr_beartrap", // Unique ID "name": "bear trap", // In-game name displayed "color": "blue", @@ -1568,7 +1701,7 @@ it is present to help catch errors. "avoidance": 7, // 0 to ??, affects avoidance "difficulty": 3, // 0 to ??, difficulty of assembly & disassembly "trap_radius": 1, // 0 to ??, trap radius - "action": "blade", + "action": "blade", "map_regen": "microlab_shifting_hall", // a valid overmap id, for map_regen action traps "benign": true, "always_invisible": true, @@ -1978,7 +2111,7 @@ When adding a new book, please use this color key: A few exceptions to this color key may apply, for example for books that donā€™t are what they seem to be. Never use `yellow` and `red`, those colors are reserved for sounds and infrared vision. -####CBMs +#### CBMs CBMs can be defined like this: From 1f223f5b6d95b16c5db97457c0081bedeed00174 Mon Sep 17 00:00:00 2001 From: UrbanCMC Date: Tue, 14 Jul 2020 13:31:57 +0200 Subject: [PATCH 033/151] Fix crash when repairing with bionic-powered tools --- src/activity_handlers.cpp | 17 +++++++++++++---- src/item.cpp | 6 +++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 094d771cc1b92..72a5cc094c501 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -288,6 +288,7 @@ static const std::string flag_SKINNED( "SKINNED" ); static const std::string flag_SPEEDLOADER( "SPEEDLOADER" ); static const std::string flag_SUPPORTS_ROOF( "SUPPORTS_ROOF" ); static const std::string flag_TREE( "TREE" ); +static const std::string flag_USES_BIONIC_POWER( "USES_BIONIC_POWER" ); using namespace activity_handlers; @@ -2689,15 +2690,23 @@ void activity_handlers::repair_item_finish( player_activity *act, player *p ) repair_item_actor::action_description( action_type ), fix.tname() ); ammotype current_ammo; - if( used_tool->ammo_current().is_null() ) { - current_ammo = item_controller->find_template( used_tool->ammo_default() )->ammo->type; + std::string ammo_name; + if( used_tool->has_flag( flag_USES_BIONIC_POWER ) ) { + ammo_name = _( "bionic power" ); + } else { - current_ammo = item_controller->find_template( used_tool->ammo_current() )->ammo->type; + if( used_tool->ammo_current().is_null() ) { + current_ammo = item_controller->find_template( used_tool->ammo_default() )->ammo->type; + } else { + current_ammo = item_controller->find_template( used_tool->ammo_current() )->ammo->type; + } + + ammo_name = item::nname( used_tool->ammo_current() ); } title += string_format( _( "Charges: %s/%s %s (%s per use)\n" ), used_tool->ammo_remaining(), used_tool->ammo_capacity( current_ammo ), - item::nname( used_tool->ammo_current() ), + ammo_name, used_tool->ammo_required() ); title += string_format( _( "Skill used: %s (%s)\n" ), actor->used_skill.obj().name(), level ); diff --git a/src/item.cpp b/src/item.cpp index 06b6e01341f61..bc96a17648187 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -589,7 +589,9 @@ units::energy item::set_energy( const units::energy &qty ) item &item::ammo_set( const itype_id &ammo, int qty ) { if( !ammo->ammo ) { - debugmsg( "can't set ammo %s in %s as it is not an ammo", ammo.c_str(), type_name() ); + if( !has_flag( flag_USES_BIONIC_POWER ) ) { + debugmsg( "can't set ammo %s in %s as it is not an ammo", ammo.c_str(), type_name() ); + } return *this; } const ammotype &ammo_type = ammo->ammo->type; @@ -7363,6 +7365,8 @@ int item::ammo_capacity( const ammotype &ammo ) const const item *mag = magazine_current(); if( mag ) { return mag->ammo_capacity( ammo ); + } else if( has_flag( flag_USES_BIONIC_POWER ) ) { + return units::to_kilojoule( get_player_character().get_max_power_level() ); } return contents.ammo_capacity( ammo ); From 9e4c66bbe09c0ea847d9191b3573fbb5507a305e Mon Sep 17 00:00:00 2001 From: andrei Date: Tue, 14 Jul 2020 19:16:51 +0300 Subject: [PATCH 034/151] player: fix process_items() for new pocket system update getting inventory list remove redundant code --- src/player.cpp | 45 ++++++++++++++------------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/src/player.cpp b/src/player.cpp index ffeb47439bb43..c8a6c308d7d7d 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1823,29 +1823,20 @@ void player::process_items() // Active item processing done, now we're recharging. item *cloak = nullptr; item *power_armor = nullptr; - std::vector active_worn_items; - bool weapon_active = weapon.has_flag( "USE_UPS" ) && - weapon.charges < weapon.type->maximum_charges(); - std::vector active_held_items; int ch_UPS = 0; - for( size_t index = 0; index < inv.size(); index++ ) { - item &it = inv.find_item( index ); - itype_id identifier = it.type->get_id(); + const auto inv_is_ups = items_with( []( const item & itm ) { + return itm.has_flag( "IS_UPS" ); + } ); + for( auto &it : inv_is_ups ) { + itype_id identifier = it->type->get_id(); if( identifier == itype_UPS_off ) { - ch_UPS += it.ammo_remaining(); + ch_UPS += it->ammo_remaining(); } else if( identifier == itype_adv_UPS_off ) { - ch_UPS += it.ammo_remaining() / 0.6; - } - if( it.has_flag( "USE_UPS" ) && it.charges < it.type->maximum_charges() ) { - active_held_items.push_back( index ); + ch_UPS += it->ammo_remaining() / 0.6; } } bool update_required = get_check_encumbrance(); for( item &w : worn ) { - if( w.has_flag( "USE_UPS" ) && - w.charges < w.type->maximum_charges() ) { - active_worn_items.push_back( &w ); - } if( w.active ) { if( cloak == nullptr && w.has_flag( "ACTIVE_CLOAKING" ) ) { cloak = &w; @@ -1912,24 +1903,16 @@ void player::process_items() // Load all items that use the UPS to their minimal functional charge, // The tool is not really useful if its charges are below charges_to_use - for( size_t index : active_held_items ) { - if( ch_UPS_used >= ch_UPS ) { - break; - } - item &it = inv.find_item( index ); - ch_UPS_used++; - it.charges++; - } - if( weapon_active && ch_UPS_used < ch_UPS ) { - ch_UPS_used++; - weapon.charges++; - } - for( item *worn_item : active_worn_items ) { - if( ch_UPS_used >= ch_UPS ) { + const auto inv_use_ups = items_with( []( const item & itm ) { + return itm.has_flag( "USE_UPS" ); + } ); + for( auto &it : inv_use_ups ) { + if( ch_UPS_used >= ch_UPS || + it->ammo_remaining() >= it->ammo_capacity( ammotype( "battery" ) ) ) { break; } ch_UPS_used++; - worn_item->charges++; + it->ammo_set( itype_battery, it->ammo_remaining() + 1 ); } if( ch_UPS_used > 0 ) { use_charges( itype_UPS, ch_UPS_used ); From 62774a3e3773a6b1de6f31e8b650e11437fe3af0 Mon Sep 17 00:00:00 2001 From: I-am-Erk <45136638+I-am-Erk@users.noreply.github.com> Date: Tue, 14 Jul 2020 16:20:56 -0700 Subject: [PATCH 035/151] better looks_like support --- .../furniture-industrial.json | 14 +++++++++++--- .../furniture_and_terrain/furniture-tools.json | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/data/json/furniture_and_terrain/furniture-industrial.json b/data/json/furniture_and_terrain/furniture-industrial.json index f993a57aab249..d41e378ec97ff 100644 --- a/data/json/furniture_and_terrain/furniture-industrial.json +++ b/data/json/furniture_and_terrain/furniture-industrial.json @@ -46,6 +46,7 @@ { "type": "furniture", "id": "f_chemical_mixer", + "looks_like": "f_machinery_light", "description": "A large vat with a motorized mixing device for combining large quantities of chemicals.", "name": "chemical mixer", "symbol": "0", @@ -82,10 +83,10 @@ "type": "furniture", "id": "f_generator_broken", "name": "broken generator", + "looks_like": "f_machinery_old", "description": "This generator is broken and will not help you produce usable electricity.", "symbol": "&", "color": "light_gray", - "looks_like": "f_machinery_old", "move_cost_mod": -1, "coverage": 30, "required_str": 16, @@ -119,10 +120,10 @@ "type": "furniture", "id": "f_compact_ASRG_containment", "name": "Compact Advanced Sterling Radioisotope Generator", + "looks_like": "t_plut_generator", "description": "This hefty lump of steel and lead is the housing unit for a small nuclear reactor. It is plastered with warning signs. You could probably ignore those and salvage the steel and lead shielding, what could possibly go wrong?", "symbol": "0", "color": "green_white", - "looks_like": "f_machinery_electronic", "move_cost_mod": -1, "coverage": 80, "required_str": -1, @@ -157,10 +158,10 @@ "type": "furniture", "id": "f_compact_ASRG", "name": "Compact Advanced Sterling Radioisotope Generator", + "looks_like": "f_compact_ASRG_containment", "description": "Some insane fool has removed the outer containment on this small-scale nuclear reactor. It is still fairly safe as it is: the reactor has considerable built-in containment as well. Nevertheless, you probably don't want to stand too close for too long.", "symbol": "0", "color": "green", - "looks_like": "f_machinery_electronic", "move_cost_mod": -1, "coverage": 50, "required_str": -1, @@ -185,6 +186,7 @@ "type": "furniture", "id": "f_machinery_light", "name": "light machinery", + "looks_like": "t_machinery_light", "description": "Assorted light machinery. You could scavenge it for parts.", "symbol": "$", "color": "dark_gray", @@ -228,6 +230,7 @@ "type": "furniture", "id": "f_machinery_heavy", "name": "heavy machinery", + "looks_like": "t_machinery_heavy", "description": "Assorted heavy machinery. You could scavenge it for parts.", "symbol": "%", "color": "light_gray", @@ -277,6 +280,7 @@ "type": "furniture", "id": "f_machinery_old", "name": "old machinery", + "looks_like": "t_machinery_old", "description": "Assorted old, rusty machinery. You could scavenge it for parts.", "symbol": "&", "color": "brown", @@ -324,6 +328,7 @@ "type": "furniture", "id": "f_machinery_electronic", "name": "electronic machinery", + "looks_like": "t_machinery_electronic", "description": "Assorted electronic machinery. You could scavenge it for parts.", "symbol": "$", "color": "yellow", @@ -378,6 +383,7 @@ "type": "furniture", "id": "f_robotic_arm", "name": "robotic arm", + "looks_like": "f_machinery_electronic", "description": "An automated robotic arm used in assembly lines, which appears to be more general-purpose than specially designed assemblers. Despite being functionless now, the parts could be useful.", "symbol": "&", "bgcolor": "yellow", @@ -420,6 +426,7 @@ "type": "furniture", "id": "f_ground_cable", "name": "ground cable", + "looks_like": "t_sewer_pipe", "description": "A bunch of loose cables snake along the floor.", "symbol": "}", "color": "white", @@ -439,6 +446,7 @@ "type": "furniture", "id": "f_capacitor", "name": "capacitor bank", + "looks_like": "f_machinery_electronic", "description": "A bank of heavy metal cylinders connected by large wires.", "symbol": "=", "color": "light_blue", diff --git a/data/json/furniture_and_terrain/furniture-tools.json b/data/json/furniture_and_terrain/furniture-tools.json index 666b2a53540fd..fbd610073b17c 100644 --- a/data/json/furniture_and_terrain/furniture-tools.json +++ b/data/json/furniture_and_terrain/furniture-tools.json @@ -3,6 +3,7 @@ "type": "furniture", "id": "f_console_broken", "name": "broken console", + "looks_like": "t_console_broken", "description": "This is a standalone computer terminal. It doesn't seem to be working. It's the broken screen and shattered circuit boards that's telling you that.", "symbol": "6", "color": "light_gray", @@ -50,6 +51,7 @@ "type": "furniture", "id": "f_console", "name": "computer console", + "looks_like": "t_console", "description": "This is a standalone computer terminal. It can be used to view contents and perform any allowed functions. It might even be possible to hack it, given the skills.", "symbol": "6", "color": "blue", @@ -98,6 +100,7 @@ "type": "furniture", "id": "f_forge", "name": "forge", + "looks_like": "f_fireplace", "description": "Metalworking station typically used in combination with an anvil.", "symbol": "^", "color": "light_red", @@ -120,6 +123,7 @@ "type": "furniture", "id": "f_anvil", "name": "anvil", + "looks_like": "f_boulder", "description": "Used in metalworking.", "symbol": "^", "color": "light_red", @@ -151,6 +155,7 @@ "type": "furniture", "id": "f_kiln_empty", "name": "charcoal kiln", + "looks_like": "f_fireplace", "description": "A rock kiln designed to burn wood and organic material into charcoal in absence of oxygen.", "symbol": "U", "color": "brown", @@ -196,6 +201,7 @@ "type": "furniture", "id": "f_kiln_metal_empty", "name": "metal charcoal kiln", + "looks_like": "f_kiln_empty", "description": "A metal kiln designed to burn wood and organic material into charcoal in absence of oxygen.", "symbol": "U", "color": "blue", @@ -303,6 +309,7 @@ "type": "furniture", "id": "f_smoking_rack", "name": "smoking rack", + "looks_like": "f_rack", "description": "A special rack designed to smoke food for better preservation and taste. Works as a charcoal smoker in crafting recipes.", "symbol": "=", "bgcolor": "brown", @@ -391,6 +398,7 @@ "type": "furniture", "id": "f_forge_rock", "name": "rock forge", + "looks_like": "f_fireplace", "description": "Metalworking station made of rock, typically used in combination with an anvil. Works as a charcoal forge in crafting recipes.", "symbol": "^", "color": "light_red", @@ -413,6 +421,7 @@ "type": "furniture", "id": "f_clay_kiln", "name": "clay kiln", + "looks_like": "f_fireplace", "description": "A kiln designed to bake clay pottery and bricks.", "symbol": "^", "color": "light_red", @@ -868,6 +877,7 @@ "type": "furniture", "id": "f_fvat_empty", "name": "fermenting vat", + "looks_like": "f_standing_tank", "description": "A sealable vat for fermenting vinegar and various alcoholic brews.", "symbol": "O", "color": "brown", @@ -903,6 +913,7 @@ "type": "furniture", "id": "f_fvat_full", "name": "filled fermenting vat", + "looks_like": "f_fvat_empty", "description": "A sealable vat for fermenting vinegar and various alcoholic brews.", "symbol": "O", "color": "brown_cyan", @@ -938,6 +949,7 @@ "type": "furniture", "id": "f_butcher_rack", "name": "butchering rack", + "looks_like": "f_rack", "description": "Butchering rack designed to hang a carcass in the air.", "symbol": "^", "bgcolor": "brown", @@ -966,6 +978,7 @@ "type": "furniture", "id": "f_metal_butcher_rack", "name": "metal butchering rack", + "looks_like": "f_butcher_rack", "description": "Metal butchering rack designed to hang a carcass in the air. It can be deconstructed and folded for easy transportation.", "symbol": "^", "bgcolor": "light_gray", @@ -987,6 +1000,7 @@ "id": "f_hanging_meathook", "type": "furniture", "name": "hanging meathook", + "looks_like": "f_butcher_rack", "description": "A hefty hook suspended from a chain for stringing up corpses.", "symbol": "g", "required_str": -1, @@ -1024,6 +1038,7 @@ "type": "furniture", "id": "f_wind_mill_active", "name": "active wind mill", + "looks_like": "f_wind_mill", "description": "A small wind-powered mill that can convert starchy products into flour. Its brake has been removed and it is turning.", "symbol": "T", "bgcolor": "red", @@ -1076,6 +1091,7 @@ "type": "furniture", "id": "f_water_mill_active", "name": "active water mill", + "looks_like": "f_water_mill", "description": "A small water-powered mill that can convert starchy products into flour. Its brake has been removed and it is turning.", "symbol": "*", "bgcolor": "red", From b54d51483981a7a15ab056cc433d3eacea08febf Mon Sep 17 00:00:00 2001 From: anothersimulacrum <42699974+anothersimulacrum@users.noreply.github.com> Date: Tue, 14 Jul 2020 16:40:37 -0700 Subject: [PATCH 036/151] Move crafting related functions to character Shake the tree of moving crafting functions to Character, and pick up whatever falls out. --- src/character.cpp | 219 +++++++++++++++++++++++ src/character.h | 189 +++++++++++++++++++- src/character_crafting.cpp | 143 +++++++++++++++ src/craft_command.h | 6 +- src/crafting.cpp | 122 ++++++------- src/crafting.h | 4 +- src/game_inventory.cpp | 12 +- src/game_inventory.h | 2 +- src/inventory.cpp | 2 +- src/inventory.h | 2 +- src/item.cpp | 2 +- src/item.h | 6 +- src/iuse.cpp | 2 +- src/iuse.h | 2 +- src/player.cpp | 351 ------------------------------------- src/player.h | 180 ------------------- src/requirements.cpp | 4 +- src/requirements.h | 4 +- 18 files changed, 636 insertions(+), 616 deletions(-) create mode 100644 src/character_crafting.cpp diff --git a/src/character.cpp b/src/character.cpp index 07eb2fe34728a..a14644137d805 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -63,6 +63,7 @@ #include "overmapbuffer.h" #include "pathfinding.h" #include "player.h" +#include "recipe_dictionary.h" #include "proficiency.h" #include "ret_val.h" #include "rng.h" @@ -212,6 +213,8 @@ static const trait_id trait_BADBACK( "BADBACK" ); static const trait_id trait_DEBUG_NODMG( "DEBUG_NODMG" ); static const trait_id trait_HUGE( "HUGE" ); static const trait_id trait_HUGE_OK( "HUGE_OK" ); +static const trait_id trait_PACIFIST( "PACIFIST" ); +static const trait_id trait_SAVANT( "SAVANT" ); static const trait_id trait_SMALL2( "SMALL2" ); static const trait_id trait_SMALL_OK( "SMALL_OK" ); static const trait_id trait_SQUEAMISH( "SQUEAMISH" ); @@ -1299,6 +1302,21 @@ void Character::dismount() } } +void Character::handle_skill_warning( const skill_id &id, bool force_warning ) +{ + //remind the player intermittently that no skill gain takes place + if( is_player() && ( force_warning || one_in( 5 ) ) ) { + SkillLevel &level = get_skill_level_object( id ); + + const Skill &skill = id.obj(); + std::string skill_name = skill.name(); + int curLevel = level.level(); + + add_msg( m_info, _( "This task is too simple to train your %s beyond %d." ), + skill_name, curLevel ); + } +} + /** Returns true if the character has two functioning arms */ bool Character::has_two_arms() const { @@ -2043,6 +2061,118 @@ bionic_id Character::get_most_efficient_bionic( const std::vector &bi return bio; } +void Character::practice( const skill_id &id, int amount, int cap, bool suppress_warning ) +{ + SkillLevel &level = get_skill_level_object( id ); + const Skill &skill = id.obj(); + if( !level.can_train() && !in_sleep_state() ) { + // If leveling is disabled, don't train, don't drain focus, don't print anything + // Leaving as a skill method rather than global for possible future skill cap setting + return; + } + + const auto highest_skill = [&]() { + std::pair result( skill_id::NULL_ID(), -1 ); + for( const auto &pair : *_skills ) { + const SkillLevel &lobj = pair.second; + if( lobj.level() > result.second ) { + result = std::make_pair( pair.first, lobj.level() ); + } + } + return result.first; + }; + + const bool isSavant = has_trait( trait_SAVANT ); + const skill_id savantSkill = isSavant ? highest_skill() : skill_id::NULL_ID(); + + amount = adjust_for_focus( amount ); + + if( has_trait( trait_PACIFIST ) && skill.is_combat_skill() ) { + if( !one_in( 3 ) ) { + amount = 0; + } + } + if( has_trait_flag( "PRED2" ) && skill.is_combat_skill() ) { + if( one_in( 3 ) ) { + amount *= 2; + } + } + if( has_trait_flag( "PRED3" ) && skill.is_combat_skill() ) { + amount *= 2; + } + + if( has_trait_flag( "PRED4" ) && skill.is_combat_skill() ) { + amount *= 3; + } + + if( isSavant && id != savantSkill ) { + amount /= 2; + } + + if( amount > 0 && get_skill_level( id ) > cap ) { //blunt grinding cap implementation for crafting + amount = 0; + if( !suppress_warning ) { + handle_skill_warning( id, false ); + } + } + if( amount > 0 && level.isTraining() ) { + int oldLevel = get_skill_level( id ); + get_skill_level_object( id ).train( amount ); + int newLevel = get_skill_level( id ); + std::string skill_name = skill.name(); + if( newLevel > oldLevel ) { + g->events().send( getID(), id, newLevel ); + } + if( is_player() && newLevel > oldLevel ) { + add_msg( m_good, _( "Your skill in %s has increased to %d!" ), skill_name, newLevel ); + } + if( is_player() && newLevel > cap ) { + //inform player immediately that the current recipe can't be used to train further + add_msg( m_info, _( "You feel that %s tasks of this level are becoming trivial." ), + skill_name ); + } + + int chance_to_drop = focus_pool; + focus_pool -= chance_to_drop / 100; + // Apex Predators don't think about much other than killing. + // They don't lose Focus when practicing combat skills. + if( ( rng( 1, 100 ) <= ( chance_to_drop % 100 ) ) && ( !( has_trait_flag( "PRED4" ) && + skill.is_combat_skill() ) ) ) { + focus_pool--; + } + } + + get_skill_level_object( id ).practice(); +} + +// Returned values range from 1.0 (unimpeded vision) to 11.0 (totally blind). +// 1.0 is LIGHT_AMBIENT_LIT or brighter +// 4.0 is a dark clear night, barely bright enough for reading and crafting +// 6.0 is LIGHT_AMBIENT_DIM +// 7.3 is LIGHT_AMBIENT_MINIMAL, a dark cloudy night, unlit indoors +// 11.0 is zero light or blindness +float Character::fine_detail_vision_mod( const tripoint &p ) const +{ + // PER_SLIME_OK implies you can get enough eyes around the bile + // that you can generally see. There still will be the haze, but + // it's annoying rather than limiting. + if( is_blind() || + ( ( has_effect( effect_boomered ) || has_effect( effect_darkness ) ) && + !has_trait( trait_PER_SLIME_OK ) ) ) { + return 11.0; + } + // Scale linearly as light level approaches LIGHT_AMBIENT_LIT. + // If we're actually a source of light, assume we can direct it where we need it. + // Therefore give a hefty bonus relative to ambient light. + float own_light = std::max( 1.0f, LIGHT_AMBIENT_LIT - active_light() - 2.0f ); + + // Same calculation as above, but with a result 3 lower. + float ambient_light = std::max( 1.0f, + LIGHT_AMBIENT_LIT - get_map().ambient_light_at( p == tripoint_zero ? pos() : p ) + 1.0f ); + + return std::min( own_light, ambient_light ); +} + units::energy Character::get_power_level() const { return power_level; @@ -8730,6 +8860,95 @@ void Character::did_hit( Creature &target ) enchantment_cache.cast_hit_you( *this, target ); } +ret_val Character::can_wield( const item &it ) const +{ + if( it.made_of_from_type( phase_id::LIQUID ) ) { + return ret_val::make_failure( _( "Can't wield spilt liquids." ) ); + } + + if( get_working_arm_count() <= 0 ) { + return ret_val::make_failure( + _( "You need at least one arm to even consider wielding something." ) ); + } + + if( is_armed() && !can_unwield( weapon ).success() ) { + return ret_val::make_failure( _( "The %s is preventing you from wielding the %s." ), + weapname(), it.tname() ); + } + + if( it.is_two_handed( *this ) && ( !has_two_arms() || worn_with_flag( "RESTRICT_HANDS" ) ) ) { + if( worn_with_flag( "RESTRICT_HANDS" ) ) { + return ret_val::make_failure( + _( "Something you are wearing hinders the use of both hands." ) ); + } else if( it.has_flag( "ALWAYS_TWOHAND" ) ) { + return ret_val::make_failure( _( "The %s can't be wielded with only one arm." ), + it.tname() ); + } else { + return ret_val::make_failure( _( "You are too weak to wield %s with only one arm." ), + it.tname() ); + } + } + + return ret_val::make_success(); +} + +bool Character::unwield() +{ + if( weapon.is_null() ) { + return true; + } + + if( !can_unwield( weapon ).success() ) { + return false; + } + + // currently the only way to unwield NO_UNWIELD weapon is if it's a bionic that can be deactivated + if( weapon.has_flag( "NO_UNWIELD" ) ) { + cata::optional wi = active_bionic_weapon_index(); + return wi && deactivate_bionic( *wi ); + } + + const std::string query = string_format( _( "Stop wielding %s?" ), weapon.tname() ); + + if( !dispose_item( item_location( *this, &weapon ), query ) ) { + return false; + } + + inv.unsort(); + + return true; +} + +std::string Character::weapname() const +{ + if( weapon.is_gun() ) { + std::string gunmode; + // only required for empty mags and empty guns + std::string mag_ammo; + if( weapon.gun_all_modes().size() > 1 ) { + gunmode = weapon.gun_current_mode().tname(); + } + + if( weapon.ammo_remaining() == 0 ) { + if( weapon.magazine_current() != nullptr ) { + const item *mag = weapon.magazine_current(); + mag_ammo = string_format( " (0/%d)", + mag->ammo_capacity( item( mag->ammo_default() ).ammo_type() ) ); + } else { + mag_ammo = _( " (empty)" ); + } + } + + return string_format( "%s%s%s", gunmode, weapon.display_name(), mag_ammo ); + + } else if( !is_armed() ) { + return _( "fists" ); + + } else { + return weapon.tname(); + } +} + void Character::on_hit( Creature *source, bodypart_id /*bp_hit*/, float /*difficulty*/, dealt_projectile_attack const *const /*proj*/ ) { diff --git a/src/character.h b/src/character.h index c83a3e9a0b915..e7af3f6467185 100644 --- a/src/character.h +++ b/src/character.h @@ -55,6 +55,7 @@ class JsonObject; class JsonOut; class SkillLevel; class SkillLevelMap; +class basecamp; class bionic_collection; class faction; class player; @@ -65,6 +66,7 @@ struct construction; struct dealt_projectile_attack; struct islot_comestible; struct itype; +class recipe_subset; struct mutation_branch; struct needs_rates; struct pathfinding_settings; @@ -72,6 +74,8 @@ struct points_left; template struct enum_traits; enum npc_attitude : int; +static const std::string DEFAULT_HOTKEYS( "1234567890abcdefghijklmnopqrstuvwxyz" ); + using drop_location = std::pair; using drop_locations = std::list; @@ -733,6 +737,22 @@ class Character : public Creature, public visitable std::vector &targets ); public: + /** This handles giving xp for a skill */ + void practice( const skill_id &id, int amount, int cap = 99, bool suppress_warning = false ); + /** This handles warning the player that there current activity will not give them xp */ + void handle_skill_warning( const skill_id &id, bool force_warning = false ); + + /** + * Check player capable of wielding an item. + * @param it Thing to be wielded + */ + ret_val can_wield( const item &it ) const; + + bool unwield(); + + /** Get the formatted name of the currently wielded item (if any) with current gun mode (if gun) */ + std::string weapname() const; + // any side effects that might happen when the Character is hit void on_hit( Creature *source, bodypart_id /*bp_hit*/, float /*difficulty*/, dealt_projectile_attack const * /*proj*/ ) override; @@ -1449,6 +1469,10 @@ class Character : public Creature, public visitable &locations ) const; units::volume free_space() const; + + /** Note that we've read a book at least once. **/ + virtual bool has_identified( const itype_id &item_id ) const = 0; + bool can_pickVolume( const item &it, bool safe = false ) const; bool can_pickWeight( const item &it, bool safe = true ) const; /** @@ -2058,8 +2082,8 @@ class Character : public Creature, public visitable /** Used to apply stimulation modifications from food and medication **/ void modify_stimulation( const islot_comestible &comest ); /** Used to apply fatigue modifications from food and medication **/ - void modify_fatigue( const islot_comestible &comest ); /** Used to apply radiation from food and medication **/ + void modify_fatigue( const islot_comestible &comest ); void modify_radiation( const islot_comestible &comest ); /** Used to apply addiction modifications from food and medication **/ void modify_addiction( const islot_comestible &comest ); @@ -2146,6 +2170,163 @@ class Character : public Creature, public visitable int radius = PICKUP_RANGE, bool clear_path = true ); void invalidate_crafting_inventory(); + + /** Returns a value from 1.0 to 5.0 that acts as a multiplier + * for the time taken to perform tasks that require detail vision, + * above 4.0 means these activities cannot be performed. + * takes pos as a parameter so that remote spots can be judged + * if they will potentially have enough light when player gets there */ + float fine_detail_vision_mod( const tripoint &p = tripoint_zero ) const; + + // ---- CRAFTING ---- + void make_craft_with_command( const recipe_id &id_to_make, int batch_size, bool is_long = false, + const tripoint &loc = tripoint_zero ); + pimpl last_craft; + + recipe_id lastrecipe; + int last_batch; + itype_id lastconsumed; //used in crafting.cpp and construction.cpp + + // Checks crafting inventory for books providing the requested recipe. + // Then checks nearby NPCs who could provide it too. + // Returns -1 to indicate recipe not found, otherwise difficulty to learn. + int has_recipe( const recipe *r, const inventory &crafting_inv, + const std::vector &helpers ) const; + bool knows_recipe( const recipe *rec ) const; + void learn_recipe( const recipe *rec ); + int exceeds_recipe_requirements( const recipe &rec ) const; + bool has_recipe_requirements( const recipe &rec ) const; + bool can_decomp_learn( const recipe &rec ) const; + + bool studied_all_recipes( const itype &book ) const; + + /** Returns all known recipes. */ + const recipe_subset &get_learned_recipes() const; + /** Returns all recipes that are known from the books (either in inventory or nearby). */ + recipe_subset get_recipes_from_books( const inventory &crafting_inv ) const; + /** + * Returns all available recipes (from books and npc companions) + * @param crafting_inv Current available items to craft + * @param helpers List of NPCs that could help with crafting. + */ + recipe_subset get_available_recipes( const inventory &crafting_inv, + const std::vector *helpers = nullptr ) const; + /** + * Returns the set of book types in crafting_inv that provide the + * given recipe. + * @param crafting_inv Current available items that may contain readable books + * @param r Recipe to search for in the available books + */ + std::set get_books_for_recipe( const inventory &crafting_inv, + const recipe *r ) const; + + // crafting.cpp + float morale_crafting_speed_multiplier( const recipe &rec ) const; + float lighting_craft_speed_multiplier( const recipe &rec ) const; + float crafting_speed_multiplier( const recipe &rec, bool in_progress = false ) const; + /** For use with in progress crafts */ + float crafting_speed_multiplier( const item &craft, const tripoint &loc ) const; + int available_assistant_count( const recipe &rec ) const; + /** + * Time to craft not including speed multiplier + */ + int base_time_to_craft( const recipe &rec, int batch_size = 1 ) const; + /** + * Expected time to craft a recipe, with assumption that multipliers stay constant. + */ + int expected_time_to_craft( const recipe &rec, int batch_size = 1, bool in_progress = false ) const; + std::vector get_eligible_containers_for_crafting() const; + bool check_eligible_containers_for_crafting( const recipe &rec, int batch_size = 1 ) const; + bool can_make( const recipe *r, int batch_size = 1 ); // have components? + /** + * Returns true if the player can start crafting the recipe with the given batch size + * The player is not required to have enough tool charges to finish crafting, only to + * complete the first step (total / 20 + total % 20 charges) + */ + bool can_start_craft( const recipe *rec, recipe_filter_flags, int batch_size = 1 ); + bool making_would_work( const recipe_id &id_to_make, int batch_size ); + + /** + * Start various types of crafts + * @param loc the location of the workbench. tripoint_zero indicates crafting from inventory. + */ + void craft( const tripoint &loc = tripoint_zero ); + void recraft( const tripoint &loc = tripoint_zero ); + void long_craft( const tripoint &loc = tripoint_zero ); + void make_craft( const recipe_id &id, int batch_size, const tripoint &loc = tripoint_zero ); + void make_all_craft( const recipe_id &id, int batch_size, const tripoint &loc = tripoint_zero ); + /** consume components and create an active, in progress craft containing them */ + void start_craft( craft_command &command, const tripoint &loc ); + /** + * Calculate a value representing the success of the player at crafting the given recipe, + * taking player skill, recipe difficulty, npc helpers, and player mutations into account. + * @param making the recipe for which to calculate + * @return a value >= 0.0 with >= 1.0 representing unequivocal success + */ + double crafting_success_roll( const recipe &making ) const; + void complete_craft( item &craft, const tripoint &loc = tripoint_zero ); + /** + * Check if the player meets the requirements to continue the in progress craft and if + * unable to continue print messages explaining the reason. + * If the craft is missing components due to messing up, prompt to consume new ones to + * allow the craft to be continued. + * @param craft the currently in progress craft + * @return if the craft can be continued + */ + bool can_continue_craft( item &craft ); + /** Returns nearby NPCs ready and willing to help with crafting. */ + std::vector get_crafting_helpers() const; + int get_num_crafting_helpers( int max ) const; + /** + * Handle skill gain for player and followers during crafting + * @param craft the currently in progress craft + * @param multiplier what factor to multiply the base skill gain by. This is used to apply + * multiple steps of incremental skill gain simultaneously if needed. + */ + void craft_skill_gain( const item &craft, const int &multiplier ); + /** + * Check if the player can disassemble an item using the current crafting inventory + * @param obj Object to check for disassembly + * @param inv current crafting inventory + */ + ret_val can_disassemble( const item &obj, const inventory &inv ) const; + + bool disassemble(); + bool disassemble( item_location target, bool interactive = true ); + void disassemble_all( bool one_pass ); // Disassemble all items on the tile + void complete_disassemble(); + void complete_disassemble( item_location &target, const recipe &dis ); + + const requirement_data *select_requirements( + const std::vector &, int batch, const inventory &, + const std::function &filter ) const; + comp_selection + select_item_component( const std::vector &components, + int batch, inventory &map_inv, bool can_cancel = false, + const std::function &filter = return_true, bool player_inv = true ); + std::list consume_items( const comp_selection &is, int batch, + const std::function &filter = return_true ); + std::list consume_items( map &m, const comp_selection &is, int batch, + const std::function &filter = return_true, + const tripoint &origin = tripoint_zero, int radius = PICKUP_RANGE ); + std::list consume_items( const std::vector &components, int batch = 1, + const std::function &filter = return_true ); + comp_selection + select_tool_component( const std::vector &tools, int batch, inventory &map_inv, + const std::string &hotkeys = DEFAULT_HOTKEYS, + bool can_cancel = false, bool player_inv = true, + std::function charges_required_modifier = []( int i ) { + return i; + } ); + /** Consume tools for the next multiplier * 5% progress of the craft */ + bool craft_consume_tools( item &craft, int mulitplier, bool start_craft ); + void consume_tools( const comp_selection &tool, int batch ); + void consume_tools( map &m, const comp_selection &tool, int batch, + const tripoint &origin = tripoint_zero, int radius = PICKUP_RANGE, + basecamp *bcp = nullptr ); + void consume_tools( const std::vector &tools, int batch = 1, + const std::string &hotkeys = DEFAULT_HOTKEYS ); + /** Checks permanent morale for consistency and recovers it when an inconsistency is found. */ void check_and_recover_morale(); @@ -2382,6 +2563,12 @@ class Character : public Creature, public visitable inventory cached_crafting_inventory; protected: + /** Subset of learned recipes. Needs to be mutable for lazy initialization. */ + mutable pimpl learned_recipes; + + /** Stamp of skills. @ref learned_recipes are valid only with this set of skills. */ + mutable decltype( _skills ) valid_autolearn_skills; + /** Amount of time the player has spent in each overmap tile. */ std::unordered_map overmap_time; diff --git a/src/character_crafting.cpp b/src/character_crafting.cpp new file mode 100644 index 0000000000000..6535bfa108f33 --- /dev/null +++ b/src/character_crafting.cpp @@ -0,0 +1,143 @@ +#include "character.h" + +#include "itype.h" +#include "recipe_dictionary.h" +#include "recipe.h" +#include "skill.h" +#include "player.h" +#include "npc.h" + +int Character::has_recipe( const recipe *r, const inventory &crafting_inv, + const std::vector &helpers ) const +{ + if( !r->skill_used ) { + return 0; + } + + if( knows_recipe( r ) ) { + return r->difficulty; + } + + const auto available = get_available_recipes( crafting_inv, &helpers ); + return available.contains( r ) ? available.get_custom_difficulty( r ) : -1; +} + +bool Character::knows_recipe( const recipe *rec ) const +{ + return get_learned_recipes().contains( rec ); +} + +void Character::learn_recipe( const recipe *const rec ) +{ + if( rec->never_learn ) { + return; + } + learned_recipes->include( rec ); +} + +int Character::exceeds_recipe_requirements( const recipe &rec ) const +{ + return get_all_skills().exceeds_recipe_requirements( rec ); +} + +bool Character::has_recipe_requirements( const recipe &rec ) const +{ + return get_all_skills().has_recipe_requirements( rec ); +} + +bool Character::can_decomp_learn( const recipe &rec ) const +{ + return !rec.learn_by_disassembly.empty() && + meets_skill_requirements( rec.learn_by_disassembly ); +} + +bool Character::studied_all_recipes( const itype &book ) const +{ + if( !book.book ) { + return true; + } + for( auto &elem : book.book->recipes ) { + if( !knows_recipe( elem.recipe ) ) { + return false; + } + } + return true; +} +const recipe_subset &Character::get_learned_recipes() const +{ + // Cache validity check + if( *_skills != *valid_autolearn_skills ) { + for( const auto &r : recipe_dict.all_autolearn() ) { + if( meets_skill_requirements( r->autolearn_requirements ) ) { + learned_recipes->include( r ); + } + } + *valid_autolearn_skills = *_skills; // Reassign the validity stamp + } + + return *learned_recipes; +} + +recipe_subset Character::get_recipes_from_books( const inventory &crafting_inv ) const +{ + recipe_subset res; + + for( const auto &stack : crafting_inv.const_slice() ) { + const item &candidate = stack->front(); + + for( std::pair recipe_entry : + candidate.get_available_recipes( *this ) ) { + res.include( recipe_entry.first, recipe_entry.second ); + } + } + + return res; +} + +recipe_subset Character::get_available_recipes( const inventory &crafting_inv, + const std::vector *helpers ) const +{ + recipe_subset res( get_learned_recipes() ); + + res.include( get_recipes_from_books( crafting_inv ) ); + + if( helpers != nullptr ) { + for( npc *np : *helpers ) { + // Directly form the helper's inventory + res.include( get_recipes_from_books( np->inv ) ); + // Being told what to do + res.include_if( np->get_learned_recipes(), [ this ]( const recipe & r ) { + return get_skill_level( r.skill_used ) >= static_cast( r.difficulty * + 0.8f ); // Skilled enough to understand + } ); + } + } + + return res; +} + +std::set Character::get_books_for_recipe( const inventory &crafting_inv, + const recipe *r ) const +{ + std::set book_ids; + const int skill_level = get_skill_level( r->skill_used ); + for( auto &book_lvl : r->booksets ) { + itype_id book_id = book_lvl.first; + int required_skill_level = book_lvl.second; + // NPCs don't need to identify books + if( !has_identified( book_id ) ) { + continue; + } + + if( skill_level >= required_skill_level && crafting_inv.amount_of( book_id ) > 0 ) { + book_ids.insert( book_id ); + } + } + return book_ids; +} + +int Character::get_num_crafting_helpers( int max ) const +{ + std::vector helpers = get_crafting_helpers(); + return std::min( max, static_cast( helpers.size() ) ); +} diff --git a/src/craft_command.h b/src/craft_command.h index a99e223670faa..f05f6e1362fde 100644 --- a/src/craft_command.h +++ b/src/craft_command.h @@ -14,7 +14,7 @@ class JsonIn; class JsonOut; class inventory; class item; -class player; +class Character; template struct enum_traits; /** @@ -66,7 +66,7 @@ class craft_command public: /** Instantiates an empty craft_command, which can't be executed. */ craft_command() = default; - craft_command( const recipe *to_make, int batch_size, bool is_long, player *crafter, + craft_command( const recipe *to_make, int batch_size, bool is_long, Character *crafter, const tripoint &loc = tripoint_zero ) : rec( to_make ), batch_size( batch_size ), longcraft( is_long ), crafter( crafter ), loc( loc ) {} @@ -101,7 +101,7 @@ class craft_command */ bool longcraft = false; // This is mainly here for maintainability reasons. - player *crafter; + Character *crafter; recipe_filter_flags flags = recipe_filter_flags::none; diff --git a/src/crafting.cpp b/src/crafting.cpp index 0ec2697d80965..8a3f3606d6afb 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -107,7 +107,7 @@ static const std::string flag_VARSIZE( "VARSIZE" ); class basecamp; -static bool crafting_allowed( const player &p, const recipe &rec ) +static bool crafting_allowed( const Character &p, const recipe &rec ) { if( p.morale_crafting_speed_multiplier( rec ) <= 0.0f ) { add_msg( m_info, _( "Your morale is too low to craft such a difficult thingā€¦" ) ); @@ -126,7 +126,7 @@ static bool crafting_allowed( const player &p, const recipe &rec ) return true; } -float player::lighting_craft_speed_multiplier( const recipe &rec ) const +float Character::lighting_craft_speed_multiplier( const recipe &rec ) const { // negative is bright, 0 is just bright enough, positive is dark, +7.0f is pitch black float darkness = fine_detail_vision_mod() - 4.0f; @@ -154,7 +154,7 @@ float player::lighting_craft_speed_multiplier( const recipe &rec ) const return 0.0f; // it's dark and you could craft this if you had more skill } -float player::morale_crafting_speed_multiplier( const recipe &rec ) const +float Character::morale_crafting_speed_multiplier( const recipe &rec ) const { int morale = get_morale_level(); if( morale >= 0 ) { @@ -241,7 +241,7 @@ static float workbench_crafting_speed_multiplier( const item &craft, const tripo return multiplier; } -float player::crafting_speed_multiplier( const recipe &rec, bool in_progress ) const +float Character::crafting_speed_multiplier( const recipe &rec, bool in_progress ) const { const float result = morale_crafting_speed_multiplier( rec ) * lighting_craft_speed_multiplier( rec ); @@ -257,7 +257,7 @@ float player::crafting_speed_multiplier( const recipe &rec, bool in_progress ) c return result; } -float player::crafting_speed_multiplier( const item &craft, const tripoint &loc ) const +float Character::crafting_speed_multiplier( const item &craft, const tripoint &loc ) const { if( !craft.is_craft() ) { debugmsg( "Can't calculate crafting speed multiplier of non-craft '%s'", craft.tname() ); @@ -314,7 +314,7 @@ bool Character::has_morale_to_craft() const return get_morale_level() >= -50; } -void player::craft( const tripoint &loc ) +void Character::craft( const tripoint &loc ) { int batch_size = 0; const recipe *rec = select_crafting_recipe( batch_size ); @@ -325,7 +325,7 @@ void player::craft( const tripoint &loc ) } } -void player::recraft( const tripoint &loc ) +void Character::recraft( const tripoint &loc ) { if( lastrecipe.str().empty() ) { popup( _( "Craft something first" ) ); @@ -334,7 +334,7 @@ void player::recraft( const tripoint &loc ) } } -void player::long_craft( const tripoint &loc ) +void Character::long_craft( const tripoint &loc ) { int batch_size = 0; const recipe *rec = select_crafting_recipe( batch_size ); @@ -345,7 +345,7 @@ void player::long_craft( const tripoint &loc ) } } -bool player::making_would_work( const recipe_id &id_to_make, int batch_size ) +bool Character::making_would_work( const recipe_id &id_to_make, int batch_size ) { const auto &making = *id_to_make; if( !( making && crafting_allowed( *this, making ) ) ) { @@ -363,9 +363,9 @@ bool player::making_would_work( const recipe_id &id_to_make, int batch_size ) return check_eligible_containers_for_crafting( making, batch_size ); } -int player::available_assistant_count( const recipe &rec ) const +int Character::available_assistant_count( const recipe &rec ) const +// NPCs around you should assist in batch production if they have the skills { - // NPCs around you should assist in batch production if they have the skills // TODO: Cache them in activity, include them in modifier calculations const auto helpers = get_crafting_helpers(); return std::count_if( helpers.begin(), helpers.end(), @@ -374,20 +374,20 @@ int player::available_assistant_count( const recipe &rec ) const } ); } -int player::base_time_to_craft( const recipe &rec, int batch_size ) const +int Character::base_time_to_craft( const recipe &rec, int batch_size ) const { const size_t assistants = available_assistant_count( rec ); return rec.batch_time( *this, batch_size, 1.0f, assistants ); } -int player::expected_time_to_craft( const recipe &rec, int batch_size, bool in_progress ) const +int Character::expected_time_to_craft( const recipe &rec, int batch_size, bool in_progress ) const { const size_t assistants = available_assistant_count( rec ); float modifier = crafting_speed_multiplier( rec, in_progress ); return rec.batch_time( *this, batch_size, modifier, assistants ); } -bool player::check_eligible_containers_for_crafting( const recipe &rec, int batch_size ) const +bool Character::check_eligible_containers_for_crafting( const recipe &rec, int batch_size ) const { std::vector conts = get_eligible_containers_for_crafting(); const std::vector res = rec.create_results( batch_size ); @@ -450,7 +450,7 @@ static bool is_container_eligible_for_crafting( const item &cont, bool allow_buc return false; } -std::vector player::get_eligible_containers_for_crafting() const +std::vector Character::get_eligible_containers_for_crafting() const { std::vector conts; @@ -498,7 +498,7 @@ std::vector player::get_eligible_containers_for_crafting() const return conts; } -bool player::can_make( const recipe *r, int batch_size ) +bool Character::can_make( const recipe *r, int batch_size ) { const inventory &crafting_inv = crafting_inventory(); @@ -514,7 +514,7 @@ bool player::can_make( const recipe *r, int batch_size ) crafting_inv, r->get_component_filter(), batch_size ); } -bool player::can_start_craft( const recipe *rec, recipe_filter_flags flags, int batch_size ) +bool Character::can_start_craft( const recipe *rec, recipe_filter_flags flags, int batch_size ) { if( !rec ) { return false; @@ -581,18 +581,18 @@ void Character::invalidate_crafting_inventory() cached_time = calendar::before_time_starts; } -void player::make_craft( const recipe_id &id_to_make, int batch_size, const tripoint &loc ) +void Character::make_craft( const recipe_id &id_to_make, int batch_size, const tripoint &loc ) { make_craft_with_command( id_to_make, batch_size, false, loc ); } -void player::make_all_craft( const recipe_id &id_to_make, int batch_size, const tripoint &loc ) +void Character::make_all_craft( const recipe_id &id_to_make, int batch_size, const tripoint &loc ) { make_craft_with_command( id_to_make, batch_size, true, loc ); } -void player::make_craft_with_command( const recipe_id &id_to_make, int batch_size, bool is_long, - const tripoint &loc ) +void Character::make_craft_with_command( const recipe_id &id_to_make, int batch_size, bool is_long, + const tripoint &loc ) { const auto &recipe_to_make = *id_to_make; @@ -630,7 +630,7 @@ static void set_components( std::list &components, const std::list & } } -static cata::optional wield_craft( player &p, item &craft ) +static cata::optional wield_craft( Character &p, item &craft ) { if( p.wield( craft ) ) { if( p.weapon.invlet ) { @@ -643,7 +643,7 @@ static cata::optional wield_craft( player &p, item &craft ) return cata::nullopt; } -static item *set_item_inventory( player &p, item &newit ) +static item *set_item_inventory( Character &p, item &newit ) { item *ret_val = nullptr; if( newit.made_of( phase_id::LIQUID ) ) { @@ -685,7 +685,7 @@ static item_location set_item_map( const tripoint &loc, item &newit ) /** * Set an item on the map or in a vehicle and return the new location */ -static item_location set_item_map_or_vehicle( const player &p, const tripoint &loc, item &newit ) +static item_location set_item_map_or_vehicle( const Character &p, const tripoint &loc, item &newit ) { map &here = get_map(); if( const cata::optional vp = here.veh_at( loc ).part_with_feature( "CARGO", @@ -726,7 +726,7 @@ static item_location set_item_map_or_vehicle( const player &p, const tripoint &l } } -void player::start_craft( craft_command &command, const tripoint &loc ) +void Character::start_craft( craft_command &command, const tripoint &loc ) { if( command.empty() ) { debugmsg( "Attempted to start craft with empty command" ); @@ -849,7 +849,7 @@ void player::start_craft( craft_command &command, const tripoint &loc ) craft.tname() ); } -void player::craft_skill_gain( const item &craft, const int &multiplier ) +void Character::craft_skill_gain( const item &craft, const int &multiplier ) { if( !craft.is_craft() ) { debugmsg( "craft_skill_check() called on non-craft '%s.' Aborting.", craft.tname() ); @@ -894,7 +894,7 @@ void player::craft_skill_gain( const item &craft, const int &multiplier ) } } -double player::crafting_success_roll( const recipe &making ) const +double Character::crafting_success_roll( const recipe &making ) const { int secondary_dice = 0; int secondary_difficulty = 0; @@ -985,7 +985,7 @@ int item::get_next_failure_point() const return craft_data_->next_failure_point >= 0 ? craft_data_->next_failure_point : INT_MAX; } -void item::set_next_failure_point( const player &crafter ) +void item::set_next_failure_point( const Character &crafter ) { if( !is_craft() ) { debugmsg( "set_next_failure_point() called on non-craft '%s.' Aborting.", tname() ); @@ -998,7 +998,7 @@ void item::set_next_failure_point( const player &crafter ) craft_data_->next_failure_point = item_counter + failure_point_delta; } -static void destroy_random_component( item &craft, const player &crafter ) +static void destroy_random_component( item &craft, const Character &crafter ) { if( craft.components.empty() ) { debugmsg( "destroy_random_component() called on craft with no components! Aborting" ); @@ -1011,7 +1011,7 @@ static void destroy_random_component( item &craft, const player &crafter ) _( " messes up and destroys the %s" ), destroyed.tname() ); } -bool item::handle_craft_failure( player &crafter ) +bool item::handle_craft_failure( Character &crafter ) { if( !is_craft() ) { debugmsg( "handle_craft_failure() called on non-craft '%s.' Aborting.", tname() ); @@ -1100,7 +1100,7 @@ void item::inherit_flags( const std::list &parents, const recipe &making ) } } -void player::complete_craft( item &craft, const tripoint &loc ) +void Character::complete_craft( item &craft, const tripoint &loc ) { if( !craft.is_craft() ) { debugmsg( "complete_craft() called on non-craft '%s.' Aborting.", craft.tname() ); @@ -1268,7 +1268,7 @@ void player::complete_craft( item &craft, const tripoint &loc ) inv.restack( *this ); } -bool player::can_continue_craft( item &craft ) +bool Character::can_continue_craft( item &craft ) { if( !craft.is_craft() ) { debugmsg( "complete_craft() called on non-craft '%s.' Aborting.", craft.tname() ); @@ -1388,7 +1388,7 @@ bool player::can_continue_craft( item &craft ) return true; } -const requirement_data *player::select_requirements( +const requirement_data *Character::select_requirements( const std::vector &alternatives, int batch, const inventory &inv, const std::function &filter ) const { @@ -1421,7 +1421,8 @@ const requirement_data *player::select_requirements( } /* selection of component if a recipe requirement has multiple options (e.g. 'duct tap' or 'welder') */ -comp_selection player::select_item_component( const std::vector &components, +comp_selection Character::select_item_component( const std::vector + &components, int batch, inventory &map_inv, bool can_cancel, const std::function &filter, bool player_inv ) { @@ -1593,7 +1594,7 @@ comp_selection player::select_item_component( const std::vector player::consume_items( const comp_selection &is, int batch, - const std::function &filter ) +std::list Character::consume_items( const comp_selection &is, int batch, + const std::function &filter ) { return consume_items( get_map(), is, batch, filter, pos(), PICKUP_RANGE ); } -std::list player::consume_items( map &m, const comp_selection &is, int batch, - const std::function &filter, - const tripoint &origin, int radius ) +std::list Character::consume_items( map &m, const comp_selection &is, int batch, + const std::function &filter, + const tripoint &origin, int radius ) { std::list ret; @@ -1670,8 +1671,8 @@ std::list player::consume_items( map &m, const comp_selection & /* This call is in-efficient when doing it for multiple items with the same map inventory. In that case, consider using select_item_component with 1 pre-created map inventory, and then passing the results to consume_items */ -std::list player::consume_items( const std::vector &components, int batch, - const std::function &filter ) +std::list Character::consume_items( const std::vector &components, int batch, + const std::function &filter ) { inventory map_inv; map_inv.form_from_map( pos(), PICKUP_RANGE, this ); @@ -1680,9 +1681,10 @@ std::list player::consume_items( const std::vector &components, } comp_selection -player::select_tool_component( const std::vector &tools, int batch, inventory &map_inv, - const std::string &hotkeys, bool can_cancel, bool player_inv, - const std::function charges_required_modifier ) +Character::select_tool_component( const std::vector &tools, int batch, + inventory &map_inv, + const std::string &hotkeys, bool can_cancel, bool player_inv, + const std::function charges_required_modifier ) { comp_selection selected; @@ -1795,7 +1797,7 @@ player::select_tool_component( const std::vector &tools, int batch, i return selected; } -bool player::craft_consume_tools( item &craft, int mulitplier, bool start_craft ) +bool Character::craft_consume_tools( item &craft, int mulitplier, bool start_craft ) { if( !craft.is_craft() ) { debugmsg( "craft_consume_tools() called on non-craft '%s.' Aborting.", craft.tname() ); @@ -1882,14 +1884,14 @@ bool player::craft_consume_tools( item &craft, int mulitplier, bool start_craft return true; } -void player::consume_tools( const comp_selection &tool, int batch ) +void Character::consume_tools( const comp_selection &tool, int batch ) { consume_tools( get_map(), tool, batch, pos(), PICKUP_RANGE ); } /* we use this if we selected the tool earlier */ -void player::consume_tools( map &m, const comp_selection &tool, int batch, - const tripoint &origin, int radius, basecamp *bcp ) +void Character::consume_tools( map &m, const comp_selection &tool, int batch, + const tripoint &origin, int radius, basecamp *bcp ) { if( has_trait( trait_DEBUG_HS ) ) { return; @@ -1910,15 +1912,15 @@ void player::consume_tools( map &m, const comp_selection &tool, int b /* This call is in-efficient when doing it for multiple items with the same map inventory. In that case, consider using select_tool_component with 1 pre-created map inventory, and then passing the results to consume_tools */ -void player::consume_tools( const std::vector &tools, int batch, - const std::string &hotkeys ) +void Character::consume_tools( const std::vector &tools, int batch, + const std::string &hotkeys ) { inventory map_inv; map_inv.form_from_map( pos(), PICKUP_RANGE, this ); consume_tools( select_tool_component( tools, batch, map_inv, hotkeys ), batch ); } -ret_val player::can_disassemble( const item &obj, const inventory &inv ) const +ret_val Character::can_disassemble( const item &obj, const inventory &inv ) const { if( !obj.is_disassemblable() ) { return ret_val::make_failure( _( "You cannot disassemble this." ) ); @@ -1991,12 +1993,12 @@ ret_val player::can_disassemble( const item &obj, const inventory &inv ) c return ret_val::make_success(); } -bool player::disassemble() +bool Character::disassemble() { return disassemble( game_menus::inv::disassemble( *this ), false ); } -bool player::disassemble( item_location target, bool interactive ) +bool Character::disassemble( item_location target, bool interactive ) { if( !target ) { add_msg( _( "Never mind." ) ); @@ -2094,7 +2096,7 @@ bool player::disassemble( item_location target, bool interactive ) return true; } -void player::disassemble_all( bool one_pass ) +void Character::disassemble_all( bool one_pass ) { // Reset all the activity values assign_activity( ACT_DISASSEMBLE, 0 ); @@ -2117,7 +2119,7 @@ void player::disassemble_all( bool one_pass ) } } -void player::complete_disassemble() +void Character::complete_disassemble() { // Cancel the activity if we have bad (possibly legacy) values if( activity.targets.empty() || !activity.targets.back() || @@ -2168,7 +2170,7 @@ void player::complete_disassemble() activity.moves_left = next_recipe.time_to_craft_moves( *this ); } -void player::complete_disassemble( item_location &target, const recipe &dis ) +void Character::complete_disassemble( item_location &target, const recipe &dis ) { // Get the proper recipe - the one for disassembly, not assembly const auto dis_requirements = dis.disassembly_requirements(); @@ -2345,7 +2347,7 @@ void player::complete_disassemble( item_location &target, const recipe &dis ) } } -void remove_ammo( std::list &dis_items, player &p ) +void remove_ammo( std::list &dis_items, Character &p ) { for( auto &dis_item : dis_items ) { remove_ammo( dis_item, p ); @@ -2362,7 +2364,7 @@ void drop_or_handle( const item &newit, Character &p ) } } -void remove_ammo( item &dis_item, player &p ) +void remove_ammo( item &dis_item, Character &p ) { dis_item.remove_items_with( [&p]( const item & it ) { if( it.is_irremovable() ) { @@ -2392,7 +2394,7 @@ void remove_ammo( item &dis_item, player &p ) } } -std::vector player::get_crafting_helpers() const +std::vector Character::get_crafting_helpers() const { return g->get_npcs_if( [this]( const npc & guy ) { // NPCs can help craft if awake, taking orders, within pickup range and have clear path diff --git a/src/crafting.h b/src/crafting.h index e21c4a4297faa..0b03d28eb56b2 100644 --- a/src/crafting.h +++ b/src/crafting.h @@ -20,9 +20,9 @@ inline constexpr craft_flags operator&( craft_flags l, craft_flags r ) // removes any (removable) ammo from the item and stores it in the // players inventory. -void remove_ammo( item &dis_item, player &p ); +void remove_ammo( item &dis_item, Character &p ); // same as above but for each item in the list -void remove_ammo( std::list &dis_items, player &p ); +void remove_ammo( std::list &dis_items, Character &p ); void drop_or_handle( const item &newit, Character &p ); #endif // CATA_SRC_CRAFTING_H diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index 49828e2564b33..008d66446436d 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -120,7 +120,7 @@ static item_location_filter convert_filter( const item_filter &filter ) }; } -static item_location inv_internal( player &u, const inventory_selector_preset &preset, +static item_location inv_internal( Character &u, const inventory_selector_preset &preset, const std::string &title, int radius, const std::string &none_message, const std::string &hint = std::string() ) @@ -426,7 +426,7 @@ item_location game_menus::inv::container_for( avatar &you, const item &liquid, i class pickup_inventory_preset : public inventory_selector_preset { public: - pickup_inventory_preset( const player &p ) : p( p ) {} + pickup_inventory_preset( const Character &p ) : p( p ) {} std::string get_denial( const item_location &loc ) const override { if( !p.has_item( *loc ) ) { @@ -443,13 +443,13 @@ class pickup_inventory_preset : public inventory_selector_preset } private: - const player &p; + const Character &p; }; class disassemble_inventory_preset : public pickup_inventory_preset { public: - disassemble_inventory_preset( const player &p, const inventory &inv ) : + disassemble_inventory_preset( const Character &p, const inventory &inv ) : pickup_inventory_preset( p ), p( p ), inv( inv ) { check_components = true; @@ -490,11 +490,11 @@ class disassemble_inventory_preset : public pickup_inventory_preset } private: - const player &p; + const Character &p; const inventory &inv; }; -item_location game_menus::inv::disassemble( player &p ) +item_location game_menus::inv::disassemble( Character &p ) { return inv_internal( p, disassemble_inventory_preset( p, p.crafting_inventory() ), _( "Disassemble item" ), 1, diff --git a/src/game_inventory.h b/src/game_inventory.h index ce5d6ae2b4b1d..3353a73a8b5d2 100644 --- a/src/game_inventory.h +++ b/src/game_inventory.h @@ -86,7 +86,7 @@ item_location consume_meds( player &p ); /** Choosing a container for liquid. */ item_location container_for( avatar &you, const item &liquid, int radius = 0 ); /** Item disassembling menu. */ -item_location disassemble( player &p ); +item_location disassemble( Character &p ); /** Gunmod installation menu. */ item_location gun_to_modify( player &p, const item &gunmod ); /** Book reading menu. */ diff --git a/src/inventory.cpp b/src/inventory.cpp index ca1f21e9859ea..9723c37d4564a 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -335,7 +335,7 @@ void inventory::push_back( item newit ) extern void remove_stale_inventory_quick_shortcuts(); #endif -void inventory::restack( player &p ) +void inventory::restack( Character &p ) { // tasks that the old restack seemed to do: // 1. reassign inventory letters diff --git a/src/inventory.h b/src/inventory.h index 0b935752c3ee3..aa005773ae257 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -124,7 +124,7 @@ class inventory : public visitable * game pointer is not necessary, but if supplied, will ensure no overlap with * the player's worn items / weapon */ - void restack( player &p ); + void restack( Character &p ); void form_from_zone( map &m, std::unordered_set &zone_pts, const Character *pl = nullptr, bool assign_invlet = true ); void form_from_map( const tripoint &origin, int range, const Character *pl = nullptr, diff --git a/src/item.cpp b/src/item.cpp index bc96a17648187..9b6de1d7f0362 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -7020,7 +7020,7 @@ void item::mark_chapter_as_read( const player &u ) set_var( var, remain ); } -std::vector> item::get_available_recipes( const player &u ) const +std::vector> item::get_available_recipes( const Character &u ) const { std::vector> recipe_entries; if( is_book() ) { diff --git a/src/item.h b/src/item.h index 770c159c87939..c5aed88575924 100644 --- a/src/item.h +++ b/src/item.h @@ -1696,7 +1696,7 @@ class item : public visitable /** * Enumerates recipes available from this book and the skill level required to use them. */ - std::vector> get_available_recipes( const player &u ) const; + std::vector> get_available_recipes( const Character &u ) const; /*@}*/ /** @@ -2096,7 +2096,7 @@ class item : public visitable * Causes a debugmsg if called on non-craft. * @param crafter the crafting player */ - void set_next_failure_point( const player &crafter ); + void set_next_failure_point( const Character &crafter ); /** * Handle failure during crafting. @@ -2104,7 +2104,7 @@ class item : public visitable * @param crafter the crafting player. * @return whether the craft being worked on should be entirely destroyed */ - bool handle_craft_failure( player &crafter ); + bool handle_craft_failure( Character &crafter ); /** * Returns requirement data representing what is needed to resume work on an in progress craft. diff --git a/src/iuse.cpp b/src/iuse.cpp index f4299b08e33ee..bc999f348e205 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -430,7 +430,7 @@ static const std::vector camera_ter_whitelist_types = { ter_str_id( "t_pit_spiked_covered" ), ter_str_id( "t_pit_glass" ), ter_str_id( "t_pit_glass" ), ter_str_id( "t_utility_light" ) }; -void remove_radio_mod( item &it, player &p ) +void remove_radio_mod( item &it, Character &p ) { if( !it.has_flag( "RADIO_MOD" ) ) { return; diff --git a/src/iuse.h b/src/iuse.h index 5930baf9b27dc..ddc3779b59180 100644 --- a/src/iuse.h +++ b/src/iuse.h @@ -241,7 +241,7 @@ int handle_ground_graffiti( Character &p, item *it, const std::string &prefix, } // namespace iuse -void remove_radio_mod( item &it, player &p ); +void remove_radio_mod( item &it, Character &p ); // Helper for clothes washing struct washing_requirements { diff --git a/src/player.cpp b/src/player.cpp index c8a6c308d7d7d..31d023f8281a9 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1069,12 +1069,6 @@ int player::get_lift_assist() const return result; } -int player::get_num_crafting_helpers( int max ) const -{ - std::vector helpers = get_crafting_helpers(); - return std::min( max, static_cast( helpers.size() ) ); -} - bool player::immune_to( const bodypart_id &bp, damage_unit dam ) const { if( has_trait( trait_DEBUG_NODMG ) || is_immune_damage( dam.type ) ) { @@ -2329,65 +2323,6 @@ item::reload_option player::select_ammo( const item &base, bool prompt, bool emp return select_ammo( base, std::move( ammo_list ) ); } -ret_val player::can_wield( const item &it ) const -{ - if( it.made_of_from_type( phase_id::LIQUID ) ) { - return ret_val::make_failure( _( "Can't wield spilt liquids." ) ); - } - - if( get_working_arm_count() <= 0 ) { - return ret_val::make_failure( - _( "You need at least one arm to even consider wielding something." ) ); - } - - if( is_armed() && !can_unwield( weapon ).success() ) { - return ret_val::make_failure( _( "The %s is preventing you from wielding the %s." ), - weapname(), it.tname() ); - } - - if( it.is_two_handed( *this ) && ( !has_two_arms() || worn_with_flag( "RESTRICT_HANDS" ) ) ) { - if( worn_with_flag( "RESTRICT_HANDS" ) ) { - return ret_val::make_failure( - _( "Something you are wearing hinders the use of both hands." ) ); - } else if( it.has_flag( "ALWAYS_TWOHAND" ) ) { - return ret_val::make_failure( _( "The %s can't be wielded with only one arm." ), - it.tname() ); - } else { - return ret_val::make_failure( _( "You are too weak to wield %s with only one arm." ), - it.tname() ); - } - } - - return ret_val::make_success(); -} - -bool player::unwield() -{ - if( weapon.is_null() ) { - return true; - } - - if( !can_unwield( weapon ).success() ) { - return false; - } - - // currently the only way to unwield NO_UNWIELD weapon is if it's a bionic that can be deactivated - if( weapon.has_flag( "NO_UNWIELD" ) ) { - cata::optional wi = active_bionic_weapon_index(); - return wi && deactivate_bionic( *wi ); - } - - const std::string query = string_format( _( "Stop wielding %s?" ), weapon.tname() ); - - if( !dispose_item( item_location( *this, &weapon ), query ) ) { - return false; - } - - inv.unsort(); - - return true; -} - // ids of martial art styles that are available with the bio_cqb bionic. static const std::vector bio_cqb_styles{ { matype_id{ "style_aikido" }, @@ -3357,92 +3292,6 @@ int player::book_fun_for( const item &book, const player &p ) const return fun_bonus; } -bool player::studied_all_recipes( const itype &book ) const -{ - if( !book.book ) { - return true; - } - for( auto &elem : book.book->recipes ) { - if( !knows_recipe( elem.recipe ) ) { - return false; - } - } - return true; -} - -const recipe_subset &player::get_learned_recipes() const -{ - // Cache validity check - if( *_skills != *valid_autolearn_skills ) { - for( const auto &r : recipe_dict.all_autolearn() ) { - if( meets_skill_requirements( r->autolearn_requirements ) ) { - learned_recipes->include( r ); - } - } - *valid_autolearn_skills = *_skills; // Reassign the validity stamp - } - - return *learned_recipes; -} - -recipe_subset player::get_recipes_from_books( const inventory &crafting_inv ) const -{ - recipe_subset res; - - for( const auto &stack : crafting_inv.const_slice() ) { - const item &candidate = stack->front(); - - for( std::pair recipe_entry : - candidate.get_available_recipes( *this ) ) { - res.include( recipe_entry.first, recipe_entry.second ); - } - } - - return res; -} - -std::set player::get_books_for_recipe( const inventory &crafting_inv, - const recipe *r ) const -{ - std::set book_ids; - const int skill_level = get_skill_level( r->skill_used ); - for( auto &book_lvl : r->booksets ) { - itype_id book_id = book_lvl.first; - int required_skill_level = book_lvl.second; - // NPCs don't need to identify books - if( !has_identified( book_id ) ) { - continue; - } - - if( skill_level >= required_skill_level && crafting_inv.amount_of( book_id ) > 0 ) { - book_ids.insert( book_id ); - } - } - return book_ids; -} - -recipe_subset player::get_available_recipes( const inventory &crafting_inv, - const std::vector *helpers ) const -{ - recipe_subset res( get_learned_recipes() ); - - res.include( get_recipes_from_books( crafting_inv ) ); - - if( helpers != nullptr ) { - for( npc *np : *helpers ) { - // Directly form the helper's inventory - res.include( get_recipes_from_books( np->inv ) ); - // Being told what to do - res.include_if( np->get_learned_recipes(), [ this ]( const recipe & r ) { - return get_skill_level( r.skill_used ) >= static_cast( r.difficulty * - 0.8f ); // Skilled enough to understand - } ); - } - } - - return res; -} - void player::try_to_sleep( const time_duration &dur ) { map &here = get_map(); @@ -3655,176 +3504,6 @@ bool player::can_sleep() return result; } -// Returned values range from 1.0 (unimpeded vision) to 11.0 (totally blind). -// 1.0 is LIGHT_AMBIENT_LIT or brighter -// 4.0 is a dark clear night, barely bright enough for reading and crafting -// 6.0 is LIGHT_AMBIENT_DIM -// 7.3 is LIGHT_AMBIENT_MINIMAL, a dark cloudy night, unlit indoors -// 11.0 is zero light or blindness -float player::fine_detail_vision_mod( const tripoint &p ) const -{ - // PER_SLIME_OK implies you can get enough eyes around the bile - // that you can generally see. There still will be the haze, but - // it's annoying rather than limiting. - if( is_blind() || - ( ( has_effect( effect_boomered ) || has_effect( effect_darkness ) ) && - !has_trait( trait_PER_SLIME_OK ) ) ) { - return 11.0; - } - // Scale linearly as light level approaches LIGHT_AMBIENT_LIT. - // If we're actually a source of light, assume we can direct it where we need it. - // Therefore give a hefty bonus relative to ambient light. - float own_light = std::max( 1.0f, LIGHT_AMBIENT_LIT - active_light() - 2.0f ); - - // Same calculation as above, but with a result 3 lower. - float ambient_light = std::max( 1.0f, - LIGHT_AMBIENT_LIT - get_map().ambient_light_at( p == tripoint_zero ? pos() : p ) + 1.0f ); - - return std::min( own_light, ambient_light ); -} - -void player::practice( const skill_id &id, int amount, int cap, bool suppress_warning ) -{ - SkillLevel &level = get_skill_level_object( id ); - const Skill &skill = id.obj(); - if( !level.can_train() && !in_sleep_state() ) { - // If leveling is disabled, don't train, don't drain focus, don't print anything - // Leaving as a skill method rather than global for possible future skill cap setting - return; - } - - const auto highest_skill = [&]() { - std::pair result( skill_id::NULL_ID(), -1 ); - for( const auto &pair : *_skills ) { - const SkillLevel &lobj = pair.second; - if( lobj.level() > result.second ) { - result = std::make_pair( pair.first, lobj.level() ); - } - } - return result.first; - }; - - const bool isSavant = has_trait( trait_SAVANT ); - const skill_id savantSkill = isSavant ? highest_skill() : skill_id::NULL_ID(); - - amount = adjust_for_focus( amount ); - - if( has_trait( trait_PACIFIST ) && skill.is_combat_skill() ) { - if( !one_in( 3 ) ) { - amount = 0; - } - } - if( has_trait_flag( "PRED2" ) && skill.is_combat_skill() ) { - if( one_in( 3 ) ) { - amount *= 2; - } - } - if( has_trait_flag( "PRED3" ) && skill.is_combat_skill() ) { - amount *= 2; - } - - if( has_trait_flag( "PRED4" ) && skill.is_combat_skill() ) { - amount *= 3; - } - - if( isSavant && id != savantSkill ) { - amount /= 2; - } - - if( amount > 0 && get_skill_level( id ) > cap ) { //blunt grinding cap implementation for crafting - amount = 0; - if( !suppress_warning ) { - handle_skill_warning( id, false ); - } - } - if( amount > 0 && level.isTraining() ) { - int oldLevel = get_skill_level( id ); - get_skill_level_object( id ).train( amount ); - int newLevel = get_skill_level( id ); - std::string skill_name = skill.name(); - if( newLevel > oldLevel ) { - g->events().send( getID(), id, newLevel ); - } - if( is_player() && newLevel > oldLevel ) { - add_msg( m_good, _( "Your skill in %s has increased to %d!" ), skill_name, newLevel ); - } - if( is_player() && newLevel > cap ) { - //inform player immediately that the current recipe can't be used to train further - add_msg( m_info, _( "You feel that %s tasks of this level are becoming trivial." ), - skill_name ); - } - - int chance_to_drop = focus_pool; - focus_pool -= chance_to_drop / 100; - // Apex Predators don't think about much other than killing. - // They don't lose Focus when practicing combat skills. - if( ( rng( 1, 100 ) <= ( chance_to_drop % 100 ) ) && ( !( has_trait_flag( "PRED4" ) && - skill.is_combat_skill() ) ) ) { - focus_pool--; - } - } - - get_skill_level_object( id ).practice(); -} - -void player::handle_skill_warning( const skill_id &id, bool force_warning ) -{ - //remind the player intermittently that no skill gain takes place - if( is_player() && ( force_warning || one_in( 5 ) ) ) { - SkillLevel &level = get_skill_level_object( id ); - - const Skill &skill = id.obj(); - std::string skill_name = skill.name(); - int curLevel = level.level(); - - add_msg( m_info, _( "This task is too simple to train your %s beyond %d." ), - skill_name, curLevel ); - } -} - -int player::exceeds_recipe_requirements( const recipe &rec ) const -{ - return get_all_skills().exceeds_recipe_requirements( rec ); -} - -bool player::has_recipe_requirements( const recipe &rec ) const -{ - return get_all_skills().has_recipe_requirements( rec ); -} - -bool player::can_decomp_learn( const recipe &rec ) const -{ - return !rec.learn_by_disassembly.empty() && - meets_skill_requirements( rec.learn_by_disassembly ); -} - -bool player::knows_recipe( const recipe *rec ) const -{ - return get_learned_recipes().contains( rec ); -} - -int player::has_recipe( const recipe *r, const inventory &crafting_inv, - const std::vector &helpers ) const -{ - if( !r->skill_used ) { - return 0; - } - - if( knows_recipe( r ) ) { - return r->difficulty; - } - - const auto available = get_available_recipes( crafting_inv, &helpers ); - return available.contains( r ) ? available.get_custom_difficulty( r ) : -1; -} - -void player::learn_recipe( const recipe *const rec ) -{ - if( rec->never_learn ) { - return; - } - learned_recipes->include( rec ); -} bool player::has_gun_for_ammo( const ammotype &at ) const { @@ -3845,36 +3524,6 @@ bool player::has_magazine_for_ammo( const ammotype &at ) const } ); } -std::string player::weapname() const -{ - if( weapon.is_gun() ) { - std::string gunmode; - // only required for empty mags and empty guns - std::string mag_ammo; - if( weapon.gun_all_modes().size() > 1 ) { - gunmode = weapon.gun_current_mode().tname(); - } - - if( weapon.ammo_remaining() == 0 ) { - if( weapon.magazine_current() != nullptr ) { - const item *mag = weapon.magazine_current(); - mag_ammo = string_format( " (0/%d)", - mag->ammo_capacity( item( mag->ammo_default() ).ammo_type() ) ); - } else { - mag_ammo = _( " (empty)" ); - } - } - - return string_format( "%s%s%s", gunmode, weapon.display_name(), mag_ammo ); - - } else if( !is_armed() ) { - return _( "fists" ); - - } else { - return weapon.tname(); - } -} - bool player::wield_contents( item &container, item *internal_item, bool penalties, int base_cost ) { // if index not specified and container has multiple items then ask the player to choose one diff --git a/src/player.h b/src/player.h index dde53a1a251d0..5c762e7a3b7f8 100644 --- a/src/player.h +++ b/src/player.h @@ -52,8 +52,6 @@ struct requirement_data; enum class recipe_filter_flags : int; struct itype; -static const std::string DEFAULT_HOTKEYS( "1234567890abcdefghijklmnopqrstuvwxyz" ); - class recipe_subset; enum action_id : int; @@ -373,13 +371,6 @@ class player : public Character */ ret_val can_takeoff( const item &it, const std::list *res = nullptr ); - /** - * Check player capable of wielding an item. - * @param it Thing to be wielded - */ - ret_val can_wield( const item &it ) const; - - bool unwield(); /** * Attempt to mend an item (fix any current faults) @@ -462,8 +453,6 @@ class player : public Character void toolmod_add( item_location tool, item_location mod ); bool fun_to_read( const item &book ) const; - /** Note that we've read a book at least once. **/ - virtual bool has_identified( const itype_id &item_id ) const = 0; /** Handles sleep attempts by the player, starts ACT_TRY_SLEEP activity */ void try_to_sleep( const time_duration &dur ); @@ -478,13 +467,6 @@ class player : public Character bool bio_soporific_powered_at_last_sleep_check; public: - /** Returns a value from 1.0 to 5.0 that acts as a multiplier - * for the time taken to perform tasks that require detail vision, - * above 4.0 means these activities cannot be performed. - * takes pos as a parameter so that remote spots can be judged - * if they will potentially have enough light when player gets there */ - float fine_detail_vision_mod( const tripoint &p = tripoint_zero ) const; - //returns true if the warning is now beyond final and results in hostility. bool add_faction_warning( const faction_id &id ); int current_warnings_fac( const faction_id &id ); @@ -494,16 +476,9 @@ class player : public Character int kcal_speed_penalty() const; /** Returns the penalty to speed from thirst */ static int thirst_speed_penalty( int thirst ); - /** This handles giving xp for a skill */ - void practice( const skill_id &id, int amount, int cap = 99, bool suppress_warning = false ); - /** This handles warning the player that there current activity will not give them xp */ - void handle_skill_warning( const skill_id &id, bool force_warning = false ); void on_worn_item_transform( const item &old_it, const item &new_it ); - /** Get the formatted name of the currently wielded item (if any) with current gun mode (if gun) */ - std::string weapname() const; - void process_items(); /** * Remove charges from a specific item (given by its item position). @@ -536,146 +511,6 @@ class player : public Character bool has_gun_for_ammo( const ammotype &at ) const; bool has_magazine_for_ammo( const ammotype &at ) const; - // Checks crafting inventory for books providing the requested recipe. - // Then checks nearby NPCs who could provide it too. - // Returns -1 to indicate recipe not found, otherwise difficulty to learn. - int has_recipe( const recipe *r, const inventory &crafting_inv, - const std::vector &helpers ) const; - bool knows_recipe( const recipe *rec ) const; - void learn_recipe( const recipe *rec ); - int exceeds_recipe_requirements( const recipe &rec ) const; - bool has_recipe_requirements( const recipe &rec ) const; - bool can_decomp_learn( const recipe &rec ) const; - - bool studied_all_recipes( const itype &book ) const; - - /** Returns all known recipes. */ - const recipe_subset &get_learned_recipes() const; - /** Returns all recipes that are known from the books (either in inventory or nearby). */ - recipe_subset get_recipes_from_books( const inventory &crafting_inv ) const; - /** - * Returns all available recipes (from books and npc companions) - * @param crafting_inv Current available items to craft - * @param helpers List of NPCs that could help with crafting. - */ - recipe_subset get_available_recipes( const inventory &crafting_inv, - const std::vector *helpers = nullptr ) const; - /** - * Returns the set of book types in crafting_inv that provide the - * given recipe. - * @param crafting_inv Current available items that may contain readable books - * @param r Recipe to search for in the available books - */ - std::set get_books_for_recipe( const inventory &crafting_inv, - const recipe *r ) const; - - // crafting.cpp - float morale_crafting_speed_multiplier( const recipe &rec ) const; - float lighting_craft_speed_multiplier( const recipe &rec ) const; - float crafting_speed_multiplier( const recipe &rec, bool in_progress = false ) const; - /** For use with in progress crafts */ - float crafting_speed_multiplier( const item &craft, const tripoint &loc ) const; - int available_assistant_count( const recipe &rec ) const; - /** - * Time to craft not including speed multiplier - */ - int base_time_to_craft( const recipe &rec, int batch_size = 1 ) const; - /** - * Expected time to craft a recipe, with assumption that multipliers stay constant. - */ - int expected_time_to_craft( const recipe &rec, int batch_size = 1, bool in_progress = false ) const; - std::vector get_eligible_containers_for_crafting() const; - bool check_eligible_containers_for_crafting( const recipe &rec, int batch_size = 1 ) const; - bool can_make( const recipe *r, int batch_size = 1 ); // have components? - /** - * Returns true if the player can start crafting the recipe with the given batch size - * The player is not required to have enough tool charges to finish crafting, only to - * complete the first step (total / 20 + total % 20 charges) - */ - bool can_start_craft( const recipe *rec, recipe_filter_flags, int batch_size = 1 ); - bool making_would_work( const recipe_id &id_to_make, int batch_size ); - - /** - * Start various types of crafts - * @param loc the location of the workbench. tripoint_zero indicates crafting from inventory. - */ - void craft( const tripoint &loc = tripoint_zero ); - void recraft( const tripoint &loc = tripoint_zero ); - void long_craft( const tripoint &loc = tripoint_zero ); - void make_craft( const recipe_id &id, int batch_size, const tripoint &loc = tripoint_zero ); - void make_all_craft( const recipe_id &id, int batch_size, const tripoint &loc = tripoint_zero ); - /** consume components and create an active, in progress craft containing them */ - void start_craft( craft_command &command, const tripoint &loc ); - /** - * Calculate a value representing the success of the player at crafting the given recipe, - * taking player skill, recipe difficulty, npc helpers, and player mutations into account. - * @param making the recipe for which to calculate - * @return a value >= 0.0 with >= 1.0 representing unequivocal success - */ - double crafting_success_roll( const recipe &making ) const; - void complete_craft( item &craft, const tripoint &loc = tripoint_zero ); - /** - * Check if the player meets the requirements to continue the in progress craft and if - * unable to continue print messages explaining the reason. - * If the craft is missing components due to messing up, prompt to consume new ones to - * allow the craft to be continued. - * @param craft the currently in progress craft - * @return if the craft can be continued - */ - bool can_continue_craft( item &craft ); - /** Returns nearby NPCs ready and willing to help with crafting. */ - std::vector get_crafting_helpers() const; - int get_num_crafting_helpers( int max ) const; - /** - * Handle skill gain for player and followers during crafting - * @param craft the currently in progress craft - * @param multiplier what factor to multiply the base skill gain by. This is used to apply - * multiple steps of incremental skill gain simultaneously if needed. - */ - void craft_skill_gain( const item &craft, const int &multiplier ); - /** - * Check if the player can disassemble an item using the current crafting inventory - * @param obj Object to check for disassembly - * @param inv current crafting inventory - */ - ret_val can_disassemble( const item &obj, const inventory &inv ) const; - - bool disassemble(); - bool disassemble( item_location target, bool interactive = true ); - void disassemble_all( bool one_pass ); // Disassemble all items on the tile - void complete_disassemble(); - void complete_disassemble( item_location &target, const recipe &dis ); - - const requirement_data *select_requirements( - const std::vector &, int batch, const inventory &, - const std::function &filter ) const; - comp_selection - select_item_component( const std::vector &components, - int batch, inventory &map_inv, bool can_cancel = false, - const std::function &filter = return_true, bool player_inv = true ); - std::list consume_items( const comp_selection &is, int batch, - const std::function &filter = return_true ); - std::list consume_items( map &m, const comp_selection &is, int batch, - const std::function &filter = return_true, - const tripoint &origin = tripoint_zero, int radius = PICKUP_RANGE ); - std::list consume_items( const std::vector &components, int batch = 1, - const std::function &filter = return_true ); - comp_selection - select_tool_component( const std::vector &tools, int batch, inventory &map_inv, - const std::string &hotkeys = DEFAULT_HOTKEYS, - bool can_cancel = false, bool player_inv = true, - std::function charges_required_modifier = []( int i ) { - return i; - } ); - /** Consume tools for the next multiplier * 5% progress of the craft */ - bool craft_consume_tools( item &craft, int mulitplier, bool start_craft ); - void consume_tools( const comp_selection &tool, int batch ); - void consume_tools( map &m, const comp_selection &tool, int batch, - const tripoint &origin = tripoint_zero, int radius = PICKUP_RANGE, - basecamp *bcp = nullptr ); - void consume_tools( const std::vector &tools, int batch = 1, - const std::string &hotkeys = DEFAULT_HOTKEYS ); - // ---------------VALUES----------------- tripoint view_offset; // Relative direction of a grab, add to posx, posy to get the coordinates of the grabbed thing. @@ -698,14 +533,6 @@ class player : public Character vproto_id starting_vehicle; std::vector starting_pets; - void make_craft_with_command( const recipe_id &id_to_make, int batch_size, bool is_long = false, - const tripoint &loc = tripoint_zero ); - pimpl last_craft; - - recipe_id lastrecipe; - int last_batch; - itype_id lastconsumed; //used in crafting.cpp and construction.cpp - std::set follower_ids; void mod_stat( const std::string &stat, float modifier ) override; @@ -759,13 +586,6 @@ class player : public Character /** warnings from a faction about bad behavior */ std::map> warning_record; - protected: - - /** Subset of learned recipes. Needs to be mutable for lazy initialization. */ - mutable pimpl learned_recipes; - - /** Stamp of skills. @ref learned_recipes are valid only with this set of skills. */ - mutable decltype( _skills ) valid_autolearn_skills; }; #endif // CATA_SRC_PLAYER_H diff --git a/src/requirements.cpp b/src/requirements.cpp index 6f0c4775c48fc..2980fd08dc7f8 100644 --- a/src/requirements.cpp +++ b/src/requirements.cpp @@ -1454,14 +1454,14 @@ std::vector deduped_requirement_data::feasible_alterna } const requirement_data *deduped_requirement_data::select_alternative( - player &crafter, const std::function &filter, int batch, + Character &crafter, const std::function &filter, int batch, craft_flags flags ) const { return select_alternative( crafter, crafter.crafting_inventory(), filter, batch, flags ); } const requirement_data *deduped_requirement_data::select_alternative( - player &crafter, const inventory &inv, const std::function &filter, + Character &crafter, const inventory &inv, const std::function &filter, int batch, craft_flags flags ) const { const std::vector all_reqs = diff --git a/src/requirements.h b/src/requirements.h index a8bcefd880106..ecb8067770860 100644 --- a/src/requirements.h +++ b/src/requirements.h @@ -436,11 +436,11 @@ class deduped_requirement_data int batch = 1, craft_flags = craft_flags::none ) const; const requirement_data *select_alternative( - player &, const std::function &filter, int batch = 1, + Character &, const std::function &filter, int batch = 1, craft_flags = craft_flags::none ) const; const requirement_data *select_alternative( - player &, const inventory &, const std::function &filter, + Character &, const inventory &, const std::function &filter, int batch = 1, craft_flags = craft_flags::none ) const; bool can_make_with_inventory( From 094904ca66b1e8cf8c251b2066d21858c28c8e89 Mon Sep 17 00:00:00 2001 From: trioct Date: Tue, 14 Jul 2020 23:55:26 -0500 Subject: [PATCH 037/151] Fix another item deletion bug --- src/character.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/character.cpp b/src/character.cpp index b8d2ffc15d019..983f5c6032201 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -7797,7 +7797,7 @@ bool Character::dispose_item( item_location &&obj, const std::string &prompt ) } moves -= item_handling_cost( *obj ); - this->i_add( *obj ); + this->i_add( *obj, true, &*obj ); obj.remove_item(); return true; } From 0907f8c2302ae91b716183715469d94d4dc96b68 Mon Sep 17 00:00:00 2001 From: Trioct Date: Wed, 15 Jul 2020 00:57:24 -0500 Subject: [PATCH 038/151] Remove and replace Character::i_rem( int ) uses (#42136) --- src/avatar_action.cpp | 2 +- src/character.cpp | 20 ++------------------ src/character.h | 10 +--------- src/iuse_actor.cpp | 4 ++-- src/npc.h | 2 +- src/npcmove.cpp | 21 +++++++-------------- src/player.cpp | 16 ---------------- src/player.h | 11 ++--------- tests/throwing_test.cpp | 4 ++-- 9 files changed, 18 insertions(+), 72 deletions(-) diff --git a/src/avatar_action.cpp b/src/avatar_action.cpp index 709816c8fb9d4..9b45f0cc58393 100644 --- a/src/avatar_action.cpp +++ b/src/avatar_action.cpp @@ -1058,7 +1058,7 @@ void avatar_action::plthrow( avatar &you, item_location loc, you.weapon.mod_charges( -1 ); thrown.charges = 1; } else { - you.i_rem( -1 ); + you.remove_weapon(); } you.throw_item( trajectory.back(), thrown, blind_throw_from_pos ); g->reenter_fullscreen(); diff --git a/src/character.cpp b/src/character.cpp index a14644137d805..52c2fadcb000f 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -2668,22 +2668,6 @@ int Character::get_item_position( const item *it ) const return inv.position_by_item( it ); } -item Character::i_rem( int pos ) -{ - item tmp; - if( pos == -1 ) { - return remove_weapon(); - } else if( pos < -1 && pos > worn_position_to_index( worn.size() ) ) { - auto iter = worn.begin(); - std::advance( iter, worn_position_to_index( pos ) ); - tmp = *iter; - tmp.on_takeoff( *this ); - worn.erase( iter ); - return tmp; - } - return inv.remove_item( pos ); -} - item Character::i_rem( const item *it ) { auto tmp = remove_items_with( [&it]( const item & i ) { @@ -2696,9 +2680,9 @@ item Character::i_rem( const item *it ) return tmp.front(); } -void Character::i_rem_keep_contents( const int idx ) +void Character::i_rem_keep_contents( const item *const it ) { - i_rem( idx ).spill_contents( pos() ); + i_rem( it ).spill_contents( pos() ); } bool Character::i_add_or_drop( item &it, int qty ) diff --git a/src/character.h b/src/character.h index e7af3f6467185..9c7a81ccbab6a 100644 --- a/src/character.h +++ b/src/character.h @@ -1345,14 +1345,6 @@ class Character : public Creature, public visitable bool pour_into( vehicle &veh, item &liquid ); /**@}*/ - /** - * Remove a specific item from player possession. The item is compared - * by pointer. Contents of the item are removed as well. - * @param pos The item position of the item to be removed. The item *must* - * exists, use @ref has_item to check this. - * @return A copy of the removed item. - */ - item i_rem( int pos ); /** * Remove a specific item from player possession. The item is compared * by pointer. Contents of the item are removed as well. @@ -1361,7 +1353,7 @@ class Character : public Creature, public visitable * @return A copy of the removed item. */ item i_rem( const item *it ); - void i_rem_keep_contents( int idx ); + void i_rem_keep_contents( const item *it ); /** Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded. * An optional qty can be provided (and will perform better than separate calls). */ bool i_add_or_drop( item &it, int qty = 1 ); diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index dd654742b8839..082cb274947e4 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -2894,7 +2894,7 @@ static bool damage_item( player &pl, item_location &fix ) if( destroyed ) { pl.add_msg_if_player( m_bad, _( "You destroy it!" ) ); if( fix.where() == item_location::type::character ) { - pl.i_rem_keep_contents( pl.get_item_position( fix.get_item() ) ); + pl.i_rem_keep_contents( fix.get_item() ); } else { for( const item *it : fix->contents.all_items_top() ) { put_into_vehicle_or_drop( pl, item_drop_reason::deliberate, { *it }, fix.position() ); @@ -4386,7 +4386,7 @@ int sew_advanced_actor::use( player &p, item &it, bool, const tripoint & ) const mod.tname( 1, false ), startdurability, resultdurability ); if( destroyed ) { p.add_msg_if_player( m_bad, _( "You destroy it!" ) ); - p.i_rem_keep_contents( p.get_item_position( &mod ) ); + p.i_rem_keep_contents( &mod ); } return thread_needed / 2; } else if( rn <= 10 ) { diff --git a/src/npc.h b/src/npc.h index 2fd39689e78ab..79f7d1981def7 100644 --- a/src/npc.h +++ b/src/npc.h @@ -961,7 +961,7 @@ class npc : public player bool has_painkiller(); bool took_painkiller() const; void use_painkiller(); - void activate_item( int item_index ); + void activate_item( item &it ); bool has_identified( const itype_id & ) const override { return true; } diff --git a/src/npcmove.cpp b/src/npcmove.cpp index 56da28364fb27..a6df59a36da6a 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -3197,7 +3197,7 @@ void npc::drop_items( const units::mass &drop_weight, const units::volume &drop_ } weight_dropped += slice[index]->front().weight(); volume_dropped += slice[index]->front().volume(); - item dropped = i_rem( index ); + item dropped = i_rem( &i_at( index ) ); num_items_dropped++; if( num_items_dropped == 1 ) { item_name += dropped.tname(); @@ -3454,7 +3454,7 @@ bool npc::scan_new_items() // TODO: Armor? } -static void npc_throw( npc &np, item &it, int index, const tripoint &pos ) +static void npc_throw( npc &np, item &it, const tripoint &pos ) { if( get_player_character().sees( np ) ) { add_msg( _( "%1$s throws a %2$s." ), np.name, it.tname() ); @@ -3470,7 +3470,7 @@ static void npc_throw( npc &np, item &it, int index, const tripoint &pos ) } // Throw a single charge of a stacking object. if( stack_size == -1 || stack_size == 1 ) { - np.i_rem( index ); + np.i_rem( &it ); } else { it.charges = stack_size - 1; } @@ -3535,15 +3535,9 @@ bool npc::alt_attack() return false; } - int weapon_index = get_item_position( used ); - if( weapon_index == INT_MIN ) { - debugmsg( "npc::alt_attack() couldn't find expected item %s", used->tname() ); - return false; - } - // Are we going to throw this item? if( !used->active && used->has_flag( "NPC_ACTIVATE" ) ) { - activate_item( weapon_index ); + activate_item( *used ); // Note: intentional lack of return here // We want to ignore player-centric rules to avoid carrying live explosives // TODO: Non-grenades @@ -3553,7 +3547,7 @@ bool npc::alt_attack() int conf = confident_throw_range( *used, critter ); const bool wont_hit = wont_hit_friend( tar, *used, true ); if( dist <= conf && wont_hit ) { - npc_throw( *this, *used, weapon_index, tar ); + npc_throw( *this, *used, tar ); return true; } @@ -3610,14 +3604,13 @@ bool npc::alt_attack() * should be equal to the original location of our target, and risking friendly * fire is better than holding on to a live grenade / whatever. */ - npc_throw( *this, *used, weapon_index, tar ); + npc_throw( *this, *used, tar ); return true; } -void npc::activate_item( int item_index ) +void npc::activate_item( item &it ) { const int oldmoves = moves; - item &it = i_at( item_index ); if( it.is_tool() || it.is_food() ) { it.type->invoke( *this, it, pos() ); } diff --git a/src/player.cpp b/src/player.cpp index 31d023f8281a9..8a149a52fdc66 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1913,22 +1913,6 @@ void player::process_items() } } -item player::reduce_charges( int position, int quantity ) -{ - item &it = i_at( position ); - if( it.is_null() ) { - debugmsg( "invalid item position %d for reduce_charges", position ); - return item(); - } - if( it.charges <= quantity ) { - return i_rem( position ); - } - it.mod_charges( -quantity ); - item tmp( it ); - tmp.charges = quantity; - return tmp; -} - item player::reduce_charges( item *it, int quantity ) { if( !has_item( *it ) ) { diff --git a/src/player.h b/src/player.h index 5c762e7a3b7f8..0c9e790387fd4 100644 --- a/src/player.h +++ b/src/player.h @@ -481,21 +481,14 @@ class player : public Character void process_items(); /** - * Remove charges from a specific item (given by its item position). + * Remove charges from a specific item. * The item must exist and it must be counted by charges. - * @param position Item position of the item. + * @param it A pointer to the item, it *must* exist. * @param quantity The number of charges to remove, must not be larger than * the current charges of the item. * @return An item that contains the removed charges, it's effectively a * copy of the item with the proper charges. */ - item reduce_charges( int position, int quantity ); - /** - * Remove charges from a specific item (given by a pointer to it). - * Otherwise identical to @ref reduce_charges(int,int) - * @param it A pointer to the item, it *must* exist. - * @param quantity How many charges to remove - */ item reduce_charges( item *it, int quantity ); /** diff --git a/tests/throwing_test.cpp b/tests/throwing_test.cpp index dc0e71d15bcb6..9fe7ba95fd063 100644 --- a/tests/throwing_test.cpp +++ b/tests/throwing_test.cpp @@ -129,7 +129,7 @@ static void test_throwing_player_versus( } } g->remove_zombie( mon ); - p.i_rem( -1 ); + p.remove_weapon(); // only need to check dmg_thresh_met because it can only be true if // hit_thresh_met first } while( !dmg_thresh_met && data.hits.n() < max_throws ); @@ -279,7 +279,7 @@ static void test_player_kills_monster( while( p.get_moves() > 0 ) { p.wield( it ); p.throw_item( mon.pos(), it ); - p.i_rem( -1 ); + p.remove_weapon(); ++num_items; } mon_is_dead = mon.is_dead(); From 678ed230704052bcdc0b7adc21a067c620d15e1d Mon Sep 17 00:00:00 2001 From: johnrdconnolly <59102789+johnrdconnolly@users.noreply.github.com> Date: Tue, 14 Jul 2020 23:31:42 -0700 Subject: [PATCH 039/151] Update cooking.json update volume, weight, and longest_side values where appropriate --- data/json/items/tool/cooking.json | 52 ++++++++++++++++++------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/data/json/items/tool/cooking.json b/data/json/items/tool/cooking.json index 8eb6cb1a54ad7..12e20e5d28174 100644 --- a/data/json/items/tool/cooking.json +++ b/data/json/items/tool/cooking.json @@ -27,6 +27,8 @@ "looks_like": "knife_butcher", "weight": "1170 g", "volume": "800 ml", + "longest_side": "40 cm", + "//": "butcher knives and carving knives are between 30-40cm.", "price": 8000, "price_postapoc": 150, "qualities": [ [ "CUT", 1 ], [ "CUT_FINE", 1 ], [ "BUTCHER", 37 ] ] @@ -71,6 +73,7 @@ "description": "An electric meat carver powered by batteries. Two serrated blades that vibrate together to slice just about anything from turkey to hamā€¦ even zombies!", "weight": "1106 g", "volume": "1500 ml", + "longest_side": "30 cm", "price": 2000, "price_postapoc": 50, "bashing": 2, @@ -116,6 +119,7 @@ "description": "Using this item on a container full of water will purify the water using layered charcoal. Once the charcoal has purified enough water, it will become unusable and can be disassembled and recycled. Water taken from uncertain sources like a river may be dirty.", "weight": "1820 g", "volume": "3750 ml", + "longest_side": "30 cm", "price": 4000, "price_postapoc": 2000, "to_hit": -3, @@ -135,8 +139,9 @@ "type": "TOOL", "name": { "str": "charcoal smoker" }, "description": "This is a portable charcoal smoker. Good for weekend barbecuing and preserving meat with smoke.", - "weight": "2600 g", - "volume": "5 L", + "weight": "4000 g", + "volume": "20 L", + "longest_side": "60 cm", "price": 10000, "price_postapoc": 1500, "to_hit": -2, @@ -154,8 +159,9 @@ "type": "TOOL", "name": { "str": "charcoal cooker" }, "description": "This is a little metal tank for holding charcoal with a pilot light attached. You could use it for cooking food.", - "weight": "405 g", - "volume": "1250 ml", + "weight": "450 g", + "volume": "2 L", + "longest_side": "30 cm", "price": 5000, "price_postapoc": 250, "to_hit": -1, @@ -227,8 +233,9 @@ "type": "TOOL", "name": { "str": "coffeemaker" }, "description": "This is a heating element with pot and frame for holding coffee or other powders. It's got a battery compartment for use when the power goes out. You can use it to make coffee, or other drinks if you so choose.", - "weight": "3100 g", - "volume": "750 ml", + "weight": "1000 g", + "volume": "7 L", + "longest_side": "25 cm", "price": 2000, "price_postapoc": 50, "to_hit": -5, @@ -256,8 +263,8 @@ "type": "TOOL", "name": { "str": "food dehydrator" }, "description": "This is a portable electric food dehydrator. It's powered by batteries, and could be invaluable in preserving food.", - "weight": "4200 g", - "volume": "4500 ml", + "weight": "2500 g", + "volume": "13 L", "price": 6000, "price_postapoc": 2000, "to_hit": -2, @@ -306,8 +313,8 @@ "type": "TOOL", "name": { "str": "hexamine stove" }, "description": "Known as an Esbit stove, this is a lightweight, folding stove designed to use small hexamine tablets for cooking.", - "weight": "180 g", - "volume": "750 ml", + "weight": "92 g", + "volume": "147 ml", "price": 2000, "price_postapoc": 100, "to_hit": -1, @@ -356,8 +363,8 @@ "category": "tools", "name": { "str": "food processor" }, "description": "This is a kitchen appliance capable of slicing, chopping, shredding, grinding, pureeing and mixing.", - "weight": "3000 g", - "volume": "2 L", + "weight": "1224 g", + "volume": "5500 ml", "price": 50, "price_postapoc": 250, "to_hit": -1, @@ -383,7 +390,7 @@ "type": "TOOL", "name": { "str": "gasoline cooker" }, "description": "This is a simple heater powered by gasoline. It is designed for cooking food.", - "weight": "1944 g", + "weight": "800 g", "volume": "1250 ml", "price": 5000, "price_postapoc": 250, @@ -459,8 +466,9 @@ "type": "TOOL", "name": { "str": "hotplate" }, "description": "This is a small heating element on a stand, powered by batteries. It is indispensable for cooking and chemistry. Try not to burn yourself.", - "weight": "2835 g", - "volume": "1250 ml", + "weight": "795 g", + "volume": "5 L", + "longest_side": "35 cm", "price": 2500, "price_postapoc": 250, "to_hit": -1, @@ -556,8 +564,9 @@ "type": "TOOL", "name": { "str": "makeshift vacuum sealer" }, "description": "This is a homemade heat sealer unit with an air pump. It's used for vacuum packing food to preserve it.", - "weight": "3218 g", - "volume": "2 L", + "weight": "2000 g", + "volume": "5 L", + "longest_side": "35 cm", "price": 1000, "price_postapoc": 250, "to_hit": -1, @@ -776,7 +785,7 @@ "category": "tools", "name": { "str": "pasta extruder" }, "description": "A pasta extruder run by a hand-crank. Useful in making pasta. It comes with various heads to make various kinds of pasta.", - "weight": "2628 g", + "weight": "650 g", "volume": "1 L", "price": 2000, "price_postapoc": 100, @@ -983,8 +992,9 @@ "type": "TOOL", "name": { "str": "vacuum sealer" }, "description": "This is a portable heat sealer unit with an air pump. It's used for vacuum packing food to preserve it.", - "weight": "2449 g", - "volume": "1250 ml", + "weight": "1770 g", + "volume": "4100 ml", + "longest_side": "35cm", "price": 2500, "price_postapoc": 2000, "to_hit": -1, @@ -1012,7 +1022,7 @@ "name": { "str": "waffle iron" }, "description": "A waffle iron. For making waffles.", "weight": "2628 g", - "volume": "1 L", + "volume": "5 L", "price": 2000, "price_postapoc": 10, "to_hit": 2, From 8d05b8309232455363ccaf900b2b89f5dc3e7d76 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Wed, 15 Jul 2020 02:43:39 +0000 Subject: [PATCH 040/151] Global reference migration part 25 --- src/iexamine.cpp | 85 ++++++++++++++++------------ src/map.cpp | 114 ++++++++++++++++++++++---------------- src/mission_companion.cpp | 104 ++++++++++++++++++++-------------- src/npctalk.cpp | 32 +++++++---- tests/crafting_test.cpp | 77 +++++++++++++------------ 5 files changed, 237 insertions(+), 175 deletions(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index a6efac7f6eb92..8f7cbb34866c7 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -373,13 +373,14 @@ void iexamine::gaspump( player &p, const tripoint &examp ) void iexamine::translocator( player &, const tripoint &examp ) { const tripoint omt_loc = ms_to_omt_copy( get_map().getabs( examp ) ); - const bool activated = g->u.translocators.knows_translocator( examp ); + avatar &player_character = get_avatar(); + const bool activated = player_character.translocators.knows_translocator( examp ); if( !activated ) { - g->u.translocators.activate_teleporter( omt_loc, examp ); + player_character.translocators.activate_teleporter( omt_loc, examp ); add_msg( m_info, _( "Translocator gate active." ) ); } else { if( query_yn( _( "Do you want to deactivate this active Translocator?" ) ) ) { - g->u.translocators.deactivate_teleporter( omt_loc, examp ); + player_character.translocators.deactivate_teleporter( omt_loc, examp ); } } } @@ -1126,7 +1127,9 @@ void iexamine::chainfence( player &p, const tripoint &examp ) return; } p.moves += climb * 10; - sfx::play_variant_sound( "plmove", "clear_obstacle", sfx::get_heard_volume( g->u.pos() ) ); + Character &player_character = get_player_character(); + sfx::play_variant_sound( "plmove", "clear_obstacle", + sfx::get_heard_volume( player_character.pos() ) ); } if( p.in_vehicle ) { here.unboard_vehicle( p.pos() ); @@ -2120,7 +2123,7 @@ void iexamine::plant_seed( player &p, const tripoint &examp, const itype_id &see void iexamine::dirtmound( player &p, const tripoint &examp ) { - if( !warm_enough_to_plant( g->u.pos() ) ) { + if( !warm_enough_to_plant( get_player_character().pos() ) ) { add_msg( m_info, _( "It is too cold to plant anything now." ) ); return; } @@ -3195,8 +3198,9 @@ void iexamine::keg( player &p, const tripoint &examp ) drink.set_relative_rot( drink_rot[ drink_index ] ); drink.charges = 0; bool keg_full = false; + Character &player_character = get_player_character(); for( int i = 0; i < charges_held && !keg_full; i++ ) { - g->u.use_charges( drink.typeId(), 1 ); + player_character.use_charges( drink.typeId(), 1 ); drink.charges++; keg_full = drink.volume() >= keg_cap; } @@ -3515,8 +3519,9 @@ void iexamine::tree_maple_tapped( player &p, const tripoint &examp ) } case REMOVE_CONTAINER: { - g->u.assign_activity( player_activity( pickup_activity_actor( - { item_location( map_cursor( examp ), container ) }, { 0 }, g->u.pos() ) ) ); + Character &player_character = get_player_character(); + player_character.assign_activity( player_activity( pickup_activity_actor( + { item_location( map_cursor( examp ), container ) }, { 0 }, player_character.pos() ) ) ); return; } @@ -3695,20 +3700,22 @@ void iexamine::recycle_compactor( player &, const tripoint &examp ) void trap::examine( const tripoint &examp ) const { + avatar &player_character = get_avatar(); map &here = get_map(); // If the player can't see the trap, they can't interact with it. - if( !can_see( examp, g->u ) ) { + if( !can_see( examp, player_character ) ) { return; } - if( g->u.is_mounted() ) { + if( player_character.is_mounted() ) { add_msg( m_warning, _( "You cannot do that while mounted." ) ); return; } if( partial_con *const pc = here.partial_con_at( examp ) ) { - if( g->u.fine_detail_vision_mod() > 4 && !g->u.has_trait( trait_DEBUG_HS ) ) { + if( player_character.fine_detail_vision_mod() > 4 && + !player_character.has_trait( trait_DEBUG_HS ) ) { add_msg( m_info, _( "It is too dark to construct right now." ) ); return; } @@ -3718,13 +3725,13 @@ void trap::examine( const tripoint &examp ) const if( query_yn( _( "Cancel construction?" ) ) ) { on_disarmed( here, examp ); for( const item &it : pc->components ) { - here.add_item_or_charges( g->u.pos(), it ); + here.add_item_or_charges( player_character.pos(), it ); } here.partial_con_remove( examp ); } } else { - g->u.assign_activity( ACT_BUILD ); - g->u.activity.placement = here.getabs( examp ); + player_character.assign_activity( ACT_BUILD ); + player_character.activity.placement = here.getabs( examp ); } return; } @@ -3744,7 +3751,7 @@ void trap::examine( const tripoint &examp ) const } if( query_yn( _( "There is a %s there. Disarm?" ), name() ) ) { - const int tSkillLevel = g->u.get_skill_level( skill_traps ); + const int tSkillLevel = player_character.get_skill_level( skill_traps ); int roll = rng( tSkillLevel, 4 * tSkillLevel ); ///\EFFECT_PER increases chance of disarming trap @@ -3752,36 +3759,37 @@ void trap::examine( const tripoint &examp ) const ///\EFFECT_DEX increases chance of disarming trap ///\EFFECT_TRAPS increases chance of disarming trap - while( ( rng( 5, 20 ) < g->u.per_cur || rng( 1, 20 ) < g->u.dex_cur ) && roll < 50 ) { + while( ( rng( 5, 20 ) < player_character.per_cur || + rng( 1, 20 ) < player_character.dex_cur ) && roll < 50 ) { roll++; } if( roll >= difficulty ) { add_msg( _( "You disarm the trap!" ) ); const int morale_buff = avoidance * 0.4 + difficulty + rng( 0, 4 ); - g->u.rem_morale( MORALE_FAILURE ); - g->u.add_morale( MORALE_ACCOMPLISHMENT, morale_buff, 40 ); + player_character.rem_morale( MORALE_FAILURE ); + player_character.add_morale( MORALE_ACCOMPLISHMENT, morale_buff, 40 ); on_disarmed( here, examp ); if( difficulty > 1.25 * tSkillLevel ) { // failure might have set off trap - g->u.practice( skill_traps, 1.5 * ( difficulty - tSkillLevel ) ); + player_character.practice( skill_traps, 1.5 * ( difficulty - tSkillLevel ) ); } } else if( roll >= difficulty * .8 ) { add_msg( _( "You fail to disarm the trap." ) ); const int morale_debuff = -rng( 6, 18 ); - g->u.rem_morale( MORALE_ACCOMPLISHMENT ); - g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 ); + player_character.rem_morale( MORALE_ACCOMPLISHMENT ); + player_character.add_morale( MORALE_FAILURE, morale_debuff, -40 ); if( difficulty > 1.25 * tSkillLevel ) { - g->u.practice( skill_traps, 1.5 * ( difficulty - tSkillLevel ) ); + player_character.practice( skill_traps, 1.5 * ( difficulty - tSkillLevel ) ); } } else { add_msg( m_bad, _( "You fail to disarm the trap, and you set it off!" ) ); const int morale_debuff = -rng( 12, 24 ); - g->u.rem_morale( MORALE_ACCOMPLISHMENT ); - g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 ); - trigger( examp, g->u ); + player_character.rem_morale( MORALE_ACCOMPLISHMENT ); + player_character.add_morale( MORALE_FAILURE, morale_debuff, -40 ); + trigger( examp, player_character ); if( difficulty - roll <= 6 ) { // Give xp for failing, but not if we failed terribly (in which // case the trap may not be disarmable). - g->u.practice( skill_traps, 2 * difficulty ); + player_character.practice( skill_traps, 2 * difficulty ); } } return; @@ -3846,11 +3854,12 @@ void iexamine::reload_furniture( player &p, const tripoint &examp ) 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 ) ) ) { + Character &player_character = get_player_character(); map_stack items = here.i_at( examp ); for( auto &itm : items ) { if( itm.type == ammo ) { - g->u.assign_activity( player_activity( pickup_activity_actor( - { item_location( map_cursor( examp ), &itm ) }, { 0 }, g->u.pos() ) ) ); + player_character.assign_activity( player_activity( pickup_activity_actor( + { item_location( map_cursor( examp ), &itm ) }, { 0 }, player_character.pos() ) ) ); return; } } @@ -4100,7 +4109,7 @@ static int findBestGasDiscount( player &p ) static std::string str_to_illiterate_str( std::string s ) { - if( !g->u.has_trait( trait_ILLITERATE ) ) { + if( !get_player_character().has_trait( trait_ILLITERATE ) ) { return s; } else { for( auto &i : s ) { @@ -4598,12 +4607,13 @@ static player &best_installer( player &p, player &null_player, int difficulty ) return rhs.first < lhs.first; } ); int player_cos = bionic_success_chance( true, -1, difficulty, p ); + avatar &player_character = get_avatar(); for( size_t i = 0; i < g->allies().size() ; i ++ ) { if( ally_chances[ i ].first > player_cos ) { const npc *e = g->allies()[ ally_chances[ i ].second ]; player &ally = *g->critter_by_id( e->getID() ); if( e->has_effect( effect_sleep ) ) { - if( !g->u.query_yn( + if( !player_character.query_yn( //~ %1$s is the name of the ally _( "%1$s is asleep, but has a %2$d chance of success compared to your %3$d chance of success. Continue with a higher risk of failure?" ), ally.disp_name(), ally_chances[i].first, player_cos ) ) { @@ -4795,6 +4805,7 @@ void iexamine::autodoc( player &p, const tripoint &examp ) return; } + Character &player_character = get_player_character(); for( const bionic &bio : installed_bionics ) { if( bio.id != bio_power_storage || bio.id != bio_power_storage_mkII ) { @@ -4806,14 +4817,14 @@ void iexamine::autodoc( player &p, const tripoint &examp ) // TODO: refactor this whole bit. adding items to the inventory will // cause major issues when inv gets removed. this is a shim for now // in order to reduce lines of change for nested containers. - g->u.inv.push_back( bionic_to_uninstall ); + player_character.inv.push_back( bionic_to_uninstall ); } } } const item_location bionic = game_menus::inv::uninstall_bionic( p, patient ); if( !bionic ) { - g->u.remove_items_with( []( const item & it ) {// remove cbm items from inventory + player_character.remove_items_with( []( const item & it ) {// remove cbm items from inventory return it.has_flag( flag_IN_CBM ); } ); return; @@ -4822,7 +4833,7 @@ void iexamine::autodoc( player &p, const tripoint &examp ) const itype *itemtype = it->type; const bionic_id &bid = itemtype->bionic->id; - g->u.remove_items_with( []( const item & it ) {// remove cbm items from inventory + player_character.remove_items_with( []( const item & it ) {// remove cbm items from inventory return it.has_flag( flag_IN_CBM ); } ); @@ -5329,8 +5340,9 @@ static void smoker_load_food( player &p, const tripoint &examp, comps.clear(); comps.push_back( item_comp( what->typeId(), amount ) ); + Character &player_character = get_player_character(); // select from where to get the items from and place them - inv.form_from_map( g->u.pos(), PICKUP_RANGE, &g->u ); + inv.form_from_map( player_character.pos(), PICKUP_RANGE, &player_character ); inv.remove_items_with( []( const item & it ) { return it.rotten(); } ); @@ -5437,8 +5449,9 @@ static void mill_load_food( player &p, const tripoint &examp, comps.clear(); comps.push_back( item_comp( what->typeId(), amount ) ); + Character &player_character = get_player_character(); // select from where to get the items from and place them - inv.form_from_map( g->u.pos(), PICKUP_RANGE, &g->u ); + inv.form_from_map( player_character.pos(), PICKUP_RANGE, &player_character ); inv.remove_items_with( []( const item & it ) { return it.rotten(); } ); @@ -5460,7 +5473,7 @@ void iexamine::on_smoke_out( const tripoint &examp, const time_point &start_time map &here = get_map(); if( here.furn( examp ) == furn_str_id( "f_smoking_rack_active" ) || here.furn( examp ) == furn_str_id( "f_metal_smoking_rack_active" ) ) { - smoker_finalize( g->u, examp, start_time ); + smoker_finalize( get_avatar(), examp, start_time ); } } diff --git a/src/map.cpp b/src/map.cpp index fe16c37d2118c..04e980bfc5813 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -616,7 +616,8 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &fac } } - const bool seen = sees_veh( g->u, veh, false ); + Character &player_character = get_player_character(); + const bool seen = sees_veh( player_character, veh, false ); vehicle *new_vehicle = &veh; if( can_move ) { @@ -642,7 +643,8 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &fac veh.check_falling_or_floating(); // If the PC is in the currently moved vehicle, adjust the // view offset. - if( g->u.controlling_vehicle && veh_pointer_or_null( veh_at( g->u.pos() ) ) == &veh ) { + if( player_character.controlling_vehicle && + veh_pointer_or_null( veh_at( player_character.pos() ) ) == &veh ) { g->calc_driving_offset( &veh ); if( veh.skidding && can_move ) { // TODO: Make skid recovery in air hard @@ -691,7 +693,7 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &fac } // Redraw scene // But only if the vehicle was seen before or after the move - if( seen || sees_veh( g->u, veh, true ) ) { + if( seen || sees_veh( player_character, veh, true ) ) { g->invalidate_main_ui_adaptor(); ui_manager::redraw_invalidated(); refresh_display(); @@ -1016,7 +1018,7 @@ void map::board_vehicle( const tripoint &pos, Character *p ) p->setpos( pos ); p->in_vehicle = true; if( p->is_avatar() ) { - g->update_map( g->u ); + g->update_map( *p->as_avatar() ); } } @@ -1119,8 +1121,9 @@ bool map::displace_vehicle( vehicle &veh, const tripoint &dp, const bool adjust_ return true; } + Character &player_character = get_player_character(); // Need old coordinates to check for remote control - const bool remote = veh.remote_controlled( g->u ); + const bool remote = veh.remote_controlled( player_character ); // record every passenger and pet inside std::vector riders = veh.get_riders(); @@ -1146,7 +1149,7 @@ bool map::displace_vehicle( vehicle &veh, const tripoint &dp, const bool adjust_ if( psg == nullptr ) { debugmsg( "Empty passenger for part #%d at %d,%d,%d player at %d,%d,%d?", prt, part_pos.x, part_pos.y, part_pos.z, - g->u.posx(), g->u.posy(), g->u.posz() ); + player_character.posx(), player_character.posy(), player_character.posz() ); veh.part( prt ).remove_flag( vehicle_part::passenger_flag ); r.moved = true; continue; @@ -1199,7 +1202,7 @@ bool map::displace_vehicle( vehicle &veh, const tripoint &dp, const bool adjust_ dst_submap->is_uniform = false; } if( need_update ) { - g->update_map( g->u ); + g->update_map( player_character ); } add_vehicle_to_cache( &veh ); @@ -1347,11 +1350,12 @@ void map::furn_set( const tripoint &p, const furn_id &new_furniture ) const furn_t &old_t = old_id.obj(); const furn_t &new_t = new_furniture.obj(); + avatar &player_character = get_avatar(); // If player has grabbed this furniture and it's no longer grabbable, release the grab. - if( g->u.get_grab_type() == object_type::FURNITURE && g->u.grab_point == p && - !new_t.is_movable() ) { + if( player_character.get_grab_type() == object_type::FURNITURE && + player_character.grab_point == p && !new_t.is_movable() ) { add_msg( _( "The %s you were grabbing is destroyed!" ), old_t.name() ); - g->u.grab( object_type::NONE ); + player_character.grab( object_type::NONE ); } // If a creature was crushed under a rubble -> free it if( old_id == f_rubble && new_furniture == f_null ) { @@ -1457,17 +1461,18 @@ uint8_t map::get_known_connections( const tripoint &p, int connect_group, auto &ch = access_cache( p.z ); uint8_t val = 0; std::function is_memorized; + avatar &player_character = get_avatar(); #ifdef TILES if( use_tiles ) { is_memorized = [&]( const tripoint & q ) { - return !g->u.get_memorized_tile( getabs( q ) ).tile.empty(); + return !player_character.get_memorized_tile( getabs( q ) ).tile.empty(); }; } else { #endif is_memorized = [&]( const tripoint & q ) { - return g->u.get_memorized_symbol( getabs( q ) ); + return player_character.get_memorized_symbol( getabs( q ) ); }; #ifdef TILES } @@ -2974,15 +2979,16 @@ void map::smash_items( const tripoint &p, const int power, const std::string &ca } } + Character &player_character = get_player_character(); // Let the player know that the item was damaged if they can see it. - if( items_destroyed > 1 && g->u.sees( p ) ) { + if( items_destroyed > 1 && player_character.sees( p ) ) { add_msg( m_bad, _( "The %s destroys several items!" ), cause_message ); - } else if( items_destroyed == 1 && items_damaged == 1 && g->u.sees( p ) ) { + } else if( items_destroyed == 1 && items_damaged == 1 && player_character.sees( p ) ) { //~ %1$s: the cause of destruction, %2$s: destroyed item name add_msg( m_bad, _( "The %1$s destroys the %2$s!" ), cause_message, damaged_item_name ); - } else if( items_damaged > 1 && g->u.sees( p ) ) { + } else if( items_damaged > 1 && player_character.sees( p ) ) { add_msg( m_bad, _( "The %s damages several items." ), cause_message ); - } else if( items_damaged == 1 && g->u.sees( p ) ) { + } else if( items_damaged == 1 && player_character.sees( p ) ) { //~ %1$s: the cause of damage, %2$s: damaged item name add_msg( m_bad, _( "The %1$s damages the %2$s." ), cause_message, damaged_item_name ); } @@ -3097,9 +3103,10 @@ void map::bash_ter_furn( const tripoint &p, bash_params ¶ms ) if( has_flag( "ALARMED", p ) && !g->timed_events.queued( timed_event_type::WANTED ) ) { sounds::sound( p, 40, sounds::sound_t::alarm, _( "an alarm go off!" ), false, "environment", "alarm" ); + Character &player_character = get_player_character(); // Blame nearby player - if( rl_dist( g->u.pos(), p ) <= 3 ) { - g->events().send( g->u.getID() ); + if( rl_dist( player_character.pos(), p ) <= 3 ) { + g->events().send( player_character.getID() ); const point abs = ms_to_sm_copy( getabs( p.xy() ) ); g->timed_events.add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, tripoint( abs, p.z ) ); @@ -3641,7 +3648,7 @@ void map::shoot( const tripoint &p, projectile &proj, const bool hit_items ) } else { //Greatly weakens power of bullets dam -= 40; - if( dam <= 0 && g->u.sees( p ) ) { + if( dam <= 0 && get_player_character().sees( p ) ) { if( terrain == t_reinforced_door_glass_c ) { add_msg( _( "The shot is stopped by the reinforced glass door!" ) ); } else { @@ -3811,6 +3818,7 @@ bool map::open_door( const tripoint &p, const bool inside, const bool check_only { const auto &ter = this->ter( p ).obj(); const auto &furn = this->furn( p ).obj(); + avatar &player_character = get_avatar(); if( ter.open ) { if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) { return false; @@ -3821,9 +3829,10 @@ bool map::open_door( const tripoint &p, const bool inside, const bool check_only "open_door", ter.id.str() ); ter_set( p, ter.open ); - if( ( g->u.has_trait( trait_id( "SCHIZOPHRENIC" ) ) || g->u.has_artifact_with( AEP_SCHIZO ) ) - && one_in( 50 ) && !ter.has_flag( "TRANSPARENT" ) ) { - tripoint mp = p + -2 * g->u.pos().xy() + tripoint( 2 * p.x, 2 * p.y, p.z ); + if( ( player_character.has_trait( trait_id( "SCHIZOPHRENIC" ) ) || + player_character.has_artifact_with( AEP_SCHIZO ) ) && + one_in( 50 ) && !ter.has_flag( "TRANSPARENT" ) ) { + tripoint mp = p + -2 * player_character.pos().xy() + tripoint( 2 * p.x, 2 * p.y, p.z ); g->spawn_hallucination( mp ); } } @@ -3845,7 +3854,7 @@ bool map::open_door( const tripoint &p, const bool inside, const bool check_only int openable = vp->vehicle().next_part_to_open( vp->part_index(), true ); if( openable >= 0 ) { if( !check_only ) { - if( !vp->vehicle().handle_potential_theft( dynamic_cast( g->u ) ) ) { + if( !vp->vehicle().handle_potential_theft( player_character ) ) { return false; } vp->vehicle().open_all_at( openable ); @@ -5164,7 +5173,7 @@ void map::remove_trap( const tripoint &p ) trap_id tid = current_submap->get_trap( l ); if( tid != tr_null ) { if( g != nullptr && this == &get_map() ) { - g->u.add_known_trap( p, tr_null.obj() ); + get_player_character().add_known_trap( p, tr_null.obj() ); } current_submap->set_trap( l, tr_null ); @@ -5318,8 +5327,10 @@ bool map::add_field( const tripoint &p, const field_type_id &type, int intensity } } - if( g != nullptr && this == &get_map() && p == g->u.pos() ) { - creature_in_field( g->u ); //Hit the player with the field if it spawned on top of them. + Character &player_character = get_player_character(); + if( g != nullptr && this == &get_map() && p == player_character.pos() ) { + //Hit the player with the field if it spawned on top of them. + creature_in_field( player_character ); } // Dirty the transparency cache now that field processing doesn't always do it @@ -5454,7 +5465,7 @@ void map::add_camp( const tripoint &omt_pos, const std::string &name ) { basecamp temp_camp = basecamp( name, omt_pos ); overmap_buffer.add_camp( temp_camp ); - g->u.camps.insert( omt_pos ); + get_player_character().camps.insert( omt_pos ); g->validate_camps(); } @@ -5469,14 +5480,16 @@ void map::update_submap_active_item_status( const tripoint &p ) void map::update_visibility_cache( const int zlev ) { + Character &player_character = get_player_character(); visibility_variables_cache.variables_set = true; // Not used yet visibility_variables_cache.g_light_level = static_cast( g->light_level( zlev ) ); - visibility_variables_cache.vision_threshold = g->u.get_vision_threshold( - get_cache_ref( g->u.posz() ).lm[g->u.posx()][g->u.posy()].max() ); + visibility_variables_cache.vision_threshold = player_character.get_vision_threshold( + get_cache_ref( + player_character.posz() ).lm[player_character.posx()][player_character.posy()].max() ); - visibility_variables_cache.u_clairvoyance = g->u.clairvoyance(); - visibility_variables_cache.u_sight_impaired = g->u.sight_impaired(); - visibility_variables_cache.u_is_boomered = g->u.has_effect( effect_boomered ); + visibility_variables_cache.u_clairvoyance = player_character.clairvoyance(); + visibility_variables_cache.u_sight_impaired = player_character.sight_impaired(); + visibility_variables_cache.u_is_boomered = player_character.has_effect( effect_boomered ); int sm_squares_seen[MAPSIZE][MAPSIZE]; std::memset( sm_squares_seen, 0, sizeof( sm_squares_seen ) ); @@ -5579,7 +5592,7 @@ bool map::apply_vision_effects( const catacurses::window &w, const visibility_ty bool map::draw_maptile_from_memory( const catacurses::window &w, const tripoint &p, const tripoint &view_center, bool move_cursor ) const { - int sym = g->u.get_memorized_symbol( getabs( p ) ); + int sym = get_avatar().get_memorized_symbol( getabs( p ) ); if( sym == 0 ) { return true; } @@ -5614,7 +5627,8 @@ void map::draw( const catacurses::window &w, const tripoint ¢er ) p.z = center.z; int &x = p.x; int &y = p.y; - const bool do_map_memory = g->u.should_show_map_memory(); + avatar &player_character = get_avatar(); + const bool do_map_memory = player_character.should_show_map_memory(); for( y = center.y - getmaxy( w ) / 2; y <= center.y + getmaxy( w ) / 2; y++ ) { if( y - center.y + getmaxy( w ) / 2 >= getmaxy( w ) ) { continue; @@ -5652,14 +5666,14 @@ void map::draw( const catacurses::window &w, const tripoint ¢er ) if( !apply_vision_effects( w, vis ) ) { const maptile curr_maptile = maptile( cur_submap, l ); const bool draw_lower_zlevel = - draw_maptile( w, g->u, p, curr_maptile, + draw_maptile( w, player_character, p, curr_maptile, false, true, center, lighting == lit_level::LOW, lighting == lit_level::BRIGHT, true ); if( draw_lower_zlevel ) { p.z--; const maptile tile_below = maptile( sm_below, l ); - draw_from_above( w, g->u, p, tile_below, false, center, + draw_from_above( w, player_character, p, tile_below, false, center, lighting == lit_level::LOW, lighting == lit_level::BRIGHT, false ); p.z++; @@ -5759,8 +5773,9 @@ bool map::draw_maptile( const catacurses::window &w, const player &u, const trip !u.is_underwater() ) { show_items = false; // Can only see underwater items if WE are underwater } + avatar &player_character = get_avatar(); // If there's a trap here, and we have sufficient perception, draw that instead - if( curr_trap.can_see( p, g->u ) ) { + if( curr_trap.can_see( p, player_character ) ) { tercol = curr_trap.color; if( curr_trap.sym == '%' ) { switch( rng( 1, 5 ) ) { @@ -5839,7 +5854,8 @@ bool map::draw_maptile( const catacurses::window &w, const player &u, const trip std::string item_sym; // If there are items here, draw those instead - if( show_items && curr_maptile.get_item_count() > 0 && sees_some_items( p, g->u ) ) { + if( show_items && curr_maptile.get_item_count() > 0 && + sees_some_items( p, player_character ) ) { // if there's furniture/terrain/trap/fields (sym!='.') // and we should not override it, then only highlight the square if( sym != '.' && sym != '%' && !draw_item_sym ) { @@ -5864,13 +5880,13 @@ bool map::draw_maptile( const catacurses::window &w, const player &u, const trip tercol = veh->part_color( veh_part ); item_sym.clear(); // clear the item symbol so `sym` is used instead. - if( !veh->forward_velocity() && !veh->player_in_control( g->u ) ) { + if( !veh->forward_velocity() && !veh->player_in_control( player_character ) ) { memory_sym = sym; } } if( check_and_set_seen_cache( p ) ) { - g->u.memorize_symbol( getabs( p ), memory_sym ); + player_character.memorize_symbol( getabs( p ), memory_sym ); } // If there's graffiti here, change background color @@ -6483,10 +6499,11 @@ void map::shift( const point &sp ) set_abs_sub( abs + sp ); + Character &player_character = get_player_character(); // if player is in vehicle, (s)he must be shifted with vehicle too - if( g->u.in_vehicle ) { - g->u.setx( g->u.posx() - sp.x * SEEX ); - g->u.sety( g->u.posy() - sp.y * SEEY ); + if( player_character.in_vehicle ) { + player_character.setx( player_character.posx() - sp.x * SEEX ); + player_character.sety( player_character.posy() - sp.y * SEEY ); } g->shift_destination_preview( point( -sp.x * SEEX, -sp.y * SEEY ) ); @@ -6779,7 +6796,7 @@ void map::rotten_item_spawn( const item &item, const tripoint &pnt ) if( rng( 0, 100 ) < chance ) { MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( mgroup ); add_spawn( spawn_details, pnt ); - if( g->u.sees( pnt ) ) { + if( get_player_character().sees( pnt ) ) { if( item.is_seed() ) { add_msg( m_warning, _( "Something has crawled out of the %s plants!" ), item.get_plant_name() ); } else { @@ -7175,8 +7192,9 @@ void map::copy_grid( const tripoint &to, const tripoint &from ) void map::spawn_monsters_submap_group( const tripoint &gp, mongroup &group, bool ignore_sight ) { + Character &player_character = get_player_character(); const int s_range = std::min( HALF_MAPSIZE_X, - g->u.sight_range( g->light_level( g->u.posz() ) ) ); + player_character.sight_range( g->light_level( player_character.posz() ) ) ); int pop = group.population; std::vector locations; if( !ignore_sight ) { @@ -7187,7 +7205,7 @@ void map::spawn_monsters_submap_group( const tripoint &gp, mongroup &group, bool } } - if( gp.z != g->u.posz() ) { + if( gp.z != player_character.posz() ) { // Note: this is only OK because 3D vision isn't a thing yet ignore_sight = true; } @@ -7231,7 +7249,7 @@ void map::spawn_monsters_submap_group( const tripoint &gp, mongroup &group, bool continue; // solid area, impassable } - if( !ignore_sight && sees( g->u.pos(), fp, s_range ) ) { + if( !ignore_sight && sees( player_character.pos(), fp, s_range ) ) { continue; // monster must spawn outside the viewing range of the player } @@ -7782,7 +7800,7 @@ void map::build_map_cache( const int zlev, bool skip_lightmap ) skew_vision_cache.clear(); } // Initial value is illegal player position. - const tripoint &p = g->u.pos(); + const tripoint &p = get_player_character().pos(); static tripoint player_prev_pos; if( seen_cache_dirty || player_prev_pos != p ) { build_seen_cache( p, zlev ); diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index 0074e24485605..636d60e214aa9 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -695,14 +695,15 @@ npc_ptr talk_function::individual_mission( const tripoint &omt_pos, if( comp->has_effect( effect_riding ) ) { comp->npc_dismount(); } + Character &player_character = get_player_character(); //Ensure we have someone to give equipment to before we lose it for( auto i : equipment ) { comp->companion_mission_inv.add_item( *i ); //comp->i_add(*i); if( item::count_by_charges( i->typeId() ) ) { - g->u.use_charges( i->typeId(), i->charges ); + player_character.use_charges( i->typeId(), i->charges ); } else { - g->u.use_amount( i->typeId(), 1 ); + player_character.use_amount( i->typeId(), 1 ); } } if( comp->in_vehicle ) { @@ -740,8 +741,10 @@ void talk_function::caravan_depart( npc &p, const std::string &dest, const std:: //Could be expanded to actually path to the site, just returns the distance int talk_function::caravan_dist( const std::string &dest ) { - const tripoint site = overmap_buffer.find_closest( g->u.global_omt_location(), dest, 0, false ); - int distance = rl_dist( g->u.pos(), site ); + Character &player_character = get_player_character(); + const tripoint site = overmap_buffer.find_closest( player_character.global_omt_location(), dest, 0, + false ); + int distance = rl_dist( player_character.pos(), site ); return distance; } @@ -811,7 +814,7 @@ void talk_function::caravan_return( npc &p, const std::string &dest, const std:: } if( money != 0 ) { - g->u.cash += ( 100 * money ); + get_player_character().cash += ( 100 * money ); popup( _( "The caravan party has returned. Your share of the profits are $%d!" ), money ); } else { popup( _( "The caravan was a disaster and your companions never made it homeā€¦" ) ); @@ -912,14 +915,15 @@ npc_ptr talk_function::temp_npc( const string_id &type ) //The field is designed as more of a convenience than a profit opportunity. void talk_function::field_build_1( npc &p ) { - if( g->u.cash < 100000 ) { + Character &player_character = get_player_character(); + if( player_character.cash < 100000 ) { popup( _( "I'm sorry, you don't have enough money." ) ); return; } p.set_mutation( trait_NPC_CONSTRUCTION_LEV_1 ); - g->u.cash += -100000; - const tripoint site = overmap_buffer.find_closest( g->u.global_omt_location(), "ranch_camp_63", 20, - false ); + player_character.cash += -100000; + const tripoint site = overmap_buffer.find_closest( player_character.global_omt_location(), + "ranch_camp_63", 20, false ); tinymap bay; bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); bay.draw_square_ter( t_dirt, point( 5, 4 ), point( 15, 14 ) ); @@ -936,13 +940,15 @@ void talk_function::field_build_1( npc &p ) //Really expensive, but that is so you can't tear down the fence and sell the wood for a profit! void talk_function::field_build_2( npc &p ) { - if( g->u.cash < 550000 ) { + Character &player_character = get_player_character(); + if( player_character.cash < 550000 ) { popup( _( "I'm sorry, you don't have enough money." ) ); return; } p.set_mutation( trait_NPC_CONSTRUCTION_LEV_2 ); - g->u.cash += -550000; - const tripoint site = overmap_buffer.find_closest( g->u.global_omt_location(), "ranch_camp_63", + player_character.cash += -550000; + const tripoint site = overmap_buffer.find_closest( player_character.global_omt_location(), + "ranch_camp_63", 20, false ); tinymap bay; bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); @@ -960,11 +966,12 @@ void talk_function::field_build_2( npc &p ) void talk_function::field_plant( npc &p, const std::string &place ) { - if( !warm_enough_to_plant( g->u.pos() ) ) { + Character &player_character = get_player_character(); + if( !warm_enough_to_plant( player_character.pos() ) ) { popup( _( "It is too cold to plant anything now." ) ); return; } - std::vector seed_inv = g->u.items_with( []( const item & itm ) { + std::vector seed_inv = player_character.items_with( []( const item & itm ) { return itm.is_seed() && itm.typeId() != itype_marloss_seed && itm.typeId() != itype_fungal_seeds; } ); @@ -994,14 +1001,14 @@ void talk_function::field_plant( npc &p, const std::string &place ) const auto &seed_id = seed_types[seed_index]; if( item::count_by_charges( seed_id ) ) { - free_seeds = g->u.charges_of( seed_id ); + free_seeds = player_character.charges_of( seed_id ); } else { - free_seeds = g->u.amount_of( seed_id ); + free_seeds = player_character.amount_of( seed_id ); } //Now we need to find how many free plots we have to plant in... - const tripoint site = overmap_buffer.find_closest( g->u.global_omt_location(), place, 20, - false ); + const tripoint site = overmap_buffer.find_closest( player_character.global_omt_location(), place, + 20, false ); tinymap bay; bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); for( const tripoint &plot : bay.points_on_zlevel() ) { @@ -1021,7 +1028,7 @@ void talk_function::field_plant( npc &p, const std::string &place ) } signed int a = limiting_number * 300; - if( a > g->u.cash ) { + if( a > player_character.cash ) { popup( _( "I'm sorry, you don't have enough money to plant those seedsā€¦" ) ); return; } @@ -1035,9 +1042,9 @@ void talk_function::field_plant( npc &p, const std::string &place ) if( bay.ter( plot ) == t_dirtmound && limiting_number > 0 ) { std::list used_seed; if( item::count_by_charges( seed_id ) ) { - used_seed = g->u.use_charges( seed_id, 1 ); + used_seed = player_character.use_charges( seed_id, 1 ); } else { - used_seed = g->u.use_amount( seed_id, 1 ); + used_seed = player_character.use_amount( seed_id, 1 ); } used_seed.front().set_age( 0_turns ); bay.add_item_or_charges( plot, used_seed.front() ); @@ -1053,9 +1060,10 @@ void talk_function::field_plant( npc &p, const std::string &place ) void talk_function::field_harvest( npc &p, const std::string &place ) { + Character &player_character = get_player_character(); //First we need a list of plants that can be harvested... - const tripoint site = overmap_buffer.find_closest( g->u.global_omt_location(), place, 20, - false ); + const tripoint site = overmap_buffer.find_closest( player_character.global_omt_location(), place, + 20, false ); tinymap bay; item tmp; std::vector seed_types; @@ -1142,7 +1150,7 @@ void talk_function::field_harvest( npc &p, const std::string &place ) bool liquidate = false; signed int a = number_plots * 2; - if( a > g->u.cash ) { + if( a > player_character.cash ) { liquidate = true; popup( _( "You don't have enough to pay the workers to harvest the crop so you are forced " "to sellā€¦" ) ); @@ -1154,14 +1162,14 @@ void talk_function::field_harvest( npc &p, const std::string &place ) //Add fruit if( liquidate ) { add_msg( _( "The %s are sold for $%dā€¦" ), plant_names[plant_index], money ); - g->u.cash += ( number_plants * tmp.price( true ) - number_plots * 2 ) / 100; + player_character.cash += ( number_plants * tmp.price( true ) - number_plots * 2 ) / 100; } else { if( tmp.count_by_charges() ) { tmp.charges = 1; } for( int i = 0; i < number_plants; ++i ) { //Should be dropped at your feet once greedy companions can be controlled - g->u.i_add( tmp ); + player_character.i_add( tmp ); } add_msg( _( "You receive %d %sā€¦" ), number_plants, plant_names[plant_index] ); } @@ -1172,7 +1180,7 @@ void talk_function::field_harvest( npc &p, const std::string &place ) tmp.charges = 1; } for( int i = 0; i < number_seeds; ++i ) { - g->u.i_add( tmp ); + player_character.i_add( tmp ); } add_msg( _( "You receive %d %sā€¦" ), number_seeds, tmp.type_name( 3 ) ); } @@ -1225,8 +1233,9 @@ bool talk_function::scavenging_patrol_return( npc &p ) } } + Character &player_character = get_player_character(); int money = rng( 25, 450 ); - g->u.cash += money * 100; + player_character.cash += money * 100; companion_skill_trainer( *comp, "combat", experience * 10_minutes, 10 ); popup( _( "%s returns from patrol having earned $%d and a fair bit of experienceā€¦" ), @@ -1234,7 +1243,7 @@ bool talk_function::scavenging_patrol_return( npc &p ) if( one_in( 10 ) ) { popup( _( "%s was impressed with %s's performance and gave you a small bonus ( $100 )" ), p.name, comp->name ); - g->u.cash += 10000; + player_character.cash += 10000; } if( one_in( 10 ) && !p.has_trait( trait_NPC_MISSION_LEV_1 ) ) { p.set_mutation( trait_NPC_MISSION_LEV_1 ); @@ -1273,8 +1282,9 @@ bool talk_function::scavenging_raid_return( npc &p ) } } } + Character &player_character = get_player_character(); //The loot value needs to be added to the faction - what the player is payed - tripoint loot_location = g->u.global_omt_location(); + tripoint loot_location = player_character.global_omt_location(); // Only check at the ground floor. loot_location.z = 0; for( int i = 0; i < rng( 2, 3 ); i++ ) { @@ -1285,7 +1295,7 @@ bool talk_function::scavenging_raid_return( npc &p ) } int money = rng( 200, 900 ); - g->u.cash += money * 100; + player_character.cash += money * 100; companion_skill_trainer( *comp, "combat", experience * 10_minutes, 10 ); popup( _( "%s returns from the raid having earned $%d and a fair bit of experienceā€¦" ), @@ -1293,7 +1303,7 @@ bool talk_function::scavenging_raid_return( npc &p ) if( one_in( 20 ) ) { popup( _( "%s was impressed with %s's performance and gave you a small bonus ( $100 )" ), p.name, comp->name ); - g->u.cash += 10000; + player_character.cash += 10000; } if( one_in( 2 ) ) { std::string itemlist = "npc_misc"; @@ -1303,7 +1313,7 @@ bool talk_function::scavenging_raid_return( npc &p ) auto result = item_group::item_from( itemlist ); if( !result.is_null() ) { popup( _( "%s returned with a %s for you!" ), comp->name, result.tname() ); - g->u.i_add( result ); + player_character.i_add( result ); } } companion_return( *comp ); @@ -1317,9 +1327,10 @@ bool talk_function::labor_return( npc &p ) return false; } + Character &player_character = get_player_character(); float hours = to_hours( calendar::turn - comp->companion_mission_time ); int money = 8 * hours; - g->u.cash += money * 100; + player_character.cash += money * 100; companion_skill_trainer( *comp, "menial", calendar::turn - comp->companion_mission_time, 1 ); @@ -1376,7 +1387,7 @@ bool talk_function::carpenter_return( npc &p ) float hours = to_hours( calendar::turn - comp->companion_mission_time ); int money = 12 * hours; - g->u.cash += money * 100; + get_player_character().cash += money * 100; companion_skill_trainer( *comp, "construction", calendar::turn - comp->companion_mission_time, 2 ); @@ -1436,9 +1447,10 @@ bool talk_function::forage_return( npc &p ) } } + Character &player_character = get_player_character(); float hours = to_hours( calendar::turn - comp->companion_mission_time ); int money = 10 * hours; - g->u.cash += money * 100; + player_character.cash += money * 100; companion_skill_trainer( *comp, "gathering", calendar::turn - comp->companion_mission_time, 2 ); @@ -1472,7 +1484,7 @@ bool talk_function::forage_return( npc &p ) auto result = item_group::item_from( itemlist ); if( !result.is_null() ) { popup( _( "%s returned with a %s for you!" ), comp->name, result.tname() ); - g->u.i_add( result ); + player_character.i_add( result ); } if( one_in( 6 ) && !p.has_trait( trait_NPC_MISSION_LEV_1 ) ) { p.set_mutation( trait_NPC_MISSION_LEV_1 ); @@ -1567,7 +1579,8 @@ bool talk_function::force_on_force( const std::vector &defender, } else if( advantage > 0 ) { adv = ", defender advantage"; } - faction *yours = g->u.get_faction(); + Character &player_character = get_player_character(); + faction *yours = player_character.get_faction(); //Find out why your followers don't have your faction... popup( _( "Engagement between %d members of %s %s and %d %s%s!" ), defender.size(), yours->name, def_desc, monsters_fighting.size(), att_desc, adv ); @@ -1730,11 +1743,12 @@ void talk_function::companion_return( npc &comp ) comp.reset_companion_mission(); comp.companion_mission_time = calendar::before_time_starts; comp.companion_mission_time_ret = calendar::before_time_starts; + Character &player_character = get_player_character(); map &here = get_map(); for( size_t i = 0; i < comp.companion_mission_inv.size(); i++ ) { for( const auto &it : comp.companion_mission_inv.const_stack( i ) ) { if( !it.count_by_charges() || it.charges > 0 ) { - here.add_item_or_charges( g->u.pos(), it ); + here.add_item_or_charges( player_character.pos(), it ); } } } @@ -1866,8 +1880,10 @@ std::vector talk_function::companion_rank( const std::vector npc_ptr talk_function::companion_choose( const std::map &required_skills ) { + Character &player_character = get_player_character(); std::vector available; - cata::optional bcp = overmap_buffer.find_camp( g->u.global_omt_location().xy() ); + cata::optional bcp = overmap_buffer.find_camp( + player_character.global_omt_location().xy() ); for( auto &elem : g->get_follower_list() ) { npc_ptr guy = overmap_buffer.find_npc( elem ); @@ -1876,9 +1892,10 @@ npc_ptr talk_function::companion_choose( const std::map &required } npc_companion_mission c_mission = guy->get_companion_mission(); // get non-assigned visible followers - if( g->u.posz() == guy->posz() && !guy->has_companion_mission() && + if( player_character.posz() == guy->posz() && !guy->has_companion_mission() && !guy->is_travelling() && - ( rl_dist( g->u.pos(), guy->pos() ) <= SEEX * 2 ) && g->u.sees( guy->pos() ) ) { + ( rl_dist( player_character.pos(), guy->pos() ) <= SEEX * 2 ) && + player_character.sees( guy->pos() ) ) { available.push_back( guy ); } else if( bcp ) { basecamp *player_camp = *bcp; @@ -1984,13 +2001,14 @@ npc_ptr talk_function::companion_choose_return( const tripoint &omt_pos, const bool by_mission ) { std::vector available; + Character &player_character = get_player_character(); for( npc_ptr &guy : overmap_buffer.get_companion_mission_npcs() ) { npc_companion_mission c_mission = guy->get_companion_mission(); if( c_mission.position != omt_pos || ( by_mission && c_mission.mission_id != mission_id ) || c_mission.role_id != role_id ) { continue; } - if( g->u.has_trait( trait_DEBUG_HS ) ) { + if( player_character.has_trait( trait_DEBUG_HS ) ) { available.push_back( guy ); } else if( deadline == calendar::before_time_starts ) { if( guy->companion_mission_time_ret <= calendar::turn ) { diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 52db3954f51a1..658bb9defee40 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -148,7 +148,8 @@ int calc_skill_training_cost( const npc &p, const skill_id &skill ) return 0; } - return 1000 * ( 1 + g->u.get_skill_level( skill ) ) * ( 1 + g->u.get_skill_level( skill ) ); + int skill_level = get_player_character().get_skill_level( skill ); + return 1000 * ( 1 + skill_level ) * ( 1 + skill_level ); } // TODO: all styles cost the same and take the same time to train, @@ -256,7 +257,7 @@ static void npc_temp_orders_menu( const std::vector &npc_list ) return; } npc *guy = npc_list.front(); - + Character &player_character = get_player_character(); bool done = false; uilist nmenu; @@ -282,7 +283,7 @@ static void npc_temp_orders_menu( const std::vector &npc_list ) nmenu.reset(); nmenu.text = _( "Issue what temporary order?" ); nmenu.desc_enabled = true; - parse_tags( output_string, g->u, *guy ); + parse_tags( output_string, player_character, *guy ); nmenu.footer_text = output_string; nmenu.addentry( NPC_CHAT_DONE, true, 'd', _( "Done issuing orders" ) ); nmenu.addentry( NPC_CHAT_FORBID_ENGAGE, true, 'f', @@ -340,9 +341,10 @@ static void npc_temp_orders_menu( const std::vector &npc_list ) static void tell_veh_stop_following() { + Character &player_character = get_player_character(); for( wrapped_vehicle &veh : get_map().get_vehicles() ) { vehicle *v = veh.v; - if( v->has_engine_type( fuel_type_animal, false ) && v->is_owned_by( g->u ) ) { + if( v->has_engine_type( fuel_type_animal, false ) && v->is_owned_by( player_character ) ) { v->is_following = false; v->engine_on = false; } @@ -351,9 +353,10 @@ static void tell_veh_stop_following() static void assign_veh_to_follow() { + Character &player_character = get_player_character(); for( wrapped_vehicle &veh : get_map().get_vehicles() ) { vehicle *v = veh.v; - if( v->has_engine_type( fuel_type_animal, false ) && v->is_owned_by( g->u ) ) { + if( v->has_engine_type( fuel_type_animal, false ) && v->is_owned_by( player_character ) ) { v->activate_animal_follow(); } } @@ -361,12 +364,13 @@ static void assign_veh_to_follow() static void tell_magic_veh_to_follow() { + Character &player_character = get_player_character(); for( wrapped_vehicle &veh : get_map().get_vehicles() ) { vehicle *v = veh.v; if( v->magic ) { for( const vpart_reference &vp : v->get_all_parts() ) { const vpart_info &vpi = vp.info(); - if( vpi.has_flag( "MAGIC_FOLLOW" ) && v->is_owned_by( g->u ) ) { + if( vpi.has_flag( "MAGIC_FOLLOW" ) && v->is_owned_by( player_character ) ) { v->activate_magical_follow(); break; } @@ -394,7 +398,8 @@ static void tell_magic_veh_stop_following() void game::chat() { - int volume = g->u.get_shout_volume(); + Character &player_character = get_player_character(); + int volume = player_character.get_shout_volume(); const std::vector available = get_npcs_if( [&]( const npc & guy ) { // TODO: Get rid of the z-level check when z-level vision gets "better" @@ -413,8 +418,9 @@ void game::chat() } ); const int guard_count = guards.size(); - if( g->u.has_trait( trait_PROF_FOODP ) && !( g->u.is_wearing( itype_id( "foodperson_mask" ) ) || - g->u.is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) { + if( player_character.has_trait( trait_PROF_FOODP ) && + !( player_character.is_wearing( itype_id( "foodperson_mask" ) ) || + player_character.is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) { add_msg( m_warning, _( "You can't speak without your face!" ) ); return; } @@ -424,7 +430,8 @@ void game::chat() std::vector magic_following_vehicles; for( auto &veh : get_map().get_vehicles() ) { auto &v = veh.v; - if( v->has_engine_type( fuel_type_animal, false ) && v->is_owned_by( g->u ) ) { + if( v->has_engine_type( fuel_type_animal, false ) && + v->is_owned_by( player_character ) ) { animal_vehicles.push_back( v ); if( v->is_following ) { following_vehicles.push_back( v ); @@ -635,7 +642,8 @@ void npc::handle_sound( const sounds::sound_t spriority, const std::string &desc disp_name(), description, static_cast( spriority ), heard_volume, s_abs_pos.x, s_abs_pos.y, my_abs_pos.x, my_abs_pos.y ); - bool player_ally = g->u.pos() == spos && is_player_ally(); + Character &player_character = get_player_character(); + bool player_ally = player_character.pos() == spos && is_player_ally(); player *const sound_source = g->critter_at( spos ); bool npc_ally = sound_source && sound_source->is_npc() && is_ally( *sound_source ); @@ -661,7 +669,7 @@ void npc::handle_sound( const sounds::sound_t spriority, const std::string &desc } // discount if sound source is player, or seen by player, // and listener is friendly and sound source is combat or alert only. - if( spriority < sounds::sound_t::alarm && g->u.sees( spos ) ) { + if( spriority < sounds::sound_t::alarm && player_character.sees( spos ) ) { if( is_player_ally() ) { add_msg( m_debug, "NPC %s ignored low priority noise that player can see", name ); return; diff --git a/tests/crafting_test.cpp b/tests/crafting_test.cpp index 0cd15f9a4bc53..c5fa16be1ed2e 100644 --- a/tests/crafting_test.cpp +++ b/tests/crafting_test.cpp @@ -295,25 +295,26 @@ static void prep_craft( const recipe_id &rid, const std::vector &tools, clear_map(); const tripoint test_origin( 60, 60, 0 ); - g->u.setpos( test_origin ); + Character &player_character = get_player_character(); + player_character.setpos( test_origin ); const item backpack( "backpack" ); - g->u.worn.push_back( backpack ); - g->u.worn.push_back( backpack ); + player_character.worn.push_back( backpack ); + player_character.worn.push_back( backpack ); for( const item &gear : tools ) { - g->u.i_add( gear ); + player_character.i_add( gear ); } const recipe &r = rid.obj(); // Ensure adequate skill for all "required" skills for( const std::pair &skl : r.required_skills ) { - g->u.set_skill_level( skl.first, skl.second ); + player_character.set_skill_level( skl.first, skl.second ); } // and just in case "used" skill difficulty is higher, set that too - g->u.set_skill_level( r.skill_used, std::max( r.difficulty, - g->u.get_skill_level( r.skill_used ) ) ); - g->u.moves--; - const inventory &crafting_inv = g->u.crafting_inventory(); + player_character.set_skill_level( r.skill_used, std::max( r.difficulty, + player_character.get_skill_level( r.skill_used ) ) ); + player_character.moves--; + const inventory &crafting_inv = player_character.crafting_inventory(); bool can_craft = r.deduped_requirements().can_make_with_inventory( crafting_inv, r.get_component_filter() ); REQUIRE( can_craft == expect_craftable ); @@ -326,7 +327,7 @@ static void set_time( const time_point &time ) { calendar::turn = time; g->reset_light_level(); - int z = g->u.posz(); + int z = get_player_character().posz(); map &here = get_map(); here.update_visibility_cache( z ); here.invalidate_map_cache( z ); @@ -340,27 +341,29 @@ static int actually_test_craft( const recipe_id &rid, const std::vector &t { prep_craft( rid, tools, true ); set_time( midday ); // Ensure light for crafting + avatar &player_character = get_avatar(); const recipe &rec = rid.obj(); - REQUIRE( g->u.morale_crafting_speed_multiplier( rec ) == 1.0 ); - REQUIRE( g->u.lighting_craft_speed_multiplier( rec ) == 1.0 ); - REQUIRE( !g->u.activity ); + REQUIRE( player_character.morale_crafting_speed_multiplier( rec ) == 1.0 ); + REQUIRE( player_character.lighting_craft_speed_multiplier( rec ) == 1.0 ); + REQUIRE( !player_character.activity ); // This really shouldn't be needed, but for some reason the tests fail for mingw builds without it - g->u.learn_recipe( &rec ); - REQUIRE( g->u.has_recipe( &rec, g->u.crafting_inventory(), g->u.get_crafting_helpers() ) != -1 ); - g->u.remove_weapon(); - REQUIRE( !g->u.is_armed() ); - g->u.make_craft( rid, 1 ); - REQUIRE( g->u.activity ); - REQUIRE( g->u.activity.id() == activity_id( "ACT_CRAFT" ) ); + player_character.learn_recipe( &rec ); + REQUIRE( player_character.has_recipe( &rec, player_character.crafting_inventory(), + player_character.get_crafting_helpers() ) != -1 ); + player_character.remove_weapon(); + REQUIRE( !player_character.is_armed() ); + player_character.make_craft( rid, 1 ); + REQUIRE( player_character.activity ); + REQUIRE( player_character.activity.id() == activity_id( "ACT_CRAFT" ) ); int turns = 0; - while( g->u.activity.id() == activity_id( "ACT_CRAFT" ) ) { + while( player_character.activity.id() == activity_id( "ACT_CRAFT" ) ) { if( turns >= interrupt_after_turns ) { set_time( midnight ); // Kill light to interrupt crafting } ++turns; - g->u.moves = 100; - g->u.activity.do_turn( g->u ); + player_character.moves = 100; + player_character.activity.do_turn( player_character ); } return turns; } @@ -502,22 +505,23 @@ TEST_CASE( "tool_use", "[crafting][tool]" ) // Resume the first in progress craft found in the player's inventory static int resume_craft() { - std::vector crafts = g->u.items_with( []( const item & itm ) { + avatar &player_character = get_avatar(); + std::vector crafts = player_character.items_with( []( const item & itm ) { return itm.is_craft(); } ); REQUIRE( crafts.size() == 1 ); item *craft = crafts.front(); set_time( midday ); // Ensure light for crafting - REQUIRE( g->u.crafting_speed_multiplier( *craft, tripoint_zero ) == 1.0 ); - REQUIRE( !g->u.activity ); - g->u.use( g->u.get_item_position( craft ) ); - REQUIRE( g->u.activity ); - REQUIRE( g->u.activity.id() == activity_id( "ACT_CRAFT" ) ); + REQUIRE( player_character.crafting_speed_multiplier( *craft, tripoint_zero ) == 1.0 ); + REQUIRE( !player_character.activity ); + player_character.use( player_character.get_item_position( craft ) ); + REQUIRE( player_character.activity ); + REQUIRE( player_character.activity.id() == activity_id( "ACT_CRAFT" ) ); int turns = 0; - while( g->u.activity.id() == activity_id( "ACT_CRAFT" ) ) { + while( player_character.activity.id() == activity_id( "ACT_CRAFT" ) ) { ++turns; - g->u.moves = 100; - g->u.activity.do_turn( g->u ); + player_character.moves = 100; + player_character.activity.do_turn( player_character ); } return turns; } @@ -527,21 +531,22 @@ static void verify_inventory( const std::vector &has, { std::ostringstream os; os << "Inventory:\n"; - for( const item *i : g->u.inv_dump() ) { + Character &player_character = get_player_character(); + for( const item *i : player_character.inv_dump() ) { os << " " << i->typeId().str() << " (" << i->charges << ")\n"; } - os << "Wielded:\n" << g->u.weapon.tname() << "\n"; + os << "Wielded:\n" << player_character.weapon.tname() << "\n"; INFO( os.str() ); for( const std::string &i : has ) { INFO( "expecting " << i ); const bool has_item = - player_has_item_of_type( i ) || g->u.weapon.type->get_id() == itype_id( i ); + player_has_item_of_type( i ) || player_character.weapon.type->get_id() == itype_id( i ); REQUIRE( has_item ); } for( const std::string &i : hasnt ) { INFO( "not expecting " << i ); const bool hasnt_item = - !player_has_item_of_type( i ) && !( g->u.weapon.type->get_id() == itype_id( i ) ); + !player_has_item_of_type( i ) && !( player_character.weapon.type->get_id() == itype_id( i ) ); REQUIRE( hasnt_item ); } } From 897d84e6ae92f45753bf509a38e98bfc325202f3 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Wed, 15 Jul 2020 07:00:13 +0000 Subject: [PATCH 041/151] Global reference migration part 26 --- src/explosion.cpp | 77 +++-- src/gamemode_defense.cpp | 76 +++-- src/gamemode_tutorial.cpp | 71 ++-- src/handle_action.cpp | 667 ++++++++++++++++++++------------------ src/vehicle.h | 4 +- src/vehicle_move.cpp | 4 +- 6 files changed, 472 insertions(+), 427 deletions(-) diff --git a/src/explosion.cpp b/src/explosion.cpp index 4b5499d0caa09..899427a111fd0 100644 --- a/src/explosion.cpp +++ b/src/explosion.cpp @@ -14,7 +14,6 @@ #include #include -#include "avatar.h" #include "bodypart.h" #include "calendar.h" #include "cata_utility.h" @@ -44,7 +43,6 @@ #include "mtype.h" #include "npc.h" #include "optional.h" -#include "player.h" #include "point.h" #include "projectile.h" #include "rng.h" @@ -275,7 +273,7 @@ static void do_blast( const tripoint &p, const float power, explosion_colors[pt] = col; } - draw_custom_explosion( g->u.pos(), explosion_colors ); + draw_custom_explosion( get_player_character().pos(), explosion_colors ); for( const tripoint &pt : closed ) { const float force = power * std::pow( distance_factor, dist_map.at( pt ) ); @@ -315,7 +313,7 @@ static void do_blast( const tripoint &p, const float power, add_msg( m_debug, "Blast hits %s with force %.1f", critter->disp_name(), force ); - player *pl = dynamic_cast( critter ); + Character *pl = critter->as_character(); if( pl == nullptr ) { // TODO: player's fault? const double dmg = std::max( force - critter->get_armor_bash( bodypart_id( "torso" ) ) / 2.0, 0.0 ); @@ -402,6 +400,7 @@ static std::vector shrapnel( const tripoint &src, int power, update_fragment_cloud, accumulate_fragment_cloud> ( visited_cache, obstacle_cache, src.xy(), 0, initial_cloud ); + Character &player_character = get_player_character(); // Now visited_caches are populated with density and velocity of fragments. for( const tripoint &target : area ) { fragment_cloud &cloud = visited_cache[target.x][target.y]; @@ -444,7 +443,7 @@ static std::vector shrapnel( const tripoint &src, int power, } } int total_hits = damaging_hits + non_damaging_hits; - if( total_hits > 0 && g->u.sees( *critter ) ) { + if( total_hits > 0 && player_character.sees( *critter ) ) { // Building a phrase to summarize the fragment effects. // Target, Number of impacts, total amount of damage, proportion of deflected fragments. std::map impact_count_descriptions = { @@ -554,28 +553,31 @@ void explosion( const tripoint &p, const explosion_data &ex ) void flashbang( const tripoint &p, bool player_immune ) { draw_explosion( p, 8, c_white ); - int dist = rl_dist( g->u.pos(), p ); + Character &player_character = get_player_character(); + int dist = rl_dist( player_character.pos(), p ); map &here = get_map(); if( dist <= 8 && !player_immune ) { - if( !g->u.has_bionic( bio_ears ) && !g->u.is_wearing( itype_rm13_armor_on ) ) { - g->u.add_effect( effect_deaf, time_duration::from_turns( 40 - dist * 4 ) ); + if( !player_character.has_bionic( bio_ears ) && + !player_character.is_wearing( itype_rm13_armor_on ) ) { + player_character.add_effect( effect_deaf, time_duration::from_turns( 40 - dist * 4 ) ); } - if( here.sees( g->u.pos(), p, 8 ) ) { + if( here.sees( player_character.pos(), p, 8 ) ) { int flash_mod = 0; - if( g->u.has_trait( trait_PER_SLIME ) ) { + if( player_character.has_trait( trait_PER_SLIME ) ) { if( one_in( 2 ) ) { flash_mod = 3; // Yay, you weren't looking! } - } else if( g->u.has_trait( trait_PER_SLIME_OK ) ) { + } else if( player_character.has_trait( trait_PER_SLIME_OK ) ) { flash_mod = 8; // Just retract those and extrude fresh eyes - } else if( g->u.has_bionic( bio_sunglasses ) || - g->u.is_wearing( itype_rm13_armor_on ) ) { + } else if( player_character.has_bionic( bio_sunglasses ) || + player_character.is_wearing( itype_rm13_armor_on ) ) { flash_mod = 6; - } else if( g->u.worn_with_flag( flag_BLIND ) || g->u.worn_with_flag( flag_FLASH_PROTECTION ) ) { + } else if( player_character.worn_with_flag( flag_BLIND ) || + player_character.worn_with_flag( flag_FLASH_PROTECTION ) ) { flash_mod = 3; // Not really proper flash protection, but better than nothing } - g->u.add_env_effect( effect_blind, bp_eyes, ( 12 - flash_mod - dist ) / 2, - time_duration::from_turns( 10 - dist ) ); + player_character.add_env_effect( effect_blind, bp_eyes, ( 12 - flash_mod - dist ) / 2, + time_duration::from_turns( 10 - dist ) ); } } for( monster &critter : g->all_monsters() ) { @@ -617,7 +619,7 @@ void shockwave( const tripoint &p, int radius, int force, int stun, int dam_mult g->knockback( p, critter.pos(), force, stun, dam_mult ); } } - // TODO: combine the two loops and the case for g->u using all_creatures() + // TODO: combine the two loops and the case for avatar using all_creatures() for( npc &guy : g->all_npcs() ) { if( guy.posz() != p.z ) { continue; @@ -627,11 +629,13 @@ void shockwave( const tripoint &p, int radius, int force, int stun, int dam_mult g->knockback( p, guy.pos(), force, stun, dam_mult ); } } - if( rl_dist( g->u.pos(), p ) <= radius && !ignore_player && - ( !g->u.has_trait( trait_LEG_TENT_BRACE ) || g->u.footwear_factor() == 1 || - ( g->u.footwear_factor() == .5 && one_in( 2 ) ) ) ) { + Character &player_character = get_player_character(); + if( rl_dist( player_character.pos(), p ) <= radius && !ignore_player && + ( !player_character.has_trait( trait_LEG_TENT_BRACE ) || + player_character.footwear_factor() == 1 || + ( player_character.footwear_factor() == .5 && one_in( 2 ) ) ) ) { add_msg( m_bad, _( "You're caught in the shockwave!" ) ); - g->knockback( p, g->u.pos(), force, stun, dam_mult ); + g->knockback( p, player_character.pos(), force, stun, dam_mult ); } } @@ -651,7 +655,8 @@ void emp_blast( const tripoint &p ) { // TODO: Implement z part point p2( p.xy() ); - const bool sight = g->u.sees( p ); + Character &player_character = get_player_character(); + const bool sight = player_character.sees( p ); map &here = get_map(); if( here.has_flag( "CONSOLE", p2 ) ) { if( sight ) { @@ -744,21 +749,21 @@ void emp_blast( const tripoint &p ) add_msg( _( "The %s is unaffected by the EMP blast." ), critter.name() ); } } - if( g->u.posx() == p2.x && g->u.posy() == p2.y ) { - if( g->u.get_power_level() > 0_kJ ) { + if( player_character.posx() == p2.x && player_character.posy() == p2.y ) { + if( player_character.get_power_level() > 0_kJ ) { add_msg( m_bad, _( "The EMP blast drains your power." ) ); - int max_drain = ( g->u.get_power_level() > 1000_kJ ? 1000 : units::to_kilojoule( - g->u.get_power_level() ) ); - g->u.mod_power_level( units::from_kilojoule( -rng( 1 + max_drain / 3, max_drain ) ) ); + int max_drain = ( player_character.get_power_level() > 1000_kJ ? 1000 : units::to_kilojoule( + player_character.get_power_level() ) ); + player_character.mod_power_level( units::from_kilojoule( -rng( 1 + max_drain / 3, max_drain ) ) ); } // TODO: More effects? //e-handcuffs effects - if( g->u.weapon.typeId() == itype_e_handcuffs && g->u.weapon.charges > 0 ) { - g->u.weapon.item_tags.erase( "NO_UNWIELD" ); - g->u.weapon.charges = 0; - g->u.weapon.active = false; + if( player_character.weapon.typeId() == itype_e_handcuffs && player_character.weapon.charges > 0 ) { + player_character.weapon.item_tags.erase( "NO_UNWIELD" ); + player_character.weapon.charges = 0; + player_character.weapon.active = false; add_msg( m_good, _( "The %s on your wrists spark briefly, then release your hands!" ), - g->u.weapon.tname() ); + player_character.weapon.tname() ); } } // Drain any items of their battery charge @@ -772,12 +777,14 @@ void emp_blast( const tripoint &p ) void resonance_cascade( const tripoint &p ) { - const time_duration maxglow = time_duration::from_turns( 100 - 5 * trig_dist( p, g->u.pos() ) ); + Character &player_character = get_player_character(); + const time_duration maxglow = time_duration::from_turns( 100 - 5 * trig_dist( p, + player_character.pos() ) ); MonsterGroupResult spawn_details; if( maxglow > 0_turns ) { const time_duration minglow = std::max( 0_turns, time_duration::from_turns( 60 - 5 * trig_dist( p, - g->u.pos() ) ) ); - g->u.add_effect( effect_teleglow, rng( minglow, maxglow ) * 100 ); + player_character.pos() ) ) ); + player_character.add_effect( effect_teleglow, rng( minglow, maxglow ) * 100 ); } int startx = ( p.x < 8 ? 0 : p.x - 8 ), endx = ( p.x + 8 >= SEEX * 3 ? SEEX * 3 - 1 : p.x + 8 ); int starty = ( p.y < 8 ? 0 : p.y - 8 ), endy = ( p.y + 8 >= SEEY * 3 ? SEEY * 3 - 1 : p.y + 8 ); diff --git a/src/gamemode_defense.cpp b/src/gamemode_defense.cpp index e7e35b6207640..94dbc7c2b9078 100644 --- a/src/gamemode_defense.cpp +++ b/src/gamemode_defense.cpp @@ -62,7 +62,7 @@ std::string caravan_category_name( caravan_category cat ); std::vector caravan_items( caravan_category cat ); std::set monflags_to_add; -int caravan_price( player &u, int price ); +int caravan_price( Character &u, int price ); void draw_caravan_borders( const catacurses::window &w, int current_window ); void draw_caravan_categories( const catacurses::window &w, int category_selected, @@ -96,13 +96,14 @@ bool defense_game::init() { calendar::turn = calendar::turn_zero + 12_hours; // Start at noon g->weather.temperature = 65; - if( !g->u.create( character_type::CUSTOM ) ) { + avatar &player_character = get_avatar(); + if( !player_character.create( character_type::CUSTOM ) ) { return false; } - g->u.str_cur = g->u.str_max; - g->u.per_cur = g->u.per_max; - g->u.int_cur = g->u.int_max; - g->u.dex_cur = g->u.dex_max; + player_character.str_cur = player_character.str_max; + player_character.per_cur = player_character.per_max; + player_character.int_cur = player_character.int_max; + player_character.dex_cur = player_character.dex_max; init_mtypes(); init_constructions(); current_wave = 0; @@ -119,7 +120,7 @@ bool defense_game::init() allow_save = false; init_to_style( DEFENSE_EASY ); setup(); - g->u.cash = initial_cash; + player_character.cash = initial_cash; // TODO: support multiple defense games? clean up old defense game defloc_pos = tripoint( 50, 50, 0 ); init_map(); @@ -129,14 +130,15 @@ bool defense_game::init() void defense_game::per_turn() { + Character &player_character = get_player_character(); if( !thirst ) { - g->u.set_thirst( 0 ); + player_character.set_thirst( 0 ); } if( !hunger ) { - g->u.set_hunger( 0 ); + player_character.set_hunger( 0 ); } if( !sleep ) { - g->u.set_fatigue( 0 ); + player_character.set_fatigue( 0 ); } if( calendar::once_every( time_between_waves ) ) { current_wave++; @@ -171,11 +173,13 @@ void defense_game::pre_action( action_id &act ) case ACTION_MOVE_BACK_LEFT: case ACTION_MOVE_LEFT: case ACTION_MOVE_FORTH_LEFT: { + Character &player_character = get_player_character(); const point delta = get_delta_from_movement_action( act, iso_rotate::yes ); - if( ( delta.y < 0 && g->u.posy() == HALF_MAPSIZE_Y && g->get_levy() <= 93 ) - || ( delta.y > 0 && g->u.posy() == HALF_MAPSIZE_Y + SEEY - 1 && g->get_levy() >= 98 ) - || ( delta.x < 0 && g->u.posx() == HALF_MAPSIZE_X && g->get_levx() <= 93 ) - || ( delta.x > 0 && g->u.posx() == HALF_MAPSIZE_X + SEEX - 1 && g->get_levx() >= 98 ) ) { + if( ( delta.y < 0 && player_character.posy() == HALF_MAPSIZE_Y && g->get_levy() <= 93 ) + || ( delta.y > 0 && player_character.posy() == HALF_MAPSIZE_Y + SEEY - 1 && g->get_levy() >= 98 ) + || ( delta.x < 0 && player_character.posx() == HALF_MAPSIZE_X && g->get_levx() <= 93 ) + || ( delta.x > 0 && player_character.posx() == HALF_MAPSIZE_X + SEEX - 1 && + g->get_levx() >= 98 ) ) { action_error_message = string_format( _( "You cannot leave the %s behind!" ), defense_location_name( location ) ); } @@ -291,11 +295,13 @@ void defense_game::init_map() } g->load_map( omt_to_sm_copy( defloc_pos ) ); - g->u.setx( SEEX ); - g->u.sety( SEEY ); + Character &player_character = get_player_character(); + player_character.setx( SEEX ); + player_character.sety( SEEY ); - g->update_map( g-> u ); - monster *const generator = g->place_critter_around( mtype_id( "mon_generator" ), g->u.pos(), 2 ); + g->update_map( player_character ); + monster *const generator = g->place_critter_around( mtype_id( "mon_generator" ), + player_character.pos(), 2 ); assert( generator ); generator->friendly = -1; } @@ -890,8 +896,9 @@ void defense_game::caravan() int current_window = 0; + Character &player_character = get_player_character(); ui.on_redraw( [&]( const ui_adaptor & ) { - draw_caravan_categories( w, category_selected, total_price, g->u.cash ); + draw_caravan_categories( w, category_selected, total_price, player_character.cash ); draw_caravan_items( w, &( items[category_selected] ), &( item_count[category_selected] ), offset, item_selected ); draw_caravan_borders( w, current_window ); @@ -969,7 +976,7 @@ void defense_game::caravan() if( current_window == 1 && !items[category_selected].empty() ) { item_count[category_selected][item_selected]++; itype_id tmp_itm = items[category_selected][item_selected]; - total_price += caravan_price( g->u, item( tmp_itm, 0 ).price( false ) ); + total_price += caravan_price( player_character, item( tmp_itm, 0 ).price( false ) ); if( category_selected == CARAVAN_CART ) { // Find the item in its category for( int i = 1; i < NUM_CARAVAN_CATEGORIES; i++ ) { for( size_t j = 0; j < items[i].size(); j++ ) { @@ -997,7 +1004,7 @@ void defense_game::caravan() item_count[category_selected][item_selected] > 0 ) { item_count[category_selected][item_selected]--; itype_id tmp_itm = items[category_selected][item_selected]; - total_price -= caravan_price( g->u, item( tmp_itm, 0 ).price( false ) ); + total_price -= caravan_price( player_character, item( tmp_itm, 0 ).price( false ) ); if( category_selected == CARAVAN_CART ) { // Find the item in its category for( int i = 1; i < NUM_CARAVAN_CATEGORIES; i++ ) { for( size_t j = 0; j < items[i].size(); j++ ) { @@ -1028,7 +1035,7 @@ void defense_game::caravan() done = true; } } else if( action == "CONFIRM" ) { - if( total_price > g->u.cash ) { + if( total_price > player_character.cash ) { popup( _( "You can't afford those items!" ) ); } else if( ( items[0].empty() && query_yn( _( "Really buy nothing?" ) ) ) || ( !items[0].empty() && @@ -1036,7 +1043,7 @@ void defense_game::caravan() "Buy %d items, leaving you with %s?", items[0].size() ), items[0].size(), - format_money( static_cast( g->u.cash ) - static_cast( total_price ) ) ) ) ) { + format_money( static_cast( player_character.cash ) - static_cast( total_price ) ) ) ) ) { done = true; } } // "switch" on (action) @@ -1044,7 +1051,7 @@ void defense_game::caravan() } // while (!done) if( !cancel ) { - g->u.cash -= total_price; + player_character.cash -= total_price; bool dropped_some = false; for( size_t i = 0; i < items[0].size(); i++ ) { item tmp( items[0][i] ); @@ -1057,11 +1064,11 @@ void defense_game::caravan() } for( int j = 0; j < item_count[0][i]; j++ ) { - if( g->u.can_pickVolume( tmp ) && g->u.can_pickWeight( tmp ) ) { - g->u.i_add( tmp ); + if( player_character.can_pickVolume( tmp ) && player_character.can_pickWeight( tmp ) ) { + player_character.i_add( tmp ); } else { // Could fit it in the inventory! dropped_some = true; - get_map().add_item_or_charges( g->u.pos(), tmp ); + get_map().add_item_or_charges( player_character.pos(), tmp ); } } } @@ -1242,6 +1249,7 @@ void draw_caravan_items( const catacurses::window &w, std::vector *ite for( int i = 1; i <= FULL_SCREEN_HEIGHT - 2; i++ ) { mvwprintz( w, point( 40, i ), c_black, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ); } + Character &player_character = get_player_character(); // Finally, print the item list on the right for( int i = offset; i <= offset + FULL_SCREEN_HEIGHT - 2 && i < static_cast( items->size() ); i++ ) { @@ -1249,15 +1257,15 @@ void draw_caravan_items( const catacurses::window &w, std::vector *ite item::nname( ( *items )[i], ( *counts )[i] ) ); wprintz( w, c_white, " x %2d", ( *counts )[i] ); if( ( *counts )[i] > 0 ) { - int price = caravan_price( g->u, item( ( *items )[i], - 0 ).price( false ) * ( *counts )[i] ); - wprintz( w, ( price > g->u.cash ? c_red : c_green ), " (%s)", format_money( price ) ); + int price = caravan_price( player_character, item( ( *items )[i], + 0 ).price( false ) * ( *counts )[i] ); + wprintz( w, ( price > player_character.cash ? c_red : c_green ), " (%s)", format_money( price ) ); } } wnoutrefresh( w ); } -int caravan_price( player &u, int price ) +int caravan_price( Character &u, int price ) { ///\EFFECT_BARTER reduces caravan prices, 5% per point, up to 50% if( u.get_skill_level( skill_barter ) > 10 ) { @@ -1268,10 +1276,11 @@ int caravan_price( player &u, int price ) void defense_game::spawn_wave() { + Character &player_character = get_player_character(); add_msg( m_info, "********" ); int diff = initial_difficulty + current_wave * wave_difficulty; bool themed_wave = one_in( SPECIAL_WAVE_CHANCE ); // All a single monster type - g->u.cash += cash_per_wave + ( current_wave - 1 ) * cash_increase; + player_character.cash += cash_per_wave + ( current_wave - 1 ) * cash_increase; std::vector valid = pick_monster_wave(); while( diff > 0 ) { // Clear out any monsters that exceed our remaining difficulty @@ -1346,6 +1355,7 @@ std::vector defense_game::pick_monster_wave() void defense_game::spawn_wave_monster( const mtype_id &type ) { + tripoint player_pos = get_player_character().pos(); for( int tries = 0; tries < 1000; tries++ ) { point pnt; if( location == DEFLOC_HOSPITAL || location == DEFLOC_MALL ) { @@ -1367,7 +1377,7 @@ void defense_game::spawn_wave_monster( const mtype_id &type ) continue; } monster &tmp = *mon; - tmp.wander_pos = g->u.pos(); + tmp.wander_pos = player_pos; tmp.wandf = 150; // We want to kill! tmp.anger = 100; diff --git a/src/gamemode_tutorial.cpp b/src/gamemode_tutorial.cpp index 4c77de9204ff5..d8942a8db5f2d 100644 --- a/src/gamemode_tutorial.cpp +++ b/src/gamemode_tutorial.cpp @@ -115,18 +115,19 @@ bool tutorial_game::init() g->weather.temperature = 65; // We use a Z-factor of 10 so that we don't plop down tutorial rooms in the // middle of the "real" game world - g->u.normalize(); - g->u.str_cur = g->u.str_max; - g->u.per_cur = g->u.per_max; - g->u.int_cur = g->u.int_max; - g->u.dex_cur = g->u.dex_max; + avatar &player_character = get_avatar(); + player_character.normalize(); + player_character.str_cur = player_character.str_max; + player_character.per_cur = player_character.per_max; + player_character.int_cur = player_character.int_max; + player_character.dex_cur = player_character.dex_max; - g->u.set_all_parts_hp_to_max(); + player_character.set_all_parts_hp_to_max(); const oter_id rock( "rock" ); //~ default name for the tutorial - g->u.name = _( "John Smith" ); - g->u.prof = profession::generic(); + player_character.name = _( "John Smith" ); + player_character.prof = profession::generic(); // overmap terrain coordinates const tripoint lp( 50, 50, 0 ); auto &starting_om = overmap_buffer.get( point_zero ); @@ -142,18 +143,18 @@ bool tutorial_game::init() starting_om.ter_set( lp + tripoint_below, oter_id( "tutorial" ) ); starting_om.clear_mon_groups(); - g->u.toggle_trait( trait_QUICK ); + player_character.toggle_trait( trait_QUICK ); item lighter( "lighter", 0 ); lighter.invlet = 'e'; - g->u.inv.add_item( lighter, true, false ); - g->u.set_skill_level( skill_gun, 5 ); - g->u.set_skill_level( skill_melee, 5 ); + player_character.inv.add_item( lighter, true, false ); + player_character.set_skill_level( skill_gun, 5 ); + player_character.set_skill_level( skill_melee, 5 ); g->load_map( omt_to_sm_copy( lp ) ); - g->u.setx( 2 ); - g->u.sety( 4 ); + player_character.setx( 2 ); + player_character.sety( 4 ); // This shifts the view to center the players pos - g->update_map( g->u ); + g->update_map( player_character ); return true; } @@ -164,25 +165,26 @@ void tutorial_game::per_turn() add_message( tut_lesson::LESSON_MOVE ); add_message( tut_lesson::LESSON_LOOK ); - if( g->light_level( g->u.posz() ) == 1 ) { - if( g->u.has_amount( itype_flashlight, 1 ) ) { + Character &player_character = get_player_character(); + if( g->light_level( player_character.posz() ) == 1 ) { + if( player_character.has_amount( itype_flashlight, 1 ) ) { add_message( tut_lesson::LESSON_DARK ); } else { add_message( tut_lesson::LESSON_DARK_NO_FLASH ); } } - if( g->u.get_pain() > 0 ) { + if( player_character.get_pain() > 0 ) { add_message( tut_lesson::LESSON_PAIN ); } - if( g->u.recoil >= MAX_RECOIL ) { + if( player_character.recoil >= MAX_RECOIL ) { add_message( tut_lesson::LESSON_RECOIL ); } map &here = get_map(); if( !tutorials_seen[tut_lesson::LESSON_BUTCHER] ) { - for( const item &it : here.i_at( point( g->u.posx(), g->u.posy() ) ) ) { + for( const item &it : here.i_at( player_character.pos().xy() ) ) { if( it.is_corpse() ) { add_message( tut_lesson::LESSON_BUTCHER ); break; @@ -190,7 +192,7 @@ void tutorial_game::per_turn() } } - for( const tripoint &p : here.points_in_radius( g->u.pos(), 1 ) ) { + for( const tripoint &p : here.points_in_radius( player_character.pos(), 1 ) ) { if( here.ter( p ) == t_door_o ) { add_message( tut_lesson::LESSON_OPEN ); break; @@ -212,7 +214,7 @@ void tutorial_game::per_turn() } } - if( !here.i_at( point( g->u.posx(), g->u.posy() ) ).empty() ) { + if( !here.i_at( point( player_character.posx(), player_character.posy() ) ).empty() ) { add_message( tut_lesson::LESSON_PICKUP ); } } @@ -233,12 +235,13 @@ void tutorial_game::pre_action( action_id &act ) void tutorial_game::post_action( action_id act ) { + Character &player_character = get_player_character(); switch( act ) { case ACTION_RELOAD_WEAPON: - if( g->u.weapon.is_gun() && !tutorials_seen[tut_lesson::LESSON_GUN_FIRE] ) { - g->place_critter_at( mon_zombie, tripoint( g->u.posx(), g->u.posy() - 6, g->u.posz() ) ); - g->place_critter_at( mon_zombie, tripoint( g->u.posx() + 2, g->u.posy() - 5, g->u.posz() ) ); - g->place_critter_at( mon_zombie, tripoint( g->u.posx() - 2, g->u.posy() - 5, g->u.posz() ) ); + if( player_character.weapon.is_gun() && !tutorials_seen[tut_lesson::LESSON_GUN_FIRE] ) { + g->place_critter_at( mon_zombie, player_character.pos() + tripoint( 0, -6, 0 ) ); + g->place_critter_at( mon_zombie, player_character.pos() + tripoint( 2, -5, 0 ) ); + g->place_critter_at( mon_zombie, player_character.pos() + tripoint( -2, -5, 0 ) ); add_message( tut_lesson::LESSON_GUN_FIRE ); } break; @@ -252,11 +255,11 @@ void tutorial_game::post_action( action_id act ) break; case ACTION_USE: { - if( g->u.has_amount( itype_grenade_act, 1 ) ) { + if( player_character.has_amount( itype_grenade_act, 1 ) ) { add_message( tut_lesson::LESSON_ACT_GRENADE ); } map &here = get_map(); - for( const tripoint &dest : here.points_in_radius( g->u.pos(), 1 ) ) { + for( const tripoint &dest : here.points_in_radius( player_character.pos(), 1 ) ) { if( here.tr_at( dest ).id == trap_str_id( "tr_bubblewrap" ) ) { add_message( tut_lesson::LESSON_ACT_BUBBLEWRAP ); } @@ -265,17 +268,17 @@ void tutorial_game::post_action( action_id act ) break; case ACTION_EAT: - if( g->u.last_item == itype_codeine ) { + if( player_character.last_item == itype_codeine ) { add_message( tut_lesson::LESSON_TOOK_PAINKILLER ); - } else if( g->u.last_item == itype_cig ) { + } else if( player_character.last_item == itype_cig ) { add_message( tut_lesson::LESSON_TOOK_CIG ); - } else if( g->u.last_item == itype_water ) { + } else if( player_character.last_item == itype_water ) { add_message( tut_lesson::LESSON_DRANK_WATER ); } break; case ACTION_WEAR: { - item it( g->u.last_item, 0 ); + item it( player_character.last_item, 0 ); if( it.is_armor() ) { if( it.get_avg_coverage() >= 2 || it.get_thickness() >= 2 ) { add_message( tut_lesson::LESSON_WORE_ARMOR ); @@ -288,7 +291,7 @@ void tutorial_game::post_action( action_id act ) break; case ACTION_WIELD: - if( g->u.weapon.is_gun() ) { + if( player_character.weapon.is_gun() ) { add_message( tut_lesson::LESSON_GUN_LOAD ); } break; @@ -297,7 +300,7 @@ void tutorial_game::post_action( action_id act ) add_message( tut_lesson::LESSON_INTERACT ); /* fallthrough */ case ACTION_PICKUP: { - item it( g->u.last_item, 0 ); + item it( player_character.last_item, 0 ); if( it.is_armor() ) { add_message( tut_lesson::LESSON_GOT_ARMOR ); } else if( it.is_gun() ) { diff --git a/src/handle_action.cpp b/src/handle_action.cpp index 86fd2a33b210c..9996e79e2b363 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -347,13 +347,13 @@ input_context game::get_player_input( std::string &action ) inline static void rcdrive( const point &d ) { - player &u = g->u; + Character &player_character = get_player_character(); map &here = get_map(); - std::stringstream car_location_string( u.get_value( "remote_controlling" ) ); + std::stringstream car_location_string( player_character.get_value( "remote_controlling" ) ); if( car_location_string.str().empty() ) { //no turned radio car found - u.add_msg_if_player( m_warning, _( "No radio car connected." ) ); + add_msg( m_warning, _( "No radio car connected." ) ); return; } tripoint c; @@ -367,8 +367,8 @@ inline static void rcdrive( const point &d ) } } if( rc_pair == rc_pairs.end() ) { - u.add_msg_if_player( m_warning, _( "No radio car connected." ) ); - u.remove_value( "remote_controlling" ); + add_msg( m_warning, _( "No radio car connected." ) ); + player_character.remove_value( "remote_controlling" ); return; } item *rc_car = rc_pair->second; @@ -383,11 +383,11 @@ inline static void rcdrive( const point &d ) tripoint src( c ); //~ Sound of moving a remote controlled car sounds::sound( src, 6, sounds::sound_t::movement, _( "zzzā€¦" ), true, "misc", "rc_car_drives" ); - u.moves -= 50; + player_character.moves -= 50; here.i_rem( src, rc_car ); car_location_string.clear(); car_location_string << dest.x << ' ' << dest.y << ' ' << dest.z; - u.set_value( "remote_controlling", car_location_string.str() ); + player_character.set_value( "remote_controlling", car_location_string.str() ); return; } } @@ -397,13 +397,13 @@ static void pldrive( const tripoint &p ) if( !g->check_safe_mode_allowed() ) { return; } - player &u = g->u; vehicle *veh = g->remoteveh(); bool remote = true; int part = -1; + Character &player_character = get_player_character(); map &here = get_map(); if( !veh ) { - if( const optional_vpart_position vp = here.veh_at( u.pos() ) ) { + if( const optional_vpart_position vp = here.veh_at( player_character.pos() ) ) { veh = &vp->vehicle(); part = vp->part_index(); } @@ -412,7 +412,7 @@ static void pldrive( const tripoint &p ) if( !veh ) { dbg( D_ERROR ) << "game::pldrive: can't find vehicle! Drive mode is now off."; debugmsg( "game::pldrive error: can't find vehicle! Drive mode is now off." ); - u.in_vehicle = false; + player_character.in_vehicle = false; return; } if( !remote ) { @@ -423,11 +423,11 @@ static void pldrive( const tripoint &p ) veh->has_harnessed_animal(); if( !has_controls && !has_animal_controls ) { add_msg( m_info, _( "You can't drive the vehicle from here. You need controls!" ) ); - u.controlling_vehicle = false; + player_character.controlling_vehicle = false; return; } else if( !has_controls && has_animal_controls && !has_animal ) { add_msg( m_info, _( "You can't drive this vehicle without an animal to pull it." ) ); - u.controlling_vehicle = false; + player_character.controlling_vehicle = false; return; } } else { @@ -437,28 +437,28 @@ static void pldrive( const tripoint &p ) } } if( p.z != 0 ) { - if( !u.has_proficiency( proficiency_prof_helicopter_pilot ) ) { - u.add_msg_if_player( m_info, _( "You have no idea how to make the vehicle fly." ) ); + if( !player_character.has_proficiency( proficiency_prof_helicopter_pilot ) ) { + player_character.add_msg_if_player( m_info, _( "You have no idea how to make the vehicle fly." ) ); return; } if( !veh->is_flyable() ) { - u.add_msg_if_player( m_info, _( "This vehicle doesn't look very airworthy." ) ); + player_character.add_msg_if_player( m_info, _( "This vehicle doesn't look very airworthy." ) ); return; } if( !here.has_zlevels() ) { - u.add_msg_if_player( m_info, _( "This vehicle cannot be flown without z levels." ) ); + player_character.add_msg_if_player( m_info, _( "This vehicle cannot be flown without z levels." ) ); return; } } if( p.z == -1 ) { - if( veh->check_heli_descend( u ) ) { - u.add_msg_if_player( m_info, _( "You steer the vehicle into a descent." ) ); + if( veh->check_heli_descend( player_character ) ) { + player_character.add_msg_if_player( m_info, _( "You steer the vehicle into a descent." ) ); } else { return; } } else if( p.z == 1 ) { - if( veh->check_heli_ascend( u ) ) { - u.add_msg_if_player( m_info, _( "You steer the vehicle into an ascent." ) ); + if( veh->check_heli_ascend( player_character ) ) { + player_character.add_msg_if_player( m_info, _( "You steer the vehicle into an ascent." ) ); } else { return; } @@ -473,7 +473,7 @@ inline static void pldrive( point d ) static void open() { - player &u = g->u; + avatar &player_character = get_avatar(); const cata::optional openp_ = choose_adjacent_highlight( _( "Open where?" ), pgettext( "no door, gate, curtain, etc.", "There is nothing that can be opened nearby." ), ACTION_OPEN, false ); @@ -484,17 +484,17 @@ static void open() const tripoint openp = *openp_; map &here = get_map(); - u.moves -= 100; + player_character.moves -= 100; if( const optional_vpart_position vp = here.veh_at( openp ) ) { vehicle *const veh = &vp->vehicle(); int openable = veh->next_part_to_open( vp->part_index() ); if( openable >= 0 ) { - const vehicle *player_veh = veh_pointer_or_null( here.veh_at( u.pos() ) ); + const vehicle *player_veh = veh_pointer_or_null( here.veh_at( player_character.pos() ) ); bool outside = !player_veh || player_veh != veh; if( !outside ) { - if( !veh->handle_potential_theft( dynamic_cast( g->u ) ) ) { - u.moves += 100; + if( !veh->handle_potential_theft( player_character ) ) { + player_character.moves += 100; return; } else { veh->open( openable ); @@ -508,10 +508,10 @@ static void open() if( outside_openable == -1 ) { const std::string name = veh->part_info( openable ).name(); add_msg( m_info, _( "That %s can only opened from the inside." ), name ); - u.moves += 100; + player_character.moves += 100; } else { - if( !veh->handle_potential_theft( dynamic_cast( g->u ) ) ) { - u.moves += 100; + if( !veh->handle_potential_theft( player_character ) ) { + player_character.moves += 100; return; } else { veh->open_all_at( openable ); @@ -525,12 +525,12 @@ static void open() const std::string name = already_open->info().name(); add_msg( m_info, _( "That %s is already open." ), name ); } - u.moves += 100; + player_character.moves += 100; } return; } - bool didit = here.open_door( openp, !here.is_outside( u.pos() ) ); + bool didit = here.open_door( openp, !here.is_outside( player_character.pos() ) ); if( !didit ) { const ter_str_id tid = here.ter( openp ).id(); @@ -541,11 +541,11 @@ static void open() } else if( tid.obj().close ) { // if the following message appears unexpectedly, the prior check was for t_door_o add_msg( m_info, _( "That door is already open." ) ); - u.moves += 100; + player_character.moves += 100; return; } add_msg( m_info, _( "No door there." ) ); - u.moves += 100; + player_character.moves += 100; } } @@ -554,13 +554,14 @@ static void close() if( const cata::optional pnt = choose_adjacent_highlight( _( "Close where?" ), pgettext( "no door, gate, etc.", "There is nothing that can be closed nearby." ), ACTION_CLOSE, false ) ) { - doors::close_door( get_map(), g->u, *pnt ); + doors::close_door( get_map(), get_player_character(), *pnt ); } } static void handbrake() { - const optional_vpart_position vp = get_map().veh_at( g->u.pos() ); + Character &player_character = get_player_character(); + const optional_vpart_position vp = get_map().veh_at( player_character.pos() ); if( !vp ) { return; } @@ -580,13 +581,13 @@ static void handbrake() veh->velocity = sgn * ( std::abs( veh->velocity ) - braking_power ); } } - g->u.moves = 0; + player_character.moves = 0; } // Establish or release a grab on a vehicle static void grab() { - avatar &you = g->u; + avatar &you = get_avatar(); map &here = get_map(); if( you.get_grab_type() != object_type::NONE ) { @@ -613,7 +614,7 @@ static void grab() return; } if( const optional_vpart_position vp = here.veh_at( grabp ) ) { - if( !vp->vehicle().handle_potential_theft( dynamic_cast( g->u ) ) ) { + if( !vp->vehicle().handle_potential_theft( you ) ) { return; } you.grab( object_type::VEHICLE, grabp - you.pos() ); @@ -636,32 +637,32 @@ static void grab() static void haul() { - player &u = g->u; + Character &player_character = get_player_character(); map &here = get_map(); - if( u.is_hauling() ) { - u.stop_hauling(); + if( player_character.is_hauling() ) { + player_character.stop_hauling(); } else { - if( here.veh_at( u.pos() ) ) { + if( here.veh_at( player_character.pos() ) ) { add_msg( m_info, _( "You cannot haul inside vehicles." ) ); - } else if( here.has_flag( TFLAG_DEEP_WATER, u.pos() ) ) { + } else if( here.has_flag( TFLAG_DEEP_WATER, player_character.pos() ) ) { add_msg( m_info, _( "You cannot haul while in deep water." ) ); - } else if( !here.can_put_items( u.pos() ) ) { + } else if( !here.can_put_items( player_character.pos() ) ) { add_msg( m_info, _( "You cannot haul items here." ) ); - } else if( !here.has_items( u.pos() ) ) { + } else if( !here.has_items( player_character.pos() ) ) { add_msg( m_info, _( "There are no items to haul here." ) ); } else { - u.start_hauling(); + player_character.start_hauling(); } } } static void smash() { - player &u = g->u; + avatar &player_character = get_avatar(); map &here = get_map(); - if( u.is_mounted() ) { - auto mons = u.mounted_creature.get(); + if( player_character.is_mounted() ) { + auto mons = player_character.mounted_creature.get(); if( mons->has_flag( MF_RIDEABLE_MECH ) ) { if( !mons->check_mech_powered() ) { add_msg( m_bad, _( "Your %s refuses to move as its batteries have been drained." ), @@ -670,18 +671,19 @@ static void smash() } } } - const int move_cost = !u.is_armed() ? 80 : u.weapon.attack_time() * 0.8; + const int move_cost = !player_character.is_armed() ? 80 : player_character.weapon.attack_time() * + 0.8; bool didit = false; bool mech_smash = false; int smashskill; ///\EFFECT_STR increases smashing capability - if( u.is_mounted() ) { - auto mon = u.mounted_creature.get(); - smashskill = u.str_cur + mon->mech_str_addition() + mon->type->melee_dice * + if( player_character.is_mounted() ) { + auto mon = player_character.mounted_creature.get(); + smashskill = player_character.str_cur + mon->mech_str_addition() + mon->type->melee_dice * mon->type->melee_sides; mech_smash = true; } else { - smashskill = u.str_cur + u.weapon.damage_melee( DT_BASH ); + smashskill = player_character.str_cur + player_character.weapon.damage_melee( DT_BASH ); } const bool allow_floor_bash = debug_mode; // Should later become "true" @@ -692,17 +694,17 @@ static void smash() tripoint smashp = *smashp_; bool smash_floor = false; - if( smashp.z != u.posz() ) { - if( smashp.z > u.posz() ) { + if( smashp.z != player_character.posz() ) { + if( smashp.z > player_character.posz() ) { // TODO: Knock on the ceiling return; } - smashp.z = u.posz(); + smashp.z = player_character.posz(); smash_floor = true; } - if( u.is_mounted() ) { - monster *crit = u.mounted_creature.get(); + if( player_character.is_mounted() ) { + monster *crit = player_character.mounted_creature.get(); if( crit->has_flag( MF_RIDEABLE_MECH ) ) { crit->use_mech_power( -3 ); } @@ -720,7 +722,7 @@ static void smash() "field" ); here.remove_field( smashp, fd_to_smsh.first ); here.spawn_items( smashp, item_group::items_from( bash_info.drop_group, calendar::turn ) ); - u.mod_moves( - bash_info.fd_bash_move_cost ); + player_character.mod_moves( - bash_info.fd_bash_move_cost ); add_msg( m_info, bash_info.field_bash_msg_success.translated() ); return; } else { @@ -735,14 +737,14 @@ static void smash() if( maybe_corpse.is_corpse() && maybe_corpse.damage() < maybe_corpse.max_damage() && maybe_corpse.can_revive() ) { // do activity forever. ACT_PULP stops itself - u.assign_activity( ACT_PULP, calendar::INDEFINITELY_LONG, 0 ); - u.activity.placement = here.getabs( smashp ); + player_character.assign_activity( ACT_PULP, calendar::INDEFINITELY_LONG, 0 ); + player_character.activity.placement = here.getabs( smashp ); return; // don't smash terrain if we've smashed a corpse } } vehicle *veh = veh_pointer_or_null( here.veh_at( smashp ) ); if( veh != nullptr ) { - if( !veh->handle_potential_theft( dynamic_cast( g->u ) ) ) { + if( !veh->handle_potential_theft( player_character ) ) { return; } } @@ -753,36 +755,38 @@ static void smash() didit = here.bash( smashp, smashskill, false, false, smash_floor ).did_bash; if( didit ) { if( !mech_smash ) { - u.increase_activity_level( MODERATE_EXERCISE ); - u.handle_melee_wear( u.weapon ); + player_character.increase_activity_level( MODERATE_EXERCISE ); + player_character.handle_melee_wear( player_character.weapon ); - const int mod_sta = 2 * u.get_standard_stamina_cost(); - u.mod_stamina( mod_sta ); + const int mod_sta = 2 * player_character.get_standard_stamina_cost(); + player_character.mod_stamina( mod_sta ); - if( u.get_skill_level( skill_melee ) == 0 ) { - u.practice( skill_melee, rng( 0, 1 ) * rng( 0, 1 ) ); + if( player_character.get_skill_level( skill_melee ) == 0 ) { + player_character.practice( skill_melee, rng( 0, 1 ) * rng( 0, 1 ) ); } - const int vol = u.weapon.volume() / units::legacy_volume_factor; - if( u.weapon.made_of( material_id( "glass" ) ) && + const int vol = player_character.weapon.volume() / units::legacy_volume_factor; + if( player_character.weapon.made_of( material_id( "glass" ) ) && rng( 0, vol + 3 ) < vol ) { - add_msg( m_bad, _( "Your %s shatters!" ), u.weapon.tname() ); - u.weapon.spill_contents( u.pos() ); - sounds::sound( u.pos(), 24, sounds::sound_t::combat, "CRACK!", true, "smash", "glass" ); - u.deal_damage( nullptr, bodypart_id( "hand_r" ), damage_instance( DT_CUT, rng( 0, vol ) ) ); + add_msg( m_bad, _( "Your %s shatters!" ), player_character.weapon.tname() ); + player_character.weapon.spill_contents( player_character.pos() ); + sounds::sound( player_character.pos(), 24, sounds::sound_t::combat, "CRACK!", true, "smash", + "glass" ); + player_character.deal_damage( nullptr, bodypart_id( "hand_r" ), damage_instance( DT_CUT, rng( 0, + vol ) ) ); if( vol > 20 ) { // Hurt left arm too, if it was big - u.deal_damage( nullptr, bodypart_id( "hand_l" ), damage_instance( DT_CUT, rng( 0, - static_cast( vol * .5 ) ) ) ); + player_character.deal_damage( nullptr, bodypart_id( "hand_l" ), damage_instance( DT_CUT, rng( 0, + static_cast( vol * .5 ) ) ) ); } - u.remove_weapon(); - u.check_dead_state(); + player_character.remove_weapon(); + player_character.check_dead_state(); } // It hurts if you smash things with your hands. const bool hard_target = ( ( bash_furn > 2 ) || ( bash_furn == -1 && bash_ter > 2 ) ); int glove_coverage = 0; - for( const item &i : u.worn ) { + for( const item &i : player_character.worn ) { if( ( i.covers( bodypart_id( "hand_l" ) ) || i.covers( bodypart_id( "hand_r" ) ) ) ) { int l_coverage = i.get_coverage( bodypart_id( "hand_l" ) ); int r_coverage = i.get_coverage( bodypart_id( "hand_r" ) ); @@ -790,19 +794,20 @@ static void smash() } } - if( !u.has_weapon() && hard_target ) { + if( !player_character.has_weapon() && hard_target ) { int dam = roll_remainder( 5.0 * ( 1 - glove_coverage / 100.0 ) ); - if( u.get_part_hp_cur( bodypart_id( "arm_r" ) ) > u.get_part_hp_cur( bodypart_id( "arm_l" ) ) ) { - u.deal_damage( nullptr, bodypart_id( "hand_r" ), damage_instance( DT_BASH, dam ) ); + if( player_character.get_part_hp_cur( bodypart_id( "arm_r" ) ) > player_character.get_part_hp_cur( + bodypart_id( "arm_l" ) ) ) { + player_character.deal_damage( nullptr, bodypart_id( "hand_r" ), damage_instance( DT_BASH, dam ) ); } else { - u.deal_damage( nullptr, bodypart_id( "hand_l" ), damage_instance( DT_BASH, dam ) ); + player_character.deal_damage( nullptr, bodypart_id( "hand_l" ), damage_instance( DT_BASH, dam ) ); } if( dam > 0 ) { add_msg( m_bad, _( "You hurt your hands trying to smash the %s." ), here.furnname( smashp ) ); } } } - u.moves -= move_cost; + player_character.moves -= move_cost; if( smashskill < here.bash_resistance( smashp ) && one_in( 10 ) ) { if( here.has_furn( smashp ) && here.furn( smashp ).obj().bash.str_min != -1 ) { @@ -821,7 +826,7 @@ static void smash() static int try_set_alarm() { uilist as_m; - const bool already_set = g->u.has_effect( effect_alarm_clock ); + const bool already_set = get_player_character().has_effect( effect_alarm_clock ); as_m.text = already_set ? _( "You already have an alarm set. What do you want to do?" ) : @@ -842,17 +847,18 @@ static void wait() { std::map durations; uilist as_m; - player &u = g->u; + Character &player_character = get_player_character(); bool setting_alarm = false; map &here = get_map(); - if( u.controlling_vehicle && ( here.veh_at( u.pos() )->vehicle().velocity || - here.veh_at( u.pos() )->vehicle().cruise_velocity ) ) { + if( player_character.controlling_vehicle && + ( here.veh_at( player_character.pos() )->vehicle().velocity || + here.veh_at( player_character.pos() )->vehicle().cruise_velocity ) ) { popup( _( "You can't pass time while controlling a moving vehicle." ) ); return; } - if( u.has_alarm_clock() ) { + if( player_character.has_alarm_clock() ) { int alarm_query = try_set_alarm(); if( alarm_query == UILIST_CANCEL ) { return; @@ -860,7 +866,7 @@ static void wait() setting_alarm = alarm_query == 1; } - const bool has_watch = u.has_watch() || setting_alarm; + const bool has_watch = player_character.has_watch() || setting_alarm; const auto add_menu_item = [ &as_m, &durations, has_watch ] ( int retval, int hotkey, const std::string &caption = "", @@ -885,7 +891,7 @@ static void wait() } } else { - if( g->u.get_stamina() < g->u.get_stamina_max() ) { + if( player_character.get_stamina() < player_character.get_stamina_max() ) { as_m.addentry( 12, true, 'w', _( "Wait until you catch your breath" ) ); durations.emplace( 12, 15_minutes ); // to hide it from showing } @@ -923,7 +929,7 @@ static void wait() setting_alarm ? _( "Set alarm for midnight" ) : _( "Wait till midnight" ), diurnal_time_before( last_midnight + 0_hours ) ); if( setting_alarm ) { - if( u.has_effect( effect_alarm_clock ) ) { + if( player_character.has_effect( effect_alarm_clock ) ) { add_menu_item( 11, 'x', _( "Cancel the currently set alarm." ), 0_turns ); } @@ -945,11 +951,11 @@ static void wait() if( setting_alarm ) { // Setting alarm - u.remove_effect( effect_alarm_clock ); + player_character.remove_effect( effect_alarm_clock ); if( as_m.ret == 11 ) { add_msg( _( "You cancel your alarm." ) ); } else { - u.add_effect( effect_alarm_clock, time_to_wait ); + player_character.add_effect( effect_alarm_clock, time_to_wait ); add_msg( _( "You set your alarm." ) ); } @@ -966,15 +972,15 @@ static void wait() player_activity new_act( actType, 100 * ( to_turns( time_to_wait ) - 1 ), 0 ); - u.assign_activity( new_act, false ); + player_character.assign_activity( new_act, false ); } } static void sleep() { - player &u = g->u; - if( u.is_mounted() ) { - u.add_msg_if_player( m_info, _( "You cannot sleep while mounted." ) ); + avatar &player_character = get_avatar(); + if( player_character.is_mounted() ) { + add_msg( m_info, _( "You cannot sleep while mounted." ) ); return; } uilist as_m; @@ -992,15 +998,16 @@ static void sleep() // List all active items, bionics or mutations so player can deactivate them std::vector active; - for( auto &it : u.inv_dump() ) { + for( auto &it : player_character.inv_dump() ) { if( it->has_flag( flag_LITCIG ) || - ( it->active && ( it->charges > 0 || it->units_remaining( u ) > 0 ) && it->is_tool() && + ( it->active && ( it->charges > 0 || it->units_remaining( player_character ) > 0 ) && + it->is_tool() && !it->has_flag( flag_SLEEP_IGNORE ) ) ) { active.push_back( it->tname() ); } } - for( int i = 0; i < g->u.num_bionics(); i++ ) { - const bionic &bio = u.bionic_at_index( i ); + for( int i = 0; i < player_character.num_bionics(); i++ ) { + const bionic &bio = player_character.bionic_at_index( i ); if( !bio.powered ) { continue; } @@ -1017,17 +1024,18 @@ static void sleep() active.push_back( info.name.translated() ); } } - for( auto &mut : u.get_mutations() ) { + for( auto &mut : player_character.get_mutations() ) { const auto &mdata = mut.obj(); - if( mdata.cost > 0 && u.has_active_mutation( mut ) ) { + if( mdata.cost > 0 && player_character.has_active_mutation( mut ) ) { active.push_back( mdata.name() ); } } // check for deactivating any currently played music instrument. - for( auto &item : u.inv_dump() ) { + for( auto &item : player_character.inv_dump() ) { if( item->active && item->get_use( "musical_instrument" ) != nullptr ) { - u.add_msg_if_player( _( "You stop playing your %s before trying to sleep." ), item->tname() ); + player_character.add_msg_if_player( _( "You stop playing your %s before trying to sleep." ), + item->tname() ); // deactivate instrument item->active = false; } @@ -1058,12 +1066,13 @@ static void sleep() time_duration try_sleep_dur = 24_hours; std::string deaf_text; - if( g->u.is_deaf() ) { + if( player_character.is_deaf() ) { deaf_text = _( " (DEAF!)" ); } - if( u.has_alarm_clock() ) { + if( player_character.has_alarm_clock() ) { /* Reuse menu to ask player whether they want to set an alarm. */ - bool can_hibernate = u.get_hunger() < -60 && u.has_active_mutation( trait_HIBERNATE ); + bool can_hibernate = player_character.get_hunger() < -60 && + player_character.has_active_mutation( trait_HIBERNATE ); as_m.reset(); as_m.text = can_hibernate ? @@ -1083,15 +1092,15 @@ static void sleep() as_m.query(); if( as_m.ret >= 3 && as_m.ret <= 9 ) { - u.add_effect( effect_alarm_clock, 1_hours * as_m.ret ); + player_character.add_effect( effect_alarm_clock, 1_hours * as_m.ret ); try_sleep_dur = 1_hours * as_m.ret + 1_turns; } else if( as_m.ret < 0 ) { return; } } - u.moves = 0; - u.try_to_sleep( try_sleep_dur ); + player_character.moves = 0; + player_character.try_to_sleep( try_sleep_dur ); } static void loot() @@ -1110,31 +1119,36 @@ static void loot() MultiMining = 8192 }; - player &u = g->u; + Character &player_character = get_player_character(); int flags = 0; auto &mgr = zone_manager::get_manager(); - const bool has_fertilizer = u.has_item_with_flag( "FERTILIZER" ); + const bool has_fertilizer = player_character.has_item_with_flag( "FERTILIZER" ); // Manually update vehicle cache. // In theory this would be handled by the related activity (activity_on_turn_move_loot()) // but with a stale cache we never get that far. mgr.cache_vzones(); - flags |= g->check_near_zone( zone_type_id( "LOOT_UNSORTED" ), u.pos() ) ? SortLoot : 0; - if( g->check_near_zone( zone_type_id( "FARM_PLOT" ), u.pos() ) ) { + flags |= g->check_near_zone( zone_type_id( "LOOT_UNSORTED" ), + player_character.pos() ) ? SortLoot : 0; + if( g->check_near_zone( zone_type_id( "FARM_PLOT" ), player_character.pos() ) ) { flags |= FertilizePlots; flags |= MultiFarmPlots; } flags |= g->check_near_zone( zone_type_id( "CONSTRUCTION_BLUEPRINT" ), - u.pos() ) ? ConstructPlots : 0; + player_character.pos() ) ? ConstructPlots : 0; - flags |= g->check_near_zone( zone_type_id( "CHOP_TREES" ), u.pos() ) ? Multichoptrees : 0; - flags |= g->check_near_zone( zone_type_id( "LOOT_WOOD" ), u.pos() ) ? Multichopplanks : 0; + flags |= g->check_near_zone( zone_type_id( "CHOP_TREES" ), + player_character.pos() ) ? Multichoptrees : 0; + flags |= g->check_near_zone( zone_type_id( "LOOT_WOOD" ), + player_character.pos() ) ? Multichopplanks : 0; flags |= g->check_near_zone( zone_type_id( "VEHICLE_DECONSTRUCT" ), - u.pos() ) ? Multideconvehicle : 0; - flags |= g->check_near_zone( zone_type_id( "VEHICLE_REPAIR" ), u.pos() ) ? Multirepairvehicle : 0; - flags |= g->check_near_zone( zone_type_id( "LOOT_CORPSE" ), u.pos() ) ? MultiButchery : 0; - flags |= g->check_near_zone( zone_type_id( "MINING" ), u.pos() ) ? MultiMining : 0; + player_character.pos() ) ? Multideconvehicle : 0; + flags |= g->check_near_zone( zone_type_id( "VEHICLE_REPAIR" ), + player_character.pos() ) ? Multirepairvehicle : 0; + flags |= g->check_near_zone( zone_type_id( "LOOT_CORPSE" ), + player_character.pos() ) ? MultiButchery : 0; + flags |= g->check_near_zone( zone_type_id( "MINING" ), player_character.pos() ) ? MultiMining : 0; if( flags == 0 ) { add_msg( m_info, _( "There is no compatible zone nearby." ) ); add_msg( m_info, _( "Compatible zones are %s and %s" ), @@ -1199,34 +1213,34 @@ static void loot() add_msg( _( "Never mind." ) ); break; case SortLoot: - u.assign_activity( ACT_MOVE_LOOT ); + player_character.assign_activity( ACT_MOVE_LOOT ); break; case FertilizePlots: - u.assign_activity( ACT_FERTILIZE_PLOT ); + player_character.assign_activity( ACT_FERTILIZE_PLOT ); break; case ConstructPlots: - u.assign_activity( ACT_MULTIPLE_CONSTRUCTION ); + player_character.assign_activity( ACT_MULTIPLE_CONSTRUCTION ); break; case MultiFarmPlots: - u.assign_activity( ACT_MULTIPLE_FARM ); + player_character.assign_activity( ACT_MULTIPLE_FARM ); break; case Multichoptrees: - u.assign_activity( ACT_MULTIPLE_CHOP_TREES ); + player_character.assign_activity( ACT_MULTIPLE_CHOP_TREES ); break; case Multichopplanks: - u.assign_activity( ACT_MULTIPLE_CHOP_PLANKS ); + player_character.assign_activity( ACT_MULTIPLE_CHOP_PLANKS ); break; case Multideconvehicle: - u.assign_activity( ACT_VEHICLE_DECONSTRUCTION ); + player_character.assign_activity( ACT_VEHICLE_DECONSTRUCTION ); break; case Multirepairvehicle: - u.assign_activity( ACT_VEHICLE_REPAIR ); + player_character.assign_activity( ACT_VEHICLE_REPAIR ); break; case MultiButchery: - u.assign_activity( ACT_MULTIPLE_BUTCHER ); + player_character.assign_activity( ACT_MULTIPLE_BUTCHER ); break; case MultiMining: - u.assign_activity( ACT_MULTIPLE_MINE ); + player_character.assign_activity( ACT_MULTIPLE_MINE ); break; default: debugmsg( "Unsupported flag" ); @@ -1236,11 +1250,11 @@ static void loot() static void wear() { - avatar &u = g->u; - item_location loc = game_menus::inv::wear( u ); + avatar &player_character = get_avatar(); + item_location loc = game_menus::inv::wear( player_character ); if( loc ) { - u.wear( *loc.obtain( u ) ); + player_character.wear( *loc.obtain( player_character ) ); } else { add_msg( _( "Never mind." ) ); } @@ -1248,11 +1262,11 @@ static void wear() static void takeoff() { - avatar &u = g->u; - item_location loc = game_menus::inv::take_off( u ); + avatar &player_character = get_avatar(); + item_location loc = game_menus::inv::take_off( player_character ); if( loc ) { - u.takeoff( *loc.obtain( u ) ); + player_character.takeoff( *loc.obtain( player_character ) ); } else { add_msg( _( "Never mind." ) ); } @@ -1260,16 +1274,17 @@ static void takeoff() static void read() { - avatar &u = g->u; + avatar &player_character = get_avatar(); // Can read items from inventory or within one tile (including in vehicles) - item_location loc = game_menus::inv::read( u ); + item_location loc = game_menus::inv::read( player_character ); if( loc ) { if( loc->type->can_use( "learn_spell" ) ) { item spell_book = *loc.get_item(); - spell_book.get_use( "learn_spell" )->call( u, spell_book, spell_book.active, u.pos() ); + spell_book.get_use( "learn_spell" )->call( player_character, spell_book, + spell_book.active, player_character.pos() ); } else { - u.read( *loc.obtain( u ) ); + player_character.read( *loc.obtain( player_character ) ); } } else { add_msg( _( "Never mind." ) ); @@ -1291,17 +1306,17 @@ static void reach_attack( avatar &you ) static void fire() { - avatar &u = g->u; + avatar &player_character = get_avatar(); map &here = get_map(); // Use vehicle turret or draw a pistol from a holster if unarmed - if( !u.is_armed() ) { + if( !player_character.is_armed() ) { - const optional_vpart_position vp = here.veh_at( u.pos() ); + const optional_vpart_position vp = here.veh_at( player_character.pos() ); turret_data turret; - if( vp && ( turret = vp->vehicle().turret_query( u.pos() ) ) ) { - avatar_action::fire_turret_manual( u, here, turret ); + if( vp && ( turret = vp->vehicle().turret_query( player_character.pos() ) ) ) { + avatar_action::fire_turret_manual( player_character, here, turret ); return; } @@ -1314,7 +1329,7 @@ static void fire() std::vector options; std::vector> actions; - for( auto &w : u.worn ) { + for( auto &w : player_character.worn ) { std::vector guns = w.items_with( []( const item & it ) { return it.is_gun(); @@ -1328,12 +1343,12 @@ static void fire() w.type_name(), guns.front()->ammo_remaining() ) ); - actions.emplace_back( [&] { u.invoke_item( &w, "holster" ); } ); + actions.emplace_back( [&] { player_character.invoke_item( &w, "holster" ); } ); } else if( w.is_gun() && w.gunmod_find( itype_shoulder_strap ) ) { // wield item currently worn using shoulder strap options.push_back( w.display_name() ); - actions.emplace_back( [&] { u.wield( w ); } ); + actions.emplace_back( [&] { player_character.wield( w ); } ); } } if( !options.empty() ) { @@ -1344,26 +1359,26 @@ static void fire() } } - if( u.weapon.is_gun() && !u.weapon.gun_current_mode().melee() ) { - avatar_action::fire_wielded_weapon( u ); - } else if( u.weapon.current_reach_range( u ) > 1 ) { - if( u.has_effect( effect_relax_gas ) ) { + if( player_character.weapon.is_gun() && !player_character.weapon.gun_current_mode().melee() ) { + avatar_action::fire_wielded_weapon( player_character ); + } else if( player_character.weapon.current_reach_range( player_character ) > 1 ) { + if( player_character.has_effect( effect_relax_gas ) ) { if( one_in( 8 ) ) { add_msg( m_good, _( "Your willpower asserts itself, and so do you!" ) ); - reach_attack( u ); + reach_attack( player_character ); } else { - u.moves -= rng( 2, 8 ) * 10; + player_character.moves -= rng( 2, 8 ) * 10; add_msg( m_bad, _( "You're too pacified to strike anythingā€¦" ) ); } } else { - reach_attack( u ); + reach_attack( player_character ); } } } static void open_movement_mode_menu() { - avatar &u = g->u; + avatar &player_character = get_avatar(); const std::vector &modes = move_modes_by_speed(); const int cycle = 1027; uilist as_m; @@ -1372,10 +1387,12 @@ static void open_movement_mode_menu() for( size_t i = 0; i < modes.size(); ++i ) { const move_mode_id &curr = modes[i]; - as_m.entries.emplace_back( static_cast( i ), u.can_switch_to( curr ), curr->letter(), + as_m.entries.emplace_back( static_cast( i ), player_character.can_switch_to( curr ), + curr->letter(), curr->name() ); } - as_m.entries.emplace_back( cycle, u.can_switch_to( u.current_movement_mode()->cycle() ), '"', + as_m.entries.emplace_back( cycle, + player_character.can_switch_to( player_character.current_movement_mode()->cycle() ), '"', _( "Cycle move mode" ) ); // This should select the middle move mode as_m.selected = std::floor( modes.size() / 2 ); @@ -1383,20 +1400,20 @@ static void open_movement_mode_menu() if( as_m.ret != UILIST_CANCEL ) { if( as_m.ret == cycle ) { - u.cycle_move_mode(); + player_character.cycle_move_mode(); } else { - u.set_movement_mode( modes[as_m.ret] ); + player_character.set_movement_mode( modes[as_m.ret] ); } } } -static bool assign_spellcasting( avatar &you, spell &sp, bool fake_spell ); +static bool assign_spellcasting( Character &you, spell &sp, bool fake_spell ); static void cast_spell() { - avatar &u = g->u; + Character &player_character = get_player_character(); - std::vector spells = u.magic.spells(); + std::vector spells = player_character.magic.spells(); if( spells.empty() ) { add_msg( game_message_params{ m_bad, gmf_bypass_cooldown }, @@ -1406,8 +1423,8 @@ static void cast_spell() bool can_cast_spells = false; for( const spell_id &sp : spells ) { - spell temp_spell = u.magic.get_spell( sp ); - if( temp_spell.can_cast( u ) ) { + spell temp_spell = player_character.magic.get_spell( sp ); + if( temp_spell.can_cast( player_character ) ) { can_cast_spells = true; } } @@ -1417,18 +1434,18 @@ static void cast_spell() _( "You can't cast any of the spells you know!" ) ); } - const int spell_index = u.magic.select_spell( u ); + const int spell_index = player_character.magic.select_spell( player_character ); if( spell_index < 0 ) { return; } - spell &sp = *u.magic.get_spells()[spell_index]; + spell &sp = *player_character.magic.get_spells()[spell_index]; - assign_spellcasting( u, sp, false ); + assign_spellcasting( player_character, sp, false ); } // returns if the spell was assigned -static bool assign_spellcasting( avatar &you, spell &sp, bool fake_spell ) +static bool assign_spellcasting( Character &you, spell &sp, bool fake_spell ) { if( you.is_armed() && !sp.has_flag( spell_flag::NO_HANDS ) && !you.weapon.has_flag( flag_MAGIC_FOCUS ) ) { @@ -1504,15 +1521,16 @@ void game::open_consume_item_menu() as_m.entries.emplace_back( 2, true, 'm', _( "Medication" ) ); as_m.query(); + avatar &player_character = get_avatar(); switch( as_m.ret ) { case 0: - avatar_action::eat( u, game_menus::inv::consume_food( u ) ); + avatar_action::eat( player_character, game_menus::inv::consume_food( player_character ) ); break; case 1: - avatar_action::eat( u, game_menus::inv::consume_drink( u ) ); + avatar_action::eat( player_character, game_menus::inv::consume_drink( player_character ) ); break; case 2: - avatar_action::eat( u, game_menus::inv::consume_meds( u ) ); + avatar_action::eat( player_character, game_menus::inv::consume_meds( player_character ) ); break; default: break; @@ -1525,26 +1543,27 @@ bool game::handle_action() input_context ctxt; action_id act = ACTION_NULL; user_turn current_turn; + avatar &player_character = get_avatar(); // Check if we have an auto-move destination - if( u.has_destination() ) { - act = u.get_next_auto_move_direction(); + if( player_character.has_destination() ) { + act = player_character.get_next_auto_move_direction(); if( act == ACTION_NULL ) { add_msg( m_info, _( "Auto-move canceled" ) ); - u.clear_destination(); + player_character.clear_destination(); return false; } - } else if( u.has_destination_activity() ) { + } else if( player_character.has_destination_activity() ) { // starts destination activity after the player successfully reached his destination - u.start_destination_activity(); + player_character.start_destination_activity(); return false; } else { // No auto-move, ask player for input ctxt = get_player_input( action ); } - const optional_vpart_position vp = m.veh_at( u.pos() ); - bool veh_ctrl = !u.is_dead_state() && - ( ( vp && vp->vehicle().player_in_control( u ) ) || remoteveh() != nullptr ); + const optional_vpart_position vp = m.veh_at( player_character.pos() ); + bool veh_ctrl = !player_character.is_dead_state() && + ( ( vp && vp->vehicle().player_in_control( player_character ) ) || remoteveh() != nullptr ); // If performing an action with right mouse button, co-ordinates // of location clicked. @@ -1568,7 +1587,7 @@ bool game::handle_action() return false; } // No auto-move actions have or can be set at this point. - u.clear_destination(); + player_character.clear_destination(); destination_preview.clear(); act = handle_main_menu(); if( act == ACTION_NULL ) { @@ -1581,7 +1600,7 @@ bool game::handle_action() return false; } // No auto-move actions have or can be set at this point. - u.clear_destination(); + player_character.clear_destination(); destination_preview.clear(); act = handle_action_menu(); if( act == ACTION_NULL ) { @@ -1595,7 +1614,7 @@ bool game::handle_action() } if( act == ACTION_KEYBINDINGS ) { - u.clear_destination(); + player_character.clear_destination(); destination_preview.clear(); act = ctxt.display_menu( true ); if( act == ACTION_NULL ) { @@ -1614,7 +1633,7 @@ bool game::handle_action() return false; } - if( u.is_dead_state() ) { + if( player_character.is_dead_state() ) { // do not allow mouse actions while dead return false; } @@ -1622,7 +1641,7 @@ bool game::handle_action() const cata::optional mouse_pos = ctxt.get_coordinates( w_terrain ); if( !mouse_pos ) { return false; - } else if( !u.sees( *mouse_pos ) ) { + } else if( !player_character.sees( *mouse_pos ) ) { // Not clicked in visible terrain return false; } @@ -1647,7 +1666,7 @@ bool game::handle_action() // auto-move destination if the action is only a timeout, as this // would require the user to double click quicker than the // timeout delay. - u.clear_destination(); + player_character.clear_destination(); destination_preview.clear(); } } @@ -1675,18 +1694,18 @@ bool game::handle_action() int soffset = get_option( "MOVE_VIEW_OFFSET" ); - int before_action_moves = u.moves; + int before_action_moves = player_character.moves; // These actions are allowed while deathcam is active. Registered in game::get_player_input - if( uquit == QUIT_WATCH || !u.is_dead_state() ) { + if( uquit == QUIT_WATCH || !player_character.is_dead_state() ) { switch( act ) { case ACTION_TOGGLE_MAP_MEMORY: - u.toggle_map_memory(); + player_character.toggle_map_memory(); break; case ACTION_CENTER: - u.view_offset.x = driving_view_offset.x; - u.view_offset.y = driving_view_offset.y; + player_character.view_offset.x = driving_view_offset.x; + player_character.view_offset.y = driving_view_offset.y; break; case ACTION_SHIFT_N: @@ -1707,8 +1726,8 @@ bool game::handle_action() { ACTION_SHIFT_W, { point_west, point_north_west } }, { ACTION_SHIFT_NW, { point_north_west, point_north } }, }; - u.view_offset += use_tiles && tile_iso ? - shift_delta.at( act ).second * soffset : shift_delta.at( act ).first * soffset; + player_character.view_offset += use_tiles && tile_iso ? + shift_delta.at( act ).second * soffset : shift_delta.at( act ).first * soffset; } break; @@ -1726,7 +1745,7 @@ bool game::handle_action() } // actions allowed only while alive - if( !u.is_dead_state() ) { + if( !player_character.is_dead_state() ) { switch( act ) { case ACTION_NULL: case NUM_ACTIONS: @@ -1738,30 +1757,30 @@ bool game::handle_action() case ACTION_TIMEOUT: if( check_safe_mode_allowed( false ) ) { - u.pause(); + player_character.pause(); } break; case ACTION_PAUSE: if( check_safe_mode_allowed() ) { - u.pause(); + player_character.pause(); } break; case ACTION_CYCLE_MOVE: - u.cycle_move_mode(); + player_character.cycle_move_mode(); break; case ACTION_RESET_MOVE: - u.reset_move_mode(); + player_character.reset_move_mode(); break; case ACTION_TOGGLE_RUN: - u.toggle_run_mode(); + player_character.toggle_run_mode(); break; case ACTION_TOGGLE_CROUCH: - u.toggle_crouch_mode(); + player_character.toggle_crouch_mode(); break; case ACTION_OPEN_MOVEMENT: @@ -1776,9 +1795,9 @@ bool game::handle_action() case ACTION_MOVE_BACK_LEFT: case ACTION_MOVE_LEFT: case ACTION_MOVE_FORTH_LEFT: - if( !u.get_value( "remote_controlling" ).empty() && - ( u.has_active_item( itype_radiocontrol ) || - u.has_active_bionic( bio_remote ) ) ) { + if( !player_character.get_value( "remote_controlling" ).empty() && + ( player_character.has_active_item( itype_radiocontrol ) || + player_character.has_active_bionic( bio_remote ) ) ) { rcdrive( get_delta_from_movement_action( act, iso_rotate::yes ) ); } else if( veh_ctrl ) { // vehicle control uses x for steering and y for ac/deceleration, @@ -1786,43 +1805,43 @@ bool game::handle_action() pldrive( get_delta_from_movement_action( act, iso_rotate::no ) ); } else { point dest_delta = get_delta_from_movement_action( act, iso_rotate::yes ); - if( auto_travel_mode && !u.is_auto_moving() ) { + if( auto_travel_mode && !player_character.is_auto_moving() ) { for( int i = 0; i < SEEX; i++ ) { - tripoint auto_travel_destination( u.posx() + dest_delta.x * ( SEEX - i ), - u.posy() + dest_delta.y * ( SEEX - i ), - u.posz() ); - destination_preview = m.route( u.pos(), + tripoint auto_travel_destination( player_character.posx() + dest_delta.x * ( SEEX - i ), + player_character.posy() + dest_delta.y * ( SEEX - i ), + player_character.posz() ); + destination_preview = m.route( player_character.pos(), auto_travel_destination, - u.get_pathfinding_settings(), - u.get_path_avoid() ); + player_character.get_pathfinding_settings(), + player_character.get_path_avoid() ); if( !destination_preview.empty() ) { destination_preview.erase( destination_preview.begin() + 1, destination_preview.end() ); - u.set_destination( destination_preview ); + player_character.set_destination( destination_preview ); break; } } - act = u.get_next_auto_move_direction(); + act = player_character.get_next_auto_move_direction(); const point dest_next = get_delta_from_movement_action( act, iso_rotate::yes ); if( dest_next == point_zero ) { - u.clear_destination(); + player_character.clear_destination(); } dest_delta = dest_next; } - if( !avatar_action::move( u, m, dest_delta ) ) { + if( !avatar_action::move( player_character, m, dest_delta ) ) { // auto-move should be canceled due to a failed move or obstacle - u.clear_destination(); + player_character.clear_destination(); } } break; case ACTION_MOVE_DOWN: - if( u.is_mounted() ) { - auto mon = u.mounted_creature.get(); + if( player_character.is_mounted() ) { + auto mon = player_character.mounted_creature.get(); if( !mon->has_flag( MF_RIDEABLE_MECH ) ) { add_msg( m_info, _( "You can't go down stairs while you're riding." ) ); break; } } - if( !u.in_vehicle ) { + if( !player_character.in_vehicle ) { vertical_move( -1, false ); } else if( veh_ctrl && vp->vehicle().is_rotorcraft() ) { pldrive( tripoint_below ); @@ -1830,14 +1849,14 @@ bool game::handle_action() break; case ACTION_MOVE_UP: - if( u.is_mounted() ) { - auto mon = u.mounted_creature.get(); + if( player_character.is_mounted() ) { + auto mon = player_character.mounted_creature.get(); if( !mon->has_flag( MF_RIDEABLE_MECH ) ) { add_msg( m_info, _( "You can't go down stairs while you're riding." ) ); break; } } - if( !u.in_vehicle ) { + if( !player_character.in_vehicle ) { vertical_move( 1, false ); } else if( veh_ctrl && vp->vehicle().is_rotorcraft() ) { pldrive( tripoint_above ); @@ -1845,9 +1864,9 @@ bool game::handle_action() break; case ACTION_OPEN: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't open things while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't open things while you're riding." ) ); } else { open(); @@ -1855,15 +1874,15 @@ bool game::handle_action() break; case ACTION_CLOSE: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't close things while you're in your shell." ) ); - } else if( u.is_mounted() ) { - auto mon = u.mounted_creature.get(); + } else if( player_character.is_mounted() ) { + auto mon = player_character.mounted_creature.get(); if( !mon->has_flag( MF_RIDEABLE_MECH ) ) { add_msg( m_info, _( "You can't close things while you're riding." ) ); } } else if( mouse_target ) { - doors::close_door( m, u, *mouse_target ); + doors::close_door( m, player_character, *mouse_target ); } else { close(); } @@ -1872,7 +1891,7 @@ bool game::handle_action() case ACTION_SMASH: if( veh_ctrl ) { handbrake(); - } else if( u.has_active_mutation( trait_SHELL2 ) ) { + } else if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't smash things while you're in your shell." ) ); } else { smash(); @@ -1880,7 +1899,7 @@ bool game::handle_action() break; case ACTION_EXAMINE: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't examine your surroundings while you're in your shell." ) ); } else if( mouse_target ) { examine( *mouse_target ); @@ -1890,9 +1909,9 @@ bool game::handle_action() break; case ACTION_ADVANCEDINV: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't move mass quantities while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't move mass quantities while you're riding." ) ); } else { create_advanced_inv(); @@ -1900,9 +1919,9 @@ bool game::handle_action() break; case ACTION_PICKUP: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't pick anything up while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't pick anything up while you're riding." ) ); } else if( mouse_target ) { pickup( *mouse_target ); @@ -1912,7 +1931,7 @@ bool game::handle_action() break; case ACTION_PICKUP_FEET: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't pick anything up while you're in your shell." ) ); } else { pickup_feet(); @@ -1920,9 +1939,9 @@ bool game::handle_action() break; case ACTION_GRAB: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't grab things while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't grab things while you're riding." ) ); } else { grab(); @@ -1930,9 +1949,9 @@ bool game::handle_action() break; case ACTION_HAUL: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't haul things while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't haul things while you're riding." ) ); } else { haul(); @@ -1940,9 +1959,9 @@ bool game::handle_action() break; case ACTION_BUTCHER: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't butcher while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't butcher while you're riding." ) ); } else { butcher(); @@ -1954,9 +1973,9 @@ bool game::handle_action() break; case ACTION_PEEK: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't peek around corners while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't peek around corners while you're riding." ) ); } else { peek(); @@ -1976,25 +1995,25 @@ bool game::handle_action() break; case ACTION_INVENTORY: - game_menus::inv::common( u ); + game_menus::inv::common( player_character ); break; case ACTION_COMPARE: - game_menus::inv::compare( u, cata::nullopt ); + game_menus::inv::compare( player_character, cata::nullopt ); break; case ACTION_ORGANIZE: - game_menus::inv::swap_letters( u ); + game_menus::inv::swap_letters( player_character ); break; case ACTION_USE: // Shell-users are presumed to be able to mess with their inventories, etc // while in the shell. Eating, gear-changing, and item use are OK. - avatar_action::use_item( u ); + avatar_action::use_item( player_character ); break; case ACTION_USE_WIELDED: - u.use_wielded(); + player_character.use_wielded(); break; case ACTION_WEAR: @@ -2006,13 +2025,13 @@ bool game::handle_action() break; case ACTION_EAT: - if( !avatar_action::eat_here( u ) ) { - avatar_action::eat( u ); + if( !avatar_action::eat_here( player_character ) ) { + avatar_action::eat( player_character ); } break; case ACTION_OPEN_CONSUME: - if( !avatar_action::eat_here( u ) ) { + if( !avatar_action::eat_here( player_character ) ) { open_consume_item_menu(); } break; @@ -2027,7 +2046,7 @@ bool game::handle_action() break; case ACTION_PICK_STYLE: - u.martial_arts_data.pick_style( u ); + player_character.martial_arts_data.pick_style( player_character ); break; case ACTION_RELOAD_ITEM: @@ -2043,16 +2062,16 @@ bool game::handle_action() break; case ACTION_UNLOAD: - avatar_action::unload( u ); + avatar_action::unload( player_character ); break; case ACTION_MEND: - avatar_action::mend( g->u, item_location() ); + avatar_action::mend( player_character, item_location() ); break; case ACTION_THROW: { item_location loc; - avatar_action::plthrow( g->u, loc ); + avatar_action::plthrow( player_character, loc ); break; } @@ -2065,26 +2084,28 @@ bool game::handle_action() break; case ACTION_FIRE_BURST: { - gun_mode_id original_mode = u.weapon.gun_get_mode_id(); - if( u.weapon.gun_set_mode( gun_mode_id( "AUTO" ) ) ) { - avatar_action::fire_wielded_weapon( u ); - u.weapon.gun_set_mode( original_mode ); + gun_mode_id original_mode = player_character.weapon.gun_get_mode_id(); + if( player_character.weapon.gun_set_mode( gun_mode_id( "AUTO" ) ) ) { + avatar_action::fire_wielded_weapon( player_character ); + player_character.weapon.gun_set_mode( original_mode ); } break; } case ACTION_SELECT_FIRE_MODE: - if( u.is_armed() ) { - if( u.weapon.is_gun() && !u.weapon.is_gunmod() && u.weapon.gun_all_modes().size() > 1 ) { - u.weapon.gun_cycle_mode(); - } else if( u.weapon.has_flag( flag_RELOAD_ONE ) || u.weapon.has_flag( flag_RELOAD_AND_SHOOT ) ) { - item::reload_option opt = u.select_ammo( u.weapon, false ); + if( player_character.is_armed() ) { + if( player_character.weapon.is_gun() && !player_character.weapon.is_gunmod() && + player_character.weapon.gun_all_modes().size() > 1 ) { + player_character.weapon.gun_cycle_mode(); + } else if( player_character.weapon.has_flag( flag_RELOAD_ONE ) || + player_character.weapon.has_flag( flag_RELOAD_AND_SHOOT ) ) { + item::reload_option opt = player_character.select_ammo( player_character.weapon, false ); if( !opt ) { break; - } else if( u.ammo_location && opt.ammo == u.ammo_location ) { - u.ammo_location = item_location(); + } else if( player_character.ammo_location && opt.ammo == player_character.ammo_location ) { + player_character.ammo_location = item_location(); } else { - u.ammo_location = opt.ammo; + player_character.ammo_location = opt.ammo; } } } @@ -2096,21 +2117,21 @@ bool game::handle_action() break; case ACTION_DIR_DROP: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't drop things to another tile while you're in your shell." ) ); } else { drop_in_direction(); } break; case ACTION_BIONICS: - u.power_bionics(); + player_character.power_bionics(); break; case ACTION_MUTATIONS: - u.power_mutations(); + player_character.power_mutations(); break; case ACTION_SORT_ARMOR: - u.sort_armor(); + player_character.sort_armor(); break; case ACTION_WAIT: @@ -2118,51 +2139,51 @@ bool game::handle_action() break; case ACTION_CRAFT: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't craft while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't craft while you're riding." ) ); } else { - u.craft(); + player_character.craft(); } break; case ACTION_RECRAFT: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't craft while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't craft while you're riding." ) ); } else { - u.recraft(); + player_character.recraft(); } break; case ACTION_LONGCRAFT: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't craft while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't craft while you're riding." ) ); } else { - u.long_craft(); + player_character.long_craft(); } break; case ACTION_DISASSEMBLE: - if( u.controlling_vehicle ) { + if( player_character.controlling_vehicle ) { add_msg( m_info, _( "You can't disassemble items while driving." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't disassemble items while you're riding." ) ); } else { - u.disassemble(); + player_character.disassemble(); } break; case ACTION_CONSTRUCT: - if( u.in_vehicle ) { + if( player_character.in_vehicle ) { add_msg( m_info, _( "You can't construct while in a vehicle." ) ); - } else if( u.has_active_mutation( trait_SHELL2 ) ) { + } else if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't construct while you're in your shell." ) ); - } else if( u.is_mounted() ) { + } else if( player_character.is_mounted() ) { add_msg( m_info, _( "You can't construct while you're riding." ) ); } else { construction_menu( false ); @@ -2180,11 +2201,11 @@ bool game::handle_action() break; case ACTION_CONTROL_VEHICLE: - if( u.has_active_mutation( trait_SHELL2 ) ) { + if( player_character.has_active_mutation( trait_SHELL2 ) ) { add_msg( m_info, _( "You can't operate a vehicle while you're in your shell." ) ); - } else if( u.is_mounted() ) { - u.dismount(); - } else if( u.has_trait( trait_WAYFARER ) ) { + } else if( player_character.is_mounted() ) { + player_character.dismount(); + } else if( player_character.has_trait( trait_WAYFARER ) ) { add_msg( m_info, _( "You refuse to take control of this vehicle." ) ); } else { control_vehicle(); @@ -2207,8 +2228,8 @@ bool game::handle_action() add_msg( m_info, get_option( "AUTOSAFEMODE" ) ? _( "Safe mode OFF! (Auto safe mode still enabled!)" ) : _( "Safe mode OFF!" ) ); } - if( u.has_effect( effect_laserlocked ) ) { - u.remove_effect( effect_laserlocked ); + if( player_character.has_effect( effect_laserlocked ) ) { + player_character.remove_effect( effect_laserlocked ); safe_mode_warning_logged = false; } break; @@ -2224,18 +2245,18 @@ bool game::handle_action() case ACTION_IGNORE_ENEMY: if( safe_mode == SAFE_MODE_STOP ) { add_msg( m_info, _( "Ignoring enemy!" ) ); - for( auto &elem : u.get_mon_visible().new_seen_mon ) { + for( auto &elem : player_character.get_mon_visible().new_seen_mon ) { monster &critter = *elem; - critter.ignoring = rl_dist( u.pos(), critter.pos() ); + critter.ignoring = rl_dist( player_character.pos(), critter.pos() ); } set_safe_mode( SAFE_MODE_ON ); - } else if( u.has_effect( effect_laserlocked ) ) { - if( u.has_trait( trait_PROF_CHURL ) ) { + } else if( player_character.has_effect( effect_laserlocked ) ) { + if( player_character.has_trait( trait_PROF_CHURL ) ) { add_msg( m_warning, _( "You make the sign of the cross." ) ); } else { add_msg( m_info, _( "Ignoring laser targeting!" ) ); } - u.remove_effect( effect_laserlocked ); + player_character.remove_effect( effect_laserlocked ); safe_mode_warning_logged = false; } break; @@ -2254,15 +2275,16 @@ bool game::handle_action() case ACTION_WORKOUT: if( query_yn( _( "Start workout?" ) ) ) { - u.assign_activity( player_activity( workout_activity_actor( u.pos() ) ) ); + player_character.assign_activity( player_activity( workout_activity_actor( + player_character.pos() ) ) ); } break; case ACTION_SUICIDE: if( query_yn( _( "Commit suicide?" ) ) ) { if( query_yn( _( "REALLY commit suicide?" ) ) ) { - u.moves = 0; - u.place_corpse(); + player_character.moves = 0; + player_character.place_corpse(); uquit = QUIT_SUICIDE; } } @@ -2271,7 +2293,7 @@ bool game::handle_action() case ACTION_SAVE: if( query_yn( _( "Save and quit?" ) ) ) { if( save() ) { - u.moves = 0; + player_character.moves = 0; uquit = QUIT_SAVED; } } @@ -2286,7 +2308,7 @@ bool game::handle_action() return false; case ACTION_PL_INFO: - u.disp_info(); + player_character.disp_info(); break; case ACTION_MAP: @@ -2294,7 +2316,7 @@ bool game::handle_action() break; case ACTION_SKY: - if( m.is_outside( u.pos() ) ) { + if( m.is_outside( player_character.pos() ) ) { ui::omap::display_visible_weather(); } else { add_msg( m_info, _( "You can't see the sky from here." ) ); @@ -2314,7 +2336,7 @@ bool game::handle_action() break; case ACTION_MORALE: - u.disp_morale(); + player_character.disp_morale(); break; case ACTION_MESSAGES: @@ -2400,24 +2422,25 @@ bool game::handle_action() break; case ACTION_TOGGLE_THIEF_MODE: - if( g->u.get_value( "THIEF_MODE" ) == "THIEF_ASK" ) { - u.set_value( "THIEF_MODE", "THIEF_HONEST" ); - u.set_value( "THIEF_MODE_KEEP", "YES" ); + if( player_character.get_value( "THIEF_MODE" ) == "THIEF_ASK" ) { + player_character.set_value( "THIEF_MODE", "THIEF_HONEST" ); + player_character.set_value( "THIEF_MODE_KEEP", "YES" ); //~ Thief mode cycled between THIEF_ASK/THIEF_HONEST/THIEF_STEAL add_msg( _( "You will not pick up other peoples belongings." ) ); - } else if( g->u.get_value( "THIEF_MODE" ) == "THIEF_HONEST" ) { - u.set_value( "THIEF_MODE", "THIEF_STEAL" ); - u.set_value( "THIEF_MODE_KEEP", "YES" ); + } else if( player_character.get_value( "THIEF_MODE" ) == "THIEF_HONEST" ) { + player_character.set_value( "THIEF_MODE", "THIEF_STEAL" ); + player_character.set_value( "THIEF_MODE_KEEP", "YES" ); //~ Thief mode cycled between THIEF_ASK/THIEF_HONEST/THIEF_STEAL add_msg( _( "You will pick up also those things that belong to others!" ) ); - } else if( g->u.get_value( "THIEF_MODE" ) == "THIEF_STEAL" ) { - u.set_value( "THIEF_MODE", "THIEF_ASK" ); - u.set_value( "THIEF_MODE_KEEP", "NO" ); + } else if( player_character.get_value( "THIEF_MODE" ) == "THIEF_STEAL" ) { + player_character.set_value( "THIEF_MODE", "THIEF_ASK" ); + player_character.set_value( "THIEF_MODE_KEEP", "NO" ); //~ Thief mode cycled between THIEF_ASK/THIEF_HONEST/THIEF_STEAL add_msg( _( "You will be reminded not to steal." ) ); } else { // ERROR - add_msg( _( "THIEF_MODE CONTAINED BAD VALUE [ %s ]!" ), g->u.get_value( "THIEF_MODE" ) ); + add_msg( _( "THIEF_MODE CONTAINED BAD VALUE [ %s ]!" ), + player_character.get_value( "THIEF_MODE" ) ); } break; @@ -2511,7 +2534,7 @@ bool game::handle_action() break; case ACTION_AUTOATTACK: - avatar_action::autoattack( u, m ); + avatar_action::autoattack( player_character, m ); break; default: @@ -2519,12 +2542,14 @@ bool game::handle_action() } } if( act != ACTION_TIMEOUT ) { - u.mod_moves( -current_turn.moves_elapsed() ); + player_character.mod_moves( -current_turn.moves_elapsed() ); } gamemode->post_action( act ); - u.movecounter = ( !u.is_dead_state() ? ( before_action_moves - u.moves ) : 0 ); + player_character.movecounter = ( !player_character.is_dead_state() ? ( before_action_moves - + player_character.moves ) : 0 ); dbg( D_INFO ) << string_format( "%s: [%d] %d - %d = %d", action_ident( act ), - to_turn( calendar::turn ), before_action_moves, u.movecounter, u.moves ); - return ( !u.is_dead_state() ); + to_turn( calendar::turn ), before_action_moves, player_character.movecounter, + player_character.moves ); + return ( !player_character.is_dead_state() ); } diff --git a/src/vehicle.h b/src/vehicle.h index eeb2a82f6aad0..234b195b8d5fb 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -1449,8 +1449,8 @@ class vehicle /** * can the helicopter descend/ascend here? */ - bool check_heli_descend( player &p ); - bool check_heli_ascend( player &p ); + bool check_heli_descend( Character &p ); + bool check_heli_ascend( Character &p ); bool check_is_heli_landed(); /** * Player is driving the vehicle diff --git a/src/vehicle_move.cpp b/src/vehicle_move.cpp index f1056feca21f4..88b33d2076c29 100644 --- a/src/vehicle_move.cpp +++ b/src/vehicle_move.cpp @@ -1281,7 +1281,7 @@ bool vehicle::check_is_heli_landed() return false; } -bool vehicle::check_heli_descend( player &p ) +bool vehicle::check_heli_descend( Character &p ) { if( !is_rotorcraft() ) { debugmsg( "A vehicle is somehow flying without being an aircraft" ); @@ -1316,7 +1316,7 @@ bool vehicle::check_heli_descend( player &p ) } -bool vehicle::check_heli_ascend( player &p ) +bool vehicle::check_heli_ascend( Character &p ) { if( !is_rotorcraft() ) { debugmsg( "A vehicle is somehow flying without being an aircraft" ); From 661946c8dc1e87f24d599d347967e064ddd6614d Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Wed, 15 Jul 2020 08:07:18 +0000 Subject: [PATCH 042/151] Global reference migration part 27 --- src/action.cpp | 57 ++++++++++--------- src/character.cpp | 40 ++++++++------ src/debug_menu.cpp | 135 ++++++++++++++++++++++++--------------------- 3 files changed, 127 insertions(+), 105 deletions(-) diff --git a/src/action.cpp b/src/action.cpp index 6c90378d8d543..5738a3c529d94 100644 --- a/src/action.cpp +++ b/src/action.cpp @@ -593,20 +593,21 @@ int hotkey_for_action( action_id action, const bool restrict_to_printable ) bool can_butcher_at( const tripoint &p ) { + Character &player_character = get_player_character(); // TODO: unify this with game::butcher - const int factor = g->u.max_quality( qual_BUTCHER ); - const int factorD = g->u.max_quality( qual_CUT_FINE ); + const int factor = player_character.max_quality( qual_BUTCHER ); + const int factorD = player_character.max_quality( qual_CUT_FINE ); map_stack items = get_map().i_at( p ); bool has_item = false; bool has_corpse = false; - const inventory &crafting_inv = g->u.crafting_inventory(); + const inventory &crafting_inv = player_character.crafting_inventory(); for( item &items_it : items ) { if( items_it.is_corpse() ) { if( factor != INT_MIN || factorD != INT_MIN ) { has_corpse = true; } - } else if( g->u.can_disassemble( items_it, crafting_inv ).success() ) { + } else if( player_character.can_disassemble( items_it, crafting_inv ).success() ) { has_item = true; } } @@ -615,13 +616,15 @@ bool can_butcher_at( const tripoint &p ) bool can_move_vertical_at( const tripoint &p, int movez ) { + Character &player_character = get_player_character(); map &here = get_map(); // TODO: unify this with game::move_vertical if( here.has_flag( flag_SWIMMABLE, p ) && here.has_flag( TFLAG_DEEP_WATER, p ) ) { if( movez == -1 ) { - return !g->u.is_underwater() && !g->u.worn_with_flag( flag_FLOTATION ); + return !player_character.is_underwater() && !player_character.worn_with_flag( flag_FLOTATION ); } else { - return g->u.swim_speed() < 500 || g->u.is_wearing( itype_id( "swim_fins" ) ); + return player_character.swim_speed() < 500 || + player_character.is_wearing( itype_id( "swim_fins" ) ); } } @@ -654,11 +657,11 @@ bool can_examine_at( const tripoint &p ) } Creature *c = g->critter_at( p ); - if( c != nullptr && p != g->u.pos() ) { + if( c != nullptr && !c->is_avatar() ) { return true; } - return here.can_see_trap_at( p, g->u ); + return here.can_see_trap_at( p, get_player_character() ); } static bool can_pickup_at( const tripoint &p ) @@ -676,15 +679,16 @@ static bool can_pickup_at( const tripoint &p ) bool can_interact_at( action_id action, const tripoint &p ) { map &here = get_map(); + tripoint player_pos = get_player_character().pos(); switch( action ) { case ACTION_OPEN: - return here.open_door( p, !here.is_outside( g->u.pos() ), true ); + return here.open_door( p, !here.is_outside( player_pos ), true ); case ACTION_CLOSE: { const optional_vpart_position vp = here.veh_at( p ); return ( vp && vp->vehicle().next_part_to_close( vp->part_index(), - veh_pointer_or_null( here.veh_at( g->u.pos() ) ) != &vp->vehicle() ) >= 0 ) || - here.close_door( p, !here.is_outside( g->u.pos() ), true ); + veh_pointer_or_null( here.veh_at( player_pos ) ) != &vp->vehicle() ) >= 0 ) || + here.close_door( p, !here.is_outside( player_pos ), true ); } case ACTION_BUTCHER: return can_butcher_at( p ); @@ -719,38 +723,39 @@ action_id handle_action_menu() // Weight >= 200: Special action only available right now std::map action_weightings; + Character &player_character = get_player_character(); // Check if we're in a potential combat situation, if so, sort a few actions to the top. - if( !g->u.get_hostile_creatures( 60 ).empty() ) { + if( !player_character.get_hostile_creatures( 60 ).empty() ) { // Only prioritize movement options if we're not driving. - if( !g->u.controlling_vehicle ) { + if( !player_character.controlling_vehicle ) { action_weightings[ACTION_CYCLE_MOVE] = 400; } // Only prioritize fire weapon options if we're wielding a ranged weapon. - if( g->u.weapon.is_gun() || g->u.weapon.has_flag( flag_REACH_ATTACK ) ) { + if( player_character.weapon.is_gun() || player_character.weapon.has_flag( flag_REACH_ATTACK ) ) { action_weightings[ACTION_FIRE] = 350; } } // If we're already running, make it simple to toggle running to off. - if( g->u.is_running() ) { + if( player_character.is_running() ) { action_weightings[ACTION_TOGGLE_RUN] = 300; } // If we're already crouching, make it simple to toggle crouching to off. - if( g->u.is_crouching() ) { + if( player_character.is_crouching() ) { action_weightings[ACTION_TOGGLE_CROUCH] = 300; } map &here = get_map(); // Check if we're on a vehicle, if so, vehicle controls should be top. - if( here.veh_at( g->u.pos() ) ) { + if( here.veh_at( player_character.pos() ) ) { // Make it 300 to prioritize it before examining the vehicle. action_weightings[ACTION_CONTROL_VEHICLE] = 300; } // Check if we can perform one of our actions on nearby terrain. If so, // display that action at the top of the list. - for( const tripoint &pos : here.points_in_radius( g->u.pos(), 1 ) ) { - if( pos != g->u.pos() ) { + for( const tripoint &pos : here.points_in_radius( player_character.pos(), 1 ) ) { + if( pos != player_character.pos() ) { // Check for actions that work on nearby tiles if( can_interact_at( ACTION_OPEN, pos ) ) { action_weightings[ACTION_OPEN] = 200; @@ -1040,11 +1045,12 @@ cata::optional choose_direction( const std::string &message, const boo ui_manager::redraw(); action = ctxt.handle_input(); if( const cata::optional vec = ctxt.get_direction( action ) ) { + FacingDirection &facing = get_player_character().facing; // Make player's sprite face left/right if interacting with something to the left or right if( vec->x > 0 ) { - g->u.facing = FacingDirection::RIGHT; + facing = FacingDirection::RIGHT; } else if( vec->x < 0 ) { - g->u.facing = FacingDirection::LEFT; + facing = FacingDirection::LEFT; } return vec; } else if( action == "pause" ) { @@ -1063,7 +1069,7 @@ cata::optional choose_direction( const std::string &message, const boo cata::optional choose_adjacent( const std::string &message, const bool allow_vertical ) { const cata::optional dir = choose_direction( message, allow_vertical ); - return dir ? *dir + g->u.pos() : dir; + return dir ? *dir + get_player_character().pos() : dir; } cata::optional choose_adjacent_highlight( const std::string &message, @@ -1080,9 +1086,10 @@ cata::optional choose_adjacent_highlight( const std::string &message, const bool allow_vertical ) { std::vector valid; + avatar &player_character = get_avatar(); map &here = get_map(); if( allowed ) { - for( const tripoint &pos : here.points_in_radius( g->u.pos(), 1 ) ) { + for( const tripoint &pos : here.points_in_radius( player_character.pos(), 1 ) ) { if( allowed( pos ) ) { valid.emplace_back( pos ); } @@ -1101,8 +1108,8 @@ cata::optional choose_adjacent_highlight( const std::string &message, if( !valid.empty() ) { hilite_cb = make_shared_fast( [&]() { for( const tripoint &pos : valid ) { - here.drawsq( g->w_terrain, g->u, pos, - true, true, g->u.pos() + g->u.view_offset ); + here.drawsq( g->w_terrain, player_character, pos, + true, true, player_character.pos() + player_character.view_offset ); } } ); g->add_draw_callback( hilite_cb ); diff --git a/src/character.cpp b/src/character.cpp index 215ecb6d7d5f2..861be980d2be2 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -1082,12 +1082,13 @@ void Character::mount_creature( monster &z ) mounted_creature = mons; mons->mounted_player = this; if( is_avatar() ) { - if( g->u.is_hauling() ) { - g->u.stop_hauling(); + avatar &player_character = get_avatar(); + if( player_character.is_hauling() ) { + player_character.stop_hauling(); } - if( g->u.get_grab_type() != object_type::NONE ) { + if( player_character.get_grab_type() != object_type::NONE ) { add_msg( m_warning, _( "You let go of the grabbed object." ) ); - g->u.grab( object_type::NONE ); + player_character.grab( object_type::NONE ); } g->place_player( pnt ); } else { @@ -1255,15 +1256,17 @@ void Character::forced_dismount() add_msg( m_debug, "Forced_dismount could not find a square to deposit player" ); } if( is_avatar() ) { - if( g->u.get_grab_type() != object_type::NONE ) { + avatar &player_character = get_avatar(); + if( player_character.get_grab_type() != object_type::NONE ) { add_msg( m_warning, _( "You let go of the grabbed object." ) ); - g->u.grab( object_type::NONE ); + player_character.grab( object_type::NONE ); } set_movement_mode( move_mode_id( "walk" ) ); - if( g->u.is_auto_moving() || g->u.has_destination() || g->u.has_destination_activity() ) { - g->u.clear_destination(); + if( player_character.is_auto_moving() || player_character.has_destination() || + player_character.has_destination_activity() ) { + player_character.clear_destination(); } - g->update_map( g->u ); + g->update_map( player_character ); } if( activity ) { cancel_activity(); @@ -1288,9 +1291,10 @@ void Character::dismount() if( critter->has_flag( MF_RIDEABLE_MECH ) && !critter->type->mech_weapon.is_empty() ) { remove_item( weapon ); } - if( is_avatar() && g->u.get_grab_type() != object_type::NONE ) { + avatar &player_character = get_avatar(); + if( is_avatar() && player_character.get_grab_type() != object_type::NONE ) { add_msg( m_warning, _( "You let go of the grabbed object." ) ); - g->u.grab( object_type::NONE ); + player_character.grab( object_type::NONE ); } critter->remove_effect( effect_ridden ); critter->add_effect( effect_controlled, 5_turns ); @@ -2364,8 +2368,7 @@ cata::optional::iterator> Character::wear_item( const item &to_w } const bool was_deaf = is_deaf(); - const bool supertinymouse = g->u.has_trait( trait_SMALL2 ) || - g->u.has_trait( trait_SMALL_OK ); + const bool supertinymouse = has_trait( trait_SMALL2 ) || has_trait( trait_SMALL_OK ); last_item = to_wear.typeId(); std::list::iterator position = position_to_wear_new_item( to_wear ); @@ -2400,7 +2403,7 @@ cata::optional::iterator> Character::wear_item( const item &to_w _( "This %s is too small to wear comfortably! Maybe it could be refitted." ), to_wear.tname() ); } - } else if( is_npc() && g->u.sees( *this ) ) { + } else if( is_npc() && get_player_character().sees( *this ) ) { add_msg_if_npc( _( " puts on their %s." ), to_wear.tname() ); } @@ -8700,7 +8703,7 @@ void Character::absorb_hit( const bodypart_id &bp, damage_instance &dam ) } if( destroy ) { - if( g->u.sees( *this ) ) { + if( get_player_character().sees( *this ) ) { SCT.add( point( posx(), posy() ), direction::NORTH, remove_color_tags( pre_damage_name ), m_neutral, _( "destroyed" ), m_info ); } @@ -9006,7 +9009,7 @@ dealt_damage_instance Character::deal_damage( Creature *source, bodypart_id bp, int dam = dealt_dams.total_damage(); // TODO: Pre or post blit hit tile onto "this"'s location here - if( dam > 0 && g->u.sees( pos() ) ) { + if( dam > 0 && get_player_character().sees( pos() ) ) { g->draw_hit_player( *this, dam ); if( is_player() && source ) { @@ -9042,11 +9045,12 @@ dealt_damage_instance Character::deal_damage( Creature *source, bodypart_id bp, } } + Character &player_character = get_player_character(); //Acid blood effects. - bool u_see = g->u.sees( *this ); + bool u_see = player_character.sees( *this ); int cut_dam = dealt_dams.type_damage( DT_CUT ); if( source && has_trait( trait_ACIDBLOOD ) && !one_in( 3 ) && - ( dam >= 4 || cut_dam > 0 ) && ( rl_dist( g->u.pos(), source->pos() ) <= 1 ) ) { + ( dam >= 4 || cut_dam > 0 ) && ( rl_dist( player_character.pos(), source->pos() ) <= 1 ) ) { if( is_player() ) { add_msg( m_good, _( "Your acidic blood splashes %s in mid-attack!" ), source->disp_name() ); diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index cd609212a2ca6..e9e94f7298e26 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -405,11 +405,12 @@ static cata::optional debug_menu_uilist( bool display_all_entr void teleport_short() { const cata::optional where = g->look_around(); - if( !where || *where == g->u.pos() ) { + Character &player_character = get_player_character(); + if( !where || *where == player_character.pos() ) { return; } g->place_player( *where ); - const tripoint new_pos( g->u.pos() ); + const tripoint new_pos( player_character.pos() ); add_msg( _( "You teleport to point (%d,%d,%d)." ), new_pos.x, new_pos.y, new_pos.z ); } @@ -430,12 +431,13 @@ void teleport_overmap() return; } + Character &player_character = get_player_character(); const tripoint offset( OMAPX * dir_->x, OMAPY * dir_->y, dir_->z ); - const tripoint where( g->u.global_omt_location() + offset ); + const tripoint where( player_character.global_omt_location() + offset ); g->place_player_overmap( where ); - const tripoint new_pos( omt_to_om_copy( g->u.global_omt_location() ) ); + const tripoint new_pos( omt_to_om_copy( player_character.global_omt_location() ) ); add_msg( _( "You teleport to overmap (%d,%d,%d)." ), new_pos.x, new_pos.y, new_pos.z ); } @@ -480,8 +482,9 @@ void character_edit_menu() std::vector< tripoint > locations; uilist charmenu; int charnum = 0; + avatar &player_character = get_avatar(); charmenu.addentry( charnum++, true, MENU_AUTOASSIGN, "%s", _( "You" ) ); - locations.emplace_back( g->u.pos() ); + locations.emplace_back( player_character.pos() ); for( const npc &guy : g->all_npcs() ) { charmenu.addentry( charnum++, true, MENU_AUTOASSIGN, guy.name ); locations.emplace_back( guy.pos() ); @@ -497,7 +500,7 @@ void character_edit_menu() const size_t index = charmenu.ret; // The NPC is also required for "Add mission", so has to be in this scope npc *np = g->critter_at( locations[index], false ); - player &p = np ? static_cast( *np ) : static_cast( g->u ); + player &p = np ? *np->as_player() : *player_character.as_player(); uilist nmenu; if( np != nullptr ) { @@ -623,7 +626,7 @@ void character_edit_menu() p.remove_weapon(); break; case D_ITEM_WORN: { - item_location loc = game_menus::inv::titled_menu( g->u, _( "Make target equip" ) ); + item_location loc = game_menus::inv::titled_menu( player_character, _( "Make target equip" ) ); if( !loc ) { break; } @@ -915,7 +918,7 @@ void character_edit_menu() if( p.is_mounted() ) { p.mounted_creature->setpos( *newpos ); } - g->update_map( g->u ); + g->update_map( player_character ); } } } @@ -1055,20 +1058,21 @@ void mission_debug::edit_player() uilist mmenu; mmenu.text = _( "Select mission to edit" ); + avatar &player_character = get_avatar(); add_header( mmenu, _( "Active missions:" ) ); - for( mission *m : g->u.active_missions ) { + for( mission *m : player_character.active_missions ) { mmenu.addentry( all_missions.size(), true, MENU_AUTOASSIGN, "%s", m->type->id.c_str() ); all_missions.emplace_back( m ); } add_header( mmenu, _( "Completed missions:" ) ); - for( mission *m : g->u.completed_missions ) { + for( mission *m : player_character.completed_missions ) { mmenu.addentry( all_missions.size(), true, MENU_AUTOASSIGN, "%s", m->type->id.c_str() ); all_missions.emplace_back( m ); } add_header( mmenu, _( "Failed missions:" ) ); - for( mission *m : g->u.failed_missions ) { + for( mission *m : player_character.failed_missions ) { mmenu.addentry( all_missions.size(), true, MENU_AUTOASSIGN, "%s", m->type->id.c_str() ); all_missions.emplace_back( m ); } @@ -1091,18 +1095,19 @@ static bool remove_from_vec( std::vector &vec, mission *m ) void mission_debug::remove_mission( mission &m ) { - if( remove_from_vec( g->u.active_missions, &m ) ) { + avatar &player_character = get_avatar(); + if( remove_from_vec( player_character.active_missions, &m ) ) { add_msg( _( "Removing from active_missions" ) ); } - if( remove_from_vec( g->u.completed_missions, &m ) ) { + if( remove_from_vec( player_character.completed_missions, &m ) ) { add_msg( _( "Removing from completed_missions" ) ); } - if( remove_from_vec( g->u.failed_missions, &m ) ) { + if( remove_from_vec( player_character.failed_missions, &m ) ) { add_msg( _( "Removing from failed_missions" ) ); } - if( g->u.active_mission == &m ) { - g->u.active_mission = nullptr; + if( player_character.active_mission == &m ) { + player_character.active_mission = nullptr; add_msg( _( "Unsetting active mission" ) ); } @@ -1213,11 +1218,11 @@ void debug() g->events().send( *action ); - avatar &u = g->u; + avatar &player_character = get_avatar(); map &here = get_map(); switch( *action ) { case debug_menu_index::WISH: - debug_menu::wishitem( &u ); + debug_menu::wishitem( &player_character ); break; case debug_menu_index::SHORT_TELEPORT: @@ -1245,9 +1250,10 @@ void debug() shared_ptr_fast temp = make_shared_fast(); temp->normalize(); temp->randomize(); - temp->spawn_at_precise( { g->get_levx(), g->get_levy() }, u.pos() + point( -4, -4 ) ); + temp->spawn_at_precise( { g->get_levx(), g->get_levy() }, player_character.pos() + point( -4, + -4 ) ); overmap_buffer.insert_npc( temp ); - temp->form_opinion( u ); + temp->form_opinion( player_character ); temp->mission = NPC_MISSION_NULL; temp->add_new_mission( mission::reserve_random( ORIGIN_ANY_NPC, temp->global_omt_location(), temp->getID() ) ); @@ -1273,7 +1279,7 @@ void debug() std::sort( sorted.begin(), sorted.end(), []( std::pair a, std::pair b ) { return a.second != b.second ? a.second > b.second : a.first < b.first; } ); - popup( u.total_daily_calories_string() ); + popup( player_character.total_daily_calories_string() ); for( auto &m_flag_stat : sorted ) { mfus += string_format( "%s;%d\n", io::enum_to_string( m_flag_stat.first ), m_flag_stat.second ); @@ -1287,8 +1293,8 @@ void debug() s += ngettext( "%d creature exists.\n", "%d creatures exist.\n", g->num_creatures() ); popup_top( s.c_str(), - u.posx(), g->u.posy(), g->get_levx(), g->get_levy(), - overmap_buffer.ter( g->u.global_omt_location() )->get_name(), + player_character.posx(), player_character.posy(), g->get_levx(), g->get_levy(), + overmap_buffer.ter( player_character.global_omt_location() )->get_name(), to_turns( calendar::turn - calendar::turn_zero ), g->num_creatures() ); for( const npc &guy : g->all_npcs() ) { @@ -1297,21 +1303,24 @@ void debug() t.y, guy.posx(), guy.posy() ); } - add_msg( m_info, _( "(you: %d:%d)" ), u.posx(), u.posy() ); + add_msg( m_info, _( "(you: %d:%d)" ), player_character.posx(), player_character.posy() ); std::string stom = _( "Stomach Contents: %d ml / %d ml kCal: %d, Water: %d ml" ); - add_msg( m_info, stom.c_str(), units::to_milliliter( u.stomach.contains() ), - units::to_milliliter( u.stomach.capacity( u ) ), u.stomach.get_calories(), - units::to_milliliter( u.stomach.get_water() ), u.get_hunger() ); + add_msg( m_info, stom.c_str(), units::to_milliliter( player_character.stomach.contains() ), + units::to_milliliter( player_character.stomach.capacity( player_character ) ), + player_character.stomach.get_calories(), + units::to_milliliter( player_character.stomach.get_water() ), player_character.get_hunger() ); stom = _( "Guts Contents: %d ml / %d ml kCal: %d, Water: %d ml\nHunger: %d, Thirst: %d, kCal: %d / %d" ); - add_msg( m_info, stom.c_str(), units::to_milliliter( u.guts.contains() ), - units::to_milliliter( u.guts.capacity( u ) ), u.guts.get_calories(), - units::to_milliliter( u.guts.get_water() ), u.get_hunger(), u.get_thirst(), u.get_stored_kcal(), - u.get_healthy_kcal() ); - add_msg( m_info, _( "Body Mass Index: %.0f\nBasal Metabolic Rate: %i" ), u.get_bmi(), u.get_bmr() ); - add_msg( m_info, _( "Player activity level: %s" ), u.activity_level_str() ); + add_msg( m_info, stom.c_str(), units::to_milliliter( player_character.guts.contains() ), + units::to_milliliter( player_character.guts.capacity( player_character ) ), + player_character.guts.get_calories(), units::to_milliliter( player_character.guts.get_water() ), + player_character.get_hunger(), player_character.get_thirst(), player_character.get_stored_kcal(), + player_character.get_healthy_kcal() ); + add_msg( m_info, _( "Body Mass Index: %.0f\nBasal Metabolic Rate: %i" ), player_character.get_bmi(), + player_character.get_bmr() ); + add_msg( m_info, _( "Player activity level: %s" ), player_character.activity_level_str() ); if( get_option( "STATS_THROUGH_KILLS" ) ) { - add_msg( m_info, _( "Kill xp: %d" ), u.kill_xp() ); + add_msg( m_info, _( "Kill xp: %d" ), player_character.kill_xp() ); } g->invalidate_main_ui_adaptor(); g->disp_NPCs(); @@ -1325,11 +1334,11 @@ void debug() break; case debug_menu_index::MUTATE: - debug_menu::wishmutate( &u ); + debug_menu::wishmutate( &player_character ); break; case debug_menu_index::SPAWN_VEHICLE: - if( here.veh_at( u.pos() ) ) { + if( here.veh_at( player_character.pos() ) ) { dbg( D_ERROR ) << "game:load: There's already vehicle here"; debugmsg( "There's already vehicle here" ); } else { @@ -1355,7 +1364,7 @@ void debug() if( veh_menu.ret >= 0 && veh_menu.ret < static_cast( veh_strings.size() ) ) { // Didn't cancel const vproto_id &selected_opt = veh_strings[veh_menu.ret].second; - tripoint dest = u.pos(); + tripoint dest = player_character.pos(); uilist veh_cond_menu; veh_cond_menu.text = _( "Vehicle condition" ); veh_cond_menu.addentry( 0, true, MENU_AUTOASSIGN, _( "Light damage" ) ); @@ -1367,7 +1376,7 @@ void debug() // TODO: Allow picking this when add_vehicle has 3d argument vehicle *veh = here.add_vehicle( selected_opt, dest, -90, 100, veh_cond_menu.ret - 1 ); if( veh != nullptr ) { - here.board_vehicle( dest, &u ); + here.board_vehicle( dest, &player_character ); } } } @@ -1375,7 +1384,7 @@ void debug() break; case debug_menu_index::CHANGE_SKILLS: { - debug_menu::wishskill( &u ); + debug_menu::wishskill( &player_character ); } break; @@ -1384,7 +1393,7 @@ void debug() add_msg( _( "Your eyes blink rapidly as knowledge floods your brain." ) ); for( auto &style : all_martialart_types() ) { if( style != matype_id( "style_none" ) ) { - u.martial_arts_data.add_martialart( style ); + player_character.martial_arts_data.add_martialart( style ); } } add_msg( m_good, _( "You now know a lot more than just 10 styles of kung fu." ) ); @@ -1394,7 +1403,7 @@ void debug() add_msg( m_info, _( "Recipe debug." ) ); add_msg( _( "Your eyes blink rapidly as knowledge floods your brain." ) ); for( const auto &e : recipe_dict ) { - u.learn_recipe( &e.second ); + player_character.learn_recipe( &e.second ); } add_msg( m_good, _( "You know how to craft that now." ) ); } @@ -1414,7 +1423,7 @@ void debug() break; case debug_menu_index::SPAWN_CLAIRVOYANCE: - u.i_add( item( architects_cube(), calendar::turn ) ); + player_character.i_add( item( architects_cube(), calendar::turn ) ); break; case debug_menu_index::MAP_EDITOR: @@ -1505,12 +1514,12 @@ void debug() // Damage Self case debug_menu_index::DAMAGE_SELF: { - const int torso_hp = u.get_part_hp_cur( bodypart_id( "torso" ) ); - const int head_hp = u.get_part_hp_cur( bodypart_id( "head" ) ); - const int arm_l_hp = u.get_part_hp_cur( bodypart_id( "arm_l" ) ); - const int arm_r_hp = u.get_part_hp_cur( bodypart_id( "arm_r" ) ); - const int leg_l_hp = u.get_part_hp_cur( bodypart_id( "leg_l" ) ); - const int leg_r_hp = u.get_part_hp_cur( bodypart_id( "leg_r" ) ); + const int torso_hp = player_character.get_part_hp_cur( bodypart_id( "torso" ) ); + const int head_hp = player_character.get_part_hp_cur( bodypart_id( "head" ) ); + const int arm_l_hp = player_character.get_part_hp_cur( bodypart_id( "arm_l" ) ); + const int arm_r_hp = player_character.get_part_hp_cur( bodypart_id( "arm_r" ) ); + const int leg_l_hp = player_character.get_part_hp_cur( bodypart_id( "leg_l" ) ); + const int leg_r_hp = player_character.get_part_hp_cur( bodypart_id( "leg_r" ) ); uilist smenu; smenu.addentry( 0, true, 'q', "%s: %d", _( "Torso" ), torso_hp ); smenu.addentry( 1, true, 'w', "%s: %d", _( "Head" ), head_hp ); @@ -1544,8 +1553,8 @@ void debug() break; } if( query_int( dbg_damage, _( "Damage self for how much? hp: %s" ), part.id().c_str() ) ) { - u.apply_damage( nullptr, part, dbg_damage ); - u.die( nullptr ); + player_character.apply_damage( nullptr, part, dbg_damage ); + player_character.die( nullptr ); } } break; @@ -1585,7 +1594,7 @@ void debug() break; } if( query_int( intensity, _( "Add bleeding duration in minutes, equal to intensity:" ) ) ) { - u.make_bleed( part, 1_minutes * intensity ); + player_character.make_bleed( part, 1_minutes * intensity ); } } break; @@ -1596,7 +1605,7 @@ void debug() shared_ptr_fast sound_cb = make_shared_fast( [&]() { const point offset { - u.view_offset.xy() + point( POSX - u.posx(), POSY - u.posy() ) + player_character.view_offset.xy() + point( POSX - player_character.posx(), POSY - player_character.posy() ) }; for( const auto &sound : sounds_to_draw.first ) { mvwputch( g->w_terrain, offset + sound.xy(), c_yellow, '?' ); @@ -1708,20 +1717,21 @@ void debug() break; case debug_menu_index::SET_AUTOMOVE: { const cata::optional dest = g->look_around(); - if( !dest || *dest == u.pos() ) { + if( !dest || *dest == player_character.pos() ) { break; } - auto rt = here.route( u.pos(), *dest, u.get_pathfinding_settings(), u.get_path_avoid() ); + auto rt = here.route( player_character.pos(), *dest, player_character.get_pathfinding_settings(), + player_character.get_path_avoid() ); if( !rt.empty() ) { - u.set_destination( rt ); + player_character.set_destination( rt ); } else { popup( "Couldn't find path" ); } } break; case debug_menu_index::SHOW_MUT_CAT: - for( const auto &elem : u.mutation_category_level ) { + for( const auto &elem : player_character.mutation_category_level ) { add_msg( "%s: %d", elem.first.c_str(), elem.second ); } break; @@ -1800,7 +1810,7 @@ void debug() << std::endl; count++; } - std::cout << "Player faction is " << g->u.get_faction()->id.str() << std::endl; + std::cout << "Player faction is " << player_character.get_faction()->id.str() << std::endl; break; } case debug_menu_index::PRINT_NPC_MAGIC: { @@ -1827,7 +1837,7 @@ void debug() case debug_menu_index::QUIT_NOSAVE: if( query_yn( _( "Quit without saving? This may cause issues such as duplicated or missing items and vehicles!" ) ) ) { - u.moves = 0; + player_character.moves = 0; g->uquit = QUIT_NOSAVED; } break; @@ -1848,7 +1858,8 @@ void debug() std::time_t time = std::time( nullptr ); std::stringstream date_buffer; date_buffer << std::put_time( std::gmtime( &time ), "%F_%H-%M-%S_%z" ); - const auto tmp_file_name = string_format( "[%s]_%s.png", g->u.get_name(), date_buffer.str() ); + const auto tmp_file_name = string_format( "[%s]_%s.png", player_character.get_name(), + date_buffer.str() ); std::string file_name = ensure_valid_file_name( tmp_file_name ); auto current_file_path = map_directory.str() + file_name; @@ -1887,14 +1898,14 @@ void debug() add_msg( m_bad, _( "There are no spells to learn. You must install a mod that adds some." ) ); } else { for( const spell_type &learn : spell_type::get_all() ) { - g->u.magic.learn_spell( &learn, g->u, true ); + player_character.magic.learn_spell( &learn, player_character, true ); } add_msg( m_good, _( "You have become an Archwizardpriest! What will you do with your newfound power?" ) ); } break; case debug_menu_index::LEVEL_SPELLS: { - std::vector spells = g->u.magic.get_spells(); + std::vector spells = player_character.magic.get_spells(); if( spells.empty() ) { add_msg( m_bad, _( "Try learning some spells first." ) ); return; @@ -1940,7 +1951,7 @@ void debug() case debug_menu_index::VEHICLE_BATTERY_CHARGE: { - optional_vpart_position v_part_pos = here.veh_at( u.pos() ); + optional_vpart_position v_part_pos = here.veh_at( player_character.pos() ); if( !v_part_pos ) { add_msg( m_bad, _( "There's no vehicle there." ) ); break; From e2e870d181141697fb84dad1a82046625d8e7a55 Mon Sep 17 00:00:00 2001 From: andrei Date: Wed, 15 Jul 2020 11:17:35 +0300 Subject: [PATCH 043/151] npc: fix consume_food for new pocket system also fix decide_needs() --- src/npc.cpp | 13 ++++++------- src/npcmove.cpp | 50 ++++++++++++++++++++++++++----------------------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/npc.cpp b/src/npc.cpp index d0c76c456fa4f..c5943261a2ba6 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -1522,13 +1522,12 @@ void npc::decide_needs() needrank[need_weapon] = weapon_value( weapon ); needrank[need_food] = 15 - get_hunger(); needrank[need_drink] = 15 - get_thirst(); - invslice slice = inv.slice(); - for( auto &i : slice ) { - item inventory_item = i->front(); - if( const item *food = inventory_item.get_food() ) { - needrank[ need_food ] += nutrition_for( *food ) / 4.0; - needrank[ need_drink ] += food->get_comestible()->quench / 4.0; - } + const auto inv_food = items_with( []( const item & itm ) { + return itm.is_food(); + } ); + for( auto &food : inv_food ) { + needrank[ need_food ] += nutrition_for( *food ) / 4.0; + needrank[ need_drink ] += food->get_comestible()->quench / 4.0; } needs.clear(); size_t j; diff --git a/src/npcmove.cpp b/src/npcmove.cpp index a6df59a36da6a..b5a9342cb8847 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -3848,41 +3848,45 @@ bool npc::consume_food_from_camp() bool npc::consume_food() { float best_weight = 0.0f; - int index = -1; + item* best_food = nullptr; + bool consumed = false; int want_hunger = std::max( 0, get_hunger() ); int want_quench = std::max( 0, get_thirst() ); - invslice slice = inv.slice(); - for( size_t i = 0; i < slice.size(); i++ ) { - const item &it = slice[i]->front(); - if( const item *food_item = it.get_food() ) { + + const auto inv_food = items_with( []( const item & itm ) { + return itm.is_food(); + } ); + + if( inv_food.empty() ) { + if( !is_player_ally() ) { + // TODO: Remove this and let player "exploit" hungry NPCs + set_hunger( 0 ); + set_thirst( 0 ); + } + } else { + for ( const auto &food_item : inv_food ) { float cur_weight = rate_food( *food_item, want_hunger, want_quench ); // Note: will_eat is expensive, avoid calling it if possible if( cur_weight > best_weight && will_eat( *food_item ).success() ) { best_weight = cur_weight; - index = i; + best_food = food_item; } } - } - if( index == -1 ) { - if( !is_player_ally() ) { - // TODO: Remove this and let player "exploit" hungry NPCs - set_hunger( 0 ); - set_thirst( 0 ); + // consume doesn't return a meaningful answer, we need to compare moves + // TODO: Make player::consume return false if it fails to consume + if ( best_food != nullptr ) { + const time_duration &consume_time = get_consume_time( *best_food ); + consumed = consume( item_location( *this, best_food ) ); + if( consumed ) { + moves -= to_moves( consume_time ); + } else { + debugmsg( "%s failed to consume %s", name, best_food->tname() ); + } } - return false; - } - // consume doesn't return a meaningful answer, we need to compare moves - // TODO: Make player::consume return false if it fails to consume - item_location loc = item_location( *this, &i_at( index ) ); - const time_duration &consume_time = get_consume_time( *loc ); - moves -= to_moves( consume_time ); - bool consumed = consume( loc ); - if( !consumed ) { - debugmsg( "%s failed to consume %s", name, i_at( index ).tname() ); } - + return consumed; } From a1f27e12a3093762e0dd8230f9b3548b23e06c04 Mon Sep 17 00:00:00 2001 From: andrei Date: Wed, 15 Jul 2020 12:29:19 +0300 Subject: [PATCH 044/151] npc: fix heal_self() for pocket system --- src/npcmove.cpp | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/npcmove.cpp b/src/npcmove.cpp index b5a9342cb8847..b8ffc24eb8df5 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -3667,19 +3667,28 @@ void npc:: pretend_heal( player &patient, item used ) void npc::heal_self() { if( has_effect( effect_asthma ) ) { - item &treatment = null_item_reference(); - std::string iusage = "OXYGEN_BOTTLE"; - if( has_charges( itype_inhaler, 1 ) ) { - treatment = inv.find_item( inv.position_by_type( itype_inhaler ) ); + item *treatment = nullptr; + std::string iusage; + + const auto inv_inhalers = items_with( []( const item & itm ) { + return ( itm.type->get_use( "INHALER" ) != nullptr ) && + ( itm.ammo_sufficient() ); + } ); + + if( !inv_inhalers.empty() ) { + treatment = inv_inhalers.front(); iusage = "INHALER"; - } else if( has_charges( itype_oxygen_tank, 1 ) ) { - treatment = inv.find_item( inv.position_by_type( itype_oxygen_tank ) ); - } else if( has_charges( itype_smoxygen_tank, 1 ) ) { - treatment = inv.find_item( inv.position_by_type( itype_smoxygen_tank ) ); - } - if( !treatment.is_null() ) { - treatment.type->invoke( *this, treatment, pos(), iusage ); - consume_charges( treatment, 1 ); + } else { + const auto inv_oxybottles = items_with( []( const item & itm ) { + return ( itm.type->get_use( "OXYGEN_BOTTLE" ) != nullptr ) && + ( itm.ammo_sufficient() ); + } ); + treatment = inv_oxybottles.front(); + iusage = "OXYGEN_BOTTLE"; + } + if( treatment != nullptr ) { + treatment->get_use(iusage)->call(*this, *treatment, treatment->active, pos() ); + treatment->ammo_consume( treatment->ammo_required(), pos() ); return; } } From f559654383300315cb565fcebf9cc17818f5187e Mon Sep 17 00:00:00 2001 From: andrei Date: Wed, 15 Jul 2020 13:04:44 +0300 Subject: [PATCH 045/151] npc: replace code duplication with code uglyness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit also add a nullptr check šŸ¤¦ --- src/npcmove.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/npcmove.cpp b/src/npcmove.cpp index b8ffc24eb8df5..ca630120428b8 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -3668,23 +3668,25 @@ void npc::heal_self() { if( has_effect( effect_asthma ) ) { item *treatment = nullptr; - std::string iusage; + std::string iusage = "INHALER"; - const auto inv_inhalers = items_with( []( const item & itm ) { - return ( itm.type->get_use( "INHALER" ) != nullptr ) && - ( itm.ammo_sufficient() ); - } ); + const auto filter_use = [this]( const std::string &filter ) -> std::vector { + const auto inv_filtered = items_with( [&filter]( const item & itm ) { + return ( itm.type->get_use( filter ) != nullptr ) && + ( itm.ammo_sufficient() ); + } ); + return inv_filtered; + }; + const auto inv_inhalers = filter_use( iusage ); if( !inv_inhalers.empty() ) { treatment = inv_inhalers.front(); - iusage = "INHALER"; } else { - const auto inv_oxybottles = items_with( []( const item & itm ) { - return ( itm.type->get_use( "OXYGEN_BOTTLE" ) != nullptr ) && - ( itm.ammo_sufficient() ); - } ); - treatment = inv_oxybottles.front(); iusage = "OXYGEN_BOTTLE"; + const auto inv_oxybottles = filter_use( iusage ); + if( !inv_oxybottles.empty() ) { + treatment = inv_oxybottles.front(); + } } if( treatment != nullptr ) { treatment->get_use(iusage)->call(*this, *treatment, treatment->active, pos() ); From 10608665c5021af70e182b547f0a67e8d317bbda Mon Sep 17 00:00:00 2001 From: andrei Date: Wed, 15 Jul 2020 13:52:49 +0300 Subject: [PATCH 046/151] npc: remove dead code wrt wielding there's no need anymore for special handling of holstered items and this block of code didn't do anything anyway (slice() returned empty container) --- src/npc.cpp | 18 ------------------ src/npcmove.cpp | 1 - 2 files changed, 19 deletions(-) diff --git a/src/npc.cpp b/src/npc.cpp index c5943261a2ba6..2406dbdf2d89c 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -1158,24 +1158,6 @@ bool npc::wield( item &it ) return true; } - // check if the item is in a holster - int position = inv.position_by_item( &it ); - if( position != INT_MIN ) { - item &maybe_holster = inv.find_item( position ); - assert( !maybe_holster.is_null() ); - if( &maybe_holster != &it && maybe_holster.is_holster() ) { - assert( !maybe_holster.contents.empty() ); - const size_t old_size = maybe_holster.contents.num_item_stacks(); - invoke_item( &maybe_holster ); - // TODO: change invoke_item to somehow report this change - // HACK: test whether wielding the item from the holster has been done. - // (Wielding may be prevented by various reasons: see player::wield_contained) - if( old_size != maybe_holster.contents.num_item_stacks() ) { - return true; - } - } - } - moves -= 15; if( has_item( it ) ) { weapon = remove_item( it ); diff --git a/src/npcmove.cpp b/src/npcmove.cpp index ca630120428b8..f9c8da1270d70 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -3375,7 +3375,6 @@ bool npc::wield_better_weapon() // TODO: Allow wielding weaker weapons against weaker targets bool can_use_gun = ( !is_player_ally() || rules.has_flag( ally_rule::use_guns ) ); bool use_silent = ( is_player_ally() && rules.has_flag( ally_rule::use_silent ) ); - invslice slice = inv.slice(); // Check if there's something better to wield item *best = &weapon; From fce40ba905299f1c96e8d6391d3ea8b33580990c Mon Sep 17 00:00:00 2001 From: andrei Date: Wed, 15 Jul 2020 14:00:55 +0300 Subject: [PATCH 047/151] npc: update inventory access in alt_attack() --- src/npcmove.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/npcmove.cpp b/src/npcmove.cpp index f9c8da1270d70..674716cb9db8d 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -3525,9 +3525,9 @@ bool npc::alt_attack() }; check_alt_item( weapon ); - for( auto &sl : inv.slice() ) { + for( auto &it : items_with( []( const item & ) { return true; } ) ) { // TODO: Cached values - an itype slot maybe? - check_alt_item( sl->front() ); + check_alt_item( *it ); } if( used == nullptr ) { From 48a16bde9669067759600d11b8c63e08f3e1835e Mon Sep 17 00:00:00 2001 From: andrei Date: Wed, 15 Jul 2020 14:15:33 +0300 Subject: [PATCH 048/151] npc: update inventory access in mug_player() --- src/npcmove.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/npcmove.cpp b/src/npcmove.cpp index 674716cb9db8d..a5d8ca09bf92a 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -3943,9 +3943,11 @@ void npc::mug_player( Character &mark ) } double best_value = minimum_item_value() * value_mod; item *to_steal = nullptr; - invslice slice = mark.inv.slice(); - for( std::list *stack : slice ) { - item &front_stack = stack->front(); + const auto inv_valuables = items_with( [this](const item & itm) { + return value( itm ) > 0; + }); + for( auto &it : inv_valuables ) { + item &front_stack = *it; // is this safe? if( value( front_stack ) >= best_value && can_pickVolume( front_stack, true ) && can_pickWeight( front_stack, true ) ) { From de1791f23af5e7e6285cae8cb9b914ba933cef33 Mon Sep 17 00:00:00 2001 From: andrei Date: Wed, 15 Jul 2020 14:26:53 +0300 Subject: [PATCH 049/151] npc: update inventory access in init_selling() affects asking NPC to give equipment --- src/npctrade.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/npctrade.cpp b/src/npctrade.cpp index 95195e851b19d..2c0f96657f19e 100644 --- a/src/npctrade.cpp +++ b/src/npctrade.cpp @@ -90,14 +90,14 @@ void npc_trading::transfer_items( std::vector &stuff, player &give std::vector npc_trading::init_selling( npc &np ) { std::vector result; - invslice slice = np.inv.slice(); - for( auto &i : slice ) { - item &it = i->front(); + const auto inv_all = np.items_with( []( const item & ) { return true; } ); + for( auto &i : inv_all ) { + item &it = *i; const int price = it.price( true ); int val = np.value( it ); if( np.wants_to_sell( it, val, price ) ) { - result.emplace_back( np, i->front(), val, static_cast( i->size() ) ); + result.emplace_back( np, it, val, static_cast( it.count() ) ); } } From 301af41d40f05046562e759156ff845d5046ee00 Mon Sep 17 00:00:00 2001 From: andrei Date: Wed, 15 Jul 2020 14:39:06 +0300 Subject: [PATCH 050/151] npc: astyle --- src/npcmove.cpp | 27 +++++++++++++++------------ src/npctrade.cpp | 4 +++- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/npcmove.cpp b/src/npcmove.cpp index a5d8ca09bf92a..662821e7fe2d6 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -3525,7 +3525,10 @@ bool npc::alt_attack() }; check_alt_item( weapon ); - for( auto &it : items_with( []( const item & ) { return true; } ) ) { + const auto inv_all = items_with( []( const item & ) { + return true; + } ); + for( auto &it : inv_all ) { // TODO: Cached values - an itype slot maybe? check_alt_item( *it ); } @@ -3669,10 +3672,10 @@ void npc::heal_self() item *treatment = nullptr; std::string iusage = "INHALER"; - const auto filter_use = [this]( const std::string &filter ) -> std::vector { - const auto inv_filtered = items_with( [&filter]( const item & itm ) { - return ( itm.type->get_use( filter ) != nullptr ) && - ( itm.ammo_sufficient() ); + const auto filter_use = [this]( const std::string & filter ) -> std::vector { + const auto inv_filtered = items_with( [&filter]( const item & itm ) + { + return ( itm.type->get_use( filter ) != nullptr ) && ( itm.ammo_sufficient() ); } ); return inv_filtered; }; @@ -3688,7 +3691,7 @@ void npc::heal_self() } } if( treatment != nullptr ) { - treatment->get_use(iusage)->call(*this, *treatment, treatment->active, pos() ); + treatment->get_use( iusage )->call( *this, *treatment, treatment->active, pos() ); treatment->ammo_consume( treatment->ammo_required(), pos() ); return; } @@ -3858,7 +3861,7 @@ bool npc::consume_food_from_camp() bool npc::consume_food() { float best_weight = 0.0f; - item* best_food = nullptr; + item *best_food = nullptr; bool consumed = false; int want_hunger = std::max( 0, get_hunger() ); int want_quench = std::max( 0, get_thirst() ); @@ -3874,7 +3877,7 @@ bool npc::consume_food() set_thirst( 0 ); } } else { - for ( const auto &food_item : inv_food ) { + for( const auto &food_item : inv_food ) { float cur_weight = rate_food( *food_item, want_hunger, want_quench ); // Note: will_eat is expensive, avoid calling it if possible if( cur_weight > best_weight && will_eat( *food_item ).success() ) { @@ -3885,7 +3888,7 @@ bool npc::consume_food() // consume doesn't return a meaningful answer, we need to compare moves // TODO: Make player::consume return false if it fails to consume - if ( best_food != nullptr ) { + if( best_food != nullptr ) { const time_duration &consume_time = get_consume_time( *best_food ); consumed = consume( item_location( *this, best_food ) ); if( consumed ) { @@ -3896,7 +3899,7 @@ bool npc::consume_food() } } - + return consumed; } @@ -3943,9 +3946,9 @@ void npc::mug_player( Character &mark ) } double best_value = minimum_item_value() * value_mod; item *to_steal = nullptr; - const auto inv_valuables = items_with( [this](const item & itm) { + const auto inv_valuables = items_with( [this]( const item & itm ) { return value( itm ) > 0; - }); + } ); for( auto &it : inv_valuables ) { item &front_stack = *it; // is this safe? if( value( front_stack ) >= best_value && diff --git a/src/npctrade.cpp b/src/npctrade.cpp index 2c0f96657f19e..daafb438ddcf7 100644 --- a/src/npctrade.cpp +++ b/src/npctrade.cpp @@ -90,7 +90,9 @@ void npc_trading::transfer_items( std::vector &stuff, player &give std::vector npc_trading::init_selling( npc &np ) { std::vector result; - const auto inv_all = np.items_with( []( const item & ) { return true; } ); + const auto inv_all = np.items_with( []( const item & ) { + return true; + } ); for( auto &i : inv_all ) { item &it = *i; From 5abe74c155bb8df7fc8365c13004d2a080ab1c91 Mon Sep 17 00:00:00 2001 From: UrbanCMC Date: Wed, 15 Jul 2020 14:11:08 +0200 Subject: [PATCH 051/151] Fix MRE Accessory pack creating empty matchbooks --- data/json/recipes/recipe_deconstruction_package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/recipes/recipe_deconstruction_package.json b/data/json/recipes/recipe_deconstruction_package.json index 8bc5582f70f5b..0cebfe08ce1cb 100644 --- a/data/json/recipes/recipe_deconstruction_package.json +++ b/data/json/recipes/recipe_deconstruction_package.json @@ -14,7 +14,7 @@ [ [ "spork", 1 ] ], [ [ "bag_plastic", 1 ] ] ], - "flags": [ "BLIND_EASY" ] + "flags": [ "BLIND_EASY", "FULL_MAGAZINE" ] }, { "result": "mre_dessert", From d97692fd1b0f5159dd216cb11b976ece95f937bb Mon Sep 17 00:00:00 2001 From: Valiant Date: Wed, 15 Jul 2020 16:38:56 +0400 Subject: [PATCH 052/151] Added a zombull --- data/json/monsters/zed-animal.json | 35 +++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/data/json/monsters/zed-animal.json b/data/json/monsters/zed-animal.json index 7567cf917171e..9f9fbb37ab2d7 100644 --- a/data/json/monsters/zed-animal.json +++ b/data/json/monsters/zed-animal.json @@ -390,7 +390,7 @@ "description": "Once a placid cow, this leathery horror stumbles and shudders, its pulsing black eyes scanning for prey beneath wicked horns. It is big and heavy and murderous.", "looks_like": "mon_cow", "default_faction": "zombie", - "bodytype": "dog", + "bodytype": "horse", "categories": [ "CLASSIC" ], "species": [ "ZOMBIE" ], "volume": "680 L", @@ -416,6 +416,39 @@ "harvest": "zombie_leather", "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "POISON", "NO_BREATHE", "REVIVES", "FILTHY" ] }, + { + "id": "mon_zombull", + "type": "MONSTER", + "name": { "str": "zombull" }, + "description": "This enormous and massive creature with oily black eyes and dread horns once was a domestic bull. Its nasty character makes it attack everyone it meets with an unbridled rage and tremendous speed.", + "default_faction": "zombie", + "bodytype": "horse", + "categories": [ "CLASSIC" ], + "species": [ "ZOMBIE" ], + "volume": "750 L", + "weight": "750 kg", + "hp": 210, + "speed": 150, + "material": [ "flesh" ], + "symbol": "B", + "color": "green", + "aggression": 100, + "morale": 100, + "melee_skill": 6, + "melee_dice": 4, + "melee_dice_sides": 6, + "melee_cut": 6, + "armor_bash": 6, + "armor_cut": 4, + "armor_bullet": 3, + "vision_day": 30, + "vision_night": 3, + "anger_triggers": [ "PLAYER_CLOSE", "HURT" ], + "fear_triggers": [ "FIRE" ], + "death_function": [ "NORMAL" ], + "harvest": "zombie_leather", + "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY", "PUSH_MON", "ATTACKMON" ] + }, { "id": "mon_zeer", "type": "MONSTER", From f7b782b065e5e1b584fc7d2c13ef2e45c618131b Mon Sep 17 00:00:00 2001 From: Valiant Date: Wed, 15 Jul 2020 16:43:14 +0400 Subject: [PATCH 053/151] Added zombulls and zows spawn to a variation of dairy farm --- data/json/mapgen/farm_dairy.json | 41 ++++++++++++++++++++++++++++ data/json/monstergroups/zombies.json | 9 ++++++ 2 files changed, 50 insertions(+) diff --git a/data/json/mapgen/farm_dairy.json b/data/json/mapgen/farm_dairy.json index d276382daadf1..2b502ae9a4f5d 100644 --- a/data/json/mapgen/farm_dairy.json +++ b/data/json/mapgen/farm_dairy.json @@ -47,6 +47,47 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ [ "dairy_farm_NW", "dairy_farm_NE" ] ], + "weight": 200, + "object": { + "fill_ter": "t_dirt", + "rows": [ + ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,", + ",$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$,", + ",$............................................$," + ], + "terrain": { + "$": "t_splitrail_fence", + ".": [ "t_grass", "t_grass", "t_dirt", "t_dirt", "t_dirt" ], + ",": [ "t_grass", "t_grass", "t_dirt", "t_dirt", "t_dirt" ] + }, + "monsters": { ".": { "monster": "GROUP_ZOMBIE_BOVINE", "chance": 1, "density": 0.0005 } } + } + }, { "type": "mapgen", "method": "json", diff --git a/data/json/monstergroups/zombies.json b/data/json/monstergroups/zombies.json index a4b77da6f149e..8a34ad451b73d 100644 --- a/data/json/monstergroups/zombies.json +++ b/data/json/monstergroups/zombies.json @@ -633,5 +633,14 @@ { "monster": "mon_zombie_swimmer", "freq": 100, "cost_multiplier": 2 }, { "monster": "mon_zombie_swimmer", "freq": 50, "cost_multiplier": 10, "pack_size": [ 3, 8 ] } ] + }, + { + "name": "GROUP_ZOMBIE_BOVINE", + "type": "monstergroup", + "default": "mon_zow", + "monsters": [ + { "monster": "mon_zow", "freq": 100, "cost_multiplier": 1, "pack_size": [ 1, 3 ] }, + { "monster": "mon_zombull", "freq": 75, "cost_multiplier": 1, "pack_size": [ 1, 2 ] } + ] } ] From 49d600508853bb123353c46671ba7f71728372b2 Mon Sep 17 00:00:00 2001 From: Valiant Date: Wed, 15 Jul 2020 16:55:24 +0400 Subject: [PATCH 054/151] Added a SMASH special attack and an ability to shove vehicles --- data/json/monsters/zed-animal.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/data/json/monsters/zed-animal.json b/data/json/monsters/zed-animal.json index 9f9fbb37ab2d7..ba20f0e855ab1 100644 --- a/data/json/monsters/zed-animal.json +++ b/data/json/monsters/zed-animal.json @@ -447,7 +447,22 @@ "fear_triggers": [ "FIRE" ], "death_function": [ "NORMAL" ], "harvest": "zombie_leather", - "flags": [ "SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "REVIVES", "FILTHY", "PUSH_MON", "ATTACKMON" ] + "special_attacks": [ [ "SMASH", 10 ] ], + "flags": [ + "SEES", + "HEARS", + "SMELLS", + "STUMBLES", + "WARM", + "BASHES", + "POISON", + "NO_BREATHE", + "REVIVES", + "FILTHY", + "PUSH_MON", + "PUSH_VEH", + "ATTACKMON" + ] }, { "id": "mon_zeer", From 05d4338ad41291044e4d264e0375a256131bb417 Mon Sep 17 00:00:00 2001 From: Your Name Here Date: Wed, 15 Jul 2020 06:09:46 -0700 Subject: [PATCH 055/151] Fix mutagen withdrawal messages being sent each second --- src/addiction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addiction.cpp b/src/addiction.cpp index edaafb54e68ee..3567e0c6ceb07 100644 --- a/src/addiction.cpp +++ b/src/addiction.cpp @@ -222,7 +222,7 @@ void addict_effect( Character &u, addiction &add ) u.add_msg_if_player( m_warning, _( "You daydream what it'd be like if you were *different*. Different is good." ) ); } - } else if( in > 5 || one_in( 500 - 15 * in ) ) { + } else if( one_in( 500 - 15 * in ) ) { u.add_msg_if_player( m_warning, rng( 0, 6 ) < in ? _( "You haven't had any mutagen lately." ) : _( "You could use some new partsā€¦" ) ); u.add_morale( MORALE_CRAVING_MUTAGEN, -5, -50 ); From 202687325cbc00ba6e187911628dac8c6788737e Mon Sep 17 00:00:00 2001 From: UrbanCMC Date: Wed, 15 Jul 2020 16:25:01 +0200 Subject: [PATCH 056/151] activity_handlers: Fix crash when reloading --- src/activity_handlers.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 9801c0c2deb54..ab57faf248cb4 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -2042,6 +2042,8 @@ void activity_handlers::reload_finish( player_activity *act, player *p ) item &ammo = *act->targets[ 1 ]; std::string reloadable_name = reloadable.tname(); std::string ammo_name = ammo.tname(); + const bool ammo_is_filthy = ammo.is_filthy(); + const bool ammo_uses_speedloader = ammo.has_flag( flag_SPEEDLOADER ); const int qty = act->index; if( !reloadable.reload( *p, std::move( act->targets[ 1 ] ), qty ) ) { @@ -2049,7 +2051,7 @@ void activity_handlers::reload_finish( player_activity *act, player *p ) return; } - if( ammo.is_filthy() ) { + if( ammo_is_filthy ) { reloadable.set_flag( "FILTHY" ); } @@ -2062,7 +2064,7 @@ void activity_handlers::reload_finish( player_activity *act, player *p ) if( reloadable.is_gun() ) { p->recoil = MAX_RECOIL; - if( reloadable.has_flag( flag_RELOAD_ONE ) && !ammo.has_flag( flag_SPEEDLOADER ) ) { + if( reloadable.has_flag( flag_RELOAD_ONE ) && !ammo_uses_speedloader ) { for( int i = 0; i != qty; ++i ) { add_msg( m_neutral, _( "You insert one %2$s into the %1$s." ), reloadable_name, ammo_name ); } From df9a0218b8624273193a675e868057e3a0de193a Mon Sep 17 00:00:00 2001 From: UrbanCMC Date: Wed, 15 Jul 2020 17:20:47 +0200 Subject: [PATCH 057/151] activity_handlers: document reason for cached values --- src/activity_handlers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index ab57faf248cb4..156b00eb61f2e 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -2042,6 +2042,7 @@ void activity_handlers::reload_finish( player_activity *act, player *p ) item &ammo = *act->targets[ 1 ]; std::string reloadable_name = reloadable.tname(); std::string ammo_name = ammo.tname(); + // cache check results because reloading deletes the ammo item const bool ammo_is_filthy = ammo.is_filthy(); const bool ammo_uses_speedloader = ammo.has_flag( flag_SPEEDLOADER ); const int qty = act->index; From b2125cd1fd63a06c171e5f8a964c4c50848d74d8 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Wed, 15 Jul 2020 06:48:12 -0500 Subject: [PATCH 058/151] dialogue: move npc_chatbin into its own file npc_chatbin needs to be generic so it can be used for other talker entities. Move it into its own file in preparation for cleaning it up. --- src/debug_menu.cpp | 1 + src/dialogue_chatbin.cpp | 21 ++++++++++++++ src/dialogue_chatbin.h | 59 ++++++++++++++++++++++++++++++++++++++++ src/game.cpp | 1 + src/npc.cpp | 9 +----- src/npc.h | 46 +------------------------------ src/npcmove.cpp | 1 + src/npctalk.cpp | 12 +------- src/npctalk_funcs.cpp | 1 + src/savegame_json.cpp | 1 + src/talker_npc.cpp | 1 + 11 files changed, 89 insertions(+), 64 deletions(-) create mode 100644 src/dialogue_chatbin.cpp create mode 100644 src/dialogue_chatbin.h diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index e9e94f7298e26..d02a941d7454e 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -37,6 +37,7 @@ #include "coordinate_conversions.h" #include "cursesdef.h" #include "debug.h" +#include "dialogue_chatbin.h" #include "enum_conversions.h" #include "enums.h" #include "faction.h" diff --git a/src/dialogue_chatbin.cpp b/src/dialogue_chatbin.cpp new file mode 100644 index 0000000000000..c0ec47c2c7bdc --- /dev/null +++ b/src/dialogue_chatbin.cpp @@ -0,0 +1,21 @@ +#include "dialogue_chatbin.h" +#include "mission.h" + +void npc_chatbin::add_new_mission( mission *miss ) +{ + if( miss == nullptr ) { + return; + } + missions.push_back( miss ); +} + +void npc_chatbin::check_missions() +{ + // TODO: or simply fail them? Some missions might only need to be reported. + auto &ma = missions_assigned; + const auto last = std::remove_if( ma.begin(), ma.end(), []( class mission const * m ) { + return !m->is_assigned(); + } ); + std::copy( last, ma.end(), std::back_inserter( missions ) ); + ma.erase( last, ma.end() ); +} diff --git a/src/dialogue_chatbin.h b/src/dialogue_chatbin.h new file mode 100644 index 0000000000000..387e4ed646b2c --- /dev/null +++ b/src/dialogue_chatbin.h @@ -0,0 +1,59 @@ +#pragma once +#ifndef CATA_SRC_DIALOGUE_CHATBIN_H +#define CATA_SRC_DIALOGUE_CHATBIN_H + +#include +#include +#include "string_id.h" +#include "type_id.h" + +class JsonIn; +class JsonOut; +class mission; + +struct npc_chatbin { + /** + * Add a new mission to the available missions (@ref missions). For compatibility it silently + * ignores null pointers passed to it. + */ + void add_new_mission( mission *miss ); + /** + * Check that assigned missions are still assigned if not move them back to the + * unassigned vector. This is called directly before talking. + */ + void check_missions(); + /** + * Missions that the NPC can give out. All missions in this vector should be unassigned, + * when given out, they should be moved to @ref missions_assigned. + */ + std::vector missions; + /** + * Mission that have been assigned by this NPC to a player character. + */ + std::vector missions_assigned; + /** + * The mission (if any) that we talk about right now. Can be null. Should be one of the + * missions in @ref missions or @ref missions_assigned. + */ + mission *mission_selected = nullptr; + /** + * The skill this NPC offers to train. + */ + skill_id skill = skill_id::NULL_ID(); + /** + * The martial art style this NPC offers to train. + */ + matype_id style; + /** + * The spell this NPC offers to train + */ + spell_id dialogue_spell; + std::string first_topic = "TALK_NONE"; + + npc_chatbin() = default; + + void serialize( JsonOut &json ) const; + void deserialize( JsonIn &jsin ); +}; + +#endif // CATA_SRC_DIALOGUE_CHATBIN_H diff --git a/src/game.cpp b/src/game.cpp index b43a66ffea612..f170f30ebf3be 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -58,6 +58,7 @@ #include "damage.h" #include "debug.h" #include "dependency_tree.h" +#include "dialogue_chatbin.h" #include "editmap.h" #include "enums.h" #include "event.h" diff --git a/src/npc.cpp b/src/npc.cpp index a436ac15786ad..da495d52d0ecb 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -21,6 +21,7 @@ #include "coordinate_conversions.h" #include "damage.h" #include "debug.h" +#include "dialogue_chatbin.h" #include "effect.h" #include "enums.h" #include "event.h" @@ -2775,14 +2776,6 @@ void npc::on_load() } } -void npc_chatbin::add_new_mission( mission *miss ) -{ - if( miss == nullptr ) { - return; - } - missions.push_back( miss ); -} - constexpr tripoint npc::no_goal_point; bool npc::query_yn( const std::string &/*msg*/ ) const diff --git a/src/npc.h b/src/npc.h index d0a3e1dabad74..b0826fa469833 100644 --- a/src/npc.h +++ b/src/npc.h @@ -21,6 +21,7 @@ #include "color.h" #include "creature.h" #include "cursesdef.h" +#include "dialogue_chatbin.h" #include "enums.h" #include "faction.h" #include "game_constants.h" @@ -739,51 +740,6 @@ enum talk_topic_enum { // Function for conversion of legacy topics, defined in savegame_legacy.cpp std::string convert_talk_topic( talk_topic_enum old_value ); -struct npc_chatbin { - /** - * Add a new mission to the available missions (@ref missions). For compatibility it silently - * ignores null pointers passed to it. - */ - void add_new_mission( mission *miss ); - /** - * Check that assigned missions are still assigned if not move them back to the - * unassigned vector. This is called directly before talking. - */ - void check_missions(); - /** - * Missions that the NPC can give out. All missions in this vector should be unassigned, - * when given out, they should be moved to @ref missions_assigned. - */ - std::vector missions; - /** - * Mission that have been assigned by this NPC to a player character. - */ - std::vector missions_assigned; - /** - * The mission (if any) that we talk about right now. Can be null. Should be one of the - * missions in @ref missions or @ref missions_assigned. - */ - mission *mission_selected = nullptr; - /** - * The skill this NPC offers to train. - */ - skill_id skill = skill_id::NULL_ID(); - /** - * The martial art style this NPC offers to train. - */ - matype_id style; - /** - * The spell this NPC offers to train - */ - spell_id dialogue_spell; - std::string first_topic = "TALK_NONE"; - - npc_chatbin() = default; - - void serialize( JsonOut &json ) const; - void deserialize( JsonIn &jsin ); -}; - class npc_template; class npc : public player diff --git a/src/npcmove.cpp b/src/npcmove.cpp index ebc24c555f300..901c154b90377 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -24,6 +24,7 @@ #include "coordinate_conversions.h" #include "damage.h" #include "debug.h" +#include "dialogue_chatbin.h" #include "dispersion.h" #include "effect.h" #include "enums.h" diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 12a819cf3d5eb..1bb2ebf0d7a87 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -28,6 +28,7 @@ #include "compatibility.h" // IWYU pragma: keep #include "condition.h" #include "debug.h" +#include "dialogue_chatbin.h" #include "enums.h" #include "faction.h" #include "faction_camp.h" @@ -716,17 +717,6 @@ void npc::handle_sound( const sounds::sound_t spriority, const std::string &desc } } -void npc_chatbin::check_missions() -{ - // TODO: or simply fail them? Some missions might only need to be reported. - auto &ma = missions_assigned; - const auto last = std::remove_if( ma.begin(), ma.end(), []( class mission const * m ) { - return !m->is_assigned(); - } ); - std::copy( last, ma.end(), std::back_inserter( missions ) ); - ma.erase( last, ma.end() ); -} - void avatar::talk_to( std::unique_ptr talk_with, bool text_only, bool radio_contact ) { const bool has_mind_control = has_trait( trait_DEBUG_MIND_CONTROL ); diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index 3a4f3067ae35c..d47d72cb3a834 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -17,6 +17,7 @@ #include "character_id.h" #include "character_martial_arts.h" #include "debug.h" +#include "dialogue_chatbin.h" #include "enums.h" #include "event.h" #include "event_bus.h" diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 199c386a60b45..40e502608052f 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -50,6 +50,7 @@ #include "creature_tracker.h" #include "damage.h" #include "debug.h" +#include "dialogue_chatbin.h" #include "effect.h" #include "enum_conversions.h" #include "event.h" diff --git a/src/talker_npc.cpp b/src/talker_npc.cpp index ca48809c742b7..ede597747d1e9 100644 --- a/src/talker_npc.cpp +++ b/src/talker_npc.cpp @@ -1,4 +1,5 @@ #include "avatar.h" +#include "dialogue_chatbin.h" #include "game.h" #include "game_constants.h" #include "game_inventory.h" From 2c6f2bb25cbad5870ac99ce9889da438aad34eea Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Wed, 15 Jul 2020 07:15:49 -0500 Subject: [PATCH 059/151] dialogue_chatbin: clean up and add some utility functions Rename npc_chatbin to dialogue_chatbin and add some basic utility functions. --- src/debug_menu.cpp | 2 +- src/dialogue_chatbin.cpp | 32 ++++++++++++++++++++++++++++++-- src/dialogue_chatbin.h | 18 +++++++++++------- src/game.cpp | 4 +--- src/npc.h | 4 ++-- src/savegame_json.cpp | 6 +++--- src/talker_npc.cpp | 14 +------------- 7 files changed, 49 insertions(+), 31 deletions(-) diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index d02a941d7454e..1e8b82d33aacb 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -1026,7 +1026,7 @@ void mission_debug::edit( player &who ) void mission_debug::edit_npc( npc &who ) { - npc_chatbin &bin = who.chatbin; + dialogue_chatbin &bin = who.chatbin; std::vector all_missions; uilist mmenu; diff --git a/src/dialogue_chatbin.cpp b/src/dialogue_chatbin.cpp index c0ec47c2c7bdc..7332e91e96c36 100644 --- a/src/dialogue_chatbin.cpp +++ b/src/dialogue_chatbin.cpp @@ -1,7 +1,7 @@ #include "dialogue_chatbin.h" #include "mission.h" -void npc_chatbin::add_new_mission( mission *miss ) +void dialogue_chatbin::add_new_mission( mission *miss ) { if( miss == nullptr ) { return; @@ -9,7 +9,7 @@ void npc_chatbin::add_new_mission( mission *miss ) missions.push_back( miss ); } -void npc_chatbin::check_missions() +void dialogue_chatbin::check_missions() { // TODO: or simply fail them? Some missions might only need to be reported. auto &ma = missions_assigned; @@ -19,3 +19,31 @@ void npc_chatbin::check_missions() std::copy( last, ma.end(), std::back_inserter( missions ) ); ma.erase( last, ma.end() ); } + +void dialogue_chatbin::store_chosen_training( const skill_id &c_skill, const matype_id &c_style, + const spell_id &c_spell ) +{ + clear_training(); + if( c_skill ) { + skill = c_skill; + } else if( c_style ) { + style = c_style; + } else if( c_spell != spell_id() ) { + dialogue_spell = c_spell; + } +} + +void dialogue_chatbin::clear_training() +{ + style = matype_id::NULL_ID(); + skill = skill_id::NULL_ID(); + dialogue_spell = spell_id(); +} + +void dialogue_chatbin::clear_all() +{ + clear_training(); + missions.clear(); + missions_assigned.clear(); + mission_selected = nullptr; +} diff --git a/src/dialogue_chatbin.h b/src/dialogue_chatbin.h index 387e4ed646b2c..d26119aec344c 100644 --- a/src/dialogue_chatbin.h +++ b/src/dialogue_chatbin.h @@ -11,7 +11,7 @@ class JsonIn; class JsonOut; class mission; -struct npc_chatbin { +struct dialogue_chatbin { /** * Add a new mission to the available missions (@ref missions). For compatibility it silently * ignores null pointers passed to it. @@ -23,12 +23,12 @@ struct npc_chatbin { */ void check_missions(); /** - * Missions that the NPC can give out. All missions in this vector should be unassigned, + * Missions that the talker can give out. All missions in this vector should be unassigned, * when given out, they should be moved to @ref missions_assigned. */ std::vector missions; /** - * Mission that have been assigned by this NPC to a player character. + * Mission that have been assigned by this dialogue to a player character. */ std::vector missions_assigned; /** @@ -37,21 +37,25 @@ struct npc_chatbin { */ mission *mission_selected = nullptr; /** - * The skill this NPC offers to train. + * The skill this dialogue offers to train. */ skill_id skill = skill_id::NULL_ID(); /** - * The martial art style this NPC offers to train. + * The martial art style this dialogue offers to train. */ matype_id style; /** - * The spell this NPC offers to train + * The spell this dialogue offers to train */ spell_id dialogue_spell; + void store_chosen_training( const skill_id &c_skill, const matype_id &c_style, + const spell_id &c_spell ); + void clear_training(); std::string first_topic = "TALK_NONE"; - npc_chatbin() = default; + dialogue_chatbin() = default; + void clear_all(); void serialize( JsonOut &json ) const; void deserialize( JsonIn &jsin ); }; diff --git a/src/game.cpp b/src/game.cpp index f170f30ebf3be..1b93bd5d1ffb0 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3061,10 +3061,8 @@ void game::reset_npc_dispositions() continue; } npc *npc_to_add = npc_to_get.get(); - npc_to_add->chatbin.missions.clear(); - npc_to_add->chatbin.missions_assigned.clear(); + npc_to_add->chatbin.clear_all(); npc_to_add->mission = NPC_MISSION_NULL; - npc_to_add->chatbin.mission_selected = nullptr; npc_to_add->set_attitude( NPCATT_NULL ); npc_to_add->op_of_u.anger = 0; npc_to_add->op_of_u.fear = 0; diff --git a/src/npc.h b/src/npc.h index b0826fa469833..d7ba3928f2aa7 100644 --- a/src/npc.h +++ b/src/npc.h @@ -794,7 +794,7 @@ class npc : public player */ void place_on_map(); /** - * See @ref npc_chatbin::add_new_mission + * See @ref dialogue_chatbin::add_new_mission */ void add_new_mission( mission *miss ); skill_id best_skill() const; @@ -1297,7 +1297,7 @@ class npc : public player npc_mission previous_mission = NPC_MISSION_NULL; npc_personality personality; npc_opinion op_of_u; - npc_chatbin chatbin; + dialogue_chatbin chatbin; int patience = 0; // Used when we expect the player to leave the area npc_follower_rules rules; bool marked_for_death = false; // If true, we die as soon as we respawn! diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 40e502608052f..7965b697d8541 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -1279,7 +1279,7 @@ void avatar::load( const JsonObject &data ) // In 0.C there was no player_id member of mission, so it'll be the default -1. // When the member was introduced, no steps were taken to ensure compatibility with 0.C, so // missions will be buggy for saves between experimental commits bd2088c033 and dd83800. - // see npc_chatbin::check_missions and npc::talk_to_u + // see dialogue_chatbin::check_missions and npc::talk_to_u for( mission *miss : active_missions ) { miss->set_player_id_legacy_0c( getID() ); } @@ -1407,7 +1407,7 @@ void npc_follower_rules::deserialize( JsonIn &jsin ) data.read( "pickup_whitelist", *pickup_whitelist ); } -void npc_chatbin::serialize( JsonOut &json ) const +void dialogue_chatbin::serialize( JsonOut &json ) const { json.start_object(); json.member( "first_topic", first_topic ); @@ -1421,7 +1421,7 @@ void npc_chatbin::serialize( JsonOut &json ) const json.end_object(); } -void npc_chatbin::deserialize( JsonIn &jsin ) +void dialogue_chatbin::deserialize( JsonIn &jsin ) { JsonObject data = jsin.get_object(); diff --git a/src/talker_npc.cpp b/src/talker_npc.cpp index ede597747d1e9..19f368fa23b55 100644 --- a/src/talker_npc.cpp +++ b/src/talker_npc.cpp @@ -318,19 +318,7 @@ std::string talker_npc::spell_training_text( talker &student, const spell_id &sp void talker_npc::store_chosen_training( const skill_id &c_skill, const matype_id &c_style, const spell_id &c_spell ) { - if( c_skill ) { - me_npc->chatbin.skill = c_skill; - me_npc->chatbin.style = matype_id::NULL_ID(); - me_npc->chatbin.dialogue_spell = spell_id(); - } else if( c_style ) { - me_npc->chatbin.style = c_style; - me_npc->chatbin.skill = skill_id::NULL_ID(); - me_npc->chatbin.dialogue_spell = spell_id(); - } else if( c_spell != spell_id() ) { - me_npc->chatbin.style = matype_id::NULL_ID(); - me_npc->chatbin.skill = skill_id::NULL_ID(); - me_npc->chatbin.dialogue_spell = c_spell; - } + me_npc->chatbin.store_chosen_training( c_skill, c_style, c_spell ); } int talker_npc::debt() const From 016082ff2065d3b273c4ba7d6dfa227e46e485ff Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Wed, 15 Jul 2020 07:50:15 -0500 Subject: [PATCH 060/151] dialogue: add npc_set_first_topic dialogue effect Add a new dialogue effect to explicitly set the first conversation for the NPC. --- data/json/npcs/TALK_TEST.json | 13 +++++++++++++ doc/NPCs.md | 1 + src/dialogue.h | 1 + src/npctalk.cpp | 10 ++++++++++ src/talker.h | 1 + src/talker_npc.cpp | 5 +++++ src/talker_npc.h | 1 + tests/npc_talk_test.cpp | 15 +++++++++++++++ 8 files changed, 47 insertions(+) diff --git a/data/json/npcs/TALK_TEST.json b/data/json/npcs/TALK_TEST.json index 6c23dd217571c..ccbe18cf93bfd 100644 --- a/data/json/npcs/TALK_TEST.json +++ b/data/json/npcs/TALK_TEST.json @@ -854,6 +854,19 @@ } ] }, + { + "type": "talk_topic", + "id": "TALK_TEST_SET_TOPIC", + "dynamic_line": "This is a test conversation that shouldn't appear in the game.", + "responses": [ + { "text": "This is a basic test response.", "topic": "TALK_DONE" }, + { + "text": "This is an npc_first_topic test response.", + "topic": "TALK_DONE", + "effect": { "npc_first_topic": "TALK_TEST_SET_TOPIC" } + } + ] + }, { "type": "npc", "id": "test_talker", diff --git a/doc/NPCs.md b/doc/NPCs.md index b7c40527e44cc..b088f8904b039 100644 --- a/doc/NPCs.md +++ b/doc/NPCs.md @@ -432,6 +432,7 @@ Effect | Description `barber_hair` | Opens a menu allowing the player to choose a new hair style. `barber_beard` | Opens a menu allowing the player to choose a new beard style. `u_learn_recipe: recipe_string` | Your character will learn and memorize the recipe `recipe_string`. +`npc_first_topic: talk_topic_string` | Changes the initial talk_topic of the NPC in all future dialogues. #### Trade / Items diff --git a/src/dialogue.h b/src/dialogue.h index a317292b107e7..728a550c4028f 100644 --- a/src/dialogue.h +++ b/src/dialogue.h @@ -124,6 +124,7 @@ struct talk_effect_fun_t { void set_u_buy_monster( const std::string &monster_type_id, int cost, int count, bool pacified, const translation &name ); void set_u_learn_recipe( const std::string &learned_recipe_id ); + void set_npc_first_topic( const std::string &chat_topic ); void operator()( const dialogue &d ) const { if( !function ) { diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 1bb2ebf0d7a87..5e91cb4804ebb 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -1972,6 +1972,13 @@ void talk_effect_fun_t::set_u_learn_recipe( const std::string &learned_recipe_id }; } +void talk_effect_fun_t::set_npc_first_topic( const std::string &chat_topic ) +{ + function = [chat_topic]( const dialogue & d ) { + d.beta->set_first_topic( chat_topic ); + }; +} + void talk_effect_t::set_effect_consequence( const talk_effect_fun_t &fun, dialogue_consequence con ) { effects.push_back( fun ); @@ -2179,6 +2186,9 @@ void talk_effect_t::parse_sub_effect( const JsonObject &jo ) } else if( jo.has_string( "u_learn_recipe" ) ) { const std::string recipe_id = jo.get_string( "u_learn_recipe" ); subeffect_fun.set_u_learn_recipe( recipe_id ); + } else if( jo.has_string( "npc_first_topic" ) ) { + const std::string chat_topic = jo.get_string( "npc_first_topic" ); + subeffect_fun.set_npc_first_topic( chat_topic ); } else { jo.throw_error( "invalid sub effect syntax: " + jo.str() ); } diff --git a/src/talker.h b/src/talker.h index 16bce5b90040a..3c5196243bf7c 100644 --- a/src/talker.h +++ b/src/talker.h @@ -298,5 +298,6 @@ class talker } virtual void add_opinion( int /*trust*/, int /*fear*/, int /*value*/, int /*anger*/, int /*debt*/ ) {} + virtual void set_first_topic( const std::string & ) {} }; #endif // CATA_SRC_TALKER_H diff --git a/src/talker_npc.cpp b/src/talker_npc.cpp index 19f368fa23b55..b51d131b2077c 100644 --- a/src/talker_npc.cpp +++ b/src/talker_npc.cpp @@ -819,3 +819,8 @@ bool talker_npc::enslave_mind() talk_function::follow( *me_npc ); return not_following; } + +void talker_npc::set_first_topic( const std::string &chat_topic ) +{ + me_npc->chatbin.first_topic = chat_topic; +} diff --git a/src/talker_npc.h b/src/talker_npc.h index 6b90de18b340d..0eba9cb4bb059 100644 --- a/src/talker_npc.h +++ b/src/talker_npc.h @@ -99,6 +99,7 @@ class talker_npc : public talker_character std::string opinion_text() const override; void add_opinion( int trust, int fear, int value, int anger, int debt ) override; bool enslave_mind() override; + void set_first_topic( const std::string &chat_topic ) override; protected: npc *me_npc; diff --git a/tests/npc_talk_test.cpp b/tests/npc_talk_test.cpp index 3318b0bdf545b..1c4c36f0e26b5 100644 --- a/tests/npc_talk_test.cpp +++ b/tests/npc_talk_test.cpp @@ -969,3 +969,18 @@ TEST_CASE( "npc_talk_effects", "[npc_talk]" ) effects.apply( d ); CHECK( talker_npc.myclass == npc_class_id( "NC_NONE" ) ); } + +TEST_CASE( "npc_change_topic", "[npc_talk]" ) +{ + dialogue d; + npc &talker_npc = prep_test( d ); + + const std::string original_chat = talker_npc.chatbin.first_topic; + REQUIRE( original_chat != "TALK_TEST_SET_TOPIC" ); + d.add_topic( "TALK_TEST_SET_TOPIC" ); + gen_response_lines( d, 2 ); + talk_effect_t &effects = d.responses[1].success; + effects.apply( d ); + CHECK( talker_npc.chatbin.first_topic != original_chat ); + CHECK( talker_npc.chatbin.first_topic == "TALK_TEST_SET_TOPIC" ); +} From 1890934108f23f1503420cff17e3061356a5094e Mon Sep 17 00:00:00 2001 From: johnrdconnolly <59102789+johnrdconnolly@users.noreply.github.com> Date: Wed, 15 Jul 2020 11:21:51 -0700 Subject: [PATCH 061/151] Update deployable.json update volume, weight, and longest_side for real world values where necessary --- data/json/items/tool/deployable.json | 33 ++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/data/json/items/tool/deployable.json b/data/json/items/tool/deployable.json index 03ce1a58d9856..aabee1f3819c1 100644 --- a/data/json/items/tool/deployable.json +++ b/data/json/items/tool/deployable.json @@ -6,6 +6,7 @@ "description": "A large metal stand used to contain a fire. Fires set in a brazier will not spread to surrounding flammable objects.", "weight": "5000 g", "volume": "2500 ml", + "longest_side": "50 cm", "price": 5000, "price_postapoc": 10, "to_hit": -4, @@ -23,6 +24,8 @@ "description": "A large metal barrel used to contain a fire. It has multiple holes punched in its walls for air supply. Fires set in a fire barrel will not spread to surrounding flammable objects.", "weight": "20000 g", "volume": "200 L", + "longest_side": "100 cm", + "//": "values based on real world 55 gallon metal barrel", "price": 10000, "price_postapoc": 10, "to_hit": -5, @@ -38,8 +41,10 @@ "type": "TOOL", "name": { "str": "fire barrel (100L)", "str_pl": "fire barrels (100L)" }, "description": "A large metal barrel used to contain a fire. It has multiple holes punched in its walls for air supply. Fires set in a fire barrel will not spread to surrounding flammable objects.", - "weight": "12000 g", + "weight": "15000 g", "volume": "100 L", + "longest_side": "85 cm", + "//": "values based on real world 30 gal metal barrel", "price": 5000, "price_postapoc": 10, "to_hit": -4, @@ -55,8 +60,10 @@ "type": "TOOL", "name": { "str": "camp chair" }, "description": "Folded camp chair, deploy to sit down.", - "weight": "1000 g", - "volume": "2500 ml", + "weight": "2200 g", + "volume": "15 L", + "longest_side": "90 cm", + "//": "values based on basic real world folding camp chair", "price": 5000, "price_postapoc": 100, "to_hit": -4, @@ -72,8 +79,9 @@ "type": "TOOL", "name": { "str": "cot" }, "description": "This is a military style fold up cot. While it may not be quite as comfortable as a bed, it's better than slumming it on the ground.", - "weight": "6164 g", - "volume": "2 L", + "weight": "7500 g", + "volume": "15 L", + "longest_side": "100 cm", "price": 7500, "price_postapoc": 500, "to_hit": -1, @@ -97,6 +105,7 @@ "description": "This is a bicycle folded into a relatively portable package.", "weight": "9071 g", "volume": "21500 ml", + "//": "needs huge realism balance, current values are wildly inaccurate", "price": 35000, "price_postapoc": 2000, "to_hit": -5, @@ -130,6 +139,7 @@ "description": "Metal butchering rack designed to hang a carcass in the air. It is folded for easy transportation.", "weight": "5000 g", "volume": "10 L", + "longest_side": "60 cm", "price": 5000, "price_postapoc": 250, "to_hit": -4, @@ -149,8 +159,8 @@ "price": 350000, "price_postapoc": 4000, "material": [ "rubber" ], - "weight": "9071 g", - "volume": "21500 ml", + "weight": "1100 g", + "volume": "10000 ml", "bashing": 10, "to_hit": -5, "use_action": { @@ -168,6 +178,7 @@ "description": "A metal rack designed to smoke food for better preservation and taste. It is folded for easy transportation.", "weight": "5000 g", "volume": "25 L", + "longest_side": "90 cm", "price": 5000, "price_postapoc": 750, "to_hit": -4, @@ -182,8 +193,10 @@ "type": "TOOL", "name": { "str": "tourist table" }, "description": "Metal tourist table for off-road trips. It is folded for easy transportation.", - "weight": "6000 g", - "volume": "25 L", + "weight": "4500 g", + "volume": "15 L", + "longest_side": "90 cm", + "//": "values based on real world collapsible camping table", "price": 5000, "price_postapoc": 100, "to_hit": -3, @@ -250,6 +263,7 @@ "description": "A small water-powered mill that can convert starchy products into flour. Can be placed via the construction menu.", "weight": "120000 g", "volume": "22500 ml", + "longest_side": "150 cm", "price": 100000, "price_postapoc": 1500, "to_hit": -5, @@ -266,6 +280,7 @@ "description": "A small wind-powered mill that can convert starchy products into flour. Can be placed via the construction menu.", "weight": "120000 g", "volume": "22500 ml", + "longest_side": "150 cm", "price": 100000, "price_postapoc": 1500, "to_hit": -5, From 1b293a83590a514941ac0eaa967e30e76fc20223 Mon Sep 17 00:00:00 2001 From: Duck Date: Wed, 15 Jul 2020 18:18:36 -0500 Subject: [PATCH 062/151] Make makeshift bandage dark craftable --- data/json/items/comestibles/med.json | 2 +- data/json/recipes/other/medical.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/data/json/items/comestibles/med.json b/data/json/items/comestibles/med.json index b65fc0df3abf6..980360db621f0 100644 --- a/data/json/items/comestibles/med.json +++ b/data/json/items/comestibles/med.json @@ -207,7 +207,7 @@ "copy-from": "bandages", "description": "Simple cloth bandages. Better than nothing.", "price_postapoc": 100, - "flags": [ "NO_INGEST", "BLIND_EASY" ], + "flags": [ "NO_INGEST" ], "use_action": { "type": "heal", "bandages_power": 2, "bleed": 10, "move_cost": 300 } }, { diff --git a/data/json/recipes/other/medical.json b/data/json/recipes/other/medical.json index fae569ecd4be0..17c66fe907b1e 100644 --- a/data/json/recipes/other/medical.json +++ b/data/json/recipes/other/medical.json @@ -23,6 +23,7 @@ "time": "9 s", "autolearn": true, "charges": 1, + "flags": [ "BLIND_EASY" ], "components": [ [ [ "rag", 1 ] ] ] }, { From c884f0283eeea65f75dcc470b8af8a06d12fc2b5 Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Wed, 15 Jul 2020 14:14:14 +0300 Subject: [PATCH 063/151] Fix MSVC and Android builds --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index bcb7869dbe5d8..2bfca4a078efe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -544,7 +544,7 @@ int main( int argc, const char *argv[] ) MAP_SHARING::setDefaults(); - cli_opts cli = parse_commandline( argc, argv ); + cli_opts cli = parse_commandline( argc, const_cast( argv ) ); if( !dir_exist( PATH_INFO::datadir() ) ) { printf( "Fatal: Can't find data directory \"%s\"\nPlease ensure the current working directory is correct or specify data directory with --datadir. Perhaps you meant to start \"cataclysm-launcher\"?\n", From 6bf1df219bcedbed03dc178834d11be96896d2c8 Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Wed, 15 Jul 2020 20:07:07 -0400 Subject: [PATCH 064/151] Fix iteminfo trailing spaces Some iteminfo lines had trailing spaces. This causes clang-tidy complaints, and is just wrong. Fix the code that generates them and the corresponding test data. --- src/item.cpp | 102 +++++++++++++++++++++------------------- src/item.h | 1 + src/output.cpp | 11 ++--- tests/iteminfo_test.cpp | 26 +++++----- 4 files changed, 72 insertions(+), 68 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 9b6de1d7f0362..083b80901bc2c 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -2241,7 +2241,7 @@ void item::gun_info( const item *mod, std::vector &info, const iteminf if( parts->test( iteminfo_parts::GUN_RELOAD_TIME ) ) { info.emplace_back( "GUN", _( "Reload time: " ), has_flag( flag_RELOAD_ONE ) ? _( " moves per round" ) : - _( " moves " ), + _( " moves" ), iteminfo::lower_is_better, mod->get_reload_time() ); } @@ -2563,83 +2563,83 @@ void item::armor_info( std::vector &info, const iteminfo_query *parts, if( parts->test( iteminfo_parts::ARMOR_BODYPARTS ) ) { insert_separation_line( info ); - std::string coverage = _( "Covers: " ); + std::string coverage = _( "Covers:" ); if( covers( bodypart_id( "head" ) ) ) { - coverage += _( "The head. " ); + coverage += _( " The head." ); } if( covers( bodypart_id( "eyes" ) ) ) { - coverage += _( "The eyes. " ); + coverage += _( " The eyes." ); } if( covers( bodypart_id( "mouth" ) ) ) { - coverage += _( "The mouth. " ); + coverage += _( " The mouth." ); } if( covers( bodypart_id( "torso" ) ) ) { - coverage += _( "The torso. " ); + coverage += _( " The torso." ); } if( is_sided() && ( covers( bodypart_id( "arm_l" ) ) || covers( bodypart_id( "arm_r" ) ) ) ) { - coverage += _( "Either arm. " ); + coverage += _( " Either arm." ); } else if( covers( bodypart_id( "arm_l" ) ) && covers( bodypart_id( "arm_r" ) ) ) { - coverage += _( "The arms. " ); + coverage += _( " The arms." ); } else if( covers( bodypart_id( "arm_l" ) ) ) { - coverage += _( "The left arm. " ); + coverage += _( " The left arm." ); } else if( covers( bodypart_id( "arm_r" ) ) ) { - coverage += _( "The right arm. " ); + coverage += _( " The right arm." ); } if( is_sided() && ( covers( bodypart_id( "hand_l" ) ) || covers( bodypart_id( "hand_r" ) ) ) ) { - coverage += _( "Either hand. " ); + coverage += _( " Either hand." ); } else if( covers( bodypart_id( "hand_l" ) ) && covers( bodypart_id( "hand_r" ) ) ) { - coverage += _( "The hands. " ); + coverage += _( " The hands." ); } else if( covers( bodypart_id( "hand_l" ) ) ) { - coverage += _( "The left hand. " ); + coverage += _( " The left hand." ); } else if( covers( bodypart_id( "hand_r" ) ) ) { - coverage += _( "The right hand. " ); + coverage += _( " The right hand." ); } if( is_sided() && ( covers( bodypart_id( "leg_l" ) ) || covers( bodypart_id( "leg_r" ) ) ) ) { - coverage += _( "Either leg. " ); + coverage += _( " Either leg." ); } else if( covers( bodypart_id( "leg_l" ) ) && covers( bodypart_id( "leg_r" ) ) ) { - coverage += _( "The legs. " ); + coverage += _( " The legs." ); } else if( covers( bodypart_id( "leg_l" ) ) ) { - coverage += _( "The left leg. " ); + coverage += _( " The left leg." ); } else if( covers( bodypart_id( "leg_r" ) ) ) { - coverage += _( "The right leg. " ); + coverage += _( " The right leg." ); } if( is_sided() && ( covers( bodypart_id( "foot_l" ) ) || covers( bodypart_id( "foot_r" ) ) ) ) { - coverage += _( "Either foot. " ); + coverage += _( " Either foot." ); } else if( covers( bodypart_id( "foot_l" ) ) && covers( bodypart_id( "foot_r" ) ) ) { - coverage += _( "The feet. " ); + coverage += _( " The feet." ); } else if( covers( bodypart_id( "foot_l" ) ) ) { - coverage += _( "The left foot. " ); + coverage += _( " The left foot." ); } else if( covers( bodypart_id( "foot_r" ) ) ) { - coverage += _( "The right foot. " ); + coverage += _( " The right foot." ); } if( !covers_anything ) { - coverage += _( "Nothing." ); + coverage += _( " Nothing." ); } info.push_back( iteminfo( "ARMOR", coverage ) ); } if( parts->test( iteminfo_parts::ARMOR_LAYER ) && covers_anything ) { - std::string layering = _( "Layer: " ); + std::string layering = _( "Layer:" ); if( has_flag( flag_PERSONAL ) ) { - layering += _( "Personal aura. " ); + layering += _( " Personal aura." ); } else if( has_flag( flag_SKINTIGHT ) ) { - layering += _( "Close to skin. " ); + layering += _( " Close to skin." ); } else if( has_flag( flag_BELTED ) ) { - layering += _( "Strapped. " ); + layering += _( " Strapped." ); } else if( has_flag( flag_OUTER ) ) { - layering += _( "Outer. " ); + layering += _( " Outer." ); } else if( has_flag( flag_WAIST ) ) { - layering += _( "Waist. " ); + layering += _( " Waist." ); } else if( has_flag( flag_AURA ) ) { - layering += _( "Outer aura. " ); + layering += _( " Outer aura." ); } else { - layering += _( "Normal. " ); + layering += _( " Normal." ); } info.push_back( iteminfo( "ARMOR", layering ) ); @@ -3396,58 +3396,59 @@ void item::bionic_info( std::vector &info, const iteminfo_query *parts insert_separation_line( info ); if( !bid->encumbrance.empty() ) { - info.push_back( iteminfo( "DESCRIPTION", _( "Encumbrance: " ), + info.push_back( iteminfo( "DESCRIPTION", _( "Encumbrance:" ), iteminfo::no_newline ) ); for( const std::pair &element : bid->encumbrance ) { - info.push_back( iteminfo( "CBM", body_part_name_as_heading( element.first.id(), 1 ), - " ", iteminfo::no_newline, element.second ) ); + info.push_back( + iteminfo( "CBM", " " + body_part_name_as_heading( element.first.id(), 1 ), + " ", iteminfo::no_newline, element.second ) ); } } if( !bid->env_protec.empty() ) { info.push_back( iteminfo( "DESCRIPTION", - _( "Environmental Protection: " ), + _( "Environmental Protection:" ), iteminfo::no_newline ) ); for( const std::pair< const bodypart_str_id, size_t > &element : bid->env_protec ) { - info.push_back( iteminfo( "CBM", body_part_name_as_heading( element.first, 1 ), - " ", iteminfo::no_newline, element.second ) ); + info.push_back( iteminfo( "CBM", " " + body_part_name_as_heading( element.first, 1 ), + " ", iteminfo::no_newline, element.second ) ); } } if( !bid->bash_protec.empty() ) { info.push_back( iteminfo( "DESCRIPTION", - _( "Bash Protection: " ), + _( "Bash Protection:" ), iteminfo::no_newline ) ); for( const std::pair< const bodypart_str_id, size_t > &element : bid->bash_protec ) { - info.push_back( iteminfo( "CBM", body_part_name_as_heading( element.first, 1 ), - " ", iteminfo::no_newline, element.second ) ); + info.push_back( iteminfo( "CBM", " " + body_part_name_as_heading( element.first, 1 ), + " ", iteminfo::no_newline, element.second ) ); } } if( !bid->cut_protec.empty() ) { info.push_back( iteminfo( "DESCRIPTION", - _( "Cut Protection: " ), + _( "Cut Protection:" ), iteminfo::no_newline ) ); for( const std::pair< const bodypart_str_id, size_t > &element : bid->cut_protec ) { - info.push_back( iteminfo( "CBM", body_part_name_as_heading( element.first, 1 ), - " ", iteminfo::no_newline, element.second ) ); + info.push_back( iteminfo( "CBM", " " + body_part_name_as_heading( element.first, 1 ), + " ", iteminfo::no_newline, element.second ) ); } } if( !bid->bullet_protec.empty() ) { - info.push_back( iteminfo( "DESCRIPTION", _( "Ballistic Protection: " ), + info.push_back( iteminfo( "DESCRIPTION", _( "Ballistic Protection:" ), iteminfo::no_newline ) ); for( const std::pair &element : bid->bullet_protec ) { - info.push_back( iteminfo( "CBM", body_part_name_as_heading( element.first, 1 ), - " ", iteminfo::no_newline, element.second ) ); + info.push_back( iteminfo( "CBM", " " + body_part_name_as_heading( element.first, 1 ), + " ", iteminfo::no_newline, element.second ) ); } } if( !bid->stat_bonus.empty() ) { - info.push_back( iteminfo( "DESCRIPTION", _( "Stat Bonus: " ), + info.push_back( iteminfo( "DESCRIPTION", _( "Stat Bonus:" ), iteminfo::no_newline ) ); for( const auto &element : bid->stat_bonus ) { - info.push_back( iteminfo( "CBM", get_stat_name( element.first ), " ", + info.push_back( iteminfo( "CBM", " " + get_stat_name( element.first ), " ", iteminfo::no_newline, element.second ) ); } } @@ -8668,6 +8669,11 @@ iteminfo::iteminfo( const std::string &Type, const std::string &Name, const std: bDrawName = !( Flags & no_name ); } +iteminfo::iteminfo( const std::string &Type, const std::string &Name, flags Flags ) + : iteminfo( Type, Name, "", Flags ) +{ +} + iteminfo::iteminfo( const std::string &Type, const std::string &Name, double Value ) : iteminfo( Type, Name, "", no_flags, Value ) { diff --git a/src/item.h b/src/item.h index c5aed88575924..9b3b10b67982f 100644 --- a/src/item.h +++ b/src/item.h @@ -153,6 +153,7 @@ struct iteminfo { */ iteminfo( const std::string &Type, const std::string &Name, const std::string &Fmt = "", flags Flags = no_flags, double Value = -999 ); + iteminfo( const std::string &Type, const std::string &Name, flags Flags ); iteminfo( const std::string &Type, const std::string &Name, double Value ); }; diff --git a/src/output.cpp b/src/output.cpp index 63ffcdf4e7381..6e55bb6e0f2d6 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -879,9 +879,6 @@ std::string format_item_info( const std::vector &vItemDisplay, if( i.bDrawName ) { buffer += i.sName; } - // Always end with a linebreak for sType == "DESCRIPTION" - buffer += "\n"; - bIsNewLine = true; } else { if( i.bDrawName ) { buffer += i.sName; @@ -927,11 +924,11 @@ std::string format_item_info( const std::vector &vItemDisplay, buffer += colorize( i.sValue, thisColor ); } buffer += sPost; + } - // Set bIsNewLine in case the next line should always start in a new line - if( ( bIsNewLine = i.bNewLine ) ) { - buffer += "\n"; - } + // Set bIsNewLine in case the next line should always start in a new line + if( ( bIsNewLine = i.bNewLine ) ) { + buffer += "\n"; } } diff --git a/tests/iteminfo_test.cpp b/tests/iteminfo_test.cpp index 013a4cfb0777f..4afb7ee8acfba 100644 --- a/tests/iteminfo_test.cpp +++ b/tests/iteminfo_test.cpp @@ -667,11 +667,11 @@ TEST_CASE( "armor coverage, warmth, and encumbrance", "[iteminfo][armor][coverag "--\n" "Covers:" " The torso." - " The arms. \n" ); // NOLINT(cata-text-style) + " The arms.\n" ); CHECK( item_info_str( longshirt, { iteminfo_parts::ARMOR_LAYER } ) == "--\n" - "Layer: Normal. \n" ); // NOLINT(cata-text-style) + "Layer: Normal.\n" ); // Coverage and warmth are displayed together on a single line std::vector cov_warm_shirt = { iteminfo_parts::ARMOR_COVERAGE, iteminfo_parts::ARMOR_WARMTH }; @@ -739,11 +739,11 @@ TEST_CASE( "armor coverage, warmth, and encumbrance", "[iteminfo][armor][coverag "Covers:" " The torso." " The arms." - " The legs. \n" ); + " The legs.\n" ); CHECK( item_info_str( swat_armor, { iteminfo_parts::ARMOR_LAYER } ) == "--\n" - "Layer: Normal. \n" ); + "Layer: Normal.\n" ); std::vector cov_warm_swat = { iteminfo_parts::ARMOR_COVERAGE, iteminfo_parts::ARMOR_WARMTH }; REQUIRE( swat_armor.get_avg_coverage() == 95 ); @@ -828,11 +828,11 @@ TEST_CASE( "armor coverage, warmth, and encumbrance", "[iteminfo][armor][coverag CHECK( item_info_str( faux_fur_pants, { iteminfo_parts::ARMOR_BODYPARTS } ) == "--\n" "Covers:" - " The legs. \n" ); + " The legs.\n" ); CHECK( item_info_str( faux_fur_pants, { iteminfo_parts::ARMOR_LAYER } ) == "--\n" - "Layer: Normal. \n" ); + "Layer: Normal.\n" ); std::vector cov_warm_pants = { iteminfo_parts::ARMOR_COVERAGE, iteminfo_parts::ARMOR_WARMTH }; REQUIRE( faux_fur_pants.get_avg_coverage() == 95 ); @@ -902,11 +902,11 @@ TEST_CASE( "armor coverage, warmth, and encumbrance", "[iteminfo][armor][coverag " The head." " The torso." " The arms." - " The legs. \n" ); + " The legs.\n" ); CHECK( item_info_str( faux_fur_suit, { iteminfo_parts::ARMOR_LAYER } ) == "--\n" - "Layer: Normal. \n" ); + "Layer: Normal.\n" ); std::vector cov_warm_suit = { iteminfo_parts::ARMOR_COVERAGE, iteminfo_parts::ARMOR_WARMTH }; REQUIRE( faux_fur_suit.get_avg_coverage() == 75 ); @@ -1439,7 +1439,7 @@ TEST_CASE( "gun or other ranged weapon attributes", "[iteminfo][weapon][gun]" ) SECTION( "time to reload weapon" ) { CHECK( item_info_str( compbow, { iteminfo_parts::GUN_RELOAD_TIME } ) == "--\n" - "Reload time: 110 moves \n" ); // NOLINT(cata-text-style) + "Reload time: 110 moves\n" ); } SECTION( "weapon firing modes" ) { @@ -2171,13 +2171,13 @@ TEST_CASE( "bionic info", "[iteminfo][bionic]" ) // NOTE: Funky trailing space CHECK( item_info_str( nostril, {} ) == "--\n" - "Encumbrance: \n" // NOLINT(cata-text-style) - "Mouth 10 " ); + "Encumbrance: " + "Mouth 10" ); CHECK( item_info_str( purifier, {} ) == "--\n" - "Environmental Protection: \n" // NOLINT(cata-text-style) - "Mouth 7 " ); + "Environmental Protection: " + "Mouth 7" ); } // Functions: From 080f9fd0a8c6cead390a30f4fb022ba3efbfbbae Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Wed, 15 Jul 2020 14:42:52 -0400 Subject: [PATCH 065/151] Small clang-tidy fix --- src/item.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/item.cpp b/src/item.cpp index 083b80901bc2c..36f2e66687184 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -2718,7 +2718,7 @@ void item::armor_info( std::vector &info, const iteminfo_query *parts, // Handle things that use both sides to avoid showing L. Arm R. Arm etc when both are the same if( !t->sided ) { for( const body_part &legacy_part : all_body_parts ) { - bodypart_str_id bp( convert_bp( legacy_part ) ); + const bodypart_str_id &bp( convert_bp( legacy_part ) ); bodypart_str_id opposite = bp->opposite_part; if( opposite != bp && covers( bp ) && covers( opposite ) && to_display_data.at( bp ).portion == to_display_data.at( opposite ).portion From 11b1759306f61852392ca2ac1a54320130cd57e8 Mon Sep 17 00:00:00 2001 From: Hirmuolio Date: Thu, 16 Jul 2020 09:03:12 +0300 Subject: [PATCH 066/151] Combine last_rot_check into last_temp_check (#42100) --- src/item.cpp | 75 ++++++++++++++------------------------ src/item.h | 18 ++++----- src/item_pocket.cpp | 7 ++-- src/savegame_json.cpp | 1 - tests/temperature_test.cpp | 3 +- 5 files changed, 40 insertions(+), 64 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index a5ae412f1ba71..f103ea377811c 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -397,7 +397,6 @@ item::item( const itype *type, time_point turn, int qty ) : type( type ), bday( } else if( has_temperature() || goes_bad() ) { active = true; last_temp_check = bday; - last_rot_check = bday; } else if( type->tool ) { if( ammo_remaining() && !ammo_types().empty() ) { @@ -466,7 +465,6 @@ item::item( const recipe *rec, int qty, std::list items, std::vector &info, const iteminfo_query *parts, info.push_back( iteminfo( "BASE", space + _( "max rot (turns): " ), "", iteminfo::lower_is_better, to_turns( food->get_shelf_life() ) ) ); - info.push_back( iteminfo( "BASE", _( "last rot: " ), - "", iteminfo::lower_is_better, - to_turn( food->last_rot_check ) ) ); } if( food && food->has_temperature() ) { info.push_back( iteminfo( "BASE", _( "last temp: " ), @@ -5468,11 +5463,11 @@ void item::set_relative_rot( double val ) { if( goes_bad() ) { rot = get_shelf_life() * val; - // calc_rot uses last_rot_check (when it's not turn_zero) instead of bday. + // calc_rot uses last_temp_check (when it's not turn_zero) instead of bday. // this makes sure the rotting starts from now, not from bday. // if this item is the result of smoking or milling don't do this, we want to start from bday. if( !has_flag( flag_PROCESSING_RESULT ) ) { - last_rot_check = calendar::turn; + last_temp_check = calendar::turn; } } } @@ -5566,19 +5561,18 @@ int get_hourly_rotpoints_at_temp( const int temp ) return rot_chart[temp]; } -void item::calc_rot( time_point time, int temp, const float spoil_modifier ) +void item::calc_rot( int temp, const float spoil_modifier, + const time_duration &time_delta ) { // Avoid needlessly calculating already rotten things. Corpses should // always rot away and food rots away at twice the shelf life. If the food // is in a sealed container they won't rot away, this avoids needlessly // calculating their rot in that case. if( !is_corpse() && get_relative_rot() > 2.0 ) { - last_rot_check = time; return; } if( item_tags.count( "FROZEN" ) ) { - last_rot_check = time; return; } @@ -5599,14 +5593,12 @@ void item::calc_rot( time_point time, int temp, const float spoil_modifier ) // conditions by applying starting variation bonus/penalty of +/- 20% of base shelf-life // positive = food was produced some time before calendar::start and/or bad storage // negative = food was stored in good conditions before calendar::start - if( last_rot_check <= calendar::start_of_cataclysm ) { + if( last_temp_check <= calendar::start_of_cataclysm ) { time_duration spoil_variation = get_shelf_life() * 0.2f; rot += rng( -spoil_variation, spoil_variation ); } - time_duration time_delta = time - last_rot_check; rot += factor * time_delta / 1_hours * get_hourly_rotpoints_at_temp( temp ) * 1_turns; - last_rot_check = time; } void item::calc_rot_while_processing( time_duration processing_duration ) @@ -5617,7 +5609,6 @@ void item::calc_rot_while_processing( time_duration processing_duration ) } // Apply no rot or temperature while smoking - last_rot_check += processing_duration; last_temp_check += processing_duration; } @@ -8900,11 +8891,9 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, const time_point now = calendar::turn; // if player debug menu'd the time backward it breaks stuff, just reset the - // last_temp_check and last_rot_check in this case - // if spoil_modifier is 0 then similarly it will not rot - if( now - last_temp_check < 0_turns || spoil_modifier == 0.0f ) { + // last_temp_check in this case + if( now - last_temp_check < 0_turns ) { reset_temp_check(); - last_rot_check = now; return false; } @@ -8944,15 +8933,9 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, temp += 5; } - time_point time; + time_point time = last_temp_check; item_internal::scoped_goes_bad_cache _cache( this ); - const bool process_rot = goes_bad(); - - if( process_rot ) { - time = std::min( last_rot_check, last_temp_check ); - } else { - time = last_temp_check; - } + const bool process_rot = goes_bad() && spoil_modifier != 0; if( now - time > 1_hours ) { // This code is for items that were left out of reality bubble for long time @@ -8974,13 +8957,14 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, local_mod += 5; // body heat increases inventory temperature } - // Process the past of this item since the last time it was processed + // Process the past of this item in 1h chunks until there is less than 1h left. + time_duration time_delta = 1_hours; + while( now - time > 1_hours ) { - // Get the environment temperature - time_duration time_delta = std::min( 1_hours, now - 1_hours - time ); time += time_delta; - //Use weather if above ground, use map temp if below + // Get the environment temperature + // Use weather if above ground, use map temp if below double env_temperature = 0; if( pos.z >= 0 && flag != temperature_flag::ROOT_CELLAR ) { double weather_temperature = wgen.get_weather_temperature( pos, time, seed ); @@ -9014,14 +8998,14 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, if( now - time > 2_days ) { // This value shouldn't be there anymore after the loop is done so we don't bother with the set_item_temperature() temperature = static_cast( 100000 * temp_to_kelvin( env_temperature ) ); - last_temp_check = time; - } else if( time - last_temp_check > smallest_interval ) { - calc_temp( env_temperature, insulation, time ); + } else { + calc_temp( env_temperature, insulation, time_delta ); } + last_temp_check = time; // Calculate item rot - if( process_rot && time - last_rot_check > smallest_interval ) { - calc_rot( time, env_temperature, spoil_modifier ); + if( process_rot ) { + calc_rot( env_temperature, spoil_modifier, time_delta ); if( has_rotten_away() && carrier == nullptr ) { // No need to track item that will be gone @@ -9034,9 +9018,10 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, // Remaining <1 h from above // and items that are held near the player if( now - time > smallest_interval ) { - calc_temp( temp, insulation, now ); + calc_temp( temp, insulation, now - time ); + last_temp_check = now; if( process_rot ) { - calc_rot( now, temp, spoil_modifier ); + calc_rot( temp, spoil_modifier, now - time ); return has_rotten_away() && carrier == nullptr; } } @@ -9048,7 +9033,7 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, return false; } -void item::calc_temp( const int temp, const float insulation, const time_point &time ) +void item::calc_temp( const int temp, const float insulation, const time_duration &time_delta ) { // Limit calculations to max 4000 C (4273.15 K) to avoid specific energy from overflowing const float env_temperature = std::min( temp_to_kelvin( temp ), 4273.15 ); @@ -9057,7 +9042,6 @@ void item::calc_temp( const int temp, const float insulation, const time_point & // If no or only small temperature difference then no need to do math. if( std::abs( temperature_difference ) < 0.9 ) { - last_temp_check = time; return; } const float mass = to_gram( weight() ); // g @@ -9065,7 +9049,6 @@ void item::calc_temp( const int temp, const float insulation, const time_point & // If item has negative energy set to environment temperature (it not been processed ever) if( specific_energy < 0 ) { set_item_temperature( env_temperature ); - last_temp_check = time; return; } @@ -9086,7 +9069,6 @@ void item::calc_temp( const int temp, const float insulation, const time_point & float new_item_temperature; float freeze_percentage = 0; int extra_time; - const time_duration time_delta = time - last_temp_check; // Temperature calculations based on Newton's law of cooling. // Calculations are done assuming that the item stays in its phase. @@ -9115,7 +9097,6 @@ void item::calc_temp( const int temp, const float insulation, const time_point & // This may happen rarely with very small items // Just set the item to environment temperature set_item_temperature( env_temperature ); - last_temp_check = time; return; } } @@ -9144,7 +9125,6 @@ void item::calc_temp( const int temp, const float insulation, const time_point & // This may happen rarely with very small items // Just set the item to environment temperature set_item_temperature( env_temperature ); - last_temp_check = time; return; } } @@ -9226,7 +9206,6 @@ void item::calc_temp( const int temp, const float insulation, const time_point & temperature = std::lround( 100000 * new_item_temperature ); specific_energy = std::lround( 100000 * new_specific_energy ); - last_temp_check = time; } float item::get_item_thermal_energy() const @@ -9726,9 +9705,9 @@ bool item::process( player *carrier, const tripoint &pos, float insulation, return process_internal( carrier, pos, insulation, flag, spoil_multiplier_parent ); } -void item::set_last_rot_check( const time_point &pt ) +void item::set_last_temp_check( const time_point &pt ) { - last_rot_check = pt; + last_temp_check = pt; } bool item::process_internal( player *carrier, const tripoint &pos, @@ -10126,8 +10105,8 @@ void item::legacy_fast_forward_time() rot *= 6; - const time_duration tmp_rot = ( last_rot_check - calendar::turn_zero ) * 6; - last_rot_check = calendar::turn_zero + tmp_rot; + const time_duration tmp_temp = ( last_temp_check - calendar::turn_zero ) * 6; + last_temp_check = calendar::turn_zero + tmp_temp; } time_point item::birthday() const diff --git a/src/item.h b/src/item.h index 9b3b10b67982f..8f79dc1aa5630 100644 --- a/src/item.h +++ b/src/item.h @@ -804,7 +804,7 @@ class item : public visitable * @param time Time point to which rot is calculated * @param temp Temperature at which the rot is calculated */ - void calc_rot( time_point time, int temp, float spoil_modifier ); + void calc_rot( int temp, float spoil_modifier, const time_duration &time_delta ); /** * This is part of a workaround so that items don't rot away to nothing if the smoking rack @@ -826,16 +826,16 @@ class item : public visitable bool process_temperature_rot( float insulation, const tripoint &pos, player *carrier, temperature_flag flag = temperature_flag::NORMAL, float spoil_modifier = 1.0f ); - /** Set the item to HOT */ + /** Set the item to HOT and resets last_temp_check */ void heat_up(); - /** Set the item to COLD */ + /** Set the item to COLD and resets last_temp_check*/ void cold_up(); - /** Sets the item temperature and item energy from new temperature (K)*/ + /** Sets the item temperature and item energy from new temperature (K) and resets last_temp_check */ void set_item_temperature( float new_temperature ); - /** Sets the item to new temperature and energy based new specific energy (J/g)*/ + /** Sets the item to new temperature and energy based new specific energy (J/g) and resets last_temp_check*/ void set_item_specific_energy( float specific_energy ); /** reset the last_temp_check used when crafting new items and the like */ @@ -1220,7 +1220,7 @@ class item : public visitable item *get_food(); const item *get_food() const; - void set_last_rot_check( const time_point &pt ); + void set_last_temp_check( const time_point &pt ); /** What faults can potentially occur with this item? */ std::set faults_potential() const; @@ -2153,9 +2153,9 @@ class item : public visitable * Calculate the thermal energy and temperature change of the item * @param temp Temperature of surroundings * @param insulation Amount of insulation item has - * @param time time point which the item is processed to + * @param time_delta time duration from previous temperature calculation */ - void calc_temp( int temp, float insulation, const time_point &time ); + void calc_temp( int temp, float insulation, const time_duration &time_delta ); /** * Get the thermal energy of the item in Joules. @@ -2268,8 +2268,6 @@ class item : public visitable * the item is rotten. */ time_duration rot = 0_turns; - /** Time when the rot calculation was last performed. */ - time_point last_rot_check = calendar::turn_zero; /** the last time the temperature was updated for this item */ time_point last_temp_check = calendar::turn_zero; /// The time the item was created. diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index 40ff5bbc0ea62..18817b04c191c 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -665,13 +665,12 @@ bool item_pocket::process( const itype &type, player *carrier, const tripoint &p float insulation, const temperature_flag flag ) { bool processed = false; + float spoil_multiplier = 1; for( auto it = contents.begin(); it != contents.end(); ) { if( _sealed ) { - // Simulate that the item has already "rotten" up to last_rot_check, but as item::rot - // is not changed, the item is still fresh. - it->set_last_rot_check( calendar::turn ); + spoil_multiplier = 0; } - if( it->process( carrier, pos, type.insulation_factor * insulation, flag ) ) { + if( it->process( carrier, pos, type.insulation_factor * insulation, flag, spoil_multiplier ) ) { it = contents.erase( it ); processed = true; } else { diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 199c386a60b45..ec691a1e406d8 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -2283,7 +2283,6 @@ void item::io( Archive &archive ) archive.io( "is_favorite", is_favorite, false ); archive.io( "item_counter", item_counter, static_cast( 0 ) ); archive.io( "rot", rot, 0_turns ); - archive.io( "last_rot_check", last_rot_check, calendar::start_of_cataclysm ); archive.io( "last_temp_check", last_temp_check, calendar::start_of_cataclysm ); archive.io( "current_phase", cur_phase, static_cast( type->phase ) ); archive.io( "techniques", techniques, io::empty_default_tag() ); diff --git a/tests/temperature_test.cpp b/tests/temperature_test.cpp index b3a533b8e74db..b2e382ac489dc 100644 --- a/tests/temperature_test.cpp +++ b/tests/temperature_test.cpp @@ -54,7 +54,7 @@ TEST_CASE( "Rate of temperature change" ) // Don't bother with times shorter than this // Note: If process interval is longer than 1 hour the calculations will be done using the environment temperature - // Processing intervals should be kept below 1 hour to avoid this. + // IMPORTANT: Processing intervals should be kept below 1 hour to avoid this. // Sections: // Water bottle (realisticity check) @@ -128,6 +128,7 @@ TEST_CASE( "Rate of temperature change" ) calendar::turn = to_turn( calendar::turn + 15_minutes ); meat1.process_temperature_rot( 1, tripoint_zero, nullptr ); + meat2.process_temperature_rot( 1, tripoint_zero, nullptr ); // 33.5 C CHECK( is_nearly( meat1.temperature, 30673432 ) ); From b66068ac0cfaee189527e9b3ea372ab9fbd8c8cd Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Thu, 16 Jul 2020 07:14:07 +0100 Subject: [PATCH 067/151] Add a few more functions for coord_point (#42141) Things we want to be able to call on these new point types: * square_dist * trig_dist * rl_dist * manhattan_dist * direction_from * line_to * midpoint And tests for all the above. --- src/coordinates.h | 59 +++++++++++++++++++++++++++++++++++++++ src/point.h | 3 ++ tests/coordinate_test.cpp | 33 ++++++++++++++++++++++ tests/line_test.cpp | 25 ++++++++++++++++- 4 files changed, 119 insertions(+), 1 deletion(-) diff --git a/src/coordinates.h b/src/coordinates.h index b4abca602e448..9e2daaae88649 100644 --- a/src/coordinates.h +++ b/src/coordinates.h @@ -10,6 +10,8 @@ #include "point.h" #include "debug.h" +enum class direction : unsigned; + namespace coords { @@ -463,6 +465,63 @@ using coords::project_to; using coords::project_remain; using coords::project_combine; +template +inline int square_dist( const coords::coord_point &loc1, + const coords::coord_point &loc2 ) +{ + return square_dist( loc1.raw(), loc2.raw() ); +} + +template +inline int trig_dist( const coords::coord_point &loc1, + const coords::coord_point &loc2 ) +{ + return trig_dist( loc1.raw(), loc2.raw() ); +} + +template +inline int rl_dist( const coords::coord_point &loc1, + const coords::coord_point &loc2 ) +{ + return rl_dist( loc1.raw(), loc2.raw() ); +} + +template +inline int manhattan_dist( const coords::coord_point &loc1, + const coords::coord_point &loc2 ) +{ + return manhattan_dist( loc1.raw(), loc2.raw() ); +} + +template +direction direction_from( const coords::coord_point &loc1, + const coords::coord_point &loc2 ) +{ + return direction_from( loc1.raw(), loc2.raw() ); +} + +template +std::vector> + line_to( const coords::coord_point &loc1, + const coords::coord_point &loc2 ) +{ + std::vector raw_result = line_to( loc1.raw(), loc2.raw() ); + std::vector> result; + std::transform( raw_result.begin(), raw_result.end(), std::back_inserter( result ), + []( const Point & p ) { + return coords::coord_point( p ); + } ); + return result; +} + +template +coords::coord_point +midpoint( const coords::coord_point &loc1, + const coords::coord_point &loc2 ) +{ + return coords::coord_point( ( loc1.raw() + loc2.raw() ) / 2 ); +} + template std::vector> closest_points_first( const coords::coord_point &loc, diff --git a/src/point.h b/src/point.h index 32248ad071ed1..2dcd7a3eebd20 100644 --- a/src/point.h +++ b/src/point.h @@ -184,6 +184,9 @@ struct tripoint { z *= rhs; return *this; } + constexpr tripoint operator/( const int rhs ) const { + return tripoint( x / rhs, y / rhs, z / rhs ); + } /*** some point operators and functions ***/ constexpr tripoint operator+( const point &rhs ) const { return tripoint( x + rhs.x, y + rhs.y, z ); diff --git a/tests/coordinate_test.cpp b/tests/coordinate_test.cpp index f410010cfb00f..262c36b57a548 100644 --- a/tests/coordinate_test.cpp +++ b/tests/coordinate_test.cpp @@ -347,3 +347,36 @@ TEST_CASE( "combine_is_opposite_of_remain", "[point][coords]" ) CHECK( recombined == orig ); } } + +TEST_CASE( "coord_point_distances", "[point][coords]" ) +{ + point_abs_omt p0; + point_abs_omt p1( 10, 10 ); + tripoint_abs_omt t0; + tripoint_abs_omt t1( 10, 10, 10 ); + + SECTION( "square" ) { + CHECK( square_dist( p0, p1 ) == 10 ); + CHECK( square_dist( t0, t1 ) == 10 ); + } + + SECTION( "trig" ) { + CHECK( trig_dist( p0, p1 ) == 14 ); // int(10*sqrt(2)) + CHECK( trig_dist( t0, t1 ) == 17 ); // int(10*sqrt(3)) + } + + SECTION( "manhattan" ) { + CHECK( manhattan_dist( p0, p1 ) == 20 ); + } +} + +TEST_CASE( "coord_point_midpoint", "[point][coords]" ) +{ + point_abs_omt p0( 2, 2 ); + point_abs_omt p1( 8, 17 ); + tripoint_abs_omt t0( 2, 2, 2 ); + tripoint_abs_omt t1( 8, 17, 5 ); + + CHECK( midpoint( p0, p1 ) == point_abs_omt( 5, 9 ) ); + CHECK( midpoint( t0, t1 ) == tripoint_abs_omt( 5, 9, 3 ) ); +} diff --git a/tests/line_test.cpp b/tests/line_test.cpp index 1ef623d27d0f6..6e07b2892f9a0 100644 --- a/tests/line_test.cpp +++ b/tests/line_test.cpp @@ -6,7 +6,9 @@ #include #include +#include "cata_generators.h" #include "catch/catch.hpp" +#include "coordinates.h" #include "line.h" #include "point.h" #include "rng.h" @@ -286,13 +288,16 @@ TEST_CASE( "Test bounds for mapping x/y/z/ offsets to direction enum", "[line]" REQUIRE( make_xyz( tripoint( 60, 30, -1 ) ) == direction::BELOWSOUTHEAST ); } -TEST_CASE( "direction_from", "[line]" ) +TEST_CASE( "direction_from", "[point][line][coords]" ) { for( int x = -2; x <= 2; ++x ) { for( int y = -2; y <= 2; ++y ) { for( int z = -2; z <= 2; ++z ) { tripoint p( x, y, z ); + tripoint_abs_omt c( p ); CHECK( direction_from( tripoint_zero, p ) == direction_from( p ) ); + CHECK( direction_from( tripoint_zero, p ) == + direction_from( tripoint_abs_omt(), c ) ); CHECK( direction_from( p ) == make_xyz( p ) ); } } @@ -439,3 +444,21 @@ TEST_CASE( "line_to_performance", "[.]" ) { line_to_comparison( 10000 ); } + +TEST_CASE( "coord_point_line_to_consistency", "[point][coords][line]" ) +{ + point p0 = GENERATE( take( 5, random_points() ) ); + point p1 = GENERATE( take( 5, random_points() ) ); + CAPTURE( p0, p1 ); + point_abs_ms cp0( p0 ); + point_abs_ms cp1( p1 ); + + std::vector raw_line = line_to( p0, p1 ); + std::vector coord_line = line_to( cp0, cp1 ); + + REQUIRE( raw_line.size() == coord_line.size() ); + for( size_t i = 0; i < raw_line.size(); ++i ) { + CAPTURE( i ); + CHECK( raw_line[i] == coord_line[i].raw() ); + } +} From 49da4c1f80b96cbf2aeaa017ecc1dfbf689a50b0 Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Wed, 15 Jul 2020 14:01:04 +0300 Subject: [PATCH 068/151] Display missing and obsolete mods for current world --- src/worldfactory.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/worldfactory.cpp b/src/worldfactory.cpp index a9b5d99c3cb9c..607a4e0049cae 100644 --- a/src/worldfactory.cpp +++ b/src/worldfactory.cpp @@ -653,7 +653,10 @@ void worldfactory::draw_mod_list( const catacurses::window &w, int &start, size_ mSortCategory[0] = sLastCategoryName; for( size_t i = 0; i < mods.size(); ++i ) { - const std::string category_name = _( mods[i]->category.second ); + std::string category_name = _( "MISSING MODS" ); + if( mods[i].is_valid() ) { + category_name = mods[i]->obsolete ? _( "OBSOLETE MODS" ) : _( mods[i]->category.second ); + } if( sLastCategoryName != category_name ) { sLastCategoryName = category_name; mSortCategory[ i + iCatSortNum++ ] = sLastCategoryName; @@ -703,8 +706,21 @@ void worldfactory::draw_mod_list( const catacurses::window &w, int &start, size_ } } - const MOD_INFORMATION &mod = **iter; - trim_and_print( w, point( 4, iNum - start ), wwidth, c_white, mod.name() ); + const mod_id &mod_entry_id = *iter; + std::string mod_entry_name = string_format( _( " [%s]" ), mod_entry_id.str() ); + nc_color mod_entry_color = c_white; + if( mod_entry_id.is_valid() ) { + const MOD_INFORMATION &mod = *mod_entry_id; + mod_entry_name = mod.name() + mod_entry_name; + if( mod.obsolete ) { + mod_entry_color = c_dark_gray; + } + } else { + mod_entry_color = c_light_red; + mod_entry_name = _( "N/A" ) + mod_entry_name; + + } + trim_and_print( w, point( 4, iNum - start ), wwidth, mod_entry_color, mod_entry_name ); if( w_shift ) { // get shift information for the active item From a37b93e8c7d06ca0ad26e7c8e205132e4d235a20 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Thu, 16 Jul 2020 06:36:12 +0000 Subject: [PATCH 069/151] Global reference migration part 29 --- src/activity_handlers.cpp | 38 ++++++++------ src/crafting_gui.cpp | 38 +++++++------- src/game_inventory.cpp | 40 ++++++++------- src/item.cpp | 2 +- src/item.h | 2 +- src/weather.cpp | 90 ++++++++++++++++---------------- tests/reload_magazine_test.cpp | 93 ++++++++++++++++++---------------- 7 files changed, 163 insertions(+), 140 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 9801c0c2deb54..da62c7bba360c 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -705,7 +705,7 @@ static void set_up_butchery( player_activity &act, player &u, butcher_type actio _( "You try to look away, but this gruesome image will stay on your mind for some time." ) ); break; } - g->u.add_morale( MORALE_BUTCHER, -50, 0, 2_days, 3_hours ); + get_player_character().add_morale( MORALE_BUTCHER, -50, 0, 2_days, 3_hours ); } else { u.add_msg_if_player( m_good, _( "It needs a coffin, not a knife." ) ); act.targets.pop_back(); @@ -788,7 +788,7 @@ int butcher_time_to_cut( const player &u, const item &corpse_item, const butcher if( corpse_item.has_flag( flag_QUARTERED ) ) { time_to_cut /= 4; } - time_to_cut = time_to_cut * ( 1 - ( g->u.get_num_crafting_helpers( 3 ) / 10 ) ); + time_to_cut = time_to_cut * ( 1 - ( get_player_character().get_num_crafting_helpers( 3 ) / 10 ) ); return time_to_cut; } @@ -1887,7 +1887,7 @@ void activity_handlers::pickaxe_finish( player_activity *act, player *p ) // Invalidate the activity early to prevent a query from mod_pain() act->set_to_null(); if( p->is_avatar() ) { - const int helpersize = g->u.get_num_crafting_helpers( 3 ); + const int helpersize = get_player_character().get_num_crafting_helpers( 3 ); if( here.is_bashable( pos ) && here.has_flag( flag_SUPPORTS_ROOF, pos ) && here.ter( pos ) != t_tree ) { // Tunneling through solid rock is hungry, sweaty, tiring, backbreaking work @@ -2155,7 +2155,7 @@ static bool magic_train( player_activity *act, player *p ) } const spell_id &sp_id = spell_id( act->name ); if( sp_id.is_valid() ) { - const bool knows = g->u.magic.knows_spell( sp_id ); + const bool knows = get_player_character().magic.knows_spell( sp_id ); if( knows ) { spell &studying = p->magic.get_spell( sp_id ); const int expert_multiplier = act->values.empty() ? 0 : act->values[0]; @@ -2318,7 +2318,7 @@ void activity_handlers::start_engines_finish( player_activity *act, player *p ) vehicle *veh = g->remoteveh(); map &here = get_map(); if( !veh ) { - const tripoint pos = act->placement + g->u.pos(); + const tripoint pos = act->placement + get_player_character().pos(); veh = veh_pointer_or_null( here.veh_at( pos ) ); if( !veh ) { return; @@ -2926,22 +2926,25 @@ void activity_handlers::wear_do_turn( player_activity *act, player *p ) // This activity opens the menu (it's not meant to queue consumption of items) void activity_handlers::eat_menu_do_turn( player_activity *, player * ) { - avatar_action::eat( g->u ); + avatar_action::eat( get_avatar() ); } void activity_handlers::consume_food_menu_do_turn( player_activity *, player * ) { - avatar_action::eat( g->u, game_menus::inv::consume_food( g->u ) ); + avatar &player_character = get_avatar(); + avatar_action::eat( player_character, game_menus::inv::consume_food( player_character ) ); } void activity_handlers::consume_drink_menu_do_turn( player_activity *, player * ) { - avatar_action::eat( g->u, game_menus::inv::consume_drink( g->u ) ); + avatar &player_character = get_avatar(); + avatar_action::eat( player_character, game_menus::inv::consume_drink( player_character ) ); } void activity_handlers::consume_meds_menu_do_turn( player_activity *, player * ) { - avatar_action::eat( g->u, game_menus::inv::consume_meds( g->u ) ); + avatar &player_character = get_avatar(); + avatar_action::eat( player_character, game_menus::inv::consume_meds( player_character ) ); } void activity_handlers::move_loot_do_turn( player_activity *act, player *p ) @@ -2964,11 +2967,12 @@ void activity_handlers::drive_do_turn( player_activity *act, player *p ) p->cancel_activity(); return; } + Character &player_character = get_player_character(); if( p->in_vehicle && p->controlling_vehicle && player_veh->is_autodriving && - !g->u.omt_path.empty() && !player_veh->omt_path.empty() ) { + !player_character.omt_path.empty() && !player_veh->omt_path.empty() ) { player_veh->do_autodrive(); - if( g->u.global_omt_location() == g->u.omt_path.back() ) { - g->u.omt_path.pop_back(); + if( player_character.global_omt_location() == player_character.omt_path.back() ) { + player_character.omt_path.pop_back(); } p->moves = 0; } else { @@ -3305,8 +3309,10 @@ void activity_handlers::operation_do_turn( player_activity *act, player *p ) }; const bionic_id bid( act->str_values[cbm_id] ); const bool autodoc = act->str_values[is_autodoc] == "true"; - const bool u_see = g->u.sees( p->pos() ) && ( !g->u.has_effect( effect_narcosis ) || - g->u.has_bionic( bio_painkiller ) || g->u.has_trait( trait_NOPAIN ) ); + Character &player_character = get_player_character(); + const bool u_see = player_character.sees( p->pos() ) && + ( !player_character.has_effect( effect_narcosis ) || + player_character.has_bionic( bio_painkiller ) || player_character.has_trait( trait_NOPAIN ) ); const int difficulty = act->values.front(); @@ -4035,7 +4041,7 @@ void activity_handlers::jackhammer_finish( player_activity *act, player *p ) here.destroy( pos, true ); if( p->is_avatar() ) { - const int helpersize = g->u.get_num_crafting_helpers( 3 ); + const int helpersize = get_player_character().get_num_crafting_helpers( 3 ); p->mod_stored_nutr( 5 - helpersize ); p->mod_thirst( 5 - helpersize ); p->mod_fatigue( 10 - ( helpersize * 2 ) ); @@ -4073,7 +4079,7 @@ void activity_handlers::fill_pit_finish( player_activity *act, player *p ) } else { here.ter_set( pos, t_dirt ); } - const int helpersize = g->u.get_num_crafting_helpers( 3 ); + const int helpersize = get_player_character().get_num_crafting_helpers( 3 ); p->mod_stored_nutr( 5 - helpersize ); p->mod_thirst( 5 - helpersize ); p->mod_fatigue( 10 - ( helpersize * 2 ) ); diff --git a/src/crafting_gui.cpp b/src/crafting_gui.cpp index 56a4d109054b8..c22680c7b72c9 100644 --- a/src/crafting_gui.cpp +++ b/src/crafting_gui.cpp @@ -11,14 +11,13 @@ #include #include -#include "avatar.h" #include "calendar.h" #include "cata_utility.h" #include "catacharset.h" +#include "character.h" #include "color.h" #include "crafting.h" #include "cursesdef.h" -#include "game.h" #include "input.h" #include "item.h" #include "item_contents.h" @@ -237,7 +236,7 @@ const recipe *select_crafting_recipe( int &batch_size ) struct availability { availability( const recipe *r, int batch_size = 1 ) { - const inventory &inv = g->u.crafting_inventory(); + const inventory &inv = get_player_character().crafting_inventory(); auto all_items_filter = r->get_component_filter( recipe_filter_flags::none ); auto no_rotten_filter = r->get_component_filter( recipe_filter_flags::no_rotten ); const deduped_requirement_data &req = r->deduped_requirements(); @@ -300,11 +299,12 @@ const recipe *select_crafting_recipe( int &batch_size ) ctxt.register_action( "RELATED_RECIPES" ); ctxt.register_action( "HIDE_SHOW_RECIPE" ); - const inventory &crafting_inv = g->u.crafting_inventory(); - const std::vector helpers = g->u.get_crafting_helpers(); + Character &player_character = get_player_character(); + const inventory &crafting_inv = player_character.crafting_inventory(); + const std::vector helpers = player_character.get_crafting_helpers(); std::string filterstring; - const auto &available_recipes = g->u.get_available_recipes( crafting_inv, &helpers ); + const auto &available_recipes = player_character.get_available_recipes( crafting_inv, &helpers ); std::map availability_cache; ui.on_redraw( [&]( const ui_adaptor & ) { @@ -453,9 +453,9 @@ const recipe *select_crafting_recipe( int &batch_size ) component_print_buffer.insert( component_print_buffer.end(), tools.begin(), tools.end() ); component_print_buffer.insert( component_print_buffer.end(), comps.begin(), comps.end() ); - if( !g->u.knows_recipe( current[line] ) ) { + if( !player_character.knows_recipe( current[line] ) ) { component_print_buffer.push_back( _( "Recipe not memorized yet" ) ); - auto books_with_recipe = g->u.get_books_for_recipe( crafting_inv, current[line] ); + auto books_with_recipe = player_character.get_books_for_recipe( crafting_inv, current[line] ); std::string enumerated_books = enumerate_as_string( books_with_recipe.begin(), books_with_recipe.end(), []( const itype_id & type_id ) { @@ -492,16 +492,16 @@ const recipe *select_crafting_recipe( int &batch_size ) print_colored_text( w_data, point( xpos, ypos++ ), col, col, string_format( _( "Primary skill: %s" ), - current[line]->primary_skill_string( &g->u, false ) ) ); + current[line]->primary_skill_string( &player_character, false ) ) ); ypos += fold_and_print( w_data, point( xpos, ypos ), pane, col, _( "Other skills: %s" ), - current[line]->required_skills_string( &g->u, false, false ) ); + current[line]->required_skills_string( &player_character, false, false ) ); ypos += fold_and_print( w_data, point( xpos, ypos ), pane, col, _( "Proficiencies Required: %s" ), current[line]->required_proficiencies_string( get_player_character() ) ); - const int expected_turns = g->u.expected_time_to_craft( *current[line], + const int expected_turns = player_character.expected_time_to_craft( *current[line], count ) / to_moves( 1_turns ); ypos += fold_and_print( w_data, point( xpos, ypos ), pane, col, _( "Time to complete: %s" ), @@ -663,7 +663,7 @@ const recipe *select_crafting_recipe( int &batch_size ) break; case 'm': { - auto &learned = g->u.get_learned_recipes(); + auto &learned = player_character.get_learned_recipes(); recipe_subset temp_subset; if( query_is_yes( qry_filter_str ) ) { temp_subset = available_recipes.intersection( learned ); @@ -783,7 +783,7 @@ const recipe *select_crafting_recipe( int &batch_size ) } else if( action == "CONFIRM" ) { if( available.empty() || !available[line].can_craft ) { popup( _( "You can't do that! Press [ESC]!" ) ); - } else if( !g->u.check_eligible_containers_for_crafting( *current[line], + } else if( !player_character.check_eligible_containers_for_crafting( *current[line], ( batch ) ? line + 1 : 1 ) ) { // popup is already inside check } else { @@ -958,7 +958,8 @@ std::string peek_related_recipe( const recipe *current, const recipe_subset &ava item tmp = current->create_result(); // use this item const itype_id tid = tmp.typeId(); - const std::set &known_recipes = g->u.get_learned_recipes().of_component( tid ); + const std::set &known_recipes = + get_player_character().get_learned_recipes().of_component( tid ); for( const auto &b : known_recipes ) { if( available.contains( b ) ) { related_results.push_back( { b->result(), b->result_name() } ); @@ -1071,15 +1072,16 @@ static void draw_hidden_amount( const catacurses::window &w, int amount, int num // Anchors top-right static void draw_can_craft_indicator( const catacurses::window &w, const recipe &rec ) { + Character &player_character = get_player_character(); // Draw text - if( g->u.lighting_craft_speed_multiplier( rec ) <= 0.0f ) { + if( player_character.lighting_craft_speed_multiplier( rec ) <= 0.0f ) { right_print( w, 0, 1, i_red, _( "too dark to craft" ) ); - } else if( g->u.crafting_speed_multiplier( rec ) <= 0.0f ) { + } else if( player_character.crafting_speed_multiplier( rec ) <= 0.0f ) { // Technically not always only too sad, but must be too sad right_print( w, 0, 1, i_red, _( "too sad to craft" ) ); - } else if( g->u.crafting_speed_multiplier( rec ) < 1.0f ) { + } else if( player_character.crafting_speed_multiplier( rec ) < 1.0f ) { right_print( w, 0, 1, i_yellow, string_format( _( "crafting is slow %d%%" ), - static_cast( g->u.crafting_speed_multiplier( rec ) * 100 ) ) ); + static_cast( player_character.crafting_speed_multiplier( rec ) * 100 ) ) ); } else { right_print( w, 0, 1, i_green, _( "craftable" ) ); } diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index 008d66446436d..7baf150589e92 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -548,13 +548,14 @@ class comestible_inventory_preset : public inventory_selector_preset return string_format( _( "%.2f%s" ), converted_volume, volume_units_abbr() ); }, _( "VOLUME" ) ); - append_cell( []( const item_location & loc ) { - time_duration time = g->u.get_consume_time( *loc ); + Character &player_character = get_player_character(); + append_cell( [&player_character]( const item_location & loc ) { + time_duration time = player_character.get_consume_time( *loc ); return string_format( _( "%s" ), to_string( time ) ); }, _( "CONSUME TIME" ) ); - append_cell( [this]( const item_location & loc ) { - if( g->u.can_estimate_rot() ) { + append_cell( [this, &player_character]( const item_location & loc ) { + if( player_character.can_estimate_rot() ) { if( loc->is_comestible() && loc->get_comestible()->spoils > 0_turns ) { return get_freshness( loc ); } @@ -563,8 +564,8 @@ class comestible_inventory_preset : public inventory_selector_preset return std::string(); }, _( "FRESHNESS" ) ); - append_cell( [ this ]( const item_location & loc ) { - if( g->u.can_estimate_rot() ) { + append_cell( [ this, &player_character ]( const item_location & loc ) { + if( player_character.can_estimate_rot() ) { if( loc->is_comestible() && loc->get_comestible()->spoils > 0_turns ) { if( !loc->rotten() ) { return get_time_left_rounded( loc ); @@ -574,7 +575,6 @@ class comestible_inventory_preset : public inventory_selector_preset } return std::string(); }, _( "SPOILS IN" ) ); - append_cell( [&p]( const item_location & loc ) { std::string cbm_name; @@ -744,8 +744,9 @@ static std::string get_consume_needs_hint( player &p ) item_location game_menus::inv::consume( player &p ) { - if( !g->u.has_activity( ACT_EAT_MENU ) ) { - g->u.assign_activity( ACT_EAT_MENU ); + Character &player_character = get_player_character(); + if( !player_character.has_activity( ACT_EAT_MENU ) ) { + player_character.assign_activity( ACT_EAT_MENU ); } return inv_internal( p, comestible_inventory_preset( p ), @@ -771,8 +772,9 @@ class comestible_filtered_inventory_preset : public comestible_inventory_preset item_location game_menus::inv::consume_food( player &p ) { - if( !g->u.has_activity( ACT_CONSUME_FOOD_MENU ) ) { - g->u.assign_activity( ACT_CONSUME_FOOD_MENU ); + Character &player_character = get_player_character(); + if( !player_character.has_activity( ACT_CONSUME_FOOD_MENU ) ) { + player_character.assign_activity( ACT_CONSUME_FOOD_MENU ); } return inv_internal( p, comestible_filtered_inventory_preset( p, []( const item & it ) { @@ -786,8 +788,9 @@ item_location game_menus::inv::consume_food( player &p ) item_location game_menus::inv::consume_drink( player &p ) { - if( !g->u.has_activity( ACT_CONSUME_DRINK_MENU ) ) { - g->u.assign_activity( ACT_CONSUME_DRINK_MENU ); + Character &player_character = get_player_character(); + if( !player_character.has_activity( ACT_CONSUME_DRINK_MENU ) ) { + player_character.assign_activity( ACT_CONSUME_DRINK_MENU ); } return inv_internal( p, comestible_filtered_inventory_preset( p, []( const item & it ) { @@ -801,8 +804,9 @@ item_location game_menus::inv::consume_drink( player &p ) item_location game_menus::inv::consume_meds( player &p ) { - if( !g->u.has_activity( ACT_CONSUME_MEDS_MENU ) ) { - g->u.assign_activity( ACT_CONSUME_MEDS_MENU ); + Character &player_character = get_player_character(); + if( !player_character.has_activity( ACT_CONSUME_MEDS_MENU ) ) { + player_character.assign_activity( ACT_CONSUME_MEDS_MENU ); } return inv_internal( p, comestible_filtered_inventory_preset( p, []( const item & it ) { @@ -1742,7 +1746,7 @@ class bionic_install_preset: public inventory_selector_preset int chance_of_failure = 100; player &installer = p; - if( g->u.has_trait( trait_DEBUG_BIONICS ) ) { + if( get_player_character().has_trait( trait_DEBUG_BIONICS ) ) { chance_of_failure = 0; } else { chance_of_failure = 100 - bionic_success_chance( true, -1, difficulty, installer ); @@ -1832,7 +1836,7 @@ class bionic_install_surgeon_preset : public inventory_selector_preset int chance_of_failure = 100; player &installer = p; - if( g->u.has_trait( trait_DEBUG_BIONICS ) ) { + if( get_player_character().has_trait( trait_DEBUG_BIONICS ) ) { chance_of_failure = 0; } else { chance_of_failure = 100 - bionic_success_chance( true, 20, difficulty, installer ); @@ -1913,7 +1917,7 @@ class bionic_uninstall_preset : public inventory_selector_preset int chance_of_failure = 100; player &installer = p; - if( g->u.has_trait( trait_DEBUG_BIONICS ) ) { + if( get_player_character().has_trait( trait_DEBUG_BIONICS ) ) { chance_of_failure = 0; } else { chance_of_failure = 100 - bionic_success_chance( true, -1, difficulty, installer ); diff --git a/src/item.cpp b/src/item.cpp index f103ea377811c..f479efaf5e7f0 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -7938,7 +7938,7 @@ void item::casings_handle( const std::function &func ) contents.casings_handle( func ); } -bool item::reload( player &u, item_location ammo, int qty ) +bool item::reload( Character &u, item_location ammo, int qty ) { if( qty <= 0 ) { debugmsg( "Tried to reload zero or less charges" ); diff --git a/src/item.h b/src/item.h index 8f79dc1aa5630..f66b6b39b13ce 100644 --- a/src/item.h +++ b/src/item.h @@ -507,7 +507,7 @@ class item : public visitable * @param ammo Location of ammo to be reloaded * @param qty caps reloading to this (or fewer) units */ - bool reload( player &u, item_location ammo, int qty ); + bool reload( Character &u, item_location ammo, int qty ); template void io( Archive & ); diff --git a/src/weather.cpp b/src/weather.cpp index e4415a2be3fc6..e886329be142c 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -8,10 +8,10 @@ #include #include "assign.h" -#include "avatar.h" #include "bodypart.h" #include "calendar.h" #include "cata_utility.h" +#include "character.h" #include "colony.h" #include "coordinate_conversions.h" #include "enums.h" @@ -89,13 +89,14 @@ weather_type_id get_bad_weather() */ void glare( weather_type_id w ) { - Character &target_character = g->u;//todo npcs, also + Character &player_character = get_player_character();//todo npcs, also //General prepequisites for glare - if( !is_creature_outside( target_character ) || !g->is_in_sunlight( g->u.pos() ) || - g->u.in_sleep_state() || - g->u.worn_with_flag( flag_SUN_GLASSES ) || - g->u.has_bionic( bio_sunglasses ) || - g->u.is_blind() ) { + if( !is_creature_outside( player_character ) || + !g->is_in_sunlight( player_character.pos() ) || + player_character.in_sleep_state() || + player_character.worn_with_flag( flag_SUN_GLASSES ) || + player_character.has_bionic( bio_sunglasses ) || + player_character.is_blind() ) { return; } @@ -105,19 +106,19 @@ void glare( weather_type_id w ) if( season == WINTER ) { //Winter snow glare: for both clear & sunny weather effect = &effect_snow_glare; - dur = target_character.has_effect( *effect ) ? 1_turns : 2_turns; + dur = player_character.has_effect( *effect ) ? 1_turns : 2_turns; } else if( w->sun_intensity == sun_intensity_type::high ) { //Sun glare: only for bright sunny weather effect = &effect_glare; - dur = target_character.has_effect( *effect ) ? 1_turns : 2_turns; + dur = player_character.has_effect( *effect ) ? 1_turns : 2_turns; } //apply final glare effect if( dur > 0_turns && effect != nullptr ) { //enhance/reduce by some traits - if( target_character.has_trait( trait_CEPH_VISION ) ) { + if( player_character.has_trait( trait_CEPH_VISION ) ) { dur = dur * 2; } - target_character.add_env_effect( *effect, bp_eyes, 2, dur ); + player_character.add_env_effect( *effect, bp_eyes, 2, dur ); } } @@ -430,18 +431,19 @@ void wet( Character &target, int amount ) void weather_sound( translation sound_message, std::string sound_effect ) { - if( !g->u.has_effect( effect_sleep ) && !g->u.is_deaf() ) { + Character &player_character = get_player_character(); + if( !player_character.has_effect( effect_sleep ) && !player_character.is_deaf() ) { if( g->get_levz() >= 0 ) { add_msg( sound_message ); if( !sound_effect.empty() ) { sfx::play_variant_sound( "environment", sound_effect, 80, rng( 0, 359 ) ); } } else if( one_in( std::max( roll_remainder( 2.0f * g->get_levz() / - g->u.mutation_value( "hearing_modifier" ) ), 1 ) ) ) { + player_character.mutation_value( "hearing_modifier" ) ), 1 ) ) ) { add_msg( sound_message ); if( !sound_effect.empty() ) { sfx::play_variant_sound( "environment", sound_effect, - ( 80 * g->u.mutation_value( "hearing_modifier" ) ), rng( 0, 359 ) ); + ( 80 * player_character.mutation_value( "hearing_modifier" ) ), rng( 0, 359 ) ); } } } @@ -461,7 +463,7 @@ double precip_mm_per_hour( precip_class const p ) void handle_weather_effects( weather_type_id const w ) { //Possible TODO, make npc/monsters affected - Character &target_character = get_player_character(); + Character &player_character = get_player_character(); if( w->rains && w->precip != precip_class::none ) { fill_water_collectors( precip_mm_per_hour( w->precip ), w->acidic ); @@ -478,14 +480,14 @@ void handle_weather_effects( weather_type_id const w ) wetness = 60; } get_map().decay_fields_and_scent( decay_time ); - wet( target_character, wetness ); + wet( player_character, wetness ); } glare( w ); g->weather.lightning_active = false; for( const weather_effect ¤t_effect : w->effects ) { - if( current_effect.must_be_outside && !is_creature_outside( target_character ) ) { + if( current_effect.must_be_outside && !is_creature_outside( player_character ) ) { continue; } if( current_effect.time_between > 0_seconds && @@ -505,16 +507,16 @@ void handle_weather_effects( weather_type_id const w ) } else if( w->precip >= precip_class::heavy ) { chance = 4; } - if( target_character.weapon.has_flag( "RAIN_PROTECT" ) && one_in( chance ) ) { - add_msg( _( "Your %s protects you from the weather." ), target_character.weapon.tname() ); + if( player_character.weapon.has_flag( "RAIN_PROTECT" ) && one_in( chance ) ) { + add_msg( _( "Your %s protects you from the weather." ), player_character.weapon.tname() ); continue; } else { - if( target_character.worn_with_flag( "RAINPROOF" ) && one_in( chance * 2 ) ) { + if( player_character.worn_with_flag( "RAINPROOF" ) && one_in( chance * 2 ) ) { add_msg( _( "Your clothing protects you from the weather." ) ); continue; } else { bool has_helmet = false; - if( target_character.is_wearing_power_armor( &has_helmet ) && ( has_helmet || + if( player_character.is_wearing_power_armor( &has_helmet ) && ( has_helmet || one_in( chance * 2 ) ) ) { add_msg( _( "Your power armor protects you from the weather." ) ); continue; @@ -522,7 +524,7 @@ void handle_weather_effects( weather_type_id const w ) } } } - if( target_character.get_pain() >= current_effect.pain_max ) { + if( player_character.get_pain() >= current_effect.pain_max ) { continue; } @@ -547,7 +549,7 @@ void handle_weather_effects( weather_type_id const w ) for( int i = 0; i < spawn.hallucination_count; i++ ) { tripoint point; - if( g->find_nearby_spawn_point( target_character, target_monster.type->id, spawn.min_radius, + if( g->find_nearby_spawn_point( player_character, target_monster.type->id, spawn.min_radius, spawn.max_radius, point ) ) { g->spawn_hallucination( point, target_monster.type->id ); spawned = true; @@ -555,7 +557,7 @@ void handle_weather_effects( weather_type_id const w ) } for( int i = 0; i < spawn.real_count; i++ ) { tripoint point; - if( g->find_nearby_spawn_point( target_character, target_monster.type->id, spawn.min_radius, + if( g->find_nearby_spawn_point( player_character, target_monster.type->id, spawn.min_radius, spawn.max_radius, point ) ) { g->place_critter_at( target_monster.type->id, point ); spawned = true; @@ -566,7 +568,7 @@ void handle_weather_effects( weather_type_id const w ) continue; } for( const weather_field &field : current_effect.fields ) { - for( const tripoint &dest : get_map().points_in_radius( target_character.pos(), field.radius ) ) { + for( const tripoint &dest : get_map().points_in_radius( player_character.pos(), field.radius ) ) { if( !field.outdoor_only || get_map().is_outside( dest ) ) { get_map().add_field( dest, field.type, field.intensity, field.age ); } @@ -574,33 +576,33 @@ void handle_weather_effects( weather_type_id const w ) } if( current_effect.effect_id.is_valid() ) { if( current_effect.target_part.is_valid() ) { - target_character.add_effect( current_effect.effect_id, current_effect.effect_duration, + player_character.add_effect( current_effect.effect_id, current_effect.effect_duration, current_effect.target_part->token ); } else { - target_character.add_effect( current_effect.effect_id, current_effect.effect_duration ); + player_character.add_effect( current_effect.effect_id, current_effect.effect_duration ); } } if( current_effect.trait_id_to_add.is_valid() ) { - target_character.set_mutation( current_effect.trait_id_to_add ); + player_character.set_mutation( current_effect.trait_id_to_add ); } if( current_effect.trait_id_to_remove.is_valid() ) { - target_character.unset_mutation( current_effect.trait_id_to_remove ); + player_character.unset_mutation( current_effect.trait_id_to_remove ); } if( current_effect.target_part.is_valid() ) { - target_character.deal_damage( nullptr, current_effect.target_part, damage_instance( DT_BASH, + player_character.deal_damage( nullptr, current_effect.target_part, damage_instance( DT_BASH, current_effect.damage ) ); } else { - for( const bodypart_id &bp : target_character.get_all_body_parts() ) { - target_character.deal_damage( nullptr, bp, damage_instance( DT_BASH, current_effect.damage ) ); + for( const bodypart_id &bp : player_character.get_all_body_parts() ) { + player_character.deal_damage( nullptr, bp, damage_instance( DT_BASH, current_effect.damage ) ); } } - target_character.mod_healthy( current_effect.healthy ); - target_character.mod_rad( current_effect.radiation ); - wet( target_character, current_effect.wet ); - target_character.mod_pain( current_effect.pain ); + player_character.mod_healthy( current_effect.healthy ); + player_character.mod_rad( current_effect.radiation ); + wet( player_character, current_effect.wet ); + player_character.mod_pain( current_effect.pain ); weather_sound( current_effect.sound_message, current_effect.sound_effect ); - target_character.add_msg_if_player( current_effect.message ); + player_character.add_msg_if_player( current_effect.message ); } } @@ -1037,14 +1039,16 @@ void weather_manager::update_weather() w_point &w = *weather_precise; winddirection = wind_direction_override ? *wind_direction_override : w.winddirection; windspeed = windspeed_override ? *windspeed_override : w.windpower; + Character &player_character = get_player_character(); if( weather_id == WEATHER_NULL || calendar::turn >= nextweather ) { const weather_generator &weather_gen = get_cur_weather_gen(); - w = weather_gen.get_weather( g->u.global_square_location(), calendar::turn, g->get_seed() ); + w = weather_gen.get_weather( player_character.global_square_location(), calendar::turn, + g->get_seed() ); weather_type_id old_weather = weather_id; weather_id = weather_override == WEATHER_NULL ? weather_gen.get_weather_conditions( w ) : weather_override; - if( !g->u.has_artifact_with( AEP_BAD_WEATHER ) ) { + if( !player_character.has_artifact_with( AEP_BAD_WEATHER ) ) { weather_override = WEATHER_NULL; } sfx::do_ambient(); @@ -1054,14 +1058,14 @@ void weather_manager::update_weather() // TODO: predict when the weather changes and use that time. nextweather = calendar::turn + 5_minutes; if( weather_id != old_weather && weather_id->dangerous && - g->get_levz() >= 0 && get_map().is_outside( g->u.pos() ) - && !g->u.has_activity( ACT_WAIT_WEATHER ) ) { + g->get_levz() >= 0 && get_map().is_outside( player_character.pos() ) + && !player_character.has_activity( ACT_WAIT_WEATHER ) ) { g->cancel_activity_or_ignore_query( distraction_type::weather_change, string_format( _( "The weather changed to %s!" ), weather_id->name ) ); } - if( weather_id != old_weather && g->u.has_activity( ACT_WAIT_WEATHER ) ) { - g->u.assign_activity( ACT_WAIT_WEATHER, 0, 0 ); + if( weather_id != old_weather && player_character.has_activity( ACT_WAIT_WEATHER ) ) { + player_character.assign_activity( ACT_WAIT_WEATHER, 0, 0 ); } if( weather_id->sight_penalty != diff --git a/tests/reload_magazine_test.cpp b/tests/reload_magazine_test.cpp index 0bcd9b8e6401d..855efa8e9e516 100644 --- a/tests/reload_magazine_test.cpp +++ b/tests/reload_magazine_test.cpp @@ -4,14 +4,12 @@ #include #include -#include "avatar.h" #include "calendar.h" #include "catch/catch.hpp" -#include "game.h" +#include "character.h" #include "inventory.h" #include "item.h" #include "item_location.h" -#include "player.h" #include "type_id.h" #include "visitable.h" @@ -32,22 +30,22 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) CHECK( mag_id != bad_mag ); CHECK( mag_cap > 0 ); - player &p = g->u; - p.worn.clear(); - p.inv.clear(); - p.remove_weapon(); - p.wear_item( item( "backpack" ) ); // so we don't drop anything + Character &player_character = get_player_character(); + player_character.worn.clear(); + player_character.inv.clear(); + player_character.remove_weapon(); + player_character.wear_item( item( "backpack" ) ); // so we don't drop anything - item &mag = p.i_add( item( mag_id ) ); + item &mag = player_character.i_add( item( mag_id ) ); CHECK( mag.is_magazine() == true ); CHECK( mag.is_reloadable() == true ); CHECK( mag.is_reloadable_with( ammo_id ) == true ); CHECK( mag.is_reloadable_with( alt_ammo ) == true ); CHECK( mag.is_reloadable_with( bad_ammo ) == false ); - CHECK( p.can_reload( mag ) == true ); - CHECK( p.can_reload( mag, ammo_id ) == true ); - CHECK( p.can_reload( mag, alt_ammo ) == true ); - CHECK( p.can_reload( mag, bad_ammo ) == false ); + CHECK( player_character.can_reload( mag ) == true ); + CHECK( player_character.can_reload( mag, ammo_id ) == true ); + CHECK( player_character.can_reload( mag, alt_ammo ) == true ); + CHECK( player_character.can_reload( mag, bad_ammo ) == false ); CHECK( mag.ammo_types().count( gun_ammo ) ); CHECK( mag.ammo_capacity( gun_ammo ) == mag_cap ); CHECK( mag.ammo_current().is_null() ); @@ -57,8 +55,9 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) CHECK( mag.ammo_remaining() == 0 ); WHEN( "the magazine is reloaded with incompatible ammo" ) { - item &ammo = p.i_add( item( bad_ammo ) ); - bool ok = mag.reload( g->u, item_location( p, &ammo ), mag.ammo_capacity( gun_ammo ) ); + item &ammo = player_character.i_add( item( bad_ammo ) ); + bool ok = mag.reload( player_character, item_location( player_character, &ammo ), + mag.ammo_capacity( gun_ammo ) ); THEN( "reloading should fail" ) { REQUIRE_FALSE( ok ); REQUIRE( mag.ammo_remaining() == 0 ); @@ -66,10 +65,11 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } WHEN( "the magazine is loaded with an excess of ammo" ) { - item &ammo = p.i_add( item( ammo_id, calendar::turn, mag_cap + 5 ) ); + item &ammo = player_character.i_add( item( ammo_id, calendar::turn, mag_cap + 5 ) ); REQUIRE( ammo.charges == mag_cap + 5 ); - bool ok = mag.reload( g->u, item_location( p, &ammo ), mag.ammo_capacity( gun_ammo ) ); + bool ok = mag.reload( player_character, item_location( player_character, &ammo ), + mag.ammo_capacity( gun_ammo ) ); THEN( "reloading is successful" ) { REQUIRE( ok ); @@ -82,7 +82,7 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } AND_THEN( "a single correctly sized ammo stack remains in the inventory" ) { std::vector found; - p.visit_items( [&ammo_id, &found]( const item * e ) { + player_character.visit_items( [&ammo_id, &found]( const item * e ) { if( e->typeId() == ammo_id ) { found.push_back( e ); } @@ -96,10 +96,11 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } WHEN( "the magazine is partially reloaded with compatible ammo" ) { - item &ammo = p.i_add( item( ammo_id, calendar::turn, mag_cap - 2 ) ); + item &ammo = player_character.i_add( item( ammo_id, calendar::turn, mag_cap - 2 ) ); REQUIRE( ammo.charges == mag_cap - 2 ); - bool ok = mag.reload( g->u, item_location( p, &ammo ), mag.ammo_capacity( gun_ammo ) ); + bool ok = mag.reload( player_character, item_location( player_character, &ammo ), + mag.ammo_capacity( gun_ammo ) ); THEN( "reloading is successful" ) { REQUIRE( ok == true ); @@ -112,7 +113,7 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } AND_THEN( "the ammo stack was completely used" ) { std::vector found; - p.visit_items( [&ammo_id, &found]( const item * e ) { + player_character.visit_items( [&ammo_id, &found]( const item * e ) { if( e->typeId() == ammo_id ) { found.push_back( e ); } @@ -124,11 +125,12 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } AND_WHEN( "the magazine is further reloaded with matching ammo" ) { - item &ammo = p.i_add( item( ammo_id, calendar::turn, 10 ) ); + item &ammo = player_character.i_add( item( ammo_id, calendar::turn, 10 ) ); REQUIRE( ammo.charges == 10 ); REQUIRE( mag.ammo_remaining() == mag_cap - 2 ); - bool ok = mag.reload( g->u, item_location( p, &ammo ), mag.ammo_capacity( gun_ammo ) ); + bool ok = mag.reload( player_character, item_location( player_character, &ammo ), + mag.ammo_capacity( gun_ammo ) ); THEN( "further reloading is successful" ) { REQUIRE( ok ); @@ -137,7 +139,7 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } AND_THEN( "a single correctly sized ammo stack remains in the inventory" ) { std::vector found; - p.visit_items( [&ammo_id, &found]( const item * e ) { + player_character.visit_items( [&ammo_id, &found]( const item * e ) { if( e->typeId() == ammo_id ) { found.push_back( e ); } @@ -151,8 +153,9 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } AND_WHEN( "the magazine is further reloaded with compatible but different ammo" ) { - item &ammo = p.i_add( item( alt_ammo ) ); - bool ok = mag.reload( g->u, item_location( p, &ammo ), mag.ammo_capacity( gun_ammo ) ); + item &ammo = player_character.i_add( item( alt_ammo ) ); + bool ok = mag.reload( player_character, item_location( player_character, &ammo ), + mag.ammo_capacity( gun_ammo ) ); THEN( "further reloading should fail" ) { REQUIRE_FALSE( ok ); REQUIRE( mag.ammo_remaining() == mag_cap - 2 ); @@ -160,8 +163,9 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } AND_WHEN( "the magazine is further reloaded with incompatible ammo" ) { - item &ammo = p.i_add( item( bad_ammo ) ); - bool ok = mag.reload( g->u, item_location( p, &ammo ), mag.ammo_capacity( gun_ammo ) ); + item &ammo = player_character.i_add( item( bad_ammo ) ); + bool ok = mag.reload( player_character, item_location( player_character, &ammo ), + mag.ammo_capacity( gun_ammo ) ); THEN( "further reloading should fail" ) { REQUIRE_FALSE( ok ); REQUIRE( mag.ammo_remaining() == mag_cap - 2 ); @@ -171,12 +175,12 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } GIVEN( "an empty gun without an integral magazine" ) { - item &gun = p.i_add( item( gun_id ) ); + item &gun = player_character.i_add( item( gun_id ) ); CHECK( gun.is_gun() == true ); CHECK( gun.is_reloadable() == true ); - CHECK( p.can_reload( gun ) == true ); - CHECK( p.can_reload( gun, mag_id ) == true ); - CHECK( p.can_reload( gun, ammo_id ) == false ); + CHECK( player_character.can_reload( gun ) == true ); + CHECK( player_character.can_reload( gun, mag_id ) == true ); + CHECK( player_character.can_reload( gun, ammo_id ) == false ); CHECK( gun.magazine_integral() == false ); CHECK( gun.magazine_default() == mag_id ); CHECK( gun.magazine_compatible().count( mag_id ) == 1 ); @@ -188,8 +192,8 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) CHECK( gun.ammo_data() == nullptr ); WHEN( "the gun is reloaded with an incompatible magazine" ) { - item &mag = p.i_add( item( bad_mag ) ); - bool ok = gun.reload( g->u, item_location( p, &mag ), 1 ); + item &mag = player_character.i_add( item( bad_mag ) ); + bool ok = gun.reload( player_character, item_location( player_character, &mag ), 1 ); THEN( "reloading should fail" ) { REQUIRE_FALSE( ok ); REQUIRE_FALSE( gun.magazine_current() ); @@ -199,7 +203,7 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) WHEN( "the gun is reloaded with an empty compatible magazine" ) { CHECK( mag.ammo_remaining() == 0 ); - bool ok = gun.reload( g->u, item_location( p, &mag ), 1 ); + bool ok = gun.reload( player_character, item_location( player_character, &mag ), 1 ); THEN( "reloading is successful" ) { REQUIRE( ok ); REQUIRE( gun.magazine_current() ); @@ -226,7 +230,7 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) CHECK( mag.ammo_current() == ammo_id ); CHECK( mag.ammo_remaining() == mag_cap - 2 ); - bool ok = gun.reload( g->u, item_location( p, &mag ), 1 ); + bool ok = gun.reload( player_character, item_location( player_character, &mag ), 1 ); THEN( "reloading is successful" ) { REQUIRE( ok ); REQUIRE( gun.magazine_current() ); @@ -247,8 +251,9 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } AND_WHEN( "the guns magazine is further reloaded with compatible but different ammo" ) { - item &ammo = p.i_add( item( alt_ammo, calendar::turn, 10 ) ); - bool ok = gun.magazine_current()->reload( g->u, item_location( p, &ammo ), 10 ); + item &ammo = player_character.i_add( item( alt_ammo, calendar::turn, 10 ) ); + bool ok = gun.magazine_current()->reload( player_character, item_location( player_character, + &ammo ), 10 ); THEN( "further reloading should fail" ) { REQUIRE_FALSE( ok ); REQUIRE( gun.ammo_remaining() == mag_cap - 2 ); @@ -256,8 +261,9 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } AND_WHEN( "the guns magazine is further reloaded with incompatible ammo" ) { - item &ammo = p.i_add( item( bad_ammo, calendar::turn, 10 ) ); - bool ok = gun.magazine_current()->reload( g->u, item_location( p, &ammo ), 10 ); + item &ammo = player_character.i_add( item( bad_ammo, calendar::turn, 10 ) ); + bool ok = gun.magazine_current()->reload( player_character, item_location( player_character, + &ammo ), 10 ); THEN( "further reloading should fail" ) { REQUIRE_FALSE( ok ); REQUIRE( gun.ammo_remaining() == mag_cap - 2 ); @@ -265,10 +271,11 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } AND_WHEN( "the guns magazine is further reloaded with matching ammo" ) { - item &ammo = p.i_add( item( ammo_id, calendar::turn, 10 ) ); + item &ammo = player_character.i_add( item( ammo_id, calendar::turn, 10 ) ); REQUIRE( ammo.charges == 10 ); - bool ok = gun.magazine_current()->reload( g->u, item_location( p, &ammo ), 10 ); + bool ok = gun.magazine_current()->reload( player_character, item_location( player_character, + &ammo ), 10 ); THEN( "further reloading is successful" ) { REQUIRE( ok ); @@ -277,7 +284,7 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) } AND_THEN( "a single correctly sized ammo stack remains in the inventory" ) { std::vector found; - p.visit_items( [&ammo_id, &found]( const item * e ) { + player_character.visit_items( [&ammo_id, &found]( const item * e ) { if( e->typeId() == ammo_id ) { found.push_back( e ); } From 3b15cc45743547a88c8ed3bbcb4f7d75f0ab6002 Mon Sep 17 00:00:00 2001 From: UrbanCMC Date: Wed, 15 Jul 2020 19:20:57 +0200 Subject: [PATCH 070/151] Fix portable autoclave deleting CBMs --- data/json/items/tool/med.json | 7 +++++++ src/iuse.cpp | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/data/json/items/tool/med.json b/data/json/items/tool/med.json index fdde5da93823b..b2093ffb42b9a 100644 --- a/data/json/items/tool/med.json +++ b/data/json/items/tool/med.json @@ -43,6 +43,13 @@ "max_contains_volume": "20 L", "max_contains_weight": "20 kg", "item_restriction": [ "heavy_plus_battery_cell", "heavy_battery_cell", "heavy_atomic_battery_cell", "heavy_disposable_cell" ] + }, + { + "pocket_type": "CONTAINER", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "flag_restriction": [ "CBM" ] } ] }, diff --git a/src/iuse.cpp b/src/iuse.cpp index bc999f348e205..32dbe5cae5ced 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -8653,6 +8653,7 @@ int iuse::autoclave( player *p, item *it, bool t, const tripoint &pos ) add_msg( m_bad, _( "The autoclave ran out of battery and stopped before completing its cycle." ) ); it->active = false; it->erase_var( "CYCLETIME" ); + it->unset_flag( "NO_UNLOAD" ); return 0; } @@ -8661,12 +8662,11 @@ int iuse::autoclave( player *p, item *it, bool t, const tripoint &pos ) if( Cycle_time <= 0 ) { it->active = false; it->erase_var( "CYCLETIME" ); - it->visit_items( []( item * bio ) { - if( bio->is_bionic() && !bio->has_flag( "NO_PACKED" ) ) { - bio->unset_flag( "NO_STERILE" ); - } - return VisitResponse::NEXT; + it->unset_flag( "NO_UNLOAD" ); + item *cbm = it->contents.get_item_with( []( const item & it ) { + return it.is_bionic() && !it.has_flag( "NO_PACKED" ); } ); + cbm->unset_flag( "NO_STERILE" ); } else { it->set_var( "CYCLETIME", Cycle_time ); } @@ -8729,6 +8729,7 @@ int iuse::autoclave( player *p, item *it, bool t, const tripoint &pos ) it->activate(); it->set_var( "CYCLETIME", to_seconds( 90_minutes ) ); // one cycle + it->set_flag( "NO_UNLOAD" ); return it->type->charges_to_use(); } } else { From 8f9860bbacc26bf4d254e64e13fcb56dc0685269 Mon Sep 17 00:00:00 2001 From: UrbanCMC Date: Thu, 16 Jul 2020 13:13:36 +0200 Subject: [PATCH 071/151] Consider magazine contents as CBM fuel source --- src/character.cpp | 6 +++++- src/consumption.cpp | 12 ++++++++++-- src/game_inventory.cpp | 14 ++++++++++++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index 861be980d2be2..ef3e88e7a3f10 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -2012,7 +2012,7 @@ bionic_id Character::get_remote_fueled_bionic() const bool Character::can_fuel_bionic_with( const item &it ) const { - if( !it.is_fuel() ) { + if( !it.is_fuel() && !it.type->magazine ) { return false; } @@ -2020,6 +2020,8 @@ bool Character::can_fuel_bionic_with( const item &it ) const for( const itype_id &fuel : bid->fuel_opts ) { if( fuel == it.typeId() ) { return true; + } else if( it.type->magazine && fuel == it.ammo_current() ) { + return true; } } } @@ -2034,6 +2036,8 @@ std::vector Character::get_bionic_fueled_with( const item &it ) const for( const itype_id &fuel : bid->fuel_opts ) { if( fuel == it.typeId() ) { bionics.emplace_back( bid ); + } else if( it.type->magazine && fuel == it.ammo_current() ) { + bionics.emplace_back( bid ); } } } diff --git a/src/consumption.cpp b/src/consumption.cpp index d2d950e370eee..3977222b7db72 100644 --- a/src/consumption.cpp +++ b/src/consumption.cpp @@ -1579,8 +1579,16 @@ int Character::get_acquirable_energy( const item &it, rechargeable_cbm cbm ) con } case rechargeable_cbm::other: const bionic_id &bid = get_most_efficient_bionic( get_bionic_fueled_with( it ) ); - const int to_consume = std::min( it.charges, bid->fuel_capacity ); - const int to_charge = static_cast( it.fuel_energy() * to_consume * bid->fuel_efficiency ); + int to_consume; + int to_charge; + if( it.type->magazine ) { + item ammo = item( it.ammo_current() ); + to_consume = std::min( it.ammo_remaining(), bid->fuel_capacity ); + to_charge = ammo.fuel_energy() * to_consume * bid->fuel_efficiency; + } else { + to_consume = std::min( it.charges, bid->fuel_capacity ); + to_charge = it.fuel_energy() * to_consume * bid->fuel_efficiency; + } return to_charge; } diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index 008d66446436d..b0bb23f724e11 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -629,8 +629,18 @@ class comestible_inventory_preset : public inventory_selector_preset if( !res.success() && cbm == rechargeable_cbm::none ) { return res.str(); - } else if( cbm == rechargeable_cbm::other && ( p.get_fuel_capacity( it.typeId() ) <= 0 ) ) { - return string_format( _( "No space to store more %s" ), it.tname() ); + } else if( cbm == rechargeable_cbm::other ) { + std::string item_name = it.tname(); + itype_id item_type = it.typeId(); + if( it.type->magazine ) { + const item ammo = item( it.ammo_current() ); + item_name = ammo.tname(); + item_type = ammo.typeId(); + } + + if( p.get_fuel_capacity( item_type ) <= 0 ) { + return string_format( _( "No space to store more %s" ), item_name ); + } } return inventory_selector_preset::get_denial( loc ); From d858405dbacb16dce0b7944a38feba749a68ebb0 Mon Sep 17 00:00:00 2001 From: UrbanCMC Date: Thu, 16 Jul 2020 13:16:20 +0200 Subject: [PATCH 072/151] Use correct fuel source when filling CBMs --- src/consumption.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/consumption.cpp b/src/consumption.cpp index 3977222b7db72..15c1a9995583c 100644 --- a/src/consumption.cpp +++ b/src/consumption.cpp @@ -1500,8 +1500,22 @@ bool Character::fuel_bionic_with( item &it ) const bionic_id bio = get_most_efficient_bionic( get_bionic_fueled_with( it ) ); - const int loadable = std::min( it.charges, get_fuel_capacity( it.typeId() ) ); - const std::string str_loaded = get_value( it.typeId().str() ); + const bool is_magazine = !!it.type->magazine; + std::string item_name = it.tname(); + itype_id item_type = it.typeId(); + int loadable; + if( is_magazine ) { + const item ammo = item( it.ammo_current() ); + item_name = ammo.tname(); + item_type = ammo.typeId(); + loadable = std::min( it.ammo_remaining(), get_fuel_capacity( item_type ) ); + it.ammo_set( item_type, it.ammo_remaining() - loadable ); + } else { + loadable = std::min( it.charges, get_fuel_capacity( item_type ) ); + it.charges -= loadable; + } + + const std::string str_loaded = get_value( item_type.str() ); int loaded = 0; if( !str_loaded.empty() ) { loaded = std::stoi( str_loaded ); @@ -1509,19 +1523,19 @@ bool Character::fuel_bionic_with( item &it ) const std::string new_charge = std::to_string( loadable + loaded ); - it.charges -= loadable; // Type and amount of fuel - set_value( it.typeId().str(), new_charge ); - update_fuel_storage( it.typeId() ); + set_value( item_type.str(), new_charge ); + update_fuel_storage( item_type ); add_msg_player_or_npc( m_info, //~ %1$i: charge number, %2$s: item name, %3$s: bionics name ngettext( "You load %1$i charge of %2$s in your %3$s.", "You load %1$i charges of %2$s in your %3$s.", loadable ), //~ %1$i: charge number, %2$s: item name, %3$s: bionics name ngettext( " load %1$i charge of %2$s in their %3$s.", - " load %1$i charges of %2$s in their %3$s.", loadable ), loadable, it.tname(), bio->name ); + " load %1$i charges of %2$s in their %3$s.", loadable ), loadable, item_name, bio->name ); mod_moves( -250 ); - return true; + // Return false for magazines because only their ammo is consumed + return !is_magazine; } rechargeable_cbm Character::get_cbm_rechargeable_with( const item &it ) const From 3a7caf6602002de05b69a0421f05c936c9d61241 Mon Sep 17 00:00:00 2001 From: UrbanCMC Date: Thu, 16 Jul 2020 13:53:12 +0200 Subject: [PATCH 073/151] Update bionics tests --- tests/bionics_test.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/bionics_test.cpp b/tests/bionics_test.cpp index 0462a61ef357e..912a7186c1546 100644 --- a/tests/bionics_test.cpp +++ b/tests/bionics_test.cpp @@ -109,11 +109,17 @@ TEST_CASE( "bionics", "[bionics] [item]" ) test_consumable_charges( dummy, it, true, true ); } + static const std::list ammo_when_full = { + "light_battery_cell", // MAGAZINE, NO_UNLOAD + }; + for( auto it : ammo_when_full ) { + test_consumable_ammo( dummy, it, false, true ); + } + static const std::list never = { "flashlight", // !is_magazine() "laser_rifle", // NO_UNLOAD, uses ups_charges - "UPS_off", // NO_UNLOAD, !is_magazine() - "battery_car" // NO_UNLOAD, is_magazine() + "UPS_off" // NO_UNLOAD, !is_magazine() }; for( auto it : never ) { test_consumable_ammo( dummy, it, false, false ); From 98580bdcd3a68f698be4526316b83140c0574699 Mon Sep 17 00:00:00 2001 From: andrei Date: Thu, 16 Jul 2020 16:13:30 +0300 Subject: [PATCH 074/151] bodypart: fix and simplify comparison functions don't iterate over and delete from the same container in intersect_set use defined accessors instead of implementation details fixes #41103 --- src/bodypart.cpp | 25 ++++++++++++++----------- src/bodypart.h | 6 +++++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/bodypart.cpp b/src/bodypart.cpp index a14ea79334a33..093b9c505e1e5 100644 --- a/src/bodypart.cpp +++ b/src/bodypart.cpp @@ -348,9 +348,9 @@ std::string get_body_part_id( body_part bp ) body_part_set body_part_set::unify_set( const body_part_set &rhs ) { - for( const bodypart_str_id &i : rhs.parts ) { - if( parts.count( i ) == 0 ) { - parts.insert( i ); + for( const bodypart_str_id &i : rhs ) { + if( !test( i ) ) { + set( i ); } } return *this; @@ -358,28 +358,31 @@ body_part_set body_part_set::unify_set( const body_part_set &rhs ) body_part_set body_part_set::intersect_set( const body_part_set &rhs ) { - for( const bodypart_str_id &j : parts ) { - if( rhs.parts.count( j ) == 0 ) { - parts.erase( j ); + body_part_set temp; + for( const bodypart_str_id &j : rhs ) { + if( test( j ) ) { + temp.set( j ); } } + clear(); + unify_set(temp); return *this; } body_part_set body_part_set::substract_set( const body_part_set &rhs ) { - for( const bodypart_str_id &j : rhs.parts ) { - if( parts.count( j ) > 0 ) { - parts.erase( j ); + for( const bodypart_str_id &j : rhs ) { + if( test( j ) ) { + reset( j ); } } return *this; } -body_part_set body_part_set::make_intersection( const body_part_set &rhs ) +body_part_set body_part_set::make_intersection( const body_part_set &rhs ) const { body_part_set new_intersection; - new_intersection.parts = parts; + new_intersection.unify_set(*this); return new_intersection.intersect_set( rhs ); } diff --git a/src/bodypart.h b/src/bodypart.h index d0dff3c1f6f35..90ad88715973a 100644 --- a/src/bodypart.h +++ b/src/bodypart.h @@ -259,7 +259,7 @@ class body_part_set body_part_set unify_set( const body_part_set &rhs ); body_part_set intersect_set( const body_part_set &rhs ); - body_part_set make_intersection( const body_part_set &rhs ); + body_part_set make_intersection( const body_part_set &rhs ) const; body_part_set substract_set( const body_part_set &rhs ); void fill( const std::vector &bps ); @@ -291,6 +291,10 @@ class body_part_set return parts.end(); } + void clear() { + parts.clear(); + } + template void serialize( Stream &s ) const { s.write( parts ); From 87de25fabaaf8bd6430d9c74624eb4e66c131bc8 Mon Sep 17 00:00:00 2001 From: andrei Date: Thu, 16 Jul 2020 16:22:59 +0300 Subject: [PATCH 075/151] =?UTF-8?q?bodypart:=20astyle=20=F0=9F=A4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bodypart.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bodypart.cpp b/src/bodypart.cpp index 093b9c505e1e5..69528fb67a020 100644 --- a/src/bodypart.cpp +++ b/src/bodypart.cpp @@ -365,7 +365,7 @@ body_part_set body_part_set::intersect_set( const body_part_set &rhs ) } } clear(); - unify_set(temp); + unify_set( temp ); return *this; } @@ -382,7 +382,7 @@ body_part_set body_part_set::substract_set( const body_part_set &rhs ) body_part_set body_part_set::make_intersection( const body_part_set &rhs ) const { body_part_set new_intersection; - new_intersection.unify_set(*this); + new_intersection.unify_set( *this ); return new_intersection.intersect_set( rhs ); } From d265d119e0e18d12aa85932b4f354844e6a660df Mon Sep 17 00:00:00 2001 From: Hirmuolio Date: Thu, 16 Jul 2020 18:21:56 +0300 Subject: [PATCH 076/151] remove unused rotten_away --- src/item.cpp | 12 ------------ src/item.h | 9 --------- src/item_contents.cpp | 10 ---------- src/item_contents.h | 1 - src/item_pocket.cpp | 11 ----------- src/item_pocket.h | 1 - 6 files changed, 44 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index f103ea377811c..8ac3691591924 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -8744,18 +8744,6 @@ bool item::has_rotten_away() const } } -bool item::has_rotten_away( const tripoint &pnt, float spoil_multiplier, temperature_flag flag ) -{ - if( goes_bad() ) { - process_temperature_rot( 1, pnt, nullptr, flag, spoil_multiplier ); - return has_rotten_away(); - } else { - contents.remove_rotten( pnt ); - - return false; - } -} - bool item_ptr_compare_by_charges( const item *left, const item *right ) { if( left->contents.empty() ) { diff --git a/src/item.h b/src/item.h index 8f79dc1aa5630..0bd38a9b09c89 100644 --- a/src/item.h +++ b/src/item.h @@ -787,15 +787,6 @@ class item : public visitable * @param mod How many charges should be removed. */ void mod_charges( int mod ); - /** - * Whether the item has to be removed as it has rotten away completely. May change the item as it calls process_temperature_rot() - * @param pnt The *absolute* position of the item in the world (see @ref map::getabs), - * @param spoil_multiplier the multiplier for spoilage rate, based on what this item is inside of. - * used for rot calculation. - * @return true if the item has rotten away and should be removed, false otherwise. - */ - bool has_rotten_away( const tripoint &pnt, float spoil_multiplier = 1.0f, - temperature_flag flag = temperature_flag::NORMAL ); /** * Accumulate rot of the item since last rot calculation. diff --git a/src/item_contents.cpp b/src/item_contents.cpp index 8b14c7a56126b..8444a9e7484d7 100644 --- a/src/item_contents.cpp +++ b/src/item_contents.cpp @@ -1223,16 +1223,6 @@ units::volume item_contents::total_contained_volume() const return total_vol; } -void item_contents::remove_rotten( const tripoint &pnt ) -{ - for( item_pocket &pocket : contents ) { - // no reason to check mods, they won't rot - if( !pocket.is_type( item_pocket::pocket_type::MOD ) ) { - pocket.remove_rotten( pnt ); - } - } -} - void item_contents::remove_internal( const std::function &filter, int &count, std::list &res ) { diff --git a/src/item_contents.h b/src/item_contents.h index 9c8570bd79d84..6152a79240323 100644 --- a/src/item_contents.h +++ b/src/item_contents.h @@ -208,7 +208,6 @@ class item_contents bool has_any_with( const std::function &filter, item_pocket::pocket_type pk_type ) const; - void remove_rotten( const tripoint &pnt ); /** * Is part of the recursive call of item::process. see that function for additional comments * NOTE: this destroys the items that get processed diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index 18817b04c191c..c5b35ee712b34 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -1214,17 +1214,6 @@ void item_pocket::has_rotten_away() } } -void item_pocket::remove_rotten( const tripoint &pnt ) -{ - for( auto iter = contents.begin(); iter != contents.end(); ) { - if( iter->has_rotten_away( pnt, spoil_multiplier() ) ) { - iter = contents.erase( iter ); - } else { - ++iter; - } - } -} - void item_pocket::process( player *carrier, const tripoint &pos, float insulation, temperature_flag flag, float spoil_multiplier_parent ) { diff --git a/src/item_pocket.h b/src/item_pocket.h index 376f33f2fafe5..de8a667073027 100644 --- a/src/item_pocket.h +++ b/src/item_pocket.h @@ -219,7 +219,6 @@ class item_pocket item *get_item_with( const std::function &filter ); void remove_items_if( const std::function &filter ); void has_rotten_away(); - void remove_rotten( const tripoint &pnt ); /** * Is part of the recursive call of item::process. see that function for additional comments * NOTE: this destroys the items that get processed From c7e0c743e97f018edf864ad003d1011e2ba37843 Mon Sep 17 00:00:00 2001 From: Hirmuolio Date: Thu, 16 Jul 2020 18:54:38 +0300 Subject: [PATCH 077/151] remove unused rotten_away --- src/item_pocket.cpp | 11 ----------- src/item_pocket.h | 1 - 2 files changed, 12 deletions(-) diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index c5b35ee712b34..2c039a2fd070c 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -1203,17 +1203,6 @@ void item_pocket::remove_items_if( const std::function &filter ) on_contents_changed(); } -void item_pocket::has_rotten_away() -{ - for( auto it = contents.begin(); it != contents.end(); ) { - if( it->has_rotten_away() ) { - it = contents.erase( it ); - } else { - ++it; - } - } -} - void item_pocket::process( player *carrier, const tripoint &pos, float insulation, temperature_flag flag, float spoil_multiplier_parent ) { diff --git a/src/item_pocket.h b/src/item_pocket.h index de8a667073027..48755168ee0a5 100644 --- a/src/item_pocket.h +++ b/src/item_pocket.h @@ -218,7 +218,6 @@ class item_pocket bool has_item( const item &it ) const; item *get_item_with( const std::function &filter ); void remove_items_if( const std::function &filter ); - void has_rotten_away(); /** * Is part of the recursive call of item::process. see that function for additional comments * NOTE: this destroys the items that get processed From 86319d7c568d70120c6c6082fa0343a41cab1498 Mon Sep 17 00:00:00 2001 From: Hirmuolio Date: Thu, 16 Jul 2020 19:01:22 +0300 Subject: [PATCH 078/151] do not set item temperature >2d ago --- src/item.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 8ac3691591924..efaa388462ed3 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -8982,11 +8982,8 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, } // Calculate item temperature from environment temperature - // If the time was more than 2 d ago just set the item to environment temperature - if( now - time > 2_days ) { - // This value shouldn't be there anymore after the loop is done so we don't bother with the set_item_temperature() - temperature = static_cast( 100000 * temp_to_kelvin( env_temperature ) ); - } else { + // If the time was more than 2 d ago we do not care about item temperature. + if( now - time < 2_days ) { calc_temp( env_temperature, insulation, time_delta ); } last_temp_check = time; From 715806bd18b7a146b4f2f7e23bae90cf0164b038 Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Thu, 16 Jul 2020 16:45:34 -0400 Subject: [PATCH 079/151] enchantments can have mutations --- src/magic_enchantment.cpp | 8 ++++++++ src/magic_enchantment.h | 5 +++++ src/newcharacter.cpp | 14 ++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index b4fb44ef4e478..e9c1cd1da5d38 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -227,6 +227,8 @@ void enchantment::load( const JsonObject &jo, const std::string & ) ench_effects.emplace( efftype_id( jsobj.get_string( "effect" ) ), jsobj.get_int( "intensity" ) ); } + optional( jo, was_loaded, "mutations", mutations ); + if( jo.has_array( "values" ) ) { for( const JsonObject value_obj : jo.get_array( "values" ) ) { const enchant_vals::mod value = io::string_to_enum @@ -282,6 +284,8 @@ void enchantment::serialize( JsonOut &jsout ) const jsout.end_object(); } + jsout.member( "mutations", mutations ); + jsout.member( "values" ); jsout.start_array(); for( int value = 0; value < static_cast( enchant_vals::mod::NUM_MOD ); value++ ) { @@ -339,6 +343,10 @@ void enchantment::force_add( const enchantment &rhs ) emitter = rhs.emitter; } + for( const trait_id &branch : rhs.mutations ) { + mutations.emplace( branch ); + } + for( const std::pair> &act_pair : rhs.intermittent_activation ) { for( const fake_spell &fake : act_pair.second ) { diff --git a/src/magic_enchantment.h b/src/magic_enchantment.h index a05b0aa27a7b7..b921080af5897 100644 --- a/src/magic_enchantment.h +++ b/src/magic_enchantment.h @@ -163,7 +163,12 @@ class enchantment void cast_hit_you( Character &caster, const Creature &target ) const; // casts all the hit_me_effects on self or a target depending on the enchantment definition void cast_hit_me( Character &caster, const Creature *target ) const; + + std::set get_mutations() const { + return mutations; + } private: + std::set mutations; cata::optional emitter; std::map ench_effects; // values that add to the base value diff --git a/src/newcharacter.cpp b/src/newcharacter.cpp index fb035bf7172b0..b384a66abd36f 100644 --- a/src/newcharacter.cpp +++ b/src/newcharacter.cpp @@ -2894,6 +2894,20 @@ std::vector Character::get_mutations( bool include_hidden ) const result.push_back( t.first ); } } + for( const trait_id &ench_trait : enchantment_cache.get_mutations() ) { + if( include_hidden || ench_trait->player_display ) { + bool found = false; + for( const trait_id &exist : result ) { + if( exist == ench_trait ) { + found = true; + break; + } + } + if( !found ) { + result.push_back( ench_trait ); + } + } + } return result; } From b2945da825ffbf6114f3c4c28c06bad24a5bcc60 Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Thu, 16 Jul 2020 17:39:18 -0400 Subject: [PATCH 080/151] create architect's cube json and modify debug for it --- data/json/artifact/premade_artifacts.json | 15 ++++++++++++ data/json/mutations/mutations.json | 10 ++++++++ src/artifact.cpp | 29 ----------------------- src/artifact.h | 1 - src/character.cpp | 11 +++------ src/debug_menu.cpp | 2 +- 6 files changed, 29 insertions(+), 39 deletions(-) create mode 100644 data/json/artifact/premade_artifacts.json diff --git a/data/json/artifact/premade_artifacts.json b/data/json/artifact/premade_artifacts.json new file mode 100644 index 0000000000000..93fbd6e2f8813 --- /dev/null +++ b/data/json/artifact/premade_artifacts.json @@ -0,0 +1,15 @@ +[ + { + "id": "architect_cube", + "type": "TOOL", + "name": { "str": "The Architect's Cube" }, + "description": "This is a solid cube that is much heavier than its size suggests. When you look at it, it pulls your gaze inward until you fall through the sky, showing you a top-down view of your position with the surroundings revealed.", + "weight": "2 kg", + "volume": "100 ml", + "material": [ "iron" ], + "symbol": "]", + "relic_data": { "passive_effects": [ { "mutations": [ "DEBUG_CLAIRVOYANCE" ] } ] }, + "color": "light_gray", + "flags": [ "TRADER_AVOID" ] + } +] diff --git a/data/json/mutations/mutations.json b/data/json/mutations/mutations.json index f0c243de08e19..a501522c8174d 100644 --- a/data/json/mutations/mutations.json +++ b/data/json/mutations/mutations.json @@ -6645,6 +6645,16 @@ "description": "You can clearly see that this is for dev purposes only.", "debug": true }, + { + "type": "mutation", + "id": "DEBUG_CLAIRVOYANCE", + "name": { "str": "Debug Clairvoyance" }, + "points": 99, + "valid": false, + "description": "You can clearly see that this is for dev purposes only.", + "flags": [ "SUPER_CLAIRVOYANCE" ], + "debug": true + }, { "type": "mutation", "id": "DEBUG_CLOAK", diff --git a/src/artifact.cpp b/src/artifact.cpp index 9746a4f6cff6d..59ef084ec1cec 100644 --- a/src/artifact.cpp +++ b/src/artifact.cpp @@ -1031,35 +1031,6 @@ itype_id new_natural_artifact( artifact_natural_property prop ) return def.get_id(); } -// Make a special debugging artifact. -itype_id architects_cube() -{ - it_artifact_tool def; - - const artifact_tool_form_datum &info = artifact_tool_form_data[ARTTOOLFORM_CUBE]; - def.create_name( _( info.name ) ); - def.color = info.color; - def.sym = std::string( 1, info.sym ); - def.materials.push_back( info.material ); - def.volume = rng( info.volume_min, info.volume_max ); - def.weight = rng( info.weight_min, info.weight_max ); - // Set up the basic weapon type - const artifact_weapon_datum &weapon = artifact_weapon_data[info.base_weapon]; - def.melee[DT_BASH] = rng( weapon.bash_min, weapon.bash_max ); - def.melee[DT_CUT] = rng( weapon.cut_min, weapon.cut_max ); - def.m_to_hit = rng( weapon.to_hit_min, weapon.to_hit_max ); - if( !weapon.tag.empty() ) { - def.item_tags.insert( weapon.tag ); - } - // Add an extra weapon perhaps? - // Most artifact descriptions are generated and stored using `no_translation`, - // also do it here for consistency - def.description = no_translation( _( "The architect's cube." ) ); - def.artifact->effects_carried.push_back( AEP_SUPER_CLAIRVOYANCE ); - item_controller->add_item_type( static_cast( def ) ); - return def.get_id(); -} - std::vector fill_good_passive() { std::vector ret; diff --git a/src/artifact.h b/src/artifact.h index 40829bac967f3..eab6738584dba 100644 --- a/src/artifact.h +++ b/src/artifact.h @@ -123,7 +123,6 @@ class it_artifact_armor : public itype itype_id new_artifact(); itype_id new_natural_artifact( artifact_natural_property prop ); -itype_id architects_cube(); // note: needs to be called by main() before MAPBUFFER.load void load_artifacts( const std::string &path ); diff --git a/src/character.cpp b/src/character.cpp index 861be980d2be2..a06a7fdf2800b 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -1879,16 +1879,11 @@ void Character::recalc_sight_limits() vision_mode_cache.set( IR_VISION ); } - // Since this is called from the player constructor, - // these are going to resolve to Character::has_artifact_with() anyway - // This case should be harmless to apply artifact effects to NPCs. - if( Character::has_artifact_with( AEP_SUPER_CLAIRVOYANCE ) ) { + if( has_trait_flag( "SUPER_CLAIRVOYANCE" ) ) { vision_mode_cache.set( VISION_CLAIRVOYANCE_SUPER ); - } - if( Character::has_artifact_with( AEP_CLAIRVOYANCE_PLUS ) ) { + } else if( has_trait_flag( "CLAIRVOYANCE_PLUS" ) ) { vision_mode_cache.set( VISION_CLAIRVOYANCE_PLUS ); - } - if( Character::has_artifact_with( AEP_CLAIRVOYANCE ) ) { + } else if( has_trait_flag( "CLAIRVOYANCE" ) ) { vision_mode_cache.set( VISION_CLAIRVOYANCE ); } } diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index 1e8b82d33aacb..0c89ee1ebf04a 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -1424,7 +1424,7 @@ void debug() break; case debug_menu_index::SPAWN_CLAIRVOYANCE: - player_character.i_add( item( architects_cube(), calendar::turn ) ); + player_character.i_add( item( "architect_cube", calendar::turn ) ); break; case debug_menu_index::MAP_EDITOR: From e21032c9f7a50273ca2ba793db88298879cce3d7 Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Thu, 16 Jul 2020 17:51:05 -0400 Subject: [PATCH 081/151] bugfix - enchantments can be "held" the enchantment_cache recalculation only checked worn and wielded items, but items also had a third option for "has" which is HELD - it means it can just be in your inventory and confers the effects. visit_items is the perfect vehicle to use for this --- src/character.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index a06a7fdf2800b..db79ebb26c2ca 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -8469,19 +8469,14 @@ void Character::recalculate_enchantment_cache() // start by resetting the cache to all inventory items enchantment_cache = inv.get_active_enchantment_cache( *this ); - for( const enchantment &ench : weapon.get_enchantments() ) { - if( ench.is_active( *this, weapon ) ) { - enchantment_cache.force_add( ench ); - } - } - - for( const item &worn_it : worn ) { - for( const enchantment &ench : worn_it.get_enchantments() ) { - if( ench.is_active( *this, worn_it ) ) { + visit_items( [&]( const item * it ) { + for( const enchantment &ench : it->get_enchantments() ) { + if( ench.is_active( *this, *it ) ) { enchantment_cache.force_add( ench ); } } - } + return VisitResponse::NEXT; + } ); // get from traits/ mutations for( const std::pair &mut_map : my_mutations ) { From 04f541bbf2c1768f89c138364dd9369dc7e73e90 Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Thu, 16 Jul 2020 21:35:29 -0600 Subject: [PATCH 082/151] Rework Cryosleep Survivor profession --- data/mods/Aftershock/items/tool_armor.json | 57 +++++++++++++++++++ data/mods/Aftershock/mutations/mutations.json | 2 +- data/mods/Aftershock/player/professions.json | 4 +- 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 data/mods/Aftershock/items/tool_armor.json diff --git a/data/mods/Aftershock/items/tool_armor.json b/data/mods/Aftershock/items/tool_armor.json new file mode 100644 index 0000000000000..e1bbb5f9f1d69 --- /dev/null +++ b/data/mods/Aftershock/items/tool_armor.json @@ -0,0 +1,57 @@ +[ + { + "id": "afs_cryopod_bodyglove", + "type": "TOOL_ARMOR", + "category": "clothing", + "symbol": "[", + "color": "light_gray", + "name": { "str": "cryopod bodyglove" }, + "looks_like": "jumpsuit", + "description": "A dark orange bodyglove, hundreds of tubes curl over its surface, tracing the contours of human musculature. Meant to control body temperature during prolonged cryopreservation, it could easily keep you comfortable in any earthly climate. Use it to activate its climate control functionality.", + "price": 1500000, + "price_postapoc": 150000, + "material": [ "graphene_weave" ], + "weight": "1250 g", + "volume": "4500 ml", + "charges_per_use": 5, + "ammo": "battery", + "pocket_data": [ + { + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "rigid": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "medium_battery_cell", "medium_plus_battery_cell", "medium_atomic_battery_cell", "medium_disposable_cell" ] + } + ], + "use_action": { + "type": "transform", + "msg": "You activate your %s.", + "target": "afs_cryopod_bodyglove_on", + "active": true, + "need_charges": 5, + "need_charges_msg": "The %s's batteries are dead." + }, + "covers": [ "HEAD", "MOUTH", "EYES", "TORSO", "ARMS", "HANDS", "LEGS", "FEET" ], + "warmth": 20, + "environmental_protection": 10, + "coverage": 100, + "material_thickness": 1, + "encumbrance": 5, + "flags": [ "VARSIZE", "SKINTIGHT", "RAINPROOF", "STURDY", "WATERPROOF", "HYGROMETER" ] + }, + { + "id": "afs_cryopod_bodyglove_on", + "copy-from": "afs_cryopod_bodyglove", + "repairs_like": "afs_cryopod_bodyglove", + "type": "TOOL_ARMOR", + "name": { "str": "cryopod bodyglove (on)", "str_pl": "cryopod bodygloves (on)" }, + "looks_like": "afs_cryopod_bodyglove", + "description": "The temperature control units of this high-tech garment are currently active, and continuously draining battery power. Use it to turn them off.", + "power_draw": 90000, + "revert_to": "afs_cryopod_bodyglove", + "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "afs_cryopod_bodyglove" }, + "flags": [ "STURDY", "WATERPROOF", "THERMOMETER", "RAINPROOF", "CLIMATE_CONTROL" ] + } +] diff --git a/data/mods/Aftershock/mutations/mutations.json b/data/mods/Aftershock/mutations/mutations.json index f95792dc2e8db..d588cddee04f6 100644 --- a/data/mods/Aftershock/mutations/mutations.json +++ b/data/mods/Aftershock/mutations/mutations.json @@ -644,7 +644,7 @@ "id": "AFS_CRYOADAPTATION", "name": { "str": "Cryoadaptation" }, "description": "An experimental cryosleep procedure has permanently altered your body, allowing you to better tolerate cold temperatures.", - "bodytemp_modifiers": [ 50, 100 ], + "bodytemp_modifiers": [ -850, 850 ], "points": 0, "valid": false, "purifiable": false, diff --git a/data/mods/Aftershock/player/professions.json b/data/mods/Aftershock/player/professions.json index c1f586a2ec1a9..3795c4d5fca29 100644 --- a/data/mods/Aftershock/player/professions.json +++ b/data/mods/Aftershock/player/professions.json @@ -28,7 +28,9 @@ "description": "A sudden power failure woke you from the cryosleep sarcophagus in which you had entombed yourself lifetimes ago. It seems the emergency reanimation procedure has damaged your memory, and now, bearing almost no knowledge of your past life, you must find a way to survive in a ruined and alien world.", "points": 2, "traits": [ "AFS_CRYOADAPTATION" ], - "items": { "both": [ "jumpsuit", "boots_winter", "under_armor", "under_armor_shorts", "gloves_wool" ] } + "items": { + "both": { "entries": [ { "item": "afs_cryopod_bodyglove", "ammo-item": "medium_atomic_battery_cell", "charges": 5000 } ] } + } }, { "type": "profession", From 1c0cdeb00ccdba701551f7459e759c8a347278c2 Mon Sep 17 00:00:00 2001 From: mqrause Date: Tue, 14 Jul 2020 20:32:57 +0200 Subject: [PATCH 083/151] fix volume calculation for nested and rigid containers --- src/character.cpp | 52 +++++++++++++++++++++++++++++++++++------------ src/character.h | 4 ++++ 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index 861be980d2be2..32ff326cae7d0 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -3067,30 +3067,56 @@ units::volume Character::volume_carried_with_tweaks( const item_tweaks &tweaks ) units::volume ret = 0_ml; for( auto &i : worn ) { if( !without.count( &i ) ) { - for( auto j : i.contents.all_items_top( item_pocket::pocket_type::CONTAINER ) ) { - if( j->count_by_charges() ) { - ret += j->volume() - get_selected_stack_volume( j, without ); - } else if( !without.count( j ) ) { - ret += j->volume(); - } - } + ret += get_contents_volume_with_tweaks( &i.contents, without ); } } // Wielded item if( !without.count( &weapon ) ) { - for( auto i : weapon.contents.all_items_top( item_pocket::pocket_type::CONTAINER ) ) { - if( i->count_by_charges() ) { - ret += i->volume() - get_selected_stack_volume( i, without ); - } else if( !without.count( i ) ) { - ret += i->volume(); - } + ret += get_contents_volume_with_tweaks( &weapon.contents, without ); + } + + return ret; +} + +units::volume Character::get_contents_volume_with_tweaks( const item_contents *contents, + const std::map &without ) const +{ + units::volume ret = 0_ml; + + for( auto i : contents->all_items_top( item_pocket::pocket_type::CONTAINER ) ) { + if( i->count_by_charges() ) { + ret += i->volume() - get_selected_stack_volume( i, without ); + } else if( !without.count( i ) ) { + ret += i->volume(); + ret -= get_nested_content_volume_recursive( &i->contents, without ); } } return ret; } +units::volume Character::get_nested_content_volume_recursive( const item_contents *contents, + const std::map &without ) const +{ + units::volume ret = 0_ml; + + for( auto i : contents->all_items_top( item_pocket::pocket_type::CONTAINER ) ) { + if( i->count_by_charges() ) { + ret += get_selected_stack_volume( i, without ); + } else if( without.count( i ) ) { + ret += i->volume(); + } else { + ret += get_nested_content_volume_recursive( &i->contents, without ); + } + } + if( contents->all_pockets_rigid() ) { + ret += contents->remaining_container_capacity(); + } + + return ret; +} + units::volume Character::get_selected_stack_volume( const item *i, const std::map &without ) const { diff --git a/src/character.h b/src/character.h index 9c7a81ccbab6a..041c78e592965 100644 --- a/src/character.h +++ b/src/character.h @@ -1452,6 +1452,10 @@ class Character : public Creature, public visitable units::volume volume_carried_with_tweaks( const item_tweaks &tweaks ) const; units::volume volume_carried_with_tweaks( const std::vector> &locations ) const; + units::volume get_contents_volume_with_tweaks( const item_contents *contents, + const std::map &without ) const; + units::volume get_nested_content_volume_recursive( const item_contents *contents, + const std::map &without ) const; units::volume get_selected_stack_volume( const item *i, const std::map &without ) const; units::mass weight_capacity() const override; From a9bcec189655a9015748a338030297239319602d Mon Sep 17 00:00:00 2001 From: Qrox Date: Wed, 15 Jul 2020 22:25:05 +0800 Subject: [PATCH 084/151] Fix crash when unloading wielded tool with battery when another empty tool that can contain the battery is in inventory --- src/player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player.cpp b/src/player.cpp index 8a149a52fdc66..395a36bd92e1b 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -2757,7 +2757,7 @@ bool player::add_or_drop_with_msg( item &it, const bool /*unloading*/, const ite } else if( !this->can_pickWeight( it, !get_option( "DANGEROUS_PICKUPS" ) ) ) { put_into_vehicle_or_drop( *this, item_drop_reason::too_heavy, { it } ); } else { - const bool allow_wield = !weapon.has_item( it ); + const bool allow_wield = !weapon.has_item( it ) && weapon.magazine_current() != ⁢ const int prev_charges = it.charges; auto &ni = this->i_add( it, true, avoid, /*allow_drop=*/false, /*allow_wield=*/allow_wield ); if( ni.is_null() ) { From a3cf22eecd567e72abe8a030db0280c26ddb2233 Mon Sep 17 00:00:00 2001 From: johnrdconnolly <59102789+johnrdconnolly@users.noreply.github.com> Date: Wed, 15 Jul 2020 17:14:25 -0700 Subject: [PATCH 085/151] Update electronics.json add longest_side where applicable --- data/json/items/tool/electronics.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/json/items/tool/electronics.json b/data/json/items/tool/electronics.json index 8620d9f8e610b..6d1befd646140 100644 --- a/data/json/items/tool/electronics.json +++ b/data/json/items/tool/electronics.json @@ -155,6 +155,7 @@ "description": "This is an antenna designed to pick up signals better when pointed at the source. You could use this with a radio to receive faint signals.", "weight": "454 g", "volume": "500 ml", + "longest_side": "60 cm", "price": 800, "price_postapoc": 250, "to_hit": 1, @@ -189,6 +190,7 @@ "description": "A tablet PC using an efficient color e-ink display. Before the Cataclysm, these were nifty gadgets; now, it's an almost priceless resource. Runs on conventional batteries.", "weight": "250 g", "volume": "250 ml", + "longest_side": "25 cm", "price": 20000, "price_postapoc": 100, "to_hit": -1, @@ -345,6 +347,7 @@ "material": [ "plastic", "aluminum" ], "weight": "2721 g", "volume": "2500 ml", + "longest_side": "40 cm", "price": 75000, "price_postapoc": 250, "bashing": 6, @@ -601,6 +604,7 @@ "description": "This battery-devouring device is just the thing to knead the tension out and help you relax. Use it to take a break and unwind.", "weight": "453 g", "volume": "500 ml", + "longest_side": "25 cm", "price": 5500, "price_postapoc": 100, "material": [ "aluminum", "plastic" ], From f011e2f2eb0662421dbfe4d1468635670e85dbfd Mon Sep 17 00:00:00 2001 From: DialoMalison Date: Thu, 16 Jul 2020 03:46:53 -0400 Subject: [PATCH 086/151] Fix Barrett length --- data/json/items/gun/50.json | 1 + 1 file changed, 1 insertion(+) diff --git a/data/json/items/gun/50.json b/data/json/items/gun/50.json index a3d2580414955..8a65d30d2f109 100644 --- a/data/json/items/gun/50.json +++ b/data/json/items/gun/50.json @@ -9,6 +9,7 @@ "description": "A large, shoulder-fired, .50 caliber anti-materiel rifle. Its large size, recoil, and noise is offset by its damage and range.", "weight": "12602 g", "volume": "3500 ml", + "longest_side": "122 cm", "price": 1483300, "price_postapoc": 12000, "to_hit": -1, From 02a3e04ab42ecc27515b85583597003ad68e2b98 Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Thu, 16 Jul 2020 23:22:14 -0600 Subject: [PATCH 087/151] Replace plutonium generator in microlab reactor room (#42209) --- data/json/mapgen/microlab/microlab_reactor.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data/json/mapgen/microlab/microlab_reactor.json b/data/json/mapgen/microlab/microlab_reactor.json index c68075f8e6209..d9b8000b6bdd1 100644 --- a/data/json/mapgen/microlab/microlab_reactor.json +++ b/data/json/mapgen/microlab/microlab_reactor.json @@ -39,7 +39,8 @@ ], "palettes": [ "microlab" ], "items": { "d": { "item": "cop_armory", "chance": 5 }, "l": { "item": "decontamination_room", "chance": 70 } }, - "terrain": { "-": "t_wall_metal", "`": "t_hole", "#": "t_rock", "G": "t_card_science", "g": "t_bridge", "A": "t_plut_generator" } + "terrain": { "-": "t_wall_metal", "`": "t_hole", "#": "t_rock", "G": "t_card_science", "g": "t_bridge", "A": "t_bridge" }, + "furniture": { "A": "f_compact_ASRG" } } }, { @@ -78,7 +79,8 @@ { "square": "radiation", "amount": 10000, "x": 9, "y": 5, "x2": 14, "y2": 8 } ], "palettes": [ "microlab" ], - "terrain": { "-": "t_wall_metal", "#": "t_rock", "g": "t_bridge", "A": "t_plut_generator", "w": "t_water_pool" } + "terrain": { "-": "t_wall_metal", "#": "t_rock", "g": "t_bridge", "A": "t_bridge", "w": "t_water_pool" }, + "furniture": { "A": "f_compact_ASRG" } } } ] From 7b49034b11cacc02e8033a36b2e6ede5e5db32d2 Mon Sep 17 00:00:00 2001 From: johnrdconnolly <59102789+johnrdconnolly@users.noreply.github.com> Date: Thu, 16 Jul 2020 10:15:10 -0700 Subject: [PATCH 088/151] add longest_side to fishing.json --- data/json/items/tool/fishing.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data/json/items/tool/fishing.json b/data/json/items/tool/fishing.json index fd81ac3ca3b6a..c1d4c80720605 100644 --- a/data/json/items/tool/fishing.json +++ b/data/json/items/tool/fishing.json @@ -52,6 +52,7 @@ "description": "'Fishing rod' might be a bit too charitable of a description. In truth, this is a stick with a piece of string and a hook.", "weight": "1700 g", "volume": "1250 ml", + "longest_side": "90 cm", "price": 0, "price_postapoc": 10, "to_hit": -3, @@ -61,7 +62,7 @@ "color": "brown", "use_action": [ "FISH_ROD" ], "qualities": [ [ "FISHING", 1 ] ], - "flags": [ "FISH_POOR" ] + "flags": [ "FISH_POOR", "SHEATH_SPEAR" ] }, { "id": "fishing_rod_professional", @@ -70,6 +71,7 @@ "description": "A professional fishing rod with a matching set of weights. With this you should be able to catch 'em all.", "weight": "1000 g", "volume": "1250 ml", + "longest_side": "200 cm", "price": 20000, "price_postapoc": 1500, "to_hit": 2, @@ -79,6 +81,6 @@ "color": "brown", "use_action": [ "FISH_ROD" ], "qualities": [ [ "FISHING", 2 ] ], - "flags": [ "FISH_GOOD" ] + "flags": [ "FISH_GOOD", "SHEATH_SPEAR" ] } ] From c81ee7242b152979a9ffe2cf301e496a26fc5c3f Mon Sep 17 00:00:00 2001 From: johnrdconnolly <59102789+johnrdconnolly@users.noreply.github.com> Date: Thu, 16 Jul 2020 10:19:07 -0700 Subject: [PATCH 089/151] add longest_side to handloading.json --- data/json/items/tool/handloading.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/data/json/items/tool/handloading.json b/data/json/items/tool/handloading.json index cf5d160b9bf58..80b54615c84ef 100644 --- a/data/json/items/tool/handloading.json +++ b/data/json/items/tool/handloading.json @@ -6,6 +6,7 @@ "description": "This is a small hand press for hand loading firearm ammunition. It comes with everything you need to start hand loading your own munitions.", "weight": "6350 g", "volume": "500 ml", + "longest_side": "30 cm", "price": 10000, "price_postapoc": 2000, "to_hit": -2, @@ -21,6 +22,7 @@ "description": "This is a collection of items improvised for field reloading of shotshells. A plank with a hole cut in the center, a medium-sized nail, and a whittled dowel are used to seat wads, decap primers, and reprime (carefully!) hulls. Powder and shot are measured with a cut down fired shotshell. The opposite side of the plank has been shaped to allow for roll crimping of the plastic hulls. There's no provision for resizing, so reloaded hulls will fire best in the firearm they were fired from.", "weight": "348 g", "volume": "250 ml", + "longest_side": "30 cm", "price": 600, "price_postapoc": 1500, "to_hit": -2, @@ -37,6 +39,7 @@ "description": "This is a tool used for properly disassembling firearm ammunition.", "weight": "489 g", "volume": "250 ml", + "longest_side": "35 cm", "price": 1000, "price_postapoc": 2000, "bashing": 5, From 0b001f6f8b0fd15427b215566b6c369d4835613f Mon Sep 17 00:00:00 2001 From: DialoMalison Date: Fri, 17 Jul 2020 03:02:02 -0400 Subject: [PATCH 090/151] Update glass items in containers.json --- data/json/items/containers.json | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/data/json/items/containers.json b/data/json/items/containers.json index f591fcd4e6e52..ea20682ce26fc 100644 --- a/data/json/items/containers.json +++ b/data/json/items/containers.json @@ -255,8 +255,9 @@ "name": { "str": "glass bottle" }, "looks_like": "bottle_plastic", "description": "A resealable glass bottle, holds 750 ml of liquid.", - "weight": "200 g", - "volume": "787 ml", + "weight": "450 g", + "volume": "1734 ml", + "longest_side": "276 mm", "price": 0, "price_postapoc": 10, "to_hit": 1, @@ -871,7 +872,8 @@ "looks_like": "bottle_glass", "description": "A 250 ml laboratory conical flask, with a rubber bung.", "weight": "48 g", - "volume": "251 ml", + "volume": "700 ml", + "longest_side": "132 mm", "price": 400, "price_postapoc": 10, "to_hit": 1, @@ -898,7 +900,8 @@ "looks_like": "flask_glass", "description": "A 10ml laboratory cylindrical test tube, with a rubber stopper.", "weight": "36 g", - "volume": "11ml", + "volume": "92 ml", + "longest_side": "100 mm", "price": 300, "price_postapoc": 10, "to_hit": -1, @@ -925,7 +928,8 @@ "looks_like": "flask_glass", "description": "A 250ml laboratory beaker. Basically a cup with delusions of grandeur.", "weight": "150 g", - "volume": "251ml", + "volume": "383 ml", + "longest_side": "72 mm", "price": 500, "price_postapoc": 10, "to_hit": -1, @@ -952,7 +956,8 @@ "looks_like": "flask_glass", "description": "A tall, narrow glass cylinder with precise markings for measuring fluid quantities. An important science tool, it is also useful for anal retentive chefs.", "weight": "150 g", - "volume": "101ml", + "volume": "528 ml", + "longest_side": "25 cm", "price": 500, "price_postapoc": 10, "to_hit": -1, @@ -1036,7 +1041,8 @@ "looks_like": "jar_glass", "description": "A three-liter glass jar with a metal screw top lid, used for canning.", "weight": "365 g", - "volume": "3003 ml", + "volume": "3352 ml", + "longest_side": "298 mm", "price": 0, "price_postapoc": 10, "to_hit": -1, @@ -1082,7 +1088,8 @@ "looks_like": "jar_glass", "description": "A half-liter glass jar with a metal screw top lid, used for canning.", "weight": "150 g", - "volume": "502 ml", + "volume": "704 ml", + "longest_side": "132 mm", "price": 0, "bashing": 4, "material": [ "glass" ], From 5a9cc5596191b08cc527709b3f9ae8d9682caf62 Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Thu, 16 Jul 2020 18:57:07 -0400 Subject: [PATCH 091/151] [AFS] bionic difficuly tweaks --- data/mods/Aftershock/options.json | 26 ++++++++++++++++++++++++++ src/game_inventory.cpp | 12 ++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 data/mods/Aftershock/options.json diff --git a/data/mods/Aftershock/options.json b/data/mods/Aftershock/options.json new file mode 100644 index 0000000000000..5b369d68858b2 --- /dev/null +++ b/data/mods/Aftershock/options.json @@ -0,0 +1,26 @@ +[ + { + "type": "furniture", + "id": "f_autodoc", + "name": "Autodoc Mk. XI", + "symbol": "&", + "color": "light_cyan", + "copy-from": "f_autodoc", + "flags": [ "TRANSPARENT", "AUTODOC" ], + "examine_action": "autodoc", + "//": "Easy installation", + "surgery_skill_multiplier": 999999 + }, + { + "id": "anesthetic", + "type": "requirement", + "//": "Anesthetic cost removed in this mod, as autodocs do all the heavy lifting.", + "tools": [ ] + }, + { + "type": "EXTERNAL_OPTION", + "name": "CBM_SLOTS_ENABLED", + "stype": "bool", + "value": true + } +] diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index 008d66446436d..56ec041e3e40e 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -1757,7 +1757,11 @@ class bionic_install_preset: public inventory_selector_preset const int duration = loc.get_item()->type->bionic->difficulty * 2; const requirement_data req_anesth = *requirement_id( "anesthetic" ) * duration * weight; - return string_format( _( "%i mL" ), req_anesth.get_tools().front().front().count ); + int count = 0; + if( !req_anesth.get_tools().empty() && !req_anesth.get_tools().front().empty() ) { + count = req_anesth.get_tools().front().front().count; + } + return string_format( _( "%i mL" ), count ); } }; @@ -1928,7 +1932,11 @@ class bionic_uninstall_preset : public inventory_selector_preset const int duration = loc.get_item()->type->bionic->difficulty * 2; const requirement_data req_anesth = *requirement_id( "anesthetic" ) * duration * weight; - return string_format( _( "%i mL" ), req_anesth.get_tools().front().front().count ); + int count = 0; + if( !req_anesth.get_tools().empty() && !req_anesth.get_tools().front().empty() ) { + count = req_anesth.get_tools().front().front().count; + } + return string_format( _( "%i mL" ), count ); } }; From 95881fd0dfd0ef9c80de0514bdb77bb3a11dfa25 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Thu, 16 Jul 2020 05:56:05 +0000 Subject: [PATCH 092/151] Global reference migration part 28 --- src/activity_handlers.cpp | 2 +- src/bionics.cpp | 47 ++++++++++++--------- src/cata_tiles.cpp | 2 +- src/character.cpp | 6 +-- src/debug_menu.cpp | 2 +- src/faction_camp.cpp | 43 +++++++++++-------- src/game.cpp | 9 ++++ src/game.h | 2 + src/game_inventory.cpp | 2 +- src/game_inventory.h | 2 +- src/gamemode_defense.cpp | 2 +- src/gamemode_tutorial.cpp | 2 +- src/handle_liquid.cpp | 43 +++++++++---------- src/iexamine.cpp | 2 +- src/item.cpp | 4 +- src/iuse.cpp | 2 +- src/pickup.cpp | 80 ++++++++++++++++++------------------ src/player.cpp | 2 +- src/player_display.cpp | 2 +- src/scenario.h | 3 ++ src/vehicle_use.cpp | 2 +- src/weather.cpp | 4 +- tests/new_character_test.cpp | 46 +++++++++++---------- 23 files changed, 171 insertions(+), 140 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 156b00eb61f2e..5d270b08c6279 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -1591,7 +1591,7 @@ void activity_handlers::fill_liquid_do_turn( player_activity *act, player *p ) liquid.charges = std::min( charges_per_second, liquid.charges ); const int original_charges = liquid.charges; if( liquid.has_temperature() && liquid.specific_energy < 0 ) { - liquid.set_item_temperature( std::max( temp_to_kelvin( g->weather.get_temperature( p->pos() ) ), + liquid.set_item_temperature( std::max( temp_to_kelvin( get_weather().get_temperature( p->pos() ) ), 277.15 ) ); } diff --git a/src/bionics.cpp b/src/bionics.cpp index 3737a80ea7810..57ad84e96230c 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -591,6 +591,7 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui ) }; item tmp_item; + avatar &player_character = get_avatar(); map &here = get_map(); // On activation effects go here if( bio.info().has_flag( flag_BIO_GUN ) ) { @@ -599,7 +600,8 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui ) if( close_bionics_ui ) { *close_bionics_ui = true; } - avatar_action::fire_ranged_bionic( g->u, item( bio.info().fake_item ), bio.info().power_activate ); + avatar_action::fire_ranged_bionic( player_character, item( bio.info().fake_item ), + bio.info().power_activate ); } else if( bio.info().has_flag( flag_BIO_WEAPON ) ) { if( weapon.has_flag( flag_NO_UNWIELD ) ) { cata::optional active_bio_weapon_index = active_bionic_weapon_index(); @@ -631,7 +633,7 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui ) weapon.invlet = '#'; if( bio.ammo_count > 0 ) { weapon.ammo_set( bio.ammo_loaded, bio.ammo_count ); - avatar_action::fire_wielded_weapon( g->u ); + avatar_action::fire_wielded_weapon( player_character ); } } else if( bio.id == bio_ears && has_active_bionic( bio_earplugs ) ) { add_msg_activate(); @@ -653,9 +655,9 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui ) } } else if( bio.id == bio_evap ) { add_msg_activate(); - const w_point weatherPoint = *g->weather.weather_precise; + const w_point weatherPoint = *get_weather().weather_precise; int humidity = get_local_humidity( weatherPoint.humidity, get_weather().weather_id, - g->is_sheltered( g->u.pos() ) ); + g->is_sheltered( player_character.pos() ) ); // thirst units = 5 mL int water_available = std::lround( humidity * 3.0 / 100.0 ); if( water_available == 0 ) { @@ -980,7 +982,7 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui ) if( !is_avatar() ) { return false; } - cata::optional target = lockpick_activity_actor::select_location( g->u ); + cata::optional target = lockpick_activity_actor::select_location( player_character ); if( target.has_value() ) { add_msg_activate(); item fake_lockpick = item( itype_pseudo_bio_picklock ); @@ -1013,7 +1015,7 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui ) } const oter_id &cur_om_ter = overmap_buffer.ter( global_omt_location() ); /* cache g->get_temperature( player location ) since it is used twice. No reason to recalc */ - const auto player_local_temp = g->weather.get_temperature( g->u.pos() ); + const auto player_local_temp = g->weather.get_temperature( player_character.pos() ); /* windpower defined in internal velocity units (=.01 mph) */ double windpower = 100.0f * get_local_windpower( g->weather.windspeed + vehwindspeed, cur_om_ter, pos(), g->weather.winddirection, g->is_sheltered( pos() ) ); @@ -1022,7 +1024,7 @@ bool Character::activate_bionic( int b, bool eff_only, bool *close_bionics_ui ) add_msg_if_player( m_info, _( "Relative Humidity: %s." ), print_humidity( get_local_humidity( weatherPoint.humidity, get_weather().weather_id, - g->is_sheltered( g->u.pos() ) ) ) ); + g->is_sheltered( player_character.pos() ) ) ) ); add_msg_if_player( m_info, _( "Pressure: %s." ), print_pressure( static_cast( weatherPoint.pressure ) ) ); add_msg_if_player( m_info, _( "Wind Speed: %.1f %s." ), @@ -1209,11 +1211,12 @@ bool Character::deactivate_bionic( int b, bool eff_only ) add_msg_if_player( m_neutral, _( "You deactivate your %s." ), bio.info().name ); } + Character &player_character = get_player_character(); // Deactivation effects go here if( bio.info().has_flag( flag_BIO_WEAPON ) ) { if( weapon.typeId() == bio.info().fake_item ) { add_msg_if_player( _( "You withdraw your %s." ), weapon.tname() ); - if( g->u.sees( pos() ) ) { + if( player_character.sees( pos() ) ) { add_msg_if_npc( m_info, _( " withdraws %s %s." ), disp_name( true ), weapon.tname() ); } @@ -1638,6 +1641,7 @@ static bool attempt_recharge( Character &p, bionic &bio, units::energy &amount, void Character::process_bionic( int b ) { bionic &bio = ( *my_bionics )[b]; + Character &player_character = get_player_character(); if( ( !bio.id->fuel_opts.empty() || bio.id->is_remote_fueled ) && bio.is_auto_start_on() ) { const float start_threshold = bio.get_auto_start_thresh(); std::vector fuel_available = get_fuel_available( bio.id ); @@ -1654,7 +1658,7 @@ void Character::process_bionic( int b ) } } if( !fuel_available.empty() && get_power_level() <= start_threshold * get_max_power_level() ) { - g->u.activate_bionic( b ); + player_character.activate_bionic( b ); } else if( get_power_level() <= start_threshold * get_max_power_level() && calendar::once_every( 1_hours ) ) { add_msg_player_or_npc( m_bad, _( "Your %s does not have enough fuel to use Auto Start." ), @@ -1777,7 +1781,7 @@ void Character::process_bionic( int b ) if( calendar::once_every( 5_minutes ) ) { const w_point weatherPoint = *get_weather().weather_precise; int humidity = get_local_humidity( weatherPoint.humidity, get_weather().weather_id, - g->is_sheltered( g->u.pos() ) ); + g->is_sheltered( player_character.pos() ) ); // in thirst units = 5 mL water int water_available = std::lround( humidity * 3.0 / 100.0 ); // At 50% relative humidity or more, the player will draw 10 mL @@ -2120,7 +2124,7 @@ int bionic_success_chance( bool autodoc, int skill_level, int difficulty, const // bionic manipulation chance of success int bionic_manip_cos( float adjusted_skill, int bionic_difficulty ) { - if( g->u.has_trait( trait_DEBUG_BIONICS ) ) { + if( get_player_character().has_trait( trait_DEBUG_BIONICS ) ) { return 100; } @@ -2162,8 +2166,9 @@ bool Character::can_uninstall_bionic( const bionic_id &b_id, player &installer, return false; } + Character &player_character = get_player_character(); if( ( b_id == bio_reactor ) || ( b_id == bio_advreactor ) ) { - if( !g->u.query_yn( + if( !player_character.query_yn( _( "WARNING: Removing a reactor may leave radioactive material! Remove anyway?" ) ) ) { return false; } @@ -2188,13 +2193,13 @@ bool Character::can_uninstall_bionic( const bionic_id &b_id, player &installer, installer ); if( chance_of_success >= 100 ) { - if( !g->u.query_yn( + if( !player_character.query_yn( _( "Are you sure you wish to uninstall the selected bionic?" ), 100 - chance_of_success ) ) { return false; } } else { - if( !g->u.query_yn( + if( !player_character.query_yn( _( "WARNING: %i percent chance of SEVERE damage to all body parts! Continue anyway?" ), ( 100 - static_cast( chance_of_success ) ) ) ) { return false; @@ -2294,8 +2299,9 @@ void Character::perform_uninstall( const bionic_id &bid, int difficulty, int suc bool Character::uninstall_bionic( const bionic &target_cbm, monster &installer, player &patient, float adjusted_skill ) { + Character &player_character = get_player_character(); if( installer.ammo[itype_anesthetic] <= 0 ) { - if( g->u.sees( installer ) ) { + if( player_character.sees( installer ) ) { add_msg( _( "The %s's anesthesia kit looks empty." ), installer.name() ); } return false; @@ -2316,7 +2322,7 @@ bool Character::uninstall_bionic( const bionic &target_cbm, monster &installer, if( patient.is_player() ) { add_msg( m_bad, _( "You feel a tiny pricking sensation in your right arm, and lose all sensation before abruptly blacking out." ) ); - } else if( g->u.sees( installer ) ) { + } else if( player_character.sees( installer ) ) { add_msg( m_bad, _( "The %1$s gently inserts a syringe into %2$s's arm and starts injecting something while holding them down." ), installer.name(), patient.disp_name() ); @@ -2329,7 +2335,7 @@ bool Character::uninstall_bionic( const bionic &target_cbm, monster &installer, if( patient.is_player() ) { add_msg( _( "You fall asleep and %1$s starts operating." ), installer.disp_name() ); - } else if( g->u.sees( patient ) ) { + } else if( player_character.sees( patient ) ) { add_msg( _( "%1$s falls asleep and %2$s starts operating." ), patient.disp_name(), installer.disp_name() ); } @@ -2339,7 +2345,7 @@ bool Character::uninstall_bionic( const bionic &target_cbm, monster &installer, if( patient.is_player() ) { add_msg( m_neutral, _( "Your parts are jiggled back into their familiar places." ) ); add_msg( m_mixed, _( "Successfully removed %s." ), target_cbm.info().name ); - } else if( patient.is_npc() && g->u.sees( patient ) ) { + } else if( patient.is_npc() && player_character.sees( patient ) ) { add_msg( m_neutral, _( "%s's parts are jiggled back into their familiar places." ), patient.disp_name() ); add_msg( m_mixed, _( "Successfully removed %s." ), target_cbm.info().name ); @@ -2417,14 +2423,15 @@ bool Character::can_install_bionics( const itype &type, Character &installer, bo return false; } + Character &player_character = get_player_character(); if( chance_of_success >= 100 ) { - if( !g->u.query_yn( + if( !player_character.query_yn( _( "Are you sure you wish to install the selected bionic?" ), 100 - chance_of_success ) ) { return false; } } else { - if( !g->u.query_yn( + if( !player_character.query_yn( _( "WARNING: %i percent chance of failure that may result in damage, pain, or a faulty installation! Continue anyway?" ), ( 100 - chance_of_success ) ) ) { return false; diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index 219f8781167d0..d9da726652137 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -1164,7 +1164,7 @@ void cata_tiles::draw( const point &dest, const tripoint ¢er, int width, int // Add temperature value to the overlay_strings list for every visible tile when displaying temperature if( g->display_overlay_state( ACTION_DISPLAY_TEMPERATURE ) && !invisible[0] ) { - int temp_value = g->weather.get_temperature( pos ); + int temp_value = get_weather().get_temperature( pos ); int ctemp = temp_to_celsius( temp_value ); short color; const short bold = 8; diff --git a/src/character.cpp b/src/character.cpp index 32ff326cae7d0..1fc0a1ee136f1 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -5306,7 +5306,7 @@ needs_rates Character::calc_needs_rates() const if( has_trait( trait_TRANSPIRATION ) ) { // Transpiration, the act of moving nutrients with evaporating water, can take a very heavy toll on your thirst when it's really hot. - rates.thirst *= ( ( g->weather.get_temperature( pos() ) - 32.5f ) / 40.0f ); + rates.thirst *= ( ( get_weather().get_temperature( pos() ) - 32.5f ) / 40.0f ); } if( is_npc() ) { @@ -5680,7 +5680,7 @@ void Character::update_bodytemp() const int lying_warmth = use_floor_warmth ? floor_warmth( pos() ) : 0; const int water_temperature = - 100 * temp_to_celsius( g->weather.get_cur_weather_gen().get_water_temperature() ); + 100 * temp_to_celsius( get_weather().get_cur_weather_gen().get_water_temperature() ); // Correction of body temperature due to traits and mutations // Lower heat is applied always @@ -10436,7 +10436,7 @@ int Character::heartrate_bpm() const average_heartbeat *= 1.1; } //COLDBLOOD dependencies, works almost same way as temperature effect for speed. - const int player_local_temp = g->weather.get_temperature( pos() ); + const int player_local_temp = get_weather().get_temperature( pos() ); float temperature_modifier = 0; if( has_trait( trait_COLDBLOOD ) ) { temperature_modifier = 0.002; diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index 1e8b82d33aacb..0f64933bb606c 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -1843,7 +1843,7 @@ void debug() } break; case debug_menu_index::TEST_WEATHER: { - g->weather.get_cur_weather_gen().test_weather( g->get_seed() ); + get_weather().get_cur_weather_gen().test_weather( g->get_seed() ); } break; diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index eefe9587cd31e..7b32ebd923cb9 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -473,6 +473,7 @@ bool survive_random_encounter( npc &comp, std::string &situation, int favor, int static bool update_time_left( std::string &entry, const comp_list &npc_list ) { bool avail = false; + Character &player_character = get_player_character(); for( auto &comp : npc_list ) { if( comp->companion_mission_time_ret < calendar:: turn ) { entry = entry + _( " [DONE]\n" ); @@ -481,7 +482,7 @@ static bool update_time_left( std::string &entry, const comp_list &npc_list ) entry = entry + " [" + to_string( comp->companion_mission_time_ret - calendar::turn ) + _( " left]\n" ); - avail = g->u.has_trait( trait_DEBUG_HS ); + avail = player_character.has_trait( trait_DEBUG_HS ); } } entry = entry + _( "\n\nDo you wish to bring your allies back into your party?" ); @@ -641,7 +642,7 @@ void talk_function::basecamp_mission( npc &p ) return; } basecamp *bcp = *temp_camp; - bcp->set_by_radio( g->u.dialogue_by_radio ); + bcp->set_by_radio( get_avatar().dialogue_by_radio ); if( bcp->get_dumping_spot() == tripoint_zero ) { map &here = get_map(); auto &mgr = zone_manager::get_manager(); @@ -1990,7 +1991,7 @@ void basecamp::start_setup_hide_site() omt_pos, true ); if( forest != tripoint( -999, -999, -999 ) ) { int dist = rl_dist( forest.xy(), omt_pos.xy() ); - inventory tgt_inv = g->u.inv; + inventory tgt_inv = get_player_character().inv; std::vector pos_inv = tgt_inv.items_with( []( const item & itm ) { return !itm.can_revive(); } ); @@ -2033,7 +2034,7 @@ void basecamp::start_relay_hide_site() omt_pos, true ); if( forest != tripoint( -999, -999, -999 ) ) { int dist = rl_dist( forest.xy(), omt_pos.xy() ); - inventory tgt_inv = g->u.inv; + inventory tgt_inv = get_player_character().inv; std::vector pos_inv = tgt_inv.items_with( []( const item & itm ) { return !itm.can_revive(); } ); @@ -2302,6 +2303,7 @@ static std::pair farm_action( const tripoint &omt_tgt, farm tripoint mapmin = tripoint( 0, 0, omt_tgt.z ); tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, omt_tgt.z ); bool done_planting = false; + Character &player_character = get_player_character(); map &here = get_map(); for( const tripoint &pos : farm_map.points_in_rectangle( mapmin, mapmax ) ) { if( done_planting ) { @@ -2358,7 +2360,7 @@ static std::pair farm_action( const tripoint &omt_tgt, farm int seed_cnt = std::max( 1, rng( plant_cnt / 4, plant_cnt / 2 ) ); for( auto &i : iexamine::get_harvest_items( *seed->type, plant_cnt, seed_cnt, true ) ) { - here.add_item_or_charges( g->u.pos(), i ); + here.add_item_or_charges( player_character.pos(), i ); } farm_map.i_clear( pos ); farm_map.furn_set( pos, f_null ); @@ -2867,9 +2869,11 @@ void basecamp::recruit_return( const std::string &task, int score ) } // Time durations always subtract from camp food supply camp_food_supply( 1_days * food_desire ); - recruit->spawn_at_precise( { g->get_levx(), g->get_levy() }, g->u.pos() + point( -4, -4 ) ); + avatar &player_character = get_avatar(); + recruit->spawn_at_precise( { g->get_levx(), g->get_levy() }, + player_character.pos() + point( -4, -4 ) ); overmap_buffer.insert_npc( recruit ); - recruit->form_opinion( g->u ); + recruit->form_opinion( player_character ); recruit->mission = NPC_MISSION_NULL; recruit->add_new_mission( mission::reserve_random( ORIGIN_ANY_NPC, recruit->global_omt_location(), @@ -2980,11 +2984,12 @@ bool basecamp::farm_return( const std::string &task, const tripoint &omt_tgt, fa farm_action( omt_tgt, op, comp ); + Character &player_character = get_player_character(); //Give any seeds the NPC didn't use back to you. for( size_t i = 0; i < comp->companion_mission_inv.size(); i++ ) { for( const auto &it : comp->companion_mission_inv.const_stack( i ) ) { if( it.charges > 0 ) { - g->u.i_add( it ); + player_character.i_add( it ); } } } @@ -3445,9 +3450,10 @@ bool om_set_hide_site( npc &comp, const tripoint &omt_tgt, comp.companion_mission_inv.add_item( *i ); target_bay.i_rem( point( 11, 10 ), i ); } + Character &player_character = get_player_character(); for( auto i : itms ) { target_bay.add_item_or_charges( point( 11, 10 ), *i ); - g->u.use_amount( i->typeId(), 1 ); + player_character.use_amount( i->typeId(), 1 ); } target_bay.save(); @@ -3583,7 +3589,7 @@ bool basecamp::validate_sort_points() mgr.cache_vzones(); } tripoint src_loc = here.getlocal( bb_pos ) + point_north; - const tripoint abspos = here.getabs( g->u.pos() ); + const tripoint abspos = here.getabs( get_player_character().pos() ); if( !mgr.has_near( zone_type_CAMP_STORAGE, abspos, 60 ) || !mgr.has_near( zone_type_CAMP_FOOD, abspos, 60 ) ) { if( query_yn( _( "You do not have sufficient sort zones. Do you want to add them?" ) ) ) { @@ -3716,7 +3722,7 @@ int basecamp::recruit_evaluation( int &sbase, int &sexpansions, int &sfaction, i } //More machine than man //Bionics count > 10, respect > 75 - if( g->u.get_bionics().size() > 10 && camp_discipline() > 75 ) { + if( get_player_character().get_bionics().size() > 10 && camp_discipline() > 75 ) { sbonus += 10; } //Survival of the fittest @@ -3849,7 +3855,7 @@ std::string camp_car_description( vehicle *car ) // food supply int camp_food_supply( int change, bool return_days ) { - faction *yours = g->u.get_faction(); + faction *yours = get_player_character().get_faction(); yours->food_supply += change; if( yours->food_supply < 0 ) { yours->likes_u += yours->food_supply / 1250; @@ -3986,14 +3992,14 @@ bool basecamp::distribute_food() // morale int camp_discipline( int change ) { - faction *yours = g->u.get_faction(); + faction *yours = get_player_character().get_faction(); yours->respects_u += change; return yours->respects_u; } int camp_morale( int change ) { - faction *yours = g->u.get_faction(); + faction *yours = get_player_character().get_faction(); yours->likes_u += change; return yours->likes_u; } @@ -4013,7 +4019,8 @@ void basecamp::place_results( const item &result ) if( here.check_vehicle_zones( g->get_levz() ) ) { mgr.cache_vzones(); } - const auto abspos = here.getabs( g->u.pos() ); + Character &player_character = get_player_character(); + const auto abspos = here.getabs( player_character.pos() ); if( mgr.has_near( zone_type_CAMP_STORAGE, abspos ) ) { const auto &src_set = mgr.get_near( zone_type_CAMP_STORAGE, abspos ); const auto &src_sorted = get_sorted_tiles_by_distance( abspos, src_set ); @@ -4026,8 +4033,8 @@ void basecamp::place_results( const item &result ) } //or dump them at players feet } else { - here.add_item_or_charges( g->u.pos(), result, true ); - apply_camp_ownership( g->u.pos(), 0 ); + here.add_item_or_charges( player_character.pos(), result, true ); + apply_camp_ownership( player_character.pos(), 0 ); } } } @@ -4039,7 +4046,7 @@ void apply_camp_ownership( const tripoint &camp_pos, int radius ) camp_pos + point( radius, radius ) ) ) { map_stack items = here.i_at( p.xy() ); for( item &elem : items ) { - elem.set_owner( g->u ); + elem.set_owner( get_player_character() ); } } } diff --git a/src/game.cpp b/src/game.cpp index 1b93bd5d1ffb0..3ce8c7141136e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -12604,3 +12604,12 @@ event_bus &get_event_bus() { return g->events(); } + +const scenario *get_scenario() +{ + return g->scen; +} +void set_scenario( const scenario *new_scenario ) +{ + g->scen = new_scenario; +} diff --git a/src/game.h b/src/game.h index 0d0638a09330d..48c80bd78d490 100644 --- a/src/game.h +++ b/src/game.h @@ -153,6 +153,8 @@ class game friend Character &get_player_character(); friend avatar &get_avatar(); friend weather_manager &get_weather(); + friend const scenario *get_scenario(); + friend void set_scenario( const scenario *new_scenario ); public: game(); ~game(); diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index 56ec041e3e40e..1c2240c3b75bd 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -401,7 +401,7 @@ item_location game::inv_map_splice( const item_filter &filter, const std::string title, radius, none_message ); } -item_location game_menus::inv::container_for( avatar &you, const item &liquid, int radius ) +item_location game_menus::inv::container_for( Character &you, const item &liquid, int radius ) { const auto filter = [ &liquid ]( const item_location & location ) { if( location.where() == item_location::type::character ) { diff --git a/src/game_inventory.h b/src/game_inventory.h index 3353a73a8b5d2..95d30ccd85b65 100644 --- a/src/game_inventory.h +++ b/src/game_inventory.h @@ -84,7 +84,7 @@ item_location consume_drink( player &p ); /** Consuming a medication item via a custom menu. */ item_location consume_meds( player &p ); /** Choosing a container for liquid. */ -item_location container_for( avatar &you, const item &liquid, int radius = 0 ); +item_location container_for( Character &you, const item &liquid, int radius = 0 ); /** Item disassembling menu. */ item_location disassemble( Character &p ); /** Gunmod installation menu. */ diff --git a/src/gamemode_defense.cpp b/src/gamemode_defense.cpp index 94dbc7c2b9078..6e572aa61a9bf 100644 --- a/src/gamemode_defense.cpp +++ b/src/gamemode_defense.cpp @@ -95,7 +95,7 @@ defense_game::defense_game() bool defense_game::init() { calendar::turn = calendar::turn_zero + 12_hours; // Start at noon - g->weather.temperature = 65; + get_weather().temperature = 65; avatar &player_character = get_avatar(); if( !player_character.create( character_type::CUSTOM ) ) { return false; diff --git a/src/gamemode_tutorial.cpp b/src/gamemode_tutorial.cpp index d8942a8db5f2d..044fe89f2c51c 100644 --- a/src/gamemode_tutorial.cpp +++ b/src/gamemode_tutorial.cpp @@ -112,7 +112,7 @@ bool tutorial_game::init() calendar::turn = calendar::turn_zero + 12_hours; tutorials_seen.clear(); g->scent.reset(); - g->weather.temperature = 65; + get_weather().temperature = 65; // We use a Z-factor of 10 so that we don't plop down tutorial rooms in the // middle of the "real" game world avatar &player_character = get_avatar(); diff --git a/src/handle_liquid.cpp b/src/handle_liquid.cpp index deabc4e60c07e..14828d9ee3fbd 100644 --- a/src/handle_liquid.cpp +++ b/src/handle_liquid.cpp @@ -13,12 +13,11 @@ #include #include "action.h" -#include "avatar.h" #include "cata_utility.h" +#include "character.h" #include "colony.h" #include "debug.h" #include "enums.h" -#include "game.h" #include "game_inventory.h" #include "iexamine.h" #include "item.h" @@ -188,9 +187,10 @@ static bool get_liquid_target( item &liquid, item *const source, const int radiu //~ %s: liquid name menu.text = string_format( pgettext( "liquid", "What to do with the %s?" ), liquid_name ); } + Character &player_character = get_player_character(); std::vector> actions; - if( g->u.can_consume( liquid ) && !source_mon && ( source_veh || source_pos ) ) { - if( g->u.can_consume_for_bionic( liquid ) ) { + if( player_character.can_consume( liquid ) && !source_mon && ( source_veh || source_pos ) ) { + if( player_character.can_consume_for_bionic( liquid ) ) { menu.addentry( -1, true, 'e', _( "Fuel bionic with it" ) ); } else { menu.addentry( -1, true, 'e', _( "Consume it" ) ); @@ -203,7 +203,7 @@ static bool get_liquid_target( item &liquid, item *const source, const int radiu // This handles containers found anywhere near the player, including on the map and in vehicle storage. menu.addentry( -1, true, 'c', _( "Pour into a container" ) ); actions.emplace_back( [&]() { - target.item_loc = game_menus::inv::container_for( g->u, liquid, radius ); + target.item_loc = game_menus::inv::container_for( player_character, liquid, radius ); item *const cont = target.item_loc.get_item(); if( cont == nullptr || cont->is_null() ) { @@ -220,7 +220,7 @@ static bool get_liquid_target( item &liquid, item *const source, const int radiu } ); // This handles liquids stored in vehicle parts directly (e.g. tanks). std::set opts; - for( const auto &e : here.points_in_radius( g->u.pos(), 1 ) ) { + for( const auto &e : here.points_in_radius( player_character.pos(), 1 ) ) { auto veh = veh_pointer_or_null( here.veh_at( e ) ); vehicle_part_range vpr = veh->get_all_parts(); if( veh && std::any_of( vpr.begin(), vpr.end(), [&liquid]( const vpart_reference & pt ) { @@ -240,14 +240,14 @@ static bool get_liquid_target( item &liquid, item *const source, const int radiu } ); } - for( auto &target_pos : here.points_in_radius( g->u.pos(), 1 ) ) { + for( auto &target_pos : here.points_in_radius( player_character.pos(), 1 ) ) { if( !iexamine::has_keg( target_pos ) ) { continue; } if( source_pos != nullptr && *source_pos == target_pos ) { continue; } - const std::string dir = direction_name( direction_from( g->u.pos(), target_pos ) ); + const std::string dir = direction_name( direction_from( player_character.pos(), target_pos ) ); menu.addentry( -1, true, MENU_AUTOASSIGN, _( "Pour into an adjacent keg (%s)" ), dir ); actions.emplace_back( [ &, target_pos]() { target.pos = target_pos; @@ -315,14 +315,15 @@ static bool perform_liquid_transfer( item &liquid, const tripoint *const source_ return transfer_ok; } + Character &player_character = get_player_character(); const auto create_activity = [&]() { if( source_veh != nullptr ) { - g->u.assign_activity( activity_id( "ACT_FILL_LIQUID" ) ); - serialize_liquid_source( g->u.activity, *source_veh, part_num, liquid ); + player_character.assign_activity( activity_id( "ACT_FILL_LIQUID" ) ); + serialize_liquid_source( player_character.activity, *source_veh, part_num, liquid ); return true; } else if( source_pos != nullptr ) { - g->u.assign_activity( activity_id( "ACT_FILL_LIQUID" ) ); - serialize_liquid_source( g->u.activity, *source_pos, liquid ); + player_character.assign_activity( activity_id( "ACT_FILL_LIQUID" ) ); + serialize_liquid_source( player_character.activity, *source_pos, liquid ); return true; } else if( source_mon != nullptr ) { return false; @@ -334,7 +335,7 @@ static bool perform_liquid_transfer( item &liquid, const tripoint *const source_ map &here = get_map(); switch( target.dest_opt ) { case LD_CONSUME: - g->u.assign_activity( player_activity( consume_activity_actor( liquid ) ) ); + player_character.assign_activity( player_activity( consume_activity_actor( liquid ) ) ); liquid.charges--; transfer_ok = true; break; @@ -342,8 +343,8 @@ static bool perform_liquid_transfer( item &liquid, const tripoint *const source_ // Currently activities can only store item position in the players inventory, // not on ground or similar. TODO: implement storing arbitrary container locations. if( target.item_loc && create_activity() ) { - serialize_liquid_target( g->u.activity, target.item_loc ); - } else if( g->u.pour_into( *target.item_loc, liquid ) ) { + serialize_liquid_target( player_character.activity, target.item_loc ); + } else if( player_character.pour_into( *target.item_loc, liquid ) ) { if( target.item_loc->needs_processing() ) { // Polymorphism fail, have to introspect into the type to set the target container as active. switch( target.item_loc.where() ) { @@ -359,7 +360,7 @@ static bool perform_liquid_transfer( item &liquid, const tripoint *const source_ break; } } - g->u.mod_moves( -100 ); + player_character.mod_moves( -100 ); } transfer_ok = true; break; @@ -369,16 +370,16 @@ static bool perform_liquid_transfer( item &liquid, const tripoint *const source_ break; } if( create_activity() ) { - serialize_liquid_target( g->u.activity, *target.veh ); - } else if( g->u.pour_into( *target.veh, liquid ) ) { - g->u.mod_moves( -1000 ); // consistent with veh_interact::do_refill activity + serialize_liquid_target( player_character.activity, *target.veh ); + } else if( player_character.pour_into( *target.veh, liquid ) ) { + player_character.mod_moves( -1000 ); // consistent with veh_interact::do_refill activity } transfer_ok = true; break; case LD_KEG: case LD_GROUND: if( create_activity() ) { - serialize_liquid_target( g->u.activity, target.pos ); + serialize_liquid_target( player_character.activity, target.pos ); } else { if( target.dest_opt == LD_KEG ) { iexamine::pour_into_keg( target.pos, liquid ); @@ -386,7 +387,7 @@ static bool perform_liquid_transfer( item &liquid, const tripoint *const source_ here.add_item_or_charges( target.pos, liquid ); liquid.charges = 0; } - g->u.mod_moves( -100 ); + player_character.mod_moves( -100 ); } transfer_ok = true; break; diff --git a/src/iexamine.cpp b/src/iexamine.cpp index aef9fbe4187b3..c5e6104157554 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1719,7 +1719,7 @@ static void handle_harvest( player &p, const std::string &itemid, bool force_dro { item harvest = item( itemid ); if( harvest.has_temperature() ) { - harvest.set_item_temperature( temp_to_kelvin( g->weather.get_temperature( p.pos() ) ) ); + harvest.set_item_temperature( temp_to_kelvin( get_weather().get_temperature( p.pos() ) ) ); } if( !force_drop && p.can_pickVolume( harvest, true ) && p.can_pickWeight( harvest, !get_option( "DANGEROUS_PICKUPS" ) ) ) { diff --git a/src/item.cpp b/src/item.cpp index efaa388462ed3..053e5d5b04855 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -8892,7 +8892,7 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, return false; } - int temp = g->weather.get_temperature( pos ); + int temp = get_weather().get_temperature( pos ); switch( flag ) { case temperature_flag::NORMAL: @@ -8928,7 +8928,7 @@ bool item::process_temperature_rot( float insulation, const tripoint &pos, if( now - time > 1_hours ) { // This code is for items that were left out of reality bubble for long time - const weather_generator &wgen = g->weather.get_cur_weather_gen(); + const weather_generator &wgen = get_weather().get_cur_weather_gen(); const unsigned int seed = g->get_seed(); int local_mod = g->new_game ? 0 : get_map().get_temperature( pos ); diff --git a/src/iuse.cpp b/src/iuse.cpp index 32dbe5cae5ced..4d73485ba3235 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -8770,7 +8770,7 @@ int iuse::multicooker( player *p, item *it, bool t, const tripoint &pos ) meal.heat_up(); } else { meal.set_item_temperature( temp_to_kelvin( std::max( temperatures::cold, - g->weather.get_temperature( pos ) ) ) ); + get_weather().get_temperature( pos ) ) ) ); } it->active = false; diff --git a/src/pickup.cpp b/src/pickup.cpp index df5b82f176331..db0b70512e172 100644 --- a/src/pickup.cpp +++ b/src/pickup.cpp @@ -12,7 +12,6 @@ #include #include "auto_pickup.h" -#include "avatar.h" #include "cata_utility.h" #include "catacharset.h" #include "character.h" @@ -38,7 +37,6 @@ #include "options.h" #include "output.h" #include "panels.h" -#include "player.h" #include "player_activity.h" #include "point.h" #include "popup.h" @@ -219,7 +217,7 @@ bool Pickup::query_thief() bool pick_one_up( item_location &loc, int quantity, bool &got_water, bool &offered_swap, PickupMap &mapPickup, bool autopickup ) { - player &u = get_avatar(); + Character &player_character = get_player_character(); int moves_taken = 100; bool picked_up = false; pickup_answer option = CANCEL; @@ -232,17 +230,17 @@ bool pick_one_up( item_location &loc, int quantity, bool &got_water, bool &offer //new item (copy) item newit = it; - if( !newit.is_owned_by( u, true ) ) { + if( !newit.is_owned_by( player_character, true ) ) { // Has the player given input on if stealing is ok? - if( u.get_value( "THIEF_MODE" ) == "THIEF_ASK" ) { + if( player_character.get_value( "THIEF_MODE" ) == "THIEF_ASK" ) { Pickup::query_thief(); } - if( u.get_value( "THIEF_MODE" ) == "THIEF_HONEST" ) { + if( player_character.get_value( "THIEF_MODE" ) == "THIEF_HONEST" ) { return true; // Since we are honest, return no problem before picking up } } if( newit.invlet != '\0' && - u.invlet_to_item( newit.invlet ) != nullptr ) { + player_character.invlet_to_item( newit.invlet ) != nullptr ) { // Existing invlet is not re-usable, remove it and let the code in player.cpp/inventory.cpp // add a new invlet, otherwise keep the (usable) invlet. newit.invlet = '\0'; @@ -257,12 +255,12 @@ bool pick_one_up( item_location &loc, int quantity, bool &got_water, bool &offer bool did_prompt = false; if( newit.is_frozen_liquid() ) { - if( !( got_water = !( u.crush_frozen_liquid( newloc ) ) ) ) { + if( !( got_water = !( player_character.crush_frozen_liquid( newloc ) ) ) ) { option = STASH; } } else if( newit.made_of_from_type( phase_id::LIQUID ) && !newit.is_frozen_liquid() ) { got_water = true; - } else if( !u.can_pickWeight( newit, false ) ) { + } else if( !player_character.can_pickWeight( newit, false ) ) { if( !autopickup ) { const std::string &explain = string_format( _( "The %s is too heavy!" ), newit.display_name() ); @@ -280,7 +278,7 @@ bool pick_one_up( item_location &loc, int quantity, bool &got_water, bool &offer } else { option = CANCEL; } - } else if( !u.can_stash( newit ) ) { + } else if( !player_character.can_stash( newit ) ) { if( !autopickup ) { const std::string &explain = string_format( _( "Not enough capacity to stash %s" ), newit.display_name() ); @@ -301,21 +299,21 @@ bool pick_one_up( item_location &loc, int quantity, bool &got_water, bool &offer picked_up = false; break; case WEAR: - picked_up = !!u.wear_item( newit ); + picked_up = !!player_character.wear_item( newit ); break; case WIELD: { - const auto wield_check = u.can_wield( it ); + const auto wield_check = player_character.can_wield( it ); if( wield_check.success() ) { //using original item, possibly modifying it - picked_up = u.wield( it ); + picked_up = player_character.wield( it ); if( picked_up ) { - u.weapon.charges = newit.charges; + player_character.weapon.charges = newit.charges; } - if( u.weapon.invlet ) { - add_msg( m_info, _( "Wielding %c - %s" ), u.weapon.invlet, - u.weapon.display_name() ); + if( player_character.weapon.invlet ) { + add_msg( m_info, _( "Wielding %c - %s" ), player_character.weapon.invlet, + player_character.weapon.display_name() ); } else { - add_msg( m_info, _( "Wielding - %s" ), u.weapon.display_name() ); + add_msg( m_info, _( "Wielding - %s" ), player_character.weapon.display_name() ); } } else { add_msg( m_neutral, wield_check.c_str() ); @@ -328,13 +326,13 @@ bool pick_one_up( item_location &loc, int quantity, bool &got_water, bool &offer break; } //using original item, possibly modifying it - picked_up = it.spill_contents( u ); + picked_up = it.spill_contents( player_character ); if( !picked_up ) { break; } // Intentional fallthrough case STASH: { - item &added_it = u.i_add( newit, true, nullptr, /*allow_drop=*/false ); + item &added_it = player_character.i_add( newit, true, nullptr, /*allow_drop=*/false ); if( added_it.is_null() ) { // failed to add, do nothing } else if( &added_it == &it ) { @@ -361,7 +359,7 @@ bool pick_one_up( item_location &loc, int quantity, bool &got_water, bool &offer } else { loc.remove_item(); } - u.moves -= moves_taken; + player_character.moves -= moves_taken; } return picked_up || !did_prompt; @@ -371,7 +369,8 @@ bool Pickup::do_pickup( std::vector &targets, std::vector &q bool autopickup ) { bool got_water = false; - bool weight_is_okay = ( g->u.weight_carried() <= g->u.weight_capacity() ); + Character &player_character = get_player_character(); + bool weight_is_okay = ( player_character.weight_carried() <= player_character.weight_capacity() ); bool offered_swap = false; // Map of items picked up so we can output them all at the end and @@ -379,7 +378,7 @@ bool Pickup::do_pickup( std::vector &targets, std::vector &q PickupMap mapPickup; bool problem = false; - while( !problem && g->u.moves >= 0 && !targets.empty() ) { + while( !problem && player_character.moves >= 0 && !targets.empty() ) { item_location target = std::move( targets.back() ); int quantity = quantities.back(); // Whether we pick the item up or not, we're done trying to do so, @@ -402,7 +401,7 @@ bool Pickup::do_pickup( std::vector &targets, std::vector &q if( got_water ) { add_msg( m_info, _( "You can't pick up a liquid!" ) ); } - if( weight_is_okay && g->u.weight_carried() > g->u.weight_capacity() ) { + if( weight_is_okay && player_character.weight_carried() > player_character.weight_capacity() ) { add_msg( m_bad, _( "You're overburdened!" ) ); } @@ -480,9 +479,10 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) } } + Character &player_character = get_player_character(); if( min == -1 ) { // Recursively pick up adjacent items if that option is on. - if( get_option( "AUTO_PICKUP_ADJACENT" ) && g->u.pos() == p ) { + if( get_option( "AUTO_PICKUP_ADJACENT" ) && player_character.pos() == p ) { //Autopickup adjacent direction adjacentDir[8] = {direction::NORTH, direction::NORTHEAST, direction::EAST, direction::SOUTHEAST, direction::SOUTH, direction::SOUTHWEST, direction::WEST, direction::NORTHWEST}; for( auto &elem : adjacentDir ) { @@ -505,17 +505,17 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) // Not many items, just grab them if( static_cast( here.size() ) <= min && min != -1 ) { if( from_vehicle ) { - g->u.assign_activity( player_activity( pickup_activity_actor( + player_character.assign_activity( player_activity( pickup_activity_actor( { item_location( vehicle_cursor( *veh, cargo_part ), &*here.front() ) }, { 0 }, cata::nullopt - ) ) ); + ) ) ); } else { - g->u.assign_activity( player_activity( pickup_activity_actor( + player_character.assign_activity( player_activity( pickup_activity_actor( {item_location( map_cursor( p ), &*here.front() ) }, { 0 }, - g->u.pos() - ) ) ); + player_character.pos() + ) ) ); } return; } @@ -735,7 +735,7 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) } // if the item does not belong to your fraction then add the stolen symbol - if( !this_item.is_owned_by( g->u, true ) ) { + if( !this_item.is_owned_by( player_character, true ) ) { item_name = string_format( "! %s", item_name ); } @@ -764,13 +764,13 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) const std::string fmted_weight_predict = colorize( string_format( "%.1f", round_up( convert_weight( weight_predict ), 1 ) ), - weight_predict > g->u.weight_capacity() ? c_red : c_white ); + weight_predict > player_character.weight_capacity() ? c_red : c_white ); const std::string fmted_weight_capacity = string_format( - "%.1f", round_up( convert_weight( g->u.weight_capacity() ), 1 ) ); + "%.1f", round_up( convert_weight( player_character.weight_capacity() ), 1 ) ); const std::string fmted_volume_predict = colorize( format_volume( volume_predict ), - volume_predict > g->u.volume_capacity() ? c_red : c_white ); - const std::string fmted_volume_capacity = format_volume( g->u.volume_capacity() ); + volume_predict > player_character.volume_capacity() ? c_red : c_white ); + const std::string fmted_volume_capacity = format_volume( player_character.volume_capacity() ); trim_and_print( w_pickup, point_zero, pickupW, c_white, string_format( _( "PICK Wgt %1$s/%2$s Vol %3$s/%4$s" ), @@ -958,8 +958,8 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) } } - weight_predict = g->u.weight_carried() + weight_picked_up; - volume_predict = g->u.volume_carried() + volume_picked_up; + weight_predict = player_character.weight_carried() + weight_picked_up; + volume_predict = player_character.volume_carried() + volume_picked_up; } ui_manager::redraw(); @@ -1022,11 +1022,11 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) quantities.push_back( iter_qty.second ); } - g->u.assign_activity( player_activity( pickup_activity_actor( target_items, quantities, - g->u.pos() ) ) ); + player_character.assign_activity( player_activity( pickup_activity_actor( target_items, quantities, + player_character.pos() ) ) ); if( min == -1 ) { // Auto pickup will need to auto resume since there can be several of them on the stack. - g->u.activity.auto_resume = true; + player_character.activity.auto_resume = true; } g->reenter_fullscreen(); diff --git a/src/player.cpp b/src/player.cpp index 395a36bd92e1b..195aa5efcfba9 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -515,7 +515,7 @@ void player::recalc_speed_bonus() } const float temperature_speed_modifier = mutation_value( "temperature_speed_modifier" ); if( temperature_speed_modifier != 0 ) { - const auto player_local_temp = g->weather.get_temperature( pos() ); + const auto player_local_temp = get_weather().get_temperature( pos() ); if( has_trait( trait_COLDBLOOD4 ) || player_local_temp < 65 ) { mod_speed_bonus( ( player_local_temp - 65 ) * temperature_speed_modifier ); } diff --git a/src/player_display.cpp b/src/player_display.cpp index 725c0bfa6f6e1..d05907fa943d7 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -874,7 +874,7 @@ static void draw_speed_tab( const catacurses::window &w_speed, if( temperature_speed_modifier != 0 ) { nc_color pen_color; std::string pen_sign; - const auto player_local_temp = g->weather.get_temperature( you.pos() ); + const auto player_local_temp = get_weather().get_temperature( you.pos() ); if( you.has_trait( trait_id( "COLDBLOOD4" ) ) && player_local_temp > 65 ) { pen_color = c_green; pen_sign = "+"; diff --git a/src/scenario.h b/src/scenario.h index 5319982710ab0..05da1d283a740 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -129,4 +129,7 @@ struct scen_blacklist { void reset_scenarios_blacklist(); +const scenario *get_scenario(); +void set_scenario( const scenario *new_scenario ); + #endif // CATA_SRC_SCENARIO_H diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index 18d261cc04d49..f5f478d0d623f 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -866,7 +866,7 @@ double vehicle::engine_cold_factor( const int e ) const return 0.0; } - int eff_temp = g->weather.get_temperature( get_player_character().pos() ); + int eff_temp = get_weather().get_temperature( get_player_character().pos() ); if( !parts[ engines[ e ] ].faults().count( fault_engine_glow_plug ) ) { eff_temp = std::min( eff_temp, 20 ); } diff --git a/src/weather.cpp b/src/weather.cpp index e4415a2be3fc6..6d32f080e9b82 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -692,7 +692,7 @@ std::string weather_forecast( const point &abs_sm_pos ) 1_hours; for( int d = 0; d < 6; d++ ) { weather_type_id forecast = WEATHER_NULL; - const auto wgen = g->weather.get_cur_weather_gen(); + const auto wgen = get_weather().get_cur_weather_gen(); for( time_point i = last_hour + d * 12_hours; i < last_hour + ( d + 1 ) * 12_hours; i += 1_hours ) { w_point w = wgen.get_weather( abs_ms_pos, i, g->get_seed() ); forecast = std::max( forecast, wgen.get_weather_conditions( w ) ); @@ -1013,7 +1013,7 @@ rl_vec2d convert_wind_to_coord( const int angle ) bool warm_enough_to_plant( const tripoint &pos ) { // semi-appropriate temperature for most plants - return g->weather.get_temperature( pos ) >= 50; + return get_weather().get_temperature( pos ) >= 50; } weather_manager::weather_manager() diff --git a/tests/new_character_test.cpp b/tests/new_character_test.cpp index 9223612a2d63a..388ad0a68eb31 100644 --- a/tests/new_character_test.cpp +++ b/tests/new_character_test.cpp @@ -12,7 +12,6 @@ #include "avatar.h" #include "catch/catch.hpp" -#include "game.h" #include "item.h" #include "item_contents.h" #include "itype.h" @@ -51,13 +50,15 @@ static std::vector next_subset( const std::vector &set ) static bool try_set_traits( const std::vector &traits ) { - g->u.clear_mutations(); - g->u.add_traits(); // mandatory prof/scen traits + avatar &player_character = get_avatar(); + player_character.clear_mutations(); + player_character.add_traits(); // mandatory prof/scen traits for( const trait_id &tr : traits ) { - if( g->u.has_conflicting_trait( tr ) || !g->scen->traitquery( tr ) ) { + if( player_character.has_conflicting_trait( tr ) || + !get_scenario()->traitquery( tr ) ) { return false; - } else if( !g->u.has_trait( tr ) ) { - g->u.set_mutation( tr ); + } else if( !player_character.has_trait( tr ) ) { + player_character.set_mutation( tr ); } } return true; @@ -130,51 +131,52 @@ TEST_CASE( "starting_items", "[slow]" ) std::set failures; - g->u = get_sanitized_player(); + avatar &player_character = get_avatar(); + player_character = get_sanitized_player(); // Avoid false positives from ingredients like salt and cornmeal. const avatar control = get_sanitized_player(); std::vector traits = next_subset( mutations ); for( ; !traits.empty(); traits = next_subset( mutations ) ) { for( const auto &pair : scen_prof_combos ) { - g->scen = pair.first; + set_scenario( pair.first ); for( const string_id &prof : pair.second ) { - g->u.prof = &prof.obj(); + player_character.prof = &prof.obj(); if( !try_set_traits( traits ) ) { continue; // Trait conflict: this prof/scen/trait combo is impossible to attain } for( int i = 0; i < 2; i++ ) { - g->u.worn.clear(); - g->u.remove_weapon(); - g->u.inv.clear(); - g->u.calc_encumbrance(); - g->u.male = i == 0; + player_character.worn.clear(); + player_character.remove_weapon(); + player_character.inv.clear(); + player_character.calc_encumbrance(); + player_character.male = i == 0; - g->u.add_profession_items(); + player_character.add_profession_items(); std::set items_visited; const auto visitable_counter = [&items_visited]( const item * it ) { items_visited.emplace( it ); return VisitResponse::NEXT; }; - g->u.visit_items( visitable_counter ); - g->u.inv.visit_items( visitable_counter ); + player_character.visit_items( visitable_counter ); + player_character.inv.visit_items( visitable_counter ); const int num_items_pre_migration = items_visited.size(); items_visited.clear(); - g->u.migrate_items_to_storage( true ); - g->u.visit_items( visitable_counter ); + player_character.migrate_items_to_storage( true ); + player_character.visit_items( visitable_counter ); const int num_items_post_migration = items_visited.size(); items_visited.clear(); if( num_items_pre_migration != num_items_post_migration ) { failure cur_fail; - cur_fail.prof = g->u.prof->ident(); - cur_fail.mut = g->u.get_mutations(); + cur_fail.prof = player_character.prof->ident(); + cur_fail.mut = player_character.get_mutations(); cur_fail.reason = string_format( "does not have enough space to store all items." ); failures.insert( cur_fail ); } - CAPTURE( g->u.prof->ident().c_str() ); + CAPTURE( player_character.prof->ident().c_str() ); CHECK( num_items_pre_migration == num_items_post_migration ); } // all genders } // all profs From e9064f1c9cdee399f3a9fe7400c8a18dfddb165c Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Fri, 17 Jul 2020 07:05:59 +0000 Subject: [PATCH 093/151] Global reference migration part 31 --- src/avatar.cpp | 5 ---- src/character.cpp | 6 ----- src/condition.cpp | 2 +- src/construction.cpp | 13 +++++----- src/creature.cpp | 22 +++++++++-------- src/game.cpp | 15 ++++++++++++ src/iexamine.cpp | 2 +- src/iuse_actor.cpp | 2 +- src/lightmap.cpp | 25 ++++++++++---------- src/map.cpp | 5 ---- src/map.h | 2 +- src/mattack_actors.cpp | 16 +++++++------ src/mission.cpp | 43 ++++++++++++++++----------------- src/mission_util.cpp | 22 +++++++++-------- src/npcmove.cpp | 2 +- src/npctalk.cpp | 16 +++++++------ src/npctrade.cpp | 19 ++++++++------- src/talker_npc.cpp | 29 ++++++++++++----------- src/vehicle_move.cpp | 7 +++--- tests/char_stamina_test.cpp | 47 +++++++++++++++++-------------------- tests/itemname_test.cpp | 20 ++++++++-------- tests/player_helpers.cpp | 4 ++-- tests/player_helpers.h | 2 +- 23 files changed, 169 insertions(+), 157 deletions(-) diff --git a/src/avatar.cpp b/src/avatar.cpp index 592ad58f0e619..1e831811b90cc 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -123,11 +123,6 @@ static const std::string flag_FIX_FARSIGHT( "FIX_FARSIGHT" ); class JsonIn; class JsonOut; -avatar &get_avatar() -{ - return g->u; -} - avatar::avatar() { show_map_memory = true; diff --git a/src/character.cpp b/src/character.cpp index 32ff326cae7d0..e5798292fe776 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -400,12 +400,6 @@ std::string enum_to_string( blood_type data ) } // namespace io -Character &get_player_character() -{ - return g->u; -} - - // *INDENT-OFF* Character::Character() : diff --git a/src/condition.cpp b/src/condition.cpp index 46e93270b7fcc..4916a3fb5d9e0 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -814,7 +814,7 @@ void conditional_t::set_u_know_recipe( const JsonObject &jo, const std::strin condition = [known_recipe_id]( const T & ) { const recipe &rep = recipe_id( known_recipe_id ).obj(); // should be a talker function but recipes aren't in Character:: yet - return g->u.knows_recipe( &rep ); + return get_player_character().knows_recipe( &rep ); }; } diff --git a/src/construction.cpp b/src/construction.cpp index 754bd2438b414..b5690e53fc747 100644 --- a/src/construction.cpp +++ b/src/construction.cpp @@ -1260,19 +1260,20 @@ void construct::done_deconstruct( const tripoint &p ) add_msg( m_info, _( "That %s can not be disassembled!" ), f.name() ); return; } + Character &player_character = get_player_character(); if( f.id.id() == furn_str_id( "f_console_broken" ) ) { - if( g->u.get_skill_level( skill_electronics ) >= 1 ) { - g->u.practice( skill_electronics, 20, 4 ); + if( player_character.get_skill_level( skill_electronics ) >= 1 ) { + player_character.practice( skill_electronics, 20, 4 ); } } if( f.id.id() == furn_str_id( "f_console" ) ) { - if( g->u.get_skill_level( skill_electronics ) >= 1 ) { - g->u.practice( skill_electronics, 40, 8 ); + if( player_character.get_skill_level( skill_electronics ) >= 1 ) { + player_character.practice( skill_electronics, 40, 8 ); } } if( f.id.id() == furn_str_id( "f_machinery_electronic" ) ) { - if( g->u.get_skill_level( skill_electronics ) >= 1 ) { - g->u.practice( skill_electronics, 40, 8 ); + if( player_character.get_skill_level( skill_electronics ) >= 1 ) { + player_character.practice( skill_electronics, 40, 8 ); } } if( f.deconstruct.furn_set.str().empty() ) { diff --git a/src/creature.cpp b/src/creature.cpp index ec758074aab4d..fa9380e8104e5 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -299,7 +299,7 @@ bool Creature::sees( const tripoint &t, bool is_avatar, int range_mod ) const } if( is_avatar ) { // Special case monster -> player visibility, forcing it to be symmetric with player vision. - const float player_visibility_factor = g->u.visibility() / 100.0f; + const float player_visibility_factor = get_player_character().visibility() / 100.0f; int adj_range = std::floor( range * player_visibility_factor ); return adj_range >= wanted_range && here.get_cache_ref( pos().z ).seen_cache[pos().x][pos().y] > LIGHT_TRANSPARENCY_SOLID; @@ -329,7 +329,8 @@ static bool overlaps_vehicle( const std::set &veh_area, const tripoint Creature *Creature::auto_find_hostile_target( int range, int &boo_hoo, int area ) { Creature *target = nullptr; - player &u = g->u; // Could easily protect something that isn't the player + Character &player_character = get_player_character(); + tripoint player_pos = player_character.pos(); constexpr int hostile_adj = 2; // Priority bonus for hostile targets const int iff_dist = ( range + area ) * 3 / 2 + 6; // iff check triggers at this distance int iff_hangle = 15 + area; // iff safety margin (degrees). less accuracy, more paranoia @@ -339,20 +340,20 @@ Creature *Creature::auto_find_hostile_target( int range, int &boo_hoo, int area bool self_area_iff = false; // Need to check if the target is near the vehicle we're a part of bool area_iff = false; // Need to check distance from target to player bool angle_iff = true; // Need to check if player is in a cone between us and target - int pldist = rl_dist( pos(), g->u.pos() ); + int pldist = rl_dist( pos(), player_pos ); map &here = get_map(); vehicle *in_veh = is_fake() ? veh_pointer_or_null( here.veh_at( pos() ) ) : nullptr; - if( pldist < iff_dist && sees( g->u ) ) { + if( pldist < iff_dist && sees( player_character ) ) { area_iff = area > 0; // Player inside vehicle won't be hit by shots from the roof, // so we can fire "through" them just fine. - const optional_vpart_position vp = here.veh_at( u.pos() ); + const optional_vpart_position vp = here.veh_at( player_pos ); if( in_veh && veh_pointer_or_null( vp ) == in_veh && vp->is_inside() ) { angle_iff = false; // No angle IFF, but possibly area IFF } else if( pldist < 3 ) { iff_hangle = ( pldist == 2 ? 30 : 60 ); // granularity increases with proximity } - u_angle = coord_to_angle( pos(), u.pos() ); + u_angle = coord_to_angle( pos(), player_pos ); } if( area > 0 && in_veh != nullptr ) { @@ -422,7 +423,7 @@ Creature *Creature::auto_find_hostile_target( int range, int &boo_hoo, int area // No shooting stuff on vehicle we're a part of continue; } - if( area_iff && rl_dist( u.pos(), m->pos() ) <= area ) { + if( area_iff && rl_dist( player_pos, m->pos() ) <= area ) { // Player in AoE boo_hoo++; continue; @@ -444,7 +445,7 @@ Creature *Creature::auto_find_hostile_target( int range, int &boo_hoo, int area // Helps avoid (possibly expensive) attitude calculation continue; } - if( m->attitude_to( u ) == Attitude::HOSTILE ) { + if( m->attitude_to( player_character ) == Attitude::HOSTILE ) { target_rating = ( mon_rating + hostile_adj ) / dist; if( maybe_boo ) { boo_hoo++; @@ -594,7 +595,8 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack dealt_damage_instance &dealt_dam = attack.dealt_dam; const auto &proj_effects = proj.proj_effects; - const bool u_see_this = g->u.sees( *this ); + Character &player_character = get_player_character(); + const bool u_see_this = player_character.sees( *this ); const int avoid_roll = dodge_roll(); // Do dice(10, speed) instead of dice(speed, 10) because speed could potentially be > 10000 @@ -610,7 +612,7 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack } // "Avoid" rather than "dodge", because it includes removing self from the line of fire // rather than just Matrix-style bullet dodging - if( source != nullptr && g->u.sees( *source ) ) { + if( source != nullptr && player_character.sees( *source ) ) { add_msg_player_or_npc( m_warning, _( "You avoid %s projectile!" ), diff --git a/src/game.cpp b/src/game.cpp index 1b93bd5d1ffb0..3d20b20b28240 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -12600,6 +12600,21 @@ void game_ui::init_ui() g->init_ui( true ); } +Character &get_player_character() +{ + return g->u; +} + +avatar &get_avatar() +{ + return g->u; +} + +map &get_map() +{ + return g->m; +} + event_bus &get_event_bus() { return g->events(); diff --git a/src/iexamine.cpp b/src/iexamine.cpp index aef9fbe4187b3..b0df444748a73 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1060,7 +1060,7 @@ void iexamine::intercom( player &p, const tripoint &examp ) p.add_msg_if_player( m_info, _( "No one responds." ) ); } else { // TODO: This needs to be converted a talker_console or something - g->u.talk_to( get_talker_for( *intercom_npcs.front() ), false, false ); + get_avatar().talk_to( get_talker_for( *intercom_npcs.front() ), false, false ); } } diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 082cb274947e4..a3ca3671f5b33 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -3519,7 +3519,7 @@ void heal_actor::info( const item &, std::vector &dump ) const dump.emplace_back( "HEAL", _( "Effect on bleeding: " ), texitify_bandage_power( bleed ) ); if( g != nullptr ) { dump.emplace_back( "HEAL", _( "Actual effect on bleeding: " ), - texitify_healing_power( get_stopbleed_level( g->u ) ) ); + texitify_healing_power( get_stopbleed_level( get_player_character() ) ) ); } } if( bite > 0.0f || infect > 0.0f ) { diff --git a/src/lightmap.cpp b/src/lightmap.cpp index 29096b3252caa..72c9395472af9 100644 --- a/src/lightmap.cpp +++ b/src/lightmap.cpp @@ -8,7 +8,6 @@ #include #include -#include "avatar.h" #include "calendar.h" #include "character.h" #include "colony.h" @@ -27,7 +26,6 @@ #include "mtype.h" #include "npc.h" #include "optional.h" -#include "player.h" #include "point.h" #include "string_formatter.h" #include "submap.h" @@ -154,7 +152,8 @@ bool map::build_vision_transparency_cache( const int zlev ) memcpy( &vision_transparency_cache, &transparency_cache, sizeof( transparency_cache ) ); - const tripoint &p = g->u.pos(); + Character &player_character = get_player_character(); + const tripoint &p = player_character.pos(); if( p.z != zlev ) { return false; @@ -162,7 +161,7 @@ bool map::build_vision_transparency_cache( const int zlev ) bool dirty = false; - bool is_crouching = g->u.is_crouching(); + bool is_crouching = player_character.is_crouching(); for( const tripoint &loc : points_in_radius( p, 1 ) ) { if( loc == p ) { // The tile player is standing on should always be visible @@ -180,7 +179,7 @@ bool map::build_vision_transparency_cache( const int zlev ) return dirty; } -void map::apply_character_light( player &p ) +void map::apply_character_light( Character &p ) { if( p.has_effect( effect_onfire ) ) { apply_light_source( p.pos(), 8 ); @@ -317,7 +316,7 @@ void map::generate_lightmap( const int zlev ) for( int z = maxz; z >= minz; z-- ) { build_sunlight_cache( z ); } - apply_character_light( g->u ); + apply_character_light( get_player_character() ); for( npc &guy : g->all_npcs() ) { apply_character_light( guy ); } @@ -607,7 +606,8 @@ map::apparent_light_info map::apparent_light_helper( const level_cache &map_cach lit_level map::apparent_light_at( const tripoint &p, const visibility_variables &cache ) const { - const int dist = rl_dist( g->u.pos(), p ); + Character &player_character = get_player_character(); + const int dist = rl_dist( player_character.pos(), p ); // Clairvoyance overrides everything. if( cache.u_clairvoyance > 0 && dist <= cache.u_clairvoyance ) { @@ -622,7 +622,7 @@ lit_level map::apparent_light_at( const tripoint &p, const visibility_variables // Unimpaired range is an override to strictly limit vision range based on various conditions, // but the player can still see light sources. - if( dist > g->u.unimpaired_range() ) { + if( dist > player_character.unimpaired_range() ) { if( !a.obstructed && map_cache.sm[p.x][p.y] > 0.0 ) { return lit_level::BRIGHT_ONLY; } else { @@ -663,15 +663,16 @@ bool map::pl_sees( const tripoint &t, const int max_range ) const return false; } - if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) { + Character &player_character = get_player_character(); + if( max_range >= 0 && square_dist( t, player_character.pos() ) > max_range ) { return false; // Out of range! } const auto &map_cache = get_cache_ref( t.z ); const apparent_light_info a = apparent_light_helper( map_cache, t ); - const float light_at_player = map_cache.lm[g->u.posx()][g->u.posy()].max(); + const float light_at_player = map_cache.lm[player_character.posx()][player_character.posy()].max(); return !a.obstructed && - ( a.apparent_light > g->u.get_vision_threshold( light_at_player ) || + ( a.apparent_light > player_character.get_vision_threshold( light_at_player ) || map_cache.sm[t.x][t.y] > 0.0 ); } @@ -681,7 +682,7 @@ bool map::pl_line_of_sight( const tripoint &t, const int max_range ) const return false; } - if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) { + if( max_range >= 0 && square_dist( t, get_player_character().pos() ) > max_range ) { // Out of range! return false; } diff --git a/src/map.cpp b/src/map.cpp index 04e980bfc5813..5a4f637d58a06 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -123,11 +123,6 @@ static cata::colony nulitems; // Returned when &i_at() is asked f static field nulfield; // Returned when &field_at() is asked for an OOB value static level_cache nullcache; // Dummy cache for z-levels outside bounds -map &get_map() -{ - return g->m; -} - // Map stack methods. map_stack::iterator map_stack::erase( map_stack::const_iterator it ) { diff --git a/src/map.h b/src/map.h index f2e033219f702..eb87ff3d23a22 100644 --- a/src/map.h +++ b/src/map.h @@ -1588,7 +1588,7 @@ class map protected: void generate_lightmap( int zlev ); void build_seen_cache( const tripoint &origin, int target_z ); - void apply_character_light( player &p ); + void apply_character_light( Character &p ); int my_MAPSIZE; bool zlevels; diff --git a/src/mattack_actors.cpp b/src/mattack_actors.cpp index bb6cf66b59c6c..8ccfbaa58f97b 100644 --- a/src/mattack_actors.cpp +++ b/src/mattack_actors.cpp @@ -138,10 +138,11 @@ bool leap_actor::call( monster &z ) const } z.moves -= move_cost; + Character &player_character = get_player_character(); const tripoint chosen = random_entry( options ); - bool seen = g->u.sees( z ); // We can see them jump... + bool seen = player_character.sees( z ); // We can see them jump... z.setpos( chosen ); - seen |= g->u.sees( z ); // ... or we can see them land + seen |= player_character.sees( z ); // ... or we can see them land if( seen ) { add_msg( _( "The %s leaps!" ), z.name() ); } @@ -198,7 +199,7 @@ bool mon_spellcasting_actor::call( monster &mon ) const target_name = target_monster->disp_name(); } - if( g->u.sees( target ) ) { + if( get_player_character().sees( target ) ) { add_msg( spell_data.message(), mon.disp_name(), spell_data.name(), target_name ); } @@ -328,7 +329,8 @@ void melee_actor::on_damage( monster &z, Creature &target, dealt_damage_instance sfx::get_heard_angle( z.pos() ) ); sfx::do_player_death_hurt( dynamic_cast( target ), false ); } - auto msg_type = target.attitude_to( g->u ) == Creature::Attitude::FRIENDLY ? m_bad : m_neutral; + auto msg_type = target.attitude_to( get_player_character() ) == Creature::Attitude::FRIENDLY ? + m_bad : m_neutral; const bodypart_id &bp = dealt.bp_hit ; target.add_msg_player_or_npc( msg_type, hit_dmg_u, hit_dmg_npc, z.name(), body_part_name_accusative( bp ) ); @@ -464,7 +466,7 @@ bool gun_actor::call( monster &z ) const int hostiles; // hostiles which cannot be engaged without risking friendly fire target = z.auto_find_hostile_target( max_range, hostiles ); if( !target ) { - if( hostiles > 0 && g->u.sees( z ) ) { + if( hostiles > 0 && get_player_character().sees( z ) ) { add_msg( m_warning, ngettext( "Pointed in your direction, the %s emits an IFF warning beep.", "Pointed in your direction, the %s emits %d annoyed sounding beeps.", hostiles ), @@ -493,7 +495,7 @@ bool gun_actor::call( monster &z ) const void gun_actor::shoot( monster &z, Creature &target, const gun_mode_id &mode ) const { if( require_sunlight && !g->is_in_sunlight( z.pos() ) ) { - if( one_in( 3 ) && g->u.sees( z ) ) { + if( one_in( 3 ) && get_player_character().sees( z ) ) { add_msg( _( failure_msg ), z.name() ); } return; @@ -567,7 +569,7 @@ void gun_actor::shoot( monster &z, Creature &target, const gun_mode_id &mode ) c tmp.weapon = gun; tmp.i_add( item( "UPS_off", calendar::turn, 1000 ) ); - if( g->u.sees( z ) ) { + if( get_player_character().sees( z ) ) { add_msg( m_warning, _( description ), z.name(), tmp.weapon.tname() ); } diff --git a/src/mission.cpp b/src/mission.cpp index 094def531af1c..d11187dc33990 100644 --- a/src/mission.cpp +++ b/src/mission.cpp @@ -155,7 +155,7 @@ void mission::on_creature_death( Creature &poor_dead_dude ) npc *p = dynamic_cast( &poor_dead_dude ); if( p == nullptr ) { // Must be the player - for( auto &miss : g->u.get_active_missions() ) { + for( auto &miss : get_avatar().get_active_missions() ) { // mission is free and can be reused miss->player_id = character_id(); } @@ -238,8 +238,9 @@ void mission::assign( avatar &u ) void mission::fail() { status = mission_status::failure; - if( g->u.getID() == player_id ) { - g->u.on_mission_finished( *this ); + avatar &player_character = get_avatar(); + if( player_character.getID() == player_id ) { + player_character.on_mission_finished( *this ); } type->fail( this ); @@ -277,20 +278,20 @@ void mission::step_complete( const int _step ) void mission::wrap_up() { - auto &u = g->u; - if( u.getID() != player_id ) { + avatar &player_character = get_avatar(); + if( player_character.getID() != player_id ) { // This is called from npctalk.cpp, the npc should only offer the option to wrap up mission // that have been assigned to the current player. debugmsg( "mission::wrap_up called, player %d was assigned, but current player is %d", - player_id.get_value(), u.getID().get_value() ); + player_id.get_value(), player_character.getID().get_value() ); } status = mission_status::success; - u.on_mission_finished( *this ); + player_character.on_mission_finished( *this ); std::vector comps; switch( type->goal ) { case MGOAL_FIND_ITEM_GROUP: { - inventory tmp_inv = u.crafting_inventory(); + inventory tmp_inv = player_character.crafting_inventory(); std::vector items = std::vector(); tmp_inv.dump( items ); Group_tag grp_type = type->group_id; @@ -309,16 +310,16 @@ void mission::wrap_up() } - u.consume_items( comps ); + player_character.consume_items( comps ); if( remove_container ) { std::vector container_comp = std::vector(); if( !empty_container.is_null() ) { container_comp.push_back( item_comp( empty_container, type->item_count ) ); - u.consume_items( container_comp ); + player_character.consume_items( container_comp ); } else { container_comp.push_back( item_comp( container, type->item_count ) ); - u.consume_items( container_comp ); + player_character.consume_items( container_comp ); } } } @@ -326,10 +327,10 @@ void mission::wrap_up() case MGOAL_FIND_ITEM: comps.push_back( item_comp( type->item_id, item_count ) ); - u.consume_items( comps ); + player_character.consume_items( comps ); break; case MGOAL_FIND_ANY_ITEM: - u.remove_mission_items( uid ); + player_character.remove_mission_items( uid ); break; default: //Suppress warnings @@ -345,20 +346,20 @@ bool mission::is_complete( const character_id &_npc_id ) const return true; } - auto &u = g->u; + avatar &player_character = get_avatar(); switch( type->goal ) { case MGOAL_GO_TO: { - const tripoint cur_pos = g->u.global_omt_location(); + const tripoint cur_pos = player_character.global_omt_location(); return ( rl_dist( cur_pos, target ) <= 1 ); } case MGOAL_GO_TO_TYPE: { - const auto cur_ter = overmap_buffer.ter( g->u.global_omt_location() ); + const auto cur_ter = overmap_buffer.ter( player_character.global_omt_location() ); return is_ot_match( type->target_id.str(), cur_ter, ot_match_type::type ); } case MGOAL_FIND_ITEM_GROUP: { - inventory tmp_inv = u.crafting_inventory(); + inventory tmp_inv = player_character.crafting_inventory(); std::vector items = std::vector(); tmp_inv.dump( items ); Group_tag grp_type = type->group_id; @@ -386,7 +387,7 @@ bool mission::is_complete( const character_id &_npc_id ) const if( npc_id.is_valid() && npc_id != _npc_id ) { return false; } - const inventory &tmp_inv = u.crafting_inventory(); + const inventory &tmp_inv = player_character.crafting_inventory(); // TODO: check for count_by_charges and use appropriate player::has_* function if( !tmp_inv.has_amount( type->item_id, item_count ) ) { return tmp_inv.has_amount( type->item_id, 1 ) && tmp_inv.has_charges( type->item_id, item_count ); @@ -395,7 +396,7 @@ bool mission::is_complete( const character_id &_npc_id ) const return true; case MGOAL_FIND_ANY_ITEM: - return u.has_mission_item( uid ) && ( !npc_id.is_valid() || npc_id == _npc_id ); + return player_character.has_mission_item( uid ) && ( !npc_id.is_valid() || npc_id == _npc_id ); case MGOAL_FIND_MONSTER: if( npc_id.is_valid() && npc_id != _npc_id ) { @@ -448,11 +449,11 @@ bool mission::is_complete( const character_id &_npc_id ) const } mission_goal_condition_context cc; - cc.alpha = get_talker_for( g->u ); + cc.alpha = get_talker_for( player_character ); cc.beta = get_talker_for( *n ); for( auto &mission : n->chatbin.missions_assigned ) { - if( mission->get_assigned_player_id() == g->u.getID() ) { + if( mission->get_assigned_player_id() == player_character.getID() ) { cc.missions_assigned.push_back( mission ); } } diff --git a/src/mission_util.cpp b/src/mission_util.cpp index 2e0fd87880f58..1b9b8c07bdad3 100644 --- a/src/mission_util.cpp +++ b/src/mission_util.cpp @@ -32,7 +32,7 @@ static tripoint reveal_destination( const std::string &type ) { - const tripoint your_pos = g->u.global_omt_location(); + const tripoint your_pos = get_player_character().global_omt_location(); const tripoint center_pos = overmap_buffer.find_random( your_pos, type, rng( 40, 80 ), false ); if( center_pos != overmap::invalid_tripoint ) { @@ -51,7 +51,7 @@ static void reveal_route( mission *miss, const tripoint &destination ) return; } - const tripoint source = g->u.global_omt_location(); + const tripoint source = get_player_character().global_omt_location(); const tripoint source_road = overmap_buffer.find_closest( source, "road", 3, false ); const tripoint dest_road = overmap_buffer.find_closest( destination, "road", 3, false ); @@ -100,7 +100,7 @@ tripoint mission_util::reveal_om_ter( const std::string &omter, int reveal_rad, int target_z ) { // Missions are normally on z-level 0, but allow an optional argument. - tripoint loc = g->u.global_omt_location(); + tripoint loc = get_player_character().global_omt_location(); loc.z = target_z; const tripoint place = overmap_buffer.find_closest( loc, omter, 0, must_see ); if( place != overmap::invalid_tripoint && reveal_rad >= 0 ) { @@ -127,11 +127,12 @@ static tripoint random_house_in_city( const city_reference &cref ) tripoint mission_util::random_house_in_closest_city() { - const auto center = g->u.global_sm_location(); - const auto cref = overmap_buffer.closest_city( center ); + Character &player_character = get_player_character(); + const tripoint center = player_character.global_sm_location(); + const city_reference cref = overmap_buffer.closest_city( center ); if( !cref ) { debugmsg( "could not find closest city" ); - return g->u.global_omt_location(); + return player_character.global_omt_location(); } return random_house_in_city( cref ); } @@ -249,7 +250,7 @@ static cata::optional find_or_create_om_terrain( const tripoint &origi static tripoint get_mission_om_origin( const mission_target_params ¶ms ) { // use the player or NPC's current position, adjust for the z value if any - tripoint origin_pos = g->u.global_omt_location(); + tripoint origin_pos = get_player_character().global_omt_location(); if( !params.origin_u ) { npc *guy = nullptr; @@ -333,13 +334,14 @@ tripoint mission_util::target_om_ter( const std::string &omter, int reveal_rad, tripoint mission_util::target_om_ter_random( const std::string &omter, int reveal_rad, mission *miss, bool must_see, int range, tripoint loc ) { + Character &player_character = get_player_character(); if( loc == overmap::invalid_tripoint ) { - loc = g->u.global_omt_location(); + loc = player_character.global_omt_location(); } auto places = overmap_buffer.find_all( loc, omter, range, must_see ); if( places.empty() ) { - return g->u.global_omt_location(); + return player_character.global_omt_location(); } const overmap *loc_om = overmap_buffer.get_existing_om_global( loc ).om; assert( loc_om ); @@ -526,7 +528,7 @@ bool mission_type::parse_funcs( const JsonObject &jo, std::functionu ); + d.alpha = get_talker_for( get_avatar() ); d.beta = get_talker_for( beta ); for( const talk_effect_fun_t &effect : talk_effects.effects ) { effect( d ); diff --git a/src/npcmove.cpp b/src/npcmove.cpp index 3b63188393ace..e8cd5640876e0 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -1239,7 +1239,7 @@ void npc::execute_action( npc_action action ) break; case npc_talk_to_player: - g->u.talk_to( get_talker_for( this ) ); + get_avatar().talk_to( get_talker_for( this ) ); moves = 0; break; diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 5e91cb4804ebb..872d8eae32412 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -503,7 +503,7 @@ void game::chat() if( npcselect < 0 ) { return; } - g->u.talk_to( get_talker_for( *available[npcselect] ) ); + get_avatar().talk_to( get_talker_for( *available[npcselect] ) ); break; } case NPC_CHAT_YELL: @@ -805,12 +805,13 @@ std::string dialogue::dynamic_line( const talk_topic &the_topic ) const _( "&You are deaf and can't talk. When you don't respond, %s becomes angry!" ), beta->disp_name() ); } + avatar &player_character = get_avatar(); if( topic == "TALK_SEDATED" ) { return string_format( _( "%1$s is sedated and can't be moved or woken up until the " "medication or sedation wears off.\nYou estimate it will wear " "off in %2$s." ), beta->disp_name(), - to_string_approx( g->u.estimate_effect_dur( skill_id( "firstaid" ), + to_string_approx( player_character.estimate_effect_dur( skill_id( "firstaid" ), effect_narcosis, 15_minutes, 6, *beta->get_npc() ) ) ); } @@ -854,7 +855,7 @@ std::string dialogue::dynamic_line( const talk_topic &the_topic ) const if( topic == "TALK_NONE" || topic == "TALK_DONE" ) { return _( "Bye." ); } else if( topic == "TALK_TRAIN" ) { - if( !g->u.backlog.empty() && g->u.backlog.front().id() == ACT_TRAIN ) { + if( !player_character.backlog.empty() && player_character.backlog.front().id() == ACT_TRAIN ) { return _( "Shall we resume?" ); } else if( beta->skills_offered_to( *alpha ).empty() && beta->styles_offered_to( *alpha ).empty() && @@ -1007,6 +1008,7 @@ void dialogue::gen_responses( const talk_topic &the_topic ) } } + Character &player_character = get_player_character(); if( the_topic.id == "TALK_MISSION_LIST" ) { if( beta->available_missions().size() == 1 ) { add_response( _( "Tell me about it." ), "TALK_MISSION_OFFER", @@ -1025,9 +1027,9 @@ void dialogue::gen_responses( const talk_topic &the_topic ) } } } else if( the_topic.id == "TALK_TRAIN" ) { - if( !g->u.backlog.empty() && g->u.backlog.front().id() == ACT_TRAIN && - g->u.backlog.front().index == beta->getID().get_value() ) { - player_activity &backlog = g->u.backlog.front(); + if( !player_character.backlog.empty() && player_character.backlog.front().id() == ACT_TRAIN && + player_character.backlog.front().index == beta->getID().get_value() ) { + player_activity &backlog = player_character.backlog.front(); const skill_id skillt( backlog.name ); // TODO: This is potentially dangerous. A skill and a martial art // could have the same ident! @@ -1967,7 +1969,7 @@ void talk_effect_fun_t::set_u_learn_recipe( const std::string &learned_recipe_id { function = [learned_recipe_id]( const dialogue & ) { const recipe &r = recipe_id( learned_recipe_id ).obj(); - g->u.learn_recipe( &r ); + get_player_character().learn_recipe( &r ); popup( _( "You learn how to craft %s." ), r.result_name() ); }; } diff --git a/src/npctrade.cpp b/src/npctrade.cpp index daafb438ddcf7..bf912cfa52c5b 100644 --- a/src/npctrade.cpp +++ b/src/npctrade.cpp @@ -251,12 +251,13 @@ void trading_window::setup_win( ui_adaptor &ui ) // 'cost' is the cost of a service the NPC may be rendering, if any. void trading_window::setup_trade( int cost, npc &np ) { + avatar &player_character = get_avatar(); // Populate the list of what the NPC is willing to buy, and the prices they pay // Note that the NPC's barter skill is factored into these prices. // TODO: Recalc item values every time a new item is selected // Trading is not linear - starving NPC may pay $100 for 3 jerky, but not $100000 for 300 jerky - theirs = npc_trading::init_buying( g->u, np, true ); - yours = npc_trading::init_buying( np, g->u, false ); + theirs = npc_trading::init_buying( player_character, np, true ); + yours = npc_trading::init_buying( np, player_character, false ); if( np.will_exchange_items_freely() ) { your_balance = 0; @@ -335,13 +336,14 @@ void trading_window::update_win( npc &np, const std::string &deal ) mvwprintz( w_them, point( 2, 0 ), trade_color, np.name ); mvwprintz( w_you, point( 2, 0 ), trade_color, _( "You" ) ); + avatar &player_character = get_avatar(); // Draw lists of items, starting from offset for( size_t whose = 0; whose <= 1; whose++ ) { const bool they = whose == 0; const std::vector &list = they ? theirs : yours; const size_t &offset = they ? them_off : you_off; - const player &person = they ? static_cast( np ) : - static_cast( g->u ); + const player &person = they ? static_cast( np ) : static_cast + ( player_character ); catacurses::window &w_whose = they ? w_them : w_you; int win_w = getmaxx( w_whose ); // Borders @@ -355,7 +357,7 @@ void trading_window::update_win( npc &np, const std::string &deal ) std::string itname = it->display_name(); if( np.will_exchange_items_freely() && ip.loc.where() != item_location::type::character ) { - itname = itname + " (" + ip.loc.describe( &g->u ) + ")"; + itname = itname + " (" + ip.loc.describe( &player_character ) + ")"; color = c_light_blue; } @@ -681,8 +683,9 @@ bool npc_trading::trade( npc &np, int cost, const std::string &deal ) std::list from_map; - npc_trading::transfer_items( trade_win.yours, g->u, np, from_map, false ); - npc_trading::transfer_items( trade_win.theirs, np, g->u, from_map, true ); + avatar &player_character = get_avatar(); + npc_trading::transfer_items( trade_win.yours, player_character, np, from_map, false ); + npc_trading::transfer_items( trade_win.theirs, np, player_character, from_map, true ); for( item_location *loc_ptr : from_map ) { if( !loc_ptr ) { @@ -707,7 +710,7 @@ bool npc_trading::trade( npc &np, int cost, const std::string &deal ) // NPCs will remember debts, to the limit that they'll extend credit or previous debts if( !np.will_exchange_items_freely() ) { trade_win.update_npc_owed( np ); - g->u.practice( skill_barter, practice / 10000 ); + player_character.practice( skill_barter, practice / 10000 ); } } return traded; diff --git a/src/talker_npc.cpp b/src/talker_npc.cpp index b51d131b2077c..0f8ea3fe4b5a4 100644 --- a/src/talker_npc.cpp +++ b/src/talker_npc.cpp @@ -55,7 +55,7 @@ bool talker_npc::will_talk_to_u( const player &u, bool force ) me_npc->set_attitude( NPCATT_NULL ); return false; } - if( g->u.getID() == u.getID() ) { + if( get_player_character().getID() == u.getID() ) { if( me_npc->get_faction() ) { me_npc->get_faction()->known_by_u = true; } @@ -77,9 +77,10 @@ bool talker_npc::will_talk_to_u( const player &u, bool force ) std::vector talker_npc::get_topics( bool radio_contact ) { + avatar &player_character = get_avatar(); std::vector add_topics; // For each active mission we have, let the mission know we talked to this NPC. - for( auto &mission : g->u.get_active_missions() ) { + for( auto &mission : player_character.get_active_missions() ) { mission->on_talk_with_npc( me_npc->getID() ); } @@ -105,7 +106,7 @@ std::vector talker_npc::get_topics( bool radio_contact ) most_difficult_mission = 0; bool chosen_urgent = false; for( auto &mission : me_npc->chatbin.missions_assigned ) { - if( mission->get_assigned_player_id() != g->u.getID() ) { + if( mission->get_assigned_player_id() != player_character.getID() ) { // Not assigned to the player that is currently talking to the npc continue; } @@ -132,11 +133,11 @@ std::vector talker_npc::get_topics( bool radio_contact ) } if( add_topics.back() == "TALK_NONE" ) { - add_topics.back() = me_npc->pick_talk_topic( g->u ); + add_topics.back() = me_npc->pick_talk_topic( player_character ); } me_npc->moves -= 100; - if( g->u.is_deaf() ) { + if( player_character.is_deaf() ) { if( add_topics.back() == "TALK_MUG" || add_topics.back() == "TALK_STRANGER_AGGRESSIVE" ) { me_npc->make_angry(); @@ -416,24 +417,24 @@ static consumption_result try_consume( npc &p, item &it, std::string &reason ) std::string talker_npc::give_item_to( const bool to_use ) { - avatar &u = get_avatar(); + avatar &player_character = get_avatar(); if( me_npc->is_hallucination() ) { return _( "No thanks, I'm good." ); } - item_location loc = game_menus::inv::titled_menu( g->u, _( "Offer what?" ), + item_location loc = game_menus::inv::titled_menu( player_character, _( "Offer what?" ), _( "You have no items to offer." ) ); if( !loc ) { return _( "Changed your mind?" ); } item &given = *loc; - if( ( &given == &u.weapon && given.has_flag( "NO_UNWIELD" ) ) || - ( u.is_worn( given ) && given.has_flag( "NO_TAKEOFF" ) ) ) { + if( ( &given == &player_character.weapon && given.has_flag( "NO_UNWIELD" ) ) || + ( player_character.is_worn( given ) && given.has_flag( "NO_TAKEOFF" ) ) ) { // Bionic weapon or shackles return _( "How?" ); } - if( given.is_dangerous() && !u.has_trait( trait_DEBUG_MIND_CONTROL ) ) { + if( given.is_dangerous() && !player_character.has_trait( trait_DEBUG_MIND_CONTROL ) ) { return _( "Are you insane!?" ); } @@ -452,9 +453,9 @@ std::string talker_npc::give_item_to( const bool to_use ) const consumption_result consume_res = try_consume( *me_npc, given, reason ); if( consume_res != REFUSED ) { if( consume_res == CONSUMED_ALL ) { - u.i_rem( &given ); + player_character.i_rem( &given ); } - u.moves -= 100; + player_character.moves -= 100; if( given.is_container() ) { given.on_contents_changed(); } @@ -510,8 +511,8 @@ std::string talker_npc::give_item_to( const bool to_use ) if( taken ) { - u.i_rem( &given ); - u.moves -= 100; + player_character.i_rem( &given ); + player_character.moves -= 100; me_npc->has_new_items = true; } diff --git a/src/vehicle_move.cpp b/src/vehicle_move.cpp index 88b33d2076c29..f9f5180ba16c3 100644 --- a/src/vehicle_move.cpp +++ b/src/vehicle_move.cpp @@ -143,12 +143,13 @@ void vehicle:: smart_controller_handle_turn( bool thrusting, bool rotorcraft = is_flying && is_rotorcraft(); + Character &player_character = get_player_character(); if( rotorcraft || c_engines.size() <= 1 || c_engines.size() > 5 ) { // bail and shut down for( const vpart_reference &vp : get_avail_parts( "SMART_ENGINE_CONTROLLER" ) ) { vp.part().enabled = false; } - if( player_in_control( g->u ) ) { + if( player_in_control( player_character ) ) { if( rotorcraft ) { add_msg( _( "Smart controller does not support flying vehicles." ) ); } else if( c_engines.size() <= 1 ) { @@ -345,7 +346,7 @@ void vehicle:: smart_controller_handle_turn( bool thrusting, for( const vpart_reference &vp : get_avail_parts( "SMART_ENGINE_CONTROLLER" ) ) { vp.part().enabled = false; } - if( player_in_control( g->u ) ) { + if( player_in_control( player_character ) ) { add_msg( m_bad, _( "Smart controller failed to start an engine." ) ); add_msg( m_bad, _( "Smart controller is shutting down." ) ); } @@ -363,7 +364,7 @@ void vehicle:: smart_controller_handle_turn( bool thrusting, } smart_controller_state = cur_state; - if( player_in_control( g->u ) ) { + if( player_in_control( player_character ) ) { add_msg( m_debug, _( "Smart controller optimizes engine state." ) ); } } diff --git a/tests/char_stamina_test.cpp b/tests/char_stamina_test.cpp index 1e3c588b2d647..0ac112dd8b3d3 100644 --- a/tests/char_stamina_test.cpp +++ b/tests/char_stamina_test.cpp @@ -1,14 +1,11 @@ #include -#include "avatar.h" #include "bodypart.h" #include "calendar.h" #include "catch/catch.hpp" #include "character.h" -#include "game.h" #include "item.h" #include "options.h" -#include "player.h" #include "player_helpers.h" #include "type_id.h" #include "units.h" @@ -41,19 +38,19 @@ static const move_mode_id move_mode_crouch( "crouch" ); // See also `clear_character` in `tests/player_helpers.cpp` -// Remove "winded" effect from the player (but do not change stamina) -static void catch_breath( player &dummy ) +// Remove "winded" effect from the Character (but do not change stamina) +static void catch_breath( Character &dummy ) { dummy.remove_effect( effect_winded ); REQUIRE_FALSE( dummy.has_effect( effect_winded ) ); } // Return `stamina_move_cost_modifier` in the given move_mode with [0.0 .. 1.0] stamina remaining -static float move_cost_mod( player &dummy, const move_mode_id &move_mode, +static float move_cost_mod( Character &dummy, const move_mode_id &move_mode, float stamina_proportion = 1.0 ) { // Reset and be able to run - clear_character( dummy ); + clear_avatar(); catch_breath( dummy ); REQUIRE( dummy.can_run() ); @@ -71,7 +68,7 @@ static float move_cost_mod( player &dummy, const move_mode_id &move_mode, } // Return amount of stamina burned per turn by `burn_move_stamina` in the given movement mode. -static int actual_burn_rate( player &dummy, const move_mode_id &move_mode ) +static int actual_burn_rate( Character &dummy, const move_mode_id &move_mode ) { // Ensure we can run if necessary (aaaa zombies!) dummy.set_stamina( dummy.get_stamina_max() ); @@ -92,8 +89,8 @@ static int actual_burn_rate( player &dummy, const move_mode_id &move_mode ) return before_stam - after_stam; } -// Burden the player with a given proportion [0.0 .. inf) of their maximum weight capacity -static void burden_player( player &dummy, float burden_proportion ) +// Burden the Character with a given proportion [0.0 .. inf) of their maximum weight capacity +static void burden_player( Character &dummy, float burden_proportion ) { units::mass capacity = dummy.weight_capacity(); int units = static_cast( capacity * burden_proportion / 1_gram ); @@ -110,16 +107,16 @@ static void burden_player( player &dummy, float burden_proportion ) // Return amount of stamina burned per turn by `burn_move_stamina` in the given movement mode, // while carrying the given proportion [0.0, inf) of their maximum weight capacity. -static int burdened_burn_rate( player &dummy, const move_mode_id &move_mode, +static int burdened_burn_rate( Character &dummy, const move_mode_id &move_mode, float burden_proportion = 0.0 ) { - clear_character( dummy, false ); + clear_avatar( false ); burden_player( dummy, burden_proportion ); return actual_burn_rate( dummy, move_mode ); } // Return the actual amount of stamina regenerated by `update_stamina` in the given number of moves -static float actual_regen_rate( player &dummy, int moves ) +static float actual_regen_rate( Character &dummy, int moves ) { // Start at 10% stamina, plenty of space for regen dummy.set_stamina( dummy.get_stamina_max() / 10 ); @@ -137,7 +134,7 @@ static float actual_regen_rate( player &dummy, int moves ) TEST_CASE( "stamina movement cost modifier", "[stamina][cost]" ) { - player &dummy = g->u; + Character &dummy = get_player_character(); SECTION( "running cost is double walking cost for the same stamina level" ) { CHECK( move_cost_mod( dummy, move_mode_run, 1.0 ) == 2 * move_cost_mod( dummy, move_mode_walk, @@ -184,8 +181,8 @@ TEST_CASE( "stamina movement cost modifier", "[stamina][cost]" ) TEST_CASE( "modify character stamina", "[stamina][modify]" ) { - player &dummy = g->u; - clear_character( dummy ); + Character &dummy = get_player_character(); + clear_avatar(); catch_breath( dummy ); REQUIRE_FALSE( dummy.is_npc() ); REQUIRE_FALSE( dummy.has_effect( effect_winded ) ); @@ -259,7 +256,7 @@ TEST_CASE( "modify character stamina", "[stamina][modify]" ) TEST_CASE( "stamina burn for movement", "[stamina][burn][move]" ) { - player &dummy = g->u; + Character &dummy = get_player_character(); // Defined in game_balance.json const int normal_burn_rate = get_option( "PLAYER_BASE_STAMINA_BURN_RATE" ); @@ -322,7 +319,7 @@ TEST_CASE( "stamina burn for movement", "[stamina][burn][move]" ) TEST_CASE( "burning stamina when overburdened may cause pain", "[stamina][burn][pain]" ) { - player &dummy = g->u; + Character &dummy = get_player_character(); int pain_before; int pain_after; @@ -334,7 +331,7 @@ TEST_CASE( "burning stamina when overburdened may cause pain", "[stamina][burn][ // To guarantee pain when moving and ensure consistent test results, // set to 350% burden. - clear_character( dummy, false ); + clear_avatar( false ); burden_player( dummy, 3.5 ); WHEN( "they have zero stamina left" ) { @@ -365,8 +362,8 @@ TEST_CASE( "burning stamina when overburdened may cause pain", "[stamina][burn][ TEST_CASE( "stamina regeneration rate", "[stamina][update][regen]" ) { - player &dummy = g->u; - clear_character( dummy ); + Character &dummy = get_player_character(); + clear_avatar(); int turn_moves = to_moves( 1_turns ); const float normal_regen_rate = get_option( "PLAYER_BASE_STAMINA_REGEN_RATE" ); @@ -392,8 +389,8 @@ TEST_CASE( "stamina regeneration rate", "[stamina][update][regen]" ) TEST_CASE( "stamina regen in different movement modes", "[stamina][update][regen][mode]" ) { - player &dummy = g->u; - clear_character( dummy ); + Character &dummy = get_player_character(); + clear_avatar(); catch_breath( dummy ); int turn_moves = to_moves( 1_turns ); @@ -425,8 +422,8 @@ TEST_CASE( "stamina regen in different movement modes", "[stamina][update][regen TEST_CASE( "stamina regen with mouth encumbrance", "[stamina][update][regen][encumbrance]" ) { - player &dummy = g->u; - clear_character( dummy ); + Character &dummy = get_player_character(); + clear_avatar(); catch_breath( dummy ); dummy.set_body(); diff --git a/tests/itemname_test.cpp b/tests/itemname_test.cpp index 728c5fdd5bb86..7ea664f20197f 100644 --- a/tests/itemname_test.cpp +++ b/tests/itemname_test.cpp @@ -1,18 +1,18 @@ #include #include -#include "avatar.h" #include "catch/catch.hpp" +#include "character.h" #include "player_helpers.h" #include "flat_set.h" -#include "game.h" #include "item.h" #include "type_id.h" TEST_CASE( "item sizing display", "[item][iteminfo][display_name][sizing]" ) { + Character &player_character = get_player_character(); GIVEN( "player is a normal size" ) { - g->u.clear_mutations(); + player_character.clear_mutations(); WHEN( "the item is a normal size" ) { std::string name = item( "bookplate" ).display_name(); @@ -35,7 +35,7 @@ TEST_CASE( "item sizing display", "[item][iteminfo][display_name][sizing]" ) std::string name = i.display_name(); THEN( "we have the correct sizing" ) { - const item::sizing sizing_level = i.get_sizing( g->u ); + const item::sizing sizing_level = i.get_sizing( player_character ); CHECK( sizing_level == item::sizing::small_sized_human_char ); } @@ -47,8 +47,8 @@ TEST_CASE( "item sizing display", "[item][iteminfo][display_name][sizing]" ) } GIVEN( "player is a huge size" ) { - g->u.clear_mutations(); - g->u.toggle_trait( trait_id( "HUGE_OK" ) ); + player_character.clear_mutations(); + player_character.toggle_trait( trait_id( "HUGE_OK" ) ); WHEN( "the item is a normal size" ) { std::string name = item( "bookplate" ).display_name(); @@ -71,7 +71,7 @@ TEST_CASE( "item sizing display", "[item][iteminfo][display_name][sizing]" ) std::string name = i.display_name(); THEN( "we have the correct sizing" ) { - const item::sizing sizing_level = i.get_sizing( g->u ); + const item::sizing sizing_level = i.get_sizing( player_character ); CHECK( sizing_level == item::sizing::small_sized_big_char ); } @@ -83,8 +83,8 @@ TEST_CASE( "item sizing display", "[item][iteminfo][display_name][sizing]" ) } GIVEN( "player is a small size" ) { - g->u.clear_mutations(); - g->u.toggle_trait( trait_id( "SMALL_OK" ) ); + player_character.clear_mutations(); + player_character.toggle_trait( trait_id( "SMALL_OK" ) ); WHEN( "the item is a normal size" ) { std::string name = item( "bookplate" ).display_name(); @@ -107,7 +107,7 @@ TEST_CASE( "item sizing display", "[item][iteminfo][display_name][sizing]" ) std::string name = i.display_name(); THEN( "we have the correct sizing" ) { - const item::sizing sizing_level = i.get_sizing( g->u ); + const item::sizing sizing_level = i.get_sizing( player_character ); CHECK( sizing_level == item::sizing::small_sized_small_char ); } diff --git a/tests/player_helpers.cpp b/tests/player_helpers.cpp index 7619904eb3585..095d5aa6cae54 100644 --- a/tests/player_helpers.cpp +++ b/tests/player_helpers.cpp @@ -111,9 +111,9 @@ void clear_character( player &dummy, bool debug_storage ) dummy.setpos( spot ); } -void clear_avatar() +void clear_avatar( bool debug_storage ) { - clear_character( get_avatar() ); + clear_character( get_avatar(), debug_storage ); } void process_activity( player &dummy ) diff --git a/tests/player_helpers.h b/tests/player_helpers.h index 09bcdc2abc48a..179335681f975 100644 --- a/tests/player_helpers.h +++ b/tests/player_helpers.h @@ -14,7 +14,7 @@ struct point; int get_remaining_charges( const std::string &tool_id ); bool player_has_item_of_type( const std::string & ); void clear_character( player &, bool debug_storage = true ); -void clear_avatar(); +void clear_avatar( bool debug_storage = true ); void process_activity( player &dummy ); npc &spawn_npc( const point &, const std::string &npc_class ); From f95326e8ad4dddc653f3e459d270f0947a61936a Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Fri, 17 Jul 2020 02:58:14 -0700 Subject: [PATCH 094/151] Global reference migration part 30 (#42208) --- src/activity_item_handling.cpp | 24 ++++++++++++--------- src/advanced_inv_area.cpp | 29 ++++++++++++++------------ src/armor_layers.cpp | 30 +++++++++++++-------------- src/editmap.cpp | 31 +++++++++++++++------------ src/faction.cpp | 28 ++++++++++++++----------- src/main_menu.cpp | 38 +++++++++++++++++++--------------- src/map_field.cpp | 23 ++++++++++---------- src/mission_start.cpp | 33 ++++++++++++++++------------- tests/item_tname_test.cpp | 27 ++++++++++++------------ tests/stats_tracker_test.cpp | 19 +++++++---------- 10 files changed, 153 insertions(+), 129 deletions(-) diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index 0fbd1e36f82d9..d8fb16a271ac3 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -660,9 +660,10 @@ static int move_cost_inv( const item &it, const tripoint &src, const tripoint &d // typical flat ground move cost const int mc_per_tile = 100; + Character &player_character = get_player_character(); // only free inventory capacity - const int inventory_capacity = units::to_milliliter( g->u.volume_capacity() - - g->u.volume_carried() ); + const int inventory_capacity = units::to_milliliter( player_character.volume_capacity() - + player_character.volume_carried() ); const int item_volume = units::to_milliliter( it.volume() ); @@ -681,7 +682,7 @@ static int move_cost_cart( const item &it, const tripoint &src, const tripoint & const int MAX_COST = 500; // cost to move item into the cart - const int pickup_cost = Pickup::cost_to_move_item( g->u, it ); + const int pickup_cost = Pickup::cost_to_move_item( get_player_character(), it ); // cost to move item out of the cart const int drop_cost = pickup_cost; @@ -704,8 +705,9 @@ static int move_cost_cart( const item &it, const tripoint &src, const tripoint & static int move_cost( const item &it, const tripoint &src, const tripoint &dest ) { - if( g->u.get_grab_type() == object_type::VEHICLE ) { - tripoint cart_position = g->u.pos() + g->u.grab_point; + avatar &player_character = get_avatar(); + if( player_character.get_grab_type() == object_type::VEHICLE ) { + tripoint cart_position = player_character.pos() + player_character.grab_point; if( const cata::optional vp = get_map().veh_at( cart_position ).part_with_feature( "CARGO", false ) ) { @@ -1099,6 +1101,7 @@ static activity_reason_info can_do_activity_there( const activity_id &act, playe p.invalidate_crafting_inventory(); zone_manager &mgr = zone_manager::get_manager(); std::vector zones; + Character &player_character = get_player_character(); map &here = get_map(); if( act == ACT_VEHICLE_DECONSTRUCTION || act == ACT_VEHICLE_REPAIR ) { @@ -1108,7 +1111,7 @@ static activity_reason_info can_do_activity_there( const activity_id &act, playe return activity_reason_info::fail( do_activity_reason::NO_ZONE ); } // if the vehicle is moving or player is controlling it. - if( std::abs( veh->velocity ) > 100 || veh->player_in_control( g->u ) ) { + if( std::abs( veh->velocity ) > 100 || veh->player_in_control( player_character ) ) { return activity_reason_info::fail( do_activity_reason::NO_ZONE ); } for( const npc &guy : g->all_npcs() ) { @@ -1122,8 +1125,9 @@ static activity_reason_info can_do_activity_there( const activity_id &act, playe } // If their position or intended position or player position/intended position // then discount, don't need to move each other out of the way. - if( here.getlocal( g->u.activity.placement ) == src_loc || - guy_work_spot == src_loc || guy.pos() == src_loc || ( p.is_npc() && g->u.pos() == src_loc ) ) { + if( here.getlocal( player_character.activity.placement ) == src_loc || + guy_work_spot == src_loc || guy.pos() == src_loc || + ( p.is_npc() && player_character.pos() == src_loc ) ) { return activity_reason_info::fail( do_activity_reason::ALREADY_WORKING ); } if( guy_work_spot != tripoint_zero ) { @@ -1133,8 +1137,8 @@ static activity_reason_info can_do_activity_there( const activity_id &act, playe already_working_indexes.push_back( guy.activity_vehicle_part_index ); } } - if( g->u.activity_vehicle_part_index != -1 ) { - already_working_indexes.push_back( g->u.activity_vehicle_part_index ); + if( player_character.activity_vehicle_part_index != -1 ) { + already_working_indexes.push_back( player_character.activity_vehicle_part_index ); } } if( act == ACT_VEHICLE_DECONSTRUCTION ) { diff --git a/src/advanced_inv_area.cpp b/src/advanced_inv_area.cpp index a75b5dfc5dc34..85372e33e8308 100644 --- a/src/advanced_inv_area.cpp +++ b/src/advanced_inv_area.cpp @@ -14,7 +14,6 @@ #include "enums.h" #include "field.h" #include "field_type.h" -#include "game.h" #include "game_constants.h" #include "int_id.h" #include "inventory.h" @@ -33,10 +32,11 @@ int advanced_inv_area::get_item_count() const { + Character &player_character = get_player_character(); if( id == AIM_INVENTORY ) { - return g->u.inv.size(); + return player_character.inv.size(); } else if( id == AIM_WORN ) { - return g->u.worn.size(); + return player_character.worn.size(); } else if( id == AIM_ALL ) { return 0; } else if( id == AIM_DRAGGED ) { @@ -60,7 +60,8 @@ advanced_inv_area::advanced_inv_area( aim_location id, const point &h, tripoint void advanced_inv_area::init() { - pos = g->u.pos() + off; + avatar &player_character = get_avatar(); + pos = player_character.pos() + off; veh = nullptr; vstor = -1; // must update in main function @@ -76,15 +77,15 @@ void advanced_inv_area::init() canputitemsloc = true; break; case AIM_DRAGGED: - if( g->u.get_grab_type() != object_type::VEHICLE ) { + if( player_character.get_grab_type() != object_type::VEHICLE ) { canputitemsloc = false; desc[0] = _( "Not dragging any vehicle!" ); break; } // offset for dragged vehicles is not statically initialized, so get it - off = g->u.grab_point; + off = player_character.grab_point; // Reset position because offset changed - pos = g->u.pos() + off; + pos = player_character.pos() + off; if( const cata::optional vp = here.veh_at( pos ).part_with_feature( "CARGO", false ) ) { veh = &vp->vehicle(); @@ -169,7 +170,7 @@ void advanced_inv_area::init() // trap? const trap &tr = here.tr_at( pos ); - if( tr.can_see( pos, g->u ) && !tr.is_benign() ) { + if( tr.can_see( pos, player_character ) && !tr.is_benign() ) { flags.append( _( " TRAP" ) ); } @@ -189,7 +190,7 @@ units::volume advanced_inv_area::free_volume( bool in_vehicle ) const // should be a specific location instead assert( id != AIM_ALL ); if( id == AIM_INVENTORY || id == AIM_WORN ) { - return g->u.free_space(); + return get_player_character().free_space(); } return in_vehicle ? veh->free_volume( vstor ) : get_map().free_volume( pos ); } @@ -237,10 +238,11 @@ item *advanced_inv_area::get_container( bool in_vehicle ) { item *container = nullptr; + Character &player_character = get_player_character(); if( uistate.adv_inv_container_location != -1 ) { // try to find valid container in the area if( uistate.adv_inv_container_location == AIM_INVENTORY ) { - const invslice &stacks = g->u.inv.slice(); + const invslice &stacks = player_character.inv.slice(); // check index first if( stacks.size() > static_cast( uistate.adv_inv_container_index ) ) { @@ -262,7 +264,7 @@ item *advanced_inv_area::get_container( bool in_vehicle ) } } } else if( uistate.adv_inv_container_location == AIM_WORN ) { - auto &worn = g->u.worn; + auto &worn = player_character.worn; size_t idx = static_cast( uistate.adv_inv_container_index ); if( worn.size() > idx ) { auto iter = worn.begin(); @@ -387,14 +389,15 @@ static tripoint aim_vector( aim_location id ) } void advanced_inv_area::set_container_position() { + avatar &player_character = get_avatar(); // update the offset of the container based on location if( uistate.adv_inv_container_location == AIM_DRAGGED ) { - off = g->u.grab_point; + off = player_character.grab_point; } else { off = aim_vector( static_cast( uistate.adv_inv_container_location ) ); } // update the absolute position - pos = g->u.pos() + off; + pos = player_character.pos() + off; // update vehicle information if( const cata::optional vp = get_map().veh_at( pos ).part_with_feature( "CARGO", false ) ) { diff --git a/src/armor_layers.cpp b/src/armor_layers.cpp index 69494835eacaf..0c3b77a318b63 100644 --- a/src/armor_layers.cpp +++ b/src/armor_layers.cpp @@ -8,12 +8,11 @@ #include #include -#include "avatar.h" #include "cata_utility.h" #include "catacharset.h" // used for utf8_width() +#include "character.h" #include "debug.h" #include "enums.h" -#include "game.h" #include "game_inventory.h" #include "input.h" #include "inventory.h" @@ -535,10 +534,11 @@ void player::sort_armor() ctxt.register_action( "USAGE_HELP" ); ctxt.register_action( "HELP_KEYBINDINGS" ); - auto do_return_entry = []() { - g->u.assign_activity( ACT_ARMOR_LAYERS, 0 ); - g->u.activity.auto_resume = true; - g->u.activity.moves_left = INT_MAX; + Character &player_character = get_player_character(); + auto do_return_entry = [&player_character]() { + player_character.assign_activity( ACT_ARMOR_LAYERS, 0 ); + player_character.activity.auto_resume = true; + player_character.activity.moves_left = INT_MAX; }; int leftListSize = 0; @@ -711,17 +711,17 @@ void player::sort_armor() while( !exit ) { if( is_player() ) { // Totally hoisted this from advanced_inv - if( g->u.moves < 0 ) { + if( player_character.moves < 0 ) { do_return_entry(); return; } } else { // Player is sorting NPC's armor here - if( rl_dist( g->u.pos(), pos() ) > 1 ) { + if( rl_dist( player_character.pos(), pos() ) > 1 ) { add_msg_if_npc( m_bad, _( "%s is too far to sort armor." ), name ); return; } - if( attitude_to( g->u ) != Creature::Attitude::FRIENDLY ) { + if( attitude_to( player_character ) != Creature::Attitude::FRIENDLY ) { add_msg_if_npc( m_bad, _( "%s is not friendly!" ), name ); return; } @@ -802,9 +802,9 @@ void player::sort_armor() } } else if( action == "CHANGE_SIDE" ) { if( leftListIndex < leftListSize && tmp_worn[leftListIndex]->is_sided() ) { - if( g->u.query_yn( _( "Swap side for %s?" ), - colorize( tmp_worn[leftListIndex]->tname(), - tmp_worn[leftListIndex]->color_in_inventory() ) ) ) { + if( player_character.query_yn( _( "Swap side for %s?" ), + colorize( tmp_worn[leftListIndex]->tname(), + tmp_worn[leftListIndex]->color_in_inventory() ) ) ) { change_side( *tmp_worn[leftListIndex] ); } } @@ -867,16 +867,16 @@ void player::sort_armor() } else if( action == "REMOVE_ARMOR" ) { // query (for now) if( leftListIndex < leftListSize ) { - if( g->u.query_yn( _( "Remove selected armor?" ) ) ) { + if( player_character.query_yn( _( "Remove selected armor?" ) ) ) { do_return_entry(); // remove the item, asking to drop it if necessary takeoff( *tmp_worn[leftListIndex] ); - if( !g->u.has_activity( ACT_ARMOR_LAYERS ) ) { + if( !player_character.has_activity( ACT_ARMOR_LAYERS ) ) { // An activity has been created to take off the item; // we must surrender control until it is done. return; } - g->u.cancel_activity(); + player_character.cancel_activity(); selected = -1; } } diff --git a/src/editmap.cpp b/src/editmap.cpp index 4852877175a8a..5e254ed4bd9a2 100644 --- a/src/editmap.cpp +++ b/src/editmap.cpp @@ -260,7 +260,7 @@ bool editmap::eget_direction( tripoint &p, const std::string &action ) const { p = tripoint_zero; if( action == "CENTER" ) { - p = g->u.pos() - target; + p = get_player_character().pos() - target; } else if( action == "LEFT_WIDE" ) { p.x = -tmax.x / 2; } else if( action == "DOWN_WIDE" ) { @@ -337,8 +337,9 @@ shared_ptr_fast editmap::create_or_get_ui_adaptor() cata::optional editmap::edit() { - restore_on_out_of_scope view_offset_prev( g->u.view_offset ); - target = g->u.pos() + g->u.view_offset; + avatar &player_character = get_avatar(); + restore_on_out_of_scope view_offset_prev( player_character.view_offset ); + target = player_character.pos() + player_character.view_offset; input_context ctxt( "EDITMAP" ); ctxt.set_iso( true ); ctxt.register_directions(); @@ -463,6 +464,7 @@ void editmap::uber_draw_ter( const catacurses::window &w, map *m ) if( refresh_mplans ) { hilights["mplan"].points.clear(); } + avatar &player_character = get_avatar(); for( const tripoint &p : tripoint_range( start, end ) ) { int sym = game_map ? '%' : ' '; if( p.x >= 0 && p.x < msize && p.y >= 0 && p.y < msize ) { @@ -471,7 +473,7 @@ void editmap::uber_draw_ter( const catacurses::window &w, map *m ) if( critter != nullptr ) { critter->draw( w, center.xy(), false ); } else { - m->drawsq( w, g->u, p, false, draw_itm, center, false, true ); + m->drawsq( w, player_character, p, false, draw_itm, center, false, true ); } if( refresh_mplans ) { monster *mon = dynamic_cast( critter ); @@ -482,7 +484,7 @@ void editmap::uber_draw_ter( const catacurses::window &w, map *m ) } } } else { - m->drawsq( w, g->u, p, false, draw_itm, center, false, true ); + m->drawsq( w, player_character, p, false, draw_itm, center, false, true ); } } else { mvwputch( w, p.xy() - start.xy(), c_dark_gray, sym ); @@ -495,7 +497,8 @@ void editmap::uber_draw_ter( const catacurses::window &w, map *m ) void editmap::do_ui_invalidation() { - g->u.view_offset = target - g->u.pos(); + avatar &player_character = get_avatar(); + player_character.view_offset = target - player_character.pos(); g->invalidate_main_ui_adaptor(); create_or_get_ui_adaptor()->invalidate_ui(); } @@ -504,6 +507,7 @@ void editmap::draw_main_ui_overlay() { const Creature *critter = g->critter_at( target ); + avatar &player_character = get_avatar(); map &here = get_map(); #if !defined( TILES ) if( uberdraw ) { @@ -515,7 +519,7 @@ void editmap::draw_main_ui_overlay() if( critter != nullptr ) { critter->draw( g->w_terrain, target, true ); } else { - here.drawsq( g->w_terrain, g->u, target, true, true, target ); + here.drawsq( g->w_terrain, player_character, target, true, true, target ); } #ifdef TILES // give some visual indication of different cursor moving modes @@ -625,7 +629,7 @@ void editmap::draw_main_ui_overlay() g->draw_trap_override( map_p, tmpmap.tr_at( tmp_p ).loadid ); g->draw_field_override( map_p, tmpmap.field_at( tmp_p ).displayed_field_type() ); const maptile &tile = tmpmap.maptile_at( tmp_p ); - if( tmpmap.sees_some_items( tmp_p, g->u.pos() - origin_p ) ) { + if( tmpmap.sees_some_items( tmp_p, player_character.pos() - origin_p ) ) { const item &itm = tile.get_uppermost_item(); const mtype *const mon = itm.get_mtype(); g->draw_item_override( map_p, itm.typeId(), mon ? mon->id : mtype_id::NULL_ID(), @@ -681,7 +685,7 @@ void editmap::draw_main_ui_overlay() tmpmap.reset_vehicle_cache( target.z ); const tripoint center( SEEX - 1, SEEY - 1, target.z ); for( const tripoint &p : tmpmap.points_on_zlevel() ) { - tmpmap.drawsq( g->w_terrain, g->u, p, false, true, center, false, true ); + tmpmap.drawsq( g->w_terrain, player_character, p, false, true, center, false, true ); } #ifdef TILES } @@ -731,12 +735,13 @@ void editmap::update_view_with_help( const std::string &txt, const std::string & } const auto &map_cache = here.get_cache( target.z ); - const std::string u_see_msg = g->u.sees( target ) ? _( "yes" ) : _( "no" ); + Character &player_character = get_player_character(); + const std::string u_see_msg = player_character.sees( target ) ? _( "yes" ) : _( "no" ); mvwprintw( w_info, point( 1, off++ ), _( "dist: %d u_see: %s veh: %s scent: %d" ), - rl_dist( g->u.pos(), target ), u_see_msg, veh_msg, g->scent.get( target ) ); + rl_dist( player_character.pos(), target ), u_see_msg, veh_msg, g->scent.get( target ) ); mvwprintw( w_info, point( 1, off++ ), _( "sight_range: %d, daylight_sight_range: %d," ), - g->u.sight_range( g->light_level( g->u.posz() ) ), - g->u.sight_range( current_daylight_level( calendar::turn ) ) ); + player_character.sight_range( g->light_level( player_character.posz() ) ), + player_character.sight_range( current_daylight_level( calendar::turn ) ) ); mvwprintw( w_info, point( 1, off++ ), _( "transparency: %.5f, visibility: %.5f," ), map_cache.transparency_cache[target.x][target.y], map_cache.seen_cache[target.x][target.y] ); diff --git a/src/faction.cpp b/src/faction.cpp index d135375e5a66b..6f185f8245179 100644 --- a/src/faction.cpp +++ b/src/faction.cpp @@ -464,7 +464,8 @@ void basecamp::faction_display( const catacurses::window &fac_w, const int width { int y = 2; const nc_color col = c_white; - const tripoint player_abspos = g->u.global_omt_location(); + Character &player_character = get_player_character(); + const tripoint player_abspos = player_character.global_omt_location(); tripoint camp_pos = camp_omt_pos(); std::string direction = direction_name( direction_from( player_abspos, camp_pos ) ); mvwprintz( fac_w, point( width, ++y ), c_light_gray, _( "Press enter to rename this camp" ) ); @@ -472,7 +473,7 @@ void basecamp::faction_display( const catacurses::window &fac_w, const int width mvwprintz( fac_w, point( width, ++y ), c_light_gray, _( "Direction: to the " ) + direction ); } mvwprintz( fac_w, point( width, ++y ), col, _( "Location: (%d, %d)" ), camp_pos.x, camp_pos.y ); - faction *yours = g->u.get_faction(); + faction *yours = player_character.get_faction(); std::string food_text = string_format( _( "Food Supply: %s %d calories" ), yours->food_supply_text(), yours->food_supply ); nc_color food_col = yours->food_supply_color(); @@ -497,7 +498,8 @@ int npc::faction_display( const catacurses::window &fac_w, const int width ) con int retval = 0; int y = 2; const nc_color col = c_white; - const tripoint player_abspos = g->u.global_omt_location(); + Character &player_character = get_player_character(); + const tripoint player_abspos = player_character.global_omt_location(); //get NPC followers, status, direction, location, needs, weapon, etc. mvwprintz( fac_w, point( width, ++y ), c_light_gray, _( "Press enter to talk to this follower " ) ); @@ -546,15 +548,15 @@ int npc::faction_display( const catacurses::window &fac_w, const int width ) con } std::string can_see; nc_color see_color; - bool u_has_radio = g->u.has_item_with_flag( "TWO_WAY_RADIO", true ); + bool u_has_radio = player_character.has_item_with_flag( "TWO_WAY_RADIO", true ); bool guy_has_radio = has_item_with_flag( "TWO_WAY_RADIO", true ); // is the NPC even in the same area as the player? if( rl_dist( player_abspos, global_omt_location() ) > 3 || - ( rl_dist( g->u.pos(), pos() ) > SEEX * 2 || !g->u.sees( pos() ) ) ) { + ( rl_dist( player_character.pos(), pos() ) > SEEX * 2 || !player_character.sees( pos() ) ) ) { if( u_has_radio && guy_has_radio ) { // TODO: better range calculation than just elevation. int max_range = 200; - max_range *= ( 1 + ( g->u.pos().z * 0.1 ) ); + max_range *= ( 1 + ( player_character.pos().z * 0.1 ) ); max_range *= ( 1 + ( pos().z * 0.1 ) ); if( is_stationed ) { // if camp that NPC is at, has a radio tower @@ -564,15 +566,16 @@ int npc::faction_display( const catacurses::window &fac_w, const int width ) con } // if camp that player is at, has a radio tower cata::optional player_camp = - overmap_buffer.find_camp( g->u.global_omt_location().xy() ); + overmap_buffer.find_camp( player_character.global_omt_location().xy() ); if( const cata::optional player_camp = overmap_buffer.find_camp( - g->u.global_omt_location().xy() ) ) { + player_character.global_omt_location().xy() ) ) { if( ( *player_camp )->has_provides( "radio_tower" ) ) { max_range *= 5; } } - if( ( ( g->u.pos().z >= 0 && pos().z >= 0 ) || ( g->u.pos().z == pos().z ) ) && - square_dist( g->u.global_sm_location(), global_sm_location() ) <= max_range ) { + if( ( ( player_character.pos().z >= 0 && pos().z >= 0 ) || + ( player_character.pos().z == pos().z ) ) && + square_dist( player_character.global_sm_location(), global_sm_location() ) <= max_range ) { retval = 2; can_see = _( "Within radio range" ); see_color = c_light_green; @@ -815,6 +818,7 @@ void faction_manager::display() const wnoutrefresh( w_missions ); } ); + avatar &player_character = get_avatar(); while( true ) { // create a list of NPCs, visible and the ones on overmapbuffer followers.clear(); @@ -839,7 +843,7 @@ void faction_manager::display() const camp = nullptr; // create a list of faction camps camps.clear(); - for( auto elem : g->u.camps ) { + for( auto elem : player_character.camps ) { cata::optional p = overmap_buffer.find_camp( elem.xy() ); if( !p ) { continue; @@ -900,7 +904,7 @@ void faction_manager::display() const popup( _( "%s returns from their mission" ), guy->disp_name() ); } else { if( tab == tab_mode::TAB_FOLLOWERS && guy && ( interactable || radio_interactable ) ) { - g->u.talk_to( get_talker_for( *guy ), false, radio_interactable ); + player_character.talk_to( get_talker_for( *guy ), false, radio_interactable ); } else if( tab == tab_mode::TAB_MYFACTION && camp ) { camp->query_new_name(); } diff --git a/src/main_menu.cpp b/src/main_menu.cpp index 413e050f29b46..2a85ea8f4a641 100644 --- a/src/main_menu.cpp +++ b/src/main_menu.cpp @@ -503,7 +503,8 @@ bool main_menu::opening_screen() ctxt.register_action( "ANY_INPUT" ); bool start = false; - g->u = avatar(); + avatar &player_character = get_avatar(); + player_character = avatar(); int sel_line = 0; @@ -674,9 +675,9 @@ bool main_menu::opening_screen() } if( action == "UP" || action == "CONFIRM" ) { if( sel2 >= 0 && sel2 < static_cast( special_game_type::NUM_SPECIAL_GAME_TYPES ) - 1 ) { - on_out_of_scope cleanup( []() { + on_out_of_scope cleanup( [&player_character]() { g->gamemode.reset(); - g->u = avatar(); + player_character = avatar(); world_generator->set_active_world( nullptr ); } ); g->gamemode = get_special_game( static_cast( sel2 + 1 ) ); @@ -812,6 +813,7 @@ bool main_menu::new_character_tab() ui.position_from_window( w_open ); } ); ui.position_from_window( w_open ); + avatar &player_character = get_avatar(); bool start = false; while( !start && sel1 == 1 && ( layer == 2 || layer == 3 ) ) { @@ -853,8 +855,8 @@ bool main_menu::new_character_tab() } if( action == "UP" || action == "CONFIRM" ) { if( sel2 == 0 || sel2 == 2 || sel2 == 3 || sel2 == 4 ) { - on_out_of_scope cleanup( []() { - g->u = avatar(); + on_out_of_scope cleanup( [&player_character]() { + player_character = avatar(); world_generator->set_active_world( nullptr ); } ); g->gamemode = nullptr; @@ -887,7 +889,7 @@ bool main_menu::new_character_tab() play_type = character_type::FULL_RANDOM; break; } - if( !g->u.create( play_type ) ) { + if( !player_character.create( play_type ) ) { load_char_templates(); MAPBUFFER.reset(); overmap_buffer.clear(); @@ -943,8 +945,8 @@ bool main_menu::new_character_tab() } } } else if( action == "RIGHT" || action == "NEXT_TAB" || action == "CONFIRM" ) { - on_out_of_scope cleanup( []() { - g->u = avatar(); + on_out_of_scope cleanup( [&player_character]() { + player_character = avatar(); world_generator->set_active_world( nullptr ); } ); g->gamemode = nullptr; @@ -959,7 +961,7 @@ bool main_menu::new_character_tab() debugmsg( "Error: %s", err.what() ); continue; } - if( !g->u.create( character_type::TEMPLATE, templates[sel3] ) ) { + if( !player_character.create( character_type::TEMPLATE, templates[sel3] ) ) { load_char_templates(); MAPBUFFER.reset(); overmap_buffer.clear(); @@ -975,10 +977,10 @@ bool main_menu::new_character_tab() } // end while if( start ) { - add_msg( g->scen->description( g->u.male ) ); + add_msg( g->scen->description( player_character.male ) ); world_generator->last_world_name = world_generator->active_world->world_name; - world_generator->last_character_name = g->u.name; + world_generator->last_character_name = player_character.name; world_generator->save_last_world_info(); } return start; @@ -1072,6 +1074,7 @@ bool main_menu::load_character_tab( bool transfer ) ui.position_from_window( w_open ); } ); ui.position_from_window( w_open ); + avatar &player_character = get_avatar(); while( !start && sel1 == 2 && ( layer == 2 || layer == 3 ) ) { ui_manager::redraw(); @@ -1138,8 +1141,8 @@ bool main_menu::load_character_tab( bool transfer ) } if( action == "RIGHT" || action == "NEXT_TAB" || action == "CONFIRM" ) { if( sel3 >= 0 && sel3 < static_cast( savegames.size() ) ) { - on_out_of_scope cleanup( []() { - g->u = avatar(); + on_out_of_scope cleanup( [&player_character]() { + player_character = avatar(); world_generator->set_active_world( nullptr ); } ); @@ -1237,6 +1240,7 @@ void main_menu::world_tab() } ); ui.position_from_window( w_open ); + avatar &player_character = get_avatar(); while( sel1 == 3 && ( layer == 2 || layer == 3 || layer == 4 ) ) { ui_manager::redraw(); if( layer == 4 ) { //Character to Template @@ -1247,11 +1251,11 @@ void main_menu::world_tab() points.skill_points = 0; points.limit = points_left::TRANSFER; - g->u.setID( character_id(), true ); - g->u.reset_all_misions(); - g->u.save_template( g->u.name, points ); + player_character.setID( character_id(), true ); + player_character.reset_all_misions(); + player_character.save_template( player_character.name, points ); - g->u = avatar(); + player_character = avatar(); MAPBUFFER.reset(); overmap_buffer.clear(); diff --git a/src/map_field.cpp b/src/map_field.cpp index ca8733c4f4b00..cb3860690ad10 100644 --- a/src/map_field.cpp +++ b/src/map_field.cpp @@ -398,6 +398,7 @@ bool map::process_fields_in_submap( submap *const current_submap, // Just to avoid typing that long string for a temp value. field_entry *tmpfld = nullptr; + Character &player_character = get_player_character(); map &here = get_map(); tripoint thep; thep.z = submap.z; @@ -663,25 +664,25 @@ bool map::process_fields_in_submap( submap *const current_submap, if( !valid.empty() ) { tripoint newp = random_entry( valid ); add_item_or_charges( newp, tmp ); - if( g->u.pos() == newp ) { + if( player_character.pos() == newp ) { add_msg( m_bad, _( "A %s hits you!" ), tmp.tname() ); - const bodypart_id hit = g->u.get_random_body_part(); - g->u.deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) ); - g->u.check_dead_state(); + const bodypart_id hit = player_character.get_random_body_part(); + player_character.deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) ); + player_character.check_dead_state(); } if( npc *const p = g->critter_at( newp ) ) { // TODO: combine with player character code above - const bodypart_id hit = g->u.get_random_body_part(); + const bodypart_id hit = player_character.get_random_body_part(); p->deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) ); - if( g->u.sees( newp ) ) { + if( player_character.sees( newp ) ) { add_msg( _( "A %1$s hits %2$s!" ), tmp.tname(), p->name ); } p->check_dead_state(); } else if( monster *const mon = g->critter_at( newp ) ) { mon->apply_damage( nullptr, bodypart_id( "torso" ), 6 - mon->get_armor_bash( bodypart_id( "torso" ) ) ); - if( g->u.sees( newp ) ) { + if( player_character.sees( newp ) ) { add_msg( _( "A %1$s hits the %2$s!" ), tmp.tname(), mon->name() ); } mon->check_dead_state(); @@ -781,12 +782,12 @@ bool map::process_fields_in_submap( submap *const current_submap, cur.set_field_intensity( 0 ); } else { // Bees chase the player if in range, wander randomly otherwise. - if( !g->u.is_underwater() && - rl_dist( p, g->u.pos() ) < 10 && - clear_path( p, g->u.pos(), 10, 1, 100 ) ) { + if( !player_character.is_underwater() && + rl_dist( p, player_character.pos() ) < 10 && + clear_path( p, player_character.pos(), 10, 1, 100 ) ) { std::vector candidate_positions = - squares_in_direction( p.xy(), point( g->u.posx(), g->u.posy() ) ); + squares_in_direction( p.xy(), player_character.pos().xy() ); for( const point &candidate_position : candidate_positions ) { field &target_field = get_field( tripoint( candidate_position, p.z ) ); // Only shift if there are no bees already there. diff --git a/src/mission_start.cpp b/src/mission_start.cpp index 8ec3f52507ec5..ea1e282519b30 100644 --- a/src/mission_start.cpp +++ b/src/mission_start.cpp @@ -4,7 +4,7 @@ #include #include -#include "avatar.h" +#include "character.h" #include "computer.h" #include "debug.h" #include "game.h" @@ -57,7 +57,7 @@ void mission_start::place_dog( mission *miss ) debugmsg( "Couldn't find NPC! %d", miss->npc_id.get_value() ); return; } - g->u.i_add( item( "dog_whistle", 0 ) ); + get_player_character().i_add( item( "dog_whistle", 0 ) ); add_msg( _( "%s gave you a dog whistle." ), dev->name ); miss->target = house; @@ -192,7 +192,7 @@ void mission_start::place_npc_software( mission *miss ) debugmsg( "Couldn't find NPC! %d", miss->npc_id.get_value() ); return; } - g->u.i_add( item( "usb_drive", 0 ) ); + get_player_character().i_add( item( "usb_drive", 0 ) ); add_msg( _( "%s gave you a USB drive." ), dev->name ); std::string type = "house"; @@ -300,7 +300,7 @@ void mission_start::place_deposit_box( mission *miss ) void mission_start::find_safety( mission *miss ) { - const tripoint place = g->u.global_omt_location(); + const tripoint place = get_player_character().global_omt_location(); for( int radius = 0; radius <= 20; radius++ ) { for( int dist = 0 - radius; dist <= radius; dist++ ) { int offset = rng( 0, 3 ); // Randomizes the direction we check first @@ -611,8 +611,9 @@ void mission_start::reveal_refugee_center( mission *miss ) return; } - const tripoint source_road = overmap_buffer.find_closest( g->u.global_omt_location(), "road", - 3, false ); + const tripoint source_road = overmap_buffer.find_closest( + get_player_character().global_omt_location(), "road", + 3, false ); const tripoint dest_road = overmap_buffer.find_closest( *target_pos, "road", 3, false ); if( overmap_buffer.reveal_route( source_road, dest_road, 1, true ) ) { @@ -649,8 +650,9 @@ void static create_lab_consoles( mission *miss, const tripoint &place, const std void mission_start::create_lab_console( mission *miss ) { + Character &player_character = get_player_character(); // Pick a lab that has spaces on z = -1: e.g., in hidden labs. - tripoint loc = g->u.global_omt_location(); + tripoint loc = player_character.global_omt_location(); loc.z = -1; const tripoint place = overmap_buffer.find_closest( loc, "lab", 0, false ); @@ -659,13 +661,14 @@ void mission_start::create_lab_console( mission *miss ) // Target the lab entrance. const tripoint target = mission_util::target_closest_lab_entrance( place, 2, miss ); - mission_util::reveal_road( g->u.global_omt_location(), target, overmap_buffer ); + mission_util::reveal_road( player_character.global_omt_location(), target, overmap_buffer ); } void mission_start::create_hidden_lab_console( mission *miss ) { + Character &player_character = get_player_character(); // Pick a hidden lab entrance. - tripoint loc = g->u.global_omt_location(); + tripoint loc = player_character.global_omt_location(); loc.z = -1; tripoint place = mission_util::target_om_ter_random( "basement_hidden_lab_stairs", -1, miss, false, 0, loc ); @@ -676,13 +679,14 @@ void mission_start::create_hidden_lab_console( mission *miss ) // Target the lab entrance. const tripoint target = mission_util::target_closest_lab_entrance( place, 2, miss ); - mission_util::reveal_road( g->u.global_omt_location(), target, overmap_buffer ); + mission_util::reveal_road( player_character.global_omt_location(), target, overmap_buffer ); } void mission_start::create_ice_lab_console( mission *miss ) { + Character &player_character = get_player_character(); // Pick an ice lab with spaces on z = -4. - tripoint loc = g->u.global_omt_location(); + tripoint loc = player_character.global_omt_location(); loc.z = -4; const tripoint place = overmap_buffer.find_closest( loc, "ice_lab", 0, false ); @@ -691,13 +695,14 @@ void mission_start::create_ice_lab_console( mission *miss ) // Target the lab entrance. const tripoint target = mission_util::target_closest_lab_entrance( place, 2, miss ); - mission_util::reveal_road( g->u.global_omt_location(), target, overmap_buffer ); + mission_util::reveal_road( player_character.global_omt_location(), target, overmap_buffer ); } void mission_start::reveal_lab_train_depot( mission *miss ) { + Character &player_character = get_player_character(); // Find and prepare lab location. - tripoint loc = g->u.global_omt_location(); + tripoint loc = player_character.global_omt_location(); loc.z = -4; // tunnels are at z = -4 const tripoint place = overmap_buffer.find_closest( loc, "lab_train_depot", 0, false ); @@ -725,5 +730,5 @@ void mission_start::reveal_lab_train_depot( mission *miss ) // Target the lab entrance. const tripoint target = mission_util::target_closest_lab_entrance( place, 2, miss ); - mission_util::reveal_road( g->u.global_omt_location(), target, overmap_buffer ); + mission_util::reveal_road( player_character.global_omt_location(), target, overmap_buffer ); } diff --git a/tests/item_tname_test.cpp b/tests/item_tname_test.cpp index f3d13560e9c28..040b8f3e3778b 100644 --- a/tests/item_tname_test.cpp +++ b/tests/item_tname_test.cpp @@ -2,10 +2,9 @@ #include #include -#include "avatar.h" #include "calendar.h" #include "catch/catch.hpp" -#include "game.h" +#include "character.h" #include "item.h" #include "itype.h" #include "options_helpers.h" @@ -47,7 +46,8 @@ static const skill_id skill_survival( "survival" ); TEST_CASE( "food with hidden effects", "[item][tname][hidden]" ) { - g->u.clear_mutations(); + Character &player_character = get_player_character(); + player_character.clear_mutations(); GIVEN( "food with hidden poison" ) { item coffee = item( "coffee_pod" ); @@ -55,8 +55,8 @@ TEST_CASE( "food with hidden effects", "[item][tname][hidden]" ) REQUIRE( coffee.has_flag( flag_HIDDEN_POISON ) ); WHEN( "avatar has level 2 survival skill" ) { - g->u.set_skill_level( skill_survival, 2 ); - REQUIRE( g->u.get_skill_level( skill_survival ) == 2 ); + player_character.set_skill_level( skill_survival, 2 ); + REQUIRE( player_character.get_skill_level( skill_survival ) == 2 ); THEN( "they cannot see it is poisonous" ) { CHECK( coffee.tname() == "Kentucky coffee pod" ); @@ -64,8 +64,8 @@ TEST_CASE( "food with hidden effects", "[item][tname][hidden]" ) } WHEN( "avatar has level 3 survival skill" ) { - g->u.set_skill_level( skill_survival, 3 ); - REQUIRE( g->u.get_skill_level( skill_survival ) == 3 ); + player_character.set_skill_level( skill_survival, 3 ); + REQUIRE( player_character.get_skill_level( skill_survival ) == 3 ); THEN( "they see it is poisonous" ) { CHECK( coffee.tname() == "Kentucky coffee pod (poisonous)" ); @@ -80,8 +80,8 @@ TEST_CASE( "food with hidden effects", "[item][tname][hidden]" ) REQUIRE( mushroom.has_flag( flag_HIDDEN_HALLU ) ); WHEN( "avatar has level 4 survival skill" ) { - g->u.set_skill_level( skill_survival, 4 ); - REQUIRE( g->u.get_skill_level( skill_survival ) == 4 ); + player_character.set_skill_level( skill_survival, 4 ); + REQUIRE( player_character.get_skill_level( skill_survival ) == 4 ); THEN( "they cannot see it is hallucinogenic" ) { CHECK( mushroom.tname() == "mushroom (fresh)" ); @@ -89,8 +89,8 @@ TEST_CASE( "food with hidden effects", "[item][tname][hidden]" ) } WHEN( "avatar has level 5 survival skill" ) { - g->u.set_skill_level( skill_survival, 5 ); - REQUIRE( g->u.get_skill_level( skill_survival ) == 5 ); + player_character.set_skill_level( skill_survival, 5 ); + REQUIRE( player_character.get_skill_level( skill_survival ) == 5 ); THEN( "they see it is hallucinogenic" ) { CHECK( mushroom.tname() == "mushroom (hallucinogenic) (fresh)" ); @@ -384,9 +384,10 @@ TEST_CASE( "weapon fouling", "[item][tname][fouling][dirt]" ) GIVEN( "a gun with potential fouling" ) { item gun( "hk_mp5" ); + Character &player_character = get_player_character(); // Ensure the player and gun are normal size to prevent "too big" or "too small" suffix in tname - g->u.clear_mutations(); - REQUIRE( gun.get_sizing( g-> u ) == item::sizing::ignore ); + player_character.clear_mutations(); + REQUIRE( gun.get_sizing( player_character ) == item::sizing::ignore ); REQUIRE_FALSE( gun.has_flag( "OVERSIZE" ) ); REQUIRE_FALSE( gun.has_flag( "UNDERSIZE" ) ); diff --git a/tests/stats_tracker_test.cpp b/tests/stats_tracker_test.cpp index 8cc023d09c95c..762dd73966053 100644 --- a/tests/stats_tracker_test.cpp +++ b/tests/stats_tracker_test.cpp @@ -2,10 +2,10 @@ #include #include "achievement.h" -#include "avatar.h" #include "calendar.h" #include "cata_variant.h" #include "catch/catch.hpp" +#include "character.h" #include "character_id.h" #include "event.h" #include "event_bus.h" @@ -28,7 +28,7 @@ TEST_CASE( "stats_tracker_count_events", "[stats]" ) event_bus b; b.subscribe( &s ); - const character_id u_id = g->u.getID(); + const character_id u_id = get_player_character().getID(); const mtype_id mon1( "mon_zombie" ); const mtype_id mon2( "mon_zombie_brute" ); const cata::event kill1 = cata::event::make( u_id, mon1 ); @@ -54,7 +54,7 @@ TEST_CASE( "stats_tracker_total_events", "[stats]" ) event_bus b; b.subscribe( &s ); - const character_id u_id = g->u.getID(); + const character_id u_id = get_player_character().getID(); character_id other_id = u_id; ++other_id; const cata::event::data_type damage_to_any{}; @@ -139,7 +139,7 @@ TEST_CASE( "stats_tracker_event_time_bounds", "[stats]" ) event_bus b; b.subscribe( &s ); - const character_id u_id = g->u.getID(); + const character_id u_id = get_player_character().getID(); constexpr event_type ctd = event_type::character_takes_damage; const time_point start = calendar::turn; @@ -265,8 +265,8 @@ TEST_CASE( "stats_tracker_with_event_statistics", "[stats]" ) CHECK( score_swam_underwater->value( s ).get() == 1 ); } + const character_id u_id = get_player_character().getID(); SECTION( "kills" ) { - const character_id u_id = g->u.getID(); character_id other_id = u_id; ++other_id; const mtype_id mon_zombie( "mon_zombie" ); @@ -301,7 +301,6 @@ TEST_CASE( "stats_tracker_with_event_statistics", "[stats]" ) } SECTION( "damage" ) { - const character_id u_id = g->u.getID(); const cata::event avatar_2_damage = cata::event::make( u_id, 2 ); const string_id damage_taken( "score_damage_taken" ); @@ -313,7 +312,6 @@ TEST_CASE( "stats_tracker_with_event_statistics", "[stats]" ) } SECTION( "first_last_events" ) { - const character_id u_id = g->u.getID(); const oter_id field( "field" ); const itype_id crowbar( "crowbar" ); const itype_id pipe( "pipe" ); @@ -468,8 +466,8 @@ TEST_CASE( "stats_tracker_watchers", "[stats]" ) CHECK( swam_underwater_watcher.value == cata_variant( 1 ) ); } + const character_id u_id = get_player_character().getID(); SECTION( "kills" ) { - const character_id u_id = g->u.getID(); character_id other_id = u_id; ++other_id; const mtype_id mon_zombie( "mon_zombie" ); @@ -502,7 +500,6 @@ TEST_CASE( "stats_tracker_watchers", "[stats]" ) } SECTION( "damage" ) { - const character_id u_id = g->u.getID(); const cata::event avatar_2_damage = cata::event::make( u_id, 2 ); const string_id damage_taken( "avatar_damage_taken" ); @@ -534,7 +531,7 @@ TEST_CASE( "achievments_tracker", "[stats]" ) } ); b.subscribe( &a ); - const character_id u_id = g->u.getID(); + const character_id u_id = get_player_character().getID(); SECTION( "time" ) { calendar::turn = calendar::start_of_game; @@ -875,7 +872,7 @@ TEST_CASE( "achievements_tracker_in_game", "[stats]" ) test_subscriber sub; g->events().subscribe( &sub ); - const character_id u_id = g->u.getID(); + const character_id u_id = get_player_character().getID(); send_game_start( g->events(), u_id ); const mtype_id mon_zombie( "mon_zombie" ); From 1ea5556a4102dc8d58fbd0980922b56fd176351d Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Fri, 17 Jul 2020 02:59:41 -0700 Subject: [PATCH 095/151] Global reference migration part 32 (#42215) --- src/activity_actor.cpp | 4 ++-- src/activity_handlers.cpp | 8 ++++---- src/avatar.cpp | 10 +++++----- src/bionics.cpp | 10 +++++----- src/character.cpp | 32 ++++++++++++++++---------------- src/computer_session.cpp | 14 +++++++------- src/construction.cpp | 4 ++-- src/creature.cpp | 4 ++-- src/debug_menu.cpp | 4 ++-- src/game.cpp | 12 ++++++------ src/game.h | 3 ++- src/iexamine.cpp | 2 +- src/iuse.cpp | 18 +++++++++--------- src/magic.cpp | 4 ++-- src/map.cpp | 2 +- src/monattack.cpp | 2 +- src/monster.cpp | 2 +- src/mutation.cpp | 12 ++++++------ src/npc.cpp | 10 +++++----- src/npctalk_funcs.cpp | 2 +- src/player.cpp | 4 ++-- src/player_hardcoded_effects.cpp | 16 ++++++++-------- src/ranged.cpp | 4 ++-- src/suffer.cpp | 8 ++++---- src/teleport.cpp | 4 ++-- src/timed_event.cpp | 8 ++++---- src/vehicle.cpp | 2 +- tests/memorial_test.cpp | 2 +- tests/stats_tracker_test.cpp | 8 ++++---- 29 files changed, 108 insertions(+), 107 deletions(-) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index 5f98da78dbefa..fd18516ad571e 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -384,7 +384,7 @@ void dig_activity_actor::finish( player_activity &act, Character &who ) it->set_damage( rng( 1, it->max_damage() - 1 ) ); } } - g->events().send( who.getID() ); + get_event_bus().send( who.getID() ); } here.ter_set( location, ter_id( result_terrain ) ); @@ -620,7 +620,7 @@ void hacking_activity_actor::finish( player_activity &act, Character &who ) case hack_result::FAIL: // currently all things that can be hacked have equivalent alarm failure states. // this may not always be the case with new hackable things. - g->events().send( who.getID() ); + get_event_bus().send( who.getID() ); sounds::sound( who.pos(), 60, sounds::sound_t::music, _( "an alarm sound!" ), true, "environment", "alarm" ); if( examp.z > 0 && !g->timed_events.queued( timed_event_type::WANTED ) ) { diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 297b26c8b4eb3..de0c442561e1d 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -2192,7 +2192,7 @@ void activity_handlers::train_finish( player_activity *act, player *p ) if( old_skill_level != new_skill_level ) { add_msg( m_good, _( "You finish training %s to level %d." ), skill_name, new_skill_level ); - g->events().send( p->getID(), sk, new_skill_level ); + get_event_bus().send( p->getID(), sk, new_skill_level ); } else { add_msg( m_good, _( "You get some training in %s." ), skill_name ); } @@ -2204,7 +2204,7 @@ void activity_handlers::train_finish( player_activity *act, player *p ) if( ma_id.is_valid() ) { const martialart &mastyle = ma_id.obj(); // Trained martial arts, - g->events().send( p->getID(), ma_id ); + get_event_bus().send( p->getID(), ma_id ); p->martial_arts_data.learn_style( mastyle.id, p->is_avatar() ); } else if( !magic_train( act, p ) ) { debugmsg( "train_finish without a valid skill or style or spell name" ); @@ -3948,7 +3948,7 @@ void activity_handlers::chop_tree_finish( player_activity *act, player *p ) // sound of falling tree sfx::play_variant_sound( "misc", "timber", sfx::get_heard_volume( here.getlocal( act->placement ) ) ); - g->events().send( p->getID() ); + get_event_bus().send( p->getID() ); act->set_to_null(); resume_for_multi_activities( *p ); } @@ -4511,7 +4511,7 @@ void activity_handlers::spellcasting_finish( player_activity *act, player *p ) spell_being_cast.xp() ); } if( spell_being_cast.get_level() != old_level ) { - g->events().send( p->getID(), + get_event_bus().send( p->getID(), spell_being_cast.id(), spell_being_cast.get_level() ); } } diff --git a/src/avatar.cpp b/src/avatar.cpp index 1e831811b90cc..8675026dfabc3 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -432,7 +432,7 @@ bool avatar::read( item &it, const bool continuous ) add_msg( m_info, _( "%s reads aloudā€¦" ), reader->disp_name() ); } assign_activity( act ); - g->events().send( getID(), it.typeId() ); + get_event_bus().send( getID(), it.typeId() ); return true; } @@ -444,7 +444,7 @@ bool avatar::read( item &it, const bool continuous ) } else { add_msg( m_info, get_hint() ); } - g->events().send( getID(), it.typeId() ); + get_event_bus().send( getID(), it.typeId() ); mod_moves( -100 ); return false; } @@ -677,7 +677,7 @@ bool avatar::read( item &it, const bool continuous ) elem->add_morale( MORALE_BOOK, 0, book_fun_for( it, *elem ) * 15, decay_start + 30_minutes, decay_start, false, it.type ); } - g->events().send( getID(), it.typeId() ); + get_event_bus().send( getID(), it.typeId() ); return true; } @@ -831,7 +831,7 @@ void avatar::do_read( item &book ) std::string skill_name = skill.obj().name(); if( skill_level != originalSkillLevel ) { - g->events().send( + get_event_bus().send( learner->getID(), skill, skill_level.level() ); if( learner->is_player() ) { add_msg( m_good, _( "You increase %s to level %d." ), skill.obj().name(), @@ -1575,7 +1575,7 @@ bool avatar::wield( item &target, const int obtain_cost ) weapon.on_wield( *this, mv ); - g->events().send( getID(), last_item ); + get_event_bus().send( getID(), last_item ); inv.update_invlet( weapon ); inv.update_cache_with_item( weapon ); diff --git a/src/bionics.cpp b/src/bionics.cpp index 57ad84e96230c..e7b1df2f87f95 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -2264,7 +2264,7 @@ void Character::perform_uninstall( const bionic_id &bid, int difficulty, int suc { map &here = get_map(); if( success > 0 ) { - g->events().send( getID(), bid ); + get_event_bus().send( getID(), bid ); // until bionics can be flagged as non-removable add_msg_player_or_npc( m_neutral, _( "Your parts are jiggled back into their familiar places." ), @@ -2285,7 +2285,7 @@ void Character::perform_uninstall( const bionic_id &bid, int difficulty, int suc cbm.faults.emplace( fault_bionic_salvaged ); here.add_item( pos(), cbm ); } else { - g->events().send( getID(), bid ); + get_event_bus().send( getID(), bid ); // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30 float adjusted_skill = static_cast( pl_skill ) - std::min( static_cast( 40 ), static_cast( pl_skill ) - static_cast( pl_skill ) / static_cast @@ -2510,7 +2510,7 @@ void Character::perform_install( const bionic_id &bid, const bionic_id &upbid, i const std::vector &trait_to_rem, const tripoint &patient_pos ) { if( success > 0 ) { - g->events().send( getID(), bid ); + get_event_bus().send( getID(), bid ); if( upbid != bionic_id( "" ) ) { remove_bionic( upbid ); //~ %1$s - name of the bionic to be upgraded (inferior), %2$s - name of the upgraded bionic (superior). @@ -2532,7 +2532,7 @@ void Character::perform_install( const bionic_id &bid, const bionic_id &upbid, i } } else { - g->events().send( getID(), bid ); + get_event_bus().send( getID(), bid ); // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30 float adjusted_skill = static_cast( pl_skill ) - std::min( static_cast( 40 ), @@ -2611,7 +2611,7 @@ void Character::bionics_install_failure( const bionic_id &bid, const std::string } else { const bionic_id &id = random_entry( valid ); add_bionic( id ); - g->events().send( getID(), id ); + get_event_bus().send( getID(), id ); } break; diff --git a/src/character.cpp b/src/character.cpp index 3ffe9be842b24..8fe28d01049b3 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -2119,7 +2119,7 @@ void Character::practice( const skill_id &id, int amount, int cap, bool suppress int newLevel = get_skill_level( id ); std::string skill_name = skill.name(); if( newLevel > oldLevel ) { - g->events().send( getID(), id, newLevel ); + get_event_bus().send( getID(), id, newLevel ); } if( is_player() && newLevel > oldLevel ) { add_msg( m_good, _( "Your skill in %s has increased to %d!" ), skill_name, newLevel ); @@ -2368,7 +2368,7 @@ cata::optional::iterator> Character::wear_item( const item &to_w std::list::iterator position = position_to_wear_new_item( to_wear ); std::list::iterator new_item_it = worn.insert( position, to_wear ); - g->events().send( getID(), last_item ); + get_event_bus().send( getID(), last_item ); if( interactive ) { add_msg_player_or_npc( @@ -2784,7 +2784,7 @@ item Character::remove_weapon() { item tmp = weapon; weapon = item(); - g->events().send( getID(), weapon.typeId() ); + get_event_bus().send( getID(), weapon.typeId() ); cached_info.erase( "weapon_value" ); return tmp; } @@ -5321,13 +5321,13 @@ void Character::check_needs_extremes() add_msg_player_or_npc( m_bad, _( "You have a sudden heart attack!" ), _( " has a sudden heart attack!" ) ); - g->events().send( getID(), efftype_id() ); + get_event_bus().send( getID(), efftype_id() ); set_part_hp_cur( bodypart_id( "torso" ), 0 ); } else if( get_stim() < -200 || get_painkiller() > 240 ) { add_msg_player_or_npc( m_bad, _( "Your breathing stops completely." ), _( "'s breathing stops completely." ) ); - g->events().send( getID(), efftype_id() ); + get_event_bus().send( getID(), efftype_id() ); set_part_hp_cur( bodypart_id( "torso" ), 0 ); } else if( has_effect( effect_jetinjector ) && get_effect_dur( effect_jetinjector ) > 40_minutes ) { if( !( has_trait( trait_NOPAIN ) ) ) { @@ -5338,19 +5338,19 @@ void Character::check_needs_extremes() add_msg_player_or_npc( _( "Your heart spasms and stops." ), _( "'s heart spasms and stops." ) ); } - g->events().send( getID(), effect_jetinjector ); + get_event_bus().send( getID(), effect_jetinjector ); set_part_hp_cur( bodypart_id( "torso" ), 0 ); } else if( get_effect_dur( effect_adrenaline ) > 50_minutes ) { add_msg_player_or_npc( m_bad, _( "Your heart spasms and stops." ), _( "'s heart spasms and stops." ) ); - g->events().send( getID(), effect_adrenaline ); + get_event_bus().send( getID(), effect_adrenaline ); set_part_hp_cur( bodypart_id( "torso" ), 0 ); } else if( get_effect_int( effect_drunk ) > 4 ) { add_msg_player_or_npc( m_bad, _( "Your breathing slows down to a stop." ), _( "'s breathing slows down to a stop." ) ); - g->events().send( getID(), effect_drunk ); + get_event_bus().send( getID(), effect_drunk ); set_part_hp_cur( bodypart_id( "torso" ), 0 ); } @@ -5358,7 +5358,7 @@ void Character::check_needs_extremes() if( is_player() ) { if( get_stored_kcal() <= 0 ) { add_msg_if_player( m_bad, _( "You have starved to death." ) ); - g->events().send( getID() ); + get_event_bus().send( getID() ); set_part_hp_cur( bodypart_id( "torso" ), 0 ); } else { if( calendar::once_every( 12_hours ) ) { @@ -5398,7 +5398,7 @@ void Character::check_needs_extremes() guts.get_water() == 0_ml ) ) { if( get_thirst() >= 1200 ) { add_msg_if_player( m_bad, _( "You have died of dehydration." ) ); - g->events().send( getID() ); + get_event_bus().send( getID() ); set_part_hp_cur( bodypart_id( "torso" ), 0 ); } else if( get_thirst() >= 1000 && calendar::once_every( 30_minutes ) ) { add_msg_if_player( m_warning, _( "Even your eyes feel dryā€¦" ) ); @@ -5413,7 +5413,7 @@ void Character::check_needs_extremes() if( get_fatigue() >= fatigue_levels::EXHAUSTED + 25 && !in_sleep_state() ) { if( get_fatigue() >= fatigue_levels::MASSIVE_FATIGUE ) { add_msg_if_player( m_bad, _( "Survivor sleep now." ) ); - g->events().send( getID() ); + get_event_bus().send( getID() ); mod_fatigue( -10 ); fall_asleep(); } else if( get_fatigue() >= 800 && calendar::once_every( 30_minutes ) ) { @@ -8186,7 +8186,7 @@ void Character::wake_up() // effects) with a duration of 0 turns. if( has_effect( effect_sleep ) ) { - g->events().send( getID() ); + get_event_bus().send( getID() ); get_effect( effect_sleep ).set_duration( 0_turns ); } remove_effect( effect_slept_through_alarm ); @@ -8309,7 +8309,7 @@ void Character::shout( std::string msg, bool order ) void Character::vomit() { - g->events().send( getID() ); + get_event_bus().send( getID() ); if( stomach.contains() != 0_ml ) { stomach.empty(); @@ -8984,7 +8984,7 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam, const const int dam_to_bodypart = std::min( dam, get_part_hp_cur( hurt ) ); mod_part_hp_cur( hurt, - dam_to_bodypart ); - g->events().send( getID(), dam_to_bodypart ); + get_event_bus().send( getID(), dam_to_bodypart ); if( !weapon.is_null() && !as_player()->can_wield( weapon ).success() && can_unwield( weapon ).success() ) { @@ -9201,7 +9201,7 @@ void Character::heal( const bodypart_id &healed, int dam ) if( !is_limb_broken( healed ) ) { int effective_heal = std::min( dam, get_part_hp_max( healed ) - get_part_hp_cur( healed ) ); mod_part_hp_cur( healed, effective_heal ); - g->events().send( getID(), effective_heal ); + get_event_bus().send( getID(), effective_heal ); } } @@ -9223,7 +9223,7 @@ void Character::hurtall( int dam, Creature *source, bool disturb /*= true*/ ) // Don't use apply_damage here or it will annoy the player with 6 queries const int dam_to_bodypart = std::min( dam, get_part_hp_cur( bp ) ); mod_part_hp_cur( bp, - dam_to_bodypart ); - g->events().send( getID(), dam_to_bodypart ); + get_event_bus().send( getID(), dam_to_bodypart ); } // Low pain: damage is spread all over the body, so not as painful as 6 hits in one part diff --git a/src/computer_session.cpp b/src/computer_session.cpp index 1b47e817320ab..0c4a284c38c03 100644 --- a/src/computer_session.cpp +++ b/src/computer_session.cpp @@ -450,7 +450,7 @@ void computer_session::action_sample() void computer_session::action_release() { - g->events().send(); + get_event_bus().send(); Character &player_character = get_player_character(); sounds::sound( player_character.pos(), 40, sounds::sound_t::alarm, _( "an alarm sound!" ), false, "environment", @@ -478,7 +478,7 @@ void computer_session::action_release_bionics() void computer_session::action_terminate() { - g->events().send(); + get_event_bus().send(); Character &player_character = get_player_character(); map &here = get_map(); for( const tripoint &p : here.points_on_zlevel() ) { @@ -498,7 +498,7 @@ void computer_session::action_terminate() void computer_session::action_portal() { - g->events().send(); + get_event_bus().send(); map &here = get_map(); for( const tripoint &tmp : here.points_on_zlevel() ) { int numtowers = 0; @@ -522,7 +522,7 @@ void computer_session::action_cascade() if( !query_bool( _( "WARNING: Resonance cascade carries severe risk! Continue?" ) ) ) { return; } - g->events().send(); + get_event_bus().send(); tripoint player_pos = get_player_character().pos(); map &here = get_map(); std::vector cascade_points; @@ -630,7 +630,7 @@ void computer_session::action_miss_disarm() { // TODO: stop the nuke from creating radioactive clouds. if( query_yn( _( "Disarm missile." ) ) ) { - g->events().send(); + get_event_bus().send(); add_msg( m_info, _( "Nuclear missile disarmed!" ) ); //disable missile. comp.options.clear(); @@ -993,7 +993,7 @@ void computer_session::action_srcf_seal_order() void computer_session::action_srcf_seal() { - g->events().send(); + get_event_bus().send(); print_line( _( "Charges Detonated" ) ); print_line( _( "Backup Generator Power Failing" ) ); print_line( _( "Evacuate Immediately" ) ); @@ -1345,7 +1345,7 @@ void computer_session::failure_shutdown() void computer_session::failure_alarm() { Character &player_character = get_player_character(); - g->events().send( player_character.getID() ); + get_event_bus().send( player_character.getID() ); sounds::sound( player_character.pos(), 60, sounds::sound_t::alarm, _( "an alarm sound!" ), false, "environment", "alarm" ); diff --git a/src/construction.cpp b/src/construction.cpp index b5690e53fc747..2b394c69dea3b 100644 --- a/src/construction.cpp +++ b/src/construction.cpp @@ -1188,7 +1188,7 @@ void construct::done_grave( const tripoint &p ) it.get_corpse_name() ); } } - g->events().send( + get_event_bus().send( player_character.getID(), it.get_mtype()->id, it.get_corpse_name() ); } } @@ -1356,7 +1356,7 @@ void construct::done_digormine_stair( const tripoint &p, bool dig ) unroll_digging( dig ? 8 : 12 ); } else { add_msg( m_warning, _( "You just tunneled into lava!" ) ); - g->events().send(); + get_event_bus().send(); here.ter_set( p, t_hole ); } diff --git a/src/creature.cpp b/src/creature.cpp index fa9380e8104e5..12354974733d5 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -1065,7 +1065,7 @@ void Creature::add_effect( const efftype_id &eff_id, const time_duration &dur, b } ( *effects )[eff_id][bp] = e; if( Character *ch = as_character() ) { - g->events().send( ch->getID(), eff_id ); + get_event_bus().send( ch->getID(), eff_id ); if( is_player() && !type.get_apply_message().empty() ) { add_msg( type.gain_game_message_type(), _( type.get_apply_message() ) ); } @@ -1118,7 +1118,7 @@ bool Creature::remove_effect( const efftype_id &eff_id, body_part bp ) add_msg( type.lose_game_message_type(), _( type.get_remove_message() ) ); } } - g->events().send( ch->getID(), eff_id ); + get_event_bus().send( ch->getID(), eff_id ); } // num_bp means remove all of a given effect id diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index 0f64933bb606c..8b1bfb975cf0a 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -637,7 +637,7 @@ void character_edit_menu() p.worn.push_back( to_wear ); } else if( !to_wear.is_null() ) { p.weapon = to_wear; - g->events().send( p.getID(), p.weapon.typeId() ); + get_event_bus().send( p.getID(), p.weapon.typeId() ); } } break; @@ -1217,7 +1217,7 @@ void debug() return; } - g->events().send( *action ); + get_event_bus().send( *action ); avatar &player_character = get_avatar(); map &here = get_map(); diff --git a/src/game.cpp b/src/game.cpp index 431f786c6528e..820092761ccae 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -282,7 +282,7 @@ static void achievement_attained( const achievement *a, bool achievements_enable add_msg( m_good, _( "You completed the achievement \"%s\"." ), a->name() ); } - g->events().send( a->id, achievements_enabled ); + get_event_bus().send( a->id, achievements_enabled ); } static void achievement_failed( const achievement *a, bool achievements_enabled ) @@ -293,7 +293,7 @@ static void achievement_failed( const achievement *a, bool achievements_enabled if( achievements_enabled ) { add_msg( m_bad, _( "You lost the conduct \"%s\"." ), a->name() ); } - g->events().send( a->id, achievements_enabled ); + get_event_bus().send( a->id, achievements_enabled ); } // This is the main game set-up process. @@ -813,13 +813,13 @@ bool game::start_game() mission->assign( u ); } - g->events().send( u.getID(), u.name, u.male, u.prof->ident(), + get_event_bus().send( u.getID(), u.name, u.male, u.prof->ident(), u.custom_profession, getVersionString() ); time_played_at_last_load = std::chrono::seconds( 0 ); time_of_last_load = std::chrono::steady_clock::now(); tripoint abs_omt = u.global_omt_location(); const oter_id &cur_ter = overmap_buffer.ter( abs_omt ); - g->events().send( abs_omt, cur_ter ); + get_event_bus().send( abs_omt, cur_ter ); return true; } @@ -12583,14 +12583,14 @@ void avatar_moves( const tripoint &old_abs_pos, const avatar &u, const map &m ) if( u.is_mounted() ) { mount_type = u.mounted_creature->type->id; } - g->events().send( mount_type, m.ter( new_pos ).id(), + get_event_bus().send( mount_type, m.ter( new_pos ).id(), u.current_movement_mode(), u.is_underwater(), new_pos.z ); const tripoint old_abs_omt = ms_to_omt_copy( old_abs_pos ); const tripoint new_abs_omt = ms_to_omt_copy( new_abs_pos ); if( old_abs_omt != new_abs_omt ) { const oter_id &cur_ter = overmap_buffer.ter( new_abs_omt ); - g->events().send( new_abs_omt, cur_ter ); + get_event_bus().send( new_abs_omt, cur_ter ); } } } // namespace cata_event_dispatch diff --git a/src/game.h b/src/game.h index 48c80bd78d490..33ccc7dc6f270 100644 --- a/src/game.h +++ b/src/game.h @@ -149,6 +149,7 @@ class game friend class editmap; friend class advanced_inventory; friend class main_menu; + friend event_bus &get_event_bus(); friend map &get_map(); friend Character &get_player_character(); friend avatar &get_avatar(); @@ -974,12 +975,12 @@ class game pimpl spell_events_ptr; map &m; + event_bus &events(); public: avatar &u; scent_map &scent; timed_event_manager &timed_events; - event_bus &events(); stats_tracker &stats(); achievements_tracker &achievements(); memorial_logger &memorial(); diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 00872eb86f514..47adc4fe784bc 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1529,7 +1529,7 @@ void iexamine::pedestal_wyrm( player &p, const tripoint &examp ) return; } // Send in a few wyrms to start things off. - g->events().send(); + get_event_bus().send(); int num_wyrms = rng( 1, 4 ); for( int i = 0; i < num_wyrms; i++ ) { if( monster *const mon = g->place_critter_around( mon_dark_wyrm, p.pos(), 2 ) ) { diff --git a/src/iuse.cpp b/src/iuse.cpp index 4d73485ba3235..27dade3b52518 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -470,7 +470,7 @@ int iuse::sewage( player *p, item *it, bool, const tripoint & ) return 0; } - g->events().send(); + get_event_bus().send(); p->vomit(); if( one_in( 4 ) ) { p->mutate(); @@ -1430,7 +1430,7 @@ static void marloss_common( player &p, item &it, const trait_id ¤t_color ) p.set_mutation( trait_THRESH_MARLOSS ); get_map().ter_set( p.pos(), t_marloss ); - g->events().send( p.getID() ); + get_event_bus().send( p.getID() ); p.add_msg_if_player( m_good, _( "You wake up in a marloss bush. Almost *cradled* in it, actually, as though it grew there for you." ) ); p.add_msg_if_player( m_good, @@ -1476,7 +1476,7 @@ int iuse::marloss( player *p, item *it, bool, const tripoint & ) return 0; } - g->events().send( p->getID(), it->typeId() ); + get_event_bus().send( p->getID(), it->typeId() ); marloss_common( *p, *it, trait_MARLOSS ); return it->type->charges_to_use(); @@ -1493,7 +1493,7 @@ int iuse::marloss_seed( player *p, item *it, bool, const tripoint & ) return 0; } - g->events().send( p->getID(), it->typeId() ); + get_event_bus().send( p->getID(), it->typeId() ); marloss_common( *p, *it, trait_MARLOSS_BLUE ); return it->type->charges_to_use(); @@ -1505,7 +1505,7 @@ int iuse::marloss_gel( player *p, item *it, bool, const tripoint & ) return 0; } - g->events().send( p->getID(), it->typeId() ); + get_event_bus().send( p->getID(), it->typeId() ); marloss_common( *p, *it, trait_MARLOSS_YELLOW ); return it->type->charges_to_use(); @@ -1518,7 +1518,7 @@ int iuse::mycus( player *p, item *it, bool t, const tripoint &pos ) } // Welcome our guide. Welcome. To. The Mycus. if( p->has_trait( trait_THRESH_MARLOSS ) ) { - g->events().send( p->getID() ); + get_event_bus().send( p->getID() ); p->add_msg_if_player( m_neutral, _( "It tastes amazing, and you finish it quickly." ) ); p->add_msg_if_player( m_good, _( "You feel better all over." ) ); @@ -2607,7 +2607,7 @@ int iuse::crowbar( player *p, item *it, bool, const tripoint &pos ) here.spawn_item( pnt, itype_manhole_cover ); } if( type == t_door_locked_alarm ) { - g->events().send( p->getID() ); + get_event_bus().send( p->getID() ); sounds::sound( p->pos(), 40, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment", "alarm" ); if( !g->timed_events.queued( timed_event_type::WANTED ) ) { @@ -4041,7 +4041,7 @@ int iuse::mininuke( player *p, item *it, bool, const tripoint & ) } p->add_msg_if_player( _( "You set the timer to %s." ), to_string( time_duration::from_turns( time ) ) ); - g->events().send( p->getID() ); + get_event_bus().send( p->getID() ); it->convert( itype_mininuke_act ); it->charges = time; it->active = true; @@ -5381,7 +5381,7 @@ int iuse::artifact( player *p, item *it, bool, const tripoint & ) it->tname() ); return 0; } - g->events().send( p->getID(), it->tname( 1, false ) ); + get_event_bus().send( p->getID(), it->tname( 1, false ) ); const auto &art = it->type->artifact; size_t num_used = rng( 1, art->effects_activated.size() ); diff --git a/src/magic.cpp b/src/magic.cpp index 016e4e64984e9..86196d20acb6d 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -1404,7 +1404,7 @@ void known_magic::learn_spell( const spell_type *sp, Character &guy, bool force } if( force || can_learn_spell( guy, sp->id ) ) { spellbook.emplace( sp->id, temp_spell ); - g->events().send( guy.getID(), sp->id ); + get_event_bus().send( guy.getID(), sp->id ); guy.add_msg_if_player( m_good, _( "You learned %s!" ), sp->name ); } else { guy.add_msg_if_player( m_bad, _( "You can't learn this spell." ) ); @@ -1424,7 +1424,7 @@ void known_magic::forget_spell( const spell_id &sp ) } add_msg( m_bad, _( "All knowledge of %s leaves you." ), sp->name ); // TODO: add parameter for owner of known_magic for this function - g->events().send( get_player_character().getID(), sp->id ); + get_event_bus().send( get_player_character().getID(), sp->id ); spellbook.erase( sp ); } diff --git a/src/map.cpp b/src/map.cpp index 5a4f637d58a06..050c15e492168 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3101,7 +3101,7 @@ void map::bash_ter_furn( const tripoint &p, bash_params ¶ms ) Character &player_character = get_player_character(); // Blame nearby player if( rl_dist( player_character.pos(), p ) <= 3 ) { - g->events().send( player_character.getID() ); + get_event_bus().send( player_character.getID() ); const point abs = ms_to_sm_copy( getabs( p.xy() ) ); g->timed_events.add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, tripoint( abs, p.z ) ); diff --git a/src/monattack.cpp b/src/monattack.cpp index a6a63997b010e..09bded69be960 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -2247,7 +2247,7 @@ bool mattack::dermatik( monster *z ) body_part_name_accusative( targeted ) ); if( !foe->has_trait( trait_PARAIMMUNE ) || !foe->has_trait( trait_ACIDBLOOD ) ) { foe->add_effect( effect_dermatik, 1_turns, targeted->token, true ); - g->events().send( foe->getID() ); + get_event_bus().send( foe->getID() ); } return true; diff --git a/src/monster.cpp b/src/monster.cpp index be92a588ef758..5cb16b4b2b711 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -2198,7 +2198,7 @@ void monster::die( Creature *nkiller ) // has guilt flag or player is pacifist && monster is humanoid mdeath::guilt( *this ); } - g->events().send( ch->getID(), type->id ); + get_event_bus().send( ch->getID(), type->id ); if( ch->is_player() && ch->has_trait( trait_KILLER ) ) { if( one_in( 4 ) ) { const translation snip = SNIPPET.random_from_category( "killer_on_kill" ).value_or( translation() ); diff --git a/src/mutation.cpp b/src/mutation.cpp index 0f5080298b279..9045b2a456ce3 100644 --- a/src/mutation.cpp +++ b/src/mutation.cpp @@ -1166,7 +1166,7 @@ bool Character::mutate_towards( const trait_id &mut ) _( "'s %1$s mutation turns into %2$s!" ), replace_mdata.name(), mdata.name() ); - g->events().send( getID(), replace_mdata.id, mdata.id ); + get_event_bus().send( getID(), replace_mdata.id, mdata.id ); unset_mutation( replacing ); mutation_replaced = true; } @@ -1185,7 +1185,7 @@ bool Character::mutate_towards( const trait_id &mut ) _( "Your %1$s mutation turns into %2$s!" ), _( "'s %1$s mutation turns into %2$s!" ), replace_mdata.name(), mdata.name() ); - g->events().send( getID(), replace_mdata.id, mdata.id ); + get_event_bus().send( getID(), replace_mdata.id, mdata.id ); unset_mutation( replacing2 ); mutation_replaced = true; } @@ -1207,7 +1207,7 @@ bool Character::mutate_towards( const trait_id &mut ) _( "Your innate %1$s trait turns into %2$s!" ), _( "'s innate %1$s trait turns into %2$s!" ), cancel_mdata.name(), mdata.name() ); - g->events().send( getID(), cancel_mdata.id, mdata.id ); + get_event_bus().send( getID(), cancel_mdata.id, mdata.id ); unset_mutation( i ); mutation_replaced = true; } @@ -1226,7 +1226,7 @@ bool Character::mutate_towards( const trait_id &mut ) _( "You gain a mutation called %s!" ), _( " gains a mutation called %s!" ), mdata.name() ); - g->events().send( getID(), mdata.id ); + get_event_bus().send( getID(), mdata.id ); } set_mutation( mut ); @@ -1491,7 +1491,7 @@ static mutagen_rejection try_reject_mutagen( Character &guy, const item &it, boo mutagen_attempt mutagen_common_checks( Character &guy, const item &it, bool strong, const mutagen_technique technique ) { - g->events().send( guy.getID(), technique ); + get_event_bus().send( guy.getID(), technique ); mutagen_rejection status = try_reject_mutagen( guy, it, strong ); if( status == mutagen_rejection::rejected ) { return mutagen_attempt( false, 0 ); @@ -1541,7 +1541,7 @@ void test_crossing_threshold( Character &guy, const mutation_category_trait &m_c guy.add_msg_if_player( m_good, _( "Something strains mightily for a momentā€¦ and thenā€¦ you'reā€¦ FREE!" ) ); guy.set_mutation( mutation_thresh ); - g->events().send( guy.getID(), m_category.id ); + get_event_bus().send( guy.getID(), m_category.id ); // Manually removing Carnivore, since it tends to creep in // This is because carnivore is a prerequisite for the // predator-style post-threshold mutations. diff --git a/src/npc.cpp b/src/npc.cpp index 70eda556505db..790f831febeed 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -841,7 +841,7 @@ void npc::starting_weapon( const npc_class_id &type ) } } - g->events().send( getID(), weapon.typeId() ); + get_event_bus().send( getID(), weapon.typeId() ); weapon.set_owner( get_faction()->id ); } @@ -957,7 +957,7 @@ void npc::finish_read( item &book ) skill_level.readBook( min_ex, max_ex, reading->level ); const std::string skill_name = skill.obj().name(); if( skill_level != originalSkillLevel ) { - g->events().send( getID(), skill, skill_level.level() ); + get_event_bus().send( getID(), skill, skill_level.level() ); if( display_messages ) { add_msg( m_good, _( "%s increases their %s level." ), disp_name(), skill_name ); // NPC reads until they gain a level, then stop. @@ -1157,7 +1157,7 @@ bool npc::wield( item &it ) if( it.is_null() ) { weapon = item(); - g->events().send( getID(), weapon.typeId() ); + get_event_bus().send( getID(), weapon.typeId() ); return true; } @@ -1168,7 +1168,7 @@ bool npc::wield( item &it ) weapon = it; } - g->events().send( getID(), weapon.typeId() ); + get_event_bus().send( getID(), weapon.typeId() ); if( get_player_character().sees( pos() ) ) { add_msg_if_npc( m_info, _( " wields a %s." ), weapon.tname() ); @@ -2521,7 +2521,7 @@ void npc::die( Creature *nkiller ) } if( Character *ch = dynamic_cast( killer ) ) { - g->events().send( ch->getID(), getID(), get_name() ); + get_event_bus().send( ch->getID(), getID(), get_name() ); } if( killer == &player_character && ( !guaranteed_hostile() || hit_by_player ) ) { diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index d47d72cb3a834..ec84410e5fcc8 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -781,7 +781,7 @@ void talk_function::hostile( npc &p ) add_msg( _( "%s turns hostile!" ), p.name ); } - g->events().send( p.getID(), p.name ); + get_event_bus().send( p.getID(), p.name ); p.set_attitude( NPCATT_KILL ); } diff --git a/src/player.cpp b/src/player.cpp index 195aa5efcfba9..4933769586d5c 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -2677,7 +2677,7 @@ player::wear( item &to_wear, bool interactive ) } if( was_weapon ) { - g->events().send( getID(), weapon.typeId() ); + get_event_bus().send( getID(), weapon.typeId() ); } return result; @@ -3574,7 +3574,7 @@ bool player::wield_contents( item &container, item *internal_item, bool penaltie weapon.on_wield( *this, mv ); - g->events().send( getID(), weapon.typeId() ); + get_event_bus().send( getID(), weapon.typeId() ); return true; } diff --git a/src/player_hardcoded_effects.cpp b/src/player_hardcoded_effects.cpp index 842b55eb174cf..9e51d91638418 100644 --- a/src/player_hardcoded_effects.cpp +++ b/src/player_hardcoded_effects.cpp @@ -535,7 +535,7 @@ void player::hardcoded_effects( effect &it ) } } } - g->events().send( getID() ); + get_event_bus().send( getID() ); remove_effect( effect_formication, bp->token ); moves -= 600; triggered = true; @@ -668,7 +668,7 @@ void player::hardcoded_effects( effect &it ) add_msg( _( "Glowing lights surround you, and you teleport." ) ); } teleport::teleport( *this ); - g->events().send( getID() ); + get_event_bus().send( getID() ); if( one_in( 10 ) ) { // Set ourselves up for removal it.set_duration( 0_turns ); @@ -778,7 +778,7 @@ void player::hardcoded_effects( effect &it ) it.set_duration( 0_turns ); } else if( dur > 2_hours ) { add_msg_if_player( m_bad, _( "Your asthma overcomes you.\nYou asphyxiate." ) ); - g->events().send( getID() ); + get_event_bus().send( getID() ); hurtall( 500, nullptr ); } else if( dur > 70_minutes ) { if( one_in( 120 ) ) { @@ -899,7 +899,7 @@ void player::hardcoded_effects( effect &it ) add_msg_if_player( _( "You dissolve into beautiful paroxysms of energy. Life fades from your nebulae and you are no more." ) ); } - g->events().send( getID(), id ); + get_event_bus().send( getID(), id ); set_part_hp_cur( bodypart_id( "torso" ), 0 ); } } else if( id == effect_hypovolemia ) { @@ -915,13 +915,13 @@ void player::hardcoded_effects( effect &it ) add_msg_player_or_npc( m_bad, _( "You bleed to death!" ), _( " bleeds to death!" ) ); - g->events().send( getID() ); + get_event_bus().send( getID() ); } else { add_msg_player_or_npc( m_bad, _( "Your heart can't keep up the pace and fails!" ), _( " has a sudden heart attack!" ) ); - g->events().send( getID() ); + get_event_bus().send( getID() ); } set_part_hp_cur( bodypart_id( "torso" ), 0 ); }; @@ -1021,7 +1021,7 @@ void player::hardcoded_effects( effect &it ) add_msg_player_or_npc( m_bad, _( "You cannot breathe and your body gives out!" ), _( " gasps for air and dies!" ) ); - g->events().send( getID() ); + get_event_bus().send( getID() ); set_part_hp_cur( bodypart_id( "torso" ), 0 ); } if( one_in( 900 / intense ) && !in_sleep_state() ) { @@ -1249,7 +1249,7 @@ void player::hardcoded_effects( effect &it ) // Death happens if( dur > 1_days ) { add_msg_if_player( m_bad, _( "You succumb to the infection." ) ); - g->events().send( getID() ); + get_event_bus().send( getID() ); hurtall( 500, nullptr ); } else if( has_effect( effect_strong_antibiotic ) ) { it.mod_duration( -1_turns ); diff --git a/src/ranged.cpp b/src/ranged.cpp index 9f28a8e586fbe..73cdafb061527 100644 --- a/src/ranged.cpp +++ b/src/ranged.cpp @@ -804,7 +804,7 @@ int player::fire_gun( const tripoint &target, int shots, item &gun ) if( shot.missed_by <= .1 ) { // TODO: check head existence for headshot - g->events().send( getID() ); + get_event_bus().send( getID() ); } if( shot.hit_critter ) { @@ -1087,7 +1087,7 @@ dealt_projectile_attack player::throw_item( const tripoint &target, const item & if( missed_by <= 0.1 && dealt_attack.hit_critter != nullptr ) { practice( skill_used, final_xp_mult, MAX_SKILL ); // TODO: Check target for existence of head - g->events().send( getID() ); + get_event_bus().send( getID() ); } else if( dealt_attack.hit_critter != nullptr && missed_by > 0.0f ) { practice( skill_used, final_xp_mult / ( 1.0f + missed_by ), MAX_SKILL ); } else { diff --git a/src/suffer.cpp b/src/suffer.cpp index e55970da33e56..2525c93577d52 100644 --- a/src/suffer.cpp +++ b/src/suffer.cpp @@ -1448,7 +1448,7 @@ void Character::suffer() for( const std::pair &elem : get_body() ) { if( elem.second.get_hp_cur() <= 0 ) { add_effect( effect_disabled, 1_turns, elem.first->token, true ); - g->events().send( getID(), elem.first->token ); + get_event_bus().send( getID(), elem.first->token ); } } @@ -1667,7 +1667,7 @@ void Character::mend( int rate_multiplier ) if( eff.get_duration() >= eff.get_max_duration() ) { set_part_hp_cur( bp, 1 ); remove_effect( effect_mending, bp->token ); - g->events().send( getID(), bp->token ); + get_event_bus().send( getID(), bp->token ); //~ %s is bodypart add_msg_if_player( m_good, _( "Your %s has started to mend!" ), body_part_name( bp ) ); @@ -1903,7 +1903,7 @@ void Character::add_addiction( add_type type, int strength ) const std::string &type_name = addiction_type_name( type ); add_msg( m_debug, "%s got addicted to %s", disp_name(), type_name ); addictions.emplace_back( type, 1 ); - g->events().send( getID(), type ); + get_event_bus().send( getID(), type ); } } @@ -1924,7 +1924,7 @@ void Character::rem_addiction( add_type type ) if( iter != addictions.end() ) { addictions.erase( iter ); - g->events().send( getID(), type ); + get_event_bus().send( getID(), type ); } } diff --git a/src/teleport.cpp b/src/teleport.cpp index c420880121dd6..2a06bbb26ed38 100644 --- a/src/teleport.cpp +++ b/src/teleport.cpp @@ -58,7 +58,7 @@ bool teleport::teleport( Creature &critter, int min_distance, int max_distance, } critter.apply_damage( nullptr, bodypart_id( "torso" ), 9999 ); if( c_is_u ) { - g->events().send( p->getID(), here.obstacle_name( new_pos ) ); + get_event_bus().send( p->getID(), here.obstacle_name( new_pos ) ); add_msg( m_bad, _( "You die after teleporting into a solid." ) ); } critter.check_dead_state(); @@ -87,7 +87,7 @@ bool teleport::teleport( Creature &critter, int min_distance, int max_distance, _( "You teleport into %s, and they explode into thousands of fragments." ), _( " teleports into %s, and they explode into thousands of fragments." ), poor_soul->disp_name() ); - g->events().send( p->getID(), poor_soul->get_name() ); + get_event_bus().send( p->getID(), poor_soul->get_name() ); } else { if( get_player_character().sees( *poor_soul ) ) { add_msg( m_good, _( "%1$s teleports into %2$s, killing them!" ), diff --git a/src/timed_event.cpp b/src/timed_event.cpp index 1fd1e629d68e8..46dfafca2ddbb 100644 --- a/src/timed_event.cpp +++ b/src/timed_event.cpp @@ -61,7 +61,7 @@ void timed_event::actualize() if( rl_dist( u_pos, map_point ) <= 4 ) { const mtype_id &robot_type = one_in( 2 ) ? mon_copbot : mon_riotbot; - g->events().send( player_character.getID() ); + get_event_bus().send( player_character.getID() ); point rob( u_pos.x > map_point.x ? 0 - SEEX * 2 : SEEX * 4, u_pos.y > map_point.y ? 0 - SEEY * 2 : SEEY * 4 ); g->place_critter_at( robot_type, tripoint( rob, player_character.posz() ) ); @@ -101,7 +101,7 @@ void timed_event::actualize() break; case timed_event_type::AMIGARA: { - g->events().send(); + get_event_bus().send(); int num_horrors = rng( 3, 5 ); cata::optional fault_point; bool horizontal = false; @@ -140,7 +140,7 @@ void timed_event::actualize() break; case timed_event_type::ROOTS_DIE: - g->events().send(); + get_event_bus().send(); for( const tripoint &p : here.points_on_zlevel() ) { if( here.ter( p ) == t_root_wall && one_in( 3 ) ) { here.ter_set( p, t_underbrush ); @@ -149,7 +149,7 @@ void timed_event::actualize() break; case timed_event_type::TEMPLE_OPEN: { - g->events().send(); + get_event_bus().send(); bool saw_grate = false; for( const tripoint &p : here.points_on_zlevel() ) { if( here.ter( p ) == t_grate ) { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index b129659941fc0..dfb77aedb70a5 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -6511,7 +6511,7 @@ bool vehicle::explode_fuel( int p, damage_type type ) int explosion_chance = type == DT_HEAT ? data.explosion_chance_hot : data.explosion_chance_cold; if( one_in( explosion_chance ) ) { - g->events().send( name ); + get_event_bus().send( name ); const int pow = 120 * ( 1 - std::exp( data.explosion_factor / -5000 * ( parts[p].ammo_remaining() * data.fuel_size_factor ) ) ); //debugmsg( "damage check dmg=%d pow=%d amount=%d", dmg, pow, parts[p].amount ); diff --git a/tests/memorial_test.cpp b/tests/memorial_test.cpp index 17d291fb4f330..bbda4972f5f05 100644 --- a/tests/memorial_test.cpp +++ b/tests/memorial_test.cpp @@ -56,7 +56,7 @@ TEST_CASE( "memorials", "[memorial]" ) m.clear(); clear_avatar(); - event_bus &b = g->events(); + event_bus &b = get_event_bus(); avatar &player_character = get_avatar(); player_character.male = false; diff --git a/tests/stats_tracker_test.cpp b/tests/stats_tracker_test.cpp index 762dd73966053..b58772eb04ee2 100644 --- a/tests/stats_tracker_test.cpp +++ b/tests/stats_tracker_test.cpp @@ -851,7 +851,7 @@ TEST_CASE( "stats_tracker_in_game", "[stats]" ) { g->stats().clear(); cata::event e = cata::event::make(); - g->events().send( e ); + get_event_bus().send( e ); CHECK( g->stats().get_events( e.type() ).count( e.data() ) == 1 ); } @@ -870,15 +870,15 @@ TEST_CASE( "achievements_tracker_in_game", "[stats]" ) { g->achievements().clear(); test_subscriber sub; - g->events().subscribe( &sub ); + get_event_bus().subscribe( &sub ); const character_id u_id = get_player_character().getID(); - send_game_start( g->events(), u_id ); + send_game_start( get_event_bus(), u_id ); const mtype_id mon_zombie( "mon_zombie" ); const cata::event avatar_zombie_kill = cata::event::make( u_id, mon_zombie ); - g->events().send( avatar_zombie_kill ); + get_event_bus().send( avatar_zombie_kill ); achievement_id c_pacifist( "conduct_zero_kills" ); achievement_id a_kill_zombie( "achievement_kill_zombie" ); From 9da5d932a4c0e7dbaede49d0cee86ce274a1f99f Mon Sep 17 00:00:00 2001 From: Brett Dong Date: Fri, 17 Jul 2020 20:37:00 +0800 Subject: [PATCH 096/151] Routine i18n updates on 17 Jul 2020 --- lang/extract_json_strings.py | 1 + lang/po/cataclysm-dda.pot | 2379 +++++++++++----- lang/po/de.po | 2993 +++++++++++++------- lang/po/es_AR.po | 4986 ++++++++++++++++++++++++---------- lang/po/ja.po | 3248 ++++++++++++++-------- lang/po/pl.po | 3017 +++++++++++++------- lang/po/ru.po | 3351 ++++++++++++++++------- lang/po/zh_CN.po | 3092 ++++++++++++++------- lang/po/zh_TW.po | 2985 +++++++++++++------- 9 files changed, 17935 insertions(+), 8117 deletions(-) diff --git a/lang/extract_json_strings.py b/lang/extract_json_strings.py index 9e93578fdbc4e..cee8158d25bbf 100755 --- a/lang/extract_json_strings.py +++ b/lang/extract_json_strings.py @@ -99,6 +99,7 @@ def warning_supressed(filename): "palette", "region_overlay", "region_settings", + "relic_procgen_data", "requirement", "rotatable_symbol", "SCENARIO_BLACKLIST", diff --git a/lang/po/cataclysm-dda.pot b/lang/po/cataclysm-dda.pot index 5bc7f89518f01..2c8c501e543a7 100644 --- a/lang/po/cataclysm-dda.pot +++ b/lang/po/cataclysm-dda.pot @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: cataclysm-dda 0.E\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-07-10 14:53+0800\n" +"POT-Creation-Date: 2020-07-17 20:36+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -6988,6 +6988,49 @@ msgid "" "designed to fit Huge survivors." msgstr "" +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm)" +msgid_plural "tourniquets (arm)" +msgstr[0] "" +msgstr[1] "" + +#. ~ Use action menu_text for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets (arm)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets (arm XL)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "Adjust" +msgstr "" + +#. ~ Use action msg for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets (arm)'}. +#. ~ Use action msg for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets (arm XL)'}. +#. ~ Use action msg for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "You adjust the tourniquet." +msgstr "" + +#. ~ Description for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets (arm)'} +#. ~ Description for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets (arm XL)'} +#. ~ Description for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets (leg)'} +#: lang/json/ARMOR_from_json.py +msgid "" +"First aid device used to apply pressure to a limb or extremity in order to " +"limit blood flow. Should be employed only to manage heavy bleedings, " +"because prolonged use will harm the limb. It can be adjusted in size to fit " +"different limbs." +msgstr "" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm XL)" +msgid_plural "tourniquets (arm XL)" +msgstr[0] "" +msgstr[1] "" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (leg)" +msgid_plural "tourniquets (leg)" +msgstr[0] "" +msgstr[1] "" + #: lang/json/ARMOR_from_json.py msgid "blindfold" msgid_plural "blindfolds" @@ -37864,6 +37907,20 @@ msgid "" "appetite, and is quite addictive." msgstr "" +#: lang/json/COMESTIBLE_from_json.py +msgid "adhesive bandage" +msgid_plural "adhesive bandages" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'adhesive bandage'} +#: lang/json/COMESTIBLE_from_json.py +msgid "" +"A set of small medical dressings, each made of a piece of sterile cloth and " +"a sticky tape, used for small injuries not serious enough to require a full-" +"size bandage." +msgstr "" + #: lang/json/COMESTIBLE_from_json.py msgid "syringe of adrenaline" msgid_plural "syringes of adrenaline" @@ -37945,7 +38002,9 @@ msgstr[1] "" #. ~ Description for {'str': 'bandage'} #: lang/json/COMESTIBLE_from_json.py -msgid "Simple cloth bandages. Used for healing small amounts of damage." +msgid "" +"Simple cloth bandages. Used for stopping bloodloss and protecting wounds " +"from external factors." msgstr "" #: lang/json/COMESTIBLE_from_json.py @@ -47786,8 +47845,8 @@ msgstr[1] "" #. ~ Description for {'str': 'bundle of planks', 'str_pl': 'bundles of planks'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten construction planks securely lashed together with a rope. Disassemble " -"to unpack." +"Ten construction planks securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" #: lang/json/GENERIC_from_json.py @@ -47799,8 +47858,21 @@ msgstr[1] "" #. ~ Description for {'str': 'bundle of stout branches', 'str_pl': 'bundles of stout branches'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten stout branches securely lashed together with a rope. Disassemble to " -"untie them." +"Ten stout branches securely tied together for easier transport. Disassemble " +"to untie them." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "bundle of long stout branches" +msgid_plural "bundles of long stout branches" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'bundle of long stout branches', 'str_pl': 'bundles of long stout branches'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Five long stout branches securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" #: lang/json/GENERIC_from_json.py @@ -51385,9 +51457,23 @@ msgstr[1] "" #. ~ Description for {'str': 'first aid kit'} #: lang/json/GENERIC_from_json.py msgid "" -"A full medical kit, with bandages, local anesthetics, and rapid healing " -"agents. Used for healing large amounts of damage. Disassemble to get its " -"content." +"A typical universal first aid kit, one you'd see in a car or in a " +"household. It contains a variety of common medical items stored in case of " +"accidents and injuries. Disassemble to get its content." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "IFAK" +msgid_plural "IFAKs" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'IFAK'} +#: lang/json/GENERIC_from_json.py +msgid "" +"An IFAK, or individual first aid kit, is a specialized set of wound " +"dressings and accessories, and being of military origin focuses on combat " +"trauma and preventing blood loss. Disassemble to get its content." msgstr "" #: lang/json/GENERIC_from_json.py @@ -55912,11 +55998,11 @@ msgstr "" #: lang/json/GENERIC_from_json.py msgid "inscribed metal plates" -msgid_plural "inscribed metal platess" +msgid_plural "inscribed metal plates" msgstr[0] "" msgstr[1] "" -#. ~ Description for {'str': 'inscribed metal plates'} +#. ~ Description for {'str_sp': 'inscribed metal plates'} #: lang/json/GENERIC_from_json.py msgid "" "This device looks electronic, but is unfamiliar. It is a series of tightly " @@ -55953,6 +56039,35 @@ msgid "" "work." msgstr "" +#: lang/json/GENERIC_from_json.py +msgid "engraved parabolic dish" +msgid_plural "engraved parabolic dishes" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'engraved parabolic dish', 'str_pl': 'engraved parabolic dishes'} +#: lang/json/GENERIC_from_json.py +msgid "" +"This hefty parabolic dish is engraved with an unrecognizable pattern of " +"symbols that might, at a guess, be some sort of circuitry pattern - or maybe " +"a religious incantation." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "oblong device" +msgid_plural "oblong devices" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'oblong device'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Perfectly smooth, cool to the touch, and a dull blue-grey colour, this looks " +"almost like a perfect riverstone at first glance. Its artificial nature is " +"betrayed on closer inspection by a network of intricate patterns visible as " +"a slight difference in the reflection of light off its surface." +msgstr "" + #: lang/json/GENERIC_from_json.py msgid "sheet of glass" msgid_plural "sheets of glass" @@ -70656,6 +70771,49 @@ msgid "" "eyes wide open and shining black." msgstr "" +#: lang/json/MONSTER_from_json.py +msgid "zombie cow" +msgid_plural "zombie cows" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'zombie cow'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Once a placid cow, this leathery horror stumbles and shudders, its pulsing " +"black eyes scanning for prey beneath wicked horns. It is big and heavy and " +"murderous." +msgstr "" + +#: lang/json/MONSTER_from_json.py +msgid "zombull" +msgid_plural "zombulls" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'zombull'} +#: lang/json/MONSTER_from_json.py +msgid "" +"This enormous and massive creature with oily black eyes and dread horns once " +"was a domestic bull. Its nasty character makes it attack everyone it meets " +"with an unbridled rage and tremendous speed." +msgstr "" + +#: lang/json/MONSTER_from_json.py +msgid "woodland wight" +msgid_plural "woodland wights" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'woodland wight'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pale, stumbling white-tailed deer with blackened eyes and drooling slime " +"down its neck. Its legs twist and bend in strange, haphazard directions, " +"but with unnatural strength and speed. Preys on coyotes, wolves, and giant " +"spider mutants." +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "mass of zombie spiders" msgid_plural "mass of zombie spiderss" @@ -75796,7 +75954,7 @@ msgid "Increases pain" msgstr "" #: lang/json/SPELL_from_json.py -#: src/character.cpp src/npctalk.cpp +#: src/character.cpp src/talker_npc.cpp msgid "Tired" msgstr "" @@ -77707,7 +77865,7 @@ msgstr[1] "" #. ~ Description for {'str': 'RM13 combat armor'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. Use it to turn it on." msgstr "" @@ -77721,7 +77879,7 @@ msgstr[1] "" #. ~ Description for {'str': 'RM13 combat armor (on)', 'str_pl': 'RM13 combat armors (on)'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. It is turned on, and continually draining " "power. Use it to turn it off." @@ -83533,8 +83691,8 @@ msgstr "" msgid "" "This is an advanced version of the unified power supply, or UPS. This " "device has been significantly redesigned to provide better efficiency as " -"well as to consume plutonium fuel cells rather than batteries. Sadly, its " -"plutonium reactor can't be charged in UPS charging station." +"well as to consume plutonium fuel batteries rather than regular batteries. " +"Sadly, its plutonium reactor can't be charged in UPS charging station." msgstr "" #. ~ Description for {'str': 'camera'} @@ -95663,6 +95821,26 @@ msgstr "" msgid "Build Junk Metal Floor" msgstr "" +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Bolts" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Welder" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bench" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Table" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Lay down decorative ground cable" +msgstr "" + #: lang/json/construction_from_json.py msgid "Build Pillow Fort" msgstr "" @@ -98034,6 +98212,15 @@ msgstr "" msgid "Your muscles won't cooperate!" msgstr "" +#: lang/json/effects_from_json.py +msgid "Minor Bleeding" +msgstr "" + +#. ~ Description of effect 'Minor Bleeding'. +#: lang/json/effects_from_json.py +msgid "Tis but a scratch." +msgstr "" + #: lang/json/effects_from_json.py msgid "Bleeding" msgstr "" @@ -98061,7 +98248,16 @@ msgstr "" msgid "You are rapidly losing blood." msgstr "" -#. ~ Apply message for effect(s) 'Bleeding, Bad Bleeding, Heavy Bleeding'. +#: lang/json/effects_from_json.py +msgid "Heavy Arterial Bleeding" +msgstr "" + +#. ~ Description of effect 'Heavy Arterial Bleeding'. +#: lang/json/effects_from_json.py +msgid "Blood is gushing from you like a fountain." +msgstr "" + +#. ~ Apply message for effect(s) 'Minor Bleeding, Minor Bleeding, Minor Bleeding, Minor Bleeding, Minor Bleeding, Bleeding, Bleeding, Bleeding, Bleeding, Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding'. #: lang/json/effects_from_json.py msgid "You're bleeding!" msgstr "" @@ -98805,39 +99001,87 @@ msgstr "" msgid "Your bones become stronger as your calcium deficiency improves." msgstr "" +#: lang/json/effects_from_json.py +msgid "Early iron deficiency" +msgstr "" + +#. ~ Description of effect 'Early iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"A lack of iron in your diet has hampered efficiency and regeneration of your " +"red blood cells." +msgstr "" + #: lang/json/effects_from_json.py msgid "Iron deficiency" msgstr "" +#. ~ Description of effect 'Iron deficiency'. #: lang/json/effects_from_json.py -msgid "Early anemia" +msgid "" +"Prolonged lack of iron in your diet has compromised efficiency and " +"regeneration of your red blood cells." msgstr "" #: lang/json/effects_from_json.py -msgid "Anemia" +msgid "Acute iron deficiency" msgstr "" +#. ~ Description of effect 'Acute iron deficiency'. #: lang/json/effects_from_json.py msgid "" -"A lack of iron in your diet will result in progressively worsening anemia." +"Severe lack of iron in your diet results in your red blood cells dying " +"faster then they are regenerating." msgstr "" -#. ~ Apply message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Apply message for effect(s) 'Early iron deficiency, Iron deficiency, Acute iron deficiency'. +#. ~ Apply message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You begin feeling increasingly tired and listless." msgstr "" -#. ~ Remove message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Remove message for effect(s) 'Early iron deficiency, Iron deficiency, Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "You are no longer in risk of becoming anemic." +msgstr "" + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your irom deficiency is nearly resolved." +msgstr "" + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your iron deficiency starts to improve." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Early anemia" +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Anemia" +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Acute anemia" +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Loss of red blood cells results in progressively worsening anemia." +msgstr "" + +#. ~ Remove message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You no longer feel anemic." msgstr "" -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py -msgid "Your iron deficiency is nearly resolved." +msgid "Your anemia is nearly resolved." msgstr "" -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "Your feel stronger as your anemia starts to improve." msgstr "" @@ -99020,6 +99264,72 @@ msgid "" "disgusting rations day in and day out?" msgstr "" +#: lang/json/effects_from_json.py +msgid "Mild hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Mild hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost some blood and look somewhat pale." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Moderate hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Moderate hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost large amount of blood, and you're not feeling well." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Advanced hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Advanced hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost an awful lot of blood, and your condition is severe. Seek " +"medical attention." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Severe hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost tremendous amount of blood, and you're standing on death's door. " +"Transfusion might save you." +msgstr "" + +#. ~ Apply message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You have lost lot of blood, and your condition worsens." +msgstr "" + +#. ~ Remove message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You are no longer in shock." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your blood level increase, and you feel better, but still look pale." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your blood levels starts to improve." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You're not dying from lack of blood, but you're not out of the woods yet." +msgstr "" + #: lang/json/effects_from_json.py msgid "Lit up" msgstr "" @@ -100886,27 +101196,351 @@ msgid "mutated cactus" msgstr "" #: lang/json/furniture_from_json.py -msgid "cooling unit" +msgid "glowing tendril" msgstr "" -#. ~ Description for cooling unit +#. ~ Description for glowing tendril #: lang/json/furniture_from_json.py msgid "" -"A large, blocky appliance encased in sheet metal. This commonplace fixture " -"is used for cooling large indoor areas." +"A willowy tendril growing from the floor, gently waving back and forth. A " +"faint light spills from it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "splorch!" msgstr "" #: lang/json/furniture_from_json.py #: lang/json/furniture_from_json.py lang/json/terrain_from_json.py #: lang/json/terrain_from_json.py -msgid "metal screeching!" +msgid "whump!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "wafting anemone" +msgstr "" + +#. ~ Description for wafting anemone +#: lang/json/furniture_from_json.py +msgid "" +"A fleshy white protuberance growing from the floor, with a cluster of " +"tendrils pouring out of it. It looks almost exactly like a sea anemone, " +"even waving gently as though underwater." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "gasping tube" +msgstr "" + +#. ~ Description for gasping tube +#: lang/json/furniture_from_json.py +msgid "" +"This is a meaty green stalactite with a thickened hide like that of a " +"starfish, extending from the floor to the ceiling. In the center is a " +"series of ports somewhat like mouths, from which pour bursts of a vile-" +"smelling gas." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "twitching frond" +msgstr "" + +#. ~ Description for twitching frond +#: lang/json/furniture_from_json.py +msgid "" +"A spine resembling moth antennae juts from the ground, swaying gently in the " +"air. Every so often, a cascade of energy arcs along it and discharges into " +"the ceiling." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scarred lump" +msgstr "" + +#. ~ Description for scarred lump +#: lang/json/furniture_from_json.py +msgid "" +"This is a pile of nondescript alien flesh, twitching and belching strange " +"gases out of injured orifices." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "splat!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "slimy pod" +msgstr "" + +#. ~ Description for slimy pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a slick, translucent pod suspended on a thin stalk. It is covered " +"in a thick mucus, obscuring whatever is floating in the gel-like substance " +"inside." +msgstr "" + +#: lang/json/furniture_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py +msgid "whump." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "organ pod" +msgstr "" + +#. ~ Description for organ pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside you can see the " +"dimly outlined shape of human organs, floating in some kind of preservative " +"goo." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "resin pod" msgstr "" +#. ~ Description for resin pod #: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside is a clean, " +"clear resinous-looking fluid. You could fairly easily tear it from the " +"stalk and take it with you." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "fleshy altar" +msgstr "" + +#. ~ Description for fleshy altar +#: lang/json/furniture_from_json.py +msgid "" +"This pulsing protuberance juts from the floor, its sides covered in scaled, " +"oozing skin. The surface is flat, but undulates softly. A handful of " +"unidentifiable appendages reach from the sides, suggesting a sort of " +"nightmarish living autodoc." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scrap antenna" +msgstr "" + +#. ~ Description for scrap antenna +#: lang/json/furniture_from_json.py +msgid "" +"This contraption looks like some sort of cobbled-together transmitter or " +"receiver antenna. It consists of a number of mismatched blinking lights, " +"spinning servos, and dangling wires connected to a heft metal box." +msgstr "" + +#: lang/json/furniture_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py #: lang/json/terrain_from_json.py msgid "clang!" msgstr "" +#: lang/json/furniture_from_json.py +msgid "rack of robots" +msgstr "" + +#. ~ Description for rack of robots +#: lang/json/furniture_from_json.py +msgid "" +"This is a wire cage containing a number of robot parts, from chassis to " +"limbs, firmly clamped on to sturdy hanging rods. It looks like it would be " +"exceptionally difficult to open it and get at them without damaging them, " +"probably by design." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "spinning dish" +msgstr "" + +#. ~ Description for spinning dish +#: lang/json/furniture_from_json.py +msgid "" +"This is a slowly spinning parabolic dish engraved with an unrecognizable " +"pattern of symbols that might, at a guess, be some sort of circuitry pattern " +"- or maybe a religious incantation. It is mounted on a completely " +"mismatched electric motor that looks fairly mundane." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scavenged utility light" +msgstr "" + +#. ~ Description for scavenged utility light +#: lang/json/furniture_from_json.py +msgid "" +"The bulbs emit an eery greenish glow, and some parts of it have a curved " +"appearance as though the metal were grown in a lab, but by and large this " +"isn't a particularly unusual looking area light." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "clanking fluid pump" +msgstr "" + +#. ~ Description for clanking fluid pump +#: lang/json/furniture_from_json.py +msgid "" +"The huge sweating pipes and large tank reveal this clanking and tortuous " +"piece of equipment to be some sort of fluid pump. It is cobbled from " +"several apparently ill-fitting parts that have been fitted together with " +"some very strange looking but surprisingly clever adaptors." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "metalloid printer" +msgstr "" + +#. ~ Description for metalloid printer +#: lang/json/furniture_from_json.py +msgid "" +"This huge device actually resembles a 3D printer fairly closely, aside from " +"its industrial size. Huge spools of various thin metallic wires top it and " +"feed into what seems to be some sort of nozzle, and massive electrical " +"cables disappear into the wall behind it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "circuit printer" +msgstr "" + +#. ~ Description for circuit printer +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall device with a lattice of pipes and nozzles. Based on the " +"pile of products sitting in the output hopper, it looks like itā€™s used as a " +"printer for complex electronic components." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "Mavrik 10-101 power core" +msgstr "" + +#. ~ Description for Mavrik 10-101 power core +#: lang/json/furniture_from_json.py +msgid "" +"There is a faded metallic plaque on the side of this cylindrical device. " +"The lettering is a strange combination of English and Cyrillic script. It " +"reads:\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" +msgstr "" + +#: lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py +msgid "metal screeching!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "spherical generator" +msgstr "" + +#. ~ Description for spherical generator +#: lang/json/furniture_from_json.py +msgid "" +"This huge steel plated sphere gives off a soft hum as it, presumably, " +"generates power. A heavy lead plate bolted to the front might describe what " +"it is, but it is written in something that looks vaguely like cuneiform." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "fluidic generator" +msgstr "" + +#. ~ Description for fluidic generator +#: lang/json/furniture_from_json.py +msgid "" +"Twisting reams of copper and steel pipes wrap around a central core that " +"thrums softly. Although there are no labels in any language you recognize, " +"the cables connected to the base suggest that this is some sort of power " +"generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "rusty generator" +msgstr "" + +#. ~ Description for rusty generator +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall, unremarkable cylinder capped by a wide flat saucer. There " +"is heavy rusting at the base. A series of connected cables suggest that " +"it's some sort of power generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "personal charging station" +msgstr "" + +#. ~ Description for personal charging station +#: lang/json/furniture_from_json.py +msgid "" +"The cyborg equivalent of a bed, this is a custom-shaped near-vertical booth " +"designed to mount a heavy metal frame and connect it to a central power " +"supply and nutrient source." +msgstr "" + +#: lang/json/furniture_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py +#: src/map.cpp +msgid "crash!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "simple charging station" +msgstr "" + +#. ~ Description for simple charging station +#: lang/json/furniture_from_json.py +msgid "" +"This is a simple, unadorned, corroded metal charging and refeeding station, " +"with hookups for two units somewhat larger than a human to stand side by " +"side and be recharged and refueled." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shimmering superstructure" +msgstr "" + +#. ~ Description for shimmering superstructure +#: lang/json/furniture_from_json.py +msgid "" +"A simple metal superstructure like you might see holding up a radio tower, " +"this one seems to give off just the faintest hint of shimmer, like heat " +"waves. The metal has a burnt, iridescent pattern. There is a boxy, " +"unimpressive looking device at the top of the tower." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "portal enclosure" +msgstr "" + +#. ~ Description for portal enclosure +#: lang/json/furniture_from_json.py +msgid "" +"A heavy metal ring attached to dozens of wires, charred by residue that " +"gives off an acrid, unfamiliar smell." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "cooling unit" +msgstr "" + +#. ~ Description for cooling unit +#: lang/json/furniture_from_json.py +msgid "" +"A large, blocky appliance encased in sheet metal. This commonplace fixture " +"is used for cooling large indoor areas." +msgstr "" + #: lang/json/furniture_from_json.py msgid "central air filter" msgstr "" @@ -101065,7 +101699,6 @@ msgid "" msgstr "" #: lang/json/furniture_from_json.py -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py #: lang/json/terrain_from_json.py msgid "whack!" msgstr "" @@ -101083,18 +101716,12 @@ msgid "" msgstr "" #: lang/json/furniture_from_json.py -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py #: lang/json/terrain_from_json.py -#: src/map.cpp src/mapdata.cpp -#: src/vehicle_move.cpp +#: lang/json/terrain_from_json.py src/map.cpp +#: src/mapdata.cpp src/vehicle_move.cpp msgid "smash!" msgstr "" -#: lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py -msgid "whump." -msgstr "" - #: lang/json/furniture_from_json.py msgid "earthbag barricade" msgstr "" @@ -101433,10 +102060,6 @@ msgid "" "them moving slightly. Gross." msgstr "" -#: lang/json/furniture_from_json.py -msgid "splat!" -msgstr "" - #. ~ Description for spider egg sack #: lang/json/furniture_from_json.py msgid "" @@ -101516,19 +102139,6 @@ msgid "" "the smoke to the outside. Dangerous to leave unattended while lit." msgstr "" -#: lang/json/furniture_from_json.py -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -#: lang/json/terrain_from_json.py -#: src/map.cpp -msgid "crash!" -msgstr "" - -#: lang/json/furniture_from_json.py -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -#: lang/json/terrain_from_json.py -msgid "whump!" -msgstr "" - #: lang/json/furniture_from_json.py msgid "wood stove" msgstr "" @@ -101688,8 +102298,9 @@ msgid "" msgstr "" #: lang/json/furniture_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py #: lang/json/terrain_from_json.py -#: src/iuse.cpp +#: lang/json/terrain_from_json.py src/iuse.cpp msgid "crunch!" msgstr "" @@ -101852,6 +102463,78 @@ msgid "" "chemicals." msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken generator" +msgstr "" + +#. ~ Description for broken generator +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This generator is broken and will not help you produce usable electricity." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "Compact Advanced Sterling Radioisotope Generator" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"This hefty lump of steel and lead is the housing unit for a small nuclear " +"reactor. It is plastered with warning signs. You could probably ignore " +"those and salvage the steel and lead shielding, what could possibly go wrong?" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"Some insane fool has removed the outer containment on this small-scale " +"nuclear reactor. It is still fairly safe as it is: the reactor has " +"considerable built-in containment as well. Nevertheless, you probably don't " +"want to stand too close for too long." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "light machinery" +msgstr "" + +#. ~ Description for light machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted light machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py +msgid "ting." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "heavy machinery" +msgstr "" + +#. ~ Description for heavy machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted heavy machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "old machinery" +msgstr "" + +#. ~ Description for old machinery +#: lang/json/furniture_from_json.py +msgid "Assorted old, rusty machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "electronic machinery" +msgstr "" + +#. ~ Description for electronic machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted electronic machinery. You could scavenge it for parts." +msgstr "" + #: lang/json/furniture_from_json.py msgid "robotic arm" msgstr "" @@ -101869,6 +102552,32 @@ msgstr "" msgid "thunk." msgstr "" +#: lang/json/furniture_from_json.py +msgid "ground cable" +msgstr "" + +#. ~ Description for ground cable +#: lang/json/furniture_from_json.py +msgid "A bunch of loose cables snake along the floor." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shred!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "thud!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "capacitor bank" +msgstr "" + +#. ~ Description for capacitor bank +#: lang/json/furniture_from_json.py +msgid "A bank of heavy metal cylinders connected by large wires." +msgstr "" + #: lang/json/furniture_from_json.py msgid "Autodoc Mk. XI" msgstr "" @@ -102133,116 +102842,17 @@ msgstr "" msgid "Stop peeking!" msgstr "" -#: lang/json/furniture_from_json.py -msgid "glowing tendril" -msgstr "" - -#. ~ Description for glowing tendril -#: lang/json/furniture_from_json.py -msgid "" -"A willowy tendril growing from the floor, gently waving back and forth. A " -"faint light spills from it." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "splorch!" -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "wafting anemone" -msgstr "" - -#. ~ Description for wafting anemone -#: lang/json/furniture_from_json.py -msgid "" -"A fleshy white protuberance growing from the floor, with a cluster of " -"tendrils pouring out of it. It looks almost exactly like a sea anemone, " -"even waving gently as though underwater." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "gasping tube" -msgstr "" - -#. ~ Description for gasping tube -#: lang/json/furniture_from_json.py -msgid "" -"This is a meaty green stalactite with a thickened hide like that of a " -"starfish, extending from the floor to the ceiling. In the center is a " -"series of ports somewhat like mouths, from which pour bursts of a vile-" -"smelling gas." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "twitching frond" -msgstr "" - -#. ~ Description for twitching frond -#: lang/json/furniture_from_json.py -msgid "" -"A spine resembling moth antennae juts from the ground, swaying gently in the " -"air. Every so often, a cascade of energy arcs along it and discharges into " -"the ceiling." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "scarred lump" -msgstr "" - -#. ~ Description for scarred lump -#: lang/json/furniture_from_json.py -msgid "" -"This is a pile of nondescript alien flesh, twitching and belching strange " -"gases out of injured orifices." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "slimy pod" -msgstr "" - -#. ~ Description for slimy pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a slick, translucent pod suspended on a thin stalk. It is covered " -"in a thick mucus, obscuring whatever is floating in the gel-like substance " -"inside." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "organ pod" -msgstr "" - -#. ~ Description for organ pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside you can see the " -"dimly outlined shape of human organs, floating in some kind of preservative " -"goo." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "resin pod" -msgstr "" - -#. ~ Description for resin pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside is a clean, " -"clear resinous-looking fluid. You could fairly easily tear it from the " -"stalk and take it with you." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "fleshy altar" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "centrifuge" msgstr "" -#. ~ Description for fleshy altar +#. ~ Description for centrifuge #: lang/json/furniture_from_json.py msgid "" -"This pulsing protuberance juts from the floor, its sides covered in scaled, " -"oozing skin. The surface is flat, but undulates softly. A handful of " -"unidentifiable appendages reach from the sides, suggesting a sort of " -"nightmarish living autodoc." +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. For some reason, this one has an attached battery pack. It could be " +"used to analyze a medical fluid sample, such as blood, if a test tube was " +"placed in it." msgstr "" #: lang/json/furniture_from_json.py @@ -102737,6 +103347,17 @@ msgid "" "it's not particularly comfortable." msgstr "" +#: lang/json/furniture_from_json.py +msgid "metal bench" +msgstr "" + +#. ~ Description for metal bench +#: lang/json/furniture_from_json.py +msgid "" +"A bench made of scrap metal. Not the most comfortable furniture you've ever " +"seen." +msgstr "" + #: lang/json/furniture_from_json.py msgid "bulletin board" msgstr "" @@ -103237,6 +103858,37 @@ msgid "" "A huge metal tank that can be used to safely store large amounts of liquid." msgstr "" +#: lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py +msgid "fuel tank" +msgstr "" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with gasoline." +msgstr "" + +#: lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py +msgid "broken fuel tank" +msgstr "" + +#. ~ Description for broken fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with gasoline." +msgstr "" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with diesel." +msgstr "" + +#. ~ Description for broken fuel tank +#. ~ Description for broken diesel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with diesel." +msgstr "" + #: lang/json/furniture_from_json.py msgid "dumpster" msgstr "" @@ -103260,6 +103912,42 @@ msgid "" "electricity, it is pedal-driven, allowing use without power." msgstr "" +#: lang/json/furniture_from_json.py +msgid "riveted metal crate" +msgstr "" + +#. ~ Description for riveted metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This huge box is made of a dull metal, riveted together. There is no " +"obvious opening mechanism, and the rivets don't match any of your tools. " +"The only way in would be to smash it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "sealed metal crate" +msgstr "" + +#. ~ Description for sealed metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This is a huge, tightly sealed storage crate made from welded and riveted " +"sheet metal. The sealing mechanism is too tight to open bare-handed and " +"would need some kind of prying instrument to release." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "open metal crate" +msgstr "" + +#. ~ Description for open metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This large metal crateā€™s lid is unsealed, and hinges open easily to reveal a " +"number of storage shelves inside. Once open, the side panels also swing " +"wider for easy access." +msgstr "" + #: lang/json/furniture_from_json.py msgid "counter" msgstr "" @@ -103359,6 +104047,15 @@ msgstr "" msgid "a low table for livingrooms." msgstr "" +#: lang/json/furniture_from_json.py +msgid "metal table" +msgstr "" + +#. ~ Description for metal table +#: lang/json/furniture_from_json.py +msgid "A serviceable but simple table made of scrap metal." +msgstr "" + #: lang/json/furniture_from_json.py msgid "tatami mat" msgstr "" @@ -103589,6 +104286,17 @@ msgstr "" msgid "Pile of various bent and twisted metals." msgstr "" +#: lang/json/furniture_from_json.py +msgid "radioactive slag" +msgstr "" + +#. ~ Description for radioactive slag +#: lang/json/furniture_from_json.py +msgid "" +"A pile of melted slag from a destroyed nuclear reactor. What are you doing " +"looking at this? Get the hell out of here, you nutcase!" +msgstr "" + #: lang/json/furniture_from_json.py msgid "pile of ash" msgstr "" @@ -103662,6 +104370,39 @@ msgid "" "public utilities, but it doesn't work anymore." msgstr "" +#: lang/json/furniture_from_json.py +msgid "scrap metal bridge" +msgstr "" + +#. ~ Description for scrap metal bridge +#: lang/json/furniture_from_json.py +msgid "A simple bridge made of riveted sheet metal." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py +msgid "broken console" +msgstr "" + +#. ~ Description for broken console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It doesn't seem to be working. " +"It's the broken screen and shattered circuit boards that's telling you that." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "computer console" +msgstr "" + +#. ~ Description for computer console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It can be used to view contents and " +"perform any allowed functions. It might even be possible to hack it, given " +"the skills." +msgstr "" + #: lang/json/furniture_from_json.py msgid "forge" msgstr "" @@ -104020,6 +104761,15 @@ msgid "" "you wouldn't need to pay at all!" msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "rope leading up" +msgstr "" + +#. ~ Description for rope leading up +#: lang/json/furniture_from_json.py +msgid "A rope. You could climb it up." +msgstr "" + #: lang/json/furniture_from_json.py msgid "atomic butter churn on a stand" msgstr "" @@ -133691,17 +134441,6 @@ msgid "" "anything now is another question." msgstr "" -#: lang/json/mutation_from_json.py -msgid "Helicopter Pilot" -msgstr "" - -#. ~ Description for Helicopter Pilot -#: lang/json/mutation_from_json.py -msgid "" -"You are a trained helicopter pilot. This makes you one of the few living " -"people who can operate a helicopter after the Cataclysm." -msgstr "" - #: lang/json/mutation_from_json.py msgid "SWAT Officer" msgstr "" @@ -138621,6 +139360,10 @@ msgstr "" msgid "subway station?" msgstr "" +#: lang/json/overmap_terrain_from_json.py +msgid "science lab reactor" +msgstr "" + #: lang/json/overmap_terrain_from_json.py msgid "lab" msgstr "" @@ -145920,6 +146663,18 @@ msgid "" "You have your whole life ahead of you and it's gonna be sweet!" msgstr "" +#: lang/json/proficiency_from_json.py +msgid "Knapping" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Blacksmithing" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Helicopter Piloting" +msgstr "" + #. ~ Crafting recipes category name #: lang/json/recipe_category_from_json.py msgid "*" @@ -153812,7 +154567,7 @@ msgstr "" msgid "Finally, something to take the edge off." msgstr "" -#: lang/json/snippet_from_json.py src/npctalk.cpp +#: lang/json/snippet_from_json.py src/talker_npc.cpp msgid "No thanks, I'm good." msgstr "" @@ -173754,6 +174509,10 @@ msgstr "" msgid "This is a low driving test response." msgstr "" +#: lang/json/talk_topic_from_json.py +msgid "This is an npc_first_topic test response." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "Greetings friend, it's nice to see you." msgstr "" @@ -182072,7 +182831,8 @@ msgid "Will do, thanks!" msgstr "" #: lang/json/talk_topic_from_json.py -#: lang/json/talk_topic_from_json.py src/npctalk.cpp +#: lang/json/talk_topic_from_json.py src/talker.h +#: src/talker_npc.cpp msgid "Nope." msgstr "" @@ -187965,6 +188725,36 @@ msgstr "" msgid "The door opens forcefully!" msgstr "" +#: lang/json/terrain_from_json.py +msgid "broken diesel tank" +msgstr "" + +#. ~ Description for centrifuge +#: lang/json/terrain_from_json.py +msgid "" +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. It could be used to analyze a medical fluid sample, such as blood, if " +"a test tube was placed in it." +msgstr "" + +#: lang/json/terrain_from_json.py +msgid "plutonium generator" +msgstr "" + +#. ~ Description for plutonium generator +#: lang/json/terrain_from_json.py +msgid "" +"This imposing apparatus harnesses the power of the atom. Refined nuclear " +"fuel is 'burned' to provide nearly limitless electrical power. It's not " +"doing much good here though. Perhaps it could be salvaged for other " +"purposes." +msgstr "" + +#. ~ Description for old machinery +#: lang/json/terrain_from_json.py +msgid "Assorted old machinery. You could scavenge it for parts." +msgstr "" + #: lang/json/terrain_from_json.py msgid "scorched earth" msgstr "" @@ -190688,24 +191478,6 @@ msgid "" "press them into basic shapes, ready for further crafting." msgstr "" -#: lang/json/terrain_from_json.py -msgid "fuel tank" -msgstr "" - -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with gasoline." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "broken fuel tank" -msgstr "" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with gasoline." -msgstr "" - #: lang/json/terrain_from_json.py msgid "gasoline pump" msgstr "" @@ -190730,16 +191502,6 @@ msgid "" "the liquid gold." msgstr "" -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with diesel." -msgstr "" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with diesel." -msgstr "" - #: lang/json/terrain_from_json.py msgid "diesel pump" msgstr "" @@ -190817,16 +191579,6 @@ msgid "" "airflow." msgstr "" -#: lang/json/terrain_from_json.py -msgid "broken generator" -msgstr "" - -#. ~ Description for broken generator -#: lang/json/terrain_from_json.py -msgid "" -"This generator is broken and will not help you produce usable electricity." -msgstr "" - #: lang/json/terrain_from_json.py msgid "missile" msgstr "" @@ -190884,18 +191636,6 @@ msgid "" "This unpowered pump previously would have moved fluids around in a hurry." msgstr "" -#: lang/json/terrain_from_json.py -msgid "centrifuge" -msgstr "" - -#. ~ Description for centrifuge -#: lang/json/terrain_from_json.py -msgid "" -"This is a centrifuge, a liquid separating device with an automated analyzer " -"unit. It could be used to analyze a medical fluid sample, such as blood, if " -"a test tube was placed in it." -msgstr "" - #: lang/json/terrain_from_json.py msgid "CVD machine" msgstr "" @@ -190991,19 +191731,6 @@ msgstr "" msgid "A machine with several taps that dispenses clean water." msgstr "" -#: lang/json/terrain_from_json.py -msgid "plutonium generator" -msgstr "" - -#. ~ Description for plutonium generator -#: lang/json/terrain_from_json.py -msgid "" -"This imposing apparatus harnesses the power of the atom. Refined nuclear " -"fuel is 'burned' to provide nearly limitless electrical power. It's not " -"doing much good here though. Perhaps it could be salvaged for other " -"purposes." -msgstr "" - #: lang/json/terrain_from_json.py msgid "telecom cabinet" msgstr "" @@ -191118,46 +191845,6 @@ msgstr "" msgid "A conveyor belt. Used to transport things." msgstr "" -#: lang/json/terrain_from_json.py -msgid "ting." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "light machinery" -msgstr "" - -#. ~ Description for light machinery -#: lang/json/terrain_from_json.py -msgid "Assorted light machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "heavy machinery" -msgstr "" - -#. ~ Description for heavy machinery -#: lang/json/terrain_from_json.py -msgid "Assorted heavy machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "old machinery" -msgstr "" - -#. ~ Description for old machinery -#: lang/json/terrain_from_json.py -msgid "Assorted old machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "electronic machinery" -msgstr "" - -#. ~ Description for electronic machinery -#: lang/json/terrain_from_json.py -msgid "Assorted electronic machinery. You could scavenge it for parts." -msgstr "" - #: lang/json/terrain_from_json.py msgid "milking machine" msgstr "" @@ -191228,29 +191915,6 @@ msgid "" "from the elements or to protect a campfire from the rain." msgstr "" -#: lang/json/terrain_from_json.py -msgid "broken console" -msgstr "" - -#. ~ Description for broken console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It doesn't seem to be working. " -"It's the broken screen and shattered circuit boards that's telling you that." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "computer console" -msgstr "" - -#. ~ Description for computer console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It can be used to view contents and " -"perform any allowed functions. It might even be possible to hack it, given " -"the skills." -msgstr "" - #: lang/json/terrain_from_json.py msgid "mechanical winch" msgstr "" @@ -193381,10 +194045,6 @@ msgstr "" msgid "An upward facing slope." msgstr "" -#: lang/json/terrain_from_json.py -msgid "rope leading up" -msgstr "" - #. ~ Description for rope leading up #: lang/json/terrain_from_json.py msgid "A rope. You could climb up it." @@ -196913,6 +197573,14 @@ msgstr "" msgid "Disgusting Diet" msgstr "" +#: lang/json/vitamin_from_json.py +msgid "Blood" +msgstr "" + +#: lang/json/vitamin_from_json.py +msgid "Red Blood Cells" +msgstr "" + #: lang/json/weather_type_from_json.py msgid "NULL Weather - BUG" msgstr "" @@ -197134,8 +197802,7 @@ msgstr "" #: src/activity_actor.cpp #: src/computer_session.cpp -#: src/computer_session.cpp src/iuse.cpp -#: src/map.cpp +#: src/iuse.cpp src/map.cpp msgid "an alarm sound!" msgstr "" @@ -197275,6 +197942,16 @@ msgstr "" msgid "Continue trying to fall asleep and don't ask again." msgstr "" +#: src/activity_actor.cpp +#, c-format +msgid "You disassemble your %s." +msgstr "" + +#: src/activity_actor.cpp src/player.cpp +#, c-format +msgid "You unload your %s." +msgstr "" + #: src/activity_actor.cpp msgid "You are too tired to exercise." msgstr "" @@ -197766,11 +198443,6 @@ msgstr[1] "" msgid "Can't reload the %s." msgstr "" -#: src/activity_handlers.cpp src/iexamine.cpp -#, c-format -msgid "You reload the %s." -msgstr "" - #: src/activity_handlers.cpp #, c-format msgid "You manage to loosen some debris and make your %s somewhat operational." @@ -197786,6 +198458,11 @@ msgstr "" msgid "You refill the %s." msgstr "" +#: src/activity_handlers.cpp +#, c-format +msgid "You reload the %1$s with %2$s." +msgstr "" + #: src/activity_handlers.cpp src/bionics.cpp msgid "There's nothing to light there." msgstr "" @@ -197917,6 +198594,10 @@ msgstr "" msgid "%s %s\n" msgstr "" +#: src/activity_handlers.cpp src/magic.cpp +msgid "bionic power" +msgstr "" + #: src/activity_handlers.cpp #, c-format msgid "Charges: %s/%s %s (%s per use)\n" @@ -198296,16 +198977,6 @@ msgstr "" msgid "You give your hair a trim." msgstr "" -#: src/activity_handlers.cpp -#, c-format -msgid "You disassemble your %s." -msgstr "" - -#: src/activity_handlers.cpp src/player.cpp -#, c-format -msgid "You unload your %s." -msgstr "" - #: src/activity_handlers.cpp #, c-format msgid "You have run out of %s." @@ -199292,7 +199963,7 @@ msgstr "" msgid "Properties" msgstr "" -#: src/armor_layers.cpp +#: src/armor_layers.cpp src/item.cpp msgid "Coverage:" msgstr "" @@ -201263,7 +201934,7 @@ msgstr "" msgid "Deactivate your %s first!" msgstr "" -#: src/bionics.cpp src/player.cpp +#: src/bionics.cpp src/character.cpp #, c-format msgid "Stop wielding %s?" msgstr "" @@ -202654,6 +203325,11 @@ msgstr "" msgid "You cannot dismount there!" msgstr "" +#: src/character.cpp +#, c-format +msgid "This task is too simple to train your %s beyond %d." +msgstr "" + #: src/character.cpp msgid "You struggle to stand." msgstr "" @@ -202824,6 +203500,16 @@ msgstr "" msgid "Your %s bionic comes back online." msgstr "" +#: src/character.cpp +#, c-format +msgid "Your skill in %s has increased to %d!" +msgstr "" + +#: src/character.cpp +#, c-format +msgid "You feel that %s tasks of this level are becoming trivial." +msgstr "" + #: src/character.cpp #, c-format msgid "You put on your %s." @@ -202937,6 +203623,15 @@ msgstr "" msgid "%s doesn't have any broken limbs this could help." msgstr "" +#: src/character.cpp +msgid "You don't need a tourniquet to stop the bleeding." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "%s doesn't need a tourniquet to stop the bleeding." +msgstr "" + #: src/character.cpp msgid "You don't have enough arms to wear that." msgstr "" @@ -203117,7 +203812,7 @@ msgstr "" msgid "ERROR!" msgstr "" -#: src/character.cpp src/npctalk.cpp +#: src/character.cpp src/talker_npc.cpp msgid "Exhausted" msgstr "" @@ -203161,7 +203856,7 @@ msgstr "" msgid "You have a sudden heart attack!" msgstr "" -#: src/character.cpp +#: src/character.cpp src/player_hardcoded_effects.cpp msgid " has a sudden heart attack!" msgstr "" @@ -203389,11 +204084,11 @@ msgstr "" #: src/character.cpp #, c-format -msgid "Chance to stop: %d %%" +msgid "Expected reduction of bleeding by: %d %%" msgstr "" #: src/character.cpp -msgid "This will not stop the bleeding." +msgid "This will not affect the bleeding." msgstr "" #: src/character.cpp @@ -203828,6 +204523,41 @@ msgstr "" msgid "Your %1$s is %2$s!" msgstr "" +#: src/character.cpp +msgid "Can't wield spilt liquids." +msgstr "" + +#: src/character.cpp +msgid "You need at least one arm to even consider wielding something." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "The %s is preventing you from wielding the %s." +msgstr "" + +#: src/character.cpp +msgid "Something you are wearing hinders the use of both hands." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "The %s can't be wielded with only one arm." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "You are too weak to wield %s with only one arm." +msgstr "" + +#: src/character.cpp +msgid " (empty)" +msgstr "" + +#: src/character.cpp src/npctalk.cpp +msgid "fists" +msgstr "" + #: src/character.cpp #, c-format msgid "You are no longer able to wield your %s and drop it!" @@ -204377,6 +205107,11 @@ msgstr "" msgid "%s - Root Menu" msgstr "" +#: src/computer_session.cpp +#, c-format +msgid "%s (UNAVAILABLE)" +msgstr "" + #: src/computer_session.cpp msgid "Password required." msgstr "" @@ -204939,7 +205674,7 @@ msgstr "" msgid "Result: " msgstr "" -#: src/construction.cpp +#: src/construction.cpp src/worldfactory.cpp msgid "N/A" msgstr "" @@ -205593,6 +206328,10 @@ msgid "" "Start crafting anyway?" msgstr "" +#: src/craft_command.cpp +msgid "You don't have the required proficiencies to craft this!" +msgstr "" + #: src/craft_command.cpp msgid "" "This craft will use rotten components.\n" @@ -206059,6 +206798,11 @@ msgstr "" msgid "Other skills: %s" msgstr "" +#: src/crafting_gui.cpp +#, c-format +msgid "Proficiencies Required: %s" +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "Time to complete: %s" @@ -206102,6 +206846,12 @@ msgid "" "components" msgstr "" +#: src/crafting_gui.cpp +msgid "" +"Cannot be crafted because you lack the required proficiencies." +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "v (%s for more)" @@ -206483,6 +207233,10 @@ msgstr "" msgid "Damage self" msgstr "" +#: src/debug_menu.cpp +msgid "Bleed self" +msgstr "" + #: src/debug_menu.cpp msgid "Set automove route" msgstr "" @@ -207394,6 +208148,10 @@ msgstr "" msgid "Damage self for how much? hp: %s" msgstr "" +#: src/debug_menu.cpp +msgid "Add bleeding duration in minutes, equal to intensity:" +msgstr "" + #: src/debug_menu.cpp msgid "This binary was not compiled with tiles support." msgstr "" @@ -208217,7 +208975,8 @@ msgstr "" msgid "average" msgstr "" -#: src/effect.cpp src/iuse.cpp +#: src/effect.cpp +#: src/iuse.cpp msgid "good" msgstr "" @@ -208237,6 +208996,22 @@ msgstr "" msgid "perfect" msgstr "" +#: src/effect.cpp +msgid "miniscule" +msgstr "" + +#: src/effect.cpp +msgid "small" +msgstr "" + +#: src/effect.cpp +msgid "moderate" +msgstr "" + +#: src/effect.cpp +msgid "excellent" +msgstr "" + #. ~ Default format for scores. %1$s is statistic description; %2$s is value. #: src/event_statistics.cpp #, c-format @@ -212475,11 +213250,11 @@ msgid "Your inventory is empty." msgstr "" #: src/game_inventory.cpp -msgid "ENCUMBRANCE" +msgid "AVG ENCUMBRANCE" msgstr "" #: src/game_inventory.cpp -msgid "COVERAGE" +msgid "AVG COVERAGE" msgstr "" #: src/game_inventory.cpp @@ -215627,6 +216402,11 @@ msgstr "" msgid "The %1$s contains %2$d %3$s." msgstr "" +#: src/iexamine.cpp +#, c-format +msgid "You reload the %s." +msgstr "" + #: src/iexamine.cpp msgid "Do what with the curtains?" msgstr "" @@ -217315,10 +218095,6 @@ msgstr "" msgid "max rot (turns): " msgstr "" -#: src/item.cpp -msgid "last rot: " -msgstr "" - #: src/item.cpp msgid "last temp: " msgstr "" @@ -217582,7 +218358,7 @@ msgid "Recommended strength (burst): " msgstr "" #: src/item.cpp -msgid " moves " +msgid " moves" msgstr "" #: src/item.cpp @@ -217620,10 +218396,6 @@ msgstr "" msgid "" msgstr "" -#: src/item.cpp -msgid " moves" -msgstr "" - #: src/item.cpp msgid "Time to reach aim level: " msgstr "" @@ -217752,127 +218524,127 @@ msgid "" msgstr "" #: src/item.cpp -msgid "Covers: " +msgid "Covers:" msgstr "" #: src/item.cpp -msgid "The head. " +msgid " The head." msgstr "" #: src/item.cpp -msgid "The eyes. " +msgid " The eyes." msgstr "" #: src/item.cpp -msgid "The mouth. " +msgid " The mouth." msgstr "" #: src/item.cpp -msgid "The torso. " +msgid " The torso." msgstr "" #: src/item.cpp -msgid "Either arm. " +msgid " Either arm." msgstr "" #: src/item.cpp -msgid "The arms. " +msgid " The arms." msgstr "" #: src/item.cpp -msgid "The left arm. " +msgid " The left arm." msgstr "" #: src/item.cpp -msgid "The right arm. " +msgid " The right arm." msgstr "" #: src/item.cpp -msgid "Either hand. " +msgid " Either hand." msgstr "" #: src/item.cpp -msgid "The hands. " +msgid " The hands." msgstr "" #: src/item.cpp -msgid "The left hand. " +msgid " The left hand." msgstr "" #: src/item.cpp -msgid "The right hand. " +msgid " The right hand." msgstr "" #: src/item.cpp -msgid "Either leg. " +msgid " Either leg." msgstr "" #: src/item.cpp -msgid "The legs. " +msgid " The legs." msgstr "" #: src/item.cpp -msgid "The left leg. " +msgid " The left leg." msgstr "" #: src/item.cpp -msgid "The right leg. " +msgid " The right leg." msgstr "" #: src/item.cpp -msgid "Either foot. " +msgid " Either foot." msgstr "" #: src/item.cpp -msgid "The feet. " +msgid " The feet." msgstr "" #: src/item.cpp -msgid "The left foot. " +msgid " The left foot." msgstr "" #: src/item.cpp -msgid "The right foot. " +msgid " The right foot." msgstr "" #: src/item.cpp -msgid "Nothing." +msgid " Nothing." msgstr "" #: src/item.cpp -msgid "Layer: " +msgid "Layer:" msgstr "" #: src/item.cpp -msgid "Personal aura. " +msgid " Personal aura." msgstr "" #: src/item.cpp -msgid "Close to skin. " +msgid " Close to skin." msgstr "" #: src/item.cpp -msgid "Strapped. " +msgid " Strapped." msgstr "" #: src/item.cpp -msgid "Outer. " +msgid " Outer." msgstr "" #: src/item.cpp -msgid "Waist. " +msgid " Waist." msgstr "" #: src/item.cpp -msgid "Outer aura. " +msgid " Outer aura." msgstr "" #: src/item.cpp -msgid "Normal. " +msgid " Normal." msgstr "" #: src/item.cpp -msgid "Coverage: " +msgid "Average Coverage: " msgstr "" #: src/item.cpp @@ -217880,35 +218652,40 @@ msgid "Warmth: " msgstr "" #: src/item.cpp -msgid " (fits)" +msgid " (fits)" msgstr "" #: src/item.cpp -msgid " (poor fit)" +msgid " (poor fit)" msgstr "" #: src/item.cpp -msgid " (too big)" +msgid " (too big)" msgstr "" #: src/item.cpp -msgid " (huge!)" +msgid " (huge!)" msgstr "" #: src/item.cpp -msgid " (too small)" +msgid " (too small)" msgstr "" #: src/item.cpp -msgid " (tiny!)" +msgid " (tiny!)" msgstr "" #: src/item.cpp -msgid "Encumbrance: " +msgid "Encumbrance:" +msgstr "" + +#: src/item.cpp +#, c-format +msgid "%s:" msgstr "" #: src/item.cpp -msgid "Encumbrance when full: " +msgid "When Full:" msgstr "" #: src/item.cpp @@ -218291,23 +219068,23 @@ msgid "Power Capacity:" msgstr "" #: src/item.cpp -msgid "Environmental Protection: " +msgid "Environmental Protection:" msgstr "" #: src/item.cpp -msgid "Bash Protection: " +msgid "Bash Protection:" msgstr "" #: src/item.cpp -msgid "Cut Protection: " +msgid "Cut Protection:" msgstr "" #: src/item.cpp -msgid "Ballistic Protection: " +msgid "Ballistic Protection:" msgstr "" #: src/item.cpp -msgid "Stat Bonus: " +msgid "Stat Bonus:" msgstr "" #: src/item.cpp @@ -223378,6 +224155,10 @@ msgstr "" msgid "It itches a little." msgstr "" +#: src/iuse_actor.cpp +msgid "Bleeding has not stopped completely!" +msgstr "" + #: src/iuse_actor.cpp msgid "You cannot cauterize while mounted." msgstr "" @@ -223701,11 +224482,21 @@ msgid "You stop the bleeding." msgstr "" #: src/iuse_actor.cpp -msgid "The wound still bleeds." +msgid "You reduce the bleeding, but it's not stopped yet." +msgstr "" + +#: src/iuse_actor.cpp +msgid "The bleeding is reduced, but not stopped." +msgstr "" + +#: src/iuse_actor.cpp +msgid "" +"Your dressing is too ineffective for a bleeding of this extent, and you fail " +"to stop it." msgstr "" #: src/iuse_actor.cpp -msgid "You fail to stop the bleeding." +msgid "The wound still bleeds." msgstr "" #: src/iuse_actor.cpp @@ -223809,11 +224600,15 @@ msgid "Actual disinfecting quality: " msgstr "" #: src/iuse_actor.cpp -msgid "Chance to heal (percent): " +msgid "Effect on bleeding: " msgstr "" #: src/iuse_actor.cpp -msgid "* Bleeding: " +msgid "Actual effect on bleeding: " +msgstr "" + +#: src/iuse_actor.cpp +msgid "Chance to heal (percent): " msgstr "" #: src/iuse_actor.cpp @@ -223880,7 +224675,7 @@ msgid "It's not a gun." msgstr "" #: src/iuse_actor.cpp -msgid "The barrel is too short." +msgid "The barrel is too small." msgstr "" #: src/iuse_actor.cpp @@ -225375,10 +226170,6 @@ msgstr "" msgid "stamina" msgstr "" -#: src/magic.cpp -msgid "bionic power" -msgstr "" - #: src/magic.cpp msgid "error: energy_type" msgstr "" @@ -227395,7 +228186,7 @@ msgstr "" msgid "You smash %s with all your might but %s remains in their hands!" msgstr "" -#: src/melee.cpp src/npctalk.cpp +#: src/melee.cpp src/talker_npc.cpp #, c-format msgid "%s is hostile!" msgstr "" @@ -228224,6 +229015,36 @@ msgctxt "memorial_female" msgid "Died of a drug overdose." msgstr "" +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died from loss of red blood cells." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died from loss of red blood cells." +msgstr "" + #: src/memorial_logger.cpp msgctxt "memorial_male" msgid "Succumbed to the infection." @@ -232150,10 +232971,6 @@ msgctxt "Paralyze as an action" msgid "paralyze" msgstr "" -#: src/monster.cpp -msgid "cause bleed" -msgstr "" - #: src/monster.cpp msgid "It has a head." msgstr "" @@ -233195,6 +234012,15 @@ msgstr "" msgid "%s (activated)" msgstr "" +#: src/newcharacter.cpp +msgid "Profession proficiencies:" +msgstr "" + +#: src/newcharacter.cpp +msgctxt "Profession has no proficiencies" +msgid "None" +msgstr "" + #: src/newcharacter.cpp msgid "Pets:" msgstr "" @@ -233451,7 +234277,11 @@ msgid "" msgstr "" #: src/newcharacter.cpp -msgid "_______NO NAME ENTERED!_______" +msgid "--- NO NAME ENTERED ---" +msgstr "" + +#: src/newcharacter.cpp +msgid "--- RANDOM NAME ---" msgstr "" #: src/newcharacter.cpp @@ -233533,15 +234363,19 @@ msgid "Enter height in centimeters. Minimum 145, maximum 200" msgstr "" #: src/newcharacter.cpp -msgid "Enter blood type (omit Rh):" +msgid "Select blood type" msgstr "" #: src/newcharacter.cpp -msgid "Invalid blood type." +msgid "Select Rh factor" msgstr "" #: src/newcharacter.cpp -msgid "Enter Rh factor:" +msgid "negative" +msgstr "" + +#: src/newcharacter.cpp +msgid "positive" msgstr "" #: src/newcharacter.cpp @@ -233922,6 +234756,25 @@ msgstr "" msgid " is no longer afraid." msgstr "" +#: src/npc.cpp +#, c-format +msgid "I'm holing up here for safety. Long term, %s" +msgstr "" + +#: src/npc.cpp +msgid "I run the shop here." +msgstr "" + +#: src/npc.cpp +#, c-format +msgid "Currently, I'm guarding this location. Overall, %s" +msgstr "" + +#: src/npc.cpp +#, c-format +msgid "Right now, I'm . In general, %s" +msgstr "" + #: src/npcmove.cpp msgid "" msgstr "" @@ -234072,6 +234925,15 @@ msgstr "" msgid "My %s is bleeding!" msgstr "" +#: src/npcmove.cpp +#, c-format +msgid "My %s is bleeding badly!" +msgstr "" + +#: src/npcmove.cpp +msgid "I've lost lot of blood." +msgstr "" + #: src/npcmove.cpp #, c-format msgid "%1$s reloads their %2$s." @@ -234318,11 +235180,6 @@ msgstr "" msgid "%s yelling %s" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%s is fleeing from you!" -msgstr "" - #: src/npctalk.cpp #, c-format msgid "%s talked to you." @@ -234379,37 +235236,6 @@ msgstr "" msgid "Here's what I can teach youā€¦" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%d.%d miles." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "%d foot." -msgid_plural "%d feet." -msgstr[0] "" -msgstr[1] "" - -#: src/npctalk.cpp -#, c-format -msgid "I'm holing up here for safety. Long term, %s" -msgstr "" - -#: src/npctalk.cpp -msgid "I run the shop here." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "Currently, I'm guarding this location. Overall, %s" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "Right now, I'm . In general, %s" -msgstr "" - #: src/npctalk.cpp msgid "&You yell, but can't hear yourself." msgstr "" @@ -234418,66 +235244,6 @@ msgstr "" msgid "&You yell." msgstr "" -#: src/npctalk.cpp -msgid "&You can't make anything out." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "Str %d - %d" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid " Dex %d - %d" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid " Int %d - %d" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid " Per %d - %d" -msgstr "" - -#: src/npctalk.cpp -msgid "Dead tired" -msgstr "" - -#: src/npctalk.cpp -msgid "Not tired" -msgstr "" - -#: src/npctalk.cpp -msgid ". Will need sleep in " -msgstr "" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need water in " -msgstr "" - -#: src/npctalk.cpp -msgid "" -"\n" -"Thirsty" -msgstr "" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need food in " -msgstr "" - -#: src/npctalk.cpp -msgid "" -"\n" -"Hungry" -msgstr "" - #: src/npctalk.cpp msgid "YES, MASTER!" msgstr "" @@ -234491,33 +235257,6 @@ msgstr "" msgid "Yes, let's resume training %s" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%s: 1 hour lesson (cost %s)" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "%s: teaching spell knowledge (cost %s)" -msgstr "" - -#. ~Martial art style (cost in dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s ( cost $%d )" -msgstr "" - -#. ~Skill name: current level (exercise) -> next level (exercise) (cost in dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%)" -msgstr "" - #: src/npctalk.cpp msgid "Okay, thanks." msgstr "" @@ -234530,10 +235269,6 @@ msgstr "" msgid "OBEY ME!" msgstr "" -#: src/npctalk.cpp src/player.cpp -msgid "fists" -msgstr "" - #: src/npctalk.cpp msgid "BADAMMO" msgstr "" @@ -234603,7 +235338,7 @@ msgctxt "you say something" msgid "You: %s" msgstr "" -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp msgid "You can't afford it!" msgstr "" @@ -234614,7 +235349,7 @@ msgid "%1$s gives you a %2$s." msgstr "" #. ~ %1%s is the NPC name, %2$d is a number of items, %3$s are items -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp #, c-format msgid "%1$s gives you %2$d %3$s." msgstr "" @@ -234643,97 +235378,11 @@ msgstr "" msgid "%1$s doesn't have a %2$s!" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%1$s gives you %2$s." -msgstr "" - #: src/npctalk.cpp #, c-format msgid "You learn how to craft %s." msgstr "" -#: src/npctalk.cpp -msgid "I don't trust you enough to eat THISā€¦" -msgstr "" - -#: src/npctalk.cpp -msgid "It doesn't look like a good idea to consume thisā€¦" -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, that hit the spot." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "I need a %s to consume that!" -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I feel better already." -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I used it." -msgstr "" - -#: src/npctalk.cpp -msgid "Offer what?" -msgstr "" - -#: src/npctalk.cpp -msgid "You have no items to offer." -msgstr "" - -#: src/npctalk.cpp -msgid "Changed your mind?" -msgstr "" - -#: src/npctalk.cpp -msgid "How?" -msgstr "" - -#: src/npctalk.cpp -msgid "Are you insane!?" -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I'll wield that now." -msgstr "" - -#: src/npctalk.cpp -msgid " Should I take something off?" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "" -"My current weapon is better than this.\n" -"(new weapon value: %.1f vs %.1f)." -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I'll carry that now." -msgstr "" - -#: src/npctalk.cpp -msgid "I have no space to store it." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "I can only store %s %s more." -msgstr "" - -#: src/npctalk.cpp -msgid "ā€¦or to store anything else for that matter." -msgstr "" - -#: src/npctalk.cpp -msgid "It is too heavy for me to carry." -msgstr "" - #: src/npctalk_funcs.cpp msgid "Reward" msgstr "" @@ -238256,6 +238905,38 @@ msgstr "" msgid " attempts to put out the fire on them!" msgstr "" +#: src/player.cpp +msgid "" +"Your broken limb significantly hampers your efforts to puting pressure on " +"the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s broken limb significantly hampers efforts of putting pressure on " +"the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"Your hands are too encumbred to effectivly put pressure on the bleeding " +"wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s hands are too encumbred to effectivly put pressure on the " +"bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "You attempt to put pressure on the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid " attempts to put pressure on the bleeding wound!" +msgstr "" + #: src/player.cpp #, c-format msgid "Your ground sonar detected a %1$s to the %2$s!" @@ -238527,33 +239208,6 @@ msgstr "" msgid "You don't have any %s to reload your %s!" msgstr "" -#: src/player.cpp -msgid "Can't wield spilt liquids." -msgstr "" - -#: src/player.cpp -msgid "You need at least one arm to even consider wielding something." -msgstr "" - -#: src/player.cpp -#, c-format -msgid "The %s is preventing you from wielding the %s." -msgstr "" - -#: src/player.cpp -msgid "Something you are wearing hinders the use of both hands." -msgstr "" - -#: src/player.cpp -#, c-format -msgid "The %s can't be wielded with only one arm." -msgstr "" - -#: src/player.cpp -#, c-format -msgid "You are too weak to wield %s with only one arm." -msgstr "" - #: src/player.cpp msgid "Keep hands free (off)" msgstr "" @@ -238733,15 +239387,6 @@ msgstr "" msgid "Your %s isn't loaded." msgstr "" -#: src/player.cpp -#, c-format -msgid "You recover %i unused plutonium." -msgstr "" - -#: src/player.cpp -msgid "You can't remove partially depleted plutonium!" -msgstr "" - #. ~ %1$s - gunmod, %2$s - gun. #: src/player.cpp #, c-format @@ -238876,25 +239521,6 @@ msgstr "" msgid "Your soporific inducer starts back up." msgstr "" -#: src/player.cpp -#, c-format -msgid "Your skill in %s has increased to %d!" -msgstr "" - -#: src/player.cpp -#, c-format -msgid "You feel that %s tasks of this level are becoming trivial." -msgstr "" - -#: src/player.cpp -#, c-format -msgid "This task is too simple to train your %s beyond %d." -msgstr "" - -#: src/player.cpp -msgid " (empty)" -msgstr "" - #: src/player.cpp msgid "Wield what?" msgstr "" @@ -238950,6 +239576,10 @@ msgstr "" msgid "SPEED" msgstr "" +#: src/player_display.cpp +msgid "PROFICIENCIES" +msgstr "" + #: src/player_display.cpp #, c-format msgid "Swimming movement point cost: %+d\n" @@ -239777,6 +240407,149 @@ msgid "" "nebulae and you are no more." msgstr "" +#: src/player_hardcoded_effects.cpp +msgid "You bleed to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " bleeds to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your heart can't keep up the pace and fails!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks pale and you feel anxious and thirsty. Blood loss?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"Your pale skin is sweating, your heart beats fast and you feel restless. " +"Maybe you lost too much blood?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You're unsettlingly white, but your fingetips are bluish. You are agitated " +"and your heart is racing. Your blood loss must be serious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You are pale as a ghost, dripping wet from the sweat, and sluggish despite " +"your heart racing like a train. You are on a brink of colapse from effects " +"of a bood loss." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and lightheaded." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel tired and you breathe heavily." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are anxcious and cannot collect your thoughts." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are sweating profusely, but you feel cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You huff and puff. Your breath is rapid and shallow." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You drop to the ground, fighting to keep yourself conscious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your mind slips away." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You cannot breathe and your body gives out!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " gasps for air and dies!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your hands feel unusually cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your feet feel unusualy cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks very pale." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel weak. Where has your strength gone?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel feeble. A gust of wind could make you stumble." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "There is an overwhelming aura of tiredness inside of you." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Rest is what you want. Rest is what you need." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and can't coordinate movement of your feet." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your muscles are quivering." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You crave for ice. Dirt under your feet looks tasty too." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your whole mouth is sore, and your tongue is swollen." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel lightheaded. And a migrane follows." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your legs are restless. Urge to move them is so strong." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel like you'd sleep on a rock." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You gasp for air!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Can't breathe. Must rest." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You can't take it any more. Rest first, everything else later." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You must sit down for a moment. Just a moment." +msgstr "" + #. ~ %s is bodypart name. #: src/player_hardcoded_effects.cpp #, c-format @@ -240383,6 +241156,11 @@ msgstr "" msgid "Turrets in range: %d/%d" msgstr "" +#: src/recipe.cpp +#, c-format +msgid "Proficiencies Used: %s" +msgstr "" + #: src/recipe.cpp msgid "none" msgstr "" @@ -241138,6 +241916,14 @@ msgstr "" msgid "You fall over!" msgstr "" +#: src/suffer.cpp +msgid "Your tourniquet hurts you." +msgstr "" + +#: src/suffer.cpp +msgid " is hurting from the tourniquet." +msgstr "" + #: src/suffer.cpp #, c-format msgid "Your radiation badge changes from %1$s to %2$s!" @@ -241157,6 +241943,200 @@ msgstr "" msgid "You feel the water burning your skin." msgstr "" +#: src/talker_avatar.cpp +#, c-format +msgid "%s can't sell you any %s" +msgstr "" + +#: src/talker_avatar.cpp +#, c-format +msgid "%1$s gives you %2$s." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%d.%d miles." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%d foot." +msgid_plural "%d feet." +msgstr[0] "" +msgstr[1] "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s is fleeing from you!" +msgstr "" + +#. ~Skill name: current level (exercise) -> next level (exercise) (cost in dollars) +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s ( cost $%d )" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: 1 hour lesson (cost %s)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: teaching spell knowledge (cost %s)" +msgstr "" + +#: src/talker_npc.cpp +msgid "I don't trust you enough to eat THISā€¦" +msgstr "" + +#: src/talker_npc.cpp +msgid "It doesn't look like a good idea to consume thisā€¦" +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, that hit the spot." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "I need a %s to consume that!" +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I feel better already." +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I used it." +msgstr "" + +#: src/talker_npc.cpp +msgid "Offer what?" +msgstr "" + +#: src/talker_npc.cpp +msgid "You have no items to offer." +msgstr "" + +#: src/talker_npc.cpp +msgid "Changed your mind?" +msgstr "" + +#: src/talker_npc.cpp +msgid "How?" +msgstr "" + +#: src/talker_npc.cpp +msgid "Are you insane!?" +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I'll wield that now." +msgstr "" + +#: src/talker_npc.cpp +msgid " Should I take something off?" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "" +"My current weapon is better than this.\n" +"(new weapon value: %.1f vs %.1f)." +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I'll carry that now." +msgstr "" + +#: src/talker_npc.cpp +msgid "I have no space to store it." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "I can only store %s %s more." +msgstr "" + +#: src/talker_npc.cpp +msgid "ā€¦or to store anything else for that matter." +msgstr "" + +#: src/talker_npc.cpp +msgid "It is too heavy for me to carry." +msgstr "" + +#: src/talker_npc.cpp +msgid "&You can't make anything out." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "Str %d - %d" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid " Dex %d - %d" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid " Int %d - %d" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid " Per %d - %d" +msgstr "" + +#: src/talker_npc.cpp +msgid "Dead tired" +msgstr "" + +#: src/talker_npc.cpp +msgid "Not tired" +msgstr "" + +#: src/talker_npc.cpp +msgid ". Will need sleep in " +msgstr "" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need water in " +msgstr "" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Thirsty" +msgstr "" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need food in " +msgstr "" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Hungry" +msgstr "" + #: src/teleport.cpp msgid "You feel a strange, inwards force." msgstr "" @@ -243982,49 +244962,17 @@ msgstr "" msgid "You purify the contents of the %1$s's %2$s" msgstr "" -#: src/weather.cpp -msgid "You hear a distant rumble of thunder." -msgstr "" - -#: src/weather.cpp -msgid "You hear a rumble of thunder from above." -msgstr "" - -#: src/weather.cpp -msgid "A flash of lightning illuminates your surroundings!" -msgstr "" - #: src/weather.cpp #, c-format -msgid "Your %s protects you from the acidic drizzle." -msgstr "" - -#: src/weather.cpp -msgid "Your clothing protects you from the acidic drizzle." +msgid "Your %s protects you from the weather." msgstr "" #: src/weather.cpp -msgid "Your power armor protects you from the acidic drizzle." +msgid "Your clothing protects you from the weather." msgstr "" #: src/weather.cpp -msgid "The acid rain stings, but is mostly harmless for nowā€¦" -msgstr "" - -#: src/weather.cpp -msgid "Your umbrella protects you from the acid rain." -msgstr "" - -#: src/weather.cpp -msgid "Your clothing protects you from the acid rain." -msgstr "" - -#: src/weather.cpp -msgid "Your power armor protects you from the acid rain." -msgstr "" - -#: src/weather.cpp -msgid "The acid rain burns!" +msgid "Your power armor protects you from the weather." msgstr "" #: src/weather.cpp @@ -244388,6 +245336,19 @@ msgstr "" msgid "last world info" msgstr "" +#: src/worldfactory.cpp +msgid "MISSING MODS" +msgstr "" + +#: src/worldfactory.cpp +msgid "OBSOLETE MODS" +msgstr "" + +#: src/worldfactory.cpp +#, c-format +msgid " [%s]" +msgstr "" + #: src/worldfactory.cpp msgid " ACTIVE WORLD MODS " msgstr "" diff --git a/lang/po/de.po b/lang/po/de.po index fa42264846d0d..b4853484d69bf 100644 --- a/lang/po/de.po +++ b/lang/po/de.po @@ -5,8 +5,8 @@ # Nico Brandt , 2018 # Enrico Grunitz, 2018 # OzoneH3 , 2018 -# Nipaporn P. , 2018 # Mark Bies, 2018 +# Nipaporn P. , 2018 # - - , 2018 # Tarnath , 2018 # Phil Mait , 2018 @@ -23,16 +23,16 @@ # Pupsi , 2020 # Matyas Taller , 2020 # Vlasov Vitaly , 2020 -# Brett Dong , 2020 # Wuzzy , 2020 +# Brett Dong , 2020 # msgid "" msgstr "" "Project-Id-Version: cataclysm-dda 0.E\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-07-08 10:07+0800\n" +"POT-Creation-Date: 2020-07-16 21:36+0800\n" "PO-Revision-Date: 2018-04-26 14:47+0000\n" -"Last-Translator: Wuzzy , 2020\n" +"Last-Translator: Brett Dong , 2020\n" "Language-Team: German (https://www.transifex.com/cataclysm-dda-translators/teams/2217/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -8227,6 +8227,58 @@ msgstr "" "Ein Werkzeug, das hilft, Knochen zu richten und sie gerade zu halten. Es " "wurde speziell fĆ¼r groƟe Ɯberlebende entwickelt." +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm)" +msgid_plural "tourniquets (arm)" +msgstr[0] "" +msgstr[1] "" + +#. ~ Use action menu_text for {'str': 'tourniquet (arm)', 'str_pl': +#. 'tourniquets (arm)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (arm XL)', 'str_pl': +#. 'tourniquets (arm XL)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (leg)', 'str_pl': +#. 'tourniquets (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "Adjust" +msgstr "" + +#. ~ Use action msg for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'}. +#. ~ Use action msg for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'}. +#. ~ Use action msg for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "You adjust the tourniquet." +msgstr "" + +#. ~ Description for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'} +#. ~ Description for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'} +#. ~ Description for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'} +#: lang/json/ARMOR_from_json.py +msgid "" +"First aid device used to apply pressure to a limb or extremity in order to " +"limit blood flow. Should be employed only to manage heavy bleedings, " +"because prolonged use will harm the limb. It can be adjusted in size to fit" +" different limbs." +msgstr "" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm XL)" +msgid_plural "tourniquets (arm XL)" +msgstr[0] "" +msgstr[1] "" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (leg)" +msgid_plural "tourniquets (leg)" +msgstr[0] "" +msgstr[1] "" + #: lang/json/ARMOR_from_json.py msgid "blindfold" msgid_plural "blindfolds" @@ -41982,6 +42034,20 @@ msgstr "" "HyperaktivitƤtssyndroms verschrieben. Es unterdrĆ¼ckt den Appetit und ist " "ziemlich sĆ¼chtig machend." +#: lang/json/COMESTIBLE_from_json.py +msgid "adhesive bandage" +msgid_plural "adhesive bandages" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'adhesive bandage'} +#: lang/json/COMESTIBLE_from_json.py +msgid "" +"A set of small medical dressings, each made of a piece of sterile cloth and " +"a sticky tape, used for small injuries not serious enough to require a full-" +"size bandage." +msgstr "" + #: lang/json/COMESTIBLE_from_json.py msgid "syringe of adrenaline" msgid_plural "syringes of adrenaline" @@ -42075,10 +42141,10 @@ msgstr[1] "Bandagen" #. ~ Description for {'str': 'bandage'} #: lang/json/COMESTIBLE_from_json.py -msgid "Simple cloth bandages. Used for healing small amounts of damage." +msgid "" +"Simple cloth bandages. Used for stopping bloodloss and protecting wounds " +"from external factors." msgstr "" -"Einfache Stoffbandage. Kann zur Heilung kleiner Verletzungen verwendet " -"werden." #: lang/json/COMESTIBLE_from_json.py msgid "makeshift bandage" @@ -52631,8 +52697,8 @@ msgstr[1] "" #. planks'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten construction planks securely lashed together with a rope. Disassemble " -"to unpack." +"Ten construction planks securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" #: lang/json/GENERIC_from_json.py @@ -52645,8 +52711,22 @@ msgstr[1] "" #. stout branches'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten stout branches securely lashed together with a rope. Disassemble to " -"untie them." +"Ten stout branches securely tied together for easier transport. Disassemble" +" to untie them." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "bundle of long stout branches" +msgid_plural "bundles of long stout branches" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'bundle of long stout branches', 'str_pl': +#. 'bundles of long stout branches'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Five long stout branches securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" #: lang/json/GENERIC_from_json.py @@ -54862,6 +54942,12 @@ msgid "" "gutted for parts." msgstr "" +#: lang/json/GENERIC_from_json.py +msgid "broken laser turret" +msgid_plural "broken laser turrets" +msgstr[0] "kaputter Laser-GeschĆ¼tzturm" +msgstr[1] "kaputte Laser-GeschĆ¼tztĆ¼rme" + #: lang/json/GENERIC_from_json.py msgid "fire brick" msgid_plural "fire bricks" @@ -55499,12 +55585,6 @@ msgstr "" " ziemlich zerbrechlich aus; es sieht so aus, als kƶnnte sie auch keine " "Panzerungsschicht vertragen." -#: lang/json/GENERIC_from_json.py -msgid "broken laser turret" -msgid_plural "broken laser turrets" -msgstr[0] "kaputter Laser-GeschĆ¼tzturm" -msgstr[1] "kaputte Laser-GeschĆ¼tztĆ¼rme" - #: lang/json/GENERIC_from_json.py msgid "TX-5LR Laser Cannon" msgid_plural "TX-5LR Laser Cannons" @@ -56417,11 +56497,9 @@ msgstr[1] "unreife Sauerteigstarter" #. ~ Use action msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py msgid "" -"After feeding it and caring for it for weeks, your sourdough starter is " +"After feeding it and caring for it for a week, your sourdough starter is " "finally ready for the big leagues." msgstr "" -"Nach wochenlanger sorgsamer Pflege ist dein Sauerteigstarter endlich bereit " -"fĆ¼r die Oberliga." #. ~ Use action not_ready_msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py @@ -56462,11 +56540,8 @@ msgstr "Dieser Starter ist noch nicht fertig." #: lang/json/GENERIC_from_json.py msgid "" "This jar contains a floury paste with sourdough starter mixed in. It needs " -"a few hours to recover its strength before it can be used again." +"a day to recover its strength before it can be used again." msgstr "" -"Dieses GefƤƟ enthƤlt eine mehlige Paste, in die Sauerteigstarter eingemischt" -" wurde. Es wird einige Stunden dauern, bis seine StƤrke wieder hergestellt " -"ist und es wieder verwendet werden kann." #: lang/json/GENERIC_from_json.py msgid "sourdough starter" @@ -56519,13 +56594,24 @@ msgstr[1] "VerbandkƤsten" #. ~ Description for {'str': 'first aid kit'} #: lang/json/GENERIC_from_json.py msgid "" -"A full medical kit, with bandages, local anesthetics, and rapid healing " -"agents. Used for healing large amounts of damage. Disassemble to get its " -"content." +"A typical universal first aid kit, one you'd see in a car or in a household." +" It contains a variety of common medical items stored in case of accidents " +"and injuries. Disassemble to get its content." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "IFAK" +msgid_plural "IFAKs" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'IFAK'} +#: lang/json/GENERIC_from_json.py +msgid "" +"An IFAK, or individual first aid kit, is a specialized set of wound " +"dressings and accessories, and being of military origin focuses on combat " +"trauma and preventing blood loss. Disassemble to get its content." msgstr "" -"Ein vollstƤndige medizinische Ausstattung mit Bandagen, LokalanƤsthetika und" -" Schnellheilungswirkstoffen. Benutzt, um schwere Verletzungen zu heilen. " -"Demontiere dies, um den Inhalt zu erhalten." #: lang/json/GENERIC_from_json.py msgid "MRE" @@ -61541,11 +61627,11 @@ msgstr "" #: lang/json/GENERIC_from_json.py msgid "inscribed metal plates" -msgid_plural "inscribed metal platess" +msgid_plural "inscribed metal plates" msgstr[0] "" msgstr[1] "" -#. ~ Description for {'str': 'inscribed metal plates'} +#. ~ Description for {'str_sp': 'inscribed metal plates'} #: lang/json/GENERIC_from_json.py msgid "" "This device looks electronic, but is unfamiliar. It is a series of tightly " @@ -61582,6 +61668,36 @@ msgid "" "work." msgstr "" +#: lang/json/GENERIC_from_json.py +msgid "engraved parabolic dish" +msgid_plural "engraved parabolic dishes" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'engraved parabolic dish', 'str_pl': 'engraved +#. parabolic dishes'} +#: lang/json/GENERIC_from_json.py +msgid "" +"This hefty parabolic dish is engraved with an unrecognizable pattern of " +"symbols that might, at a guess, be some sort of circuitry pattern - or maybe" +" a religious incantation." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "oblong device" +msgid_plural "oblong devices" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'oblong device'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Perfectly smooth, cool to the touch, and a dull blue-grey colour, this looks" +" almost like a perfect riverstone at first glance. Its artificial nature is" +" betrayed on closer inspection by a network of intricate patterns visible as" +" a slight difference in the reflection of light off its surface." +msgstr "" + #: lang/json/GENERIC_from_json.py msgid "sheet of glass" msgid_plural "sheets of glass" @@ -72477,6 +72593,23 @@ msgid "" " before running out of power." msgstr "" +#: lang/json/MONSTER_from_json.py +msgid "feral human" +msgid_plural "feral humans" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'feral human'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pupils dilated and what remains to be seen of the iris and sclera are " +"bloodshot. It still breathes but the zombies treat it like one of them." +msgstr "" + +#: lang/json/MONSTER_from_json.py +msgid "They throw a loose brick at you!" +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "alpha razorclaw" msgid_plural "alpha razorclaws" @@ -76561,6 +76694,20 @@ msgstr "" "fƤrbte sich blassgelb vom Leben unter der Erde. Sie schwƤrmt unter dem Boden" " aus und ist nach ihrer Gewohnheit, AbwƤsserkanƤle zu verseuchen, benannt." +#: lang/json/MONSTER_from_json.py +msgid "prototype laser turret" +msgid_plural "prototype laser turrets" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'prototype laser turret'} +#: lang/json/MONSTER_from_json.py +msgid "" +"This appears to be a very experimental automated tower. Plating-less and " +"seemingly half-built, it's little more than an oversized laser emitter and a" +" camera, both welded to a swiveling platform." +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "blob" msgid_plural "blobs" @@ -77409,6 +77556,22 @@ msgstr "" "Ein ansonsten normalaussehender Puma, auƟer, dass seine HinterlƤufe " "angeschwollen und seine Augen mit einem schwarzen Glibber unterlaufen sind." +#: lang/json/MONSTER_from_json.py +msgid "zombie horse" +msgid_plural "zombie horses" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'zombie horse'} +#: lang/json/MONSTER_from_json.py +msgid "" +"From the looks of this zombie horse's ghastly features, with its protruding " +"ribs, whitish skull, and empty eyes, the exposed part of the internal organs" +" shows a seemingly lifeless color, and the black body fluid drips slowly. " +"The new strength makes the horse no longer dependent on its muscles, but it " +"can still pursue the enemy quickly." +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "Tiger wight" msgid_plural "Tiger wights" @@ -77422,6 +77585,35 @@ msgid "" "eyes wide open and shining black." msgstr "" +#: lang/json/MONSTER_from_json.py +msgid "zombie cow" +msgid_plural "zombie cows" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'zombie cow'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Once a placid cow, this leathery horror stumbles and shudders, its pulsing " +"black eyes scanning for prey beneath wicked horns. It is big and heavy and " +"murderous." +msgstr "" + +#: lang/json/MONSTER_from_json.py +msgid "woodland wight" +msgid_plural "woodland wights" +msgstr[0] "" +msgstr[1] "" + +#. ~ Description for {'str': 'woodland wight'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pale, stumbling white-tailed deer with blackened eyes and drooling slime " +"down its neck. Its legs twist and bend in strange, haphazard directions, " +"but with unnatural strength and speed. Preys on coyotes, wolves, and giant " +"spider mutants." +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "mass of zombie spiders" msgid_plural "mass of zombie spiderss" @@ -78320,12 +78512,12 @@ msgstr "" "angeschwollen ist, mit Armen, so breit wie eine MĆ¼lltonne." #: lang/json/MONSTER_from_json.py -msgid "feral hunter" -msgid_plural "feral hunters" -msgstr[0] "verwilderter JƤger" -msgstr[1] "verwilderte JƤger" +msgid "zombie hunter" +msgid_plural "zombie hunters" +msgstr[0] "" +msgstr[1] "" -#. ~ Description for {'str': 'feral hunter'} +#. ~ Description for {'str': 'zombie hunter'} #: lang/json/MONSTER_from_json.py msgid "" "This once-human body is barely recognizable, scrambling about on all fours, " @@ -78424,12 +78616,12 @@ msgid "" msgstr "" #: lang/json/MONSTER_from_json.py -msgid "feral runner" -msgid_plural "feral runners" -msgstr[0] "verwilderter LƤufer" -msgstr[1] "verwilderte LƤufer" +msgid "zombie runner" +msgid_plural "zombie runners" +msgstr[0] "" +msgstr[1] "" -#. ~ Description for {'str': 'feral runner'} +#. ~ Description for {'str': 'zombie runner'} #: lang/json/MONSTER_from_json.py msgid "" "This recently-risen body moves quickly, darting its head back and forth and " @@ -78439,12 +78631,12 @@ msgstr "" "hin- und her schaukelnd und an seinen HƤnden kauend." #: lang/json/MONSTER_from_json.py -msgid "feral predator" -msgid_plural "feral predators" -msgstr[0] "verwilderter RƤuber" -msgstr[1] "verwilderte RƤuber" +msgid "zombie predator" +msgid_plural "zombie predators" +msgstr[0] "" +msgstr[1] "" -#. ~ Description for {'str': 'feral predator'} +#. ~ Description for {'str': 'zombie predator'} #: lang/json/MONSTER_from_json.py msgid "" "With its joints in odd places and angles, this humanoid creature prowls " @@ -82804,7 +82996,7 @@ msgstr "Schmerz" msgid "Increases pain" msgstr "" -#: lang/json/SPELL_from_json.py src/character.cpp src/npctalk.cpp +#: lang/json/SPELL_from_json.py src/character.cpp src/talker_npc.cpp msgid "Tired" msgstr "MĆ¼de" @@ -83884,7 +84076,7 @@ msgstr "" msgid "Lightning Blast" msgstr "" -#: lang/json/SPELL_from_json.py src/weather_data.cpp +#: lang/json/SPELL_from_json.py lang/json/weather_type_from_json.py msgid "Lightning Storm" msgstr "Gewittersturm" @@ -84838,14 +85030,10 @@ msgstr[1] "RM13-KampfrĆ¼stungen" #. ~ Description for {'str': 'RM13 combat armor'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. Use it to turn it on." msgstr "" -"Dieser intern von bis zu zehn Plutoniumzellen angetriebene Ganzkƶrperanzug " -"aus schnittiger schwarzer MilitƤrpanzerung stellt den Hƶhepunkt von Rivtechs" -" biegeschlaffer Strompanzerungstechnlogie dar. Benutze sie, um sie " -"einzuschalten." #: lang/json/TOOL_ARMOR_from_json.py msgid "RM13 combat armor (on)" @@ -84857,15 +85045,11 @@ msgstr[1] "RM13-KampfrĆ¼stungen (an)" #. armors (on)'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. It is turned on, and continually draining " "power. Use it to turn it off." msgstr "" -"Dieser intern von bis zu zehn Plutoniumzellen angetriebene Ganzkƶrperanzug " -"aus schnittiger schwarzer MilitƤrpanzerung stellt den Hƶhepunkt von Rivtechs" -" biegeschlaffer Strompanzerungstechnlogie dar. Sie ist eingeschaltet und " -"verbraucht bestƤndig Energie. Benutze sie, um sie auszuschalten." #: lang/json/TOOL_ARMOR_from_json.py msgid "5-point anchor" @@ -86171,12 +86355,8 @@ msgstr[1] "SolarrucksƤcke (zusammengeklappt)" msgid "" "Personal portable charging system consisting of an array of solar panels " "neatly folded in a form of a large backpack. It can be worn as one, and has" -" an integrated cable to plug it into a cable charger system." +" an integrated cable to plug it into a cable charger system CBM." msgstr "" -"Ein persƶnliches tragbares Ladesystem, das aus einem Feld aus Solarmodulen " -"besteht, die schƶn in einer Form eines groƟen Rucksacks zusammengeklappt " -"sind. Es kann wie ein Rucksack getragen werden und hat ein eingebautes " -"Kabel, um es in ein Kabelladesystem einzustƶpseln." #: lang/json/TOOL_ARMOR_from_json.py msgid "solar backpack (unfolded)" @@ -86189,10 +86369,8 @@ msgstr[1] "SolarrucksƤcke (ausgeklappt)" #: lang/json/TOOL_ARMOR_from_json.py msgid "" "Unfolded array of portable solar panels ready to push some power into an " -"active cable charger system." +"active cable charger system CBM." msgstr "" -"Ein ausgeklapptes Feld aus tragbaren Solarmodulen, bereit, etwas Strom in " -"ein aktives Kabelladesystem zu befƶrdern." #: lang/json/TOOL_ARMOR_from_json.py msgid "riot helmet" @@ -91517,14 +91695,9 @@ msgstr "" msgid "" "This is an advanced version of the unified power supply, or UPS. This " "device has been significantly redesigned to provide better efficiency as " -"well as to consume plutonium fuel cells rather than batteries. Sadly, its " -"plutonium reactor can't be charged in UPS charging station." +"well as to consume plutonium fuel batteries rather than regular batteries. " +"Sadly, its plutonium reactor can't be charged in UPS charging station." msgstr "" -"Dies ist eine fortgeschrittene Version der Einheitsstromzufuhr, oder kurz " -"Ā»Esz.Ā«. Sie wurde signifikant umgestaltet, um einen hƶheren Wirkungsgrad zu " -"erzielen und statt Batterien Plutonium-Brennstoffzellen zu verbrauchen. Sie " -"ist momentan angeschaltet. Leider kann ihr Plutoniumreaktor nicht in der " -"Esz.-Ladestation aufgeladen werden." #. ~ Description for {'str': 'camera'} #: lang/json/TOOL_from_json.py @@ -92489,10 +92662,11 @@ msgstr "Du ziehst den Stift der EMP-Granate." #: lang/json/TOOL_from_json.py msgid "" "This is a grenade that generates an electromagnetic pulse with a low-" -"inductance capacitor bank discharged into a single-loop antenna. Use this " -"item to pull the pin and light the fuse, turning it into an active EMP " -"grenade. You will then have three turns before it detonates, creating an " -"EMP field that damages robots and drains bionic energy." +"inductance capacitor bank discharged into a single-loop antenna. It also " +"produces a mild electric shock cloud. Use this item to pull the pin and " +"light the fuse, turning it into an active EMP grenade. You will then have " +"three turns before it detonates, creating an EMP field that damages robots " +"and drains bionic energy." msgstr "" #: lang/json/TOOL_from_json.py @@ -92505,12 +92679,9 @@ msgstr[1] "aktive EMP-Granaten" #: lang/json/TOOL_from_json.py msgid "" "This EMP grenade is active, and will shortly detonate, creating a large EMP " -"field that damages robots and drains bionic energy. You may not want to be " -"holding it much longer." +"field that damages robots and drains bionic energy as well as a mild " +"electric shock cloud. You may not want to be holding it much longer." msgstr "" -"Diese EMP-Granate ist aktiv und wird gleich detonieren, was ein EMP-Feld, " -"das Roboter beschƤdigt und den Strom von Bioniken entlƤdt, erzeugt. Du " -"willst sie nicht mehr lange behalten." #: lang/json/TOOL_from_json.py msgid "incendiary grenade" @@ -97287,14 +97458,10 @@ msgstr "Du stellst die Flintenfalle." #. ~ Description for {'str': 'shotgun trap'} #: lang/json/TOOL_from_json.py msgid "" -"This is a simple tripwire is attached to the trigger of a loaded double-" -"barreled shotgun. When pulled, the shotgun fires. Two shells are loaded; " +"This is a simple tripwire is attached to the trigger of a loaded double " +"slamfire shotgun. When pulled, the shotgun fires. Two shells are loaded; " "the first time the trigger is pulled, one or both shells may be discharged." msgstr "" -"Dies ist ein einfacher Stolperdraht, der am Abzug einer geladenen abgesƤgten" -" doppellƤufigen Flinte ist. Sobald er gedrĆ¼ckt wird, feuert die Flinte. Zwei" -" Patronen sind geladen; das erste mal, in dem der Abzug betƤtigt wird, " -"werden eine oder beide Patronen abgefeuert." #: lang/json/TOOL_from_json.py msgid "tripwire trap" @@ -104818,6 +104985,26 @@ msgstr "Die Schrott-Barriere mit SchweiƟpunkten verstƤrken" msgid "Build Junk Metal Floor" msgstr "Schrott-FuƟboden bauen" +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Bolts" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Welder" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bench" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Table" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Lay down decorative ground cable" +msgstr "" + #: lang/json/construction_from_json.py msgid "Build Pillow Fort" msgstr "Kissenburg bauen" @@ -107434,6 +107621,15 @@ msgstr "" msgid "Your muscles won't cooperate!" msgstr "" +#: lang/json/effects_from_json.py +msgid "Minor Bleeding" +msgstr "" + +#. ~ Description of effect 'Minor Bleeding'. +#: lang/json/effects_from_json.py +msgid "Tis but a scratch." +msgstr "" + #: lang/json/effects_from_json.py msgid "Bleeding" msgstr "Blutung" @@ -107461,7 +107657,25 @@ msgstr "Heftige Blutung" msgid "You are rapidly losing blood." msgstr "Du hast rapiden Blutverlust." -#. ~ Apply message for effect(s) 'Bleeding, Bad Bleeding, Heavy Bleeding'. +#: lang/json/effects_from_json.py +msgid "Heavy Arterial Bleeding" +msgstr "" + +#. ~ Description of effect 'Heavy Arterial Bleeding'. +#: lang/json/effects_from_json.py +msgid "Blood is gushing from you like a fountain." +msgstr "" + +#. ~ Apply message for effect(s) 'Minor Bleeding, Minor Bleeding, Minor +#. Bleeding, Minor Bleeding, Minor Bleeding, Bleeding, Bleeding, Bleeding, +#. Bleeding, Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, +#. Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad +#. Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, +#. Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy +#. Bleeding, Heavy Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding'. #: lang/json/effects_from_json.py msgid "You're bleeding!" msgstr "Du blutest!" @@ -108238,10 +108452,64 @@ msgstr "Dein Kalziummangel ist fast beseitigt." msgid "Your bones become stronger as your calcium deficiency improves." msgstr "Deine Knochen werden stƤrker, da sich dein Kalziummangel verbessert." +#: lang/json/effects_from_json.py +msgid "Early iron deficiency" +msgstr "" + +#. ~ Description of effect 'Early iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"A lack of iron in your diet has hampered efficiency and regeneration of your" +" red blood cells." +msgstr "" + #: lang/json/effects_from_json.py msgid "Iron deficiency" msgstr "Eisenmangel" +#. ~ Description of effect 'Iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"Prolonged lack of iron in your diet has compromised efficiency and " +"regeneration of your red blood cells." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Acute iron deficiency" +msgstr "" + +#. ~ Description of effect 'Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"Severe lack of iron in your diet results in your red blood cells dying " +"faster then they are regenerating." +msgstr "" + +#. ~ Apply message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#. ~ Apply message for effect(s) 'Early anemia, Anemia, Acute anemia'. +#: lang/json/effects_from_json.py +msgid "You begin feeling increasingly tired and listless." +msgstr "AllmƤhlich fĆ¼hlst du dich mehr und mehr mĆ¼de und lustlos." + +#. ~ Remove message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "You are no longer in risk of becoming anemic." +msgstr "" + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your irom deficiency is nearly resolved." +msgstr "" + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your iron deficiency starts to improve." +msgstr "" + #: lang/json/effects_from_json.py msgid "Early anemia" msgstr "FrĆ¼he Blutarmut" @@ -108251,28 +108519,24 @@ msgid "Anemia" msgstr "Blutarmut" #: lang/json/effects_from_json.py -msgid "" -"A lack of iron in your diet will result in progressively worsening anemia." +msgid "Acute anemia" msgstr "" -"Ein Eisenmangel in deiner ErnƤhrung wird deine Blutarmut allmƤhlich " -"schlimmer machen." -#. ~ Apply message for effect(s) 'Iron deficiency, Early anemia, Anemia'. #: lang/json/effects_from_json.py -msgid "You begin feeling increasingly tired and listless." -msgstr "AllmƤhlich fĆ¼hlst du dich mehr und mehr mĆ¼de und lustlos." +msgid "Loss of red blood cells results in progressively worsening anemia." +msgstr "" -#. ~ Remove message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Remove message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You no longer feel anemic." msgstr "Du hast keine Blutarmut mehr." -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py -msgid "Your iron deficiency is nearly resolved." -msgstr "Dein Eisenmangel ist fast beseitigt." +msgid "Your anemia is nearly resolved." +msgstr "" -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "Your feel stronger as your anemia starts to improve." msgstr "Du fĆ¼hlst dich stƤrker, da sich deine Blutarmut verbessert." @@ -108473,6 +108737,77 @@ msgid "" "disgusting rations day in and day out?" msgstr "" +#: lang/json/effects_from_json.py +msgid "Mild hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Mild hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost some blood and look somewhat pale." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Moderate hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Moderate hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost large amount of blood, and you're not feeling well." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Advanced hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Advanced hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost an awful lot of blood, and your condition is severe. Seek " +"medical attention." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Severe hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost tremendous amount of blood, and you're standing on death's door." +" Transfusion might save you." +msgstr "" + +#. ~ Apply message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You have lost lot of blood, and your condition worsens." +msgstr "" + +#. ~ Remove message for effect(s) 'Mild hypovolemic shock, Moderate +#. hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You are no longer in shock." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your blood level increase, and you feel better, but still look pale." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your blood levels starts to improve." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You're not dying from lack of blood, but you're not out of the woods yet." +msgstr "" + #: lang/json/effects_from_json.py msgid "Lit up" msgstr "Erhellt" @@ -110403,25 +110738,343 @@ msgid "mutated cactus" msgstr "mutierter Kaktus" #: lang/json/furniture_from_json.py -msgid "cooling unit" +msgid "glowing tendril" msgstr "" -#. ~ Description for cooling unit +#. ~ Description for glowing tendril #: lang/json/furniture_from_json.py msgid "" -"A large, blocky appliance encased in sheet metal. This commonplace fixture " -"is used for cooling large indoor areas." +"A willowy tendril growing from the floor, gently waving back and forth. A " +"faint light spills from it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "splorch!" msgstr "" #: lang/json/furniture_from_json.py lang/json/furniture_from_json.py #: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "metal screeching!" -msgstr "Metall knirschen." +msgid "whump!" +msgstr "Ā»Wumm!Ā«." -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py +msgid "wafting anemone" +msgstr "" + +#. ~ Description for wafting anemone +#: lang/json/furniture_from_json.py +msgid "" +"A fleshy white protuberance growing from the floor, with a cluster of " +"tendrils pouring out of it. It looks almost exactly like a sea anemone, " +"even waving gently as though underwater." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "gasping tube" +msgstr "" + +#. ~ Description for gasping tube +#: lang/json/furniture_from_json.py +msgid "" +"This is a meaty green stalactite with a thickened hide like that of a " +"starfish, extending from the floor to the ceiling. In the center is a " +"series of ports somewhat like mouths, from which pour bursts of a vile-" +"smelling gas." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "twitching frond" +msgstr "" + +#. ~ Description for twitching frond +#: lang/json/furniture_from_json.py +msgid "" +"A spine resembling moth antennae juts from the ground, swaying gently in the" +" air. Every so often, a cascade of energy arcs along it and discharges into" +" the ceiling." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scarred lump" +msgstr "" + +#. ~ Description for scarred lump +#: lang/json/furniture_from_json.py +msgid "" +"This is a pile of nondescript alien flesh, twitching and belching strange " +"gases out of injured orifices." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "splat!" +msgstr "Ā»Platsch!Ā«." + +#: lang/json/furniture_from_json.py +msgid "slimy pod" +msgstr "" + +#. ~ Description for slimy pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a slick, translucent pod suspended on a thin stalk. It is covered " +"in a thick mucus, obscuring whatever is floating in the gel-like substance " +"inside." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "whump." +msgstr "Ā»Wumms!Ā«." + +#: lang/json/furniture_from_json.py +msgid "organ pod" +msgstr "" + +#. ~ Description for organ pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside you can see the" +" dimly outlined shape of human organs, floating in some kind of preservative" +" goo." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "resin pod" +msgstr "" + +#. ~ Description for resin pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside is a clean, " +"clear resinous-looking fluid. You could fairly easily tear it from the " +"stalk and take it with you." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "fleshy altar" +msgstr "" + +#. ~ Description for fleshy altar +#: lang/json/furniture_from_json.py +msgid "" +"This pulsing protuberance juts from the floor, its sides covered in scaled, " +"oozing skin. The surface is flat, but undulates softly. A handful of " +"unidentifiable appendages reach from the sides, suggesting a sort of " +"nightmarish living autodoc." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scrap antenna" +msgstr "" + +#. ~ Description for scrap antenna +#: lang/json/furniture_from_json.py +msgid "" +"This contraption looks like some sort of cobbled-together transmitter or " +"receiver antenna. It consists of a number of mismatched blinking lights, " +"spinning servos, and dangling wires connected to a heft metal box." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py msgid "clang!" msgstr "Ā»KlƤng!Ā«." +#: lang/json/furniture_from_json.py +msgid "rack of robots" +msgstr "" + +#. ~ Description for rack of robots +#: lang/json/furniture_from_json.py +msgid "" +"This is a wire cage containing a number of robot parts, from chassis to " +"limbs, firmly clamped on to sturdy hanging rods. It looks like it would be " +"exceptionally difficult to open it and get at them without damaging them, " +"probably by design." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "spinning dish" +msgstr "" + +#. ~ Description for spinning dish +#: lang/json/furniture_from_json.py +msgid "" +"This is a slowly spinning parabolic dish engraved with an unrecognizable " +"pattern of symbols that might, at a guess, be some sort of circuitry pattern" +" - or maybe a religious incantation. It is mounted on a completely " +"mismatched electric motor that looks fairly mundane." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scavenged utility light" +msgstr "" + +#. ~ Description for scavenged utility light +#: lang/json/furniture_from_json.py +msgid "" +"The bulbs emit an eery greenish glow, and some parts of it have a curved " +"appearance as though the metal were grown in a lab, but by and large this " +"isn't a particularly unusual looking area light." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "clanking fluid pump" +msgstr "" + +#. ~ Description for clanking fluid pump +#: lang/json/furniture_from_json.py +msgid "" +"The huge sweating pipes and large tank reveal this clanking and tortuous " +"piece of equipment to be some sort of fluid pump. It is cobbled from " +"several apparently ill-fitting parts that have been fitted together with " +"some very strange looking but surprisingly clever adaptors." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "metalloid printer" +msgstr "" + +#. ~ Description for metalloid printer +#: lang/json/furniture_from_json.py +msgid "" +"This huge device actually resembles a 3D printer fairly closely, aside from " +"its industrial size. Huge spools of various thin metallic wires top it and " +"feed into what seems to be some sort of nozzle, and massive electrical " +"cables disappear into the wall behind it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "circuit printer" +msgstr "" + +#. ~ Description for circuit printer +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall device with a lattice of pipes and nozzles. Based on the " +"pile of products sitting in the output hopper, it looks like itā€™s used as a " +"printer for complex electronic components." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "Mavrik 10-101 power core" +msgstr "" + +#. ~ Description for Mavrik 10-101 power core +#: lang/json/furniture_from_json.py +msgid "" +"There is a faded metallic plaque on the side of this cylindrical device. The lettering is a strange combination of English and Cyrillic script. It reads:\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "metal screeching!" +msgstr "Metall knirschen." + +#: lang/json/furniture_from_json.py +msgid "spherical generator" +msgstr "" + +#. ~ Description for spherical generator +#: lang/json/furniture_from_json.py +msgid "" +"This huge steel plated sphere gives off a soft hum as it, presumably, " +"generates power. A heavy lead plate bolted to the front might describe what" +" it is, but it is written in something that looks vaguely like cuneiform." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "fluidic generator" +msgstr "" + +#. ~ Description for fluidic generator +#: lang/json/furniture_from_json.py +msgid "" +"Twisting reams of copper and steel pipes wrap around a central core that " +"thrums softly. Although there are no labels in any language you recognize, " +"the cables connected to the base suggest that this is some sort of power " +"generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "rusty generator" +msgstr "" + +#. ~ Description for rusty generator +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall, unremarkable cylinder capped by a wide flat saucer. There " +"is heavy rusting at the base. A series of connected cables suggest that " +"it's some sort of power generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "personal charging station" +msgstr "" + +#. ~ Description for personal charging station +#: lang/json/furniture_from_json.py +msgid "" +"The cyborg equivalent of a bed, this is a custom-shaped near-vertical booth " +"designed to mount a heavy metal frame and connect it to a central power " +"supply and nutrient source." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp +msgid "crash!" +msgstr "Ā»Krach!Ā«." + +#: lang/json/furniture_from_json.py +msgid "simple charging station" +msgstr "" + +#. ~ Description for simple charging station +#: lang/json/furniture_from_json.py +msgid "" +"This is a simple, unadorned, corroded metal charging and refeeding station, " +"with hookups for two units somewhat larger than a human to stand side by " +"side and be recharged and refueled." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shimmering superstructure" +msgstr "" + +#. ~ Description for shimmering superstructure +#: lang/json/furniture_from_json.py +msgid "" +"A simple metal superstructure like you might see holding up a radio tower, " +"this one seems to give off just the faintest hint of shimmer, like heat " +"waves. The metal has a burnt, iridescent pattern. There is a boxy, " +"unimpressive looking device at the top of the tower." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "portal enclosure" +msgstr "" + +#. ~ Description for portal enclosure +#: lang/json/furniture_from_json.py +msgid "" +"A heavy metal ring attached to dozens of wires, charred by residue that " +"gives off an acrid, unfamiliar smell." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "cooling unit" +msgstr "" + +#. ~ Description for cooling unit +#: lang/json/furniture_from_json.py +msgid "" +"A large, blocky appliance encased in sheet metal. This commonplace fixture " +"is used for cooling large indoor areas." +msgstr "" + #: lang/json/furniture_from_json.py msgid "central air filter" msgstr "" @@ -110579,8 +111232,7 @@ msgid "" "priceless tools, invaluable to any survivor." msgstr "" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py msgid "whack!" msgstr "Ā»Bonk!Ā«" @@ -110596,16 +111248,12 @@ msgid "" "little to stop a moving car." msgstr "" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -#: src/mapdata.cpp src/vehicle_move.cpp +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/map.cpp src/mapdata.cpp +#: src/vehicle_move.cpp msgid "smash!" msgstr "Ā»Schepper!Ā«." -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -msgid "whump." -msgstr "Ā»Wumms!Ā«." - #: lang/json/furniture_from_json.py msgid "earthbag barricade" msgstr "" @@ -110942,10 +111590,6 @@ msgid "" "them moving slightly. Gross." msgstr "" -#: lang/json/furniture_from_json.py -msgid "splat!" -msgstr "Ā»Platsch!Ā«." - #. ~ Description for spider egg sack #: lang/json/furniture_from_json.py msgid "" @@ -111024,16 +111668,6 @@ msgid "" "the smoke to the outside. Dangerous to leave unattended while lit." msgstr "" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -msgid "crash!" -msgstr "Ā»Krach!Ā«." - -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "whump!" -msgstr "Ā»Wumm!Ā«." - #: lang/json/furniture_from_json.py msgid "wood stove" msgstr "Holzherd" @@ -111192,8 +111826,9 @@ msgid "" "comfort or warmth." msgstr "" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -#: src/iuse.cpp +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/iuse.cpp msgid "crunch!" msgstr "Ā»Knirsch!Ā«." @@ -111355,6 +111990,78 @@ msgid "" " chemicals." msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken generator" +msgstr "kaputter Generator" + +#. ~ Description for broken generator +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This generator is broken and will not help you produce usable electricity." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "Compact Advanced Sterling Radioisotope Generator" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"This hefty lump of steel and lead is the housing unit for a small nuclear " +"reactor. It is plastered with warning signs. You could probably ignore " +"those and salvage the steel and lead shielding, what could possibly go " +"wrong?" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"Some insane fool has removed the outer containment on this small-scale " +"nuclear reactor. It is still fairly safe as it is: the reactor has " +"considerable built-in containment as well. Nevertheless, you probably don't" +" want to stand too close for too long." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "light machinery" +msgstr "leichte Maschinenanlage" + +#. ~ Description for light machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted light machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "ting." +msgstr "Ā»TingĀ«." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "heavy machinery" +msgstr "schwere Maschinenanlage" + +#. ~ Description for heavy machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted heavy machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "old machinery" +msgstr "alte Maschinenanlage" + +#. ~ Description for old machinery +#: lang/json/furniture_from_json.py +msgid "Assorted old, rusty machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "electronic machinery" +msgstr "elektronische Maschinenanlage" + +#. ~ Description for electronic machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted electronic machinery. You could scavenge it for parts." +msgstr "" + #: lang/json/furniture_from_json.py msgid "robotic arm" msgstr "Roboterarm" @@ -111372,6 +112079,32 @@ msgstr "" msgid "thunk." msgstr "Ā»DonkĀ«." +#: lang/json/furniture_from_json.py +msgid "ground cable" +msgstr "" + +#. ~ Description for ground cable +#: lang/json/furniture_from_json.py +msgid "A bunch of loose cables snake along the floor." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shred!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "thud!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "capacitor bank" +msgstr "" + +#. ~ Description for capacitor bank +#: lang/json/furniture_from_json.py +msgid "A bank of heavy metal cylinders connected by large wires." +msgstr "" + #: lang/json/furniture_from_json.py msgid "Autodoc Mk. XI" msgstr "Autodoktor Typ XI" @@ -111640,116 +112373,17 @@ msgstr "" msgid "Stop peeking!" msgstr "" -#: lang/json/furniture_from_json.py -msgid "glowing tendril" -msgstr "" - -#. ~ Description for glowing tendril -#: lang/json/furniture_from_json.py -msgid "" -"A willowy tendril growing from the floor, gently waving back and forth. A " -"faint light spills from it." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "splorch!" -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "wafting anemone" -msgstr "" - -#. ~ Description for wafting anemone -#: lang/json/furniture_from_json.py -msgid "" -"A fleshy white protuberance growing from the floor, with a cluster of " -"tendrils pouring out of it. It looks almost exactly like a sea anemone, " -"even waving gently as though underwater." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "gasping tube" -msgstr "" - -#. ~ Description for gasping tube -#: lang/json/furniture_from_json.py -msgid "" -"This is a meaty green stalactite with a thickened hide like that of a " -"starfish, extending from the floor to the ceiling. In the center is a " -"series of ports somewhat like mouths, from which pour bursts of a vile-" -"smelling gas." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "twitching frond" -msgstr "" - -#. ~ Description for twitching frond -#: lang/json/furniture_from_json.py -msgid "" -"A spine resembling moth antennae juts from the ground, swaying gently in the" -" air. Every so often, a cascade of energy arcs along it and discharges into" -" the ceiling." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "scarred lump" -msgstr "" - -#. ~ Description for scarred lump -#: lang/json/furniture_from_json.py -msgid "" -"This is a pile of nondescript alien flesh, twitching and belching strange " -"gases out of injured orifices." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "slimy pod" -msgstr "" - -#. ~ Description for slimy pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a slick, translucent pod suspended on a thin stalk. It is covered " -"in a thick mucus, obscuring whatever is floating in the gel-like substance " -"inside." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "organ pod" -msgstr "" - -#. ~ Description for organ pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside you can see the" -" dimly outlined shape of human organs, floating in some kind of preservative" -" goo." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "resin pod" -msgstr "" - -#. ~ Description for resin pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside is a clean, " -"clear resinous-looking fluid. You could fairly easily tear it from the " -"stalk and take it with you." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "fleshy altar" -msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "centrifuge" +msgstr "Zentrifuge" -#. ~ Description for fleshy altar +#. ~ Description for centrifuge #: lang/json/furniture_from_json.py msgid "" -"This pulsing protuberance juts from the floor, its sides covered in scaled, " -"oozing skin. The surface is flat, but undulates softly. A handful of " -"unidentifiable appendages reach from the sides, suggesting a sort of " -"nightmarish living autodoc." +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. For some reason, this one has an attached battery pack. It could be " +"used to analyze a medical fluid sample, such as blood, if a test tube was " +"placed in it." msgstr "" #: lang/json/furniture_from_json.py @@ -112246,6 +112880,17 @@ msgid "" " it's not particularly comfortable." msgstr "" +#: lang/json/furniture_from_json.py +msgid "metal bench" +msgstr "" + +#. ~ Description for metal bench +#: lang/json/furniture_from_json.py +msgid "" +"A bench made of scrap metal. Not the most comfortable furniture you've ever" +" seen." +msgstr "" + #: lang/json/furniture_from_json.py msgid "bulletin board" msgstr "Pinnwand" @@ -112742,6 +113387,35 @@ msgid "" "A huge metal tank that can be used to safely store large amounts of liquid." msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "fuel tank" +msgstr "" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with gasoline." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken fuel tank" +msgstr "" + +#. ~ Description for broken fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with gasoline." +msgstr "" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with diesel." +msgstr "" + +#. ~ Description for broken fuel tank +#. ~ Description for broken diesel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with diesel." +msgstr "" + #: lang/json/furniture_from_json.py msgid "dumpster" msgstr "MĆ¼llcontainer" @@ -112765,6 +113439,42 @@ msgid "" "electricity, it is pedal-driven, allowing use without power." msgstr "" +#: lang/json/furniture_from_json.py +msgid "riveted metal crate" +msgstr "" + +#. ~ Description for riveted metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This huge box is made of a dull metal, riveted together. There is no " +"obvious opening mechanism, and the rivets don't match any of your tools. " +"The only way in would be to smash it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "sealed metal crate" +msgstr "" + +#. ~ Description for sealed metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This is a huge, tightly sealed storage crate made from welded and riveted " +"sheet metal. The sealing mechanism is too tight to open bare-handed and " +"would need some kind of prying instrument to release." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "open metal crate" +msgstr "" + +#. ~ Description for open metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This large metal crateā€™s lid is unsealed, and hinges open easily to reveal a" +" number of storage shelves inside. Once open, the side panels also swing " +"wider for easy access." +msgstr "" + #: lang/json/furniture_from_json.py msgid "counter" msgstr "Theke" @@ -112870,6 +113580,15 @@ msgstr "Setz dich hin, wenn du isst!" msgid "a low table for livingrooms." msgstr "" +#: lang/json/furniture_from_json.py +msgid "metal table" +msgstr "" + +#. ~ Description for metal table +#: lang/json/furniture_from_json.py +msgid "A serviceable but simple table made of scrap metal." +msgstr "" + #: lang/json/furniture_from_json.py msgid "tatami mat" msgstr "Tatami-Matte" @@ -113103,6 +113822,17 @@ msgstr "MetalltrĆ¼mmer" msgid "Pile of various bent and twisted metals." msgstr "Haufen aus diversen verbogenen und gewundenen Metallen." +#: lang/json/furniture_from_json.py +msgid "radioactive slag" +msgstr "" + +#. ~ Description for radioactive slag +#: lang/json/furniture_from_json.py +msgid "" +"A pile of melted slag from a destroyed nuclear reactor. What are you doing " +"looking at this? Get the hell out of here, you nutcase!" +msgstr "" + #: lang/json/furniture_from_json.py msgid "pile of ash" msgstr "Aschehaufen" @@ -113180,6 +113910,39 @@ msgid "" "public utilities, but it doesn't work anymore." msgstr "" +#: lang/json/furniture_from_json.py +msgid "scrap metal bridge" +msgstr "" + +#. ~ Description for scrap metal bridge +#: lang/json/furniture_from_json.py +msgid "A simple bridge made of riveted sheet metal." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py +msgid "broken console" +msgstr "kaputte Konsole" + +#. ~ Description for broken console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It doesn't seem to be working. " +"It's the broken screen and shattered circuit boards that's telling you that." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "computer console" +msgstr "Computerkonsole" + +#. ~ Description for computer console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It can be used to view contents and" +" perform any allowed functions. It might even be possible to hack it, given" +" the skills." +msgstr "" + #: lang/json/furniture_from_json.py msgid "forge" msgstr "Schmiede" @@ -113560,6 +114323,15 @@ msgid "" "you wouldn't need to pay at all!" msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "rope leading up" +msgstr "Seil nach oben" + +#. ~ Description for rope leading up +#: lang/json/furniture_from_json.py +msgid "A rope. You could climb it up." +msgstr "" + #: lang/json/furniture_from_json.py msgid "atomic butter churn on a stand" msgstr "" @@ -117713,6 +118485,21 @@ msgstr[1] "" msgid "Electricity unnaturally arcs from the tips of this alien frond." msgstr "" +#: lang/json/gun_from_json.py +msgid "hurled rubble" +msgid_plural "hurled rubbles" +msgstr[0] "" +msgstr[1] "" + +#: lang/json/gun_from_json.py +msgid "Stone at the ready to crush that which isn't part of the blob." +msgstr "" + +#: lang/json/gun_from_json.py +msgctxt "gun_type_type" +msgid "throw" +msgstr "werfen" + #: lang/json/gun_from_json.py msgid "nail gun" msgid_plural "nail guns" @@ -117773,7 +118560,7 @@ msgstr[1] "" msgid "" "A short homemade lever-action shotgun with a small internal tube magazine. " "While still a primitive pipe and 2x4 design, it is a formiddable shotgun in " -"it's own right with room for improvement." +"its own right with room for improvement." msgstr "" #: lang/json/gun_from_json.py @@ -118129,8 +118916,8 @@ msgid "" msgstr "" #: lang/json/gun_from_json.py -msgid "four winds shotgun" -msgid_plural "four winds shotguns" +msgid "slam-fire pipe shotgun" +msgid_plural "slam-fire pipe shotguns" msgstr[0] "" msgstr[1] "" @@ -118140,6 +118927,19 @@ msgid "" "The lack of sights make this weapon only useful at point-blank range." msgstr "" +#: lang/json/gun_from_json.py +msgid "double slam-fire pipe shotgun" +msgid_plural "double slam-fire pipe shotguns" +msgstr[0] "" +msgstr[1] "" + +#: lang/json/gun_from_json.py +msgid "" +"A crude shotgun, composed of four thick steel pipes, two end caps and two " +"nails. The lack of sights make this weapon only useful at point-blank " +"range." +msgstr "" + #: lang/json/gun_from_json.py msgid "flaregun" msgid_plural "flareguns" @@ -118666,11 +119466,6 @@ msgid "" " by hand." msgstr "" -#: lang/json/gun_from_json.py -msgctxt "gun_type_type" -msgid "throw" -msgstr "werfen" - #: lang/json/gun_from_json.py msgid "slingshot" msgid_plural "slingshots" @@ -124697,6 +125492,11 @@ msgid "" "access the controls, or use the vehicle control key (default '^')." msgstr "" +#. ~ Please leave anything in unchanged. +#: lang/json/json_flag_from_json.py +msgid "When active, turns engines on and off automatically." +msgstr "" + #. ~ Please leave anything in unchanged. #: lang/json/json_flag_from_json.py msgid "Illuminated items in this space will not illuminate nearby squares." @@ -126430,6 +127230,10 @@ msgstr "Wasserreiniger umschalten" msgid "Toggle tracking" msgstr "Verfolgung umschalten" +#: lang/json/keybinding_from_json.py +msgid "Toggle smart engine controller" +msgstr "" + #: lang/json/keybinding_from_json.py src/turret.cpp src/vehicle_use.cpp msgid "Set turret firing modes" msgstr "Turmfeuermodus anpassen" @@ -145757,17 +146561,6 @@ msgstr "" " Vereinbarungen. Ob das nun Ć¼berhaupt irgendwas bedeutet, ist eine andere " "Frage." -#: lang/json/mutation_from_json.py -msgid "Helicopter Pilot" -msgstr "" - -#. ~ Description for Helicopter Pilot -#: lang/json/mutation_from_json.py -msgid "" -"You are a trained helicopter pilot. This makes you one of the few living " -"people who can operate a helicopter after the Cataclysm." -msgstr "" - #: lang/json/mutation_from_json.py msgid "SWAT Officer" msgstr "SWAT-Polizistin" @@ -150836,6 +151629,10 @@ msgstr "" msgid "subway station?" msgstr "" +#: lang/json/overmap_terrain_from_json.py +msgid "science lab reactor" +msgstr "" + #: lang/json/overmap_terrain_from_json.py msgid "lab" msgstr "" @@ -158234,6 +159031,18 @@ msgid "" "You have your whole life ahead of you and it's gonna be sweet!" msgstr "" +#: lang/json/proficiency_from_json.py +msgid "Knapping" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Blacksmithing" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Helicopter Piloting" +msgstr "" + #. ~ Crafting recipes category name #: lang/json/recipe_category_from_json.py msgid "*" @@ -166682,7 +167491,7 @@ msgstr "" msgid "Finally, something to take the edge off." msgstr "" -#: lang/json/snippet_from_json.py src/npctalk.cpp +#: lang/json/snippet_from_json.py src/talker_npc.cpp msgid "No thanks, I'm good." msgstr "" @@ -187270,6 +188079,18 @@ msgstr "" msgid "This is a npc_has_var, npc_remove_var test response." msgstr "" +#: lang/json/talk_topic_from_json.py +msgid "This is a u_add_var time test response." +msgstr "" + +#: lang/json/talk_topic_from_json.py +msgid "This is a npc_add_var time test response." +msgstr "" + +#: lang/json/talk_topic_from_json.py +msgid "This is a u_compare_var time test response for > 3_days." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "This is a u_adjust_var test response that increments by 1." msgstr "" @@ -187370,6 +188191,10 @@ msgstr "" msgid "This is a low driving test response." msgstr "" +#: lang/json/talk_topic_from_json.py +msgid "This is an npc_first_topic test response." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "Greetings friend, it's nice to see you." msgstr "" @@ -196606,7 +197431,7 @@ msgid "Will do, thanks!" msgstr "Wird gemacht, danke!" #: lang/json/talk_topic_from_json.py lang/json/talk_topic_from_json.py -#: src/npctalk.cpp +#: src/talker.h src/talker_npc.cpp msgid "Nope." msgstr "Nein." @@ -202728,6 +203553,36 @@ msgstr "" msgid "The door opens forcefully!" msgstr "" +#: lang/json/terrain_from_json.py +msgid "broken diesel tank" +msgstr "" + +#. ~ Description for centrifuge +#: lang/json/terrain_from_json.py +msgid "" +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. It could be used to analyze a medical fluid sample, such as blood, if" +" a test tube was placed in it." +msgstr "" + +#: lang/json/terrain_from_json.py +msgid "plutonium generator" +msgstr "Plutoniumgenerator" + +#. ~ Description for plutonium generator +#: lang/json/terrain_from_json.py +msgid "" +"This imposing apparatus harnesses the power of the atom. Refined nuclear " +"fuel is 'burned' to provide nearly limitless electrical power. It's not " +"doing much good here though. Perhaps it could be salvaged for other " +"purposes." +msgstr "" + +#. ~ Description for old machinery +#: lang/json/terrain_from_json.py +msgid "Assorted old machinery. You could scavenge it for parts." +msgstr "" + #: lang/json/terrain_from_json.py msgid "scorched earth" msgstr "verbrannte Erde" @@ -205826,24 +206681,6 @@ msgstr "" "aufnehmen und in einfache Grundformen pressen kann, um diese dann " "anschlieƟend zur Fertigung verwenden zu kƶnnen." -#: lang/json/terrain_from_json.py -msgid "fuel tank" -msgstr "" - -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with gasoline." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "broken fuel tank" -msgstr "" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with gasoline." -msgstr "" - #: lang/json/terrain_from_json.py msgid "gasoline pump" msgstr "BenzinzapfsƤule" @@ -205868,16 +206705,6 @@ msgid "" "the liquid gold." msgstr "" -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with diesel." -msgstr "" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with diesel." -msgstr "" - #: lang/json/terrain_from_json.py msgid "diesel pump" msgstr "DieselzapfsƤule" @@ -205957,16 +206784,6 @@ msgid "" "airflow." msgstr "" -#: lang/json/terrain_from_json.py -msgid "broken generator" -msgstr "kaputter Generator" - -#. ~ Description for broken generator -#: lang/json/terrain_from_json.py -msgid "" -"This generator is broken and will not help you produce usable electricity." -msgstr "" - #: lang/json/terrain_from_json.py msgid "missile" msgstr "Rakete" @@ -206024,18 +206841,6 @@ msgid "" "This unpowered pump previously would have moved fluids around in a hurry." msgstr "" -#: lang/json/terrain_from_json.py -msgid "centrifuge" -msgstr "Zentrifuge" - -#. ~ Description for centrifuge -#: lang/json/terrain_from_json.py -msgid "" -"This is a centrifuge, a liquid separating device with an automated analyzer " -"unit. It could be used to analyze a medical fluid sample, such as blood, if" -" a test tube was placed in it." -msgstr "" - #: lang/json/terrain_from_json.py msgid "CVD machine" msgstr "CVD-Maschine" @@ -206139,19 +206944,6 @@ msgstr "" msgid "A machine with several taps that dispenses clean water." msgstr "" -#: lang/json/terrain_from_json.py -msgid "plutonium generator" -msgstr "Plutoniumgenerator" - -#. ~ Description for plutonium generator -#: lang/json/terrain_from_json.py -msgid "" -"This imposing apparatus harnesses the power of the atom. Refined nuclear " -"fuel is 'burned' to provide nearly limitless electrical power. It's not " -"doing much good here though. Perhaps it could be salvaged for other " -"purposes." -msgstr "" - #: lang/json/terrain_from_json.py msgid "telecom cabinet" msgstr "Verteilerkasten" @@ -206266,46 +207058,6 @@ msgstr "FlieƟband" msgid "A conveyor belt. Used to transport things." msgstr "" -#: lang/json/terrain_from_json.py -msgid "ting." -msgstr "Ā»TingĀ«." - -#: lang/json/terrain_from_json.py -msgid "light machinery" -msgstr "leichte Maschinenanlage" - -#. ~ Description for light machinery -#: lang/json/terrain_from_json.py -msgid "Assorted light machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "heavy machinery" -msgstr "schwere Maschinenanlage" - -#. ~ Description for heavy machinery -#: lang/json/terrain_from_json.py -msgid "Assorted heavy machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "old machinery" -msgstr "alte Maschinenanlage" - -#. ~ Description for old machinery -#: lang/json/terrain_from_json.py -msgid "Assorted old machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "electronic machinery" -msgstr "elektronische Maschinenanlage" - -#. ~ Description for electronic machinery -#: lang/json/terrain_from_json.py -msgid "Assorted electronic machinery. You could scavenge it for parts." -msgstr "" - #: lang/json/terrain_from_json.py msgid "milking machine" msgstr "Melkmaschine" @@ -206380,29 +207132,6 @@ msgid "" "from the elements or to protect a campfire from the rain." msgstr "" -#: lang/json/terrain_from_json.py -msgid "broken console" -msgstr "kaputte Konsole" - -#. ~ Description for broken console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It doesn't seem to be working. " -"It's the broken screen and shattered circuit boards that's telling you that." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "computer console" -msgstr "Computerkonsole" - -#. ~ Description for computer console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It can be used to view contents and" -" perform any allowed functions. It might even be possible to hack it, given" -" the skills." -msgstr "" - #: lang/json/terrain_from_json.py msgid "mechanical winch" msgstr "mechanische Winde" @@ -208733,10 +209462,6 @@ msgstr "Steigung" msgid "An upward facing slope." msgstr "" -#: lang/json/terrain_from_json.py -msgid "rope leading up" -msgstr "Seil nach oben" - #. ~ Description for rope leading up #: lang/json/terrain_from_json.py msgid "A rope. You could climb up it." @@ -209396,6 +210121,10 @@ msgstr "Auto" msgid "Car Chassis" msgstr "Auto-Fahrgestell" +#: lang/json/vehicle_from_json.py +msgid "Hybrid Car" +msgstr "" + #: lang/json/vehicle_from_json.py msgid "City Car" msgstr "" @@ -211289,6 +212018,21 @@ msgstr "" "passenden SchlĆ¼ssel zu starten. Sie werden einen Alarm ertƶnen lassen, wenn " "du es versuchst. Der Alarm kann ausgeschaltet werden." +#: lang/json/vehicle_part_from_json.py +msgid "smart engine controller" +msgstr "" + +#. ~ Description for {'str': 'smart engine controller'} +#: lang/json/vehicle_part_from_json.py +#, no-python-format +msgid "" +"Electronic module that automatically switches combustion and electric " +"engines on and off minimizing fuel consumption and optimizing power output " +"and battery charge rate. Must be turned on to work. Simplified ruleset: 1." +" When throttling, maximize acceleration. 2. Keep battery at 90%. 3. " +"Minimize fuel consumption." +msgstr "" + #: lang/json/vehicle_part_from_json.py msgid "5-point harness" msgstr "FĆ¼nfpunktgurt" @@ -212581,6 +213325,66 @@ msgstr "" msgid "Disgusting Diet" msgstr "" +#: lang/json/vitamin_from_json.py +msgid "Blood" +msgstr "" + +#: lang/json/vitamin_from_json.py +msgid "Red Blood Cells" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "NULL Weather - BUG" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "Clear" +msgstr "Klar" + +#: lang/json/weather_type_from_json.py +msgid "Sunny" +msgstr "Sonnig" + +#: lang/json/weather_type_from_json.py +msgid "Cloudy" +msgstr "Bewƶlkt" + +#: lang/json/weather_type_from_json.py +msgid "Light Drizzle" +msgstr "Leichter Nieselregen" + +#: lang/json/weather_type_from_json.py +msgid "Drizzle" +msgstr "Nieselregen" + +#: lang/json/weather_type_from_json.py +msgid "Rain" +msgstr "Regen" + +#: lang/json/weather_type_from_json.py +msgid "Thunder Storm" +msgstr "Gewitter" + +#: lang/json/weather_type_from_json.py +msgid "Acidic Drizzle" +msgstr "Saures Nieseln" + +#: lang/json/weather_type_from_json.py +msgid "Acid Rain" +msgstr "Saurer Regen" + +#: lang/json/weather_type_from_json.py +msgid "Flurries" +msgstr "Schneegestƶber" + +#: lang/json/weather_type_from_json.py +msgid "Snowing" +msgstr "Schnee" + +#: lang/json/weather_type_from_json.py +msgid "Snowstorm" +msgstr "Schneesturm" + #: src/achievement.cpp msgid "time of cataclysm" msgstr "" @@ -212746,8 +213550,7 @@ msgstr "Dein Strom ist erschƶpft!" msgid "You cannot hack this." msgstr "" -#: src/activity_actor.cpp src/computer_session.cpp src/computer_session.cpp -#: src/iuse.cpp src/map.cpp +#: src/activity_actor.cpp src/computer_session.cpp src/iuse.cpp src/map.cpp msgid "an alarm sound!" msgstr "einen Alarm ertƶnen!" @@ -212892,6 +213695,16 @@ msgstr "" msgid "Continue trying to fall asleep and don't ask again." msgstr "" +#: src/activity_actor.cpp +#, c-format +msgid "You disassemble your %s." +msgstr "Du demontierst: %s." + +#: src/activity_actor.cpp src/player.cpp +#, c-format +msgid "You unload your %s." +msgstr "%s wird entladen." + #: src/activity_actor.cpp msgid "You are too tired to exercise." msgstr "" @@ -213429,11 +214242,6 @@ msgstr[1] " ist fertig damit, die Leichen zu zermalmen." msgid "Can't reload the %s." msgstr "Du kannst %s nicht nachladen." -#: src/activity_handlers.cpp src/iexamine.cpp -#, c-format -msgid "You reload the %s." -msgstr "Du lƤdst %s nach." - #: src/activity_handlers.cpp #, c-format msgid "" @@ -213450,6 +214258,11 @@ msgstr "" msgid "You refill the %s." msgstr "Du befĆ¼llst %s wieder." +#: src/activity_handlers.cpp +#, c-format +msgid "You reload the %1$s with %2$s." +msgstr "" + #: src/activity_handlers.cpp src/bionics.cpp msgid "There's nothing to light there." msgstr "Dort ist nichts zum AnzĆ¼nden." @@ -213582,6 +214395,10 @@ msgstr "Von dieser TƤtigkeit wirst du nichts neues lernen." msgid "%s %s\n" msgstr "" +#: src/activity_handlers.cpp src/magic.cpp +msgid "bionic power" +msgstr "" + #: src/activity_handlers.cpp #, c-format msgid "Charges: %s/%s %s (%s per use)\n" @@ -213960,16 +214777,6 @@ msgstr "Du ƶffnest dein Set und rasierst dich." msgid "You give your hair a trim." msgstr "Du schneidest dir die Haare." -#: src/activity_handlers.cpp -#, c-format -msgid "You disassemble your %s." -msgstr "Du demontierst: %s." - -#: src/activity_handlers.cpp src/player.cpp -#, c-format -msgid "You unload your %s." -msgstr "%s wird entladen." - #: src/activity_handlers.cpp #, c-format msgid "You have run out of %s." @@ -214998,7 +215805,7 @@ msgstr "" msgid "Properties" msgstr "Eigenschaften" -#: src/armor_layers.cpp +#: src/armor_layers.cpp src/item.cpp msgid "Coverage:" msgstr "Bedeckung:" @@ -216976,7 +217783,7 @@ msgstr "Du hast nicht genĆ¼gend Strom, um dein %s zu aktivieren." msgid "Deactivate your %s first!" msgstr "Deaktiviere zuerst dein %s!" -#: src/bionics.cpp src/player.cpp +#: src/bionics.cpp src/character.cpp #, c-format msgid "Stop wielding %s?" msgstr "%s nicht mehr halten?" @@ -218409,6 +219216,13 @@ msgstr "Wo absteigen?" msgid "You cannot dismount there!" msgstr "Dort kannst du nicht absteigen!" +#: src/character.cpp +#, c-format +msgid "This task is too simple to train your %s beyond %d." +msgstr "" +"Diese TƤtigkeit ist zu simpel, um deine Fertigkeit Ā»%sĀ« Ć¼ber den Wert Ā»%dĀ« " +"hinaus zu trainieren." + #: src/character.cpp msgid "You struggle to stand." msgstr "Du hast Schwierigkeiten, gerade zu stehen." @@ -218588,6 +219402,16 @@ msgstr " entkommt der Grube!" msgid "Your %s bionic comes back online." msgstr "Dein %s Bionik ist wieder eingeschaltet." +#: src/character.cpp +#, c-format +msgid "Your skill in %s has increased to %d!" +msgstr "Deine Fertigkeit in %s hat sich auf %d erhƶht!" + +#: src/character.cpp +#, c-format +msgid "You feel that %s tasks of this level are becoming trivial." +msgstr "Du merkst, dass %s-Aufgaben dieser Stufe trivial werden." + #: src/character.cpp #, c-format msgid "You put on your %s." @@ -218702,6 +219526,15 @@ msgstr "" msgid "%s doesn't have any broken limbs this could help." msgstr "" +#: src/character.cpp +msgid "You don't need a tourniquet to stop the bleeding." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "%s doesn't need a tourniquet to stop the bleeding." +msgstr "" + #: src/character.cpp msgid "You don't have enough arms to wear that." msgstr "" @@ -218885,7 +219718,7 @@ msgstr "Ausgehungert" msgid "ERROR!" msgstr "FEHLER!" -#: src/character.cpp src/npctalk.cpp +#: src/character.cpp src/talker_npc.cpp msgid "Exhausted" msgstr "Erschƶpft" @@ -218931,7 +219764,7 @@ msgstr "" msgid "You have a sudden heart attack!" msgstr "Du hast eine plƶtzliche Herzattacke!" -#: src/character.cpp +#: src/character.cpp src/player_hardcoded_effects.cpp msgid " has a sudden heart attack!" msgstr "" @@ -219163,12 +219996,12 @@ msgstr "Gut" #: src/character.cpp #, c-format -msgid "Chance to stop: %d %%" -msgstr "Wahrscheinlichkeit, die Blutung zu stoppen: %d %%" +msgid "Expected reduction of bleeding by: %d %%" +msgstr "" #: src/character.cpp -msgid "This will not stop the bleeding." -msgstr "Das wird die Blutung nicht stoppen." +msgid "This will not affect the bleeding." +msgstr "" #: src/character.cpp #, c-format @@ -219603,6 +220436,41 @@ msgstr "%1$s ist weiter %2$s!" msgid "Your %1$s is %2$s!" msgstr "%1$s ist %2$s!" +#: src/character.cpp +msgid "Can't wield spilt liquids." +msgstr "VerschĆ¼ttete FlĆ¼ssigkeiten kƶnnen nicht gehalten werden." + +#: src/character.cpp +msgid "You need at least one arm to even consider wielding something." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "The %s is preventing you from wielding the %s." +msgstr "" + +#: src/character.cpp +msgid "Something you are wearing hinders the use of both hands." +msgstr "Etwas, was du trƤgst, hindert dich daran, beide HƤnde zu benutzen." + +#: src/character.cpp +#, c-format +msgid "The %s can't be wielded with only one arm." +msgstr "%s kann nicht mit nur einem Arm gehalten werden." + +#: src/character.cpp +#, c-format +msgid "You are too weak to wield %s with only one arm." +msgstr "Du bist zu schwach, um %s mit nur einem Arm zu halten." + +#: src/character.cpp +msgid " (empty)" +msgstr "" + +#: src/character.cpp src/npctalk.cpp +msgid "fists" +msgstr "FƤuste" + #: src/character.cpp #, c-format msgid "You are no longer able to wield your %s and drop it!" @@ -220158,6 +221026,11 @@ msgstr "" msgid "%s - Root Menu" msgstr "" +#: src/computer_session.cpp +#, c-format +msgid "%s (UNAVAILABLE)" +msgstr "" + #: src/computer_session.cpp msgid "Password required." msgstr "Passwort erforderlich." @@ -220729,7 +221602,7 @@ msgstr "" msgid "Result: " msgstr "Ergebnis: " -#: src/construction.cpp +#: src/construction.cpp src/worldfactory.cpp msgid "N/A" msgstr "(entfƤllt)" @@ -221408,6 +222281,10 @@ msgid "" "Start crafting anyway?" msgstr "" +#: src/craft_command.cpp +msgid "You don't have the required proficiencies to craft this!" +msgstr "" + #: src/craft_command.cpp msgid "" "This craft will use rotten components.\n" @@ -221883,6 +222760,11 @@ msgstr "" msgid "Other skills: %s" msgstr "Andere Fertigkeiten: %s" +#: src/crafting_gui.cpp +#, c-format +msgid "Proficiencies Required: %s" +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "Time to complete: %s" @@ -221926,6 +222808,12 @@ msgid "" "components" msgstr "" +#: src/crafting_gui.cpp +msgid "" +"Cannot be crafted because you lack the required " +"proficiencies." +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "v (%s for more)" @@ -222311,6 +223199,10 @@ msgstr "Spieler/NPC bearbeiten" msgid "Damage self" msgstr "" +#: src/debug_menu.cpp +msgid "Bleed self" +msgstr "" + #: src/debug_menu.cpp msgid "Set automove route" msgstr "Autobewegen-Route zeigen" @@ -222443,6 +223335,14 @@ msgstr "" msgid "Gameā€¦" msgstr "" +#: src/debug_menu.cpp +msgid "Change [b]attery charge" +msgstr "" + +#: src/debug_menu.cpp +msgid "Vehicleā€¦" +msgstr "" + #: src/debug_menu.cpp msgid "Teleport - short range" msgstr "" @@ -223072,12 +223972,8 @@ msgstr "Ort: %d:%d in %d:%d, %s\n" #: src/debug_menu.cpp #, c-format -msgid "" -"Current turn: %d.\n" -"%s\n" +msgid "Current turn: %d.\n" msgstr "" -"Aktueller Zug: %d.\n" -"%s\n" #: src/debug_menu.cpp #, c-format @@ -223086,14 +223982,6 @@ msgid_plural "%d creatures exist.\n" msgstr[0] "%d Kreaturen existiert.\n" msgstr[1] "%d Kreaturen existieren.\n" -#: src/debug_menu.cpp -msgid "NPCs are going to spawn." -msgstr "NPCs tauchen in KĆ¼rze auf." - -#: src/debug_menu.cpp -msgid "NPCs are NOT going to spawn." -msgstr "NPCs tauchen in KĆ¼rze NICHT auf." - #: src/debug_menu.cpp #, c-format msgid "%s: map ( %d:%d ) pos ( %d:%d )" @@ -223149,6 +224037,22 @@ msgstr "Von welchem Typ soll das Fahrzeug sein?" msgid "%1$s (%2$s)" msgstr "%1$s (%2$s)" +#: src/debug_menu.cpp +msgid "Vehicle condition" +msgstr "" + +#: src/debug_menu.cpp +msgid "Light damage" +msgstr "" + +#: src/debug_menu.cpp +msgid "Undamaged" +msgstr "" + +#: src/debug_menu.cpp +msgid "Disabled (tires or engine)" +msgstr "" + #: src/debug_menu.cpp msgid "Martial arts debug." msgstr "KampfkĆ¼nste-Debug." @@ -223211,6 +224115,10 @@ msgstr "" msgid "Damage self for how much? hp: %s" msgstr "" +#: src/debug_menu.cpp +msgid "Add bleeding duration in minutes, equal to intensity:" +msgstr "" + #: src/debug_menu.cpp msgid "This binary was not compiled with tiles support." msgstr "Dieses Programm wurde nicht mit Kachel-UnterstĆ¼tzung kompiliert." @@ -223343,6 +224251,14 @@ msgstr "" msgid "%s is now level %d!" msgstr "" +#: src/debug_menu.cpp src/iuse.cpp src/iuse.cpp +msgid "There's no vehicle there." +msgstr "Dort ist kein Fahrzeug." + +#: src/debug_menu.cpp +msgid "By how much? (in kJ, negative to discharge)" +msgstr "" + #: src/descriptions.cpp #, c-format msgid "" @@ -224066,6 +224982,22 @@ msgstr "hervorragend" msgid "perfect" msgstr "perfekt" +#: src/effect.cpp +msgid "miniscule" +msgstr "" + +#: src/effect.cpp +msgid "small" +msgstr "klein" + +#: src/effect.cpp +msgid "moderate" +msgstr "" + +#: src/effect.cpp +msgid "excellent" +msgstr "" + #. ~ Default format for scores. %1$s is statistic description; %2$s is value. #: src/event_statistics.cpp #, c-format @@ -226568,6 +227500,11 @@ msgstr "Deine Position auf der Oberkarte: %d; %d; %d" msgid "Your local position: %d, %d, %d" msgstr "Deine lokale Position: %d; %d; %d" +#: src/game.cpp +#, c-format +msgid "Total NPCs within %d OMTs: %d. %d are static NPCs." +msgstr "" + #: src/game.cpp msgid "East:" msgstr "Ost:" @@ -228384,12 +229321,12 @@ msgid "Your inventory is empty." msgstr "Dein Inventar ist leer." #: src/game_inventory.cpp -msgid "ENCUMBRANCE" -msgstr "HINDERUNG" +msgid "AVG ENCUMBRANCE" +msgstr "" #: src/game_inventory.cpp -msgid "COVERAGE" -msgstr "BEDECKUNG" +msgid "AVG COVERAGE" +msgstr "" #: src/game_inventory.cpp msgid "WARMTH" @@ -231599,6 +232536,11 @@ msgstr "Wieviel von %1$s in %2$s tun?" msgid "The %1$s contains %2$d %3$s." msgstr "%1$s enthƤlt %2$d %3$s." +#: src/iexamine.cpp +#, c-format +msgid "You reload the %s." +msgstr "Du lƤdst %s nach." + #: src/iexamine.cpp msgid "Do what with the curtains?" msgstr "Was mit dem Vorhang anstellen?" @@ -232479,6 +233421,10 @@ msgstr "Fertigstellung" msgid "Body parts" msgstr "Kƶrperteile" +#: src/init.cpp +msgid "Weather types" +msgstr "" + #: src/init.cpp msgid "Field types" msgstr "" @@ -233341,10 +234287,6 @@ msgstr "Faul (Runden):" msgid "max rot (turns): " msgstr "Max Faul (Runden):" -#: src/item.cpp -msgid "last rot: " -msgstr "Letztes Faul: " - #: src/item.cpp msgid "last temp: " msgstr "Letzte Temp: " @@ -233626,8 +234568,8 @@ msgid "Recommended strength (burst): " msgstr "Empfohlene StƤrke (FeuerstoƟ): " #: src/item.cpp -msgid " moves " -msgstr " ZĆ¼ge" +msgid " moves" +msgstr "" #: src/item.cpp msgid "Skill used: " @@ -233664,10 +234606,6 @@ msgstr "Gleiche Chance fĆ¼r guten Fernschuss: " msgid "" msgstr "" -#: src/item.cpp -msgid " moves" -msgstr "" - #: src/item.cpp msgid "Time to reach aim level: " msgstr "Zielgeschwindigkeitsmalus: " @@ -233802,164 +234740,169 @@ msgstr "" "Werte verbessern, indem du diesen Gegenstand reparierst." #: src/item.cpp -msgid "Covers: " +msgid "Covers:" msgstr "" #: src/item.cpp -msgid "The head. " -msgstr "Den Kopf. " +msgid " The head." +msgstr "" #: src/item.cpp -msgid "The eyes. " -msgstr "Die Augen. " +msgid " The eyes." +msgstr "" #: src/item.cpp -msgid "The mouth. " -msgstr "Den Mund. " +msgid " The mouth." +msgstr "" #: src/item.cpp -msgid "The torso. " -msgstr "Den Torso. " +msgid " The torso." +msgstr "" #: src/item.cpp -msgid "Either arm. " -msgstr "Einen Arm. " +msgid " Either arm." +msgstr "" #: src/item.cpp -msgid "The arms. " -msgstr "Die Arme. " +msgid " The arms." +msgstr "" #: src/item.cpp -msgid "The left arm. " -msgstr "Den linken Arm. " +msgid " The left arm." +msgstr "" #: src/item.cpp -msgid "The right arm. " -msgstr "Den rechten Arm. " +msgid " The right arm." +msgstr "" #: src/item.cpp -msgid "Either hand. " -msgstr "Eine Hand. " +msgid " Either hand." +msgstr "" #: src/item.cpp -msgid "The hands. " -msgstr "Die HƤnde. " +msgid " The hands." +msgstr "" #: src/item.cpp -msgid "The left hand. " -msgstr "Die linke Hand. " +msgid " The left hand." +msgstr "" #: src/item.cpp -msgid "The right hand. " -msgstr "Die rechte Hand. " +msgid " The right hand." +msgstr "" #: src/item.cpp -msgid "Either leg. " -msgstr "Ein Bein. " +msgid " Either leg." +msgstr "" #: src/item.cpp -msgid "The legs. " -msgstr "Die Beine. " +msgid " The legs." +msgstr "" #: src/item.cpp -msgid "The left leg. " -msgstr "Das linke Bein. " +msgid " The left leg." +msgstr "" #: src/item.cpp -msgid "The right leg. " -msgstr "Das rechte Bein. " +msgid " The right leg." +msgstr "" #: src/item.cpp -msgid "Either foot. " -msgstr "Einen FuƟ. " +msgid " Either foot." +msgstr "" #: src/item.cpp -msgid "The feet. " -msgstr "Die FĆ¼ĆŸe. " +msgid " The feet." +msgstr "" #: src/item.cpp -msgid "The left foot. " -msgstr "Den linken FuƟ. " +msgid " The left foot." +msgstr "" #: src/item.cpp -msgid "The right foot. " -msgstr "Den rechten FuƟ. " +msgid " The right foot." +msgstr "" #: src/item.cpp -msgid "Nothing." -msgstr "Nichts." +msgid " Nothing." +msgstr "" #: src/item.cpp -msgid "Layer: " -msgstr "Schicht: " +msgid "Layer:" +msgstr "" #: src/item.cpp -msgid "Personal aura. " -msgstr "Persƶnliche Aura. " +msgid " Personal aura." +msgstr "" #: src/item.cpp -msgid "Close to skin. " -msgstr "Hauteng. " +msgid " Close to skin." +msgstr "" #: src/item.cpp -msgid "Strapped. " -msgstr "Angebunden. " +msgid " Strapped." +msgstr "" #: src/item.cpp -msgid "Outer. " -msgstr "ƄuƟere. " +msgid " Outer." +msgstr "" #: src/item.cpp -msgid "Waist. " -msgstr "Taille. " +msgid " Waist." +msgstr "" #: src/item.cpp -msgid "Outer aura. " -msgstr "ƄuƟere Aura. " +msgid " Outer aura." +msgstr "" #: src/item.cpp -msgid "Normal. " -msgstr "Normal. " +msgid " Normal." +msgstr "" #: src/item.cpp -msgid "Coverage: " -msgstr "Bedeckung: " +msgid "Average Coverage: " +msgstr "" #: src/item.cpp msgid "Warmth: " msgstr "WƤrme: " #: src/item.cpp -msgid " (fits)" -msgstr " (passt)" +msgid " (fits)" +msgstr "" + +#: src/item.cpp +msgid " (poor fit)" +msgstr "" #: src/item.cpp -msgid " (poor fit)" -msgstr " (sitzt schlecht)" +msgid " (too big)" +msgstr "" #: src/item.cpp -msgid " (too big)" +msgid " (huge!)" msgstr "" #: src/item.cpp -msgid " (huge!)" +msgid " (too small)" msgstr "" #: src/item.cpp -msgid " (too small)" +msgid " (tiny!)" msgstr "" #: src/item.cpp -msgid " (tiny!)" +msgid "Encumbrance:" msgstr "" #: src/item.cpp -msgid "Encumbrance: " -msgstr "Hinderung: " +#, c-format +msgid "%s:" +msgstr "" #: src/item.cpp -msgid "Encumbrance when full: " -msgstr "Hinderung wenn voll: " +msgid "When Full:" +msgstr "" #: src/item.cpp msgid "Weight capacity modifier: " @@ -234387,24 +235330,24 @@ msgid "Power Capacity:" msgstr "Energie KapazitƤt: " #: src/item.cpp -msgid "Environmental Protection: " -msgstr "Umgebungs-Schutz: " +msgid "Environmental Protection:" +msgstr "" #: src/item.cpp -msgid "Bash Protection: " -msgstr "Schlag-Schutz: " +msgid "Bash Protection:" +msgstr "" #: src/item.cpp -msgid "Cut Protection: " -msgstr "Schnitt-Schutz: " +msgid "Cut Protection:" +msgstr "" #: src/item.cpp -msgid "Ballistic Protection: " -msgstr "Ballistik-Schutz: " +msgid "Ballistic Protection:" +msgstr "" #: src/item.cpp -msgid "Stat Bonus: " -msgstr "Werte-Bonus: " +msgid "Stat Bonus:" +msgstr "" #: src/item.cpp msgid "Melee damage: " @@ -236553,10 +237496,6 @@ msgstr "Von wo soll was abgesaugt werden?" msgid "There is nothing to siphon nearby." msgstr "" -#: src/iuse.cpp -msgid "There's no vehicle there." -msgstr "Dort ist kein Fahrzeug." - #: src/iuse.cpp msgid "With a snarl, the combat chainsaw screams to life!" msgstr "Knurrend erwacht die KampfkettensƤge zum Leben!" @@ -239651,6 +240590,10 @@ msgstr "Es tut hƶllisch weh!" msgid "It itches a little." msgstr "Es juckt ein wenig." +#: src/iuse_actor.cpp +msgid "Bleeding has not stopped completely!" +msgstr "" + #: src/iuse_actor.cpp msgid "You cannot cauterize while mounted." msgstr "" @@ -239979,12 +240922,22 @@ msgid "You stop the bleeding." msgstr "Du beendest die Blutung." #: src/iuse_actor.cpp -msgid "The wound still bleeds." -msgstr "Die Wunde blutet noch." +msgid "You reduce the bleeding, but it's not stopped yet." +msgstr "" #: src/iuse_actor.cpp -msgid "You fail to stop the bleeding." -msgstr "Dir misslingt es, die Blutung zu beenden." +msgid "The bleeding is reduced, but not stopped." +msgstr "" + +#: src/iuse_actor.cpp +msgid "" +"Your dressing is too ineffective for a bleeding of this extent, and you fail" +" to stop it." +msgstr "" + +#: src/iuse_actor.cpp +msgid "The wound still bleeds." +msgstr "Die Wunde blutet noch." #: src/iuse_actor.cpp msgid "The wound is cleaned." @@ -240090,12 +241043,16 @@ msgid "Actual disinfecting quality: " msgstr "" #: src/iuse_actor.cpp -msgid "Chance to heal (percent): " -msgstr "Heilungschancen (%):" +msgid "Effect on bleeding: " +msgstr "" + +#: src/iuse_actor.cpp +msgid "Actual effect on bleeding: " +msgstr "" #: src/iuse_actor.cpp -msgid "* Bleeding: " -msgstr "* Blutung: " +msgid "Chance to heal (percent): " +msgstr "Heilungschancen (%):" #: src/iuse_actor.cpp msgid "* Bite: " @@ -240161,8 +241118,8 @@ msgid "It's not a gun." msgstr "Es ist keine Feuerwaffe." #: src/iuse_actor.cpp -msgid "The barrel is too short." -msgstr "Der Lauf ist zu kurz." +msgid "The barrel is too small." +msgstr "" #: src/iuse_actor.cpp msgid "The barrel is already sawn-off." @@ -241694,10 +242651,6 @@ msgstr "" msgid "stamina" msgstr "" -#: src/magic.cpp -msgid "bionic power" -msgstr "" - #: src/magic.cpp msgid "error: energy_type" msgstr "" @@ -243733,7 +244686,7 @@ msgid "You smash %s with all your might but %s remains in their hands!" msgstr "" "Mir aller Machst schlƤgst du auf %s zu, jedoch bleibt %s in den HƤnden!" -#: src/melee.cpp src/npctalk.cpp +#: src/melee.cpp src/talker_npc.cpp #, c-format msgid "%s is hostile!" msgstr "%s ist feindlich!" @@ -244572,6 +245525,36 @@ msgctxt "memorial_female" msgid "Died of a drug overdose." msgstr "Starb an einer Ɯberdosis Drogen." +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died from loss of red blood cells." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died from loss of red blood cells." +msgstr "" + #: src/memorial_logger.cpp msgctxt "memorial_male" msgid "Succumbed to the infection." @@ -248581,10 +249564,6 @@ msgctxt "Paralyze as an action" msgid "paralyze" msgstr "paralysieren" -#: src/monster.cpp -msgid "cause bleed" -msgstr "Blutungen verursachen" - #: src/monster.cpp msgid "It has a head." msgstr "Hat einen Kopf." @@ -249664,6 +250643,15 @@ msgstr "" msgid "%s (activated)" msgstr "" +#: src/newcharacter.cpp +msgid "Profession proficiencies:" +msgstr "" + +#: src/newcharacter.cpp +msgctxt "Profession has no proficiencies" +msgid "None" +msgstr "Keine" + #: src/newcharacter.cpp msgid "Pets:" msgstr "" @@ -249922,8 +250910,12 @@ msgid "" msgstr "" #: src/newcharacter.cpp -msgid "_______NO NAME ENTERED!_______" -msgstr "___KEINEN NAMEN EINGEGEBEN!___" +msgid "--- NO NAME ENTERED ---" +msgstr "" + +#: src/newcharacter.cpp +msgid "--- RANDOM NAME ---" +msgstr "" #: src/newcharacter.cpp #, c-format @@ -250012,15 +251004,19 @@ msgid "Enter height in centimeters. Minimum 145, maximum 200" msgstr "Gib deine GrĆ¶ĆŸe in cm an. Min 145, Max 200" #: src/newcharacter.cpp -msgid "Enter blood type (omit Rh):" +msgid "Select blood type" msgstr "" #: src/newcharacter.cpp -msgid "Invalid blood type." +msgid "Select Rh factor" msgstr "" #: src/newcharacter.cpp -msgid "Enter Rh factor:" +msgid "negative" +msgstr "" + +#: src/newcharacter.cpp +msgid "positive" msgstr "" #: src/newcharacter.cpp @@ -250407,6 +251403,25 @@ msgstr " beruhigt sich." msgid " is no longer afraid." msgstr " hat keine Angst mehr." +#: src/npc.cpp +#, c-format +msgid "I'm holing up here for safety. Long term, %s" +msgstr "" + +#: src/npc.cpp +msgid "I run the shop here." +msgstr "Mir gehƶrt dieses GeschƤft." + +#: src/npc.cpp +#, c-format +msgid "Currently, I'm guarding this location. Overall, %s" +msgstr "" + +#: src/npc.cpp +#, c-format +msgid "Right now, I'm . In general, %s" +msgstr "" + #: src/npcmove.cpp msgid "" msgstr "" @@ -250558,6 +251573,15 @@ msgstr "" msgid "My %s is bleeding!" msgstr "Mein %s blutet!" +#: src/npcmove.cpp +#, c-format +msgid "My %s is bleeding badly!" +msgstr "" + +#: src/npcmove.cpp +msgid "I've lost lot of blood." +msgstr "" + #: src/npcmove.cpp #, c-format msgid "%1$s reloads their %2$s." @@ -250804,11 +251828,6 @@ msgstr "Du schreist Ā»%sĀ«" msgid "%s yelling %s" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%s is fleeing from you!" -msgstr "%s flieht vor dir!" - #: src/npctalk.cpp #, c-format msgid "%s talked to you." @@ -250869,37 +251888,6 @@ msgstr "" msgid "Here's what I can teach youā€¦" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%d.%d miles." -msgstr "%d,%d Meilen." - -#: src/npctalk.cpp -#, c-format -msgid "%d foot." -msgid_plural "%d feet." -msgstr[0] "%d FuƟ." -msgstr[1] "%d FuƟ." - -#: src/npctalk.cpp -#, c-format -msgid "I'm holing up here for safety. Long term, %s" -msgstr "" - -#: src/npctalk.cpp -msgid "I run the shop here." -msgstr "Mir gehƶrt dieses GeschƤft." - -#: src/npctalk.cpp -#, c-format -msgid "Currently, I'm guarding this location. Overall, %s" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "Right now, I'm . In general, %s" -msgstr "" - #: src/npctalk.cpp msgid "&You yell, but can't hear yourself." msgstr "&Du schreist, aber du kannst dich nicht hƶren." @@ -250908,74 +251896,6 @@ msgstr "&Du schreist, aber du kannst dich nicht hƶren." msgid "&You yell." msgstr "&Du schreist." -#: src/npctalk.cpp -msgid "&You can't make anything out." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "Str %d - %d" -msgstr "StƤ %d ā€“ %d" - -#: src/npctalk.cpp -#, c-format -msgid " Dex %d - %d" -msgstr " Ges %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Int %d - %d" -msgstr " Int %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Per %d - %d" -msgstr " Wah %d - %d" - -#: src/npctalk.cpp -msgid "Dead tired" -msgstr "TodmĆ¼de" - -#: src/npctalk.cpp -msgid "Not tired" -msgstr "Nicht mĆ¼de" - -#: src/npctalk.cpp -msgid ". Will need sleep in " -msgstr ". Muss schlafen in " - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need water in " -msgstr "" -"\n" -"Wird Wasser brauchen in " - -#: src/npctalk.cpp -msgid "" -"\n" -"Thirsty" -msgstr "" -"\n" -"Durstig" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need food in " -msgstr "" -"\n" -"Wird Essen brauchen in " - -#: src/npctalk.cpp -msgid "" -"\n" -"Hungry" -msgstr "" -"\n" -"Hungrig" - #: src/npctalk.cpp msgid "YES, MASTER!" msgstr "JA, MEISTER!" @@ -250989,34 +251909,6 @@ msgstr "Ich habe Neuigkeiten." msgid "Yes, let's resume training %s" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%s: 1 hour lesson (cost %s)" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "%s: teaching spell knowledge (cost %s)" -msgstr "" - -#. ~Martial art style (cost in dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s ( cost $%d )" -msgstr "%s ( Kosten: %d $ )" - -#. ~Skill name: current level (exercise) -> next level (exercise) (cost in -#. dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%)" -msgstr "" - #: src/npctalk.cpp msgid "Okay, thanks." msgstr "Okay, danke." @@ -251029,10 +251921,6 @@ msgstr "Lass uns weitergehen." msgid "OBEY ME!" msgstr "GEHORCH MIR!" -#: src/npctalk.cpp src/player.cpp -msgid "fists" -msgstr "FƤuste" - #: src/npctalk.cpp msgid "BADAMMO" msgstr "BADAMMO" @@ -251104,7 +251992,7 @@ msgctxt "you say something" msgid "You: %s" msgstr "Du: %s" -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp msgid "You can't afford it!" msgstr "" @@ -251115,7 +252003,7 @@ msgid "%1$s gives you a %2$s." msgstr "" #. ~ %1%s is the NPC name, %2$d is a number of items, %3$s are items -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp #, c-format msgid "%1$s gives you %2$d %3$s." msgstr "" @@ -251144,97 +252032,11 @@ msgstr "" msgid "%1$s doesn't have a %2$s!" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%1$s gives you %2$s." -msgstr "" - #: src/npctalk.cpp #, c-format msgid "You learn how to craft %s." msgstr "" -#: src/npctalk.cpp -msgid "I don't trust you enough to eat THISā€¦" -msgstr "" - -#: src/npctalk.cpp -msgid "It doesn't look like a good idea to consume thisā€¦" -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, that hit the spot." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "I need a %s to consume that!" -msgstr "Ich brauche 1 %s, um dies zu konsumieren!" - -#: src/npctalk.cpp -msgid "Thanks, I feel better already." -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I used it." -msgstr "" - -#: src/npctalk.cpp -msgid "Offer what?" -msgstr "Was anbieten?" - -#: src/npctalk.cpp -msgid "You have no items to offer." -msgstr "Du hast keine GegenstƤnde zum Anbieten." - -#: src/npctalk.cpp -msgid "Changed your mind?" -msgstr "Hast du es dir anders Ć¼berlegt?" - -#: src/npctalk.cpp -msgid "How?" -msgstr "Wie?" - -#: src/npctalk.cpp -msgid "Are you insane!?" -msgstr "Bist du verrĆ¼ckt!?" - -#: src/npctalk.cpp -msgid "Thanks, I'll wield that now." -msgstr "" - -#: src/npctalk.cpp -msgid " Should I take something off?" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "" -"My current weapon is better than this.\n" -"(new weapon value: %.1f vs %.1f)." -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I'll carry that now." -msgstr "" - -#: src/npctalk.cpp -msgid "I have no space to store it." -msgstr "Ich habe keinen Platz, um es einzulagern." - -#: src/npctalk.cpp -#, c-format -msgid "I can only store %s %s more." -msgstr "Ich kann nur noch %s %s einlagern." - -#: src/npctalk.cpp -msgid "ā€¦or to store anything else for that matter." -msgstr "" - -#: src/npctalk.cpp -msgid "It is too heavy for me to carry." -msgstr "Es ist zu schwer fĆ¼r mich, es zu tragen." - #: src/npctalk_funcs.cpp msgid "Reward" msgstr "Belohnung" @@ -253105,13 +253907,15 @@ msgid "A scaling factor that determines density of item spawns." msgstr "Ein Skalierungsfaktor, der die Dichte der Gegenstandsspawns festlegt." #: src/options.cpp -msgid "NPC spawn rate scaling factor" -msgstr "NPC-Spawnraten-Skalierungsfaktor" +msgid "Random NPC spawn time" +msgstr "" #: src/options.cpp -msgid "A scaling factor that determines density of dynamic NPC spawns." +msgid "" +"Baseline average number of days between random NPC spawns. Average duration" +" goes up with the number of NPCs already spawned. Set to 0 days to disable " +"random NPCs." msgstr "" -"Ein Skalierungsfaktor, der die Dichte der dynamischen NPC-Spawns festlegt." #: src/options.cpp msgid "Monster evolution scaling factor" @@ -253254,39 +254058,6 @@ msgstr "" "Falls wahr, tauchen Zombies an UnterkĆ¼nften auf. Macht den Start des Spiels " "wesentlich schwieriger." -#: src/options.cpp -msgid "Static NPCs" -msgstr "Statische NPCs" - -#: src/options.cpp -msgid "" -"If true, static NPCs will spawn at pre-defined locations. Requires world " -"reset." -msgstr "" - -#: src/options.cpp -msgid "Starting NPCs spawn" -msgstr "Startende NPCs spawnen" - -#: src/options.cpp -msgid "" -"Determines whether starting NPCs should spawn, and if they do, how exactly." -msgstr "" -"Legt fest, ob startende NPCs auftauchen sollten, und, wenn sie auftauchen, " -"wie genau." - -#: src/options.cpp -msgid "Scenario-based" -msgstr "Szenariobasiert" - -#: src/options.cpp -msgid "Random NPCs" -msgstr "ZufƤllige NPCs" - -#: src/options.cpp -msgid "If true, the game will randomly spawn NPCs during gameplay." -msgstr "Falls wahr, wird das Spiel zufƤllig NPCs im Spiel auftauchen lassen." - #: src/options.cpp msgid "Mutations by radiation" msgstr "Mutationen durch Strahlung" @@ -255071,6 +255842,38 @@ msgstr "Du versuchst, das Feuer auf dir zu lƶschen!" msgid " attempts to put out the fire on them!" msgstr " versucht, das eigene Feuer zu lƶschen." +#: src/player.cpp +msgid "" +"Your broken limb significantly hampers your efforts to puting pressure on " +"the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s broken limb significantly hampers efforts of putting pressure on" +" the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"Your hands are too encumbred to effectivly put pressure on the bleeding " +"wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s hands are too encumbred to effectivly put pressure on the " +"bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "You attempt to put pressure on the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid " attempts to put pressure on the bleeding wound!" +msgstr "" + #: src/player.cpp #, c-format msgid "Your ground sonar detected a %1$s to the %2$s!" @@ -255345,33 +256148,6 @@ msgstr "Nichts zum Nachladen!" msgid "You don't have any %s to reload your %s!" msgstr "Du hast keine %s, um %s nachzuladen." -#: src/player.cpp -msgid "Can't wield spilt liquids." -msgstr "VerschĆ¼ttete FlĆ¼ssigkeiten kƶnnen nicht gehalten werden." - -#: src/player.cpp -msgid "You need at least one arm to even consider wielding something." -msgstr "" - -#: src/player.cpp -#, c-format -msgid "The %s is preventing you from wielding the %s." -msgstr "" - -#: src/player.cpp -msgid "Something you are wearing hinders the use of both hands." -msgstr "Etwas, was du trƤgst, hindert dich daran, beide HƤnde zu benutzen." - -#: src/player.cpp -#, c-format -msgid "The %s can't be wielded with only one arm." -msgstr "%s kann nicht mit nur einem Arm gehalten werden." - -#: src/player.cpp -#, c-format -msgid "You are too weak to wield %s with only one arm." -msgstr "Du bist zu schwach, um %s mit nur einem Arm zu halten." - #: src/player.cpp msgid "Keep hands free (off)" msgstr "HƤnde freihalten (aus)" @@ -255558,15 +256334,6 @@ msgstr "Dein %s ist nicht aufgeladen." msgid "Your %s isn't loaded." msgstr "Dein %s ist nicht geladen." -#: src/player.cpp -#, c-format -msgid "You recover %i unused plutonium." -msgstr "Du verwertest %i unbenutztes Plutonium wieder." - -#: src/player.cpp -msgid "You can't remove partially depleted plutonium!" -msgstr "Du kannst teilweise verbrauchtes Plutonium nicht entfernen!" - #. ~ %1$s - gunmod, %2$s - gun. #: src/player.cpp #, c-format @@ -255711,27 +256478,6 @@ msgstr "" msgid "Your soporific inducer starts back up." msgstr "" -#: src/player.cpp -#, c-format -msgid "Your skill in %s has increased to %d!" -msgstr "Deine Fertigkeit in %s hat sich auf %d erhƶht!" - -#: src/player.cpp -#, c-format -msgid "You feel that %s tasks of this level are becoming trivial." -msgstr "Du merkst, dass %s-Aufgaben dieser Stufe trivial werden." - -#: src/player.cpp -#, c-format -msgid "This task is too simple to train your %s beyond %d." -msgstr "" -"Diese TƤtigkeit ist zu simpel, um deine Fertigkeit Ā»%sĀ« Ć¼ber den Wert Ā»%dĀ« " -"hinaus zu trainieren." - -#: src/player.cpp -msgid " (empty)" -msgstr "" - #: src/player.cpp msgid "Wield what?" msgstr "Was halten?" @@ -255787,6 +256533,10 @@ msgstr "WIRKUNGEN" msgid "SPEED" msgstr "GESCHWINDIGKEIT" +#: src/player_display.cpp +msgid "PROFICIENCIES" +msgstr "" + #: src/player_display.cpp #, c-format msgid "Swimming movement point cost: %+d\n" @@ -256648,6 +257398,149 @@ msgstr "" "Du lƶst dich in wunderschƶne Freudentaumel aus Energie auf. Das Leben " "verschwimmt aus deinen Nebeln und hƶrst auf, zu sein." +#: src/player_hardcoded_effects.cpp +msgid "You bleed to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " bleeds to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your heart can't keep up the pace and fails!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks pale and you feel anxious and thirsty. Blood loss?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"Your pale skin is sweating, your heart beats fast and you feel restless. " +"Maybe you lost too much blood?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You're unsettlingly white, but your fingetips are bluish. You are agitated " +"and your heart is racing. Your blood loss must be serious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You are pale as a ghost, dripping wet from the sweat, and sluggish despite " +"your heart racing like a train. You are on a brink of colapse from effects " +"of a bood loss." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and lightheaded." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel tired and you breathe heavily." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are anxcious and cannot collect your thoughts." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are sweating profusely, but you feel cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You huff and puff. Your breath is rapid and shallow." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You drop to the ground, fighting to keep yourself conscious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your mind slips away." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You cannot breathe and your body gives out!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " gasps for air and dies!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your hands feel unusually cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your feet feel unusualy cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks very pale." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel weak. Where has your strength gone?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel feeble. A gust of wind could make you stumble." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "There is an overwhelming aura of tiredness inside of you." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Rest is what you want. Rest is what you need." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and can't coordinate movement of your feet." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your muscles are quivering." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You crave for ice. Dirt under your feet looks tasty too." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your whole mouth is sore, and your tongue is swollen." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel lightheaded. And a migrane follows." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your legs are restless. Urge to move them is so strong." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel like you'd sleep on a rock." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You gasp for air!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Can't breathe. Must rest." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You can't take it any more. Rest first, everything else later." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You must sit down for a moment. Just a moment." +msgstr "" + #. ~ %s is bodypart name. #: src/player_hardcoded_effects.cpp #, c-format @@ -257257,6 +258150,11 @@ msgstr "%s-Verzƶgerung: %i" msgid "Turrets in range: %d/%d" msgstr "" +#: src/recipe.cpp +#, c-format +msgid "Proficiencies Used: %s" +msgstr "" + #: src/recipe.cpp msgid "none" msgstr "keine" @@ -258030,6 +258928,14 @@ msgstr "" msgid "You fall over!" msgstr "Du fƤllst um!" +#: src/suffer.cpp +msgid "Your tourniquet hurts you." +msgstr "" + +#: src/suffer.cpp +msgid " is hurting from the tourniquet." +msgstr "" + #: src/suffer.cpp #, c-format msgid "Your radiation badge changes from %1$s to %2$s!" @@ -258049,6 +258955,209 @@ msgstr "" msgid "You feel the water burning your skin." msgstr "" +#: src/talker_avatar.cpp +#, c-format +msgid "%s can't sell you any %s" +msgstr "" + +#: src/talker_avatar.cpp +#, c-format +msgid "%1$s gives you %2$s." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%d.%d miles." +msgstr "%d,%d Meilen." + +#: src/talker_npc.cpp +#, c-format +msgid "%d foot." +msgid_plural "%d feet." +msgstr[0] "%d FuƟ." +msgstr[1] "%d FuƟ." + +#: src/talker_npc.cpp +#, c-format +msgid "%s is fleeing from you!" +msgstr "%s flieht vor dir!" + +#. ~Skill name: current level (exercise) -> next level (exercise) (cost in +#. dollars) +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s ( cost $%d )" +msgstr "%s ( Kosten: %d $ )" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: 1 hour lesson (cost %s)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: teaching spell knowledge (cost %s)" +msgstr "" + +#: src/talker_npc.cpp +msgid "I don't trust you enough to eat THISā€¦" +msgstr "" + +#: src/talker_npc.cpp +msgid "It doesn't look like a good idea to consume thisā€¦" +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, that hit the spot." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "I need a %s to consume that!" +msgstr "Ich brauche 1 %s, um dies zu konsumieren!" + +#: src/talker_npc.cpp +msgid "Thanks, I feel better already." +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I used it." +msgstr "" + +#: src/talker_npc.cpp +msgid "Offer what?" +msgstr "Was anbieten?" + +#: src/talker_npc.cpp +msgid "You have no items to offer." +msgstr "Du hast keine GegenstƤnde zum Anbieten." + +#: src/talker_npc.cpp +msgid "Changed your mind?" +msgstr "Hast du es dir anders Ć¼berlegt?" + +#: src/talker_npc.cpp +msgid "How?" +msgstr "Wie?" + +#: src/talker_npc.cpp +msgid "Are you insane!?" +msgstr "Bist du verrĆ¼ckt!?" + +#: src/talker_npc.cpp +msgid "Thanks, I'll wield that now." +msgstr "" + +#: src/talker_npc.cpp +msgid " Should I take something off?" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "" +"My current weapon is better than this.\n" +"(new weapon value: %.1f vs %.1f)." +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I'll carry that now." +msgstr "" + +#: src/talker_npc.cpp +msgid "I have no space to store it." +msgstr "Ich habe keinen Platz, um es einzulagern." + +#: src/talker_npc.cpp +#, c-format +msgid "I can only store %s %s more." +msgstr "Ich kann nur noch %s %s einlagern." + +#: src/talker_npc.cpp +msgid "ā€¦or to store anything else for that matter." +msgstr "" + +#: src/talker_npc.cpp +msgid "It is too heavy for me to carry." +msgstr "Es ist zu schwer fĆ¼r mich, es zu tragen." + +#: src/talker_npc.cpp +msgid "&You can't make anything out." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "Str %d - %d" +msgstr "StƤ %d ā€“ %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Dex %d - %d" +msgstr " Ges %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Int %d - %d" +msgstr " Int %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Per %d - %d" +msgstr " Wah %d - %d" + +#: src/talker_npc.cpp +msgid "Dead tired" +msgstr "TodmĆ¼de" + +#: src/talker_npc.cpp +msgid "Not tired" +msgstr "Nicht mĆ¼de" + +#: src/talker_npc.cpp +msgid ". Will need sleep in " +msgstr ". Muss schlafen in " + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need water in " +msgstr "" +"\n" +"Wird Wasser brauchen in " + +#: src/talker_npc.cpp +msgid "" +"\n" +"Thirsty" +msgstr "" +"\n" +"Durstig" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need food in " +msgstr "" +"\n" +"Wird Essen brauchen in " + +#: src/talker_npc.cpp +msgid "" +"\n" +"Hungry" +msgstr "" +"\n" +"Hungrig" + #: src/teleport.cpp msgid "You feel a strange, inwards force." msgstr "" @@ -259890,6 +260999,34 @@ msgstr ", %3.1f%% / Stunden, %s bis %s" msgid "pile-up" msgstr "Auffahrunfall" +#: src/vehicle_move.cpp +msgid "Smart controller does not support flying vehicles." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller detects only a single controllable engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller is designed to control more than one engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller does not support more than five engines." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller is shutting down." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller failed to start an engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller optimizes engine state." +msgstr "" + #: src/vehicle_move.cpp #, c-format msgid "The %s is too leaky!" @@ -260267,6 +261404,11 @@ msgctxt "electronics menu option" msgid "water purifier" msgstr "Wasserreiniger" +#: src/vehicle_use.cpp +msgctxt "electronics menu option" +msgid "smart controller" +msgstr "" + #: src/vehicle_use.cpp msgid "Turn off camera system" msgstr "Kamerasystem ausschalten" @@ -260903,50 +262045,18 @@ msgstr "Zu wenig Strom, um die Inhalte aus %2$s von %1$s zu reinigen" msgid "You purify the contents of the %1$s's %2$s" msgstr "Du reinigst die Inhalte aus %2$s von %1$s" -#: src/weather.cpp -msgid "You hear a distant rumble of thunder." -msgstr "Du hƶrst ein fernes Donnern." - -#: src/weather.cpp -msgid "You hear a rumble of thunder from above." -msgstr "Du hƶrst einen Donner Ć¼ber dir." - -#: src/weather.cpp -msgid "A flash of lightning illuminates your surroundings!" -msgstr "Ein Blitzstrahl erhellt deine Umgebung!" - #: src/weather.cpp #, c-format -msgid "Your %s protects you from the acidic drizzle." -msgstr "%s schĆ¼tzt dich vor dem sauren Nieseln." - -#: src/weather.cpp -msgid "Your clothing protects you from the acidic drizzle." -msgstr "Deine Bekleidung schĆ¼tzt dich vor dem sauren Nieseln." - -#: src/weather.cpp -msgid "Your power armor protects you from the acidic drizzle." -msgstr "Deine EnergierĆ¼stung schĆ¼tzt dich vor dem saurem Nieseln." - -#: src/weather.cpp -msgid "The acid rain stings, but is mostly harmless for nowā€¦" +msgid "Your %s protects you from the weather." msgstr "" #: src/weather.cpp -msgid "Your umbrella protects you from the acid rain." -msgstr "Dein Regenschirm schĆ¼tzt dich vor dem sauren Regen." - -#: src/weather.cpp -msgid "Your clothing protects you from the acid rain." -msgstr "Deine Kleidung schĆ¼tzt dich vor dem sauren Regen." - -#: src/weather.cpp -msgid "Your power armor protects you from the acid rain." -msgstr "Deine EnergierĆ¼stung schĆ¼tzt dich vor dem sauren Regen." +msgid "Your clothing protects you from the weather." +msgstr "" #: src/weather.cpp -msgid "The acid rain burns!" -msgstr "Der saure Regen brennt!" +msgid "Your power armor protects you from the weather." +msgstr "" #: src/weather.cpp msgid "Monday" @@ -261121,54 +262231,6 @@ msgstr "Orkan" msgid "The weather changed to %s!" msgstr "Das Wetter ist nun: %s." -#: src/weather_data.cpp -msgid "Clear" -msgstr "Klar" - -#: src/weather_data.cpp -msgid "Sunny" -msgstr "Sonnig" - -#: src/weather_data.cpp -msgid "Cloudy" -msgstr "Bewƶlkt" - -#: src/weather_data.cpp -msgid "Light Drizzle" -msgstr "Leichter Nieselregen" - -#: src/weather_data.cpp -msgid "Drizzle" -msgstr "Nieselregen" - -#: src/weather_data.cpp -msgid "Rain" -msgstr "Regen" - -#: src/weather_data.cpp -msgid "Thunder Storm" -msgstr "Gewitter" - -#: src/weather_data.cpp -msgid "Acidic Drizzle" -msgstr "Saures Nieseln" - -#: src/weather_data.cpp -msgid "Acid Rain" -msgstr "Saurer Regen" - -#: src/weather_data.cpp -msgid "Flurries" -msgstr "Schneegestƶber" - -#: src/weather_data.cpp -msgid "Snowing" -msgstr "Schnee" - -#: src/weather_data.cpp -msgid "Snowstorm" -msgstr "Schneesturm" - #: src/wish.cpp msgid "Nonvalid" msgstr "UngĆ¼ltig" @@ -261360,6 +262422,19 @@ msgstr "WƤhle eine Welt, um das Spiel zu starten" msgid "last world info" msgstr "" +#: src/worldfactory.cpp +msgid "MISSING MODS" +msgstr "" + +#: src/worldfactory.cpp +msgid "OBSOLETE MODS" +msgstr "" + +#: src/worldfactory.cpp +#, c-format +msgid " [%s]" +msgstr "" + #: src/worldfactory.cpp msgid " ACTIVE WORLD MODS " msgstr " AKTIVE WELT-MODS " diff --git a/lang/po/es_AR.po b/lang/po/es_AR.po index 9681701566443..bd3a51dbd0b48 100644 --- a/lang/po/es_AR.po +++ b/lang/po/es_AR.po @@ -1,15 +1,15 @@ # # Translators: # Vlasov Vitaly , 2020 -# Brett Dong , 2020 # Diego Gonzalo Ballesteros Palomo , 2020 +# Brett Dong , 2020 # Noctivagante , 2020 # msgid "" msgstr "" "Project-Id-Version: cataclysm-dda 0.E\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-07-08 10:07+0800\n" +"POT-Creation-Date: 2020-07-16 21:36+0800\n" "PO-Revision-Date: 2018-04-26 14:47+0000\n" "Last-Translator: Noctivagante , 2020\n" "Language-Team: Spanish (Argentina) (https://www.transifex.com/cataclysm-dda-translators/teams/2217/es_AR/)\n" @@ -8173,6 +8173,62 @@ msgstr "" "Es una pequeƱa madera que sirve para ayudar a mantener los huesos en su " "lugar. EstĆ” especĆ­ficamente diseƱada para supervivientes enormes." +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm)" +msgid_plural "tourniquets (arm)" +msgstr[0] "torniquete (brazo)" +msgstr[1] "torniquetes (brazo)" + +#. ~ Use action menu_text for {'str': 'tourniquet (arm)', 'str_pl': +#. 'tourniquets (arm)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (arm XL)', 'str_pl': +#. 'tourniquets (arm XL)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (leg)', 'str_pl': +#. 'tourniquets (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "Adjust" +msgstr "Ajustar" + +#. ~ Use action msg for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'}. +#. ~ Use action msg for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'}. +#. ~ Use action msg for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "You adjust the tourniquet." +msgstr "Te ajustĆ”s el torniquete." + +#. ~ Description for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'} +#. ~ Description for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'} +#. ~ Description for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'} +#: lang/json/ARMOR_from_json.py +msgid "" +"First aid device used to apply pressure to a limb or extremity in order to " +"limit blood flow. Should be employed only to manage heavy bleedings, " +"because prolonged use will harm the limb. It can be adjusted in size to fit" +" different limbs." +msgstr "" +"Es un dispositivo de primeros auxilios que sirve para aplicar presiĆ³n en una" +" extremidad para limitar el flujo de sangre. Solo deberĆ­a usarse en caso de " +"sangrados grandes, porque el uso prolongado lastimarĆ” la extremidad. Puede " +"ser ajustado para adecuarse a las diferentes extremidades." + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm XL)" +msgid_plural "tourniquets (arm XL)" +msgstr[0] "torniquete (brazo XL)" +msgstr[1] "torniquetes (brazo XL)" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (leg)" +msgid_plural "tourniquets (leg)" +msgstr[0] "torniquete (pierna)" +msgstr[1] "torniquetes (pierna)" + #: lang/json/ARMOR_from_json.py msgid "blindfold" msgid_plural "blindfolds" @@ -29557,7 +29613,7 @@ msgid "" "A short paper of the economic viability of constructing an agricultural " "outpost." msgstr "" -"Un artĆ­culo corto sobre la viabilidad econĆ³mica de construir un puesto " +"Es un artĆ­culo corto sobre la viabilidad econĆ³mica de construir un puesto " "agrĆ­cola." #. ~ Description for {'str': 'standpipe maintenance log'} @@ -44642,6 +44698,23 @@ msgstr "" " comĆŗnmente es recetada para tratar el trastorno de hiperactividad con " "dĆ©ficit de atenciĆ³n. Calma el apetito y es bastante adictivo." +#: lang/json/COMESTIBLE_from_json.py +msgid "adhesive bandage" +msgid_plural "adhesive bandages" +msgstr[0] "venda adhesiva" +msgstr[1] "vendas adhesivas" + +#. ~ Description for {'str': 'adhesive bandage'} +#: lang/json/COMESTIBLE_from_json.py +msgid "" +"A set of small medical dressings, each made of a piece of sterile cloth and " +"a sticky tape, used for small injuries not serious enough to require a full-" +"size bandage." +msgstr "" +"Es un equipo de vendajes mĆ©dicos, cada uno hecho de un pedazo esterilizado " +"de tela y cinta adhesiva. Se usan para pequeƱas heridas que no necesitan una" +" venda de tamaƱo completo." + #: lang/json/COMESTIBLE_from_json.py msgid "syringe of adrenaline" msgid_plural "syringes of adrenaline" @@ -44737,8 +44810,12 @@ msgstr[1] "vendas" #. ~ Description for {'str': 'bandage'} #: lang/json/COMESTIBLE_from_json.py -msgid "Simple cloth bandages. Used for healing small amounts of damage." -msgstr "Son vendas comunes de tela. Se usan para curar lastimaduras pequeƱas." +msgid "" +"Simple cloth bandages. Used for stopping bloodloss and protecting wounds " +"from external factors." +msgstr "" +"Son vendas comunes de tela. Se usan para frenar hemorragias y proteger las " +"heridas de factores externos." #: lang/json/COMESTIBLE_from_json.py msgid "makeshift bandage" @@ -54861,8 +54938,8 @@ msgstr "" #: lang/json/GENERIC_from_json.py msgid "gallon jug" msgid_plural "gallon jugs" -msgstr[0] "jarro de galĆ³n" -msgstr[1] "jarros de galĆ³n" +msgstr[0] "bidĆ³n de 4 litros" +msgstr[1] "bidones de 4 litros" #. ~ Description for {'str': 'gallon jug'} #: lang/json/GENERIC_from_json.py @@ -55815,11 +55892,11 @@ msgstr[1] "paquetes de tablas" #. planks'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten construction planks securely lashed together with a rope. Disassemble " -"to unpack." +"Ten construction planks securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" -"Son diez tablas atadas juntas con una soga. Hay que desarmarlo para " -"desatarlas." +"Son diez tablas atadas juntas para facilitar su transporte. Hay que " +"desarmarlo para desatarlas." #: lang/json/GENERIC_from_json.py msgid "bundle of stout branches" @@ -55831,11 +55908,27 @@ msgstr[1] "paquetes de ramas fuertes" #. stout branches'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten stout branches securely lashed together with a rope. Disassemble to " -"untie them." +"Ten stout branches securely tied together for easier transport. Disassemble" +" to untie them." +msgstr "" +"Son diez ramas fuertes atadas juntas para facilitar su transporte. Hay que " +"desarmarlo para desatarlas." + +#: lang/json/GENERIC_from_json.py +msgid "bundle of long stout branches" +msgid_plural "bundles of long stout branches" +msgstr[0] "paquete de ramas fuertes largas" +msgstr[1] "paquetes de ramas fuertes largas" + +#. ~ Description for {'str': 'bundle of long stout branches', 'str_pl': +#. 'bundles of long stout branches'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Five long stout branches securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" -"Son diez ramas fuertes atadas juntas con una soga. Hay que desarmarlo para " -"desatarlas." +"Son cinco ramas fuertes atadas juntas para facilitar su transporte. Hay que " +"desarmarlo para desatarlas." #: lang/json/GENERIC_from_json.py msgid "t-substrate sample" @@ -58125,6 +58218,12 @@ msgstr "" "Es un TALON UGV con su chasis roto y perdiendo fluidos. Puede ser desarmado " "para recuperar partes." +#: lang/json/GENERIC_from_json.py +msgid "broken laser turret" +msgid_plural "broken laser turrets" +msgstr[0] "torreta lĆ”ser rota" +msgstr[1] "torretas lĆ”ser rotas" + #: lang/json/GENERIC_from_json.py msgid "fire brick" msgid_plural "fire bricks" @@ -58790,12 +58889,6 @@ msgstr "" " extraƱo, pero parece un poco frĆ”gil. Tampoco parece que pueda soportar un " "panel de refuerzo." -#: lang/json/GENERIC_from_json.py -msgid "broken laser turret" -msgid_plural "broken laser turrets" -msgstr[0] "torreta lĆ”ser rota" -msgstr[1] "torretas lĆ”ser rotas" - #: lang/json/GENERIC_from_json.py msgid "TX-5LR Laser Cannon" msgid_plural "TX-5LR Laser Cannons" @@ -59746,11 +59839,11 @@ msgstr[1] "masas madre nuevas" #. ~ Use action msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py msgid "" -"After feeding it and caring for it for weeks, your sourdough starter is " +"After feeding it and caring for it for a week, your sourdough starter is " "finally ready for the big leagues." msgstr "" -"Luego de alimentarla y cuidarla por semanas, la masa madre estĆ” finalmente " -"preparada para jugar en primera." +"Luego de alimentarla y cuidarla por una semana, la masa madre estĆ” " +"finalmente preparada para jugar en primera." #. ~ Use action not_ready_msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py @@ -59792,10 +59885,10 @@ msgstr "La masa en fermentaciĆ³n todavĆ­a no estĆ” lista." #: lang/json/GENERIC_from_json.py msgid "" "This jar contains a floury paste with sourdough starter mixed in. It needs " -"a few hours to recover its strength before it can be used again." +"a day to recover its strength before it can be used again." msgstr "" "Este frasco contiene una pasta harinosa con masa madre mezclada adentro. " -"Necesita unas horas para recuperar su fuerza antes de que se pueda volver a " +"Necesita un dĆ­a para recuperar su fuerza antes de que se pueda volver a " "usar." #: lang/json/GENERIC_from_json.py @@ -59854,13 +59947,31 @@ msgstr[1] "botiquines de primeros auxilios" #. ~ Description for {'str': 'first aid kit'} #: lang/json/GENERIC_from_json.py msgid "" -"A full medical kit, with bandages, local anesthetics, and rapid healing " -"agents. Used for healing large amounts of damage. Disassemble to get its " -"content." +"A typical universal first aid kit, one you'd see in a car or in a household." +" It contains a variety of common medical items stored in case of accidents " +"and injuries. Disassemble to get its content." +msgstr "" +"Es el equipo tĆ­pico de primeros auxilios, el que encontrĆ”s en un auto o en " +"una casa. Contiene una variedad de objetos mĆ©dicos comunes guardados en caso" +" de accidentes o heridas. Hay que desarmarlo para obtener su contenido." + +#: lang/json/GENERIC_from_json.py +msgid "IFAK" +msgid_plural "IFAKs" +msgstr[0] "IFAK" +msgstr[1] "IFAK" + +#. ~ Description for {'str': 'IFAK'} +#: lang/json/GENERIC_from_json.py +msgid "" +"An IFAK, or individual first aid kit, is a specialized set of wound " +"dressings and accessories, and being of military origin focuses on combat " +"trauma and preventing blood loss. Disassemble to get its content." msgstr "" -"Es un botiquĆ­n mĆ©dico completo, con vendas, anestesias y agentes de " -"aceleraciĆ³n curativa. Se usa para curar grandes heridas. Hay que desarmarlo " -"para acceder a su contenido." +"El IFAK (del inglĆ©s Individual First Aid Kit) es un equipo especializado de " +"accesorios y vendajes para atender heridas, y como es de origen militar es " +"especial para heridas de combate y frenar hemorragias. Hay que desarmarlo " +"para obtener su contenido." #: lang/json/GENERIC_from_json.py msgid "MRE" @@ -60937,7 +61048,7 @@ msgid "" "Imagine the thinnest, most disposable paper you could possibly make. Now " "imagine something thinner than that." msgstr "" -"Imaginate el papel mĆ”s fino, mĆ”s deshechabla que se pueda hacer. Ahora " +"Imaginate el papel mĆ”s fino, mĆ”s desechable que se pueda hacer. Ahora " "imaginate algo mĆ”s fino que eso." #: lang/json/GENERIC_from_json.py @@ -61516,7 +61627,7 @@ msgid "" "can be exchanged for food, water, and other services through the Free " "Merchants in the Refugee Center." msgstr "" -"Es un Bono Certificado de Mercader Libre, tambiĆ©n conocido como la 'nota-c' " +"Es un Bono Certificado de Mercader Libre, tambiĆ©n conocido como la 'bono-c' " "o 'merc', es una moneda basada en los viejos billetes estadounidenses. Los " "billetes de 50 o mĆ”s grandes son impresos con una nota de pagarĆ© firmada por" " el tesorero de los Mercaderes Libres, en un diseƱo complejo. La nota " @@ -65147,11 +65258,11 @@ msgstr "" #: lang/json/GENERIC_from_json.py msgid "inscribed metal plates" -msgid_plural "inscribed metal platess" -msgstr[0] "placa inscripta de metal" -msgstr[1] "placas inscriptas de metal" +msgid_plural "inscribed metal plates" +msgstr[0] "placa metĆ”lica inscripta" +msgstr[1] "placas metĆ”licas inscriptas" -#. ~ Description for {'str': 'inscribed metal plates'} +#. ~ Description for {'str_sp': 'inscribed metal plates'} #: lang/json/GENERIC_from_json.py msgid "" "This device looks electronic, but is unfamiliar. It is a series of tightly " @@ -65197,6 +65308,44 @@ msgstr "" " alguna especie de motor o generador, pero el diseƱo no se parece a nada que" " hayas visto antes, y no te das cuenta cĆ³mo hacerlo funcionar." +#: lang/json/GENERIC_from_json.py +msgid "engraved parabolic dish" +msgid_plural "engraved parabolic dishes" +msgstr[0] "antena parabĆ³lica grabada" +msgstr[1] "antenas parabĆ³licas grabadas" + +#. ~ Description for {'str': 'engraved parabolic dish', 'str_pl': 'engraved +#. parabolic dishes'} +#: lang/json/GENERIC_from_json.py +msgid "" +"This hefty parabolic dish is engraved with an unrecognizable pattern of " +"symbols that might, at a guess, be some sort of circuitry pattern - or maybe" +" a religious incantation." +msgstr "" +"Esta pesada antena parabĆ³lica estĆ” grabada con un patrĆ³n de sĆ­mbolos " +"irreconocibles que podrĆ­an ser, suponemos, alguna clase de patrĆ³n de " +"circuito - o tal vez un mantra religioso." + +#: lang/json/GENERIC_from_json.py +msgid "oblong device" +msgid_plural "oblong devices" +msgstr[0] "dispositivo oblongo" +msgstr[1] "dispositivos oblongos" + +#. ~ Description for {'str': 'oblong device'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Perfectly smooth, cool to the touch, and a dull blue-grey colour, this looks" +" almost like a perfect riverstone at first glance. Its artificial nature is" +" betrayed on closer inspection by a network of intricate patterns visible as" +" a slight difference in the reflection of light off its surface." +msgstr "" +"Es perfectamente suave y frĆ­o al tacto y de un color azul grisĆ”ceo, a " +"primera vista parece casi una piedra de rĆ­o perfecta. Su naturaleza " +"artificial es traicionada al inspeccionarla por una red de patrones " +"intrincados visibles como una leve diferencia en el reflejo de la luz en su " +"superficie." + #: lang/json/GENERIC_from_json.py msgid "sheet of glass" msgid_plural "sheets of glass" @@ -77043,6 +77192,26 @@ msgstr "" "de las corrientes de aire. Parece capaz de suspenderse en el aire por un " "largo tiempo antes de quedarse sin energĆ­a." +#: lang/json/MONSTER_from_json.py +msgid "feral human" +msgid_plural "feral humans" +msgstr[0] "humano salvaje" +msgstr[1] "humanos salvajes" + +#. ~ Description for {'str': 'feral human'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pupils dilated and what remains to be seen of the iris and sclera are " +"bloodshot. It still breathes but the zombies treat it like one of them." +msgstr "" +"Las pupilas dilatadas y lo que queda del iris y la esclerĆ³tica estĆ”n llenos " +"de sangre. TodavĆ­a respira pero los zombis lo tratan como si fuera uno de " +"ellos." + +#: lang/json/MONSTER_from_json.py +msgid "They throw a loose brick at you!" +msgstr "Ā”Te tiran un ladrillo suelto!" + #: lang/json/MONSTER_from_json.py msgid "alpha razorclaw" msgid_plural "alpha razorclaws" @@ -81370,6 +81539,23 @@ msgstr "" "pĆ”lido por su vida subterrĆ”nea. Se mueve en manada por debajo del suelo y su" " nombre es por su hĆ”bito de infestar las cloacas." +#: lang/json/MONSTER_from_json.py +msgid "prototype laser turret" +msgid_plural "prototype laser turrets" +msgstr[0] "torreta lĆ”ser prototipo" +msgstr[1] "torretas lĆ”ser prototipo" + +#. ~ Description for {'str': 'prototype laser turret'} +#: lang/json/MONSTER_from_json.py +msgid "" +"This appears to be a very experimental automated tower. Plating-less and " +"seemingly half-built, it's little more than an oversized laser emitter and a" +" camera, both welded to a swiveling platform." +msgstr "" +"Esto parece ser una torreta automatizada muy experimental. Sin las placas y " +"a medio construir, es poco mĆ”s que un emisor lĆ”ser muy grande y una cĆ”mara, " +"los dos soldados a una plataforma giratoria." + #: lang/json/MONSTER_from_json.py msgid "blob" msgid_plural "blobs" @@ -82294,6 +82480,27 @@ msgstr "" "PodrĆ­a parecer un puma normal si no fuera que sus patas traseras estĆ”n " "agrandadas, y sus ojos resaltan con una viscosidad negra." +#: lang/json/MONSTER_from_json.py +msgid "zombie horse" +msgid_plural "zombie horses" +msgstr[0] "caballo zombi" +msgstr[1] "caballos zombis" + +#. ~ Description for {'str': 'zombie horse'} +#: lang/json/MONSTER_from_json.py +msgid "" +"From the looks of this zombie horse's ghastly features, with its protruding " +"ribs, whitish skull, and empty eyes, the exposed part of the internal organs" +" shows a seemingly lifeless color, and the black body fluid drips slowly. " +"The new strength makes the horse no longer dependent on its muscles, but it " +"can still pursue the enemy quickly." +msgstr "" +"Por la apariencia de los rasgos de este caballo zombi horroroso, con sus " +"costillas saltonas, crĆ”neo blanquecino y los ojos vacĆ­os. La parte expuesta " +"de sus Ć³rganos internos muestran un color sin vida, y un fluido negro " +"chorreando lentamente. Su nueva fuerza hace que el caballo ya no dependa de " +"sus mĆŗsculos, pero igual puede perseguir rĆ”pidamente a sus enemigos." + #: lang/json/MONSTER_from_json.py msgid "Tiger wight" msgid_plural "Tiger wights" @@ -82309,6 +82516,42 @@ msgstr "" "Esto que podrĆ­a parecer un tigre normal se va tambaleando y tropezando, con " "su mandĆ­bula floja y sus ojos bien abiertos de un negro brillante." +#: lang/json/MONSTER_from_json.py +msgid "zombie cow" +msgid_plural "zombie cows" +msgstr[0] "vaca zombi" +msgstr[1] "vacas zombi" + +#. ~ Description for {'str': 'zombie cow'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Once a placid cow, this leathery horror stumbles and shudders, its pulsing " +"black eyes scanning for prey beneath wicked horns. It is big and heavy and " +"murderous." +msgstr "" +"Lo que alguna vez fue una plĆ”cida vaca, ahora es un horror de cuero que se " +"va tropezando y se sacudo, con ojos negros palpitantes que buscan su presa, " +"debajo de unos retorcidos cuernos. Es grande y pesada y homicida." + +#: lang/json/MONSTER_from_json.py +msgid "woodland wight" +msgid_plural "woodland wights" +msgstr[0] "criatura del bosque" +msgstr[1] "criaturas del bosque" + +#. ~ Description for {'str': 'woodland wight'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pale, stumbling white-tailed deer with blackened eyes and drooling slime " +"down its neck. Its legs twist and bend in strange, haphazard directions, " +"but with unnatural strength and speed. Preys on coyotes, wolves, and giant " +"spider mutants." +msgstr "" +"Es como un ciervo pĆ”lido de cola blanca que avanza a los tropiezos, con los " +"ojos ennegrecidos y una baba cayendo por su cuello. Sus patas se tuercen y " +"doblan en direcciones extraƱas y aleatorias, pero igual tienen velocidad y " +"fuerza sobrenaturales. Caza coyotes, lobos y araƱas mutantes gigantes." + #: lang/json/MONSTER_from_json.py msgid "mass of zombie spiders" msgid_plural "mass of zombie spiderss" @@ -83262,12 +83505,12 @@ msgstr "" "hombres, con brazos tan anchos como tachos de basura." #: lang/json/MONSTER_from_json.py -msgid "feral hunter" -msgid_plural "feral hunters" -msgstr[0] "cazador salvaje" -msgstr[1] "cazadores salvajes" +msgid "zombie hunter" +msgid_plural "zombie hunters" +msgstr[0] "zombi cazador" +msgstr[1] "zombis cazadores" -#. ~ Description for {'str': 'feral hunter'} +#. ~ Description for {'str': 'zombie hunter'} #: lang/json/MONSTER_from_json.py msgid "" "This once-human body is barely recognizable, scrambling about on all fours, " @@ -83374,12 +83617,12 @@ msgstr "" "inspira terror de completo Ć©xtasis cĆ³smico e inhumano." #: lang/json/MONSTER_from_json.py -msgid "feral runner" -msgid_plural "feral runners" -msgstr[0] "corredor salvaje" -msgstr[1] "corredores salvajes" +msgid "zombie runner" +msgid_plural "zombie runners" +msgstr[0] "zombi corredor" +msgstr[1] "zombis corredores" -#. ~ Description for {'str': 'feral runner'} +#. ~ Description for {'str': 'zombie runner'} #: lang/json/MONSTER_from_json.py msgid "" "This recently-risen body moves quickly, darting its head back and forth and " @@ -83390,12 +83633,12 @@ msgstr "" "manos." #: lang/json/MONSTER_from_json.py -msgid "feral predator" -msgid_plural "feral predators" -msgstr[0] "depredador salvaje" -msgstr[1] "depredadores salvajes" +msgid "zombie predator" +msgid_plural "zombie predators" +msgstr[0] "zombi depredador" +msgstr[1] "zombis depredadores" -#. ~ Description for {'str': 'feral predator'} +#. ~ Description for {'str': 'zombie predator'} #: lang/json/MONSTER_from_json.py msgid "" "With its joints in odd places and angles, this humanoid creature prowls " @@ -88472,7 +88715,7 @@ msgstr "Dolor" msgid "Increases pain" msgstr "Incrementa el dolor" -#: lang/json/SPELL_from_json.py src/character.cpp src/npctalk.cpp +#: lang/json/SPELL_from_json.py src/character.cpp src/talker_npc.cpp msgid "Tired" msgstr "Cansado/a" @@ -89613,7 +89856,7 @@ msgstr "" msgid "Lightning Blast" msgstr "Bomba ElĆ©ctrica" -#: lang/json/SPELL_from_json.py src/weather_data.cpp +#: lang/json/SPELL_from_json.py lang/json/weather_type_from_json.py msgid "Lightning Storm" msgstr "Lluvia con rayos" @@ -90622,14 +90865,14 @@ msgstr[1] "armaduras de combate RM13" #. ~ Description for {'str': 'RM13 combat armor'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. Use it to turn it on." msgstr "" -"EstĆ” alimentada internamente con hasta un mĆ”ximo de diez celdas de " -"combustible de plutonio. Este traje de cuerpo completo de armadura negra " -"militar, representa el pinĆ”culo de la tecnologĆ­a de armaduras alimentadas no" -" rĆ­gidas de Rivtech. Usala para encenderla." +"EstĆ” alimentada internamente con baterĆ­as de combustible de plutonio, " +"exclusivamente. Este traje de cuerpo completo de armadura negra militar, " +"representa el pinĆ”culo de la tecnologĆ­a de armaduras alimentadas no rĆ­gidas " +"de Rivtech. Usala para encenderla." #: lang/json/TOOL_ARMOR_from_json.py msgid "RM13 combat armor (on)" @@ -90641,16 +90884,16 @@ msgstr[1] "armaduras de combate RM13 (encendidas)" #. armors (on)'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. It is turned on, and continually draining " "power. Use it to turn it off." msgstr "" -"EstĆ” alimentada internamente con hasta un mĆ”ximo de diez celdas de " -"combustible de plutonio. Este traje de cuerpo completo de armadura negra " -"militar, representa el pinĆ”culo de la tecnologĆ­a de armaduras alimentadas no" -" rĆ­gidas de Rivtech. EstĆ” encendida, consumiendo gradualmente su energĆ­a. " -"Usala para apagarla." +"EstĆ” alimentada internamente con baterĆ­as de combustible de plutonio, " +"exclusivamente. Este traje de cuerpo completo de armadura negra militar, " +"representa el pinĆ”culo de la tecnologĆ­a de armaduras alimentadas no rĆ­gidas " +"de Rivtech. EstĆ” encendida, consumiendo gradualmente su energĆ­a. Usala para " +"apagarla." #: lang/json/TOOL_ARMOR_from_json.py msgid "5-point anchor" @@ -91970,12 +92213,12 @@ msgstr[1] "mochilas solares (plegadas)" msgid "" "Personal portable charging system consisting of an array of solar panels " "neatly folded in a form of a large backpack. It can be worn as one, and has" -" an integrated cable to plug it into a cable charger system." +" an integrated cable to plug it into a cable charger system CBM." msgstr "" "Es un sistema portĆ”til de recarga que consiste en varios paneles solares " "prolijamente plegados en forma de una gran mochila. Puede ser llevada como " -"si lo fuera, y tiene cables integrados para enchufarla a un sistema de " -"recarga." +"si lo fuera, y tiene cables integrados para enchufarla a un MCB de sistema " +"de recarga." #: lang/json/TOOL_ARMOR_from_json.py msgid "solar backpack (unfolded)" @@ -91988,10 +92231,10 @@ msgstr[1] "mochilas solares (desplegadas)" #: lang/json/TOOL_ARMOR_from_json.py msgid "" "Unfolded array of portable solar panels ready to push some power into an " -"active cable charger system." +"active cable charger system CBM." msgstr "" "Son varios paneles solares portĆ”tiles desplegados, listos para generar " -"energĆ­a para algĆŗn sistema de recarga." +"energĆ­a para algĆŗn MCB de sistema de recarga." #: lang/json/TOOL_ARMOR_from_json.py msgid "riot helmet" @@ -97710,14 +97953,14 @@ msgstr "" msgid "" "This is an advanced version of the unified power supply, or UPS. This " "device has been significantly redesigned to provide better efficiency as " -"well as to consume plutonium fuel cells rather than batteries. Sadly, its " -"plutonium reactor can't be charged in UPS charging station." +"well as to consume plutonium fuel batteries rather than regular batteries. " +"Sadly, its plutonium reactor can't be charged in UPS charging station." msgstr "" "Es una versiĆ³n mejorada del sistema de alimentaciĆ³n ininterrumpida, o UPS. " "Este dispositivo ha sido rediseƱado significativamente para proveer una " -"mayor eficacia y tambiĆ©n para consumir celdas de combustible de plutonio, en" -" lugar de baterĆ­as. Lamentablemente, su reactor de plutonio no puede ser " -"cargador en una estaciĆ³n de carga UPS." +"mayor eficacia y tambiĆ©n para consumir baterĆ­as de combustible de plutonio, " +"en lugar de baterĆ­as comunes. Lamentablemente, su reactor de plutonio no " +"puede ser cargado en una estaciĆ³n de carga UPS." #. ~ Description for {'str': 'camera'} #: lang/json/TOOL_from_json.py @@ -98738,16 +98981,17 @@ msgstr "SacĆ”s el gancho de la granada PEM." #: lang/json/TOOL_from_json.py msgid "" "This is a grenade that generates an electromagnetic pulse with a low-" -"inductance capacitor bank discharged into a single-loop antenna. Use this " -"item to pull the pin and light the fuse, turning it into an active EMP " -"grenade. You will then have three turns before it detonates, creating an " -"EMP field that damages robots and drains bionic energy." +"inductance capacitor bank discharged into a single-loop antenna. It also " +"produces a mild electric shock cloud. Use this item to pull the pin and " +"light the fuse, turning it into an active EMP grenade. You will then have " +"three turns before it detonates, creating an EMP field that damages robots " +"and drains bionic energy." msgstr "" "Es una granada que genera un pulso electromagnĆ©tico cuando el banco de " -"capacitares se descarga en una antena espira. Usala para sacar el gancho y " -"activar el detonador, lo que activa la granada PEM. DespuĆ©s de esto, tenĆ©s " -"tres turnos antes de que detone, creando un campo PEM que daƱa robots y " -"drena energĆ­a biĆ³nica." +"capacitares se descarga en una antena espira. TambiĆ©n produce una nube de " +"choque elĆ©ctrico. Usala para sacar el gancho y activar el detonador, lo que " +"activa la granada PEM. DespuĆ©s de esto, tenĆ©s tres turnos antes de que " +"detone, creando un campo PEM que daƱa robots y drena energĆ­a biĆ³nica." #: lang/json/TOOL_from_json.py msgid "active EMP grenade" @@ -98759,12 +99003,12 @@ msgstr[1] "granadas PEM activadas" #: lang/json/TOOL_from_json.py msgid "" "This EMP grenade is active, and will shortly detonate, creating a large EMP " -"field that damages robots and drains bionic energy. You may not want to be " -"holding it much longer." +"field that damages robots and drains bionic energy as well as a mild " +"electric shock cloud. You may not want to be holding it much longer." msgstr "" "Es una granada PEM activada, y en cualquier momento detonarĆ” creando un gran" -" campo PEM que daƱa robots y drena energĆ­a biĆ³nica. Tal vez no quieras " -"tenerla en la mano mucho mĆ”s tiempo." +" campo PEM que daƱa robots y drena energĆ­a biĆ³nica y una nube de choque " +"elĆ©ctrico. Tal vez no quieras tenerla en la mano mucho mĆ”s tiempo." #: lang/json/TOOL_from_json.py msgid "incendiary grenade" @@ -103752,13 +103996,13 @@ msgstr "PonĆ©s la trampa de escopeta." #. ~ Description for {'str': 'shotgun trap'} #: lang/json/TOOL_from_json.py msgid "" -"This is a simple tripwire is attached to the trigger of a loaded double-" -"barreled shotgun. When pulled, the shotgun fires. Two shells are loaded; " +"This is a simple tripwire is attached to the trigger of a loaded double " +"slamfire shotgun. When pulled, the shotgun fires. Two shells are loaded; " "the first time the trigger is pulled, one or both shells may be discharged." msgstr "" "Es una simple trampa de cuerda, que tiene la punta atada al gatillo de una " -"escopeta de doble caƱo cargada. Cuando se tira de la cuerda, la escopeta se " -"dispara. Tiene dos cartuchos cargados. La primera vez que la trampa es " +"escopeta de doble slamfire cargada. Cuando se tira de la cuerda, la escopeta" +" se dispara. Tiene dos cartuchos cargados. La primera vez que la trampa es " "activada, uno o los dos cartuchos pueden dispararse." #: lang/json/TOOL_from_json.py @@ -111847,6 +112091,26 @@ msgstr "Reforzar Pared de Chatarra con soldadora" msgid "Build Junk Metal Floor" msgstr "Construir Suelo de Chatarra" +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Bolts" +msgstr "Construir Puente de Chatarra Usando Tornillos" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Welder" +msgstr "Construir Puente de Chatarra Usando Soldadora" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bench" +msgstr "Construir Banco de Chatarra" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Table" +msgstr "Construir Mesa de Chatarra" + +#: lang/json/construction_from_json.py +msgid "Lay down decorative ground cable" +msgstr "Poner cable a tierra decorativo" + #: lang/json/construction_from_json.py msgid "Build Pillow Fort" msgstr "Construir Fuerte de Almohadas" @@ -114508,6 +114772,15 @@ msgstr "Ā”RecuperĆ”s el control de tus mĆŗsculos!" msgid "Your muscles won't cooperate!" msgstr "Ā”Tus mĆŗsculos no estarĆ­an cooperando!" +#: lang/json/effects_from_json.py +msgid "Minor Bleeding" +msgstr "Sangrado Leve" + +#. ~ Description of effect 'Minor Bleeding'. +#: lang/json/effects_from_json.py +msgid "Tis but a scratch." +msgstr "Es solo un rasguƱo." + #: lang/json/effects_from_json.py msgid "Bleeding" msgstr "Sangrando" @@ -114535,7 +114808,25 @@ msgstr "Sangrado Grave" msgid "You are rapidly losing blood." msgstr "EstĆ”s perdiendo sangre rĆ”pidamente." -#. ~ Apply message for effect(s) 'Bleeding, Bad Bleeding, Heavy Bleeding'. +#: lang/json/effects_from_json.py +msgid "Heavy Arterial Bleeding" +msgstr "Sangrado Arterial Grave" + +#. ~ Description of effect 'Heavy Arterial Bleeding'. +#: lang/json/effects_from_json.py +msgid "Blood is gushing from you like a fountain." +msgstr "La sangre te estĆ” saliendo como una fuente." + +#. ~ Apply message for effect(s) 'Minor Bleeding, Minor Bleeding, Minor +#. Bleeding, Minor Bleeding, Minor Bleeding, Bleeding, Bleeding, Bleeding, +#. Bleeding, Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, +#. Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad +#. Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, +#. Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy +#. Bleeding, Heavy Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding'. #: lang/json/effects_from_json.py msgid "You're bleeding!" msgstr "Ā”EstĆ”s sangrando!" @@ -115313,40 +115604,99 @@ msgstr "" "Tus huesos se vuelven mĆ”s fuertes a medida que mejorĆ”s tus niveles de " "calcio." +#: lang/json/effects_from_json.py +msgid "Early iron deficiency" +msgstr "Deficiencia inicial de hierro" + +#. ~ Description of effect 'Early iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"A lack of iron in your diet has hampered efficiency and regeneration of your" +" red blood cells." +msgstr "" +"La falta de hierro en tu dieta ha enlentecido la eficiencia y regeneraciĆ³n " +"de tus glĆ³bulos rojos." + #: lang/json/effects_from_json.py msgid "Iron deficiency" msgstr "Deficiencia de hierro" +#. ~ Description of effect 'Iron deficiency'. #: lang/json/effects_from_json.py -msgid "Early anemia" -msgstr "Anemia precoz" +msgid "" +"Prolonged lack of iron in your diet has compromised efficiency and " +"regeneration of your red blood cells." +msgstr "" +"La falta prolongada de hierro en tu dieta ha puesto en riesgo la eficiencia " +"y regeneraciĆ³n de tus glĆ³bulos rojos." #: lang/json/effects_from_json.py -msgid "Anemia" -msgstr "Anemia" +msgid "Acute iron deficiency" +msgstr "Deficiencia grave de hierro" +#. ~ Description of effect 'Acute iron deficiency'. #: lang/json/effects_from_json.py msgid "" -"A lack of iron in your diet will result in progressively worsening anemia." +"Severe lack of iron in your diet results in your red blood cells dying " +"faster then they are regenerating." msgstr "" -"La falta de hierro en tu dieta irĆ” progresivamente empeorando tu anemia." +"La severa falta de hierro en tu dieta ha resultado en glĆ³bulos rojos " +"muriendo mĆ”s rĆ”pidamente de lo que se pueden regenerar." -#. ~ Apply message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Apply message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#. ~ Apply message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You begin feeling increasingly tired and listless." msgstr "EmpezĆ”s a sentirte cada vez mĆ”s cansado y apĆ”tico." -#. ~ Remove message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Remove message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "You are no longer in risk of becoming anemic." +msgstr "Ya no estĆ”s en riesgo de volverte anĆ©mico." + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your irom deficiency is nearly resolved." +msgstr "Ya casi has superado tu deficiencia de hierro." + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your iron deficiency starts to improve." +msgstr "Te sentĆ­s con mĆ”s fuerza a medida que mejorĆ”s de tu falta de hierro." + +#: lang/json/effects_from_json.py +msgid "Early anemia" +msgstr "Anemia precoz" + +#: lang/json/effects_from_json.py +msgid "Anemia" +msgstr "Anemia" + +#: lang/json/effects_from_json.py +msgid "Acute anemia" +msgstr "Anemia grave" + +#: lang/json/effects_from_json.py +msgid "Loss of red blood cells results in progressively worsening anemia." +msgstr "" +"La pĆ©rdida de glĆ³bulos rojos resulta en una anemia que empeora " +"progresivamente." + +#. ~ Remove message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You no longer feel anemic." msgstr "Ya no te sentĆ­s anĆ©mico." -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py -msgid "Your iron deficiency is nearly resolved." -msgstr "Ya casi has superado tu deficiencia de hierro." +msgid "Your anemia is nearly resolved." +msgstr "Ya casi has superado tu anemia." -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "Your feel stronger as your anemia starts to improve." msgstr "Te sentĆ­s con mĆ”s fuerza a medida que mejorĆ”s de tu anemia." @@ -115547,6 +115897,83 @@ msgstr "" "SĆ­, sobreviviste, pero ĀæquĆ© clase de supervivencia es esta, comiendo estas " "raciones desagradables dĆ­a por medio?" +#: lang/json/effects_from_json.py +msgid "Mild hypovolemic shock" +msgstr "Choque hipovolĆ©mico leve" + +#. ~ Description of effect 'Mild hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost some blood and look somewhat pale." +msgstr "Perdiste un poco de sangre y estĆ”s un poco pĆ”lido." + +#: lang/json/effects_from_json.py +msgid "Moderate hypovolemic shock" +msgstr "Choque hipovolĆ©mico moderado" + +#. ~ Description of effect 'Moderate hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost large amount of blood, and you're not feeling well." +msgstr "Perdiste una gran cantidad de sangre y ahora no te sentĆ­s bien." + +#: lang/json/effects_from_json.py +msgid "Advanced hypovolemic shock" +msgstr "Choque hipovolĆ©mico avanzado" + +#. ~ Description of effect 'Advanced hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost an awful lot of blood, and your condition is severe. Seek " +"medical attention." +msgstr "" +"Perdiste muchĆ­sima sangre y tu condiciĆ³n es severa. BuscĆ” atenciĆ³n mĆ©dica." + +#: lang/json/effects_from_json.py +msgid "Severe hypovolemic shock" +msgstr "Choque hipovolĆ©mico severo" + +#. ~ Description of effect 'Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost tremendous amount of blood, and you're standing on death's door." +" Transfusion might save you." +msgstr "" +"Perdiste cantidades tremendas de sangre y estĆ”s a punto de morir. Una " +"transfusiĆ³n podrĆ­a salvarte." + +#. ~ Apply message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You have lost lot of blood, and your condition worsens." +msgstr "Perdiste mucha sangre y tu condiciĆ³n empeora." + +#. ~ Remove message for effect(s) 'Mild hypovolemic shock, Moderate +#. hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You are no longer in shock." +msgstr "Ya no estĆ”s en choque hipovolĆ©mico." + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your blood level increase, and you feel better, but still look pale." +msgstr "" +"Tu nivel de sangre aumenta y te sentĆ­s mejor, pero todavĆ­a estĆ”s pĆ”lido." + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your blood levels starts to improve." +msgstr "" +"Te sentĆ­s mĆ”s fuerte a medida que tu nivel de sangre comienza a mejorar." + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You're not dying from lack of blood, but you're not out of the woods yet." +msgstr "" +"Ya no te estĆ”s muriendo por falta de sangre pero todavĆ­a estĆ”s en riesgo." + #: lang/json/effects_from_json.py msgid "Lit up" msgstr "Encendido" @@ -116433,7 +116860,7 @@ msgid "" "An outpost started by the Free Merchants to provide a source of food and raw" " materials." msgstr "" -"Un puesto fundado por los Mercaderes Libres para proveer una fuente de " +"Es un puesto fundado por los Mercaderes Libres para proveer una fuente de " "comida y materias primas." #: lang/json/faction_from_json.py @@ -117537,6 +117964,413 @@ msgstr "red dura de goma" msgid "mutated cactus" msgstr "cactus mutado" +#: lang/json/furniture_from_json.py +msgid "glowing tendril" +msgstr "zarcillo brillante" + +#. ~ Description for glowing tendril +#: lang/json/furniture_from_json.py +msgid "" +"A willowy tendril growing from the floor, gently waving back and forth. A " +"faint light spills from it." +msgstr "" +"Es un zarcillo esbelto que crece desde el suelo, meciĆ©ndose gentilmente " +"hacia atrĆ”s y adelante. Una suave luz se desprende de Ć©l." + +#: lang/json/furniture_from_json.py +msgid "splorch!" +msgstr "splorch!" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "whump!" +msgstr "Ā”whump!" + +#: lang/json/furniture_from_json.py +msgid "wafting anemone" +msgstr "anĆ©mona flotante" + +#. ~ Description for wafting anemone +#: lang/json/furniture_from_json.py +msgid "" +"A fleshy white protuberance growing from the floor, with a cluster of " +"tendrils pouring out of it. It looks almost exactly like a sea anemone, " +"even waving gently as though underwater." +msgstr "" +"Es una protuberancia carnosa blanca que crece del suelo, con un grupo de " +"zarcillos saliendo de ella. Es casi igual a una anĆ©mona de mar, incluso se " +"mece suavemente como si estuviera bajo el agua." + +#: lang/json/furniture_from_json.py +msgid "gasping tube" +msgstr "tubo de respiraciĆ³n" + +#. ~ Description for gasping tube +#: lang/json/furniture_from_json.py +msgid "" +"This is a meaty green stalactite with a thickened hide like that of a " +"starfish, extending from the floor to the ceiling. In the center is a " +"series of ports somewhat like mouths, from which pour bursts of a vile-" +"smelling gas." +msgstr "" +"Es una estalactita carnosa verde con una piel gruesa como el de una estrella" +" de mar, que se extiende desde el suelo hasta el techo. En el medio hay una " +"serie de puertos que parecen bocas, desde las cuales expulsa unas nubes de " +"gas de olor repugnante." + +#: lang/json/furniture_from_json.py +msgid "twitching frond" +msgstr "fronda moviente" + +#. ~ Description for twitching frond +#: lang/json/furniture_from_json.py +msgid "" +"A spine resembling moth antennae juts from the ground, swaying gently in the" +" air. Every so often, a cascade of energy arcs along it and discharges into" +" the ceiling." +msgstr "" +"Es una espina que se parece a las antenas de las polillas, que sobresale del" +" suelo, meciĆ©ndose suavemente en el aire. Cada tanto, una cascada de energĆ­a" +" pasa por ella y se descarga en el techo." + +#: lang/json/furniture_from_json.py +msgid "scarred lump" +msgstr "bulto cicatrizado" + +#. ~ Description for scarred lump +#: lang/json/furniture_from_json.py +msgid "" +"This is a pile of nondescript alien flesh, twitching and belching strange " +"gases out of injured orifices." +msgstr "" +"Es una pila de carne alienĆ­gena indescriptible, que se retuerce y escupe " +"unos gases extraƱos desde sus orificios." + +#: lang/json/furniture_from_json.py +msgid "splat!" +msgstr "Ā”splat!" + +#: lang/json/furniture_from_json.py +msgid "slimy pod" +msgstr "vaina babosa" + +#. ~ Description for slimy pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a slick, translucent pod suspended on a thin stalk. It is covered " +"in a thick mucus, obscuring whatever is floating in the gel-like substance " +"inside." +msgstr "" +"Es una vaina translĆŗcida y escurridiza suspendido en un tallo fino. EstĆ” " +"cubierta de una mucosidad espesa, oscureciendo lo que sea que estĆ” flotando " +"en la sustancia parecida al gel de su interior." + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "whump." +msgstr "whump." + +#: lang/json/furniture_from_json.py +msgid "organ pod" +msgstr "vaina orgĆ”nica" + +#. ~ Description for organ pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside you can see the" +" dimly outlined shape of human organs, floating in some kind of preservative" +" goo." +msgstr "" +"Es una vaina translĆŗcida suspendido en un tallo fino. Adentro podĆ©s ver " +"apenas la forma de Ć³rganos humanos, flotando en una especie de viscosidad " +"que los preserva." + +#: lang/json/furniture_from_json.py +msgid "resin pod" +msgstr "vaina de resina" + +#. ~ Description for resin pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside is a clean, " +"clear resinous-looking fluid. You could fairly easily tear it from the " +"stalk and take it with you." +msgstr "" +"Es una vaina translĆŗcida suspendido en un tallo fino. Adentro tiene un " +"fluido limpio y claro similar a una resina. PodĆ©s arrancarlo con facilidad y" +" llevĆ”rtelo." + +#: lang/json/furniture_from_json.py +msgid "fleshy altar" +msgstr "altar cĆ”rnico" + +#. ~ Description for fleshy altar +#: lang/json/furniture_from_json.py +msgid "" +"This pulsing protuberance juts from the floor, its sides covered in scaled, " +"oozing skin. The surface is flat, but undulates softly. A handful of " +"unidentifiable appendages reach from the sides, suggesting a sort of " +"nightmarish living autodoc." +msgstr "" +"Esta protuberancia palpitante sale del suelo, sus costados estĆ”n cubiertos " +"por una piel escamada y purulenta. Su superficie es plana pero suavemente " +"ondulada. Un puƱado de apĆ©ndices inidentificables salen de los costados, " +"asemejando una especie de autodoc viviente y pesadillesco." + +#: lang/json/furniture_from_json.py +msgid "scrap antenna" +msgstr "antena de chatarra" + +#. ~ Description for scrap antenna +#: lang/json/furniture_from_json.py +msgid "" +"This contraption looks like some sort of cobbled-together transmitter or " +"receiver antenna. It consists of a number of mismatched blinking lights, " +"spinning servos, and dangling wires connected to a heft metal box." +msgstr "" +"Este aparato parece una clase de antena improvisada transmisora o receptora." +" Consiste en un nĆŗmero de luces de diferentes tamaƱos parpadeantes, servos " +"giratorios y cables colgando conectados a una caja de metal." + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "clang!" +msgstr "Ā”clang!" + +#: lang/json/furniture_from_json.py +msgid "rack of robots" +msgstr "estante de robots" + +#. ~ Description for rack of robots +#: lang/json/furniture_from_json.py +msgid "" +"This is a wire cage containing a number of robot parts, from chassis to " +"limbs, firmly clamped on to sturdy hanging rods. It looks like it would be " +"exceptionally difficult to open it and get at them without damaging them, " +"probably by design." +msgstr "" +"Es una jaula de alambre que contiene una cantidad de partes de robot, desde " +"chasis hasta extremidades, sujetadas con unas varas resistentes para colgar." +" Pareciera ser excepcionalmente difĆ­cil de abrir y sacar su contenido sin " +"romperlo, probablemente por diseƱo." + +#: lang/json/furniture_from_json.py +msgid "spinning dish" +msgstr "parabĆ³lica giratoria" + +#. ~ Description for spinning dish +#: lang/json/furniture_from_json.py +msgid "" +"This is a slowly spinning parabolic dish engraved with an unrecognizable " +"pattern of symbols that might, at a guess, be some sort of circuitry pattern" +" - or maybe a religious incantation. It is mounted on a completely " +"mismatched electric motor that looks fairly mundane." +msgstr "" +"Es una antena parabĆ³lica que va rotando lentamente, grabada con un patrĆ³n de" +" sĆ­mbolos irreconocibles que podrĆ­an ser, suponemos, alguna clase de patrĆ³n " +"de circuito - o tal vez un mantra religioso. EstĆ” montado en un motor " +"completamente disparejo que parece mundano." + +#: lang/json/furniture_from_json.py +msgid "scavenged utility light" +msgstr "luz de utilidad recuperada" + +#. ~ Description for scavenged utility light +#: lang/json/furniture_from_json.py +msgid "" +"The bulbs emit an eery greenish glow, and some parts of it have a curved " +"appearance as though the metal were grown in a lab, but by and large this " +"isn't a particularly unusual looking area light." +msgstr "" +"Las lamparitas emiten un brillo verdusco fantasmagĆ³rico, y algunas de sus " +"partes estĆ”n curvadas como si el metal hubiera crecido en un laboratorio, " +"pero en lĆ­neas generales no es una luz particularmente inusual." + +#: lang/json/furniture_from_json.py +msgid "clanking fluid pump" +msgstr "bomba rechinante de fluido" + +#. ~ Description for clanking fluid pump +#: lang/json/furniture_from_json.py +msgid "" +"The huge sweating pipes and large tank reveal this clanking and tortuous " +"piece of equipment to be some sort of fluid pump. It is cobbled from " +"several apparently ill-fitting parts that have been fitted together with " +"some very strange looking but surprisingly clever adaptors." +msgstr "" +"Este gran tanque y enormes caƱos transpirando revelan esta pieza ruidosa y " +"tortuosa de equipo que es una especie de bomba de fluido. EstĆ” armada como " +"un rejunte de diversas partes que no encajan, pero han sido unidas mediante " +"unos adaptadores muy extraƱos pero sorprendentemente ingeniosos." + +#: lang/json/furniture_from_json.py +msgid "metalloid printer" +msgstr "impresora de semimetal" + +#. ~ Description for metalloid printer +#: lang/json/furniture_from_json.py +msgid "" +"This huge device actually resembles a 3D printer fairly closely, aside from " +"its industrial size. Huge spools of various thin metallic wires top it and " +"feed into what seems to be some sort of nozzle, and massive electrical " +"cables disappear into the wall behind it." +msgstr "" +"Este gigante aparato se parece bastante a una impresora 3D, aparte de su " +"tamaƱo industrial. Tiene unas enormes bobinas de varios cables metĆ”licos " +"delgados que alimentan lo que parece ser una especie de boquilla, y unos " +"cables enormes elĆ©ctricos desaparecen en la pared que estĆ” atrĆ”s." + +#: lang/json/furniture_from_json.py +msgid "circuit printer" +msgstr "impresora de circuitos" + +#. ~ Description for circuit printer +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall device with a lattice of pipes and nozzles. Based on the " +"pile of products sitting in the output hopper, it looks like itā€™s used as a " +"printer for complex electronic components." +msgstr "" +"Es un dispositivo alto con un entramado de caƱos y boquillas. BasĆ”ndose en " +"la pila de productos en la tolva de salida, parece que se usa como impresora" +" de componentes electrĆ³nicos complejos." + +#: lang/json/furniture_from_json.py +msgid "Mavrik 10-101 power core" +msgstr "nĆŗcleo de energĆ­a Mavrik 10-101" + +#. ~ Description for Mavrik 10-101 power core +#: lang/json/furniture_from_json.py +msgid "" +"There is a faded metallic plaque on the side of this cylindrical device. The lettering is a strange combination of English and Cyrillic script. It reads:\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" +msgstr "" +"Hay una placa metĆ”lica un poco borrada en el costado de este dispositivo cilĆ­ndrico. Las letras son una extraƱa combinaciĆ³n de inglĆ©s y cirĆ­lico. Dice:\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "metal screeching!" +msgstr "Ā”chillido de metal!" + +#: lang/json/furniture_from_json.py +msgid "spherical generator" +msgstr "generador esfĆ©rico" + +#. ~ Description for spherical generator +#: lang/json/furniture_from_json.py +msgid "" +"This huge steel plated sphere gives off a soft hum as it, presumably, " +"generates power. A heavy lead plate bolted to the front might describe what" +" it is, but it is written in something that looks vaguely like cuneiform." +msgstr "" +"Es una enorme esfera de placas de acero que emite un suave zumbido mientras," +" presuntamente, genera energĆ­a. Una placa pesada de plomo atornillada a la " +"parte frontal podrĆ­a estar describiendo lo que es, pero estĆ” escrito en algo" +" que parece vagamente cuneiforme." + +#: lang/json/furniture_from_json.py +msgid "fluidic generator" +msgstr "generador fluĆ­dico" + +#. ~ Description for fluidic generator +#: lang/json/furniture_from_json.py +msgid "" +"Twisting reams of copper and steel pipes wrap around a central core that " +"thrums softly. Although there are no labels in any language you recognize, " +"the cables connected to the base suggest that this is some sort of power " +"generator." +msgstr "" +"Montones de caƱos retorcidos de cobre y acero se enroscan alrededor de un " +"nĆŗcleo central que tamborilea suavemente. Aunque no hay etiquetas en ningĆŗn " +"idioma que puedas reconocer, los cables conectados a la base sugieren que es" +" una clase de generador de energĆ­a." + +#: lang/json/furniture_from_json.py +msgid "rusty generator" +msgstr "generador oxidado" + +#. ~ Description for rusty generator +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall, unremarkable cylinder capped by a wide flat saucer. There " +"is heavy rusting at the base. A series of connected cables suggest that " +"it's some sort of power generator." +msgstr "" +"Es un cilindro alto y comĆŗn, tapado por un plato ancho y chato. Tiene una " +"base pesada y oxidada. Una serie de cables conectados sugieren que es una " +"especie de generador de energĆ­a." + +#: lang/json/furniture_from_json.py +msgid "personal charging station" +msgstr "estaciĆ³n personal de carga" + +#. ~ Description for personal charging station +#: lang/json/furniture_from_json.py +msgid "" +"The cyborg equivalent of a bed, this is a custom-shaped near-vertical booth " +"designed to mount a heavy metal frame and connect it to a central power " +"supply and nutrient source." +msgstr "" +"Es el equivalente a una cama pero para ciborgs. Es una cabina casi vertical " +"diseƱada para montar sobre una estructura metĆ”lica resistente y conectada a " +"su fuente central de energĆ­a y suministro de nutrientes." + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp +msgid "crash!" +msgstr "Ā”crash!" + +#: lang/json/furniture_from_json.py +msgid "simple charging station" +msgstr "estaciĆ³n simple de carga" + +#. ~ Description for simple charging station +#: lang/json/furniture_from_json.py +msgid "" +"This is a simple, unadorned, corroded metal charging and refeeding station, " +"with hookups for two units somewhat larger than a human to stand side by " +"side and be recharged and refueled." +msgstr "" +"Es una simple estaciĆ³n de carga y realimentaciĆ³n sin adornos, de metal " +"corroĆ­do, con conexiĆ³n para dos unidades un poco mĆ”s grandes que dos humanos" +" parados juntos, y pueden ser recargadas y realimentados." + +#: lang/json/furniture_from_json.py +msgid "shimmering superstructure" +msgstr "superestructura reluciente" + +#. ~ Description for shimmering superstructure +#: lang/json/furniture_from_json.py +msgid "" +"A simple metal superstructure like you might see holding up a radio tower, " +"this one seems to give off just the faintest hint of shimmer, like heat " +"waves. The metal has a burnt, iridescent pattern. There is a boxy, " +"unimpressive looking device at the top of the tower." +msgstr "" +"Es una simple superestructura de metal como la que podĆ©s ver sosteniendo una" +" torre de radio. Esta parece estar emitiendo un muy dĆ©bil brillo, como ondas" +" de calor. El metal tiene un patrĆ³n quemado iridiscente. Tiene un " +"dispositivo cuadrado mediocre en la punta de la torre." + +#: lang/json/furniture_from_json.py +msgid "portal enclosure" +msgstr "cercado de portal" + +#. ~ Description for portal enclosure +#: lang/json/furniture_from_json.py +msgid "" +"A heavy metal ring attached to dozens of wires, charred by residue that " +"gives off an acrid, unfamiliar smell." +msgstr "" +"Es un anillo pesado de metal unido a docenas de cables, chamuscados por " +"residuos que emanan un olor agrio y desconocido." + #: lang/json/furniture_from_json.py msgid "cooling unit" msgstr "aire acondicionado" @@ -117550,15 +118384,6 @@ msgstr "" "Es un electrodomĆ©stico grande y cuadrado cubierto por una caja de metal. " "Este mueble amurado es usado para refrescar grandes Ć”reas internas." -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "metal screeching!" -msgstr "Ā”chillido de metal!" - -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -msgid "clang!" -msgstr "Ā”clang!" - #: lang/json/furniture_from_json.py msgid "central air filter" msgstr "filtro de aire central" @@ -117760,8 +118585,7 @@ msgstr "" "Cataclismo, ahora se han convertido en herramientas invalorables para " "cualquier sobreviviente." -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py msgid "whack!" msgstr "Ā”whack!" @@ -117781,16 +118605,12 @@ msgstr "" "visibilidad. A pesar de su nombre, no logra mucho para detener a un vehĆ­culo" " en movimiento." -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -#: src/mapdata.cpp src/vehicle_move.cpp +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/map.cpp src/mapdata.cpp +#: src/vehicle_move.cpp msgid "smash!" msgstr "Ā”smash!" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -msgid "whump." -msgstr "whump." - #: lang/json/furniture_from_json.py msgid "earthbag barricade" msgstr "barricada de bolsas de tierra" @@ -118185,10 +119005,6 @@ msgstr "" "Es un saco de huevos grandes blanquecinos. Al examinarlos podĆ©s ver cĆ³mo se " "mueven levemente. Un asco." -#: lang/json/furniture_from_json.py -msgid "splat!" -msgstr "Ā”splat!" - #. ~ Description for spider egg sack #: lang/json/furniture_from_json.py msgid "" @@ -118285,16 +119101,6 @@ msgstr "" "manera segura, con una chimenea para ventilar el humo. Igual, es peligroso " "dejar un fuego sin atender." -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -msgid "crash!" -msgstr "Ā”crash!" - -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "whump!" -msgstr "Ā”whump!" - #: lang/json/furniture_from_json.py msgid "wood stove" msgstr "cocina de madera" @@ -118486,8 +119292,9 @@ msgstr "" "Es una gran pila de hojas. PodrĆ­as dormir ahĆ­ encima si no te preocupa el " "confort o el frĆ­o." -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -#: src/iuse.cpp +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/iuse.cpp msgid "crunch!" msgstr "Ā”crunch!" @@ -118683,6 +119490,95 @@ msgstr "" "Es un gran tanque con un dispositivo motorizado de mezclado para combinar " "grandes cantidades de quĆ­micos." +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken generator" +msgstr "generador roto" + +#. ~ Description for broken generator +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This generator is broken and will not help you produce usable electricity." +msgstr "" +"Este generador estĆ” roto y no te puede asistir en la producciĆ³n de " +"electricidad utilizable." + +#: lang/json/furniture_from_json.py +msgid "Compact Advanced Sterling Radioisotope Generator" +msgstr "Generador RadioisotĆ³pico Sterling Compacto Avanzado" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"This hefty lump of steel and lead is the housing unit for a small nuclear " +"reactor. It is plastered with warning signs. You could probably ignore " +"those and salvage the steel and lead shielding, what could possibly go " +"wrong?" +msgstr "" +"Este pesado pedazo de acero y plomo es el hogar de un pequeƱo reactor " +"nuclear. EstĆ” cubierto de carteles de advertencia. Probablemente puedas " +"ignorarlos y sacar el exterior de acero y plomo, ĀæquĆ© podrĆ­a salir mal?" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"Some insane fool has removed the outer containment on this small-scale " +"nuclear reactor. It is still fairly safe as it is: the reactor has " +"considerable built-in containment as well. Nevertheless, you probably don't" +" want to stand too close for too long." +msgstr "" +"AlgĆŗn estĆŗpido loco le ha quitado el contenedor exterior a este reactor " +"nuclear de escala pequeƱa. Es bastante seguro como estĆ”: el reactor tiene " +"incorporado un considerable contenedor. De todas maneras, probablemente no " +"te quieras parar muy cerca por mucho tiempo." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "light machinery" +msgstr "maquinaria ligera" + +#. ~ Description for light machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted light machinery. You could scavenge it for parts." +msgstr "" +"Es una variedad de maquinaria ligera. PodrĆ­as recuperar algunas partes de " +"acĆ”." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "ting." +msgstr "ting." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "heavy machinery" +msgstr "maquinaria pesada" + +#. ~ Description for heavy machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted heavy machinery. You could scavenge it for parts." +msgstr "" +"Es una variedad de maquinaria pesada. PodrĆ­as recuperar algunas partes de " +"acĆ”." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "old machinery" +msgstr "maquinaria antigua" + +#. ~ Description for old machinery +#: lang/json/furniture_from_json.py +msgid "Assorted old, rusty machinery. You could scavenge it for parts." +msgstr "" +"Es una variedad de maquinaria vieja y oxidada. PodrĆ­as recuperar algunas " +"partes de acĆ”." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "electronic machinery" +msgstr "maquinaria elĆ©ctrica" + +#. ~ Description for electronic machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted electronic machinery. You could scavenge it for parts." +msgstr "" +"Es una variedad de maquinaria electrĆ³nica. PodrĆ­as recuperar algunas partes " +"de acĆ”." + #: lang/json/furniture_from_json.py msgid "robotic arm" msgstr "brazo robĆ³tico" @@ -118703,6 +119599,33 @@ msgstr "" msgid "thunk." msgstr "tonk," +#: lang/json/furniture_from_json.py +msgid "ground cable" +msgstr "cable a tierra" + +#. ~ Description for ground cable +#: lang/json/furniture_from_json.py +msgid "A bunch of loose cables snake along the floor." +msgstr "Es un manojo de cables sueltos tirados en el suelo." + +#: lang/json/furniture_from_json.py +msgid "shred!" +msgstr "triturado!" + +#: lang/json/furniture_from_json.py +msgid "thud!" +msgstr "golpe seco!" + +#: lang/json/furniture_from_json.py +msgid "capacitor bank" +msgstr "banco de capacitores" + +#. ~ Description for capacitor bank +#: lang/json/furniture_from_json.py +msgid "A bank of heavy metal cylinders connected by large wires." +msgstr "" +"Es un banco de pesados cilindros metĆ”licos conectados por grandes cables." + #: lang/json/furniture_from_json.py msgid "Autodoc Mk. XI" msgstr "Autodoc Mk. XI" @@ -119032,144 +119955,22 @@ msgstr "abrir cortina de privacidad" msgid "Stop peeking!" msgstr "Ā”DejĆ” de espiar!" -#: lang/json/furniture_from_json.py -msgid "glowing tendril" -msgstr "zarcillo brillante" - -#. ~ Description for glowing tendril -#: lang/json/furniture_from_json.py -msgid "" -"A willowy tendril growing from the floor, gently waving back and forth. A " -"faint light spills from it." -msgstr "" -"Es un zarcillo esbelto que crece desde el suelo, meciĆ©ndose gentilmente " -"hacia atrĆ”s y adelante. Una suave luz se desprende de Ć©l." - -#: lang/json/furniture_from_json.py -msgid "splorch!" -msgstr "splorch!" - -#: lang/json/furniture_from_json.py -msgid "wafting anemone" -msgstr "anĆ©mona flotante" - -#. ~ Description for wafting anemone -#: lang/json/furniture_from_json.py -msgid "" -"A fleshy white protuberance growing from the floor, with a cluster of " -"tendrils pouring out of it. It looks almost exactly like a sea anemone, " -"even waving gently as though underwater." -msgstr "" -"Es una protuberancia carnosa blanca que crece del suelo, con un grupo de " -"zarcillos saliendo de ella. Es casi igual a una anĆ©mona de mar, incluso se " -"mece suavemente como si estuviera bajo el agua." - -#: lang/json/furniture_from_json.py -msgid "gasping tube" -msgstr "tubo de respiraciĆ³n" - -#. ~ Description for gasping tube -#: lang/json/furniture_from_json.py -msgid "" -"This is a meaty green stalactite with a thickened hide like that of a " -"starfish, extending from the floor to the ceiling. In the center is a " -"series of ports somewhat like mouths, from which pour bursts of a vile-" -"smelling gas." -msgstr "" -"Es una estalactita carnosa verde con una piel gruesa como el de una estrella" -" de mar, que se extiende desde el suelo hasta el techo. En el medio hay una " -"serie de puertos que parecen bocas, desde las cuales expulsa unas nubes de " -"gas de olor repugnante." - -#: lang/json/furniture_from_json.py -msgid "twitching frond" -msgstr "fronda moviente" - -#. ~ Description for twitching frond -#: lang/json/furniture_from_json.py -msgid "" -"A spine resembling moth antennae juts from the ground, swaying gently in the" -" air. Every so often, a cascade of energy arcs along it and discharges into" -" the ceiling." -msgstr "" -"Es una espina que se parece a las antenas de las polillas, que sobresale del" -" suelo, meciĆ©ndose suavemente en el aire. Cada tanto, una cascada de energĆ­a" -" pasa por ella y se descarga en el techo." - -#: lang/json/furniture_from_json.py -msgid "scarred lump" -msgstr "bulto cicatrizado" - -#. ~ Description for scarred lump -#: lang/json/furniture_from_json.py -msgid "" -"This is a pile of nondescript alien flesh, twitching and belching strange " -"gases out of injured orifices." -msgstr "" -"Es una pila de carne alienĆ­gena indescriptible, que se retuerce y escupe " -"unos gases extraƱos desde sus orificios." - -#: lang/json/furniture_from_json.py -msgid "slimy pod" -msgstr "vaina babosa" - -#. ~ Description for slimy pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a slick, translucent pod suspended on a thin stalk. It is covered " -"in a thick mucus, obscuring whatever is floating in the gel-like substance " -"inside." -msgstr "" -"Es una vaina translĆŗcida y escurridiza suspendido en un tallo fino. EstĆ” " -"cubierta de una mucosidad espesa, oscureciendo lo que sea que estĆ” flotando " -"en la sustancia parecida al gel de su interior." - -#: lang/json/furniture_from_json.py -msgid "organ pod" -msgstr "vaina orgĆ”nica" - -#. ~ Description for organ pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside you can see the" -" dimly outlined shape of human organs, floating in some kind of preservative" -" goo." -msgstr "" -"Es una vaina translĆŗcida suspendido en un tallo fino. Adentro podĆ©s ver " -"apenas la forma de Ć³rganos humanos, flotando en una especie de viscosidad " -"que los preserva." - -#: lang/json/furniture_from_json.py -msgid "resin pod" -msgstr "vaina de resina" - -#. ~ Description for resin pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside is a clean, " -"clear resinous-looking fluid. You could fairly easily tear it from the " -"stalk and take it with you." -msgstr "" -"Es una vaina translĆŗcida suspendido en un tallo fino. Adentro tiene un " -"fluido limpio y claro similar a una resina. PodĆ©s arrancarlo con facilidad y" -" llevĆ”rtelo." - -#: lang/json/furniture_from_json.py -msgid "fleshy altar" -msgstr "altar cĆ”rnico" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "centrifuge" +msgstr "centrifugadora" -#. ~ Description for fleshy altar +#. ~ Description for centrifuge #: lang/json/furniture_from_json.py msgid "" -"This pulsing protuberance juts from the floor, its sides covered in scaled, " -"oozing skin. The surface is flat, but undulates softly. A handful of " -"unidentifiable appendages reach from the sides, suggesting a sort of " -"nightmarish living autodoc." +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. For some reason, this one has an attached battery pack. It could be " +"used to analyze a medical fluid sample, such as blood, if a test tube was " +"placed in it." msgstr "" -"Esta protuberancia palpitante sale del suelo, sus costados estĆ”n cubiertos " -"por una piel escamada y purulenta. Su superficie es plana pero suavemente " -"ondulada. Un puƱado de apĆ©ndices inidentificables salen de los costados, " -"asemejando una especie de autodoc viviente y pesadillesco." +"Es un dispositivo centrĆ­fugo para separar lĆ­quidos, con una unidad de " +"anĆ”lisis automatizada. Por alguna razĆ³n, esta ha sido unida a un paquete de " +"baterĆ­as. Puede ser usada para analizar muestras mĆ©dicas de fluidos, como la" +" sangre, si se le pone un tubo de ensayo." #: lang/json/furniture_from_json.py msgid "bathtub" @@ -119783,6 +120584,19 @@ msgstr "" "madera. Aunque estĆ” fabricada para soportar las condiciones del exterior y " "es una mejora con respecto al suelo, no es particularmente cĆ³moda." +#: lang/json/furniture_from_json.py +msgid "metal bench" +msgstr "banco metĆ”lico" + +#. ~ Description for metal bench +#: lang/json/furniture_from_json.py +msgid "" +"A bench made of scrap metal. Not the most comfortable furniture you've ever" +" seen." +msgstr "" +"Es un banco hecho de chatarra. No es el mueble mĆ”s cĆ³modo que hayas visto en" +" tu vida." + #: lang/json/furniture_from_json.py msgid "bulletin board" msgstr "tablĆ³n de anuncios" @@ -120395,6 +121209,35 @@ msgstr "" "Es un tanque enorme de metal que puede contener de manera segura una gran " "cantidad de lĆ­quido." +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "fuel tank" +msgstr "tanque de combustible" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with gasoline." +msgstr "Es un tanque lleno de combustible." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken fuel tank" +msgstr "tanque roto de combustible" + +#. ~ Description for broken fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with gasoline." +msgstr "Es un tanque roto que en algĆŗn momento tuvo combustible." + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with diesel." +msgstr "Es un tanque lleno de gasoil." + +#. ~ Description for broken fuel tank +#. ~ Description for broken diesel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with diesel." +msgstr "Es un tanque roto que en algĆŗn momento tuvo gasoil." + #: lang/json/furniture_from_json.py msgid "dumpster" msgstr "contenedor" @@ -120424,6 +121267,52 @@ msgstr "" " de necesitar alimentaciĆ³n elĆ©ctrica, tiene un pedal que te permite " "utilizarla sin electricidad." +#: lang/json/furniture_from_json.py +msgid "riveted metal crate" +msgstr "caja metĆ”lica remachada" + +#. ~ Description for riveted metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This huge box is made of a dull metal, riveted together. There is no " +"obvious opening mechanism, and the rivets don't match any of your tools. " +"The only way in would be to smash it." +msgstr "" +"Este enorme caja estĆ” hecha de metal armada con remaches. No tiene un " +"mecanismo de apertura obvio y los remaches no coinciden con ninguna de tus " +"herramientas. La Ćŗnica forma de abrirla serĆ­a rompiĆ©ndola." + +#: lang/json/furniture_from_json.py +msgid "sealed metal crate" +msgstr "caja metĆ”lica sellada" + +#. ~ Description for sealed metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This is a huge, tightly sealed storage crate made from welded and riveted " +"sheet metal. The sealing mechanism is too tight to open bare-handed and " +"would need some kind of prying instrument to release." +msgstr "" +"Es una enorme caja sellada firmemente hecha con placas de metal remachadas y" +" soldadas. El mecanismo de sellado es muy fuerte como para abrirla con la " +"mano y necesitarĆ­as alguna clase de herramienta para sacarla." + +#: lang/json/furniture_from_json.py +msgid "open metal crate" +msgstr "caja metĆ”lica abierta" + +#. ~ Description for open metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This large metal crateā€™s lid is unsealed, and hinges open easily to reveal a" +" number of storage shelves inside. Once open, the side panels also swing " +"wider for easy access." +msgstr "" +"La tapa de esta gran caja metĆ”lica estĆ” sin sellar, y se puede abrir " +"fĆ”cilmente para revelar varios estantes de almacenamiento que tiene adentro." +" Una vez abierta, los paneles del costado tambiĆ©n se mueven para tener un " +"acceso mĆ”s fĆ”cil." + #: lang/json/furniture_from_json.py msgid "counter" msgstr "mesada" @@ -120536,6 +121425,15 @@ msgstr "Ā”Sentate cuando comĆ©s!" msgid "a low table for livingrooms." msgstr "es una mesa para livings." +#: lang/json/furniture_from_json.py +msgid "metal table" +msgstr "mesa metĆ”lica" + +#. ~ Description for metal table +#: lang/json/furniture_from_json.py +msgid "A serviceable but simple table made of scrap metal." +msgstr "Es una mesa simper pero Ćŗtil hecha de chatarra." + #: lang/json/furniture_from_json.py msgid "tatami mat" msgstr "tatami" @@ -120782,6 +121680,19 @@ msgstr "restos de metal" msgid "Pile of various bent and twisted metals." msgstr "Es una pila de distintos metales doblados y torcidos." +#: lang/json/furniture_from_json.py +msgid "radioactive slag" +msgstr "desecho radioactivo" + +#. ~ Description for radioactive slag +#: lang/json/furniture_from_json.py +msgid "" +"A pile of melted slag from a destroyed nuclear reactor. What are you doing " +"looking at this? Get the hell out of here, you nutcase!" +msgstr "" +"Es una pila de desecho derretido de algĆŗn reactor nuclear destruido. ĀæQuĆ© " +"hacĆ©s mirando esto? Ā”SalĆ­ de acĆ”, loco de mierda!" + #: lang/json/furniture_from_json.py msgid "pile of ash" msgstr "pila de ceniza" @@ -120866,6 +121777,44 @@ msgstr "" "Es un poste largo de madera que se usaba para sostener los cables de " "electricidad y otros servicios, pero ahora no sirve de mucho." +#: lang/json/furniture_from_json.py +msgid "scrap metal bridge" +msgstr "puente de chatarra" + +#. ~ Description for scrap metal bridge +#: lang/json/furniture_from_json.py +msgid "A simple bridge made of riveted sheet metal." +msgstr "Es un simple puente hecho con lĆ”minas de metal remachadas." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py +msgid "broken console" +msgstr "consola rota" + +#. ~ Description for broken console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It doesn't seem to be working. " +"It's the broken screen and shattered circuit boards that's telling you that." +msgstr "" +"Es una terminal autĆ³noma de computadora. No parece estar funcionando. Eso te" +" lo sugieren la pantalla rota y los circuitos destrozados." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "computer console" +msgstr "consola de computadora" + +#. ~ Description for computer console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It can be used to view contents and" +" perform any allowed functions. It might even be possible to hack it, given" +" the skills." +msgstr "" +"Es una terminal autĆ³noma de computadora. Puede ser usada para ver su " +"contenido y realizar las funciones permitidas. Incluso podrĆ­a ser hackeada, " +"si tenĆ©s la habilidad." + #: lang/json/furniture_from_json.py msgid "forge" msgstr "forja" @@ -121295,6 +122244,15 @@ msgstr "" "ConsiderĆ”s si podrĆ”s comprar algo acĆ”, porque estĆ” rota. Por ahĆ­ si la " "rompĆ©s un poco mĆ”s, Ā”no vas a necesitar pagar nada!" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "rope leading up" +msgstr "soga para subir" + +#. ~ Description for rope leading up +#: lang/json/furniture_from_json.py +msgid "A rope. You could climb it up." +msgstr "Es una soga. PodĆ©s trepar por ella." + #: lang/json/furniture_from_json.py msgid "atomic butter churn on a stand" msgstr "mantequeras atĆ³micas con pie" @@ -125813,6 +126771,21 @@ msgstr "" "La electricidad salta sobrenaturalmente entre las puntas de esta fronda " "alienĆ­gena." +#: lang/json/gun_from_json.py +msgid "hurled rubble" +msgid_plural "hurled rubbles" +msgstr[0] "escombro arrojado" +msgstr[1] "escombros arrojados" + +#: lang/json/gun_from_json.py +msgid "Stone at the ready to crush that which isn't part of the blob." +msgstr "Es piedra lista para aplastar que no es parte del blobo." + +#: lang/json/gun_from_json.py +msgctxt "gun_type_type" +msgid "throw" +msgstr "tirar" + #: lang/json/gun_from_json.py msgid "nail gun" msgid_plural "nail guns" @@ -125880,7 +126853,7 @@ msgstr[1] "escopetas de palanca caseras" msgid "" "A short homemade lever-action shotgun with a small internal tube magazine. " "While still a primitive pipe and 2x4 design, it is a formiddable shotgun in " -"it's own right with room for improvement." +"its own right with room for improvement." msgstr "" "Es una escopeta de acciĆ³n de palanca corta, hecha en casa, con un pequeƱo " "tubo cargador interno. Aunque sigue siendo un primitivo diseƱo de caƱo y " @@ -126322,10 +127295,10 @@ msgstr "" "el objetivo." #: lang/json/gun_from_json.py -msgid "four winds shotgun" -msgid_plural "four winds shotguns" -msgstr[0] "escopeta cuatro vientos" -msgstr[1] "escopetas cuatro vientos" +msgid "slam-fire pipe shotgun" +msgid_plural "slam-fire pipe shotguns" +msgstr[0] "escopeta de caƱo slamfire" +msgstr[1] "escopetas de caƱo slamfire" #: lang/json/gun_from_json.py msgid "" @@ -126335,6 +127308,22 @@ msgstr "" "Es una escopeta simple compuesta de dos caƱos gruesos de acero, una tapa en " "la punta y un clavo. La ausencia de miras la hacen solamente Ćŗtil de cerca." +#: lang/json/gun_from_json.py +msgid "double slam-fire pipe shotgun" +msgid_plural "double slam-fire pipe shotguns" +msgstr[0] "escopeta doble de caƱo slamfire" +msgstr[1] "escopetas dobles de caƱo slamfire" + +#: lang/json/gun_from_json.py +msgid "" +"A crude shotgun, composed of four thick steel pipes, two end caps and two " +"nails. The lack of sights make this weapon only useful at point-blank " +"range." +msgstr "" +"Es una escopeta simple compuesta de cuatro caƱos gruesos de acero, dos tapas" +" en la punta y dos clavo. La ausencia de miras la hacen solamente Ćŗtil de " +"cerca." + #: lang/json/gun_from_json.py msgid "flaregun" msgid_plural "flareguns" @@ -126878,11 +127867,6 @@ msgstr "" "Es una honda de cuero. Puede lanzar piedras mucho mĆ”s lejos y rĆ”pido que si " "lo hicieras con la mano." -#: lang/json/gun_from_json.py -msgctxt "gun_type_type" -msgid "throw" -msgstr "tirar" - #: lang/json/gun_from_json.py msgid "slingshot" msgid_plural "slingshots" @@ -134054,6 +135038,11 @@ msgstr "" "para acceder a los controles o usar la tecla para controlar vehĆ­culos (por " "defecto '^')." +#. ~ Please leave anything in unchanged. +#: lang/json/json_flag_from_json.py +msgid "When active, turns engines on and off automatically." +msgstr "Cuando estĆ” activo, enciende o apaga los motores automĆ”ticamente." + #. ~ Please leave anything in unchanged. #: lang/json/json_flag_from_json.py msgid "Illuminated items in this space will not illuminate nearby squares." @@ -135782,6 +136771,10 @@ msgstr "Activar purificadores de agua" msgid "Toggle tracking" msgstr "Rastreador" +#: lang/json/keybinding_from_json.py +msgid "Toggle smart engine controller" +msgstr "Cambiar controlador inteligente de motor" + #: lang/json/keybinding_from_json.py src/turret.cpp src/vehicle_use.cpp msgid "Set turret firing modes" msgstr "Establecer modo de disparo de torreta" @@ -143285,7 +144278,7 @@ msgstr "Quisquilloso" #. ~ Description for mission '{'str': 'Picky Meals'}' #: lang/json/mission_def_from_json.py msgid "Find 100 salt." -msgstr "Encontrar 100 unidades de sal." +msgstr "Conseguir 100 unidades de sal." #: lang/json/mission_def_from_json.py msgid "I need a supply of salt." @@ -143339,7 +144332,7 @@ msgstr "Comidas al Escabeche" #. ~ Description for mission '{'str': 'Pickled Meals'}' #: lang/json/mission_def_from_json.py msgid "Find 5 glass jars." -msgstr "Encontrar 5 frascos de vidrio." +msgstr "Conseguir 5 frascos de vidrio." #: lang/json/mission_def_from_json.py msgid "I need several glass jars." @@ -143385,7 +144378,8 @@ msgstr "ĀæEncontraste los frascos?" msgid "" "Thank you for your help. Here's your reward. I have one more task to do." msgstr "" -"Gracias por tu ayuda. AcĆ” estĆ” tu recompensa. Tengo otra tarea para hacer." +"Gracias por tu ayuda. AcĆ” estĆ” tu recompensa. Tengo otra tarea para " +"ofrecerte." #: lang/json/mission_def_from_json.py msgid "It's not a big deal, it isn't that urgent." @@ -143398,7 +144392,7 @@ msgstr "Comidas Espinosas" #. ~ Description for mission '{'str': 'Prickled Meals'}' #: lang/json/mission_def_from_json.py msgid "Find a butcher knife." -msgstr "Encontrar cuchillo de carnicero." +msgstr "Conseguir cuchillo de carnicero." #: lang/json/mission_def_from_json.py msgid "I need something sharper." @@ -143446,7 +144440,7 @@ msgstr "Ocupado en el Trabajo" #. ~ Description for mission '{'str': 'Busy While Work'}' #: lang/json/mission_def_from_json.py msgid "Find 3 mystery novels." -msgstr "Encontrar 3 novelas de misterio." +msgstr "Conseguir 3 novelas de misterio." #: lang/json/mission_def_from_json.py msgid "I'd like to read some mystery novels." @@ -143535,7 +144529,7 @@ msgstr "Golosinas" #. ~ Description for mission '{'str': 'Sweets'}' #: lang/json/mission_def_from_json.py msgid "Find 25 blackberries." -msgstr "Encontrar 25 zarzamoras." +msgstr "Conseguir 25 zarzamoras." #: lang/json/mission_def_from_json.py msgid "I need 25 blackberries." @@ -143613,7 +144607,7 @@ msgstr "Decile a mi familia que los amoā€¦" #: lang/json/mission_def_from_json.py msgid "Find an anvil" -msgstr "Encontrar un yunque" +msgstr "Conseguir un yunque" #: lang/json/mission_def_from_json.py msgid "I need an anvil to do advanced metal work." @@ -143795,7 +144789,7 @@ msgstr "Me pregunto si los animales se habrĆ”n comido todo lo verdeā€¦" #: lang/json/mission_def_from_json.py msgid "Find 20 bee balm seeds" -msgstr "Encontrar 20 semillas de monarda" +msgstr "Conseguir 20 semillas de monarda" #: lang/json/mission_def_from_json.py msgid "I could use some seeds from the forest." @@ -144006,7 +145000,7 @@ msgstr "Daisy" #: lang/json/mission_def_from_json.py msgid "Find 10 3L jars" -msgstr "Encontrar 10 frascos de 3L" +msgstr "Conseguir 10 frascos de 3L" #: lang/json/mission_def_from_json.py msgid "I could use some help scavenging." @@ -144045,7 +145039,7 @@ msgstr "Me pregunto quĆ© habrĆ” pasado con todos los frascosā€¦" #: lang/json/mission_def_from_json.py msgid "Find 100 wheat seeds" -msgstr "Encontrar 20 semillas de trigo" +msgstr "Conseguir 20 semillas de trigo" #: lang/json/mission_def_from_json.py msgid "I do have some more scavenging for you." @@ -144151,7 +145145,7 @@ msgstr "Steve" #: lang/json/mission_def_from_json.py msgid "Find The Art of Glassblowing book" -msgstr "Encontrar el libro El Arte de Soplar Vidrio" +msgstr "Conseguir el libro El Arte de Soplar Vidrio" #: lang/json/mission_def_from_json.py msgid "I need more knowledge to get the glass blowing started." @@ -144658,11 +145652,11 @@ msgstr "Ā”No! Por dios, no, esto no puede estar pasandoā€¦" #: lang/json/mission_def_from_json.py msgid "Find Dana's family sourdough culture" -msgstr "" +msgstr "Encontrar cultivo de masa madre de familia de Dana" #: lang/json/mission_def_from_json.py msgid "I could get my real sourdough starterā€¦" -msgstr "" +msgstr "PodrĆ­a conseguir mi verdadero prefermento de masa madreā€¦" #: lang/json/mission_def_from_json.py msgid "" @@ -144672,28 +145666,39 @@ msgid "" "my family for generationsā€¦ if you can bring him to me, I'll bake you the " "finest bread you've ever had." msgstr "" +"Si te gusta este pan de segunda, podrĆ­as arriesgar tu vida por algo que " +"realmente valga la pena. DejĆ© mi verdadero prefermento de masa madre en la " +"panaderĆ­a donde trabajaba. Ese bebĆ© tiene cien aƱos de edad, y ha estado en " +"mi familia por generacionesā€¦ si me lo podrĆ­as traer, te podrĆ­a cocinar el " +"pan de mayor calidad que verĆ”s en tu vida." #: lang/json/mission_def_from_json.py msgid "" "Take care of yourself out there. And listen, when you bring my sourdough " "back, I don't want to see a scratch on him, you understand?" msgstr "" +"TenĆ© cuidado allĆ”. Y escuchame, cuando traigas mi masa madre, no quiero ni " +"ver un rasguƱo en ella, Āæentendiste?" #: lang/json/mission_def_from_json.py msgid "" "I can understand why you think you wouldn't want to risk your life for a " "bread starter. You haven't tried that bread." msgstr "" +"Puedo entender por quĆ© no querrĆ­as arriesgar tu vida por un prefermento de " +"pan. No sabĆ©s lo que es ese pan." #: lang/json/mission_def_from_json.py msgid "" "He'll be in the right-hand fridge, in a jar with a picture of the Millennium" " Falcon on it." msgstr "" +"EstĆ” en la heladera de la derecha, en un frasco con una imagen del " +"Millennium Falcon." #: lang/json/mission_def_from_json.py msgid "So, you seen my sourdough starter?" -msgstr "" +msgstr "ĀæY? ĀæViste mi prefermento de masa madre?" #: lang/json/mission_def_from_json.py msgid "" @@ -144702,20 +145707,26 @@ msgid "" "being abandoned so long, but he'll be operational soon and then you can come" " back for some real bread." msgstr "" +"Uh, no te vas a arrepentir de esto. Puede que no te parezca mucho pero tiene" +" lo necesario, pibe. Me va a llevar unos dĆ­as revivirla despuĆ©s de haber " +"estado abandonada por tanto tiempo, pero pronto estarĆ” funcionando y vas a " +"poder venir a buscar un verdadero pan." #: lang/json/mission_def_from_json.py msgid "This ain't it." -msgstr "" +msgstr "Esta no es." #: lang/json/mission_def_from_json.py msgid "" "I am not sure if I'm gonna make it through the Cataclysm without my special " "jar of goop." msgstr "" +"No estoy seguro si podrĆ© sobrevivir al Cataclismo sin mi frasco especial de " +"pegote." #: lang/json/mission_def_from_json.py msgid "Bring an acoustic guitar" -msgstr "" +msgstr "Traer una guitarra acĆŗstica" #: lang/json/mission_def_from_json.py msgid "" @@ -144723,52 +145734,62 @@ msgid "" "here? I don't know how much I could thank you, though, if you're looking " "for payment. You'd sure be improving the mood, though." msgstr "" +"SĆ­, seguro, imaginate cĆ³mo serĆ­an las cosas si tuviĆ©ramos un poco de mĆŗsica " +"en vivo. No sĆ© cuĆ”nto te podrĆ­a agradecer, igual, si es que esperĆ”s una " +"recompensa. Lo que sĆ­, nos vas a mejorar el humor." #: lang/json/mission_def_from_json.py msgid "" "I just want a functional acoustic guitar. Preferably one that hasn't been " "used to cave in any zombie skulls." msgstr "" +"Solamente quiero una guitarra acĆŗstica que funcione. Preferiblemente, una " +"que no haya sido usada para romperle la cabeza a un zombi." #: lang/json/mission_def_from_json.py msgid "Great! We'll be makin' music in no time!" -msgstr "" +msgstr "Ā”Genial! Ā”Vamos a empezar con la mĆŗsica en vivo en cualquier momento!" #: lang/json/mission_def_from_json.py msgid "Oh well. I understand your reluctancyā€¦ I guess." -msgstr "" +msgstr "Uh, bueno. Entiendo tu renuenciaā€¦ creo." #: lang/json/mission_def_from_json.py msgid "" "Well, I'll let you in on a little secret. Guitars COULD be found at a music" " store. Let that one sink in a bit." msgstr "" +"Bueno, te cuento un pequeƱo secreto. Las guitarras PODRƍAN encontrarse en un" +" local de instrumentos. PensĆ” en eso un ratito." #: lang/json/mission_def_from_json.py msgid "How's my guitar comin', friend?" -msgstr "" +msgstr "ĀæY? ĀæCĆ³mo va lo de mi guitarra, amigo?" #: lang/json/mission_def_from_json.py msgid "" "Hell yeah, bud! You just made a lot of people really happy! In thanks, " "I'll have enough cash to offer you more recompense for our little dealings." msgstr "" +"Ā”Una buena, viejo! Ā”AcabĆ”s de hacer feliz a mucha gente! En agradecimiento, " +"tengo suficiente plata para ofrecerte en recompensa por nuestros pequeƱos " +"acuerdos." #: lang/json/mission_def_from_json.py msgid "Huh. Thisā€¦ is something, isn't it." -msgstr "" +msgstr "Huh. Estoā€¦ es algo, Āæno?" #: lang/json/mission_def_from_json.py msgid "No worries. They don't grow from trees, but we have time." -msgstr "" +msgstr "No hay drama. No crecen en los Ć”rboles, pero tenemos tiempo." #: lang/json/mission_def_from_json.py msgid "Find a copy of the Quran" -msgstr "" +msgstr "Conseguir una copia del CorĆ”n" #: lang/json/mission_def_from_json.py msgid "I could use a bit of help to find a copy of the Quran." -msgstr "" +msgstr "Me vendrĆ­a bien un poco de ayuda para encontrar una copia del CorĆ”n." #: lang/json/mission_def_from_json.py msgid "" @@ -144779,14 +145800,20 @@ msgid "" "really love to have a copy of the Quran to read. This seems like a time to " "get back in touch with God, you know?" msgstr "" +"Me siento un poco tonto pidiendo esto, pero bueno. Nunca me interesaron los " +"libros religiosos ni cosas asĆ­. Generalmente iba a la mezquita los viernes, " +"e intentaba rezar cinco veces al dĆ­a pero casi nunca lo hacĆ­a. Supongo que " +"no soy buen musulmĆ”n, pero con todo lo que pasĆ³ me gustarĆ­a tener una copia " +"del CorĆ”n para leer. Este parece un momento para volver a conectarse con " +"Dios, Āæno te parece?" #: lang/json/mission_def_from_json.py msgid "Thank you. I'll see if I can save up a little reward for you." -msgstr "" +msgstr "Gracias. Voy a intentar juntar una recompensa para vos." #: lang/json/mission_def_from_json.py msgid "That's okay. Thanks for offering." -msgstr "" +msgstr "EstĆ” bien. Gracias por ofrecerte." #: lang/json/mission_def_from_json.py msgid "" @@ -144794,6 +145821,9 @@ msgid "" "most libraries and bookstores. Make sure you get the translated version, I " "can't read Arabic!" msgstr "" +"No es tan comĆŗn como la biblia pero deberĆ­as encontrar copias en la mayorĆ­a " +"de las bibliotecas y librerĆ­as. Fijate de conseguir una versiĆ³n traducida, " +"Ā”no leo Ć”rabe!" #: lang/json/mission_def_from_json.py msgid "" @@ -144802,16 +145832,21 @@ msgid "" "proceeds for if you managed this, here you go. It's not much but I hope it " "helps." msgstr "" +"Muchas gracias. Teniendo una copia a mano ya me siento un poco mejor. Hice " +"unas tareas de mĆ”s y guardĆ© las ganancias para vos. No es mucho pero espero " +"que te ayude." #: lang/json/mission_def_from_json.py msgid "" "It's okay. I don't know how much comfort I'd have found in an old book " "anyway." msgstr "" +"EstĆ” bien. No sĆ© cuĆ”nto consuelo hubiera encontrado en un libro viejo, " +"igual." #: lang/json/mission_def_from_json.py msgid "Find an electric motor" -msgstr "" +msgstr "Conseguir un motor elĆ©ctrico" #: lang/json/mission_def_from_json.py msgid "" @@ -144868,7 +145903,7 @@ msgstr "No hay problema. Avisame si querĆ©s volver a intentarlo." #: lang/json/mission_def_from_json.py msgid "Bring back a 60L metal tank" -msgstr "" +msgstr "Traer un tanque de metal de 60L" #: lang/json/mission_def_from_json.py msgid "" @@ -144883,6 +145918,9 @@ msgid "" "I can get started building the compressor, but I need a large metal tank to " "store compressed air centrally. About 60 liters should doā€¦" msgstr "" +"Puedo empezar a construir el compresor, pero necesito un tanque grande de " +"metal para almacenar el aire comprimido. De unos 60 litros deberĆ­a andar " +"bienā€¦" #: lang/json/mission_def_from_json.py msgid "" @@ -144891,6 +145929,9 @@ msgid "" "enough. Heck, if you get some sheet metal you could probably even weld a " "good one together." msgstr "" +"Tiene que ser un tanque bien fuerte, como uno de propano o algo asĆ­ā€¦ podĆ©s " +"fijarte los tanques de combustible, siempre que sean resistentes. Carajo, si" +" conseguĆ­s lĆ”minas de metal probablemente puedas soldarlas y hacer uno." #: lang/json/mission_def_from_json.py msgid "Any sign of a tank I can use?" @@ -144917,7 +145958,7 @@ msgstr "" #: lang/json/mission_def_from_json.py msgid "Find 5 first aid kits" -msgstr "" +msgstr "Conseguir 5 botiquines de primeros auxilios" #: lang/json/mission_def_from_json.py msgid "" @@ -144926,20 +145967,27 @@ msgid "" "common stuff if I had some supplies to help out. Could you bring me a few " "extra first aid kits? Five would probably have enough to last us a while." msgstr "" +"Hay un mĆ©dico en frente ayudando a cualquiera que pueda pagarā€¦ pero para " +"nosotros acĆ”, la plata es para la comida. Puedo atender cortes simples, " +"golpes y las cosas comunes si tuviera suministros mĆ©dicos. ĀæMe podrĆ”s " +"conseguir unos botiquines de primeros auxilios? Con cinco estarĆ­amos bien " +"por un tiempo." #: lang/json/mission_def_from_json.py msgid "Thanks so much. It's a small thing but it'd be really helpful." -msgstr "" +msgstr "Muchas gracias. Es poco pero nos va a ayudar bastante." #: lang/json/mission_def_from_json.py msgid "That's okay. I'm sure we'll make do somehow." -msgstr "" +msgstr "EstĆ” bien. Seguro que vamos a poder solucionarlo" #: lang/json/mission_def_from_json.py msgid "" "Lots of people used to have first aid kits in their bathrooms. I'm sure " "they can't all have been looted." msgstr "" +"Mucha gente guardaba botiquines en los baƱos. Seguro que alguno quedarĆ” " +"todavĆ­a." #: lang/json/mission_def_from_json.py msgid "" @@ -144948,14 +145996,18 @@ msgid "" "these are merch, the local money, you can trade them for goods from the " "shop." msgstr "" +"Muchas gracias. Escuchame, le dije a algunos lo que ibas a hacer para " +"nosotros y pudimos juntar un poco de plata. No es mucho pero espero que te " +"sirvaā€¦ acĆ” tenĆ©s unos mercs, es plata local, podĆ©s usarlos para comprar " +"cosas en el local." #: lang/json/mission_def_from_json.py msgid "Find 6 bottles of Prozac" -msgstr "" +msgstr "Conseguir 6 botellas de Prozac" #: lang/json/mission_def_from_json.py msgid "We could still use your helpā€¦" -msgstr "" +msgstr "TodavĆ­a nos podrĆ­as hacer algoā€¦" #: lang/json/mission_def_from_json.py msgid "" @@ -144965,26 +146017,37 @@ msgid "" " people having to starve to pay for them. Three month's worth - about 6 " "bottles - would last us a little while." msgstr "" +"Yo probablemente no tendrĆ­a que estar recetando estas cosas, pero hay mucha " +"gente necesitando ayuda para dormir. Si me podĆ©s conseguir unos " +"antidepresivos, Rhyzaea y yo podrĆ­as asegurarnos de repartirlos " +"apropiadamente sin que la gente tenga que morirse de hambre para poder " +"pagarlos. Unas 6 botellas, lo que dura unos tres meses, va a estar bien por " +"ahora." #: lang/json/mission_def_from_json.py msgid "" "Prozac was really common. You can probably find it in most medicine " "cabinets and pharmacies." msgstr "" +"El Prozac era muy comĆŗn. Probablemente lo puedas encontrar en los armarios " +"de consultorios o farmacias." #: lang/json/mission_def_from_json.py msgid "" "Thanks so much. Listen, I told some of the others what you were up to for " "us and we pooled our cash to thank you. You've done a lot to help us out." msgstr "" +"Muchas gracias. Escuchame, le dije a algunos lo que ibas a hacer para " +"nosotros y pudimos juntar un poco de plata. Hiciste mucho para ayudarnos." #: lang/json/mission_def_from_json.py msgid "Make a makeshift haircut kit" -msgstr "" +msgstr "Hacer un equipo improvisado cortapelo" #: lang/json/mission_def_from_json.py msgid "If I had some equipment, I could do some hairdresser work here." msgstr "" +"Si tuviera equipamiento, podrĆ­a hacer algĆŗn trabajo de peliquerĆ­a acĆ”." #: lang/json/mission_def_from_json.py msgid "" @@ -144993,16 +146056,22 @@ msgid "" "styling for people around here. I'll even give you a free haircut for your " "troubles." msgstr "" +"No pensĆ© en traerme el equipo de peluquerĆ­a cuando fui evacuado. Si pudieras" +" conseguirme un equipo bĆ”sico para cortar pelo, podrĆ­a hacer un poco de " +"estilismo para la gente acĆ”. Incluso te voy a dar un corte gratis por tu " +"ayuda." #: lang/json/mission_def_from_json.py msgid "" "Cool, thanks. It'll be good to have something useful to do, and to not be " "staring at so many shaggy slobs." msgstr "" +"Copado, gracias. Va a estar bueno tener algo Ćŗtil para hacer, y no estar " +"viendo tantos peludos desaliƱados." #: lang/json/mission_def_from_json.py msgid "Whatever, I'll keep twiddling my thumbs then." -msgstr "" +msgstr "No importa, voy a seguir cruzado de brazos entonces." #: lang/json/mission_def_from_json.py msgid "" @@ -145010,6 +146079,9 @@ msgid "" "way to keep it all stored clean when I'm not using it, like a leather pouch " "or something. I can get the rest of what I need from shelter supplies." msgstr "" +"No necesito muchas cosas. Tijeras, un espejito, un poco de tela y alguna " +"manera de mantener todo limpio cuando no lo uso, como un bolsito de cuero o " +"algo asĆ­. El resto lo puedo conseguir en los refugios." #: lang/json/mission_def_from_json.py msgid "" @@ -145017,16 +146089,21 @@ msgid "" " I could probably inexplicably make your hair longer or a different color " "with them." msgstr "" +"Bueno, esto estĆ” bastante bien. MirĆ”, estas tijeras son tan buenas que " +"podrĆ­a hacer que tu pelo sea inexplicablemente mĆ”s largo o de un color " +"diferente." #: lang/json/mission_def_from_json.py msgid "" "Seriously? You failed to find *scissors*? How do you tie your shoes in the" " morning?" msgstr "" +"ĀæEn serio? ĀæNo pudiste encontrar *tijeras*? ĀæCĆ³mo hacĆ©s para atarte los " +"cordones cuando te levantĆ”s?" #: lang/json/mission_def_from_json.py msgid "In a Pickle Pt. 2" -msgstr "" +msgstr "En un Berenjenal, parte 2" #. ~ Description for mission '{'str': 'In a Pickle Pt. 2'}' #: lang/json/mission_def_from_json.py @@ -145034,10 +146111,12 @@ msgid "" "Deliver 50 large three-liter jars in exchange for " "certified notes." msgstr "" +"Entregar 50 frascos grandes de tres litros a cambio de " +" Bonos Certificados." #: lang/json/mission_def_from_json.py msgid "I do have some work for you." -msgstr "" +msgstr "Tengo un trabajo para vos." #: lang/json/mission_def_from_json.py msgid "" @@ -145046,6 +146125,11 @@ msgid "" " use some larger jars though for big stock items. Can you bring me 50 large" " three liter jars? I'll pay you a Certified Note per two." msgstr "" +"Escuchaste bien. Cuando trajiste esos frascos nos pusimos a pensar en " +"agrandar nuestro almacenamiento de comida, desde deshidratados a incluir " +"enlatados. Nos vendrĆ­an bien unos frascos mĆ”s grandes para las cosas " +"grandes. ĀæMe podrĆ”s traer 50 frascos grandes de tres litros? Te voy a dar un" +" Bono Certificado por cada dos frascos." #: lang/json/mission_def_from_json.py msgid "" @@ -145054,16 +146138,22 @@ msgid "" "scavengers in smaller lots. This should be enough to test out our " "equipment." msgstr "" +"Gracias. Una vez que establezcamos una industria artesanal con algunos de " +"nuestros compaƱeros, te voy a poder empezar a comprar estos a vos y otros " +"viajeros en pequeƱas cantidades. Esto deberĆ­a ser suficiente para probar " +"nuestro equipamiento." #: lang/json/mission_def_from_json.py msgid "" "Wow, that's a lot more jars than it sounded on paper. Thanks. Here's your " "payment." msgstr "" +"Wow, esos son muchos mĆ”s frascos de los que parecĆ­an por escrito. Gracias. " +"AcĆ” estĆ” tu pago." #: lang/json/mission_def_from_json.py msgid "Smokes, let's go." -msgstr "" +msgstr "Cigarrillos, vamos." #. ~ Description for mission '{'str': "Smokes, let's go."}' #: lang/json/mission_def_from_json.py @@ -145071,10 +146161,12 @@ msgid "" "Make a friend at the refugee center by handing over around five packs - 100 " "cigarettes." msgstr "" +"Hacete un amigo en el centro de refugiados regalando unos cinco paquetes - " +"100 cigarrillos." #: lang/json/mission_def_from_json.py msgid "Come on man, I just need a smoke." -msgstr "" +msgstr "Vamos, chabĆ³n, necesito un pucho." #: lang/json/mission_def_from_json.py msgid "" @@ -145082,10 +146174,13 @@ msgid "" "smoke. My stash has been running low for a while now. Think you could help" " me out here? A few packs is all I need." msgstr "" +"Con todo lo que estĆ” pasando, cada vez es mĆ”s difĆ­cil conseguir un " +"cigarrillo. Ya casi no me quedan mĆ”s. ĀæTe parece que me podrĆ”s ayudar? Con " +"unos paquetes estarĆ­a bien." #: lang/json/mission_def_from_json.py msgid "Thanks, it's great to see someone willing to help a guy out." -msgstr "" +msgstr "Gracias, quĆ© bueno es encontrarse gente dispuesta a ayudar a otro." #: lang/json/mission_def_from_json.py msgid "Well, I'll find someone else to do it for me." @@ -145096,14 +146191,18 @@ msgid "" "Plenty of smokers in towns. Gotta be some left over cigs in some of them " "houses." msgstr "" +"Hay muchos fumadores en los pueblos. Tienen que haber quedado algunos " +"cigarrillos en las casas." #: lang/json/mission_def_from_json.py msgid "Got the smokes?" -msgstr "" +msgstr "ĀæTenĆ©s los puchos?" #: lang/json/mission_def_from_json.py msgid "Thanks! I'll be sure to put in a good word for you around the center." msgstr "" +"Ā”Gracias! Me voy a asegurar de que se enteren lo que hiciste por mĆ­ en el " +"centro." #: lang/json/mission_def_from_json.py msgid "Clear Back Bay" @@ -145116,6 +146215,9 @@ msgid "" "leader of the Free Merchants to rest, in exchange for the local currency: " "Free Merchant certified notes." msgstr "" +"Limpiar la parte barricada de atrĆ”s del centro de refugiados y eliminar al " +"antiguo lĆ­der de los Mercaderes Libres, a cambio de la moneda local: Bonos " +"Certificados de los Mercaderes Libres." #: lang/json/mission_def_from_json.py msgid "" @@ -145127,6 +146229,14 @@ msgid "" "bother us again. We can't pay much, besides some of our own internal money " "which isn't good for that much yet, but it would help us to reclaim the bay." msgstr "" +"Si realmente querĆ©s dar una mano nos podrĆ­as ayudar a limpiar de muertos la " +"plataforma de atrĆ”s. Por miedo a salir durante los primeros dĆ­as del " +"Cataclismo, terminamos tirando nuestros muertos y los zombis que matamos en " +"la plataforma sellada de atrĆ”s. Nuestro prometedor lĆ­der de ese momento " +"tambiĆ©n muriĆ³ā€¦ se convirtiĆ³ en algo diferente. Matalos a todos y asegurate " +"de que no nos vuelvan a molestar. No podemos pagarte mucho y ademĆ”s algo de " +"nuestra moneda interna que todavĆ­a no sirve para mucho, pero nos ayudarĆ­a " +"para reclamar la bahĆ­a." #: lang/json/mission_def_from_json.py msgid "Please be careful, we don't need any more deaths." @@ -145155,6 +146265,10 @@ msgid "" "workers in exchange for supplies. They're getting some value in the center " "as a trade item, I'm afraid they're all we have to spare at the moment." msgstr "" +"Gracias, tener esa amenaza tan grande cerca de casa es estresante. AcĆ” tenĆ©s" +" algunos bonos certificados locales, con esto le pagamos a nuestros " +"trabajadores a cambio de suministros. Tienen algo de valor en el centro como" +" objeto de cambio, pero es lo Ćŗnico que tenemos para darte por el momento." #: lang/json/mission_def_from_json.py msgid "Missing Caravan" @@ -145167,6 +146281,9 @@ msgid "" "party, and eliminate any bandits or raiders in the vicinity in exchange for " " certified notes." msgstr "" +"Investigar el Ćŗltimo lugar conocido del grupo de cartoneros desaparecido, y " +"eliminar los bandidos o piratas en los alrededores a cambio de " +" Bonos Certificados." #: lang/json/mission_def_from_json.py msgid "" @@ -145179,6 +146296,15 @@ msgid "" "the supplies they were carrying, plus thirty certified notes - that's our " "own internal money, good for trading and such." msgstr "" +"Esta es un poco mĆ”s complicada que la Ćŗltima tarea, recientemente perdimos " +"un grupo de cartoneros que venĆ­an a comerciar con nosotros y nos gustarĆ­a " +"que investigues. Sospechamos que una banda de piratas o una horda los agarrĆ³" +" desprevenidos. Te puedo dar las coordenadas del Ćŗltimo mensaje de radio " +"pero nada mĆ”s. En cualquier caso, encargate de la amenaza asĆ­ los cartoneros" +" pueden seguir pasando relativamente seguros. La mejor recompensa que te " +"puedo ofrecer es que te quedes con los suministros que ellos llevaban ademĆ”s" +" de treinta bonos certificados - que es nuestra moneda interna, sirve para " +"comerciar y esas cosas." #: lang/json/mission_def_from_json.py msgid "Our community survives on trade, we appreciate it." @@ -145197,6 +146323,12 @@ msgid "" "food supply. If you get a chance, you should see if they need your " "assistance in the futureā€¦" msgstr "" +"Gracias, el mundo es un lugar mejor sin ellos. Dos de nuestros mejores " +"hombres han aceptado la ayuda de la Vieja Guardia para establecer un puesto " +"mientras vos no estabas. No tenĆ­amos otras opciones, los refugiados todavĆ­a " +"estĆ”n llegando y no sabemos quĆ© otra cosa hacer con nuestra provisiĆ³n " +"limitada de comida. Si tenĆ©s la oportunidad, deberĆ­as ir a ver si necesitan " +"tu ayudaā€¦" #: lang/json/mission_def_from_json.py msgid "Retrieve Prospectus" @@ -145208,6 +146340,8 @@ msgid "" "Visit the farming commune and bring the foreman's prospectus back to the " "refugee center, for certified notes." msgstr "" +"Visitar la comunidad granjera y traer el informe del capataz de nuevo al " +"centro de refugiados, por bonos certificados." #: lang/json/mission_def_from_json.py msgid "" @@ -145218,6 +146352,12 @@ msgid "" " with the foreman to get more detailed tasks. We've got 50 Certified Notes " "for you if you can do this for us." msgstr "" +"Recientemente, mandamos unas personas a iniciar un puesto, para asegurarnos " +"comida en un lugar mĆ”s seguro. El nuevo puesto que hemos comenzado podrĆ­a " +"usar tu ayuda. Necesito que consigas el informe del capataz antes de empezar" +" a mandar mĆ”s refugiados a la comunidad de la granja. Preguntale al capataz " +"para obtener tareas mĆ”s detalladas. Tenemos 50 Bonos Certificados para darte" +" si podĆ©s hacer esto." #: lang/json/mission_def_from_json.py msgid "I'm sure the outpost will expand quickly with your assistance." @@ -145238,10 +146378,14 @@ msgid "" "the garage in the back, so feel free to make use of that - you've been a " "great help to us." msgstr "" +"Con esto seremos capaces de convencer a otros de invertir en nuestra " +"comunidad. Gracias, acĆ” estĆ” tu plata. TambiĆ©n pudimos conseguir una palanca" +" para conectar en el garage en la parte de atrĆ”s, asĆ­ que usalo cuando " +"quieras - fuiste de gran ayuda para nosotros." #: lang/json/mission_def_from_json.py msgid "Solar Power" -msgstr "" +msgstr "EnergĆ­a Solar" #. ~ Description for mission '{'str': 'Solar Power'}' #: lang/json/mission_def_from_json.py @@ -145249,6 +146393,8 @@ msgid "" "Deliver 10 solar panels to help the Free Merchants set up a renewable power " "grid, in exchange for a handsome reward." msgstr "" +"Entregar 10 paneles solares para ayudar a los Mercaderes Libres a armar una " +"grilla de energĆ­a renovable, a cambio de una linda recompensa." #: lang/json/mission_def_from_json.py msgid "" @@ -145259,6 +146405,12 @@ msgid "" "few solar panels we could use them to top up our usage. We could pay you " "pretty handsomely to bring us, say, ten solar panels?" msgstr "" +"Estamos empezando a construir una nueva infraestructura acĆ” y nos gustarĆ­a " +"tener funcionando unos sistemas elĆ©ctricos nuevosā€¦ lamentablemente nuestro " +"sistema actual depende de un despliegue de algo llamado RTG. Los generadores" +" no son una opciĆ³n para usar bajo tierra, claro. Tenemos un techo grande y " +"plano y si tuviĆ©ramos algunos paneles solares podrĆ­amos usarlos. Te podemos " +"pagar bastante bien por traernos, digamos, diez paneles solares." #: lang/json/mission_def_from_json.py msgid "If you can do this for us our survival options would vastly increase." @@ -145269,6 +146421,8 @@ msgstr "" #: lang/json/mission_def_from_json.py msgid "Solar panels are pretty common on electric cars and on rooftops." msgstr "" +"Los paneles solares son bastante comunes en los autos elĆ©ctricos y en los " +"techos." #: lang/json/mission_def_from_json.py msgid "" @@ -145280,7 +146434,7 @@ msgstr "" #: lang/json/mission_def_from_json.py msgid "In a Pickle" -msgstr "" +msgstr "En un Berenjenal" #. ~ Description for mission '{'str': 'In a Pickle'}' #: lang/json/mission_def_from_json.py @@ -145288,6 +146442,8 @@ msgid "" "Deliver 100 half-liter glass canning jars to the Free Merchants to kickstart" " their food storage plans." msgstr "" +"Entregar 100 frascos para enlatar de medio litro a los Mercaderes Libres, " +"para que comiencen sus planes de conservaciĆ³n de comida." #: lang/json/mission_def_from_json.py msgid "" @@ -145300,18 +146456,29 @@ msgid "" "to get us set for the winter. I'll pay you a premium rate if you can bring " "us around a hundred jars to get us started." msgstr "" +"Mientras nos pudimos asegurar la comida para el dĆ­a a dĆ­a, llegamos con lo " +"justo. Nuestras reservas apenas alcanzarĆ”n para unos dĆ­as si algo hace que " +"nos tengamos que mantener encerrados. Necesitamos suministros para evitar " +"eso. Gracias a nuestro puesto tenemos un poco de carne y verduras llegando, " +"pero necesitamos una mejor manera para preservarlos. Algunos saben cĆ³mo " +"enlatar comidas, si tuviĆ©ramos una buena cantidad de frascos para conserva, " +"podrĆ­amos hacer pickles y carne enlatada para pasar el invierno. Te voy a " +"pagar mejor si nos podĆ©s traer unos cien frascos como para que empecemos." #: lang/json/mission_def_from_json.py msgid "" "It'll take a load off my shoulders if I can finally stop worrying about " "this." msgstr "" +"Me vas a sacar un peso de encima si puedo dejar de preocuparme por esto." #: lang/json/mission_def_from_json.py msgid "" "We'll hold for the moment, but I'll get an ulcer if I have to keep worrying." " If you reconsider let me know." msgstr "" +"Vamos a esperar por el momento, pero me va a salir una Ćŗlcera si me sigo " +"preocupando. Avisame si lo volvĆ©s a considerar." #: lang/json/mission_def_from_json.py msgid "" @@ -145322,6 +146489,12 @@ msgid "" "might be easier to just go straight through their office if you want more " "work." msgstr "" +"Una cosa menos en quĆ© preocuparse. Me alegra tener a alguien como vos de mi " +"lado. AcĆ” tenĆ©s 25 mercs, y el agente de bolsa va a comprar cualquier otro " +"frasco de vidrio que traigas - a un precio reducido, no podemos seguir " +"pagĆ”ndote tanto. En realidad, el agente dice que tiene otros trabajos como " +"este para vos, y que puede ser mĆ”s fĆ”cil ir directamente a su oficina si " +"buscĆ”s mĆ”s trabajo." #: lang/json/mission_def_from_json.py msgid "" @@ -145445,6 +146618,12 @@ msgid "" "everything to subzero temperatures. I bet the archives inside that lab are " "still working." msgstr "" +"AsĆ­ que parece que hubo meses, tal vez aƱos, de experimentos, y la " +"informaciĆ³n debe ser enorme. Las bases de datos lo suficientemente grandes " +"para almacenarla se sobrecalentarĆ”. Pero encontrĆ© comunicaciones de un " +"laboratorio que tenĆ­a una especie de portal de congelamiento abierto durante" +" el Cataclismo, haciendo que todo llegue a temperaturas bajo cero. Estoy " +"casi seguro que el laboratorio de ahĆ­ adentro sigue funcionando." #: lang/json/mission_def_from_json.py msgid "" @@ -145480,6 +146659,12 @@ msgid "" "there, find the tunnels that they dug, and download everything you can about" " the train network." msgstr "" +"En la informaciĆ³n encontramos un contrato grande para un tĆŗnel y " +"equipamiento de trenes, comprados hace mucho tiempo. Es la mejor pista que " +"tenemos. AcĆ” estĆ” la direcciĆ³n del laboratorio gubernamental donde fue " +"entregado el equipamiento. Quiero que vayas ahĆ­, encuentres los tĆŗneles que " +"hicieron y descargues cualquier informaciĆ³n que consigas de la red de " +"trenes." #: lang/json/mission_def_from_json.py msgid "So glad for your help." @@ -145506,16 +146691,16 @@ msgstr "" #: lang/json/mission_def_from_json.py msgid "Supply the arsonist." -msgstr "" +msgstr "Suministrar al pirĆ³mano." #. ~ Description for mission '{'str': 'Supply the arsonist.'}' #: lang/json/mission_def_from_json.py msgid "Bring the arsonist 42 kg of commercial fertilizer" -msgstr "" +msgstr "Conseguirle 42 kg de fertilizante comercial al pirĆ³mano" #: lang/json/mission_def_from_json.py msgid "I could use some help getting some materials." -msgstr "" +msgstr "Me vendrĆ­a bien un poco de ayuda para conseguir unos materiales." #: lang/json/mission_def_from_json.py msgid "" @@ -145524,40 +146709,51 @@ msgid "" " get me two bags of commercial fertilizer I could make something a lot more " "potent." msgstr "" +"Me vendrĆ­a bien un poco de ayuda para conseguir unos materiales. Las " +"molotovs estĆ”n buenos para quemar edificios pero son medio peligrosas para " +"uno mismo. Si me pudieras conseguir dos bolsas de fertilizante comercial, " +"podrĆ­a hacer algo mĆ”s potente." #: lang/json/mission_def_from_json.py msgid "Oh man, thanks so much friend. You won't regret it." -msgstr "" +msgstr "Uh, chabĆ³n, muchas gracias. No te vas a arrepentir." #: lang/json/mission_def_from_json.py msgid "Think it over." -msgstr "" +msgstr "Pensalo mejor." #: lang/json/mission_def_from_json.py msgid "" "Commercial fertilizer tends to be made from ammonium nitrate, which is also " "usable as an explosive. Try looking for some around the abandoned farms." msgstr "" +"El fertilizante comercial suele estar hecho de nitrato de amonio, que " +"tambiĆ©n es utilizable como explosivo. Fijate alrededor de algunas granjas " +"abandonadas." #: lang/json/mission_def_from_json.py msgid "" "Did you find any fertilizer? Are you sure this is the ammonium nitrate " "kind?" msgstr "" +"ĀæEncontraste algo de fertilizante? ĀæEstĆ”s seguro que estĆ” hecho con nitrato " +"de amonio?" #: lang/json/mission_def_from_json.py msgid "" "This is great! I'll get to work making something of this. You can have " "some of my Molotovs, I won't need quite so many now." msgstr "" +"Ā”EstĆ” buenĆ­simo! Voy a empezar a hacer algo con esto. Llevate algunas de mis" +" molotovs, no las voy a necesitar tanto ahora." #: lang/json/mission_def_from_json.py msgid "I guess I could convince the shelter to sell me some." -msgstr "" +msgstr "Supongo que puedo convencer al refugio para venderme un poco." #: lang/json/mission_def_from_json.py msgid "Damn. Perhaps I wasn't the only one who thought of this." -msgstr "" +msgstr "Mierda. Tal vez no fui el Ćŗnico en pensar en eso." #: lang/json/mission_def_from_json.py msgid "Kill Bandits" @@ -145570,6 +146766,9 @@ msgid "" " Ensure they meet a bitter end along with any associates, but watch out for" " traps around their hideout." msgstr "" +"Un par de ladrones estuvieron atacando negocios, y tienen una base cerca de " +"una cabina, Asegurate de darles un final oscuro pero cuidado con las trampas" +" que debe haber en su guarida." #: lang/json/mission_def_from_json.py msgid "" @@ -145579,6 +146778,12 @@ msgid "" "quick endā€¦ execute both of them for their crimes. Complete this and the Old" " Guard will consider you an asset in the region." msgstr "" +"No me gusta enviar hombres sin probar al campo pero si te mantuviste vivo " +"por tanto tiempo debĆ©s tener algunas habilidades. Hay por lo menos un par de" +" ladrones ocupando una cabaƱa por acĆ”, cualquiera que se abusa de los " +"civiles encuentra su final rĆ”pidamenteā€¦ ejecutalos a los dos por sus " +"crĆ­menes. TerminĆ” esto y la Vieja Guardia te va a considerar un valor en la " +"regiĆ³n." #: lang/json/mission_def_from_json.py msgid "Contractor, I welcome you aboard." @@ -145613,6 +146818,9 @@ msgid "" "Refugee Center. Investigate and bring them to justice without arousing any " "suspicions." msgstr "" +"La banda llamada Piratas del Infierno pueden tener un informante trabajando " +"dentro del Centro de Refugiados. InvestigĆ” y traelos a la justicia sin " +"levantar ninguna sospecha." #: lang/json/mission_def_from_json.py msgid "" @@ -145638,7 +146846,7 @@ msgstr "VolvĆ© cuando tengas la oportunidad, nos viene bien otro hombre Ćŗtil." #: lang/json/mission_def_from_json.py msgid "If they draw first blood their friends are less likely to blame youā€¦" -msgstr "" +msgstr "Si ellos son los primeros en atacar, sus amigos no van a culparteā€¦" #: lang/json/mission_def_from_json.py msgid "You deal with the rat?" @@ -145650,7 +146858,7 @@ msgstr "Gracias, yo voy a explicar todo si alguien pregunta." #: lang/json/mission_def_from_json.py msgid "Secure Trade Route" -msgstr "" +msgstr "Asegurar Ruta de Comercio" #. ~ Description for mission '{'str': 'Secure Trade Route'}' #: lang/json/mission_def_from_json.py @@ -145659,6 +146867,9 @@ msgid "" "caravan. Whoever or whatever is responsible must be quick and quiet - " "investigate the trade route and eliminate the threat." msgstr "" +"Uno de los Mercaderes Libres desapareciĆ³ mientras escoltaba una caravana. " +"Sea quien sea el responsable debe ser rĆ”pido y sigiloso - investigĆ” la ruta " +"y eliminĆ” la amenaza." #: lang/json/mission_def_from_json.py msgid "" @@ -145667,6 +146878,11 @@ msgid "" "packed caravan. They didn't hear any shots but I suppose some raider may " "have been real sneaky. Check out the area and report anything you find." msgstr "" +"Hay otro monstruo causĆ”ndole problemas a los comerciantes pero esta vez no " +"es humanoā€¦ por lo menos no parece. Un tipo desapareciĆ³ cuando estaba " +"caminando atrĆ”s de una caravana. No escucharon ningĆŗn disparo pero supongo " +"que algĆŗn pirata puede haber sido sigiloso. RevisĆ” el Ć”rea y avisanos de lo " +"que encuentres." #: lang/json/mission_def_from_json.py msgid "Thanks, keeping the people safe is what we try and do." @@ -145686,7 +146902,7 @@ msgstr "Buen trabajo, no estaba seguro de a quĆ© te estaba mandando. " #: lang/json/mission_def_from_json.py msgid "Assassinate Raider Leader" -msgstr "" +msgstr "Asesinar LĆ­der Pirata" #. ~ Description for mission '{'str': 'Assassinate Raider Leader'}' #: lang/json/mission_def_from_json.py @@ -145695,6 +146911,9 @@ msgid "" "attacks on the Free Merchants. Pay them a visit and execute the area " "leadership." msgstr "" +"La Vieja Guardia encontrĆ© un campamento de Piratas del Infierno que estĆ” " +"coordinando ataques contra los Mercaderes Libres. Visitalos y ejecutĆ” al " +"lĆ­der del lugar." #: lang/json/mission_def_from_json.py msgid "" @@ -145726,12 +146945,25 @@ msgid "" " don't forget your badge and gun. As a marshal all men or women assisting " "you are considered deputy marshals so keep them in line." msgstr "" +"Ahora, repita conmigoā€¦ Juro solemnemente que cuidarĆ© y defenderĆ© la " +"ConstituciĆ³n de los Estados unidos contra todos los enemigos, extranjeros y " +"localesā€¦ que mantendrĆ© la fĆ© verdadera y lealtad hacia los propiosā€¦ que " +"libremente tomarĆ© estĆ” obligaciĆ³n, sin ninguna reserva mental o propĆ³sito de" +" evasiĆ³nā€¦ y que cumplirĆ© bien y fielmente las tareas de la oficina a la que " +"estoy por pertenecer. Para establecer justicia, asegurar la tranquilidad, " +"proveer la defensa comĆŗn, promover el bienestar general y asegurar la " +"bendiciĆ³n de la libertad. Que Dios me ayude. Felicitaciones, Alguacil, no se" +" olvide la placa y el arma. Como alguacil, todos los hombres y mujeres que " +"lo acompaƱen serĆ”n considerados ayudantes de alguacil, asĆ­ que mantĆ©ngalos a" +" raya." #: lang/json/mission_def_from_json.py msgid "" "I'd recommend having two deputiesā€¦ it would be a death trap if a single man " "got surrounded." msgstr "" +"Te recomiendo tener dos ayudantesā€¦ serĆ­a una trampa mortal si un hombre solo" +" queda rodeado." #: lang/json/mission_def_from_json.py msgid "Has the leadership been dealt with?" @@ -145757,7 +146989,7 @@ msgstr "" #: lang/json/mission_def_from_json.py msgid "Return Field Data" -msgstr "" +msgstr "Recuperar InformaciĆ³n de Campo" #. ~ Description for mission '{'str': 'Return Field Data'}' #: lang/json/mission_def_from_json.py @@ -145767,6 +146999,10 @@ msgid "" " robot. If the robot remains operational, avoid direct confrontation and " "use EMP grenades to disable it." msgstr "" +"InvestigĆ” el campo cercano y volvĆ© con la Dra. Prado y el prototipo del " +"robot que ella estaba probando. Si no podĆ©s hacerlo, recuperĆ” la grabadora " +"E/S almacenada dentro del robot. Si el robot sigue estando operativo, evitĆ” " +"la confrontaciĆ³n directa y utilizĆ” granadas PEM para desactivarlo." #: lang/json/mission_def_from_json.py lang/json/talk_topic_from_json.py msgid "" @@ -145775,14 +147011,19 @@ msgid "" "Investigate the test and return with her and the prototype. Failing that, " "return with the data recorder that was attached to our prototype." msgstr "" +"Uno de nuestros cientĆ­ficos fue hace poco al laboratorio para realizar una " +"prueba de campo en un robot prototipo, pero no regresĆ³ y no sabemos nada " +"desde entonces. InvestigĆ” la prueba y regresĆ” con ella y el prototipo. Si no" +" lo podĆ©s hacer, recuperĆ” la grabadora de informaciĆ³n que estĆ” en el " +"prototipo." #: lang/json/mission_def_from_json.py msgid "We appreciate your help, good luck." -msgstr "" +msgstr "Agradecemos tu ayuda, buena suerte." #: lang/json/mission_def_from_json.py msgid "Don't expect our help then." -msgstr "" +msgstr "No esperes ayuda nuestra, entonces." #: lang/json/mission_def_from_json.py lang/json/talk_topic_from_json.py msgid "" @@ -145790,24 +147031,29 @@ msgid "" "WILL kill you. Dr. Prado left the Hub with a handful of EMP grenades, use " "those to disable the robot." msgstr "" +"Si el robot sigue estando operativo, no intentes luchar contra Ć©l porque te " +"va a MATAR. La Dra. Prado dejĆ³ el Hub con varias granadas PEM, usalas para " +"desactivar el robot." #: lang/json/mission_def_from_json.py msgid "Don't you have a job to do?" -msgstr "" +msgstr "ĀæNo tenĆ©s un trabajo que realizar?" #: lang/json/mission_def_from_json.py msgid "" "Unfortunate only the data was salvageable, but you have our thanks for " "returning it nonetheless." msgstr "" +"Lamentablemente, solo la informaciĆ³n pudo recuperarse, pero igual te " +"agradecemos por traerla." #: lang/json/mission_def_from_json.py msgid "Simply uselessā€¦" -msgstr "" +msgstr "Simplemente, inĆŗtilā€¦" #: lang/json/mission_def_from_json.py msgid "Steal a dead man's mind" -msgstr "" +msgstr "Robar la mente de un muerto" #. ~ Description for mission '{'str': "Steal a dead man's mind"}' #: lang/json/mission_def_from_json.py @@ -145815,6 +147061,9 @@ msgid "" "Find the corpse of a Hub 01's AI researcher and use the mind splicer kit to " "recover the memories stored inside their memory implant." msgstr "" +"EncontrĆ” el cadĆ”ver del investigador de IA del Hub 01 y usĆ” un equipo para " +"empalmar mentes para recuperar los recuerdos almacenados dentro de su " +"implante de memoria." #: lang/json/mission_def_from_json.py msgid "" @@ -145826,18 +147075,29 @@ msgid "" "valuable knowledge. We want you to travel to the location, make a copy of " "his Bionic Memory Unit, and return it to us." msgstr "" +"Cuando comenzaron las tormentas del portal, el gobierno ordenĆ³ una " +"evacuaciĆ³n para el personal fundamental XEDRA y enviĆ³ vehĆ­culos para " +"escoltarlos, con nuestro director de investigaciĆ³n de IA entre los " +"retirados. Descubrimos recientemente que muriĆ³ cuando el equipo que lo " +"estaba trasladando fue emboscado dentro del caos inicial, pero su cadĆ”ver y " +"biĆ³nico de memoria pueden mantenerse intactos como para extraer ese valioso " +"conocimiento. Queremos que vayas al lugar, hagas una copia de su Unidad " +"BiĆ³nica de Memoria y la traigas." #: lang/json/mission_def_from_json.py msgid "" "Remember, perform the extraction /exactly/ as specified, otherwise the " "bionic will self-destruct." msgstr "" +"Acordate, hacĆ© la extracciĆ³n \"exactamente\" como estĆ” especificada, de otra" +" manera, el biĆ³nico se autodestruirĆ”." #: lang/json/mission_def_from_json.py msgid "" "Yes, we recognize that our request is exceptional. Return if you change " "your mind." msgstr "" +"SĆ­, sabemos que nuestro pedido es excepcional. VolvĆ© si cambiĆ”s de idea." #: lang/json/mission_def_from_json.py msgid "" @@ -145845,18 +147105,22 @@ msgid "" "right in front of the corpus callosum. We suggest a forceps through the eye" " socket, shaking slightly, then slowly and carefullyā€¦" msgstr "" +"SabĆ©s cĆ³mo es una unidad de memoria, Āæno? Gris mate, del tamaƱo de una " +"pastilla, justo adelante del corpus callosum. Te sugerimos unos fĆ³rceps a " +"travĆ©s de la cuenca del ojo, lo sacudas levemente, y despuĆ©s lentamente y " +"con cuidadoā€¦" #: lang/json/mission_def_from_json.py msgid "Do you have the scan?" -msgstr "" +msgstr "ĀæTenĆ©s el scanner?" #: lang/json/mission_def_from_json.py msgid "You have our thanks and payment." -msgstr "" +msgstr "RecibĆ­ nuestro agradecimiento y nuestro pago." #: lang/json/mission_def_from_json.py msgid "Light retrieval" -msgstr "" +msgstr "Rescate ligero" #. ~ Description for mission '{'str': 'Light retrieval'}' #: lang/json/mission_def_from_json.py @@ -145865,6 +147129,9 @@ msgid "" "circuitry template. The intercom warned you about heavy enemy presence, and" " of the existence of a hazardous environment." msgstr "" +"Ir al sĆ³tano de la torre derrumbada y buscar en las ruinas la plantilla del " +"circuito fotĆ³nico. El intercomunicador te advirtiĆ³ acerca de una presencia " +"importante de enemigos, y la existencia de peligro ambiental." #: lang/json/mission_def_from_json.py msgid "" @@ -145872,14 +147139,17 @@ msgid "" "\n" "the intercom: We ask you to investigate the ruins, and if possible, retrieve a template for the fabrication of said photonic circuitry." msgstr "" +"Nuestras instalaciones produjeron una vez un circuito fotĆ³nico avanzado de un fabricante cercano de robĆ³tica. Su edificio sufriĆ³ un gran daƱo durante las tormentas del portal y se derrumbĆ³ casi completamente. Sin embargo, unas exploraciones indican que el laboratorio de prototipos del sĆ³tano quedĆ³ intacto.\n" +"\n" +"intercomunicado: Te pedimos que investigues las ruinas y si es posible, recuperes la plantilla para la fabricaciĆ³n de dicho circuito fotĆ³nico." #: lang/json/mission_def_from_json.py msgid "We expect your success, mercenary." -msgstr "" +msgstr "Esperamos que tengas Ć©xito, mercenario." #: lang/json/mission_def_from_json.py msgid "Return if you change your mind." -msgstr "" +msgstr "VolvĆ© si cambiĆ”s de idea." #: lang/json/mission_def_from_json.py msgid "" @@ -145888,49 +147158,55 @@ msgid "" "are willing to sell you some protective gear at a discount, if you require " "it." msgstr "" +"El dron de exploraciĆ³n tambiĆ©n indicĆ³ signos de mucho calor y grandes " +"concentraciones de compuestos tĆ³xicos dentro de las ruinas. Tenelo en " +"cuenta. Estamos dispuestos a venderte equipo de protecciĆ³n con descuento, si" +" lo necesitĆ”s." #: lang/json/mission_def_from_json.py msgid "Have you retrieved the blueprints?" -msgstr "" +msgstr "ĀæConseguiste los planos?" #: lang/json/mission_def_from_json.py msgid "Retrieve chunks of gold" -msgstr "" +msgstr "Recuperar pedazos de oro" #. ~ Description for mission '{'str': 'Retrieve chunks of gold'}' #: lang/json/mission_def_from_json.py msgid "Find 200 units of gold." -msgstr "" +msgstr "Conseguir 200 unidades de oro." #: lang/json/mission_def_from_json.py msgid "I could do with some helpā€¦" -msgstr "" +msgstr "Me vendrĆ­a bien un poco de ayudaā€¦" #: lang/json/mission_def_from_json.py msgid "" "I'm still supposed to scavenge for gold, I can offer you the same deal as " "last time." msgstr "" +"TodavĆ­a se supone que tengo que buscar oro, te puedo ofrecer el mismo " +"negocio que la otra vez." #: lang/json/mission_def_from_json.py msgid "Wonderful." -msgstr "" +msgstr "Maravilloso." #: lang/json/mission_def_from_json.py msgid "Well I'll look for the gold myself." -msgstr "" +msgstr "Bueno, voy a buscar el oro yo mismo." #: lang/json/mission_def_from_json.py msgid "Try searching banks and security vans." -msgstr "" +msgstr "Fijate buscando en bancos y camiones de seguridad." #: lang/json/mission_def_from_json.py msgid "You got that gold yet?" -msgstr "" +msgstr "ĀæYa conseguiste el oro?" #: lang/json/mission_def_from_json.py msgid "I appreciate it, here's your pay." -msgstr "" +msgstr "Te lo agradezco, acĆ” estĆ” tu pago." #: lang/json/mission_def_from_json.py lang/json/snippet_from_json.py msgid "Yeah, sure." @@ -145938,11 +147214,11 @@ msgstr "SĆ­, seguro." #: lang/json/mission_def_from_json.py msgid "Well I'll have to scavenge the gold myself, thanks for nothing." -msgstr "" +msgstr "Bueno, voy a tener que buscar el oro yo mismo, gracias por nada." #: lang/json/mission_def_from_json.py msgid "Active Noise Control" -msgstr "" +msgstr "Activar Control de Ruido" #. ~ Description for mission 'Active Noise Control' #: lang/json/mission_def_from_json.py @@ -145950,6 +147226,8 @@ msgid "" "Investigate Hub 01's radio tower, discover the source of the interference, " "and fix the problem." msgstr "" +"InvestigĆ” la torre de radio del Hub 01, descrbrĆ­ la fuente de la " +"interferencia y arreglĆ” el problema." #: lang/json/mission_def_from_json.py msgid "" @@ -145957,69 +147235,74 @@ msgid "" "stopped working recently. If you are willing to be my back up while I check" " it out, I'll owe you a favor." msgstr "" +"Hace unos dĆ­as, instalĆ© un transmisor de radio en la torre que estĆ” cerca, " +"pero dejĆ³ de funcionar hace poco. Si podĆ©s ayudarme mientras lo reviso, te " +"voy a deber un favor." #: lang/json/mission_def_from_json.py msgid "Alright, lets be off. You don't mind taking point, right?" -msgstr "" +msgstr "Bien, vayamos entonces. No te molesta ir adelante, Āæno?" #: lang/json/mission_def_from_json.py msgid "Well thanks for offering, I guess." -msgstr "" +msgstr "Bueno, gracias por preguntar, supongo." #: lang/json/mission_def_from_json.py msgid "" "I'm sure we'll figure it out once there. In any case, make sure to shoot " "first." msgstr "" +"Estoy seguro que nos daremos cuenta cuando estemos allĆ”. En cualquier caso, " +"asegurate de ser el primero en disparar." #: lang/json/mission_def_from_json.py msgid "You think we killed the culprit?" -msgstr "" +msgstr "ĀæTe parece que matamos al culpable?" #: lang/json/mission_def_from_json.py msgid "Sure seems like it. Lets go back to the hub." -msgstr "" +msgstr "Parece que sĆ­. Volvamos al hub." #: lang/json/mission_def_from_json.py msgid "Sure, thanks for nothing." -msgstr "" +msgstr "Seguro, gracias por nada." #: lang/json/mission_def_from_json.py msgid "Return to Hub 01" -msgstr "" +msgstr "Regresar al Hub 01" #. ~ Description for mission 'Return to Hub 01' #: lang/json/mission_def_from_json.py msgid "Return to Hub 01." -msgstr "" +msgstr "Regresar al Hub 01." #: lang/json/mission_def_from_json.py msgid "Lets go back to the Hub" -msgstr "" +msgstr "Volvamos al Hub" #: lang/json/mission_def_from_json.py msgid "Wellā€¦" -msgstr "" +msgstr "Buenoā€¦" #: lang/json/mission_def_from_json.py msgid "You keep a map around don't you? I do, and you probably should too." -msgstr "" +msgstr "TenĆ©s un mapa, Āæno? Yo sĆ­, y vos tambiĆ©n deberĆ­as." #: lang/json/mission_def_from_json.py msgid "We there yet?" -msgstr "" +msgstr "ĀæFalta mucho?" #: lang/json/mission_def_from_json.py msgid "Thanks for having my back. As I said, I owe you one." -msgstr "" +msgstr "Gracias por cuidarme la espalda. Como te dije, te debo una." #: lang/json/mission_def_from_json.py msgid "Are you lost or something?" -msgstr "" +msgstr "ĀæTe perdiste o quĆ© te pasĆ³?" #: lang/json/mission_def_from_json.py msgid "Can't believe we got lostā€¦" -msgstr "" +msgstr "No puedo creer que nos hayamos perdidoā€¦" #: lang/json/mission_def_from_json.py msgid "Make 2 Stills" @@ -146047,6 +147330,7 @@ msgstr "" #: lang/json/mission_def_from_json.py msgid "Come back when you get a chance. We need skilled survivors." msgstr "" +"VolvĆ© cuando tengas oportunidad. Necesitamos supervivientes habilidosos." #: lang/json/mission_def_from_json.py msgid "" @@ -146065,7 +147349,7 @@ msgstr "Gracias por la entrega. " #: lang/json/mission_def_from_json.py msgid "Find 20 Yeast" -msgstr "Encontrar 20 de Levadura" +msgstr "Conseguir 20 unidades de Levadura" #: lang/json/mission_def_from_json.py msgid "" @@ -146093,7 +147377,7 @@ msgstr "ĀæYa conseguiste la levadura?" #: lang/json/mission_def_from_json.py msgid "Find 10 Sugar Beet Seeds" -msgstr "Encontrar 10 Sem. de Remolacha Az." +msgstr "Conseguir 10 Semillas de Remolacha Azucarera" #: lang/json/mission_def_from_json.py msgid "" @@ -146113,6 +147397,7 @@ msgstr "" #: lang/json/mission_def_from_json.py msgid "Farms or supply stores might have a few seedsā€¦" msgstr "" +"Las granjas o los almacenes de suministros podrĆ­an tener algunas semillasā€¦" #: lang/json/mission_def_from_json.py msgid "Do you have the sugar beet seeds?" @@ -146120,7 +147405,7 @@ msgstr "ĀæYa conseguiste las semillas de remolacha azucarera?" #: lang/json/mission_def_from_json.py msgid "Find 12 Metal Tanks" -msgstr "Encontrar 12 Tanques de Metal" +msgstr "Conseguir 12 Tanques de Metal" #: lang/json/mission_def_from_json.py msgid "" @@ -146149,7 +147434,7 @@ msgstr "ĀæYa conseguiste los tanques de metal?" #: lang/json/mission_def_from_json.py msgid "Find 2 200-Liter Drums" -msgstr "Encontrar 2 Tambores de 200 Litros" +msgstr "Conseguir 2 Tambores de 200 Litros" #: lang/json/mission_def_from_json.py msgid "" @@ -146188,6 +147473,12 @@ msgid "" "half and construction. If you don't have a truck, I'd make finding one your" " first priority. " msgstr "" +"Nuestro primer proyecto es cerrar el granero para que los nuevos refugiados " +"tengan un lugar seguro para dormir. Antes de que podamos realizar mejoras " +"serias necesitamos madera. Cerrar las cuatro entradas del granero nos va a " +"llevar cerca de 400 tablas de maderaā€¦ si pudieras conseguirnos la mitad de " +"eso podrĆ­amos encargarnos de la otra mitad y de la construcciĆ³n. Si no tenĆ©s" +" un camiĆ³n, te dirĆ­a que consigas uno." #: lang/json/mission_def_from_json.py msgid "" @@ -146214,7 +147505,7 @@ msgstr "" #: lang/json/mission_def_from_json.py msgid "Find 25 Blankets" -msgstr "Encontrar 25 Frazadas" +msgstr "Conseguir 25 Frazadas" #: lang/json/mission_def_from_json.py msgid "" @@ -146236,6 +147527,8 @@ msgid "" "I'd start with looting hotels or you could sew them togetherā€¦ but that would" " be a last resort." msgstr "" +"Yo empezarĆ­a por buscar en hoteles o tambiĆ©n podĆ©s coserlasā€¦ pero eso serĆ­a " +"como Ćŗltimo recurso." #: lang/json/mission_def_from_json.py msgid "Avoid destroying the furniture here, we'll be needing it." @@ -146287,6 +147580,15 @@ msgid "" "is salt. I negotiated them down from 500 units to 300ā€¦ we were hoping you " "might have access to a source." msgstr "" +"Seguro viste los nuevos trabajadores que empezaron a venir. El consejo de " +"los Mercaderes Libres nos demanda que comencemos inmediatamente los " +"proyectos para volvernos autosuficientes debido a las provisiones limitadas." +" Vamos a necesitar establecer rĆ”pidamente una industria agrĆ­cola antes de " +"que el invierno y la hambruna nos agarren desprevenidos. Para poder " +"conseguir media docena de palas y un par de bolsas de semillas, tenemos que " +"hacer un trueque. Ya conversĆ© el intercambio y lo Ćŗnico que quieren a cambio" +" es sal. NegociĆ© para que bajaran su exigencia de 500 a 300ā€¦ esperamos que " +"vos tengas acceso a esa cantidad." #: lang/json/mission_def_from_json.py msgid "" @@ -146294,6 +147596,9 @@ msgid "" "food it wouldn't do us much good now but I imagine we'll need to send you " "out to get more in the future. " msgstr "" +"La sal es clave para preservar la carne y otros alimentosā€¦ como no tenemos " +"exceso de comida, ahora no nos sirve de mucho pero me imagino que vamos a " +"necesitar mandarte a buscar mĆ”s en un futuro." #: lang/json/mission_def_from_json.py msgid "" @@ -146353,7 +147658,7 @@ msgstr "Esto va a hacer el primer invierno mĆ”s fĆ”cil de sobrevivir." #: lang/json/mission_def_from_json.py msgid "Gather 75 Rocks" -msgstr "" +msgstr "Recolectar 75 Piedras" #: lang/json/mission_def_from_json.py msgid "" @@ -146367,6 +147672,16 @@ msgid "" " task before we all get sick. After we have them installed you will have " "free access to them, guaranteed. " msgstr "" +"Nuestra evaluaciĆ³n actual de supervivencia se ha incrementado " +"significativamente gracias a tus esfuerzos. La prĆ³xima prioridad es " +"asegurarnos una fuente de agua limpia. Tomar de un charco en la parte de " +"atrĆ”s del rancho nos ha causado un brote de disenterĆ­a. Necesitamos mejorar " +"lo antes posible nuestras condiciones sanitarias en el campamento. El primer" +" paso es cavar un pozo de agua y construir chimeneas de piedra en el granero" +" para poder hervir el agua. Necesitamos que consigas por lo menos 75 piedras" +" si esperamos cumplir la tarea antes de que todos se enfermen. DespuĆ©s de " +"que tengamos eso instalado, lo vas a poder usar cuando quieras, te lo " +"garantizo." #: lang/json/mission_def_from_json.py msgid "" @@ -146420,7 +147735,7 @@ msgstr "ĀæYa conseguiste los caƱos?" #: lang/json/mission_def_from_json.py msgid "Gather 2 Electric Motors" -msgstr "" +msgstr "Conseguir 2 Motores ElĆ©ctricos" #: lang/json/mission_def_from_json.py msgid "" @@ -146466,12 +147781,12 @@ msgstr "" "los refugiados. Sin el personal mĆ©dico y las instalaciones dedicadas, dudo " "que alguien se quiera quedar cuando aparezca el prĆ³ximo brote. Hasta que " "consigamos un mĆ©dico o enfermera apropiados, voy a tener que improvisar. El " -"primer paso imagino que es la esterilizaciĆ³n. Conseguime unos 20 litros de " +"primer paso imagino que es la esterilizaciĆ³n. Conseguime 5 bidones de " "lavandina para que podamos empezar." #: lang/json/mission_def_from_json.py msgid "I'm sure you can find bleach in most homesā€¦" -msgstr "" +msgstr "Seguro que podes conseguir lavandina en la mayorĆ­a de las casasā€¦" #: lang/json/mission_def_from_json.py msgid "" @@ -146511,7 +147826,7 @@ msgstr "" #: lang/json/mission_def_from_json.py msgid "We'll do our best to make them lastā€¦" -msgstr "" +msgstr "Haremos lo posible para hacerlos rendirā€¦" #: lang/json/mission_def_from_json.py msgid "Homes, hospitals, labs, and doctor offices would be where I'd check." @@ -146525,7 +147840,7 @@ msgstr "ĀæYa conseguiste los botiquines de primeros auxilios?" #: lang/json/mission_def_from_json.py msgid "Find 2 Arc Welders" -msgstr "" +msgstr "Conseguir 2 Soldadoras ElĆ©ctricas" #: lang/json/mission_def_from_json.py msgid "" @@ -146559,7 +147874,7 @@ msgstr "ĀæYa conseguiste las soldadoras?" #: lang/json/mission_def_from_json.py msgid "Find 12 Car Batteries" -msgstr "Encontrar 12 BaterĆ­as de Auto" +msgstr "Conseguir 12 BaterĆ­as de Auto" #: lang/json/mission_def_from_json.py msgid "" @@ -146584,6 +147899,8 @@ msgid "" "Cars can be found in traffic jams along roads or in parking lotsā€¦ I'm sure " "you can find a few." msgstr "" +"PodĆ©s encontrar autos en los embotellamientos de las calles o en las playas " +"de estacionamientoā€¦ Seguro que vas a encontrar algunos." #: lang/json/mission_def_from_json.py msgid "Do you have the car batteries?" @@ -146595,7 +147912,7 @@ msgstr "Estoy impresionado con tus habilidades." #: lang/json/mission_def_from_json.py msgid "Find 2 Two-Way Radios" -msgstr "Encontrar 2 Radios Handy" +msgstr "Conseguir 2 Radios Handy" #: lang/json/mission_def_from_json.py msgid "" @@ -146607,6 +147924,13 @@ msgid "" " that. Communication is the biggest obstacle for the teamsā€¦ could you bring" " in a pair of two-way radios?" msgstr "" +"HablĆ” con el/a enfermero/a cuando puedas, sĆ© que necesita ayudar para " +"establecer nuestra clĆ­nica. En cuanto a la construcciĆ³n, necesitamos " +"conseguir equipos dedicados de cartoneros para traer los suministros " +"variados que usamos en cantidades pequeƱas. Vamos a establecer un negocio de" +" objetos usados para ellos en la parte norte del puesto asĆ­ que podemos usar" +" tu ayuda con eso. La comunicaciĆ³n es el mayor obstĆ”culo para los equiposā€¦ " +"ĀæpodrĆ­as conseguir un par de radios handy?" #: lang/json/mission_def_from_json.py msgid "" @@ -146666,7 +147990,7 @@ msgstr "" #: lang/json/mission_def_from_json.py msgid "Find Homebrewer's Bible" -msgstr "Encontrar La Biblia del Cervecero" +msgstr "Conseguir La Biblia del Cervecero" #: lang/json/mission_def_from_json.py msgid "" @@ -146680,6 +148004,15 @@ msgid "" "to find a book called the 'Homebrewer's Bible' or something along those " "lines." msgstr "" +"ƚltimamente, el crecimiento se ha estancado, tenemos gente pasando por el " +"puesto pero la perspectiva de trabajo pesado solo para ganarse la existencia" +" los estĆ” alejando. Hemos preguntado y decidido que, a pesar de nuestras " +"apremiantes necesidades, construir un bar va a atraer a las personas menos " +"comprometidas a nuestro puesto. A diferencia de otros asentamientos, cuantas" +" mĆ”s manos tengamos mĆ”s comida podemos producirā€¦ por lo menos en el largo " +"plazo. Lamentablemente, acĆ” nadie ha elaborado bebidas alcohĆ³licas antes asĆ­" +" que necesitamos que nos consigas un libro llamado 'la Biblia del Cervecero'" +" o algo de ese tema." #: lang/json/mission_def_from_json.py msgid "I guess you should search homes or libraries?" @@ -146782,6 +148115,12 @@ msgid "" "prevent me from ever seeing it. I could use your help getting a few bottles" " of aspirin to start with." msgstr "" +"Tengo un puƱado de vendas y algunos botiquines de primeros auxilios para " +"trabajar en este momentoā€¦ en otras palabras, no soy capaz de tratar las " +"emergencias mĆ©dicas mĆ”s serias. Se supone que tengo prioridad con cualquier " +"suministro mĆ©dico que los cartoneros traigan, pero me imagino que el mercado" +" negro hace que ni siquiera los vea. PodrĆ­as ayudarme a conseguir unos " +"frascos de aspirinas como para empezar." #: lang/json/mission_def_from_json.py msgid "Aspirin is pretty common in homes and convenience stores." @@ -146877,7 +148216,7 @@ msgstr "ĀæYa tenĆ©s los purificadores de agua a carbĆ³n?" #: lang/json/mission_def_from_json.py msgid "Find a Chemistry Set" -msgstr "Encontrar Equipo de QuĆ­mica" +msgstr "Conseguir Equipo de QuĆ­mica" #: lang/json/mission_def_from_json.py msgid "" @@ -146903,7 +148242,7 @@ msgstr "ĀæYa conseguiste el equipo de quĆ­mica?" #: lang/json/mission_def_from_json.py msgid "Find 10 Filter Masks" -msgstr "Encontrar 10 Barbijos" +msgstr "Conseguir 10 Barbijos" #: lang/json/mission_def_from_json.py msgid "" @@ -146925,7 +148264,7 @@ msgstr "ĀæYa tenĆ©s los barbijos?" #: lang/json/mission_def_from_json.py msgid "Find 4 Pairs of Rubber Gloves" -msgstr "Encontrar 4 Pares Guan. de Goma" +msgstr "Conseguir 4 Pares de Guantes de Goma" #: lang/json/mission_def_from_json.py msgid "" @@ -146949,7 +148288,7 @@ msgstr "ĀæYa conseguiste los guantes de goma?" #: lang/json/mission_def_from_json.py msgid "Find 2 Scalpels" -msgstr "Encontrar 2 Escalpelos" +msgstr "Conseguir 2 Escalpelos" #: lang/json/mission_def_from_json.py msgid "" @@ -146975,7 +148314,7 @@ msgstr "ĀæYa conseguiste los escalpelos?" #: lang/json/mission_def_from_json.py msgid "Find Advanced Emergency Care" -msgstr "Encontrar GuĆ­a de C. MĆ©d. Avanzado" +msgstr "Conseguir GuĆ­a de Cuidado MĆ©dico Avanzado" #: lang/json/mission_def_from_json.py msgid "" @@ -146998,7 +148337,7 @@ msgstr "ĀæYa conseguiste la GuĆ­a del Cuidado MĆ©dico Avanzado?" #: lang/json/mission_def_from_json.py msgid "Find a Flu Shot" -msgstr "Encontrar Vacuna para Gripe" +msgstr "Conseguir Vacuna para Gripe" #: lang/json/mission_def_from_json.py msgid "" @@ -147026,7 +148365,7 @@ msgstr "ĀæYa conseguiste la vacuna para la gripe?" #: lang/json/mission_def_from_json.py msgid "Find 10 Syringes" -msgstr "Encontrar 10 Jeringas" +msgstr "Conseguir 10 Jeringas" #: lang/json/mission_def_from_json.py msgid "" @@ -147060,6 +148399,12 @@ msgid "" "monsters. Could you make me a dozen of them? I may need more later but " "that should help the first few teams." msgstr "" +"Usualmente, puedo utilizar equipo de supervivencia adicional para equipar a " +"los nuevos reclutas. El arma mĆ”s bĆ”sica que todos reciben es la lanza-" +"cuchilloā€¦ provee una buena mezcla de alcance, potencia y facilidad de uso " +"para enfrentar a los monstruos mĆ”s comunes. ĀæMe podĆ©s hacer una docena de " +"esas? Puede que necesite mĆ”s despuĆ©s pero eso va a ayudar a los primeros " +"equipos." #: lang/json/mission_def_from_json.py msgid "You should be able to make them with the most basic of skills." @@ -147152,198 +148497,225 @@ msgstr "ĀæYa tenĆ©s los cĆ³cteles molotov?" #: lang/json/mission_def_from_json.py msgid "Big Game Hunting" -msgstr "" +msgstr "Cazar Animales Grandes" #. ~ Description for mission 'Big Game Hunting' #: lang/json/mission_def_from_json.py msgid "Find 50 fur pelts." -msgstr "" +msgstr "Conseguir 50 pieles." #: lang/json/mission_def_from_json.py msgid "I need 50 fur pelts." -msgstr "" +msgstr "Necesito 50 pieles." #: lang/json/mission_def_from_json.py msgid "" "I've got to maintain the orchard but at nights I work on prepping winter " "clothes. Could you find aboutā€¦ 50 fur pelts for me?" msgstr "" +"Tengo que mantener el huerto de Ć”rboles pero a la noche trabajo preparando " +"ropa para el invierno. ĀæMe podrĆ­as conseguir unas... 50 pieles?" #: lang/json/mission_def_from_json.py msgid "" "There's a lot of places to look. The entire outdoors is full of wild " "animals." msgstr "" +"Hay muchos lugares donde podĆ©s buscar. Alrededor de los pueblos estĆ” lleno " +"de animales salvajes." #: lang/json/mission_def_from_json.py msgid "Bread" -msgstr "" +msgstr "Pan" #. ~ Description for mission 'Bread' #: lang/json/mission_def_from_json.py msgid "Find 50 flour." -msgstr "" +msgstr "Conseguir 50 unidades de harina." #: lang/json/mission_def_from_json.py msgid "I need 50 flour." -msgstr "" +msgstr "Necesito 50 unidades de harina." #: lang/json/mission_def_from_json.py msgid "Flour would let me break the monotony of fruit and meats." msgstr "" +"La harina me va a permitir romper la monotonĆ­a de la fruta y las carnes." #: lang/json/mission_def_from_json.py msgid "" "Thanks for accepting this task. Otherwise I might kill a stranger for a " "sandwich. Just kidding." msgstr "" +"Gracias por aceptar esta tarea. De otra manera, podrĆ­a matar a un extraƱo " +"por un sĆ”nguche. Es un chiste." #: lang/json/mission_def_from_json.py msgid "" "Flour is not that hard to find. I'd look for them in residental areas and " "professional kitchens or bakeries." msgstr "" +"La harina no es difĆ­cil de encontrar. Yo buscarĆ­a en las Ć”reas urbanas y las" +" cocinas profesionales o las panaderĆ­as." #: lang/json/mission_def_from_json.py msgid "Have you found the flour?" -msgstr "" +msgstr "ĀæEncontraste la harina?" #: lang/json/mission_def_from_json.py msgid "Gallon Jugs" -msgstr "" +msgstr "Bidones de 4 litros" #. ~ Description for mission 'Gallon Jugs' #: lang/json/mission_def_from_json.py msgid "Find 5 gallon jugs." -msgstr "" +msgstr "Conseguir 5 bidones de 4 litros." #: lang/json/mission_def_from_json.py msgid "I need storage for various liquid products when the fruits come in." msgstr "" +"Necesito recipientes para guardar varios productos lĆ­quidos cuando empiecen " +"a aparecer las frutas." #: lang/json/mission_def_from_json.py msgid "" "Every season we produce so much fruit. Some of it will be turned into juice" " and some into alcohol. I need easy containers to load it on the caravan." msgstr "" +"En cada temporada producimos mucha fruta. Una parte se convertirĆ” en jugo y " +"otra en alcohol. Necesito recipientes sencillos para cargarlos en las " +"caravanas." #: lang/json/mission_def_from_json.py msgid "Thank you for accepting. I'm almost out after the last caravan." msgstr "" +"Gracias por aceptar. Ya casi no me queda nada despuĆ©s de la Ćŗltima caravana." #: lang/json/mission_def_from_json.py msgid "I guess I'll have to make stomach waterskins." -msgstr "" +msgstr "Supongo que voy a tener que hacer odres con estĆ³magos." #: lang/json/mission_def_from_json.py msgid "" "Gallon jugs are not that rare to find. They are commonly found in kitchens." msgstr "" +"Los bidones de 4 litros no son difĆ­ciles de encontrar. ComĆŗnmente hay en " +"cualquier cocina." #: lang/json/mission_def_from_json.py msgid "Do you have those jugs now?" -msgstr "" +msgstr "ĀæYa tenĆ©s los bidones?" #: lang/json/mission_def_from_json.py msgid "I am grateful for the help you've done. I have one more task to do." -msgstr "" +msgstr "Estoy agradecido por tu ayuda. Tengo otra tarea para ofrecerte." #: lang/json/mission_def_from_json.py msgid "Burnt Out CBMs" -msgstr "" +msgstr "MCB Fundidos" #. ~ Description for mission 'Burnt Out CBMs' #: lang/json/mission_def_from_json.py msgid "Find 5 burnt out CBMs." -msgstr "" +msgstr "Conseguir 5 MCB fundidos." #: lang/json/mission_def_from_json.py msgid "We have the ability to manufacture CBMs but lack resources." -msgstr "" +msgstr "Tenemos la habilidad de fabricar MCB pero nos falta recursos." #: lang/json/mission_def_from_json.py msgid "If you can bring me burnt out CBMs we can recycle them into new ones." msgstr "" +"Si me podĆ©s traer algunos MCB fundidos o quemados, los podemos reciclar y " +"hacer unos nuevos." #: lang/json/mission_def_from_json.py msgid "" "Thank you for accepting. You're really making yourself useful to the phyle." -msgstr "" +msgstr "Gracias por aceptar. Ya te volviste una persona Ćŗtil en la tribu." #: lang/json/mission_def_from_json.py msgid "" "These materials are often in dangerous areas. I understand your decision." msgstr "" +"Estos materiales estĆ”n generalmente en lugares peligrosos. Comprendo tu " +"decisiĆ³n." #: lang/json/mission_def_from_json.py msgid "" "Zombie scientists, technicians, shocker zombies. These are not undertaken " "lightly." -msgstr "" +msgstr "Zombis cientĆ­ficos, tĆ©cnicos, shocker. Son todos peligrosos." #: lang/json/mission_def_from_json.py msgid "Do you have those CBMs now?" -msgstr "" +msgstr "ĀæYa conseguiste los MCB?" #: lang/json/mission_def_from_json.py msgid "" "I am grateful for the help you've done. I think we might be able to " "introduce you to others soon." msgstr "" +"Estoy agradecido por tu ayuda. Creo que te voy a presentar a los otros en " +"cualquier momento." #: lang/json/mission_def_from_json.py msgid "Migo biology" -msgstr "" +msgstr "BiologĆ­a Mi-go" #. ~ Description for mission 'Migo biology' #: lang/json/mission_def_from_json.py msgid "Find fetid goop." -msgstr "" +msgstr "Encontrar pegote fĆ©tido." #: lang/json/mission_def_from_json.py msgid "I need 14 fetid goops from mi-go locations." -msgstr "" +msgstr "Necesito 14 pegotes fĆ©tidos que hay en los lugares de los mi-go." #: lang/json/mission_def_from_json.py msgid "" "My experiments are at a critical point. Could you find aboutā€¦ 14 fetid " "goops for me?" msgstr "" +"Mis experimentos llegaron a un punto crĆ­tico. ĀæPodrĆ­as conseguirme unosā€¦ 14 " +"pegotes fĆ©tidos?" #: lang/json/mission_def_from_json.py msgid "Then why are you even here? Just let me know if you reconsider." -msgstr "" +msgstr "ĀæY entonces quĆ© hacĆ©s acĆ”? Avisame si cambiĆ”s de idea." #: lang/json/mission_def_from_json.py msgid "" "Find a mi-go base, find a way inside, smash things until you find what I " "need." msgstr "" +"BuscĆ” una base mi-go, encontrĆ” la manera de entrar, rompĆ© algunas cosas " +"hasta que lo encuentres." #: lang/json/mission_def_from_json.py msgid "Why aren't you done yet?" -msgstr "" +msgstr "ĀæY por quĆ© no terminaste todavĆ­a?" #: lang/json/mission_def_from_json.py msgid "Taste this." -msgstr "" +msgstr "ProbĆ” esto." #: lang/json/mission_def_from_json.py msgid "You are holding back the evolution of the human race." -msgstr "" +msgstr "EstĆ”s retrasando la evoluciĆ³n de la raza humana." #: lang/json/mission_def_from_json.py msgid "Migo Resin" -msgstr "" +msgstr "Resina Mi-go" #. ~ Description for mission 'Migo Resin' #: lang/json/mission_def_from_json.py msgid "Find 56 chunks of mi-go resin." -msgstr "" +msgstr "Conseguir 56 pedazos de resina mi-go." #: lang/json/mission_def_from_json.py msgid "I need 56 chunks of mi-go resin." -msgstr "" +msgstr "Necesito 56 pedazos de resina mi-go." #: lang/json/mission_def_from_json.py msgid "" @@ -147351,144 +148723,168 @@ msgid "" "This research wasn't even possible previously. Bring me fifty six chunks of" " mi-go resin." msgstr "" +"Necesito entender mĆ”s acerca de su ambiente y cĆ³mo lo crean. Esta " +"investigaciĆ³n antes no era ni siquiera posible. Traeme cincuenta y seis " +"pedazos de resina mi-go." #: lang/json/mission_def_from_json.py msgid "" "My notes suggest that their building materials are alive. I need you to " "help me confirm that." msgstr "" +"Mis notas sugieren que sus materiales de construcciĆ³n estĆ”n vivos. Necesito " +"tu ayuda para confirmar eso." #: lang/json/mission_def_from_json.py msgid "You can't just walk away from this. We're changing the world!" -msgstr "" +msgstr "No podĆ©s dejarnos en banda. Ā”Estamos cambiando el mundo!" #: lang/json/mission_def_from_json.py msgid "" "Find their buildings, jackhammer them. What did you do before the world " "changed for the better, cold call salesman?" msgstr "" +"BuscĆ” sus edificios, taladralos. ĀæQuĆ© hacĆ­as antes de que el mundo cambiara " +"para mejor? ĀæTelemarketer?" #: lang/json/mission_def_from_json.py msgid "Have you found my resin?" -msgstr "" +msgstr "ĀæYa conseguiste mi resina?" #: lang/json/mission_def_from_json.py msgid "Drink this." -msgstr "" +msgstr "Tomate esto." #: lang/json/mission_def_from_json.py msgid "" "Did you act on Broadway? Because I bet that skill isn't useful anymore." msgstr "" +"ĀæActuaste en Broadway? Porque supongo que esa habilidad no ya sirve para " +"nada." #: lang/json/mission_def_from_json.py msgid "I wonder if I could trade you to them for what I need?" msgstr "" +"Me pregunto si no podrĆ© cambiarte a vos con ellos y que me den lo que " +"necesito." #: lang/json/mission_def_from_json.py msgid "Mutagen" -msgstr "" +msgstr "MutĆ”geno" #. ~ Description for mission 'Mutagen' #: lang/json/mission_def_from_json.py msgid "Bring me 3 mutagen." -msgstr "" +msgstr "Conseguime 3 mutĆ”genos." #: lang/json/mission_def_from_json.py msgid "I need three mutagen." -msgstr "" +msgstr "Necesito tres mutĆ”genos." #: lang/json/mission_def_from_json.py msgid "" "I need some mutagen and I don't want to spend the time making it myself. " "Bring me three doses, if you would be so kind." msgstr "" +"Necesito un poco de mutĆ”geno y no quiero gastar el tiempo haciĆ©ndolo yo. " +"Traeme tres dosis, si serĆ­as tan amable." #: lang/json/mission_def_from_json.py msgid "" "Mutagen makes the world go round, it's definitely more valuable than love." msgstr "" +"El mutĆ”geno hace que el mundo se mueva, es definitivamente mĆ”s valioso que " +"el amor." #: lang/json/mission_def_from_json.py msgid "Are you scared of where I'm taking you?" -msgstr "" +msgstr "ĀæTenĆ©s miedo del lugar al que te llevo?" #: lang/json/mission_def_from_json.py msgid "" "If you can't make it yourself go hit up a government lab. Be prepared for " "anything in there." msgstr "" +"Si no lo podĆ©s hacer vos, fijate en un laboratorio del gobierno. Preparate " +"para cualquier cosa ahĆ­ adentro." #: lang/json/mission_def_from_json.py msgid "Mutagen? Why are you in front of me if not?" -msgstr "" +msgstr "ĀæEl mutĆ”geno? ĀæSi no quĆ© hacĆ©s adelante mĆ­o?" #: lang/json/mission_def_from_json.py msgid "I've got something more potent for you this time." -msgstr "" +msgstr "Tengo algo mĆ”s potente para vos en esta oportunidad." #: lang/json/mission_def_from_json.py msgid "Lies and the lying liars who tell them." -msgstr "" +msgstr "Las mentiras y los mentirosos mentirosos que las dicen." #: lang/json/mission_def_from_json.py msgid "You are keeping me from my experiments. Would you like to become one?" msgstr "" +"Me estĆ”s atrasando en mis experimentos. ĀæTe gustarĆ­a convertirte en uno?" #: lang/json/mission_def_from_json.py msgid "Humming Hearts" -msgstr "" +msgstr "Corazones Zumbantes" #. ~ Description for mission 'Humming Hearts' #: lang/json/mission_def_from_json.py msgid "Find 2 humming hearts." -msgstr "" +msgstr "Conseguir 2 corazones zumbantes." #: lang/json/mission_def_from_json.py msgid "Parts, parts, parts. Bring me some hearts. " -msgstr "" +msgstr "Partes, partes, partes. Traeme algunos corazones." #: lang/json/mission_def_from_json.py msgid "" "The Whately's are known in these parts for gathering body parts. Ha! " "That's just rumors and hearsay. But I do need two humming hearts." msgstr "" +"Los Whately son conocidos en estos lugares por recolectar partes de cuerpos." +" Ā”Ja! Esos son rumores y chismes. Pero necesito dos corazones zumbantes." #: lang/json/mission_def_from_json.py msgid "" "I have some relatives you should meet, if you don't mind hard work for the " "advancement of science." msgstr "" +"Tengo algunos familiares que deberĆ­as conocer, si no te importa el trabajo " +"duro en favor del avance de la ciencia." #: lang/json/mission_def_from_json.py msgid "Even I understand this is dangerous." -msgstr "" +msgstr "Incluso yo mismo comprendo que es peligroso." #: lang/json/mission_def_from_json.py msgid "" "Brain blasters, that's what I call them. Some kind of automated weapon " "system the mi-go use." msgstr "" +"Explotacerebros, asĆ­ los llamo yo. Alguna clase de sistema automatizada de " +"armas que utilizan los mi-go." #: lang/json/mission_def_from_json.py msgid "They speak sometimes. I wonder if they still think." -msgstr "" +msgstr "A veces hablan. Me pregunto si realmente piensan." #: lang/json/mission_def_from_json.py msgid "Let's see what improvements we can divine from these beauties." -msgstr "" +msgstr "Vamos a ver quĆ© mejoras podemos descubrir a partir de estas bellezas." #: lang/json/mission_def_from_json.py msgid "I can't be Dr Frankenstein unless you get me these." -msgstr "" +msgstr "No puedo ser el Dr. Frankenstein si no me conseguĆ­s eso." #: lang/json/mission_def_from_json.py msgid "Gather meat for Bo Baronyx. About 8 should do it." -msgstr "" +msgstr "RecolectĆ” carne para Bo Baronyx. Con 8 deberĆ­a estar bien." #: lang/json/mission_def_from_json.py msgid "The eaters are hungry. They need meat" -msgstr "" +msgstr "Los comensales estĆ”n hambrientos. Necesitan carne" #: lang/json/mission_def_from_json.py msgid "" @@ -147496,14 +148892,17 @@ msgid "" " a pure animal. Not a false eater, the meat must be good to eat. Then " "bring me the meat and I will see to the eaters." msgstr "" +"Si querĆ©s alimentar a los comensales, tu trabajo deberĆ” ser recompensado. " +"SalĆ­, carneĆ” un animal puro. No un comedor falso, la carne debe ser buena " +"para comer. DespuĆ©s traeme la carne y yo se las llevarĆ©." #: lang/json/mission_def_from_json.py msgid "Excellent. The eaters must feed." -msgstr "" +msgstr "Excelente. Los comensales deben comer." #: lang/json/mission_def_from_json.py msgid "Understood. The great eaters will feed either way." -msgstr "" +msgstr "Entendido. Los grandes comensales se alimentarĆ”n igual." #: lang/json/mission_def_from_json.py msgid "" @@ -147511,46 +148910,53 @@ msgid "" "larger and more dangerous, producing tainted mutant meat. This will not " "work for the great eaters, it must be the true meat." msgstr "" +"Algunos de los animales han sido conmovidos por los pretendientes en dĆ­as " +"recientes, grandes y mĆ”s peligrosos, produciendo carne mutada contaminada. " +"Esto no servirĆ” para los grandes comensales, tiene que ser carne verdadera." #: lang/json/mission_def_from_json.py msgid "Have you brought meat?" -msgstr "" +msgstr "ĀæTrajiste carne?" #: lang/json/mission_def_from_json.py msgid "The eaters will feed." -msgstr "" +msgstr "Los comensales comerĆ”n." #: lang/json/mission_def_from_json.py msgid "The eaters will feed I am sure." -msgstr "" +msgstr "Los comensales comerĆ”n estoy seguro." #: lang/json/mission_def_from_json.py msgid "" "I see no meat. There is meat in the forests and swamps waiting for the " "eaters." msgstr "" +"No veo carne. Hay carne en los bosques y pantanos esperando por los " +"comensales." #: lang/json/mission_def_from_json.py msgid "Retrieve Magic Book" -msgstr "" +msgstr "Recuperar Libro MĆ”gico" #: lang/json/mission_def_from_json.py msgid "Where did I put that blastedā€¦" -msgstr "" +msgstr "DĆ³nde puse ese malditoā€¦" #: lang/json/mission_def_from_json.py msgid "" "I seem to have misplaced my book, The Tome of The Battle Mage. That " "worthless apprentice probably stole it. Bring it to me." msgstr "" +"Parece que perdĆ­ mi libro, El Tomo del Mago de Batalla. Ese aprendiz inĆŗtil " +"seguro que me lo robĆ³. Recuperalo." #: lang/json/mission_def_from_json.py msgid "ā€¦What? Oh you're still here. Go find my book." -msgstr "" +msgstr "ā€¦QuĆ©? Oh, todavĆ­a estĆ”s acĆ”. AndĆ” a buscar mi libro." #: lang/json/mission_def_from_json.py msgid "Just as useless as that apprenticeā€¦" -msgstr "" +msgstr "Igual de inĆŗtil que mi aprendizā€¦" #: lang/json/mission_def_from_json.py msgid "" @@ -147559,156 +148965,182 @@ msgid "" "called The Tome of The Battle Mage, you can read at least the title, can't " "you?" msgstr "" +"ĀæQuerĆ©s que yo haga tu trabajo por vos? Bah. Ese aprendiz dijo algo acerca " +"de querer conocer el pueblo, podrĆ­as empezar por ahĆ­. Ah, y el nombre es El " +"Tomo del Mago de Batalla, ĀæpodĆ©s leer el tĆ­tulo por lo menos, no?" #: lang/json/mission_def_from_json.py msgid "Where's my book?" -msgstr "" +msgstr "ĀæDĆ³nde estĆ” mi libro?" #: lang/json/mission_def_from_json.py msgid "Finally. Took you long enough." -msgstr "" +msgstr "Por fin. Te tomaste tu tiempo." #: lang/json/mission_def_from_json.py msgid "Nonsense! Useless! Waste of my time!" -msgstr "" +msgstr "Ā”TonterĆ­as! Ā”InĆŗtil! Ā”Una pĆ©rdida de tiempo!" #: lang/json/mission_def_from_json.py msgid "Ugh, why am I cursed with useless people?" -msgstr "" +msgstr "Ugh, Āæpor quĆ© tengo esta maldiciĆ³n de estar rodeado de inĆŗtiles?" #: lang/json/mission_def_from_json.py msgid "Find Power Storage CBM" -msgstr "" +msgstr "Conseguir MCB Almacenamiento de EnergĆ­a" #: lang/json/mission_def_from_json.py msgid "More powerā€¦ moar powerā€¦ MOAR POWAA!" -msgstr "" +msgstr "MĆ”s energĆ­aā€¦ mĆ”s energĆ­aā€¦ MƁS ENERRRR!" #: lang/json/mission_def_from_json.py msgid "" "I need more power. Find me more power storage and I'll give you this book." msgstr "" +"Necesito mĆ”s energĆ­a. Conseguime mĆ”s almacenamiento de energĆ­a y te voy a " +"dar este libro." #: lang/json/mission_def_from_json.py msgid "I don't care where it comes from so long as it's clean." -msgstr "" +msgstr "No me importa de donde viene mientras estĆ© limpio." #: lang/json/mission_def_from_json.py msgid "You want more power too, don't you?" -msgstr "" +msgstr "ĀæVos tambiĆ©n querĆ©s mĆ”s energĆ­a, no?" #: lang/json/mission_def_from_json.py msgid "" "Electronic Stores might have what I need. Or you could just cut it out of " "something." msgstr "" +"Los negocios de electrĆ³nica pueden tener lo que necesito. O tal vez puedas " +"sacĆ”rselo a algo." #: lang/json/mission_def_from_json.py msgid "Find anything?" -msgstr "" +msgstr "ĀæEncontraste algo?" #: lang/json/mission_def_from_json.py msgid "Perfect. More powerā€¦ powerā€¦" -msgstr "" +msgstr "Perfecto. MĆ”s energĆ­aā€¦ energĆ­aā€¦" #: lang/json/mission_def_from_json.py msgid "I don't understand." -msgstr "" +msgstr "No entiendo." #: lang/json/mission_def_from_json.py msgid "I must find more power, this setback is inconvenient." -msgstr "" +msgstr "Tengo que encontrar mĆ”s energĆ­a, esta demora es inconveniente." #: lang/json/mission_def_from_json.py msgid "Kill 50 Zombies" -msgstr "" +msgstr "Matar 50 Zombis" #: lang/json/mission_def_from_json.py msgid "Will you answer the call?" -msgstr "" +msgstr "ĀæVas a responder al llamado?" #: lang/json/mission_def_from_json.py msgid "" "This world has fallen to chaos and death. Remove 50 of the cursed from this" " world; assist me in purging this curse and you shall be rewarded." msgstr "" +"Este mundo ha caĆ­do en el caos y la muerte. Sacale 50 de esos condenados a " +"este mundo; ayudame a purgar esta maldiciĆ³n y te voy a recompensar." #: lang/json/mission_def_from_json.py msgid "" "Blessed be. I shall observe your efforts and judge you as one of the many " "or one of the few." msgstr "" +"Bendito seas. Voy a observar tus esfuerzos y juzgarte como uno de los muchos" +" o uno de los pocos." #: lang/json/mission_def_from_json.py msgid "" "You will not help purge this curse? Perhaps you are a part of the curseā€¦" msgstr "" +"ĀæNo vas a ayudar a purgar esta maldiciĆ³n? Tal vez seas parte de la " +"maldiciĆ³nā€¦" #: lang/json/mission_def_from_json.py msgid "" "The awakened congregate in towns and cities, the closer to the center the " "more you will find." msgstr "" +"Los levantados se congregan en los pueblos y ciudades, cuanto mĆ”s cerca del " +"centro, mĆ”s vas a encontrar." #: lang/json/mission_def_from_json.py lang/json/talk_topic_from_json.py msgid "Blessed be." -msgstr "" +msgstr "Bendito seas." #: lang/json/mission_def_from_json.py msgid "" "Blessed be. You are one of the few. We shall do great works together." msgstr "" +"Bendito seas. Sos uno de los pocos. Vamos a poder realizar grandes cosas " +"juntos." #: lang/json/mission_def_from_json.py msgid "Deception is the realm of the cursed. You disappoint me." -msgstr "" +msgstr "El engaƱo es el reino de los malditos. Me decepcionĆ”s." #: lang/json/mission_def_from_json.py msgid "Was the curse too strong for you?" -msgstr "" +msgstr "ĀæLa maldiciĆ³n era demasiado fuerte para vos?" #: lang/json/mission_def_from_json.py msgid "Kill 150 Zombies" -msgstr "" +msgstr "Matar 150 Zombis" #: lang/json/mission_def_from_json.py msgid "" "You have proven you are one of the few, will you stand with the few again?" msgstr "" +"Has probado ser uno de los pocos, Āæte pararĆ”s junto a los pocos otra vez?" #: lang/json/mission_def_from_json.py msgid "" "We must continue the purge. Remove 150 more of the cursed from this land " "and you shall be blessed with greatness." msgstr "" +"Debemos continuar con la purga. SacĆ” 150 mĆ”s de los malditos de esta tierra " +"y deberĆ­as ser bendecido con grandeza." #: lang/json/mission_def_from_json.py msgid "Blessed be. You are a true testament to the few." -msgstr "" +msgstr "Bendito seas. Eres un verdadero testamento de los pocos." #: lang/json/mission_def_from_json.py msgid "I see. Perhaps you will find your way back to us one day." msgstr "" +"Comprendo. QuizĆ”s alguna vez encontrarĆ”s tu camino de vuelta a nosotros." #: lang/json/mission_def_from_json.py msgid "" "The awakened stir in even the darkest of corners. Seek them out and destroy" " them." msgstr "" +"Los levantados se mueven por los rincones mĆ”s oscuros. Buscalos y " +"destruilos." #: lang/json/mission_def_from_json.py msgid "" "Blessed be. You are a valuable asset to our cause. Perhaps you may even be" " our salvation." msgstr "" +"Bendito seas. Sos un valuarte de nuestra causa. Tal vez incluso seas mi " +"salvaciĆ³n." #: lang/json/mission_def_from_json.py msgid "You have come so far. Only to fall." -msgstr "" +msgstr "Has llegado tan lejos. Solo para caer." #: lang/json/mission_def_from_json.py msgid "The curse of this land infects that which does not seek to purge." msgstr "" +"La maldiciĆ³n de esta tierra infecta a aquellos que no buscan la purga." #. ~ 1$s is monster name, 2$s bodypart in accusative #: lang/json/monster_attack_from_json.py src/monattack.cpp @@ -147761,88 +149193,90 @@ msgstr "El %1$s intenta clavarle sus garras a , pero no lo logra." #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s slams into you!" -msgstr "" +msgstr "Ā”El %1$s se choca contra vos!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s slams into !" -msgstr "" +msgstr "Ā”El %1$s se choca contra el !" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s tries to slam into you, but stumbles aside." -msgstr "" +msgstr "El %1$s intenta chocarte pero se tropieza y pasĆ” de largo." #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s tries to slam into , but fails to." -msgstr "" +msgstr "El %1$s intenta chocar contra , pero no lo logra." #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s grabs your arm and bites down hard!!" -msgstr "" +msgstr "Ā”Ā”El %1$s te agarra el brazo y te muerde muy fuerte!!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s grabs and bites down hard!!" -msgstr "" +msgstr "Ā”Ā”El %1$s agarra a y lo muerde muy fuerte!!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "" "The %1$s grabs your arm in its mouth, but fails to penetrate your armor." msgstr "" +"El %1$s te agarra el brazo con su boca, pero no puede penetrar tu armadura." #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s grabs , but fails to penetrate the armor." -msgstr "" +msgstr "El %1$s agarra a , pero no puede penetrar su armadura." #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s slashes you with an integrated tool!" -msgstr "" +msgstr "Ā”El %1$s te tajea con una herramienta integrada!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s slashes !" -msgstr "" +msgstr "Ā”El %1$s tajea a !" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s attempts to cut you, but fails to penetrate your armor." -msgstr "" +msgstr "El %1$s intenta cortarte pero no puede penetrar tu armadura." #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s tries to cut , but fails to penetrate your armor." msgstr "" +"El %1$s intenta cortar a , pero no puede penetrar su armadura." #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s hits you with a heavy sword-slash!!" -msgstr "" +msgstr "Ā”Ā”El %1$s te golpea con un corte pesado de espada!!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s heavily slashes !!" -msgstr "" +msgstr "Ā”Ā”El %1$s tajea fuertemente a !!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s sweeps your legs from under you!" -msgstr "" +msgstr "Ā”El %1$s te barre las piernas!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s knocks to the ground!" -msgstr "" +msgstr "Ā”El %1$s derriba a al suelo!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s tries to sweep out your leg, but can't get through the armor." -msgstr "" +msgstr "El %1$s intenta barrerte las piernas pero no puede por tu armadura." #: lang/json/monster_attack_from_json.py #, no-python-format @@ -147850,36 +149284,40 @@ msgid "" "The %1$s tries to sweep to the ground, but can't get through the " "armor." msgstr "" +"El %1$s intenta barrer y hacerlo caer pero no puede por su " +"armadura." #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s suddenly slams you with their shield, stunning you!" -msgstr "" +msgstr "Ā”El %1$s te golpea de repente con su escudo, aturdiĆ©ndote!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s stuns with a shield bash!" -msgstr "" +msgstr "Ā”El %1$s aturde a con un golpe de escudo!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s tries to shield bash you, but fails to penetrate your armor." msgstr "" +"El %1$s intenta golpearte con su escudo pero no puede penetrar tu armadura." #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s tries bash , but fails to penetrate the armor." msgstr "" +"El %1$s intenta golpear a , pero no puede penetrar su armadura." #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s impales your %2$s with its trident!" -msgstr "" +msgstr "Ā”El %1$s impala tu %2$s con su tridente!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s impales 's %2$s with its trident!" -msgstr "" +msgstr "Ā”El %1$s impala el %2$s de con su tridente!" #: lang/json/monster_attack_from_json.py #, no-python-format @@ -147887,6 +149325,8 @@ msgid "" "The %1$s tries to impale your %2$s with its trident, but fails to penetrate " "your armor!" msgstr "" +"Ā”El %1$s intenta impalar tu %2$s con su tridente, pero no puede penetrar tu " +"armadura!" #: lang/json/monster_attack_from_json.py #, no-python-format @@ -147894,16 +149334,18 @@ msgid "" "The %1$s tries to impale 's %2$s with its trident, but fails to " "penetrate their armor!" msgstr "" +"Ā”El %1$s intenta impalar el %2$s de con su tridente, pero no puede" +" penetrar su armadura!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s crushes your %2$s with its greatclub!" -msgstr "" +msgstr "Ā”El %1$s aplasta tu %2$s con su gran garrote!" #: lang/json/monster_attack_from_json.py #, no-python-format msgid "The %1$s crushes 's %2$s with its greatclub!" -msgstr "" +msgstr "Ā”El %1$s aplasta el %2$s de con su gran garrote!" #: lang/json/monster_attack_from_json.py #, no-python-format @@ -147911,6 +149353,8 @@ msgid "" "The %1$s tries to crush your %2$s with its greatclub, but swings wide and " "stumbles." msgstr "" +"El %1$s intenta aplastar tu %2$s con su gran garrote, pero le erra y " +"trastabilla." #: lang/json/monster_attack_from_json.py #, no-python-format @@ -147918,6 +149362,8 @@ msgid "" "The %1$s tries to crush 's %2$s with its greatclub, but swings wide" " and stumbles." msgstr "" +"El %1$s intenta aplastar el %2$s de con su gran garrote, pero le " +"erra y trastabilla." #: lang/json/morale_type_from_json.py #, no-python-format @@ -147934,11 +149380,11 @@ msgstr "Disfrutaste la conversaciĆ³n" #: lang/json/morale_type_from_json.py msgid "Ate with table" -msgstr "" +msgstr "Comer en mesa" #: lang/json/morale_type_from_json.py msgid "Ate like an animal" -msgstr "" +msgstr "Comer como un animal" #: lang/json/morale_type_from_json.py msgid "Music" @@ -147950,7 +149396,7 @@ msgstr "Disfrutaste la miel" #: lang/json/morale_type_from_json.py msgid "Played Game" -msgstr "" +msgstr "Jugar un juego" #: lang/json/morale_type_from_json.py msgid "Marloss Bliss" @@ -147962,7 +149408,7 @@ msgstr "ExpectaciĆ³n MutagĆ©nica" #: lang/json/morale_type_from_json.py msgid "Good feeling" -msgstr "" +msgstr "Sentimiento lindo" #: lang/json/morale_type_from_json.py msgid "Supported" @@ -148023,7 +149469,7 @@ msgstr "Comer Carne Humana" #: lang/json/morale_type_from_json.py msgid "Ate Demihuman Flesh" -msgstr "" +msgstr "Comer Carne Semihumana" #: lang/json/morale_type_from_json.py msgid "Ate Meat" @@ -148120,11 +149566,11 @@ msgstr "Masoquismo" #: lang/json/morale_type_from_json.py msgid "You have no face!" -msgstr "" +msgstr "Ā”No tenĆ©s cara!" #: lang/json/morale_type_from_json.py msgid "You feel pumped!" -msgstr "" +msgstr "Ā”Te sentĆ­s con mucha energĆ­a!" #: lang/json/morale_type_from_json.py lang/json/mutation_from_json.py msgid "Hoarder" @@ -148148,7 +149594,7 @@ msgstr "Equipo IncĆ³modo" #: lang/json/morale_type_from_json.py msgid "Nomadic Restlessness" -msgstr "" +msgstr "Inquietud NĆ³made" #: lang/json/morale_type_from_json.py msgid "Found kitten <3" @@ -148184,11 +149630,11 @@ msgstr "Ansias de fuego" #: lang/json/morale_type_from_json.py msgid "Killed recently" -msgstr "" +msgstr "Matado recientemente" #: lang/json/morale_type_from_json.py msgid "Longing to kill" -msgstr "" +msgstr "Anhelo de matar" #: lang/json/morale_type_from_json.py msgid "Filthy Gear" @@ -148200,19 +149646,19 @@ msgstr "Angustiado por el recuerdo de carnear un cuerpo humano" #: lang/json/morale_type_from_json.py msgid "Dug out a grave" -msgstr "" +msgstr "Cavar una tumba" #: lang/json/morale_type_from_json.py msgid "Conducted a funeral" -msgstr "" +msgstr "Dirigir un funeral" #: lang/json/morale_type_from_json.py msgid "Communed with the trees" -msgstr "" +msgstr "Comulgar con los Ć”rboles" #: lang/json/morale_type_from_json.py msgid "Accomplishment" -msgstr "" +msgstr "RealizaciĆ³n" #: lang/json/morale_type_from_json.py src/debug_menu.cpp msgid "Failure" @@ -148225,12 +149671,12 @@ msgstr "Moral Debug" #. ~ Move mode name #: lang/json/move_modes_from_json.py msgid "walk" -msgstr "" +msgstr "caminar" #. ~ Move mode character in move mode menu #: lang/json/move_modes_from_json.py msgid "w" -msgstr "" +msgstr "w" #. ~ movement-type #: lang/json/move_modes_from_json.py src/advanced_inv.cpp src/weather.cpp @@ -148240,27 +149686,28 @@ msgstr "O" #. ~ Successfully switch to this move mode, no steed #: lang/json/move_modes_from_json.py msgid "You start walking." -msgstr "" +msgstr "EmpezĆ”s a caminar." #. ~ Successfully switch to this move mode, animal steed #: lang/json/move_modes_from_json.py msgid "You nudge your steed into a steady trot." -msgstr "" +msgstr "AlentĆ”s a tu corcel hacia un trote firme." #. ~ Successfully switch to this move mode, mech steed #: lang/json/move_modes_from_json.py msgid "You set your mech's leg power to a loping fast walk." msgstr "" +"EstablecĆ©s la energĆ­a de la pierna del mecha para andar rĆ”pido a zancadas." #. ~ Move mode name #: lang/json/move_modes_from_json.py msgid "run" -msgstr "" +msgstr "correr" #. ~ Move mode character in move mode menu #: lang/json/move_modes_from_json.py msgid "r" -msgstr "" +msgstr "r" #. ~ movement-type #: lang/json/move_modes_from_json.py @@ -148275,12 +149722,13 @@ msgstr "EmpezĆ”s a correr." #. ~ Successfully switch to this move mode, animal steed #: lang/json/move_modes_from_json.py msgid "You spur your steed into a gallop." -msgstr "" +msgstr "EspoleĆ”s a tu corcel hacia un galope." #. ~ Successfully switch to this move mode, mech steed #: lang/json/move_modes_from_json.py msgid "You set the power of your mech's leg servos to maximum." msgstr "" +"EstablecĆ©s la energĆ­a de los servos de la pierna de tu mecha al mĆ”ximo." #. ~ Failure to switch to this move mode, no steed #: lang/json/move_modes_from_json.py @@ -148290,17 +149738,17 @@ msgstr "EstĆ”s muy cansado para correr." #. ~ Failure to switch to this move mode, animal steed #: lang/json/move_modes_from_json.py msgid "Your steed is too tired to go faster." -msgstr "" +msgstr "Tu corcel estĆ” muy cansado como para ir mĆ”s rĆ”pido." #. ~ Failure to switch to this move mode, mech steed #: lang/json/move_modes_from_json.py msgid "Your mech's leg servos are unable to operate faster." -msgstr "" +msgstr "Los servos de la pierna de tu mecha no pueden operar mĆ”s rĆ”pido." #. ~ Move mode name #: lang/json/move_modes_from_json.py msgid "crouch" -msgstr "" +msgstr "agacharse" #. ~ Move mode character in move mode menu #: lang/json/move_modes_from_json.py @@ -148315,17 +149763,17 @@ msgstr "Ag" #. ~ Successfully switch to this move mode, no steed #: lang/json/move_modes_from_json.py msgid "You start crouching." -msgstr "" +msgstr "EmpezĆ”s a agacharse." #. ~ Successfully switch to this move mode, animal steed #: lang/json/move_modes_from_json.py msgid "You slow your steed to a walk." -msgstr "" +msgstr "DisminuĆ­s a tu corcel para que camine." #. ~ Successfully switch to this move mode, mech steed #: lang/json/move_modes_from_json.py msgid "You reduce the power of your mech's leg servos to minimum." -msgstr "" +msgstr "ReducĆ­s la energĆ­a de los servos de la pierna de tu mecha al mĆ­nimo." #. ~ Mutation class name #: lang/json/mutation_category_from_json.py src/creature.cpp src/options.cpp @@ -148397,7 +149845,7 @@ msgstr "EscuchĆ”s un zumbido, y sentĆ­s que tu cuerpo se endurece." #. ~ Mutation class: Insect iv_message #: lang/json/mutation_category_from_json.py msgid "You sting yourselfā€¦ for the Queen." -msgstr "" +msgstr "Te picĆ”s a vos mismoā€¦ por la Reina." #. ~ Mutation class: Insect Male memorial messsage #: lang/json/mutation_category_from_json.py @@ -148424,7 +149872,7 @@ msgstr "Te sentĆ­s insidioso." #. ~ Mutation class: Spider iv_message #: lang/json/mutation_category_from_json.py msgid "Mmmā€¦ the *special* venom." -msgstr "" +msgstr "Mmmā€¦ el veneno *especial*." #. ~ Mutation class: Spider Male memorial messsage #: lang/json/mutation_category_from_json.py @@ -148559,7 +150007,7 @@ msgstr "Oso/a" #. ~ Mutation class: Bear mutagen_message #: lang/json/mutation_category_from_json.py msgid "You feel an urge toā€¦ patrol? the forests?" -msgstr "" +msgstr "SentĆ­s la urgencia deā€¦ Āæpatrullar? Āælos bosques?" #. ~ Mutation class: Bear iv_message #: lang/json/mutation_category_from_json.py @@ -148673,6 +150121,8 @@ msgstr "CefalĆ³podo" msgid "" "Your mind is overcome by images of eldritch horrorsā€¦ and then they pass." msgstr "" +"Tu mente estĆ” abrumada por imĆ”genes de horrores sobrenaturalesā€¦ y luego se " +"te pasa." #. ~ Mutation class: Cephalopod iv_message #: lang/json/mutation_category_from_json.py @@ -148735,7 +150185,7 @@ msgstr "Por un latido del corazĆ³n, tu sangre se enfrĆ­a." #. ~ Mutation class: Lizard iv_message #: lang/json/mutation_category_from_json.py msgid "Your blood cools down. The feeling isā€¦ different." -msgstr "" +msgstr "Tu sangre se enfrĆ­a. La sensaciĆ³n esā€¦ diferente." #. ~ Mutation class: Lizard Male memorial messsage #: lang/json/mutation_category_from_json.py @@ -148784,7 +150234,7 @@ msgstr "Alpha" #. ~ Mutation class: Alpha mutagen_message #: lang/json/mutation_category_from_json.py msgid "You feelā€¦ better. Somehow." -msgstr "" +msgstr "Te sentĆ­sā€¦ mejor. Por alguna razĆ³n." #. ~ Mutation class: Alpha iv_message #: lang/json/mutation_category_from_json.py @@ -148919,13 +150369,14 @@ msgstr "Raptor" #. ~ Mutation class: Raptor mutagen_message #: lang/json/mutation_category_from_json.py msgid "Mmmā€¦ sweet, bloody flavorā€¦ tastes like victory." -msgstr "" +msgstr "Mmmā€¦ dulce y sangriento saborā€¦ tiene el gusto de la victoria." #. ~ Mutation class: Raptor iv_message #: lang/json/mutation_category_from_json.py msgid "" "You distinctly smell the mutagen mixing with your bloodā€¦ and then it passes." msgstr "" +"OlĆ©s con claridad la mezcla del mutĆ”geno con tu sangreā€¦ y luego se te pasa." #. ~ Mutation class: Raptor Male memorial messsage #: lang/json/mutation_category_from_json.py @@ -148948,11 +150399,13 @@ msgstr "RatĆ³n" #: lang/json/mutation_category_from_json.py msgid "You feel a desire to curl up in a nice, warm pile ofā€¦ shredded paper." msgstr "" +"SentĆ­s el deseo de acurrucarte en una linda y tibia pila deā€¦ pedazos de " +"papel ." #. ~ Mutation class: Mouse iv_message #: lang/json/mutation_category_from_json.py msgid "You feelā€¦ small. But comfortable." -msgstr "" +msgstr "Te sentĆ­sā€¦ chiquito. Pero cĆ³modo." #. ~ Mutation class: Mouse Male memorial messsage #: lang/json/mutation_category_from_json.py @@ -148969,66 +150422,68 @@ msgstr "EncontrĆ³ el queso." #. ~ Mutation class name #: lang/json/mutation_category_from_json.py lang/json/mutation_from_json.py msgid "YUGGOTH" -msgstr "" +msgstr "YUGGOTH" #. ~ Mutation class: YUGGOTH mutagen_message #: lang/json/mutation_category_from_json.py msgid "Strange memories of another world overwhelm youā€¦" -msgstr "" +msgstr "Te abruman recuerdos extraƱos de otro mundoā€¦" #. ~ Mutation class: YUGGOTH iv_message #: lang/json/mutation_category_from_json.py msgid "You look into your own cells and change them." -msgstr "" +msgstr "MirĆ”s a tus propias cĆ©lulas y las cambiĆ”s." #. ~ Mutation class: YUGGOTH iv_sleep_message #: lang/json/mutation_category_from_json.py msgid "You gaze inside, past your fear, past good and evil, into the future." msgstr "" +"ContemplĆ”s tu interior, mĆ”s allĆ” de tu miedo, mĆ”s allĆ” del bien y del mal, " +"hacia el futuro." #. ~ Mutation class: YUGGOTH Male memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_male" msgid "Prepared the way into the galaxy." -msgstr "" +msgstr "PreparĆ³ el camino hacia la galaxia." #. ~ Mutation class: YUGGOTH Female memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_female" msgid "Prepared the way into the galaxy." -msgstr "" +msgstr "PreparĆ³ el camino hacia la galaxia." #. ~ Mutation class name #: lang/json/mutation_category_from_json.py msgid "Mastodon" -msgstr "" +msgstr "Mastodonte" #. ~ Mutation class: Mastodon mutagen_message #: lang/json/mutation_category_from_json.py msgid "You feel a desire to trumpet and toot." -msgstr "" +msgstr "SentĆ­s el deseo de barritar." #. ~ Mutation class: Mastodon iv_message #: lang/json/mutation_category_from_json.py msgid "You heart races, and you glance around for poachers." -msgstr "" +msgstr "Tu corazĆ³n se acelera y mirĆ”s buscando cazadores." #. ~ Mutation class: Mastodon Male memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_male" msgid "Went extinct." -msgstr "" +msgstr "Se extinguiĆ³." #. ~ Mutation class: Mastodon Female memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_female" msgid "Went extinct." -msgstr "" +msgstr "Se extinguiĆ³." #. ~ Mutation class name #: lang/json/mutation_category_from_json.py msgid "Vampire" -msgstr "" +msgstr "Vampiro" #. ~ Mutation class: Vampire mutagen_message #: lang/json/mutation_category_from_json.py @@ -149036,6 +150491,8 @@ msgid "" "Nearby shadows seem to bend towards you for a moment and then reality warps " "back into place." msgstr "" +"Las sombras cercanas parecen acercarse por un instante y luego la realidad " +"vuelve a su lugar." #. ~ Mutation class: Vampire iv_message #: lang/json/mutation_category_from_json.py @@ -149043,23 +150500,25 @@ msgid "" "You twitch and pant randomly as your desire to slake your inhuman thirst " "becomes overwhelming." msgstr "" +"Te retorcĆ©s y jadeĆ”s aleatoriamente mientras tu deseo de saciar tu sed " +"inhumana se vuelve abrumadora." #. ~ Mutation class: Vampire Male memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_male" msgid "Dispersed into the shadows." -msgstr "" +msgstr "Se dispersĆ³ en las sombras." #. ~ Mutation class: Vampire Female memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_female" msgid "Dispersed into the shadows." -msgstr "" +msgstr "Se dispersĆ³ en las sombras." #. ~ Mutation class name #: lang/json/mutation_category_from_json.py msgid "Wendigo" -msgstr "" +msgstr "Wendigo" #. ~ Mutation class: Wendigo mutagen_message #: lang/json/mutation_category_from_json.py @@ -149067,6 +150526,8 @@ msgid "" "Nearby plants seem to bend towards you for a moment and then they shift back" " into place." msgstr "" +"Las plantas cercanas parecen acercarse por un instante y luego vuelven a su " +"lugar." #. ~ Mutation class: Wendigo iv_message #: lang/json/mutation_category_from_json.py @@ -149074,72 +150535,74 @@ msgid "" "A serene feeling of terror grips you as become acutely aware of the flora " "and fauna beckoning towards you." msgstr "" +"Un sereno sentimiento de terror te sobrecoge cuando te volvĆ©s consciente de " +"que la flora y fauna te estĆ” llamando." #. ~ Mutation class: Wendigo Male memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_male" msgid "Reclaimed by nature." -msgstr "" +msgstr "Reclamado por la naturaleza." #. ~ Mutation class: Wendigo Female memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_female" msgid "Reclaimed by nature." -msgstr "" +msgstr "Reclamada por la naturaleza." #. ~ Mutation class name #: lang/json/mutation_category_from_json.py lang/json/mutation_from_json.py msgid "Manatouched" -msgstr "" +msgstr "ManĆ”tocado" #. ~ Mutation class: Manatouched mutagen_message #: lang/json/mutation_category_from_json.py msgid "Your ley lines surge with mana." -msgstr "" +msgstr "Tus lĆ­neas ley aumentan con manĆ”." #. ~ Mutation class: Manatouched iv_message #: lang/json/mutation_category_from_json.py msgid "A crackle of power comes from within." -msgstr "" +msgstr "Un chasquido de energĆ­a te surge de adentro." #. ~ Mutation class: Manatouched Male memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_male" msgid "Ascended to the metaphysical." -msgstr "" +msgstr "AscendiĆ³ a lo metafĆ­sico." #. ~ Mutation class: Manatouched Female memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_female" msgid "Ascended to the metaphysical." -msgstr "" +msgstr "AscendiĆ³ a lo metafĆ­sico." #. ~ Mutation class name #: lang/json/mutation_category_from_json.py msgid "Sugar Kin" -msgstr "" +msgstr "Pariente de Golosinas" #. ~ Mutation class: Sugar Kin mutagen_message #: lang/json/mutation_category_from_json.py msgid "How sweet!" -msgstr "" +msgstr "Ā”QuĆ© dulce!" #. ~ Mutation class: Sugar Kin iv_message #: lang/json/mutation_category_from_json.py msgid "You inject some more fizz into your syrup." -msgstr "" +msgstr "InyectĆ”s un poco mĆ”s de burbujas en tu jarabe." #. ~ Mutation class: Sugar Kin Male memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_male" msgid "Crystalized." -msgstr "" +msgstr "Cristalizado." #. ~ Mutation class: Sugar Kin Female memorial messsage #: lang/json/mutation_category_from_json.py msgctxt "memorial_female" msgid "Crystalized." -msgstr "" +msgstr "Cristalizada." #: lang/json/mutation_from_json.py msgid "Venom Mob Protege" @@ -149169,7 +150632,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Savings" -msgstr "" +msgstr "Ahorros" #. ~ Description for {'str': 'Savings'} #: lang/json/mutation_from_json.py @@ -149177,10 +150640,12 @@ msgid "" "You had some money stashed at the bank for a rainy day. Now that the storm " "is raging, it's a last call to use it maybe?" msgstr "" +"TenĆ­as un poco de plata guardada en el banco para un momento de carencia. " +"Ahora que la tormenta es grande, quizĆ”s sea la Ćŗltima oportunidad de usarla." #: lang/json/mutation_from_json.py msgid "Debt" -msgstr "" +msgstr "Deuda" #. ~ Description for {'str': 'Debt'} #: lang/json/mutation_from_json.py @@ -149188,10 +150653,12 @@ msgid "" "You needed money and had a big loan in a bank. Good thing nobody will come " "to collect it now, right? Right?" msgstr "" +"Necesitabas plata y tomaste un prĆ©stamo grande en un banco. Por suerte nadie" +" va a venir a cobrĆ”rtelo ahora, Āæno? ĀæNo?" #: lang/json/mutation_from_json.py msgid "Millionaire" -msgstr "" +msgstr "Millonario" #. ~ Description for {'str': 'Millionaire'} #: lang/json/mutation_from_json.py @@ -149199,388 +150666,390 @@ msgid "" "At the time of Cataclysm you were an owner of a fortune stashed in a bank. " "Does that have any meaning now?" msgstr "" +"En el momento del Cataclismo eras el dueƱo de una fortuna que guardabas en " +"un banco. ĀæTiene algĆŗn sentido eso ahora?" #: lang/json/mutation_from_json.py msgid "Hair: black, crew-cut" -msgstr "" +msgstr "Pelo: negro, rapado" #. ~ Description for {'str': 'Hair: black, crew-cut'} #: lang/json/mutation_from_json.py msgid "Crewcut black hair style." -msgstr "" +msgstr "Pelo negro y rapado." #: lang/json/mutation_from_json.py msgid "Hair: black, mohawk" -msgstr "" +msgstr "Pelo: negro, mohicano" #. ~ Description for {'str': 'Hair: black, mohawk'} #: lang/json/mutation_from_json.py msgid "Mohawk black hair style." -msgstr "" +msgstr "Pelo negro y con un corte mohicano." #: lang/json/mutation_from_json.py msgid "Hair: black, 'fro" -msgstr "" +msgstr "Pelo: negro, afro" #. ~ Description for {'str': "Hair: black, 'fro"} #: lang/json/mutation_from_json.py msgid "'Fro black hair style." -msgstr "" +msgstr "Pelo negro y con un afro." #: lang/json/mutation_from_json.py msgid "Hair: black, short" -msgstr "" +msgstr "Pelo: negro, corto" #. ~ Description for {'str': 'Hair: black, short'} #: lang/json/mutation_from_json.py msgid "Short black hair style" -msgstr "" +msgstr "Pelo negro y cortito." #: lang/json/mutation_from_json.py msgid "Hair: black, medium-length" -msgstr "" +msgstr "Pelo: negro, medio largo" #. ~ Description for {'str': 'Hair: black, medium-length'} #: lang/json/mutation_from_json.py msgid "Medium-length black hair style." -msgstr "" +msgstr "Pelo negro y de un largo medio." #: lang/json/mutation_from_json.py msgid "Hair: black, long" -msgstr "" +msgstr "Pelo: negro, largo" #. ~ Description for {'str': 'Hair: black, long'} #: lang/json/mutation_from_json.py msgid "Long black hair style." -msgstr "" +msgstr "Pelo negro y largo." #: lang/json/mutation_from_json.py msgid "Hair: brown, crew-cut" -msgstr "" +msgstr "Pelo: castaƱo, rapado" #. ~ Description for {'str': 'Hair: brown, crew-cut'} #: lang/json/mutation_from_json.py msgid "Crewcut brown hair style." -msgstr "" +msgstr "Pelo castaƱo y rapado." #: lang/json/mutation_from_json.py msgid "Hair: brown, mohawk" -msgstr "" +msgstr "Pelo: castaƱo, mohicano" #. ~ Description for {'str': 'Hair: brown, mohawk'} #: lang/json/mutation_from_json.py msgid "Mohawk brown hair style." -msgstr "" +msgstr "Pelo castaƱo y con un corte mohicano." #: lang/json/mutation_from_json.py msgid "Hair: brown, 'fro" -msgstr "" +msgstr "Pelo: castaƱo, afro" #. ~ Description for {'str': "Hair: brown, 'fro"} #: lang/json/mutation_from_json.py msgid "'Fro brown hair style." -msgstr "" +msgstr "Pelo castaƱo y con un afro." #: lang/json/mutation_from_json.py msgid "Hair: brown, short" -msgstr "" +msgstr "Pelo: castaƱo, corto" #. ~ Description for {'str': 'Hair: brown, short'} #: lang/json/mutation_from_json.py msgid "Short brown hair style" -msgstr "" +msgstr "Pelo castaƱo y cortito." #: lang/json/mutation_from_json.py msgid "Hair: brown, medium-length" -msgstr "" +msgstr "Pelo: castaƱo, medio largo" #. ~ Description for {'str': 'Hair: brown, medium-length'} #: lang/json/mutation_from_json.py msgid "Medium-length brown hair style." -msgstr "" +msgstr "Pelo castaƱo y de un largo medio." #: lang/json/mutation_from_json.py msgid "Hair: brown, long" -msgstr "" +msgstr "Pelo: castaƱo, largo" #. ~ Description for {'str': 'Hair: brown, long'} #: lang/json/mutation_from_json.py msgid "Long brown hair style." -msgstr "" +msgstr "Pelo castaƱo y largo." #: lang/json/mutation_from_json.py msgid "Hair: blond, crew-cut" -msgstr "" +msgstr "Pelo: rubio, rapado" #. ~ Description for {'str': 'Hair: blond, crew-cut'} #: lang/json/mutation_from_json.py msgid "Crewcut blond hair style." -msgstr "" +msgstr "Pelo rubio y rapado." #: lang/json/mutation_from_json.py msgid "Hair: blond, mohawk" -msgstr "" +msgstr "Pelo: rubio, mohicano" #. ~ Description for {'str': 'Hair: blond, mohawk'} #: lang/json/mutation_from_json.py msgid "Mohawk blond hair style." -msgstr "" +msgstr "Pelo rubio y con un corte mohicano." #: lang/json/mutation_from_json.py msgid "Hair: blond, 'fro" -msgstr "" +msgstr "Pelo: rubio, afro" #. ~ Description for {'str': "Hair: blond, 'fro"} #: lang/json/mutation_from_json.py msgid "'Fro blond hair style." -msgstr "" +msgstr "Pelo rubio y con un afro." #: lang/json/mutation_from_json.py msgid "Hair: blond, short" -msgstr "" +msgstr "Pelo: rubio, corto" #. ~ Description for {'str': 'Hair: blond, short'} #: lang/json/mutation_from_json.py msgid "Short blond hair style" -msgstr "" +msgstr "Pelo rubio y cortito." #: lang/json/mutation_from_json.py msgid "Hair: blond, medium-length" -msgstr "" +msgstr "Pelo: rubio, medio largo" #. ~ Description for {'str': 'Hair: blond, medium-length'} #: lang/json/mutation_from_json.py msgid "Medium-length blond hair style." -msgstr "" +msgstr "Pelo rubio y de un largo medio." #: lang/json/mutation_from_json.py msgid "Hair: blond, long" -msgstr "" +msgstr "Pelo: rubio, largo" #. ~ Description for {'str': 'Hair: blond, long'} #: lang/json/mutation_from_json.py msgid "Long blond hair style." -msgstr "" +msgstr "Pelo rubio y largo." #: lang/json/mutation_from_json.py msgid "Hair: red, crew-cut" -msgstr "" +msgstr "Pelo: colorado, rapado" #. ~ Description for {'str': 'Hair: red, crew-cut'} #: lang/json/mutation_from_json.py msgid "Crewcut red hair style." -msgstr "" +msgstr "Pelo colorado y rapado." #: lang/json/mutation_from_json.py msgid "Hair: red, mohawk" -msgstr "" +msgstr "Pelo: colorado, mohicano" #. ~ Description for {'str': 'Hair: red, mohawk'} #: lang/json/mutation_from_json.py msgid "Mohawk red hair style." -msgstr "" +msgstr "Pelo colorado y con un corte mohicano." #: lang/json/mutation_from_json.py msgid "Hair: red, 'fro" -msgstr "" +msgstr "Pelo: colorado, afro" #. ~ Description for {'str': "Hair: red, 'fro"} #: lang/json/mutation_from_json.py msgid "'Fro red hair style." -msgstr "" +msgstr "Pelo colorado y con un afro." #: lang/json/mutation_from_json.py msgid "Hair: red, short" -msgstr "" +msgstr "Pelo: colorado, corto" #. ~ Description for {'str': 'Hair: red, short'} #: lang/json/mutation_from_json.py msgid "Short red hair style" -msgstr "" +msgstr "Pelo colorado y cortito." #: lang/json/mutation_from_json.py msgid "Hair: red, medium-length" -msgstr "" +msgstr "Pelo: colorado, medio largo" #. ~ Description for {'str': 'Hair: red, medium-length'} #: lang/json/mutation_from_json.py msgid "Medium-length red hair style." -msgstr "" +msgstr "Pelo colorado y de un largo medio." #: lang/json/mutation_from_json.py msgid "Hair: red, long" -msgstr "" +msgstr "Pelo: colorado, largo" #. ~ Description for {'str': 'Hair: red, long'} #: lang/json/mutation_from_json.py msgid "Long red hair style." -msgstr "" +msgstr "Pelo colorado y largo." #: lang/json/mutation_from_json.py msgid "Hair: gray, crew-cut" -msgstr "" +msgstr "Pelo: canoso, rapado" #. ~ Description for {'str': 'Hair: gray, crew-cut'} #: lang/json/mutation_from_json.py msgid "Crewcut gray hair style." -msgstr "" +msgstr "Pelo canoso y rapado." #: lang/json/mutation_from_json.py msgid "Hair: gray, mohawk" -msgstr "" +msgstr "Pelo: canoso, mohicano" #. ~ Description for {'str': 'Hair: gray, mohawk'} #: lang/json/mutation_from_json.py msgid "Mohawk gray hair style." -msgstr "" +msgstr "Pelo canoso y con un corte mohicano." #: lang/json/mutation_from_json.py msgid "Hair: gray, 'fro" -msgstr "" +msgstr "Pelo: canoso, afro" #. ~ Description for {'str': "Hair: gray, 'fro"} #: lang/json/mutation_from_json.py msgid "'Fro gray hair style." -msgstr "" +msgstr "Pelo canoso y con un afro." #: lang/json/mutation_from_json.py msgid "Hair: gray, short" -msgstr "" +msgstr "Pelo: canoso, corto" #. ~ Description for {'str': 'Hair: gray, short'} #: lang/json/mutation_from_json.py msgid "Short gray hair style" -msgstr "" +msgstr "Pelo canoso y cortito." #: lang/json/mutation_from_json.py msgid "Hair: gray, medium-length" -msgstr "" +msgstr "Pelo: canoso, medio largo" #. ~ Description for {'str': 'Hair: gray, medium-length'} #: lang/json/mutation_from_json.py msgid "Medium-length gray hair style." -msgstr "" +msgstr "Pelo canoso y de un largo medio." #: lang/json/mutation_from_json.py msgid "Hair: gray, long" -msgstr "" +msgstr "Pelo: canoso, largo" #. ~ Description for {'str': 'Hair: gray, long'} #: lang/json/mutation_from_json.py msgid "Long gray hair style." -msgstr "" +msgstr "Pelo canoso y largo." #: lang/json/mutation_from_json.py msgid "Hair: white, crew-cut" -msgstr "" +msgstr "Pelo: blanco, rapado" #. ~ Description for {'str': 'Hair: white, crew-cut'} #: lang/json/mutation_from_json.py msgid "Crewcut white hair style." -msgstr "" +msgstr "Pelo blanco y rapado." #: lang/json/mutation_from_json.py msgid "Hair: white, mohawk" -msgstr "" +msgstr "Pelo: blanco, mohicano" #. ~ Description for {'str': 'Hair: white, mohawk'} #: lang/json/mutation_from_json.py msgid "Mohawk white hair style." -msgstr "" +msgstr "Pelo blanco y con un corte mohicano." #: lang/json/mutation_from_json.py msgid "Hair: white, 'fro" -msgstr "" +msgstr "Pelo: blanco, afro" #. ~ Description for {'str': "Hair: white, 'fro"} #: lang/json/mutation_from_json.py msgid "'Fro white hair style." -msgstr "" +msgstr "Pelo blanco y con un afro." #: lang/json/mutation_from_json.py msgid "Hair: white, short" -msgstr "" +msgstr "Pelo: blanco, corto" #. ~ Description for {'str': 'Hair: white, short'} #: lang/json/mutation_from_json.py msgid "Short white hair style" -msgstr "" +msgstr "Pelo blanco y cortito." #: lang/json/mutation_from_json.py msgid "Hair: white, medium-length" -msgstr "" +msgstr "Pelo: blanco, medio largo" #. ~ Description for {'str': 'Hair: white, medium-length'} #: lang/json/mutation_from_json.py msgid "Medium-length white hair style." -msgstr "" +msgstr "Pelo blanco y de un largo medio." #: lang/json/mutation_from_json.py msgid "Hair: white, long" -msgstr "" +msgstr "Pelo: blanco, largo" #. ~ Description for {'str': 'Hair: white, long'} #: lang/json/mutation_from_json.py msgid "Long white hair style." -msgstr "" +msgstr "Pelo blanco y largo." #: lang/json/mutation_from_json.py msgid "Hair: none" -msgstr "" +msgstr "Pelo: nada" #. ~ Description for {'str': 'Hair: none'} #: lang/json/mutation_from_json.py msgid "You are bald." -msgstr "" +msgstr "Sos pelado/a." #: lang/json/mutation_from_json.py msgid "Skin tone: dark brown" -msgstr "" +msgstr "Tono de piel: marrĆ³n oscuro" #. ~ Description for {'str': 'Skin tone: dark brown'} #: lang/json/mutation_from_json.py msgid "You have a dark brown skin tone." -msgstr "" +msgstr "TenĆ©s un tono de piel marrĆ³n oscuro." #: lang/json/mutation_from_json.py msgid "Skin tone: light" -msgstr "" +msgstr "Tono de piel: pĆ”lido" #. ~ Description for {'str': 'Skin tone: light'} #: lang/json/mutation_from_json.py msgid "You have a light peach skin tone." -msgstr "" +msgstr "TenĆ©s un tono de piel de un rosita pĆ”lido." #: lang/json/mutation_from_json.py msgid "Skin tone: light brown" -msgstr "" +msgstr "Tono de piel: marrĆ³n clarito" #. ~ Description for {'str': 'Skin tone: light brown'} #: lang/json/mutation_from_json.py msgid "You have a light brown skin tone." -msgstr "" +msgstr "TenĆ©s un tono de piel marrĆ³n clarito." #: lang/json/mutation_from_json.py msgid "Skin tone: rose" -msgstr "" +msgstr "Tono de piel: rosado" #. ~ Description for {'str': 'Skin tone: rose'} #: lang/json/mutation_from_json.py msgid "You have a rosy pink skin tone." -msgstr "" +msgstr "TenĆ©s un tono de piel rosado." #: lang/json/mutation_from_json.py msgid "Skin tone: bronze" -msgstr "" +msgstr "Tono de piel: bronce" #. ~ Description for {'str': 'Skin tone: bronze'} #: lang/json/mutation_from_json.py msgid "You have a bronze or tan skin tone." -msgstr "" +msgstr "TenĆ©s un tono de piel bronceado." #: lang/json/mutation_from_json.py msgid "Facial hair: none" -msgstr "" +msgstr "Pelo facial: nada" #. ~ Description for {'str': 'Facial hair: none'} #: lang/json/mutation_from_json.py @@ -149588,19 +151057,21 @@ msgid "" "You have no hair on your face, it is shaven or simply untouched by the " "presence of hair." msgstr "" +"No tenĆ©s pelo en la cara, estĆ” afeitada o simplemente nunca tuvo presencia " +"de pelo" #: lang/json/mutation_from_json.py msgid "Facial hair: goatee" -msgstr "" +msgstr "Pelo facial: chiva" #. ~ Description for {'str': 'Facial hair: goatee'} #: lang/json/mutation_from_json.py msgid "You have a short beard at the tip of your chin." -msgstr "" +msgstr "TenĆ©s una barba corta en la punta de tu pera." #: lang/json/mutation_from_json.py msgid "Facial hair: circle beard" -msgstr "" +msgstr "Pelo facial: candado" #. ~ Description for {'str': 'Facial hair: circle beard'} #: lang/json/mutation_from_json.py @@ -149608,20 +151079,21 @@ msgid "" "You have a moustache and a short beard, that both form a circle around your " "lips." msgstr "" +"TenĆ©s bigote y barba corta, formando un cĆ­rculo alrededor de tus labios." #: lang/json/mutation_from_json.py msgid "Facial hair: royale beard" -msgstr "" +msgstr "Pelo facial: barba real" #. ~ Description for {'str': 'Facial hair: royale beard'} #: lang/json/mutation_from_json.py msgid "" "You have a moustache and a short beard forming a patch under your lips." -msgstr "" +msgstr "TenĆ©s bigote y barba corta debajo de los labios pero que no se tocan." #: lang/json/mutation_from_json.py msgid "Facial hair: anchor beard" -msgstr "" +msgstr "Pelo facial: barbita ancla" #. ~ Description for {'str': 'Facial hair: anchor beard'} #: lang/json/mutation_from_json.py @@ -149630,10 +151102,13 @@ msgid "" "bottom lip, then tracing the jaw lines. It looks a bit like an anchor, thus" " the name." msgstr "" +"TenĆ©s bigote y barba que comienzan con una lĆ­nea yendo hacia desde el labio " +"inferior y por el borde de la lĆ­nea de la mandĆ­bula. Se parece un poco a un " +"ancla, por eso el nombre." #: lang/json/mutation_from_json.py msgid "Facial hair: short boxed beard" -msgstr "" +msgstr "Pelo facial: barba corta cuadrada" #. ~ Description for {'str': 'Facial hair: short boxed beard'} #: lang/json/mutation_from_json.py @@ -149641,29 +151116,32 @@ msgid "" "You have a moustache and a short beard with trimmed sides. Thin patches " "connect them both, forming a 'box' around the lips, thus the name." msgstr "" +"TenĆ©s bigote y barba corta con los costados cortados. PequeƱos pedazos " +"conectan a los dos, formando una especie de caja alrededor de los labios, " +"por eso el nombre." #: lang/json/mutation_from_json.py msgid "Facial hair: chevron moustache" -msgstr "" +msgstr "Pelo facial: bigote chevron" #. ~ Description for {'str': 'Facial hair: chevron moustache'} #: lang/json/mutation_from_json.py msgid "You have a moustache that covers your entire top lip." -msgstr "" +msgstr "TenĆ©s bigote que cubre el labio superior completamente." #: lang/json/mutation_from_json.py msgid "Facial hair: 3-day stubble" -msgstr "" +msgstr "Pelo facial: barba de 3 dĆ­as" #. ~ Description for {'str': 'Facial hair: 3-day stubble'} #: lang/json/mutation_from_json.py msgid "" "You have a short trimmed moustache and beard imitating a 3-day stubble." -msgstr "" +msgstr "TenĆ©s bigote recortado y barba que asemejan una crecida de 3 dĆ­as." #: lang/json/mutation_from_json.py msgid "Facial hair: horseshoe" -msgstr "" +msgstr "Pelo facial: herradura" #. ~ Description for {'str': 'Facial hair: horseshoe'} #: lang/json/mutation_from_json.py @@ -149671,10 +151149,12 @@ msgid "" "You have a moustache with patches going down the chin from both ends, thus " "the name." msgstr "" +"TenĆ©s bigote con puntas hacia la pera desde los dos costados, por eso el " +"nombre." #: lang/json/mutation_from_json.py msgid "Facial hair: original moustache" -msgstr "" +msgstr "Pelo facial: bigote original" #. ~ Description for {'str': 'Facial hair: original moustache'} #: lang/json/mutation_from_json.py @@ -149682,10 +151162,12 @@ msgid "" "You have a moustache with shortened ends, that covers only the skin above " "your upper lip." msgstr "" +"TenĆ©s bigote con las puntas cortas, que cubre solamente la piel sobre tu " +"labio superior." #: lang/json/mutation_from_json.py msgid "Facial hair: mutton chops beard" -msgstr "" +msgstr "Pelo facial: patillas souvarov" #. ~ Description for {'str': 'Facial hair: mutton chops beard'} #: lang/json/mutation_from_json.py @@ -149693,29 +151175,31 @@ msgid "" "You have long sideburns that connect to your moustache, with the tip of the " "chin shaven clean." msgstr "" +"TenĆ©s patillas largas que se conectan con el bigote, con la punta de la pera" +" afeitada." #: lang/json/mutation_from_json.py msgid "Facial hair: gunslinger beard" -msgstr "" +msgstr "Pelo facial: barba pistolero" #. ~ Description for {'str': 'Facial hair: gunslinger beard'} #: lang/json/mutation_from_json.py msgid "You have a horseshoe moustache and disconnected sideburns." -msgstr "" +msgstr "TenĆ©s bigote herradura y patillas que no llegan hasta el bigote." #: lang/json/mutation_from_json.py msgid "Facial hair: chin strip" -msgstr "" +msgstr "Pelo facial: raya de mentĆ³n" #. ~ Description for {'str': 'Facial hair: chin strip'} #: lang/json/mutation_from_json.py msgid "" "You have a short beard in a form of a vertical patch under your bottom lip." -msgstr "" +msgstr "TenĆ©s una barba corta en forma vertical bajo tu labio inferior." #: lang/json/mutation_from_json.py msgid "Facial hair: chin curtain" -msgstr "" +msgstr "Pelo facial: cortina de mentĆ³n" #. ~ Description for {'str': 'Facial hair: chin curtain'} #: lang/json/mutation_from_json.py @@ -149723,20 +151207,23 @@ msgid "" "You have a full beard without a moustache, restricted to the chin, sometimes" " called a 'lion's mane'. Much like Abraham Lincoln's beard." msgstr "" +"TenĆ©s barba completa sin bigote, solamente en el mentĆ³n, que a veces llaman " +"'melena de leĆ³n'. Muy parecida a la barba de Abraham Lincoln." #: lang/json/mutation_from_json.py msgid "Facial hair: chin strap" -msgstr "" +msgstr "Pelo facial: tira de mentĆ³n" #. ~ Description for {'str': 'Facial hair: chin strap'} #: lang/json/mutation_from_json.py msgid "" "You have beard along the jaw lines, circling the chin, and no moustache." msgstr "" +"TenĆ©s barba por la lĆ­nea de la mandĆ­bula, alrededor de la pera y sin bigote." #: lang/json/mutation_from_json.py msgid "Facial hair: beard" -msgstr "" +msgstr "Pelo facial: barba" #. ~ Description for {'str': 'Facial hair: beard'} #: lang/json/mutation_from_json.py @@ -149744,19 +151231,21 @@ msgid "" "You have a moustache and a long beard, both formed by allowing free growth " "of hair, with no particular styling." msgstr "" +"TenĆ©s bigote y barba larga, que crecen libres sin ningĆŗn estilo en " +"particular." #: lang/json/mutation_from_json.py msgid "Facial hair: handlebar moustache" -msgstr "" +msgstr "Pelo facial: bigote manubrio" #. ~ Description for {'str': 'Facial hair: handlebar moustache'} #: lang/json/mutation_from_json.py msgid "You have a moustache with long flared out ends." -msgstr "" +msgstr "TenĆ©s bigote con las puntas largas hacia arriba." #: lang/json/mutation_from_json.py msgid "Facial hair: neckbeard" -msgstr "" +msgstr "Pelo facial: barba de cuello" #. ~ Description for {'str': 'Facial hair: neckbeard'} #: lang/json/mutation_from_json.py @@ -149764,19 +151253,21 @@ msgid "" "You have a beard formed from hair grown on neck below the chin line. No " "moustache included." msgstr "" +"TenĆ©s barba formada por el pelo creciendo del cuello, debajo de la lĆ­nea de " +"la mandĆ­bula. No incluye bigote." #: lang/json/mutation_from_json.py msgid "Facial hair: pencil moustache" -msgstr "" +msgstr "Pelo facial: bigote pincel" #. ~ Description for {'str': 'Facial hair: pencil moustache'} #: lang/json/mutation_from_json.py msgid "You have a very thin moustache just above the line of the upper lip." -msgstr "" +msgstr "TenĆ©s bigote muy finito justo arriba de la lĆ­nea del labio superior." #: lang/json/mutation_from_json.py msgid "Facial hair: shenandoah" -msgstr "" +msgstr "Pelo facial: shenandoah" #. ~ Description for {'str': 'Facial hair: shenandoah'} #: lang/json/mutation_from_json.py @@ -149784,10 +151275,12 @@ msgid "" "Long full beard with no moustache, popular among Amish community, often with" " two pointed ends." msgstr "" +"TenĆ©s barba larga sin bigote, popular en la comunidad amish, a veces con dos" +" puntas." #: lang/json/mutation_from_json.py msgid "Facial hair: sideburns" -msgstr "" +msgstr "Pelo facial: patillas" #. ~ Description for {'str': 'Facial hair: sideburns'} #: lang/json/mutation_from_json.py @@ -149795,21 +151288,23 @@ msgid "" "You have patches of hair in front of your ears, that normally would connect " "your hair with the beard, but they are here by themselves." msgstr "" +"TenĆ©s pedazos de pelo adelante de las orejas, que normalmente conectarĆ­an tu" +" pelo con la barba pero estĆ”n ahĆ­ solos." #: lang/json/mutation_from_json.py msgid "Facial hair: soul patch" -msgstr "" +msgstr "Pelo facial: mosca" #. ~ Description for {'str': 'Facial hair: soul patch'} #: lang/json/mutation_from_json.py msgid "" "You have a little bit of hair in the dip under your lower lip, and no other " "facial hair whatsoever." -msgstr "" +msgstr "TenĆ©s un pedacito de pelo debajo de tu labio inferior y nada mĆ”s." #: lang/json/mutation_from_json.py msgid "Facial hair: toothbrush moustache" -msgstr "" +msgstr "Pelo facial: bigote cepillo" #. ~ Description for {'str': 'Facial hair: toothbrush moustache'} #: lang/json/mutation_from_json.py @@ -149818,19 +151313,23 @@ msgid "" "but then that other guy used it as a characteristic, and it became " "unwelcomed." msgstr "" +"Charlie Chaplin usaba este tipo de pedacito de pelo justo debajo de la " +"nariz, pero despuĆ©s ese otro tipo lo usĆ³ como caracterĆ­stica, y este bigote " +"ya no es bien recibido." #: lang/json/mutation_from_json.py msgid "Facial hair: Van Dyke" -msgstr "" +msgstr "Pelo facial: Van Dyke" #. ~ Description for {'str': 'Facial hair: Van Dyke'} #: lang/json/mutation_from_json.py msgid "You have handlebar moustache with a chin strip or a small goatee." msgstr "" +"TenĆ©s bigote manubrio con una lĆ­nea en el mentĆ³n o un pequeƱo candado." #: lang/json/mutation_from_json.py msgid "Facial hair: walrus" -msgstr "" +msgstr "Pelo facial: morsa" #. ~ Description for {'str': 'Facial hair: walrus'} #: lang/json/mutation_from_json.py @@ -149838,10 +151337,12 @@ msgid "" "You have long thick moustache, overshadowing you lips, that somewhat " "resembles facial hair of a walrus." msgstr "" +"TenĆ©s bigote largo y grueso, que sobrepasa los labios y que de alguna manera" +" parece el pelo facial de una morsa." #: lang/json/mutation_from_json.py msgid "Facial hair: The Zappa" -msgstr "" +msgstr "Pelo facial: El Zappa" #. ~ Description for {'str': 'Facial hair: The Zappa'} #: lang/json/mutation_from_json.py @@ -149849,6 +151350,8 @@ msgid "" "You have a wide soul patch and a full moustache that extends a bit downwards" " at the corners of your lips." msgstr "" +"TenĆ©s bigote mosca ancho que se extiende hacia abajo hasta los bordes de tus" +" labios." #: lang/json/mutation_from_json.py msgid "Fleet-Footed" @@ -149867,7 +151370,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Reflex Photophore" -msgstr "" +msgstr "FotĆ³foro Reflejo" #. ~ Description for {'str': 'Reflex Photophore'} #. ~ Description for {'str': 'Reflex Photophore (on)'} @@ -149877,14 +151380,17 @@ msgid "" "and it might start to shine in response to your emotions or your " "physiological state." msgstr "" +"Un fotĆ³foro ha crecido en tu cabeza. No podĆ©s controlarlo de manera " +"consciente y podrĆ­a empezar a brillar en respuesta a tus emociones o tu " +"estado psicolĆ³gico." #: lang/json/mutation_from_json.py msgid "Reflex Photophore (on)" -msgstr "" +msgstr "FotĆ³foro Reflejo (encendido)" #: lang/json/mutation_from_json.py msgid "Weak Photophore" -msgstr "" +msgstr "FotĆ³foro DĆ©bil" #. ~ Description for {'str': 'Weak Photophore'} #: lang/json/mutation_from_json.py @@ -149893,52 +151399,55 @@ msgid "" "will make you very visible in the dark, ideal to attract a partner during " "mating season." msgstr "" +"Un fotĆ³foro ha crecido en tu cabeza, lo podĆ©s hacer brillar suavemente. Esto" +" te harĆ” muy visible en la oscuridad, ideal para atraer un compaƱero en la " +"temporada de apareamiento." #: lang/json/mutation_from_json.py msgid "Weak Photophore (on)" -msgstr "" +msgstr "FotĆ³foro DĆ©bil (encendido)" #. ~ Description for {'str': 'Weak Photophore (on)'} #: lang/json/mutation_from_json.py msgid "Your photophore is glowing softly." -msgstr "" +msgstr "Tu fotĆ³foro brilla suavemente." #: lang/json/mutation_from_json.py msgid "Photophore" -msgstr "" +msgstr "FotĆ³foro" #. ~ Description for {'str': 'Photophore'} #: lang/json/mutation_from_json.py msgid "You can make your photophore glow brightly." -msgstr "" +msgstr "PodĆ©s hacer brillar fuertemente a tu fotĆ³foro." #: lang/json/mutation_from_json.py msgid "Photophore (on)" -msgstr "" +msgstr "FotĆ³foro (encendido)" #. ~ Description for {'str': 'Photophore (on)'} #: lang/json/mutation_from_json.py msgid "You photophore is glowing brightly." -msgstr "" +msgstr "Tu fotĆ³foro brilla fuertemente." #: lang/json/mutation_from_json.py msgid "Normal Human" -msgstr "" +msgstr "Humano Normal" #. ~ Description for {'str': 'Normal Human'} #: lang/json/mutation_from_json.py msgid "" "You're a normal human, there's nothing wrong with you. No need to worry." -msgstr "" +msgstr "Sos un humano normal, no tenĆ©s nada raro. No necesitĆ”s preocuparte." #: lang/json/mutation_from_json.py msgid "Violent Monster" -msgstr "" +msgstr "Monstruo Violent" #. ~ Description for {'str': 'Violent Monster'} #: lang/json/mutation_from_json.py msgid "Anger clouds your mind, you can't think straight but you feel strong." -msgstr "" +msgstr "La ira te nubla la mente, no podĆ©s pensar bien pero te sentĆ­s fuerte." #: lang/json/mutation_from_json.py msgid "Good Hearing" @@ -149955,7 +151464,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Fey Hearing" -msgstr "" +msgstr "OĆ­do Fey" #. ~ Description for {'str': 'Fey Hearing'} #: lang/json/mutation_from_json.py @@ -149963,6 +151472,8 @@ msgid "" "Your not sure the shape of your ears are helping, but regardless you have " "become very sensitive to sounds." msgstr "" +"No estĆ”s seguro si es por forma la de tus orejas, pero te volviste muy " +"sensible a los sonidos." #: lang/json/mutation_from_json.py msgid "Outdoorsman" @@ -150052,6 +151563,9 @@ msgid "" "asleep and 20% faster whilst awake. Your broken limbs also heal twice as " "fast." msgstr "" +"Tus heridas se curan solas mĆ”s rĆ”pido de lo normal. Te curĆ”s 50% mĆ”s rĆ”pido " +"mientras dormĆ­s y 20% mĆ”s rĆ”pido cuando estĆ”s despierto. Tus miembros " +"fracturados tambiĆ©n sanarĆ”n al doble de velocidad." #: lang/json/mutation_from_json.py msgid "Light Eater" @@ -150194,6 +151708,9 @@ msgid "" "Your skin is tough. Cutting and bash damage is slightly reduced for you. " "There's a small chance you don't cut yourself on sharp terrain." msgstr "" +"Tu piel es resistente. El daƱo cortante y golpeante es reducido levemente. " +"Hay una pequeƱa probabilidad de que no te cortes pasando por lugares " +"filosos." #: lang/json/mutation_from_json.py msgid "Packmule" @@ -150206,6 +151723,8 @@ msgid "" "You pack things very efficiently! You can retrieve things from containers " "10% faster." msgstr "" +"Ā”GuardĆ”s las cosas de manera muy eficiente! PodĆ©s sacar cosas de los " +"recipientes 10% mĆ”s rĆ”pido." #: lang/json/mutation_from_json.py msgid "Strong Back" @@ -150238,7 +151757,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Rigid Table Manners" -msgstr "" +msgstr "Modales RĆ­gidos" #. ~ Description for {'str': 'Rigid Table Manners'} #: lang/json/mutation_from_json.py @@ -150248,6 +151767,10 @@ msgid "" "Eating without it frustrates you, but eating like a civilized person gives " "you a bigger morale bonus." msgstr "" +"Te han enseƱado cĆ³mo comportarte apropiadamente en la mesa desde tu niƱez. " +"Ahora ni se te ocurre pensar en comer sin una mesa o no tomarte tu tiempo " +"para hacerlo. Comer sin esos cuidados te frustra, pero comer como una " +"persona civilizada te da un bonus mayor a tu moral." #: lang/json/mutation_from_json.py msgid "Strong Stomach" @@ -150378,7 +151901,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Animal Kinship" -msgstr "" +msgstr "Parentesco Animal" #. ~ Description for {'str': 'Animal Kinship'} #: lang/json/mutation_from_json.py @@ -150387,6 +151910,9 @@ msgid "" " with innate trust. This only applies to natural animals such as woodland " "creatures." msgstr "" +"Algo de tu presencia calma a los animales, y te tratarĆ”n con confianza " +"innata. Esto solo se aplica a los animales naturales como las criaturas del " +"bosque." #: lang/json/mutation_from_json.py msgid "Terrifying" @@ -150472,6 +151998,9 @@ msgid "" "You can tolerate a lot more of them without overdosing, but if you indulge " "too much, you start seeing thingsā€¦" msgstr "" +"TenĆ©s una historia Ćŗnica con los estimulantes (como el cafĆ© o las " +"anfetaminas). TolerĆ”s mucho mĆ”s sin llegar a la sobredosis, pero si te " +"entregĆ”s demasiado, empezĆ”s a ver cosasā€¦" #. ~ Description for {'str': 'Stylish'} #: lang/json/mutation_from_json.py @@ -150789,6 +152318,9 @@ msgid "" "Your wounds heal a little slower than most. Your HP whilst asleep as well " "as your broken limbs heal at 75% the regular rate." msgstr "" +"Tus heridas se curan un poco mĆ”s despacio que lo normal. Tus PV mientras " +"dormĆ­s y tus miembros fracturados se curarĆ”n a un 75% de la velocidad " +"normal." #: lang/json/mutation_from_json.py msgid "Poor Healer" @@ -150801,6 +152333,9 @@ msgid "" "Your health recovery is severely impaired. Your HP whilst asleep as well as" " your broken limbs heal at 33% the regular rate." msgstr "" +"Tu recuperaciĆ³n de salud estĆ” severamente dificultada. Tus PV mientras " +"dormĆ­s y tus miembros fracturados se curarĆ”n a un 33% de la velocidad " +"normal." #: lang/json/mutation_from_json.py msgid "Imperceptive Healer" @@ -150813,6 +152348,9 @@ msgid "" "Wounds are incredibly dangerous to you, as they barely heal at all. Your HP" " whilst asleep as well as your broken limbs heal at 10% the regular rate." msgstr "" +"Las heridas son increĆ­blemente peligrosas para vos, ya que apenas si se " +"curan. Tus PV mientras dormĆ­s y tus miembros fracturados se curarĆ”n a un 10%" +" de la velocidad normal." #: lang/json/mutation_from_json.py msgid "Far-Sighted" @@ -150902,6 +152440,8 @@ msgid "" "You are terrible at organizing and storing your possessions. You retrieve " "things from containers 10% slower." msgstr "" +"Sos horrible para organizar y guardar tus posesiones. SacĆ”s las cosas de los" +" recipientes un 10% mĆ”s despacio." #: lang/json/mutation_from_json.py msgid "Illiterate" @@ -151145,7 +152685,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Trigger Happy" -msgstr "" +msgstr "Gatillo FĆ”cil" #. ~ Description for {'str': 'Trigger Happy'} #: lang/json/mutation_from_json.py @@ -151526,6 +153066,8 @@ msgid "" "Your eyes have turnedā€¦ green. It's tough to tell the exact shade as it " "seems to shift. The effect isā€¦ pleasant." msgstr "" +"Tus ojos se han vueltoā€¦ verdes. Es difĆ­cil decir exactamente de quĆ© matiz " +"son porque parecen cambiar. El efecto esā€¦ placentero." #: lang/json/mutation_from_json.py msgid "Fey Vision" @@ -151656,6 +153198,9 @@ msgid "" "Your wounds heal very quickly. You heal 50% faster whilst asleep and 66% " "faster whilst awake. Your broken limbs also heal 4 times faster than usual." msgstr "" +"Tus heridas se curan solas muy rĆ”pidamente. Te curĆ”s 50% mĆ”s rĆ”pido mientras" +" dormĆ­s y 66% mĆ”s rĆ”pido cuando estĆ”s despierto. Tus miembros fracturados " +"tambiĆ©n sanarĆ”n al cuĆ”druple de velocidad." #: lang/json/mutation_from_json.py msgid "Regeneration" @@ -151669,6 +153214,9 @@ msgid "" " whilst asleep and 200% faster whilst awake. Your broken limbs also heal 16" " times faster than usual." msgstr "" +"Tu carne se regenera de las heridas increĆ­blemente rĆ”pido. Te curĆ”s 150% mĆ”s" +" rĆ”pido mientras dormĆ­s y 200% mĆ”s rĆ”pido cuando estĆ”s despierto. Tus " +"miembros fracturados tambiĆ©n sanarĆ”n 16 veces mĆ”s rĆ”pido de lo normal." #: lang/json/mutation_from_json.py msgid "Reptilian Healing" @@ -151680,6 +153228,9 @@ msgid "" "Your broken limbs mend themselves without significant difficulty. You do " "not require splints and broken limbs heal 20 times faster than usual." msgstr "" +"Tus miembros rotos se curan solos sin mayor dificultad. No necesitĆ”s usar " +"tablillas y tus miembros fracturados sanarĆ”n 20 veces mĆ”s rĆ”pido que lo " +"normal." #: lang/json/mutation_from_json.py msgid "Very Little Sleep" @@ -152048,6 +153599,11 @@ msgid "" " Dexterity by 1 and encumbers all body parts but your eyes and mouth. " "Greatly reduces wet effects." msgstr "" +"Te ha crecido un exoesqueleto de placas rĆ­gidas y gruesas de quitina. Te " +"brinda una excelente protecciĆ³n fĆ­sica y hace tus golpes mĆ”s fuertes pero " +"reduce tu Destreza en 1 punto, y aumenta la incomodidad en todas las partes " +"de tu cuerpo, excepto los ojos y la boca. Reduce mucho los efectos de estar " +"mojado." #: lang/json/mutation_from_json.py msgid "Hairy Chitin" @@ -152142,6 +153698,8 @@ msgid "" "Some of the quills on your arms have become quite loose. By flinging your " "arms, you can fire off these quills as projectiles." msgstr "" +"Algunos de las pĆŗas en tus brazos se han aflojado. Al azotar tus brazos " +"podĆ©s arrojar estas pĆŗas como proyectiles." #: lang/json/mutation_from_json.py msgid "Phelloderm" @@ -152200,10 +153758,14 @@ msgid "" "nutrition while in sunlight when your head is uncovered. Slightly reduces " "wet effects." msgstr "" +"Todo el pelo de tu cuerpo se ha convertido en unas hojas largas como pasto. " +"AdemĆ”s de ser llamativo, te brinda una pequeƱa cuota de nutriciĆ³n mientras " +"estĆ”s al sol cuando no tenĆ©s cubierta la cabeza. Reduce un poco los efectos " +"de estar mojado." #: lang/json/mutation_from_json.py msgid "Lush Leaves" -msgstr "" +msgstr "Hojas Exuberantes" #. ~ Description for {'str': 'Lush Leaves'} #: lang/json/mutation_from_json.py @@ -152213,10 +153775,14 @@ msgid "" " photosynthesize additional nutrients while in sunlight. Reduces wet " "effects." msgstr "" +"Tus hojas han crecido en tamaƱo y prominencia, con mĆ”s hojas brotando por " +"tus brazos. Mientras tus brazos y cabeza estĆ©n sin cubrir, vas a poder " +"fotosintetizar nutrientes adicionales cuando estĆ©s a la luz del sol. Reduce " +"los efectos de estar mojado." #: lang/json/mutation_from_json.py msgid "Verdant Leaves" -msgstr "" +msgstr "Hojas Verdes" #. ~ Description for {'str': 'Verdant Leaves'} #: lang/json/mutation_from_json.py @@ -152226,10 +153792,14 @@ msgid "" " gain a large amount of nutrition by standing in the sunlight. Reduces wet " "effects." msgstr "" +"Tus hojas son verdes, vibrantes y grandes y se han vuelto una gran fuente de" +" nutrientes para tu cuerpo. Cuando tus brazos y cabeza estĆ©n descubiertos " +"ganarĆ”s una gran cantidad de nutriciĆ³n al estar parado a la luz del sol. " +"Reduce los efectos de estar mojado." #: lang/json/mutation_from_json.py msgid "Transpiration" -msgstr "" +msgstr "TranspiraciĆ³n" #. ~ Description for {'str': 'Transpiration'} #: lang/json/mutation_from_json.py @@ -152237,6 +153807,9 @@ msgid "" "You body has begun moving nutrients via the evaporation of water. This " "increases your thirst when it's hot, but reduces it when it's cold." msgstr "" +"Tu cuerpo ha comenzado a mover los nutrientes a travĆ©s de la evaporaciĆ³n del" +" agua. Esto incrementa tu sed cuando hace calor, pero la reduce cuando hace " +"frĆ­o." #: lang/json/mutation_from_json.py msgid "Flowering" @@ -152253,7 +153826,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Rosebuds" -msgstr "" +msgstr "Pimpollos" #. ~ Description for {'str': 'Rosebuds'} #: lang/json/mutation_from_json.py @@ -152261,6 +153834,8 @@ msgid "" "The top of your head is blooming with rosebuds. They're eye catching, and " "have a strong fragrance that makes you pleasant to be around." msgstr "" +"La parte superior de tu cabeza estĆ” llena de pimpollos. Son vistosos y tiene" +" una fragancia fuerte que te hace placentero de tenerte al lado." #: lang/json/mutation_from_json.py msgid "Mycus Spores" @@ -152396,12 +153971,12 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Extended Claws" -msgstr "" +msgstr "Garras Extendidas" #. ~ Description for {'str': 'Extended Claws'} #: lang/json/mutation_from_json.py msgid "Sharp claws are exten from the end of your fingers." -msgstr "" +msgstr "Unas garras filosas se extienden de la punta de tus dedos." #: lang/json/mutation_from_json.py msgid "Tentacle Rakes" @@ -152419,7 +153994,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Ink glands" -msgstr "" +msgstr "GlĆ”ndulas de tinta" #. ~ Description for Ink glands #: lang/json/mutation_from_json.py @@ -152428,6 +154003,9 @@ msgid "" "defensive ink and blind an attacker in an emergency, as long as the torso " "isn't covered." msgstr "" +"Varias glĆ”ndulas de tinta te han crecido en el torso. Pueden usarse para " +"lanzar una tinta defensiva y enceguecer al atacante en una emergencia, " +"siempre que el torso estĆ© descubierto." #: lang/json/mutation_from_json.py msgid "Large Talons" @@ -152467,6 +154045,8 @@ msgid "" "Ever since you ate that Marloss berry, you can't get its scent out of your " "nose, and you have a strong desire to try some seeds andā€¦ sap?" msgstr "" +"Desde que comiste esas bayas Marloss, no te podĆ©s sacar su olor de la nariz," +" y tenĆ©s como un fuerte deseo de probar semillas yā€¦ Āæsavia?" #: lang/json/mutation_from_json.py msgid "Marloss Vessel" @@ -152478,6 +154058,8 @@ msgid "" "Ever since you ate that Marloss seed, you can't get its taste off of your " "tongue, and you have a strong desire to try some berries andā€¦ sap?" msgstr "" +"Desde que comiste esas semillas de Marloss, no te podĆ©s sacar su gusto de la" +" lengua, y tenĆ©s como un fuerte deseo de probar unas bayas yā€¦ Āæsavia?" #: lang/json/mutation_from_json.py msgid "Marloss Vector" @@ -152946,6 +154528,9 @@ msgid "" "impossible to wear mouthgear and difficult to eatā€¦ but leave nasty wounds " "when you bite." msgstr "" +"Tus colmillos han crecido extremadamente grandes e increĆ­blemente afilados. " +"Te va a ser imposible usar equipo que cubre tu boca, y te resultarĆ” difĆ­cil " +"comerā€¦ pero dejĆ”s unas horribles heridas cuando mordĆ©s." #: lang/json/mutation_from_json.py #, no-python-format @@ -152983,7 +154568,7 @@ msgid "" "piercing headbutt attack." msgstr "" "TenĆ©s un par de pequeƱos cuernos en la cabeza. Te permiten causar un poco de" -" daƱo penetrante con tu cabezazo." +" daƱo punzante con tu cabezazo." #: lang/json/mutation_from_json.py #, no-python-format @@ -153031,7 +154616,7 @@ msgid "" "headwear that is not made of fabric." msgstr "" "TenĆ©s un par de cuernos largos y puntiagudos, como los de un antĆ­lope. Te " -"permiten causar mucho daƱo penetrante con tus cabezazos, pero te impiden " +"permiten causar mucho daƱo punzante con tus cabezazos, pero te impiden " "utilizar equipo en la cabeza que no sea de tela." #: lang/json/mutation_from_json.py @@ -153232,6 +154817,9 @@ msgid "" "your balance at all, but allows for a powerful piercing attack. Prevents " "wearing non-fabric pants." msgstr "" +"TenĆ©s una cola larga que termina con un feroz aguijĆ³n. No te mejora el " +"balance para nada, pero te permite tener un poderoso ataque punzante. No te " +"permite utilizar pantalones que no sean de tela." #: lang/json/mutation_from_json.py #, no-python-format @@ -154379,6 +155967,8 @@ msgid "" "Your face and jaw have begunā€¦ changing. Masks and such fit OK, but you're " "noticeably mutated." msgstr "" +"Tu cara y mandĆ­bula han empezado aā€¦ cambiar. Las mĆ”scaras te quedan bien, " +"pero se te nota la mutaciĆ³n." #: lang/json/mutation_from_json.py msgid "Bovine Snout" @@ -154390,8 +155980,8 @@ msgid "" "Your face resembles that of a bull, with a significant snout. It looks " "fearsome but prevents wearing mouthgear." msgstr "" -"Tu cara recuerda a la de un toro, con un hocico importante. Parece temible " -"pero te impide usar cosas sobre la boca." +"Tu cara parece la de un toro, con un hocico importante. Parece temible pero " +"te impide usar cosas sobre la boca." #: lang/json/mutation_from_json.py msgid "Lupine Muzzle" @@ -154964,6 +156554,9 @@ msgid "" "to be moving around, and your leg-equivalents flow comfortably - if a little" " slower than your old meat-legs." msgstr "" +"Tu carne tiene un agradable consistencia similar al gel. Tus funciones " +"corporales parecen estar moviĆ©ndose, y lo que serĆ­an tus piernas fluyen " +"cĆ³modamente - aunque un poco mĆ”s lentas que tus viejas piernas de carne." #: lang/json/mutation_from_json.py msgid "Omnicellular" @@ -155003,6 +156596,8 @@ msgid "" "Your body's ability to digest fruits, vegetables, grains and nuts is " "severely hampered. You cannot eat anything besides meat." msgstr "" +"La capacidad de tu cuerpo para digerir frutas, verduras, granos y frutos " +"secos estĆ” muy limitada. No podĆ©s comer nada que no sea carne." #: lang/json/mutation_from_json.py msgid "Ponderous" @@ -155110,7 +156705,7 @@ msgstr "Te sacĆ”s una liana de tu cuerpo." #: lang/json/mutation_from_json.py msgid "Hair Roots" -msgstr "" +msgstr "Pelos Absorbentes" #. ~ Description for {'str': 'Hair Roots'} #: lang/json/mutation_from_json.py @@ -155118,6 +156713,8 @@ msgid "" "Roots have started growing from your leaf like hair, they don't seem to do " "much." msgstr "" +"Unas raĆ­ces han comenzado a crecer desde tus hojas como pelos, pero no " +"parecen servir para nada." #: lang/json/mutation_from_json.py msgid "Toe Roots" @@ -155180,7 +156777,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Mycorrhizal Communion" -msgstr "" +msgstr "ComuniĆ³n Micorrizal" #. ~ Description for {'str': 'Mycorrhizal Communion'} #: lang/json/mutation_from_json.py @@ -155189,6 +156786,9 @@ msgid "" "ancient wisdom. Activate next to a tree to gradually gain overmap vision " "through connected forests." msgstr "" +"Has recibido la habilidad de comunicarte con los Ć”rboles y comprender su " +"antigua sabidurĆ­a. Activala al lado de un Ć”rbol para ganar gradualmente " +"visiĆ³n en el mapa general a travĆ©s de los bosques conectados." #: lang/json/mutation_from_json.py msgid "Heat Dependent" @@ -155250,6 +156850,10 @@ msgid "" "1% for every 2 (1.1) degrees below or above 65 F (18.3 C). You only need to" " eat half as much as an average human." msgstr "" +"Ahora tu cuerpo se ha vuelto permanentemente de sangre frĆ­a. Tu velocidad " +"disminuye o aumenta un 1% por cada 1.1 C grados (2 F) por debajo o por " +"encima de 18.3 C (65 F). Solo necesitĆ”s comer la mitad de lo que come un " +"humano promedio." #: lang/json/mutation_from_json.py msgid "Growling Voice" @@ -155595,6 +157199,8 @@ msgid "" "It would be good to be a Queen, having workers constantly servicing your " "every needā€¦ but how would you keep them in line?" msgstr "" +"EstarĆ­a bueno ser Reina, tener a los obreros constantemente a tu servicioā€¦ " +"pero ĀæcĆ³mo hacĆ©s para mantenerlos controlados?" #. ~ Description for {'str': 'Plant'} #: lang/json/mutation_from_json.py @@ -155615,6 +157221,8 @@ msgid "" "What was that old advertisement, 'paint the planet'? That might be a good " "long-term goal, but for nowā€¦" msgstr "" +"ĀæCĆ³mo era esa publicidad vieja, 'pintar el planeta'? Eso puede ser un buen " +"objetivo a largo plazo, pero por ahoraā€¦" #: lang/json/mutation_from_json.py msgid "Subterranean" @@ -155920,17 +157528,6 @@ msgstr "" "de New England, gracias a los acuerdos interestatales. Que esto signifique " "algo ahora, eso ya es otra cosa." -#: lang/json/mutation_from_json.py -msgid "Helicopter Pilot" -msgstr "" - -#. ~ Description for Helicopter Pilot -#: lang/json/mutation_from_json.py -msgid "" -"You are a trained helicopter pilot. This makes you one of the few living " -"people who can operate a helicopter after the Cataclysm." -msgstr "" - #: lang/json/mutation_from_json.py msgid "SWAT Officer" msgstr "Agente de SWAT" @@ -156004,7 +157601,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "True Foodperson" -msgstr "" +msgstr "Foodperson Verdadera" #. ~ Description for {'str': 'True Foodperson'} #: lang/json/mutation_from_json.py @@ -156014,6 +157611,10 @@ msgid "" " are real and the only thing standing between this world and oblivion is " "you." msgstr "" +"Sos una verdadera Foodperson, algunos pueden pensar que Foodperson es solo " +"una mascota, pero vos tenĆ©s mĆ”s conocimiento. Sos una Foodperson, esta " +"mĆ”scara se ha vuelto tu cara, sos real y la Ćŗnica cosa parada entre este " +"mundo y el olvido sos vos." #. ~ Description for {'str': 'MD'} #: lang/json/mutation_from_json.py @@ -156037,6 +157638,9 @@ msgid "" " and are less likely to fall down if hit in melee combat while you're " "wearing rollerskates or rollerblades." msgstr "" +"Sos habilidoso para maniobrar sobre patines. SufrĆ­s menos penalidades a " +"esquivar y es menos probable que te caigas al suelo si te golpean en un " +"combate cuerpo a cuerpo mientras tenĆ©s puestos patines o rollers." #: lang/json/mutation_from_json.py msgid "Martial Artist" @@ -156379,10 +157983,12 @@ msgid "" "You're too adventurous for your own good. The more time you spend " "somewhere, the unhappier it makes you to be there." msgstr "" +"Sos demasiado aventurero incluso para tu propio bien. Cuanto mĆ”s tiempo " +"pasĆ”s en un lugar, menos feliz te volvĆ©s." #: lang/json/mutation_from_json.py msgid "Antsy" -msgstr "" +msgstr "Ansioso" #. ~ Description for {'str': 'Antsy'} #: lang/json/mutation_from_json.py @@ -156390,10 +157996,12 @@ msgid "" "You can't bear to stay still for long. Your morale will suffer unless you " "constantly explore new territory." msgstr "" +"No aguantĆ”s estar quieto por mucho tiempo. Tu moral sufrirĆ” a menos que " +"estĆ©s constantemente explorando territorio nuevo." #: lang/json/mutation_from_json.py msgid "Restless" -msgstr "" +msgstr "Inquieto" #. ~ Description for {'str': 'Restless'} #: lang/json/mutation_from_json.py @@ -156401,10 +158009,12 @@ msgid "" "Spending any amount of time in familiar places makes you miserable. Must. " "Keep. Moving." msgstr "" +"Pasar una cantidad de tiempo en lugares conocidos te hace sentir miserable. " +"Debes. Seguir. MoviĆ©ndote." #: lang/json/mutation_from_json.py msgid "Wayfarer" -msgstr "" +msgstr "Caminante" #. ~ Description for {'str': 'Wayfarer'} #: lang/json/mutation_from_json.py @@ -156412,20 +158022,24 @@ msgid "" "Whether from personal choice or childhood trauma, traveling with vehicles is" " off-limits to you, even if your life depended on it." msgstr "" +"Ya sea por elecciĆ³n personal o por un trauma de la infancia, viajar dentro " +"de vehĆ­culos te estĆ” prohibido, incluso aunque tu vida dependa de eso." #: lang/json/mutation_from_json.py msgid "Fast Reflexes" -msgstr "" +msgstr "Reflejos RĆ”pidos" #. ~ Description for {'str': 'Fast Reflexes'} #: lang/json/mutation_from_json.py msgid "" "You have fast reflexes, allowing you to dodge attacks and grabs more easily." msgstr "" +"Tenes reflejos rĆ”pidos, lo que te permite esquivar mĆ”s fĆ”cilmente ataques y " +"agarres." #: lang/json/mutation_from_json.py msgid "Survivor: Confused 1" -msgstr "" +msgstr "Sobreviviente: Confundido 1" #. ~ Description for {'str': 'Survivor: Confused 1'} #. ~ Description for {'str': 'Survivor: No Past 1'} @@ -156452,83 +158066,83 @@ msgstr "" #. ~ Description for {'str': 'Survivor Story'} #: lang/json/mutation_from_json.py msgid "This NPC could tell you about how they survived the Cataclysm" -msgstr "" +msgstr "Este PNJ podrĆ­a contarte cĆ³mo sobreviviĆ³ al Cataclismo" #: lang/json/mutation_from_json.py msgid "Survivor: No Past 1" -msgstr "" +msgstr "Sobreviviente: Sin Pasado 1" #: lang/json/mutation_from_json.py msgid "Survivor: No Past 2" -msgstr "" +msgstr "Sobreviviente: Sin Pasado 2" #: lang/json/mutation_from_json.py msgid "Survivor: No Past 3" -msgstr "" +msgstr "Sobreviviente: Sin Pasado 3" #: lang/json/mutation_from_json.py msgid "Survivor: No Past 4" -msgstr "" +msgstr "Sobreviviente: Sin Pasado 4" #: lang/json/mutation_from_json.py msgid "Survivor: No Past 5" -msgstr "" +msgstr "Sobreviviente: Sin Pasado 5" #: lang/json/mutation_from_json.py msgid "Survivor: Religious 1" -msgstr "" +msgstr "Sobreviviente: Religioso 1" #: lang/json/mutation_from_json.py msgid "Survivor: Religious 2" -msgstr "" +msgstr "Sobreviviente: Religioso 2" #: lang/json/mutation_from_json.py msgid "Survivor: Dreamer 1" -msgstr "" +msgstr "Sobreviviente: SoƱador 1" #: lang/json/mutation_from_json.py msgid "Survivor: Wedding 1" -msgstr "" +msgstr "Sobreviviente: Casamiento 1" #: lang/json/mutation_from_json.py msgid "Survivor: Evacuee 1" -msgstr "" +msgstr "Sobreviviente: Evacuado 1" #: lang/json/mutation_from_json.py msgid "Survivor: Evacuee 2" -msgstr "" +msgstr "Sobreviviente: Evacuado 2" #: lang/json/mutation_from_json.py msgid "Survivor: Evacuee 3" -msgstr "" +msgstr "Sobreviviente: Evacuado 3" #: lang/json/mutation_from_json.py msgid "Survivor: Evacuee 4" -msgstr "" +msgstr "Sobreviviente: Evacuado 4" #: lang/json/mutation_from_json.py msgid "Survivor: Evacuee 5" -msgstr "" +msgstr "Sobreviviente: Evacuado 5" #: lang/json/mutation_from_json.py msgid "Survivor: Evacuee 6" -msgstr "" +msgstr "Sobreviviente: Evacuado 6" #: lang/json/mutation_from_json.py msgid "Survivor: FEMA Evacuee 1" -msgstr "" +msgstr "Sobreviviente: Evacuado FEMA 1" #: lang/json/mutation_from_json.py msgid "Survivor: Left for Dead 1" -msgstr "" +msgstr "Sobreviviente: Dado por Muerto 1" #: lang/json/mutation_from_json.py msgid "Survivor: Left for Dead 2" -msgstr "" +msgstr "Sobreviviente: Dado por Muerto 2" #: lang/json/mutation_from_json.py msgid "Survivor: Left for Dead 3" -msgstr "" +msgstr "Sobreviviente: Dado por Muerto 3" #: lang/json/mutation_from_json.py msgid "Survivor Story" @@ -156536,12 +158150,13 @@ msgstr "Historia de Superviviente" #: lang/json/mutation_from_json.py msgid "Mark of the Seer" -msgstr "" +msgstr "Marca del Vidente" #. ~ Description for {'str': 'Mark of the Seer'} #: lang/json/mutation_from_json.py msgid "A strange occult symbol carved into your hand by Brigitte LaCroix." msgstr "" +"Un extraƱo sĆ­mbolo mĆ­stico estĆ” tallado en tu mano por Brigitte LaCroix." #: lang/json/mutation_from_json.py msgid "Agriculture Training" @@ -157048,7 +158663,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Killophant" -msgstr "" +msgstr "Asesifante" #. ~ Description for {'str': 'Killophant'} #: lang/json/mutation_from_json.py @@ -157056,10 +158671,12 @@ msgid "" "Your species was created as the ultimate shock troop. Inherit the earth, " "pedigree your ancestors, crush the foe." msgstr "" +"Tu especie fue creada como la mĆ”xima tropa de asalto. Heredar la tierra, " +"linaje de tus ancestros, aplastar al enemigo." #: lang/json/mutation_from_json.py msgid "Mi-go acclimatization" -msgstr "" +msgstr "AclimataciĆ³n mi-go" #. ~ Description for Mi-go acclimatization #: lang/json/mutation_from_json.py @@ -157067,42 +158684,47 @@ msgid "" "Fleshy fronds grown from your scalp function like organic heat sinks. They " "allow you to live comfortably within the mi-go atmosphere." msgstr "" +"Unas hojas nuevas han crecido en tu cuero cabelludo que funcionan como " +"disipadores de calor orgĆ”nicos. Te permiten vivir cĆ³modamente dentro de una " +"atmĆ³sfera mi-go." #: lang/json/mutation_from_json.py msgid "Facial Tentacles" -msgstr "" +msgstr "TentĆ”culos Faciales" #: lang/json/mutation_from_json.py msgid "Mouth Tendrils" -msgstr "" +msgstr "Zarcillos Bucales" #: lang/json/mutation_from_json.py msgid "Warm Natured" -msgstr "" +msgstr "Naturaleza Tibia" #. ~ Description for Warm Natured #: lang/json/mutation_from_json.py msgid "" "Your body becomes much more efficient at distributing heat from itself." msgstr "" +"Tu cuerpo se vuelve mucho mĆ”s eficiente para distribuir el calor por sĆ­ " +"mismo." #: lang/json/mutation_from_json.py msgid "Neural Improvement" -msgstr "" +msgstr "Mejora Neuronal" #. ~ Description for Neural Improvement #: lang/json/mutation_from_json.py msgid "You see the world a little differently today. Intelligence + 1" -msgstr "" +msgstr "Ves el mundo un poco diferente hoy. Inteligencia +1" #: lang/json/mutation_from_json.py msgid "Expanded Consciousness" -msgstr "" +msgstr "Consciencia Expandida" #. ~ Description for Expanded Consciousness #: lang/json/mutation_from_json.py msgid "You are beginning to see a way off this planet. Intelligence + 2" -msgstr "" +msgstr "Comenzaste a ver un camino fuera de este planeta. Inteligencia +2." #. ~ Description for Extremely Smart #: lang/json/mutation_from_json.py @@ -157110,10 +158732,12 @@ msgid "" "As humans uplifted our pets in the final years this process is lifting you " "to a new level of intelligence. Intelligence + 4" msgstr "" +"Como los humanos elevaron a nuestras mascotas en los Ćŗltimos aƱos, este " +"proceso te elevarĆ” a vos a un nivel nuevo de inteligencia. Inteligencia +4." #: lang/json/mutation_from_json.py msgid "Alien Intelligence" -msgstr "" +msgstr "Inteligencia AlienĆ­gena" #. ~ Description for Alien Intelligence #: lang/json/mutation_from_json.py @@ -157121,28 +158745,30 @@ msgid "" "You can see the connections from A to B to C to D. You look at fellow " "survivors like you are imagining taking them apart. Intelligence + 5" msgstr "" +"PodĆ©s ver las conexiones entre A y B y C y D. Ves a tus compaƱeros " +"sobrevivientes como si los imaginaras desarmĆ”ndolos. Inteligencia +5." #: lang/json/mutation_from_json.py msgid "Enhanced Reactions" -msgstr "" +msgstr "Reacciones Mejoradas" #. ~ Description for Enhanced Reactions #: lang/json/mutation_from_json.py msgid "Today is the day to start juggling. Dexterity + 1" -msgstr "" +msgstr "Hoy es el dĆ­a para empezar a hacer malabares. Destreza +1." #: lang/json/mutation_from_json.py msgid "Quickening" -msgstr "" +msgstr "Acelerad" #. ~ Description for Quickening #: lang/json/mutation_from_json.py msgid "You are starting to move like they do. Dexterity + 2" -msgstr "" +msgstr "Te empezaste a mover como lo hacen ellos. Destreza +2." #: lang/json/mutation_from_json.py msgid "Otherworldly Grace" -msgstr "" +msgstr "Gracia Sobrenatural" #. ~ Description for Otherworldly Grace #: lang/json/mutation_from_json.py @@ -157150,10 +158776,11 @@ msgid "" "You no longer move like a human, others find it disconcerting. Dexterity + " "4" msgstr "" +"Ya no te movĆ©s como un humano, a los otros los desconcertĆ”s. Destreza +4." #: lang/json/mutation_from_json.py msgid "New Muscles" -msgstr "" +msgstr "MĆŗsculos Nuevos" #. ~ Description for New Muscles #: lang/json/mutation_from_json.py @@ -157161,19 +158788,22 @@ msgid "" "You see some new muscles that you aren't sure you've seen on humans before." " Strength + 1" msgstr "" +"Ves algunos mĆŗsculos nuevos que no estĆ”s seguro haber visto antes en " +"humanos. Fuerza +1." #: lang/json/mutation_from_json.py msgid "Muscle Fiber" -msgstr "" +msgstr "Fibra Muscular" #. ~ Description for Muscle Fiber #: lang/json/mutation_from_json.py msgid "Fibrous tissue seems to be spreading through your body. Strength + 2" msgstr "" +"El tejido fibroso parece estar esparciĆ©ndose por tu cuerpo. Fuerza +2." #: lang/json/mutation_from_json.py msgid "Mi-go Ears" -msgstr "" +msgstr "Orejas Mi-go" #. ~ Description for Mi-go Ears #: lang/json/mutation_from_json.py @@ -157181,10 +158811,12 @@ msgid "" "Your ears have split into a series of tuberous projections. They waggle " "towards far away sounds." msgstr "" +"Tus orejas se han dividido en varias series de proyecciones tuberosos. Se " +"menea hacia los sonidos lejanos." #: lang/json/mutation_from_json.py msgid "Detachment" -msgstr "" +msgstr "Indiferencia" #. ~ Description for Detachment #: lang/json/mutation_from_json.py @@ -157192,6 +158824,8 @@ msgid "" "When were you ever like these creatures, helpless before the changes " "ravaging this world. " msgstr "" +"CuĆ”ndo fuiste como estas criaturas, indefensas ante los cambios devastadores" +" de este mundo." #: lang/json/mutation_from_json.py src/artifact.cpp msgid "Eldritch" @@ -157204,15 +158838,21 @@ msgid "" "You feel no sorrow at the deaths of humans and your brain now processes " "combat skills more efficiently as you mentally dissect your opponents." msgstr "" +"Tenes el aspecto siniestro de tu comportamiento, ya ajeno a este mundo. No " +"sentĆ­s pena por las muertes de los humanos y tu cerebro ahora procesa " +"habilidades de combate mĆ”s eficientes mientras diseccionĆ”s mentalmente a tus" +" oponentes." #. ~ Description for YUGGOTH #: lang/json/mutation_from_json.py msgid "This death throes of this world are the birthing pangs of yours." msgstr "" +"Estas agonĆ­as de muerte de este mundo son las contracciones de nacimiento " +"del tuyo." #: lang/json/mutation_from_json.py msgid "Fetid scent" -msgstr "" +msgstr "Aroma FĆ©tido" #. ~ Description for Fetid scent #: lang/json/mutation_from_json.py @@ -157220,10 +158860,12 @@ msgid "" "Your sweat now smells otherworldly, and not in a good way. The mi-go still " "hate you but at least they aren't offended by your smell. " msgstr "" +"Tu transpiraciĆ³n ahora tiene un olor sobrenatural, y no de buena manera. Los" +" mi-go te siguen odiando pero por lo menos no estĆ”n ofendidos por tu olor." #: lang/json/mutation_from_json.py msgid "Eerie" -msgstr "" +msgstr "Escalofriante" #. ~ Description for Eerie #: lang/json/mutation_from_json.py @@ -157231,10 +158873,12 @@ msgid "" "You are offputting to others. You're mannerisms have changed as if human " "interaction is becoming foreign." msgstr "" +"Sos repulsivo para los demĆ”s. Tus maneras han cambiado como si la " +"interacciĆ³n humana se te hubiera hecho desconocida." #: lang/json/mutation_from_json.py msgid "Mi-go Wings" -msgstr "" +msgstr "Alas Mi-go" #. ~ Description for Mi-go Wings #: lang/json/mutation_from_json.py @@ -157242,29 +158886,32 @@ msgid "" "You have a pair of large, veiny wings. They don't appear to be made for " "this atmosphere but they grant a powerful buffeting attack." msgstr "" +"TenĆ©s un par de alas grandes y venosas. No parecen estar hechas para esta " +"atmĆ³sfera pero te permiten un poderoso cacheteo." #: lang/json/mutation_from_json.py #, no-python-format msgid "You buffet %s with your wings" -msgstr "" +msgstr "CacheteĆ”s al %s con tus alas" #: lang/json/mutation_from_json.py #, no-python-format msgid "%1$s buffets %2$s with their wings" -msgstr "" +msgstr "%1$s cachetea al %2$s con sus alas" #: lang/json/mutation_from_json.py msgid "Mi-go breathe" -msgstr "" +msgstr "RespiraciĆ³n Mi-go" #. ~ Description for Mi-go breathe #: lang/json/mutation_from_json.py msgid "You can now breathe the gasses the mi-go thrive in." msgstr "" +"Ahora podĆ©s respirar los gases en los cuales se desarrollan los mi-go." #: lang/json/mutation_from_json.py msgid "Uplifted" -msgstr "" +msgstr "Elevado" #. ~ Description for Uplifted #: lang/json/mutation_from_json.py @@ -157272,10 +158919,12 @@ msgid "" "You come from uplifted animal stock. This decreases morale penalties for " "being wet." msgstr "" +"Has salido elevado del ganado. Esto hace que sea menor la penalidad a la " +"moral por estar mojado." #: lang/json/mutation_from_json.py msgid "Hauler" -msgstr "" +msgstr "Acarreador" #. ~ Description for Hauler #: lang/json/mutation_from_json.py @@ -157284,10 +158933,12 @@ msgid "" "You are capable of carrying far more than someone with similar strength " "could. Your maximum weight carried is increased by 60%." msgstr "" +"Sos capaz de cargar mucho mĆ”s que una persona con fuerza similar. Tu mĆ”xima " +"carga posible estĆ” incrementada en un 60%." #: lang/json/mutation_from_json.py msgid "Patched Fur" -msgstr "" +msgstr "Parches de Piel" #. ~ Description for Patched Fur #: lang/json/mutation_from_json.py @@ -157295,10 +158946,12 @@ msgid "" "Your skin has patches of light fur. This has no impact on your life except " "marking you as not fully human." msgstr "" +"Tu piel tiene pedazos de pelaje tenue. Esto no tiene impacto en tu vida " +"excepto marcarte como no completamente humano." #: lang/json/mutation_from_json.py msgid "Crushing Feet" -msgstr "" +msgstr "Pies Destrozadores" #. ~ Description for Crushing Feet #: lang/json/mutation_from_json.py @@ -157308,30 +158961,37 @@ msgid "" "the need to wear shoes; however, you cannot wear normal size shoes. Reduces" " wet effects." msgstr "" +"Tus pies han crecido enormemente y estĆ”n preparados para aguantar un peso " +"enorme. Esto te permite pegar patadas para hacer mucho daƱo, te brinda " +"armadura natural, y te quita la necesidad de usar calzado. Sin embargo, no " +"vas a poder usar calzado de tamaƱo normal. Disminuye los efectos de estar " +"mojado." #: lang/json/mutation_from_json.py #, no-python-format msgid "You kick %s with your massive feet" -msgstr "" +msgstr "PateĆ”s al %s con tus enormes pies" #: lang/json/mutation_from_json.py #, no-python-format msgid "%1$s kicks %2$s with their massive feet" -msgstr "" +msgstr "%1$s patea al %2$s con sus enormes pies" #: lang/json/mutation_from_json.py msgid "Face Bumps" -msgstr "" +msgstr "Protuberancias Faciales" #. ~ Description for Face Bumps #: lang/json/mutation_from_json.py msgid "" "You have a pair of bumps on your face above your mouth and beside your nose." msgstr "" +"TenĆ©s un par de protuberancias en tu cara sobre tu boca y a los costados de " +"tu nariz." #: lang/json/mutation_from_json.py msgid "Tusks" -msgstr "" +msgstr "Colmillos Largos" #. ~ Description for Tusks #: lang/json/mutation_from_json.py @@ -157339,20 +158999,22 @@ msgid "" "You have a pair of small tusks on your face. They allow you to make a weak " "piercing goring attack." msgstr "" +"TenĆ©s un par de pequeƱos colmillos como los de un elefante en la cara. Te " +"permiten causar un poco de daƱo punzante corneando." #: lang/json/mutation_from_json.py #, no-python-format msgid "You gore %s with your tusks" -msgstr "" +msgstr "DestripĆ”s al %s con tus colmillos" #: lang/json/mutation_from_json.py #, no-python-format msgid "%1$s gores %2$s with their tusks" -msgstr "" +msgstr "%1$s destripa al %2$s con sus colmillos" #: lang/json/mutation_from_json.py msgid "Pointed Tusks" -msgstr "" +msgstr "Colmillos Puntiagudos" #. ~ Description for Pointed Tusks #: lang/json/mutation_from_json.py @@ -157361,20 +159023,23 @@ msgid "" " They allow you to make a strong piercing headbutt attack, but prevent " "wearing mouthgear that is not made of fabric." msgstr "" +"TenĆ©s un par de colmillos largos y puntiagudos, como los de un elefante. Te " +"permiten causar mucho daƱo punzante con tus cabezazos, pero te impiden " +"utilizar equipamiento en la boca que no sea de tela." #: lang/json/mutation_from_json.py #, no-python-format msgid "You stab %s with your pointed tusks" -msgstr "" +msgstr "ApuƱalĆ”s al %s con tus colmillos puntiagudos" #: lang/json/mutation_from_json.py #, no-python-format msgid "%1$s stabs %2$s with their pointed tusks" -msgstr "" +msgstr "%1$s apuƱala al %2$s con sus colmillos puntiagudos" #: lang/json/mutation_from_json.py msgid "Elephant Trunk" -msgstr "" +msgstr "Trompa de Elefante" #. ~ Description for {'str': 'Elephant Trunk'} #: lang/json/mutation_from_json.py @@ -157383,10 +159048,13 @@ msgid "" " fierce but prevents wearing mouthgear. Prehensile and able to perform some" " fine detail work." msgstr "" +"Tu cara parece la de un elefante, con la significativa trompa. Parece " +"temible pero te impide usar equipamiento en la boca. Es prensil y capaz de " +"hacer algĆŗn trabajo fino." #: lang/json/mutation_from_json.py msgid "Three Fingered" -msgstr "" +msgstr "Tres Dedos" #. ~ Description for Three Fingered #: lang/json/mutation_from_json.py @@ -157395,10 +159063,14 @@ msgid "" "challenge: permanent hand encumbrance of 10, difficulty with delicate " "craftwork, and your gloves don't fit. But they handle water better." msgstr "" +"Tus manos se han fusionado en patas de tres dedos. Se te complica la " +"motricidad fina: tenĆ©s una incomodidad de 10 permanente en las manos, es " +"difĆ­cil la fabricaciĆ³n de cosas delicadas, y no entran los guantes. Pero se " +"manejan mejor en el agua." #: lang/json/mutation_from_json.py msgid "Trumpeting Voice" -msgstr "" +msgstr "Voz de Trompeta" #. ~ Description for Trumpeting Voice #: lang/json/mutation_from_json.py @@ -157406,19 +159078,22 @@ msgid "" "You have a trumpeting elephantine voice. threatening NPCs will be easier, " "but lying will very hard." msgstr "" +"TenĆ©s una voz de trompeta como un elefante. Te resulta mĆ”s fĆ”cil amenazar a " +"los PNJ, pero es muy difĆ­cil mentir." #: lang/json/mutation_from_json.py msgid "Brutal Strength" -msgstr "" +msgstr "Fuerza Brutal" #. ~ Description for {'str': 'Brutal Strength'} #: lang/json/mutation_from_json.py msgid "Genetic tampering made your body incredibly strong. Strength + 7." msgstr "" +"La manipulaciĆ³n genĆ©tica hizo tu cuerpo increĆ­blemente fuerte. Fuerza +7." #: lang/json/mutation_from_json.py msgid "Cryoadaptation" -msgstr "" +msgstr "CrioadaptaciĆ³n" #. ~ Description for {'str': 'Cryoadaptation'} #: lang/json/mutation_from_json.py @@ -157426,10 +159101,12 @@ msgid "" "An experimental cryosleep procedure has permanently altered your body, " "allowing you to better tolerate cold temperatures." msgstr "" +"Un procedimiento experimental de criosueƱo ha alterado permanentemente tu " +"cuerpo, permitiĆ©ndote tolerar mejor las temperaturas frĆ­as." #: lang/json/mutation_from_json.py msgid "Alpine Conditioning" -msgstr "" +msgstr "CondiciĆ³n Alpina" #. ~ Description for {'str': 'Alpine Conditioning'} #: lang/json/mutation_from_json.py @@ -157437,15 +159114,18 @@ msgid "" "Time spent in high altitudes and low temperatures have adapted you to them, " "and you're slightly better at resisting the cold." msgstr "" +"El tiempo pasado en las alturas y bajas temperaturas te han adaptado a " +"ellas, y sos un poco mejor resistiendo el frĆ­o." #. ~ Description for {'str': 'Brutal Strength'} #: lang/json/mutation_from_json.py msgid "Genetic defects have made your body incredibly strong. Strength + 7." msgstr "" +"Los defectos genĆ©ticos hicieron tu cuerpo increĆ­blemente fuerte. Fuerza +7." #: lang/json/mutation_from_json.py msgid "Leathered Feet" -msgstr "" +msgstr "Pie Ɓspero" #. ~ Description for Leathered Feet #: lang/json/mutation_from_json.py @@ -157453,10 +159133,12 @@ msgid "" "The bottoms of your feet are tough like an animals. You receive no movement" " penalty for not wearing shoes." msgstr "" +"Las plantas de tus pies son resistentes como las de los animales. Si no usĆ”s" +" nada en los pies, no se te aplica ninguna penalidad." #: lang/json/mutation_from_json.py msgid "Skinfolds" -msgstr "" +msgstr "Pliegues CutĆ”neos" #. ~ Description for Skinfolds #: lang/json/mutation_from_json.py @@ -157469,7 +159151,7 @@ msgstr "" #: lang/json/mutation_from_json.py msgid "Weak Joints" -msgstr "" +msgstr "Articulaciones FrĆ”giles" #. ~ Description for {'str': 'Weak Joints'} #: lang/json/mutation_from_json.py @@ -157477,10 +159159,13 @@ msgid "" "A common flaw in your genemod, brought on by increased muscle mass and bone " "density. Moving over rough terrain will slow you down more than normal." msgstr "" +"Es un defecto comĆŗn en tu modificaciĆ³n genĆ©tica, causado al incrementar la " +"masa muscular y la densidad Ć³sea. Atravesar terreno duro te hace mĆ”s lento, " +"mĆ”s que lo normal." #: lang/json/mutation_from_json.py msgid "Herbivorous Ancestry" -msgstr "" +msgstr "Linaje HerbĆ­voro" #. ~ Description for Strong Scent #: lang/json/mutation_from_json.py @@ -157488,14 +159173,16 @@ msgid "" "Your scent is particularly strong. It's vaguely offensive to humans, and " "animals that track your scent will do so more easily." msgstr "" +"Tu olor es particularmente fuerte. Es un poco ofensivo para los humanos, y " +"los animales que te rastrean por tu olor lo harĆ”n mĆ”s fĆ”cilmente." #: lang/json/mutation_from_json.py msgid "Giant Step" -msgstr "" +msgstr "Paso Gigante" #: lang/json/mutation_from_json.py msgid "Slow and Steady" -msgstr "" +msgstr "Lento y Firme" #. ~ Description for Slow and Steady #: lang/json/mutation_from_json.py @@ -157504,10 +159191,12 @@ msgid "" "You can't move as fast as most, resulting in a 10% speed penalty on flat " "ground." msgstr "" +"No te podĆ©s mover tan rĆ”pido como los demĆ”s. TenĆ©s una penalidad de 10% en " +"suelo plano." #: lang/json/mutation_from_json.py msgid "Short Fur Coat" -msgstr "" +msgstr "Cobertura Corta de Piel" #. ~ Description for {'str': 'Short Fur Coat'} #: lang/json/mutation_from_json.py @@ -157515,6 +159204,8 @@ msgid "" "Short fur has grown to cover your entire body, providing slight protection " "from cold." msgstr "" +"Un pelaje corto ha crecido y cubre tu cuerpo entero, lo que te brinda una " +"pequeƱa protecciĆ³n contra el frĆ­o." #. ~ Description for {'str': 'Furry'} #: lang/json/mutation_from_json.py @@ -157522,34 +159213,37 @@ msgid "" "Thick brown fur has grown to cover your entire body, providing a slight " "protection against attacks, and some protection from cold." msgstr "" +"Te ha crecido pelo marrĆ³n y grueso que cubre todo tu cuerpo, lo que te " +"brinda una leve protecciĆ³n contra los ataques, y algo de protecciĆ³n contra " +"el frĆ­o." #: lang/json/mutation_from_json.py msgid "Immovable" -msgstr "" +msgstr "Inamovible" #: lang/json/mutation_from_json.py msgid "Unstoppable" -msgstr "" +msgstr "Imparable" #: lang/json/mutation_from_json.py msgid "Meatshield" -msgstr "" +msgstr "Escudo de Carne" #: lang/json/mutation_from_json.py msgid "Elephantine" -msgstr "" +msgstr "Elefantino" #: lang/json/mutation_from_json.py msgid "Freakishly Gigantic" -msgstr "" +msgstr "Peculiarmente Gigantesco" #: lang/json/mutation_from_json.py msgid "Gigantic" -msgstr "" +msgstr "Gigantesco" #: lang/json/mutation_from_json.py msgid "Terrible Odor" -msgstr "" +msgstr "Olor Terrible" #. ~ Description for Terrible Odor #: lang/json/mutation_from_json.py @@ -157558,14 +159252,17 @@ msgid "" "which you do. Monsters that track scent will find you very easily, and " "humans will react poorly." msgstr "" +"TenĆ©s el mismo olor que tendrĆ­a un elefante desprolijo, si es que " +"transpirara, cosa que vos hacĆ©s. Los monstruos que te rastrean por tu olor " +"te van a encontrar fĆ”cilmente, y los humanos no te van a querer cerca." #: lang/json/mutation_from_json.py msgid "Constant Eater" -msgstr "" +msgstr "Comensal Constante" #: lang/json/mutation_from_json.py msgid "Large Diet" -msgstr "" +msgstr "Dieta Grande" #. ~ Description for Large Diet #: lang/json/mutation_from_json.py @@ -157573,16 +159270,20 @@ msgid "" "You require more food than others but your ability to go the distance in " "both combat and athleticism is expanded." msgstr "" +"NecesitĆ”s mĆ”s comida que los demĆ”s pero tu habilidad de resistencia estĆ” " +"expandida tanto en combate como atlĆ©ticamente." #. ~ Description for High Thirst #: lang/json/mutation_from_json.py msgid "" "Your body needs more water than usual to flush the denser waste products." msgstr "" +"Tu cuerpo necesita mĆ”s agua que lo normal para depurar los desechos mĆ”s " +"densos." #: lang/json/mutation_from_json.py msgid "Giant Thirst" -msgstr "" +msgstr "Sed Gigantesca" #. ~ Description for Ponderous #: lang/json/mutation_from_json.py @@ -157591,20 +159292,24 @@ msgid "" "Your weight must be delicately placed lest the ground give way. You move " "10% slower." msgstr "" +"Tu peso debe ser delicadamente puesto cuando el suelo te de espacio. Te " +"movĆ©s un 10% mĆ”s lento." #: lang/json/mutation_from_json.py msgid "Very Deliberate" -msgstr "" +msgstr "Muy Deliberado" #. ~ Description for Very Deliberate #: lang/json/mutation_from_json.py #, no-python-format msgid "Your muscles are quite slow to move. You move 25% slower." msgstr "" +"Tus mĆŗsculos son bastante lentos en sus movimientos. Te movĆ©s un 25% mĆ”s " +"lento." #: lang/json/mutation_from_json.py msgid "CRIT Melee Training" -msgstr "" +msgstr "Entrenamiento CRIT Armas Cuerpo a Cuerpo" #. ~ Description for CRIT Melee Training #: lang/json/mutation_from_json.py @@ -157612,10 +159317,12 @@ msgid "" "You have received CQB training. For every hit you land, gain themed combat " "bonuses." msgstr "" +"Recibiste entrenamiento en combate en espacios cerrados. Por cada golpe que " +"das, ganĆ”s bonus de combate." #: lang/json/mutation_from_json.py msgid "Shadow Meld" -msgstr "" +msgstr "UniĆ³n SombrĆ­a" #. ~ Description for Shadow Meld #: lang/json/mutation_from_json.py @@ -157623,10 +159330,12 @@ msgid "" "The light around you bends strangely, making it harder for enemies to notice" " you." msgstr "" +"La luz a tu alrededor se dobla extraƱamente, haciendo mĆ”s difĆ­cil que te " +"vean tus enemigos." #: lang/json/mutation_from_json.py msgid "Moon-lit Grace" -msgstr "" +msgstr "Gracia Luz de Luna" #. ~ Description for Moon-lit Grace #: lang/json/mutation_from_json.py @@ -157634,10 +159343,12 @@ msgid "" "Aside from your appearances, your movements are incredibly graceful and " "allow you to seemingly glide through every task." msgstr "" +"MĆ”s allĆ” de tu apariencia, tus movimientos son increĆ­blemente Ć”giles y te " +"permiten deslizarte entre las tareas." #: lang/json/mutation_from_json.py msgid "Red Iris" -msgstr "" +msgstr "Iris Rojo" #. ~ Description for Red Iris #: lang/json/mutation_from_json.py @@ -157645,16 +159356,19 @@ msgid "" "You eyes are a pleasant shade of hypnotic scarlet. People feel mildly " "persuaded by you." msgstr "" +"Tus ojos son de un tono placentero de escarlata hipnĆ³tico. La gente se " +"siente un poco persuadida por vos." #: lang/json/mutation_from_json.py msgid "Night Walker" -msgstr "" +msgstr "Caminante Nocturno" #. ~ Description for Night Walker #: lang/json/mutation_from_json.py msgid "" "Emerge from the grave of the old world, and become the night once again." msgstr "" +"Emerge de la tumba del viejo mundo, y conviĆ©rtete en la noche una vez mĆ”s." #: lang/json/mutation_from_json.py msgid "Forest Guardian" @@ -159089,7 +160803,7 @@ msgstr "Supervisor de Cosecha" #: lang/json/npc_from_json.py msgid "Foreman" -msgstr "Encargado" +msgstr "Capataz" #: lang/json/npc_from_json.py msgid "Nurse" @@ -160226,11 +161940,11 @@ msgstr "" #: lang/json/overmap_terrain_from_json.py msgid "music store" -msgstr "local de mĆŗsica" +msgstr "local de instrumentos" #: lang/json/overmap_terrain_from_json.py msgid "music store roof" -msgstr "" +msgstr "techo de local de instrumentos" #: lang/json/overmap_terrain_from_json.py msgid "megastore parking lot" @@ -160976,6 +162690,10 @@ msgstr "" msgid "subway station?" msgstr "" +#: lang/json/overmap_terrain_from_json.py +msgid "science lab reactor" +msgstr "" + #: lang/json/overmap_terrain_from_json.py msgid "lab" msgstr "" @@ -162505,7 +164223,7 @@ msgstr "" #: lang/json/professions_from_json.py msgctxt "profession_male" msgid "True Foodperson" -msgstr "" +msgstr "Foodperson Verdadera" #. ~ Profession (male True Foodperson) description #: lang/json/professions_from_json.py @@ -162519,7 +164237,7 @@ msgstr "" #: lang/json/professions_from_json.py msgctxt "profession_female" msgid "True Foodperson" -msgstr "" +msgstr "Foodperson Verdadera" #. ~ Profession (female True Foodperson) description #: lang/json/professions_from_json.py @@ -163033,7 +164751,7 @@ msgstr "" #: lang/json/professions_from_json.py msgctxt "profession_male" msgid "Helicopter Pilot" -msgstr "" +msgstr "Piloto de HelicĆ³ptero" #. ~ Profession (male Helicopter Pilot) description #: lang/json/professions_from_json.py @@ -163047,7 +164765,7 @@ msgstr "" #: lang/json/professions_from_json.py msgctxt "profession_female" msgid "Helicopter Pilot" -msgstr "" +msgstr "Piloto de HelicĆ³ptero" #. ~ Profession (female Helicopter Pilot) description #: lang/json/professions_from_json.py @@ -168382,6 +170100,18 @@ msgid "" "You have your whole life ahead of you and it's gonna be sweet!" msgstr "" +#: lang/json/proficiency_from_json.py +msgid "Knapping" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Blacksmithing" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Helicopter Piloting" +msgstr "" + #. ~ Crafting recipes category name #: lang/json/recipe_category_from_json.py msgid "*" @@ -176804,7 +178534,7 @@ msgstr "" msgid "Finally, something to take the edge off." msgstr "" -#: lang/json/snippet_from_json.py src/npctalk.cpp +#: lang/json/snippet_from_json.py src/talker_npc.cpp msgid "No thanks, I'm good." msgstr "" @@ -197207,6 +198937,18 @@ msgstr "" msgid "This is a npc_has_var, npc_remove_var test response." msgstr "" +#: lang/json/talk_topic_from_json.py +msgid "This is a u_add_var time test response." +msgstr "" + +#: lang/json/talk_topic_from_json.py +msgid "This is a npc_add_var time test response." +msgstr "" + +#: lang/json/talk_topic_from_json.py +msgid "This is a u_compare_var time test response for > 3_days." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "This is a u_adjust_var test response that increments by 1." msgstr "" @@ -197307,6 +199049,10 @@ msgstr "" msgid "This is a low driving test response." msgstr "" +#: lang/json/talk_topic_from_json.py +msgid "This is an npc_first_topic test response." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "Greetings friend, it's nice to see you." msgstr "Saludos, amigo, quĆ© bueno verte." @@ -206319,7 +208065,7 @@ msgid "Will do, thanks!" msgstr "Lo voy a hacer, Ā”gracias!" #: lang/json/talk_topic_from_json.py lang/json/talk_topic_from_json.py -#: src/npctalk.cpp +#: src/talker.h src/talker_npc.cpp msgid "Nope." msgstr "Para nada." @@ -212417,6 +214163,36 @@ msgstr "" msgid "The door opens forcefully!" msgstr "" +#: lang/json/terrain_from_json.py +msgid "broken diesel tank" +msgstr "" + +#. ~ Description for centrifuge +#: lang/json/terrain_from_json.py +msgid "" +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. It could be used to analyze a medical fluid sample, such as blood, if" +" a test tube was placed in it." +msgstr "" + +#: lang/json/terrain_from_json.py +msgid "plutonium generator" +msgstr "generador de plutonio" + +#. ~ Description for plutonium generator +#: lang/json/terrain_from_json.py +msgid "" +"This imposing apparatus harnesses the power of the atom. Refined nuclear " +"fuel is 'burned' to provide nearly limitless electrical power. It's not " +"doing much good here though. Perhaps it could be salvaged for other " +"purposes." +msgstr "" + +#. ~ Description for old machinery +#: lang/json/terrain_from_json.py +msgid "Assorted old machinery. You could scavenge it for parts." +msgstr "" + #: lang/json/terrain_from_json.py msgid "scorched earth" msgstr "tierra calcinada" @@ -215509,24 +217285,6 @@ msgstr "" "apretarlos hasta formar diferentes formas, que pueden ser usadas en " "fabricaciones." -#: lang/json/terrain_from_json.py -msgid "fuel tank" -msgstr "" - -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with gasoline." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "broken fuel tank" -msgstr "" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with gasoline." -msgstr "" - #: lang/json/terrain_from_json.py msgid "gasoline pump" msgstr "surtidor de nafta" @@ -215551,16 +217309,6 @@ msgid "" "the liquid gold." msgstr "" -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with diesel." -msgstr "" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with diesel." -msgstr "" - #: lang/json/terrain_from_json.py msgid "diesel pump" msgstr "surtidor diĆ©sel" @@ -215639,16 +217387,6 @@ msgid "" "airflow." msgstr "" -#: lang/json/terrain_from_json.py -msgid "broken generator" -msgstr "generador roto" - -#. ~ Description for broken generator -#: lang/json/terrain_from_json.py -msgid "" -"This generator is broken and will not help you produce usable electricity." -msgstr "" - #: lang/json/terrain_from_json.py msgid "missile" msgstr "misil" @@ -215706,18 +217444,6 @@ msgid "" "This unpowered pump previously would have moved fluids around in a hurry." msgstr "" -#: lang/json/terrain_from_json.py -msgid "centrifuge" -msgstr "centrifugadora" - -#. ~ Description for centrifuge -#: lang/json/terrain_from_json.py -msgid "" -"This is a centrifuge, a liquid separating device with an automated analyzer " -"unit. It could be used to analyze a medical fluid sample, such as blood, if" -" a test tube was placed in it." -msgstr "" - #: lang/json/terrain_from_json.py msgid "CVD machine" msgstr "mĆ”quina CVD" @@ -215820,19 +217546,6 @@ msgstr "" msgid "A machine with several taps that dispenses clean water." msgstr "" -#: lang/json/terrain_from_json.py -msgid "plutonium generator" -msgstr "generador de plutonio" - -#. ~ Description for plutonium generator -#: lang/json/terrain_from_json.py -msgid "" -"This imposing apparatus harnesses the power of the atom. Refined nuclear " -"fuel is 'burned' to provide nearly limitless electrical power. It's not " -"doing much good here though. Perhaps it could be salvaged for other " -"purposes." -msgstr "" - #: lang/json/terrain_from_json.py msgid "telecom cabinet" msgstr "cabina de telecomunicaciĆ³n" @@ -215947,46 +217660,6 @@ msgstr "cinta transportadora" msgid "A conveyor belt. Used to transport things." msgstr "" -#: lang/json/terrain_from_json.py -msgid "ting." -msgstr "ting." - -#: lang/json/terrain_from_json.py -msgid "light machinery" -msgstr "maquinaria ligera" - -#. ~ Description for light machinery -#: lang/json/terrain_from_json.py -msgid "Assorted light machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "heavy machinery" -msgstr "maquinaria pesada" - -#. ~ Description for heavy machinery -#: lang/json/terrain_from_json.py -msgid "Assorted heavy machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "old machinery" -msgstr "maquinaria antigua" - -#. ~ Description for old machinery -#: lang/json/terrain_from_json.py -msgid "Assorted old machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "electronic machinery" -msgstr "maquinaria elĆ©ctrica" - -#. ~ Description for electronic machinery -#: lang/json/terrain_from_json.py -msgid "Assorted electronic machinery. You could scavenge it for parts." -msgstr "" - #: lang/json/terrain_from_json.py msgid "milking machine" msgstr "mĆ”quina de ordeƱe" @@ -216061,29 +217734,6 @@ msgid "" "from the elements or to protect a campfire from the rain." msgstr "" -#: lang/json/terrain_from_json.py -msgid "broken console" -msgstr "consola rota" - -#. ~ Description for broken console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It doesn't seem to be working. " -"It's the broken screen and shattered circuit boards that's telling you that." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "computer console" -msgstr "consola de computadora" - -#. ~ Description for computer console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It can be used to view contents and" -" perform any allowed functions. It might even be possible to hack it, given" -" the skills." -msgstr "" - #: lang/json/terrain_from_json.py msgid "mechanical winch" msgstr "malacate mecĆ”nico" @@ -218393,10 +220043,6 @@ msgstr "pendiente hacia arriba" msgid "An upward facing slope." msgstr "" -#: lang/json/terrain_from_json.py -msgid "rope leading up" -msgstr "soga para subir" - #. ~ Description for rope leading up #: lang/json/terrain_from_json.py msgid "A rope. You could climb up it." @@ -219056,6 +220702,10 @@ msgstr "Auto" msgid "Car Chassis" msgstr "Chasis de Auto" +#: lang/json/vehicle_from_json.py +msgid "Hybrid Car" +msgstr "" + #: lang/json/vehicle_from_json.py msgid "City Car" msgstr "" @@ -220936,6 +222586,21 @@ msgstr "" "llave adecuada, y que harĆ”n sonar una alarma si lo intentĆ”s. La alarma puede" " ser desactivada." +#: lang/json/vehicle_part_from_json.py +msgid "smart engine controller" +msgstr "" + +#. ~ Description for {'str': 'smart engine controller'} +#: lang/json/vehicle_part_from_json.py +#, no-python-format +msgid "" +"Electronic module that automatically switches combustion and electric " +"engines on and off minimizing fuel consumption and optimizing power output " +"and battery charge rate. Must be turned on to work. Simplified ruleset: 1." +" When throttling, maximize acceleration. 2. Keep battery at 90%. 3. " +"Minimize fuel consumption." +msgstr "" + #: lang/json/vehicle_part_from_json.py msgid "5-point harness" msgstr "arnĆ©s de 5 puntos" @@ -222220,6 +223885,66 @@ msgstr "" msgid "Disgusting Diet" msgstr "" +#: lang/json/vitamin_from_json.py +msgid "Blood" +msgstr "" + +#: lang/json/vitamin_from_json.py +msgid "Red Blood Cells" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "NULL Weather - BUG" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "Clear" +msgstr "Despejado" + +#: lang/json/weather_type_from_json.py +msgid "Sunny" +msgstr "Soleado" + +#: lang/json/weather_type_from_json.py +msgid "Cloudy" +msgstr "Nublado" + +#: lang/json/weather_type_from_json.py +msgid "Light Drizzle" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "Drizzle" +msgstr "Llovizna" + +#: lang/json/weather_type_from_json.py +msgid "Rain" +msgstr "Lluvia" + +#: lang/json/weather_type_from_json.py +msgid "Thunder Storm" +msgstr "Lluvia con truenos" + +#: lang/json/weather_type_from_json.py +msgid "Acidic Drizzle" +msgstr "Llovizna Ć”cida" + +#: lang/json/weather_type_from_json.py +msgid "Acid Rain" +msgstr "Lluvia Ć”cida" + +#: lang/json/weather_type_from_json.py +msgid "Flurries" +msgstr "Nevisca" + +#: lang/json/weather_type_from_json.py +msgid "Snowing" +msgstr "Nieve" + +#: lang/json/weather_type_from_json.py +msgid "Snowstorm" +msgstr "Tormenta de nieve" + #: src/achievement.cpp msgid "time of cataclysm" msgstr "" @@ -222385,8 +224110,7 @@ msgstr "Ā”Te quedaste sin energĆ­a!" msgid "You cannot hack this." msgstr "" -#: src/activity_actor.cpp src/computer_session.cpp src/computer_session.cpp -#: src/iuse.cpp src/map.cpp +#: src/activity_actor.cpp src/computer_session.cpp src/iuse.cpp src/map.cpp msgid "an alarm sound!" msgstr "el sonido de una alarma!" @@ -222530,6 +224254,16 @@ msgstr "" msgid "Continue trying to fall asleep and don't ask again." msgstr "" +#: src/activity_actor.cpp +#, c-format +msgid "You disassemble your %s." +msgstr "Desarmaste tu %s." + +#: src/activity_actor.cpp src/player.cpp +#, c-format +msgid "You unload your %s." +msgstr "DescargĆ”s tu %s." + #: src/activity_actor.cpp msgid "You are too tired to exercise." msgstr "" @@ -223059,11 +224793,6 @@ msgstr[1] " terminĆ³ de destrozar los cadĆ”veres." msgid "Can't reload the %s." msgstr "No pudiste recargar el/a %s." -#: src/activity_handlers.cpp src/iexamine.cpp -#, c-format -msgid "You reload the %s." -msgstr "RecargĆ”s el/a %s." - #: src/activity_handlers.cpp #, c-format msgid "" @@ -223080,6 +224809,11 @@ msgstr "" msgid "You refill the %s." msgstr "RellenĆ”s el %s." +#: src/activity_handlers.cpp +#, c-format +msgid "You reload the %1$s with %2$s." +msgstr "" + #: src/activity_handlers.cpp src/bionics.cpp msgid "There's nothing to light there." msgstr "AhĆ­ no hay nada para prender fuego." @@ -223211,6 +224945,10 @@ msgstr "Ya no vas a aprender nada mĆ”s haciendo eso." msgid "%s %s\n" msgstr "" +#: src/activity_handlers.cpp src/magic.cpp +msgid "bionic power" +msgstr "" + #: src/activity_handlers.cpp #, c-format msgid "Charges: %s/%s %s (%s per use)\n" @@ -223589,16 +225327,6 @@ msgstr "AbrĆ­s tu equipo y te afeitĆ”s." msgid "You give your hair a trim." msgstr "Te cortĆ”s un poco el pelo." -#: src/activity_handlers.cpp -#, c-format -msgid "You disassemble your %s." -msgstr "Desarmaste tu %s." - -#: src/activity_handlers.cpp src/player.cpp -#, c-format -msgid "You unload your %s." -msgstr "DescargĆ”s tu %s." - #: src/activity_handlers.cpp #, c-format msgid "You have run out of %s." @@ -224631,7 +226359,7 @@ msgstr "" msgid "Properties" msgstr "Propiedades" -#: src/armor_layers.cpp +#: src/armor_layers.cpp src/item.cpp msgid "Coverage:" msgstr "Cobertura:" @@ -226616,7 +228344,7 @@ msgstr "No tenĆ©s energĆ­a para activar tu %s." msgid "Deactivate your %s first!" msgstr "Ā”Primero desactivĆ” tu %s!" -#: src/bionics.cpp src/player.cpp +#: src/bionics.cpp src/character.cpp #, c-format msgid "Stop wielding %s?" msgstr "ĀæQuerĆ©s dejar de empuƱar el/a %s?" @@ -228038,6 +229766,11 @@ msgstr "" msgid "You cannot dismount there!" msgstr "" +#: src/character.cpp +#, c-format +msgid "This task is too simple to train your %s beyond %d." +msgstr "Esta tarea es demasiado simple para entrenar tu %s mĆ”s de %d." + #: src/character.cpp msgid "You struggle to stand." msgstr "Te cuesta estar parado." @@ -228208,6 +229941,16 @@ msgstr "Ā” se escapa del pozo!" msgid "Your %s bionic comes back online." msgstr "" +#: src/character.cpp +#, c-format +msgid "Your skill in %s has increased to %d!" +msgstr "Ā”Tu habilidad en %s se ha incrementado a %d!" + +#: src/character.cpp +#, c-format +msgid "You feel that %s tasks of this level are becoming trivial." +msgstr "SentĆ­s que las tareas de %s de este nivel se han vuelto algo trivial." + #: src/character.cpp #, c-format msgid "You put on your %s." @@ -228323,6 +230066,15 @@ msgstr "" msgid "%s doesn't have any broken limbs this could help." msgstr "" +#: src/character.cpp +msgid "You don't need a tourniquet to stop the bleeding." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "%s doesn't need a tourniquet to stop the bleeding." +msgstr "" + #: src/character.cpp msgid "You don't have enough arms to wear that." msgstr "" @@ -228505,7 +230257,7 @@ msgstr "FamĆ©lico/a" msgid "ERROR!" msgstr "" -#: src/character.cpp src/npctalk.cpp +#: src/character.cpp src/talker_npc.cpp msgid "Exhausted" msgstr "Exhausto/a" @@ -228549,7 +230301,7 @@ msgstr "EstĆ”s sintiendo calambres por meterte en este vehĆ­culo." msgid "You have a sudden heart attack!" msgstr "Ā”SufrĆ­s un repentino ataque al corazĆ³n!" -#: src/character.cpp +#: src/character.cpp src/player_hardcoded_effects.cpp msgid " has a sudden heart attack!" msgstr "" @@ -228790,12 +230542,12 @@ msgstr "Bueno" #: src/character.cpp #, c-format -msgid "Chance to stop: %d %%" -msgstr "Posibilidad de pararlo: %d %%" +msgid "Expected reduction of bleeding by: %d %%" +msgstr "" #: src/character.cpp -msgid "This will not stop the bleeding." -msgstr "Esto no va a parar el sangrado." +msgid "This will not affect the bleeding." +msgstr "" #: src/character.cpp #, c-format @@ -229231,6 +230983,42 @@ msgstr "Ā”Tu %1$s es %2$s aĆŗn mĆ”s!" msgid "Your %1$s is %2$s!" msgstr "Ā”Tu %1$s es %2$s!" +#: src/character.cpp +msgid "Can't wield spilt liquids." +msgstr "No podĆ©s empuƱar lĆ­quidos derramados." + +#: src/character.cpp +msgid "You need at least one arm to even consider wielding something." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "The %s is preventing you from wielding the %s." +msgstr "" + +#: src/character.cpp +msgid "Something you are wearing hinders the use of both hands." +msgstr "" +"Algo de lo que tenĆ©s puesto te dificulta la utilizaciĆ³n de las dos manos." + +#: src/character.cpp +#, c-format +msgid "The %s can't be wielded with only one arm." +msgstr "El/a %s no puede ser empuƱado/a con una sola mano." + +#: src/character.cpp +#, c-format +msgid "You are too weak to wield %s with only one arm." +msgstr "Sos demasiado dĆ©bil para empuƱar %s con una sola mano." + +#: src/character.cpp +msgid " (empty)" +msgstr "" + +#: src/character.cpp src/npctalk.cpp +msgid "fists" +msgstr "puƱos" + #: src/character.cpp #, c-format msgid "You are no longer able to wield your %s and drop it!" @@ -229781,6 +231569,11 @@ msgstr "Acceso completo. Presione una tecla..." msgid "%s - Root Menu" msgstr "%s - MenĆŗ RaĆ­z" +#: src/computer_session.cpp +#, c-format +msgid "%s (UNAVAILABLE)" +msgstr "" + #: src/computer_session.cpp msgid "Password required." msgstr "Requiere contraseƱa." @@ -230364,7 +232157,7 @@ msgstr "" msgid "Result: " msgstr "Resultado: " -#: src/construction.cpp +#: src/construction.cpp src/worldfactory.cpp msgid "N/A" msgstr "N/D" @@ -231035,6 +232828,10 @@ msgid "" "Start crafting anyway?" msgstr "" +#: src/craft_command.cpp +msgid "You don't have the required proficiencies to craft this!" +msgstr "" + #: src/craft_command.cpp msgid "" "This craft will use rotten components.\n" @@ -231510,6 +233307,11 @@ msgstr "" msgid "Other skills: %s" msgstr "Otras habilidades: %s" +#: src/crafting_gui.cpp +#, c-format +msgid "Proficiencies Required: %s" +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "Time to complete: %s" @@ -231553,6 +233355,12 @@ msgid "" "components" msgstr "" +#: src/crafting_gui.cpp +msgid "" +"Cannot be crafted because you lack the required " +"proficiencies." +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "v (%s for more)" @@ -231940,6 +233748,10 @@ msgstr "Editar jugador/PNJ" msgid "Damage self" msgstr "" +#: src/debug_menu.cpp +msgid "Bleed self" +msgstr "" + #: src/debug_menu.cpp msgid "Set automove route" msgstr "Determinar ruta de automovimiento" @@ -232072,6 +233884,14 @@ msgstr "" msgid "Gameā€¦" msgstr "" +#: src/debug_menu.cpp +msgid "Change [b]attery charge" +msgstr "" + +#: src/debug_menu.cpp +msgid "Vehicleā€¦" +msgstr "" + #: src/debug_menu.cpp msgid "Teleport - short range" msgstr "" @@ -232701,12 +234521,8 @@ msgstr "LocaciĆ³n %d:%d en %d:%d, %s\n" #: src/debug_menu.cpp #, c-format -msgid "" -"Current turn: %d.\n" -"%s\n" +msgid "Current turn: %d.\n" msgstr "" -"Turno actual: %d.\n" -"%s\n" #: src/debug_menu.cpp #, c-format @@ -232715,14 +234531,6 @@ msgid_plural "%d creatures exist.\n" msgstr[0] "%d criatura existe.\n" msgstr[1] "%d criaturas existen.\n" -#: src/debug_menu.cpp -msgid "NPCs are going to spawn." -msgstr "Se van a generar PNJs." - -#: src/debug_menu.cpp -msgid "NPCs are NOT going to spawn." -msgstr "NO se van a generar PNJs." - #: src/debug_menu.cpp #, c-format msgid "%s: map ( %d:%d ) pos ( %d:%d )" @@ -232778,6 +234586,22 @@ msgstr "Elegir vehĆ­culo para crear" msgid "%1$s (%2$s)" msgstr "%1$s (%2$s)" +#: src/debug_menu.cpp +msgid "Vehicle condition" +msgstr "" + +#: src/debug_menu.cpp +msgid "Light damage" +msgstr "" + +#: src/debug_menu.cpp +msgid "Undamaged" +msgstr "" + +#: src/debug_menu.cpp +msgid "Disabled (tires or engine)" +msgstr "" + #: src/debug_menu.cpp msgid "Martial arts debug." msgstr "Debug de artes marciales." @@ -232841,6 +234665,10 @@ msgstr "" msgid "Damage self for how much? hp: %s" msgstr "" +#: src/debug_menu.cpp +msgid "Add bleeding duration in minutes, equal to intensity:" +msgstr "" + #: src/debug_menu.cpp msgid "This binary was not compiled with tiles support." msgstr "Este binario no estĆ” compilado con soporte para grĆ”ficos." @@ -232973,6 +234801,14 @@ msgstr "" msgid "%s is now level %d!" msgstr "" +#: src/debug_menu.cpp src/iuse.cpp src/iuse.cpp +msgid "There's no vehicle there." +msgstr "AhĆ­ no hay un vehĆ­culo." + +#: src/debug_menu.cpp +msgid "By how much? (in kJ, negative to discharge)" +msgstr "" + #: src/descriptions.cpp #, c-format msgid "" @@ -233694,6 +235530,22 @@ msgstr "excelente" msgid "perfect" msgstr "perfecto" +#: src/effect.cpp +msgid "miniscule" +msgstr "" + +#: src/effect.cpp +msgid "small" +msgstr "chico" + +#: src/effect.cpp +msgid "moderate" +msgstr "" + +#: src/effect.cpp +msgid "excellent" +msgstr "" + #. ~ Default format for scores. %1$s is statistic description; %2$s is value. #: src/event_statistics.cpp #, c-format @@ -236384,6 +238236,11 @@ msgstr "Tu posiciĆ³n en el mapa general: %d, %d, %d" msgid "Your local position: %d, %d, %d" msgstr "Tu posiciĆ³n local: %d, %d, %d" +#: src/game.cpp +#, c-format +msgid "Total NPCs within %d OMTs: %d. %d are static NPCs." +msgstr "" + #: src/game.cpp msgid "East:" msgstr "Este:" @@ -238164,12 +240021,12 @@ msgid "Your inventory is empty." msgstr "Tu inventario estĆ” vacĆ­o." #: src/game_inventory.cpp -msgid "ENCUMBRANCE" -msgstr "INCOMODIDAD" +msgid "AVG ENCUMBRANCE" +msgstr "" #: src/game_inventory.cpp -msgid "COVERAGE" -msgstr "COBERTURA" +msgid "AVG COVERAGE" +msgstr "" #: src/game_inventory.cpp msgid "WARMTH" @@ -241367,6 +243224,11 @@ msgstr "ĀæCuĆ”ntas unidades de %1$s querĆ©s poner en el %2$s?" msgid "The %1$s contains %2$d %3$s." msgstr "El %1$s adentro tiene %2$d %3$s." +#: src/iexamine.cpp +#, c-format +msgid "You reload the %s." +msgstr "RecargĆ”s el/a %s." + #: src/iexamine.cpp msgid "Do what with the curtains?" msgstr "ĀæQuĆ© querĆ©s hacer con las cortinas?" @@ -242244,6 +244106,10 @@ msgstr "Terminando" msgid "Body parts" msgstr "Partes del cuerpo" +#: src/init.cpp +msgid "Weather types" +msgstr "" + #: src/init.cpp msgid "Field types" msgstr "" @@ -243098,10 +244964,6 @@ msgstr "" msgid "max rot (turns): " msgstr "" -#: src/item.cpp -msgid "last rot: " -msgstr "Ćŗltimo rot: " - #: src/item.cpp msgid "last temp: " msgstr "Ćŗltima temp:" @@ -243376,7 +245238,7 @@ msgid "Recommended strength (burst): " msgstr "Fuerza recomendada (rĆ”faga):" #: src/item.cpp -msgid " moves " +msgid " moves" msgstr "" #: src/item.cpp @@ -243414,10 +245276,6 @@ msgstr "Oportunidad de acertar a distancia:" msgid "" msgstr "" -#: src/item.cpp -msgid " moves" -msgstr "" - #: src/item.cpp msgid "Time to reach aim level: " msgstr "Tiempo para llegar a apuntar:" @@ -243552,164 +245410,169 @@ msgstr "" "mejorarla reparĆ”ndola." #: src/item.cpp -msgid "Covers: " -msgstr "Cubre: " +msgid "Covers:" +msgstr "" #: src/item.cpp -msgid "The head. " -msgstr "La cabeza. " +msgid " The head." +msgstr "" #: src/item.cpp -msgid "The eyes. " -msgstr "Los ojos. " +msgid " The eyes." +msgstr "" #: src/item.cpp -msgid "The mouth. " -msgstr "La boca. " +msgid " The mouth." +msgstr "" #: src/item.cpp -msgid "The torso. " -msgstr "El torso. " +msgid " The torso." +msgstr "" #: src/item.cpp -msgid "Either arm. " -msgstr "Cualquier brazo. " +msgid " Either arm." +msgstr "" #: src/item.cpp -msgid "The arms. " -msgstr "Los brazos. " +msgid " The arms." +msgstr "" #: src/item.cpp -msgid "The left arm. " -msgstr "El brazo izquierdo. " +msgid " The left arm." +msgstr "" #: src/item.cpp -msgid "The right arm. " -msgstr "El brazo derecho. " +msgid " The right arm." +msgstr "" #: src/item.cpp -msgid "Either hand. " -msgstr "Cualquier mano. " +msgid " Either hand." +msgstr "" #: src/item.cpp -msgid "The hands. " -msgstr "Las manos. " +msgid " The hands." +msgstr "" #: src/item.cpp -msgid "The left hand. " -msgstr "La mano izquierda. " +msgid " The left hand." +msgstr "" #: src/item.cpp -msgid "The right hand. " -msgstr "La mano derecha. " +msgid " The right hand." +msgstr "" #: src/item.cpp -msgid "Either leg. " -msgstr "Cualquier pierna. " +msgid " Either leg." +msgstr "" #: src/item.cpp -msgid "The legs. " -msgstr "Las piernas. " +msgid " The legs." +msgstr "" #: src/item.cpp -msgid "The left leg. " -msgstr "La pierna izquierda. " +msgid " The left leg." +msgstr "" #: src/item.cpp -msgid "The right leg. " -msgstr "La pierna derecha. " +msgid " The right leg." +msgstr "" #: src/item.cpp -msgid "Either foot. " -msgstr "Cualquier pie. " +msgid " Either foot." +msgstr "" #: src/item.cpp -msgid "The feet. " -msgstr "Los pies. " +msgid " The feet." +msgstr "" #: src/item.cpp -msgid "The left foot. " -msgstr "El pie izquierdo. " +msgid " The left foot." +msgstr "" #: src/item.cpp -msgid "The right foot. " -msgstr "El pie derecho. " +msgid " The right foot." +msgstr "" #: src/item.cpp -msgid "Nothing." +msgid " Nothing." msgstr "" #: src/item.cpp -msgid "Layer: " -msgstr "Nivel: " +msgid "Layer:" +msgstr "" #: src/item.cpp -msgid "Personal aura. " +msgid " Personal aura." msgstr "" #: src/item.cpp -msgid "Close to skin. " -msgstr "Contra la piel. " +msgid " Close to skin." +msgstr "" #: src/item.cpp -msgid "Strapped. " -msgstr "Atado. " +msgid " Strapped." +msgstr "" #: src/item.cpp -msgid "Outer. " -msgstr "Externo. " +msgid " Outer." +msgstr "" #: src/item.cpp -msgid "Waist. " -msgstr "Cintura. " +msgid " Waist." +msgstr "" #: src/item.cpp -msgid "Outer aura. " +msgid " Outer aura." msgstr "" #: src/item.cpp -msgid "Normal. " -msgstr "Normal. " +msgid " Normal." +msgstr "" #: src/item.cpp -msgid "Coverage: " -msgstr "Cobertura: " +msgid "Average Coverage: " +msgstr "" #: src/item.cpp msgid "Warmth: " msgstr "Abrigo: " #: src/item.cpp -msgid " (fits)" -msgstr " (tu talle)" +msgid " (fits)" +msgstr "" + +#: src/item.cpp +msgid " (poor fit)" +msgstr "" #: src/item.cpp -msgid " (poor fit)" -msgstr " (te queda mal)" +msgid " (too big)" +msgstr "" #: src/item.cpp -msgid " (too big)" +msgid " (huge!)" msgstr "" #: src/item.cpp -msgid " (huge!)" +msgid " (too small)" msgstr "" #: src/item.cpp -msgid " (too small)" +msgid " (tiny!)" msgstr "" #: src/item.cpp -msgid " (tiny!)" +msgid "Encumbrance:" msgstr "" #: src/item.cpp -msgid "Encumbrance: " -msgstr "Incomodidad: " +#, c-format +msgid "%s:" +msgstr "" #: src/item.cpp -msgid "Encumbrance when full: " -msgstr "Incomodidad cuando estĆ” lleno:" +msgid "When Full:" +msgstr "" #: src/item.cpp msgid "Weight capacity modifier: " @@ -244113,23 +245976,23 @@ msgid "Power Capacity:" msgstr "" #: src/item.cpp -msgid "Environmental Protection: " +msgid "Environmental Protection:" msgstr "" #: src/item.cpp -msgid "Bash Protection: " +msgid "Bash Protection:" msgstr "" #: src/item.cpp -msgid "Cut Protection: " +msgid "Cut Protection:" msgstr "" #: src/item.cpp -msgid "Ballistic Protection: " -msgstr "ProtecciĆ³n BalĆ­stica: " +msgid "Ballistic Protection:" +msgstr "" #: src/item.cpp -msgid "Stat Bonus: " +msgid "Stat Bonus:" msgstr "" #: src/item.cpp @@ -246268,10 +248131,6 @@ msgstr "ĀæDesde dĆ³nde querĆ©s chupar?" msgid "There is nothing to siphon nearby." msgstr "" -#: src/iuse.cpp -msgid "There's no vehicle there." -msgstr "AhĆ­ no hay un vehĆ­culo." - #: src/iuse.cpp msgid "With a snarl, the combat chainsaw screams to life!" msgstr "Ā”Con un gruƱido, la motosierra de combate grita y arranca!" @@ -249343,6 +251202,10 @@ msgstr "Ā”Te duele mĆ”s que la mierda!" msgid "It itches a little." msgstr "Te pica un poco." +#: src/iuse_actor.cpp +msgid "Bleeding has not stopped completely!" +msgstr "" + #: src/iuse_actor.cpp msgid "You cannot cauterize while mounted." msgstr "" @@ -249668,12 +251531,22 @@ msgid "You stop the bleeding." msgstr "FrenĆ”s el sangrado." #: src/iuse_actor.cpp -msgid "The wound still bleeds." -msgstr "La herida todavĆ­a sangra." +msgid "You reduce the bleeding, but it's not stopped yet." +msgstr "" + +#: src/iuse_actor.cpp +msgid "The bleeding is reduced, but not stopped." +msgstr "" + +#: src/iuse_actor.cpp +msgid "" +"Your dressing is too ineffective for a bleeding of this extent, and you fail" +" to stop it." +msgstr "" #: src/iuse_actor.cpp -msgid "You fail to stop the bleeding." -msgstr "No pudiste frenar el sangrado." +msgid "The wound still bleeds." +msgstr "La herida todavĆ­a sangra." #: src/iuse_actor.cpp msgid "The wound is cleaned." @@ -249778,12 +251651,16 @@ msgid "Actual disinfecting quality: " msgstr "" #: src/iuse_actor.cpp -msgid "Chance to heal (percent): " +msgid "Effect on bleeding: " msgstr "" #: src/iuse_actor.cpp -msgid "* Bleeding: " -msgstr "* Sangrado: " +msgid "Actual effect on bleeding: " +msgstr "" + +#: src/iuse_actor.cpp +msgid "Chance to heal (percent): " +msgstr "" #: src/iuse_actor.cpp msgid "* Bite: " @@ -249849,8 +251726,8 @@ msgid "It's not a gun." msgstr "No es un arma de fuego." #: src/iuse_actor.cpp -msgid "The barrel is too short." -msgstr "El caĆ±Ć³n es demasiado corto." +msgid "The barrel is too small." +msgstr "" #: src/iuse_actor.cpp msgid "The barrel is already sawn-off." @@ -251374,10 +253251,6 @@ msgstr "" msgid "stamina" msgstr "" -#: src/magic.cpp -msgid "bionic power" -msgstr "" - #: src/magic.cpp msgid "error: energy_type" msgstr "" @@ -253413,7 +255286,7 @@ msgstr "" msgid "You smash %s with all your might but %s remains in their hands!" msgstr "Ā”GolpeĆ”s el %s con toda tu fuerza pero su %s sigue en sus manos!" -#: src/melee.cpp src/npctalk.cpp +#: src/melee.cpp src/talker_npc.cpp #, c-format msgid "%s is hostile!" msgstr "Ā”%s es hostil!" @@ -254247,6 +256120,36 @@ msgctxt "memorial_female" msgid "Died of a drug overdose." msgstr "MuriĆ³ por sobredosis de drogas." +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died from loss of red blood cells." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died from loss of red blood cells." +msgstr "" + #: src/memorial_logger.cpp msgctxt "memorial_male" msgid "Succumbed to the infection." @@ -258231,10 +260134,6 @@ msgctxt "Paralyze as an action" msgid "paralyze" msgstr "paralizar" -#: src/monster.cpp -msgid "cause bleed" -msgstr "causar sangrado" - #: src/monster.cpp msgid "It has a head." msgstr "Tiene cabeza." @@ -259308,6 +261207,15 @@ msgstr "" msgid "%s (activated)" msgstr "" +#: src/newcharacter.cpp +msgid "Profession proficiencies:" +msgstr "" + +#: src/newcharacter.cpp +msgctxt "Profession has no proficiencies" +msgid "None" +msgstr "Ninguno" + #: src/newcharacter.cpp msgid "Pets:" msgstr "" @@ -259566,8 +261474,12 @@ msgid "" msgstr "" #: src/newcharacter.cpp -msgid "_______NO NAME ENTERED!_______" -msgstr "_______Ā”NO INGRESASTE NOMBRE!_______" +msgid "--- NO NAME ENTERED ---" +msgstr "" + +#: src/newcharacter.cpp +msgid "--- RANDOM NAME ---" +msgstr "" #: src/newcharacter.cpp #, c-format @@ -259653,15 +261565,19 @@ msgid "Enter height in centimeters. Minimum 145, maximum 200" msgstr "" #: src/newcharacter.cpp -msgid "Enter blood type (omit Rh):" +msgid "Select blood type" msgstr "" #: src/newcharacter.cpp -msgid "Invalid blood type." +msgid "Select Rh factor" msgstr "" #: src/newcharacter.cpp -msgid "Enter Rh factor:" +msgid "negative" +msgstr "" + +#: src/newcharacter.cpp +msgid "positive" msgstr "" #: src/newcharacter.cpp @@ -260046,6 +261962,25 @@ msgstr " se calma." msgid " is no longer afraid." msgstr " ya no tiene miedo." +#: src/npc.cpp +#, c-format +msgid "I'm holing up here for safety. Long term, %s" +msgstr "" + +#: src/npc.cpp +msgid "I run the shop here." +msgstr "Yo manejo el negocio acĆ”." + +#: src/npc.cpp +#, c-format +msgid "Currently, I'm guarding this location. Overall, %s" +msgstr "" + +#: src/npc.cpp +#, c-format +msgid "Right now, I'm . In general, %s" +msgstr "" + #: src/npcmove.cpp msgid "" msgstr "" @@ -260198,6 +262133,15 @@ msgstr "" msgid "My %s is bleeding!" msgstr "Ā”Mi %s estĆ” sangrando!" +#: src/npcmove.cpp +#, c-format +msgid "My %s is bleeding badly!" +msgstr "" + +#: src/npcmove.cpp +msgid "I've lost lot of blood." +msgstr "" + #: src/npcmove.cpp #, c-format msgid "%1$s reloads their %2$s." @@ -260444,11 +262388,6 @@ msgstr "GritĆ”s %s" msgid "%s yelling %s" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%s is fleeing from you!" -msgstr "Ā”%s se estĆ” escapando de vos!" - #: src/npctalk.cpp #, c-format msgid "%s talked to you." @@ -260504,37 +262443,6 @@ msgstr "Lo lamento, pero no parece que haya nada que te pueda enseƱar." msgid "Here's what I can teach youā€¦" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%d.%d miles." -msgstr "%d.%d millas." - -#: src/npctalk.cpp -#, c-format -msgid "%d foot." -msgid_plural "%d feet." -msgstr[0] "%d pie." -msgstr[1] "%d pies." - -#: src/npctalk.cpp -#, c-format -msgid "I'm holing up here for safety. Long term, %s" -msgstr "" - -#: src/npctalk.cpp -msgid "I run the shop here." -msgstr "Yo manejo el negocio acĆ”." - -#: src/npctalk.cpp -#, c-format -msgid "Currently, I'm guarding this location. Overall, %s" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "Right now, I'm . In general, %s" -msgstr "" - #: src/npctalk.cpp msgid "&You yell, but can't hear yourself." msgstr "&GritĆ”s, pero no te podĆ©s escuchar a vos mismo." @@ -260543,66 +262451,6 @@ msgstr "&GritĆ”s, pero no te podĆ©s escuchar a vos mismo." msgid "&You yell." msgstr "&GritĆ”s." -#: src/npctalk.cpp -msgid "&You can't make anything out." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "Str %d - %d" -msgstr "Fue %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Dex %d - %d" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid " Int %d - %d" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid " Per %d - %d" -msgstr "" - -#: src/npctalk.cpp -msgid "Dead tired" -msgstr "Muerto/a de cansancio" - -#: src/npctalk.cpp -msgid "Not tired" -msgstr "Sin cansancio" - -#: src/npctalk.cpp -msgid ". Will need sleep in " -msgstr "" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need water in " -msgstr "" - -#: src/npctalk.cpp -msgid "" -"\n" -"Thirsty" -msgstr "" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need food in " -msgstr "" - -#: src/npctalk.cpp -msgid "" -"\n" -"Hungry" -msgstr "" - #: src/npctalk.cpp msgid "YES, MASTER!" msgstr "Ā”Sƍ, AMO!" @@ -260616,34 +262464,6 @@ msgstr "Tengo noticias." msgid "Yes, let's resume training %s" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%s: 1 hour lesson (cost %s)" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "%s: teaching spell knowledge (cost %s)" -msgstr "" - -#. ~Martial art style (cost in dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s ( cost $%d )" -msgstr "%s ( cuesta $%d )" - -#. ~Skill name: current level (exercise) -> next level (exercise) (cost in -#. dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%)" -msgstr "" - #: src/npctalk.cpp msgid "Okay, thanks." msgstr "Bueno, gracias. " @@ -260656,10 +262476,6 @@ msgstr "Sigamos andando." msgid "OBEY ME!" msgstr "Ā”OBEDECEME!" -#: src/npctalk.cpp src/player.cpp -msgid "fists" -msgstr "puƱos" - #: src/npctalk.cpp msgid "BADAMMO" msgstr "MALMUNICIƓN" @@ -260731,7 +262547,7 @@ msgctxt "you say something" msgid "You: %s" msgstr "Vos: %s" -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp msgid "You can't afford it!" msgstr "" @@ -260742,7 +262558,7 @@ msgid "%1$s gives you a %2$s." msgstr "" #. ~ %1%s is the NPC name, %2$d is a number of items, %3$s are items -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp #, c-format msgid "%1$s gives you %2$d %3$s." msgstr "" @@ -260771,97 +262587,11 @@ msgstr "" msgid "%1$s doesn't have a %2$s!" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%1$s gives you %2$s." -msgstr "" - #: src/npctalk.cpp #, c-format msgid "You learn how to craft %s." msgstr "" -#: src/npctalk.cpp -msgid "I don't trust you enough to eat THISā€¦" -msgstr "" - -#: src/npctalk.cpp -msgid "It doesn't look like a good idea to consume thisā€¦" -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, that hit the spot." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "I need a %s to consume that!" -msgstr "Ā”Necesito un/a %s para consumir eso!" - -#: src/npctalk.cpp -msgid "Thanks, I feel better already." -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I used it." -msgstr "" - -#: src/npctalk.cpp -msgid "Offer what?" -msgstr "ĀæQuĆ© querĆ©s ofrecer?" - -#: src/npctalk.cpp -msgid "You have no items to offer." -msgstr "No tenĆ©s ningĆŗn objeto para ofrecer." - -#: src/npctalk.cpp -msgid "Changed your mind?" -msgstr "ĀæCambiaste tu parecer?" - -#: src/npctalk.cpp -msgid "How?" -msgstr "ĀæCĆ³mo?" - -#: src/npctalk.cpp -msgid "Are you insane!?" -msgstr "ĀæĀ”EstĆ”s loco!?" - -#: src/npctalk.cpp -msgid "Thanks, I'll wield that now." -msgstr "" - -#: src/npctalk.cpp -msgid " Should I take something off?" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "" -"My current weapon is better than this.\n" -"(new weapon value: %.1f vs %.1f)." -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I'll carry that now." -msgstr "" - -#: src/npctalk.cpp -msgid "I have no space to store it." -msgstr "No tengo lugar para guardarlo." - -#: src/npctalk.cpp -#, c-format -msgid "I can only store %s %s more." -msgstr "Solamente puedo guardar %s %s mĆ”s." - -#: src/npctalk.cpp -msgid "ā€¦or to store anything else for that matter." -msgstr "" - -#: src/npctalk.cpp -msgid "It is too heavy for me to carry." -msgstr "Es demasiado pesado para que lo pueda llevar." - #: src/npctalk_funcs.cpp msgid "Reward" msgstr "Recompensa" @@ -262734,13 +264464,15 @@ msgstr "" "Factor variable que determina la densidad de la generaciĆ³n de objetos." #: src/options.cpp -msgid "NPC spawn rate scaling factor" -msgstr "Factor variable de generaciĆ³n de PNJ" +msgid "Random NPC spawn time" +msgstr "" #: src/options.cpp -msgid "A scaling factor that determines density of dynamic NPC spawns." +msgid "" +"Baseline average number of days between random NPC spawns. Average duration" +" goes up with the number of NPCs already spawned. Set to 0 days to disable " +"random NPCs." msgstr "" -"Factor variable que determina la densidad de la generaciĆ³n dinĆ”mica de PNJ." #: src/options.cpp msgid "Monster evolution scaling factor" @@ -262877,37 +264609,6 @@ msgstr "" "Si estĆ” activado, se generan zombis en los refugios. Hace mucho mĆ”s difĆ­cil " "el comienzo del juego." -#: src/options.cpp -msgid "Static NPCs" -msgstr "PNJ estĆ”ticos" - -#: src/options.cpp -msgid "" -"If true, static NPCs will spawn at pre-defined locations. Requires world " -"reset." -msgstr "" - -#: src/options.cpp -msgid "Starting NPCs spawn" -msgstr "GeneraciĆ³n de PNJ al comienzo" - -#: src/options.cpp -msgid "" -"Determines whether starting NPCs should spawn, and if they do, how exactly." -msgstr "Determina si los PNJ del comienzo aparecen, y si aparecen, cĆ³mo." - -#: src/options.cpp -msgid "Scenario-based" -msgstr "Basado en el escenario" - -#: src/options.cpp -msgid "Random NPCs" -msgstr "PNJ aleatorios" - -#: src/options.cpp -msgid "If true, the game will randomly spawn NPCs during gameplay." -msgstr "Si estĆ” activado, se generarĆ”n PNJ aleatoriamente durante el juego." - #: src/options.cpp msgid "Mutations by radiation" msgstr "Mutaciones por radiaciĆ³n" @@ -264676,6 +266377,38 @@ msgstr "Ā”IntentĆ”s apagar el fuego que tenĆ©s encima!" msgid " attempts to put out the fire on them!" msgstr "Ā” intenta apagar el fuego que tiene encima!" +#: src/player.cpp +msgid "" +"Your broken limb significantly hampers your efforts to puting pressure on " +"the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s broken limb significantly hampers efforts of putting pressure on" +" the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"Your hands are too encumbred to effectivly put pressure on the bleeding " +"wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s hands are too encumbred to effectivly put pressure on the " +"bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "You attempt to put pressure on the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid " attempts to put pressure on the bleeding wound!" +msgstr "" + #: src/player.cpp #, c-format msgid "Your ground sonar detected a %1$s to the %2$s!" @@ -264950,34 +266683,6 @@ msgstr "Ā”No hay nada para recargar!" msgid "You don't have any %s to reload your %s!" msgstr "Ā”No tenĆ©s ningĆŗn %s para recargar tu %s!" -#: src/player.cpp -msgid "Can't wield spilt liquids." -msgstr "No podĆ©s empuƱar lĆ­quidos derramados." - -#: src/player.cpp -msgid "You need at least one arm to even consider wielding something." -msgstr "" - -#: src/player.cpp -#, c-format -msgid "The %s is preventing you from wielding the %s." -msgstr "" - -#: src/player.cpp -msgid "Something you are wearing hinders the use of both hands." -msgstr "" -"Algo de lo que tenĆ©s puesto te dificulta la utilizaciĆ³n de las dos manos." - -#: src/player.cpp -#, c-format -msgid "The %s can't be wielded with only one arm." -msgstr "El/a %s no puede ser empuƱado/a con una sola mano." - -#: src/player.cpp -#, c-format -msgid "You are too weak to wield %s with only one arm." -msgstr "Sos demasiado dĆ©bil para empuƱar %s con una sola mano." - #: src/player.cpp msgid "Keep hands free (off)" msgstr "Manos libres (no)" @@ -265163,15 +266868,6 @@ msgstr "Tu %s no tiene carga." msgid "Your %s isn't loaded." msgstr "Tu %s no estĆ” cargado." -#: src/player.cpp -#, c-format -msgid "You recover %i unused plutonium." -msgstr "RecuperĆ”s %i de plutonio sin utilizar." - -#: src/player.cpp -msgid "You can't remove partially depleted plutonium!" -msgstr "Ā”No podĆ©s quitar plutonio parcialmente agotado!" - #. ~ %1$s - gunmod, %2$s - gun. #: src/player.cpp #, c-format @@ -265311,25 +267007,6 @@ msgstr "" msgid "Your soporific inducer starts back up." msgstr "" -#: src/player.cpp -#, c-format -msgid "Your skill in %s has increased to %d!" -msgstr "Ā”Tu habilidad en %s se ha incrementado a %d!" - -#: src/player.cpp -#, c-format -msgid "You feel that %s tasks of this level are becoming trivial." -msgstr "SentĆ­s que las tareas de %s de este nivel se han vuelto algo trivial." - -#: src/player.cpp -#, c-format -msgid "This task is too simple to train your %s beyond %d." -msgstr "Esta tarea es demasiado simple para entrenar tu %s mĆ”s de %d." - -#: src/player.cpp -msgid " (empty)" -msgstr "" - #: src/player.cpp msgid "Wield what?" msgstr "ĀæQuĆ© querĆ©s empuƱar?" @@ -265385,6 +267062,10 @@ msgstr "EFECTOS" msgid "SPEED" msgstr "VELOCIDAD" +#: src/player_display.cpp +msgid "PROFICIENCIES" +msgstr "" + #: src/player_display.cpp #, c-format msgid "Swimming movement point cost: %+d\n" @@ -266248,6 +267929,149 @@ msgstr "" "Te disolvĆ©s en hermosos paroxismos de energĆ­a. La vida se desvanece de tu " "nebulosa y ya no existĆ­s mĆ”s." +#: src/player_hardcoded_effects.cpp +msgid "You bleed to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " bleeds to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your heart can't keep up the pace and fails!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks pale and you feel anxious and thirsty. Blood loss?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"Your pale skin is sweating, your heart beats fast and you feel restless. " +"Maybe you lost too much blood?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You're unsettlingly white, but your fingetips are bluish. You are agitated " +"and your heart is racing. Your blood loss must be serious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You are pale as a ghost, dripping wet from the sweat, and sluggish despite " +"your heart racing like a train. You are on a brink of colapse from effects " +"of a bood loss." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and lightheaded." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel tired and you breathe heavily." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are anxcious and cannot collect your thoughts." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are sweating profusely, but you feel cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You huff and puff. Your breath is rapid and shallow." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You drop to the ground, fighting to keep yourself conscious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your mind slips away." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You cannot breathe and your body gives out!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " gasps for air and dies!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your hands feel unusually cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your feet feel unusualy cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks very pale." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel weak. Where has your strength gone?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel feeble. A gust of wind could make you stumble." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "There is an overwhelming aura of tiredness inside of you." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Rest is what you want. Rest is what you need." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and can't coordinate movement of your feet." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your muscles are quivering." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You crave for ice. Dirt under your feet looks tasty too." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your whole mouth is sore, and your tongue is swollen." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel lightheaded. And a migrane follows." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your legs are restless. Urge to move them is so strong." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel like you'd sleep on a rock." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You gasp for air!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Can't breathe. Must rest." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You can't take it any more. Rest first, everything else later." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You must sit down for a moment. Just a moment." +msgstr "" + #. ~ %s is bodypart name. #: src/player_hardcoded_effects.cpp #, c-format @@ -266856,6 +268680,11 @@ msgstr "%s Retraso: %i" msgid "Turrets in range: %d/%d" msgstr "" +#: src/recipe.cpp +#, c-format +msgid "Proficiencies Used: %s" +msgstr "" + #: src/recipe.cpp msgid "none" msgstr "nada" @@ -267624,6 +269453,14 @@ msgstr "" msgid "You fall over!" msgstr "Ā”Te caĆ©s!" +#: src/suffer.cpp +msgid "Your tourniquet hurts you." +msgstr "" + +#: src/suffer.cpp +msgid " is hurting from the tourniquet." +msgstr "" + #: src/suffer.cpp #, c-format msgid "Your radiation badge changes from %1$s to %2$s!" @@ -267643,6 +269480,201 @@ msgstr "" msgid "You feel the water burning your skin." msgstr "" +#: src/talker_avatar.cpp +#, c-format +msgid "%s can't sell you any %s" +msgstr "" + +#: src/talker_avatar.cpp +#, c-format +msgid "%1$s gives you %2$s." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%d.%d miles." +msgstr "%d.%d millas." + +#: src/talker_npc.cpp +#, c-format +msgid "%d foot." +msgid_plural "%d feet." +msgstr[0] "%d pie." +msgstr[1] "%d pies." + +#: src/talker_npc.cpp +#, c-format +msgid "%s is fleeing from you!" +msgstr "Ā”%s se estĆ” escapando de vos!" + +#. ~Skill name: current level (exercise) -> next level (exercise) (cost in +#. dollars) +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s ( cost $%d )" +msgstr "%s ( cuesta $%d )" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: 1 hour lesson (cost %s)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: teaching spell knowledge (cost %s)" +msgstr "" + +#: src/talker_npc.cpp +msgid "I don't trust you enough to eat THISā€¦" +msgstr "" + +#: src/talker_npc.cpp +msgid "It doesn't look like a good idea to consume thisā€¦" +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, that hit the spot." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "I need a %s to consume that!" +msgstr "Ā”Necesito un/a %s para consumir eso!" + +#: src/talker_npc.cpp +msgid "Thanks, I feel better already." +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I used it." +msgstr "" + +#: src/talker_npc.cpp +msgid "Offer what?" +msgstr "ĀæQuĆ© querĆ©s ofrecer?" + +#: src/talker_npc.cpp +msgid "You have no items to offer." +msgstr "No tenĆ©s ningĆŗn objeto para ofrecer." + +#: src/talker_npc.cpp +msgid "Changed your mind?" +msgstr "ĀæCambiaste tu parecer?" + +#: src/talker_npc.cpp +msgid "How?" +msgstr "ĀæCĆ³mo?" + +#: src/talker_npc.cpp +msgid "Are you insane!?" +msgstr "ĀæĀ”EstĆ”s loco!?" + +#: src/talker_npc.cpp +msgid "Thanks, I'll wield that now." +msgstr "" + +#: src/talker_npc.cpp +msgid " Should I take something off?" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "" +"My current weapon is better than this.\n" +"(new weapon value: %.1f vs %.1f)." +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I'll carry that now." +msgstr "" + +#: src/talker_npc.cpp +msgid "I have no space to store it." +msgstr "No tengo lugar para guardarlo." + +#: src/talker_npc.cpp +#, c-format +msgid "I can only store %s %s more." +msgstr "Solamente puedo guardar %s %s mĆ”s." + +#: src/talker_npc.cpp +msgid "ā€¦or to store anything else for that matter." +msgstr "" + +#: src/talker_npc.cpp +msgid "It is too heavy for me to carry." +msgstr "Es demasiado pesado para que lo pueda llevar." + +#: src/talker_npc.cpp +msgid "&You can't make anything out." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "Str %d - %d" +msgstr "Fue %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Dex %d - %d" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid " Int %d - %d" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid " Per %d - %d" +msgstr "" + +#: src/talker_npc.cpp +msgid "Dead tired" +msgstr "Muerto/a de cansancio" + +#: src/talker_npc.cpp +msgid "Not tired" +msgstr "Sin cansancio" + +#: src/talker_npc.cpp +msgid ". Will need sleep in " +msgstr "" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need water in " +msgstr "" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Thirsty" +msgstr "" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need food in " +msgstr "" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Hungry" +msgstr "" + #: src/teleport.cpp msgid "You feel a strange, inwards force." msgstr "" @@ -269464,6 +271496,34 @@ msgstr "" msgid "pile-up" msgstr "pila" +#: src/vehicle_move.cpp +msgid "Smart controller does not support flying vehicles." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller detects only a single controllable engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller is designed to control more than one engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller does not support more than five engines." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller is shutting down." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller failed to start an engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller optimizes engine state." +msgstr "" + #: src/vehicle_move.cpp #, c-format msgid "The %s is too leaky!" @@ -269840,6 +271900,11 @@ msgctxt "electronics menu option" msgid "water purifier" msgstr "" +#: src/vehicle_use.cpp +msgctxt "electronics menu option" +msgid "smart controller" +msgstr "" + #: src/vehicle_use.cpp msgid "Turn off camera system" msgstr "Apagar sistema de cĆ”maras" @@ -270478,50 +272543,18 @@ msgstr "" msgid "You purify the contents of the %1$s's %2$s" msgstr "PurificĆ”s el contenido del/a %2$s del/a %1$s" -#: src/weather.cpp -msgid "You hear a distant rumble of thunder." -msgstr "EscuchĆ”s el retumbar distante de un trueno." - -#: src/weather.cpp -msgid "You hear a rumble of thunder from above." -msgstr "EscuchĆ”s el retumbar de un trueno desde arriba." - -#: src/weather.cpp -msgid "A flash of lightning illuminates your surroundings!" -msgstr "Ā”Un rayo de luz ilumina tus alrededores!" - #: src/weather.cpp #, c-format -msgid "Your %s protects you from the acidic drizzle." -msgstr "Tu %s te protege de la llovizna Ć”cida." - -#: src/weather.cpp -msgid "Your clothing protects you from the acidic drizzle." -msgstr "Tu ropa te protege de la llovizna Ć”cida." - -#: src/weather.cpp -msgid "Your power armor protects you from the acidic drizzle." -msgstr "Tu armadura de poder te protege de la llovizna Ć”cida." - -#: src/weather.cpp -msgid "The acid rain stings, but is mostly harmless for nowā€¦" +msgid "Your %s protects you from the weather." msgstr "" #: src/weather.cpp -msgid "Your umbrella protects you from the acid rain." -msgstr "Tu paraguas te protege de la lluvia Ć”cida." - -#: src/weather.cpp -msgid "Your clothing protects you from the acid rain." -msgstr "Tu ropa te protege de la lluvia Ć”cida." - -#: src/weather.cpp -msgid "Your power armor protects you from the acid rain." -msgstr "Tu armadura de poder te protege de la lluvia Ć”cida." +msgid "Your clothing protects you from the weather." +msgstr "" #: src/weather.cpp -msgid "The acid rain burns!" -msgstr "Ā”La lluvia Ć”cida te quema!" +msgid "Your power armor protects you from the weather." +msgstr "" #: src/weather.cpp msgid "Monday" @@ -270696,54 +272729,6 @@ msgstr "" msgid "The weather changed to %s!" msgstr "Ā”El clima cambiĆ³ a %s!" -#: src/weather_data.cpp -msgid "Clear" -msgstr "Despejado" - -#: src/weather_data.cpp -msgid "Sunny" -msgstr "Soleado" - -#: src/weather_data.cpp -msgid "Cloudy" -msgstr "Nublado" - -#: src/weather_data.cpp -msgid "Light Drizzle" -msgstr "" - -#: src/weather_data.cpp -msgid "Drizzle" -msgstr "Llovizna" - -#: src/weather_data.cpp -msgid "Rain" -msgstr "Lluvia" - -#: src/weather_data.cpp -msgid "Thunder Storm" -msgstr "Lluvia con truenos" - -#: src/weather_data.cpp -msgid "Acidic Drizzle" -msgstr "Llovizna Ć”cida" - -#: src/weather_data.cpp -msgid "Acid Rain" -msgstr "Lluvia Ć”cida" - -#: src/weather_data.cpp -msgid "Flurries" -msgstr "Nevisca" - -#: src/weather_data.cpp -msgid "Snowing" -msgstr "Nieve" - -#: src/weather_data.cpp -msgid "Snowstorm" -msgstr "Tormenta de nieve" - #: src/wish.cpp msgid "Nonvalid" msgstr "No vĆ”lido" @@ -270934,6 +272919,19 @@ msgstr "Elegir mundo para entrar al juego" msgid "last world info" msgstr "" +#: src/worldfactory.cpp +msgid "MISSING MODS" +msgstr "" + +#: src/worldfactory.cpp +msgid "OBSOLETE MODS" +msgstr "" + +#: src/worldfactory.cpp +#, c-format +msgid " [%s]" +msgstr "" + #: src/worldfactory.cpp msgid " ACTIVE WORLD MODS " msgstr "MODS ACTIVOS DE MUNDO" diff --git a/lang/po/ja.po b/lang/po/ja.po index c9cfb1371ab6c..fdab6ecdf4035 100644 --- a/lang/po/ja.po +++ b/lang/po/ja.po @@ -32,7 +32,7 @@ msgid "" msgstr "" "Project-Id-Version: cataclysm-dda 0.E\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-07-08 10:07+0800\n" +"POT-Creation-Date: 2020-07-16 21:36+0800\n" "PO-Revision-Date: 2018-04-26 14:47+0000\n" "Last-Translator: Pigmentblue15, 2020\n" "Language-Team: Japanese (https://www.transifex.com/cataclysm-dda-translators/teams/2217/ja/)\n" @@ -6646,6 +6646,56 @@ msgid "" "designed to fit Huge survivors." msgstr "適切ćŖē®‡ę‰€ć§éŖØ悒ę”Æ恈å›ŗå®šć™ć‚‹é“å…·ć§ć™ć€‚å¤§ęŸ„ćŖäŗŗć«ć‚‚ćƒ•ć‚£ćƒƒćƒˆć™ć‚‹ē‰¹åˆ„č£½ć§ć™ć€‚" +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm)" +msgid_plural "tourniquets (arm)" +msgstr[0] "ę­¢č”€åøÆ(腕)" + +#. ~ Use action menu_text for {'str': 'tourniquet (arm)', 'str_pl': +#. 'tourniquets (arm)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (arm XL)', 'str_pl': +#. 'tourniquets (arm XL)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (leg)', 'str_pl': +#. 'tourniquets (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "Adjust" +msgstr "ēø›ć‚‹" + +#. ~ Use action msg for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'}. +#. ~ Use action msg for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'}. +#. ~ Use action msg for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "You adjust the tourniquet." +msgstr "ę­¢č”€åøÆ悒ä½æć„ć¾ć—ćŸć€‚" + +#. ~ Description for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'} +#. ~ Description for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'} +#. ~ Description for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'} +#: lang/json/ARMOR_from_json.py +msgid "" +"First aid device used to apply pressure to a limb or extremity in order to " +"limit blood flow. Should be employed only to manage heavy bleedings, " +"because prolonged use will harm the limb. It can be adjusted in size to fit" +" different limbs." +msgstr "" +"å››č‚¢ć‚„ę‰‹č¶³ć‚’ēø›ć£ć¦č”€ęµć‚’åˆ¶é™ć™ć‚‹åæœę€„処ē½®ē”Øć®é“å…·ć§ć™ć€‚é•·ę™‚é–“ä½æ恄ē¶šć‘ć‚‹ćØå››č‚¢ćŒå£Šę­»ć™ć‚‹ć®ć§ć€é‡åŗ¦ć®å‡ŗč”€ć‚’ę­¢ć‚ć‚‹å “åˆć«ć®ćæä½æć„ć¾ć™ć€‚éƒØä½ć®å¤Ŗ恕恫åæœć˜ć¦åøÆ恮長恕悒čŖæę•“ć§ćć¾ć™ć€‚" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm XL)" +msgid_plural "tourniquets (arm XL)" +msgstr[0] "XLę­¢č”€åøÆ(腕)" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (leg)" +msgid_plural "tourniquets (leg)" +msgstr[0] "ę­¢č”€åøÆ(脚)" + #: lang/json/ARMOR_from_json.py msgid "blindfold" msgid_plural "blindfolds" @@ -36393,6 +36443,19 @@ msgid "" msgstr "" "ćƒ‡ć‚­ć‚¹ćƒˆćƒ­ć‚¢ćƒ³ćƒ•ć‚§ć‚æćƒŸćƒ³å”©ćØć‚¢ćƒ³ćƒ•ć‚§ć‚æćƒŸćƒ³å”©ć‚’ę··åˆć—ćŸē‰©ć§ć™ć€‚ADHD恮適åæœč–¬ć«ęŒ‡å®šć•ć‚Œć¦ć„ć¾ć™ć€‚éžåøøć«é«˜ć„ä¾å­˜ę€§ćŒć‚ć‚Šć€é£Ÿę¬²ćŒęŠ‘åˆ¶ć•ć‚Œć¾ć™ć€‚" +#: lang/json/COMESTIBLE_from_json.py +msgid "adhesive bandage" +msgid_plural "adhesive bandages" +msgstr[0] "ēµ†å‰µč†" + +#. ~ Description for {'str': 'adhesive bandage'} +#: lang/json/COMESTIBLE_from_json.py +msgid "" +"A set of small medical dressings, each made of a piece of sterile cloth and " +"a sticky tape, used for small injuries not serious enough to require a full-" +"size bandage." +msgstr "ę»…čŒć—ćŸåøƒćØē²˜ē€ćƒ†ćƒ¼ćƒ—ć‚’ēµ„ćæåˆć‚ć›ćŸć€å°ć•ćŖåæœę€„処ē½®ē”Øå“ć§ć™ć€‚åŒ…åøÆć‚’å·»ćć»ć©ę·±åˆ»ć§ćÆćŖć„č»½ć„ę€Ŗęˆ‘ć®ę²»ē™‚恫ä½æć„ć¾ć™ć€‚" + #: lang/json/COMESTIBLE_from_json.py msgid "syringe of adrenaline" msgid_plural "syringes of adrenaline" @@ -36470,8 +36533,10 @@ msgstr[0] "包åøÆ" #. ~ Description for {'str': 'bandage'} #: lang/json/COMESTIBLE_from_json.py -msgid "Simple cloth bandages. Used for healing small amounts of damage." -msgstr "ć‚·ćƒ³ćƒ—ćƒ«ćŖåøƒć®åŒ…åøÆć§ć™ć€‚ćƒ€ćƒ”ćƒ¼ć‚øć‚’å°‘ć—å›žå¾©ć—ć¾ć™ć€‚" +msgid "" +"Simple cloth bandages. Used for stopping bloodloss and protecting wounds " +"from external factors." +msgstr "ć‚·ćƒ³ćƒ—ćƒ«ćŖåøƒć®åŒ…åøÆć§ć™ć€‚å¤±č”€ć‚’ę­¢ć‚ć€å¤–ēš„č¦å› ć‹ć‚‰å‚·å£ć‚’äæč­·ć™ć‚‹ćŸć‚ć«ä½æć„ć¾ć™ć€‚" #: lang/json/COMESTIBLE_from_json.py msgid "makeshift bandage" @@ -45663,9 +45728,9 @@ msgstr[0] "ē“ ęęŸ(ęœØꝐ)" #. planks'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten construction planks securely lashed together with a rope. Disassemble " -"to unpack." -msgstr "10Ꞛ恮å»ŗčØ­ē”ØęœØęć‚’ćƒ­ćƒ¼ćƒ—ć§å›ŗå®šć—ćŸć‚‚ć®ć§ć™ć€‚åˆ†č§£ć—ć¦ä½æć„ć¾ć—ć‚‡ć†ć€‚" +"Ten construction planks securely tied together for easier transport. " +"Disassemble to untie them." +msgstr "10Ꞛ恮å»ŗčØ­ē”ØęœØęć‚’ćƒ­ćƒ¼ćƒ—ć§å›ŗå®šć—ć€ęŒć”é‹ć³ć‚„ć™ćć—ćŸć‚‚ć®ć§ć™ć€‚åˆ†č§£ć™ć‚‹ćØćƒ­ćƒ¼ćƒ—ć‚’č§£ćć¾ć™ć€‚" #: lang/json/GENERIC_from_json.py msgid "bundle of stout branches" @@ -45676,9 +45741,22 @@ msgstr[0] "ē“ ęęŸ(頑äøˆćŖēŸ­ęž)" #. stout branches'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten stout branches securely lashed together with a rope. Disassemble to " -"untie them." -msgstr "10ęœ¬ć®é ‘äøˆćŖēŸ­ęžć‚’ćƒ­ćƒ¼ćƒ—ć§å›ŗå®šć—ćŸć‚‚ć®ć§ć™ć€‚åˆ†č§£ć—ć¦ä½æć„ć¾ć—ć‚‡ć†ć€‚" +"Ten stout branches securely tied together for easier transport. Disassemble" +" to untie them." +msgstr "10ęœ¬ć®é ‘äøˆćŖēŸ­ęžć‚’ćƒ­ćƒ¼ćƒ—ć§å›ŗå®šć—ć€ęŒć”é‹ć³ć‚„ć™ćć—ćŸć‚‚ć®ć§ć™ć€‚åˆ†č§£ć™ć‚‹ćØćƒ­ćƒ¼ćƒ—ć‚’č§£ćć¾ć™ć€‚" + +#: lang/json/GENERIC_from_json.py +msgid "bundle of long stout branches" +msgid_plural "bundles of long stout branches" +msgstr[0] "ē“ ęęŸ(頑äøˆćŖé•·ęž)" + +#. ~ Description for {'str': 'bundle of long stout branches', 'str_pl': +#. 'bundles of long stout branches'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Five long stout branches securely tied together for easier transport. " +"Disassemble to untie them." +msgstr "5ęœ¬ć®é ‘äøˆćŖé•·ęžć‚’ćƒ­ćƒ¼ćƒ—ć§å›ŗå®šć—ć€ęŒć”é‹ć³ć‚„ć™ćć—ćŸć‚‚ć®ć§ć™ć€‚åˆ†č§£ć™ć‚‹ćØćƒ­ćƒ¼ćƒ—ć‚’č§£ćć¾ć™ć€‚" #: lang/json/GENERIC_from_json.py msgid "t-substrate sample" @@ -47563,6 +47641,11 @@ msgid "" "gutted for parts." msgstr "å£Šć‚ŒćŸē„”äŗŗ車äø”恧恙怂ē “ęć—ć¦å†…éƒØć®ę¶²ä½“ćŒę¼ć‚Œå‡ŗć¦ć„ć¾ć™ć€‚éƒØå“ć‚’å–ć‚Šå¤–ć›ćć†ć§ć™ć€‚" +#: lang/json/GENERIC_from_json.py +msgid "broken laser turret" +msgid_plural "broken laser turrets" +msgstr[0] "å£Šć‚ŒćŸćƒ¬ćƒ¼ć‚¶ćƒ¼ć‚æ惬惃惈" + #: lang/json/GENERIC_from_json.py msgid "fire brick" msgid_plural "fire bricks" @@ -48114,11 +48197,6 @@ msgid "" msgstr "" "ć“ć®ć‚½ćƒ¼ćƒ©ćƒ¼ćƒ‘ćƒćƒ«ćÆę˜Žć‚‰ć‹ć«ęœ€å…ˆē«Æꊀ蔓恮ēµę™¶ć§ć‚ć‚Šć€čŽ«å¤§ćŖé›»åŠ›ć‚’ä¾›ēµ¦ć™ć‚‹ć§ć—ć‚‡ć†ć€‚ć‚½ćƒ¼ćƒ©ćƒ¼ć‚»ćƒ«ć«ć‚ćŸć‚‹é¢ćÆäøę€č­°ćŖē“ ęć§č¦†ć‚ć‚Œć¦ćŠć‚Šć€ć„ć‹ć«ć‚‚å£Šć‚Œć‚„ć™ćć†ć«č¦‹ćˆć¾ć™ć€‚ć‚¬ćƒ©ć‚¹ęæē­‰ć§č£œå¼·ć™ć‚‹ć®ć‚‚恩恆悄悉ē„”ē†ćć†ć§ć™ć€‚" -#: lang/json/GENERIC_from_json.py -msgid "broken laser turret" -msgid_plural "broken laser turrets" -msgstr[0] "å£Šć‚ŒćŸćƒ¬ćƒ¼ć‚¶ćƒ¼ć‚æ惬惃惈" - #: lang/json/GENERIC_from_json.py msgid "TX-5LR Laser Cannon" msgid_plural "TX-5LR Laser Cannons" @@ -48941,7 +49019,7 @@ msgstr[0] "悵ćƒÆćƒ¼ēØ®ć‚¹ć‚æćƒ¼ć‚æćƒ¼" #. ~ Use action msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py msgid "" -"After feeding it and caring for it for weeks, your sourdough starter is " +"After feeding it and caring for it for a week, your sourdough starter is " "finally ready for the big leagues." msgstr "ē™ŗé…µćŒå§‹ć¾ć£ć¦ę•°é€±é–“ēµŒć£ćŸć‚µćƒÆćƒ¼ēØ®ć§ć™ć€‚å¤§ććč†Ø悉悀ęŗ–å‚™ćŒę•“ć„ć¾ć—ćŸć€‚" @@ -48978,8 +49056,8 @@ msgstr "ć¾ć ć‚µćƒÆćƒ¼ēØ®ć®ęŗ–å‚™ćŒę•“ć£ć¦ć„ć¾ć›ć‚“ć€‚" #: lang/json/GENERIC_from_json.py msgid "" "This jar contains a floury paste with sourdough starter mixed in. It needs " -"a few hours to recover its strength before it can be used again." -msgstr "ē“¶ć®äø­ć«ćÆē²‰å”—ć‚Œć®ćƒšćƒ¼ć‚¹ćƒˆćŒå…„ć£ć¦ć„ć¾ć™ć€‚ē”Ÿåœ°ćØ恗恦ä½æ恄ē‰©ć«ćŖ悋恫ćÆę•°ę™‚é–“å¾…ć¤åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚" +"a day to recover its strength before it can be used again." +msgstr "ē“¶ć®äø­ć«ćÆē²‰ć£ć½ć„ćƒšćƒ¼ć‚¹ćƒˆćŒå…„ć£ć¦ć„ć¾ć™ć€‚ē”Ÿåœ°ćØ恗恦ä½æ恄ē‰©ć«ćŖ悋恫ćÆę•°ę—„å¾…ć¤åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚" #: lang/json/GENERIC_from_json.py msgid "sourdough starter" @@ -49026,10 +49104,25 @@ msgstr[0] "ꕑꀄē®±" #. ~ Description for {'str': 'first aid kit'} #: lang/json/GENERIC_from_json.py msgid "" -"A full medical kit, with bandages, local anesthetics, and rapid healing " -"agents. Used for healing large amounts of damage. Disassemble to get its " -"content." -msgstr "包åøÆć€å±€ę‰€éŗ»é…”ć€å³åŠ¹ę€§ć®ę²»ē™’č–¬ćŒęƒć£ćŸåŒ»ē™‚ć‚­ćƒƒćƒˆć§ć™ć€‚å¤§ććŖćƒ€ćƒ”ćƒ¼ć‚øć‚’å›žå¾©ć™ć‚‹éš›ć«å½¹ē«‹ć”ć¾ć™ć€‚åˆ†č§£ć™ć‚‹ćØäø­čŗ«ć‚’å–ć‚Šå‡ŗć—ć¾ć™ć€‚" +"A typical universal first aid kit, one you'd see in a car or in a household." +" It contains a variety of common medical items stored in case of accidents " +"and injuries. Disassemble to get its content." +msgstr "č»Šå†…ć‚„äø€čˆ¬å®¶åŗ­ć«ē½®ć‹ć‚Œć¦ć„悋态äø€čˆ¬ēš„ćŖꕑꀄē®±ć§ć™ć€‚äŗ‹ę•…ć‚„ę€Ŗęˆ‘ć«å‚™ćˆć¦ć€äø€čˆ¬ēš„ćŖ医ē™‚å“ćŒäæē®”ć—ć¦ć‚ć‚Šć¾ć™ć€‚åˆ†č§£ć™ć‚‹ćØäø­čŗ«ć‚’å–ć‚Šå‡ŗć—ć¾ć™ć€‚" + +#: lang/json/GENERIC_from_json.py +msgid "IFAK" +msgid_plural "IFAKs" +msgstr[0] "č»ē”Øåæœę€„処ē½®ć‚­ćƒƒćƒˆ" + +#. ~ Description for {'str': 'IFAK'} +#: lang/json/GENERIC_from_json.py +msgid "" +"An IFAK, or individual first aid kit, is a specialized set of wound " +"dressings and accessories, and being of military origin focuses on combat " +"trauma and preventing blood loss. Disassemble to get its content." +msgstr "" +"individual first aid " +"kit(個äŗŗē”Øåæœę€„処ē½®ć‚­ćƒƒćƒˆ)态ē•„恗恦IFAKćØć‚‚å‘¼ć°ć‚Œć‚‹ć€å‰µå‚·č¢«č¦†ęćŖć©ćŒå…„ć£ćŸē‰¹ę®ŠćŖę•‘ę€„ć‚­ćƒƒćƒˆć§ć™ć€‚äø»ć«č»ć§ä½æć‚ć‚Œć¦ć„ć‚‹ćŸć‚ć€ęˆ¦é—˜ć§ć®å¤–å‚·ę²»ē™‚ćØę­¢č”€ć«é‡ē‚¹ćŒē½®ć‹ć‚Œć¦ć„ć¾ć™ć€‚" #: lang/json/GENERIC_from_json.py msgid "MRE" @@ -49642,17 +49735,17 @@ msgstr "锎恋悉äøŠćŒę¶ˆå¤±ć—ćŸę­»ä½“ć§ć™ć€‚ä½•ćŒåŽŸå› ć§ć“ć†ćŖć£ćŸ #: lang/json/GENERIC_from_json.py msgid "broken exodii worker" msgid_plural "broken exodii workers" -msgstr[0] "" +msgstr[0] "å£Šć‚ŒćŸć‚Øć‚Æć‚¾ćƒ‡ć‚£ä½œę„­ćƒ­ćƒœćƒƒćƒˆ" #. ~ Description for broken exodii worker #: lang/json/GENERIC_from_json.py msgid "A broken exodii worker. It's possible it could be gutted for parts." -msgstr "" +msgstr "悂ćÆć‚„ä½•ć®éŸ³ć‚‚ē«‹ć¦ćŖć„ć€å£Šć‚ŒćŸć‚Øć‚Æć‚¾ćƒ‡ć‚£ä½œę„­ćƒ­ćƒœćƒƒćƒˆć§ć™ć€‚éƒØå“ć‚’å–ć‚Šå¤–ć›ćć†ć§ć™ć€‚" #: lang/json/GENERIC_from_json.py msgid "broken exodii quadruped" msgid_plural "broken exodii quadrupeds" -msgstr[0] "" +msgstr[0] "å£Šć‚ŒćŸć‚Øć‚Æć‚¾ćƒ‡ć‚£å››č¶³ę­©č”Œćƒ­ćƒœćƒƒćƒˆ" #. ~ Description for broken exodii quadruped #: lang/json/GENERIC_from_json.py @@ -49660,12 +49753,12 @@ msgid "" "A broken exodii walker. Still looks intimidating despite being permanently " "inoperative, possibly due to the sheer size and mass. Could be gutted for " "parts." -msgstr "" +msgstr "å£Šć‚ŒćŸć‚Øć‚Æć‚¾ćƒ‡ć‚£ćƒ­ćƒœćƒƒćƒˆć§ć™ć€‚ę°øä¹…ć«å‹•ä½œäøčƒ½ć§ć‚ć‚‹ć«ć‚‚ć‹ć‹ć‚ć‚‰ćšć€ćć®å¤§ćć•ć‚„č³Ŗé‡ć®ć›ć„ć§å؁圧ēš„ć«č¦‹ćˆć¾ć™ć€‚éƒØå“ć‚’å–ć‚Šå¤–ć›ćć†ć§ć™ć€‚" #: lang/json/GENERIC_from_json.py msgid "broken exodii turret" msgid_plural "broken exodii turrets" -msgstr[0] "" +msgstr[0] "å£Šć‚ŒćŸć‚Øć‚Æć‚¾ćƒ‡ć‚£ć‚æ惬惃惈" #. ~ Description for broken exodii turret #: lang/json/GENERIC_from_json.py @@ -49673,19 +49766,19 @@ msgid "" "A broken exodii turret. Still looks intimidating despite being permanently " "inoperative, possibly due to the sheer size and mass. Could be gutted for " "parts." -msgstr "" +msgstr "å£Šć‚ŒćŸć‚Øć‚Æć‚¾ćƒ‡ć‚£ć‚æćƒ¬ćƒƒćƒˆć§ć™ć€‚ę°øä¹…ć«å‹•ä½œäøčƒ½ć§ć‚ć‚‹ć«ć‚‚ć‹ć‹ć‚ć‚‰ćšć€ćć®å¤§ćć•ć‚„č³Ŗé‡ć®ć›ć„ć§å؁圧ēš„ć«č¦‹ćˆć¾ć™ć€‚éƒØå“ć‚’å–ć‚Šå¤–ć›ćć†ć§ć™ć€‚" #: lang/json/GENERIC_from_json.py msgid "broken exodii balloon-drone" msgid_plural "broken exodii balloon-drones" -msgstr[0] "" +msgstr[0] "å£Šć‚ŒćŸē‹™ę’ƒćƒ‰ćƒ­ćƒ¼ćƒ³" #. ~ Description for broken exodii balloon-drone #: lang/json/GENERIC_from_json.py msgid "" "A broken balloon drone. The balloon has been shredded, but most of the " "chassis is still intact. Could be gutted for parts." -msgstr "" +msgstr "å£Šć‚ŒćŸē‹™ę’ƒćƒ‰ćƒ­ćƒ¼ćƒ³ć§ć™ć€‚ę°—ēƒćÆå¼•ćč£‚ć‹ć‚Œć¦ć„ć¾ć™ćŒć€éŖØēµ„ćæć«ęå‚·ćÆ恻ćØć‚“ć©ć‚ć‚Šć¾ć›ć‚“ć€‚éƒØå“ć‚’å–ć‚Šå¤–ć›ćć†ć§ć™ć€‚" #: lang/json/GENERIC_from_json.py msgid "ammo belt linkage" @@ -53390,10 +53483,10 @@ msgstr "" #: lang/json/GENERIC_from_json.py msgid "inscribed metal plates" -msgid_plural "inscribed metal platess" +msgid_plural "inscribed metal plates" msgstr[0] "é‡‘å±žč£½ć®č£…ē½®" -#. ~ Description for {'str': 'inscribed metal plates'} +#. ~ Description for {'str_sp': 'inscribed metal plates'} #: lang/json/GENERIC_from_json.py msgid "" "This device looks electronic, but is unfamiliar. It is a series of tightly " @@ -53431,6 +53524,36 @@ msgid "" msgstr "" "銅ē·šć®ć‚ˆć†ćŖē‰©ć‚’å·»ć„ćŸć‚³ć‚¤ćƒ«ćØćƒ”ć‚¹ćƒˆćƒ³ćŒä»˜ć„ć¦ć„ć‚‹ćŸć‚ć€ęć‚‰ććƒ¢ćƒ¼ć‚æćƒ¼ć‚„ē™ŗé›»ę©Ÿć®äø€ēØ®ć ćØč€ƒćˆć‚‰ć‚Œć¾ć™ć€‚ä»Šć¾ć§ć«č¦‹ćŸć“ćØ悂ćŖć„ćƒ‡ć‚¶ć‚¤ćƒ³ć®ćŸć‚ć€ć©ć®ć‚ˆć†ć«å‹•ć‹ć™ć®ć‹č¦‹å½“ć‚‚ć¤ćć¾ć›ć‚“ć€‚" +#: lang/json/GENERIC_from_json.py +msgid "engraved parabolic dish" +msgid_plural "engraved parabolic dishes" +msgstr[0] "č£…é£¾å††ē›¤" + +#. ~ Description for {'str': 'engraved parabolic dish', 'str_pl': 'engraved +#. parabolic dishes'} +#: lang/json/GENERIC_from_json.py +msgid "" +"This hefty parabolic dish is engraved with an unrecognizable pattern of " +"symbols that might, at a guess, be some sort of circuitry pattern - or maybe" +" a religious incantation." +msgstr "" +"ćƒ‘ćƒ©ćƒœćƒ©ć‚¢ćƒ³ćƒ†ćƒŠć®ć‚ˆć†ćŖå½¢ēŠ¶ć®é ‘äøˆćŖ円ē›¤ć®č”Øé¢ć«ć€ä½•ć‚‰ć‹ć®å›žč·Æ恋态恂悋恄ćÆå®—ę•™ēš„ćŖå‘Ŗę–‡ć®ć‚ˆć†ć«ć‚‚č¦‹ćˆć‚‹ć€č¦‹ćŸć“ćØ悂ćŖ恄ē“‹ę§˜ćŒåˆ»ć¾ć‚Œć¦ć„ć¾ć™ć€‚" + +#: lang/json/GENERIC_from_json.py +msgid "oblong device" +msgid_plural "oblong devices" +msgstr[0] "ę„•å††å½¢ć®č£…ē½®" + +#. ~ Description for {'str': 'oblong device'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Perfectly smooth, cool to the touch, and a dull blue-grey colour, this looks" +" almost like a perfect riverstone at first glance. Its artificial nature is" +" betrayed on closer inspection by a network of intricate patterns visible as" +" a slight difference in the reflection of light off its surface." +msgstr "" +"鈍恄青ē°č‰²ć‚’ć—ćŸć€č”Øé¢ć«å‚·äø€ć¤ćŖ恄껑悉恋ćŖē‰©ä½“恧恙怂ꉋ触悊ćÆå†·ćŸćć€äø€č¦‹ć™ć‚‹ćØå·ć§ę‹¾ćˆć‚‹ē¶ŗéŗ—ćŖēŸ³ć®ć‚ˆć†ć«ć‚‚č¦‹ćˆć¾ć™ćŒć€ć‚ˆć‚Šę³Øę„ę·±ćč¦³åÆŸć™ć‚‹ćØ态č”Øé¢ć«å…‰ćŒåå°„ć—ćŸę™‚ć«č¤‡é›‘ćŖęØ”ę§˜ćŒęµ®ć‹ć³ć€ć“ć‚ŒćŒäŗŗå·„ē‰©ć§ć‚悋恓ćØćŒåˆ†ć‹ć‚Šć¾ć™ć€‚" + #: lang/json/GENERIC_from_json.py msgid "sheet of glass" msgid_plural "sheets of glass" @@ -63127,6 +63250,22 @@ msgid "" msgstr "" "č¦³ęø¬ę°—ēƒćØć‚ÆćƒÆćƒƒćƒ‰ćƒ­ćƒ¼ć‚æćƒ¼ć‚’ēµ„ćæåˆć‚ć›ćŸć‚ˆć†ćŖå§æć®ć€å„‡å¦™ćŖę©Ÿę¢°ć§ć™ć€‚ęœ¬ä½“ćØę€ć—ćć‚·ćƒ³ćƒ—ćƒ«ćŖē®±ć®äø‹ć«ćÆć€ćƒ©ć‚¤ćƒ•ćƒ«ć‚’č£…å‚™ć—ćŸå°åž‹ć®å¤šé–¢ēÆ€č…•ćŒåŠć‚‹ć•ć‚Œć¦ć„ć¾ć™ć€‚ćƒ—ćƒ­ćƒšćƒ©ćŒäø€ēž¬čµ·å‹•ć—ćŸå¾Œć™ćć«åœę­¢ć—ć€ę°—ęµć‚’ć‚‚ć®ćØ悂恗ćŖ恄恻ćØć‚“ć©é™ę­¢ć—ćŸēŠ¶ę…‹ć‚’ē¶­ęŒć—ć¦ć„ć¾ć™ć€‚é›»ęŗćŒåˆ‡ć‚Œć‚‹ć¾ć§ć‹ćŖć‚Šé•·ćē©ŗäø­ć«ē•™ć¾ć£ć¦ć„ć‚‰ć‚Œćć†ć§ć™ć€‚" +#: lang/json/MONSTER_from_json.py +msgid "feral human" +msgid_plural "feral humans" +msgstr[0] "ćƒ•ć‚§ćƒ©ćƒ«ćƒ»ćƒ’ćƒ„ćƒ¼ćƒžćƒ³" + +#. ~ Description for {'str': 'feral human'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pupils dilated and what remains to be seen of the iris and sclera are " +"bloodshot. It still breathes but the zombies treat it like one of them." +msgstr "ēž³å­”ćŒę‹”å¤§ć—ć€č™¹å½©ć‚„ē™½ē›®ćÆå……č”€ć—ć¦ć„ć¾ć™ć€‚ć¾ć å‘¼åøć—ć¦ć„ć¾ć™ćŒć€ć‚¾ćƒ³ćƒ“ćÆ仲間ćØć—ć¦ę‰±ć£ć¦ć„ć‚‹ć‚ˆć†ć§ć™ć€‚" + +#: lang/json/MONSTER_from_json.py +msgid "They throw a loose brick at you!" +msgstr "ćƒ¬ćƒ³ć‚¬ć‚’ęŠ•ć’ć¤ć‘ć¦ćć¾ć—ćŸļ¼" + #: lang/json/MONSTER_from_json.py msgid "alpha razorclaw" msgid_plural "alpha razorclaws" @@ -66572,6 +66711,20 @@ msgid "" "of infesting sewer lines." msgstr "地äø‹ē”Ÿę“»ć‚’ē¶šć‘ć‚‹ć†ć”ć«ę·”é»„č‰²ć«å¤‰č‰²ć—ćŸć€ćƒ”ć‚Æćƒ©ćƒ˜ćƒ“ć®å¤‰ē•°ä½“恮äø€ēØ®ć§ć™ć€‚åœ°äø‹ć«ē¾¤ć‚Œć§ē”Ÿę“»ć—态äø‹ę°“é“ć‚’ä½å‡¦ć«ć—ć¦ć„ć¾ć™ć€‚" +#: lang/json/MONSTER_from_json.py +msgid "prototype laser turret" +msgid_plural "prototype laser turrets" +msgstr[0] "č©¦ä½œćƒ¬ćƒ¼ć‚¶ćƒ¼ć‚æ惬惃惈" + +#. ~ Description for {'str': 'prototype laser turret'} +#: lang/json/MONSTER_from_json.py +msgid "" +"This appears to be a very experimental automated tower. Plating-less and " +"seemingly half-built, it's little more than an oversized laser emitter and a" +" camera, both welded to a swiveling platform." +msgstr "" +"非åøøć«å®Ÿéؓēš„ćŖč‡Ŗå‹•åŒ–ć•ć‚ŒćŸć‚æćƒ¬ćƒƒćƒˆć®ć‚ˆć†ć§ć™ć€‚å¤–č£…ć‚‚ćŖ恏äø€č¦‹ęœŖå®Œęˆå“ć®ć‚ˆć†ć«č¦‹ćˆć¾ć™ćŒć€ē‰¹å¤§ć®ćƒ¬ćƒ¼ć‚¶ćƒ¼ę”¾å°„č£…ē½®ćØć‚«ćƒ”ćƒ©ć‚’å›žč»¢å°ć«ćć®ć¾ć¾ęŗ¶ęŽ„ć—ćŸä½œć‚Šć«ćŖć£ć¦ć„ć¾ć™ć€‚" + #: lang/json/MONSTER_from_json.py msgid "blob" msgid_plural "blobs" @@ -67049,43 +67202,43 @@ msgstr "" #: lang/json/MONSTER_from_json.py msgid "barghest" msgid_plural "barghests" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ēŠ¬" #. ~ Description for {'str': 'barghest'} #: lang/json/MONSTER_from_json.py msgid "" "Huge swollen zombie dog, smeared black with slime. Its teeth are longer and" " its broad back is rippling with muscles and oozing wounds." -msgstr "" +msgstr "å…Øčŗ«ćŒå·Øå¤§åŒ–ć—ćŸć€é»’ć„ē²˜ę¶²å”—ć‚Œć®ć‚¾ćƒ³ćƒ“ēŠ¬ć§ć™ć€‚ē‰™ćÆé•·ćć€ē­‹č‚‰ć§ē››ć‚ŠäøŠćŒć£ćŸåŗƒć„čƒŒäø­ćÆå‚·ć¤ćč†æć‚“ć§ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "hulking horror" msgid_plural "hulking horrors" -msgstr[0] "" +msgstr[0] "å·Øå¤§ć‚¾ćƒ³ćƒ“ēŠ¬" #. ~ Description for {'str': 'hulking horror'} #: lang/json/MONSTER_from_json.py msgid "" "A four-legged canine body now grotesquely swollen, with arms as wide as a " "trash can and massive exposed teeth." -msgstr "" +msgstr "å·Ø大ćŖē‰™ć‚’ć‚€ćå‡ŗć—ć«ć—ćŸć€ć‚“ćƒŸē®±ćØåŒć˜ćć‚‰ć„ć®å¤Ŗ恕恮腕悒悂恤ē•°ę§˜ć«å·Øå¤§åŒ–ć—ćŸ4č¶³ę­©č”Œć®ć‚¤ćƒŒć§ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "boneplate wolf" msgid_plural "boneplate wolfs" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¹ć‚±ćƒ«ćƒˆćƒ³ēŠ¬" #. ~ Description for {'str': 'boneplate wolf'} #: lang/json/MONSTER_from_json.py msgid "" "This is a four legged creature covered in fused bony plates, shaped somewhat" " like a dog or wolf. Joints and cracks around its body ooze with black goo." -msgstr "" +msgstr "å…Øčŗ«ć®ēš®č†šć«éŖØć®č£…ē”²ćŒē™’ē€ć—ćŸć€ć‚¤ćƒŒć‚„ć‚Ŗć‚Ŗć‚«ćƒŸć®ć‚ˆć†ćŖå§æ恮4č¶³ę­©č”Œć®åŒ–ć‘ē‰©ć§ć™ć€‚é–¢ēƀéƒØ悄éŖØ恮äŗ€č£‚恋悉黒恄ē²˜ę¶²ćŒę»²ćæå‡ŗć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "skeletal wolf" msgid_plural "skeletal wolfs" -msgstr[0] "" +msgstr[0] "ć‚¹ć‚±ćƒ«ćƒˆćƒ³ć‚¦ćƒ«ćƒ•" #: lang/json/MONSTER_from_json.py msgid "spearcat hunter" @@ -67299,6 +67452,22 @@ msgid "" "and its eyes bulge with black goo." msgstr "ć‚¾ćƒ³ćƒ“åŒ–ć—ćŸćƒ”ćƒ„ćƒ¼ćƒžć§ć™ć€‚å¾Œć‚č„šćŒč‚„å¤§åŒ–ć—ć€ē›®ćÆé»’ćē²˜ć¤ćä½•ć‹ć«ć‚ˆć£ć¦č†Øå¼µć—ć¦č¦‹ćˆć¾ć™ć€‚" +#: lang/json/MONSTER_from_json.py +msgid "zombie horse" +msgid_plural "zombie horses" +msgstr[0] "ć‚¾ćƒ³ćƒ“é¦¬" + +#. ~ Description for {'str': 'zombie horse'} +#: lang/json/MONSTER_from_json.py +msgid "" +"From the looks of this zombie horse's ghastly features, with its protruding " +"ribs, whitish skull, and empty eyes, the exposed part of the internal organs" +" shows a seemingly lifeless color, and the black body fluid drips slowly. " +"The new strength makes the horse no longer dependent on its muscles, but it " +"can still pursue the enemy quickly." +msgstr "" +"å°–ć£ćŸč‚‹éŖØćØē™½ć£ć½ć„é ­č“‹éŖØ态ē©ŗ恮ēœ¼ēŖ©ć‚’ć‚‚ć¤ęć‚‹ć¹ćć‚¾ćƒ³ćƒ“é¦¬ć§ć™ć€‚éœ²å‡ŗć—ćŸå†…č‡“ćÆē„”ę©Ÿē‰©ćØ見ē“›ć†č‰²ć«ćŖć£ć¦ćŠć‚Šć€ćć“ć‹ć‚‰é»’ć„ę¶²ä½“ćŒć‚†ć£ćć‚ŠćØę»“ć‚Šč½ć”ć¦ć„ć¾ć™ć€‚ē­‹č‚‰ć«é ¼ć‚‹ć“ćØćÆäøåÆčƒ½ć«ćŖć‚Šć¾ć—ćŸćŒć€ę–°ć—ćå¾—ćŸåŠ›ć«ć‚ˆć£ć¦ē“ ę—©ćę•µć‚’čæ½ć„ć‹ć‘ć¾ć™ć€‚" + #: lang/json/MONSTER_from_json.py msgid "Tiger wight" msgid_plural "Tiger wights" @@ -67311,6 +67480,34 @@ msgid "" "eyes wide open and shining black." msgstr "äø€č¦‹ć™ć‚‹ćØę™®é€šć®ćƒˆćƒ©ć§ć™ćŒć€ę™‚ęŠ˜ć‚ˆć‚ć‚ćć€é”ŽćÆå¤–ć‚Œć‹ć‘ć¦ćŠć‚Šć€å¤§ććé–‹ć„ćŸē›®ćÆé»’ćč¼ć„ć¦ć„ć¾ć™ć€‚" +#: lang/json/MONSTER_from_json.py +msgid "zombie cow" +msgid_plural "zombie cows" +msgstr[0] "ć‚¾ćƒ³ćƒ“ć‚¦ć‚·" + +#. ~ Description for {'str': 'zombie cow'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Once a placid cow, this leathery horror stumbles and shudders, its pulsing " +"black eyes scanning for prey beneath wicked horns. It is big and heavy and " +"murderous." +msgstr "恋恤恦ćÆē©ć‚„恋ćŖę€§ę ¼ć®ć‚¦ć‚·ć§ć—ćŸćŒć€ä»ŠćÆčŗ«éœ‡ć„恗ćŖćŒć‚‰ćƒ•ćƒ©ćƒ•ćƒ©ćØē§»å‹•ć—态é‚Ŗę‚ŖćŖ角恮äø‹ć‹ć‚‰ēœŸć£é»’ćŖē›®ć§ē²ē‰©ć‚’ęŽ¢ć—ć¦ć„ć¾ć™ć€‚" + +#: lang/json/MONSTER_from_json.py +msgid "woodland wight" +msgid_plural "woodland wights" +msgstr[0] "ć‚¾ćƒ³ćƒ“ć‚·ć‚«" + +#. ~ Description for {'str': 'woodland wight'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pale, stumbling white-tailed deer with blackened eyes and drooling slime " +"down its neck. Its legs twist and bend in strange, haphazard directions, " +"but with unnatural strength and speed. Preys on coyotes, wolves, and giant " +"spider mutants." +msgstr "" +"首悒恆ćŖ恠悌恟态ē›®ćŒēœŸć£é»’ćŖē™½å°¾ć‚·ć‚«ć§ć™ć€‚č¶³ćÆ儇妙ćŖę–¹å‘ć«ę»ć˜ę›²ćŒć£ć¦ć„ć¾ć™ćŒć€ę™®é€šć§ćÆ考恈悉悌ćŖć„åŠ›ćØ速åŗ¦ć‚’å‚™ćˆć¦ć„ć¾ć™ć€‚ć‚³ćƒØćƒ¼ćƒ†ć€ć‚Ŗć‚Ŗć‚«ćƒŸć€å¤‰ē•°ć—ćŸå·Ø大ć‚Æćƒ¢ćŖć©ć‚’ę•é£Ÿć—ć¾ć™ć€‚" + #: lang/json/MONSTER_from_json.py msgid "mass of zombie spiders" msgid_plural "mass of zombie spiderss" @@ -67858,7 +68055,7 @@ msgstr "ęÆ’č™«ć‚¾ćƒ³ćƒ“ćÆé‡ć‚’å°„å‡ŗć—ć¾ć—ćŸļ¼" #: lang/json/MONSTER_from_json.py msgid "scissorlimbs" msgid_plural "scissorlimbss" -msgstr[0] "" +msgstr[0] "ę£˜č¶³ć‚¾ćƒ³ćƒ“" #. ~ Description for {'str': 'scissorlimbs'} #: lang/json/MONSTER_from_json.py @@ -67867,30 +68064,31 @@ msgid "" "watch of the blighted landscape. Its spindly limbs of bone slip between the" " rubble with otherworldly speed." msgstr "" +"ę‚Ŗå¤¢ć®ć‚ˆć†ćŖå§æć®č”€ć¾ćæć‚Œć®ć‚Æćƒ¢ćŒå»ƒå¢Ÿć«ćć³ćˆē«‹ć”ć€č’ć‚Œęžœć¦ćŸé¢Øę™Æć‚’é»™ć£ć¦č¦‹ć¤ć‚ć¦ć„ć¾ć™ć€‚å°–ć£ćŸéŖØć§ä½œć‚‰ć‚ŒćŸę‰‹č¶³ćÆ态äæ”恘悉悌ćŖ恄速åŗ¦ć§ē“¦ē¤«ć®äøŠć‚’čµ°ć‚ŠęŠœć‘ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "hanging innards" msgid_plural "hanging innardss" -msgstr[0] "" +msgstr[0] "垂äø‹ć‚¾ćƒ³ćƒ“" #. ~ Description for {'str': 'hanging innards'} #: lang/json/MONSTER_from_json.py msgid "" "Great snakes of flesh hang from the ceiling above, madly thrashing and " "reaching about." -msgstr "" +msgstr "č‚‰ć§ä½œć‚‰ć‚ŒćŸå·Ø大ćŖćƒ˜ćƒ“ćŒå¤©äŗ•ć‹ć‚‰ć¶ć‚‰äø‹ćŒć‚Šć€čæ‘ć„ćć‚‚ć®ć‚’ē‹‚ć£ćŸć‚ˆć†ć«ēŖćåˆŗć—ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "spasming lump" msgid_plural "spasming lumps" -msgstr[0] "" +msgstr[0] "č‚‰å”Šć‚¾ćƒ³ćƒ“" #. ~ Description for {'str': 'spasming lump'} #: lang/json/MONSTER_from_json.py msgid "" "A great pile of merged bodies and mutated flesh. It spasms in an arrhythmic" " and desperate manner." -msgstr "" +msgstr "変ē•°ć—ć¦ćƒ‰ćƒ­ćƒ‰ćƒ­ć«čžåˆć—ćŸå·Ø大ćŖč‚‰ć®å±±ć§ć™ć€‚äøę•“č„ˆć§ć‚‚čµ·ć“ć—ćŸć‹ć®ć‚ˆć†ć«ć€ęæ€ć—恏ē—™ę”£ć—ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "flesh wall" @@ -67970,7 +68168,7 @@ msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“" #: lang/json/MONSTER_from_json.py msgid "" "Its entire body bulges with distended muscles and swollen, festering wounds." -msgstr "å…Øčŗ«ćŒå‚·ć§åŒ–č†æ恗恦恊悊态ē­‹č‚‰ćÆē•°ę§˜ć«č†Ø悌äøŠćŒć£ć¦ć„ć¾ć™ć€‚" +msgstr "ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "zombie wrestler" @@ -68065,11 +68263,11 @@ msgid "" msgstr "腕ćÆ道ē«Æć®ć‚“ćƒŸē®±ēØ‹ć«č†Ø悌äøŠćŒć‚Šć€čŗ«ä½“ćÆꈐäŗŗē”·ę€§6äŗŗåˆ†ć®å¤§ćć•ć¾ć§č†Øå¼µć—ć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py -msgid "feral hunter" -msgid_plural "feral hunters" -msgstr[0] "ćƒ•ć‚§ćƒ©ćƒ«ćƒ»ćƒćƒ³ć‚æćƒ¼" +msgid "zombie hunter" +msgid_plural "zombie hunters" +msgstr[0] "ćƒćƒ³ć‚æćƒ¼ć‚¾ćƒ³ćƒ“" -#. ~ Description for {'str': 'feral hunter'} +#. ~ Description for {'str': 'zombie hunter'} #: lang/json/MONSTER_from_json.py msgid "" "This once-human body is barely recognizable, scrambling about on all fours, " @@ -68154,11 +68352,11 @@ msgstr "" "ę°—å‘³ć®ę‚Ŗ恄脂č‚Ŗć®å”Šć®ć‚ˆć†ć«ć—ć‹č¦‹ćˆćŖć„ć€é»’ć„ę±ć‚’åž‚ć‚Œęµć™č‚„å¤§åŒ–ć—ćŸć‚¾ćƒ³ćƒ“ć§ć™ć€‚čæ‘恄恄恦ćæ悋ćØč¼ćčµ¤ć„ēž³ćŒē¬‘ć£ć¦ć„ć‚‹ć‚ˆć†ć«ć‚‚č¦‹ćˆć€ćć®ēœ¼å·®ć—ćÆ宇宙ēš„ć€éžäŗŗ間ēš„ćŖę³•ę‚¦ć‚’å‘¼ć³čµ·ć“ć—ć¾ć™ć€‚ēš®č†šćÆå‚·ć¤ćć€å†…č”µćŒć‚ć‚ŠćˆćŖ恄ēØ‹ć«č†Øć‚‰ć‚“ć§ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py -msgid "feral runner" -msgid_plural "feral runners" -msgstr[0] "ćƒ•ć‚§ćƒ©ćƒ«ćƒ»ćƒ©ćƒ³ćƒŠćƒ¼" +msgid "zombie runner" +msgid_plural "zombie runners" +msgstr[0] "ćƒ©ćƒ³ćƒŠćƒ¼ć‚¾ćƒ³ćƒ“" -#. ~ Description for {'str': 'feral runner'} +#. ~ Description for {'str': 'zombie runner'} #: lang/json/MONSTER_from_json.py msgid "" "This recently-risen body moves quickly, darting its head back and forth and " @@ -68166,11 +68364,11 @@ msgid "" msgstr "ć‚¾ćƒ³ćƒ“åŒ–ć—ć¦ć¾ć ę—„ćŒęµ…ć„ćć®čŗ«ä½“ćÆē“ ę—©ćå‹•ćć€å¤§ććć®ć‘ćžć£ćŸć‹ćØꀝ恆ćØꉋ悒ēŖćå‡ŗć—ć¦ę”»ę’ƒć—ć¦ćć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py -msgid "feral predator" -msgid_plural "feral predators" -msgstr[0] "ćƒ•ć‚§ćƒ©ćƒ«ćƒ»ćƒ—ćƒ¬ćƒ‡ć‚æćƒ¼" +msgid "zombie predator" +msgid_plural "zombie predators" +msgstr[0] "ćƒ—ćƒ¬ćƒ‡ć‚æćƒ¼ć‚¾ćƒ³ćƒ“" -#. ~ Description for {'str': 'feral predator'} +#. ~ Description for {'str': 'zombie predator'} #: lang/json/MONSTER_from_json.py msgid "" "With its joints in odd places and angles, this humanoid creature prowls " @@ -70220,7 +70418,7 @@ msgstr[0] "ć‚¾ćƒ³ćƒ“ćƒ‡ć‚£ćƒ¢ćƒ«ćƒ•ć‚©ćƒ‰ćƒ³" msgid "" "The raggedly flying corpse of a feathered reptile over three feet long, " "with short wings and a big colorful beak." -msgstr "体長ē“„90cmē؋åŗ¦ć®ć€ē¾½ęÆ›ćŒćƒœćƒ­ćƒœćƒ­ć«ćŖć£ćŸé£›č”Œēˆ¬č™«é”žć®ć‚¾ćƒ³ćƒ“恧恙怂ēŸ­ć„ēæ¼ćØå¤§ććč‰²é®®ć‚„ć‹ćŖćć”ć°ć—ć‚’ęŒć£ć¦ć„ć¾ć™ć€‚" +msgstr "å…Ø長ē“„90cm恮ē¾½ę ¹ć‚’悂恤态ē¾½ęÆ›ćŒćƒœćƒ­ćƒœćƒ­ć«ćŖć£ćŸé£›č”Œēˆ¬č™«é”žć®ć‚¾ćƒ³ćƒ“恧恙怂ēŸ­ć„ēæ¼ćØå¤§ććč‰²é®®ć‚„ć‹ćŖćć”ć°ć—ć‚’ęŒć£ć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Dilophosaurus zombie" @@ -70239,7 +70437,7 @@ msgstr "" #: lang/json/MONSTER_from_json.py msgid "Gruesome Gallimimus" msgid_plural "Gruesome Gallimimuss" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ć‚¬ćƒŖćƒŸćƒ ć‚¹" #. ~ Description for {'str': 'Gruesome Gallimimus'} #: lang/json/MONSTER_from_json.py @@ -70248,11 +70446,12 @@ msgid "" "tattered feathers and black putrid liquid. Its entire body bulges with " "distended muscles and swollen, festering wounds." msgstr "" +"ćƒœćƒ­ćƒœćƒ­ć®ē¾½ęƛćØé…·ćč‡­ć†é»’ć„ę¶²ä½“ć§č¦†ć‚ć‚ŒćŸć€ćƒ•ćƒ©ćƒ•ćƒ©ćØę­©ćäø­åž‹äŗŒč¶³ę­©č”Œęē«œć®ć‚¾ćƒ³ćƒ“恧恙怂ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Skull Breaker" msgid_plural "Skull Breakers" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ćƒ‘ć‚­ć‚±ćƒ•ć‚”ćƒ­ć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Skull Breaker'} #: lang/json/MONSTER_from_json.py @@ -70262,11 +70461,12 @@ msgid "" "head sits on a body bulging with distended muscles and swollen, festering " "wounds." msgstr "" +"ćƒœćƒ­ćƒœćƒ­ć®ē¾½ęƛćØé…·ćč‡­ć†é»’ć„ę¶²ä½“ć§č¦†ć‚ć‚ŒćŸć€ćƒ•ćƒ©ćƒ•ćƒ©ćØę­©ćäø­åž‹äŗŒč¶³ę­©č”Œęē«œć®ć‚¾ćƒ³ćƒ“恧恙怂ē”¬ćć†ćŖćƒ‰ćƒ¼ćƒ åž‹ć®é ­ćŒē‰¹å¾“ēš„ć§ć™ćŒć€é…·ć„å‚·ć‚’č² ć£ć¦ćŠć‚Šć€å…Øčŗ«ć®ē­‹č‚‰ćŒč‚„å¤§ć—ć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Crusher Camp" msgid_plural "Crusher Camps" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ć‚«ćƒ³ćƒ—ćƒˆć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Crusher Camp'} #: lang/json/MONSTER_from_json.py @@ -70274,12 +70474,12 @@ msgid "" "The shuffling corpse of a large feathered bipedal dinosaur with grossly " "bulging legs, massive hulking shoulders and a vicious pointed beak. Its " "tattered feathers are stained with black, sticky liquid." -msgstr "" +msgstr "ē•°åøøęˆé•·ć—ćŸč¶³ćØč‚„å¤§ć—ćŸč‚©ć€å°–ć£ćŸå˜“ćŒē‰¹å¾“ēš„ćŖ态ē¾½ęÆ›ćŒē”ŸćˆćŸå¤§åž‹ć®äŗŒč¶³ę­©č”Œęē«œć‚¾ćƒ³ćƒ“ć§ć™ć€‚ćƒœćƒ­ćƒœćƒ­ć®ē¾½ęƛćÆ黒恄ē²˜ę¶²ć§ę±šć‚Œć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Spino Sledge" msgid_plural "Spino Sledges" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ć‚¹ćƒ”ćƒŽć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Spino Sledge'} #: lang/json/MONSTER_from_json.py @@ -70288,11 +70488,12 @@ msgid "" " black eyes, and a tattered sail on its back. Its body is even bigger than " "normal, bulging with distended muscles and swollen, festering wounds." msgstr "" +"ēž³ć‹ć‚‰é»’ć„ę¶²ä½“ćŒę»²ćæå‡ŗć¦ć„ć‚‹ć€ćƒœćƒ­ćƒœćƒ­ć®åø†ć‚’čƒŒč² ć£ćŸćƒÆćƒ‹ć®ć‚ˆć†ćŖē°ēŒ›ćŖé””ć¤ćć®ć‚¾ćƒ³ćƒ“ęē«œć§ć™ć€‚通åøøć‚ˆć‚Šć‚‚å¤§ććęˆé•·ć—ć¦ćŠć‚Šć€č†Øå¼µć—ćŸē­‹č‚‰ć®ć‚ć”ć“ć”ć«ä»˜ć„ćŸå‚·ćÆ化č†æć—ć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Rage Rex" msgid_plural "Rage Rexs" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ćƒ†ć‚£ćƒ©ćƒŽć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Rage Rex'} #: lang/json/MONSTER_from_json.py @@ -70300,23 +70501,24 @@ msgid "" "Massive piles of ragged, stinking flesh lifting enormous teeth. Its entire " "body bulges with distended muscles and swollen, festering wounds." msgstr "" +"å·Ø大ćŖē‰™ć‚’ć‚€ćå‡ŗć—ć«ć—ćŸć€é…·ć„č‡­ć„ć‚’ę”¾ć¤ćƒœćƒ­ćƒœćƒ­ć®ć‚¾ćƒ³ćƒ“ęē«œć§ć™ć€‚ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Alberta Anvil" msgid_plural "Alberta Anvils" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ć‚¢ćƒ«ćƒćƒ¼ćƒˆć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Alberta Anvil'} #: lang/json/MONSTER_from_json.py msgid "" "Massive jaws and grabbing claws lifting by a body bulging with distended " "muscles and swollen, festering wounds." -msgstr "" +msgstr "å·Ø大ćŖ锎ćØ鋭恄ēˆŖć‚’ć‚‚ć¤ć‚¾ćƒ³ćƒ“ęē«œć§ć™ć€‚å…Øčŗ«ćŒå‚·ć§åŒ–č†æ恗恦恊悊态ē­‹č‚‰ćÆē•°ę§˜ć«č†Ø悌äøŠćŒć£ć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Triceratruck" msgid_plural "Triceratrucks" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ćƒˆćƒŖć‚±ćƒ©ćƒˆćƒ—ć‚¹" #. ~ Description for {'str': 'Triceratruck'} #: lang/json/MONSTER_from_json.py @@ -70325,11 +70527,12 @@ msgid "" "three wicked looking horns emerge. Its black eyes ooze like tears. Its " "entire body bulges with distended muscles and swollen, festering wounds." msgstr "" +"ć‚µć‚¤ć«ä¼¼ćŸå¼·å¤§ćŖꁐē«œć®ć‚¾ćƒ³ćƒ“恧恙怂ē›¾ć®ć‚ˆć†ćŖē”¬č³Ŗ恮ćØ恕恋ćØ3ęœ¬ć®å¤§ććŖ角恌ē‰¹å¾“恧恙怂ē›®å…ƒć«é»’ć„ę¶²ä½“ćŒę¶™ć®ć‚ˆć†ć«ę»²ć‚“ć§ć„ć¾ć™ć€‚ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Stegosaurus Sledge" msgid_plural "Stegosaurus Sledges" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ć‚¹ćƒ†ć‚“ć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Stegosaurus Sledge'} #: lang/json/MONSTER_from_json.py @@ -70338,23 +70541,24 @@ msgid "" "a spiked tail. Its entire body bulges with distended muscles and swollen, " "festering wounds." msgstr "" +"背äø­ć®č£…ē”²ęæćØę£˜ć®ä»˜ć„ćŸå°¾ćŒē‰¹å¾“ēš„ćŖć€é…·ć„å‚·ć‚’č² ć£ćŸå››č¶³ę­©č”Œęē«œć®ć‚¾ćƒ³ćƒ“恧恙怂ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Dino Tank" msgid_plural "Dino Tanks" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ć‚¢ćƒ³ć‚­ćƒ­ć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Dino Tank'} #: lang/json/MONSTER_from_json.py msgid "" "Heavily armored zombie dinosaur. Its entire body bulges with distended " "muscles and swollen, festering wounds." -msgstr "" +msgstr "é‡č£…ē”²ć®ć‚¾ćƒ³ćƒ“ꁐē«œć§ć™ć€‚ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Zombie Dreadnought" msgid_plural "Zombie Dreadnoughts" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ć‚¢ćƒ‘ćƒˆć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Zombie Dreadnought'} #: lang/json/MONSTER_from_json.py @@ -70363,11 +70567,12 @@ msgid "" "tail. Its entire body bulges with distended muscles and swollen, festering " "wounds." msgstr "" +"長恄首ćØéž­ć®ć‚ˆć†ć«ä¼øć³ćŸå°»å°¾ć‚’ć‚‚ć¤ć€å·Ø大ćŖå››č¶³ę­©č”Œć®ęē«œć®ć‚¾ćƒ³ćƒ“恧恙怂ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Draco Titan" msgid_plural "Draco Titans" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ć‚±ćƒ©ćƒˆć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Draco Titan'} #: lang/json/MONSTER_from_json.py @@ -70376,23 +70581,24 @@ msgid "" "horrible speed. Its colorful horns and bone spikes sit on a body bulging " "with distended muscles and swollen, festering wounds." msgstr "" +"å…Øčŗ«ć‚’é±—ćØéŖØć®ę£˜ć§č¦†ć£ćŸć€ęć‚ć—ć„ć‚¹ćƒ”ćƒ¼ćƒ‰ć§å‹•ćå·Ø大ćŖć‚¾ćƒ³ćƒ“ćƒ‰ćƒ©ć‚“ćƒ³ć§ć™ć€‚č‰²é®®ć‚„ć‹ćŖ角恌ē”Ÿćˆć¦ćŠć‚Šć€å…Øčŗ«ćŒå‚·ć§åŒ–č†æ恗态ē­‹č‚‰ćÆē•°ę§˜ć«č†Ø悌äøŠćŒć£ć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Allosaurus Avalanche" msgid_plural "Allosaurus Avalanches" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ć‚¢ćƒ­ć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Allosaurus Avalanche'} #: lang/json/MONSTER_from_json.py msgid "" "The shambling corpse of a large predatory bipedal dinosaur. Its entire body" " bulges with distended muscles and swollen, festering wounds." -msgstr "" +msgstr "大型äŗŒč¶³ę­©č”Œęē«œć®ć‚¾ćƒ³ćƒ“恧恙怂ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Deino Destroyer" msgid_plural "Deino Destroyers" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ćƒ‡ć‚¤ćƒŽćƒ‹ć‚Æć‚¹" #. ~ Description for {'str': 'Deino Destroyer'} #: lang/json/MONSTER_from_json.py @@ -70402,11 +70608,12 @@ msgid "" "sickle-like claw. Its entire body bulges with distended muscles and " "swollen, festering wounds." msgstr "" +"ćƒœćƒ­ćƒœćƒ­ć®ē¾½ęƛćØé…·ćč‡­ć†é»’ć„ę¶²ä½“ć§č¦†ć‚ć‚ŒćŸć€ćƒ•ćƒ©ćƒ•ćƒ©ćØę­©ćäø­åž‹äŗŒč¶³ę­©č”Œęē«œć®ć‚¾ćƒ³ćƒ“恧恙怂äø”č¶³ć‹ć‚‰ē”ŸćˆćŸå¤§éŽŒć®ć‚ˆć†ćŖēˆŖ悒ęŒÆć‚Šå›žć—ć¦ę”»ę’ƒć—ć¾ć™ć€‚ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Utah Hoodoo" msgid_plural "Utah Hoodoos" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ćƒ¦ć‚æćƒ©ćƒ—ćƒˆćƒ«" #. ~ Description for {'str': 'Utah Hoodoo'} #: lang/json/MONSTER_from_json.py @@ -70415,11 +70622,12 @@ msgid "" " a long tail, and long sharp scythe-like claws. Its entire body bulges with" " distended muscles and swollen, festering wounds." msgstr "" +"ē¾½ęÆ›ć«č¦†ć‚ć‚ŒćŸč…•ć€é•·ć„å°¾ć€å¤§éŽŒć®ć‚ˆć†ćŖ鉤ēˆŖć‚’ęŒć¤å¤§åž‹äŗŒč¶³ę­©č”Œęē«œć®ć‚¾ćƒ³ćƒ“ć§ć™ć€‚ćƒ•ćƒ©ćƒ•ćƒ©ćØå‹•ćć¾ć‚ć‚Šć€ę™‚ęŠ˜é£›ć³č·³ć­ć¦ć„ć¾ć™ć€‚ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Parasaur Punch" msgid_plural "Parasaur Punchs" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ćƒ‘ćƒ©ć‚µć‚¦ćƒ­ćƒ­ćƒ•ć‚¹" #. ~ Description for {'str': 'Parasaur Punch'} #: lang/json/MONSTER_from_json.py @@ -70428,11 +70636,12 @@ msgid "" "vacant and swollen. Its entire body bulges with distended muscles and " "swollen, festering wounds." msgstr "" +"ć¾ć ć‚‰ęØ”ę§˜ćØę£’ēŠ¶ć®ćØć•ć‹ć‚’ęŒć¤å¤§åž‹ęē«œć§ć™ć€‚ę­»å¾Œć‚‚å‹•ćē¶šć‘恦恊悊态ē›®ēŽ‰ć‚’å¤±ć£ćŸē›®č“‹ćŒč…«ć‚Œć¦ć„ć¾ć™ć€‚ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Winged Horror" msgid_plural "Winged Horrors" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ćƒ‡ć‚£ćƒ¢ćƒ«ćƒ•ć‚©ćƒ‰ćƒ³" #. ~ Description for {'str': 'Winged Horror'} #: lang/json/MONSTER_from_json.py @@ -70441,11 +70650,12 @@ msgid "" "wings and a big colorful beak. Its entire body bulges with distended " "muscles and swollen, festering wounds." msgstr "" +"å…Ø長ē“„90cmć‚’č¶…ćˆć‚‹ē¾½ę ¹ć‚’悂恤态ē¾½ęÆ›ćŒćƒœćƒ­ćƒœćƒ­ć«ćŖć£ćŸé£›č”Œēˆ¬č™«é”žć®ć‚¾ćƒ³ćƒ“恧恙怂ēŸ­ć„ēæ¼ćØå¤§ććč‰²é®®ć‚„ć‹ćŖćć”ć°ć—ć‚’ęŒć£ć¦ć„ć¾ć™ć€‚ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Crested Crusher" msgid_plural "Crested Crushers" -msgstr[0] "" +msgstr[0] "å‡¶ęš“ć‚¾ćƒ³ćƒ“ćƒ‡ć‚£ćƒ­ćƒ•ć‚©ć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Crested Crusher'} #: lang/json/MONSTER_from_json.py @@ -70455,6 +70665,7 @@ msgid "" "like a frill. Its entire body bulges with distended muscles and swollen, " "festering wounds." msgstr "" +"č„šć‚’å¼•ććšć£ć¦ę­©ćäø­åž‹ęē«œć®ć‚¾ćƒ³ćƒ“恧恙怂鋭恄ē‰™ćŒē”Ÿćˆć¦ćŠć‚Šć€é ­éƒØ恫ćÆē‰¹å¾“ēš„ćŖ2恤恮頭éŖØćŒć‚ć‚Šć¾ć™ć€‚å‚·ć¤ć„ćŸčŗ«ä½“恋悉肉ē‰‡ćŒćƒ•ćƒŖćƒ«ć®ć‚ˆć†ć«åž‚ć‚Œäø‹ćŒć£ć¦ć„ć¾ć™ć€‚ē™ŗ達恗恟å…Øčŗ«ć®ē­‹č‚‰ćØ化č†æ恧č†Ø悌äøŠćŒć£ćŸå‚·å£ć«ć‚ˆć£ć¦ć€éžåøøć«å¤§ęŸ„ć«č¦‹ćˆć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Spinosaurus shady zombie" @@ -70511,50 +70722,50 @@ msgstr "黒恄ē²˜ę¶²ćŒę»“ć‚‹å¤§ććŖå°–ć£ćŸę­Æ悒見恛恤恑恦恄悋态å·Ø #: lang/json/MONSTER_from_json.py msgid "Skeletal Albertosaurus" msgid_plural "Skeletal Albertosauruss" -msgstr[0] "" +msgstr[0] "ć‚¹ć‚±ćƒ«ćƒˆćƒ³ć‚¢ćƒ«ćƒćƒ¼ćƒˆć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Skeletal Albertosaurus'} #: lang/json/MONSTER_from_json.py msgid "" "Monstrous columns of dense bone lifting sharp pointed teeth dripping with " "black goo. Skeletal claws reach ahead." -msgstr "" +msgstr "黒恄ē²˜ę¶²ćŒę»“ć‚‹å°–ć£ćŸę­Æ悒見恛恤恑恦恄悋态å·Ø大ćŖéŖØć®é›†åˆä½“ć§ć™ć€‚éŖØ恮ēˆŖ悂ē‰™ćØåŒć˜ć‚ˆć†ć«é•·ćä¼øć³ć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Bone Dragon" msgid_plural "Bone Dragons" -msgstr[0] "" +msgstr[0] "ćƒœćƒ¼ćƒ³ćƒ‰ćƒ©ć‚“ćƒ³" #. ~ Description for {'str': 'Bone Dragon'} #: lang/json/MONSTER_from_json.py msgid "" "Monstrous columns of dense bone lifting sharp pointed teeth dripping with " "black goo. Spikes and colorful horns jut out to complete the effect." -msgstr "" +msgstr "黒恄ē²˜ę¶²ćŒę»“ć‚‹å°–ć£ćŸę­Æ悒見恛恤恑恦恄悋态å·Ø大ćŖéŖØć®é›†åˆä½“ć§ć™ć€‚éžåøøć«ę”»ę’ƒēš„ćŖę£˜ćØč‰²é®®ć‚„ć‹ćŖ角恌ē”Ÿćˆć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Skeletal allosaurus" msgid_plural "Skeletal allosauruss" -msgstr[0] "" +msgstr[0] "ć‚¹ć‚±ćƒ«ćƒˆćƒ³ć‚¢ćƒ­ć‚µć‚¦ćƒ«ć‚¹" #. ~ Description for {'str': 'Skeletal allosaurus'} #: lang/json/MONSTER_from_json.py msgid "" "Monstrous columns of dense bone lifting sharp pointed teeth dripping with " "black goo." -msgstr "" +msgstr "黒恄ē²˜ę¶²ćŒę»“ć‚‹å°–ć£ćŸę­Æ悒見恛恤恑恦恄悋态å·Ø大ćŖéŖØć®é›†åˆä½“ć§ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "Utah Bones" msgid_plural "Utah Boness" -msgstr[0] "" +msgstr[0] "ć‚¹ć‚±ćƒ«ćƒˆćƒ³ćƒ¦ć‚æćƒ©ćƒ—ćƒˆćƒ«" #. ~ Description for {'str': 'Utah Bones'} #: lang/json/MONSTER_from_json.py msgid "" "Monstrous columns of dense bone lifting sharp pointed teeth dripping with " "black goo. There is a long tail and long sharp scythe-like claws" -msgstr "" +msgstr "黒恄ē²˜ę¶²ćŒę»“ć‚‹å°–ć£ćŸę­Æ悒見恛恤恑恦恄悋态å·Ø大ćŖéŖØć®é›†åˆä½“ć§ć™ć€‚é•·ć„å°¾ćØé‹­ćå°–ć£ćŸé‡œć®ć‚ˆć†ćŖēˆŖ恌ē”Ÿćˆć¦ć„ć¾ć™ć€‚" #: lang/json/MONSTER_from_json.py msgid "improvised SMG turret" @@ -72291,7 +72502,7 @@ msgstr "苦ē—›" msgid "Increases pain" msgstr "苦ē—›ćŒå¢—åŠ ć—ć¾ć™ć€‚" -#: lang/json/SPELL_from_json.py src/character.cpp src/npctalk.cpp +#: lang/json/SPELL_from_json.py src/character.cpp src/talker_npc.cpp msgid "Tired" msgstr "ē–²åŠ“ *" @@ -73375,7 +73586,7 @@ msgstr "å„€å¼ć«ć‚ˆć£ć¦ć‚¹ćƒˆćƒ¼ćƒ ć‚·ć‚§ć‚¤ćƒ‘ćƒ¼ćØę³¢é•·ć®åˆć†ē„žē§˜ēš„ msgid "Lightning Blast" msgstr "ćƒ©ć‚¤ćƒˆćƒ‹ćƒ³ć‚°ćƒ»ćƒ–ćƒ©ć‚¹ćƒˆ" -#: lang/json/SPELL_from_json.py src/weather_data.cpp +#: lang/json/SPELL_from_json.py lang/json/weather_type_from_json.py msgid "Lightning Storm" msgstr "ćƒ©ć‚¤ćƒˆćƒ‹ćƒ³ć‚°ćƒ»ć‚¹ćƒˆćƒ¼ćƒ " @@ -74250,11 +74461,11 @@ msgstr[0] "RM13ć‚³ćƒ³ćƒćƒƒćƒˆć‚¢ćƒ¼ćƒžćƒ¼" #. ~ Description for {'str': 'RM13 combat armor'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. Use it to turn it on." msgstr "" -"Rivtechē¤¾ćŒå…Øꊀ蔓悒ēµé›†ć—ć¦ä½œć‚ŠäøŠć’ćŸćƒ‘ćƒÆćƒ¼ć‚¢ćƒ¼ćƒžćƒ¼ć§ć™ć€‚é»’å…‰ć‚Šć™ć‚‹č»Ÿč³Ŗč£…ē”²ćŒå…Øčŗ«ć‚’包ćæć€å±å®³ć‹ć‚‰å®ˆć‚Šć¾ć™ć€‚å†…č”µé›»ęŗå¼ć§ęœ€å¤§ć§10å€‹ć®åŽŸå­åŠ›é›»ę± ć‚’å……å”«ć§ćć¾ć™ć€‚ä½æē”Ø恙悋ćØ電ęŗć‚’å…„ć‚Œć¾ć™ć€‚" +"Rivtechē¤¾ćŒéžå‰›ä½“ćƒ‘ćƒÆćƒ¼ć‚¢ćƒ¼ćƒžćƒ¼ęŠ€č”“ć‚’ēµé›†ć—ć¦ä½œć‚ŠäøŠć’ćŸć€ę“—ē·“ć•ć‚ŒćŸé»’ć„č»ē”Øć‚¹ćƒ¼ćƒ„ć§ć™ć€‚čµ·å‹•ć™ć‚‹ćØć€å†…č”µć•ć‚ŒćŸåŽŸå­åŠ›é›»ę± ć®é›»åŠ›ć‚’ę¶ˆč²»ć—ć¦ēØ¼åƒć—ć¾ć™ć€‚" #: lang/json/TOOL_ARMOR_from_json.py msgid "RM13 combat armor (on)" @@ -74265,12 +74476,12 @@ msgstr[0] "RM13ć‚³ćƒ³ćƒćƒƒćƒˆć‚¢ćƒ¼ćƒžćƒ¼(ć‚Ŗćƒ³)" #. armors (on)'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. It is turned on, and continually draining " "power. Use it to turn it off." msgstr "" -"Rivtechē¤¾ćŒå…Øꊀ蔓悒ēµé›†ć—ć¦ä½œć‚ŠäøŠć’ćŸćƒ‘ćƒÆćƒ¼ć‚¢ćƒ¼ćƒžćƒ¼ć§ć™ć€‚é»’å…‰ć‚Šć™ć‚‹č»Ÿč³Ŗč£…ē”²ćŒå…Øčŗ«ć‚’包ćæć€å±å®³ć‹ć‚‰å®ˆć‚Šć¾ć™ć€‚å†…č”µé›»ęŗå¼ć§ęœ€å¤§ć§10å€‹ć®åŽŸå­åŠ›é›»ę± ć‚’å……å”«ć§ćć¾ć™ć€‚é›»ęŗćŒå…„ć£ć¦ćŠć‚Šć€é›»ę± ć‚’ę¶ˆč²»ć—ć¦ć„ć¾ć™ć€‚ä½æē”Ø恙悋ćØ電ęŗć‚’åˆ‡ć‚Šć¾ć™ć€‚" +"Rivtechē¤¾ćŒéžå‰›ä½“ćƒ‘ćƒÆćƒ¼ć‚¢ćƒ¼ćƒžćƒ¼ęŠ€č”“ć‚’ēµé›†ć—ć¦ä½œć‚ŠäøŠć’ćŸć€ę“—ē·“ć•ć‚ŒćŸé»’ć„č»ē”Øć‚¹ćƒ¼ćƒ„ć§ć™ć€‚ę—¢ć«čµ·å‹•ć—ć¦ćŠć‚Šć€é›»åŠ›ć‚’ę¶ˆč²»ć—ć¦ć„ć¾ć™ć€‚ä½æē”Ø恙悋ćØ電ęŗć‚’åˆ‡ć‚Šć¾ć™ć€‚" #: lang/json/TOOL_ARMOR_from_json.py msgid "5-point anchor" @@ -75354,9 +75565,9 @@ msgstr[0] "ęŗåøÆåž‹ć‚½ćƒ¼ćƒ©ćƒ¼ćƒ‘ćƒćƒ«(ꊘē•³)" msgid "" "Personal portable charging system consisting of an array of solar panels " "neatly folded in a form of a large backpack. It can be worn as one, and has" -" an integrated cable to plug it into a cable charger system." +" an integrated cable to plug it into a cable charger system CBM." msgstr "" -"ꊘ悊ē•³ć¾ć‚ŒćŸćƒćƒƒć‚Æ惑惃ć‚Æåž‹ć®ć‚½ćƒ¼ćƒ©ćƒ¼ć‚¢ćƒ¬ć‚¤ć‹ć‚‰ćŖć‚‹ć€å€‹äŗŗē”Ø恮ęŗč”Œå……é›»ć‚·ć‚¹ćƒ†ćƒ ć§ć™ć€‚ē€ē”Ø恙悋恓ćØćŒć§ćć€ć‚±ćƒ¼ćƒ–ćƒ«å……é›»ć‚·ć‚¹ćƒ†ćƒ ć«åƾåæœć—ćŸäø€ä½“åž‹ć‚±ćƒ¼ćƒ–ćƒ«ćŒä»˜å±žć—ć¦ć„ć¾ć™ć€‚" +"ꊘ悊ē•³ć¾ć‚ŒćŸćƒćƒƒć‚Æ惑惃ć‚Æåž‹ć®ć‚½ćƒ¼ćƒ©ćƒ¼ć‚¢ćƒ¬ć‚¤ć‹ć‚‰ćŖć‚‹ć€å€‹äŗŗē”Ø恮ęŗč”Œå……é›»ć‚·ć‚¹ćƒ†ćƒ ć§ć™ć€‚ē€ē”Ø恙悋恓ćØćŒć§ćć€ć‚±ćƒ¼ćƒ–ćƒ«å……é›»ć‚·ć‚¹ćƒ†ćƒ ć®CBM恫åƾåæœć—ćŸäø€ä½“åž‹ć‚±ćƒ¼ćƒ–ćƒ«ćŒä»˜å±žć—ć¦ć„ć¾ć™ć€‚" #: lang/json/TOOL_ARMOR_from_json.py msgid "solar backpack (unfolded)" @@ -75368,8 +75579,8 @@ msgstr[0] "ęŗåøÆåž‹ć‚½ćƒ¼ćƒ©ćƒ¼ćƒ‘ćƒćƒ«(展開)" #: lang/json/TOOL_ARMOR_from_json.py msgid "" "Unfolded array of portable solar panels ready to push some power into an " -"active cable charger system." -msgstr "ć‚½ćƒ¼ćƒ©ćƒ¼ć‚¢ćƒ¬ć‚¤ćÆå±•é–‹ć•ć‚Œć¦ćŠć‚Šć€ēØ¼åƒć—ć¦ć„ć‚‹ć‚±ćƒ¼ćƒ–ćƒ«å……é›»ć‚·ć‚¹ćƒ†ćƒ ć«é›»åŠ›ć‚’ä¾›ēµ¦ć™ć‚‹ęŗ–å‚™ćŒć§ćć¦ć„ć¾ć™ć€‚" +"active cable charger system CBM." +msgstr "ć‚½ćƒ¼ćƒ©ćƒ¼ć‚¢ćƒ¬ć‚¤ćÆå±•é–‹ć•ć‚Œć¦ćŠć‚Šć€ēØ¼åƒć—ć¦ć„ć‚‹ć‚±ćƒ¼ćƒ–ćƒ«å……é›»ć‚·ć‚¹ćƒ†ćƒ ć®CBMć«é›»åŠ›ć‚’ä¾›ēµ¦ć™ć‚‹ęŗ–å‚™ćŒć§ćć¦ć„ć¾ć™ć€‚" #: lang/json/TOOL_ARMOR_from_json.py msgid "riot helmet" @@ -80085,10 +80296,10 @@ msgstr "恧悓恷悓č³Ŗć‚’å«ć‚€ć‚¢ć‚¤ćƒ†ćƒ ć‚’ē©€ē²‰ć«åŠ å·„ć™ć‚‹å°åž‹ć®é¢Ø msgid "" "This is an advanced version of the unified power supply, or UPS. This " "device has been significantly redesigned to provide better efficiency as " -"well as to consume plutonium fuel cells rather than batteries. Sadly, its " -"plutonium reactor can't be charged in UPS charging station." +"well as to consume plutonium fuel batteries rather than regular batteries. " +"Sadly, its plutonium reactor can't be charged in UPS charging station." msgstr "" -"ę”¹č‰Æåž‹ć®UPSć§ć™ć€‚ę ¹ęœ¬ēš„ćŖę”¹äæ®ćŒåŠ ćˆć‚‰ć‚Œć¦ćŠć‚Šć€ć‚ˆć‚ŠåŠ¹ēŽ‡ēš„ć«é›»åŠ›ć‚’ä¾›ēµ¦ć§ćć‚‹ć‚ˆć†åŽŸå­åŠ›é›»ę± ć«åƾåæœć—ć¦ć„ć¾ć™ć€‚ę®‹åæµćŖ恌悉UPSäŗ’ę›å……é›»ć‚¹ćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć§ć®å……é›»ćÆäøåÆčƒ½ć«ćŖć£ć¦ć„ć¾ć™ć€‚" +"ę”¹č‰Æåž‹ć®UPSć§ć™ć€‚ę ¹ęœ¬ēš„ćŖę”¹äæ®ćŒåŠ ćˆć‚‰ć‚Œć¦ćŠć‚Šć€ć‚ˆć‚ŠåŠ¹ēŽ‡ēš„ć«é›»åŠ›ć‚’ä¾›ēµ¦ć§ćć‚‹ć‚ˆć†ć«ć€é€šåøø恮電걠恧ćÆćŖćåŽŸå­åŠ›ē‡ƒę–™é›»ę± ć«åƾåæœć—ć¦ć„ć¾ć™ć€‚ę®‹åæµćŖ恌悉UPSäŗ’ę›å……é›»ć‚¹ćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć§ć®å……é›»ćÆäøåÆčƒ½ć«ćŖć£ć¦ć„ć¾ć™ć€‚" #. ~ Description for {'str': 'camera'} #: lang/json/TOOL_from_json.py @@ -80931,12 +81142,13 @@ msgstr "EMPę‰‹ę¦“å¼¾ć®ćƒ”ćƒ³ć‚’å¼•ćęŠœćć¾ć—ćŸć€‚" #: lang/json/TOOL_from_json.py msgid "" "This is a grenade that generates an electromagnetic pulse with a low-" -"inductance capacitor bank discharged into a single-loop antenna. Use this " -"item to pull the pin and light the fuse, turning it into an active EMP " -"grenade. You will then have three turns before it detonates, creating an " -"EMP field that damages robots and drains bionic energy." +"inductance capacitor bank discharged into a single-loop antenna. It also " +"produces a mild electric shock cloud. Use this item to pull the pin and " +"light the fuse, turning it into an active EMP grenade. You will then have " +"three turns before it detonates, creating an EMP field that damages robots " +"and drains bionic energy." msgstr "" -"ä½Žć‚¤ćƒ³ćƒ€ć‚Æć‚æćƒ³ć‚¹ć‚³ćƒ³ćƒ‡ćƒ³ć‚µćƒćƒ³ć‚Æć‹ć‚‰å˜ćƒ«ćƒ¼ćƒ—ć‚¢ćƒ³ćƒ†ćƒŠć«é€šé›»ć—ć¦é›»ē£ćƒ‘ćƒ«ć‚¹ć‚’ē™ŗē”Ÿć•ć›ć‚‹ę‰‹ę¦“å¼¾ć§ć™ć€‚ä½æē”Ø恙悋ćØćƒ”ćƒ³ć‚’å¼•ć„ć¦čµ·å‹•ć—ć€3ć‚æćƒ¼ćƒ³å¾Œć«ēˆ†ē™ŗ恗恦å‘Øå›²ć«EMPćƒ•ć‚£ćƒ¼ćƒ«ćƒ‰ć‚’ē™ŗē”Ÿć•ć›ć¦ćƒ­ćƒœćƒƒćƒˆć«ćƒ€ćƒ”ćƒ¼ć‚ø悒äøŽćˆć€ē”Ÿä½“éƒØå“ć®é›»åŠ›ć‚’ęµå‡ŗć•ć›ć¾ć™ć€‚" +"ä½Žć‚¤ćƒ³ćƒ€ć‚Æć‚æćƒ³ć‚¹ć‚³ćƒ³ćƒ‡ćƒ³ć‚µćƒćƒ³ć‚Æć‹ć‚‰å˜ćƒ«ćƒ¼ćƒ—ć‚¢ćƒ³ćƒ†ćƒŠć«é€šé›»ć—ć¦é›»ē£ćƒ‘ćƒ«ć‚¹ćØē™ŗē”Ÿć•ć›ć€å‘Øå›²ć«å¼±ć„é›»ę’ƒć‚’ę”¾å‡ŗć™ć‚‹ę‰‹ę¦“å¼¾ć§ć™ć€‚ä½æē”Ø恙悋ćØćƒ”ćƒ³ć‚’å¼•ć„ć¦čµ·å‹•ć—ć€3ć‚æćƒ¼ćƒ³å¾Œć«ēˆ†ē™ŗ恗恦å‘Øå›²ć«EMPćƒ•ć‚£ćƒ¼ćƒ«ćƒ‰ć‚’ē™ŗē”Ÿć•ć›ć¦ćƒ­ćƒœćƒƒćƒˆć«ćƒ€ćƒ”ćƒ¼ć‚ø悒äøŽćˆć€ē”Ÿä½“éƒØå“ć®é›»åŠ›ć‚’ę¼å‡ŗć•ć›ć¾ć™ć€‚" #: lang/json/TOOL_from_json.py msgid "active EMP grenade" @@ -80947,10 +81159,10 @@ msgstr[0] "EMPę‰‹ę¦“å¼¾(čµ·å‹•)" #: lang/json/TOOL_from_json.py msgid "" "This EMP grenade is active, and will shortly detonate, creating a large EMP " -"field that damages robots and drains bionic energy. You may not want to be " -"holding it much longer." +"field that damages robots and drains bionic energy as well as a mild " +"electric shock cloud. You may not want to be holding it much longer." msgstr "" -"EMPę‰‹ę¦“å¼¾ć®ćƒ”ćƒ³ćÆę—¢ć«å¼•ć‹ć‚Œć¦ćŠć‚Šć€ć¾ć‚‚ćŖ恏å‘Øå›²ć«å¤§č¦ęØ”ćŖ電ē£ćƒ‘ćƒ«ć‚¹ćŒē™ŗē”Ÿć—ć€ćƒ­ćƒœćƒƒćƒˆć‚„ē”Ÿē‰©å·„å­¦ēš„ćŖ要ē“ ć‚’ęŒć¤åÆ¾č±”ć«ćƒ€ćƒ”ćƒ¼ć‚ø悒äøŽćˆć¾ć™ć€‚ę—©ćęŠ•ć’ćŸę–¹ćŒč‰Æć„ę°—ćŒć—ć¾ć™ć­ć€‚" +"EMPę‰‹ę¦“å¼¾ć®ćƒ”ćƒ³ćÆę—¢ć«å¼•ć‹ć‚Œć¦ćŠć‚Šć€ć¾ć‚‚ćŖćå¼±ć„é›»ę’ƒćØå…±ć«å¤§č¦ęØ”ćŖ電ē£ćƒ‘ćƒ«ć‚¹ćŒå‘Øå›²ć«ē™ŗē”Ÿć—ć€ćƒ­ćƒœćƒƒćƒˆć‚„ē”Ÿē‰©å·„å­¦ēš„ćŖ要ē“ ć‚’ęŒć¤åÆ¾č±”ć«ćƒ€ćƒ”ćƒ¼ć‚ø悒äøŽćˆć¾ć™ć€‚ę—©ćęŠ•ć’ćŸę–¹ćŒč‰Æć„ę°—ćŒć—ć¾ć™ć­ć€‚" #: lang/json/TOOL_from_json.py msgid "incendiary grenade" @@ -85052,8 +85264,8 @@ msgstr "ć‚·ćƒ§ćƒƒćƒˆć‚¬ćƒ³ć®ē½ ć‚’čØ­ē½®ć—ć¾ć—ćŸć€‚" #. ~ Description for {'str': 'shotgun trap'} #: lang/json/TOOL_from_json.py msgid "" -"This is a simple tripwire is attached to the trigger of a loaded double-" -"barreled shotgun. When pulled, the shotgun fires. Two shells are loaded; " +"This is a simple tripwire is attached to the trigger of a loaded double " +"slamfire shotgun. When pulled, the shotgun fires. Two shells are loaded; " "the first time the trigger is pulled, one or both shells may be discharged." msgstr "" "č£…å”«ęøˆćæ恮2é€£ć‚·ćƒ§ćƒƒćƒˆć‚¬ćƒ³ć®å¼•ćé‡‘ć«ä»•ęŽ›ć‘ē·šć‚’ę‹¬ć‚Šä»˜ć‘ćŸē°”単ćŖē½ ć§ć™ć€‚å¼¾ćŒ2ē™ŗč£…å”«ć•ć‚Œć¦ć„ć¾ć™ć€‚ä½œå‹•ć™ć‚Œć°1ē™ŗćŖ恄恗2ē™ŗć®å¼¾äøø恌ē™ŗå°„ć•ć‚Œć¾ć™ć€‚" @@ -88430,7 +88642,7 @@ msgstr "å‰£ć®é“" msgid "" "When the sword is once drawn, the passions of men observe no bounds of " "moderation." -msgstr "" +msgstr "ć²ćØćŸć³å‰£ćŒęŠœć‹ć‚Œć‚Œć°ć€äŗŗ間恮ęæ€ęƒ…ćØ恄恆悂恮ćÆ态äø­åŗøćØć„ć†ęŠ‘ę­¢åŠ›ć‚’åˆ©ć‹ć›ćŖćć™ć‚‹ć‚‚ć®ć§ć‚ć‚‹ć€‚" #: lang/json/achievement_from_json.py msgid "Miyamoto Musashi" @@ -91927,7 +92139,7 @@ msgstr "äøŠéšŽć‚’ęŽ˜å‰Šć™ć‚‹" #: lang/json/construction_from_json.py msgid "Build Low End of a Concrete Ramp" -msgstr "" +msgstr "äøŠć‚Šå‚¾ę–œč·Æ(äø‹ē«Æ)悒čØ­ē½®ć™ć‚‹" #: lang/json/construction_from_json.py msgid "" @@ -91936,10 +92148,11 @@ msgid "" "high end of a ramp must be built adjacent to allow moving between z-levels " "in both directions." msgstr "" +"äø€ć¤äøŠć®å±¤ćøé€šć˜ć‚‹ć‚³ćƒ³ć‚ÆćƒŖćƒ¼ćƒˆč£½ć®å‚¾ę–œč·Æ悒ē¾åœØć®å±¤ć«čØ­ē½®ć—ć€ć“ć®å±¤ćøé€šć˜ć‚‹å‚¾ę–œč·Æ悒äø€ć¤äøŠć®å±¤ć«čØ­ē½®ć—ć¾ć™ć€‚ē•°ćŖć‚‹å±¤ćø恮ē§»å‹•ć‚’åÆčƒ½ć«ć™ć‚‹ćŸć‚ć«ćÆć€éš£ęŽ„ć™ć‚‹åœ°ē‚¹ć«äøŠć‚Šå‚¾ę–œč·Æ(äøŠē«Æ)悒čØ­ē½®ć—ć¦ćć ć•ć„ć€‚" #: lang/json/construction_from_json.py msgid "Build High End of a Concrete Ramp" -msgstr "" +msgstr "äøŠć‚Šå‚¾ę–œč·Æ(äøŠē«Æ)悒čØ­ē½®ć™ć‚‹" #: lang/json/construction_from_json.py msgid "" @@ -91948,6 +92161,7 @@ msgid "" "must be built next to a low end of a ramp to allow moving between z-levels " "in both directions." msgstr "" +"äø€ć¤äøŠć®å±¤ćøé€šć˜ć‚‹ć‚³ćƒ³ć‚ÆćƒŖćƒ¼ćƒˆč£½ć®å‚¾ę–œč·Æ悒ē¾åœØć®å±¤ć«čØ­ē½®ć—ć€ć“ć®å±¤ćøé€šć˜ć‚‹å‚¾ę–œč·Æ悒äø€ć¤äøŠć®å±¤ć«čØ­ē½®ć—ć¾ć™ć€‚ē•°ćŖć‚‹å±¤ćø恮ē§»å‹•ć‚’åÆčƒ½ć«ć™ć‚‹ćŸć‚ć«ćÆć€éš£ęŽ„ć™ć‚‹åœ°ē‚¹ć«äøŠć‚Šå‚¾ę–œč·Æ(äø‹ē«Æ)悒čØ­ē½®ć—ć¦ćć ć•ć„ć€‚" #: lang/json/construction_from_json.py msgid "Start Vehicle Construction" @@ -92080,6 +92294,26 @@ msgstr "壁(廃金属)悒ęŗ¶ęŽ„ć§č£œå¼·ć™ć‚‹" msgid "Build Junk Metal Floor" msgstr "åŗŠ(廃金属)悒čØ­ē½®ć™ć‚‹" +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Bolts" +msgstr "é‡‘å±žå±‘ć‚’å›ŗå®šć—ć¦ę©‹ć‚’čØ­ē½®ć™ć‚‹" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Welder" +msgstr "é‡‘å±žå±‘ć‚’ęŗ¶ęŽ„恗恦ꩋ悒čØ­ē½®ć™ć‚‹" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bench" +msgstr "ćƒ™ćƒ³ćƒ(金属屑)悒čØ­ē½®ć™ć‚‹" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Table" +msgstr "ćƒ†ćƒ¼ćƒ–ćƒ«(金属屑)悒čØ­ē½®ć™ć‚‹" + +#: lang/json/construction_from_json.py +msgid "Lay down decorative ground cable" +msgstr "č£…é£¾ē”Øć‚±ćƒ¼ćƒ–ćƒ«ć‚’čØ­ē½®ć™ć‚‹" + #: lang/json/construction_from_json.py msgid "Build Pillow Fort" msgstr "ꞕ恮ē ¦ć‚’čØ­ē½®ć™ć‚‹" @@ -94481,6 +94715,15 @@ msgstr "ē­‹č‚‰ć®ē—™ę”£ćŒę²»ć¾ć‚Šć¾ć—ćŸć€‚" msgid "Your muscles won't cooperate!" msgstr "ē­‹č‚‰ćŒäøŠę‰‹ćå‹•ćć¾ć›ć‚“ļ¼" +#: lang/json/effects_from_json.py +msgid "Minor Bleeding" +msgstr "å‡ŗ蔀(č»½å¾®)" + +#. ~ Description of effect 'Minor Bleeding'. +#: lang/json/effects_from_json.py +msgid "Tis but a scratch." +msgstr "ć‹ć™ć‚Šå‚·ć§ć™ć€‚" + #: lang/json/effects_from_json.py msgid "Bleeding" msgstr "å‡ŗ蔀(小)" @@ -94508,7 +94751,25 @@ msgstr "å‡ŗ蔀(大)" msgid "You are rapidly losing blood." msgstr "ę€„é€Ÿć«å¤±č”€ćŒé€²ć‚“ć§ć„ć¾ć™ć€‚" -#. ~ Apply message for effect(s) 'Bleeding, Bad Bleeding, Heavy Bleeding'. +#: lang/json/effects_from_json.py +msgid "Heavy Arterial Bleeding" +msgstr "å‡ŗ蔀(重ēƤ)" + +#. ~ Description of effect 'Heavy Arterial Bleeding'. +#: lang/json/effects_from_json.py +msgid "Blood is gushing from you like a fountain." +msgstr "å™“ę°“ć®ć‚ˆć†ć«å‡ŗč”€ć—ć¦ć„ć¾ć™ć€‚" + +#. ~ Apply message for effect(s) 'Minor Bleeding, Minor Bleeding, Minor +#. Bleeding, Minor Bleeding, Minor Bleeding, Bleeding, Bleeding, Bleeding, +#. Bleeding, Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, +#. Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad +#. Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, +#. Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy +#. Bleeding, Heavy Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding'. #: lang/json/effects_from_json.py msgid "You're bleeding!" msgstr "å‡ŗč”€ć—ć¦ć„ć¾ć™ļ¼" @@ -95261,39 +95522,91 @@ msgstr "ć‚«ćƒ«ć‚·ć‚¦ćƒ äøč¶³ćÆć»ć¼č§£ę¶ˆć•ć‚Œć¾ć—ćŸć€‚" msgid "Your bones become stronger as your calcium deficiency improves." msgstr "ć‚«ćƒ«ć‚·ć‚¦ćƒ äøč¶³ćŒę”¹å–„ć•ć‚Œć€éŖØćŒå‰ć‚ˆć‚Šå¼·é­ć«ćŖć‚Šć¾ć—ćŸć€‚" +#: lang/json/effects_from_json.py +msgid "Early iron deficiency" +msgstr "č»½åŗ¦é‰„分äøč¶³" + +#. ~ Description of effect 'Early iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"A lack of iron in your diet has hampered efficiency and regeneration of your" +" red blood cells." +msgstr "食äŗ‹äø­ć®é‰„åˆ†ćŒäøč¶³ć—恦恄悋ćØ态赤蔀ēƒć®č¼ø送効ēŽ‡ćØ再ē”ŸåŠ›ćŒä½Žäø‹ć—ć¾ć™ć€‚" + #: lang/json/effects_from_json.py msgid "Iron deficiency" msgstr "鉄分äøč¶³" +#. ~ Description of effect 'Iron deficiency'. #: lang/json/effects_from_json.py -msgid "Early anemia" -msgstr "č»½åŗ¦č²§č”€" +msgid "" +"Prolonged lack of iron in your diet has compromised efficiency and " +"regeneration of your red blood cells." +msgstr "食äŗ‹äø­ć®é‰„åˆ†ćŒäøč¶³ć—恦恄悋ćØ态赤蔀ēƒć®č¼ø送効ēŽ‡ćØ再ē”ŸåŠ›ćŒč‘—ć—ćä½Žäø‹ć—ć¾ć™ć€‚" #: lang/json/effects_from_json.py -msgid "Anemia" -msgstr "重åŗ¦č²§č”€" +msgid "Acute iron deficiency" +msgstr "é‰„ę¬ ä¹ē—‡" +#. ~ Description of effect 'Acute iron deficiency'. #: lang/json/effects_from_json.py msgid "" -"A lack of iron in your diet will result in progressively worsening anemia." -msgstr "食äŗ‹å†…ć®é‰„åˆ†ćŒäøč¶³ć™ć‚‹ćØć€č²§č”€ćŒę¬”ē¬¬ć«ę‚ŖåŒ–ć—ć¾ć™ć€‚" +"Severe lack of iron in your diet results in your red blood cells dying " +"faster then they are regenerating." +msgstr "ę·±åˆ»ćŖćƒ¬ćƒ™ćƒ«ć§é£Ÿäŗ‹äø­ć®é‰„åˆ†ćŒę¬ ä¹ć—ć¦ćŠć‚Šć€å†ē”Ÿć™ć‚‹ć‚ˆć‚Šć‚‚ę—©ćčµ¤č”€ēƒćŒę­»ć‚“ć§ć—ć¾ć„ć¾ć™ć€‚" -#. ~ Apply message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Apply message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#. ~ Apply message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You begin feeling increasingly tired and listless." msgstr "ē–²ć‚ŒćŒćŸć¾ć‚Šć€ę†‚鬱ćŖę°—åˆ†ć§ć™ć€‚" -#. ~ Remove message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Remove message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "You are no longer in risk of becoming anemic." +msgstr "č²§č”€ć«ćŖ悉ćŖć„ä½“čŖæć¾ć§å›žå¾©ć—ć¾ć—ćŸć€‚" + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your irom deficiency is nearly resolved." +msgstr "é‰„ę¬ ä¹ē—‡ćÆć»ć¼č§£ę¶ˆć•ć‚Œć¾ć—ćŸć€‚" + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your iron deficiency starts to improve." +msgstr "é‰„ę¬ ä¹ē—‡ćŒę”¹å–„ć—å§‹ć‚ć€å…ƒę°—ć«ćŖć£ćŸę°—ćŒć—ć¾ć™ć€‚" + +#: lang/json/effects_from_json.py +msgid "Early anemia" +msgstr "č»½åŗ¦č²§č”€" + +#: lang/json/effects_from_json.py +msgid "Anemia" +msgstr "č²§č”€" + +#: lang/json/effects_from_json.py +msgid "Acute anemia" +msgstr "重åŗ¦č²§č”€" + +#: lang/json/effects_from_json.py +msgid "Loss of red blood cells results in progressively worsening anemia." +msgstr "" + +#. ~ Remove message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You no longer feel anemic." msgstr "č²§č”€ćŒę²»ć‚Šć¾ć—ćŸć€‚" -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py -msgid "Your iron deficiency is nearly resolved." -msgstr "鉄分äøč¶³ćÆć»ć¼č§£ę¶ˆć•ć‚Œć¾ć—ćŸć€‚" +msgid "Your anemia is nearly resolved." +msgstr "" -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "Your feel stronger as your anemia starts to improve." msgstr "č²§č”€ćŒę”¹å–„ć—ć€å‰ć‚ˆć‚Šå¼·ććŖć£ćŸę°—ćŒć—ć¾ć™ć€‚" @@ -95481,6 +95794,77 @@ msgid "" "disgusting rations day in and day out?" msgstr "ē¢ŗ恋恫态ē”Ÿćć¦ćÆć„ć¾ć™ć€‚ć—ć‹ć—ć€ć“ć‚“ćŖćƒ¢ćƒŽć‚’é£Ÿć¹ē¶šć‘ć¦ć¾ć§ē”Ÿćē¶šć‘ć‚‹ę„å‘³ćŒć‚ć‚‹ć®ć§ć—ć‚‡ć†ć‹ļ¼Ÿ" +#: lang/json/effects_from_json.py +msgid "Mild hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Mild hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost some blood and look somewhat pale." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Moderate hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Moderate hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost large amount of blood, and you're not feeling well." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Advanced hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Advanced hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost an awful lot of blood, and your condition is severe. Seek " +"medical attention." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Severe hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost tremendous amount of blood, and you're standing on death's door." +" Transfusion might save you." +msgstr "" + +#. ~ Apply message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You have lost lot of blood, and your condition worsens." +msgstr "" + +#. ~ Remove message for effect(s) 'Mild hypovolemic shock, Moderate +#. hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You are no longer in shock." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your blood level increase, and you feel better, but still look pale." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your blood levels starts to improve." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You're not dying from lack of blood, but you're not out of the woods yet." +msgstr "" + #: lang/json/effects_from_json.py msgid "Lit up" msgstr "ē…§ę˜Ž" @@ -97380,25 +97764,346 @@ msgid "mutated cactus" msgstr "変ē•°ć—ćŸć‚µćƒœćƒ†ćƒ³" #: lang/json/furniture_from_json.py -msgid "cooling unit" -msgstr "å®¤å¤–ę©Ÿ" +msgid "glowing tendril" +msgstr "č¼ćč§¦ę‰‹" -#. ~ Description for cooling unit +#. ~ Description for glowing tendril #: lang/json/furniture_from_json.py msgid "" -"A large, blocky appliance encased in sheet metal. This commonplace fixture " -"is used for cooling large indoor areas." -msgstr "é‡‘å±žć§č¦†ć‚ć‚ŒćŸć€å¤§ććŖē®±åž‹ę©Ÿę¢°ć§ć™ć€‚äø€čˆ¬ēš„恫ćÆ态åŗƒć„å®¤å†…ć‚’å†·ć‚„ć™ćŸć‚ć«ä½æć‚ć‚Œć¾ć™ć€‚" +"A willowy tendril growing from the floor, gently waving back and forth. A " +"faint light spills from it." +msgstr "ć‹ć™ć‹ć«å…‰ć‚‹ć—ćŖ悄恋ćŖå·»é«­ćŒč¶³äø‹ć‹ć‚‰ä¼øć³ć€ć‚†ć£ćć‚ŠćØęŗć‚Œć¦ć„ć¾ć™ć€‚" + +#: lang/json/furniture_from_json.py +msgid "splorch!" +msgstr "ćƒ™ćƒćƒ£ćƒƒļ¼" #: lang/json/furniture_from_json.py lang/json/furniture_from_json.py #: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "metal screeching!" -msgstr "[é‡‘å±žćŒč»‹ć‚€éŸ³]" +msgid "whump!" +msgstr "ćƒ‰ćƒ¼ćƒ³ļ¼" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py +msgid "wafting anemone" +msgstr "ęŗć‚‰ć‚ćč§¦ę‰‹" + +#. ~ Description for wafting anemone +#: lang/json/furniture_from_json.py +msgid "" +"A fleshy white protuberance growing from the floor, with a cluster of " +"tendrils pouring out of it. It looks almost exactly like a sea anemone, " +"even waving gently as though underwater." +msgstr "å¤šč‚‰č³Ŗ恮ē™½ć„ē˜¤ćŒåœ°é¢ć‹ć‚‰ē”Ÿćˆć€ćć®äø­å¤®ć‹ć‚‰č¤‡ę•°ć®č§¦ę‰‹ćŒä¼øć³ć¦ć„ć¾ć™ć€‚č§¦ę‰‹ćÆé™ć‹ć«ęŗć‚Œć¦ćŠć‚Šć€ćć®å§æćÆć¾ć‚‹ć§ć‚¤ć‚½ć‚®ćƒ³ćƒćƒ£ć‚Æ恧恙怂" + +#: lang/json/furniture_from_json.py +msgid "gasping tube" +msgstr "éœ‡ćˆć‚‹č‚‰ęŸ±" + +#. ~ Description for gasping tube +#: lang/json/furniture_from_json.py +msgid "" +"This is a meaty green stalactite with a thickened hide like that of a " +"starfish, extending from the floor to the ceiling. In the center is a " +"series of ports somewhat like mouths, from which pour bursts of a vile-" +"smelling gas." +msgstr "" +"åœ°é¢ć‹ć‚‰ć‹ć‚‰å¤©äŗ•ć¾ć§ä¼øć³ćŸć€ē·‘č‰²ć®ćƒ’ćƒˆćƒ‡ć®ć‚ˆć†ć«ć‚‚č¦‹ćˆć‚‹å¤šč‚‰č³Ŗć®ęŸ±ć§ć™ć€‚äø­å¤®ć«ćÆå£ć®ć‚ˆć†ćŖ噓å‡ŗå­”ćŒé€£ćŖć£ć¦ćŠć‚Šć€ćć“ć‹ć‚‰ę‚Ŗč‡­ć‚’ę”¾ć¤ć‚¬ć‚¹ć‚’å™“ćå‡ŗć—ć¾ć™ć€‚" + +#: lang/json/furniture_from_json.py +msgid "twitching frond" +msgstr "å¼•ćć¤ć‚‹č‚‰č‘‰" + +#. ~ Description for twitching frond +#: lang/json/furniture_from_json.py +msgid "" +"A spine resembling moth antennae juts from the ground, swaying gently in the" +" air. Every so often, a cascade of energy arcs along it and discharges into" +" the ceiling." +msgstr "ć‚¬ć®č§¦č¦šć®ć‚ˆć†ćŖēŖčµ·ćŒåœ°é¢ć‹ć‚‰ē”Ÿćˆć€é¢Øć«ä¹—ć£ć¦ē©ć‚„恋恫ęŗć‚Œć¦ć„ć¾ć™ć€‚ę™‚ęŠ˜é›»ę’ƒć®ęø¦ćŒē™ŗē”Ÿć—恦ćÆē«‹ć”ę˜‡ć£ć¦ć„ćć¾ć™ć€‚" + +#: lang/json/furniture_from_json.py +msgid "scarred lump" +msgstr "č£‚ć‘ćŸč‚‰č…«" + +#. ~ Description for scarred lump +#: lang/json/furniture_from_json.py +msgid "" +"This is a pile of nondescript alien flesh, twitching and belching strange " +"gases out of injured orifices." +msgstr "ę­£ä½“äøę˜Žć®ē—™ę”£ć™ć‚‹č‚‰å”Šć§ć™ć€‚č”Øé¢ć®č”€ē®”ćŒč£‚ć‘ć€å‚·å£ć‹ć‚‰å„‡å¦™ćŖć‚¬ć‚¹ć‚’ę”¾å‡ŗć—ć¦ć„ć¾ć™ć€‚" + +#: lang/json/furniture_from_json.py +msgid "splat!" +msgstr "ćƒ”ć‚·ćƒ£ćƒƒļ¼" + +#: lang/json/furniture_from_json.py +msgid "slimy pod" +msgstr "ē²˜ć¤ćč‚‰ē˜¤" + +#. ~ Description for slimy pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a slick, translucent pod suspended on a thin stalk. It is covered " +"in a thick mucus, obscuring whatever is floating in the gel-like substance " +"inside." +msgstr "" +"ē“°ć„čŒŽć®å…ˆē«Æ恫恬悋恬悋ćØć—ćŸåŠé€ę˜Žć®ē˜¤ćŒåŠć‚‹ć•ć‚Œć¦ć„ć¾ć™ć€‚ć¹ćØ恤恏ē²˜ę¶²ć§č¦†ć‚ć‚Œć¦ćŠć‚Šć€ē˜¤ć®å†…éƒØ恫ē²˜ę¶²ćØå…±ć«å…„ć£ć¦ć„ć‚‹ē‰©ć®ę­£ä½“ćÆ判ē„¶ćØć—ć¾ć›ć‚“ć€‚" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "whump." +msgstr "ćƒ‰ćƒ³ć€‚" + +#: lang/json/furniture_from_json.py +msgid "organ pod" +msgstr "肉ē˜¤(å†…č‡“)" + +#. ~ Description for organ pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside you can see the" +" dimly outlined shape of human organs, floating in some kind of preservative" +" goo." +msgstr "ē“°ć„čŒŽć®å…ˆē«Æć«åŠé€ę˜Žć®ē˜¤ćŒåŠć‚‹ć•ć‚Œć¦ć„ć¾ć™ć€‚ē˜¤ć®å†…éƒØ恫ćÆ态ē²˜ę¶²ćØå…±ć«äŗŗ間恮臓å™Øć®ć‚ˆć†ćŖć‚‚ć®ćŒå…„ć£ć¦ć„ć‚‹ć‚ˆć†ć§ć™ć€‚" + +#: lang/json/furniture_from_json.py +msgid "resin pod" +msgstr "肉ē˜¤(ęØ¹č„‚)" + +#. ~ Description for resin pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside is a clean, " +"clear resinous-looking fluid. You could fairly easily tear it from the " +"stalk and take it with you." +msgstr "ē“°ć„čŒŽć®å…ˆē«Æć«åŠé€ę˜Žć®ē˜¤ćŒåŠć‚‹ć•ć‚Œć¦ć„ć¾ć™ć€‚ē˜¤ć®å†…éƒØ恫ćÆ态ęØ¹č„‚ć®ć‚ˆć†ćŖ透꘎ćŖę¶²ä½“ćŒå…„ć£ć¦ć„ć¾ć™ć€‚č‚‰ē˜¤ćÆ茎恋悉ē°”å˜ć«å–ć‚Šå¤–ć›ćć†ć§ć™ć€‚" + +#: lang/json/furniture_from_json.py +msgid "fleshy altar" +msgstr "肉恮ē„­å£‡" + +#. ~ Description for fleshy altar +#: lang/json/furniture_from_json.py +msgid "" +"This pulsing protuberance juts from the floor, its sides covered in scaled, " +"oozing skin. The surface is flat, but undulates softly. A handful of " +"unidentifiable appendages reach from the sides, suggesting a sort of " +"nightmarish living autodoc." +msgstr "" +"脈ꉓ恤ē„­å£‡ćŒåŗŠć‹ć‚‰ēŖćå‡ŗć—ć¦ćŠć‚Šć€ćć®å“é¢ćÆ鱗恮ē”ŸćˆćŸćƒŒćƒ”ćƒŒćƒ”ć®ēš®ć§č¦†ć‚ć‚Œć¦ć„ć¾ć™ć€‚ę­£ä½“äøę˜Žć®ēŖčµ·ćŒå“é¢ć‹ć‚‰ē”Ÿćˆć¦ćŠć‚Šć€ć“恮ē„­å£‡ćŒć‚ć‚‹ēØ®ć®ē”ŸććŸć‚Ŗćƒ¼ćƒˆćƒ‰ć‚Æ恧恂悋ćØ恄恆ę‚Ŗå¤¢ć®ć‚ˆć†ćŖäŗ‹å®Ÿć‚’ē¤ŗć—ć¦ć„ć¾ć™ć€‚" + +#: lang/json/furniture_from_json.py +msgid "scrap antenna" +msgstr "" + +#. ~ Description for scrap antenna +#: lang/json/furniture_from_json.py +msgid "" +"This contraption looks like some sort of cobbled-together transmitter or " +"receiver antenna. It consists of a number of mismatched blinking lights, " +"spinning servos, and dangling wires connected to a heft metal box." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py msgid "clang!" msgstr "ć‚¬ćƒ³ļ¼" +#: lang/json/furniture_from_json.py +msgid "rack of robots" +msgstr "" + +#. ~ Description for rack of robots +#: lang/json/furniture_from_json.py +msgid "" +"This is a wire cage containing a number of robot parts, from chassis to " +"limbs, firmly clamped on to sturdy hanging rods. It looks like it would be " +"exceptionally difficult to open it and get at them without damaging them, " +"probably by design." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "spinning dish" +msgstr "" + +#. ~ Description for spinning dish +#: lang/json/furniture_from_json.py +msgid "" +"This is a slowly spinning parabolic dish engraved with an unrecognizable " +"pattern of symbols that might, at a guess, be some sort of circuitry pattern" +" - or maybe a religious incantation. It is mounted on a completely " +"mismatched electric motor that looks fairly mundane." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scavenged utility light" +msgstr "" + +#. ~ Description for scavenged utility light +#: lang/json/furniture_from_json.py +msgid "" +"The bulbs emit an eery greenish glow, and some parts of it have a curved " +"appearance as though the metal were grown in a lab, but by and large this " +"isn't a particularly unusual looking area light." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "clanking fluid pump" +msgstr "" + +#. ~ Description for clanking fluid pump +#: lang/json/furniture_from_json.py +msgid "" +"The huge sweating pipes and large tank reveal this clanking and tortuous " +"piece of equipment to be some sort of fluid pump. It is cobbled from " +"several apparently ill-fitting parts that have been fitted together with " +"some very strange looking but surprisingly clever adaptors." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "metalloid printer" +msgstr "" + +#. ~ Description for metalloid printer +#: lang/json/furniture_from_json.py +msgid "" +"This huge device actually resembles a 3D printer fairly closely, aside from " +"its industrial size. Huge spools of various thin metallic wires top it and " +"feed into what seems to be some sort of nozzle, and massive electrical " +"cables disappear into the wall behind it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "circuit printer" +msgstr "" + +#. ~ Description for circuit printer +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall device with a lattice of pipes and nozzles. Based on the " +"pile of products sitting in the output hopper, it looks like itā€™s used as a " +"printer for complex electronic components." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "Mavrik 10-101 power core" +msgstr "" + +#. ~ Description for Mavrik 10-101 power core +#: lang/json/furniture_from_json.py +msgid "" +"There is a faded metallic plaque on the side of this cylindrical device. The lettering is a strange combination of English and Cyrillic script. It reads:\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "metal screeching!" +msgstr "[é‡‘å±žćŒč»‹ć‚€éŸ³]" + +#: lang/json/furniture_from_json.py +msgid "spherical generator" +msgstr "" + +#. ~ Description for spherical generator +#: lang/json/furniture_from_json.py +msgid "" +"This huge steel plated sphere gives off a soft hum as it, presumably, " +"generates power. A heavy lead plate bolted to the front might describe what" +" it is, but it is written in something that looks vaguely like cuneiform." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "fluidic generator" +msgstr "" + +#. ~ Description for fluidic generator +#: lang/json/furniture_from_json.py +msgid "" +"Twisting reams of copper and steel pipes wrap around a central core that " +"thrums softly. Although there are no labels in any language you recognize, " +"the cables connected to the base suggest that this is some sort of power " +"generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "rusty generator" +msgstr "" + +#. ~ Description for rusty generator +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall, unremarkable cylinder capped by a wide flat saucer. There " +"is heavy rusting at the base. A series of connected cables suggest that " +"it's some sort of power generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "personal charging station" +msgstr "" + +#. ~ Description for personal charging station +#: lang/json/furniture_from_json.py +msgid "" +"The cyborg equivalent of a bed, this is a custom-shaped near-vertical booth " +"designed to mount a heavy metal frame and connect it to a central power " +"supply and nutrient source." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp +msgid "crash!" +msgstr "ć‚¬ćƒćƒ£ćƒ³ļ¼" + +#: lang/json/furniture_from_json.py +msgid "simple charging station" +msgstr "" + +#. ~ Description for simple charging station +#: lang/json/furniture_from_json.py +msgid "" +"This is a simple, unadorned, corroded metal charging and refeeding station, " +"with hookups for two units somewhat larger than a human to stand side by " +"side and be recharged and refueled." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shimmering superstructure" +msgstr "" + +#. ~ Description for shimmering superstructure +#: lang/json/furniture_from_json.py +msgid "" +"A simple metal superstructure like you might see holding up a radio tower, " +"this one seems to give off just the faintest hint of shimmer, like heat " +"waves. The metal has a burnt, iridescent pattern. There is a boxy, " +"unimpressive looking device at the top of the tower." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "portal enclosure" +msgstr "" + +#. ~ Description for portal enclosure +#: lang/json/furniture_from_json.py +msgid "" +"A heavy metal ring attached to dozens of wires, charred by residue that " +"gives off an acrid, unfamiliar smell." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "cooling unit" +msgstr "å®¤å¤–ę©Ÿ" + +#. ~ Description for cooling unit +#: lang/json/furniture_from_json.py +msgid "" +"A large, blocky appliance encased in sheet metal. This commonplace fixture " +"is used for cooling large indoor areas." +msgstr "é‡‘å±žć§č¦†ć‚ć‚ŒćŸć€å¤§ććŖē®±åž‹ę©Ÿę¢°ć§ć™ć€‚äø€čˆ¬ēš„恫ćÆ态åŗƒć„å®¤å†…ć‚’å†·ć‚„ć™ćŸć‚ć«ä½æć‚ć‚Œć¾ć™ć€‚" + #: lang/json/furniture_from_json.py msgid "central air filter" msgstr "ē©ŗ갗ęø…ęµ„č£…ē½®" @@ -97562,8 +98267,7 @@ msgid "" "priceless tools, invaluable to any survivor." msgstr "å¤Ŗé™½å…‰ć‚’é›»ę°—ć«å¤‰ćˆć¦åˆ©ē”Ø恙悋å¤Ŗ陽光ē™ŗé›»ę©Ÿć®ć‚»ćƒƒćƒˆć§ć™ć€‚å¤§å¤‰å‹•ć®å‰ć‹ć‚‰ęœ‰ē”Øć§ć—ćŸćŒć€ä»ŠćÆ恩悓ćŖē”Ÿå­˜č€…恫ćØć£ć¦ć‚‚ć‹ć‘ćŒćˆć®ćŖć„č²“é‡ćŖč£…ē½®ć§ć™ć€‚" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py msgid "whack!" msgstr "ćƒć‚·ćƒƒļ¼" @@ -97580,16 +98284,12 @@ msgid "" msgstr "" "道č·Æć®é€šč”Œć‚’é®ę–­ć™ć‚‹ćŸć‚ć«ä½æć‚ć‚Œć‚‹ć€å¤§ććŖęœØč£½ć®å°éŽ–ęæ恧恙怂視čŖę€§ć‚’é«˜ć‚ć‚‹ćŸć‚ć®åå°„ćƒ†ćƒ¼ćƒ—ćŒč²¼ć‚Šä»˜ć‘ć¦ć‚ć‚Šć¾ć™ć€‚ćć®åå‰ć«ć‚‚ć‹ć‹ć‚ć‚‰ćšć€é‹č»¢äø­ć®č»Šć‚’ę­¢ć‚ć‚‹ć“ćØćÆ恻ćØ悓恩äøåÆčƒ½ć§ć™ć€‚" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -#: src/mapdata.cpp src/vehicle_move.cpp +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/map.cpp src/mapdata.cpp +#: src/vehicle_move.cpp msgid "smash!" msgstr "ć‚¬ćƒćƒ£ćƒ³ļ¼" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -msgid "whump." -msgstr "ćƒ‰ćƒ³ć€‚" - #: lang/json/furniture_from_json.py msgid "earthbag barricade" msgstr "åœŸåš¢ćƒćƒŖć‚±ćƒ¼ćƒ‰" @@ -97927,10 +98627,6 @@ msgid "" "them moving slightly. Gross." msgstr "å¤§ććŖć‚Ŗ惕惛ćƒÆć‚¤ćƒˆć®åµć®é›†åˆä½“ć§ć™ć€‚čæ‘åÆ„ć£ć¦ćæ悋ćØć€ć‚ćšć‹ć«å‹•ćäø­čŗ«ćŒč¦‹ćˆć¾ć™ć€‚ę°—ęŒć”ę‚Ŗ恄恧恙恭怂" -#: lang/json/furniture_from_json.py -msgid "splat!" -msgstr "ćƒ”ć‚·ćƒ£ćƒƒļ¼" - #. ~ Description for spider egg sack #: lang/json/furniture_from_json.py msgid "" @@ -98010,16 +98706,6 @@ msgid "" "the smoke to the outside. Dangerous to leave unattended while lit." msgstr "å®¤å†…ć§å®‰å…Ø恫ē«ć‚’čµ·ć“ć™ćŸć‚ć«ä½æ恆态äø€čˆ¬ēš„ćŖå®¶å…·ć§ć™ć€‚ē…™ć‚’å±‹å¤–ć«ęŽ’å‡ŗć™ć‚‹ćŸć‚ć®ē…™ēŖćŒä»˜ć„ć¦ć„ć¾ć™ć€‚ē«ć‚’ć¤ć‘ćŸć¾ć¾ę”¾ē½®ć™ć‚‹ć®ćÆ危é™ŗ恧恙怂" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -msgid "crash!" -msgstr "ć‚¬ćƒćƒ£ćƒ³ļ¼" - -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "whump!" -msgstr "ćƒ‰ćƒ¼ćƒ³ļ¼" - #: lang/json/furniture_from_json.py msgid "wood stove" msgstr "č–Ŗć‚¹ćƒˆćƒ¼ćƒ–" @@ -98179,8 +98865,9 @@ msgid "" "comfort or warmth." msgstr "ē©ćæäøŠć’ć‚‰ć‚ŒćŸęžÆ悌草恧恙怂åæ«é©ć•ć‚„Ꚗ恋恕悒갗恫恗ćŖ恄ćŖ悉态惙惃惉ćØ恗恦ä½æćˆć¾ć™ć€‚" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -#: src/iuse.cpp +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/iuse.cpp msgid "crunch!" msgstr "惐ćƒŖ惐ćƒŖ惃ļ¼" @@ -98347,6 +99034,78 @@ msgid "" " chemicals." msgstr "電動ę”Ŗę‹Œč£…ē½®ć‚’å‚™ćˆćŸć€å¤§é‡ć®č–¬å“ć‚’ę··åˆć™ć‚‹å¤§åž‹ć®ę”¶ć§ć™ć€‚" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken generator" +msgstr "å£Šć‚ŒćŸē™ŗé›»ę©Ÿ" + +#. ~ Description for broken generator +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This generator is broken and will not help you produce usable electricity." +msgstr "恓恮ē™ŗé›»ę©ŸćÆå£Šć‚Œć¦ćŠć‚Šć€ē™ŗé›»čƒ½åŠ›ćÆć‚ć‚Šć¾ć›ć‚“ć€‚" + +#: lang/json/furniture_from_json.py +msgid "Compact Advanced Sterling Radioisotope Generator" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"This hefty lump of steel and lead is the housing unit for a small nuclear " +"reactor. It is plastered with warning signs. You could probably ignore " +"those and salvage the steel and lead shielding, what could possibly go " +"wrong?" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"Some insane fool has removed the outer containment on this small-scale " +"nuclear reactor. It is still fairly safe as it is: the reactor has " +"considerable built-in containment as well. Nevertheless, you probably don't" +" want to stand too close for too long." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "light machinery" +msgstr "č»½ę©Ÿę¢°" + +#. ~ Description for light machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted light machinery. You could scavenge it for parts." +msgstr "꧘怅ćŖč»½ę©Ÿę¢°ć§ć™ć€‚åˆ†č§£ć™ć‚Œć°éƒØå“ćŒå…„ę‰‹ć§ćć¾ć™ć€‚" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "ting." +msgstr "ć‚«ćƒćƒ³ć€‚" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "heavy machinery" +msgstr "é‡ę©Ÿę¢°" + +#. ~ Description for heavy machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted heavy machinery. You could scavenge it for parts." +msgstr "꧘怅ćŖé‡ę©Ÿę¢°ć§ć™ć€‚åˆ†č§£ć™ć‚Œć°éƒØå“ćŒå…„ę‰‹ć§ćć¾ć™ć€‚" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "old machinery" +msgstr "å¤ć„ę©Ÿę¢°" + +#. ~ Description for old machinery +#: lang/json/furniture_from_json.py +msgid "Assorted old, rusty machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "electronic machinery" +msgstr "é›»å­ę©Ÿę¢°" + +#. ~ Description for electronic machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted electronic machinery. You could scavenge it for parts." +msgstr "꧘怅ćŖé›»å­ę©Ÿå™Øć§ć™ć€‚åˆ†č§£ć™ć‚Œć°éƒØå“ćŒå…„ę‰‹ć§ćć¾ć™ć€‚" + #: lang/json/furniture_from_json.py msgid "robotic arm" msgstr "ćƒ­ćƒœćƒƒćƒˆć‚¢ćƒ¼ćƒ " @@ -98364,6 +99123,32 @@ msgstr "ēµ„ćæē«‹ć¦ćƒ©ć‚¤ćƒ³ć§ć®ä½œę„­ć«é©ć—ćŸć€ē‰¹ę®ŠćŖčØ­čØˆć§ćÆćŖ msgid "thunk." msgstr "ćƒ‰ć‚¹ćƒ³ć€‚" +#: lang/json/furniture_from_json.py +msgid "ground cable" +msgstr "" + +#. ~ Description for ground cable +#: lang/json/furniture_from_json.py +msgid "A bunch of loose cables snake along the floor." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shred!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "thud!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "capacitor bank" +msgstr "" + +#. ~ Description for capacitor bank +#: lang/json/furniture_from_json.py +msgid "A bank of heavy metal cylinders connected by large wires." +msgstr "" + #: lang/json/furniture_from_json.py msgid "Autodoc Mk. XI" msgstr "ć‚Ŗćƒ¼ćƒˆćƒ‰ć‚ÆMk.XI" @@ -98637,120 +99422,18 @@ msgstr "é–“ä»•åˆ‡ć‚Šć‚«ćƒ¼ćƒ†ćƒ³ć‚’é–‹ć‘ć‚‹" msgid "Stop peeking!" msgstr "č¦—ćć®ć‚’ę­¢ć‚ć‚ļ¼" -#: lang/json/furniture_from_json.py -msgid "glowing tendril" -msgstr "č¼ćč§¦ę‰‹" - -#. ~ Description for glowing tendril -#: lang/json/furniture_from_json.py -msgid "" -"A willowy tendril growing from the floor, gently waving back and forth. A " -"faint light spills from it." -msgstr "ć‹ć™ć‹ć«å…‰ć‚‹ć—ćŖ悄恋ćŖå·»é«­ćŒč¶³äø‹ć‹ć‚‰ä¼øć³ć€ć‚†ć£ćć‚ŠćØęŗć‚Œć¦ć„ć¾ć™ć€‚" - -#: lang/json/furniture_from_json.py -msgid "splorch!" -msgstr "ćƒ™ćƒćƒ£ćƒƒļ¼" - -#: lang/json/furniture_from_json.py -msgid "wafting anemone" -msgstr "ęŗć‚‰ć‚ćč§¦ę‰‹" - -#. ~ Description for wafting anemone -#: lang/json/furniture_from_json.py -msgid "" -"A fleshy white protuberance growing from the floor, with a cluster of " -"tendrils pouring out of it. It looks almost exactly like a sea anemone, " -"even waving gently as though underwater." -msgstr "å¤šč‚‰č³Ŗ恮ē™½ć„ē˜¤ćŒåœ°é¢ć‹ć‚‰ē”Ÿćˆć€ćć®äø­å¤®ć‹ć‚‰č¤‡ę•°ć®č§¦ę‰‹ćŒä¼øć³ć¦ć„ć¾ć™ć€‚č§¦ę‰‹ćÆé™ć‹ć«ęŗć‚Œć¦ćŠć‚Šć€ćć®å§æćÆć¾ć‚‹ć§ć‚¤ć‚½ć‚®ćƒ³ćƒćƒ£ć‚Æ恧恙怂" - -#: lang/json/furniture_from_json.py -msgid "gasping tube" -msgstr "éœ‡ćˆć‚‹č‚‰ęŸ±" - -#. ~ Description for gasping tube -#: lang/json/furniture_from_json.py -msgid "" -"This is a meaty green stalactite with a thickened hide like that of a " -"starfish, extending from the floor to the ceiling. In the center is a " -"series of ports somewhat like mouths, from which pour bursts of a vile-" -"smelling gas." -msgstr "" -"åœ°é¢ć‹ć‚‰ć‹ć‚‰å¤©äŗ•ć¾ć§ä¼øć³ćŸć€ē·‘č‰²ć®ćƒ’ćƒˆćƒ‡ć®ć‚ˆć†ć«ć‚‚č¦‹ćˆć‚‹å¤šč‚‰č³Ŗć®ęŸ±ć§ć™ć€‚äø­å¤®ć«ćÆå£ć®ć‚ˆć†ćŖ噓å‡ŗå­”ćŒé€£ćŖć£ć¦ćŠć‚Šć€ćć“ć‹ć‚‰ę‚Ŗč‡­ć‚’ę”¾ć¤ć‚¬ć‚¹ć‚’å™“ćå‡ŗć—ć¾ć™ć€‚" - -#: lang/json/furniture_from_json.py -msgid "twitching frond" -msgstr "å¼•ćć¤ć‚‹č‚‰č‘‰" - -#. ~ Description for twitching frond -#: lang/json/furniture_from_json.py -msgid "" -"A spine resembling moth antennae juts from the ground, swaying gently in the" -" air. Every so often, a cascade of energy arcs along it and discharges into" -" the ceiling." -msgstr "ć‚¬ć®č§¦č¦šć®ć‚ˆć†ćŖēŖčµ·ćŒåœ°é¢ć‹ć‚‰ē”Ÿćˆć€é¢Øć«ä¹—ć£ć¦ē©ć‚„恋恫ęŗć‚Œć¦ć„ć¾ć™ć€‚ę™‚ęŠ˜é›»ę’ƒć®ęø¦ćŒē™ŗē”Ÿć—恦ćÆē«‹ć”ę˜‡ć£ć¦ć„ćć¾ć™ć€‚" - -#: lang/json/furniture_from_json.py -msgid "scarred lump" -msgstr "č£‚ć‘ćŸč‚‰č…«" - -#. ~ Description for scarred lump -#: lang/json/furniture_from_json.py -msgid "" -"This is a pile of nondescript alien flesh, twitching and belching strange " -"gases out of injured orifices." -msgstr "ę­£ä½“äøę˜Žć®ē—™ę”£ć™ć‚‹č‚‰å”Šć§ć™ć€‚č”Øé¢ć®č”€ē®”ćŒč£‚ć‘ć€å‚·å£ć‹ć‚‰å„‡å¦™ćŖć‚¬ć‚¹ć‚’ę”¾å‡ŗć—ć¦ć„ć¾ć™ć€‚" - -#: lang/json/furniture_from_json.py -msgid "slimy pod" -msgstr "ē²˜ć¤ćč‚‰ē˜¤" - -#. ~ Description for slimy pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a slick, translucent pod suspended on a thin stalk. It is covered " -"in a thick mucus, obscuring whatever is floating in the gel-like substance " -"inside." -msgstr "" -"ē“°ć„čŒŽć®å…ˆē«Æ恫恬悋恬悋ćØć—ćŸåŠé€ę˜Žć®ē˜¤ćŒåŠć‚‹ć•ć‚Œć¦ć„ć¾ć™ć€‚ć¹ćØ恤恏ē²˜ę¶²ć§č¦†ć‚ć‚Œć¦ćŠć‚Šć€ē˜¤ć®å†…éƒØ恫ē²˜ę¶²ćØå…±ć«å…„ć£ć¦ć„ć‚‹ē‰©ć®ę­£ä½“ćÆ判ē„¶ćØć—ć¾ć›ć‚“ć€‚" - -#: lang/json/furniture_from_json.py -msgid "organ pod" -msgstr "肉ē˜¤(å†…č‡“)" - -#. ~ Description for organ pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside you can see the" -" dimly outlined shape of human organs, floating in some kind of preservative" -" goo." -msgstr "ē“°ć„čŒŽć®å…ˆē«Æć«åŠé€ę˜Žć®ē˜¤ćŒåŠć‚‹ć•ć‚Œć¦ć„ć¾ć™ć€‚ē˜¤ć®å†…éƒØ恫ćÆ态ē²˜ę¶²ćØå…±ć«äŗŗ間恮臓å™Øć®ć‚ˆć†ćŖć‚‚ć®ćŒå…„ć£ć¦ć„ć‚‹ć‚ˆć†ć§ć™ć€‚" - -#: lang/json/furniture_from_json.py -msgid "resin pod" -msgstr "肉ē˜¤(ęØ¹č„‚)" - -#. ~ Description for resin pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside is a clean, " -"clear resinous-looking fluid. You could fairly easily tear it from the " -"stalk and take it with you." -msgstr "ē“°ć„čŒŽć®å…ˆē«Æć«åŠé€ę˜Žć®ē˜¤ćŒåŠć‚‹ć•ć‚Œć¦ć„ć¾ć™ć€‚ē˜¤ć®å†…éƒØ恫ćÆ态ęØ¹č„‚ć®ć‚ˆć†ćŖ透꘎ćŖę¶²ä½“ćŒå…„ć£ć¦ć„ć¾ć™ć€‚č‚‰ē˜¤ćÆ茎恋悉ē°”å˜ć«å–ć‚Šå¤–ć›ćć†ć§ć™ć€‚" - -#: lang/json/furniture_from_json.py -msgid "fleshy altar" -msgstr "肉恮ē„­å£‡" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "centrifuge" +msgstr "遠åæƒåˆ†é›¢č£…ē½®" -#. ~ Description for fleshy altar +#. ~ Description for centrifuge #: lang/json/furniture_from_json.py msgid "" -"This pulsing protuberance juts from the floor, its sides covered in scaled, " -"oozing skin. The surface is flat, but undulates softly. A handful of " -"unidentifiable appendages reach from the sides, suggesting a sort of " -"nightmarish living autodoc." +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. For some reason, this one has an attached battery pack. It could be " +"used to analyze a medical fluid sample, such as blood, if a test tube was " +"placed in it." msgstr "" -"脈ꉓ恤ē„­å£‡ćŒåŗŠć‹ć‚‰ēŖćå‡ŗć—ć¦ćŠć‚Šć€ćć®å“é¢ćÆ鱗恮ē”ŸćˆćŸćƒŒćƒ”ćƒŒćƒ”ć®ēš®ć§č¦†ć‚ć‚Œć¦ć„ć¾ć™ć€‚ę­£ä½“äøę˜Žć®ēŖčµ·ćŒå“é¢ć‹ć‚‰ē”Ÿćˆć¦ćŠć‚Šć€ć“恮ē„­å£‡ćŒć‚ć‚‹ēØ®ć®ē”ŸććŸć‚Ŗćƒ¼ćƒˆćƒ‰ć‚Æ恧恂悋ćØ恄恆ę‚Ŗå¤¢ć®ć‚ˆć†ćŖäŗ‹å®Ÿć‚’ē¤ŗć—ć¦ć„ć¾ć™ć€‚" #: lang/json/furniture_from_json.py msgid "bathtub" @@ -99264,6 +99947,17 @@ msgid "" msgstr "" "ęœØč£½ć®éŖØēµ„ćæ恫åøƒćŒå¼µć‚‰ć‚ŒćŸć€ęŠ˜ć‚Šē•³ćæå¼ć®ćƒ‡ćƒƒć‚­ćƒć‚§ć‚¢ć§ć™ć€‚å±‹å¤–ć§ä½æć†ćŸć‚ć«ćƒ‡ć‚¶ć‚¤ćƒ³ć•ć‚Œć¦ćŠć‚Šć€åœ°ć¹ćŸć«åŗ§ć‚‹ć‚ˆć‚ŠćÆćƒžć‚·ć§ć™ćŒć€åŗ§ć‚Šåæƒåœ°ćÆē‰¹ć«åæ«é©ćØ恄恆ēØ‹ć§ćÆć‚ć‚Šć¾ć›ć‚“ć€‚" +#: lang/json/furniture_from_json.py +msgid "metal bench" +msgstr "" + +#. ~ Description for metal bench +#: lang/json/furniture_from_json.py +msgid "" +"A bench made of scrap metal. Not the most comfortable furniture you've ever" +" seen." +msgstr "" + #: lang/json/furniture_from_json.py msgid "bulletin board" msgstr "ęŽ²ē¤ŗęæ" @@ -99782,6 +100476,35 @@ msgid "" "A huge metal tank that can be used to safely store large amounts of liquid." msgstr "å¤§é‡ć®ę¶²ä½“ć‚’å®‰å…Ø恫äæē®”恧恍悋态å·Ø大ćŖé‡‘å±žč£½ć®ć‚æćƒ³ć‚Æ恧恙怂" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "fuel tank" +msgstr "ē‡ƒę–™ć‚æćƒ³ć‚Æ" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with gasoline." +msgstr "ć‚¬ć‚½ćƒŖćƒ³ć‚’ęŗ€č¼‰ć—ćŸć‚æćƒ³ć‚Æ恧恙怂" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken fuel tank" +msgstr "å£Šć‚ŒćŸē‡ƒę–™ć‚æćƒ³ć‚Æ" + +#. ~ Description for broken fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with gasoline." +msgstr "ć‚¬ć‚½ćƒŖćƒ³ć‚’ęŗ€č¼‰ć—ćŸå£Šć‚ŒćŸć‚æćƒ³ć‚Æ恧恙怂" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with diesel." +msgstr "ēÆę²¹ć‚’ęŗ€č¼‰ć—ćŸć‚æćƒ³ć‚Æ恧恙怂" + +#. ~ Description for broken fuel tank +#. ~ Description for broken diesel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with diesel." +msgstr "ēÆę²¹ć‚’ęŗ€č¼‰ć—ćŸå£Šć‚ŒćŸć‚æćƒ³ć‚Æ恧恙怂" + #: lang/json/furniture_from_json.py msgid "dumpster" msgstr "å¤§åž‹ć”ćæē®±" @@ -99806,6 +100529,42 @@ msgid "" "electricity, it is pedal-driven, allowing use without power." msgstr "惐ć‚æćƒ¼ć‚’ę”Ŗę‹Œć™ć‚‹ćƒŸć‚­ć‚µćƒ¼ćŒä»˜ć„ćŸé‡‘å±žå®¹å™Øć§ć™ć€‚ćƒšćƒ€ćƒ«å¼ć®ćŸć‚ć€é›»åŠ›ćŖć—ć§å‹•ä½œć—ć¾ć™ć€‚" +#: lang/json/furniture_from_json.py +msgid "riveted metal crate" +msgstr "" + +#. ~ Description for riveted metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This huge box is made of a dull metal, riveted together. There is no " +"obvious opening mechanism, and the rivets don't match any of your tools. " +"The only way in would be to smash it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "sealed metal crate" +msgstr "" + +#. ~ Description for sealed metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This is a huge, tightly sealed storage crate made from welded and riveted " +"sheet metal. The sealing mechanism is too tight to open bare-handed and " +"would need some kind of prying instrument to release." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "open metal crate" +msgstr "" + +#. ~ Description for open metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This large metal crateā€™s lid is unsealed, and hinges open easily to reveal a" +" number of storage shelves inside. Once open, the side panels also swing " +"wider for easy access." +msgstr "" + #: lang/json/furniture_from_json.py msgid "counter" msgstr "ć‚«ć‚¦ćƒ³ć‚æćƒ¼" @@ -99905,6 +100664,15 @@ msgstr "ć”ć‚ƒć‚“ćØåŗ§ć£ć¦é£Ÿć¹ćŖ恕恄ļ¼" msgid "a low table for livingrooms." msgstr "ćƒŖćƒ“ćƒ³ć‚°ćƒ«ćƒ¼ćƒ ć«ē½®ććƒ­ćƒ¼ćƒ†ćƒ¼ćƒ–ćƒ«ć§ć™ć€‚" +#: lang/json/furniture_from_json.py +msgid "metal table" +msgstr "" + +#. ~ Description for metal table +#: lang/json/furniture_from_json.py +msgid "A serviceable but simple table made of scrap metal." +msgstr "" + #: lang/json/furniture_from_json.py msgid "tatami mat" msgstr "ē•³" @@ -100134,6 +100902,17 @@ msgstr "ꮋéŖø(金属)" msgid "Pile of various bent and twisted metals." msgstr "ęŠ˜ć‚ŒćŸć‚Šć­ć˜ę›²ćŒć£ćŸć‚Šć—ćŸé‡‘å±žé”žć®å±±ć§ć™ć€‚" +#: lang/json/furniture_from_json.py +msgid "radioactive slag" +msgstr "" + +#. ~ Description for radioactive slag +#: lang/json/furniture_from_json.py +msgid "" +"A pile of melted slag from a destroyed nuclear reactor. What are you doing " +"looking at this? Get the hell out of here, you nutcase!" +msgstr "" + #: lang/json/furniture_from_json.py msgid "pile of ash" msgstr "ē°ć®å±±" @@ -100207,6 +100986,39 @@ msgid "" "public utilities, but it doesn't work anymore." msgstr "ē©ŗäø­ć®é€é›»ē·šć‚„ćć®ä»–ć®ć‚¤ćƒ³ćƒ•ćƒ©ē¶²ć‚’ę”Æćˆć¦ć„ćŸęœØč£½ć®é•·ć„ę”ÆęŸ±ć§ć™ćŒć€ä»ŠćÆę©Ÿčƒ½ć—ć¦ć„ć¾ć›ć‚“ć€‚" +#: lang/json/furniture_from_json.py +msgid "scrap metal bridge" +msgstr "" + +#. ~ Description for scrap metal bridge +#: lang/json/furniture_from_json.py +msgid "A simple bridge made of riveted sheet metal." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py +msgid "broken console" +msgstr "å£Šć‚ŒćŸć‚³ćƒ³ć‚½ćƒ¼ćƒ«" + +#. ~ Description for broken console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It doesn't seem to be working. " +"It's the broken screen and shattered circuit boards that's telling you that." +msgstr "ć‚¹ć‚æćƒ³ćƒ‰ć‚¢ćƒ­ćƒ³åž‹ć®ć‚³ćƒ³ćƒ”ćƒ„ćƒ¼ć‚æē«Æęœ«ć§ć™ć€‚ę­£åøøć«ę©Ÿčƒ½ć—ć¦ć„ćŖ恄恓ćØćÆć€å‰²ć‚ŒćŸć‚¹ć‚ÆćƒŖćƒ¼ćƒ³ćØē²‰ć€…恫ćŖć£ćŸå›žč·ÆåŸŗęæć‚’č¦‹ć‚Œć°ę˜Žē™½ć§ć™ć€‚" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "computer console" +msgstr "ć‚³ćƒ³ćƒ”ćƒ„ćƒ¼ć‚æć‚³ćƒ³ć‚½ćƒ¼ćƒ«" + +#. ~ Description for computer console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It can be used to view contents and" +" perform any allowed functions. It might even be possible to hack it, given" +" the skills." +msgstr "ć‚¹ć‚æćƒ³ćƒ‰ć‚¢ćƒ­ćƒ³åž‹ć®ć‚³ćƒ³ćƒ”ćƒ„ćƒ¼ć‚æē«Æęœ«ć§ć™ć€‚ä½æē”Ø恙悋ćØä»»ę„ć®ę©Ÿčƒ½ć‚’å®Ÿč”Œć—ć¾ć™ć€‚ć‚¹ć‚­ćƒ«ćŒć‚ć‚Œć°ć€ćƒćƒƒć‚­ćƒ³ć‚°ć§ćć‚‹ć‹ć‚‚ć—ć‚Œć¾ć›ć‚“ć€‚" + #: lang/json/furniture_from_json.py msgid "forge" msgstr "ē‚‰" @@ -100567,6 +101379,15 @@ msgid "" "you wouldn't need to pay at all!" msgstr "ę—¢ć«å£Šć‚Œć¦ć„ć¾ć™ć€‚ćŠé‡‘ć‚’ä½æć†å‰ć«ć‚ˆćč€ƒćˆć¾ć—ć‚‡ć†ć€‚ć‚‚ć£ćØå£Šć›ć°ć€å•†å“ćŒć‚æćƒ€ć§ę‰‹ć«å…„ć‚‹ć‹ć‚‚ć—ć‚Œć¾ć›ć‚“ć‚ˆļ¼Ÿ" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "rope leading up" +msgstr "åž‚ć‚Œäø‹ćŒć£ć¦ć„ć‚‹ćƒ­ćƒ¼ćƒ—" + +#. ~ Description for rope leading up +#: lang/json/furniture_from_json.py +msgid "A rope. You could climb it up." +msgstr "" + #: lang/json/furniture_from_json.py msgid "atomic butter churn on a stand" msgstr "ć‚¢ćƒˆćƒŸćƒƒć‚Æ惐ć‚æćƒ¼ę’¹ę‹Œę©Ÿ(čØ­ē½®)" @@ -104199,6 +105020,20 @@ msgstr[0] "ē•°ę˜Ÿé›»ę’ƒč‘‰" msgid "Electricity unnaturally arcs from the tips of this alien frond." msgstr "ē•°ę˜Ÿć®č‘‰ć®å…ˆē«Æ恋悉超č‡Ŗē„¶ć®é›»ę’ƒćŒę”¾å‡ŗć•ć‚Œć¾ć™ć€‚" +#: lang/json/gun_from_json.py +msgid "hurled rubble" +msgid_plural "hurled rubbles" +msgstr[0] "å²©ęŠ•ć’" + +#: lang/json/gun_from_json.py +msgid "Stone at the ready to crush that which isn't part of the blob." +msgstr "ćƒ–ćƒ­ćƒ–ć«ä¾µé£Ÿć•ć‚Œć¦ć„ćŖ恄悂恮悒ē²‰ē •ć™ć‚‹ęŗ–å‚™ćŒć§ćć¦ć„ć‚‹å²©ć§ć™ć€‚" + +#: lang/json/gun_from_json.py +msgctxt "gun_type_type" +msgid "throw" +msgstr "ęŠ•ę“²" + #: lang/json/gun_from_json.py msgid "nail gun" msgid_plural "nail guns" @@ -104253,7 +105088,7 @@ msgstr[0] "ć‚·ćƒ§ćƒƒćƒˆć‚¬ćƒ³(12ga/ę‰‹č£½ļ¾šļ¾Šļ¾žļ½°ļ½±ļ½øļ½¼ļ½®ļ¾)" msgid "" "A short homemade lever-action shotgun with a small internal tube magazine. " "While still a primitive pipe and 2x4 design, it is a formiddable shotgun in " -"it's own right with room for improvement." +"its own right with room for improvement." msgstr "" "å°åž‹ć®ćƒćƒ„ćƒ¼ćƒ–åž‹å¼¾å€‰ć‚’å†…č”µć—ćŸć€éŠƒčŗ«ćŒēŸ­ć„č‡Ŗä½œć®ćƒ¬ćƒćƒ¼ć‚¢ć‚Æć‚·ćƒ§ćƒ³å¼ć‚·ćƒ§ćƒƒćƒˆć‚¬ćƒ³ć§ć™ć€‚ćƒ‘ć‚¤ćƒ—ćØęœØꝐ悒ēµ„ćæåˆć‚ć›ćŸåŽŸå§‹ēš„ćŖä½œć‚Šć§ć™ćŒę”¹é€ ć‚‚åÆčƒ½ć§ć‚ć‚Šć€ę‰‹å¼·ć„ć‚·ćƒ§ćƒƒćƒˆć‚¬ćƒ³ć§ć‚ć‚‹ć“ćØćÆé–“é•ć„ć‚ć‚Šć¾ć›ć‚“ć€‚" @@ -104589,9 +105424,9 @@ msgstr "" "ć‚¦ć‚£ćƒ³ćƒć‚§ć‚¹ć‚æćƒ¼1897ćÆć€å•†ę„­ēš„ć«ęˆåŠŸć—ćŸęœ€åˆć®ćƒćƒ³ćƒ—ć‚¢ć‚Æć‚·ćƒ§ćƒ³ć‚·ćƒ§ćƒƒćƒˆć‚¬ćƒ³ć®äø€ć¤ć§ć™ć€‚ćć®ć€Œćƒˆćƒ¬ćƒ³ćƒ(唹壕)ć€å‘ć‘ć®čØ­čØˆć‹ć‚‰ć€ē¬¬äø€ę¬”äø–ē•Œå¤§ęˆ¦äø­ćÆć‚¢ćƒ”ćƒŖ悫恮ē†ęƒ³ć‚’é®®ć‚„ć‹ć«ä½“ē¾ć—ćŸč±”従ćØć•ć‚Œć¦ć„ć¾ć—ćŸć€‚ę”¾ē†±ęæćØē€å‰£č£…ē½®ć€ćć—ć¦éŠƒå‰£ć‚’å‚™ćˆćŸć“ć®éŠƒć®å¤–č¦‹ćÆ态間違恄ćŖćęć‚ć—ć„ć‚‚ć®ć§ć™ć€‚ęŽƒčØŽć™ć‚‹å”¹å£•ćÆč¦‹å½“ćŸć‚‰ćŖć„ć®ć§ć€ć‚¾ćƒ³ćƒ“ćŒćÆć³ć“ć‚‹č”—ć§ę“»čŗć•ć›ć¾ć—悇恆怂" #: lang/json/gun_from_json.py -msgid "four winds shotgun" -msgid_plural "four winds shotguns" -msgstr[0] "ć‚·ćƒ§ćƒƒćƒˆć‚¬ćƒ³(ē°”ꘓ)" +msgid "slam-fire pipe shotgun" +msgid_plural "slam-fire pipe shotguns" +msgstr[0] "ć‚·ćƒ§ćƒƒćƒˆć‚¬ćƒ³(連射)" #: lang/json/gun_from_json.py msgid "" @@ -104599,6 +105434,18 @@ msgid "" "The lack of sights make this weapon only useful at point-blank range." msgstr "2ęœ¬ć®å¤Ŗć„é‹¼é‰„č£½ćƒ‘ć‚¤ćƒ—ć€ć‚Øćƒ³ćƒ‰ć‚­ćƒ£ćƒƒćƒ—ć€é‡˜ć‚’ēµ„ćæåˆć‚ć›ć¦ä½œć£ćŸē²—ę‚ŖćŖę•£å¼¾éŠƒć§ć™ć€‚ē…§ęŗ–å™Ø恌ćŖ恄恟悁态čæ‘č·é›¢ć§ć—ć‹ä½æćˆć¾ć›ć‚“ć€‚" +#: lang/json/gun_from_json.py +msgid "double slam-fire pipe shotgun" +msgid_plural "double slam-fire pipe shotguns" +msgstr[0] "ć‚·ćƒ§ćƒƒćƒˆć‚¬ćƒ³(é€£å°„č¤‡åˆ)" + +#: lang/json/gun_from_json.py +msgid "" +"A crude shotgun, composed of four thick steel pipes, two end caps and two " +"nails. The lack of sights make this weapon only useful at point-blank " +"range." +msgstr "4ęœ¬ć®å¤Ŗć„é‹¼é‰„č£½ćƒ‘ć‚¤ćƒ—ć€2恤恮ć‚Øćƒ³ćƒ‰ć‚­ćƒ£ćƒƒćƒ—ćØ釘悒ēµ„ćæåˆć‚ć›ć¦ä½œć£ćŸē²—ę‚ŖćŖę•£å¼¾éŠƒć§ć™ć€‚ē…§ęŗ–å™Ø恌ćŖ恄恟悁态čæ‘č·é›¢ć§ć—ć‹ä½æćˆć¾ć›ć‚“ć€‚" + #: lang/json/gun_from_json.py msgid "flaregun" msgid_plural "flareguns" @@ -105018,11 +105865,6 @@ msgid "" " by hand." msgstr "é©č£½ć®ć‚¹ćƒŖćƒ³ć‚°ć§ć™ć€‚ę‰‹ć‚’ä½æ恆悈悊悂ćÆć‚‹ć‹ć«é«˜ć„é€Ÿåŗ¦ć§é ććøēŸ³ć‚’ęŠ•ć’ć¤ć‘ć‚‰ć‚Œć¾ć™ć€‚" -#: lang/json/gun_from_json.py -msgctxt "gun_type_type" -msgid "throw" -msgstr "ęŠ•ę“²" - #: lang/json/gun_from_json.py msgid "slingshot" msgid_plural "slingshots" @@ -105255,20 +106097,20 @@ msgstr "é ­éƒØćØäø€ä½“åŒ–ć—ćŸć€.40口径単ē™ŗ銃恧恙怂" #: lang/json/gun_from_json.py msgid "modified Marlin 39A" msgid_plural "modified Marlin 39A" -msgstr[0] "" +msgstr[0] "ćƒ©ć‚¤ćƒ•ćƒ«(.22口径/ę”¹é€ ļ¾ļ½°ļ¾˜ļ¾39A)" #: lang/json/gun_from_json.py msgid "A Marlin 39A, modified for use in a vehicle turret." -msgstr "" +msgstr "車äø”ć‚æ惬惃惈ē”Øć«ę”¹é€ ć•ć‚ŒćŸćƒžćƒ¼ćƒŖćƒ³39A恧恙怂" #: lang/json/gun_from_json.py msgid "modified SKS" msgid_plural "modified SKSs" -msgstr[0] "" +msgstr[0] "ćƒ©ć‚¤ćƒ•ćƒ«(7.62mm/ę”¹é€ SKS)" #: lang/json/gun_from_json.py msgid "An SKS, modified to be suitable for use in a vehicle turret." -msgstr "" +msgstr "車äø”ć‚æ惬惃惈ē”Øć«ę”¹é€ ć•ć‚ŒćŸSKS恧恙怂" #: lang/json/gun_from_json.py msgid "CRIT .5 LP" @@ -110693,6 +111535,11 @@ msgid "" "access the controls, or use the vehicle control key (default '^')." msgstr "åŗ§åø­ć‚„ć‚µćƒ‰ćƒ«ć«åŗ§ć‚Šć€ć“恓恋悉車äø”ć‚’é‹č»¢ć—ć¾ć™ć€‚ć“ć®ć‚æć‚¤ćƒ«ć‚’čŖæć¹ć‚‹(e)恋車äø”é‹č»¢ć‚’é–‹å§‹ć™ć‚‹(^)ćØ車äø”ć®é‹č»¢ćŒåÆčƒ½ć«ćŖć‚Šć¾ć™ć€‚" +#. ~ Please leave anything in unchanged. +#: lang/json/json_flag_from_json.py +msgid "When active, turns engines on and off automatically." +msgstr "ęœ‰åŠ¹ćŖ堓合ćÆć‚Øćƒ³ć‚øćƒ³ć‚’č‡Ŗ動ēš„ć«čµ·å‹•/åœę­¢ć—ć¾ć™ć€‚" + #. ~ Please leave anything in unchanged. #: lang/json/json_flag_from_json.py msgid "Illuminated items in this space will not illuminate nearby squares." @@ -111459,7 +112306,7 @@ msgstr "ē·Ø集/ć‚¢ć‚¤ćƒ†ćƒ " #: lang/json/keybinding_from_json.py msgid "Edit creatures" -msgstr "ē·Ø集/ć‚ÆćƒŖćƒ¼ćƒćƒ£ćƒ¼" +msgstr "ē·Ø集/ćƒ¢ćƒ³ć‚¹ć‚æćƒ¼" #: lang/json/keybinding_from_json.py msgid "Show whole map" @@ -111503,7 +112350,7 @@ msgstr "切ę›æ/作動/čŖæć¹ć‚‹" #: lang/json/keybinding_from_json.py msgid "Toggle safe fuel mod" -msgstr "切ę›æ/ēƀē“„ćƒ¢ćƒ¼ćƒ‰" +msgstr "切ę›æ/č‡Ŗå‹•åœę­¢ćƒ¢ćƒ¼ćƒ‰" #: lang/json/keybinding_from_json.py msgid "Toggle auto start mod" @@ -112387,6 +113234,10 @@ msgstr "切ę›æ/굄갓å™Ø" msgid "Toggle tracking" msgstr "切ę›æ/čæ½č·”č£…ē½®" +#: lang/json/keybinding_from_json.py +msgid "Toggle smart engine controller" +msgstr "切ę›æ/ć‚¹ćƒžćƒ¼ćƒˆć‚Øćƒ³ć‚øćƒ³åˆ¶å¾”č£…ē½®" + #: lang/json/keybinding_from_json.py src/turret.cpp src/vehicle_use.cpp msgid "Set turret firing modes" msgstr "čح定/ć‚æćƒ¬ćƒƒćƒˆå°„ę’ƒćƒ¢ćƒ¼ćƒ‰" @@ -130868,17 +131719,6 @@ msgid "" msgstr "" "ęœå‹™ć‚’å®£čŖ“ć—ćŸę­£ć—ćę³•ć®åŸ·č”Œč€…ć§ć™ć€‚å·žé–“å”å®šć«å‰‡ć£ć¦ćć®ē®”č½„ęØ©ćÆćƒ‹ćƒ„ćƒ¼ć‚¤ćƒ³ć‚°ćƒ©ćƒ³ćƒ‰å·žå…ØåŸŸć«åŠć³ć¾ć™ć€‚ä»Šć•ć‚‰ä½•ć®ę„å‘³ćŒć‚ć‚‹ć®ć‹ćØ恄恆恮ćÆć€ć¾ćŸåˆ„ć®å•é”Œć§ć™ć€‚" -#: lang/json/mutation_from_json.py -msgid "Helicopter Pilot" -msgstr "惘ćƒŖć‚³ćƒ—ć‚æćƒ¼ę“ēø¦å£«" - -#. ~ Description for Helicopter Pilot -#: lang/json/mutation_from_json.py -msgid "" -"You are a trained helicopter pilot. This makes you one of the few living " -"people who can operate a helicopter after the Cataclysm." -msgstr "čؓē·“ć‚’å—ć‘ćŸćƒ˜ćƒŖć‚³ćƒ—ć‚æćƒ¼ć®ę“ēø¦å£«ć§ć™ć€‚å¤§å¤‰å‹•å¾Œć«ćƒ˜ćƒŖć‚³ćƒ—ć‚æćƒ¼ć‚’ę“ēø¦ć§ćć‚‹č²“重ćŖē”ŸććŸäŗŗ間恧恙怂" - #: lang/json/mutation_from_json.py msgid "SWAT Officer" msgstr "SWAT隊哔" @@ -135834,6 +136674,10 @@ msgstr "惟ļ¼ć‚“ć®åµåÆŸå””" msgid "subway station?" msgstr "地äø‹é‰„駅ļ¼Ÿ" +#: lang/json/overmap_terrain_from_json.py +msgid "science lab reactor" +msgstr "" + #: lang/json/overmap_terrain_from_json.py msgid "lab" msgstr "ē§‘å­¦ē ”ē©¶ę‰€" @@ -136474,15 +137318,15 @@ msgstr "ę©‹" #: lang/json/overmap_terrain_from_json.py msgid "bridge (overpass)" -msgstr "" +msgstr "é«˜ęž¶ę©‹" #: lang/json/overmap_terrain_from_json.py msgid "bridgehead (ground)" -msgstr "" +msgstr "ę©‹é ­(地äøŠ)" #: lang/json/overmap_terrain_from_json.py msgid "bridgehead (ramp)" -msgstr "" +msgstr "ę©‹é ­(å‚¾ę–œ)" #: lang/json/overmap_terrain_from_json.py msgid "roadstop" @@ -143474,6 +144318,18 @@ msgid "" "You have your whole life ahead of you and it's gonna be sweet!" msgstr "ć©ć†ć„ć†ć‚ć‘ć‹å‘½ć‚’äøŽćˆć‚‰ć‚ŒćŸć€äŗŗåž‹ć®ć‚­ćƒ£ćƒ³ćƒ‡ć‚£ćƒ¼ć§ć™ć€‚é•·ćē”˜ć„äŗŗē”ŸćŒå§‹ć¾ć‚Šć¾ć—ćŸļ¼" +#: lang/json/proficiency_from_json.py +msgid "Knapping" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Blacksmithing" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Helicopter Piloting" +msgstr "" + #. ~ Crafting recipes category name #: lang/json/recipe_category_from_json.py msgid "*" @@ -151512,7 +152368,7 @@ msgstr "ćƒ”ćƒ³ć‚Æć‚æćƒ–ćƒ¬ćƒƒćƒˆćŒåœ°é¢ć«č½ć”ć¦ć‚‹ļ¼ŸćŖ悓恧恠悍恆ļ¼ msgid "Finally, something to take the edge off." msgstr "ć‚„ć£ćØ态ē—›ćæę­¢ć‚ćŒč¦‹ć¤ć‹ć£ćŸć€‚" -#: lang/json/snippet_from_json.py src/npctalk.cpp +#: lang/json/snippet_from_json.py src/talker_npc.cpp msgid "No thanks, I'm good." msgstr "ć„ć‚„ć€å¤§äøˆå¤«ć ć€‚" @@ -156695,6 +157551,7 @@ msgid "" "bubbles that appear to be floating upward. It reads: \"Tergitol Tuesdays! " "50% off on all washers and driers!\"" msgstr "" +"SUDSć‚³ć‚¤ćƒ³ćƒ©ćƒ³ćƒ‰ćƒŖćƒ¼ć®åŗƒå‘Šćƒćƒ©ć‚·ć§ć™ć€‚åŗƒå‘Šę–‡ćÆ惕ćƒÆ惕ćƒÆćØęµ®ć‹ć¶ę³”ć§ēøå–ć‚‰ć‚Œć¦ć„ć¾ć™ć€‚ć€Œē«ę›œę—„ćÆę“—ęæÆę—„å’Œļ¼ć™ć¹ć¦ć®ę“—ęæÆę©Ÿć€ä¹¾ē‡„ę©Ÿä½æē”Øꖙ恌50%ć‚Ŗ惕ļ¼ć€" #: lang/json/snippet_from_json.py msgid "" @@ -156712,6 +157569,7 @@ msgid "" "performing various exercises such as running, yoga and weight lifting. It " "reads: \"I lift things up and put them down!\"" msgstr "" +"ć‚¢ć‚¤ć‚¢ćƒ³ć‚ø惠恮åŗƒå‘Šćƒćƒ©ć‚·ć§ć™ć€‚ćƒ©ćƒ³ćƒ‹ćƒ³ć‚°ć‚„ćƒØć‚¬ć€ć‚¦ć‚§ć‚¤ćƒˆćƒŖćƒ•ćƒ†ć‚£ćƒ³ć‚°ćŖć©ć€ę§˜ć€…ćŖé‹å‹•ć‚’ć™ć‚‹äŗŗć€…ć®å†™ēœŸćŒč¼‰ć£ć¦ćŠć‚Šć€ć“恆ę›øć‹ć‚Œć¦ć„ć¾ć™ć€‚ć€ŒęŒć”äøŠć’ć¦ć€č½ćØ恙ļ¼ć€" #: lang/json/snippet_from_json.py msgid "" @@ -156720,6 +157578,8 @@ msgid "" "\"Own your own piece of the Moon! For only $29.99 a month, you can have " "prime real estate amongst the stars!\"" msgstr "" +"Space Time " +"Inc.恮åŗƒå‘Šćƒćƒ©ć‚·ć§ć™ć€‚ęœˆć‚’čƒŒę™Æć«ć€å®‡å®™čˆ¹ć®å‚ć«ęµ®ć‹ć¶å®‡å®™é£›č”Œå£«ć®å†™ēœŸćŒč¼‰ć£ć¦ćŠć‚Šć€ć“恆ę›øć‹ć‚Œć¦ć„ć¾ć™ć€‚ć€Œęœˆć®äø€éƒØ悒恂ćŖćŸć®ć‚‚ć®ć«ļ¼ęœˆć€…ćŸć£ćŸć®29.99ćƒ‰ćƒ«ć§ć€ę˜Ÿć€…ć«ē…§ć‚‰ć•ć‚Œć‚‹äø€ē­‰åœ°ćŒę‰‹ć«å…„ć‚Šć¾ć™ļ¼ć€" #: lang/json/snippet_from_json.py msgid "" @@ -171882,6 +172742,18 @@ msgstr "u_has_varćŠć‚ˆć³u_remove_varć®ćƒ†ć‚¹ćƒˆē”Øčæ”ē­”恧恙怂" msgid "This is a npc_has_var, npc_remove_var test response." msgstr "npc_has_varćŠć‚ˆć³npc_remove_varć®ćƒ†ć‚¹ćƒˆē”Øčæ”ē­”恧恙怂" +#: lang/json/talk_topic_from_json.py +msgid "This is a u_add_var time test response." +msgstr "u_add_varć®ę™‚é–“ćƒ†ć‚¹ćƒˆē”Øčæ”ē­”恧恙怂" + +#: lang/json/talk_topic_from_json.py +msgid "This is a npc_add_var time test response." +msgstr "npc_add_varć®ę™‚é–“ćƒ†ć‚¹ćƒˆē”Øčæ”ē­”恧恙怂" + +#: lang/json/talk_topic_from_json.py +msgid "This is a u_compare_var time test response for > 3_days." +msgstr "Ā > 3_daysē”Ø恮u_compare_varć®ę™‚é–“ćƒ†ć‚¹ćƒˆē”Øčæ”ē­”恧恙怂" + #: lang/json/talk_topic_from_json.py msgid "This is a u_adjust_var test response that increments by 1." msgstr "1ćšć¤å¢—åŠ ć™ć‚‹u_adjust_varć®ćƒ†ć‚¹ćƒˆē”Øčæ”ē­”恧恙怂" @@ -171982,6 +172854,10 @@ msgstr "é‹č»¢ć®ćƒ†ć‚¹ćƒˆē”Øčæ”ē­”恧恙怂" msgid "This is a low driving test response." msgstr "é‹č»¢(ć‚¹ć‚­ćƒ«ćƒ¬ćƒ™ćƒ«ä½Ž)ć®ćƒ†ć‚¹ćƒˆē”Øčæ”ē­”恧恙怂" +#: lang/json/talk_topic_from_json.py +msgid "This is an npc_first_topic test response." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "Greetings friend, it's nice to see you." msgstr "ć‚„ć‚ć€å‹ć‚ˆć€‚ä¼šćˆć¦å¬‰ć—ć„ć‚ˆć€‚" @@ -180662,7 +181538,7 @@ msgid "Will do, thanks!" msgstr "恝恆恙悋悈态恂悊恌ćØ恆ļ¼" #: lang/json/talk_topic_from_json.py lang/json/talk_topic_from_json.py -#: src/npctalk.cpp +#: src/talker.h src/talker_npc.cpp msgid "Nope." msgstr "恄恄悄怂" @@ -186633,6 +187509,37 @@ msgstr "ęžÆ悌草恌ęÆć‚’å¹ćčæ”ć—ć¾ć—ćŸć€‚" msgid "The door opens forcefully!" msgstr "ćƒ‰ć‚¢ćŒå‹¢ć„ć‚ˆćé–‹ćć¾ć—ćŸļ¼" +#: lang/json/terrain_from_json.py +msgid "broken diesel tank" +msgstr "" + +#. ~ Description for centrifuge +#: lang/json/terrain_from_json.py +msgid "" +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. It could be used to analyze a medical fluid sample, such as blood, if" +" a test tube was placed in it." +msgstr "遠åæƒåˆ†é›¢ę©ŸćØåˆ†ęžč£…ē½®ćŒäø€ä½“ćØćŖć£ćŸę©Ÿę¢°ć§ć™ć€‚č”€ę¶²ćŖć©ć®ę¶²ä½“ć‚µćƒ³ćƒ—ćƒ«ćŒå…„ć£ćŸč©¦éؓē®”悒ē½®ć‘ć°ć€å†…å®¹ē‰©ć‚’åˆ†ęžć§ćć¾ć™ć€‚" + +#: lang/json/terrain_from_json.py +msgid "plutonium generator" +msgstr "ē™ŗé›»ę©Ÿ(ćƒ—ćƒ«ćƒˆćƒ‹ć‚¦ćƒ )" + +#. ~ Description for plutonium generator +#: lang/json/terrain_from_json.py +msgid "" +"This imposing apparatus harnesses the power of the atom. Refined nuclear " +"fuel is 'burned' to provide nearly limitless electrical power. It's not " +"doing much good here though. Perhaps it could be salvaged for other " +"purposes." +msgstr "" +"åŽŸå­ć®åŠ›ć‚’åˆ©ē”Ø恙悋å·Ø大ćŖč£…ē½®ć§ć™ć€‚ē”Ÿęˆć•ć‚ŒćŸę øē‡ƒę–™ć‚’ć€Œē‡ƒć‚„ć™ć€ć“ćØ恧ē„”限恫čæ‘ć„é›»åŠ›ćŒä¾›ēµ¦ć•ć‚Œć¾ć™ćŒć€ć“ć“ć®č£…ē½®ćÆę­£åøøć«å‹•ć„ć¦ć„ćŖ恄悈恆恧恙怂ē‡ƒę–™ć‚’å›žåŽć™ć‚Œć°ć€ä»–ć®ä½æć„é“ćŒć‚ć‚‹ć‹ć‚‚ć—ć‚Œć¾ć›ć‚“ć€‚" + +#. ~ Description for old machinery +#: lang/json/terrain_from_json.py +msgid "Assorted old machinery. You could scavenge it for parts." +msgstr "꧘怅ćŖå¤ć„ę©Ÿę¢°ć§ć™ć€‚åˆ†č§£ć™ć‚Œć°éƒØå“ćŒå…„ę‰‹ć§ćć¾ć™ć€‚" + #: lang/json/terrain_from_json.py msgid "scorched earth" msgstr "ē„¦åœŸ" @@ -189420,24 +190327,6 @@ msgid "" "press them into basic shapes, ready for further crafting." msgstr "꧘怅ćŖé‡‘å±žč£½ć®ć‚¢ć‚¤ćƒ†ćƒ ć‚’å–ć‚Šč¾¼ćæć€č£½ä½œć«åˆ©ē”Ø恧恍悋åŸŗęœ¬ēš„ćŖå½¢ēŠ¶ć«åœ§ēø®ć™ć‚‹č£…ē½®ć§ć™ć€‚" -#: lang/json/terrain_from_json.py -msgid "fuel tank" -msgstr "ē‡ƒę–™ć‚æćƒ³ć‚Æ" - -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with gasoline." -msgstr "ć‚¬ć‚½ćƒŖćƒ³ć‚’ęŗ€č¼‰ć—ćŸć‚æćƒ³ć‚Æ恧恙怂" - -#: lang/json/terrain_from_json.py -msgid "broken fuel tank" -msgstr "å£Šć‚ŒćŸē‡ƒę–™ć‚æćƒ³ć‚Æ" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with gasoline." -msgstr "ć‚¬ć‚½ćƒŖćƒ³ć‚’ęŗ€č¼‰ć—ćŸå£Šć‚ŒćŸć‚æćƒ³ć‚Æ恧恙怂" - #: lang/json/terrain_from_json.py msgid "gasoline pump" msgstr "ēµ¦ę²¹ćƒćƒ³ćƒ—" @@ -189463,16 +190352,6 @@ msgid "" "the liquid gold." msgstr "危ćŖ恄ļ¼ēµ¦ę²¹ćƒćƒ³ćƒ—ćÆå£Šć‚Œć¦ćŠć‚Šć€ä¾”å€¤ć‚ć‚‹ę¶²ä½“ć‚’ę±²ćæå‡ŗ恛ćŖ恄ēŠ¶ę…‹ć§ć™ć€‚" -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with diesel." -msgstr "ēÆę²¹ć‚’ęŗ€č¼‰ć—ćŸć‚æćƒ³ć‚Æ恧恙怂" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with diesel." -msgstr "ēÆę²¹ć‚’ęŗ€č¼‰ć—ćŸå£Šć‚ŒćŸć‚æćƒ³ć‚Æ恧恙怂" - #: lang/json/terrain_from_json.py msgid "diesel pump" msgstr "ćƒ‡ć‚£ćƒ¼ć‚¼ćƒ«ćƒćƒ³ćƒ—" @@ -189552,16 +190431,6 @@ msgid "" "airflow." msgstr "å£ć«å–ć‚Šä»˜ć‘ć‚‹å¤§åž‹ć®ćƒ‘ćƒćƒ«ć§ć™ć€‚ē©ŗę°—ć®ęµć‚Œć‚’čŖæę•“ć™ć‚‹č–„ć„é‡‘å±žęæć§č¦†ć‚ć‚Œć¦ć„ć¾ć™ć€‚" -#: lang/json/terrain_from_json.py -msgid "broken generator" -msgstr "å£Šć‚ŒćŸē™ŗé›»ę©Ÿ" - -#. ~ Description for broken generator -#: lang/json/terrain_from_json.py -msgid "" -"This generator is broken and will not help you produce usable electricity." -msgstr "恓恮ē™ŗé›»ę©ŸćÆå£Šć‚Œć¦ćŠć‚Šć€ē™ŗé›»čƒ½åŠ›ćÆć‚ć‚Šć¾ć›ć‚“ć€‚" - #: lang/json/terrain_from_json.py msgid "missile" msgstr "ćƒŸć‚µć‚¤ćƒ«" @@ -189619,18 +190488,6 @@ msgid "" "This unpowered pump previously would have moved fluids around in a hurry." msgstr "仄前ćÆåæ™ć—ćåƒć„ć¦ć„ćŸć‚ˆć†ć§ć™ćŒć€ä»ŠćÆēØ¼åƒć—ć¦ć„ć¾ć›ć‚“ć€‚" -#: lang/json/terrain_from_json.py -msgid "centrifuge" -msgstr "遠åæƒåˆ†é›¢č£…ē½®" - -#. ~ Description for centrifuge -#: lang/json/terrain_from_json.py -msgid "" -"This is a centrifuge, a liquid separating device with an automated analyzer " -"unit. It could be used to analyze a medical fluid sample, such as blood, if" -" a test tube was placed in it." -msgstr "遠åæƒåˆ†é›¢ę©ŸćØåˆ†ęžč£…ē½®ćŒäø€ä½“ćØćŖć£ćŸę©Ÿę¢°ć§ć™ć€‚č”€ę¶²ćŖć©ć®ę¶²ä½“ć‚µćƒ³ćƒ—ćƒ«ćŒå…„ć£ćŸč©¦éؓē®”悒ē½®ć‘ć°ć€å†…å®¹ē‰©ć‚’åˆ†ęžć§ćć¾ć™ć€‚" - #: lang/json/terrain_from_json.py msgid "CVD machine" msgstr "CVDč£…ē½®" @@ -189728,20 +190585,6 @@ msgstr "ć‚¦ć‚©ćƒ¼ć‚æćƒ¼ć‚µćƒ¼ćƒćƒ¼" msgid "A machine with several taps that dispenses clean water." msgstr "é£²ę–™ę°“ć‚’ęä¾›ć™ć‚‹ć€č›‡å£ćŒä»˜ć„ćŸę©Ÿę¢°ć§ć™ć€‚" -#: lang/json/terrain_from_json.py -msgid "plutonium generator" -msgstr "ē™ŗé›»ę©Ÿ(ćƒ—ćƒ«ćƒˆćƒ‹ć‚¦ćƒ )" - -#. ~ Description for plutonium generator -#: lang/json/terrain_from_json.py -msgid "" -"This imposing apparatus harnesses the power of the atom. Refined nuclear " -"fuel is 'burned' to provide nearly limitless electrical power. It's not " -"doing much good here though. Perhaps it could be salvaged for other " -"purposes." -msgstr "" -"åŽŸå­ć®åŠ›ć‚’åˆ©ē”Ø恙悋å·Ø大ćŖč£…ē½®ć§ć™ć€‚ē”Ÿęˆć•ć‚ŒćŸę øē‡ƒę–™ć‚’ć€Œē‡ƒć‚„ć™ć€ć“ćØ恧ē„”限恫čæ‘ć„é›»åŠ›ćŒä¾›ēµ¦ć•ć‚Œć¾ć™ćŒć€ć“ć“ć®č£…ē½®ćÆę­£åøøć«å‹•ć„ć¦ć„ćŖ恄悈恆恧恙怂ē‡ƒę–™ć‚’å›žåŽć™ć‚Œć°ć€ä»–ć®ä½æć„é“ćŒć‚ć‚‹ć‹ć‚‚ć—ć‚Œć¾ć›ć‚“ć€‚" - #: lang/json/terrain_from_json.py msgid "telecom cabinet" msgstr "電갗通äæ”ę©Ÿå™Ø収ē“ę£š" @@ -189856,46 +190699,6 @@ msgstr "ćƒ™ćƒ«ćƒˆć‚³ćƒ³ćƒ™ć‚¢" msgid "A conveyor belt. Used to transport things." msgstr "ē‰©ć‚’č¼øé€ć™ć‚‹ć‚³ćƒ³ćƒ™ć‚¢ćƒ™ćƒ«ćƒˆć§ć™ć€‚" -#: lang/json/terrain_from_json.py -msgid "ting." -msgstr "ć‚«ćƒćƒ³ć€‚" - -#: lang/json/terrain_from_json.py -msgid "light machinery" -msgstr "č»½ę©Ÿę¢°" - -#. ~ Description for light machinery -#: lang/json/terrain_from_json.py -msgid "Assorted light machinery. You could scavenge it for parts." -msgstr "꧘怅ćŖč»½ę©Ÿę¢°ć§ć™ć€‚åˆ†č§£ć™ć‚Œć°éƒØå“ćŒå…„ę‰‹ć§ćć¾ć™ć€‚" - -#: lang/json/terrain_from_json.py -msgid "heavy machinery" -msgstr "é‡ę©Ÿę¢°" - -#. ~ Description for heavy machinery -#: lang/json/terrain_from_json.py -msgid "Assorted heavy machinery. You could scavenge it for parts." -msgstr "꧘怅ćŖé‡ę©Ÿę¢°ć§ć™ć€‚åˆ†č§£ć™ć‚Œć°éƒØå“ćŒå…„ę‰‹ć§ćć¾ć™ć€‚" - -#: lang/json/terrain_from_json.py -msgid "old machinery" -msgstr "å¤ć„ę©Ÿę¢°" - -#. ~ Description for old machinery -#: lang/json/terrain_from_json.py -msgid "Assorted old machinery. You could scavenge it for parts." -msgstr "꧘怅ćŖå¤ć„ę©Ÿę¢°ć§ć™ć€‚åˆ†č§£ć™ć‚Œć°éƒØå“ćŒå…„ę‰‹ć§ćć¾ć™ć€‚" - -#: lang/json/terrain_from_json.py -msgid "electronic machinery" -msgstr "é›»å­ę©Ÿę¢°" - -#. ~ Description for electronic machinery -#: lang/json/terrain_from_json.py -msgid "Assorted electronic machinery. You could scavenge it for parts." -msgstr "꧘怅ćŖé›»å­ę©Ÿå™Øć§ć™ć€‚åˆ†č§£ć™ć‚Œć°éƒØå“ćŒå…„ę‰‹ć§ćć¾ć™ć€‚" - #: lang/json/terrain_from_json.py msgid "milking machine" msgstr "ę¾ä¹³ę©Ÿ" @@ -189966,29 +190769,6 @@ msgid "" "from the elements or to protect a campfire from the rain." msgstr "é˜²ę°“ć‚·ćƒ¼ćƒˆć§č¦†ć‚ć‚ŒćŸå°ć•ćŖć‚·ć‚§ćƒ«ć‚æćƒ¼ć§ć™ć€‚éæ難ē”Ø悄态ē„šćē«ć®é›Ø悈恑ćØ恗恦ä½æć„ć¾ć™ć€‚" -#: lang/json/terrain_from_json.py -msgid "broken console" -msgstr "å£Šć‚ŒćŸć‚³ćƒ³ć‚½ćƒ¼ćƒ«" - -#. ~ Description for broken console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It doesn't seem to be working. " -"It's the broken screen and shattered circuit boards that's telling you that." -msgstr "ć‚¹ć‚æćƒ³ćƒ‰ć‚¢ćƒ­ćƒ³åž‹ć®ć‚³ćƒ³ćƒ”ćƒ„ćƒ¼ć‚æē«Æęœ«ć§ć™ć€‚ę­£åøøć«ę©Ÿčƒ½ć—ć¦ć„ćŖ恄恓ćØćÆć€å‰²ć‚ŒćŸć‚¹ć‚ÆćƒŖćƒ¼ćƒ³ćØē²‰ć€…恫ćŖć£ćŸå›žč·ÆåŸŗęæć‚’č¦‹ć‚Œć°ę˜Žē™½ć§ć™ć€‚" - -#: lang/json/terrain_from_json.py -msgid "computer console" -msgstr "ć‚³ćƒ³ćƒ”ćƒ„ćƒ¼ć‚æć‚³ćƒ³ć‚½ćƒ¼ćƒ«" - -#. ~ Description for computer console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It can be used to view contents and" -" perform any allowed functions. It might even be possible to hack it, given" -" the skills." -msgstr "ć‚¹ć‚æćƒ³ćƒ‰ć‚¢ćƒ­ćƒ³åž‹ć®ć‚³ćƒ³ćƒ”ćƒ„ćƒ¼ć‚æē«Æęœ«ć§ć™ć€‚ä½æē”Ø恙悋ćØä»»ę„ć®ę©Ÿčƒ½ć‚’å®Ÿč”Œć—ć¾ć™ć€‚ć‚¹ć‚­ćƒ«ćŒć‚ć‚Œć°ć€ćƒćƒƒć‚­ćƒ³ć‚°ć§ćć‚‹ć‹ć‚‚ć—ć‚Œć¾ć›ć‚“ć€‚" - #: lang/json/terrain_from_json.py msgid "mechanical winch" msgstr "å·»ćäøŠć’ę©Ÿ" @@ -192161,10 +192941,6 @@ msgstr "äøŠć‚Šå‚" msgid "An upward facing slope." msgstr "äøŠć‚Šå‚ć®ę–œé¢ć§ć™ć€‚" -#: lang/json/terrain_from_json.py -msgid "rope leading up" -msgstr "åž‚ć‚Œäø‹ćŒć£ć¦ć„ć‚‹ćƒ­ćƒ¼ćƒ—" - #. ~ Description for rope leading up #: lang/json/terrain_from_json.py msgid "A rope. You could climb up it." @@ -192826,6 +193602,10 @@ msgstr "č‡Ŗå‹•č»Š" msgid "Car Chassis" msgstr "č‡Ŗå‹•č»Šć®č»Šå°" +#: lang/json/vehicle_from_json.py +msgid "Hybrid Car" +msgstr "惏悤惖ćƒŖćƒƒćƒ‰č»Š" + #: lang/json/vehicle_from_json.py msgid "City Car" msgstr "ć‚·ćƒ†ć‚£ć‚«ćƒ¼" @@ -194548,6 +195328,23 @@ msgid "" msgstr "" "適切ćŖć‚­ćƒ¼ć‚’ä½æć‚ćšć«č»Šäø”ć‚’å‹•ć‹ć™ć“ćØć‚’é˜²ćé›»å­ę©Ÿå™Ø恧恙怂悂恗車äø”悒ē„”ē†ć‚„ć‚Šå§‹å‹•ć•ć›ć‚ˆć†ćØć™ć‚Œć°č­¦å ±éŸ³ćŒé³“ć‚Šć¾ć™ćŒć€č­¦å ±ę©Ÿčƒ½ć‚’ē„”åŠ¹åŒ–ć™ć‚‹ć“ćØć‚‚ć§ćć¾ć™ć€‚" +#: lang/json/vehicle_part_from_json.py +msgid "smart engine controller" +msgstr "ć‚¹ćƒžćƒ¼ćƒˆć‚Øćƒ³ć‚øćƒ³åˆ¶å¾”č£…ē½®" + +#. ~ Description for {'str': 'smart engine controller'} +#: lang/json/vehicle_part_from_json.py +#, no-python-format +msgid "" +"Electronic module that automatically switches combustion and electric " +"engines on and off minimizing fuel consumption and optimizing power output " +"and battery charge rate. Must be turned on to work. Simplified ruleset: 1." +" When throttling, maximize acceleration. 2. Keep battery at 90%. 3. " +"Minimize fuel consumption." +msgstr "" +"ē‡ƒē„¼ć‚Øćƒ³ć‚øćƒ³ćØ電갗ć‚Øćƒ³ć‚øćƒ³ć®ć‚Ŗćƒ³ć‚Ŗ惕悒č‡Ŗ動ēš„ć«åˆ‡ć‚Šę›æ恈悋恓ćØ恧态ē‡ƒę–™ę¶ˆč²»ć‚’ęœ€å°é™ć«ęŠ‘ćˆć¦å‡ŗ力ćØ惐惃惆ćƒŖćƒ¼å……é›»ēŽ‡ć‚’ęœ€é©åŒ–ć™ć‚‹é›»å­ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć§ć™ć€‚å‹•ä½œć•ć›ć‚‹ć«ćÆ電ęŗć‚’å…„悌悋åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚å¤§ć¾ć‹ć«ć€ć“ć®ć‚ˆć†ćŖč¦å‰‡ć«åŸŗ恄恄恦čŖæę•“ć•ć‚Œć¾ć™ć€‚1.ć‚¢ć‚Æć‚»ćƒ«čøćæč¾¼ćæę™‚ć«åŠ é€Ÿć‚’ęœ€å¤§åŒ–" +" 2.惐惃惆ćƒŖćƒ¼ę®‹é‡ć‚’90%恧å›ŗ定 3.ē‡ƒę–™ę¶ˆč²»ć‚’ęœ€å°é™ć«ęŠ‘åˆ¶" + #: lang/json/vehicle_part_from_json.py msgid "5-point harness" msgstr "5ē‚¹å¼ć‚·ćƒ¼ćƒˆćƒ™ćƒ«ćƒˆ" @@ -195724,6 +196521,66 @@ msgstr "ęƒē“ " msgid "Disgusting Diet" msgstr "é£Ÿę¬²äøęŒÆ" +#: lang/json/vitamin_from_json.py +msgid "Blood" +msgstr "" + +#: lang/json/vitamin_from_json.py +msgid "Red Blood Cells" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "NULL Weather - BUG" +msgstr "å¤©ę°—ē„”効 - 惐悰" + +#: lang/json/weather_type_from_json.py +msgid "Clear" +msgstr "ę™“ć‚Œ" + +#: lang/json/weather_type_from_json.py +msgid "Sunny" +msgstr "åæ«ę™“" + +#: lang/json/weather_type_from_json.py +msgid "Cloudy" +msgstr "ꛇ悊" + +#: lang/json/weather_type_from_json.py +msgid "Light Drizzle" +msgstr "霧é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Drizzle" +msgstr "小é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Rain" +msgstr "é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Thunder Storm" +msgstr "雷é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Acidic Drizzle" +msgstr "小é…øꀧé›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Acid Rain" +msgstr "é…øꀧé›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Flurries" +msgstr "小é›Ŗ" + +#: lang/json/weather_type_from_json.py +msgid "Snowing" +msgstr "é›Ŗ" + +#: lang/json/weather_type_from_json.py +msgid "Snowstorm" +msgstr "吹é›Ŗ" + #: src/achievement.cpp msgid "time of cataclysm" msgstr "å¤§å¤‰å‹•ć®ę™‚" @@ -195891,8 +196748,7 @@ msgstr "ę”¾é›»ć—ć¾ć—ćŸļ¼" msgid "You cannot hack this." msgstr "恓悌ćÆćƒćƒƒć‚­ćƒ³ć‚°ć§ćć¾ć›ć‚“ć€‚" -#: src/activity_actor.cpp src/computer_session.cpp src/computer_session.cpp -#: src/iuse.cpp src/map.cpp +#: src/activity_actor.cpp src/computer_session.cpp src/iuse.cpp src/map.cpp msgid "an alarm sound!" msgstr "[å¤§ććŖć‚¢ćƒ©ćƒ¼ćƒ éŸ³]" @@ -196033,6 +196889,16 @@ msgstr "ē”ēœ " msgid "Continue trying to fall asleep and don't ask again." msgstr "ē”ēœ (ä»„é™ć®äø­ę–­č­¦å‘Šć‚’ē„”視)" +#: src/activity_actor.cpp +#, c-format +msgid "You disassemble your %s." +msgstr "%sć‚’åˆ†č§£ć—ć¾ć—ćŸć€‚" + +#: src/activity_actor.cpp src/player.cpp +#, c-format +msgid "You unload your %s." +msgstr "%sć®č£…å”«ē‰©ć‚’ęŠœćå–ć‚Šć¾ć—ćŸć€‚" + #: src/activity_actor.cpp msgid "You are too tired to exercise." msgstr "ē–²ć‚ŒéŽćŽć¦ć„ć¦é‹å‹•ć§ćć¾ć›ć‚“ć€‚" @@ -196047,105 +196913,105 @@ msgstr "ć¾ćšč£…å‚™ć‚’å¤–ć—ć¦ćć ć•ć„ć€‚" #: src/activity_actor.cpp msgid "You cannot train here with a broken arm." -msgstr "č…•ćŒęŠ˜ć‚Œć¦ć„ć¦ćÆčؓē·“ć§ćć¾ć›ć‚“ć€‚" +msgstr "č…•ćŒęŠ˜ć‚Œć¦ć„ć¦ćÆćƒˆćƒ¬ćƒ¼ćƒ‹ćƒ³ć‚°ć§ćć¾ć›ć‚“ć€‚" #: src/activity_actor.cpp msgid "You cannot train here with a broken leg." -msgstr "" +msgstr "č„šćŒęŠ˜ć‚Œć¦ć„ć¦ćÆćƒˆćƒ¬ćƒ¼ćƒ‹ćƒ³ć‚°ć§ćć¾ć›ć‚“ć€‚" #: src/activity_actor.cpp msgid "You cannot train freely with a broken limb." -msgstr "" +msgstr "å››č‚¢ćŒęŠ˜ć‚Œć¦ć„ć¦ćÆćƒˆćƒ¬ćƒ¼ćƒ‹ćƒ³ć‚°ć§ćć¾ć›ć‚“ć€‚" #: src/activity_actor.cpp msgid "" "Physical effort determines workout efficiency, but also rate of exhaustion." -msgstr "" +msgstr "運動強åŗ¦ćÆé‹å‹•åŠ¹ęžœć‚’å·¦å³ć—ć¾ć™ćŒć€ē–²åŠ“å…·åˆć«ć‚‚é–¢äæ‚ć—ć¦ć„ć¾ć™ć€‚" #: src/activity_actor.cpp msgid "Choose training intensity:" -msgstr "" +msgstr "運動強åŗ¦ć‚’éøꊞ:" #: src/activity_actor.cpp msgid "" "Light excercise comparable in intensity to walking, but more focused and " "methodical." -msgstr "" +msgstr "ć‚¦ć‚©ćƒ¼ć‚­ćƒ³ć‚°ćØ同ē؋åŗ¦ć®é‹å‹•ć§ć™ć€‚č² č·ćÆč»½ć„ć§ć™ćŒć€ć‚ˆć‚Šé›†äø­ć—ć¦å…„åæµć«å–ć‚Šēµ„ć‚ć¾ć™ć€‚" #: src/activity_actor.cpp msgid "Moderate" -msgstr "" +msgstr "äø­" #: src/activity_actor.cpp msgid "" "Moderate excercise without excessive exertion, but with enough effort to " "break a sweat." -msgstr "" +msgstr "過åŗ¦ć«č² č·ć‚’ꎛ恑恚恫态ēØ‹ć‚ˆćę±—ć‚’ć‹ćē؋åŗ¦ć«é‹å‹•ć—ć¾ć™ć€‚" #: src/activity_actor.cpp msgid "Active" -msgstr "" +msgstr "å¼·" #: src/activity_actor.cpp msgid "" "Active excercise with full involvement. Strenuous, but in a controlled " "manner." -msgstr "" +msgstr "恋ćŖć‚Šå¼·ć„č² č·ć‚’ć‹ć‘ć¾ć™ćŒć€ę­£ć—ć„å‹•ćć‚’å“©ć•ćŖć„ć‚ˆć†é©åˆ‡ć«é‹å‹•ć—ć¾ć™ć€‚" #: src/activity_actor.cpp msgid "" "High intensity excercise with maximum effort and full power. Exhausting in " "the long run." -msgstr "" +msgstr "ęœ€å¤§é™ć®ę°—åŠ›ćØåŠ›ć‚’å„®ć„ć€éžåøøć«å¼·ć„č² č·ć‚’ć‹ć‘ć¦é‹å‹•ć—ć¾ć™ć€‚é•·ę™‚é–“ē¶šć‘ć‚‹ćØē–²åŠ“å›°ę†Šć—ć¾ć™ć€‚" #: src/activity_actor.cpp msgid "Train for how long (minutes): " -msgstr "" +msgstr "é‹å‹•ę™‚é–“(分): " #: src/activity_actor.cpp msgid "You start your workout session." -msgstr "" +msgstr "é‹å‹•ć‚’é–‹å§‹ć—ć¾ć—ćŸć€‚" #: src/activity_actor.cpp msgid "You are exhausted so you finish your workout early." -msgstr "" +msgstr "ē–²ć‚ŒćŒćŸć¾ć£ćŸć®ć§ć€é‹å‹•ć‚’ę—©ć‚ć«åˆ‡ć‚ŠäøŠć’ć¾ć—ćŸć€‚" #: src/activity_actor.cpp msgid "You are dehydrated so you finish your workout early." -msgstr "" +msgstr "非åøøć«å–‰ćŒęø‡ć„ćŸć®ć§ć€é‹å‹•ć‚’ę—©ć‚ć«åˆ‡ć‚ŠäøŠć’ć¾ć—ćŸć€‚" #. ~ heavy breathing when excercising #: src/activity_actor.cpp msgid "yourself huffing and puffing!" -msgstr "" +msgstr "ęÆć‚’åˆ‡ć‚‰ć—ć¦ć„ć¾ć™ļ¼" #: src/activity_actor.cpp msgid "You catch your breath for few moments." -msgstr "" +msgstr "恗恰悉恏ęÆć‚’ę•“ćˆć¾ć—ćŸć€‚" #: src/activity_actor.cpp msgid "You get back to your training." -msgstr "" +msgstr "ćƒˆćƒ¬ćƒ¼ćƒ‹ćƒ³ć‚°ć‚’å†é–‹ć—ć¾ć—ćŸć€‚" #: src/activity_actor.cpp msgid "You finish your workout session." -msgstr "" +msgstr "é‹å‹•ć‚’ēµ‚ćˆć¾ć—ćŸć€‚" #: src/activity_actor.cpp msgid "You have finished your training cycle, keep training?" -msgstr "" +msgstr "äø€é€£ć®ćƒˆćƒ¬ćƒ¼ćƒ‹ćƒ³ć‚°ć‚’ēµ‚ćˆć¾ć—ćŸć€‚ę›“恫ē¶šć‘ć¾ć™ć‹ļ¼Ÿ" #: src/activity_actor.cpp msgid "Stop training." -msgstr "" +msgstr "ćƒˆćƒ¬ćƒ¼ćƒ‹ćƒ³ć‚°ć‚’ę­¢ć‚ć‚‹ć€‚" #: src/activity_actor.cpp msgid "Continue training." -msgstr "" +msgstr "ćƒˆćƒ¬ćƒ¼ćƒ‹ćƒ³ć‚°ć‚’ē¶šć‘悋怂" #: src/activity_actor.cpp msgid "Continue training and don't ask again." -msgstr "" +msgstr "ćƒˆćƒ¬ćƒ¼ćƒ‹ćƒ³ć‚°ć‚’ē¶šć‘悋怂(ä»„é™ć®č­¦å‘Šć‚’ē„”視)" #. ~ Sound of a Rat mutant burrowing! #: src/activity_handlers.cpp @@ -196523,11 +197389,6 @@ msgstr[0] "ćÆę­»ä½“ć‚’ē “å£Šć—ć¾ć—ćŸć€‚" msgid "Can't reload the %s." msgstr "%sć‚’č£…å”«ć§ćć¾ć›ć‚“ć€‚" -#: src/activity_handlers.cpp src/iexamine.cpp -#, c-format -msgid "You reload the %s." -msgstr "%sć«č£…å”«ć—ć¾ć—ćŸć€‚" - #: src/activity_handlers.cpp #, c-format msgid "" @@ -196544,6 +197405,11 @@ msgstr "%2$s悒%1$s恫ęŒæå…„ć—ć¾ć—ćŸć€‚" msgid "You refill the %s." msgstr "%sć‚’č£œå……ć—ć¾ć—ćŸć€‚" +#: src/activity_handlers.cpp +#, c-format +msgid "You reload the %1$s with %2$s." +msgstr "" + #: src/activity_handlers.cpp src/bionics.cpp msgid "There's nothing to light there." msgstr "ē«ć‚’ć¤ć‘ć‚‰ć‚Œćć†ćŖē‰©ćŒć‚ć‚Šć¾ć›ć‚“ć€‚" @@ -196670,6 +197536,10 @@ msgstr "å­¦ēæ’ć§ćć‚‹ć“ćØćÆć‚‚ć†ć‚ć‚Šć¾ć›ć‚“ć€‚" msgid "%s %s\n" msgstr "%s %s\n" +#: src/activity_handlers.cpp src/magic.cpp +msgid "bionic power" +msgstr "電力" + #: src/activity_handlers.cpp #, c-format msgid "Charges: %s/%s %s (%s per use)\n" @@ -197048,16 +197918,6 @@ msgstr "ę“—é¢ć‚­ćƒƒćƒˆć‚’é–‹ć‘ć€é””å‰ƒć‚ŠćØę“—é””ć‚’ć—ć¦ć•ć£ć±ć‚Šć—ć¾ msgid "You give your hair a trim." msgstr "é«Ŗć‚’åˆ‡ć£ć¦ę•“ćˆć¾ć—ćŸć€‚" -#: src/activity_handlers.cpp -#, c-format -msgid "You disassemble your %s." -msgstr "%sć‚’åˆ†č§£ć—ć¾ć—ćŸć€‚" - -#: src/activity_handlers.cpp src/player.cpp -#, c-format -msgid "You unload your %s." -msgstr "%sć®č£…å”«ē‰©ć‚’ęŠœćå–ć‚Šć¾ć—ćŸć€‚" - #: src/activity_handlers.cpp #, c-format msgid "You have run out of %s." @@ -198044,7 +198904,7 @@ msgstr "ē€ē”Øē‰©ć®ęœ€ć‚‚å¤–å“ć«ć¾ćØ恆ć‚Ŗćƒ¼ćƒ©ć§ć™ć€‚" msgid "Properties" msgstr "ę€§čƒ½" -#: src/armor_layers.cpp +#: src/armor_layers.cpp src/item.cpp msgid "Coverage:" msgstr "č¢«č¦†ēŽ‡: " @@ -200041,7 +200901,7 @@ msgstr "%sć‚’čµ·å‹•ć™ć‚‹é›»åŠ›ćŒć‚ć‚Šć¾ć›ć‚“ć€‚" msgid "Deactivate your %s first!" msgstr "%sć‚’åœę­¢ć•ć›ć¦äø‹ć•ć„ļ¼" -#: src/bionics.cpp src/player.cpp +#: src/bionics.cpp src/character.cpp #, c-format msgid "Stop wielding %s?" msgstr "č£…å‚™äø­ć®%sć‚’å¤–ć—ć¾ć™ć‹ļ¼Ÿ" @@ -200707,30 +201567,30 @@ msgstr "č“„é›»å®¹é‡ćŒ%iå¢—åŠ ć—ć¾ć—ćŸć€‚" #: src/bionics.cpp msgid "Chose Safe Fuel Level Threshold" -msgstr "" +msgstr "č‡Ŗå‹•åœę­¢ć™ć‚‹é›»åŠ›é‡ć‚’éøꊞ" #: src/bionics.cpp msgid "Full Power" -msgstr "" +msgstr "100%" #: src/bionics.cpp #, c-format msgid "Above 80 %%" -msgstr "" +msgstr "80%%仄äøŠ" #: src/bionics.cpp #, c-format msgid "Above 55 %%" -msgstr "" +msgstr "55%%仄äøŠ" #: src/bionics.cpp #, c-format msgid "Above 30 %%" -msgstr "" +msgstr "30%%仄äøŠ" #: src/bionics.cpp msgid "Chose Start Power Level Threshold" -msgstr "čµ·å‹•ć™ć‚‹é›»åŠ›é‡ć‚’éøꊞ" +msgstr "č‡Ŗå‹•čµ·å‹•ć™ć‚‹é›»åŠ›é‡ć‚’éøꊞ" #: src/bionics.cpp msgid "No Power Left" @@ -200806,7 +201666,7 @@ msgstr "åƾåæœē‡ƒę–™: " #: src/bionics_ui.cpp msgctxt "decimal separator" msgid "." -msgstr "怂" +msgstr "." #: src/bionics_ui.cpp src/panels.cpp src/units.h msgctxt "energy unit: kilojoule" @@ -200827,7 +201687,7 @@ msgstr "mJ" #, c-format msgid "" "Bionic Power: %s/%ikJ" -msgstr "CBM電力: %s/.%ikJ" +msgstr "電力: %s/%ikJ" #: src/bionics_ui.cpp msgid " BIONICS " @@ -200841,7 +201701,7 @@ msgid "" "[%s] Toggle auto start mode." msgstr "" "[%s] ć‚­ćƒ¼å‰²å½“ć€ [%s] ć‚æćƒ–åˆ‡ę›æ态 " -"[%s] 切ę›æ/ēƀē“„ćƒ¢ćƒ¼ćƒ‰ć€ [%s] 切ę›æ/č‡Ŗå‹•čµ·å‹•ćƒ¢ćƒ¼ćƒ‰" +"[%s] 切ę›æ/č‡Ŗå‹•åœę­¢ćƒ¢ćƒ¼ćƒ‰ć€ [%s] 切ę›æ/č‡Ŗå‹•čµ·å‹•ćƒ¢ćƒ¼ćƒ‰" #: src/bionics_ui.cpp msgid "" @@ -200896,7 +201756,7 @@ msgstr "(ä½æē”ØäøåÆ)" #: src/bionics_ui.cpp #, c-format msgid "(fuel saving ON > %d %%)" -msgstr "" +msgstr "(č‡Ŗå‹•åœę­¢ > %d%%)" #: src/bionics_ui.cpp #, c-format @@ -200948,11 +201808,11 @@ msgstr "" #: src/bionics_ui.cpp msgid "You can't toggle fuel saving mode on a non-fueled CBM." -msgstr "é›»åŠ›ć‚’ę¶ˆč²»ć—ćŖ恄CBMćÆēƀē“„ćƒ¢ćƒ¼ćƒ‰ć‚’åˆ‡ć‚Šę›æćˆć‚‰ć‚Œć¾ć›ć‚“ć€‚" +msgstr "ē™ŗ電CBM仄外ćÆč‡Ŗå‹•åœę­¢ćƒ¢ćƒ¼ćƒ‰ć‚’åˆ‡ć‚Šę›æćˆć‚‰ć‚Œć¾ć›ć‚“ć€‚" #: src/bionics_ui.cpp msgid "You can't toggle auto start mode on a non-fueled CBM." -msgstr "é›»åŠ›ć‚’ę¶ˆč²»ć—ćŖ恄CBMćÆč‡Ŗå‹•čµ·å‹•ćƒ¢ćƒ¼ćƒ‰ć‚’åˆ‡ć‚Šę›æćˆć‚‰ć‚Œć¾ć›ć‚“ć€‚" +msgstr "ē™ŗ電CBM仄外ćÆč‡Ŗå‹•čµ·å‹•ćƒ¢ćƒ¼ćƒ‰ć‚’åˆ‡ć‚Šę›æćˆć‚‰ć‚Œć¾ć›ć‚“ć€‚" #: src/bionics_ui.cpp #, c-format @@ -201443,6 +202303,11 @@ msgstr "ć©ć“ć«é™ć‚Šć¾ć™ć‹ļ¼Ÿ" msgid "You cannot dismount there!" msgstr "ćć®å “ę‰€ć«ćÆé™ć‚Šć‚‰ć‚Œć¾ć›ć‚“ļ¼" +#: src/character.cpp +#, c-format +msgid "This task is too simple to train your %s beyond %d." +msgstr "ć“ć®ä½œę„­ćÆ%sć‚¹ć‚­ćƒ«ć‚’ćƒ¬ćƒ™ćƒ«%d仄äøŠć«äøŠę˜‡ć•ć›ć‚‹ć«ćÆē°”å˜éŽćŽć¾ć™ć€‚" + #: src/character.cpp msgid "You struggle to stand." msgstr "ē«‹ć”äøŠćŒć‚ć†ćØć‚‚ćŒćć¾ć—ćŸć€‚" @@ -201582,19 +202447,19 @@ msgstr "ć‚Æćƒ¢ć®å·£ć‚’ę‰•ćŠć†ćØć—ć¾ć—ćŸćŒć€äøŠę‰‹ćę‰•ćˆć¾ć›ć‚“恧 #: src/character.cpp #, c-format msgid "The %s breaks free!" -msgstr "" +msgstr "%sćÆę‹˜ęŸć‚’č„±ć—ć¾ć—ćŸļ¼" #: src/character.cpp msgid "You free yourself!" -msgstr "" +msgstr "č‡ŖåŠ›ć§ę‹˜ęŸć‚’č„±ć—ć¾ć—ćŸļ¼" #: src/character.cpp msgid " frees themselves!" -msgstr "" +msgstr "ćÆč‡ŖåŠ›ć§ę‹˜ęŸć‚’č„±ć—ć¾ć—ćŸļ¼" #: src/character.cpp msgid "You try to free yourself, but can't!" -msgstr "" +msgstr "ę‹˜ęŸć‚’č„±ć—ć‚ˆć†ćØć—ć¦ć€å¤±ę•—ć—ć¾ć—ćŸļ¼" #: src/character.cpp msgid "You try to escape the pit, but slip back in." @@ -201613,6 +202478,16 @@ msgstr "ćÆē©“恋悉脱å‡ŗć—ć¾ć—ćŸļ¼" msgid "Your %s bionic comes back online." msgstr "%sćŒå†ć³ę©Ÿčƒ½ć™ć‚‹ć‚ˆć†ć«ćŖć‚Šć¾ć—ćŸć€‚" +#: src/character.cpp +#, c-format +msgid "Your skill in %s has increased to %d!" +msgstr "%sć‚¹ć‚­ćƒ«ćŒćƒ¬ćƒ™ćƒ«%d恫äøŠćŒć‚Šć¾ć—ćŸļ¼" + +#: src/character.cpp +#, c-format +msgid "You feel that %s tasks of this level are becoming trivial." +msgstr "ć“ć®ćƒ¬ćƒ™ćƒ«ć®%sä½œę„­ćŒē°”å˜ć«ćŖć£ć¦ććŸćØę„Ÿć˜ć¦ć„ć¾ć™ć€‚" + #: src/character.cpp #, c-format msgid "You put on your %s." @@ -201727,6 +202602,15 @@ msgstr "å››č‚¢ćÆéŖØęŠ˜ć—ć¦ć„ć¾ć›ć‚“ć€‚" msgid "%s doesn't have any broken limbs this could help." msgstr "%sć®å››č‚¢ćÆéŖØęŠ˜ć—ć¦ć„ć¾ć›ć‚“ć€‚" +#: src/character.cpp +msgid "You don't need a tourniquet to stop the bleeding." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "%s doesn't need a tourniquet to stop the bleeding." +msgstr "" + #: src/character.cpp msgid "You don't have enough arms to wear that." msgstr "腕恮ē€ē”Øē‰©ćŒé‚Ŗ魔恧ē€ē”Øć§ćć¾ć›ć‚“ć€‚" @@ -201907,7 +202791,7 @@ msgstr "ē©ŗč…¹ ***" msgid "ERROR!" msgstr "ć‚Øćƒ©ćƒ¼ļ¼" -#: src/character.cpp src/npctalk.cpp +#: src/character.cpp src/talker_npc.cpp msgid "Exhausted" msgstr "ē–²åŠ“ **" @@ -201951,7 +202835,7 @@ msgstr "å°ć•ć„č»Šäø”ć«ä½“ć‚’č©°ć‚č¾¼ć‚“ć§ć„ć‚‹ćŸć‚ć€å…Øčŗ«ćŒē· ć‚äøŠ msgid "You have a sudden heart attack!" msgstr "ꀄ恫åæƒč‡“ē™ŗä½œć‚’čµ·ć“ć—ć¾ć—ćŸļ¼" -#: src/character.cpp +#: src/character.cpp src/player_hardcoded_effects.cpp msgid " has a sudden heart attack!" msgstr "ćÆꀄ恫åæƒč‡“ē™ŗä½œć‚’čµ·ć“ć—ć¾ć—ćŸļ¼" @@ -202180,12 +203064,12 @@ msgstr "č‰Æ" #: src/character.cpp #, c-format -msgid "Chance to stop: %d %%" -msgstr "ę­¢č”€ē¢ŗēŽ‡: %d %%" +msgid "Expected reduction of bleeding by: %d %%" +msgstr "" #: src/character.cpp -msgid "This will not stop the bleeding." -msgstr "ć“ć®ć‚¢ć‚¤ćƒ†ćƒ ćÆę­¢č”€ć§ćć¾ć›ć‚“ć€‚" +msgid "This will not affect the bleeding." +msgstr "" #: src/character.cpp #, c-format @@ -202451,7 +203335,7 @@ msgstr "čŗ«ä½“ćŒé‡č·ć«ę‚²é³“悒äøŠć’ć¾ć—ćŸć€‚" #: src/character.cpp src/player.cpp msgid "Your biology is not compatible with that healing item." -msgstr "" +msgstr "体č³Ŗēš„ćŖå•é”Œć§ćć®å›žå¾©ć‚¢ć‚¤ćƒ†ćƒ ć‚’ä½æćˆć¾ć›ć‚“ć€‚" #: src/character.cpp #, c-format @@ -202617,6 +203501,41 @@ msgstr "%2$s%1$sćŒę›“ć«å‚·ä»˜ćć¾ć—ćŸļ¼" msgid "Your %1$s is %2$s!" msgstr "%1$sćÆ%2$sļ¼" +#: src/character.cpp +msgid "Can't wield spilt liquids." +msgstr "ć“ć¼ć‚ŒćŸę¶²ä½“ćÆę‰€ęŒć§ćć¾ć›ć‚“ć€‚" + +#: src/character.cpp +msgid "You need at least one arm to even consider wielding something." +msgstr "ä½•ć‹ć‚’č£…å‚™ć™ć‚‹ć«ćÆęœ€ä½Žć§ć‚‚1ęœ¬ć®č…•ćŒåæ…要恧恙怂" + +#: src/character.cpp +#, c-format +msgid "The %s is preventing you from wielding the %s." +msgstr "%s恌恂悋恟悁%sć‚’č£…å‚™ć§ćć¾ć›ć‚“ć€‚" + +#: src/character.cpp +msgid "Something you are wearing hinders the use of both hands." +msgstr "ē€ē”Øć—ć¦ć„ć‚‹ć‚‚ć®ćŒäø”ę‰‹ć®å‹•ćć‚’å¦Øć’ć¦ć„ć¾ć™ć€‚" + +#: src/character.cpp +#, c-format +msgid "The %s can't be wielded with only one arm." +msgstr "%sćÆē‰‡ę‰‹ć§ę‰±ćˆć¾ć›ć‚“怂" + +#: src/character.cpp +#, c-format +msgid "You are too weak to wield %s with only one arm." +msgstr "%s悒ē‰‡ę‰‹ć§ę‰±ć†ć«ćÆē­‹åŠ›ćŒč¶³ć‚Šć¾ć›ć‚“怂" + +#: src/character.cpp +msgid " (empty)" +msgstr "(ē©ŗ)" + +#: src/character.cpp src/npctalk.cpp +msgid "fists" +msgstr "ē“ ę‰‹" + #: src/character.cpp #, c-format msgid "You are no longer able to wield your %s and drop it!" @@ -203166,6 +204085,11 @@ msgstr "ćƒ­ć‚°ć‚¤ćƒ³ć«ęˆåŠŸć—ć¾ć—ćŸć€‚ä½•ć‹ć‚­ćƒ¼ć‚’ęŠ¼ć—ć¦äø‹ć•ć„... msgid "%s - Root Menu" msgstr "%s - ćƒ«ćƒ¼ćƒˆćƒ”ćƒ‹ćƒ„ćƒ¼" +#: src/computer_session.cpp +#, c-format +msgid "%s (UNAVAILABLE)" +msgstr "" + #: src/computer_session.cpp msgid "Password required." msgstr "ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćŒåæ…要恧恙怂" @@ -203774,7 +204698,7 @@ msgstr "å·„ē؋/惐ćƒŖć‚Øćƒ¼ć‚·ćƒ§ćƒ³ #%d: " msgid "Result: " msgstr "ēµęžœ: " -#: src/construction.cpp +#: src/construction.cpp src/worldfactory.cpp msgid "N/A" msgstr "ćŖ恗" @@ -204426,6 +205350,10 @@ msgstr "" "%sć‚’å®Œęˆć•ć›ć‚‹ć«ćÆč£…å”«é‡ćŒč¶³ć‚Šć¾ć›ć‚“ć€‚\n" "ćć‚Œć§ć‚‚č£½ä½œć‚’é–‹å§‹ć—ć¾ć™ć‹ļ¼Ÿ" +#: src/craft_command.cpp +msgid "You don't have the required proficiencies to craft this!" +msgstr "" + #: src/craft_command.cpp msgid "" "This craft will use rotten components.\n" @@ -204911,6 +205839,11 @@ msgstr "åæ…č¦ć‚¹ć‚­ćƒ«: %s" msgid "Other skills: %s" msgstr "ēæ’å¾—ę”件(ē¾åœØ/åæ…要): %s" +#: src/crafting_gui.cpp +#, c-format +msgid "Proficiencies Required: %s" +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "Time to complete: %s" @@ -204955,6 +205888,12 @@ msgid "" "components" msgstr "äø€ć¤ć®ć‚¢ć‚¤ćƒ†ćƒ ć‚’č¤‡ę•°ć®ęę–™ć«ä½æ恊恆ćØć—ć¦ćŠć‚Šč£½ä½œć§ćć¾ć›ć‚“" +#: src/crafting_gui.cpp +msgid "" +"Cannot be crafted because you lack the required " +"proficiencies." +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "v (%s for more)" @@ -205343,6 +206282,10 @@ msgstr "ē·Ø集 - ćƒ—ćƒ¬ć‚¤ćƒ¤ćƒ¼/NPC" msgid "Damage self" msgstr "č‡Ŗčŗ«ć«ćƒ€ćƒ”ćƒ¼ć‚ø" +#: src/debug_menu.cpp +msgid "Bleed self" +msgstr "" + #: src/debug_menu.cpp msgid "Set automove route" msgstr "ē·Ø集 - č‡Ŗ動ē§»å‹•ćƒ«ćƒ¼ćƒˆ" @@ -205475,6 +206418,14 @@ msgstr "ć‚²ćƒ¼ćƒ ēµ‚äŗ†" msgid "Gameā€¦" msgstr "ć‚²ćƒ¼ćƒ ..." +#: src/debug_menu.cpp +msgid "Change [b]attery charge" +msgstr "ē·Ø集 - 惐惃惆ćƒŖćƒ¼ę®‹é‡" + +#: src/debug_menu.cpp +msgid "Vehicleā€¦" +msgstr "車äø”..." + #: src/debug_menu.cpp msgid "Teleport - short range" msgstr "ēŸ­č·é›¢" @@ -206110,12 +207061,8 @@ msgstr "位ē½® %d:%d å…Ø体 %d:%d, %s\n" #: src/debug_menu.cpp #, c-format -msgid "" -"Current turn: %d.\n" -"%s\n" -msgstr "" -"ē¾åœØć‚æćƒ¼ćƒ³: %d\n" -"%s\n" +msgid "Current turn: %d.\n" +msgstr "ē¾åœØć‚æćƒ¼ćƒ³: %d.\n" #: src/debug_menu.cpp #, c-format @@ -206123,14 +207070,6 @@ msgid "%d creature exists.\n" msgid_plural "%d creatures exist.\n" msgstr[0] "ćƒ¢ćƒ³ć‚¹ć‚æćƒ¼: %d体\n" -#: src/debug_menu.cpp -msgid "NPCs are going to spawn." -msgstr "NPCē”Ÿęˆć‚ć‚Š" - -#: src/debug_menu.cpp -msgid "NPCs are NOT going to spawn." -msgstr "NPCćÆē”Ÿęˆć•ć‚Œć¾ć›ć‚“怂" - #: src/debug_menu.cpp #, c-format msgid "%s: map ( %d:%d ) pos ( %d:%d )" @@ -206190,6 +207129,22 @@ msgstr "ē”Ÿęˆć™ć‚‹č»Šäø”悒éøꊞ" msgid "%1$s (%2$s)" msgstr "%1$s(%2$s)" +#: src/debug_menu.cpp +msgid "Vehicle condition" +msgstr "車äø”ēŠ¶ę…‹" + +#: src/debug_menu.cpp +msgid "Light damage" +msgstr "č»½åŗ¦ęå‚·" + +#: src/debug_menu.cpp +msgid "Undamaged" +msgstr "ęå‚·ćŖ恗" + +#: src/debug_menu.cpp +msgid "Disabled (tires or engine)" +msgstr "ē§»å‹•äøåÆ(ć‚æć‚¤ćƒ¤ćƒ»ć‚Øćƒ³ć‚øćƒ³äøč‰Æ)" + #: src/debug_menu.cpp msgid "Martial arts debug." msgstr "ęˆ¦é—˜ć‚¹ć‚æć‚¤ćƒ«ć‚’ćƒ‡ćƒćƒƒć‚°ć—ć¾ć™ć€‚" @@ -206251,6 +207206,10 @@ msgstr "通åøø恮é¢Ø速変化" msgid "Damage self for how much? hp: %s" msgstr "č‡Ŗåˆ†ć«äøŽćˆć‚‹ćƒ€ćƒ”ćƒ¼ć‚øć‚’å…„åŠ›(éƒØ位: %s)" +#: src/debug_menu.cpp +msgid "Add bleeding duration in minutes, equal to intensity:" +msgstr "" + #: src/debug_menu.cpp msgid "This binary was not compiled with tiles support." msgstr "ć“ć®ćƒć‚¤ćƒŠćƒŖćÆć‚æć‚¤ćƒ«ć«åƾåæœć—ć¦ć„ć¾ć›ć‚“ć€‚" @@ -206382,6 +207341,14 @@ msgstr "å‘Ŗę–‡ćƒ¬ćƒ™ćƒ«ć‚’čح定: (ē¾åœØ%d)" msgid "%s is now level %d!" msgstr "%sćŒćƒ¬ćƒ™ćƒ«%d恫ćŖć‚Šć¾ć—ćŸļ¼" +#: src/debug_menu.cpp src/iuse.cpp src/iuse.cpp +msgid "There's no vehicle there." +msgstr "ćć“ć«ćÆ車äø”ćŒå­˜åœØć—ć¾ć›ć‚“ć€‚" + +#: src/debug_menu.cpp +msgid "By how much? (in kJ, negative to discharge)" +msgstr "惐惃惆ćƒŖćƒ¼ę®‹é‡ć‚’čح定(単位:kJć€ćƒžć‚¤ćƒŠć‚¹ć§ęø›å°‘)" + #: src/descriptions.cpp #, c-format msgid "" @@ -207092,6 +208059,22 @@ msgstr "ꊜē¾¤" msgid "perfect" msgstr "完ē’§" +#: src/effect.cpp +msgid "miniscule" +msgstr "" + +#: src/effect.cpp +msgid "small" +msgstr "小型" + +#: src/effect.cpp +msgid "moderate" +msgstr "" + +#: src/effect.cpp +msgid "excellent" +msgstr "" + #. ~ Default format for scores. %1$s is statistic description; %2$s is value. #: src/event_statistics.cpp #, c-format @@ -209854,6 +210837,11 @@ msgstr "å…Øä½“ćƒžćƒƒćƒ—äøŠć®ē¾åœØ地: %d, %d, %d" msgid "Your local position: %d, %d, %d" msgstr "ē¾åœØ地: %d, %d, %d" +#: src/game.cpp +#, c-format +msgid "Total NPCs within %d OMTs: %d. %d are static NPCs." +msgstr "å…Øä½“ćƒžćƒƒćƒ—åœ°å½¢(%d)å†…ć®ē·NPCꕰ: %d(å›ŗ定NPCꕰ: %d)" + #: src/game.cpp msgid "East:" msgstr "ę±: " @@ -210799,7 +211787,7 @@ msgstr "č£…å”«ć§ćć‚‹ć‚‚ć®ć‚’ę‰€ęŒć—ć¦ć„ć¾ć›ć‚“ć€‚" #: src/game.cpp msgid "You need to put the bag away before trying to wield something from it." -msgstr "" +msgstr "収ē“ć‚¢ć‚¤ćƒ†ćƒ å†…ć®ć‚¢ć‚¤ćƒ†ćƒ ć‚’č£…å‚™ć™ć‚‹ć«ćÆć€ć¾ćšåŽē“ć‚¢ć‚¤ćƒ†ćƒ ć‚’é›¢ć™åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚" #: src/game.cpp #, c-format @@ -211596,12 +212584,12 @@ msgid "Your inventory is empty." msgstr "ę‰€ęŒå“ćŒć‚ć‚Šć¾ć›ć‚“ć€‚" #: src/game_inventory.cpp -msgid "ENCUMBRANCE" -msgstr "動作制限" +msgid "AVG ENCUMBRANCE" +msgstr "" #: src/game_inventory.cpp -msgid "COVERAGE" -msgstr "č¢«č¦†ēŽ‡" +msgid "AVG COVERAGE" +msgstr "" #: src/game_inventory.cpp msgid "WARMTH" @@ -213355,7 +214343,7 @@ msgstr "惛ćƒÆ悤惈ćƒŖć‚¹ćƒˆć«ē™»éŒ²: %s" #: src/handle_action.cpp msgid "Start workout?" -msgstr "" +msgstr "é‹å‹•ć‚’é–‹å§‹ć—ć¾ć™ć‹ļ¼Ÿ" #: src/handle_action.cpp msgid "Commit suicide?" @@ -214761,6 +215749,11 @@ msgstr "%1$s悒%2$s恮äø­ć«ä½•å€‹å…„ć‚Œć¾ć™ć‹ļ¼Ÿ" msgid "The %1$s contains %2$d %3$s." msgstr "%1$s恫ćÆ(%2$d)恮%3$sćŒå…„ć£ć¦ć„ć¾ć™ć€‚" +#: src/iexamine.cpp +#, c-format +msgid "You reload the %s." +msgstr "%sć«č£…å”«ć—ć¾ć—ćŸć€‚" + #: src/iexamine.cpp msgid "Do what with the curtains?" msgstr "ć‚«ćƒ¼ćƒ†ćƒ³ć«ä½•ć‚’ć—ć¾ć™ć‹ļ¼Ÿ" @@ -215606,7 +216599,7 @@ msgstr "ćÆ%sć®ćƒ¬ć‚·ćƒ”ć‚’ēŸ„悉ćŖć„ćŸć‚ć€č£½ä½œć‚’ē¶šć‘ć‚‰ć‚Œ #: src/iexamine.cpp #, c-format msgid "Use the %s to exercise?" -msgstr "" +msgstr "%s悒ä½æē”Øć—ć¦é‹å‹•ć—ć¾ć™ć‹ļ¼Ÿ" #: src/init.cpp msgid "Finalizing" @@ -215616,6 +216609,10 @@ msgstr "꜀ēµ‚処ē†äø­" msgid "Body parts" msgstr "čŗ«ä½“éƒØ位" +#: src/init.cpp +msgid "Weather types" +msgstr "天候" + #: src/init.cpp msgid "Field types" msgstr "ćƒ•ć‚£ćƒ¼ćƒ«ćƒ‰ć‚æ悤惗" @@ -216451,10 +217448,6 @@ msgstr "腐ꕗ(ć‚æćƒ¼ćƒ³): " msgid "max rot (turns): " msgstr "腐ꕗꜟ限(ć‚æćƒ¼ćƒ³): " -#: src/item.cpp -msgid "last rot: " -msgstr "判定ć‚æćƒ¼ćƒ³: " - #: src/item.cpp msgid "last temp: " msgstr "ē›“čæ‘ęø©åŗ¦:" @@ -216719,7 +217712,7 @@ msgid "Recommended strength (burst): " msgstr "ęŽØå„Øē­‹åŠ›(ćƒćƒ¼ć‚¹ćƒˆ): " #: src/item.cpp -msgid " moves " +msgid " moves" msgstr "" #: src/item.cpp @@ -216756,10 +217749,6 @@ msgstr "é©ę­£å°„ē؋: " msgid "" msgstr "" -#: src/item.cpp -msgid " moves" -msgstr "" - #: src/item.cpp msgid "Time to reach aim level: " msgstr "ē…§ęŗ–Ꙃ間: " @@ -216887,164 +217876,169 @@ msgid "" msgstr "é˜²å¾”å€¤ćŒęå‚·ć«ć‚ˆć£ć¦ęø›å°‘ć—ć¦ć„ć¾ć™ć€‚äæ®å¾©ć«ć‚ˆć£ć¦é˜²å¾”å€¤ć‚’ę”¹å–„ć§ćć¾ć™ć€‚" #: src/item.cpp -msgid "Covers: " -msgstr "č¢«č¦†éƒØ位: " +msgid "Covers:" +msgstr "" #: src/item.cpp -msgid "The head. " -msgstr "頭怂" +msgid " The head." +msgstr "" #: src/item.cpp -msgid "The eyes. " -msgstr "ē›®ć€‚" +msgid " The eyes." +msgstr "" #: src/item.cpp -msgid "The mouth. " -msgstr "å£ć€‚" +msgid " The mouth." +msgstr "" #: src/item.cpp -msgid "The torso. " -msgstr "čƒ“ć€‚" +msgid " The torso." +msgstr "" #: src/item.cpp -msgid "Either arm. " -msgstr "ē‰‡č…•ć€‚" +msgid " Either arm." +msgstr "" #: src/item.cpp -msgid "The arms. " -msgstr "äø”腕怂" +msgid " The arms." +msgstr "" #: src/item.cpp -msgid "The left arm. " -msgstr "å·¦č…•ć€‚" +msgid " The left arm." +msgstr "" #: src/item.cpp -msgid "The right arm. " -msgstr "å³č…•ć€‚" +msgid " The right arm." +msgstr "" #: src/item.cpp -msgid "Either hand. " -msgstr "ē‰‡ę‰‹ć€‚" +msgid " Either hand." +msgstr "" #: src/item.cpp -msgid "The hands. " -msgstr "äø”ꉋ怂" +msgid " The hands." +msgstr "" #: src/item.cpp -msgid "The left hand. " -msgstr "å·¦ę‰‹ć€‚" +msgid " The left hand." +msgstr "" #: src/item.cpp -msgid "The right hand. " -msgstr "å³ę‰‹ć€‚" +msgid " The right hand." +msgstr "" #: src/item.cpp -msgid "Either leg. " -msgstr "ē‰‡č„šć€‚" +msgid " Either leg." +msgstr "" #: src/item.cpp -msgid "The legs. " -msgstr "äø”脚怂" +msgid " The legs." +msgstr "" #: src/item.cpp -msgid "The left leg. " -msgstr "å·¦č„šć€‚" +msgid " The left leg." +msgstr "" #: src/item.cpp -msgid "The right leg. " -msgstr "å³č¶³ć€‚" +msgid " The right leg." +msgstr "" #: src/item.cpp -msgid "Either foot. " -msgstr "ē‰‡č¶³ć€‚" +msgid " Either foot." +msgstr "" #: src/item.cpp -msgid "The feet. " -msgstr "äø”č¶³ć€‚" +msgid " The feet." +msgstr "" #: src/item.cpp -msgid "The left foot. " -msgstr "å·¦č¶³ć€‚" +msgid " The left foot." +msgstr "" #: src/item.cpp -msgid "The right foot. " -msgstr "å³č¶³ć€‚" +msgid " The right foot." +msgstr "" #: src/item.cpp -msgid "Nothing." -msgstr "ćŖ恗怂" +msgid " Nothing." +msgstr "" #: src/item.cpp -msgid "Layer: " -msgstr "ē©å±¤: " +msgid "Layer:" +msgstr "" #: src/item.cpp -msgid "Personal aura. " -msgstr "ć‚Ŗćƒ¼ćƒ©(内)" +msgid " Personal aura." +msgstr "" #: src/item.cpp -msgid "Close to skin. " -msgstr "肌ē€ć€‚" +msgid " Close to skin." +msgstr "" #: src/item.cpp -msgid "Strapped. " -msgstr "åøÆ怂" +msgid " Strapped." +msgstr "" #: src/item.cpp -msgid "Outer. " -msgstr "äøŠē€ć€‚" +msgid " Outer." +msgstr "" #: src/item.cpp -msgid "Waist. " -msgstr "腰怂" +msgid " Waist." +msgstr "" #: src/item.cpp -msgid "Outer aura. " -msgstr "ć‚Ŗćƒ¼ćƒ©(外)" +msgid " Outer aura." +msgstr "" #: src/item.cpp -msgid "Normal. " -msgstr "通åøø怂" +msgid " Normal." +msgstr "" #: src/item.cpp -msgid "Coverage: " -msgstr "č¢«č¦†ēŽ‡: " +msgid "Average Coverage: " +msgstr "" #: src/item.cpp msgid "Warmth: " msgstr "Ꚗ恋恕: " #: src/item.cpp -msgid " (fits)" -msgstr "(適)" +msgid " (fits)" +msgstr "" + +#: src/item.cpp +msgid " (poor fit)" +msgstr "" #: src/item.cpp -msgid " (poor fit)" -msgstr "(äøé©)" +msgid " (too big)" +msgstr "" #: src/item.cpp -msgid " (too big)" -msgstr "(大)" +msgid " (huge!)" +msgstr "" #: src/item.cpp -msgid " (huge!)" -msgstr "(過大!)" +msgid " (too small)" +msgstr "" #: src/item.cpp -msgid " (too small)" -msgstr "(小)" +msgid " (tiny!)" +msgstr "" #: src/item.cpp -msgid " (tiny!)" -msgstr "(過小!)" +msgid "Encumbrance:" +msgstr "" #: src/item.cpp -msgid "Encumbrance: " -msgstr "動作制限: " +#, c-format +msgid "%s:" +msgstr "" #: src/item.cpp -msgid "Encumbrance when full: " -msgstr "ęœ€å¤§å‹•ä½œåˆ¶é™: " +msgid "When Full:" +msgstr "" #: src/item.cpp msgid "Weight capacity modifier: " @@ -217436,24 +218430,24 @@ msgid "Power Capacity:" msgstr "電力容量:" #: src/item.cpp -msgid "Environmental Protection: " -msgstr "ē’°å¢ƒé˜²č­·: " +msgid "Environmental Protection:" +msgstr "" #: src/item.cpp -msgid "Bash Protection: " -msgstr "ꉓꒃ耐ꀧ: " +msgid "Bash Protection:" +msgstr "" #: src/item.cpp -msgid "Cut Protection: " -msgstr "ę–¬ę’ƒč€ę€§: " +msgid "Cut Protection:" +msgstr "" #: src/item.cpp -msgid "Ballistic Protection: " -msgstr "防弾: " +msgid "Ballistic Protection:" +msgstr "" #: src/item.cpp -msgid "Stat Bonus: " -msgstr "čƒ½åŠ›å€¤ćƒœćƒ¼ćƒŠć‚¹: " +msgid "Stat Bonus:" +msgstr "" #: src/item.cpp msgid "Melee damage: " @@ -218288,7 +219282,7 @@ msgstr "ćÆ容å™Ø恧ćÆćŖ恄" #, c-format msgid "pocket unacceptable because %s" msgid_plural "pockets unacceptable because %s" -msgstr[0] "" +msgstr[0] "ćƒć‚±ćƒƒćƒˆć«åŽē“ć§ććŖ恄(%s)" #: src/item_contents.cpp msgid "is not rigid" @@ -218355,7 +219349,7 @@ msgstr "ćƒć‚±ćƒƒćƒˆ%d:" #: src/item_pocket.cpp msgid "Holds: " -msgstr "" +msgstr "内容: " #: src/item_pocket.cpp msgid "Maximum item length: " @@ -219518,10 +220512,6 @@ msgstr "恩恓恋悉åø恄å‡ŗć—ć¾ć™ć‹ļ¼Ÿ" msgid "There is nothing to siphon nearby." msgstr "付čæ‘ć«ęŠœćå–ć‚‹åÆ¾č±”ćŒć‚ć‚Šć¾ć›ć‚“ć€‚" -#: src/iuse.cpp -msgid "There's no vehicle there." -msgstr "ćć“ć«ćÆ車äø”ćŒå­˜åœØć—ć¾ć›ć‚“ć€‚" - #: src/iuse.cpp msgid "With a snarl, the combat chainsaw screams to life!" msgstr "ęˆ¦é—˜ē”Øćƒć‚§ćƒ¼ćƒ³ć‚½ćƒ¼ćŒå”ø悊悒äøŠć’ć¦ęˆ¦é—˜ęŗ–å‚™ć«å…„ć‚Šć¾ć—ćŸļ¼" @@ -222550,6 +223540,10 @@ msgstr "ēŒ›ēƒˆćŖē—›ćæćŒčµ°ć‚Šć¾ć™ļ¼" msgid "It itches a little." msgstr "悀恚ē—’ć•ć‚’ę„Ÿć˜ć¾ć—ćŸć€‚" +#: src/iuse_actor.cpp +msgid "Bleeding has not stopped completely!" +msgstr "" + #: src/iuse_actor.cpp msgid "You cannot cauterize while mounted." msgstr "é؎乗äø­ćÆē„¼ē¼ć§ćć¾ć›ć‚“怂" @@ -222873,12 +223867,22 @@ msgid "You stop the bleeding." msgstr "ę­¢č”€ć—ć¾ć—ćŸć€‚" #: src/iuse_actor.cpp -msgid "The wound still bleeds." -msgstr "å‚·å£ć‹ć‚‰å‡ŗč”€ćŒē¶šć„ć¦ć„ć¾ć™ć€‚" +msgid "You reduce the bleeding, but it's not stopped yet." +msgstr "" #: src/iuse_actor.cpp -msgid "You fail to stop the bleeding." -msgstr "ę­¢č”€ć§ćć¾ć›ć‚“ć§ć—ćŸć€‚" +msgid "The bleeding is reduced, but not stopped." +msgstr "" + +#: src/iuse_actor.cpp +msgid "" +"Your dressing is too ineffective for a bleeding of this extent, and you fail" +" to stop it." +msgstr "" + +#: src/iuse_actor.cpp +msgid "The wound still bleeds." +msgstr "å‚·å£ć‹ć‚‰å‡ŗč”€ćŒē¶šć„ć¦ć„ć¾ć™ć€‚" #: src/iuse_actor.cpp msgid "The wound is cleaned." @@ -222981,12 +223985,16 @@ msgid "Actual disinfecting quality: " msgstr "å®Ÿéš›ć®ę¶ˆęÆ’ę€§čƒ½: " #: src/iuse_actor.cpp -msgid "Chance to heal (percent): " -msgstr "ē—‡ēŠ¶ę²»ē™’ēŽ‡(%): " +msgid "Effect on bleeding: " +msgstr "" #: src/iuse_actor.cpp -msgid "* Bleeding: " -msgstr "* å‡ŗ蔀: " +msgid "Actual effect on bleeding: " +msgstr "" + +#: src/iuse_actor.cpp +msgid "Chance to heal (percent): " +msgstr "ē—‡ēŠ¶ę²»ē™’ēŽ‡(%): " #: src/iuse_actor.cpp msgid "* Bite: " @@ -223052,8 +224060,8 @@ msgid "It's not a gun." msgstr "恝悌ćÆ銃恧ćÆć‚ć‚Šć¾ć›ć‚“ć€‚" #: src/iuse_actor.cpp -msgid "The barrel is too short." -msgstr "銃čŗ«ćŒēŸ­ć™ćŽć¾ć™ć€‚" +msgid "The barrel is too small." +msgstr "" #: src/iuse_actor.cpp msgid "The barrel is already sawn-off." @@ -224554,10 +225562,6 @@ msgstr "惞惊" msgid "stamina" msgstr "ć‚¹ć‚æ惟惊" -#: src/magic.cpp -msgid "bionic power" -msgstr "電力" - #: src/magic.cpp msgid "error: energy_type" msgstr "ć‚Øćƒ©ćƒ¼: energy_type" @@ -224780,12 +225784,12 @@ msgstr "召喚" #: src/magic.cpp msgid "random creature" -msgstr "" +msgstr "ćƒ©ćƒ³ćƒ€ćƒ ćƒ¢ćƒ³ć‚¹ć‚æćƒ¼" #: src/magic.cpp #, c-format msgid "Targets under: %dhp become a %s" -msgstr "" +msgstr "HP%dęœŖęŗ€ć®ęؙēš„ćŒ%sć«å¤‰åŒ–" #: src/magic.cpp src/veh_interact.cpp msgid "Range" @@ -224809,7 +225813,7 @@ msgstr "ē”Ÿęˆ" #: src/magic.cpp msgid "Threshold" -msgstr "" +msgstr "閾" #: src/magic.cpp msgid "Recover" @@ -224866,11 +225870,11 @@ msgstr "%sć®å‚·ćŒå”žćŒć£ć¦ć„ćć¾ć™ļ¼" #: src/magic_spell_effect.cpp #, c-format msgid "The %s transforms into a %s." -msgstr "" +msgstr "%sćÆ%sć«å¤‰åŒ–ć—ć¾ć—ćŸć€‚" #: src/magic_spell_effect.cpp msgid "Your target resists transformation." -msgstr "" +msgstr "ęؙēš„ćÆå¤‰åŒ–ć®é­”ę³•ć«ęŠµęŠ—ć—ć¾ć—ćŸć€‚" #: src/magic_spell_effect.cpp msgid "There is already a vehicle there." @@ -225340,12 +226344,12 @@ msgstr "%sć‹ć‚‰ä½•ć‹ćŒé€™ć„å‡ŗć—ć¾ć—ćŸļ¼" #: src/map.cpp #, c-format msgid "You've spotted a %1$ss!" -msgstr "" +msgstr "%1$s悒ē™ŗč¦‹ć—ć¾ć—ćŸļ¼" #: src/map.cpp #, c-format msgid " triggers a %s!" -msgstr "" +msgstr "ćÆ%sć‚’ä½œå‹•ć•ć›ć¾ć—ćŸļ¼" #: src/map_extras.cpp msgid "DANGER! MINEFIELD!" @@ -226576,7 +227580,7 @@ msgstr "%sć‚’åŠ›ć„ć£ć±ć„å©ćć€%s 悒čæ‘ćć«č½ćØć—ć¾ć—ćŸļ¼" msgid "You smash %s with all your might but %s remains in their hands!" msgstr "%sć‚’åŠ›ć„ć£ć±ć„å©ćć¾ć—ćŸćŒć€%sć‚’č½ćØć›ć¾ć›ć‚“ć§ć—ćŸļ¼" -#: src/melee.cpp src/npctalk.cpp +#: src/melee.cpp src/talker_npc.cpp #, c-format msgid "%s is hostile!" msgstr "%sćÆꕵåƾēš„恧恙ļ¼" @@ -226893,13 +227897,13 @@ msgstr "č­¦åÆŸć«ęŒ‡åę‰‹é…ć•ć‚Œć¾ć—ćŸļ¼" #, c-format msgctxt "memorial_male" msgid "Broke his %s." -msgstr "" +msgstr "å½¼ć®%sćŒęŠ˜ć‚Œć¾ć—ćŸć€‚" #: src/memorial_logger.cpp #, c-format msgctxt "memorial_female" msgid "Broke her %s." -msgstr "" +msgstr "å½¼å„³ć®%sćŒęŠ˜ć‚Œć¾ć—ćŸć€‚" #. ~ %s is bodypart #: src/memorial_logger.cpp @@ -227410,6 +228414,36 @@ msgctxt "memorial_female" msgid "Died of a drug overdose." msgstr "č–¬ē‰©ć®éŽå‰°ę‘‚å–ć§ę­»ć«ć¾ć—ćŸć€‚" +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died from loss of red blood cells." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died from loss of red blood cells." +msgstr "" + #: src/memorial_logger.cpp msgctxt "memorial_male" msgid "Succumbed to the infection." @@ -231443,10 +232477,6 @@ msgctxt "Paralyze as an action" msgid "paralyze" msgstr "éŗ»ē—ŗ" -#: src/monster.cpp -msgid "cause bleed" -msgstr "å‡ŗ蔀" - #: src/monster.cpp msgid "It has a head." msgstr "é ­éƒØ恌恂悋" @@ -232507,6 +233537,15 @@ msgstr "%s (切ę›æ)" msgid "%s (activated)" msgstr "%s (čµ·å‹•)" +#: src/newcharacter.cpp +msgid "Profession proficiencies:" +msgstr "" + +#: src/newcharacter.cpp +msgctxt "Profession has no proficiencies" +msgid "None" +msgstr "ćŖ恗" + #: src/newcharacter.cpp msgid "Pets:" msgstr "惚惃惈:" @@ -232767,8 +233806,12 @@ msgid "" msgstr "%sć‚’ęŠ¼ć—ć¦ć“ć®ć‚­ćƒ£ćƒ©ć‚Æć‚æćƒ¼ć‚’ćƒ†ćƒ³ćƒ—ćƒ¬ćƒ¼ćƒˆć«ē™»éŒ²ć€‚" #: src/newcharacter.cpp -msgid "_______NO NAME ENTERED!_______" -msgstr "______åå‰ćŒå…„åŠ›ć•ć‚Œć¦ć„ć¾ć›ć‚“ļ¼______" +msgid "--- NO NAME ENTERED ---" +msgstr "" + +#: src/newcharacter.cpp +msgid "--- RANDOM NAME ---" +msgstr "" #: src/newcharacter.cpp #, c-format @@ -232850,16 +233893,20 @@ msgid "Enter height in centimeters. Minimum 145, maximum 200" msgstr "čŗ«é•·ć‚’å…„åŠ›ć—ć¦ćć ć•ć„ć€‚(145ļ½ž200)" #: src/newcharacter.cpp -msgid "Enter blood type (omit Rh):" -msgstr "č”€ę¶²åž‹ć‚’å…„åŠ› (Rh因子ćÆēœē•„):" +msgid "Select blood type" +msgstr "" #: src/newcharacter.cpp -msgid "Invalid blood type." -msgstr "ē„”効ćŖč”€ę¶²åž‹ć§ć™ć€‚" +msgid "Select Rh factor" +msgstr "" #: src/newcharacter.cpp -msgid "Enter Rh factor:" -msgstr "Rhå› å­ć‚’å…„åŠ›:" +msgid "negative" +msgstr "" + +#: src/newcharacter.cpp +msgid "positive" +msgstr "" #: src/newcharacter.cpp msgid "Name of template:" @@ -233239,6 +234286,25 @@ msgstr "ćÆč½ć”ē€ćć¾ć—ćŸć€‚" msgid " is no longer afraid." msgstr "ćÆę€Æćˆć‚‹ć®ć‚’ę­¢ć‚ć¾ć—ćŸć€‚" +#: src/npc.cpp +#, c-format +msgid "I'm holing up here for safety. Long term, %s" +msgstr "安å…Øć®ćŸć‚ć«ć€ć“ć“ć§ć˜ć£ćØć—ć¦ć„ć‚‹ć‚ˆć€‚%s" + +#: src/npc.cpp +msgid "I run the shop here." +msgstr "恓恓恧åŗ—悒開恄恦悋悓恠怂" + +#: src/npc.cpp +#, c-format +msgid "Currently, I'm guarding this location. Overall, %s" +msgstr "ć“ć®å “ę‰€ć‚’å®ˆć£ć¦ć„ć‚‹ć€‚%s" + +#: src/npc.cpp +#, c-format +msgid "Right now, I'm . In general, %s" +msgstr "%s怂今ćÆć‚’ć—ć¦ć„ć‚‹ć‚ˆć€‚" + #: src/npcmove.cpp msgid "" msgstr "" @@ -233389,6 +234455,15 @@ msgstr "" msgid "My %s is bleeding!" msgstr "%s恋悉å‡ŗ蔀恗恦恄悋ļ¼" +#: src/npcmove.cpp +#, c-format +msgid "My %s is bleeding badly!" +msgstr "" + +#: src/npcmove.cpp +msgid "I've lost lot of blood." +msgstr "" + #: src/npcmove.cpp #, c-format msgid "%1$s reloads their %2$s." @@ -233635,11 +234710,6 @@ msgstr "%s" msgid "%s yelling %s" msgstr "%sćÆ%sćØå«ć‚“ć§ć„ć¾ć™ć€‚" -#: src/npctalk.cpp -#, c-format -msgid "%s is fleeing from you!" -msgstr "%sćÆ逃恒悈恆ćØć—ć¦ć„ć¾ć™ļ¼" - #: src/npctalk.cpp #, c-format msgid "%s talked to you." @@ -233697,36 +234767,6 @@ msgstr "ć™ć¾ćŖ恄恌态ꕙ恈悉悌悋恓ćØćÆć‚‚ć†ä½•ć‚‚ćŖ恄悈恆恠怂 msgid "Here's what I can teach youā€¦" msgstr "ꕙ恈悉悌恝恆ćŖ恮ćÆ恓悓ćŖćØ恓悍恠ćŖ..." -#: src/npctalk.cpp -#, c-format -msgid "%d.%d miles." -msgstr "%d.%d ćƒžć‚¤ćƒ«ć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "%d foot." -msgid_plural "%d feet." -msgstr[0] "%d ćƒ•ć‚£ćƒ¼ćƒˆć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "I'm holing up here for safety. Long term, %s" -msgstr "安å…Øć®ćŸć‚ć«ć€ć“ć“ć§ć˜ć£ćØć—ć¦ć„ć‚‹ć‚ˆć€‚%s" - -#: src/npctalk.cpp -msgid "I run the shop here." -msgstr "恓恓恧åŗ—悒開恄恦悋悓恠怂" - -#: src/npctalk.cpp -#, c-format -msgid "Currently, I'm guarding this location. Overall, %s" -msgstr "ć“ć®å “ę‰€ć‚’å®ˆć£ć¦ć„ć‚‹ć€‚%s" - -#: src/npctalk.cpp -#, c-format -msgid "Right now, I'm . In general, %s" -msgstr "%s怂今ćÆć‚’ć—ć¦ć„ć‚‹ć‚ˆć€‚" - #: src/npctalk.cpp msgid "&You yell, but can't hear yourself." msgstr "&ę€’é³“ć£ć¦ćæć¾ć—ćŸćŒć€č‡Ŗåˆ†ć®å£°ćŒč“ć“ćˆć¾ć›ć‚“ć€‚" @@ -233735,74 +234775,6 @@ msgstr "&ę€’é³“ć£ć¦ćæć¾ć—ćŸćŒć€č‡Ŗåˆ†ć®å£°ćŒč“ć“ćˆć¾ć›ć‚“ć€‚" msgid "&You yell." msgstr "&å«ć³ć¾ć—ćŸć€‚" -#: src/npctalk.cpp -msgid "&You can't make anything out." -msgstr "åˆ¤ę–­ćŒä»˜ćć¾ć›ć‚“ć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "Str %d - %d" -msgstr "力 %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Dex %d - %d" -msgstr "å™Ø %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Int %d - %d" -msgstr "ēŸ„ %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Per %d - %d" -msgstr "ꄟ %d - %d" - -#: src/npctalk.cpp -msgid "Dead tired" -msgstr "ē–²åŠ“ **" - -#: src/npctalk.cpp -msgid "Not tired" -msgstr "ē–²åŠ“ćŖ恗" - -#: src/npctalk.cpp -msgid ". Will need sleep in " -msgstr "怂ēœ ć‚‹åæ…č¦ćŒć‚ć‚‹" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need water in " -msgstr "" -"\n" -"ę°“åˆ†ćŒåæ…要恠" - -#: src/npctalk.cpp -msgid "" -"\n" -"Thirsty" -msgstr "" -"\n" -"口喝" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need food in " -msgstr "" -"\n" -"é£Ÿć¹ē‰©ćŒåæ…要恠" - -#: src/npctalk.cpp -msgid "" -"\n" -"Hungry" -msgstr "" -"\n" -"ē©ŗč…¹" - #: src/npctalk.cpp msgid "YES, MASTER!" msgstr "ę‰æēŸ„č‡“ć—ć¾ć—ćŸć€ć”äø»äŗŗ꧘怂" @@ -233816,34 +234788,6 @@ msgstr "ēŸ„悉恛恟恄äŗ‹ćŒć‚悋怂" msgid "Yes, let's resume training %s" msgstr "悈恗态%s恮čؓē·“ć‚’å†é–‹ć—ć‚ˆć†ć‹ć€‚ " -#: src/npctalk.cpp -#, c-format -msgid "%s: 1 hour lesson (cost %s)" -msgstr "%s: čؓē·“(%s/1Ꙃ間)" - -#: src/npctalk.cpp -#, c-format -msgid "%s: teaching spell knowledge (cost %s)" -msgstr "%s: ēæ’å¾—(%s)" - -#. ~Martial art style (cost in dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s ( cost $%d )" -msgstr "%s (č²»ē”Ø $%d)" - -#. ~Skill name: current level (exercise) -> next level (exercise) (cost in -#. dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" -msgstr "%s: %d (%d%%) -> %d (%d%%) (č²»ē”Ø $%d)" - -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%)" -msgstr "%s: %d (%d%%) -> %d (%d%%)" - #: src/npctalk.cpp msgid "Okay, thanks." msgstr "恂恂态恂悊恌ćØ恆怂" @@ -233856,10 +234800,6 @@ msgstr "å‹•ćē¶šć‘ć¦ćć‚Œć€‚" msgid "OBEY ME!" msgstr "å‘½ä»¤ć«å¾“ćˆļ¼" -#: src/npctalk.cpp src/player.cpp -msgid "fists" -msgstr "ē“ ę‰‹" - #: src/npctalk.cpp msgid "BADAMMO" msgstr "äøč‰Æå¼¾" @@ -233931,7 +234871,7 @@ msgctxt "you say something" msgid "You: %s" msgstr "恂ćŖ恟: %s" -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp msgid "You can't afford it!" msgstr "č³¼å…„ć™ć‚‹ä½™č£•ćŒć‚ć‚Šć¾ć›ć‚“ļ¼" @@ -233942,7 +234882,7 @@ msgid "%1$s gives you a %2$s." msgstr "%1$sćÆ%2$s悒ęø”ć—ć¾ć—ćŸć€‚" #. ~ %1%s is the NPC name, %2$d is a number of items, %3$s are items -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp #, c-format msgid "%1$s gives you %2$d %3$s." msgstr "%1$sćÆ%2$då€‹ć®%3$s悒ęø”ć—ć¾ć—ćŸć€‚" @@ -233971,99 +234911,11 @@ msgstr "%1$s恫%2$då€‹ć®%3$s悒ęø”ć—ć¾ć—ćŸć€‚" msgid "%1$s doesn't have a %2$s!" msgstr "%1$sćÆ%2$sć‚’ęŒć£ć¦ć„ć¾ć›ć‚“ļ¼" -#: src/npctalk.cpp -#, c-format -msgid "%1$s gives you %2$s." -msgstr "%1$sćÆ%2$s悒ęø”ć—ć¾ć—ćŸć€‚" - #: src/npctalk.cpp #, c-format msgid "You learn how to craft %s." msgstr "%sć®ćƒ¬ć‚·ćƒ”ć‚’ēæ’å¾—ć—ć¾ć—ćŸć€‚" -#: src/npctalk.cpp -msgid "I don't trust you enough to eat THISā€¦" -msgstr "态恓悓ćŖć‚‚ć®ć‚’é£Ÿć¹ć‚‹ć»ć©äæ”ē”ØćÆ恗恦ćŖ恄悈..." - -#: src/npctalk.cpp -msgid "It doesn't look like a good idea to consume thisā€¦" -msgstr "ć“ć‚Œć‚’ę‘‚å–ć™ć‚‹ć®ćŒč‰Æ恄考恈恠ćØćÆꀝ恈ćŖ恄恭..." - -#: src/npctalk.cpp -msgid "Thanks, that hit the spot." -msgstr "恂悊恌ćØć†ć€ć”ć‚‡ć†ć©é£Ÿć¹ćŸć‹ć£ćŸć‚“ć ć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "I need a %s to consume that!" -msgstr "ćć‚Œć‚’ę‘‚å–ć™ć‚‹ć«ćÆ%s恌åæ…要恠ļ¼" - -#: src/npctalk.cpp -msgid "Thanks, I feel better already." -msgstr "恂悊恌ćØć†ć€å…·åˆćŒć‚ˆććŖć£ćŸć‚ˆć€‚" - -#: src/npctalk.cpp -msgid "Thanks, I used it." -msgstr "恂悊恌ćØ恆态ä½æć‚ć›ć¦ć‚‚ć‚‰ć†ć‚ˆć€‚" - -#: src/npctalk.cpp -msgid "Offer what?" -msgstr "ä½•ć‚’ćć‚Œć‚‹ć‚“ć ļ¼Ÿ" - -#: src/npctalk.cpp -msgid "You have no items to offer." -msgstr "ęø”ć›ć‚‹ć‚¢ć‚¤ćƒ†ćƒ ć‚’ę‰€ęŒć—ć¦ć„ć¾ć›ć‚“ć€‚" - -#: src/npctalk.cpp -msgid "Changed your mind?" -msgstr "ę°—ćŒå¤‰ć‚ć£ćŸļ¼Ÿ" - -#: src/npctalk.cpp -msgid "How?" -msgstr "恩恆恗恦ļ¼Ÿ" - -#: src/npctalk.cpp -msgid "Are you insane!?" -msgstr "恊恄 ļ¼ę°—恧悂ē‹‚ć£ćŸć‹ļ¼ļ¼Ÿ" - -#: src/npctalk.cpp -msgid "Thanks, I'll wield that now." -msgstr "恂悊恌ćØć†ć€ć•ć£ććč£…å‚™ć™ć‚‹ć‚ˆć€‚" - -#: src/npctalk.cpp -msgid " Should I take something off?" -msgstr "ä½•ć‹č„±ć„ć ę–¹ćŒć„ć„ļ¼Ÿ" - -#: src/npctalk.cpp -#, c-format -msgid "" -"My current weapon is better than this.\n" -"(new weapon value: %.1f vs %.1f)." -msgstr "" -"ćć‚Œć‚ˆć‚Šä»Šč£…å‚™ć—ć¦ć„ć‚‹ę­¦å™Øć®ę–¹ćŒč‰Æ恄ćŖ怂\n" -"(ꖰ恟ćŖę­¦å™Ø: %.1f vs %.1f)" - -#: src/npctalk.cpp -msgid "Thanks, I'll carry that now." -msgstr "恂悊恌ćØć†ć€ęŒć£ć¦ćŠćć‚ˆć€‚" - -#: src/npctalk.cpp -msgid "I have no space to store it." -msgstr "収ē“ć™ć‚‹å “ꉀ恌ćŖ恄怂" - -#: src/npctalk.cpp -#, c-format -msgid "I can only store %s %s more." -msgstr "恂ćØ%s %sć—ć‹å…„ć‚‰ćŖ恄怂" - -#: src/npctalk.cpp -msgid "ā€¦or to store anything else for that matter." -msgstr "...ä½•ć‹åˆ„ć®ć‚‚ć®ć‚’ęŒć¤ć‚ˆć€‚" - -#: src/npctalk.cpp -msgid "It is too heavy for me to carry." -msgstr "é‡ć™ćŽć¦é‹ć¹ć¾ć›ć‚“ć€‚" - #: src/npctalk_funcs.cpp msgid "Reward" msgstr "報酬" @@ -235850,12 +236702,16 @@ msgid "A scaling factor that determines density of item spawns." msgstr "ć‚¢ć‚¤ćƒ†ćƒ å‡ŗē¾ć®å€ēŽ‡ć‚’čØ­å®šć—ć¾ć™ć€‚" #: src/options.cpp -msgid "NPC spawn rate scaling factor" -msgstr "NPCå‡ŗē¾ēŽ‡" +msgid "Random NPC spawn time" +msgstr "ćƒ©ćƒ³ćƒ€ćƒ NPCē”Ÿęˆé–“éš”" #: src/options.cpp -msgid "A scaling factor that determines density of dynamic NPC spawns." -msgstr "動ēš„ćŖNPCå‡ŗē¾ēŽ‡ć‚’čØ­å®šć—ć¾ć™ć€‚" +msgid "" +"Baseline average number of days between random NPC spawns. Average duration" +" goes up with the number of NPCs already spawned. Set to 0 days to disable " +"random NPCs." +msgstr "" +"ćƒ©ćƒ³ćƒ€ćƒ NPC恌ē™ŗē”Ÿć™ć‚‹é–“éš”ć®ćƒ™ćƒ¼ć‚¹ćØćŖć‚‹ę—„ę•°ć‚’čØ­å®šć—ć¾ć™ć€‚ć“ć®é–“éš”ćÆć€ę—¢ć«ē™ŗē”Ÿć—ćŸNPC恮äŗŗꕰ恫åæœć˜ć§å¢—å¤§ć—ć¾ć™ć€‚0恫čØ­å®šć™ć‚‹ćØć€ćƒ©ćƒ³ćƒ€ćƒ NPC恌ē„”åŠ¹åŒ–ć•ć‚Œć¾ć™ć€‚" #: src/options.cpp msgid "Monster evolution scaling factor" @@ -235983,37 +236839,6 @@ msgstr "" "true恫恙悋ćØć‚·ć‚§ćƒ«ć‚æćƒ¼ć«ć‚¾ćƒ³ćƒ“ćŒē”Ÿęˆć•ć‚Œć¾ć™ć€‚\n" "ć‚²ćƒ¼ćƒ é–‹å§‹ē›“å¾Œć®é›£ę˜“åŗ¦ćŒäøŠę˜‡ć—ć¾ć™ć€‚" -#: src/options.cpp -msgid "Static NPCs" -msgstr "å›ŗ定NPC" - -#: src/options.cpp -msgid "" -"If true, static NPCs will spawn at pre-defined locations. Requires world " -"reset." -msgstr "True恫恙悋ćØē‰¹å®šć®å “ꉀ恫å›ŗ定NPC恌ē”Ÿęˆć•ć‚Œć¾ć™ć€‚åę˜ ć™ć‚‹ć«ćÆäø–ē•Œć®åˆęœŸåŒ–ćŒåæ…要恧恙怂" - -#: src/options.cpp -msgid "Starting NPCs spawn" -msgstr "開始地ē‚¹NPCå‡ŗē¾" - -#: src/options.cpp -msgid "" -"Determines whether starting NPCs should spawn, and if they do, how exactly." -msgstr "開始地ē‚¹ć«NPC恌å‡ŗē¾ć™ć‚‹ć‹ć©ć†ć‹ć€ć©ć®ć‚ˆć†ćŖå “åˆć«å‡ŗē¾ć™ć‚‹ć‹ć‚’čØ­å®šć—ć¾ć™ć€‚" - -#: src/options.cpp -msgid "Scenario-based" -msgstr "ć‚·ćƒŠćƒŖć‚Ŗęŗ–ę‹ " - -#: src/options.cpp -msgid "Random NPCs" -msgstr "ćƒ©ćƒ³ćƒ€ćƒ NPC" - -#: src/options.cpp -msgid "If true, the game will randomly spawn NPCs during gameplay." -msgstr "True恫恙悋ćØćƒ©ćƒ³ćƒ€ćƒ ć«NPC悒ē”Ÿęˆć—ć¾ć™ć€‚" - #: src/options.cpp msgid "Mutations by radiation" msgstr "ę”¾å°„ē·šć§å¤‰ē•°" @@ -237690,6 +238515,38 @@ msgstr "ē«ć‚’ę¶ˆćć†ćØć—ć¦å¤±ę•—ć—ć¾ć—ćŸļ¼" msgid " attempts to put out the fire on them!" msgstr "ćÆē«ć‚’ę¶ˆćć†ćØć—ć¦å¤±ę•—ć—ć¾ć—ćŸļ¼" +#: src/player.cpp +msgid "" +"Your broken limb significantly hampers your efforts to puting pressure on " +"the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s broken limb significantly hampers efforts of putting pressure on" +" the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"Your hands are too encumbred to effectivly put pressure on the bleeding " +"wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s hands are too encumbred to effectivly put pressure on the " +"bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "You attempt to put pressure on the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid " attempts to put pressure on the bleeding wound!" +msgstr "" + #: src/player.cpp #, c-format msgid "Your ground sonar detected a %1$s to the %2$s!" @@ -237961,33 +238818,6 @@ msgstr "č£…å”«ć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć›ć‚“ļ¼" msgid "You don't have any %s to reload your %s!" msgstr "%sć‚’ęŒć£ć¦ć„ćŖ恄恮恧%sć«č£œå……ć§ćć¾ć›ć‚“ļ¼" -#: src/player.cpp -msgid "Can't wield spilt liquids." -msgstr "ć“ć¼ć‚ŒćŸę¶²ä½“ćÆę‰€ęŒć§ćć¾ć›ć‚“ć€‚" - -#: src/player.cpp -msgid "You need at least one arm to even consider wielding something." -msgstr "ä½•ć‹ć‚’č£…å‚™ć™ć‚‹ć«ćÆęœ€ä½Žć§ć‚‚1ęœ¬ć®č…•ćŒåæ…要恧恙怂" - -#: src/player.cpp -#, c-format -msgid "The %s is preventing you from wielding the %s." -msgstr "%s恌恂悋恟悁%sć‚’č£…å‚™ć§ćć¾ć›ć‚“ć€‚" - -#: src/player.cpp -msgid "Something you are wearing hinders the use of both hands." -msgstr "ē€ē”Øć—ć¦ć„ć‚‹ć‚‚ć®ćŒäø”ę‰‹ć®å‹•ćć‚’å¦Øć’ć¦ć„ć¾ć™ć€‚" - -#: src/player.cpp -#, c-format -msgid "The %s can't be wielded with only one arm." -msgstr "%sćÆē‰‡ę‰‹ć§ę‰±ćˆć¾ć›ć‚“怂" - -#: src/player.cpp -#, c-format -msgid "You are too weak to wield %s with only one arm." -msgstr "%s悒ē‰‡ę‰‹ć§ę‰±ć†ć«ćÆē­‹åŠ›ćŒč¶³ć‚Šć¾ć›ć‚“怂" - #: src/player.cpp msgid "Keep hands free (off)" msgstr "ē“ ę‰‹(ē„”効)" @@ -238167,15 +238997,6 @@ msgstr "%sćÆå……é›»ć•ć‚Œć¦ć„ć¾ć›ć‚“ć€‚" msgid "Your %s isn't loaded." msgstr "%sćÆå……å”«ć•ć‚Œć¦ć„ć¾ć›ć‚“ć€‚" -#: src/player.cpp -#, c-format -msgid "You recover %i unused plutonium." -msgstr "ęœŖä½æē”Øć®åŽŸå­åŠ›é›»ę± (%i)ć‚’å›žåŽć—ć¾ć—ćŸć€‚" - -#: src/player.cpp -msgid "You can't remove partially depleted plutonium!" -msgstr "ä½æć„ć‹ć‘ć®åŽŸå­åŠ›é›»ę± ć‚’é™¤åŽ»ć™ć‚‹ć“ćØćÆć§ćć¾ć›ć‚“ļ¼" - #. ~ %1$s - gunmod, %2$s - gun. #: src/player.cpp #, c-format @@ -238310,25 +239131,6 @@ msgstr "é›»åŠ›ćŒå°½ćć€ē”ēœ å°Žå…„č£…ē½®ćŒåœę­¢ć—ć¾ć—ćŸļ¼" msgid "Your soporific inducer starts back up." msgstr "ē”ēœ å°Žå…„č£…ē½®ćŒå†čµ·å‹•ć—ć¾ć—ćŸć€‚" -#: src/player.cpp -#, c-format -msgid "Your skill in %s has increased to %d!" -msgstr "%sć‚¹ć‚­ćƒ«ćŒćƒ¬ćƒ™ćƒ«%d恫äøŠćŒć‚Šć¾ć—ćŸļ¼" - -#: src/player.cpp -#, c-format -msgid "You feel that %s tasks of this level are becoming trivial." -msgstr "ć“ć®ćƒ¬ćƒ™ćƒ«ć®%sä½œę„­ćŒē°”å˜ć«ćŖć£ć¦ććŸćØę„Ÿć˜ć¦ć„ć¾ć™ć€‚" - -#: src/player.cpp -#, c-format -msgid "This task is too simple to train your %s beyond %d." -msgstr "ć“ć®ä½œę„­ćÆ%sć‚¹ć‚­ćƒ«ć‚’ćƒ¬ćƒ™ćƒ«%d仄äøŠć«äøŠę˜‡ć•ć›ć‚‹ć«ćÆē°”å˜éŽćŽć¾ć™ć€‚" - -#: src/player.cpp -msgid " (empty)" -msgstr "(ē©ŗ)" - #: src/player.cpp msgid "Wield what?" msgstr "ä½•ć‚’č£…å‚™ć—ć¾ć™ć‹ļ¼Ÿ" @@ -238384,6 +239186,10 @@ msgstr "åŠ¹ęžœ" msgid "SPEED" msgstr "速åŗ¦" +#: src/player_display.cpp +msgid "PROFICIENCIES" +msgstr "" + #: src/player_display.cpp #, c-format msgid "Swimming movement point cost: %+d\n" @@ -239226,6 +240032,149 @@ msgid "" "nebulae and you are no more." msgstr "ē¾Žć—恄ć‚Øćƒćƒ«ć‚®ćƒ¼ć®ēˆ†ē™ŗ恫ęŗ¶ć‘ć¦ć„ćć¾ć—ćŸć€‚ęæć£ćŸč§’č†œć‹ć‚‰é­‚ćŒęŠœć‘ć€äŗŒåŗ¦ćØęˆ»ć£ć¦ćć‚‹ć“ćØćÆć‚ć‚Šć¾ć›ć‚“ć§ć—ćŸć€‚" +#: src/player_hardcoded_effects.cpp +msgid "You bleed to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " bleeds to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your heart can't keep up the pace and fails!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks pale and you feel anxious and thirsty. Blood loss?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"Your pale skin is sweating, your heart beats fast and you feel restless. " +"Maybe you lost too much blood?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You're unsettlingly white, but your fingetips are bluish. You are agitated " +"and your heart is racing. Your blood loss must be serious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You are pale as a ghost, dripping wet from the sweat, and sluggish despite " +"your heart racing like a train. You are on a brink of colapse from effects " +"of a bood loss." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and lightheaded." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel tired and you breathe heavily." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are anxcious and cannot collect your thoughts." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are sweating profusely, but you feel cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You huff and puff. Your breath is rapid and shallow." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You drop to the ground, fighting to keep yourself conscious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your mind slips away." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You cannot breathe and your body gives out!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " gasps for air and dies!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your hands feel unusually cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your feet feel unusualy cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks very pale." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel weak. Where has your strength gone?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel feeble. A gust of wind could make you stumble." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "There is an overwhelming aura of tiredness inside of you." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Rest is what you want. Rest is what you need." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and can't coordinate movement of your feet." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your muscles are quivering." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You crave for ice. Dirt under your feet looks tasty too." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your whole mouth is sore, and your tongue is swollen." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel lightheaded. And a migrane follows." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your legs are restless. Urge to move them is so strong." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel like you'd sleep on a rock." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You gasp for air!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Can't breathe. Must rest." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You can't take it any more. Rest first, everything else later." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You must sit down for a moment. Just a moment." +msgstr "" + #. ~ %s is bodypart name. #: src/player_hardcoded_effects.cpp #, c-format @@ -239834,6 +240783,11 @@ msgstr "%s ć‚³ć‚¹ćƒˆ: %i" msgid "Turrets in range: %d/%d" msgstr "ć‚æćƒ¬ćƒƒćƒˆå°„ē؋: %d/%d" +#: src/recipe.cpp +#, c-format +msgid "Proficiencies Used: %s" +msgstr "" + #: src/recipe.cpp msgid "none" msgstr "ćŖ恗" @@ -240598,6 +241552,14 @@ msgstr "ćÆå€’ć‚Œč¾¼ćæć¾ć—ćŸļ¼" msgid "You fall over!" msgstr "č»¢å€’ć—ć¾ć—ćŸļ¼" +#: src/suffer.cpp +msgid "Your tourniquet hurts you." +msgstr "" + +#: src/suffer.cpp +msgid " is hurting from the tourniquet." +msgstr "" + #: src/suffer.cpp #, c-format msgid "Your radiation badge changes from %1$s to %2$s!" @@ -240617,6 +241579,210 @@ msgstr "ę°“ćŒč‡­ć„ć‚’ę“—ć„ęµć—ć¾ć—ćŸć€‚" msgid "You feel the water burning your skin." msgstr "갓恫ēš®č†šć‚’ē„¼ć‹ć‚Œć¦ć„ć‚‹ć‚ˆć†ćŖę°—ćŒć—ć¾ć™ć€‚" +#: src/talker_avatar.cpp +#, c-format +msgid "%s can't sell you any %s" +msgstr "" + +#: src/talker_avatar.cpp +#, c-format +msgid "%1$s gives you %2$s." +msgstr "%1$sćÆ%2$s悒ęø”ć—ć¾ć—ćŸć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "%d.%d miles." +msgstr "%d.%d ćƒžć‚¤ćƒ«ć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "%d foot." +msgid_plural "%d feet." +msgstr[0] "%d ćƒ•ć‚£ćƒ¼ćƒˆć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "%s is fleeing from you!" +msgstr "%sćÆ逃恒悈恆ćØć—ć¦ć„ć¾ć™ļ¼" + +#. ~Skill name: current level (exercise) -> next level (exercise) (cost in +#. dollars) +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" +msgstr "%s: %d (%d%%) -> %d (%d%%) (č²»ē”Ø $%d)" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%)" +msgstr "%s: %d (%d%%) -> %d (%d%%)" + +#: src/talker_npc.cpp +#, c-format +msgid "%s ( cost $%d )" +msgstr "%s (č²»ē”Ø $%d)" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: 1 hour lesson (cost %s)" +msgstr "%s: čؓē·“(%s/1Ꙃ間)" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: teaching spell knowledge (cost %s)" +msgstr "%s: ēæ’å¾—(%s)" + +#: src/talker_npc.cpp +msgid "I don't trust you enough to eat THISā€¦" +msgstr "态恓悓ćŖć‚‚ć®ć‚’é£Ÿć¹ć‚‹ć»ć©äæ”ē”ØćÆ恗恦ćŖ恄悈..." + +#: src/talker_npc.cpp +msgid "It doesn't look like a good idea to consume thisā€¦" +msgstr "ć“ć‚Œć‚’ę‘‚å–ć™ć‚‹ć®ćŒč‰Æ恄考恈恠ćØćÆꀝ恈ćŖ恄恭..." + +#: src/talker_npc.cpp +msgid "Thanks, that hit the spot." +msgstr "恂悊恌ćØć†ć€ć”ć‚‡ć†ć©é£Ÿć¹ćŸć‹ć£ćŸć‚“ć ć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "I need a %s to consume that!" +msgstr "ćć‚Œć‚’ę‘‚å–ć™ć‚‹ć«ćÆ%s恌åæ…要恠ļ¼" + +#: src/talker_npc.cpp +msgid "Thanks, I feel better already." +msgstr "恂悊恌ćØć†ć€å…·åˆćŒć‚ˆććŖć£ćŸć‚ˆć€‚" + +#: src/talker_npc.cpp +msgid "Thanks, I used it." +msgstr "恂悊恌ćØ恆态ä½æć‚ć›ć¦ć‚‚ć‚‰ć†ć‚ˆć€‚" + +#: src/talker_npc.cpp +msgid "Offer what?" +msgstr "ä½•ć‚’ćć‚Œć‚‹ć‚“ć ļ¼Ÿ" + +#: src/talker_npc.cpp +msgid "You have no items to offer." +msgstr "ęø”ć›ć‚‹ć‚¢ć‚¤ćƒ†ćƒ ć‚’ę‰€ęŒć—ć¦ć„ć¾ć›ć‚“ć€‚" + +#: src/talker_npc.cpp +msgid "Changed your mind?" +msgstr "ę°—ćŒå¤‰ć‚ć£ćŸļ¼Ÿ" + +#: src/talker_npc.cpp +msgid "How?" +msgstr "恩恆恗恦ļ¼Ÿ" + +#: src/talker_npc.cpp +msgid "Are you insane!?" +msgstr "恊恄 ļ¼ę°—恧悂ē‹‚ć£ćŸć‹ļ¼ļ¼Ÿ" + +#: src/talker_npc.cpp +msgid "Thanks, I'll wield that now." +msgstr "恂悊恌ćØć†ć€ć•ć£ććč£…å‚™ć™ć‚‹ć‚ˆć€‚" + +#: src/talker_npc.cpp +msgid " Should I take something off?" +msgstr "ä½•ć‹č„±ć„ć ę–¹ćŒć„ć„ļ¼Ÿ" + +#: src/talker_npc.cpp +#, c-format +msgid "" +"My current weapon is better than this.\n" +"(new weapon value: %.1f vs %.1f)." +msgstr "" +"ćć‚Œć‚ˆć‚Šä»Šč£…å‚™ć—ć¦ć„ć‚‹ę­¦å™Øć®ę–¹ćŒč‰Æ恄ćŖ怂\n" +"(ꖰ恟ćŖę­¦å™Ø: %.1f vs %.1f)" + +#: src/talker_npc.cpp +msgid "Thanks, I'll carry that now." +msgstr "恂悊恌ćØć†ć€ęŒć£ć¦ćŠćć‚ˆć€‚" + +#: src/talker_npc.cpp +msgid "I have no space to store it." +msgstr "収ē“ć™ć‚‹å “ꉀ恌ćŖ恄怂" + +#: src/talker_npc.cpp +#, c-format +msgid "I can only store %s %s more." +msgstr "恂ćØ%s %sć—ć‹å…„ć‚‰ćŖ恄怂" + +#: src/talker_npc.cpp +msgid "ā€¦or to store anything else for that matter." +msgstr "...ä½•ć‹åˆ„ć®ć‚‚ć®ć‚’ęŒć¤ć‚ˆć€‚" + +#: src/talker_npc.cpp +msgid "It is too heavy for me to carry." +msgstr "é‡ć™ćŽć¦é‹ć¹ć¾ć›ć‚“ć€‚" + +#: src/talker_npc.cpp +msgid "&You can't make anything out." +msgstr "åˆ¤ę–­ćŒä»˜ćć¾ć›ć‚“ć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "Str %d - %d" +msgstr "力 %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Dex %d - %d" +msgstr "å™Ø %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Int %d - %d" +msgstr "ēŸ„ %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Per %d - %d" +msgstr "ꄟ %d - %d" + +#: src/talker_npc.cpp +msgid "Dead tired" +msgstr "ē–²åŠ“ **" + +#: src/talker_npc.cpp +msgid "Not tired" +msgstr "ē–²åŠ“ćŖ恗" + +#: src/talker_npc.cpp +msgid ". Will need sleep in " +msgstr "怂ēœ ć‚‹åæ…č¦ćŒć‚ć‚‹" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need water in " +msgstr "" +"\n" +"ę°“åˆ†ćŒåæ…要恠" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Thirsty" +msgstr "" +"\n" +"口喝" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need food in " +msgstr "" +"\n" +"é£Ÿć¹ē‰©ćŒåæ…要恠" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Hungry" +msgstr "" +"\n" +"ē©ŗč…¹" + #: src/teleport.cpp msgid "You feel a strange, inwards force." msgstr "å†…å‘ćć«å¼•ć£å¼µć‚‰ć‚Œć‚‹ć‚ˆć†ćŖć€å„‡å¦™ćŖę„Ÿč¦šć«č„²ć‚ć‚Œć¾ć—ćŸć€‚" @@ -242434,6 +243600,34 @@ msgstr "态%3.1f%%/Ꙃ态%så¾Œć«%s" msgid "pile-up" msgstr "å¤šé‡č”ēŖč»Šäø”" +#: src/vehicle_move.cpp +msgid "Smart controller does not support flying vehicles." +msgstr "ć‚¹ćƒžćƒ¼ćƒˆć‚Øćƒ³ć‚øćƒ³åˆ¶å¾”č£…ē½®ćÆé£›č”Œč»Šäø”恫åƾåæœć—ć¦ć„ć¾ć›ć‚“ć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller detects only a single controllable engine." +msgstr "ć‚¹ćƒžćƒ¼ćƒˆć‚Øćƒ³ć‚øćƒ³åˆ¶å¾”č£…ē½®ćÆ制徔åÆčƒ½ćŖć‚Øćƒ³ć‚øćƒ³ć‚’1恤恗恋ꤜå‡ŗć§ćć¾ć›ć‚“ć§ć—ćŸć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller is designed to control more than one engine." +msgstr "ć‚¹ćƒžćƒ¼ćƒˆć‚Øćƒ³ć‚øćƒ³åˆ¶å¾”č£…ē½®ćÆ複ꕰ恮ć‚Øćƒ³ć‚øćƒ³ć‚’åˆ¶å¾”ć™ć‚‹ć‚ˆć†ć«čØ­čØˆć•ć‚Œć¦ć„ć¾ć™ć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller does not support more than five engines." +msgstr "ć‚¹ćƒžćƒ¼ćƒˆć‚Øćƒ³ć‚øćƒ³åˆ¶å¾”č£…ē½®ćÆ6恤仄äøŠć®ć‚Øćƒ³ć‚øćƒ³ć«åƾåæœć—ć¦ć„ć¾ć›ć‚“ć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller is shutting down." +msgstr "ć‚¹ćƒžćƒ¼ćƒˆć‚Øćƒ³ć‚øćƒ³åˆ¶å¾”č£…ē½®ćŒåœę­¢ć—ć¾ć—ćŸć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller failed to start an engine." +msgstr "ć‚¹ćƒžćƒ¼ćƒˆć‚Øćƒ³ć‚øćƒ³åˆ¶å¾”č£…ē½®ćÆć‚Øćƒ³ć‚øćƒ³å§‹å‹•ć«å¤±ę•—ć—ć¾ć—ćŸć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller optimizes engine state." +msgstr "ć‚¹ćƒžćƒ¼ćƒˆć‚Øćƒ³ć‚øćƒ³åˆ¶å¾”č£…ē½®ćÆć‚Øćƒ³ć‚øćƒ³ć®ēŠ¶ę…‹ć‚’ęœ€é©åŒ–ć—ć¾ć—ćŸć€‚" + #: src/vehicle_move.cpp #, c-format msgid "The %s is too leaky!" @@ -242808,6 +244002,11 @@ msgctxt "electronics menu option" msgid "water purifier" msgstr "굄갓å™Ø" +#: src/vehicle_use.cpp +msgctxt "electronics menu option" +msgid "smart controller" +msgstr "ć‚¹ćƒžćƒ¼ćƒˆć‚Øćƒ³ć‚øćƒ³åˆ¶å¾”č£…ē½®" + #: src/vehicle_use.cpp msgid "Turn off camera system" msgstr "電ęŗć‚’åˆ‡ć‚‹/ć‚«ćƒ”ćƒ©ć‚·ć‚¹ćƒ†ćƒ " @@ -243431,50 +244630,18 @@ msgstr "%1$s恮%2$sć«å…„ć£ćŸę°“ć‚’ęµ„ę°“ć™ć‚‹ć«ćÆé›»åŠ›ćŒč¶³ć‚ŠćŖ恄" msgid "You purify the contents of the %1$s's %2$s" msgstr "%1$s恮%2$sć«å…„ć£ćŸę°“ć‚’ęµ„ę°“ć—ć¾ć—ćŸć€‚" -#: src/weather.cpp -msgid "You hear a distant rumble of thunder." -msgstr "é ćć‹ć‚‰é›·ć®é³“ć‚ŠéŸæćéŸ³ćŒčžć“ćˆć¾ć—ćŸć€‚" - -#: src/weather.cpp -msgid "You hear a rumble of thunder from above." -msgstr "äøŠē©ŗć‹ć‚‰é›·ćŒé³“ć‚ŠéŸæćéŸ³ćŒčžć“ćˆć¾ć—ćŸć€‚" - -#: src/weather.cpp -msgid "A flash of lightning illuminates your surroundings!" -msgstr "č¾ŗ悊恌ēØ²å…‰ć«ē…§ć‚‰ć—å‡ŗć•ć‚Œć¾ć—ćŸļ¼" - #: src/weather.cpp #, c-format -msgid "Your %s protects you from the acidic drizzle." -msgstr "%sćŒå°é…øꀧé›Øć‚’é˜²ć„ć§ć„ć¾ć™ć€‚" - -#: src/weather.cpp -msgid "Your clothing protects you from the acidic drizzle." -msgstr "č”£é”žćŒå°é…øꀧé›Øć‚’é˜²ć„ć§ć„ć¾ć™ć€‚" - -#: src/weather.cpp -msgid "Your power armor protects you from the acidic drizzle." -msgstr "惑ćƒÆćƒ¼ć‚¢ćƒ¼ćƒžćƒ¼ćŒå°é…øꀧé›Øć‚’é˜²ć„ć§ć„ć¾ć™ć€‚" - -#: src/weather.cpp -msgid "The acid rain stings, but is mostly harmless for nowā€¦" -msgstr "é…øꀧé›Ø恌ēš®č†šć‚’åˆŗęæ€ć—ć¦ć„ć¾ć™ćŒć€ä»Šć®ę‰€ć»ćØ悓恩ē„”å®³ć§ć™..." - -#: src/weather.cpp -msgid "Your umbrella protects you from the acid rain." -msgstr "å‚˜ćŒé…øꀧé›Øć‚’é˜²ć„ć§ć„ć¾ć™ć€‚" - -#: src/weather.cpp -msgid "Your clothing protects you from the acid rain." -msgstr "č”£é”žćŒé…øꀧé›Øć‚’é˜²ć„ć§ć„ć¾ć™ć€‚" +msgid "Your %s protects you from the weather." +msgstr "" #: src/weather.cpp -msgid "Your power armor protects you from the acid rain." -msgstr "惑ćƒÆćƒ¼ć‚¢ćƒ¼ćƒžćƒ¼ćŒé…øꀧé›Øć‚’é˜²ć„ć§ć„ć¾ć™ć€‚" +msgid "Your clothing protects you from the weather." +msgstr "" #: src/weather.cpp -msgid "The acid rain burns!" -msgstr "ēš®č†šć«ē«å‚·ć‚’č² ć†ēØ‹ć®é…øꀧé›ØćŒé™ć£ć¦ć„ć¾ć™ļ¼" +msgid "Your power armor protects you from the weather." +msgstr "" #: src/weather.cpp msgid "Monday" @@ -243649,54 +244816,6 @@ msgstr "颶é¢Ø(32.7m仄äøŠ)" msgid "The weather changed to %s!" msgstr "å¤©å€™ćŒ%sć«å¤‰ć‚ć‚Šć¾ć—ćŸļ¼" -#: src/weather_data.cpp -msgid "Clear" -msgstr "ę™“ć‚Œ" - -#: src/weather_data.cpp -msgid "Sunny" -msgstr "åæ«ę™“" - -#: src/weather_data.cpp -msgid "Cloudy" -msgstr "ꛇ悊" - -#: src/weather_data.cpp -msgid "Light Drizzle" -msgstr "霧é›Ø" - -#: src/weather_data.cpp -msgid "Drizzle" -msgstr "小é›Ø" - -#: src/weather_data.cpp -msgid "Rain" -msgstr "é›Ø" - -#: src/weather_data.cpp -msgid "Thunder Storm" -msgstr "雷é›Ø" - -#: src/weather_data.cpp -msgid "Acidic Drizzle" -msgstr "小é…øꀧé›Ø" - -#: src/weather_data.cpp -msgid "Acid Rain" -msgstr "é…øꀧé›Ø" - -#: src/weather_data.cpp -msgid "Flurries" -msgstr "小é›Ŗ" - -#: src/weather_data.cpp -msgid "Snowing" -msgstr "é›Ŗ" - -#: src/weather_data.cpp -msgid "Snowstorm" -msgstr "吹é›Ŗ" - #: src/wish.cpp msgid "Nonvalid" msgstr "ē‰¹ę®Š" @@ -243887,6 +245006,19 @@ msgstr "é–‹å§‹ć™ć‚‹äø–ē•Œć‚’éøęŠžć—ć¦ćć ć•ć„" msgid "last world info" msgstr "å‰å›žć®äø–ē•Œčح定" +#: src/worldfactory.cpp +msgid "MISSING MODS" +msgstr "" + +#: src/worldfactory.cpp +msgid "OBSOLETE MODS" +msgstr "" + +#: src/worldfactory.cpp +#, c-format +msgid " [%s]" +msgstr "" + #: src/worldfactory.cpp msgid " ACTIVE WORLD MODS " msgstr "MODē¢ŗčŖ" diff --git a/lang/po/pl.po b/lang/po/pl.po index 9562b8c324906..541136d33fe58 100644 --- a/lang/po/pl.po +++ b/lang/po/pl.po @@ -17,7 +17,7 @@ msgid "" msgstr "" "Project-Id-Version: cataclysm-dda 0.E\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-07-08 10:07+0800\n" +"POT-Creation-Date: 2020-07-16 21:36+0800\n" "PO-Revision-Date: 2018-04-26 14:47+0000\n" "Last-Translator: Aleksander Sienkiewicz , 2020\n" "Language-Team: Polish (https://www.transifex.com/cataclysm-dda-translators/teams/2217/pl/)\n" @@ -8944,6 +8944,64 @@ msgstr "" "Proste narzędzie do unieruchomienia złamanych kości ramion. Jest specjalnie " "zaprojektowana by pasować na wielkich ocalałych." +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm)" +msgid_plural "tourniquets (arm)" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Use action menu_text for {'str': 'tourniquet (arm)', 'str_pl': +#. 'tourniquets (arm)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (arm XL)', 'str_pl': +#. 'tourniquets (arm XL)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (leg)', 'str_pl': +#. 'tourniquets (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "Adjust" +msgstr "" + +#. ~ Use action msg for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'}. +#. ~ Use action msg for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'}. +#. ~ Use action msg for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "You adjust the tourniquet." +msgstr "" + +#. ~ Description for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'} +#. ~ Description for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'} +#. ~ Description for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'} +#: lang/json/ARMOR_from_json.py +msgid "" +"First aid device used to apply pressure to a limb or extremity in order to " +"limit blood flow. Should be employed only to manage heavy bleedings, " +"because prolonged use will harm the limb. It can be adjusted in size to fit" +" different limbs." +msgstr "" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm XL)" +msgid_plural "tourniquets (arm XL)" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (leg)" +msgid_plural "tourniquets (leg)" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + #: lang/json/ARMOR_from_json.py msgid "blindfold" msgid_plural "blindfolds" @@ -47066,6 +47124,22 @@ msgstr "" "przepisywane w celu leczenia nadpobudliwości i ADHD. Tłumi gÅ‚Ć³d i jest " "silnie uzależniający." +#: lang/json/COMESTIBLE_from_json.py +msgid "adhesive bandage" +msgid_plural "adhesive bandages" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Description for {'str': 'adhesive bandage'} +#: lang/json/COMESTIBLE_from_json.py +msgid "" +"A set of small medical dressings, each made of a piece of sterile cloth and " +"a sticky tape, used for small injuries not serious enough to require a full-" +"size bandage." +msgstr "" + #: lang/json/COMESTIBLE_from_json.py msgid "syringe of adrenaline" msgid_plural "syringes of adrenaline" @@ -47171,8 +47245,10 @@ msgstr[3] "" #. ~ Description for {'str': 'bandage'} #: lang/json/COMESTIBLE_from_json.py -msgid "Simple cloth bandages. Used for healing small amounts of damage." -msgstr "Proste bandaże z materiału. Używane do leczenia niewielkich obrażeń." +msgid "" +"Simple cloth bandages. Used for stopping bloodloss and protecting wounds " +"from external factors." +msgstr "" #: lang/json/COMESTIBLE_from_json.py msgid "makeshift bandage" @@ -59260,8 +59336,8 @@ msgstr[3] "" #. planks'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten construction planks securely lashed together with a rope. Disassemble " -"to unpack." +"Ten construction planks securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" #: lang/json/GENERIC_from_json.py @@ -59276,8 +59352,24 @@ msgstr[3] "" #. stout branches'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten stout branches securely lashed together with a rope. Disassemble to " -"untie them." +"Ten stout branches securely tied together for easier transport. Disassemble" +" to untie them." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "bundle of long stout branches" +msgid_plural "bundles of long stout branches" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Description for {'str': 'bundle of long stout branches', 'str_pl': +#. 'bundles of long stout branches'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Five long stout branches securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" #: lang/json/GENERIC_from_json.py @@ -61779,6 +61871,14 @@ msgid "" "gutted for parts." msgstr "" +#: lang/json/GENERIC_from_json.py +msgid "broken laser turret" +msgid_plural "broken laser turrets" +msgstr[0] "zepsuta wieżyczka laserowa" +msgstr[1] "zepsuta wieżyczka laserowa" +msgstr[2] "zepsuta wieżyczka laserowa" +msgstr[3] "zepsuta wieżyczka laserowa" + #: lang/json/GENERIC_from_json.py msgid "fire brick" msgid_plural "fire bricks" @@ -62494,14 +62594,6 @@ msgstr "" "kruchą. Wygląda też na to, że nie będzie w stanie utrzymać dodatkowej " "warstwy ochronnego pokrycia." -#: lang/json/GENERIC_from_json.py -msgid "broken laser turret" -msgid_plural "broken laser turrets" -msgstr[0] "zepsuta wieżyczka laserowa" -msgstr[1] "zepsuta wieżyczka laserowa" -msgstr[2] "zepsuta wieżyczka laserowa" -msgstr[3] "zepsuta wieżyczka laserowa" - #: lang/json/GENERIC_from_json.py msgid "TX-5LR Laser Cannon" msgid_plural "TX-5LR Laser Cannons" @@ -63551,11 +63643,9 @@ msgstr[3] "młody zaczyn zakwasu" #. ~ Use action msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py msgid "" -"After feeding it and caring for it for weeks, your sourdough starter is " +"After feeding it and caring for it for a week, your sourdough starter is " "finally ready for the big leagues." msgstr "" -"Po tygodniach karmienia i opieki twĆ³j zaczyn zakwasu jest w końcu gotĆ³w do " -"gry." #. ~ Use action not_ready_msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py @@ -63599,10 +63689,8 @@ msgstr "Zaczyn nie jest jeszcze gotowy." #: lang/json/GENERIC_from_json.py msgid "" "This jar contains a floury paste with sourdough starter mixed in. It needs " -"a few hours to recover its strength before it can be used again." +"a day to recover its strength before it can be used again." msgstr "" -"Ten sÅ‚Ć³j zawiera mączną pastę zmieszaną z zaczynem zakwasu. Wymaga kilku " -"godzin regeneracji siły zanim będzie go można użyć ponownie." #: lang/json/GENERIC_from_json.py msgid "sourdough starter" @@ -63663,13 +63751,26 @@ msgstr[3] "zestawu pierwszej pomocy" #. ~ Description for {'str': 'first aid kit'} #: lang/json/GENERIC_from_json.py msgid "" -"A full medical kit, with bandages, local anesthetics, and rapid healing " -"agents. Used for healing large amounts of damage. Disassemble to get its " -"content." +"A typical universal first aid kit, one you'd see in a car or in a household." +" It contains a variety of common medical items stored in case of accidents " +"and injuries. Disassemble to get its content." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "IFAK" +msgid_plural "IFAKs" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Description for {'str': 'IFAK'} +#: lang/json/GENERIC_from_json.py +msgid "" +"An IFAK, or individual first aid kit, is a specialized set of wound " +"dressings and accessories, and being of military origin focuses on combat " +"trauma and preventing blood loss. Disassemble to get its content." msgstr "" -"Pełen zestaw medyczny z bandażami, miejscowym środkiem przeciwbĆ³lowym i " -"szybkimi środkami leczniczymi. Używane do leczenia dużej ilości obrażeń. " -"RozÅ‚Ć³Å¼ na części by otrzymać jego zawartość." #: lang/json/GENERIC_from_json.py msgid "MRE" @@ -69237,13 +69338,13 @@ msgstr "" #: lang/json/GENERIC_from_json.py msgid "inscribed metal plates" -msgid_plural "inscribed metal platess" +msgid_plural "inscribed metal plates" msgstr[0] "" msgstr[1] "" msgstr[2] "" msgstr[3] "" -#. ~ Description for {'str': 'inscribed metal plates'} +#. ~ Description for {'str_sp': 'inscribed metal plates'} #: lang/json/GENERIC_from_json.py msgid "" "This device looks electronic, but is unfamiliar. It is a series of tightly " @@ -69284,6 +69385,40 @@ msgid "" "work." msgstr "" +#: lang/json/GENERIC_from_json.py +msgid "engraved parabolic dish" +msgid_plural "engraved parabolic dishes" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Description for {'str': 'engraved parabolic dish', 'str_pl': 'engraved +#. parabolic dishes'} +#: lang/json/GENERIC_from_json.py +msgid "" +"This hefty parabolic dish is engraved with an unrecognizable pattern of " +"symbols that might, at a guess, be some sort of circuitry pattern - or maybe" +" a religious incantation." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "oblong device" +msgid_plural "oblong devices" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Description for {'str': 'oblong device'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Perfectly smooth, cool to the touch, and a dull blue-grey colour, this looks" +" almost like a perfect riverstone at first glance. Its artificial nature is" +" betrayed on closer inspection by a network of intricate patterns visible as" +" a slight difference in the reflection of light off its surface." +msgstr "" + #: lang/json/GENERIC_from_json.py msgid "sheet of glass" msgid_plural "sheets of glass" @@ -81616,6 +81751,25 @@ msgid "" " before running out of power." msgstr "" +#: lang/json/MONSTER_from_json.py +msgid "feral human" +msgid_plural "feral humans" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Description for {'str': 'feral human'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pupils dilated and what remains to be seen of the iris and sclera are " +"bloodshot. It still breathes but the zombies treat it like one of them." +msgstr "" + +#: lang/json/MONSTER_from_json.py +msgid "They throw a loose brick at you!" +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "alpha razorclaw" msgid_plural "alpha razorclaws" @@ -86165,6 +86319,22 @@ msgstr "" "Agresywny zmutowany rodzaj padalca, bladoÅ¼Ć³Å‚ty z powodu podziemnego życia. " "Roi się pod ziemią i jest znany z tego, że jest plagą kanaÅ‚Ć³w ściekowych." +#: lang/json/MONSTER_from_json.py +msgid "prototype laser turret" +msgid_plural "prototype laser turrets" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Description for {'str': 'prototype laser turret'} +#: lang/json/MONSTER_from_json.py +msgid "" +"This appears to be a very experimental automated tower. Plating-less and " +"seemingly half-built, it's little more than an oversized laser emitter and a" +" camera, both welded to a swiveling platform." +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "blob" msgid_plural "blobs" @@ -87108,6 +87278,24 @@ msgstr "" "Puma, ktĆ³ra wyglądałaby normalnie gdyby nie spuchnięte zadnie nogi i " "wybałuszone od czarnego szlamu oczy." +#: lang/json/MONSTER_from_json.py +msgid "zombie horse" +msgid_plural "zombie horses" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Description for {'str': 'zombie horse'} +#: lang/json/MONSTER_from_json.py +msgid "" +"From the looks of this zombie horse's ghastly features, with its protruding " +"ribs, whitish skull, and empty eyes, the exposed part of the internal organs" +" shows a seemingly lifeless color, and the black body fluid drips slowly. " +"The new strength makes the horse no longer dependent on its muscles, but it " +"can still pursue the enemy quickly." +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "Tiger wight" msgid_plural "Tiger wights" @@ -87123,6 +87311,39 @@ msgid "" "eyes wide open and shining black." msgstr "" +#: lang/json/MONSTER_from_json.py +msgid "zombie cow" +msgid_plural "zombie cows" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Description for {'str': 'zombie cow'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Once a placid cow, this leathery horror stumbles and shudders, its pulsing " +"black eyes scanning for prey beneath wicked horns. It is big and heavy and " +"murderous." +msgstr "" + +#: lang/json/MONSTER_from_json.py +msgid "woodland wight" +msgid_plural "woodland wights" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#. ~ Description for {'str': 'woodland wight'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pale, stumbling white-tailed deer with blackened eyes and drooling slime " +"down its neck. Its legs twist and bend in strange, haphazard directions, " +"but with unnatural strength and speed. Preys on coyotes, wolves, and giant " +"spider mutants." +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "mass of zombie spiders" msgid_plural "mass of zombie spiderss" @@ -88121,14 +88342,14 @@ msgstr "" "szerokimi jak kosz na śmieci." #: lang/json/MONSTER_from_json.py -msgid "feral hunter" -msgid_plural "feral hunters" -msgstr[0] "dziki łowca" -msgstr[1] "dzikich łowcĆ³w" -msgstr[2] "dzikich łowcĆ³w" -msgstr[3] "dzikich łowcĆ³w" +msgid "zombie hunter" +msgid_plural "zombie hunters" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" -#. ~ Description for {'str': 'feral hunter'} +#. ~ Description for {'str': 'zombie hunter'} #: lang/json/MONSTER_from_json.py msgid "" "This once-human body is barely recognizable, scrambling about on all fours, " @@ -88236,14 +88457,14 @@ msgid "" msgstr "" #: lang/json/MONSTER_from_json.py -msgid "feral runner" -msgid_plural "feral runners" -msgstr[0] "dziki biegacz" -msgstr[1] "dzikich biegaczy" -msgstr[2] "dzikich biegaczy" -msgstr[3] "dzikich biegaczy" +msgid "zombie runner" +msgid_plural "zombie runners" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" -#. ~ Description for {'str': 'feral runner'} +#. ~ Description for {'str': 'zombie runner'} #: lang/json/MONSTER_from_json.py msgid "" "This recently-risen body moves quickly, darting its head back and forth and " @@ -88253,14 +88474,14 @@ msgstr "" "tył, i obgryzając swoje dłonie." #: lang/json/MONSTER_from_json.py -msgid "feral predator" -msgid_plural "feral predators" -msgstr[0] "dziki drapieżnik" -msgstr[1] "dzikich drapieżnikĆ³w" -msgstr[2] "dzikich drapieżnikĆ³w" -msgstr[3] "dzikich drapieżnikĆ³w" +msgid "zombie predator" +msgid_plural "zombie predators" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" -#. ~ Description for {'str': 'feral predator'} +#. ~ Description for {'str': 'zombie predator'} #: lang/json/MONSTER_from_json.py msgid "" "With its joints in odd places and angles, this humanoid creature prowls " @@ -93121,7 +93342,7 @@ msgstr "Obolały" msgid "Increases pain" msgstr "Rosnący bĆ³l" -#: lang/json/SPELL_from_json.py src/character.cpp src/npctalk.cpp +#: lang/json/SPELL_from_json.py src/character.cpp src/talker_npc.cpp msgid "Tired" msgstr "Zmęczony" @@ -94203,7 +94424,7 @@ msgstr "" msgid "Lightning Blast" msgstr "" -#: lang/json/SPELL_from_json.py src/weather_data.cpp +#: lang/json/SPELL_from_json.py lang/json/weather_type_from_json.py msgid "Lightning Storm" msgstr "Burza z Piorunami" @@ -95211,13 +95432,10 @@ msgstr[3] "zbroja bojowa RM13" #. ~ Description for {'str': 'RM13 combat armor'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. Use it to turn it on." msgstr "" -"Wewnętrznie zasilana maksimum dziesięcioma ogniwami plutonowymi elegancka " -"czarna wojskowa zbroja na całe ciało, będąca szczytowym osiągnięciem Rivtech" -" w budowie nieutwardzanych pancerzy wspomaganych. Użyj by włączyć." #: lang/json/TOOL_ARMOR_from_json.py msgid "RM13 combat armor (on)" @@ -95231,15 +95449,11 @@ msgstr[3] "zbroja bojowa RM13 (wł.)" #. armors (on)'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. It is turned on, and continually draining " "power. Use it to turn it off." msgstr "" -"Wewnętrznie zasilana maksimum dziesięcioma ogniwami plutonowymi elegancka " -"czarna wojskowa zbroja na całe ciało, będąca szczytowym osiągnięciem Rivtech" -" w budowie nieutwardzanych pancerzy wspomaganych. Obecnie włączona i stale " -"drenuje baterie. Użyj, by wyłączyć." #: lang/json/TOOL_ARMOR_from_json.py msgid "5-point anchor" @@ -96659,12 +96873,8 @@ msgstr[3] "plecak solarny (złożony)" msgid "" "Personal portable charging system consisting of an array of solar panels " "neatly folded in a form of a large backpack. It can be worn as one, and has" -" an integrated cable to plug it into a cable charger system." +" an integrated cable to plug it into a cable charger system CBM." msgstr "" -"Osobisty przenośny system ładujący składający się z zestawu paneli " -"słonecznych sprytnie złożonych w kształcie dużego plecaka. Może być noszony " -"jak plecak i ma zintegrowany kabel, ktĆ³ry można wpiąć w system zasilania " -"kablowego." #: lang/json/TOOL_ARMOR_from_json.py msgid "solar backpack (unfolded)" @@ -96679,10 +96889,8 @@ msgstr[3] "plecak solarny (rozłożony)" #: lang/json/TOOL_ARMOR_from_json.py msgid "" "Unfolded array of portable solar panels ready to push some power into an " -"active cable charger system." +"active cable charger system CBM." msgstr "" -"Rozłożony zestaw przenośnych paneli słonecznych gotowych pchnąć trochę mocy " -"w aktywny system zasilania kablowego." #: lang/json/TOOL_ARMOR_from_json.py msgid "riot helmet" @@ -102467,13 +102675,9 @@ msgstr "" msgid "" "This is an advanced version of the unified power supply, or UPS. This " "device has been significantly redesigned to provide better efficiency as " -"well as to consume plutonium fuel cells rather than batteries. Sadly, its " -"plutonium reactor can't be charged in UPS charging station." +"well as to consume plutonium fuel batteries rather than regular batteries. " +"Sadly, its plutonium reactor can't be charged in UPS charging station." msgstr "" -"To zaawansowana wersja zunifikowanego systemu zasilania, czyli UPS-a. " -"Urządzenie zostało znacząco przebudowane dla zwiększenia efektywności. " -"Ponadto używa ogniw plutonowych a nie baterii. Niestety jego plutonowy " -"reaktor nie może być zasilony w stacji ładowania UPS." #. ~ Description for {'str': 'camera'} #: lang/json/TOOL_from_json.py @@ -103509,10 +103713,11 @@ msgstr "Wyciągasz zawleczkę w granacie EMP." #: lang/json/TOOL_from_json.py msgid "" "This is a grenade that generates an electromagnetic pulse with a low-" -"inductance capacitor bank discharged into a single-loop antenna. Use this " -"item to pull the pin and light the fuse, turning it into an active EMP " -"grenade. You will then have three turns before it detonates, creating an " -"EMP field that damages robots and drains bionic energy." +"inductance capacitor bank discharged into a single-loop antenna. It also " +"produces a mild electric shock cloud. Use this item to pull the pin and " +"light the fuse, turning it into an active EMP grenade. You will then have " +"three turns before it detonates, creating an EMP field that damages robots " +"and drains bionic energy." msgstr "" #: lang/json/TOOL_from_json.py @@ -103527,12 +103732,9 @@ msgstr[3] "aktywny granat EMP" #: lang/json/TOOL_from_json.py msgid "" "This EMP grenade is active, and will shortly detonate, creating a large EMP " -"field that damages robots and drains bionic energy. You may not want to be " -"holding it much longer." +"field that damages robots and drains bionic energy as well as a mild " +"electric shock cloud. You may not want to be holding it much longer." msgstr "" -"Ten granat EMP jest aktywny i zaraz zdetonuje tworząc pole " -"elektromagnetyczne uszkadzające roboty i drenujące bioniczną energię. Możesz" -" nie chcieć trzymać go dłużej." #: lang/json/TOOL_from_json.py msgid "incendiary grenade" @@ -108748,14 +108950,10 @@ msgstr "Rozstawiasz pułapkę ze strzelbą." #. ~ Description for {'str': 'shotgun trap'} #: lang/json/TOOL_from_json.py msgid "" -"This is a simple tripwire is attached to the trigger of a loaded double-" -"barreled shotgun. When pulled, the shotgun fires. Two shells are loaded; " +"This is a simple tripwire is attached to the trigger of a loaded double " +"slamfire shotgun. When pulled, the shotgun fires. Two shells are loaded; " "the first time the trigger is pulled, one or both shells may be discharged." msgstr "" -"Prosta pułapka z potykaczem przyłączonym do spustu załadowanej strzelby " -"dwururki. Pociągnięty uruchamia wystrzał ze strzelby. Załadowana jest dwoma " -"nabojami. Pierwsze pociągnięcie linki spowoduje wystrzał obu lub jednego z " -"nich." #: lang/json/TOOL_from_json.py msgid "tripwire trap" @@ -116669,6 +116867,26 @@ msgstr "Wzmocnij Ścianę ze Złomu spawaniem" msgid "Build Junk Metal Floor" msgstr "Zbuduj Podłogę ze Złomu" +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Bolts" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Welder" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bench" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Table" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Lay down decorative ground cable" +msgstr "" + #: lang/json/construction_from_json.py msgid "Build Pillow Fort" msgstr "Zbuduj Poduszkowy Fort" @@ -119175,6 +119393,15 @@ msgstr "" msgid "Your muscles won't cooperate!" msgstr "" +#: lang/json/effects_from_json.py +msgid "Minor Bleeding" +msgstr "" + +#. ~ Description of effect 'Minor Bleeding'. +#: lang/json/effects_from_json.py +msgid "Tis but a scratch." +msgstr "" + #: lang/json/effects_from_json.py msgid "Bleeding" msgstr "Krwawienie" @@ -119202,7 +119429,25 @@ msgstr "Silne Krwawienie" msgid "You are rapidly losing blood." msgstr "Gwałtownie tracisz krew." -#. ~ Apply message for effect(s) 'Bleeding, Bad Bleeding, Heavy Bleeding'. +#: lang/json/effects_from_json.py +msgid "Heavy Arterial Bleeding" +msgstr "" + +#. ~ Description of effect 'Heavy Arterial Bleeding'. +#: lang/json/effects_from_json.py +msgid "Blood is gushing from you like a fountain." +msgstr "" + +#. ~ Apply message for effect(s) 'Minor Bleeding, Minor Bleeding, Minor +#. Bleeding, Minor Bleeding, Minor Bleeding, Bleeding, Bleeding, Bleeding, +#. Bleeding, Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, +#. Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad +#. Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, +#. Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy +#. Bleeding, Heavy Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding'. #: lang/json/effects_from_json.py msgid "You're bleeding!" msgstr "Krwawisz!" @@ -119970,10 +120215,64 @@ msgid "Your bones become stronger as your calcium deficiency improves." msgstr "" "Twoje kości stają się mocniejsze gdy polepsza się twoja gospodarka wapniowa." +#: lang/json/effects_from_json.py +msgid "Early iron deficiency" +msgstr "" + +#. ~ Description of effect 'Early iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"A lack of iron in your diet has hampered efficiency and regeneration of your" +" red blood cells." +msgstr "" + #: lang/json/effects_from_json.py msgid "Iron deficiency" msgstr "NiedobĆ³r Å»elaza" +#. ~ Description of effect 'Iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"Prolonged lack of iron in your diet has compromised efficiency and " +"regeneration of your red blood cells." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Acute iron deficiency" +msgstr "" + +#. ~ Description of effect 'Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"Severe lack of iron in your diet results in your red blood cells dying " +"faster then they are regenerating." +msgstr "" + +#. ~ Apply message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#. ~ Apply message for effect(s) 'Early anemia, Anemia, Acute anemia'. +#: lang/json/effects_from_json.py +msgid "You begin feeling increasingly tired and listless." +msgstr "Czujesz się coraz bardziej zmęczony i apatyczny." + +#. ~ Remove message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "You are no longer in risk of becoming anemic." +msgstr "" + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your irom deficiency is nearly resolved." +msgstr "" + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your iron deficiency starts to improve." +msgstr "" + #: lang/json/effects_from_json.py msgid "Early anemia" msgstr "Wczesna Anemia" @@ -119983,26 +120282,24 @@ msgid "Anemia" msgstr "Anemia" #: lang/json/effects_from_json.py -msgid "" -"A lack of iron in your diet will result in progressively worsening anemia." -msgstr "Brak żelaza w twojej diecie powoduje pogarszającą się anemię." +msgid "Acute anemia" +msgstr "" -#. ~ Apply message for effect(s) 'Iron deficiency, Early anemia, Anemia'. #: lang/json/effects_from_json.py -msgid "You begin feeling increasingly tired and listless." -msgstr "Czujesz się coraz bardziej zmęczony i apatyczny." +msgid "Loss of red blood cells results in progressively worsening anemia." +msgstr "" -#. ~ Remove message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Remove message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You no longer feel anemic." msgstr "Nie czujesz się już anemicznie." -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py -msgid "Your iron deficiency is nearly resolved." -msgstr "TwĆ³j niedobĆ³r żelaza jest już prawie uzupełniony." +msgid "Your anemia is nearly resolved." +msgstr "" -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "Your feel stronger as your anemia starts to improve." msgstr "Czujesz się silniejszy gdy maleje twoja anemia." @@ -120199,6 +120496,77 @@ msgid "" "disgusting rations day in and day out?" msgstr "" +#: lang/json/effects_from_json.py +msgid "Mild hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Mild hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost some blood and look somewhat pale." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Moderate hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Moderate hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost large amount of blood, and you're not feeling well." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Advanced hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Advanced hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost an awful lot of blood, and your condition is severe. Seek " +"medical attention." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Severe hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost tremendous amount of blood, and you're standing on death's door." +" Transfusion might save you." +msgstr "" + +#. ~ Apply message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You have lost lot of blood, and your condition worsens." +msgstr "" + +#. ~ Remove message for effect(s) 'Mild hypovolemic shock, Moderate +#. hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You are no longer in shock." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your blood level increase, and you feel better, but still look pale." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your blood levels starts to improve." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You're not dying from lack of blood, but you're not out of the woods yet." +msgstr "" + #: lang/json/effects_from_json.py msgid "Lit up" msgstr "Oświetlony" @@ -122120,25 +122488,343 @@ msgid "mutated cactus" msgstr "zmutowany kaktus" #: lang/json/furniture_from_json.py -msgid "cooling unit" +msgid "glowing tendril" msgstr "" -#. ~ Description for cooling unit +#. ~ Description for glowing tendril #: lang/json/furniture_from_json.py msgid "" -"A large, blocky appliance encased in sheet metal. This commonplace fixture " -"is used for cooling large indoor areas." +"A willowy tendril growing from the floor, gently waving back and forth. A " +"faint light spills from it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "splorch!" msgstr "" #: lang/json/furniture_from_json.py lang/json/furniture_from_json.py #: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "metal screeching!" -msgstr "zgrzyt metalu!" +msgid "whump!" +msgstr "whump!" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py +msgid "wafting anemone" +msgstr "" + +#. ~ Description for wafting anemone +#: lang/json/furniture_from_json.py +msgid "" +"A fleshy white protuberance growing from the floor, with a cluster of " +"tendrils pouring out of it. It looks almost exactly like a sea anemone, " +"even waving gently as though underwater." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "gasping tube" +msgstr "" + +#. ~ Description for gasping tube +#: lang/json/furniture_from_json.py +msgid "" +"This is a meaty green stalactite with a thickened hide like that of a " +"starfish, extending from the floor to the ceiling. In the center is a " +"series of ports somewhat like mouths, from which pour bursts of a vile-" +"smelling gas." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "twitching frond" +msgstr "" + +#. ~ Description for twitching frond +#: lang/json/furniture_from_json.py +msgid "" +"A spine resembling moth antennae juts from the ground, swaying gently in the" +" air. Every so often, a cascade of energy arcs along it and discharges into" +" the ceiling." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scarred lump" +msgstr "" + +#. ~ Description for scarred lump +#: lang/json/furniture_from_json.py +msgid "" +"This is a pile of nondescript alien flesh, twitching and belching strange " +"gases out of injured orifices." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "splat!" +msgstr "splat!" + +#: lang/json/furniture_from_json.py +msgid "slimy pod" +msgstr "" + +#. ~ Description for slimy pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a slick, translucent pod suspended on a thin stalk. It is covered " +"in a thick mucus, obscuring whatever is floating in the gel-like substance " +"inside." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "whump." +msgstr "whump." + +#: lang/json/furniture_from_json.py +msgid "organ pod" +msgstr "" + +#. ~ Description for organ pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside you can see the" +" dimly outlined shape of human organs, floating in some kind of preservative" +" goo." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "resin pod" +msgstr "" + +#. ~ Description for resin pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside is a clean, " +"clear resinous-looking fluid. You could fairly easily tear it from the " +"stalk and take it with you." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "fleshy altar" +msgstr "" + +#. ~ Description for fleshy altar +#: lang/json/furniture_from_json.py +msgid "" +"This pulsing protuberance juts from the floor, its sides covered in scaled, " +"oozing skin. The surface is flat, but undulates softly. A handful of " +"unidentifiable appendages reach from the sides, suggesting a sort of " +"nightmarish living autodoc." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scrap antenna" +msgstr "" + +#. ~ Description for scrap antenna +#: lang/json/furniture_from_json.py +msgid "" +"This contraption looks like some sort of cobbled-together transmitter or " +"receiver antenna. It consists of a number of mismatched blinking lights, " +"spinning servos, and dangling wires connected to a heft metal box." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py msgid "clang!" msgstr "klang!" +#: lang/json/furniture_from_json.py +msgid "rack of robots" +msgstr "" + +#. ~ Description for rack of robots +#: lang/json/furniture_from_json.py +msgid "" +"This is a wire cage containing a number of robot parts, from chassis to " +"limbs, firmly clamped on to sturdy hanging rods. It looks like it would be " +"exceptionally difficult to open it and get at them without damaging them, " +"probably by design." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "spinning dish" +msgstr "" + +#. ~ Description for spinning dish +#: lang/json/furniture_from_json.py +msgid "" +"This is a slowly spinning parabolic dish engraved with an unrecognizable " +"pattern of symbols that might, at a guess, be some sort of circuitry pattern" +" - or maybe a religious incantation. It is mounted on a completely " +"mismatched electric motor that looks fairly mundane." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scavenged utility light" +msgstr "" + +#. ~ Description for scavenged utility light +#: lang/json/furniture_from_json.py +msgid "" +"The bulbs emit an eery greenish glow, and some parts of it have a curved " +"appearance as though the metal were grown in a lab, but by and large this " +"isn't a particularly unusual looking area light." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "clanking fluid pump" +msgstr "" + +#. ~ Description for clanking fluid pump +#: lang/json/furniture_from_json.py +msgid "" +"The huge sweating pipes and large tank reveal this clanking and tortuous " +"piece of equipment to be some sort of fluid pump. It is cobbled from " +"several apparently ill-fitting parts that have been fitted together with " +"some very strange looking but surprisingly clever adaptors." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "metalloid printer" +msgstr "" + +#. ~ Description for metalloid printer +#: lang/json/furniture_from_json.py +msgid "" +"This huge device actually resembles a 3D printer fairly closely, aside from " +"its industrial size. Huge spools of various thin metallic wires top it and " +"feed into what seems to be some sort of nozzle, and massive electrical " +"cables disappear into the wall behind it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "circuit printer" +msgstr "" + +#. ~ Description for circuit printer +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall device with a lattice of pipes and nozzles. Based on the " +"pile of products sitting in the output hopper, it looks like itā€™s used as a " +"printer for complex electronic components." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "Mavrik 10-101 power core" +msgstr "" + +#. ~ Description for Mavrik 10-101 power core +#: lang/json/furniture_from_json.py +msgid "" +"There is a faded metallic plaque on the side of this cylindrical device. The lettering is a strange combination of English and Cyrillic script. It reads:\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "metal screeching!" +msgstr "zgrzyt metalu!" + +#: lang/json/furniture_from_json.py +msgid "spherical generator" +msgstr "" + +#. ~ Description for spherical generator +#: lang/json/furniture_from_json.py +msgid "" +"This huge steel plated sphere gives off a soft hum as it, presumably, " +"generates power. A heavy lead plate bolted to the front might describe what" +" it is, but it is written in something that looks vaguely like cuneiform." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "fluidic generator" +msgstr "" + +#. ~ Description for fluidic generator +#: lang/json/furniture_from_json.py +msgid "" +"Twisting reams of copper and steel pipes wrap around a central core that " +"thrums softly. Although there are no labels in any language you recognize, " +"the cables connected to the base suggest that this is some sort of power " +"generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "rusty generator" +msgstr "" + +#. ~ Description for rusty generator +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall, unremarkable cylinder capped by a wide flat saucer. There " +"is heavy rusting at the base. A series of connected cables suggest that " +"it's some sort of power generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "personal charging station" +msgstr "" + +#. ~ Description for personal charging station +#: lang/json/furniture_from_json.py +msgid "" +"The cyborg equivalent of a bed, this is a custom-shaped near-vertical booth " +"designed to mount a heavy metal frame and connect it to a central power " +"supply and nutrient source." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp +msgid "crash!" +msgstr "krasz!" + +#: lang/json/furniture_from_json.py +msgid "simple charging station" +msgstr "" + +#. ~ Description for simple charging station +#: lang/json/furniture_from_json.py +msgid "" +"This is a simple, unadorned, corroded metal charging and refeeding station, " +"with hookups for two units somewhat larger than a human to stand side by " +"side and be recharged and refueled." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shimmering superstructure" +msgstr "" + +#. ~ Description for shimmering superstructure +#: lang/json/furniture_from_json.py +msgid "" +"A simple metal superstructure like you might see holding up a radio tower, " +"this one seems to give off just the faintest hint of shimmer, like heat " +"waves. The metal has a burnt, iridescent pattern. There is a boxy, " +"unimpressive looking device at the top of the tower." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "portal enclosure" +msgstr "" + +#. ~ Description for portal enclosure +#: lang/json/furniture_from_json.py +msgid "" +"A heavy metal ring attached to dozens of wires, charred by residue that " +"gives off an acrid, unfamiliar smell." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "cooling unit" +msgstr "" + +#. ~ Description for cooling unit +#: lang/json/furniture_from_json.py +msgid "" +"A large, blocky appliance encased in sheet metal. This commonplace fixture " +"is used for cooling large indoor areas." +msgstr "" + #: lang/json/furniture_from_json.py msgid "central air filter" msgstr "gÅ‚Ć³wny filtr powietrza" @@ -122296,8 +122982,7 @@ msgid "" "priceless tools, invaluable to any survivor." msgstr "" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py msgid "whack!" msgstr "whack!" @@ -122313,16 +122998,12 @@ msgid "" "little to stop a moving car." msgstr "" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -#: src/mapdata.cpp src/vehicle_move.cpp +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/map.cpp src/mapdata.cpp +#: src/vehicle_move.cpp msgid "smash!" msgstr "smash!" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -msgid "whump." -msgstr "whump." - #: lang/json/furniture_from_json.py msgid "earthbag barricade" msgstr "barykada z workĆ³w z ziemią" @@ -122659,10 +123340,6 @@ msgid "" "them moving slightly. Gross." msgstr "" -#: lang/json/furniture_from_json.py -msgid "splat!" -msgstr "splat!" - #. ~ Description for spider egg sack #: lang/json/furniture_from_json.py msgid "" @@ -122741,16 +123418,6 @@ msgid "" "the smoke to the outside. Dangerous to leave unattended while lit." msgstr "" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -msgid "crash!" -msgstr "krasz!" - -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "whump!" -msgstr "whump!" - #: lang/json/furniture_from_json.py msgid "wood stove" msgstr "piecyk koza" @@ -122913,8 +123580,9 @@ msgid "" "comfort or warmth." msgstr "" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -#: src/iuse.cpp +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/iuse.cpp msgid "crunch!" msgstr "crunch!" @@ -123076,6 +123744,78 @@ msgid "" " chemicals." msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken generator" +msgstr "uszkodzony generator" + +#. ~ Description for broken generator +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This generator is broken and will not help you produce usable electricity." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "Compact Advanced Sterling Radioisotope Generator" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"This hefty lump of steel and lead is the housing unit for a small nuclear " +"reactor. It is plastered with warning signs. You could probably ignore " +"those and salvage the steel and lead shielding, what could possibly go " +"wrong?" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"Some insane fool has removed the outer containment on this small-scale " +"nuclear reactor. It is still fairly safe as it is: the reactor has " +"considerable built-in containment as well. Nevertheless, you probably don't" +" want to stand too close for too long." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "light machinery" +msgstr "lekka mszyneria" + +#. ~ Description for light machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted light machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "ting." +msgstr "ting." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "heavy machinery" +msgstr "ciężka maszyneria" + +#. ~ Description for heavy machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted heavy machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "old machinery" +msgstr "stara maszyneria" + +#. ~ Description for old machinery +#: lang/json/furniture_from_json.py +msgid "Assorted old, rusty machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "electronic machinery" +msgstr "elektroniczna maszyneria" + +#. ~ Description for electronic machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted electronic machinery. You could scavenge it for parts." +msgstr "" + #: lang/json/furniture_from_json.py msgid "robotic arm" msgstr "robotyczne ramię" @@ -123093,6 +123833,32 @@ msgstr "" msgid "thunk." msgstr "thunk." +#: lang/json/furniture_from_json.py +msgid "ground cable" +msgstr "" + +#. ~ Description for ground cable +#: lang/json/furniture_from_json.py +msgid "A bunch of loose cables snake along the floor." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shred!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "thud!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "capacitor bank" +msgstr "" + +#. ~ Description for capacitor bank +#: lang/json/furniture_from_json.py +msgid "A bank of heavy metal cylinders connected by large wires." +msgstr "" + #: lang/json/furniture_from_json.py msgid "Autodoc Mk. XI" msgstr "Autodok Mk. XI" @@ -123360,116 +124126,17 @@ msgstr "otwĆ³rz zasłonę przebieralni" msgid "Stop peeking!" msgstr "Przestań podglądać!" -#: lang/json/furniture_from_json.py -msgid "glowing tendril" -msgstr "" - -#. ~ Description for glowing tendril -#: lang/json/furniture_from_json.py -msgid "" -"A willowy tendril growing from the floor, gently waving back and forth. A " -"faint light spills from it." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "splorch!" -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "wafting anemone" -msgstr "" - -#. ~ Description for wafting anemone -#: lang/json/furniture_from_json.py -msgid "" -"A fleshy white protuberance growing from the floor, with a cluster of " -"tendrils pouring out of it. It looks almost exactly like a sea anemone, " -"even waving gently as though underwater." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "gasping tube" -msgstr "" - -#. ~ Description for gasping tube -#: lang/json/furniture_from_json.py -msgid "" -"This is a meaty green stalactite with a thickened hide like that of a " -"starfish, extending from the floor to the ceiling. In the center is a " -"series of ports somewhat like mouths, from which pour bursts of a vile-" -"smelling gas." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "twitching frond" -msgstr "" - -#. ~ Description for twitching frond -#: lang/json/furniture_from_json.py -msgid "" -"A spine resembling moth antennae juts from the ground, swaying gently in the" -" air. Every so often, a cascade of energy arcs along it and discharges into" -" the ceiling." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "scarred lump" -msgstr "" - -#. ~ Description for scarred lump -#: lang/json/furniture_from_json.py -msgid "" -"This is a pile of nondescript alien flesh, twitching and belching strange " -"gases out of injured orifices." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "slimy pod" -msgstr "" - -#. ~ Description for slimy pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a slick, translucent pod suspended on a thin stalk. It is covered " -"in a thick mucus, obscuring whatever is floating in the gel-like substance " -"inside." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "organ pod" -msgstr "" - -#. ~ Description for organ pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside you can see the" -" dimly outlined shape of human organs, floating in some kind of preservative" -" goo." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "resin pod" -msgstr "" - -#. ~ Description for resin pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside is a clean, " -"clear resinous-looking fluid. You could fairly easily tear it from the " -"stalk and take it with you." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "fleshy altar" -msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "centrifuge" +msgstr "centryfuga" -#. ~ Description for fleshy altar +#. ~ Description for centrifuge #: lang/json/furniture_from_json.py msgid "" -"This pulsing protuberance juts from the floor, its sides covered in scaled, " -"oozing skin. The surface is flat, but undulates softly. A handful of " -"unidentifiable appendages reach from the sides, suggesting a sort of " -"nightmarish living autodoc." +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. For some reason, this one has an attached battery pack. It could be " +"used to analyze a medical fluid sample, such as blood, if a test tube was " +"placed in it." msgstr "" #: lang/json/furniture_from_json.py @@ -123966,6 +124633,17 @@ msgid "" " it's not particularly comfortable." msgstr "" +#: lang/json/furniture_from_json.py +msgid "metal bench" +msgstr "" + +#. ~ Description for metal bench +#: lang/json/furniture_from_json.py +msgid "" +"A bench made of scrap metal. Not the most comfortable furniture you've ever" +" seen." +msgstr "" + #: lang/json/furniture_from_json.py msgid "bulletin board" msgstr "słup ogłoszeniowy" @@ -124462,6 +125140,35 @@ msgid "" "A huge metal tank that can be used to safely store large amounts of liquid." msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "fuel tank" +msgstr "" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with gasoline." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken fuel tank" +msgstr "" + +#. ~ Description for broken fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with gasoline." +msgstr "" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with diesel." +msgstr "" + +#. ~ Description for broken fuel tank +#. ~ Description for broken diesel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with diesel." +msgstr "" + #: lang/json/furniture_from_json.py msgid "dumpster" msgstr "pojemnik na śmieci" @@ -124485,6 +125192,42 @@ msgid "" "electricity, it is pedal-driven, allowing use without power." msgstr "" +#: lang/json/furniture_from_json.py +msgid "riveted metal crate" +msgstr "" + +#. ~ Description for riveted metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This huge box is made of a dull metal, riveted together. There is no " +"obvious opening mechanism, and the rivets don't match any of your tools. " +"The only way in would be to smash it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "sealed metal crate" +msgstr "" + +#. ~ Description for sealed metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This is a huge, tightly sealed storage crate made from welded and riveted " +"sheet metal. The sealing mechanism is too tight to open bare-handed and " +"would need some kind of prying instrument to release." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "open metal crate" +msgstr "" + +#. ~ Description for open metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This large metal crateā€™s lid is unsealed, and hinges open easily to reveal a" +" number of storage shelves inside. Once open, the side panels also swing " +"wider for easy access." +msgstr "" + #: lang/json/furniture_from_json.py msgid "counter" msgstr "lada" @@ -124595,6 +125338,15 @@ msgstr "UsiądÅŗ gdy się posilasz." msgid "a low table for livingrooms." msgstr "Niski stolik do salonu." +#: lang/json/furniture_from_json.py +msgid "metal table" +msgstr "" + +#. ~ Description for metal table +#: lang/json/furniture_from_json.py +msgid "A serviceable but simple table made of scrap metal." +msgstr "" + #: lang/json/furniture_from_json.py msgid "tatami mat" msgstr "mata tatami" @@ -124830,6 +125582,17 @@ msgstr "metalowy wrak" msgid "Pile of various bent and twisted metals." msgstr "Stos rĆ³Å¼nych poskręcanych i pogiętych metali." +#: lang/json/furniture_from_json.py +msgid "radioactive slag" +msgstr "" + +#. ~ Description for radioactive slag +#: lang/json/furniture_from_json.py +msgid "" +"A pile of melted slag from a destroyed nuclear reactor. What are you doing " +"looking at this? Get the hell out of here, you nutcase!" +msgstr "" + #: lang/json/furniture_from_json.py msgid "pile of ash" msgstr "kupa popiołu" @@ -124907,6 +125670,39 @@ msgid "" "public utilities, but it doesn't work anymore." msgstr "" +#: lang/json/furniture_from_json.py +msgid "scrap metal bridge" +msgstr "" + +#. ~ Description for scrap metal bridge +#: lang/json/furniture_from_json.py +msgid "A simple bridge made of riveted sheet metal." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py +msgid "broken console" +msgstr "zniszczona konsola" + +#. ~ Description for broken console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It doesn't seem to be working. " +"It's the broken screen and shattered circuit boards that's telling you that." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "computer console" +msgstr "konsola komputerowa" + +#. ~ Description for computer console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It can be used to view contents and" +" perform any allowed functions. It might even be possible to hack it, given" +" the skills." +msgstr "" + #: lang/json/furniture_from_json.py msgid "forge" msgstr "kuÅŗnia" @@ -125284,6 +126080,15 @@ msgid "" "you wouldn't need to pay at all!" msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "rope leading up" +msgstr "lina prowadząca w gĆ³rę" + +#. ~ Description for rope leading up +#: lang/json/furniture_from_json.py +msgid "A rope. You could climb it up." +msgstr "" + #: lang/json/furniture_from_json.py msgid "atomic butter churn on a stand" msgstr "" @@ -129889,6 +130694,23 @@ msgstr[3] "" msgid "Electricity unnaturally arcs from the tips of this alien frond." msgstr "" +#: lang/json/gun_from_json.py +msgid "hurled rubble" +msgid_plural "hurled rubbles" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#: lang/json/gun_from_json.py +msgid "Stone at the ready to crush that which isn't part of the blob." +msgstr "" + +#: lang/json/gun_from_json.py +msgctxt "gun_type_type" +msgid "throw" +msgstr "rzuć" + #: lang/json/gun_from_json.py msgid "nail gun" msgid_plural "nail guns" @@ -129958,7 +130780,7 @@ msgstr[3] "" msgid "" "A short homemade lever-action shotgun with a small internal tube magazine. " "While still a primitive pipe and 2x4 design, it is a formiddable shotgun in " -"it's own right with room for improvement." +"its own right with room for improvement." msgstr "" #: lang/json/gun_from_json.py @@ -130358,8 +131180,8 @@ msgid "" msgstr "" #: lang/json/gun_from_json.py -msgid "four winds shotgun" -msgid_plural "four winds shotguns" +msgid "slam-fire pipe shotgun" +msgid_plural "slam-fire pipe shotguns" msgstr[0] "" msgstr[1] "" msgstr[2] "" @@ -130371,6 +131193,21 @@ msgid "" "The lack of sights make this weapon only useful at point-blank range." msgstr "" +#: lang/json/gun_from_json.py +msgid "double slam-fire pipe shotgun" +msgid_plural "double slam-fire pipe shotguns" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#: lang/json/gun_from_json.py +msgid "" +"A crude shotgun, composed of four thick steel pipes, two end caps and two " +"nails. The lack of sights make this weapon only useful at point-blank " +"range." +msgstr "" + #: lang/json/gun_from_json.py msgid "flaregun" msgid_plural "flareguns" @@ -130947,11 +131784,6 @@ msgid "" " by hand." msgstr "" -#: lang/json/gun_from_json.py -msgctxt "gun_type_type" -msgid "throw" -msgstr "rzuć" - #: lang/json/gun_from_json.py msgid "slingshot" msgid_plural "slingshots" @@ -137351,6 +138183,11 @@ msgid "" "access the controls, or use the vehicle control key (default '^')." msgstr "" +#. ~ Please leave anything in unchanged. +#: lang/json/json_flag_from_json.py +msgid "When active, turns engines on and off automatically." +msgstr "" + #. ~ Please leave anything in unchanged. #: lang/json/json_flag_from_json.py msgid "Illuminated items in this space will not illuminate nearby squares." @@ -139071,6 +139908,10 @@ msgstr "Przełącz oczyszczacze wody" msgid "Toggle tracking" msgstr "Przełącz śledzenie" +#: lang/json/keybinding_from_json.py +msgid "Toggle smart engine controller" +msgstr "" + #: lang/json/keybinding_from_json.py src/turret.cpp src/vehicle_use.cpp msgid "Set turret firing modes" msgstr "Ustaw tryb strzelania wieżyczek" @@ -158076,17 +158917,6 @@ msgstr "" "rozciągającą się na całą Nową Anglię dzięki porozumieniom międzystanowym. " "Jakiekolwiek ma to teraz znaczenie obecnie to odrębna sprawa." -#: lang/json/mutation_from_json.py -msgid "Helicopter Pilot" -msgstr "" - -#. ~ Description for Helicopter Pilot -#: lang/json/mutation_from_json.py -msgid "" -"You are a trained helicopter pilot. This makes you one of the few living " -"people who can operate a helicopter after the Cataclysm." -msgstr "" - #: lang/json/mutation_from_json.py msgid "SWAT Officer" msgstr "Oficer SWAT" @@ -163167,6 +163997,10 @@ msgstr "" msgid "subway station?" msgstr "" +#: lang/json/overmap_terrain_from_json.py +msgid "science lab reactor" +msgstr "" + #: lang/json/overmap_terrain_from_json.py msgid "lab" msgstr "" @@ -170563,6 +171397,18 @@ msgid "" "You have your whole life ahead of you and it's gonna be sweet!" msgstr "" +#: lang/json/proficiency_from_json.py +msgid "Knapping" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Blacksmithing" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Helicopter Piloting" +msgstr "" + #. ~ Crafting recipes category name #: lang/json/recipe_category_from_json.py msgid "*" @@ -179280,7 +180126,7 @@ msgstr "Dziwna rĆ³Å¼owa tabletka prosto z ziemi? Czemu nie?" msgid "Finally, something to take the edge off." msgstr "W końcu, coś co pozwoli się trochę zrelaksować." -#: lang/json/snippet_from_json.py src/npctalk.cpp +#: lang/json/snippet_from_json.py src/talker_npc.cpp msgid "No thanks, I'm good." msgstr "Nie dziękuję, nie trzeba." @@ -199651,6 +200497,18 @@ msgstr "" msgid "This is a npc_has_var, npc_remove_var test response." msgstr "" +#: lang/json/talk_topic_from_json.py +msgid "This is a u_add_var time test response." +msgstr "" + +#: lang/json/talk_topic_from_json.py +msgid "This is a npc_add_var time test response." +msgstr "" + +#: lang/json/talk_topic_from_json.py +msgid "This is a u_compare_var time test response for > 3_days." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "This is a u_adjust_var test response that increments by 1." msgstr "" @@ -199751,6 +200609,10 @@ msgstr "" msgid "This is a low driving test response." msgstr "" +#: lang/json/talk_topic_from_json.py +msgid "This is an npc_first_topic test response." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "Greetings friend, it's nice to see you." msgstr "" @@ -208891,7 +209753,7 @@ msgid "Will do, thanks!" msgstr "Tak zrobię, dzięki!" #: lang/json/talk_topic_from_json.py lang/json/talk_topic_from_json.py -#: src/npctalk.cpp +#: src/talker.h src/talker_npc.cpp msgid "Nope." msgstr "Nie." @@ -214969,6 +215831,36 @@ msgstr "" msgid "The door opens forcefully!" msgstr "" +#: lang/json/terrain_from_json.py +msgid "broken diesel tank" +msgstr "" + +#. ~ Description for centrifuge +#: lang/json/terrain_from_json.py +msgid "" +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. It could be used to analyze a medical fluid sample, such as blood, if" +" a test tube was placed in it." +msgstr "" + +#: lang/json/terrain_from_json.py +msgid "plutonium generator" +msgstr "generator plutonowy" + +#. ~ Description for plutonium generator +#: lang/json/terrain_from_json.py +msgid "" +"This imposing apparatus harnesses the power of the atom. Refined nuclear " +"fuel is 'burned' to provide nearly limitless electrical power. It's not " +"doing much good here though. Perhaps it could be salvaged for other " +"purposes." +msgstr "" + +#. ~ Description for old machinery +#: lang/json/terrain_from_json.py +msgid "Assorted old machinery. You could scavenge it for parts." +msgstr "" + #: lang/json/terrain_from_json.py msgid "scorched earth" msgstr "spalona ziemia" @@ -218006,24 +218898,6 @@ msgstr "" "Hydrauliczna zgniatarka, ktĆ³ra przerabia rzeczy zrobione z rĆ³Å¼nych metali, i" " wytłacza z nich podstawowe formy, gotowe do dalszej obrĆ³bki." -#: lang/json/terrain_from_json.py -msgid "fuel tank" -msgstr "" - -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with gasoline." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "broken fuel tank" -msgstr "" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with gasoline." -msgstr "" - #: lang/json/terrain_from_json.py msgid "gasoline pump" msgstr "dystrybutor benzyny" @@ -218048,16 +218922,6 @@ msgid "" "the liquid gold." msgstr "" -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with diesel." -msgstr "" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with diesel." -msgstr "" - #: lang/json/terrain_from_json.py msgid "diesel pump" msgstr "pompa diesla" @@ -218136,16 +219000,6 @@ msgid "" "airflow." msgstr "" -#: lang/json/terrain_from_json.py -msgid "broken generator" -msgstr "uszkodzony generator" - -#. ~ Description for broken generator -#: lang/json/terrain_from_json.py -msgid "" -"This generator is broken and will not help you produce usable electricity." -msgstr "" - #: lang/json/terrain_from_json.py msgid "missile" msgstr "rakieta" @@ -218203,18 +219057,6 @@ msgid "" "This unpowered pump previously would have moved fluids around in a hurry." msgstr "" -#: lang/json/terrain_from_json.py -msgid "centrifuge" -msgstr "centryfuga" - -#. ~ Description for centrifuge -#: lang/json/terrain_from_json.py -msgid "" -"This is a centrifuge, a liquid separating device with an automated analyzer " -"unit. It could be used to analyze a medical fluid sample, such as blood, if" -" a test tube was placed in it." -msgstr "" - #: lang/json/terrain_from_json.py msgid "CVD machine" msgstr "maszyna CVD" @@ -218317,19 +219159,6 @@ msgstr "" msgid "A machine with several taps that dispenses clean water." msgstr "" -#: lang/json/terrain_from_json.py -msgid "plutonium generator" -msgstr "generator plutonowy" - -#. ~ Description for plutonium generator -#: lang/json/terrain_from_json.py -msgid "" -"This imposing apparatus harnesses the power of the atom. Refined nuclear " -"fuel is 'burned' to provide nearly limitless electrical power. It's not " -"doing much good here though. Perhaps it could be salvaged for other " -"purposes." -msgstr "" - #: lang/json/terrain_from_json.py msgid "telecom cabinet" msgstr "szafa łączności" @@ -218444,46 +219273,6 @@ msgstr "pas transmisyjny" msgid "A conveyor belt. Used to transport things." msgstr "" -#: lang/json/terrain_from_json.py -msgid "ting." -msgstr "ting." - -#: lang/json/terrain_from_json.py -msgid "light machinery" -msgstr "lekka mszyneria" - -#. ~ Description for light machinery -#: lang/json/terrain_from_json.py -msgid "Assorted light machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "heavy machinery" -msgstr "ciężka maszyneria" - -#. ~ Description for heavy machinery -#: lang/json/terrain_from_json.py -msgid "Assorted heavy machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "old machinery" -msgstr "stara maszyneria" - -#. ~ Description for old machinery -#: lang/json/terrain_from_json.py -msgid "Assorted old machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "electronic machinery" -msgstr "elektroniczna maszyneria" - -#. ~ Description for electronic machinery -#: lang/json/terrain_from_json.py -msgid "Assorted electronic machinery. You could scavenge it for parts." -msgstr "" - #: lang/json/terrain_from_json.py msgid "milking machine" msgstr "maszyna dojarska" @@ -218558,29 +219347,6 @@ msgid "" "from the elements or to protect a campfire from the rain." msgstr "" -#: lang/json/terrain_from_json.py -msgid "broken console" -msgstr "zniszczona konsola" - -#. ~ Description for broken console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It doesn't seem to be working. " -"It's the broken screen and shattered circuit boards that's telling you that." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "computer console" -msgstr "konsola komputerowa" - -#. ~ Description for computer console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It can be used to view contents and" -" perform any allowed functions. It might even be possible to hack it, given" -" the skills." -msgstr "" - #: lang/json/terrain_from_json.py msgid "mechanical winch" msgstr "mechaniczna dÅŗwignia" @@ -220879,10 +221645,6 @@ msgstr "pochyłość w gĆ³rę" msgid "An upward facing slope." msgstr "" -#: lang/json/terrain_from_json.py -msgid "rope leading up" -msgstr "lina prowadząca w gĆ³rę" - #. ~ Description for rope leading up #: lang/json/terrain_from_json.py msgid "A rope. You could climb up it." @@ -221542,6 +222304,10 @@ msgstr "SamochĆ³d" msgid "Car Chassis" msgstr "Podwozie Samochodu" +#: lang/json/vehicle_from_json.py +msgid "Hybrid Car" +msgstr "" + #: lang/json/vehicle_from_json.py msgid "City Car" msgstr "" @@ -223388,6 +224154,21 @@ msgstr "" "Zestaw elektroniki, ktĆ³ry utrudnia zapłon pojazdu bez kluczykĆ³w, i włącza " "alarm przy prĆ³bie. Alarm można wyłączyć." +#: lang/json/vehicle_part_from_json.py +msgid "smart engine controller" +msgstr "" + +#. ~ Description for {'str': 'smart engine controller'} +#: lang/json/vehicle_part_from_json.py +#, no-python-format +msgid "" +"Electronic module that automatically switches combustion and electric " +"engines on and off minimizing fuel consumption and optimizing power output " +"and battery charge rate. Must be turned on to work. Simplified ruleset: 1." +" When throttling, maximize acceleration. 2. Keep battery at 90%. 3. " +"Minimize fuel consumption." +msgstr "" + #: lang/json/vehicle_part_from_json.py msgid "5-point harness" msgstr "5-punktowa uprząż" @@ -224662,6 +225443,66 @@ msgstr "" msgid "Disgusting Diet" msgstr "" +#: lang/json/vitamin_from_json.py +msgid "Blood" +msgstr "" + +#: lang/json/vitamin_from_json.py +msgid "Red Blood Cells" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "NULL Weather - BUG" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "Clear" +msgstr "Przejrzyście" + +#: lang/json/weather_type_from_json.py +msgid "Sunny" +msgstr "Słonecznie" + +#: lang/json/weather_type_from_json.py +msgid "Cloudy" +msgstr "Zachmurzenie" + +#: lang/json/weather_type_from_json.py +msgid "Light Drizzle" +msgstr "Lekka Mżawka" + +#: lang/json/weather_type_from_json.py +msgid "Drizzle" +msgstr "Mżawka" + +#: lang/json/weather_type_from_json.py +msgid "Rain" +msgstr "Deszcz" + +#: lang/json/weather_type_from_json.py +msgid "Thunder Storm" +msgstr "Burza" + +#: lang/json/weather_type_from_json.py +msgid "Acidic Drizzle" +msgstr "Kwaśna Mżawka" + +#: lang/json/weather_type_from_json.py +msgid "Acid Rain" +msgstr "Kwaśny Deszcz" + +#: lang/json/weather_type_from_json.py +msgid "Flurries" +msgstr "Zamieć Śnieżna" + +#: lang/json/weather_type_from_json.py +msgid "Snowing" +msgstr "Śnieg" + +#: lang/json/weather_type_from_json.py +msgid "Snowstorm" +msgstr "Burza Śnieżna" + #: src/achievement.cpp msgid "time of cataclysm" msgstr "" @@ -224827,8 +225668,7 @@ msgstr "Twoja moc się wyczerpała!" msgid "You cannot hack this." msgstr "" -#: src/activity_actor.cpp src/computer_session.cpp src/computer_session.cpp -#: src/iuse.cpp src/map.cpp +#: src/activity_actor.cpp src/computer_session.cpp src/iuse.cpp src/map.cpp msgid "an alarm sound!" msgstr "dÅŗwięk alarmu!" @@ -224967,6 +225807,16 @@ msgstr "" msgid "Continue trying to fall asleep and don't ask again." msgstr "" +#: src/activity_actor.cpp +#, c-format +msgid "You disassemble your %s." +msgstr "Rozkładasz twĆ³j %s." + +#: src/activity_actor.cpp src/player.cpp +#, c-format +msgid "You unload your %s." +msgstr "Rozładowujesz twĆ³j %s." + #: src/activity_actor.cpp msgid "You are too tired to exercise." msgstr "" @@ -225493,11 +226343,6 @@ msgstr[3] " zakończył rozbijanie ciał na miazgę." msgid "Can't reload the %s." msgstr "Nie można przeładować %s." -#: src/activity_handlers.cpp src/iexamine.cpp -#, c-format -msgid "You reload the %s." -msgstr "Przeładowujesz %s." - #: src/activity_handlers.cpp #, c-format msgid "" @@ -225514,6 +226359,11 @@ msgstr "" msgid "You refill the %s." msgstr "Uzupełniasz %s." +#: src/activity_handlers.cpp +#, c-format +msgid "You reload the %1$s with %2$s." +msgstr "" + #: src/activity_handlers.cpp src/bionics.cpp msgid "There's nothing to light there." msgstr "Nie ma tam czego podpalić." @@ -225650,6 +226500,10 @@ msgstr "Robiąc to niczego się już nie nauczysz." msgid "%s %s\n" msgstr "%s %s\n" +#: src/activity_handlers.cpp src/magic.cpp +msgid "bionic power" +msgstr "moc bioniczna" + #: src/activity_handlers.cpp #, c-format msgid "Charges: %s/%s %s (%s per use)\n" @@ -226028,16 +226882,6 @@ msgstr "Otwierasz swĆ³j zestaw i się golisz." msgid "You give your hair a trim." msgstr "Przycinasz sobie włosy." -#: src/activity_handlers.cpp -#, c-format -msgid "You disassemble your %s." -msgstr "Rozkładasz twĆ³j %s." - -#: src/activity_handlers.cpp src/player.cpp -#, c-format -msgid "You unload your %s." -msgstr "Rozładowujesz twĆ³j %s." - #: src/activity_handlers.cpp #, c-format msgid "You have run out of %s." @@ -227093,7 +227937,7 @@ msgstr "" msgid "Properties" msgstr "Właściwości" -#: src/armor_layers.cpp +#: src/armor_layers.cpp src/item.cpp msgid "Coverage:" msgstr "Pokrycie:" @@ -229071,7 +229915,7 @@ msgstr "Nie masz mocy by aktywować swĆ³j %s." msgid "Deactivate your %s first!" msgstr "Zdezaktywuj swĆ³j %s najpierw!" -#: src/bionics.cpp src/player.cpp +#: src/bionics.cpp src/character.cpp #, c-format msgid "Stop wielding %s?" msgstr "Przestać trzymać %s?" @@ -230523,6 +231367,11 @@ msgstr "ZejdÅŗ gdzie?" msgid "You cannot dismount there!" msgstr "Nie możesz tam zejść!" +#: src/character.cpp +#, c-format +msgid "This task is too simple to train your %s beyond %d." +msgstr "Ta czynności jest zbyt prosta by trenować %s powyżej %d." + #: src/character.cpp msgid "You struggle to stand." msgstr "Wstajesz z wysiłkiem." @@ -230694,6 +231543,16 @@ msgstr " wydostaje się z dołu!" msgid "Your %s bionic comes back online." msgstr "" +#: src/character.cpp +#, c-format +msgid "Your skill in %s has increased to %d!" +msgstr "Twoja umiejetność %s wzrosła do %d!" + +#: src/character.cpp +#, c-format +msgid "You feel that %s tasks of this level are becoming trivial." +msgstr "Czujesz że zadania w %s tego poziomu stają się trywialne." + #: src/character.cpp #, c-format msgid "You put on your %s." @@ -230809,6 +231668,15 @@ msgstr "" msgid "%s doesn't have any broken limbs this could help." msgstr "" +#: src/character.cpp +msgid "You don't need a tourniquet to stop the bleeding." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "%s doesn't need a tourniquet to stop the bleeding." +msgstr "" + #: src/character.cpp msgid "You don't have enough arms to wear that." msgstr "" @@ -230990,7 +231858,7 @@ msgstr "Wygłodniały" msgid "ERROR!" msgstr "" -#: src/character.cpp src/npctalk.cpp +#: src/character.cpp src/talker_npc.cpp msgid "Exhausted" msgstr "Wypluty" @@ -231034,7 +231902,7 @@ msgstr "Masz skurcze z tego upychania się w pojeÅŗdzie." msgid "You have a sudden heart attack!" msgstr "Masz nagły atak serca!" -#: src/character.cpp +#: src/character.cpp src/player_hardcoded_effects.cpp msgid " has a sudden heart attack!" msgstr "" @@ -231268,12 +232136,12 @@ msgstr "" #: src/character.cpp #, c-format -msgid "Chance to stop: %d %%" -msgstr "Szansa na zatrzymanie: %d %%" +msgid "Expected reduction of bleeding by: %d %%" +msgstr "" #: src/character.cpp -msgid "This will not stop the bleeding." -msgstr "To nie zatrzyma krwawienia." +msgid "This will not affect the bleeding." +msgstr "" #: src/character.cpp #, c-format @@ -231724,6 +232592,41 @@ msgstr "TwĆ³j %1$s jest %2$s dalej!" msgid "Your %1$s is %2$s!" msgstr "TwĆ³j %1$s jest %2$s!" +#: src/character.cpp +msgid "Can't wield spilt liquids." +msgstr "Nie możesz trzymać rozlanych płynĆ³w." + +#: src/character.cpp +msgid "You need at least one arm to even consider wielding something." +msgstr "Musisz mieć przynajmniej jedno ramię żeby cokolwiek trzymać." + +#: src/character.cpp +#, c-format +msgid "The %s is preventing you from wielding the %s." +msgstr "" + +#: src/character.cpp +msgid "Something you are wearing hinders the use of both hands." +msgstr "Coś co nosisz utrudnia używanie obu rąk." + +#: src/character.cpp +#, c-format +msgid "The %s can't be wielded with only one arm." +msgstr "Ten %s nie może być uchwycony tylko jedną ręką." + +#: src/character.cpp +#, c-format +msgid "You are too weak to wield %s with only one arm." +msgstr "Jesteś zbyt slaby by utrzymać %s tylko jedną ręką." + +#: src/character.cpp +msgid " (empty)" +msgstr "" + +#: src/character.cpp src/npctalk.cpp +msgid "fists" +msgstr "pięści" + #: src/character.cpp #, c-format msgid "You are no longer able to wield your %s and drop it!" @@ -232276,6 +233179,11 @@ msgstr "Logowanie zakończone sukcesem. Naciśnij dowolny klawisz..." msgid "%s - Root Menu" msgstr "" +#: src/computer_session.cpp +#, c-format +msgid "%s (UNAVAILABLE)" +msgstr "" + #: src/computer_session.cpp msgid "Password required." msgstr "Wymagane hasło." @@ -232895,7 +233803,7 @@ msgstr "" msgid "Result: " msgstr "Rezultat:" -#: src/construction.cpp +#: src/construction.cpp src/worldfactory.cpp msgid "N/A" msgstr "N/A" @@ -233586,6 +234494,10 @@ msgstr "" "Nie masz wystarczająco ładunkĆ³w żeby ukończyć %s.\n" "Zacząć wytwarzać mimo to?" +#: src/craft_command.cpp +msgid "You don't have the required proficiencies to craft this!" +msgstr "" + #: src/craft_command.cpp msgid "" "This craft will use rotten components.\n" @@ -234072,6 +234984,11 @@ msgstr "" msgid "Other skills: %s" msgstr "Inne umiejętności: %s" +#: src/crafting_gui.cpp +#, c-format +msgid "Proficiencies Required: %s" +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "Time to complete: %s" @@ -234115,6 +235032,12 @@ msgid "" "components" msgstr "" +#: src/crafting_gui.cpp +msgid "" +"Cannot be crafted because you lack the required " +"proficiencies." +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "v (%s for more)" @@ -234500,6 +235423,10 @@ msgstr "Edytuj gracza/NPC" msgid "Damage self" msgstr "Zadaj Sobie Obrażenia" +#: src/debug_menu.cpp +msgid "Bleed self" +msgstr "" + #: src/debug_menu.cpp msgid "Set automove route" msgstr "Ustaw trasę autoruchu" @@ -234632,6 +235559,14 @@ msgstr "WyjdÅŗ do GÅ‚Ć³wnego Menu" msgid "Gameā€¦" msgstr "" +#: src/debug_menu.cpp +msgid "Change [b]attery charge" +msgstr "" + +#: src/debug_menu.cpp +msgid "Vehicleā€¦" +msgstr "" + #: src/debug_menu.cpp msgid "Teleport - short range" msgstr "Teleportacja - KrĆ³tki Zasięg" @@ -235265,12 +236200,8 @@ msgstr "Lokacja %d:%d in %d:%d, %s\n" #: src/debug_menu.cpp #, c-format -msgid "" -"Current turn: %d.\n" -"%s\n" +msgid "Current turn: %d.\n" msgstr "" -"Obecna tura: %d.\n" -"%s\n" #: src/debug_menu.cpp #, c-format @@ -235281,14 +236212,6 @@ msgstr[1] "%d stworzeń istnieje.\n" msgstr[2] "%d stworzeń istnieje.\n" msgstr[3] "%d stworzeń istnieje.\n" -#: src/debug_menu.cpp -msgid "NPCs are going to spawn." -msgstr "NPC się pojawią." - -#: src/debug_menu.cpp -msgid "NPCs are NOT going to spawn." -msgstr "NPC się NIE pojawią." - #: src/debug_menu.cpp #, c-format msgid "%s: map ( %d:%d ) pos ( %d:%d )" @@ -235344,6 +236267,22 @@ msgstr "Wybierz pojazd ktĆ³ry ma się pojawić" msgid "%1$s (%2$s)" msgstr "%1$s (%2$s)" +#: src/debug_menu.cpp +msgid "Vehicle condition" +msgstr "" + +#: src/debug_menu.cpp +msgid "Light damage" +msgstr "" + +#: src/debug_menu.cpp +msgid "Undamaged" +msgstr "" + +#: src/debug_menu.cpp +msgid "Disabled (tires or engine)" +msgstr "" + #: src/debug_menu.cpp msgid "Martial arts debug." msgstr "Dubugowanie sztuk walki." @@ -235405,6 +236344,10 @@ msgstr "Zachowaj normalną prędkość wiatru" msgid "Damage self for how much? hp: %s" msgstr "" +#: src/debug_menu.cpp +msgid "Add bleeding duration in minutes, equal to intensity:" +msgstr "" + #: src/debug_menu.cpp msgid "This binary was not compiled with tiles support." msgstr "" @@ -235540,6 +236483,14 @@ msgstr "" msgid "%s is now level %d!" msgstr "" +#: src/debug_menu.cpp src/iuse.cpp src/iuse.cpp +msgid "There's no vehicle there." +msgstr "Nie ma tam pojazdu." + +#: src/debug_menu.cpp +msgid "By how much? (in kJ, negative to discharge)" +msgstr "" + #: src/descriptions.cpp #, c-format msgid "" @@ -236265,6 +237216,22 @@ msgstr "nadzwyczajny" msgid "perfect" msgstr "doskonały" +#: src/effect.cpp +msgid "miniscule" +msgstr "" + +#: src/effect.cpp +msgid "small" +msgstr "mały" + +#: src/effect.cpp +msgid "moderate" +msgstr "" + +#: src/effect.cpp +msgid "excellent" +msgstr "" + #. ~ Default format for scores. %1$s is statistic description; %2$s is value. #: src/event_statistics.cpp #, c-format @@ -238766,6 +239733,11 @@ msgstr "Twoja pozycja na mapie zasadniczej: %d, %d, %d" msgid "Your local position: %d, %d, %d" msgstr "Twoja lokalna pozycja: %d, %d, %d" +#: src/game.cpp +#, c-format +msgid "Total NPCs within %d OMTs: %d. %d are static NPCs." +msgstr "" + #: src/game.cpp msgid "East:" msgstr "WschĆ³d:" @@ -240561,12 +241533,12 @@ msgid "Your inventory is empty." msgstr "TwĆ³j ekwipunek jest pusty." #: src/game_inventory.cpp -msgid "ENCUMBRANCE" -msgstr "SKRĘPOWANIE" +msgid "AVG ENCUMBRANCE" +msgstr "" #: src/game_inventory.cpp -msgid "COVERAGE" -msgstr "POKRYCIE" +msgid "AVG COVERAGE" +msgstr "" #: src/game_inventory.cpp msgid "WARMTH" @@ -243765,6 +244737,11 @@ msgstr "Włożyć ile %1$s do %2$s?" msgid "The %1$s contains %2$d %3$s." msgstr "Ten %1$s zawiera %2$d %3$s." +#: src/iexamine.cpp +#, c-format +msgid "You reload the %s." +msgstr "Przeładowujesz %s." + #: src/iexamine.cpp msgid "Do what with the curtains?" msgstr "Co zrobić z zasłonami?" @@ -244639,6 +245616,10 @@ msgstr "Finalizowanie" msgid "Body parts" msgstr "Części ciała" +#: src/init.cpp +msgid "Weather types" +msgstr "" + #: src/init.cpp msgid "Field types" msgstr "" @@ -245493,10 +246474,6 @@ msgstr "" msgid "max rot (turns): " msgstr "" -#: src/item.cpp -msgid "last rot: " -msgstr "ostatni rot:" - #: src/item.cpp msgid "last temp: " msgstr "ostatnia temperatura:" @@ -245774,7 +246751,7 @@ msgid "Recommended strength (burst): " msgstr "Rekomendowana siła (seria):" #: src/item.cpp -msgid " moves " +msgid " moves" msgstr "" #: src/item.cpp @@ -245814,10 +246791,6 @@ msgstr "WyrĆ³wnana szansa dobrego trafienia w odległości:" msgid "" msgstr "" -#: src/item.cpp -msgid " moves" -msgstr "" - #: src/item.cpp msgid "Time to reach aim level: " msgstr "Czas do osiągnięcia poziomu wycelowania:" @@ -245954,164 +246927,169 @@ msgstr "" "ulepszyć naprawiając ten przedmiot." #: src/item.cpp -msgid "Covers: " +msgid "Covers:" msgstr "" #: src/item.cpp -msgid "The head. " -msgstr "Głowa. " +msgid " The head." +msgstr "" #: src/item.cpp -msgid "The eyes. " -msgstr "Oczy. " +msgid " The eyes." +msgstr "" #: src/item.cpp -msgid "The mouth. " -msgstr "Usta. " +msgid " The mouth." +msgstr "" #: src/item.cpp -msgid "The torso. " -msgstr "Tors. " +msgid " The torso." +msgstr "" #: src/item.cpp -msgid "Either arm. " -msgstr "Dowolna ręka. " +msgid " Either arm." +msgstr "" #: src/item.cpp -msgid "The arms. " -msgstr "Ramiona. " +msgid " The arms." +msgstr "" #: src/item.cpp -msgid "The left arm. " -msgstr "Lewa ręka. " +msgid " The left arm." +msgstr "" #: src/item.cpp -msgid "The right arm. " -msgstr "Prawa ręka. " +msgid " The right arm." +msgstr "" #: src/item.cpp -msgid "Either hand. " -msgstr "Dowolna dłoń. " +msgid " Either hand." +msgstr "" #: src/item.cpp -msgid "The hands. " -msgstr "Dłonie. " +msgid " The hands." +msgstr "" #: src/item.cpp -msgid "The left hand. " -msgstr "Lewa dłoń. " +msgid " The left hand." +msgstr "" #: src/item.cpp -msgid "The right hand. " -msgstr "Prawa dłoń. " +msgid " The right hand." +msgstr "" #: src/item.cpp -msgid "Either leg. " -msgstr "Dowolna noga. " +msgid " Either leg." +msgstr "" #: src/item.cpp -msgid "The legs. " -msgstr "Nogi. " +msgid " The legs." +msgstr "" #: src/item.cpp -msgid "The left leg. " -msgstr "Lewa noga. " +msgid " The left leg." +msgstr "" #: src/item.cpp -msgid "The right leg. " -msgstr "Prawa noga. " +msgid " The right leg." +msgstr "" #: src/item.cpp -msgid "Either foot. " -msgstr "Dowolna stopa. " +msgid " Either foot." +msgstr "" #: src/item.cpp -msgid "The feet. " -msgstr "Stopy." +msgid " The feet." +msgstr "" #: src/item.cpp -msgid "The left foot. " -msgstr "Lewa stopa. " +msgid " The left foot." +msgstr "" #: src/item.cpp -msgid "The right foot. " -msgstr "Prawa stopa. " +msgid " The right foot." +msgstr "" #: src/item.cpp -msgid "Nothing." -msgstr "Nic." +msgid " Nothing." +msgstr "" #: src/item.cpp -msgid "Layer: " -msgstr "Warstwa:" +msgid "Layer:" +msgstr "" #: src/item.cpp -msgid "Personal aura. " +msgid " Personal aura." msgstr "" #: src/item.cpp -msgid "Close to skin. " -msgstr "Na skĆ³rze. " +msgid " Close to skin." +msgstr "" #: src/item.cpp -msgid "Strapped. " -msgstr "Przytroczony. " +msgid " Strapped." +msgstr "" #: src/item.cpp -msgid "Outer. " -msgstr "Zewnętrzna. " +msgid " Outer." +msgstr "" #: src/item.cpp -msgid "Waist. " -msgstr "Talia. " +msgid " Waist." +msgstr "" #: src/item.cpp -msgid "Outer aura. " +msgid " Outer aura." msgstr "" #: src/item.cpp -msgid "Normal. " -msgstr "Normalna. " +msgid " Normal." +msgstr "" #: src/item.cpp -msgid "Coverage: " -msgstr "Pokrycie: " +msgid "Average Coverage: " +msgstr "" #: src/item.cpp msgid "Warmth: " msgstr "Ciepłota: " #: src/item.cpp -msgid " (fits)" -msgstr " (pasuje)" +msgid " (fits)" +msgstr "" + +#: src/item.cpp +msgid " (poor fit)" +msgstr "" #: src/item.cpp -msgid " (poor fit)" -msgstr " (słabo pasuje)" +msgid " (too big)" +msgstr "" #: src/item.cpp -msgid " (too big)" +msgid " (huge!)" msgstr "" #: src/item.cpp -msgid " (huge!)" +msgid " (too small)" msgstr "" #: src/item.cpp -msgid " (too small)" +msgid " (tiny!)" msgstr "" #: src/item.cpp -msgid " (tiny!)" +msgid "Encumbrance:" msgstr "" #: src/item.cpp -msgid "Encumbrance: " -msgstr "Skrępowanie: " +#, c-format +msgid "%s:" +msgstr "" #: src/item.cpp -msgid "Encumbrance when full: " -msgstr "Skrępowanie gdy pełny:" +msgid "When Full:" +msgstr "" #: src/item.cpp msgid "Weight capacity modifier: " @@ -246538,23 +247516,23 @@ msgid "Power Capacity:" msgstr "" #: src/item.cpp -msgid "Environmental Protection: " +msgid "Environmental Protection:" msgstr "" #: src/item.cpp -msgid "Bash Protection: " +msgid "Bash Protection:" msgstr "" #: src/item.cpp -msgid "Cut Protection: " +msgid "Cut Protection:" msgstr "" #: src/item.cpp -msgid "Ballistic Protection: " +msgid "Ballistic Protection:" msgstr "" #: src/item.cpp -msgid "Stat Bonus: " +msgid "Stat Bonus:" msgstr "" #: src/item.cpp @@ -248674,10 +249652,6 @@ msgstr "Spuść skąd?" msgid "There is nothing to siphon nearby." msgstr "" -#: src/iuse.cpp -msgid "There's no vehicle there." -msgstr "Nie ma tam pojazdu." - #: src/iuse.cpp msgid "With a snarl, the combat chainsaw screams to life!" msgstr "Z kaszlnięciem, łańcuchowa piła bojowa wskakuje na wysokie obroty!" @@ -251761,6 +252735,10 @@ msgstr "Boli jak diabli!" msgid "It itches a little." msgstr "Trochę swędzi." +#: src/iuse_actor.cpp +msgid "Bleeding has not stopped completely!" +msgstr "" + #: src/iuse_actor.cpp msgid "You cannot cauterize while mounted." msgstr "" @@ -252087,12 +253065,22 @@ msgid "You stop the bleeding." msgstr "Tamujesz krwawienie." #: src/iuse_actor.cpp -msgid "The wound still bleeds." -msgstr "Rana nadal krwawi." +msgid "You reduce the bleeding, but it's not stopped yet." +msgstr "" + +#: src/iuse_actor.cpp +msgid "The bleeding is reduced, but not stopped." +msgstr "" #: src/iuse_actor.cpp -msgid "You fail to stop the bleeding." -msgstr "Nie udaje ci się zatamować krwawienia." +msgid "" +"Your dressing is too ineffective for a bleeding of this extent, and you fail" +" to stop it." +msgstr "" + +#: src/iuse_actor.cpp +msgid "The wound still bleeds." +msgstr "Rana nadal krwawi." #: src/iuse_actor.cpp msgid "The wound is cleaned." @@ -252195,12 +253183,16 @@ msgid "Actual disinfecting quality: " msgstr "Faktyczna zdolność odkażania:" #: src/iuse_actor.cpp -msgid "Chance to heal (percent): " -msgstr "Szansa na leczenie (procent):" +msgid "Effect on bleeding: " +msgstr "" + +#: src/iuse_actor.cpp +msgid "Actual effect on bleeding: " +msgstr "" #: src/iuse_actor.cpp -msgid "* Bleeding: " -msgstr "* Krwawienie: " +msgid "Chance to heal (percent): " +msgstr "Szansa na leczenie (procent):" #: src/iuse_actor.cpp msgid "* Bite: " @@ -252266,8 +253258,8 @@ msgid "It's not a gun." msgstr "To nie jest spluwa." #: src/iuse_actor.cpp -msgid "The barrel is too short." -msgstr "Lufa jest zbyt krĆ³tka." +msgid "The barrel is too small." +msgstr "" #: src/iuse_actor.cpp msgid "The barrel is already sawn-off." @@ -253793,10 +254785,6 @@ msgstr "mana" msgid "stamina" msgstr "stamina" -#: src/magic.cpp -msgid "bionic power" -msgstr "moc bioniczna" - #: src/magic.cpp msgid "error: energy_type" msgstr "" @@ -255833,7 +256821,7 @@ msgstr "Uderzasz %s z całej siły zmuszając jego %s do upadku w pobliżu!" msgid "You smash %s with all your might but %s remains in their hands!" msgstr "Uderzasz %s z całej siły ale jego %s pozostaje mu w dłoniach!" -#: src/melee.cpp src/npctalk.cpp +#: src/melee.cpp src/talker_npc.cpp #, c-format msgid "%s is hostile!" msgstr "%s jest wrogi!" @@ -256666,6 +257654,36 @@ msgctxt "memorial_female" msgid "Died of a drug overdose." msgstr "Zmarłaś z przedawkowania narkotykĆ³w." +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died from loss of red blood cells." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died from loss of red blood cells." +msgstr "" + #: src/memorial_logger.cpp msgctxt "memorial_male" msgid "Succumbed to the infection." @@ -260621,10 +261639,6 @@ msgctxt "Paralyze as an action" msgid "paralyze" msgstr "sparaliżować" -#: src/monster.cpp -msgid "cause bleed" -msgstr "spowodować krwawienie" - #: src/monster.cpp msgid "It has a head." msgstr "Ma głowę." @@ -261702,6 +262716,15 @@ msgstr "" msgid "%s (activated)" msgstr "" +#: src/newcharacter.cpp +msgid "Profession proficiencies:" +msgstr "" + +#: src/newcharacter.cpp +msgctxt "Profession has no proficiencies" +msgid "None" +msgstr "Brak" + #: src/newcharacter.cpp msgid "Pets:" msgstr "" @@ -261972,8 +262995,12 @@ msgid "" msgstr "" #: src/newcharacter.cpp -msgid "_______NO NAME ENTERED!_______" -msgstr "_____NIE WPISANO IMIENIA!_____" +msgid "--- NO NAME ENTERED ---" +msgstr "" + +#: src/newcharacter.cpp +msgid "--- RANDOM NAME ---" +msgstr "" #: src/newcharacter.cpp #, c-format @@ -262060,15 +263087,19 @@ msgid "Enter height in centimeters. Minimum 145, maximum 200" msgstr "Wpisz wzrost w centrymetrach. Minimum 145, maksimum 200" #: src/newcharacter.cpp -msgid "Enter blood type (omit Rh):" +msgid "Select blood type" msgstr "" #: src/newcharacter.cpp -msgid "Invalid blood type." +msgid "Select Rh factor" msgstr "" #: src/newcharacter.cpp -msgid "Enter Rh factor:" +msgid "negative" +msgstr "" + +#: src/newcharacter.cpp +msgid "positive" msgstr "" #: src/newcharacter.cpp @@ -262453,6 +263484,25 @@ msgstr " uspokaja się." msgid " is no longer afraid." msgstr " nie jest już wystraszony." +#: src/npc.cpp +#, c-format +msgid "I'm holing up here for safety. Long term, %s" +msgstr "" + +#: src/npc.cpp +msgid "I run the shop here." +msgstr "Prowadzę tu sklep." + +#: src/npc.cpp +#, c-format +msgid "Currently, I'm guarding this location. Overall, %s" +msgstr "" + +#: src/npc.cpp +#, c-format +msgid "Right now, I'm . In general, %s" +msgstr "" + #: src/npcmove.cpp msgid "" msgstr "" @@ -262606,6 +263656,15 @@ msgstr "" msgid "My %s is bleeding!" msgstr "Krwawi mi %s!" +#: src/npcmove.cpp +#, c-format +msgid "My %s is bleeding badly!" +msgstr "" + +#: src/npcmove.cpp +msgid "I've lost lot of blood." +msgstr "" + #: src/npcmove.cpp #, c-format msgid "%1$s reloads their %2$s." @@ -262858,11 +263917,6 @@ msgstr "Krzyczysz %s" msgid "%s yelling %s" msgstr "%s krzyczy%s" -#: src/npctalk.cpp -#, c-format -msgid "%s is fleeing from you!" -msgstr "%s ucieka przed tobą!" - #: src/npctalk.cpp #, c-format msgid "%s talked to you." @@ -262920,39 +263974,6 @@ msgstr "Przepraszam, ale chyba nie mam czego cię uczyć." msgid "Here's what I can teach youā€¦" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%d.%d miles." -msgstr "%d.%d mil." - -#: src/npctalk.cpp -#, c-format -msgid "%d foot." -msgid_plural "%d feet." -msgstr[0] "%d stopa." -msgstr[1] " %d stĆ³p." -msgstr[2] "%d stĆ³p." -msgstr[3] "%d stĆ³p." - -#: src/npctalk.cpp -#, c-format -msgid "I'm holing up here for safety. Long term, %s" -msgstr "" - -#: src/npctalk.cpp -msgid "I run the shop here." -msgstr "Prowadzę tu sklep." - -#: src/npctalk.cpp -#, c-format -msgid "Currently, I'm guarding this location. Overall, %s" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "Right now, I'm . In general, %s" -msgstr "" - #: src/npctalk.cpp msgid "&You yell, but can't hear yourself." msgstr "&Krzyczysz, ale nie słyszysz siebie." @@ -262961,74 +263982,6 @@ msgstr "&Krzyczysz, ale nie słyszysz siebie." msgid "&You yell." msgstr "&Krzyczysz" -#: src/npctalk.cpp -msgid "&You can't make anything out." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "Str %d - %d" -msgstr "SIŁ %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Dex %d - %d" -msgstr " Zrę %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Int %d - %d" -msgstr " Int %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Per %d - %d" -msgstr " Per %d - %d" - -#: src/npctalk.cpp -msgid "Dead tired" -msgstr "Śmiertelnie zmęczony" - -#: src/npctalk.cpp -msgid "Not tired" -msgstr "Nie zmęczony" - -#: src/npctalk.cpp -msgid ". Will need sleep in " -msgstr ". Będzie potrzebować snu za " - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need water in " -msgstr "" -"\n" -"Będzie potrzebować pić za " - -#: src/npctalk.cpp -msgid "" -"\n" -"Thirsty" -msgstr "" -"\n" -"Spragniony" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need food in " -msgstr "" -"\n" -"Będzie potrzebować jeść za " - -#: src/npctalk.cpp -msgid "" -"\n" -"Hungry" -msgstr "" -"\n" -"Głodny" - #: src/npctalk.cpp msgid "YES, MASTER!" msgstr "TAK, PANIE!" @@ -263042,34 +263995,6 @@ msgstr "Mam wieści." msgid "Yes, let's resume training %s" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%s: 1 hour lesson (cost %s)" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "%s: teaching spell knowledge (cost %s)" -msgstr "" - -#. ~Martial art style (cost in dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s ( cost $%d )" -msgstr "%s (koszt $%d)" - -#. ~Skill name: current level (exercise) -> next level (exercise) (cost in -#. dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%)" -msgstr "" - #: src/npctalk.cpp msgid "Okay, thanks." msgstr "Okej, dziękuję." @@ -263082,10 +264007,6 @@ msgstr "Nie zatrzymujmy się." msgid "OBEY ME!" msgstr "BĄDŹ MI POSŁUSZNY!" -#: src/npctalk.cpp src/player.cpp -msgid "fists" -msgstr "pięści" - #: src/npctalk.cpp msgid "BADAMMO" msgstr "ZŁAAMUNICJA" @@ -263157,7 +264078,7 @@ msgctxt "you say something" msgid "You: %s" msgstr "Ty: %s" -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp msgid "You can't afford it!" msgstr "" @@ -263168,7 +264089,7 @@ msgid "%1$s gives you a %2$s." msgstr "" #. ~ %1%s is the NPC name, %2$d is a number of items, %3$s are items -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp #, c-format msgid "%1$s gives you %2$d %3$s." msgstr "" @@ -263197,97 +264118,11 @@ msgstr "" msgid "%1$s doesn't have a %2$s!" msgstr "%1$s nie ma %2$s!" -#: src/npctalk.cpp -#, c-format -msgid "%1$s gives you %2$s." -msgstr "" - #: src/npctalk.cpp #, c-format msgid "You learn how to craft %s." msgstr "" -#: src/npctalk.cpp -msgid "I don't trust you enough to eat THISā€¦" -msgstr "" - -#: src/npctalk.cpp -msgid "It doesn't look like a good idea to consume thisā€¦" -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, that hit the spot." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "I need a %s to consume that!" -msgstr "Potrzebuję %s żeby to zjeść!" - -#: src/npctalk.cpp -msgid "Thanks, I feel better already." -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I used it." -msgstr "" - -#: src/npctalk.cpp -msgid "Offer what?" -msgstr "Co oferujesz?" - -#: src/npctalk.cpp -msgid "You have no items to offer." -msgstr "Nie masz przedmiotĆ³w do zaoferowania." - -#: src/npctalk.cpp -msgid "Changed your mind?" -msgstr "Zmieniłeś zdanie?" - -#: src/npctalk.cpp -msgid "How?" -msgstr "Jak?" - -#: src/npctalk.cpp -msgid "Are you insane!?" -msgstr "Czyś ty oszalał?" - -#: src/npctalk.cpp -msgid "Thanks, I'll wield that now." -msgstr "Dzięki, teraz ja to potrzymam." - -#: src/npctalk.cpp -msgid " Should I take something off?" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "" -"My current weapon is better than this.\n" -"(new weapon value: %.1f vs %.1f)." -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I'll carry that now." -msgstr "" - -#: src/npctalk.cpp -msgid "I have no space to store it." -msgstr "Nie mam na to miejsca w ekwipunku." - -#: src/npctalk.cpp -#, c-format -msgid "I can only store %s %s more." -msgstr "Mogę jeszcze zmieścić tylko %s %s." - -#: src/npctalk.cpp -msgid "ā€¦or to store anything else for that matter." -msgstr "" - -#: src/npctalk.cpp -msgid "It is too heavy for me to carry." -msgstr "To zbyt ciężkie bym to uniĆ³sł." - #: src/npctalk_funcs.cpp msgid "Reward" msgstr "Nagroda" @@ -265156,14 +265991,15 @@ msgstr "" "przedmiotĆ³w." #: src/options.cpp -msgid "NPC spawn rate scaling factor" -msgstr "Skalowanie generatora NPC-tĆ³w" +msgid "Random NPC spawn time" +msgstr "" #: src/options.cpp -msgid "A scaling factor that determines density of dynamic NPC spawns." +msgid "" +"Baseline average number of days between random NPC spawns. Average duration" +" goes up with the number of NPCs already spawned. Set to 0 days to disable " +"random NPCs." msgstr "" -"Czynnik wg ktĆ³rego następuje skalowanie tempa (gęstości) pojawiania się NPC-" -"tĆ³w." #: src/options.cpp msgid "Monster evolution scaling factor" @@ -265302,39 +266138,6 @@ msgstr "" "Zaznaczone: generuje zombie w schronach. Powoduje że początek gry jest o " "wiele trudniejszy." -#: src/options.cpp -msgid "Static NPCs" -msgstr "Statyczni NPC-e" - -#: src/options.cpp -msgid "" -"If true, static NPCs will spawn at pre-defined locations. Requires world " -"reset." -msgstr "" - -#: src/options.cpp -msgid "Starting NPCs spawn" -msgstr "Generacja startowych NPC" - -#: src/options.cpp -msgid "" -"Determines whether starting NPCs should spawn, and if they do, how exactly." -msgstr "" -"Określa czy startowi NPC powinni być generowani, a jak tak to w jaki " -"dokładnie sposĆ³b." - -#: src/options.cpp -msgid "Scenario-based" -msgstr "Bazowane na scenariuszu" - -#: src/options.cpp -msgid "Random NPCs" -msgstr "Przypadkowi NPC-e" - -#: src/options.cpp -msgid "If true, the game will randomly spawn NPCs during gameplay." -msgstr "Zaznaczone: gra będzie losowo generować NCP-Ć³w w czasie gry." - #: src/options.cpp msgid "Mutations by radiation" msgstr "Mutacje popromienne" @@ -267073,6 +267876,38 @@ msgstr "PrĆ³bujesz ugasić ogień na sobie!" msgid " attempts to put out the fire on them!" msgstr " prĆ³buje ugasić ogień na sobie!" +#: src/player.cpp +msgid "" +"Your broken limb significantly hampers your efforts to puting pressure on " +"the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s broken limb significantly hampers efforts of putting pressure on" +" the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"Your hands are too encumbred to effectivly put pressure on the bleeding " +"wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s hands are too encumbred to effectivly put pressure on the " +"bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "You attempt to put pressure on the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid " attempts to put pressure on the bleeding wound!" +msgstr "" + #: src/player.cpp #, c-format msgid "Your ground sonar detected a %1$s to the %2$s!" @@ -267346,33 +268181,6 @@ msgstr "Nie ma nic do przeładowania!" msgid "You don't have any %s to reload your %s!" msgstr "Nie masz więcej %s żeby przeładować %s!" -#: src/player.cpp -msgid "Can't wield spilt liquids." -msgstr "Nie możesz trzymać rozlanych płynĆ³w." - -#: src/player.cpp -msgid "You need at least one arm to even consider wielding something." -msgstr "Musisz mieć przynajmniej jedno ramię żeby cokolwiek trzymać." - -#: src/player.cpp -#, c-format -msgid "The %s is preventing you from wielding the %s." -msgstr "" - -#: src/player.cpp -msgid "Something you are wearing hinders the use of both hands." -msgstr "Coś co nosisz utrudnia używanie obu rąk." - -#: src/player.cpp -#, c-format -msgid "The %s can't be wielded with only one arm." -msgstr "Ten %s nie może być uchwycony tylko jedną ręką." - -#: src/player.cpp -#, c-format -msgid "You are too weak to wield %s with only one arm." -msgstr "Jesteś zbyt slaby by utrzymać %s tylko jedną ręką." - #: src/player.cpp msgid "Keep hands free (off)" msgstr "Trzymaj ręce wolne (NIE)" @@ -267555,15 +268363,6 @@ msgstr "TwĆ³j %s nie jest naładowany." msgid "Your %s isn't loaded." msgstr "TwĆ³j %s nie jest nabity." -#: src/player.cpp -#, c-format -msgid "You recover %i unused plutonium." -msgstr "Odzyskujesz %i niezużytego plutonu." - -#: src/player.cpp -msgid "You can't remove partially depleted plutonium!" -msgstr "Nie możesz usunąć częściowo zużytego plutonu!" - #. ~ %1$s - gunmod, %2$s - gun. #: src/player.cpp #, c-format @@ -267701,25 +268500,6 @@ msgstr "Twojemu induktorowi nasennemu kończy się moc!" msgid "Your soporific inducer starts back up." msgstr "" -#: src/player.cpp -#, c-format -msgid "Your skill in %s has increased to %d!" -msgstr "Twoja umiejetność %s wzrosła do %d!" - -#: src/player.cpp -#, c-format -msgid "You feel that %s tasks of this level are becoming trivial." -msgstr "Czujesz że zadania w %s tego poziomu stają się trywialne." - -#: src/player.cpp -#, c-format -msgid "This task is too simple to train your %s beyond %d." -msgstr "Ta czynności jest zbyt prosta by trenować %s powyżej %d." - -#: src/player.cpp -msgid " (empty)" -msgstr "" - #: src/player.cpp msgid "Wield what?" msgstr "Trzymać co?" @@ -267775,6 +268555,10 @@ msgstr "EFEKTY" msgid "SPEED" msgstr "SZYBKOŚĆ" +#: src/player_display.cpp +msgid "PROFICIENCIES" +msgstr "" + #: src/player_display.cpp #, c-format msgid "Swimming movement point cost: %+d\n" @@ -268631,6 +269415,149 @@ msgstr "" "Rozpływasz się w pięknym paroksyzmie energii. Å»ycie opuszcza twoją mgławicę " "i już cię nie ma." +#: src/player_hardcoded_effects.cpp +msgid "You bleed to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " bleeds to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your heart can't keep up the pace and fails!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks pale and you feel anxious and thirsty. Blood loss?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"Your pale skin is sweating, your heart beats fast and you feel restless. " +"Maybe you lost too much blood?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You're unsettlingly white, but your fingetips are bluish. You are agitated " +"and your heart is racing. Your blood loss must be serious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You are pale as a ghost, dripping wet from the sweat, and sluggish despite " +"your heart racing like a train. You are on a brink of colapse from effects " +"of a bood loss." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and lightheaded." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel tired and you breathe heavily." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are anxcious and cannot collect your thoughts." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are sweating profusely, but you feel cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You huff and puff. Your breath is rapid and shallow." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You drop to the ground, fighting to keep yourself conscious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your mind slips away." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You cannot breathe and your body gives out!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " gasps for air and dies!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your hands feel unusually cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your feet feel unusualy cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks very pale." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel weak. Where has your strength gone?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel feeble. A gust of wind could make you stumble." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "There is an overwhelming aura of tiredness inside of you." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Rest is what you want. Rest is what you need." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and can't coordinate movement of your feet." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your muscles are quivering." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You crave for ice. Dirt under your feet looks tasty too." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your whole mouth is sore, and your tongue is swollen." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel lightheaded. And a migrane follows." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your legs are restless. Urge to move them is so strong." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel like you'd sleep on a rock." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You gasp for air!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Can't breathe. Must rest." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You can't take it any more. Rest first, everything else later." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You must sit down for a moment. Just a moment." +msgstr "" + #. ~ %s is bodypart name. #: src/player_hardcoded_effects.cpp #, c-format @@ -269238,6 +270165,11 @@ msgstr "%s OpĆ³Åŗnienie: %i" msgid "Turrets in range: %d/%d" msgstr "" +#: src/recipe.cpp +#, c-format +msgid "Proficiencies Used: %s" +msgstr "" + #: src/recipe.cpp msgid "none" msgstr "żaden" @@ -270039,6 +270971,14 @@ msgstr " przewraca się!" msgid "You fall over!" msgstr "Przewracasz się!" +#: src/suffer.cpp +msgid "Your tourniquet hurts you." +msgstr "" + +#: src/suffer.cpp +msgid " is hurting from the tourniquet." +msgstr "" + #: src/suffer.cpp #, c-format msgid "Your radiation badge changes from %1$s to %2$s!" @@ -270058,6 +270998,211 @@ msgstr "" msgid "You feel the water burning your skin." msgstr "" +#: src/talker_avatar.cpp +#, c-format +msgid "%s can't sell you any %s" +msgstr "" + +#: src/talker_avatar.cpp +#, c-format +msgid "%1$s gives you %2$s." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%d.%d miles." +msgstr "%d.%d mil." + +#: src/talker_npc.cpp +#, c-format +msgid "%d foot." +msgid_plural "%d feet." +msgstr[0] "%d stopa." +msgstr[1] " %d stĆ³p." +msgstr[2] "%d stĆ³p." +msgstr[3] "%d stĆ³p." + +#: src/talker_npc.cpp +#, c-format +msgid "%s is fleeing from you!" +msgstr "%s ucieka przed tobą!" + +#. ~Skill name: current level (exercise) -> next level (exercise) (cost in +#. dollars) +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s ( cost $%d )" +msgstr "%s (koszt $%d)" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: 1 hour lesson (cost %s)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: teaching spell knowledge (cost %s)" +msgstr "" + +#: src/talker_npc.cpp +msgid "I don't trust you enough to eat THISā€¦" +msgstr "" + +#: src/talker_npc.cpp +msgid "It doesn't look like a good idea to consume thisā€¦" +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, that hit the spot." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "I need a %s to consume that!" +msgstr "Potrzebuję %s żeby to zjeść!" + +#: src/talker_npc.cpp +msgid "Thanks, I feel better already." +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I used it." +msgstr "" + +#: src/talker_npc.cpp +msgid "Offer what?" +msgstr "Co oferujesz?" + +#: src/talker_npc.cpp +msgid "You have no items to offer." +msgstr "Nie masz przedmiotĆ³w do zaoferowania." + +#: src/talker_npc.cpp +msgid "Changed your mind?" +msgstr "Zmieniłeś zdanie?" + +#: src/talker_npc.cpp +msgid "How?" +msgstr "Jak?" + +#: src/talker_npc.cpp +msgid "Are you insane!?" +msgstr "Czyś ty oszalał?" + +#: src/talker_npc.cpp +msgid "Thanks, I'll wield that now." +msgstr "Dzięki, teraz ja to potrzymam." + +#: src/talker_npc.cpp +msgid " Should I take something off?" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "" +"My current weapon is better than this.\n" +"(new weapon value: %.1f vs %.1f)." +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I'll carry that now." +msgstr "" + +#: src/talker_npc.cpp +msgid "I have no space to store it." +msgstr "Nie mam na to miejsca w ekwipunku." + +#: src/talker_npc.cpp +#, c-format +msgid "I can only store %s %s more." +msgstr "Mogę jeszcze zmieścić tylko %s %s." + +#: src/talker_npc.cpp +msgid "ā€¦or to store anything else for that matter." +msgstr "" + +#: src/talker_npc.cpp +msgid "It is too heavy for me to carry." +msgstr "To zbyt ciężkie bym to uniĆ³sł." + +#: src/talker_npc.cpp +msgid "&You can't make anything out." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "Str %d - %d" +msgstr "SIŁ %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Dex %d - %d" +msgstr " Zrę %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Int %d - %d" +msgstr " Int %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Per %d - %d" +msgstr " Per %d - %d" + +#: src/talker_npc.cpp +msgid "Dead tired" +msgstr "Śmiertelnie zmęczony" + +#: src/talker_npc.cpp +msgid "Not tired" +msgstr "Nie zmęczony" + +#: src/talker_npc.cpp +msgid ". Will need sleep in " +msgstr ". Będzie potrzebować snu za " + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need water in " +msgstr "" +"\n" +"Będzie potrzebować pić za " + +#: src/talker_npc.cpp +msgid "" +"\n" +"Thirsty" +msgstr "" +"\n" +"Spragniony" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need food in " +msgstr "" +"\n" +"Będzie potrzebować jeść za " + +#: src/talker_npc.cpp +msgid "" +"\n" +"Hungry" +msgstr "" +"\n" +"Głodny" + #: src/teleport.cpp msgid "You feel a strange, inwards force." msgstr "" @@ -271889,6 +273034,34 @@ msgstr ", %3.1f%% / godz., %s do %s" msgid "pile-up" msgstr "nagromadzony" +#: src/vehicle_move.cpp +msgid "Smart controller does not support flying vehicles." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller detects only a single controllable engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller is designed to control more than one engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller does not support more than five engines." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller is shutting down." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller failed to start an engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller optimizes engine state." +msgstr "" + #: src/vehicle_move.cpp #, c-format msgid "The %s is too leaky!" @@ -272263,6 +273436,11 @@ msgctxt "electronics menu option" msgid "water purifier" msgstr "oczyszczacz do wody" +#: src/vehicle_use.cpp +msgctxt "electronics menu option" +msgid "smart controller" +msgstr "" + #: src/vehicle_use.cpp msgid "Turn off camera system" msgstr "Wyłącz system kamer" @@ -272899,50 +274077,18 @@ msgstr "Niewystarczająca moc do oczyszczenia zawartości %1$s %2$s" msgid "You purify the contents of the %1$s's %2$s" msgstr "Oczyszczasz zawartość %1$s %2$s" -#: src/weather.cpp -msgid "You hear a distant rumble of thunder." -msgstr "Słyszysz odległy dÅŗwięk gromu." - -#: src/weather.cpp -msgid "You hear a rumble of thunder from above." -msgstr "Grzmi nad tobą." - -#: src/weather.cpp -msgid "A flash of lightning illuminates your surroundings!" -msgstr "Błyskawica rozświetla okolicę!" - #: src/weather.cpp #, c-format -msgid "Your %s protects you from the acidic drizzle." -msgstr "TwĆ³j %s chroni cię przed kwaśną mżawką." - -#: src/weather.cpp -msgid "Your clothing protects you from the acidic drizzle." -msgstr "Twoje ubranie chroni cię przed kwaśną mżawką." - -#: src/weather.cpp -msgid "Your power armor protects you from the acidic drizzle." -msgstr "Twoja zbroja wspomagana chroni cię przed kwaśną mżawką." - -#: src/weather.cpp -msgid "The acid rain stings, but is mostly harmless for nowā€¦" -msgstr "Kwaśny deszcz szczypie, ale na razie jest niegroÅŗny..." - -#: src/weather.cpp -msgid "Your umbrella protects you from the acid rain." -msgstr "Parasol chroni cię przed kwaśnym deszczem." - -#: src/weather.cpp -msgid "Your clothing protects you from the acid rain." -msgstr "UbiĆ³r chroni cię przed kwaśnym deszczem." +msgid "Your %s protects you from the weather." +msgstr "" #: src/weather.cpp -msgid "Your power armor protects you from the acid rain." -msgstr "Pancerz wspomagany chroni cię przed kwaśnym deszczem." +msgid "Your clothing protects you from the weather." +msgstr "" #: src/weather.cpp -msgid "The acid rain burns!" -msgstr "Kwaśny deszcz parzy!" +msgid "Your power armor protects you from the weather." +msgstr "" #: src/weather.cpp msgid "Monday" @@ -273117,54 +274263,6 @@ msgstr "Huragan" msgid "The weather changed to %s!" msgstr "Pogoda zmienia się w %s!" -#: src/weather_data.cpp -msgid "Clear" -msgstr "Przejrzyście" - -#: src/weather_data.cpp -msgid "Sunny" -msgstr "Słonecznie" - -#: src/weather_data.cpp -msgid "Cloudy" -msgstr "Zachmurzenie" - -#: src/weather_data.cpp -msgid "Light Drizzle" -msgstr "Lekka Mżawka" - -#: src/weather_data.cpp -msgid "Drizzle" -msgstr "Mżawka" - -#: src/weather_data.cpp -msgid "Rain" -msgstr "Deszcz" - -#: src/weather_data.cpp -msgid "Thunder Storm" -msgstr "Burza" - -#: src/weather_data.cpp -msgid "Acidic Drizzle" -msgstr "Kwaśna Mżawka" - -#: src/weather_data.cpp -msgid "Acid Rain" -msgstr "Kwaśny Deszcz" - -#: src/weather_data.cpp -msgid "Flurries" -msgstr "Zamieć Śnieżna" - -#: src/weather_data.cpp -msgid "Snowing" -msgstr "Śnieg" - -#: src/weather_data.cpp -msgid "Snowstorm" -msgstr "Burza Śnieżna" - #: src/wish.cpp msgid "Nonvalid" msgstr "Niewłaściwe" @@ -273356,6 +274454,19 @@ msgstr "Wybierz świat, by wejść do gry" msgid "last world info" msgstr "info ostatniego świata" +#: src/worldfactory.cpp +msgid "MISSING MODS" +msgstr "" + +#: src/worldfactory.cpp +msgid "OBSOLETE MODS" +msgstr "" + +#: src/worldfactory.cpp +#, c-format +msgid " [%s]" +msgstr "" + #: src/worldfactory.cpp msgid " ACTIVE WORLD MODS " msgstr "AKTYWNE MODY ŚWIATA" diff --git a/lang/po/ru.po b/lang/po/ru.po index 5e7d060b8b4d7..82d691af85301 100644 --- a/lang/po/ru.po +++ b/lang/po/ru.po @@ -59,18 +59,18 @@ # Victor_U , 2020 # WX , 2020 # Arex , 2020 -# Alexey Mostovoy , 2020 # ŠŠ½Ń‚Š¾Š½ Š‘ŃƒŃ€Š¼ŠøстрŠ¾Š² <22.valiant@gmail.com>, 2020 # korick3 korick3 , 2020 # Vlasov Vitaly , 2020 # leemuar - , 2020 +# Alexey Mostovoy , 2020 # CountAlex, 2020 # msgid "" msgstr "" "Project-Id-Version: cataclysm-dda 0.E\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-07-08 10:07+0800\n" +"POT-Creation-Date: 2020-07-16 21:36+0800\n" "PO-Revision-Date: 2018-04-26 14:47+0000\n" "Last-Translator: CountAlex, 2020\n" "Language-Team: Russian (https://www.transifex.com/cataclysm-dda-translators/teams/2217/ru/)\n" @@ -9423,6 +9423,68 @@ msgstr "" "ŠŸŠ¾Š¼Š¾Š³Š°ŠµŃ‚ Š·Š°Ń„ŠøŠŗсŠøрŠ¾Š²Š°Ń‚ŃŒ сŠ»Š¾Š¼Š°Š½Š½Ń‹Šµ ŠŗŠ¾ŃŃ‚Šø. Š”Š“ŠµŠ»Š°Š½Š¾ тŠ°Šŗ, чтŠ¾Š±Ń‹ ŠæŠ¾Š“хŠ¾Š“Šøть Š“Š°Š¶Šµ " "сŠ°Š¼Ń‹Š¼ ŠŗруŠæŠ½Ń‹Š¼ Š²Ń‹Š¶ŠøŠ²Š°Š»ŃŒŃ‰ŠøŠŗŠ°Š¼." +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm)" +msgid_plural "tourniquets (arm)" +msgstr[0] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Š¹ турŠ½ŠøŠŗŠµŃ‚ (руŠŗŠ°)" +msgstr[1] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Ń… турŠ½ŠøŠŗŠµŃ‚Š° (руŠŗŠ°)" +msgstr[2] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Ń… турŠ½ŠøŠŗŠµŃ‚Š¾Š² (руŠŗŠ°)" +msgstr[3] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Šµ турŠ½ŠøŠŗŠµŃ‚Ń‹ (руŠŗŠ°)" + +#. ~ Use action menu_text for {'str': 'tourniquet (arm)', 'str_pl': +#. 'tourniquets (arm)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (arm XL)', 'str_pl': +#. 'tourniquets (arm XL)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (leg)', 'str_pl': +#. 'tourniquets (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "Adjust" +msgstr "ŠŸŠ¾Š“тяŠ½ŃƒŃ‚ŃŒ" + +#. ~ Use action msg for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'}. +#. ~ Use action msg for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'}. +#. ~ Use action msg for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "You adjust the tourniquet." +msgstr "Š’Ń‹ ŠæŠ¾Š“тяŠ³ŠøŠ²Š°ŠµŃ‚Šµ турŠ½ŠøŠŗŠµŃ‚." + +#. ~ Description for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'} +#. ~ Description for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'} +#. ~ Description for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'} +#: lang/json/ARMOR_from_json.py +msgid "" +"First aid device used to apply pressure to a limb or extremity in order to " +"limit blood flow. Should be employed only to manage heavy bleedings, " +"because prolonged use will harm the limb. It can be adjusted in size to fit" +" different limbs." +msgstr "" +"Š£ŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾ ŠæŠµŃ€Š²Š¾Š¹ ŠæŠ¾Š¼Š¾Ń‰Šø, ŠæрŠµŠ“Š½Š°Š·Š½Š°Ń‡ŠµŠ½Š½Š¾Šµ Š“Š»Ń сŠ¶Š°Ń‚Šøя ŠŗŠ¾Š½ŠµŃ‡Š½Š¾ŃŃ‚Šø с цŠµŠ»ŃŒŃŽ " +"сŠ¾ŠŗрŠ°Ń‰ŠµŠ½Šøя ŠŗрŠ¾Š²Š¾Ń‚Š¾ŠŗŠ°. Š”Š¾Š»Š¶Š½Š¾ ŠæрŠøŠ¼ŠµŠ½ŃŃ‚ŃŒŃŃ тŠ¾Š»ŃŒŠŗŠ¾ ŠæрŠø сŠ°Š¼Ń‹Ń… тяŠ¶ŠµŠ»Ń‹Ń… " +"ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½Šøях, тŠ°Šŗ ŠŗŠ°Šŗ Š“Š»ŠøтŠµŠ»ŃŒŠ½Š¾Šµ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½ŠøŠµ Š¼Š¾Š¶ŠµŃ‚ Š½Š°Š½ŠµŃŃ‚Šø Š²Ń€ŠµŠ“ " +"ŠŗŠ¾Š½ŠµŃ‡Š½Š¾ŃŃ‚Šø. Š•Š³Š¾ Š¼Š¾Š¶Š½Š¾ ŠæŠ¾Š“Š¾Š³Š½Š°Ń‚ŃŒ Š² рŠ°Š·Š¼ŠµŃ€Š°Ń… Š“Š»Ń рŠ°Š·Š½Ń‹Ń… ŠŗŠ¾Š½ŠµŃ‡Š½Š¾ŃŃ‚ŠµŠ¹." + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm XL)" +msgid_plural "tourniquets (arm XL)" +msgstr[0] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Š¹ турŠ½ŠøŠŗŠµŃ‚ (руŠŗŠ° XL)" +msgstr[1] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Ń… турŠ½ŠøŠŗŠµŃ‚Š° (руŠŗŠ° XL)" +msgstr[2] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Ń… турŠ½ŠøŠŗŠµŃ‚Š¾Š² (руŠŗŠ° XL)" +msgstr[3] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Šµ турŠ½ŠøŠŗŠµŃ‚Ń‹ (руŠŗŠ° XL)" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (leg)" +msgid_plural "tourniquets (leg)" +msgstr[0] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Š¹ турŠ½ŠøŠŗŠµŃ‚ (Š½Š¾Š³Š°)" +msgstr[1] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Ń… турŠ½ŠøŠŗŠµŃ‚Š° (Š½Š¾Š³Š°)" +msgstr[2] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Ń… турŠ½ŠøŠŗŠµŃ‚Š¾Š² (Š½Š¾Š³Š°)" +msgstr[3] "Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Šµ турŠ½ŠøŠŗŠµŃ‚Ń‹ (Š½Š¾Š³Š°)" + #: lang/json/ARMOR_from_json.py msgid "blindfold" msgid_plural "blindfolds" @@ -49934,6 +49996,25 @@ msgstr "" "ŠæрŠ¾ŠæŠøсыŠ²Š°ŠµŠ¼Ń‹Š¹ ŠæрŠø Š»ŠµŃ‡ŠµŠ½ŠøŠø сŠøŠ½Š“рŠ¾Š¼Š° Š“ŠµŃ„ŠøцŠøтŠ° Š²Š½ŠøŠ¼Š°Š½Šøя Šø Š³ŠøŠæŠµŃ€Š°ŠŗтŠøŠ²Š½Š¾ŃŃ‚Šø. " "ŠŸŠ¾Š½ŠøŠ¶Š°ŠµŃ‚ Š°ŠæŠæŠµŃ‚Šøт Šø Š¼Š¾Š¶ŠµŃ‚ Š²Ń‹Š·Š²Š°Ń‚ŃŒ Š·Š°Š²ŠøсŠøŠ¼Š¾ŃŃ‚ŃŒ." +#: lang/json/COMESTIBLE_from_json.py +msgid "adhesive bandage" +msgid_plural "adhesive bandages" +msgstr[0] "Š»ŠµŠ¹ŠŗŠ¾ŠæŠ»Š°ŃŃ‚Ń‹Ń€ŃŒ" +msgstr[1] "Š»ŠµŠ¹ŠŗŠ¾ŠæŠ»Š°ŃŃ‚Ń‹Ń€Ń" +msgstr[2] "Š»ŠµŠ¹ŠŗŠ¾ŠæŠ»Š°ŃŃ‚Ń‹Ń€ŠµŠ¹" +msgstr[3] "Š»ŠµŠ¹ŠŗŠ¾ŠæŠ»Š°ŃŃ‚Ń‹Ń€Šø" + +#. ~ Description for {'str': 'adhesive bandage'} +#: lang/json/COMESTIBLE_from_json.py +msgid "" +"A set of small medical dressings, each made of a piece of sterile cloth and " +"a sticky tape, used for small injuries not serious enough to require a full-" +"size bandage." +msgstr "" +"ŠŠµŠ±Š¾Š»ŃŒŃˆŠ¾Š¹ Š½Š°Š±Š¾Ń€ ŠæŠµŃ€ŠµŠ²ŃŠ·Š¾Ń‡Š½Ń‹Ń… Š¼Š°Ń‚ŠµŃ€ŠøŠ°Š»Š¾Š², ŠæрŠµŠ“стŠ°Š²Š»ŃŃŽŃ‰Šøх ŠøŠ· сŠµŠ±Ń стŠµŃ€ŠøŠ»ŃŒŠ½ŃƒŃŽ " +"тŠŗŠ°Š½ŃŒ Š½Š° Š»ŠøŠæŠŗŠ¾Š¹ Š»ŠµŠ½Ń‚Šµ. Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ся Š“Š»Ń Š¼ŠµŠ»ŠŗŠøх рŠ°Š½, Š½Šµ трŠµŠ±ŃƒŃŽŃ‰Šøх ŠæŠ¾Š»Š½Š¾Ń†ŠµŠ½Š½Š¾Š¹" +" ŠæŠµŃ€ŠµŠ²ŃŠ·ŠŗŠø." + #: lang/json/COMESTIBLE_from_json.py msgid "syringe of adrenaline" msgid_plural "syringes of adrenaline" @@ -50040,9 +50121,12 @@ msgstr[3] "Š±ŠøŠ½Ń‚Ń‹" #. ~ Description for {'str': 'bandage'} #: lang/json/COMESTIBLE_from_json.py -msgid "Simple cloth bandages. Used for healing small amounts of damage." +msgid "" +"Simple cloth bandages. Used for stopping bloodloss and protecting wounds " +"from external factors." msgstr "" -"ŠŸŃ€Š¾ŃŃ‚Ń‹Šµ тŠŗŠ°Š½ŠµŠ²Ń‹Šµ ŠæŠ¾Š²ŃŠ·ŠŗŠø. Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŃŽŃ‚ся Š“Š»Ń Š»ŠµŃ‡ŠµŠ½Šøя Š½ŠµŠ±Š¾Š»ŃŒŃˆŠøх ŠæŠ¾Š²Ń€ŠµŠ¶Š“ŠµŠ½ŠøŠ¹." +"ŠŸŃ€Š¾ŃŃ‚Ń‹Šµ тŠŗŠ°Š½ŠµŠ²Ń‹Šµ ŠæŠ¾Š²ŃŠ·ŠŗŠø. Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŃŽŃ‚ся Š“Š»Ń Š¾ŃŃ‚Š°Š½Š¾Š²ŠŗŠø ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠ¹ Šø Š·Š°Ń‰Šøты " +"рŠ°Š½Ń‹ Š¾Ń‚ Š²Š½ŠµŃˆŠ½Šøх фŠ°ŠŗтŠ¾Ń€Š¾Š²." #: lang/json/COMESTIBLE_from_json.py msgid "makeshift bandage" @@ -62591,10 +62675,11 @@ msgstr[3] "сŠ²ŃŠ·ŠŗŠø Š“Š¾ŃŠ¾Šŗ" #. planks'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten construction planks securely lashed together with a rope. Disassemble " -"to unpack." +"Ten construction planks securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" -"Š”ŠµŃŃŃ‚Š¾Šŗ стрŠ¾ŠøтŠµŠ»ŃŒŠ½Ń‹Ń… Š“Š¾ŃŠ¾Šŗ, сŠ²ŃŠ·Š°Š½Š½Ń‹Ń… Š²ŠµŃ€Ń‘Š²ŠŗŠ¾Š¹. Š Š°Š·Š±ŠµŃ€ŠøтŠµ Š“Š»Ń рŠ°ŃŠæŠ°ŠŗŠ¾Š²ŠŗŠø." +"Š”ŠµŃŃŃ‚Š¾Šŗ стрŠ¾ŠøтŠµŠ»ŃŒŠ½Ń‹Ń… Š“Š¾ŃŠ¾Šŗ, сŠ²ŃŠ·Š°Š½Š½Ń‹Ń… Š²Š¼ŠµŃŃ‚Šµ Š“Š»Ń Š¾Š±Š»ŠµŠ³Ń‡ŠµŠ½Šøя ŠæŠµŃ€ŠµŠ½Š¾ŃŠŗŠø. " +"Š Š°Š·Š±ŠµŃ€ŠøтŠµ Š“Š»Ń рŠ°ŃŠæŠ°ŠŗŠ¾Š²ŠŗŠø." #: lang/json/GENERIC_from_json.py msgid "bundle of stout branches" @@ -62608,9 +62693,29 @@ msgstr[3] "сŠ²ŃŠ·ŠŗŠø ŠæрŠ¾Ń‡Š½Ń‹Ń… Š²ŠµŃ‚Š¾Šŗ" #. stout branches'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten stout branches securely lashed together with a rope. Disassemble to " -"untie them." -msgstr "Š”ŠµŃŃŃ‚Š¾Šŗ ŠæрŠ¾Ń‡Š½Ń‹Ń… Š²ŠµŃ‚Š¾Šŗ, сŠ²ŃŠ·Š°Š½Š½Ń‹Ń… Š²ŠµŃ€Ń‘Š²ŠŗŠ¾Š¹. Š Š°Š·Š±ŠµŃ€ŠøтŠµ Š“Š»Ń рŠ°ŃŠæŠ°ŠŗŠ¾Š²ŠŗŠø." +"Ten stout branches securely tied together for easier transport. Disassemble" +" to untie them." +msgstr "" +"Š”ŠµŃŃŃ‚Š¾Šŗ ŠæрŠ¾Ń‡Š½Ń‹Ń… Š²ŠµŃ‚Š¾Šŗ, сŠ²ŃŠ·Š°Š½Š½Ń‹Ń… Š²Š¼ŠµŃŃ‚Šµ Š“Š»Ń Š¾Š±Š»ŠµŠ³Ń‡ŠµŠ½Šøя ŠæŠµŃ€ŠµŠ½Š¾ŃŠŗŠø. Š Š°Š·Š±ŠµŃ€ŠøтŠµ " +"Š“Š»Ń рŠ°ŃŠæŠ°ŠŗŠ¾Š²ŠŗŠø." + +#: lang/json/GENERIC_from_json.py +msgid "bundle of long stout branches" +msgid_plural "bundles of long stout branches" +msgstr[0] "сŠ²ŃŠ·ŠŗŠ° Š“Š»ŠøŠ½Š½Ń‹Ń… ŠæрŠ¾Ń‡Š½Ń‹Ń… Š²ŠµŃ‚Š¾Šŗ" +msgstr[1] "сŠ²ŃŠ·ŠŗŠø Š“Š»ŠøŠ½Š½Ń‹Ń… ŠæрŠ¾Ń‡Š½Ń‹Ń… Š²ŠµŃ‚Š¾Šŗ" +msgstr[2] "сŠ²ŃŠ·Š¾Šŗ Š“Š»ŠøŠ½Š½Ń‹Ń… ŠæрŠ¾Ń‡Š½Ń‹Ń… Š²ŠµŃ‚Š¾Šŗ" +msgstr[3] "сŠ²ŃŠ·ŠŗŠø Š“Š»ŠøŠ½Š½Ń‹Ń… ŠæрŠ¾Ń‡Š½Ń‹Ń… Š²ŠµŃ‚Š¾Šŗ" + +#. ~ Description for {'str': 'bundle of long stout branches', 'str_pl': +#. 'bundles of long stout branches'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Five long stout branches securely tied together for easier transport. " +"Disassemble to untie them." +msgstr "" +"ŠŸŃŃ‚ŃŒ Š“Š»ŠøŠ½Š½Ń‹Ń… ŠæрŠ¾Ń‡Š½Ń‹Ń… Š²ŠµŃ‚Š¾Šŗ, сŠ²ŃŠ·Š°Š½Š½Ń‹Ń… Š²Š¼ŠµŃŃ‚Šµ Š“Š»Ń Š¾Š±Š»ŠµŠ³Ń‡ŠµŠ½Šøя ŠæŠµŃ€ŠµŠ½Š¾ŃŠŗŠø. " +"Š Š°Š·Š±ŠµŃ€ŠøтŠµ Š“Š»Ń рŠ°ŃŠæŠ°ŠŗŠ¾Š²ŠŗŠø." #: lang/json/GENERIC_from_json.py msgid "t-substrate sample" @@ -65182,6 +65287,14 @@ msgstr "" "Š”Š»Š¾Š¼Š°Š½Š½Ń‹Š¹ ŠœŠ¾Š±ŠøŠ»ŃŒŠ½Ń‹Š¹ Š Š¾Š±Š¾Ń‚Š¾Ń‚ŠµŃ…Š½ŠøчŠµŃŠŗŠøŠ¹ ŠšŠ¾Š¼ŠæŠ»ŠµŠŗс TALON. Š•Š³Š¾ ŠŗŠ¾Ń€Šæус ŠæрŠ¾Š±Šøт, Š° " "Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚ŃŒ Š²Ń‹Ń‚ŠµŠŗŠ»Š°. Š•Š³Š¾ Š¼Š¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š½Š° Š·Š°ŠæчŠ°ŃŃ‚Šø." +#: lang/json/GENERIC_from_json.py +msgid "broken laser turret" +msgid_plural "broken laser turrets" +msgstr[0] "сŠ»Š¾Š¼Š°Š½Š½Š°Ń Š»Š°Š·ŠµŃ€Š½Š°Ń турŠµŠ»ŃŒ" +msgstr[1] "сŠ»Š¾Š¼Š°Š½Š½Ń‹Šµ Š»Š°Š·ŠµŃ€Š½Ń‹Šµ турŠµŠ»Šø" +msgstr[2] "сŠ»Š¾Š¼Š°Š½Š½Ń‹Ń… Š»Š°Š·ŠµŃ€Š½Ń‹Ń… турŠµŠ»ŠµŠ¹" +msgstr[3] "сŠ»Š¾Š¼Š°Š½Š½Ń‹Šµ Š»Š°Š·ŠµŃ€Š½Ń‹Šµ турŠµŠ»Šø" + #: lang/json/GENERIC_from_json.py msgid "fire brick" msgid_plural "fire bricks" @@ -65906,14 +66019,6 @@ msgstr "" " ŠžŠ½Š° ŠæŠ¾ŠŗрытŠ° Š¼Š°Ń‚ŠµŃ€ŠøŠ°Š»Š¾Š¼ стрŠ°Š½Š½Š¾Š³Š¾ Š²ŠøŠ“Š°, Š½Š¾ этŠ¾ ŠæŠ¾ŠŗрытŠøŠµ Š²Ń‹Š³Š»ŃŠ“Šøт Š“Š¾Š²Š¾Š»ŃŒŠ½Š¾ " "хруŠæŠŗŠøŠ¼. Šš сŠ¾Š¶Š°Š»ŠµŠ½Šøю, эту ŠæŠ°Š½ŠµŠ»ŃŒ Š½ŠµŠ»ŃŒŠ·Ń уŠŗрŠµŠæŠøть Š°Ń€Š¼ŠøрŠ¾Š²Š°Š½Š½Ń‹Š¼ стŠµŠŗŠ»Š¾Š¼." -#: lang/json/GENERIC_from_json.py -msgid "broken laser turret" -msgid_plural "broken laser turrets" -msgstr[0] "сŠ»Š¾Š¼Š°Š½Š½Š°Ń Š»Š°Š·ŠµŃ€Š½Š°Ń турŠµŠ»ŃŒ" -msgstr[1] "сŠ»Š¾Š¼Š°Š½Š½Ń‹Šµ Š»Š°Š·ŠµŃ€Š½Ń‹Šµ турŠµŠ»Šø" -msgstr[2] "сŠ»Š¾Š¼Š°Š½Š½Ń‹Ń… Š»Š°Š·ŠµŃ€Š½Ń‹Ń… турŠµŠ»ŠµŠ¹" -msgstr[3] "сŠ»Š¾Š¼Š°Š½Š½Ń‹Šµ Š»Š°Š·ŠµŃ€Š½Ń‹Šµ турŠµŠ»Šø" - #: lang/json/GENERIC_from_json.py msgid "TX-5LR Laser Cannon" msgid_plural "TX-5LR Laser Cannons" @@ -66993,10 +67098,10 @@ msgstr[3] "сŠ¾Š·Ń€ŠµŠ²Š°ŃŽŃ‰Š°Ń хŠ»ŠµŠ±Š½Š°Ń Š·Š°ŠŗŠ²Š°ŃŠŗŠ°" #. ~ Use action msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py msgid "" -"After feeding it and caring for it for weeks, your sourdough starter is " +"After feeding it and caring for it for a week, your sourdough starter is " "finally ready for the big leagues." msgstr "" -"ŠŸŠ¾ŃŠ»Šµ Š½ŠµŠ“ŠµŠ»ŃŒ ŠæŠ¾Š“ŠŗŠ¾Ń€Š¼ŠŗŠø Š²Š°ŃˆŠ° хŠ»ŠµŠ±Š½Š°Ń Š·Š°ŠŗŠ²Š°ŃŠŗŠ° Š½Š°ŠŗŠ¾Š½ŠµŃ† Š³Š¾Ń‚Š¾Š²Š° Šŗ Š±Š¾Š»ŃŒŃˆŠøŠ¼ Š“ŠµŠ»Š°Š¼." +"ŠŸŠ¾ŃŠ»Šµ Š½ŠµŠ“ŠµŠ»Šø ŠæŠ¾Š“ŠŗŠ¾Ń€Š¼ŠŗŠø Š²Š°ŃˆŠ° хŠ»ŠµŠ±Š½Š°Ń Š·Š°ŠŗŠ²Š°ŃŠŗŠ° Š½Š°ŠŗŠ¾Š½ŠµŃ† Š³Š¾Ń‚Š¾Š²Š° Šŗ Š±Š¾Š»ŃŒŃˆŠøŠ¼ Š“ŠµŠ»Š°Š¼." #. ~ Use action not_ready_msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py @@ -67038,10 +67143,10 @@ msgstr "Š—Š°ŠŗŠ²Š°ŃŠŗŠ° ŠµŃ‰Ń‘ Š½Šµ Š³Š¾Ń‚Š¾Š²Š°." #: lang/json/GENERIC_from_json.py msgid "" "This jar contains a floury paste with sourdough starter mixed in. It needs " -"a few hours to recover its strength before it can be used again." +"a day to recover its strength before it can be used again." msgstr "" -"Š’ этŠ¾Š¹ Š±Š°Š½ŠŗŠµ Š»ŠµŠ¶Šøт Š¼ŃƒŃ‡Š½Š°Ń сŠ¼ŠµŃŃŒ Šø Š½ŠµŠ¼Š½Š¾Š³Š¾ Š·Š°ŠŗŠ²Š°ŃŠŗŠø. Š§ŠµŃ€ŠµŠ· Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ чŠ°ŃŠ¾Š² " -"Š¾Š½Š° Š½Š°Š±ŠµŃ€Ń‘Ń‚ Š“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½ŃƒŃŽ Š¼Š°ŃŃŃƒ Š“Š»Ń ŠæŠ¾Š²Ń‚Š¾Ń€Š½Š¾Š³Š¾ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½Šøя." +"Š’ этŠ¾Š¹ Š±Š°Š½ŠŗŠµ Š»ŠµŠ¶Šøт Š¼ŃƒŃ‡Š½Š°Ń сŠ¼ŠµŃŃŒ Šø Š½ŠµŠ¼Š½Š¾Š³Š¾ Š·Š°ŠŗŠ²Š°ŃŠŗŠø. Š§ŠµŃ€ŠµŠ· сутŠŗŠø Š¾Š½Š° Š½Š°Š±ŠµŃ€Ń‘Ń‚ " +"Š“Š¾ŃŃ‚Š°Ń‚Š¾Ń‡Š½ŃƒŃŽ Š¼Š°ŃŃŃƒ Š“Š»Ń ŠæŠ¾Š²Ń‚Š¾Ń€Š½Š¾Š³Š¾ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½Šøя." #: lang/json/GENERIC_from_json.py msgid "sourdough starter" @@ -67107,13 +67212,33 @@ msgstr[3] "Š°ŠæтŠµŃ‡ŠŗŠø" #. ~ Description for {'str': 'first aid kit'} #: lang/json/GENERIC_from_json.py msgid "" -"A full medical kit, with bandages, local anesthetics, and rapid healing " -"agents. Used for healing large amounts of damage. Disassemble to get its " -"content." +"A typical universal first aid kit, one you'd see in a car or in a household." +" It contains a variety of common medical items stored in case of accidents " +"and injuries. Disassemble to get its content." msgstr "" -"ŠŸŠ¾Š»Š½Ń‹Š¹ Š¼ŠµŠ“ŠøцŠøŠ½ŃŠŗŠøŠ¹ ŠŗŠ¾Š¼ŠæŠ»ŠµŠŗт с Š±ŠøŠ½Ń‚Š°Š¼Šø, Š°Š½ŠµŃŃ‚ŠµŃ‚ŠøŠŗŠ°Š¼Šø Šø Š·Š°Š¶ŠøŠ²Š»ŃŃŽŃ‰ŠøŠ¼Šø " -"ŠæрŠµŠæŠ°Ń€Š°Ń‚Š°Š¼Šø. Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ся Š“Š»Ń Š»ŠµŃ‡ŠµŠ½Šøя сŠµŃ€ŃŒŠµŠ·Š½Ń‹Ń… рŠ°Š½. Š Š°Š·Š±ŠµŃ€ŠøтŠµ, чтŠ¾Š±Ń‹ " -"ŠæŠ¾Š»ŃƒŃ‡Šøть сŠ¾Š“ŠµŃ€Š¶ŠøŠ¼Š¾Šµ." +"Š¢ŠøŠæŠøчŠ½Ń‹Š¹ Š½Š°Š±Š¾Ń€ ŠæŠµŃ€Š²Š¾Š¹ ŠæŠ¾Š¼Š¾Ń‰Šø, ŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¹ Š¼Š¾Š¶Š½Š¾ Š½Š°Š¹Ń‚Šø Š² Š¼Š°ŃˆŠøŠ½Šµ ŠøŠ»Šø Š“Š¾Š¼Š°. ŠžŠ½ " +"сŠ¾Š“ŠµŃ€Š¶Šøт Š½Š°Š±Š¾Ń€ рŠ°Š·Š½Š¾Š¾Š±Ń€Š°Š·Š½Ń‹Ń… Š¼ŠµŠ“ŠøцŠøŠ½ŃŠŗŠøх ŠæрŠµŠ“Š¼ŠµŃ‚Š¾Š², ŠŗŠ¾Ń‚Š¾Ń€Ń‹Šµ Š¼Š¾Š¶Š½Š¾ " +"ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ ŠæрŠø Š½ŠµŃŃ‡Š°ŃŃ‚Š½Ń‹Ń… сŠ»ŃƒŃ‡Š°ŃŃ… Šø рŠ°Š½ŠµŠ½Šøях. Š Š°Š·Š±ŠµŃ€ŠøтŠµ, чтŠ¾Š±Ń‹ ŠæŠ¾Š»ŃƒŃ‡Šøть " +"сŠ¾Š“ŠµŃ€Š¶ŠøŠ¼Š¾Šµ." + +#: lang/json/GENERIC_from_json.py +msgid "IFAK" +msgid_plural "IFAKs" +msgstr[0] "Š°ŠæтŠµŃ‡ŠŗŠ° IFAK" +msgstr[1] "Š°ŠæтŠµŃ‡ŠŗŠø IFAK" +msgstr[2] "Š°ŠæтŠµŃ‡ŠµŠŗ IFAK" +msgstr[3] "Š°ŠæтŠµŃ‡ŠŗŠø IFAK" + +#. ~ Description for {'str': 'IFAK'} +#: lang/json/GENERIC_from_json.py +msgid "" +"An IFAK, or individual first aid kit, is a specialized set of wound " +"dressings and accessories, and being of military origin focuses on combat " +"trauma and preventing blood loss. Disassemble to get its content." +msgstr "" +"IFAK - ŠøŠ½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Ń‹Š¹ Š½Š°Š±Š¾Ń€ Š“Š»Ń ŠæŠµŃ€Š²Š¾Š¹ ŠæŠ¾Š¼Š¾Ń‰Šø, сŠæŠµŃ†ŠøŠ°Š»ŠøŠ·ŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ Š½Š°Š±Š¾Ń€ " +"ŠæŠµŃ€ŠµŠ²ŃŠ·Š¾Ń‡Š½Ń‹Ń… Š¼Š°Ń‚ŠµŃ€ŠøŠ°Š»Š¾Š² Šø ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Š¾Š². Š¢Š°Šŗ ŠŗŠ°Šŗ Š¾Š½ Š°Ń€Š¼ŠµŠ¹ŃŠŗŠ¾Š³Š¾ ŠæрŠ¾ŠøсхŠ¾Š¶Š“ŠµŠ½Šøя," +" Š¾Š½ ŠæрŠµŠ“Š½Š°Š·Š½Š°Ń‡ŠµŠ½ Š“Š»Ń Š±Š¾ŠµŠ²Ń‹Ń… рŠ°Š½ Šø ŠæрŠµŠ“Š¾Ń‚Š²Ń€Š°Ń‰ŠµŠ½Šøя ŠŗрŠ¾Š²Š¾ŠæŠ¾Ń‚ŠµŃ€Šø." #: lang/json/GENERIC_from_json.py msgid "MRE" @@ -72959,13 +73084,13 @@ msgstr "" #: lang/json/GENERIC_from_json.py msgid "inscribed metal plates" -msgid_plural "inscribed metal platess" +msgid_plural "inscribed metal plates" msgstr[0] "рŠ°ŃŠæŠøсŠ°Š½Š½Ń‹Šµ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠµ ŠæŠ»Š°Ń‚Ń‹" msgstr[1] "рŠ°ŃŠæŠøсŠ°Š½Š½Ń‹Šµ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠµ ŠæŠ»Š°Ń‚Ń‹" msgstr[2] "рŠ°ŃŠæŠøсŠ°Š½Š½Ń‹Šµ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠµ ŠæŠ»Š°Ń‚Ń‹" msgstr[3] "рŠ°ŃŠæŠøсŠ°Š½Š½Ń‹Šµ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠµ ŠæŠ»Š°Ń‚Ń‹" -#. ~ Description for {'str': 'inscribed metal plates'} +#. ~ Description for {'str_sp': 'inscribed metal plates'} #: lang/json/GENERIC_from_json.py msgid "" "This device looks electronic, but is unfamiliar. It is a series of tightly " @@ -73015,6 +73140,47 @@ msgstr "" "сŠ²Š¾ŠµŠ³Š¾ рŠ¾Š“Š° Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŒ ŠøŠ»Šø Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€, Š½Š¾ ŠŗŠ¾Š½ŃŃ‚Ń€ŃƒŠŗцŠøя Š½Šµ ŠæŠ¾Ń…Š¾Š¶Š° Š½Š° тŠ¾, чтŠ¾ Š²Ń‹ " "Š²ŠøŠ“ŠµŠ»Šø рŠ°Š½ŃŒŃˆŠµ, Šø Š²Ń‹ Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ ŠæŠ¾Š½ŃŃ‚ŃŒ, ŠŗŠ°Šŗ Š·Š°ŃŃ‚Š°Š²Šøть ŠµŠ³Š¾ рŠ°Š±Š¾Ń‚Š°Ń‚ŃŒ." +#: lang/json/GENERIC_from_json.py +msgid "engraved parabolic dish" +msgid_plural "engraved parabolic dishes" +msgstr[0] "Š³Ń€Š°Š²ŠøрŠ¾Š²Š°Š½Š½Š°Ń ŠæŠ°Ń€Š°Š±Š¾Š»ŠøчŠµŃŠŗŠ°Ń тŠ°Ń€ŠµŠ»ŠŗŠ°" +msgstr[1] "Š³Ń€Š°Š²ŠøрŠ¾Š²Š°Š½Š½Ń‹Šµ ŠæŠ°Ń€Š°Š±Š¾Š»ŠøчŠµŃŠŗŠøŠµ тŠ°Ń€ŠµŠ»ŠŗŠø" +msgstr[2] "Š³Ń€Š°Š²ŠøрŠ¾Š²Š°Š½Š½Ń‹Ń… ŠæŠ°Ń€Š°Š±Š¾Š»ŠøчŠµŃŠŗŠøх тŠ°Ń€ŠµŠ»Š¾Šŗ" +msgstr[3] "Š³Ń€Š°Š²ŠøрŠ¾Š²Š°Š½Š½Ń‹Šµ ŠæŠ°Ń€Š°Š±Š¾Š»ŠøчŠµŃŠŗŠøŠµ тŠ°Ń€ŠµŠ»ŠŗŠø" + +#. ~ Description for {'str': 'engraved parabolic dish', 'str_pl': 'engraved +#. parabolic dishes'} +#: lang/json/GENERIC_from_json.py +msgid "" +"This hefty parabolic dish is engraved with an unrecognizable pattern of " +"symbols that might, at a guess, be some sort of circuitry pattern - or maybe" +" a religious incantation." +msgstr "" +"Š—Š“Š¾Ń€Š¾Š²ŠµŠ½Š½Š°Ń ŠæŠ°Ń€Š°Š±Š¾Š»ŠøчŠµŃŠŗŠ°Ń тŠ°Ń€ŠµŠ»ŠŗŠ°, Š³Ń€Š°Š²ŠøрŠ¾Š²Š°Š½Š½Š°Ń уŠ·Š¾Ń€Š¾Š¼ Š½ŠµŠ·Š½Š°ŠŗŠ¾Š¼Ń‹Ń… Š²Š°Š¼ " +"сŠøŠ¼Š²Š¾Š»Š¾Š², ŠŗŠ¾Ń‚Š¾Ń€Ń‹Šµ, ŠŗŠ°Šŗ Š¼Š¾Š¶Š½Š¾ Š“Š¾Š³Š°Š“Š°Ń‚ŃŒŃŃ, Š¼Š¾Š³ŃƒŃ‚ Š±Ń‹Ń‚ŃŒ чŠµŠ¼-тŠ¾ Š²Ń€Š¾Š“Šµ " +"эŠ»ŠµŠŗтрŠøчŠµŃŠŗŠ¾Š¹ схŠµŠ¼Ń‹ - ŠøŠ»Šø, Š²Š¾Š·Š¼Š¾Š¶Š½Š¾, рŠµŠ»ŠøŠ³ŠøŠ¾Š·Š½Ń‹Š¼ Š·Š°ŠŗŠ»ŠøŠ½Š°Š½ŠøŠµŠ¼." + +#: lang/json/GENERIC_from_json.py +msgid "oblong device" +msgid_plural "oblong devices" +msgstr[0] "ŠæрŠ¾Š“Š¾Š»Š³Š¾Š²Š°Ń‚Š¾Šµ устрŠ¾Š¹ŃŃ‚Š²Š¾" +msgstr[1] "ŠæрŠ¾Š“Š¾Š»Š³Š¾Š²Š°Ń‚Ń‹Ń… устрŠ¾Š¹ŃŃ‚Š²Š°" +msgstr[2] "ŠæрŠ¾Š“Š¾Š»Š³Š¾Š²Š°Ń‚Ń‹Ń… устрŠ¾Š¹ŃŃ‚Š²" +msgstr[3] "ŠæрŠ¾Š“Š¾Š»Š³Š¾Š²Š°Ń‚Ń‹Šµ устрŠ¾Š¹ŃŃ‚Š²Š°" + +#. ~ Description for {'str': 'oblong device'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Perfectly smooth, cool to the touch, and a dull blue-grey colour, this looks" +" almost like a perfect riverstone at first glance. Its artificial nature is" +" betrayed on closer inspection by a network of intricate patterns visible as" +" a slight difference in the reflection of light off its surface." +msgstr "" +"Š˜Š“ŠµŠ°Š»ŃŒŠ½Š¾ Š³Š»Š°Š“ŠŗŠ°Ń, ŠæрŠ¾Ń…Š»Š°Š“Š½Š°Ń Š½Š° Š¾Ń‰ŃƒŠæь Š²ŠµŃ‰ŃŒ тусŠŗŠ»Š¾Š³Š¾ сŠøŠ½Šµ-сŠµŃ€Š¾Š³Š¾ цŠ²ŠµŃ‚Š°, " +"ŠæŠ¾Ń…Š¾Š¶Š°Ń Š½Š° ŠøŠ“ŠµŠ°Š»ŃŒŠ½Š¾ Š¾Š±ŠŗŠ°Ń‚Š°Š½Š½ŃƒŃŽ рŠµŃ‡Š½ŃƒŃŽ Š³Š°Š»ŃŒŠŗу. ŠŸŃ€Šø Š±Š»ŠøŠ·ŠŗŠ¾Š¼ ŠøŠ·ŃƒŃ‡ŠµŠ½ŠøŠø ŠµŃ‘ " +"ŠøсŠŗусстŠ²ŠµŠ½Š½ŃƒŃŽ ŠæрŠøрŠ¾Š“у Š²Ń‹Š“Š°Ń‘Ń‚ сŠµŃ‚ŃŒ сŠ»Š¾Š¶Š½Ń‹Ń… уŠ·Š¾Ń€Š¾Š², Š²ŠøŠ“ŠøŠ¼Ń‹Ń… Š½Š° сŠ²ŠµŃ‚Ńƒ ŠæŠ¾Š“ " +"Š¾ŠæрŠµŠ“ŠµŠ»Ń‘Š½Š½Ń‹Š¼ уŠ³Š»Š¾Š¼." + #: lang/json/GENERIC_from_json.py msgid "sheet of glass" msgid_plural "sheets of glass" @@ -86263,6 +86429,27 @@ msgstr "" "Š² Š²Š¾Š·Š“ухŠµ. ŠŸŠ¾Ń…Š¾Š¶Šµ, Š¾Š½Š¾ Š¼Š¾Š¶ŠµŃ‚ Š“Š¾Š»Š³Š¾ ŠæрŠ¾Š“ŠµŃ€Š¶Š°Ń‚ŃŒŃŃ Š² Š²Š¾Š·Š“ухŠµ, ŠæŠ¾ŠŗŠ° Š½Šµ сяŠ“ут " "Š°ŠŗŠŗуŠ¼ŃƒŠ»ŃŃ‚Š¾Ń€Ń‹." +#: lang/json/MONSTER_from_json.py +msgid "feral human" +msgid_plural "feral humans" +msgstr[0] "Š“ŠøŠŗŠøŠ¹ чŠµŠ»Š¾Š²ŠµŠŗ" +msgstr[1] "Š“ŠøŠŗŠøх чŠµŠ»Š¾Š²ŠµŠŗŠ°" +msgstr[2] "Š“ŠøŠŗŠøх Š»ŃŽŠ“ŠµŠ¹" +msgstr[3] "Š“ŠøŠŗŠøŠµ Š»ŃŽŠ“Šø" + +#. ~ Description for {'str': 'feral human'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pupils dilated and what remains to be seen of the iris and sclera are " +"bloodshot. It still breathes but the zombies treat it like one of them." +msgstr "" +"ŠžŠ³Ń€Š¾Š¼Š½Ń‹Šµ Š·Ń€Š°Ń‡ŠŗŠø, Š·Š°Š»ŠøтыŠµ ŠŗрŠ¾Š²ŃŒŃŽ Š±ŠµŠ»ŠŗŠø Š³Š»Š°Š·. ŠžŠ½Š¾ Š²ŃŃ‘ ŠµŃ‰Ń‘ Š“ышŠøт, Š½Š¾ Š·Š¾Š¼Š±Šø " +"счŠøтŠ°ŃŽŃ‚ ŠµŠ³Š¾ сŠ²Š¾ŠøŠ¼ Šø Š½Šµ Š½Š°ŠæŠ°Š“Š°ŃŽŃ‚." + +#: lang/json/MONSTER_from_json.py +msgid "They throw a loose brick at you!" +msgstr "ŠžŠ½Š¾ ŠŗŠøŠ“Š°ŠµŃ‚ Š² Š²Š°Ń ŠŗŠøрŠæŠøч!" + #: lang/json/MONSTER_from_json.py msgid "alpha razorclaw" msgid_plural "alpha razorclaws" @@ -91061,6 +91248,26 @@ msgstr "" " Š¶ŠøŠ·Š½Šø. ŠžŠ±ŠøтŠ°ŠµŃ‚ ŠæŠ¾Š“ Š·ŠµŠ¼Š»Ń‘Š¹ Šø Š½Š°Š·Š²Š°Š½ тŠ°Šŗ ŠøŠ·-Š·Š° ŠæрŠøŠ²Ń‹Ń‡ŠŗŠø ŠæŠ°Ń€Š°Š·ŠøтŠøрŠ¾Š²Š°Ń‚ŃŒ Š² " "ŠŗŠ°Š½Š°Š»ŠøŠ·Š°Ń†ŠøŠø." +#: lang/json/MONSTER_from_json.py +msgid "prototype laser turret" +msgid_plural "prototype laser turrets" +msgstr[0] "ŠæрŠ¾Ń‚Š¾Ń‚ŠøŠæ Š»Š°Š·ŠµŃ€Š½Š¾Š¹ турŠµŠ»Šø" +msgstr[1] "ŠæрŠ¾Ń‚Š¾Ń‚ŠøŠæŠ° Š»Š°Š·ŠµŃ€Š½Š¾Š¹ турŠµŠ»Šø" +msgstr[2] "ŠæрŠ¾Ń‚Š¾Ń‚ŠøŠæŠ¾Š² Š»Š°Š·ŠµŃ€Š½Š¾Š¹ турŠµŠ»Šø" +msgstr[3] "ŠæрŠ¾Ń‚Š¾Ń‚ŠøŠæы Š»Š°Š·ŠµŃ€Š½Š¾Š¹ турŠµŠ»Šø" + +#. ~ Description for {'str': 'prototype laser turret'} +#: lang/json/MONSTER_from_json.py +msgid "" +"This appears to be a very experimental automated tower. Plating-less and " +"seemingly half-built, it's little more than an oversized laser emitter and a" +" camera, both welded to a swiveling platform." +msgstr "" +"ŠŸŠ¾Ń…Š¾Š¶Šµ, этŠ¾ эŠŗсŠæŠµŃ€ŠøŠ¼ŠµŠ½Ń‚Š°Š»ŃŒŠ½Š°Ń Š°Š²Ń‚Š¾Š¼Š°Ń‚ŠøчŠµŃŠŗŠ°Ń Š¾Š±Š¾Ń€Š¾Š½ŠøтŠµŠ»ŃŒŠ½Š°Ń устŠ°Š½Š¾Š²ŠŗŠ°. Š•Ń‘ " +"ŠŗŠ°Ń€ŠŗŠ°Ń Š½Šµ Š·Š°Šŗрыт Š±Ń€Š¾Š½ŠµŠæŠ»ŠøтŠ°Š¼Šø, Šø Š¾Š½Š° Š²Ń‹Š³Š»ŃŠ“Šøт Š·Š°ŠŗŠ¾Š½Ń‡ŠµŠ½Š½Š¾Š¹ тŠ¾Š»ŃŒŠŗŠ¾ Š½Š°ŠæŠ¾Š»Š¾Š²ŠøŠ½Ńƒ," +" ŠæрŠµŠ“стŠ°Š²Š»ŃŃ ŠøŠ· сŠµŠ±Ń Š»Š°Š·ŠµŃ€Š½Ń‹Š¹ эŠ¼ŠøттŠµŃ€ с ŠŗŠ°Š¼ŠµŃ€Š¾Š¹, устŠ°Š½Š¾Š²Š»ŠµŠ½Š½Ń‹Šµ Š½Š° " +"Š²Ń€Š°Ń‰Š°ŃŽŃ‰ŠµŠ¹ŃŃ ŠæŠ»Š°Ń‚Ń„Š¾Ń€Š¼Šµ." + #: lang/json/MONSTER_from_json.py msgid "blob" msgid_plural "blobs" @@ -91749,10 +91956,10 @@ msgstr "" #: lang/json/MONSTER_from_json.py msgid "hulking horror" msgid_plural "hulking horrors" -msgstr[0] "Š¾Š³Ń€Š¾Š¼Š½Ń‹Š¹ Š¶ŃƒŃ‚ŠµŠ½ŃŒ" -msgstr[1] "Š¾Š³Ń€Š¾Š¼Š½Ń‹Ń… Š¶ŃƒŃ‚Š½Ń" -msgstr[2] "Š¾Š³Ń€Š¾Š¼Š½Ń‹Ń… Š¶ŃƒŃ‚Š½ŠµŠ¹" -msgstr[3] "Š¾Š³Ń€Š¾Š¼Š½Ń‹Šµ Š¶ŃƒŃ‚Š½Šø" +msgstr[0] "Š·Š“Š¾Ń€Š¾Š²ŠµŠ½Š½Ń‹Š¹ Š¶ŠøŠ²Š¾Š³Š»Š¾Ń‚" +msgstr[1] "Š·Š“Š¾Ń€Š¾Š²ŠµŠ½Š½Ń‹Ń… Š¶ŠøŠ²Š¾Š³Š»Š¾Ń‚Š°" +msgstr[2] "Š·Š“Š¾Ń€Š¾Š²ŠµŠ½Š½Ń‹Ń… Š¶ŠøŠ²Š¾Š³Š»Š¾Ń‚Š¾Š²" +msgstr[3] "Š·Š“Š¾Ń€Š¾Š²ŠµŠ½Š½Ń‹Šµ Š¶ŠøŠ²Š¾Š³Š»Š¾Ń‚Ń‹" #. ~ Description for {'str': 'hulking horror'} #: lang/json/MONSTER_from_json.py @@ -92085,6 +92292,29 @@ msgstr "" "Š‘Š¾Š»ŠµŠµ-Š¼ŠµŠ½ŠµŠµ Š½Š¾Ń€Š¼Š°Š»ŃŒŠ½Š¾ Š²Ń‹Š³Š»ŃŠ“ящŠ°Ń ŠæуŠ¼Š°, Š·Š° ŠøсŠŗŠ»ŃŽŃ‡ŠµŠ½ŠøŠµŠ¼ тŠ¾Š³Š¾, чтŠ¾ ŠµŃ‘ Š·Š°Š“Š½ŠøŠµ " "Š½Š¾Š³Šø рŠ°ŃŠæухŠ»Šø, Š° ŠøŠ· Š³Š»Š°Š· сŠ¾Ń‡Šøтся чёрŠ½Š°Ń сŠ»ŠøŠ·ŃŒ." +#: lang/json/MONSTER_from_json.py +msgid "zombie horse" +msgid_plural "zombie horses" +msgstr[0] "Š·Š¾Š¼Š±Šø-Š»Š¾ŃˆŠ°Š“ь" +msgstr[1] "Š·Š¾Š¼Š±Šø-Š»Š¾ŃˆŠ°Š“Šø" +msgstr[2] "Š·Š¾Š¼Š±Šø-Š»Š¾ŃˆŠ°Š“ŠµŠ¹" +msgstr[3] "Š·Š¾Š¼Š±Šø-Š»Š¾ŃˆŠ°Š“Šø" + +#. ~ Description for {'str': 'zombie horse'} +#: lang/json/MONSTER_from_json.py +msgid "" +"From the looks of this zombie horse's ghastly features, with its protruding " +"ribs, whitish skull, and empty eyes, the exposed part of the internal organs" +" shows a seemingly lifeless color, and the black body fluid drips slowly. " +"The new strength makes the horse no longer dependent on its muscles, but it " +"can still pursue the enemy quickly." +msgstr "" +"Š”уŠ“я ŠæŠ¾ уŠ¶Š°ŃŠ½Ń‹Š¼ чŠµŃ€Ń‚Š°Š¼ этŠ¾Š¹ Š»Š¾ŃˆŠ°Š“Šø-Š·Š¾Š¼Š±Šø с ŠµŠµ Š²Ń‹ŠæуŠŗŠ»Ń‹Š¼Šø рŠµŠ±Ń€Š°Š¼Šø, Š±ŠµŠ»ŠµŃŃ‹Š¼ " +"чŠµŃ€ŠµŠæŠ¾Š¼ Šø ŠæустыŠ¼Šø Š³Š»Š°Š·Š°Š¼Šø,Š¾Š±Š½Š°Š¶ŠøŠ²ŃˆŠøŠµŃŃ Š²Š½ŃƒŃ‚Ń€ŠµŠ½Š½ŠøŠµ Š¾Ń€Š³Š°Š½Ń‹ Š¼ŠµŃ€Ń‚Š²Ń‹, Šø с Š½Šøх " +"Š¼ŠµŠ“Š»ŠµŠ½Š½Š¾ ŠŗŠ°ŠæŠ°ŠµŃ‚ чŠµŃ€Š½Š°Ń Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚ŃŒ. Š”Š²ŠøŠ¶ŃƒŃ‰Š°Ń ŠµŃ‘ тŠµŠæŠµŃ€ŃŒ сŠøŠ»Š° ŠæŠ¾Š·Š²Š¾Š»ŃŠµŃ‚ Š»Š¾ŃˆŠ°Š“Šø " +"Š±Š¾Š»ŃŒŃˆŠµ Š½Šµ Š·Š°Š²ŠøсŠµŃ‚ŃŒ Š¾Ń‚ сŠ²Š¾Šøх Š¼Ń‹ŃˆŃ†, Š½Š¾ Š¾Š½Š° Š²ŃŠµ ŠµŃ‰Šµ Š¼Š¾Š¶ŠµŃ‚ Š±Ń‹ŃŃ‚Ń€Š¾ ŠæрŠµŃŠ»ŠµŠ“Š¾Š²Š°Ń‚ŃŒ " +"Š²Ń€Š°Š³Š°." + #: lang/json/MONSTER_from_json.py msgid "Tiger wight" msgid_plural "Tiger wights" @@ -92102,6 +92332,46 @@ msgstr "" "ŠŸŠ¾Ń‡Ń‚Šø Š½Š¾Ń€Š¼Š°Š»ŃŒŠ½Š¾ Š²Ń‹Š³Š»ŃŠ“ящŠøŠ¹ тŠøŠ³Ń€, чтŠ¾ сŠæŠ¾Ń‚Ń‹ŠŗŠ°ŠµŃ‚ся Šø ŠŗŠ°Ń‡Š°ŠµŃ‚ся, ŠµŠ³Š¾ чŠµŠ»ŃŽŃŃ‚Šø " "Š¾Š±Š²ŠøсŠ»Šø, Š³Š»Š°Š·Š° шŠøрŠ¾ŠŗŠ¾ Š¾Ń‚Šŗрыты Šø Š±Š»ŠµŃŃ‚ŃŃ‚ чŠµŃ€Š½Ń‹Š¼ цŠ²ŠµŃ‚Š¾Š¼." +#: lang/json/MONSTER_from_json.py +msgid "zombie cow" +msgid_plural "zombie cows" +msgstr[0] "Š·Š¾Š¼Š±Šø-ŠŗŠ¾Ń€Š¾Š²Š°" +msgstr[1] "Š·Š¾Š¼Š±Šø-ŠŗŠ¾Ń€Š¾Š²Ń‹" +msgstr[2] "Š·Š¾Š¼Š±Šø-ŠŗŠ¾Ń€Š¾Š²" +msgstr[3] "Š·Š¾Š¼Š±Šø-ŠŗŠ¾Ń€Š¾Š²Ń‹" + +#. ~ Description for {'str': 'zombie cow'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Once a placid cow, this leathery horror stumbles and shudders, its pulsing " +"black eyes scanning for prey beneath wicked horns. It is big and heavy and " +"murderous." +msgstr "" +"ŠšŠ¾Š³Š“Š°-тŠ¾ тŠøхŠ°Ń ŠŗŠ¾Ń€Š¾Š²Š°, этŠ¾Ń‚ Š¾Š±Ń‚яŠ½ŃƒŃ‚Ń‹Š¹ ŠŗŠ¾Š¶ŠµŠ¹ Š¼Š¾Š½ŃŃ‚Ń€ хŠ¾Š“Šøт, сŠæŠ¾Ń‚Ń‹ŠŗŠ°ŃŃŃŒ Šø " +"Š²Š·Š“рŠ°Š³ŠøŠ²Š°Ń, ŠµŠ³Š¾ ŠæуŠ»ŃŒŃŠøрующŠøŠµ чŠµŃ€Š½Ń‹Šµ Š³Š»Š°Š·Š° Š²Ń‹ŠøсŠŗŠøŠ²Š°ŃŽŃ‚ Š“Š¾Š±Ń‹Ń‡Ńƒ, Š° Š³Š¾Š»Š¾Š²Ńƒ " +"уŠŗрŠ¾Ń‰Š°ŃŽŃ‚ Š¾ŃŃ‚рыŠµ рŠ¾Š³Š°. ŠžŠ½ Š±Š¾Š»ŃŒŃˆŠ¾Š¹, тяŠ¶ŠµŠ»Ń‹Š¹ Šø уŠ±ŠøŠ¹ŃŃ‚Š²ŠµŠ½Š½Š¾ Š½Š°ŃŃ‚Ń€Š¾ŠµŠ½Š½Ń‹Š¹." + +#: lang/json/MONSTER_from_json.py +msgid "woodland wight" +msgid_plural "woodland wights" +msgstr[0] "Š»ŠµŃŠ½Š¾Š¹ Š“ух" +msgstr[1] "Š»ŠµŃŠ½Ń‹Ń… Š“ухŠ°" +msgstr[2] "Š»ŠµŃŠ½Ń‹Ń… Š“ухŠ¾Š²" +msgstr[3] "Š»ŠµŃŠ½Ń‹Šµ Š“ухŠø" + +#. ~ Description for {'str': 'woodland wight'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pale, stumbling white-tailed deer with blackened eyes and drooling slime " +"down its neck. Its legs twist and bend in strange, haphazard directions, " +"but with unnatural strength and speed. Preys on coyotes, wolves, and giant " +"spider mutants." +msgstr "" +"Š‘Š»ŠµŠ“Š½Ń‹Š¹, сŠæŠ¾Ń‚Ń‹ŠŗŠ°ŃŽŃ‰ŠøŠ¹ŃŃ Š±ŠµŠ»Š¾Ń…Š²Š¾ŃŃ‚Ń‹Š¹ Š¾Š»ŠµŠ½ŃŒ с ŠæŠ¾Ń‡ŠµŃ€Š½ŠµŠ²ŃˆŠøŠ¼Šø Š³Š»Š°Š·Š°Š¼Šø Šø ŠæŠ¾Š»Š¾ŃŠŗŠ¾Š¹ " +"стŠµŠŗŠ°ŃŽŃ‰ŠµŠ¹ ŠøŠ·Š¾ ртŠ° сŠ»ŠøŠ·Šø Š½Š° шŠµŠµ. Š•Š³Š¾ Š½Š¾Š³Šø Šŗрутятся Šø ŠøŠ·Š³ŠøŠ±Š°ŃŽŃ‚ся Š² стрŠ°Š½Š½Ń‹Ń…, " +"сŠ»ŃƒŃ‡Š°Š¹Š½Ń‹Ń… Š½Š°ŠæрŠ°Š²Š»ŠµŠ½Šøях, Š“ŠµŠ¼Š¾Š½ŃŃ‚Ń€Šøруя ŠæрŠø этŠ¾Š¼ Š½ŠµŠµŃŃ‚ŠµŃŃ‚Š²ŠµŠ½Š½ŃƒŃŽ сŠøŠ»Ńƒ Šø " +"сŠŗŠ¾Ń€Š¾ŃŃ‚ŃŒ. ŠžŃ…Š¾Ń‚Šøтся Š½Š° ŠŗŠ¾Š¹Š¾Ń‚Š¾Š², Š²Š¾Š»ŠŗŠ¾Š² Šø Š³ŠøŠ³Š°Š½Ń‚сŠŗŠøх ŠæŠ°ŃƒŠŗŠ¾Š²-Š¼ŃƒŃ‚Š°Š½Ń‚Š¾Š²." + #: lang/json/MONSTER_from_json.py msgid "mass of zombie spiders" msgid_plural "mass of zombie spiderss" @@ -92858,10 +93128,10 @@ msgstr "ŠŸŃ€Š¾Š½Š·Š°Ń‚ŠµŠ»ŃŒ Š²Ń‹ŃŃ‚Ń€ŠµŠ»ŠøŠ²Š°ŠµŃ‚ ŠŗŠ¾Š»ŃŽŃ‡ŠŗŠ¾Š¹!" #: lang/json/MONSTER_from_json.py msgid "scissorlimbs" msgid_plural "scissorlimbss" -msgstr[0] "Š½Š¾Š¶Š½ŠøцŠµŃ…Š¾Š“" -msgstr[1] "Š½Š¾Š¶Š½ŠøцŠµŃ…Š¾Š“Š°" -msgstr[2] "Š½Š¾Š¶Š½ŠøцŠµŃ…Š¾Š“Š¾Š²" -msgstr[3] "Š½Š¾Š¶Š½ŠøцŠµŃ…Š¾Š“ы" +msgstr[0] "Š½Š¾Š¶ŠµŃ…Š¾Š“" +msgstr[1] "Š½Š¾Š¶ŠµŃ…Š¾Š“Š°" +msgstr[2] "Š½Š¾Š¶ŠµŃ…Š¾Š“Š¾Š²" +msgstr[3] "Š½Š¾Š¶ŠµŃ…Š¾Š“ы" #. ~ Description for {'str': 'scissorlimbs'} #: lang/json/MONSTER_from_json.py @@ -93151,14 +93421,14 @@ msgstr "" "Š¼ŃƒŃŠ¾Ń€Š½Ń‹Š¹ Š±Š°Šŗ." #: lang/json/MONSTER_from_json.py -msgid "feral hunter" -msgid_plural "feral hunters" -msgstr[0] "Š“ŠøŠŗŠøŠ¹ Š¾Ń…Š¾Ń‚Š½ŠøŠŗ" -msgstr[1] "Š“ŠøŠŗŠøх Š¾Ń…Š¾Ń‚Š½ŠøŠŗŠ°" -msgstr[2] "Š“ŠøŠŗŠøх Š¾Ń…Š¾Ń‚Š½ŠøŠŗŠ¾Š²" -msgstr[3] "Š“ŠøŠŗŠøŠµ Š¾Ń…Š¾Ń‚Š½ŠøŠŗŠø" +msgid "zombie hunter" +msgid_plural "zombie hunters" +msgstr[0] "Š·Š¾Š¼Š±Šø-Š¾Ń…Š¾Ń‚Š½ŠøŠŗ" +msgstr[1] "Š·Š¾Š¼Š±Šø-Š¾Ń…Š¾Ń‚Š½ŠøŠŗŠ°" +msgstr[2] "Š·Š¾Š¼Š±Šø-Š¾Ń…Š¾Ń‚Š½ŠøŠŗŠ¾Š²" +msgstr[3] "Š·Š¾Š¼Š±Šø-Š¾Ń…Š¾Ń‚Š½ŠøŠŗŠø" -#. ~ Description for {'str': 'feral hunter'} +#. ~ Description for {'str': 'zombie hunter'} #: lang/json/MONSTER_from_json.py msgid "" "This once-human body is barely recognizable, scrambling about on all fours, " @@ -93273,14 +93543,14 @@ msgstr "" "ŠŗŠ¾ŃŠ¼ŠøчŠµŃŠŗŠøŠ¼, Š½ŠµŃ‡ŠµŠ»Š¾Š²ŠµŃ‡ŠµŃŠŗŠøŠ¼ эŠŗстŠ°Š·Š¾Š¼." #: lang/json/MONSTER_from_json.py -msgid "feral runner" -msgid_plural "feral runners" -msgstr[0] "Š“ŠøŠŗŠøŠ¹ Š±ŠµŠ³ŃƒŠ½" -msgstr[1] "Š“ŠøŠŗŠøх Š±ŠµŠ³ŃƒŠ½Š°" -msgstr[2] "Š“ŠøŠŗŠøх Š±ŠµŠ³ŃƒŠ½Š¾Š²" -msgstr[3] "Š“ŠøŠŗŠøŠµ Š±ŠµŠ³ŃƒŠ½Ń‹" +msgid "zombie runner" +msgid_plural "zombie runners" +msgstr[0] "Š·Š¾Š¼Š±Šø-Š±ŠµŠ³ŃƒŠ½" +msgstr[1] "Š·Š¾Š¼Š±Šø-Š±ŠµŠ³ŃƒŠ½Š°" +msgstr[2] "Š·Š¾Š¼Š±Šø-Š±ŠµŠ³ŃƒŠ½Š¾Š²" +msgstr[3] "Š·Š¾Š¼Š±Šø-Š±ŠµŠ³ŃƒŠ½Ń‹" -#. ~ Description for {'str': 'feral runner'} +#. ~ Description for {'str': 'zombie runner'} #: lang/json/MONSTER_from_json.py msgid "" "This recently-risen body moves quickly, darting its head back and forth and " @@ -93290,14 +93560,14 @@ msgstr "" "Š²Š·Š°Š“-Š²ŠæŠµŃ€Ń‘Š“. Š•Š³Š¾ Š¼ŃƒŃ‡Šøт ŠæŠ¾ŃŃ‚Š¾ŃŠ½Š½Ń‹Š¹ Š³Š¾Š»Š¾Š“." #: lang/json/MONSTER_from_json.py -msgid "feral predator" -msgid_plural "feral predators" -msgstr[0] "Š“ŠøŠŗŠøŠ¹ хŠøщŠ½ŠøŠŗ" -msgstr[1] "Š“ŠøŠŗŠøх хŠøщŠ½ŠøŠŗŠ°" -msgstr[2] "Š“ŠøŠŗŠøх хŠøщŠ½ŠøŠŗŠ¾Š²" -msgstr[3] "Š“ŠøŠŗŠøŠµ хŠøщŠ½ŠøŠŗŠø" +msgid "zombie predator" +msgid_plural "zombie predators" +msgstr[0] "Š·Š¾Š¼Š±Šø-хŠøщŠ½ŠøŠŗ" +msgstr[1] "Š·Š¾Š¼Š±Šø-хŠøщŠ½ŠøŠŗŠ°" +msgstr[2] "Š·Š¾Š¼Š±Šø-хŠøщŠ½ŠøŠŗŠ¾Š²" +msgstr[3] "Š·Š¾Š¼Š±Šø-хŠøщŠ½ŠøŠŗŠø" -#. ~ Description for {'str': 'feral predator'} +#. ~ Description for {'str': 'zombie predator'} #: lang/json/MONSTER_from_json.py msgid "" "With its joints in odd places and angles, this humanoid creature prowls " @@ -98816,7 +99086,7 @@ msgstr "Š‘Š¾Š»ŃŒ" msgid "Increases pain" msgstr "ŠŸŠ¾Š²Ń‹ŃˆŠ°ŠµŃ‚ Š±Š¾Š»ŃŒ" -#: lang/json/SPELL_from_json.py src/character.cpp src/npctalk.cpp +#: lang/json/SPELL_from_json.py src/character.cpp src/talker_npc.cpp msgid "Tired" msgstr "Š£ŃŃ‚Š°Š»Š¾ŃŃ‚ŃŒ" @@ -99958,7 +100228,7 @@ msgstr "" msgid "Lightning Blast" msgstr "Š—Š°Ń€ŃŠ“ Š¼Š¾Š»Š½ŠøŠø" -#: lang/json/SPELL_from_json.py src/weather_data.cpp +#: lang/json/SPELL_from_json.py lang/json/weather_type_from_json.py msgid "Lightning Storm" msgstr "Š›ŠøŠ²ŠµŠ½ŃŒ с Š³Ń€Š¾Š·Š¾Š¹" @@ -101029,13 +101299,14 @@ msgstr[3] "ŠŗŠ¾Š¼ŠæŠ»ŠµŠŗты Š±Š¾ŠµŠ²Š¾Š¹ Š±Ń€Š¾Š½Šø RM13" #. ~ Description for {'str': 'RM13 combat armor'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. Use it to turn it on." msgstr "" -"ŠŸŠ¾ŠŗрыŠ²Š°ŃŽŃ‰Š°Ń Š²ŃŃ‘ тŠµŠ»Š¾ Š¾Š±Ń‚ŠµŠŗŠ°ŠµŠ¼Š°Ń чёрŠ½Š°Ń Š±Š¾ŠµŠ²Š°Ń Š±Ń€Š¾Š½Ń, Š»ŃƒŃ‡ŃˆŠ°Ń Š³ŠøŠ±ŠŗŠ°Ń сŠøŠ»Š¾Š²Š°Ń " -"Š±Ń€Š¾Š½Ń Š² Š»ŠøŠ½ŠµŠ¹ŠŗŠµ ŠŗŠ¾Š¼ŠæŠ°Š½ŠøŠø Š ŠøŠ²Ń‚ŠµŃ…. Š˜Š¼ŠµŠµŃ‚ Š²Š½ŃƒŃ‚Ń€ŠµŠ½Š½ŠµŠµ ŠæŠøтŠ°Š½ŠøŠµ, Š¼Š¾Š¶Š½Š¾ Š·Š°Š³Ń€ŃƒŠ·Šøть " -"Š“Š¾ 10 ŠæŠ»ŃƒŃ‚Š¾Š½ŠøŠµŠ²Ń‹Ń… ячŠµŠµŠŗ. ŠŠŗтŠøŠ²ŠøруŠ¹Ń‚Šµ, чтŠ¾Š±Ń‹ Š²ŠŗŠ»ŃŽŃ‡Šøть." +"Š”Š¾ Š²ŃŃ‚Ń€Š¾ŠµŠ½Š½Ń‹Š¼ ŠæŠøтŠ°Š½ŠøŠµŠ¼ Š¾Ń‚ ŠæŠ»ŃƒŃ‚Š¾Š½ŠøŠµŠ²Ń‹Ń… тŠ¾ŠæŠ»ŠøŠ²Š½Ń‹Ń… ячŠµŠµŠŗ, этŠ¾Ń‚ ŠæŠ¾ŠŗрыŠ²Š°ŃŽŃ‰ŠøŠ¹ Š²ŃŃ‘ " +"тŠµŠ»Š¾ ŠŗŠ¾ŃŃ‚ŃŽŠ¼ ŠøŠ· Š¾Š±Ń‚ŠµŠŗŠ°ŠµŠ¼Š¾Š¹ чёрŠ½Š¾Š¹ Š±Š¾ŠµŠ²Š¾Š¹ Š±Ń€Š¾Š½Šø ŠæрŠµŠ“стŠ°Š²Š»ŃŠµŃ‚ сŠ¾Š±Š¾Š¹ Š²ŠµŃ€ŃˆŠøŠ½Ńƒ " +"тŠµŃ…Š½Š¾Š»Š¾Š³ŠøŠø срŠµŠ“Šø Š³ŠøŠ±ŠŗŠ¾Š¹ сŠøŠ»Š¾Š²Š¾Š¹ Š±Ń€Š¾Š½Šø Š¾Ń‚ ŠŗŠ¾Š¼ŠæŠ°Š½ŠøŠø Š ŠøŠ²Ń‚ŠµŃ…. ŠŠŗтŠøŠ²ŠøруŠ¹Ń‚Šµ, чтŠ¾Š±Ń‹" +" Š²ŠŗŠ»ŃŽŃ‡Šøть." #: lang/json/TOOL_ARMOR_from_json.py msgid "RM13 combat armor (on)" @@ -101049,14 +101320,15 @@ msgstr[3] "ŠŗŠ¾Š¼ŠæŠ»ŠµŠŗты Š±Š¾ŠµŠ²Š¾Š¹ Š±Ń€Š¾Š½Šø RM13 (Š²ŠŗŠ»)" #. armors (on)'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. It is turned on, and continually draining " "power. Use it to turn it off." msgstr "" -"ŠŸŠ¾ŠŗрыŠ²Š°ŃŽŃ‰Š°Ń Š²ŃŃ‘ тŠµŠ»Š¾ Š¾Š±Ń‚ŠµŠŗŠ°ŠµŠ¼Š°Ń чёрŠ½Š°Ń Š±Š¾ŠµŠ²Š°Ń Š±Ń€Š¾Š½Ń, Š»ŃƒŃ‡ŃˆŠ°Ń Š³ŠøŠ±ŠŗŠ°Ń сŠøŠ»Š¾Š²Š°Ń " -"Š±Ń€Š¾Š½Ń Š² Š»ŠøŠ½ŠµŠ¹ŠŗŠµ ŠŗŠ¾Š¼ŠæŠ°Š½ŠøŠø Š ŠøŠ²Ń‚ŠµŃ…. Š˜Š¼ŠµŠµŃ‚ Š²Š½ŃƒŃ‚Ń€ŠµŠ½Š½ŠµŠµ ŠæŠøтŠ°Š½ŠøŠµ, Š¼Š¾Š¶Š½Š¾ Š·Š°Š³Ń€ŃƒŠ·Šøть " -"Š“Š¾ 10 ŠæŠ»ŃƒŃ‚Š¾Š½ŠøŠµŠ²Ń‹Ń… ячŠµŠµŠŗ. ŠŠŗтŠøŠ²ŠøруŠ¹Ń‚Šµ, чтŠ¾Š±Ń‹ Š²Ń‹ŠŗŠ»ŃŽŃ‡Šøть." +"Š”Š¾ Š²ŃŃ‚Ń€Š¾ŠµŠ½Š½Ń‹Š¼ ŠæŠøтŠ°Š½ŠøŠµŠ¼ Š¾Ń‚ ŠæŠ»ŃƒŃ‚Š¾Š½ŠøŠµŠ²Ń‹Ń… тŠ¾ŠæŠ»ŠøŠ²Š½Ń‹Ń… ячŠµŠµŠŗ, этŠ¾Ń‚ ŠæŠ¾ŠŗрыŠ²Š°ŃŽŃ‰ŠøŠ¹ Š²ŃŃ‘ " +"тŠµŠ»Š¾ ŠŗŠ¾ŃŃ‚ŃŽŠ¼ ŠøŠ· Š¾Š±Ń‚ŠµŠŗŠ°ŠµŠ¼Š¾Š¹ чёрŠ½Š¾Š¹ Š±Š¾ŠµŠ²Š¾Š¹ Š±Ń€Š¾Š½Šø ŠæрŠµŠ“стŠ°Š²Š»ŃŠµŃ‚ сŠ¾Š±Š¾Š¹ Š²ŠµŃ€ŃˆŠøŠ½Ńƒ " +"тŠµŃ…Š½Š¾Š»Š¾Š³ŠøŠø срŠµŠ“Šø Š³ŠøŠ±ŠŗŠ¾Š¹ сŠøŠ»Š¾Š²Š¾Š¹ Š±Ń€Š¾Š½Šø Š¾Ń‚ ŠŗŠ¾Š¼ŠæŠ°Š½ŠøŠø Š ŠøŠ²Ń‚ŠµŃ…. Š”ŠµŠ¹Ń‡Š°Ń рŠ°Š±Š¾Ń‚Š°ŠµŃ‚ Šø " +"ŠæŠ¾ŃŃ‚Š¾ŃŠ½Š½Š¾ ŠæŠ¾Ń‚Ń€ŠµŠ±Š»ŃŠµŃ‚ эŠ½ŠµŃ€Š³Šøю. ŠŠŗтŠøŠ²ŠøруŠ¹Ń‚Šµ, чтŠ¾Š±Ń‹ Š²Ń‹ŠŗŠ»ŃŽŃ‡Šøть." #: lang/json/TOOL_ARMOR_from_json.py msgid "5-point anchor" @@ -102494,12 +102766,12 @@ msgstr[3] "сŠ¾Š»Š½ŠµŃ‡Š½Ń‹Šµ рюŠŗŠ·Š°ŠŗŠø (сŠ»Š¾Š¶ŠµŠ½Ń‹)" msgid "" "Personal portable charging system consisting of an array of solar panels " "neatly folded in a form of a large backpack. It can be worn as one, and has" -" an integrated cable to plug it into a cable charger system." +" an integrated cable to plug it into a cable charger system CBM." msgstr "" "Š˜Š½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Š°Ń Š¼Š¾Š±ŠøŠ»ŃŒŠ½Š°Ń Š·Š°Ń€ŃŠ“Š½Š°Ń сŠøстŠµŠ¼Š°, сŠ¾ŃŃ‚Š¾ŃŃ‰Š°Ń ŠøŠ· Š¼Š°ŃŃŠøŠ²Š° сŠ¾Š»Š½ŠµŃ‡Š½Ń‹Ń… " "ŠæŠ°Š½ŠµŠ»ŠµŠ¹, Š°ŠŗŠŗурŠ°Ń‚Š½Š¾ сŠ»Š¾Š¶ŠµŠ½Š½Ń‹Ń… Š² фŠ¾Ń€Š¼Šµ Š±Š¾Š»ŃŒŃˆŠ¾Š³Š¾ рюŠŗŠ·Š°ŠŗŠ°. Š•Š³Š¾ Š¼Š¾Š¶Š½Š¾ Š½Š¾ŃŠøть Š½Š° " "сŠæŠøŠ½Šµ. Š¢Š°ŠŗŠ¶Šµ у Š½ŠµŠ³Š¾ ŠøŠ¼ŠµŠµŃ‚ся Š²ŃŃ‚Ń€Š¾ŠµŠ½Š½Ń‹Š¹ ŠŗŠ°Š±ŠµŠ»ŃŒ Š“Š»Ń ŠæрŠøсŠ¾ŠµŠ“ŠøŠ½ŠµŠ½Šøя Šŗ сŠøстŠµŠ¼Šµ " -"Š·Š°Ń€ŃŠ“ŠŗŠø ŠæŠ¾ ŠŗŠ°Š±ŠµŠ»ŃŽ." +"Š·Š°Ń€ŃŠ“ŠŗŠø ŠšŠ‘Šœ ŠæŠ¾ ŠŗŠ°Š±ŠµŠ»ŃŽ." #: lang/json/TOOL_ARMOR_from_json.py msgid "solar backpack (unfolded)" @@ -102514,10 +102786,10 @@ msgstr[3] "сŠ¾Š»Š½ŠµŃ‡Š½Ń‹Šµ рюŠŗŠ·Š°ŠŗŠø (рŠ°Š·Š»Š¾Š¶ŠµŠ½Š¾)" #: lang/json/TOOL_ARMOR_from_json.py msgid "" "Unfolded array of portable solar panels ready to push some power into an " -"active cable charger system." +"active cable charger system CBM." msgstr "" "Š Š°Š·Š»Š¾Š¶ŠµŠ½Š½Ń‹Š¹ Š¼Š°ŃŃŠøŠ² ŠæŠ¾Ń€Ń‚Š°Ń‚ŠøŠ²Š½Ń‹Ń… сŠ¾Š»Š½ŠµŃ‡Š½Ń‹Ń… ŠæŠ°Š½ŠµŠ»ŠµŠ¹, Š³Š¾Ń‚Š¾Š²Ń‹Š¹ ŠæŠµŃ€ŠµŠ“Š°Ń‚ŃŒ эŠ½ŠµŃ€Š³Šøю Š²" -" Š°ŠŗтŠøŠ²ŠøрŠ¾Š²Š°Š½Š½ŃƒŃŽ сŠøстŠµŠ¼Ńƒ Š·Š°Ń€ŃŠ“ŠŗŠø ŠæŠ¾ ŠŗŠ°Š±ŠµŠ»ŃŽ." +" Š°ŠŗтŠøŠ²ŠøрŠ¾Š²Š°Š½Š½ŃƒŃŽ сŠøстŠµŠ¼Ńƒ Š·Š°Ń€ŃŠ“ŠŗŠø ŠšŠ‘Šœ ŠæŠ¾ ŠŗŠ°Š±ŠµŠ»ŃŽ." #: lang/json/TOOL_ARMOR_from_json.py msgid "riot helmet" @@ -108744,8 +109016,8 @@ msgstr "" msgid "" "This is an advanced version of the unified power supply, or UPS. This " "device has been significantly redesigned to provide better efficiency as " -"well as to consume plutonium fuel cells rather than batteries. Sadly, its " -"plutonium reactor can't be charged in UPS charging station." +"well as to consume plutonium fuel batteries rather than regular batteries. " +"Sadly, its plutonium reactor can't be charged in UPS charging station." msgstr "" "Š£Š»ŃƒŃ‡ŃˆŠµŠ½Š½Š°Ń Š²ŠµŃ€ŃŠøя уŠ½ŠøŠ²ŠµŃ€ŃŠ°Š»ŃŒŠ½Š¾Š¹ Š±Š°Ń‚Š°Ń€ŠµŠø ŠæŠøтŠ°Š½Šøя (Š£Š‘ŠŸ). Š­Ń‚Š¾ устрŠ¾Š¹ŃŃ‚Š²Š¾ сŠøŠ»ŃŒŠ½Š¾" " ŠæŠµŃ€ŠµŃ€Š°Š±Š¾Ń‚Š°Š½Š¾ ŠæŠ¾ срŠ°Š²Š½ŠµŠ½Šøю с ŠæрŠµŠ“шŠµŃŃ‚Š²ŠµŠ½Š½ŠøŠŗŠ¾Š¼ Š“Š»Ń ŠæŠ¾Š²Ń‹ŃˆŠµŠ½Šøя эффŠµŠŗтŠøŠ²Š½Š¾ŃŃ‚Šø Šø " @@ -109854,13 +110126,15 @@ msgstr "Š’Ń‹ Š²Ń‹Š“ŠµŃ€Š½ŃƒŠ»Šø чŠµŠŗу эŠ»ŠµŠŗтрŠ¾Š¼Š°Š³Š½ŠøтŠ½Š¾Š¹ Š³Ń€Š° #: lang/json/TOOL_from_json.py msgid "" "This is a grenade that generates an electromagnetic pulse with a low-" -"inductance capacitor bank discharged into a single-loop antenna. Use this " -"item to pull the pin and light the fuse, turning it into an active EMP " -"grenade. You will then have three turns before it detonates, creating an " -"EMP field that damages robots and drains bionic energy." +"inductance capacitor bank discharged into a single-loop antenna. It also " +"produces a mild electric shock cloud. Use this item to pull the pin and " +"light the fuse, turning it into an active EMP grenade. You will then have " +"three turns before it detonates, creating an EMP field that damages robots " +"and drains bionic energy." msgstr "" "Š“Ń€Š°Š½Š°Ń‚Š°, Š³ŠµŠ½ŠµŃ€ŠøрующŠ°Ń эŠ»ŠµŠŗтрŠ¾Š¼Š°Š³Š½ŠøтŠ½Ń‹Š¹ ŠøŠ¼ŠæуŠ»ŃŒŃ ŠæŠ¾ŃŃ€ŠµŠ“стŠ²Š¾Š¼ ряŠ·Ń€ŃŠ“ŠŗŠø " -"Š½ŠøŠ·ŠŗŠ¾ŠøŠ½Š“уŠŗтŠøŠ²Š½Š¾Š³Š¾ ŠŗŠ¾Š½Š“ŠµŠ½ŃŠ°Ń‚Š¾Ń€Š° чŠµŃ€ŠµŠ· Š¾Š“Š½Š¾Š²ŠøтŠŗŠ¾Š²ŃƒŃŽ Š°Š½Ń‚ŠµŠ½Š½Ńƒ. ŠŠŗтŠøŠ²ŠøруŠ¹Ń‚Šµ ŠµŃ‘, " +"Š½ŠøŠ·ŠŗŠ¾ŠøŠ½Š“уŠŗтŠøŠ²Š½Š¾Š³Š¾ ŠŗŠ¾Š½Š“ŠµŠ½ŃŠ°Ń‚Š¾Ń€Š° чŠµŃ€ŠµŠ· Š¾Š“Š½Š¾Š²ŠøтŠŗŠ¾Š²ŃƒŃŽ Š°Š½Ń‚ŠµŠ½Š½Ńƒ. Š¢Š°ŠŗŠ¶Šµ ŠæŠ¾Ń€Š°Š¶Š°ŠµŃ‚ " +"Š±Š»ŠøŠ¶Š°Š¹ŃˆŠøŠµ Š¾ŠŗрŠµŃŃ‚Š½Š¾ŃŃ‚Šø уŠ¼ŠµŃ€ŠµŠ½Š½Ń‹Š¼ рŠ°Š·Ń€ŃŠ“Š¾Š¼ эŠ»ŠµŠŗтрŠøчŠµŃŃ‚Š²Š°. ŠŠŗтŠøŠ²ŠøруŠ¹Ń‚Šµ ŠµŃ‘, " "чтŠ¾Š±Ń‹ Š²Ń‹Š“ŠµŃ€Š½ŃƒŃ‚ŃŒ чŠµŠŗу Šø Š°ŠŗтŠøŠ²ŠøрŠ¾Š²Š°Ń‚ŃŒ Š­ŠœŠ˜ Š³Ń€Š°Š½Š°Ń‚Ńƒ. Š£ Š²Š°Ń Š±ŃƒŠ“ŠµŃ‚ трŠø хŠ¾Š“Š° Š“Š¾ " "Š“ŠµŃ‚Š¾Š½Š°Ń†ŠøŠø. Š’Š·Ń€Ń‹Š² сŠ¾Š·Š“Š°ŃŃ‚ Š­ŠœŠ˜, ŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¹ Š½Š°Š½Š¾ŃŠøт урŠ¾Š½ рŠ¾Š±Š¾Ń‚Š°Š¼ Šø ŠæŠ¾Š³Š»Š¾Ń‰Š°ŠµŃ‚ " "Š±ŠøŠ¾Š½ŠøчŠµŃŠŗую эŠ½ŠµŃ€Š³Šøю." @@ -109877,12 +110151,13 @@ msgstr[3] "Š­ŠœŠ˜ Š³Ń€Š°Š½Š°Ń‚Ń‹ (Š°ŠŗтŠøŠ²Š½Š¾)" #: lang/json/TOOL_from_json.py msgid "" "This EMP grenade is active, and will shortly detonate, creating a large EMP " -"field that damages robots and drains bionic energy. You may not want to be " -"holding it much longer." +"field that damages robots and drains bionic energy as well as a mild " +"electric shock cloud. You may not want to be holding it much longer." msgstr "" -"Š­Š»ŠµŠŗтрŠ¾Š¼Š°Š³Š½ŠøтŠ½Š°Ń (Š­ŠœŠ“) Š³Ń€Š°Š½Š°Ń‚Š° с Š²Ń‹Š“ŠµŃ€Š½ŃƒŃ‚Š¾Š¹ чŠµŠŗŠ¾Š¹, Š“Š¾Š»Š¶Š½Š° сŠŗŠ¾Ń€Š¾ Š²Š·Š¾Ń€Š²Š°Ń‚ŃŒŃŃ, " -"сŠ¾Š·Š“Š°Š² ŠæŠ¾Š»Šµ эŠ»ŠµŠŗтрŠ¾Š¼Š°Š³Š½ŠøтŠ½Š¾Š³Š¾ ŠøŠ·Š»ŃƒŃ‡ŠµŠ½Šøя, ŠŗŠ¾Ń‚Š¾Ń€Š¾Šµ Š²Ń‹Š²Š¾Š“Šøт ŠøŠ· стрŠ¾Ń " -"рŠ¾Š±Š¾Ń‚ŠµŃ…Š½ŠøŠŗу Šø Š±ŠøŠ¾Š½ŠøчŠµŃŠŗŠøŠµ ŠøŠ¼ŠæŠ»Š°Š½Ń‚Ń‹. ŠŠµ тяŠ½ŠøтŠµ с Š±Ń€Š¾ŃŠŗŠ¾Š¼!" +"ŠŠŗтŠøŠ²ŠøрŠ¾Š²Š°Š½Š½Š°Ń Š­ŠœŠ˜ Š³Ń€Š°Š½Š°Ń‚Š° сŠŗŠ¾Ń€Š¾ Š²Š·Š¾Ń€Š²Ń‘Ń‚ŃŃ, сŠ¾Š·Š“Š°Š² Š¾Š³Ń€Š¾Š¼Š½Š¾Šµ ŠæŠ¾Š»Šµ " +"эŠ»ŠµŠŗтрŠ¾Š¼Š°Š³Š½ŠøтŠ½Š¾Š³Š¾ ŠøŠ·Š»ŃƒŃ‡ŠµŠ½Šøя, ŠŗŠ¾Ń‚Š¾Ń€Š¾Šµ Š²Ń‹Š²ŠµŠ“ŠµŃ‚ ŠøŠ· стрŠ¾Ń рŠ¾Š±Š¾Ń‚ŠµŃ…Š½ŠøŠŗу Šø " +"Š±ŠøŠ¾Š½ŠøчŠµŃŠŗŠøŠµ ŠøŠ¼ŠæŠ»Š°Š½Ń‚Ń‹, Š° тŠ°ŠŗŠ¶Šµ ŠæрŠ¾ŠøŠ·Š²ŠµŠ“ёт срŠµŠ“Š½ŠµŠ¹ сŠøŠ»Ń‹ рŠ°Š·Ń€ŃŠ“ эŠ»ŠµŠŗтрŠøчŠµŃŃ‚Š²Š°. " +"Š›ŃƒŃ‡ŃˆŠµ Š¾Ń‚ Š½ŠµŃ‘ ŠøŠ·Š±Š°Š²Šøться ŠŗŠ°Šŗ Š¼Š¾Š¶Š½Š¾ сŠŗŠ¾Ń€ŠµŠµ!" #: lang/json/TOOL_from_json.py msgid "incendiary grenade" @@ -115353,8 +115628,8 @@ msgstr "Š’Ń‹ устŠ°Š½Š¾Š²ŠøŠ»Šø Š»Š¾Š²ŃƒŃˆŠŗу с Š“рŠ¾Š±Š¾Š²ŠøŠŗŠ¾Š¼." #. ~ Description for {'str': 'shotgun trap'} #: lang/json/TOOL_from_json.py msgid "" -"This is a simple tripwire is attached to the trigger of a loaded double-" -"barreled shotgun. When pulled, the shotgun fires. Two shells are loaded; " +"This is a simple tripwire is attached to the trigger of a loaded double " +"slamfire shotgun. When pulled, the shotgun fires. Two shells are loaded; " "the first time the trigger is pulled, one or both shells may be discharged." msgstr "" "ŠŸŃ€Š¾ŃŃ‚Š°Ń рŠ°ŃŃ‚яŠ¶ŠŗŠ°, ŠæрŠøсŠ¾ŠµŠ“ŠøŠ½Ń‘Š½Š½Š°Ń Šŗ сŠæусŠŗŠ¾Š²Ń‹Š¼ ŠŗрючŠŗŠ°Š¼ Š“Š²ŃƒŃŃ‚Š²Š¾Š»ŠŗŠø. ŠšŠ¾Š³Š“Š° " @@ -123792,6 +124067,26 @@ msgstr "Š£ŃŠøŠ»Šøть стŠµŠ½Ńƒ ŠøŠ· Š¼ŠµŃ‚Š°Š»Š»Š¾Š»Š¾Š¼Š° с ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ msgid "Build Junk Metal Floor" msgstr "ŠŸŠ¾ŃŃ‚Ń€Š¾Šøть ŠæŠ¾Š» ŠøŠ· Š¼ŠµŃ‚Š°Š»Š»Š¾Š»Š¾Š¼Š°" +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Bolts" +msgstr "ŠŸŠ¾ŃŃ‚Ń€Š¾Šøть Š¼Š¾ŃŃ‚ ŠøŠ· Š¼ŠµŃ‚Š°Š»Š»Š¾Š»Š¾Š¼Š°, ŠøсŠæŠ¾Š»ŃŒŠ·ŃƒŃ Š±Š¾Š»Ń‚Ń‹" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Welder" +msgstr "ŠŸŠ¾ŃŃ‚Ń€Š¾Šøть Š¼Š¾ŃŃ‚ ŠøŠ· Š¼ŠµŃ‚Š°Š»Š»Š¾Š»Š¾Š¼Š°, ŠøсŠæŠ¾Š»ŃŒŠ·ŃƒŃ сŠ²Š°Ń€Šŗу" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bench" +msgstr "ŠŸŠ¾ŃŃ‚Š°Š²Šøть сŠŗŠ°Š¼ŃŒŃŽ ŠøŠ· Š¼ŠµŃ‚Š°Š»Š»Š¾Š»Š¾Š¼Š°" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Table" +msgstr "ŠŸŠ¾ŃŃ‚Š°Š²Šøть стŠ¾Š» ŠøŠ· Š¼ŠµŃ‚Š°Š»Š»Š¾Š»Š¾Š¼Š°" + +#: lang/json/construction_from_json.py +msgid "Lay down decorative ground cable" +msgstr "ŠŸŃ€Š¾Š»Š¾Š¶Šøть Š½Š°ŠæŠ¾Š»ŃŒŠ½Ń‹Š¹ ŠŗŠ°Š±ŠµŠ»ŃŒ" + #: lang/json/construction_from_json.py msgid "Build Pillow Fort" msgstr "ŠŸŠ¾ŃŃ‚Ń€Š¾Šøть фŠ¾Ń€Ń‚ ŠøŠ· ŠæŠ¾Š“ушŠµŠŗ" @@ -126389,6 +126684,15 @@ msgstr "Š’Ń‹ Š²Š¾ŃŃŃ‚Š°Š½Š°Š²Š»ŠøŠ²Š°ŠµŃ‚Šµ ŠŗŠ¾Š½Ń‚Ń€Š¾Š»ŃŒ Š½Š°Š“ сŠ²Š¾ŠøŠ¼ msgid "Your muscles won't cooperate!" msgstr "Š’Š°ŃˆŠø Š¼Ń‹ŃˆŃ†Ń‹ Š½Šµ сŠŗŠ¾Š¾Ń€Š“ŠøŠ½ŠøрŠ¾Š²Š°Š½Ń‹!" +#: lang/json/effects_from_json.py +msgid "Minor Bleeding" +msgstr "Š”Š»Š°Š±Š¾Šµ ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠŗ" + +#. ~ Description of effect 'Minor Bleeding'. +#: lang/json/effects_from_json.py +msgid "Tis but a scratch." +msgstr "Š­Ń‚Š¾ тŠ¾Š»ŃŒŠŗŠ¾ цŠ°Ń€Š°ŠæŠøŠ½Š°." + #: lang/json/effects_from_json.py msgid "Bleeding" msgstr "ŠšŃ€Š¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ" @@ -126416,7 +126720,25 @@ msgstr "ŠžŠ±ŠøŠ»ŃŒŠ½Š¾Šµ ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ" msgid "You are rapidly losing blood." msgstr "Š’Ń‹ Š±Ń‹ŃŃ‚Ń€Š¾ тŠµŃ€ŃŠµŃ‚Šµ ŠŗрŠ¾Š²ŃŒ." -#. ~ Apply message for effect(s) 'Bleeding, Bad Bleeding, Heavy Bleeding'. +#: lang/json/effects_from_json.py +msgid "Heavy Arterial Bleeding" +msgstr "Š¢ŃŠ¶Ń‘Š»Š¾Šµ Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Š¾Šµ ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ" + +#. ~ Description of effect 'Heavy Arterial Bleeding'. +#: lang/json/effects_from_json.py +msgid "Blood is gushing from you like a fountain." +msgstr "ŠšŃ€Š¾Š²ŃŒ хŠ»ŠµŃ‰ŠµŃ‚ ŠøŠ· Š²Š°Ń фŠ¾Š½Ń‚Š°Š½Š¾Š¼." + +#. ~ Apply message for effect(s) 'Minor Bleeding, Minor Bleeding, Minor +#. Bleeding, Minor Bleeding, Minor Bleeding, Bleeding, Bleeding, Bleeding, +#. Bleeding, Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, +#. Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad +#. Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, +#. Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy +#. Bleeding, Heavy Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding'. #: lang/json/effects_from_json.py msgid "You're bleeding!" msgstr "Š’Ń‹ ŠøстŠµŠŗŠ°ŠµŃ‚Šµ ŠŗрŠ¾Š²ŃŒŃŽ!" @@ -127188,40 +127510,98 @@ msgstr "" "Š’Š°ŃˆŠø ŠŗŠ¾ŃŃ‚Šø стŠ°Š½Š¾Š²ŃŃ‚ся ŠæрŠ¾Ń‡Š½ŠµŠµ, ŠæŠ¾ŃŠŗŠ¾Š»ŃŒŠŗу урŠ¾Š²ŠµŠ½ŃŒ ŠŗŠ°Š»ŃŒŃ†Šøя Š² Š¾Ń€Š³Š°Š½ŠøŠ·Š¼Šµ " "ŠæрŠøхŠ¾Š“Šøт Š² Š½Š¾Ń€Š¼Ńƒ." +#: lang/json/effects_from_json.py +msgid "Early iron deficiency" +msgstr "Š Š°Š½Š½ŃŃ стŠ°Š“Šøя Š“ŠµŃ„ŠøцŠøтŠ° Š¶ŠµŠ»ŠµŠ·Š°" + +#. ~ Description of effect 'Early iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"A lack of iron in your diet has hampered efficiency and regeneration of your" +" red blood cells." +msgstr "" +"Š”ŠµŃ„ŠøцŠøт Š¶ŠµŠ»ŠµŠ·Š° Š² Š²Š°ŃˆŠµŠ¼ Š¾Ń€Š³Š°Š½ŠøŠ·Š¼Šµ ŠæŠ¾Š½ŠøŠ·ŠøŠ» эффŠµŠŗтŠøŠ²Š½Š¾ŃŃ‚ŃŒ рŠ°Š±Š¾Ń‚Ń‹ Šø сŠŗŠ¾Ń€Š¾ŃŃ‚ŃŒ " +"Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Šøя Š²Š°ŃˆŠøх ŠŗрŠ°ŃŠ½Ń‹Ń… ŠŗрŠ¾Š²ŃŠ½Ń‹Ń… тŠµŠ»ŠµŃ†." + #: lang/json/effects_from_json.py msgid "Iron deficiency" msgstr "Š”ŠµŃ„ŠøцŠøт Š¶ŠµŠ»ŠµŠ·Š°" +#. ~ Description of effect 'Iron deficiency'. #: lang/json/effects_from_json.py -msgid "Early anemia" -msgstr "Š Š°Š½Š½ŃŃ Š°Š½ŠµŠ¼Šøя" +msgid "" +"Prolonged lack of iron in your diet has compromised efficiency and " +"regeneration of your red blood cells." +msgstr "" +"Š”Š»ŠøтŠµŠ»ŃŒŠ½Ń‹Š¹ Š“ŠµŃ„ŠøцŠøт Š¶ŠµŠ»ŠµŠ·Š° Š² Š²Š°ŃˆŠµŠ¼ рŠ°Ń†ŠøŠ¾Š½Šµ сŠµŃ€ŃŒŠµŠ·Š½Š¾ сŠ½ŠøŠ·ŠøŠ» эффŠµŠŗтŠøŠ²Š½Š¾ŃŃ‚ŃŒ Šø " +"сŠŗŠ¾Ń€Š¾ŃŃ‚ŃŒ Š²Š¾ŃŃŃ‚Š°Š½Š¾Š²Š»ŠµŠ½Šøя Š²Š°ŃˆŠøх ŠŗрŠ°ŃŠ½Ń‹Ń… ŠŗрŠ¾Š²ŃŠ½Ń‹Ń… ŠŗŠ»ŠµŃ‚Š¾Šŗ." #: lang/json/effects_from_json.py -msgid "Anemia" -msgstr "ŠŠ½ŠµŠ¼Šøя" +msgid "Acute iron deficiency" +msgstr "ŠžŃŃ‚рыŠ¹ Š“ŠµŃ„ŠøцŠøт Š¶ŠµŠ»ŠµŠ·Š°" +#. ~ Description of effect 'Acute iron deficiency'. #: lang/json/effects_from_json.py msgid "" -"A lack of iron in your diet will result in progressively worsening anemia." +"Severe lack of iron in your diet results in your red blood cells dying " +"faster then they are regenerating." msgstr "" -"Š”ŠµŃ„ŠøцŠøт Š¶ŠµŠ»ŠµŠ·Š° Š² Š²Š°ŃˆŠµŠ¹ Š“ŠøŠµŃ‚Šµ ŠæрŠøŠ²Ń‘Š“ŠµŃ‚ Šŗ ŠæŠ¾ŃŃ‚Š¾ŃŠ½Š½Š¾ усŠøŠ»ŠøŠ²Š°ŃŽŃ‰ŠµŠ¹ŃŃ Š°Š½ŠµŠ¼ŠøŠø." +"Š¢ŃŠ¶Ń‘Š»Ń‹Š¹ Š“ŠµŃ„ŠøцŠøт Š¶ŠµŠ»ŠµŠ·Š° ŠæрŠøŠ²Ń‘Š» Šŗ тŠ¾Š¼Ńƒ, чтŠ¾ Š²Š°ŃˆŠø ŠŗрŠ°ŃŠ½Ń‹Šµ ŠŗрŠ¾Š²ŃŠ½Ń‹Šµ ŠŗŠ»ŠµŃ‚ŠŗŠø " +"уŠ¼ŠøрŠ°ŃŽŃ‚ Š±Ń‹ŃŃ‚Ń€ŠµŠµ, чŠµŠ¼ ŠæрŠ¾ŠøŠ·Š²Š¾Š“ятся." -#. ~ Apply message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Apply message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#. ~ Apply message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You begin feeling increasingly tired and listless." msgstr "Š’Ń‹ Š½Š°Ń‡ŠøŠ½Š°ŠµŃ‚Šµ чуŠ²ŃŃ‚Š²Š¾Š²Š°Ń‚ŃŒ сŠµŠ±Ń Š²ŃŃ‘ Š±Š¾Š»ŠµŠµ устŠ°Š»Ń‹Š¼ Šø Š°ŠæŠ°Ń‚ŠøчŠ½Ń‹Š¼." -#. ~ Remove message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Remove message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "You are no longer in risk of becoming anemic." +msgstr "Š’Ń‹ Š±Š¾Š»ŃŒŃˆŠµ Š½Šµ ŠæŠ¾Š“Š²ŠµŃ€Š³Š°ŠµŃ‚ŠµŃŃŒ рŠøсŠŗу Š°Š½ŠµŠ¼ŠøŠø." + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your irom deficiency is nearly resolved." +msgstr "Š”ŠµŃ„ŠøцŠøт Š¶ŠµŠ»ŠµŠ·Š° ŠæрŠ°ŠŗтŠøчŠµŃŠŗŠø устрŠ°Š½Ń‘Š½." + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your iron deficiency starts to improve." +msgstr "Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ сŠµŠ±Ń сŠøŠ»ŃŒŠ½ŠµŠµ, ŠæŠ¾ŃŠŗŠ¾Š»ŃŒŠŗу Š“ŠµŃ„ŠøцŠøт Š¶ŠµŠ»ŠµŠ·Š° ŠøŠ“ёт Š½Š° уŠ±Ń‹Š»ŃŒ." + +#: lang/json/effects_from_json.py +msgid "Early anemia" +msgstr "Š Š°Š½Š½ŃŃ Š°Š½ŠµŠ¼Šøя" + +#: lang/json/effects_from_json.py +msgid "Anemia" +msgstr "ŠŠ½ŠµŠ¼Šøя" + +#: lang/json/effects_from_json.py +msgid "Acute anemia" +msgstr "ŠžŃŃ‚Ń€Š°Ń Š°Š½ŠµŠ¼Šøя" + +#: lang/json/effects_from_json.py +msgid "Loss of red blood cells results in progressively worsening anemia." +msgstr "" +"ŠŠµŠ“Š¾ŃŃ‚Š°Ń‚Š¾Šŗ ŠŗрŠ°ŃŠ½Ń‹Ń… ŠŗрŠ¾Š²ŃŠ½Ń‹Ń… тŠµŠ»ŠµŃ† Š²ŠµŠ“ёт Šŗ ŠæŠ¾ŃŃ‚Š¾ŃŠ½Š½Š¾ усŠøŠ»ŠøŠ²Š°ŃŽŃ‰ŠµŠ¹ŃŃ Š°Š½ŠµŠ¼ŠøŠø." + +#. ~ Remove message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You no longer feel anemic." msgstr "Š’Ń‹ Š±Š¾Š»ŃŒŃˆŠµ Š½Šµ стрŠ°Š“Š°ŠµŃ‚Šµ Š¾Ń‚ Š°Š½ŠµŠ¼ŠøŠø." -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py -msgid "Your iron deficiency is nearly resolved." -msgstr "Š”ŠµŃ„ŠøцŠøт Š¶ŠµŠ»ŠµŠ·Š° ŠæрŠ°ŠŗтŠøчŠµŃŠŗŠø устрŠ°Š½Ń‘Š½." +msgid "Your anemia is nearly resolved." +msgstr "Š’Š°ŃˆŠ° Š°Š½ŠµŠ¼Šøя ŠæрŠ°ŠŗтŠøчŠµŃŠŗŠø устрŠ°Š½ŠµŠ½Š°." -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "Your feel stronger as your anemia starts to improve." msgstr "Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ сŠµŠ±Ń сŠøŠ»ŃŒŠ½ŠµŠµ, ŠæŠ¾ŃŠŗŠ¾Š»ŃŒŠŗу Š°Š½ŠµŠ¼Šøя ŠøŠ“ёт Š½Š° уŠ±Ń‹Š»ŃŒ." @@ -127419,6 +127799,84 @@ msgstr "" "ŠšŠ¾Š½ŠµŃ‡Š½Š¾, Š²Ń‹ Š¶ŠøŠ²Ń‹, Š½Š¾ рŠ°Š·Š²Šµ этŠ¾ Š¶ŠøŠ·Š½ŃŒ ā€” ŠµŃŃ‚ŃŒ Š¾Ń‚Š²Ń€Š°Ń‚ŠøтŠµŠ»ŃŒŠ½ŃƒŃŽ ŠæŠøщу ŠøŠ·Š¾ Š“Š½Ń Š² " "Š“ŠµŠ½ŃŒ?" +#: lang/json/effects_from_json.py +msgid "Mild hypovolemic shock" +msgstr "Š›ŠµŠ³ŠŗŠøŠ¹ Š³ŠøŠæŠ¾Š²Š¾Š»ŠµŠ¼ŠøчŠµŃŠŗŠøŠ¹ шŠ¾Šŗ" + +#. ~ Description of effect 'Mild hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost some blood and look somewhat pale." +msgstr "Š’Ń‹ ŠæŠ¾Ń‚ŠµŃ€ŃŠ»Šø Š½ŠµŠ¼Š½Š¾Š³Š¾ ŠŗрŠ¾Š²Šø Šø Š²Ń‹Š³Š»ŃŠ“ŠøтŠµ Š±Š»ŠµŠ“Š½ŠµŠµ Š¾Š±Ń‹Ń‡Š½Š¾Š³Š¾" + +#: lang/json/effects_from_json.py +msgid "Moderate hypovolemic shock" +msgstr "Š“ŠøŠæŠ¾Š²Š¾Š»ŠµŠ¼ŠøчŠµŃŠŗŠøŠ¹ шŠ¾Šŗ" + +#. ~ Description of effect 'Moderate hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost large amount of blood, and you're not feeling well." +msgstr "Š’Ń‹ ŠæŠ¾Ń‚ŠµŃ€ŃŠ»Šø Š±Š¾Š»ŃŒŃˆŠ¾Šµ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ ŠŗрŠ¾Š²Šø, Šø Š²Š°Š¼ Š½ŠµŃ…Š¾Ń€Š¾ŃˆŠ¾." + +#: lang/json/effects_from_json.py +msgid "Advanced hypovolemic shock" +msgstr "Š”ŠøŠ»ŃŒŠ½Ń‹Š¹ Š³ŠøŠæŠ¾Š²Š¾Š»ŠµŠ¼ŠøчŠµŃŠŗŠøŠ¹ шŠ¾Šŗ" + +#. ~ Description of effect 'Advanced hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost an awful lot of blood, and your condition is severe. Seek " +"medical attention." +msgstr "" +"Š’Ń‹ ŠæŠ¾Ń‚ŠµŃ€ŃŠ»Šø Š¾Ń‡ŠµŠ½ŃŒ Š¼Š½Š¾Š³Š¾ ŠŗрŠ¾Š²Šø, Šø Š²Š°ŃˆŠµ сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ тяŠ¶ŠµŠ»Š¾Šµ. Š’Š°Š¼ трŠµŠ±ŃƒŠµŃ‚ся " +"Š¼ŠµŠ“ŠøцŠøŠ½ŃŠŗŠ°Ń ŠæŠ¾Š¼Š¾Ń‰ŃŒ." + +#: lang/json/effects_from_json.py +msgid "Severe hypovolemic shock" +msgstr "Š”ŠµŃ€ŃŒŃ‘Š·Š½Ń‹Š¹ Š³ŠøŠæŠ¾Š²Š¾Š»ŠµŠ¼ŠøчŠµŃŠŗŠøŠ¹ шŠ¾Šŗ" + +#. ~ Description of effect 'Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost tremendous amount of blood, and you're standing on death's door." +" Transfusion might save you." +msgstr "" +"Š’Ń‹ ŠæŠ¾Ń‚ŠµŃ€ŃŠ»Šø чŠµŃ€Ń‚Š¾Š²ŃŠŗŠø Š¼Š½Š¾Š³Š¾ ŠŗрŠ¾Š²Šø, Šø сŠ¼ŠµŃ€Ń‚ŃŒ уŠ¶Šµ Š±Š»ŠøŠ·ŠŗŠ°. Š’Š°Ń Š¼Š¾Š¶ŠµŃ‚ сŠæŠ°ŃŃ‚Šø " +"ŠæŠµŃ€ŠµŠ»ŠøŠ²Š°Š½ŠøŠµ ŠŗрŠ¾Š²Šø." + +#. ~ Apply message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You have lost lot of blood, and your condition worsens." +msgstr "Š’Ń‹ ŠæŠ¾Ń‚ŠµŃ€ŃŠ»Šø Š±Š¾Š»ŃŒŃˆŠ¾Šµ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ ŠŗрŠ¾Š²Šø, Šø Š²Š°ŃˆŠµ сŠ¾ŃŃ‚Š¾ŃŠ½ŠøŠµ ухуŠ“шŠ°ŠµŃ‚ся." + +#. ~ Remove message for effect(s) 'Mild hypovolemic shock, Moderate +#. hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You are no longer in shock." +msgstr "Š’Ń‹ шŠ¾Šŗ Š¾Ń‚ ŠŗрŠ¾Š²Š¾ŠæŠ¾Ń‚ŠµŃ€Šø Š¾Ń‚ŃŃ‚ŃƒŠæŠ°ŠµŃ‚." + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your blood level increase, and you feel better, but still look pale." +msgstr "" +"Š’Š°Ńˆ урŠ¾Š²ŠµŠ½ŃŒ ŠŗрŠ¾Š²Šø Š²Š¾Š·Š²Ń€Š°Ń‰Š°ŠµŃ‚ся Šŗ Š½Š¾Ń€Š¼Šµ, Šø Š²Ń‹ чуŠ²ŃŃ‚Š²ŠµŃ‚Šµ сŠµŠ±Ń Š»ŃƒŃ‡ŃˆŠµ, Š½Š¾ Š²ŃŃ‘ " +"ŠµŃ‰Ń‘ Š±Š»ŠµŠ“Š½Š¾Š²Š°Ń‚Ń‹." + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your blood levels starts to improve." +msgstr "Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ сŠµŠ±Ń сŠøŠ»ŃŒŠ½ŠµŠµ, ŠæŠ¾ŃŠŗŠ¾Š»ŃŒŠŗу Š“ŠµŃ„ŠøцŠøт ŠŗрŠ¾Š²Šø ŠøŠ“ёт Š½Š° уŠ±Ń‹Š»ŃŒ." + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You're not dying from lack of blood, but you're not out of the woods yet." +msgstr "" +"Š’Š°Š¼ Š½Šµ Š³Ń€Š¾Š·Šøт сŠ¼ŠµŃ€Ń‚ŃŒ Š¾Ń‚ ŠŗрŠ¾Š²Š¾ŠæŠ¾Ń‚ŠµŃ€Šø, Š½Š¾ Š“Š¾ ŠøŠ“ŠµŠ°Š»ŃŒŠ½Š¾Š³Š¾ сŠ¾ŃŃ‚Š¾ŃŠ½Šøя ŠµŃ‰Ń‘ Š“Š°Š»ŠµŠŗŠ¾." + #: lang/json/effects_from_json.py msgid "Lit up" msgstr "ŠžŃŠ²ŠµŃ‰Ń‘Š½" @@ -129401,6 +129859,411 @@ msgstr "ŠæŠ»Š¾Ń‚Š½Š°Ń ŠæŠ°ŃƒŃ‚ŠøŠ½Š° ŠøŠ· Š¶Š²Š°Ń‡ŠŗŠø" msgid "mutated cactus" msgstr "Š¼ŃƒŃ‚ŠøрŠ¾Š²Š°Š²ŃˆŠøŠ¹ ŠŗŠ°Šŗтус" +#: lang/json/furniture_from_json.py +msgid "glowing tendril" +msgstr "сŠ²ŠµŃ‚ŃŃ‰ŠøŠ¹ŃŃ Š¶Š³ŃƒŃ‚ŠøŠŗ" + +#. ~ Description for glowing tendril +#: lang/json/furniture_from_json.py +msgid "" +"A willowy tendril growing from the floor, gently waving back and forth. A " +"faint light spills from it." +msgstr "" +"Š˜Š·ŃŃ‰Š½Ń‹Š¹ Š¶Š³ŃƒŃ‚ŠøŠŗ, рŠ°ŃŃ‚ŃƒŃ‰ŠøŠ¹ ŠøŠ· ŠæŠ¾Š»Š°. ŠžŠ½ Š¼ŃŠ³ŠŗŠ¾ ŠŗŠ¾Š»Ń‹ŃˆŠµŃ‚ся Š²Š·Š°Š“ Šø Š²ŠæŠµŃ€Ń‘Š“. Š˜Š· Š½ŠµŠ³Š¾ " +"ŠæрŠ¾Š»ŠøŠ²Š°ŠµŃ‚ся тусŠŗŠ»Ń‹Š¹ сŠ²ŠµŃ‚." + +#: lang/json/furniture_from_json.py +msgid "splorch!" +msgstr "шŠ¼ŃŠŗ!" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "whump!" +msgstr "Ā«Š±ŃƒŠ¼!Ā»" + +#: lang/json/furniture_from_json.py +msgid "wafting anemone" +msgstr "ŠæŠ°Ń€ŃŃ‰ŠøŠ¹ Š°Š½ŠµŠ¼Š¾Š½" + +#. ~ Description for wafting anemone +#: lang/json/furniture_from_json.py +msgid "" +"A fleshy white protuberance growing from the floor, with a cluster of " +"tendrils pouring out of it. It looks almost exactly like a sea anemone, " +"even waving gently as though underwater." +msgstr "" +"Š Š°ŃŃ‚ŃƒŃ‰ŠøŠ¹ ŠøŠ· ŠæŠ¾Š»Š° Š¼ŃŃŠøстыŠ¹ Š±ŠµŠ»Ń‹Š¹ Š±ŃƒŠ³Š¾Ń€Š¾Šŗ с ŠæучŠŗŠ¾Š¼ Š²Ń‹Š»ŠøŠ²Š°ŃŽŃ‰Šøхся щуŠæŠ°Š»ŠµŃ†. ŠžŠ½ " +"Š¾Ń‡ŠµŠ½ŃŒ ŠæŠ¾Ń…Š¾Š¶ Š½Š° Š¼Š¾Ń€ŃŠŗŠ¾Š¹ Š°Š½ŠµŠ¼Š¾Š½, Š“Š°Š¶Šµ Š¼ŃŠ³ŠŗŠ¾ ŠŗŠ¾Š»Ń‹ŃˆŠµŃ‚ся, ŠŗŠ°Šŗ Š±ŃƒŠ“тŠ¾ ŠæŠ¾Š“ Š²Š¾Š“Š¾Š¹." + +#: lang/json/furniture_from_json.py +msgid "gasping tube" +msgstr "ŠæыхтящŠ°Ń труŠ±ŠŗŠ°" + +#. ~ Description for gasping tube +#: lang/json/furniture_from_json.py +msgid "" +"This is a meaty green stalactite with a thickened hide like that of a " +"starfish, extending from the floor to the ceiling. In the center is a " +"series of ports somewhat like mouths, from which pour bursts of a vile-" +"smelling gas." +msgstr "" +"ŠœŃŃŠøстыŠ¹ Š·ŠµŠ»Ń‘Š½Ń‹Š¹ стŠ°Š»Š°ŠŗтŠøт с тŠ¾Š»ŃŃ‚Š¾Š¹ шŠŗурŠ¾Š¹, ŠæŠ¾Ń…Š¾Š¶ŠµŠ¹ Š½Š° ŠŗŠ¾Š¶Ńƒ Š¼Š¾Ń€ŃŠŗŠ¾Š¹ Š·Š²ŠµŠ·Š“ы," +" рŠ°ŃŃ‚ŃƒŃ‰ŠøŠ¹ с ŠæŠ¾Š»Š° Š“Š¾ ŠæŠ¾Ń‚Š¾Š»ŠŗŠ°. Š’ ŠµŠ³Š¾ сŠµŃ€ŠµŠ“ŠøŠ½Šµ ŠµŃŃ‚ŃŒ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ рŠ¾Ń‚Š¾ŠæŠ¾Š“Š¾Š±Š½Ń‹Ń… " +"Š¾Ń‚Š²ŠµŃ€ŃŃ‚ŠøŠ¹, ŠøŠ·Š²ŠµŃ€Š³Š°ŃŽŃ‰Šøх ŠŗŠ»ŃƒŠ±Ń‹ Š·Š»Š¾Š²Š¾Š½Š½Š¾Š³Š¾ Š³Š°Š·Š°." + +#: lang/json/furniture_from_json.py +msgid "twitching frond" +msgstr "Š“ёрŠ³Š°ŃŽŃ‰Š°ŃŃŃ Š²ŠµŃ‚ŠŗŠ°" + +#. ~ Description for twitching frond +#: lang/json/furniture_from_json.py +msgid "" +"A spine resembling moth antennae juts from the ground, swaying gently in the" +" air. Every so often, a cascade of energy arcs along it and discharges into" +" the ceiling." +msgstr "" +"ŠŸŠ¾Ń…Š¾Š¶ŠøŠ¹ Š½Š° усŠøŠŗ Š¼Š¾Ń‚Ń‹Š»ŃŒŠŗŠ° Š¾Ń‚Ń€Š¾ŃŃ‚Š¾Šŗ, Š²Ń‹ŠæŠøрŠ°ŃŽŃ‰ŠøŠ¹ ŠøŠ· Š·ŠµŠ¼Š»Šø. ŠžŠ½ Š¼ŃŠ³ŠŗŠ¾ ŠŗŠ¾Š»Ń‹ŃˆŠµŃ‚ся " +"Š½Š° Š²ŠµŃ‚Ń€Ńƒ. ŠŸŠµŃ€ŠøŠ¾Š“ŠøчŠµŃŠŗŠø ŠæŠ¾ Š½ŠµŠ¼Ńƒ ŠæрŠ¾Š±ŠµŠ³Š°ŠµŃ‚ эŠ½ŠµŃ€Š³ŠµŃ‚ŠøчŠµŃŠŗŠøŠ¹ рŠ°Š·Ń€ŃŠ“, ŠøсчŠµŠ·Š°Ń Š² " +"ŠæŠ¾Ń‚Š¾Š»ŠŗŠµ." + +#: lang/json/furniture_from_json.py +msgid "scarred lump" +msgstr "Š¾ŠæухŠ¾Š»ŃŒ сŠ¾ шрŠ°Š¼Š°Š¼Šø" + +#. ~ Description for scarred lump +#: lang/json/furniture_from_json.py +msgid "" +"This is a pile of nondescript alien flesh, twitching and belching strange " +"gases out of injured orifices." +msgstr "" +"ŠšŃƒŃ‡Š° Š½ŠµŠ¾ŠæŠøсуŠµŠ¼Š¾Š¹ Š“ёрŠ³Š°ŃŽŃ‰ŠµŃŃ ŠøŠ½Š¾ŠæŠ»Š°Š½ŠµŃ‚Š½Š¾Š¹ ŠæŠ»Š¾Ń‚Šø, ŠøŠ·Ń€Ń‹Š³Š°ŃŽŃ‰Š°Ń стрŠ°Š½Š½Ń‹Šµ Š³Š°Š·Ń‹ ŠøŠ· " +"ŠæŠ¾Š²Ń€ŠµŠ¶Š“ёŠ½Š½Ń‹Ń… Š¾Ń€Š³Š°Š½Š¾Š²." + +#: lang/json/furniture_from_json.py +msgid "splat!" +msgstr "Ā«ŃˆŠ»Ń‘Šæ!Ā»" + +#: lang/json/furniture_from_json.py +msgid "slimy pod" +msgstr "сŠ»ŠøŠ·ŠøстыŠ¹ ŠŗŠ¾ŠŗŠ¾Š½" + +#. ~ Description for slimy pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a slick, translucent pod suspended on a thin stalk. It is covered " +"in a thick mucus, obscuring whatever is floating in the gel-like substance " +"inside." +msgstr "" +"Š”ŠŗŠ¾Š»ŃŒŠ·ŠŗŠøŠ¹ ŠæŠ¾Š»ŃƒŠæрŠ¾Š·Ń€Š°Ń‡Š½Ń‹Š¹ ŠŗŠ¾ŠŗŠ¾Š½, ŠæŠ¾Š“Š²ŠµŃˆŠµŠ½Š½Ń‹Š¹ Š½Š° тŠ¾Š½ŠŗŠ¾Š¼ стŠµŠ±ŠµŠ»ŃŒŠŗŠµ. ŠžŠ½ ŠæŠ¾Šŗрыт " +"Š³ŃƒŃŃ‚Š¾Š¹ сŠ»ŠøŠ·ŃŒŃŽ, сŠŗрыŠ²Š°ŃŽŃ‰ŠµŠ¹ ŠæŠ»Š°Š²Š°ŃŽŃ‰ŠµŠµ Š² Š³ŠµŠ»ŠµŠ¾Š±Ń€Š°Š·Š½Š¾Š¼ Š²ŠµŃ‰ŠµŃŃ‚Š²Šµ сŠ¾Š“ŠµŃ€Š¶ŠøŠ¼Š¾Šµ." + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "whump." +msgstr "Ā«Š±ŃƒŠ¼Ā»." + +#: lang/json/furniture_from_json.py +msgid "organ pod" +msgstr "ŠŗŠ¾ŠŗŠ¾Š½ с Š¾Ń€Š³Š°Š½Š°Š¼Šø" + +#. ~ Description for organ pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside you can see the" +" dimly outlined shape of human organs, floating in some kind of preservative" +" goo." +msgstr "" +"ŠŸŠ¾Š»ŃƒŠæрŠ¾Š·Ń€Š°Ń‡Š½Ń‹Š¹ ŠŗŠ¾ŠŗŠ¾Š½, ŠæŠ¾Š“Š²ŠµŃˆŠµŠ½Š½Ń‹Š¹ Š½Š° тŠ¾Š½ŠŗŠ¾Š¼ стŠµŠ±ŠµŠ»ŃŒŠŗŠµ. Š’Š½ŃƒŃ‚Ń€Šø Š²ŠøŠ“Š½Š¾ сŠ¼ŃƒŃ‚Š½Ń‹Šµ " +"Š¾Ń‡ŠµŃ€Ń‚Š°Š½Šøя чŠµŠ»Š¾Š²ŠµŃ‡ŠµŃŠŗŠøх Š¾Ń€Š³Š°Š½Š¾Š², ŠæŠ»Š°Š²Š°ŃŽŃ‰Šøх Š² ŠŗŠ°ŠŗŠ¾Š¹-тŠ¾ ŠŗŠ¾Š½ŃŠµŃ€Š²ŠøрующŠµŠ¹ сŠ»ŠøŠ·Šø." + +#: lang/json/furniture_from_json.py +msgid "resin pod" +msgstr "ŠŗŠ¾ŠŗŠ¾Š½ сŠ¾ сŠ¼Š¾Š»Š¾Š¹" + +#. ~ Description for resin pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside is a clean, " +"clear resinous-looking fluid. You could fairly easily tear it from the " +"stalk and take it with you." +msgstr "" +"ŠŸŠ¾Š»ŃƒŠæрŠ¾Š·Ń€Š°Ń‡Š½Ń‹Š¹ ŠŗŠ¾ŠŗŠ¾Š½, ŠæŠ¾Š“Š²ŠµŃˆŠµŠ½Š½Ń‹Š¹ Š½Š° тŠ¾Š½ŠŗŠ¾Š¼ стŠµŠ±ŠµŠ»ŃŒŠŗŠµ. Š’Š½ŃƒŃ‚Ń€Šø Š²ŠøŠ“Š½Š¾ чŠøстую " +"ŠæрŠ¾Š·Ń€Š°Ń‡Š½ŃƒŃŽ сŠ¼Š¾Š»Šøстую Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚ŃŒ. Š’Ń‹ Š¼Š¾Š¶ŠµŃ‚Šµ Š¾Ń‚Š½Š¾ŃŠøтŠµŠ»ŃŒŠ½Š¾ Š»ŠµŠ³ŠŗŠ¾ Š¾Ń‚Š¾Ń€Š²Š°Ń‚ŃŒ ŠŗŠ¾ŠŗŠ¾Š½ " +"Š¾Ń‚ стŠµŠ±ŠµŠ»ŃŒŠŗŠ° Šø Š·Š°Š±Ń€Š°Ń‚ŃŒ с сŠ¾Š±Š¾Š¹." + +#: lang/json/furniture_from_json.py +msgid "fleshy altar" +msgstr "Š¼ŃŃŠøстыŠ¹ Š°Š»Ń‚Š°Ń€ŃŒ" + +#. ~ Description for fleshy altar +#: lang/json/furniture_from_json.py +msgid "" +"This pulsing protuberance juts from the floor, its sides covered in scaled, " +"oozing skin. The surface is flat, but undulates softly. A handful of " +"unidentifiable appendages reach from the sides, suggesting a sort of " +"nightmarish living autodoc." +msgstr "" +"ŠŸŃƒŠ»ŃŒŃŠøрующŠøŠ¹ Š²Ń‹ŃŃ‚ŃƒŠæ, ŠæрŠ¾Ń€Š°ŃŃ‚Š°ŃŽŃ‰ŠøŠ¹ ŠøŠ· ŠæŠ¾Š»Š°, ŠµŠ³Š¾ стŠµŠ½ŠŗŠø ŠæŠ¾Šŗрыты чŠµŃˆŃƒŠ¹Ń‡Š°Ń‚Š¾Š¹ " +"ŠøстŠµŠŗŠ°ŃŽŃ‰ŠµŠ¹ сŠ»ŠøŠ·ŃŒŃŽ ŠŗŠ¾Š¶ŠµŠ¹. Š£ Š½ŠµŠ³Š¾ ŠæŠ»Š¾ŃŠŗŠ°Ń Š¼ŃŠ³ŠŗŠ¾ ŠŗŠ¾Š»Ń‹Ń…Š°ŃŽŃ‰Š°ŃŃŃ ŠæŠ¾Š²ŠµŃ€Ń…Š½Š¾ŃŃ‚ŃŒ. ŠŸŠ¾ " +"стŠ¾Ń€Š¾Š½Š°Š¼ ŠµŃŃ‚ŃŒ Š¼Š½Š¾Š¶ŠµŃŃ‚Š²Š¾ Š½ŠµŠæŠ¾Š½ŃŃ‚Š½Ń‹Ń… ŠŗŠ¾Š½ŠµŃ‡Š½Š¾ŃŃ‚ŠµŠ¹, Š½Š°ŠæŠ¾Š¼ŠøŠ½Š°ŃŽŃ‰Šøх ŠŗŠ¾ŃˆŠ¼Š°Ń€Š½Ń‹Š¹ Š¶ŠøŠ²Š¾Š¹" +" Š°Š²Ń‚Š¾Š“Š¾Šŗ." + +#: lang/json/furniture_from_json.py +msgid "scrap antenna" +msgstr "сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Š°Ń Š°Š½Ń‚ŠµŠ½Š½Š°" + +#. ~ Description for scrap antenna +#: lang/json/furniture_from_json.py +msgid "" +"This contraption looks like some sort of cobbled-together transmitter or " +"receiver antenna. It consists of a number of mismatched blinking lights, " +"spinning servos, and dangling wires connected to a heft metal box." +msgstr "" +"Š£ŃŃ‚Ń€Š¾Š¹ŃŃ‚Š²Š¾, Š²Ń‹Š³Š»ŃŃ‰ŠµŠµ ŠŗŠ°Šŗ сŠ¾Š±Ń€Š°Š½Š½Š°Ń ŠøŠ· хŠ»Š°Š¼Š° Š°Š½Ń‚ŠµŠ½Š½Š° ŠæŠµŃ€ŠµŠ“Š°Ń‚чŠøŠŗŠ° ŠøŠ»Šø " +"ŠæрŠøŠµŠ¼Š½ŠøŠŗŠ°. ŠžŠ½Š° сŠ¾ŃŃ‚Š¾Šøт ŠøŠ· Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøх Š½ŠµŠ²ŠæŠ¾Š¾Š°Š“ Š¼ŠøŠ³Š°ŃŽŃ‰Šøх Š¾Š³Š½Š¾Š½ŃŒŠŗŠ¾Š², " +"Š²Ń€Š°Ń‰Š°ŃŽŃ‰Šøхся сŠµŃ€Š²Š¾ŠæрŠøŠ²Š¾Š“Š¾Š² Šø сŠ²ŠøсŠ°ŃŽŃ‰Šøх ŠæрŠ¾Š²Š¾Š“Š¾Š², ŠæрŠøсŠ¾ŠµŠ“ŠøŠ½ŠµŠ½Š½Ń‹Ń… с Š±Š¾Š»ŃŒŃˆŠ¾Š¹ " +"Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠ¾Š¹ ŠŗŠ¾Ń€Š¾Š±ŠŗŠµ." + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "clang!" +msgstr "Š»ŃŠ·Š³!" + +#: lang/json/furniture_from_json.py +msgid "rack of robots" +msgstr "стŠ¾Š¹ŠŗŠ° Š“Š»Ń рŠ¾Š±Š¾Ń‚Š¾Š²" + +#. ~ Description for rack of robots +#: lang/json/furniture_from_json.py +msgid "" +"This is a wire cage containing a number of robot parts, from chassis to " +"limbs, firmly clamped on to sturdy hanging rods. It looks like it would be " +"exceptionally difficult to open it and get at them without damaging them, " +"probably by design." +msgstr "" +"ŠŸŃ€Š¾Š²Š¾Š»Š¾Ń‡Š½Š°Ń ŠŗŠ»ŠµŃ‚ŠŗŠ°, сŠ¾Š“ŠµŃ€Š¶Š°Ń‰Š°Ń Š¼Š½Š¾Š¶ŠµŃŃ‚Š²Š¾ чŠ°ŃŃ‚ŠµŠ¹ рŠ¾Š±Š¾Ń‚Š¾Š², Š¾Ń‚ ŠŗŠ¾Ń€ŠæусŠ¾Š² Š“Š¾ " +"ŠŗŠ¾Š½ŠµŃ‡Š½Š¾ŃŃ‚ŠµŠ¹, ŠæрŠ¾Ń‡Š½Š¾ Š·Š°ŠŗрŠµŠæŠ»ŠµŠ½Š½Ń‹Ń… Š½Š° ŠŗрŠµŠæŠŗŠøх ŠæŠ¾Š“Š²ŠµŃŠ½Ń‹Ń… стŠµŃ€Š¶Š½ŃŃ…. ŠŸŠ¾Ń…Š¾Š¶Šµ,Š¾Š½Š° " +"сŠ“ŠµŠ»Š°Š½Š° тŠ°Šŗ, чтŠ¾Š±Ń‹ ŠµŃ‘ Š±Ń‹Š»Š¾ чрŠµŠ·Š²Ń‹Ń‡Š°Š¹Š½Š¾ труŠ“Š½Š¾ Š²ŃŠŗрыть, Š½Šµ ŠæŠ¾Š²Ń€ŠµŠ“ŠøŠ² " +"сŠ¾Š“ŠµŃ€Š¶ŠøŠ¼Š¾Šµ." + +#: lang/json/furniture_from_json.py +msgid "spinning dish" +msgstr "Š²Ń€Š°Ń‰Š°ŃŽŃ‰Š°ŃŃŃ тŠ°Ń€ŠµŠ»ŠŗŠ°" + +#. ~ Description for spinning dish +#: lang/json/furniture_from_json.py +msgid "" +"This is a slowly spinning parabolic dish engraved with an unrecognizable " +"pattern of symbols that might, at a guess, be some sort of circuitry pattern" +" - or maybe a religious incantation. It is mounted on a completely " +"mismatched electric motor that looks fairly mundane." +msgstr "" +"ŠœŠµŠ“Š»ŠµŠ½Š½Š¾ Š²Ń€Š°Ń‰Š°ŃŽŃ‰Š°ŃŃŃ ŠæŠ°Ń€Š°Š±Š¾Š»ŠøчŠµŃŠŗŠ°Ń тŠ°Ń€ŠµŠ»ŠŗŠ°, Š³Ń€Š°Š²ŠøрŠ¾Š²Š°Š½Š½Š°Ń уŠ·Š¾Ń€Š¾Š¼ Š½ŠµŠ·Š½Š°ŠŗŠ¾Š¼Ń‹Ń…" +" Š²Š°Š¼ сŠøŠ¼Š²Š¾Š»Š¾Š², ŠŗŠ¾Ń‚Š¾Ń€Ń‹Šµ, ŠŗŠ°Šŗ Š¼Š¾Š¶Š½Š¾ Š“Š¾Š³Š°Š“Š°Ń‚ŃŒŃŃ, Š¼Š¾Š³ŃƒŃ‚ Š±Ń‹Ń‚ŃŒ чŠµŠ¼-тŠ¾ Š²Ń€Š¾Š“Šµ " +"эŠ»ŠµŠŗтрŠøчŠµŃŠŗŠ¾Š¹ схŠµŠ¼Ń‹ - ŠøŠ»Šø, Š²Š¾Š·Š¼Š¾Š¶Š½Š¾, рŠµŠ»ŠøŠ³ŠøŠ¾Š·Š½Ń‹Š¼ Š·Š°ŠŗŠ»ŠøŠ½Š°Š½ŠøŠµŠ¼. ŠžŠ½Š° " +"устŠ°Š½Š¾Š²Š»ŠµŠ½Š° Š½Š° сŠ¾Š²ŠµŃ€ŃˆŠµŠ½Š½Š¾ Š½ŠµŠæŠ¾Š“хŠ¾Š“ящŠµŠ¼ эŠ»ŠµŠŗтрŠ¾Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»Šµ, Š²Ń‹Š³Š»ŃŠ“ящŠµŠ¼ Š²ŠæŠ¾Š»Š½Šµ " +"Š¾Š±Ń‹Ń‡Š½Š¾." + +#: lang/json/furniture_from_json.py +msgid "scavenged utility light" +msgstr "сŠ½ŃŃ‚Š¾Šµ Š“ŠµŠ¶ŃƒŃ€Š½Š¾Šµ Š¾ŃŠ²ŠµŃ‰ŠµŠ½ŠøŠµ" + +#. ~ Description for scavenged utility light +#: lang/json/furniture_from_json.py +msgid "" +"The bulbs emit an eery greenish glow, and some parts of it have a curved " +"appearance as though the metal were grown in a lab, but by and large this " +"isn't a particularly unusual looking area light." +msgstr "" +"Š›Š°Š¼ŠæŠ¾Ń‡ŠŗŠ°, ŠøсŠæусŠŗŠ°ŃŽŃ‰Š°Ń ŠæуŠ³Š°ŃŽŃ‰ŠµŠµ Š·ŠµŠ»ŠµŠ½Š¾Š²Š°Ń‚Š¾Šµ сŠ²ŠµŃ‡ŠµŠ½ŠøŠµ, Šø Š½ŠµŠŗŠ¾Ń‚Š¾Ń€Ń‹Šµ ŠµŃ‘ чŠ°ŃŃ‚Šø " +"ŠøŠ¼ŠµŃŽŃ‚ ŠøŠ·Š¾Š³Š½ŃƒŃ‚Ń‹Š¹ Š²ŠøŠ“, ŠŗŠ°Šŗ Š±ŃƒŠ“тŠ¾ Š¼ŠµŃ‚Š°Š»Š» Š²Ń‹Ń€Š°Ń‰ŠµŠ½ Š² Š»Š°Š±Š¾Ń€Š°Ń‚Š¾Ń€ŠøŠø, Š½Š¾ Š² цŠµŠ»Š¾Š¼ этŠ¾ " +"Š²ŠæŠ¾Š»Š½Šµ Š½Š¾Ń€Š¼Š°Š»ŃŒŠ½Š¾Šµ устрŠ¾Š¹ŃŃ‚Š²Š¾ Š“Š»Ń Š¾ŃŠ²ŠµŃ‰ŠµŠ½Šøя." + +#: lang/json/furniture_from_json.py +msgid "clanking fluid pump" +msgstr "Š³Ń€ŠµŠ¼ŃŃ‰ŠøŠ¹ Š½Š°ŃŠ¾Ń" + +#. ~ Description for clanking fluid pump +#: lang/json/furniture_from_json.py +msgid "" +"The huge sweating pipes and large tank reveal this clanking and tortuous " +"piece of equipment to be some sort of fluid pump. It is cobbled from " +"several apparently ill-fitting parts that have been fitted together with " +"some very strange looking but surprisingly clever adaptors." +msgstr "" +"Š¢Š¾Š»ŃŃ‚Ń‹Šµ, ŠæŠ¾ŠŗрытыŠµ ŠŗŠ¾Š½Š“ŠµŠ½ŃŠ°Ń‚Š¾Š¼ труŠ±Ń‹ Šø Š±Š¾Š»ŃŒŃˆŠ°Ń ёŠ¼ŠŗŠ¾ŃŃ‚ŃŒ, ŠæрŠµŠ“стŠ°Š²Š»ŃŃŽŃ‰ŠøŠµ ŠøŠ· " +"сŠµŠ±Ń Š³Ń€ŠµŠ¼ŃŃ‰ŠøŠ¹ Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚Š½Ń‹Š¹ Š½Š°ŃŠ¾Ń. ŠžŠ½ Š²Ń‹Š³Š»ŃŠ“Šøт тŠ°Šŗ, Š±ŃƒŠ“тŠ¾ сŠ¾Š±Ń€Š°Š½ ŠøŠ· ŠæŠ»Š¾Ń…Š¾ " +"сŠ¾Ń‡ŠµŃ‚Š°ŃŽŃ‰Šøхся Š¼ŠµŠ¶Š“у сŠ¾Š±Š¾Š¹ чŠ°ŃŃ‚ŠµŠ¹, сŠ¾ŠµŠ“ŠøŠ½ŠµŠ½Š½Ń‹Ń… Š²Š¼ŠµŃŃ‚Šµ стрŠ°Š½Š½Ń‹Š¼Šø, Š½Š¾ Š“Š¾Š²Š¾Š»ŃŒŠ½Š¾ " +"хŠøтрŠ¾ŃƒŠ¼Š½Ń‹Š¼Šø Š°Š“Š°ŠæтŠ¾Ń€Š°Š¼Šø." + +#: lang/json/furniture_from_json.py +msgid "metalloid printer" +msgstr "Š¼ŠµŃ‚Š°Š»Š»Š¾ŠøŠ“Š½Ń‹Š¹ ŠæрŠøŠ½Ń‚ŠµŃ€" + +#. ~ Description for metalloid printer +#: lang/json/furniture_from_json.py +msgid "" +"This huge device actually resembles a 3D printer fairly closely, aside from " +"its industrial size. Huge spools of various thin metallic wires top it and " +"feed into what seems to be some sort of nozzle, and massive electrical " +"cables disappear into the wall behind it." +msgstr "" +"Š‘Š¾Š»ŃŒŃˆŠ¾Šµ устрŠ¾Š¹ŃŃ‚Š²Š¾, Š½Š°ŠæŠ¾Š¼ŠøŠ½Š°ŃŽŃ‰ŠµŠµ 3D ŠæрŠøŠ½Ń‚ŠµŃ€, Š½Š¾ тŠ¾Š»ŃŒŠŗŠ¾ ŠæрŠ¾Š¼Ń‹ŃˆŠ»ŠµŠ½Š½Š¾Š³Š¾ " +"рŠ°Š·Š¼ŠµŃ€Š°. Š‘Š¾Š»ŃŒŃˆŠøŠµ Š¼Š¾Ń‚ŠŗŠø рŠ°Š·Š½Ń‹Ń… Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøх ŠæрŠ¾Š²Š¾Š»Š¾Šŗ рŠ°ŃŠæŠ¾Š»Š¾Š¶ŠµŠ½Ń‹ Š½Š°Š“ Š½ŠøŠ¼, " +"ŠæŠøтŠ°Ń сŠæŠµŃ†ŠøфŠøчŠµŃŠŗŠøŠµ сŠ¾ŠæŠ»Š°, Š° ŠæŠ¾Š“ Š½ŠµŠ³Š¾ ухŠ¾Š“ят тŠ¾Š»ŃŃ‚Ń‹Šµ сŠøŠ»Š¾Š²Ń‹Šµ ŠŗŠ°Š±ŠµŠ»Šø ŠøŠ· стŠµŠ½Ń‹" +" Š·Š° Š½ŠøŠ¼." + +#: lang/json/furniture_from_json.py +msgid "circuit printer" +msgstr "ŠæрŠøŠ½Ń‚ŠµŃ€ эŠ»ŠµŠŗтрŠ¾ŃŃ…ŠµŠ¼" + +#. ~ Description for circuit printer +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall device with a lattice of pipes and nozzles. Based on the " +"pile of products sitting in the output hopper, it looks like itā€™s used as a " +"printer for complex electronic components." +msgstr "" +"Š’ысŠ¾ŠŗŠ¾Šµ устрŠ¾Š¹ŃŃ‚Š²Š¾ с рŠµŃˆŃ‘Ń‚ŠŗŠ¾Š¹ ŠøŠ· труŠ± Šø сŠ¾ŠæŠµŠ». Š”уŠ“я ŠæŠ¾ ŠŗучŠµ Š³Š¾Ń‚Š¾Š²Š¾Š³Š¾ " +"ŠæрŠ¾Š“уŠŗтŠ°, Š»ŠµŠ¶Š°Ń‰ŠµŠ³Š¾ Š² Š²Ń‹Ń…Š¾Š“Š½Š¾Š¼ Š±ŃƒŠ½ŠŗŠµŃ€Šµ, Š¾Š½Š¾ ŠæрŠµŠ“Š½Š°Š·Š½Š°Ń‡Š°Š»Š¾ŃŃŒ Š“Š»Ń ŠæŠµŃ‡Š°Ń‚Šø " +"сŠ»Š¾Š¶Š½Ń‹Ń… эŠ»ŠµŠŗтрŠ¾Š½Š½Ń‹Ń… ŠŗŠ¾Š¼ŠæŠ¾Š½ŠµŠ½Ń‚Š¾Š²." + +#: lang/json/furniture_from_json.py +msgid "Mavrik 10-101 power core" +msgstr "сŠøŠ»Š¾Š²Š¾Šµ яŠ“рŠ¾ Mavrik 10-101" + +#. ~ Description for Mavrik 10-101 power core +#: lang/json/furniture_from_json.py +msgid "" +"There is a faded metallic plaque on the side of this cylindrical device. The lettering is a strange combination of English and Cyrillic script. It reads:\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" +msgstr "" +"ŠŠ° Š±Š¾Šŗу этŠ¾Š³Š¾ цŠøŠ»ŠøŠ½Š“рŠøчŠµŃŠŗŠ¾Š³Š¾ устрŠ¾Š¹ŃŃ‚Š²Š° Š·Š°ŠŗрŠµŠæŠ»ŠµŠ½Š° Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠ°Ń тŠ°Š±Š»ŠøчŠŗŠ° с Š²Ń‹Ń†Š²ŠµŃ‚ŃˆŠµŠ¹ Š½Š°Š“ŠæŠøсью. Š‘ŃƒŠŗŠ²Ń‹ ŠæрŠµŠ“стŠ°Š²Š»ŃŃŽŃ‚ сŠ¾Š±Š¾Š¹ стрŠ°Š½Š½Š¾Šµ сŠ¾Ń‡ŠµŃ‚Š°Š½ŠøŠµ Š»Š°Ń‚ŠøŠ½ŃŠŗŠ¾Š³Š¾ Šø ŠŗŠøрŠøŠ»Š»ŠøчŠµŃŠŗŠ¾Š³Š¾ Š°Š»Ń„Š°Š²ŠøтŠ°. ŠŠ°Š“ŠæŠøсь Š³Š»Š°ŃŠøт:\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "metal screeching!" +msgstr "сŠŗрŠµŠ¶ŠµŃ‚ Š¼ŠµŃ‚Š°Š»Š»Š°!" + +#: lang/json/furniture_from_json.py +msgid "spherical generator" +msgstr "сфŠµŃ€ŠøчŠµŃŠŗŠøŠ¹ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€" + +#. ~ Description for spherical generator +#: lang/json/furniture_from_json.py +msgid "" +"This huge steel plated sphere gives off a soft hum as it, presumably, " +"generates power. A heavy lead plate bolted to the front might describe what" +" it is, but it is written in something that looks vaguely like cuneiform." +msgstr "" +"Š‘Š¾Š»ŃŒŃˆŠ°Ń, ŠæŠ¾ŠŗрытŠ°Ń стŠ°Š»ŃŒŠ½Ń‹Š¼Šø ŠæŠ»Š°ŃŃ‚ŠøŠ½Š°Š¼Šø сфŠµŃ€Š°, ŠøŠ·Š“Š°ŃŽŃ‰Š°Ń Š¼ŃŠ³ŠŗŠøŠ¹ Š³ŃƒŠ», Šø суŠ“я ŠæŠ¾" +" Š²ŃŠµŠ¼Ńƒ, ŠæрŠ¾ŠøŠ·Š²Š¾Š“ящŠ°Ń эŠ½ŠµŃ€Š³Šøю. Š¢ŃŠ¶ŠµŠ»Š°Ń сŠ²ŠøŠ½Ń†Š¾Š²Š°Ń ŠæŠ»Š°ŃŃ‚ŠøŠ½Š° Š² ŠæŠµŃ€ŠµŠ“Š½ŠµŠ¹ чŠ°ŃŃ‚Šø, " +"ŠæŠ¾Ń…Š¾Š¶Šµ, Š¾ŠæŠøсыŠ²Š°ŠµŃ‚, чтŠ¾ этŠ¾ Š·Š° устрŠ¾Š¹ŃŃ‚Š²Š¾, Š²Š¾Ń‚ тŠ¾Š»ŃŒŠŗŠ¾ тŠµŠŗст Š±Š¾Š»ŃŒŃˆŠµ Š²ŃŠµŠ³Š¾ " +"ŠæŠ¾Ń…Š¾Š¶ Š½Š° ŠŗŠ»ŠøŠ½Š¾ŠæŠøсь." + +#: lang/json/furniture_from_json.py +msgid "fluidic generator" +msgstr "Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚Š½Ń‹Š¹ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€" + +#. ~ Description for fluidic generator +#: lang/json/furniture_from_json.py +msgid "" +"Twisting reams of copper and steel pipes wrap around a central core that " +"thrums softly. Although there are no labels in any language you recognize, " +"the cables connected to the base suggest that this is some sort of power " +"generator." +msgstr "" +"Š”ŠŗручŠµŠ½Š½Ń‹Šµ ŠæŠ°Ń‡ŠŗŠø Š¼ŠµŠ“Š½Ń‹Ń… Šø стŠ°Š»ŃŒŠ½Ń‹Ń… труŠ± Š¾Š±Š²ŠøŠ²Š°ŃŽŃ‚ цŠµŠ½Ń‚Ń€Š°Š»ŃŒŠ½Ń‹Š¹ сŠµŃ€Š“ŠµŃ‡Š½ŠøŠŗ, " +"ŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¹ тŠøхŠ¾ Š²ŠøŠ±Ń€ŠøруŠµŃ‚. Š„Š¾Ń‚я Š·Š“ŠµŃŃŒ Š½ŠµŃ‚ ярŠ»Ń‹ŠŗŠ¾Š² Š½Š° Š·Š½Š°ŠŗŠ¾Š¼Š¾Š¼ Š²Š°Š¼ яŠ·Ń‹ŠŗŠµ, " +"ŠŗŠ°Š±ŠµŠ»Šø, ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Š½Ń‹Šµ Šŗ Š¾ŃŠ½Š¾Š²Š°Š½Šøю, Š“Š°ŃŽŃ‚ Š²Š¾Š·Š¼Š¾Š¶Š½Š¾ŃŃ‚ŃŒ ŠæрŠµŠ“ŠæŠ¾Š»Š¾Š¶Šøть, чтŠ¾ этŠ¾ " +"ŠŗŠ°ŠŗŠ¾Š¹-тŠ¾ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€ эŠ½ŠµŃ€Š³ŠøŠø." + +#: lang/json/furniture_from_json.py +msgid "rusty generator" +msgstr "рŠ¶Š°Š²Ń‹Š¹ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€" + +#. ~ Description for rusty generator +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall, unremarkable cylinder capped by a wide flat saucer. There " +"is heavy rusting at the base. A series of connected cables suggest that " +"it's some sort of power generator." +msgstr "" +"Š’ысŠ¾ŠŗŠøŠ¹, Š½ŠøчŠµŠ¼ Š½Šµ ŠæрŠøŠ¼ŠµŃ‡Š°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹ цŠøŠ»ŠøŠ½Š“р, уŠ²ŠµŠ½Ń‡Š°Š½Š½Ń‹Š¹ шŠøрŠ¾ŠŗŠøŠ¼ ŠæŠ»Š¾ŃŠŗŠøŠ¼ " +"Š±Š»ŃŽŠ“цŠµŠ¼. ŠžŃŠ½Š¾Š²Š°Š½ŠøŠµ сŠøŠ»ŃŒŠ½Š¾ ŠæŠ¾ŠŗрытŠ¾ рŠ¶Š°Š²Ń‡ŠøŠ½Š¾Š¹. ŠœŠ½Š¾Š¶ŠµŃŃ‚Š²Š¾ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Š½Ń‹Ń… ŠŗŠ°Š±ŠµŠ»ŠµŠ¹ " +"Š“Š°ŃŽŃ‚ Š²Š¾Š·Š¼Š¾Š¶Š½Š¾ŃŃ‚ŃŒ ŠæрŠµŠ“ŠæŠ¾Š»Š¾Š¶Šøть, чтŠ¾ этŠ¾ ŠŗŠ°ŠŗŠ¾Š¹-тŠ¾ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€ эŠ½ŠµŃ€Š³ŠøŠø." + +#: lang/json/furniture_from_json.py +msgid "personal charging station" +msgstr "ŠæŠµŃ€ŃŠ¾Š½Š°Š»ŃŒŠ½Š°Ń Š·Š°Ń€ŃŠ“Š½Š°Ń стŠ°Š½Ń†Šøя" + +#. ~ Description for personal charging station +#: lang/json/furniture_from_json.py +msgid "" +"The cyborg equivalent of a bed, this is a custom-shaped near-vertical booth " +"designed to mount a heavy metal frame and connect it to a central power " +"supply and nutrient source." +msgstr "" +"Š­ŠŗŠ²ŠøŠ²Š°Š»ŠµŠ½Ń‚ ŠŗрŠ¾Š²Š°Ń‚Šø Š“Š»Ń ŠŗŠøŠ±Š¾Ń€Š³Š¾Š². Š˜Š·Š³Š¾Ń‚Š¾Š²Š»ŠµŠ½Š½Š°Ń ŠæŠ¾ ŠøŠ½Š“ŠøŠ²ŠøŠ“уŠ°Š»ŃŒŠ½Š¾Š¼Ńƒ Š·Š°ŠŗŠ°Š·Ńƒ " +"ŠæŠ¾Ń‡Ń‚Šø Š²ŠµŃ€Ń‚ŠøŠŗŠ°Š»ŃŒŠ½Š°Ń стŠ¾Š¹ŠŗŠ°, ŠæрŠµŠ“Š½Š°Š·Š½Š°Ń‡ŠµŠ½Š½Š°Ń Š“Š»Ń устŠ°Š½Š¾Š²ŠŗŠø тяŠ¶ŠµŠ»Š¾Š³Š¾ " +"Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠ¾Š³Š¾ ŠŗŠ°Ń€ŠŗŠ°ŃŠ° Šø ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½Šøя ŠµŠ³Š¾ Šŗ цŠµŠ½Ń‚Ń€Š°Š»ŃŒŠ½Š¾Š¼Ńƒ ŠøстŠ¾Ń‡Š½ŠøŠŗу ŠæŠøтŠ°Š½Šøя Šø " +"ŠøстŠ¾Ń‡Š½ŠøŠŗу ŠæŠøтŠ°Ń‚ŠµŠ»ŃŒŠ½Ń‹Ń… Š²ŠµŃ‰ŠµŃŃ‚Š²." + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp +msgid "crash!" +msgstr "Ā«Ń…Ń€ŃŃŃŒ!Ā»" + +#: lang/json/furniture_from_json.py +msgid "simple charging station" +msgstr "ŠæрŠ¾ŃŃ‚Š°Ń Š·Š°Ń€ŃŠ“Š½Š°Ń стŠ°Š½Ń†Šøя" + +#. ~ Description for simple charging station +#: lang/json/furniture_from_json.py +msgid "" +"This is a simple, unadorned, corroded metal charging and refeeding station, " +"with hookups for two units somewhat larger than a human to stand side by " +"side and be recharged and refueled." +msgstr "" +"ŠŸŃ€Š¾ŃŃ‚Š°Ń, Š½ŠµŃƒŠŗрŠ°ŃˆŠµŠ½Š½Š°Ń, рŠ¶Š°Š²ŠµŃŽŃ‰Š°Ń Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠ°Ń стŠ°Š½Ń†Šøя Š·Š°Ń€ŃŠ“ŠŗŠø Šø ŠæŠøтŠ°Š½Šøя, с " +"Š¼ŠµŃŃ‚Š¾Š¼ Š“Š»Ń Š·Š°Ń€ŃŠ“ŠŗŠø Šø ŠæŠøтŠ°Š½Šøя Š“Š²ŃƒŃ… ŠµŠ“ŠøŠ½Šøц чуть ŠŗруŠæŠ½ŠµŠµ чŠµŠ»Š¾Š²ŠµŠŗŠ°." + +#: lang/json/furniture_from_json.py +msgid "shimmering superstructure" +msgstr "Š¼ŠµŃ€Ń†Š°ŃŽŃ‰Š°Ń Š½Š°Š“стрŠ¾Š¹ŠŗŠ°" + +#. ~ Description for shimmering superstructure +#: lang/json/furniture_from_json.py +msgid "" +"A simple metal superstructure like you might see holding up a radio tower, " +"this one seems to give off just the faintest hint of shimmer, like heat " +"waves. The metal has a burnt, iridescent pattern. There is a boxy, " +"unimpressive looking device at the top of the tower." +msgstr "" +"ŠŸŃ€Š¾ŃŃ‚Š°Ń Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠ°Ń Š½Š°Š“стрŠ¾Š¹ŠŗŠ° Š²Ń€Š¾Š“Šµ тŠ°ŠŗŠøх, ŠŗŠ¾Ń‚Š¾Ń€Ń‹Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŃŽŃ‚ " +"рŠ°Š“ŠøŠ¾Š²Ń‹ŃˆŠŗŠø. Š­Ń‚Š°, ŠŗŠ°Š¶ŠµŃ‚ся, ŠøсŠæусŠŗŠ°ŠµŃ‚ Š»Šøшь сŠ»Š°Š±Ń‹Š¹ Š½Š°Š¼ŠµŠŗ Š½Š° Š¼ŠµŃ€Ń†Š°Š½ŠøŠµ, Š²Ń€Š¾Š“Šµ " +"Š²Š¾Š»Š½ тŠµŠæŠ»Š°. ŠŠ° Š¼ŠµŃ‚Š°Š»Šµ ŠøŠ¼ŠµŠµŃ‚ся Š¾Š±Š¾Š¶Š¶ŠµŠ½Š½Ń‹Š¹ ŠæŠµŃ€ŠµŠ»ŠøŠ²Š°ŃŽŃ‰ŠøŠ¹ŃŃ уŠ·Š¾Ń€. Š’ Š²ŠµŃ€Ń…Š½ŠµŠ¹ " +"чŠ°ŃŃ‚Šø Š±Š°ŃˆŠ½Šø Š½Š°Ń…Š¾Š“Šøтся ŠŗŠ²Š°Š“рŠ°Ń‚Š½Š¾Šµ Š½ŠµŠ²Š·Ń€Š°Ń‡Š½Š¾Šµ устрŠ¾Š¹ŃŃ‚Š²Š¾." + +#: lang/json/furniture_from_json.py +msgid "portal enclosure" +msgstr "Š±Š°Š·Š° ŠæŠ¾Ń€Ń‚Š°Š»Š°" + +#. ~ Description for portal enclosure +#: lang/json/furniture_from_json.py +msgid "" +"A heavy metal ring attached to dozens of wires, charred by residue that " +"gives off an acrid, unfamiliar smell." +msgstr "" +"Š¢ŃŠ¶ŠµŠ»Š¾Šµ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠ¾Šµ ŠŗŠ¾Š»ŃŒŃ†Š¾, Šŗ ŠŗŠ¾Ń‚Š¾Ń€Š¾Š¼Ńƒ ŠæрŠøсŠ¾ŠµŠ“ŠøŠ½ŠµŠ½Ń‹ Š“ŠµŃŃŃ‚ŠŗŠø ŠæрŠ¾Š²Š¾Š“Š¾Š², " +"Š¾Š±ŃƒŠ³Š»ŠµŠ½Š½Š¾Šµ чŠµŠ¼-тŠ¾, ŠøŠ·Š“Š°ŃŽŃ‰ŠøŠ¼ ŠµŠ“ŠŗŠøŠ¹, Š½ŠµŠ·Š½Š°ŠŗŠ¾Š¼Ń‹Š¹ Š·Š°ŠæŠ°Ń…." + #: lang/json/furniture_from_json.py msgid "cooling unit" msgstr "Š¾Ń…Š»Š°Š“ŠøтŠµŠ»ŃŒ" @@ -129414,15 +130277,6 @@ msgstr "" "Š‘Š¾Š»ŃŒŃˆŠ¾Šµ, уŠ³Š»Š¾Š²Š°Ń‚Š¾Šµ устрŠ¾Š¹ŃŃ‚Š²Š¾ ŠøŠ· Š»ŠøстŠ¾Š²Š¾Š³Š¾ Š¼ŠµŃ‚Š°Š»Š°. Š Š°ŃŠæрŠ¾ŃŃ‚Ń€Š°Š½ŠµŠ½Š¾ Šø Š¾Š±Ń‹Ń‡Š½Š¾ " "ŠøсŠæŠ¾Š»ŃŒŠ·ŃƒŠµŃ‚ся Š“Š»Ń Š¾Ń…Š»Š°Š¶Š“ŠµŠ½Šøя ŠæŠ¾Š¼ŠµŃ‰ŠµŠ½ŠøŠ¹." -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "metal screeching!" -msgstr "сŠŗрŠµŠ¶ŠµŃ‚ Š¼ŠµŃ‚Š°Š»Š»Š°!" - -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -msgid "clang!" -msgstr "Š»ŃŠ·Š³!" - #: lang/json/furniture_from_json.py msgid "central air filter" msgstr "цŠµŠ½Ń‚Ń€Š°Š»ŃŒŠ½Ń‹Š¹ Š²Š¾Š·Š“ушŠ½Ń‹Š¹ фŠøŠ»ŃŒŃ‚Ń€" @@ -129621,8 +130475,7 @@ msgstr "" "эŠ»ŠµŠŗтрŠøчŠµŃŃ‚Š²Š¾. Š‘Ń‹Š»Šø ŠæŠ¾Š»ŠµŠ·Š½Ń‹Š¼Šø ŠæŠµŃ€ŠµŠ“ ŠšŠ°Ń‚Š°ŠŗŠ»ŠøŠ·Š¼Š¾Š¼, Š° тŠµŠæŠµŃ€ŃŒ стŠ°Š»Šø Š±ŠµŃŃ†ŠµŠ½Š½Ń‹Š¼Šø " "Š“Š»Ń Š»ŃŽŠ±Š¾Š³Š¾ Š²Ń‹Š¶ŠøŠ²ŃˆŠµŠ³Š¾." -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py msgid "whack!" msgstr "хрясь!" @@ -129641,16 +130494,12 @@ msgstr "" "Š·Š°ŠŗрŠµŠæŠ»ŠµŠ½Š° сŠ²ŠµŃ‚Š¾Š¾Ń‚Ń€Š°Š¶Š°ŃŽŃ‰Š°Ń Š»ŠµŠ½Ń‚Š°, чтŠ¾Š±Ń‹ ŠµŠµ Š±Ń‹Š»Š¾ Š»ŃƒŃ‡ŃˆŠµ Š²ŠøŠ“Š½Š¾. ŠŠµŃŠ¼Š¾Ń‚Ń€Ń Š½Š° " "Š½Š°Š·Š²Š°Š½ŠøŠµ, Š²Ń€ŃŠ“ Š»Šø сŠ¼Š¾Š¶ŠµŃ‚ Š¾ŃŃ‚Š°Š½Š¾Š²Šøть Š°Š²Ń‚Š¾Š¼Š¾Š±ŠøŠ»ŃŒ." -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -#: src/mapdata.cpp src/vehicle_move.cpp +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/map.cpp src/mapdata.cpp +#: src/vehicle_move.cpp msgid "smash!" msgstr "Š³Ń€Š¾Ń…Š¾Ń‚!" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -msgid "whump." -msgstr "Ā«Š±ŃƒŠ¼Ā»." - #: lang/json/furniture_from_json.py msgid "earthbag barricade" msgstr "Š±Š°Ń€Ń€ŠøŠŗŠ°Š“Š° ŠøŠ· Š¼ŠµŃˆŠŗŠ¾Š² с Š·ŠµŠ¼Š»Ń‘Š¹" @@ -130031,10 +130880,6 @@ msgstr "" "ŠŠµŠ¼Š°Š»ŠµŠ½ŃŒŠŗŠ°Ń Š³Ń€ŃŠ·Š½Š¾-Š±ŠµŠ»Š°Ń ŠŗŠ»Š°Š“ŠŗŠ° Š±Š¾Š»ŃŒŃˆŠøх яŠøц. ŠŸŃ€ŠøŠ³Š»ŃŠ“ŠµŠ²ŃˆŠøсь, Š²Ń‹ Š²ŠøŠ“ŠøтŠµ, ŠŗŠ°Šŗ " "Š²Š½ŃƒŃ‚Ń€Šø чтŠ¾-тŠ¾ Š½ŠµŠ¼Š½Š¾Š³Š¾ шŠµŠ²ŠµŠ»Šøтся. Š“Š°Š“Š¾ŃŃ‚ŃŒ." -#: lang/json/furniture_from_json.py -msgid "splat!" -msgstr "Ā«ŃˆŠ»Ń‘Šæ!Ā»" - #. ~ Description for spider egg sack #: lang/json/furniture_from_json.py msgid "" @@ -130128,16 +130973,6 @@ msgstr "" "Š“ыŠ¼Š¾Ń…Š¾Š“Š¾Š¼ Š“Š»Ń Š¾Ń‚Š²Š¾Š“Š° Š“ыŠ¼Š° Š½Š°Ń€ŃƒŠ¶Ńƒ. ŠžŠæŠ°ŃŠ½Š¾ Š¾ŃŃ‚Š°Š²Š»ŃŃ‚ŃŒ Š±ŠµŠ· ŠæрŠøсŠ¼Š¾Ń‚Ń€Š°, ŠæŠ¾ŠŗŠ° " "Š³Š¾Ń€Šøт." -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -msgid "crash!" -msgstr "Ā«Ń…Ń€ŃŃŃŒ!Ā»" - -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "whump!" -msgstr "Ā«Š±ŃƒŠ¼!Ā»" - #: lang/json/furniture_from_json.py msgid "wood stove" msgstr "Š“рŠ¾Š²ŃŠ½Š°Ń ŠæŠµŃ‡ŃŒ" @@ -130319,8 +131154,9 @@ msgstr "" "Š”Š¾Š²Š¾Š»ŃŒŠ½Š¾ Š±Š¾Š»ŃŒŃˆŠ°Ń ŠŗучŠ° Š»ŠøстьŠµŠ². Š’Ń‹ Š¼Š¾Š¶ŠµŃ‚Šµ сŠæŠ°Ń‚ŃŒ Š² Š½ŠµŠ¹, ŠµŃŠ»Šø Š²Š°Š¼ ŠæŠ»ŠµŠ²Š°Ń‚ŃŒ Š½Š° " "уŠ“Š¾Š±ŃŃ‚Š²Š¾ ŠøŠ»Šø тŠµŠæŠ»Š¾." -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -#: src/iuse.cpp +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/iuse.cpp msgid "crunch!" msgstr "трŠµŃŠŗ!" @@ -130512,6 +131348,86 @@ msgstr "" "Š‘Š¾Š»ŃŒŃˆŠ¾Š¹ чŠ°Š½ с эŠ»ŠµŠŗтрŠøчŠµŃŠŗŠøŠ¼ Š¼ŠøŠŗсŠµŃ€Š¾Š¼ Š“Š»Ń сŠ¼ŠµŃˆŠøŠ²Š°Š½Šøя Š±Š¾Š»ŃŒŃˆŠøх Š¾Š±ŃŠŠµŠ¼Š¾Š² " "хŠøŠ¼ŠøчŠµŃŠŗŠøх рŠµŠ°Š³ŠµŠ½Ń‚Š¾Š²." +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken generator" +msgstr "Š½ŠµŠøсŠæрŠ°Š²Š½Ń‹Š¹ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€" + +#. ~ Description for broken generator +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This generator is broken and will not help you produce usable electricity." +msgstr "Š­Ń‚Š¾Ń‚ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€ сŠ»Š¾Š¼Š°Š½ Šø Š½Šµ Š“Š°ŃŃ‚ Š²Š°Š¼ ŠæŠ¾Š»ŠµŠ·Š½Š¾Š³Š¾ эŠ»ŠµŠŗтрŠøчŠµŃŃ‚Š²Š°." + +#: lang/json/furniture_from_json.py +msgid "Compact Advanced Sterling Radioisotope Generator" +msgstr "ŠšŠ¾Š¼ŠæŠ°ŠŗтŠ½Ń‹Š¹ ŠæрŠ¾Š“Š²ŠøŠ½ŃƒŃ‚Ń‹Š¹ рŠ°Š“ŠøŠ¾ŠøŠ·Š¾Ń‚Š¾ŠæŠ½Ń‹Š¹ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€ Š”тŠµŃ€Š»ŠøŠ½Š³Š°" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"This hefty lump of steel and lead is the housing unit for a small nuclear " +"reactor. It is plastered with warning signs. You could probably ignore " +"those and salvage the steel and lead shielding, what could possibly go " +"wrong?" +msgstr "" +"Š­Ń‚Š¾Ń‚ Š·Š“Š¾Ń€Š¾Š²ŠµŠ½Š½Ń‹Š¹ ŠŗусŠ¾Šŗ стŠ°Š»Šø Šø сŠ²ŠøŠ½Ń†Š° ŠæрŠµŠ“стŠ°Š²Š»ŃŠµŃ‚ ŠøŠ· сŠµŠ±Ń ŠŗŠ¾Ń€Šæус Š½ŠµŠ±Š¾Š»ŃŒŃˆŠ¾Š³Š¾" +" яŠ“ŠµŃ€Š½Š¾Š³Š¾ рŠµŠ°ŠŗтŠ¾Ń€Š°. ŠžŠ½ ŠæŠ¾Šŗрыт ŠæрŠµŠ“уŠæрŠµŠ“ŠøтŠµŠ»ŃŒŠ½Ń‹Š¼Šø Š·Š½Š°ŠŗŠ°Š¼Šø. Š’Ń‹ Š¼Š¾Š³Š»Šø Š±Ń‹, " +"Š²ŠµŃ€Š¾ŃŃ‚Š½Š¾, ŠæрŠ¾ŠøŠ³Š½Š¾Ń€ŠøрŠ¾Š²Š°Ń‚ŃŒ этŠ¾ Šø Š“Š¾Š±Ń‹Ń‚ŃŒ Š½ŠµŠ¼Š½Š¾Š³Š¾ стŠ°Š»Šø Šø сŠ²ŠøŠ½Ń†Š¾Š²Ń‹Ń… эŠŗрŠ°Š½Š¾Š², " +"чтŠ¾ Š¼Š¾Š¶ŠµŃ‚ ŠæŠ¾Š¹Ń‚Šø Š½Šµ тŠ°Šŗ?" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"Some insane fool has removed the outer containment on this small-scale " +"nuclear reactor. It is still fairly safe as it is: the reactor has " +"considerable built-in containment as well. Nevertheless, you probably don't" +" want to stand too close for too long." +msgstr "" +"ŠšŠ°ŠŗŠ¾Š¹-тŠ¾ Š±ŠµŠ·ŃƒŠ¼Š½Ń‹Š¹ Š“урŠ°Šŗ уŠ“Š°Š»ŠøŠ» Š²Š½ŠµŃˆŠ½ŃŽŃŽ Š¾Š±Š¾Š»Š¾Ń‡Šŗу этŠ¾Š³Š¾ Š½ŠµŠ±Š¾Š»ŃŒŃˆŠ¾Š³Š¾ яŠ“ŠµŃ€Š½Š¾Š³Š¾ " +"рŠµŠ°ŠŗтŠ¾Ń€Š°. ŠžŠ½ Š²ŃŃ‘ ŠµŃ‰Ń‘ Š“Š¾Š²Š¾Š»ŃŒŠ½Š¾ Š±ŠµŠ·Š¾ŠæŠ°ŃŠµŠ½ Š² тŠ°ŠŗŠ¾Š¼ Š²ŠøŠ“Šµ: рŠµŠ°ŠŗтŠ¾Ń€ тŠ°ŠŗŠ¶Šµ Š¾Š±Š»Š°Š“Š°ŠµŃ‚" +" сŠ¾Š»ŠøŠ“Š½Š¾Š¹ Š²ŃŃ‚Ń€Š¾ŠµŠ½Š½Š¾Š¹ Š·Š°Ń‰ŠøтŠ½Š¾Š¹ Š¾Š±Š¾Š»Š¾Ń‡ŠŗŠ¾Š¹. Š¢ŠµŠ¼ Š½Šµ Š¼ŠµŠ½ŠµŠµ, Š²Š°Š¼, Š²ŠµŃ€Š¾ŃŃ‚Š½Š¾, Š½Šµ " +"стŠ¾Šøт стŠ¾ŃŃ‚ŃŒ сŠ»ŠøшŠŗŠ¾Š¼ Š±Š»ŠøŠ·ŠŗŠ¾ Šø сŠ»ŠøшŠŗŠ¾Š¼ Š“Š¾Š»Š³Š¾." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "light machinery" +msgstr "Š»Ń‘Š³ŠŗŠøŠµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹" + +#. ~ Description for light machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted light machinery. You could scavenge it for parts." +msgstr "Š Š°Š·Š½Š¾Š¾Š±Ń€Š°Š·Š½Ń‹Šµ Š»Ń‘Š³ŠŗŠøŠµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹. ŠœŠ¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š½Š° Š·Š°ŠæчŠ°ŃŃ‚Šø." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "ting." +msgstr "тŠøŠ½ŃŒ." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "heavy machinery" +msgstr "тяŠ¶Ń‘Š»Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹" + +#. ~ Description for heavy machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted heavy machinery. You could scavenge it for parts." +msgstr "Š Š°Š·Š½Š¾Š¾Š±Ń€Š°Š·Š½Ń‹Šµ тяŠ¶Ń‘Š»Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹. ŠœŠ¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š½Š° Š·Š°ŠæчŠ°ŃŃ‚Šø." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "old machinery" +msgstr "стŠ°Ń€Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹" + +#. ~ Description for old machinery +#: lang/json/furniture_from_json.py +msgid "Assorted old, rusty machinery. You could scavenge it for parts." +msgstr "Š Š°Š·Š½Š¾Š¾Š±Ń€Š°Š·Š½Ń‹Šµ стŠ°Ń€Ń‹Šµ рŠ¶Š°Š²Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹. ŠœŠ¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š½Š° Š·Š°ŠæчŠ°ŃŃ‚Šø." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "electronic machinery" +msgstr "эŠ»ŠµŠŗтрŠ¾Š½Š½Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹" + +#. ~ Description for electronic machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted electronic machinery. You could scavenge it for parts." +msgstr "Š Š°Š·Š½Š¾Š¾Š±Ń€Š°Š·Š½Ń‹Šµ эŠ»ŠµŠŗтрŠ¾Š½Š½Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹. ŠœŠ¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š½Š° Š·Š°ŠæчŠ°ŃŃ‚Šø." + #: lang/json/furniture_from_json.py msgid "robotic arm" msgstr "рŠ¾Š±Š¾Ń‚ŠøŠ·ŠøрŠ¾Š²Š°Š½Š½Š°Ń руŠŗŠ°" @@ -130533,6 +131449,33 @@ msgstr "" msgid "thunk." msgstr "хŠ»Š¾ŠæŠ°Š½ŃŒŠµ." +#: lang/json/furniture_from_json.py +msgid "ground cable" +msgstr "Š½Š°ŠæŠ¾Š»ŃŒŠ½Ń‹Š¹ ŠŗŠ°Š±ŠµŠ»ŃŒ" + +#. ~ Description for ground cable +#: lang/json/furniture_from_json.py +msgid "A bunch of loose cables snake along the floor." +msgstr "ŠšŃƒŃ‡Š° ŠŗŠ°Š±ŠµŠ»ŠµŠ¹, струящŠøхся ŠæŠ¾ ŠæŠ¾Š»Ńƒ." + +#: lang/json/furniture_from_json.py +msgid "shred!" +msgstr "трŠµŃŠŗ!" + +#: lang/json/furniture_from_json.py +msgid "thud!" +msgstr "Ā«Š±ŃƒŠ¼Ā»!" + +#: lang/json/furniture_from_json.py +msgid "capacitor bank" +msgstr "Š¼Š°ŃŃŠøŠ² ŠŗŠ¾Š½Š“ŠµŠ½ŃŠ°Ń‚Š¾Ń€Š¾Š²" + +#. ~ Description for capacitor bank +#: lang/json/furniture_from_json.py +msgid "A bank of heavy metal cylinders connected by large wires." +msgstr "" +"ŠœŠ°ŃŃŠøŠ² тяŠ¶ŠµŠ»Ń‹Š¹ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøх цŠøŠ»ŠøŠ½Š“рŠ¾Š², сŠ¾ŠµŠ“ŠøŠ½Ń‘Š½Š½Ń‹Ń… тŠ¾Š»ŃŃ‚Ń‹Š¼Šø ŠŗŠ°Š±ŠµŠ»ŃŠ¼Šø." + #: lang/json/furniture_from_json.py msgid "Autodoc Mk. XI" msgstr "Š°Š²Ń‚Š¾Š“Š¾Šŗ" @@ -130860,140 +131803,21 @@ msgstr "Š¾Ń‚ŠŗрытŠ°Ń шŠøрŠ¼Š°" msgid "Stop peeking!" msgstr "Š„Š²Š°Ń‚Šøт ŠæŠ¾Š“Š³Š»ŃŠ“ыŠ²Š°Ń‚ŃŒ!" -#: lang/json/furniture_from_json.py -msgid "glowing tendril" -msgstr "сŠ²ŠµŃ‚ŃŃ‰ŠøŠ¹ŃŃ Š¶Š³ŃƒŃ‚ŠøŠŗ" - -#. ~ Description for glowing tendril -#: lang/json/furniture_from_json.py -msgid "" -"A willowy tendril growing from the floor, gently waving back and forth. A " -"faint light spills from it." -msgstr "" -"Š˜Š·ŃŃ‰Š½Ń‹Š¹ Š¶Š³ŃƒŃ‚ŠøŠŗ, рŠ°ŃŃ‚ŃƒŃ‰ŠøŠ¹ ŠøŠ· ŠæŠ¾Š»Š°. ŠžŠ½ Š¼ŃŠ³ŠŗŠ¾ ŠŗŠ¾Š»Ń‹ŃˆŠµŃ‚ся Š²Š·Š°Š“ Šø Š²ŠæŠµŃ€Ń‘Š“. Š˜Š· Š½ŠµŠ³Š¾ " -"ŠæрŠ¾Š»ŠøŠ²Š°ŠµŃ‚ся тусŠŗŠ»Ń‹Š¹ сŠ²ŠµŃ‚." - -#: lang/json/furniture_from_json.py -msgid "splorch!" -msgstr "шŠ¼ŃŠŗ!" - -#: lang/json/furniture_from_json.py -msgid "wafting anemone" -msgstr "ŠæŠ°Ń€ŃŃ‰ŠøŠ¹ Š°Š½ŠµŠ¼Š¾Š½" - -#. ~ Description for wafting anemone -#: lang/json/furniture_from_json.py -msgid "" -"A fleshy white protuberance growing from the floor, with a cluster of " -"tendrils pouring out of it. It looks almost exactly like a sea anemone, " -"even waving gently as though underwater." -msgstr "" -"Š Š°ŃŃ‚ŃƒŃ‰ŠøŠ¹ ŠøŠ· ŠæŠ¾Š»Š° Š¼ŃŃŠøстыŠ¹ Š±ŠµŠ»Ń‹Š¹ Š±ŃƒŠ³Š¾Ń€Š¾Šŗ с ŠæучŠŗŠ¾Š¼ Š²Ń‹Š»ŠøŠ²Š°ŃŽŃ‰Šøхся щуŠæŠ°Š»ŠµŃ†. ŠžŠ½ " -"Š¾Ń‡ŠµŠ½ŃŒ ŠæŠ¾Ń…Š¾Š¶ Š½Š° Š¼Š¾Ń€ŃŠŗŠ¾Š¹ Š°Š½ŠµŠ¼Š¾Š½, Š“Š°Š¶Šµ Š¼ŃŠ³ŠŗŠ¾ ŠŗŠ¾Š»Ń‹ŃˆŠµŃ‚ся, ŠŗŠ°Šŗ Š±ŃƒŠ“тŠ¾ ŠæŠ¾Š“ Š²Š¾Š“Š¾Š¹." - -#: lang/json/furniture_from_json.py -msgid "gasping tube" -msgstr "ŠæыхтящŠ°Ń труŠ±ŠŗŠ°" - -#. ~ Description for gasping tube -#: lang/json/furniture_from_json.py -msgid "" -"This is a meaty green stalactite with a thickened hide like that of a " -"starfish, extending from the floor to the ceiling. In the center is a " -"series of ports somewhat like mouths, from which pour bursts of a vile-" -"smelling gas." -msgstr "" -"ŠœŃŃŠøстыŠ¹ Š·ŠµŠ»Ń‘Š½Ń‹Š¹ стŠ°Š»Š°ŠŗтŠøт с тŠ¾Š»ŃŃ‚Š¾Š¹ шŠŗурŠ¾Š¹, ŠæŠ¾Ń…Š¾Š¶ŠµŠ¹ Š½Š° ŠŗŠ¾Š¶Ńƒ Š¼Š¾Ń€ŃŠŗŠ¾Š¹ Š·Š²ŠµŠ·Š“ы," -" рŠ°ŃŃ‚ŃƒŃ‰ŠøŠ¹ с ŠæŠ¾Š»Š° Š“Š¾ ŠæŠ¾Ń‚Š¾Š»ŠŗŠ°. Š’ ŠµŠ³Š¾ сŠµŃ€ŠµŠ“ŠøŠ½Šµ ŠµŃŃ‚ŃŒ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ рŠ¾Ń‚Š¾ŠæŠ¾Š“Š¾Š±Š½Ń‹Ń… " -"Š¾Ń‚Š²ŠµŃ€ŃŃ‚ŠøŠ¹, ŠøŠ·Š²ŠµŃ€Š³Š°ŃŽŃ‰Šøх ŠŗŠ»ŃƒŠ±Ń‹ Š·Š»Š¾Š²Š¾Š½Š½Š¾Š³Š¾ Š³Š°Š·Š°." - -#: lang/json/furniture_from_json.py -msgid "twitching frond" -msgstr "Š“ёрŠ³Š°ŃŽŃ‰Š°ŃŃŃ Š²ŠµŃ‚ŠŗŠ°" - -#. ~ Description for twitching frond -#: lang/json/furniture_from_json.py -msgid "" -"A spine resembling moth antennae juts from the ground, swaying gently in the" -" air. Every so often, a cascade of energy arcs along it and discharges into" -" the ceiling." -msgstr "" -"ŠŸŠ¾Ń…Š¾Š¶ŠøŠ¹ Š½Š° усŠøŠŗ Š¼Š¾Ń‚Ń‹Š»ŃŒŠŗŠ° Š¾Ń‚Ń€Š¾ŃŃ‚Š¾Šŗ, Š²Ń‹ŠæŠøрŠ°ŃŽŃ‰ŠøŠ¹ ŠøŠ· Š·ŠµŠ¼Š»Šø. ŠžŠ½ Š¼ŃŠ³ŠŗŠ¾ ŠŗŠ¾Š»Ń‹ŃˆŠµŃ‚ся " -"Š½Š° Š²ŠµŃ‚Ń€Ńƒ. ŠŸŠµŃ€ŠøŠ¾Š“ŠøчŠµŃŠŗŠø ŠæŠ¾ Š½ŠµŠ¼Ńƒ ŠæрŠ¾Š±ŠµŠ³Š°ŠµŃ‚ эŠ½ŠµŃ€Š³ŠµŃ‚ŠøчŠµŃŠŗŠøŠ¹ рŠ°Š·Ń€ŃŠ“, ŠøсчŠµŠ·Š°Ń Š² " -"ŠæŠ¾Ń‚Š¾Š»ŠŗŠµ." - -#: lang/json/furniture_from_json.py -msgid "scarred lump" -msgstr "Š¾ŠæухŠ¾Š»ŃŒ сŠ¾ шрŠ°Š¼Š°Š¼Šø" - -#. ~ Description for scarred lump -#: lang/json/furniture_from_json.py -msgid "" -"This is a pile of nondescript alien flesh, twitching and belching strange " -"gases out of injured orifices." -msgstr "" -"ŠšŃƒŃ‡Š° Š½ŠµŠ¾ŠæŠøсуŠµŠ¼Š¾Š¹ Š“ёрŠ³Š°ŃŽŃ‰ŠµŃŃ ŠøŠ½Š¾ŠæŠ»Š°Š½ŠµŃ‚Š½Š¾Š¹ ŠæŠ»Š¾Ń‚Šø, ŠøŠ·Ń€Ń‹Š³Š°ŃŽŃ‰Š°Ń стрŠ°Š½Š½Ń‹Šµ Š³Š°Š·Ń‹ ŠøŠ· " -"ŠæŠ¾Š²Ń€ŠµŠ¶Š“ёŠ½Š½Ń‹Ń… Š¾Ń€Š³Š°Š½Š¾Š²." - -#: lang/json/furniture_from_json.py -msgid "slimy pod" -msgstr "сŠ»ŠøŠ·ŠøстыŠ¹ ŠŗŠ¾ŠŗŠ¾Š½" - -#. ~ Description for slimy pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a slick, translucent pod suspended on a thin stalk. It is covered " -"in a thick mucus, obscuring whatever is floating in the gel-like substance " -"inside." -msgstr "" -"Š”ŠŗŠ¾Š»ŃŒŠ·ŠŗŠøŠ¹ ŠæŠ¾Š»ŃƒŠæрŠ¾Š·Ń€Š°Ń‡Š½Ń‹Š¹ ŠŗŠ¾ŠŗŠ¾Š½, ŠæŠ¾Š“Š²ŠµŃˆŠµŠ½Š½Ń‹Š¹ Š½Š° тŠ¾Š½ŠŗŠ¾Š¼ стŠµŠ±ŠµŠ»ŃŒŠŗŠµ. ŠžŠ½ ŠæŠ¾Šŗрыт " -"Š³ŃƒŃŃ‚Š¾Š¹ сŠ»ŠøŠ·ŃŒŃŽ, сŠŗрыŠ²Š°ŃŽŃ‰ŠµŠ¹ ŠæŠ»Š°Š²Š°ŃŽŃ‰ŠµŠµ Š² Š³ŠµŠ»ŠµŠ¾Š±Ń€Š°Š·Š½Š¾Š¼ Š²ŠµŃ‰ŠµŃŃ‚Š²Šµ сŠ¾Š“ŠµŃ€Š¶ŠøŠ¼Š¾Šµ." - -#: lang/json/furniture_from_json.py -msgid "organ pod" -msgstr "ŠŗŠ¾ŠŗŠ¾Š½ с Š¾Ń€Š³Š°Š½Š°Š¼Šø" - -#. ~ Description for organ pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside you can see the" -" dimly outlined shape of human organs, floating in some kind of preservative" -" goo." -msgstr "" -"ŠŸŠ¾Š»ŃƒŠæрŠ¾Š·Ń€Š°Ń‡Š½Ń‹Š¹ ŠŗŠ¾ŠŗŠ¾Š½, ŠæŠ¾Š“Š²ŠµŃˆŠµŠ½Š½Ń‹Š¹ Š½Š° тŠ¾Š½ŠŗŠ¾Š¼ стŠµŠ±ŠµŠ»ŃŒŠŗŠµ. Š’Š½ŃƒŃ‚Ń€Šø Š²ŠøŠ“Š½Š¾ сŠ¼ŃƒŃ‚Š½Ń‹Šµ " -"Š¾Ń‡ŠµŃ€Ń‚Š°Š½Šøя чŠµŠ»Š¾Š²ŠµŃ‡ŠµŃŠŗŠøх Š¾Ń€Š³Š°Š½Š¾Š², ŠæŠ»Š°Š²Š°ŃŽŃ‰Šøх Š² ŠŗŠ°ŠŗŠ¾Š¹-тŠ¾ ŠŗŠ¾Š½ŃŠµŃ€Š²ŠøрующŠµŠ¹ сŠ»ŠøŠ·Šø." - -#: lang/json/furniture_from_json.py -msgid "resin pod" -msgstr "ŠŗŠ¾ŠŗŠ¾Š½ сŠ¾ сŠ¼Š¾Š»Š¾Š¹" - -#. ~ Description for resin pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside is a clean, " -"clear resinous-looking fluid. You could fairly easily tear it from the " -"stalk and take it with you." -msgstr "" -"ŠŸŠ¾Š»ŃƒŠæрŠ¾Š·Ń€Š°Ń‡Š½Ń‹Š¹ ŠŗŠ¾ŠŗŠ¾Š½, ŠæŠ¾Š“Š²ŠµŃˆŠµŠ½Š½Ń‹Š¹ Š½Š° тŠ¾Š½ŠŗŠ¾Š¼ стŠµŠ±ŠµŠ»ŃŒŠŗŠµ. Š’Š½ŃƒŃ‚Ń€Šø Š²ŠøŠ“Š½Š¾ чŠøстую " -"ŠæрŠ¾Š·Ń€Š°Ń‡Š½ŃƒŃŽ сŠ¼Š¾Š»Šøстую Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚ŃŒ. Š’Ń‹ Š¼Š¾Š¶ŠµŃ‚Šµ Š¾Ń‚Š½Š¾ŃŠøтŠµŠ»ŃŒŠ½Š¾ Š»ŠµŠ³ŠŗŠ¾ Š¾Ń‚Š¾Ń€Š²Š°Ń‚ŃŒ ŠŗŠ¾ŠŗŠ¾Š½ " -"Š¾Ń‚ стŠµŠ±ŠµŠ»ŃŒŠŗŠ° Šø Š·Š°Š±Ń€Š°Ń‚ŃŒ с сŠ¾Š±Š¾Š¹." - -#: lang/json/furniture_from_json.py -msgid "fleshy altar" -msgstr "Š¼ŃŃŠøстыŠ¹ Š°Š»Ń‚Š°Ń€ŃŒ" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "centrifuge" +msgstr "цŠµŠ½Ń‚Ń€ŠøфуŠ³Š°" -#. ~ Description for fleshy altar +#. ~ Description for centrifuge #: lang/json/furniture_from_json.py msgid "" -"This pulsing protuberance juts from the floor, its sides covered in scaled, " -"oozing skin. The surface is flat, but undulates softly. A handful of " -"unidentifiable appendages reach from the sides, suggesting a sort of " -"nightmarish living autodoc." +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. For some reason, this one has an attached battery pack. It could be " +"used to analyze a medical fluid sample, such as blood, if a test tube was " +"placed in it." msgstr "" -"ŠŸŃƒŠ»ŃŒŃŠøрующŠøŠ¹ Š²Ń‹ŃŃ‚ŃƒŠæ, ŠæрŠ¾Ń€Š°ŃŃ‚Š°ŃŽŃ‰ŠøŠ¹ ŠøŠ· ŠæŠ¾Š»Š°, ŠµŠ³Š¾ стŠµŠ½ŠŗŠø ŠæŠ¾Šŗрыты чŠµŃˆŃƒŠ¹Ń‡Š°Ń‚Š¾Š¹ " -"ŠøстŠµŠŗŠ°ŃŽŃ‰ŠµŠ¹ сŠ»ŠøŠ·ŃŒŃŽ ŠŗŠ¾Š¶ŠµŠ¹. Š£ Š½ŠµŠ³Š¾ ŠæŠ»Š¾ŃŠŗŠ°Ń Š¼ŃŠ³ŠŗŠ¾ ŠŗŠ¾Š»Ń‹Ń…Š°ŃŽŃ‰Š°ŃŃŃ ŠæŠ¾Š²ŠµŃ€Ń…Š½Š¾ŃŃ‚ŃŒ. ŠŸŠ¾ " -"стŠ¾Ń€Š¾Š½Š°Š¼ ŠµŃŃ‚ŃŒ Š¼Š½Š¾Š¶ŠµŃŃ‚Š²Š¾ Š½ŠµŠæŠ¾Š½ŃŃ‚Š½Ń‹Ń… ŠŗŠ¾Š½ŠµŃ‡Š½Š¾ŃŃ‚ŠµŠ¹, Š½Š°ŠæŠ¾Š¼ŠøŠ½Š°ŃŽŃ‰Šøх ŠŗŠ¾ŃˆŠ¼Š°Ń€Š½Ń‹Š¹ Š¶ŠøŠ²Š¾Š¹" -" Š°Š²Ń‚Š¾Š“Š¾Šŗ." +"Š¦ŠµŠ½Ń‚Ń€ŠøфуŠ³Š°, ŠæрŠøŠ±Š¾Ń€ Š“Š»Ń рŠ°Š·Š“ŠµŠ»ŠµŠ½Šøя Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚ŠµŠ¹ Š²Š¼ŠµŃŃ‚Šµ с Š°Š²Ń‚Š¾Š¼Š°Ń‚ŠøчŠµŃŠŗŠøŠ¼ " +"Š°Š½Š°Š»ŠøŠ·Š°Ń‚Š¾Ń€Š¾Š¼. Šš этŠ¾Š¹ Š·Š°Ń‡ŠµŠ¼-тŠ¾ ŠæŠ¾Š“ŠŗŠ»ŃŽŃ‡ŠµŠ½ Š°ŠŗŠŗуŠ¼ŃƒŠ»ŃŃ‚Š¾Ń€. Š” ŠµŃ‘ ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ Š¼Š¾Š¶Š½Š¾ " +"сŠ“ŠµŠ»Š°Ń‚ŃŒ Š°Š½Š°Š»ŠøŠ· Š¾Š±Ń€Š°Š·Ń†Š° Š¼ŠµŠ“ŠøцŠøŠ½ŃŠŗŠ¾Š¹ Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚Šø, ŠµŃŠ»Šø ŠæŠ¾Š¼ŠµŃŃ‚Šøть Š²Š½ŃƒŃ‚Ń€ŃŒ ŠæрŠ¾Š±ŠøрŠŗу." #: lang/json/furniture_from_json.py msgid "bathtub" @@ -131602,6 +132426,19 @@ msgstr "" "чтŠ¾ Š¾Š½ сŠ¾Š·Š“Š°Š½ Š“Š»Ń ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½Šøя Š½Š° Š¾Ń‚ŠŗрытŠ¾Š¼ Š²Š¾Š·Š“ухŠµ Šø уŠ“Š¾Š±Š½ŠµŠµ ŠæŠ¾ срŠ°Š²Š½ŠµŠ½Šøю с" " сŠøŠ“ŠµŠ½ŠøŠµŠ¼ Š½Š° Š·ŠµŠ¼Š»Šµ, Š¾Š½ Š½Šµ Š¾ŃŠ¾Š±ŠµŠ½Š½Š¾ уŠ“Š¾Š±ŠµŠ½." +#: lang/json/furniture_from_json.py +msgid "metal bench" +msgstr "Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠ°Ń сŠŗŠ°Š¼ŃŒŃ" + +#. ~ Description for metal bench +#: lang/json/furniture_from_json.py +msgid "" +"A bench made of scrap metal. Not the most comfortable furniture you've ever" +" seen." +msgstr "" +"Š”ŠŗŠ°Š¼ŃŒŃ ŠøŠ· Š¼ŠµŃ‚Š°Š»Š»Š¾Š»Š¾Š¼Š°. Š”Š°Š»ŠµŠŗŠ¾ Š½Šµ сŠ°Š¼Š¾Šµ уŠ“Š¾Š±Š½Š¾Šµ Š¼ŠµŃŃ‚Š¾ Š“Š»Ń сŠøŠ“ŠµŠ½Šøя ŠøŠ· Š²ŠøŠ“ŠµŠ½Š½Ń‹Ń…" +" Š²Š°Š¼Šø." + #: lang/json/furniture_from_json.py msgid "bulletin board" msgstr "Š“Š¾ŃŠŗŠ° Š¾Š±ŃŠŃŠ²Š»ŠµŠ½ŠøŠ¹" @@ -132210,6 +133047,35 @@ msgstr "" "ŠžŠ³Ń€Š¾Š¼Š½Ń‹Š¹ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠ¹ рŠµŠ·ŠµŃ€Š²ŃƒŠ°Ń€, ŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¹ Š¼Š¾Š¶Š½Š¾ ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ Š“Š»Ń Š±ŠµŠ·Š¾ŠæŠ°ŃŠ½Š¾Š³Š¾" " хрŠ°Š½ŠµŠ½Šøя Š±Š¾Š»ŃŒŃˆŠ¾Š³Š¾ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š° Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚Šø." +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "fuel tank" +msgstr "тŠ¾ŠæŠ»ŠøŠ²Š½Ń‹Š¹ рŠµŠ·ŠµŃ€Š²ŃƒŠ°Ń€" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with gasoline." +msgstr "Š‘Š°Šŗ, ŠæŠ¾Š»Š½Ń‹Š¹ Š±ŠµŠ½Š·ŠøŠ½Š°." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken fuel tank" +msgstr "ŠæрŠ¾Š±ŠøтыŠ¹ тŠ¾ŠæŠ»ŠøŠ²Š½Ń‹Š¹ рŠµŠ·ŠµŃ€Š²ŃƒŠ°Ń€" + +#. ~ Description for broken fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with gasoline." +msgstr "ŠŸŃ€Š¾Š±ŠøтыŠ¹ тŠ¾ŠæŠ»ŠøŠ²Š½Ń‹Š¹ Š±Š°Šŗ, Š² ŠŗŠ¾Ń‚Š¾Ń€Š¾Š¼ Š±Ń‹Š» Š±ŠµŠ½Š·ŠøŠ½." + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with diesel." +msgstr "Š‘Š°Šŗ, Š½Š°ŠæŠ¾Š»Š½ŠµŠ½Š½Ń‹Š¹ Š“ŠøŠ·ŠµŠ»ŠµŠ¼." + +#. ~ Description for broken fuel tank +#. ~ Description for broken diesel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with diesel." +msgstr "ŠŸŃ€Š¾Š±ŠøтыŠ¹ тŠ¾ŠæŠ»ŠøŠ²Š½Ń‹Š¹ Š±Š°Šŗ, Š² ŠŗŠ¾Ń‚Š¾Ń€Š¾Š¼ Š±Ń‹Š» Š“ŠøŠ·ŠµŠ»ŃŒ." + #: lang/json/furniture_from_json.py msgid "dumpster" msgstr "Š¼ŃƒŃŠ¾Ń€Š½Ń‹Š¹ Š±Š°Šŗ" @@ -132238,6 +133104,51 @@ msgstr "" "ŠœŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠ°Ń труŠ±Š° сŠ¾ Š²ŃŃ‚Ń€Š¾ŠµŠ½Š½Ń‹Š¼ ŠæŠ¾Ń€ŃˆŠ½ŠµŠ¼ Š“Š»Ń Š²Š·Š±ŠøŠ²Š°Š½Šøя Š¼Š°ŃŠ»Š°. Š’Š¼ŠµŃŃ‚Š¾ " "эŠ»ŠµŠŗтрŠøчŠµŃŃ‚Š²Š° Š“Š»Ń ŠµŠ³Š¾ рŠ°Š±Š¾Ń‚Ń‹ ŠøсŠæŠ¾Š»ŃŒŠ·ŃƒŃŽŃ‚ся ŠæŠµŠ“Š°Š»Šø." +#: lang/json/furniture_from_json.py +msgid "riveted metal crate" +msgstr "ŠŗŠ»Ń‘ŠæŠ°Š½Š½Ń‹Š¹ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠ¹ ящŠøŠŗ" + +#. ~ Description for riveted metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This huge box is made of a dull metal, riveted together. There is no " +"obvious opening mechanism, and the rivets don't match any of your tools. " +"The only way in would be to smash it." +msgstr "" +"Š‘Š¾Š»ŃŒŃˆŠ¾Š¹ ящŠøŠŗ ŠøŠ· тусŠŗŠ»Š¾Š³Š¾ Š¼ŠµŃ‚Š°Š»Š»Š°, сŠŗŠ»Ń‘ŠæŠ°Š½Š½Š¾Š³Š¾ Š²Š¼ŠµŃŃ‚Šµ. Š’Ń‹ Š½Šµ Š²ŠøŠ“ŠøтŠµ " +"Š¾Ń‡ŠµŠ²ŠøŠ“Š½Š¾Š³Š¾ сŠæŠ¾ŃŠ¾Š±Š° Š¾Ń‚Šŗрыть ŠµŠ³Š¾, Šø Š·Š°ŠŗŠ»Ń‘ŠæŠŗŠø Š½Šµ ŠæŠ¾Š“хŠ¾Š“ят Š½Šø Šŗ Š¾Š“Š½Š¾Š¼Ńƒ ŠøŠ· Š²Š°ŃˆŠøх " +"ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚Š¾Š². Š•Š“ŠøŠ½ŃŃ‚Š²ŠµŠ½Š½Ń‹Š¹ сŠæŠ¾ŃŠ¾Š± Š¾Ń‚Šŗрыть ŠµŠ³Š¾ - сŠ»Š¾Š¼Š°Ń‚ŃŒ." + +#: lang/json/furniture_from_json.py +msgid "sealed metal crate" +msgstr "Š·Š°ŠæŠµŃ‡Š°Ń‚Š°Š½Š½Ń‹Š¹ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠ¹ ящŠøŠŗ" + +#. ~ Description for sealed metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This is a huge, tightly sealed storage crate made from welded and riveted " +"sheet metal. The sealing mechanism is too tight to open bare-handed and " +"would need some kind of prying instrument to release." +msgstr "" +"Š‘Š¾Š»ŃŒŃˆŠ¾Š¹, ŠæŠ»Š¾Ń‚Š½Š¾ Š·Š°ŠŗрытыŠ¹ ящŠøŠŗ ŠøŠ· сŠ²Š°Ń€ŠµŠ½Š½Š¾Š³Š¾ Šø ŠŗŠ»Ń‘ŠæŠ°Š½Š¾Š³Š¾ Š»ŠøстŠ¾Š²Š¾Š³Š¾ Š¼ŠµŃ‚Š°Š»Š»Š°. " +"Š—Š°ŠæŠøрŠ°ŃŽŃ‰ŠøŠ¹ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼ сŠ»ŠøшŠŗŠ¾Š¼ туŠ³Š¾Š¹, чтŠ¾Š±Ń‹ Š¾Ń‚ŠŗрыŠ²Š°Ń‚ŃŒ ŠµŠ³Š¾ руŠŗŠ°Š¼Šø, Šø Š“Š»Ń ŠµŠ³Š¾ " +"Š²ŃŠŗрытŠøя ŠæŠ¾Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠŗŠ°ŠŗŠ¾Š¹-Š½ŠøŠ±ŃƒŠ“ь ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚." + +#: lang/json/furniture_from_json.py +msgid "open metal crate" +msgstr "Š¾Ń‚ŠŗрытыŠ¹ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠ¹ ящŠøŠŗ" + +#. ~ Description for open metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This large metal crateā€™s lid is unsealed, and hinges open easily to reveal a" +" number of storage shelves inside. Once open, the side panels also swing " +"wider for easy access." +msgstr "" +"Š­Ń‚Š¾Ń‚ Š±Š¾Š»ŃŒŃˆŠ¾Š¹ Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠ¹ ящŠøŠŗ Š¾Ń‚Šŗрыт, Šø ŠæŠµŃ‚Š»Šø ŠŗрышŠŗŠø Š»ŠµŠ³ŠŗŠ¾ " +"Š¾Ń‚ŠŗрыŠ²Š°ŃŽŃ‚ся,Š“ŠµŠ¼Š¾Š½ŃŃ‚Ń€Šøруя ряŠ“ ŠæŠ¾Š»Š¾Šŗ Š“Š»Ń хрŠ°Š½ŠµŠ½Šøя Š²Š½ŃƒŃ‚Ń€Šø. ŠŸŠø Š¾Ń‚ŠŗрытŠøŠø Š±Š¾ŠŗŠ¾Š²Ń‹Šµ " +"ŠæŠ°Š½ŠµŠ»Šø тŠ°ŠŗŠ¶Šµ рŠ°ŃŠæŠ°Ń…ŠøŠ²Š°ŃŽŃ‚ся Š“Š»Ń Š¾Š±Š»ŠµŠ³Ń‡ŠµŠ½Šøя Š“Š¾ŃŃ‚ŃƒŠæŠ°." + #: lang/json/furniture_from_json.py msgid "counter" msgstr "ŠæрŠøŠ»Š°Š²Š¾Šŗ" @@ -132347,6 +133258,15 @@ msgstr "Š­Ń‚Š¾ стŠ¾Š», Š·Š° Š½ŠøŠ¼ ŠµŠ“ят." msgid "a low table for livingrooms." msgstr "Š½ŠøŠ·ŠŗŠøŠ¹ стŠ¾Š»ŠøŠŗ Š“Š»Ń Š³Š¾ŃŃ‚ŠøŠ½Ń‹Ń…." +#: lang/json/furniture_from_json.py +msgid "metal table" +msgstr "Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠ¹ стŠ¾Š»" + +#. ~ Description for metal table +#: lang/json/furniture_from_json.py +msgid "A serviceable but simple table made of scrap metal." +msgstr "Š£Š“Š¾Š±Š½Ń‹Š¹, Š½Š¾ ŠæрŠ¾ŃŃ‚Š¾Š¹ стŠ¾Š» ŠøŠ· Š¼ŠµŃ‚Š°Š»Š»Š¾Š»Š¾Š¼Š°." + #: lang/json/furniture_from_json.py msgid "tatami mat" msgstr "тŠ°Ń‚Š°Š¼Šø" @@ -132589,6 +133509,19 @@ msgstr "Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠµ Š¾Š±Š»Š¾Š¼ŠŗŠø" msgid "Pile of various bent and twisted metals." msgstr "ŠšŃƒŃ‡Š° рŠ°Š·Š½Ń‹Ń… Š³Š½ŃƒŃ‚Ń‹Ń… Šø сŠŗручŠµŠ½Š½Ń‹Ń… Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøх штуŠŗŠ¾Š²ŠøŠ½." +#: lang/json/furniture_from_json.py +msgid "radioactive slag" +msgstr "рŠ°Š“ŠøŠ¾Š°ŠŗтŠøŠ²Š½Ń‹Š¹ шŠ»Š°Š¼" + +#. ~ Description for radioactive slag +#: lang/json/furniture_from_json.py +msgid "" +"A pile of melted slag from a destroyed nuclear reactor. What are you doing " +"looking at this? Get the hell out of here, you nutcase!" +msgstr "" +"Š“Š¾Ń€Š° рŠ°ŃŠæŠ»Š°Š²Š»ŠµŠ½Š½Š¾Š³Š¾ шŠ»Š°Š¼Š° ŠøŠ· рŠ°Š·Ń€ŃƒŃˆŠµŠ½Š½Š¾Š³Š¾ яŠ“ŠµŃ€Š½Š¾Š³Š¾ рŠµŠ°ŠŗтŠ¾Ń€Š°. ŠšŠ°ŠŗŠ¾Š³Š¾ чёртŠ° ты" +" тут стŠ¾Šøшь Šø рŠ°ŃŃŠ¼Š°Ń‚Ń€ŠøŠ²Š°ŠµŃˆŃŒ ŠµŠ³Š¾? Š’Š°Š»Šø Š¾Ń‚сюŠ“Š° ŠæŠ¾ŃŠŗŠ¾Ń€ŠµŠµ, ŠæсŠøх!" + #: lang/json/furniture_from_json.py msgid "pile of ash" msgstr "ŠŗучŠŗŠ° ŠæŠµŠæŠ»Š°" @@ -132672,6 +133605,44 @@ msgstr "" "Š”Š»ŠøŠ½Š½Ń‹Š¹ Š“ŠµŃ€ŠµŠ²ŃŠ½Š½Ń‹Š¹ стŠ¾Š»Š±, ŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¹ рŠ°Š½ŃŒŃˆŠµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°Š» Š²Š¾Š·Š“ушŠ½Ń‹Šµ Š»ŠøŠ½ŠøŠø " "эŠ»ŠµŠŗтрŠ¾ŠæŠµŃ€ŠµŠ“Š°Ń‡ Šø Š“руŠ³ŠøŠµ ŠŗŠ¾Š¼Š¼ŃƒŠ½ŠøŠŗŠ°Ń†ŠøŠø. Š‘Š¾Š»ŃŒŃˆŠµ Š½Šµ рŠ°Š±Š¾Ń‚Š°ŠµŃ‚." +#: lang/json/furniture_from_json.py +msgid "scrap metal bridge" +msgstr "Š¼Š¾ŃŃ‚ ŠøŠ· Š¼ŠµŃ‚Š°Š»Š»Š¾Š»Š¾Š¼Š°" + +#. ~ Description for scrap metal bridge +#: lang/json/furniture_from_json.py +msgid "A simple bridge made of riveted sheet metal." +msgstr "ŠŸŃ€Š¾ŃŃ‚Š¾Š¹ Š¼Š¾ŃŃ‚ ŠøŠ· ŠŗŠ»Ń‘ŠæŠ°Š½Š½Ń‹Ń… Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøх Š»ŠøстŠ¾Š²." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py +msgid "broken console" +msgstr "сŠ»Š¾Š¼Š°Š½Š½Ń‹Š¹ тŠµŃ€Š¼ŠøŠ½Š°Š»" + +#. ~ Description for broken console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It doesn't seem to be working. " +"It's the broken screen and shattered circuit boards that's telling you that." +msgstr "" +"ŠšŠ¾Š¼ŠæьютŠµŃ€Š½Ń‹Š¹ тŠµŃ€Š¼ŠøŠ½Š°Š». Š’ŠµŃ€Š¾ŃŃ‚Š½Š¾, Š¾Š½ Š±Š¾Š»ŃŒŃˆŠµ Š½Šµ рŠ°Š±Š¾Ń‚Š°ŠµŃ‚. Š’Š°Š¼ этŠ¾ ŠæŠ¾Š“сŠŗŠ°Š·Ń‹Š²Š°ŃŽŃ‚" +" рŠ°Š·Š±ŠøтыŠ¹ эŠŗрŠ°Š½ Šø ŠæŠ¾Š»Š¾Š¼Š°Š½Š½Ń‹Šµ схŠµŠ¼Ń‹." + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "computer console" +msgstr "тŠµŃ€Š¼ŠøŠ½Š°Š»" + +#. ~ Description for computer console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It can be used to view contents and" +" perform any allowed functions. It might even be possible to hack it, given" +" the skills." +msgstr "" +"ŠšŠ¾Š¼ŠæьютŠµŃ€Š½Ń‹Š¹ тŠµŃ€Š¼ŠøŠ½Š°Š». Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ ŠµŠ³Š¾ Š“Š»Ń Š“Š¾ŃŃ‚ŃƒŠæŠ° Šŗ сŠ¾Š“ŠµŃ€Š¶ŠøŠ¼Š¾Š¼Ńƒ Šø " +"Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя Š»ŃŽŠ±Ń‹Ń… ŠæŠ¾Š·Š²Š¾Š»ŠµŠ½Š½Ń‹Ń… фуŠ½ŠŗцŠøŠ¹. Š•ŃŠ»Šø хŠ²Š°Ń‚Šøт Š½Š°Š²Ń‹ŠŗŠ¾Š², ŠµŠ³Š¾ Š“Š°Š¶Šµ Š¼Š¾Š¶Š½Š¾ " +"Š²Š·Š»Š¾Š¼Š°Ń‚ŃŒ." + #: lang/json/furniture_from_json.py msgid "forge" msgstr "ŠŗуŠ·Š½Ń" @@ -133094,6 +134065,15 @@ msgstr "" "Š’Ń€ŃŠ“ Š»Šø Š²Ń‹Š¹Š“ŠµŃ‚ чтŠ¾-тŠ¾ ŠŗуŠæŠøть, Š²ŃŃ‘ сŠ»Š¾Š¼Š°Š½Š¾. ŠŠ°Š²ŠµŃ€Š½Š¾, ŠµŃŠ»Šø рŠ°Š·Š»Š¾Š¼Š°Ń‚ŃŒ ŠæŠ¾Š±Š¾Š»ŃŒŃˆŠµ," " тŠ¾ ŠæŠ»Š°Ń‚Šøть Š²Š¾Š¾Š±Ń‰Šµ Š½Šµ ŠæрŠøŠ“ётся!" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "rope leading up" +msgstr "Š²ŠµŠ“ущŠ°Ń Š²Š²ŠµŃ€Ń… Š²ŠµŃ€Ń‘Š²ŠŗŠ°" + +#. ~ Description for rope leading up +#: lang/json/furniture_from_json.py +msgid "A rope. You could climb it up." +msgstr "Š’ŠµŃ€Ń‘Š²ŠŗŠ°. ŠŸŠ¾ Š½ŠµŠ¹ Š¼Š¾Š¶Š½Š¾ Š²Š·Š¾Š±Ń€Š°Ń‚ŃŒŃŃ Š½Š°Š²ŠµŃ€Ń…." + #: lang/json/furniture_from_json.py msgid "atomic butter churn on a stand" msgstr "Š°Ń‚Š¾Š¼Š½Š°Ń Š¼Š°ŃŠ»Š¾Š±Š¾Š¹ŠŗŠ° Š½Š° ŠæŠ¾Š“стŠ°Š²ŠŗŠµ" @@ -138107,6 +139087,23 @@ msgstr "" "ŠŠµŠµŃŃ‚ŠµŃŃ‚Š²ŠµŠ½Š½Ń‹Šµ эŠ»ŠµŠŗтрŠøчŠµŃŠŗŠøŠµ рŠ°Š·Ń€ŃŠ“ы стŠµŠŗŠ°ŃŽŃ‚ с ŠŗŠ¾Š½Ń‡ŠøŠŗŠ¾Š² этŠ¾Š¹ чуŠ¶ŠµŃ€Š¾Š“Š½Š¾Š¹ " "Š²ŠµŃ‚Š²Šø." +#: lang/json/gun_from_json.py +msgid "hurled rubble" +msgid_plural "hurled rubbles" +msgstr[0] "Š±Ń€Š¾ŃˆŠµŠ½Š½Ń‹Š¹ Š¾Š±Š»Š¾Š¼Š¾Šŗ" +msgstr[1] "Š±Ń€Š¾ŃˆŠµŠ½Š½Ń‹Ń… Š¾Š±Š»Š¾Š¼ŠŗŠ°" +msgstr[2] "Š±Ń€Š¾ŃˆŠµŠ½Š½Ń‹Ń… Š¾Š±Š»Š¾Š¼ŠŗŠ¾Š²" +msgstr[3] "Š±Ń€Š¾ŃˆŠµŠ½Š½Ń‹Šµ Š¾Š±Š»Š¾Š¼ŠŗŠø" + +#: lang/json/gun_from_json.py +msgid "Stone at the ready to crush that which isn't part of the blob." +msgstr "ŠšŠ°Š¼ŠµŠ½ŃŒ, Š³Š¾Ń‚Š¾Š²Ń‹Š¹ рŠ°Š·Š¼Š¾Š·Š¶Šøть тŠ¾, чтŠ¾ Š½Šµ яŠ²Š»ŃŠµŃ‚ся чŠ°ŃŃ‚ŃŒŃŽ Š±Š»Š¾Š±Š°." + +#: lang/json/gun_from_json.py +msgctxt "gun_type_type" +msgid "throw" +msgstr "Š¼ŠµŃ‚Š°Ń‚ŠµŠ»ŃŒŠ½Š¾Šµ" + #: lang/json/gun_from_json.py msgid "nail gun" msgid_plural "nail guns" @@ -138183,7 +139180,7 @@ msgstr[3] "сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Ń‹Šµ рычŠ°Š¶Š½Ń‹Šµ Š“рŠ¾Š±Š¾Š²ŠøŠŗŠø" msgid "" "A short homemade lever-action shotgun with a small internal tube magazine. " "While still a primitive pipe and 2x4 design, it is a formiddable shotgun in " -"it's own right with room for improvement." +"its own right with room for improvement." msgstr "" "ŠšŠ¾Ń€Š¾Ń‚ŠŗŠøŠ¹ сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Ń‹Š¹ рычŠ°Š¶Š½Ń‹Š¹ Š“рŠ¾Š±Š¾Š²ŠøŠŗ с Š¼Š°Š»ŠµŠ½ŃŒŠŗŠøŠ¼ Š²ŃŃ‚Ń€Š¾ŠµŠ½Š½Ń‹Š¼ труŠ±Ń‡Š°Ń‚Ń‹Š¼ " "Š¼Š°Š³Š°Š·ŠøŠ½Š¾Š¼. Š„Š¾Ń‚я Š² цŠµŠ»Š¾Š¼ этŠ¾ Š½ŠµŠ¼Š½Š¾Š³ŠøŠ¼ Š±Š¾Š»ŃŒŃˆŠµ чŠµŠ¼ Š“Š¾ŃŠŗŠ° с ŠæрŠøŠŗрŠµŠæŠ»Ń‘Š½Š½Ń‹Š¼ " @@ -138672,12 +139669,12 @@ msgstr "" " ŠæŠ¾Š“Š¾Š¹Š“ŠµŃ‚." #: lang/json/gun_from_json.py -msgid "four winds shotgun" -msgid_plural "four winds shotguns" -msgstr[0] "сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Ń‹Š¹ Š“рŠ¾Š±Š¾Š²ŠøŠŗ Š²Ń‹Š¶ŠøŠ²Š°Š»ŃŒŃ‰ŠøŠŗŠ°" -msgstr[1] "сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Ń‹Ń… Š“рŠ¾Š±Š¾Š²ŠøŠŗŠ° Š²Ń‹Š¶ŠøŠ²Š°Š»ŃŒŃ‰ŠøŠŗŠ°" -msgstr[2] "сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Ń‹Ń… Š“рŠ¾Š±Š¾Š²ŠøŠŗŠ¾Š² Š²Ń‹Š¶ŠøŠ²Š°Š»ŃŒŃ‰ŠøŠŗŠ°" -msgstr[3] "сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Ń‹Šµ Š“рŠ¾Š±Š¾Š²ŠøŠŗŠø Š²Ń‹Š¶ŠøŠ²Š°Š»ŃŒŃ‰ŠøŠŗŠ°" +msgid "slam-fire pipe shotgun" +msgid_plural "slam-fire pipe shotguns" +msgstr[0] "уŠ“Š°Ń€Š½Ń‹Š¹ Š“рŠ¾Š±Š¾Š²ŠøŠŗ" +msgstr[1] "уŠ“Š°Ń€Š½Ń‹Ń… Š“рŠ¾Š±Š¾Š²ŠøŠŗŠ°" +msgstr[2] "уŠ“Š°Ń€Š½Ń‹Ń… Š“рŠ¾Š±Š¾Š²ŠøŠŗŠ¾Š²" +msgstr[3] "уŠ“Š°Ń€Š½Ń‹Šµ Š“рŠ¾Š±Š¾Š²ŠøŠŗŠø" #: lang/json/gun_from_json.py msgid "" @@ -138687,6 +139684,23 @@ msgstr "" "Š“Ń€ŃƒŠ±Ń‹Š¹ Š“рŠ¾Š±Š¾Š²ŠøŠŗ - Š“Š²Šµ тŠ¾Š»ŃŃ‚Ń‹Šµ стŠ°Š»ŃŒŠ½Ń‹Šµ труŠ±Ń‹ Šø Š·Š°Š³Š»ŃƒŃˆŠŗŠ° с Š³Š²Š¾Š·Š“ёŠ¼. Š˜Š·-Š·Š° " "Š¾Ń‚ŃŃƒŃ‚ŃŃ‚Š²Šøя ŠæрŠøцŠµŠ»Š° эффŠµŠŗтŠøŠ²Š½Š¾ тŠ¾Š»ŃŒŠŗŠ¾ ŠæрŠø стрŠµŠ»ŃŒŠ±Šµ ŠæрŠ°ŠŗтŠøчŠµŃŠŗŠø Š² уŠæŠ¾Ń€." +#: lang/json/gun_from_json.py +msgid "double slam-fire pipe shotgun" +msgid_plural "double slam-fire pipe shotguns" +msgstr[0] "сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Š°Ń Š“Š²ŃƒŃŃ‚Š²Š¾Š»ŠŗŠ°" +msgstr[1] "сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Ń‹Šµ Š“Š²ŃƒŃŃ‚Š²Š¾Š»ŠŗŠø" +msgstr[2] "сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Ń‹Ń… Š“Š²ŃƒŃŃ‚Š²Š¾Š»Š¾Šŗ" +msgstr[3] "сŠ°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Ń‹Šµ Š“Š²ŃƒŃŃ‚Š²Š¾Š»ŠŗŠø" + +#: lang/json/gun_from_json.py +msgid "" +"A crude shotgun, composed of four thick steel pipes, two end caps and two " +"nails. The lack of sights make this weapon only useful at point-blank " +"range." +msgstr "" +"Š“Ń€ŃƒŠ±Ń‹Š¹ Š“рŠ¾Š±Š¾Š²ŠøŠŗ - чŠµŃ‚Ń‹Ń€Šµ тŠ¾Š»ŃŃ‚Ń‹Šµ стŠ°Š»ŃŒŠ½Ń‹Šµ труŠ±Ń‹ Šø Š“Š²Šµ Š·Š°Š³Š»ŃƒŃˆŠŗŠø с Š³Š²Š¾Š·Š“ёŠ¼. " +"Š˜Š·-Š·Š° Š¾Ń‚ŃŃƒŃ‚ŃŃ‚Š²Šøя ŠæрŠøцŠµŠ»Š° эффŠµŠŗтŠøŠ²Š½Š¾ тŠ¾Š»ŃŒŠŗŠ¾ ŠæрŠø стрŠµŠ»ŃŒŠ±Šµ ŠæрŠ°ŠŗтŠøчŠµŃŠŗŠø Š² уŠæŠ¾Ń€." + #: lang/json/gun_from_json.py msgid "flaregun" msgid_plural "flareguns" @@ -139297,11 +140311,6 @@ msgid "" msgstr "" "ŠšŠ¾Š¶Š°Š½Š°Ń ŠæрŠ°Ń‰Š°, ŠæŠ¾Š·Š²Š¾Š»ŃŠµŃ‚ Š·Š°ŠæустŠøть ŠŗŠ°Š¼ŠµŠ½ŃŒ ŠŗуŠ“Š° сŠøŠ»ŃŒŠ½ŠµŠµ Šø Š“Š°Š»ŃŒŃˆŠµ, чŠµŠ¼ руŠŗŠ¾Š¹." -#: lang/json/gun_from_json.py -msgctxt "gun_type_type" -msgid "throw" -msgstr "Š¼ŠµŃ‚Š°Ń‚ŠµŠ»ŃŒŠ½Š¾Šµ" - #: lang/json/gun_from_json.py msgid "slingshot" msgid_plural "slingshots" @@ -146790,6 +147799,11 @@ msgstr "" "ŠžŃ‚сюŠ“Š° Š¼Š¾Š¶Š½Š¾ уŠæрŠ°Š²Š»ŃŃ‚ŃŒ трŠ°Š½ŃŠæŠ¾Ń€Ń‚Š¾Š¼, ŠµŃŠ»Šø ŠµŃŃ‚ŃŒ сŠøŠ“ŠµŠ½ŃŒŠµ ŠøŠ»Šø сŠµŠ“Š»Š¾. Š’Ń‹ Š¼Š¾Š¶ŠµŃ‚Šµ " "Ā«eĀ» ŠøŠ·ŃƒŃ‡Šøть тŠ°Š¹Š» ŠøŠ»Šø ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ ŠŗŠ»Š°Š²Šøшу уŠæрŠ°Š²Š»ŠµŠ½Šøя (ŠæŠ¾ уŠ¼Š¾Š»Ń‡Š°Š½Šøю Ā«^Ā»)." +#. ~ Please leave anything in unchanged. +#: lang/json/json_flag_from_json.py +msgid "When active, turns engines on and off automatically." +msgstr "ŠšŠ¾Š³Š“Š° Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾, Š°Š²Ń‚Š¾Š¼Š°Ń‚ŠøчŠµŃŠŗŠø Š·Š°ŠæусŠŗŠ°ŠµŃ‚ Šø Š¾ŃŃ‚Š°Š½Š°Š²Š»ŠøŠ²Š°ŠµŃ‚ Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»Šø." + #. ~ Please leave anything in unchanged. #: lang/json/json_flag_from_json.py msgid "Illuminated items in this space will not illuminate nearby squares." @@ -148511,6 +149525,10 @@ msgstr "Š’ŠŗŠ»/Š²Ń‹ŠŗŠ» Š²Š¾Š“Š¾Š¾Ń‡ŠøстŠøтŠµŠ»ŃŒ" msgid "Toggle tracking" msgstr "Š’ŠŗŠ»/Š²Ń‹ŠŗŠ» Š¾Ń‚сŠ»ŠµŠ¶ŠøŠ²Š°Š½ŠøŠµ" +#: lang/json/keybinding_from_json.py +msgid "Toggle smart engine controller" +msgstr "ŠŸŠµŃ€ŠµŠŗŠ»ŃŽŃ‡Šøть уŠ¼Š½Š¾Šµ уŠæрŠ°Š²Š»ŠµŠ½ŠøŠµ Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø" + #: lang/json/keybinding_from_json.py src/turret.cpp src/vehicle_use.cpp msgid "Set turret firing modes" msgstr "Š£ŃŃ‚Š°Š½Š¾Š²Šøть рŠµŠ¶ŠøŠ¼Ń‹ стрŠµŠ»ŃŒŠ±Ń‹ турŠµŠ»ŠµŠ¹" @@ -168982,19 +170000,6 @@ msgstr "" " Š² рŠµŠ³ŠøŠ¾Š½Šµ ŠŠ¾Š²Š¾Š¹ ŠŠ½Š³Š»ŠøŠø, сŠ¾Š³Š»Š°ŃŠ½Š¾ сŠ¾Š³Š»Š°ŃˆŠµŠ½ŠøяŠ¼ Š¼ŠµŠ¶Š“у штŠ°Ń‚Š°Š¼Šø. ŠžŠ·Š½Š°Ń‡Š°ŠµŃ‚ Š»Šø этŠ¾" " чтŠ¾-Š½ŠøŠ±ŃƒŠ“ь тŠµŠæŠµŃ€ŃŒ, уŠ¶Šµ Š“руŠ³Š¾Š¹ Š²Š¾ŠæрŠ¾Ń." -#: lang/json/mutation_from_json.py -msgid "Helicopter Pilot" -msgstr "ŠŸŠøŠ»Š¾Ń‚ Š²ŠµŃ€Ń‚Š¾Š»Ń‘Ń‚Š°" - -#. ~ Description for Helicopter Pilot -#: lang/json/mutation_from_json.py -msgid "" -"You are a trained helicopter pilot. This makes you one of the few living " -"people who can operate a helicopter after the Cataclysm." -msgstr "" -"Š’Ń‹ уŠ¼ŠµŠµŃ‚Šµ ŠæŠøŠ»Š¾Ń‚ŠøрŠ¾Š²Š°Ń‚ŃŒ Š²ŠµŃ€Ń‚Š¾Š»ŠµŃ‚. Š›ŃŽŠ“ŠµŠ¹ с тŠ°ŠŗŠøŠ¼ Š½Š°Š²Ń‹ŠŗŠ¾Š¼ ŠæŠ¾ŃŠ»Šµ ŠšŠ°Ń‚Š°ŠŗŠ»ŠøŠ·Š¼Š° " -"Š¼Š¾Š¶Š½Š¾ ŠæŠ¾ ŠæŠ°Š»ŃŒŃ†Š°Š¼ ŠæŠµŃ€ŠµŃŃ‡ŠøтŠ°Ń‚ŃŒ." - #: lang/json/mutation_from_json.py msgid "SWAT Officer" msgstr "ŠžŃ„ŠøцŠµŃ€ сŠæŠµŃ†Š½Š°Š·Š°" @@ -174311,6 +175316,10 @@ msgstr "Š“Š¾Š·Š¾Ń€Š½Š°Ń Š±Š°ŃˆŠ½Ń Š¼Šø-Š³Š¾" msgid "subway station?" msgstr "стŠ°Š½Ń†Šøя Š¼ŠµŃ‚Ń€Š¾?" +#: lang/json/overmap_terrain_from_json.py +msgid "science lab reactor" +msgstr "рŠµŠ°ŠŗтŠ¾Ń€ Š½Š°ŃƒŃ‡Š½Š¾Š¹ Š»Š°Š±Š¾Ń€Š°Ń‚Š¾Ń€ŠøŠø" + #: lang/json/overmap_terrain_from_json.py msgid "lab" msgstr "Š»Š°Š±Š¾Ń€Š°Ń‚Š¾Ń€Šøя" @@ -183001,6 +184010,18 @@ msgstr "" "Š’Ń‹ ā€” ŠŗŠ°Ń€Š°Š¼ŠµŠ»ŃŒ Š² фŠ¾Ń€Š¼Šµ чŠµŠ»Š¾Š²ŠµŠŗŠ°, Š¾Š¶ŠøŠ²Š»Ń‘Š½Š½Š°Ń Š² хŠ¾Š“Šµ Š½ŠµŃŃŠ½Ń‹Ń… сŠ¾Š±Ń‹Ń‚ŠøŠ¹. Š£ Š²Š°Ń " "Š²ŠæŠµŃ€ŠµŠ“Šø цŠµŠ»Š°Ń Š¶ŠøŠ·Š½ŃŒ, Šø Š¾Š½Š° Š±ŃƒŠ“ŠµŃ‚ сŠ»Š°Š“ŠŗŠ¾Š¹!" +#: lang/json/proficiency_from_json.py +msgid "Knapping" +msgstr "ŠžŠ±Ń‚ёсыŠ²Š°Š½ŠøŠµ ŠŗŠ°Š¼Š½Ń" + +#: lang/json/proficiency_from_json.py +msgid "Blacksmithing" +msgstr "ŠšŃƒŠ·Š½ŠµŃ‡ŠµŃŃ‚Š²Š¾" + +#: lang/json/proficiency_from_json.py +msgid "Helicopter Piloting" +msgstr "ŠŸŠøŠ»Š¾Ń‚ŠøрŠ¾Š²Š°Š½ŠøŠµ Š²ŠµŃ€Ń‚Š¾Š»Ń‘Ń‚Š°" + #. ~ Crafting recipes category name #: lang/json/recipe_category_from_json.py msgid "*" @@ -192433,7 +193454,7 @@ msgstr "ŠŠµŠæŠ¾Š½ŃŃ‚Š½Š°Ń рŠ¾Š·Š¾Š²Š°Ń тŠ°Š±Š»ŠµŃ‚ŠŗŠ°, Š²Š°Š»ŃŠ²ŃˆŠ°ŃŃ msgid "Finally, something to take the edge off." msgstr "ŠŠ°ŠŗŠ¾Š½ŠµŃ† чтŠ¾-тŠ¾, чтŠ¾Š± сŠ±Ń€Š¾ŃŠøть ŠæŠ°Ń€." -#: lang/json/snippet_from_json.py src/npctalk.cpp +#: lang/json/snippet_from_json.py src/talker_npc.cpp msgid "No thanks, I'm good." msgstr "ŠŠµŃ‚, сŠæŠ°ŃŠøŠ±Š¾, Š¼Š½Šµ Š½Š¾Ń€Š¼." @@ -215780,6 +216801,18 @@ msgstr "Š­Ń‚Š¾ тŠµŃŃ‚Š¾Š²Ń‹Š¹ Š¾Ń‚Š²ŠµŃ‚ u_has_var, u_remove_var." msgid "This is a npc_has_var, npc_remove_var test response." msgstr "Š­Ń‚Š¾ тŠµŃŃ‚Š¾Š²Ń‹Š¹ Š¾Ń‚Š²ŠµŃ‚ npc_has_var, npc_remove_var." +#: lang/json/talk_topic_from_json.py +msgid "This is a u_add_var time test response." +msgstr "Š­Ń‚Š¾ тŠµŃŃ‚Š¾Š²Ń‹Š¹ Š¾Ń‚Š²ŠµŃ‚ Š²Ń€ŠµŠ¼ŠµŠ½Šø u_add_var." + +#: lang/json/talk_topic_from_json.py +msgid "This is a npc_add_var time test response." +msgstr "Š­Ń‚Š¾ тŠµŃŃ‚Š¾Š²Ń‹Š¹ Š¾Ń‚Š²ŠµŃ‚ Š²Ń€ŠµŠ¼ŠµŠ½Šø npc_add_var." + +#: lang/json/talk_topic_from_json.py +msgid "This is a u_compare_var time test response for > 3_days." +msgstr "Š­Ń‚Š¾ тŠµŃŃ‚Š¾Š²Ń‹Š¹ Š¾Ń‚Š²ŠµŃ‚ Š²Ń€ŠµŠ¼ŠµŠ½Šø u_compare_var Š“Š»Ń > 3_days." + #: lang/json/talk_topic_from_json.py msgid "This is a u_adjust_var test response that increments by 1." msgstr "Š­Ń‚Š¾ тŠµŃŃ‚Š¾Š²Ń‹Š¹ Š¾Ń‚Š²ŠµŃ‚ u_adjust_var с ŠøŠ½ŠŗрŠµŠ¼ŠµŠ½Ń‚Š¾Š¼ 1." @@ -215881,6 +216914,10 @@ msgstr "Š­Ń‚Š¾ тŠµŃŃ‚Š¾Š²Ń‹Š¹ Š¾Ń‚Š²ŠµŃ‚ Š²Š¾Š¶Š“ŠµŠ½Šøя." msgid "This is a low driving test response." msgstr "Š­Ń‚Š¾ тŠµŃŃ‚Š¾Š²Ń‹Š¹ Š¾Ń‚Š²ŠµŃ‚ Š½ŠøŠ·ŠŗŠ¾Š³Š¾ урŠ¾Š²Š½Ń Š²Š¾Š¶Š“ŠµŠ½Šøя." +#: lang/json/talk_topic_from_json.py +msgid "This is an npc_first_topic test response." +msgstr "Š­Ń‚Š¾ тŠµŃŃ‚Š¾Š²Ń‹Š¹ Š¾Ń‚Š²ŠµŃ‚ npc_first_topic." + #: lang/json/talk_topic_from_json.py msgid "Greetings friend, it's nice to see you." msgstr "ŠŸŃ€ŠøŠ²ŠµŃ‚, Š“руŠ¶ŠøщŠµ, ŠæрŠøятŠ½Š¾ уŠ²ŠøŠ“ŠµŃ‚ŃŒŃŃ." @@ -226487,7 +227524,7 @@ msgid "Will do, thanks!" msgstr "Š¢Š°Šŗ Šø сŠ“ŠµŠ»Š°ŃŽ, сŠæŠ°ŃŠøŠ±Š¾!" #: lang/json/talk_topic_from_json.py lang/json/talk_topic_from_json.py -#: src/npctalk.cpp +#: src/talker.h src/talker_npc.cpp msgid "Nope." msgstr "He-a." @@ -232940,6 +233977,43 @@ msgstr "Š–ŠøŠ·Š½ŃŒ Š²Š½Š¾Š²ŃŒ Š²Ń‹Ń€Ń‹Š²Š°ŠµŃ‚ся срŠµŠ“Šø Š¼ŠµŃ€Ń‚Š²Š¾Š¹ Šæ msgid "The door opens forcefully!" msgstr "Š”Š²ŠµŃ€ŃŒ с сŠøŠ»Š¾Š¹ рŠ°ŃŠæŠ°Ń…ŠøŠ²Š°ŠµŃ‚ся!" +#: lang/json/terrain_from_json.py +msgid "broken diesel tank" +msgstr "ŠæŠ¾Š²Ń€ŠµŠ¶Š“ёŠ½Š½Ń‹Š¹ Š“ŠøŠ·ŠµŠ»ŃŒŠ½Ń‹Š¹ Š±Š°Šŗ" + +#. ~ Description for centrifuge +#: lang/json/terrain_from_json.py +msgid "" +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. It could be used to analyze a medical fluid sample, such as blood, if" +" a test tube was placed in it." +msgstr "" +"Š­Ń‚Š¾ цŠµŠ½Ń‚Ń€ŠøфуŠ³Š°, ŠæрŠøŠ±Š¾Ń€ Š“Š»Ń рŠ°Š·Š“ŠµŠ»ŠµŠ½Šøя Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚ŠµŠ¹ Š²Š¼ŠµŃŃ‚Šµ с Š°Š²Ń‚Š¾Š¼Š°Ń‚ŠøчŠµŃŠŗŠøŠ¼ " +"Š°Š½Š°Š»ŠøŠ·Š°Ń‚Š¾Ń€Š¾Š¼. Š” ŠµŃ‘ ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ Š¼Š¾Š¶Š½Š¾ сŠ“ŠµŠ»Š°Ń‚ŃŒ Š°Š½Š°Š»ŠøŠ· Š¾Š±Ń€Š°Š·Ń†Š° Š¼ŠµŠ“ŠøцŠøŠ½ŃŠŗŠ¾Š¹ " +"Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚Šø, ŠµŃŠ»Šø ŠæŠ¾Š¼ŠµŃŃ‚Šøть Š²Š½ŃƒŃ‚Ń€ŃŒ ŠæрŠ¾Š±ŠøрŠŗу." + +#: lang/json/terrain_from_json.py +msgid "plutonium generator" +msgstr "ŠæŠ»ŃƒŃ‚Š¾Š½ŠøŠµŠ²Ń‹Š¹ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€" + +#. ~ Description for plutonium generator +#: lang/json/terrain_from_json.py +msgid "" +"This imposing apparatus harnesses the power of the atom. Refined nuclear " +"fuel is 'burned' to provide nearly limitless electrical power. It's not " +"doing much good here though. Perhaps it could be salvaged for other " +"purposes." +msgstr "" +"Š­Ń‚Š¾Ń‚ Š²ŠæŠµŃ‡Š°Ń‚Š»ŃŃŽŃ‰ŠøŠ¹ Š°ŠæŠæŠ°Ń€Š°Ń‚ ŠæŠ¾Š“чŠøŠ½ŃŠµŃ‚ сŠøŠ»Ńƒ Š°Ń‚Š¾Š¼Š°. ŠžŃ‡ŠøщŠµŠ½Š½Š¾Šµ яŠ“ŠµŃ€Š½Š¾Šµ тŠ¾ŠæŠ»ŠøŠ²Š¾ " +"Ā«ŃŠ¶ŠøŠ³Š°ŠµŃ‚сяĀ» Š“Š»Ń ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½Šøя ŠæрŠ°ŠŗтŠøчŠµŃŠŗŠø Š±ŠµŃŠŗŠ¾Š½ŠµŃ‡Š½Š¾Š¹ эŠ»ŠµŠŗтрŠ¾ŃŠ½ŠµŃ€Š³ŠøŠø. ŠžŠ“Š½Š°ŠŗŠ¾ тут" +" Š¾Š½, ŠæŠ¾Ń…Š¾Š¶Šµ, ŠæрŠ¾ŃŃ‚Š°ŠøŠ²Š°ŠµŃ‚ Š±ŠµŠ· тŠ¾Š»Šŗу. ŠŠ°Š²ŠµŃ€Š½Š¾, ŠµŠ³Š¾ Š¼Š¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š“Š»Ń Š“руŠ³Šøх " +"цŠµŠ»ŠµŠ¹." + +#. ~ Description for old machinery +#: lang/json/terrain_from_json.py +msgid "Assorted old machinery. You could scavenge it for parts." +msgstr "Š Š°Š·Š½Š¾Š¾Š±Ń€Š°Š·Š½Ń‹Šµ стŠ°Ń€Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹. ŠœŠ¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š½Š° Š·Š°ŠæчŠ°ŃŃ‚Šø." + #: lang/json/terrain_from_json.py msgid "scorched earth" msgstr "Š²Ń‹Š¶Š¶ŠµŠ½Š½Š°Ń Š·ŠµŠ¼Š»Ń" @@ -236169,24 +237243,6 @@ msgstr "" "Š“ŠøŠ“рŠ°Š²Š»ŠøчŠµŃŠŗŠøŠ¹ уŠæŠ»Š¾Ń‚Š½ŠøтŠµŠ»ŃŒ, ŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¹ ŠæрŠøŠ½ŠøŠ¼Š°ŠµŃ‚ ŠæрŠµŠ“Š¼ŠµŃ‚Ń‹ ŠøŠ· рŠ°Š·Š»ŠøчŠ½Ń‹Ń… Š¼ŠµŃ‚Š°Š»Š»Š¾Š²" " Šø сŠæрŠµŃŃŠ¾Š²Ń‹Š²Š°ŠµŃ‚ Šøх Š² ŠæрŠ¾ŃŃ‚Ń‹Šµ фŠ¾Ń€Š¼Ń‹, Š³Š¾Ń‚Š¾Š²Ń‹Šµ Šŗ Š“Š°Š»ŃŒŠ½ŠµŠ¹ŃˆŠµŠ¹ Š¾Š±Ń€Š°Š±Š¾Ń‚ŠŗŠµ." -#: lang/json/terrain_from_json.py -msgid "fuel tank" -msgstr "тŠ¾ŠæŠ»ŠøŠ²Š½Ń‹Š¹ рŠµŠ·ŠµŃ€Š²ŃƒŠ°Ń€" - -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with gasoline." -msgstr "Š‘Š°Šŗ, ŠæŠ¾Š»Š½Ń‹Š¹ Š±ŠµŠ½Š·ŠøŠ½Š°." - -#: lang/json/terrain_from_json.py -msgid "broken fuel tank" -msgstr "ŠæрŠ¾Š±ŠøтыŠ¹ тŠ¾ŠæŠ»ŠøŠ²Š½Ń‹Š¹ рŠµŠ·ŠµŃ€Š²ŃƒŠ°Ń€" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with gasoline." -msgstr "ŠŸŃ€Š¾Š±ŠøтыŠ¹ тŠ¾ŠæŠ»ŠøŠ²Š½Ń‹Š¹ Š±Š°Šŗ, Š² ŠŗŠ¾Ń‚Š¾Ń€Š¾Š¼ Š±Ń‹Š» Š±ŠµŠ½Š·ŠøŠ½." - #: lang/json/terrain_from_json.py msgid "gasoline pump" msgstr "Š±ŠµŠ½Š·Š¾ŠŗŠ¾Š»Š¾Š½ŠŗŠ°" @@ -236217,16 +237273,6 @@ msgstr "" "Š£Š¶Š°ŃŠ½Š¾! Š­Ń‚Š° Š±ŠµŠ½Š·Š¾ŠŗŠ¾Š»Š¾Š½ŠŗŠ° рŠ°Š·Ń€ŃƒŃˆŠµŠ½Š°, Šø Š²Š°Š¼ Š½ŠøŠŗŠ°Šŗ Š½Šµ Š“Š¾Š±Ń€Š°Ń‚ŃŒŃŃ Š“Š¾ Š¶ŠøŠ“ŠŗŠ¾Š³Š¾ " "Š·Š¾Š»Š¾Ń‚Š°." -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with diesel." -msgstr "Š‘Š°Šŗ, Š½Š°ŠæŠ¾Š»Š½ŠµŠ½Š½Ń‹Š¹ Š“ŠøŠ·ŠµŠ»ŠµŠ¼." - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with diesel." -msgstr "ŠŸŃ€Š¾Š±ŠøтыŠ¹ тŠ¾ŠæŠ»ŠøŠ²Š½Ń‹Š¹ Š±Š°Šŗ, Š² ŠŗŠ¾Ń‚Š¾Ń€Š¾Š¼ Š±Ń‹Š» Š“ŠøŠ·ŠµŠ»ŃŒ." - #: lang/json/terrain_from_json.py msgid "diesel pump" msgstr "Š“ŠøŠ·ŠµŠ»ŃŒŠ½Š°Ń ŠŗŠ¾Š»Š¾Š½ŠŗŠ°" @@ -236321,16 +237367,6 @@ msgstr "" "Š‘Š¾Š»ŃŒŃˆŠ°Ń Š½Š°ŃŃ‚ŠµŠ½Š½Š°Ń ŠæŠ°Š½ŠµŠ»ŃŒ с тŠ¾Š½ŠŗŠøŠ¼Šø Š¼ŠµŃ‚Š°Š»Š»ŠøчŠµŃŠŗŠøŠ¼Šø ŠæŠ»Š°ŃŃ‚ŠøŠ½Š°Š¼Šø. рŠµŠ³ŃƒŠ»ŠøрующŠøŠ¼Šø " "ŠæŠ¾Ń‚Š¾Šŗ Š²Š¾Š·Š“ухŠ°." -#: lang/json/terrain_from_json.py -msgid "broken generator" -msgstr "Š½ŠµŠøсŠæрŠ°Š²Š½Ń‹Š¹ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€" - -#. ~ Description for broken generator -#: lang/json/terrain_from_json.py -msgid "" -"This generator is broken and will not help you produce usable electricity." -msgstr "Š­Ń‚Š¾Ń‚ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€ сŠ»Š¾Š¼Š°Š½ Šø Š½Šµ Š“Š°ŃŃ‚ Š²Š°Š¼ ŠæŠ¾Š»ŠµŠ·Š½Š¾Š³Š¾ эŠ»ŠµŠŗтрŠøчŠµŃŃ‚Š²Š°." - #: lang/json/terrain_from_json.py msgid "missile" msgstr "рŠ°ŠŗŠµŃ‚Š°" @@ -236394,21 +237430,6 @@ msgid "" "This unpowered pump previously would have moved fluids around in a hurry." msgstr "Š­Ń‚Š¾Ń‚ Š¾Š±ŠµŃŃ‚Š¾Ń‡ŠµŠ½Š½Ń‹Š¹ Š½Š°ŃŠ¾Ń ŠŗŠ¾Š³Š“Š°-тŠ¾ ŠæŠ¾ŃŠæŠµŃˆŠ½Š¾ ŠæŠµŃ€ŠµŠŗŠ°Ń‡ŠøŠ²Š°Š» Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚Šø." -#: lang/json/terrain_from_json.py -msgid "centrifuge" -msgstr "цŠµŠ½Ń‚Ń€ŠøфуŠ³Š°" - -#. ~ Description for centrifuge -#: lang/json/terrain_from_json.py -msgid "" -"This is a centrifuge, a liquid separating device with an automated analyzer " -"unit. It could be used to analyze a medical fluid sample, such as blood, if" -" a test tube was placed in it." -msgstr "" -"Š­Ń‚Š¾ цŠµŠ½Ń‚Ń€ŠøфуŠ³Š°, ŠæрŠøŠ±Š¾Ń€ Š“Š»Ń рŠ°Š·Š“ŠµŠ»ŠµŠ½Šøя Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚ŠµŠ¹ Š²Š¼ŠµŃŃ‚Šµ с Š°Š²Ń‚Š¾Š¼Š°Ń‚ŠøчŠµŃŠŗŠøŠ¼ " -"Š°Š½Š°Š»ŠøŠ·Š°Ń‚Š¾Ń€Š¾Š¼. Š” ŠµŃ‘ ŠæŠ¾Š¼Š¾Ń‰ŃŒŃŽ Š¼Š¾Š¶Š½Š¾ сŠ“ŠµŠ»Š°Ń‚ŃŒ Š°Š½Š°Š»ŠøŠ· Š¾Š±Ń€Š°Š·Ń†Š° Š¼ŠµŠ“ŠøцŠøŠ½ŃŠŗŠ¾Š¹ " -"Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚Šø, ŠµŃŠ»Šø ŠæŠ¾Š¼ŠµŃŃ‚Šøть Š²Š½ŃƒŃ‚Ń€ŃŒ ŠæрŠ¾Š±ŠøрŠŗу." - #: lang/json/terrain_from_json.py msgid "CVD machine" msgstr "хŠøŠ¼ŠøчŠµŃŠŗŠøŠ¹ ŠæŠ°Ń€Š¾Ń„Š°Š·Š½Ń‹Š¹ Š¾ŃŠ°Š“ŠøтŠµŠ»ŃŒ" @@ -236523,23 +237544,6 @@ msgstr "руŠŗŠ¾Š¼Š¾Š¹Š½ŠøŠŗ" msgid "A machine with several taps that dispenses clean water." msgstr "ŠšŠ¾Š½ŃŃ‚Ń€ŃƒŠŗцŠøя с Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠøŠ¼Šø ŠŗрŠ°Š½Š°Š¼Šø, ŠŗŠ¾Ń‚Š¾Ń€Š°Ń ŠæŠ¾Š“Š°Ń‘Ń‚ чŠøстую Š²Š¾Š“у." -#: lang/json/terrain_from_json.py -msgid "plutonium generator" -msgstr "ŠæŠ»ŃƒŃ‚Š¾Š½ŠøŠµŠ²Ń‹Š¹ Š³ŠµŠ½ŠµŃ€Š°Ń‚Š¾Ń€" - -#. ~ Description for plutonium generator -#: lang/json/terrain_from_json.py -msgid "" -"This imposing apparatus harnesses the power of the atom. Refined nuclear " -"fuel is 'burned' to provide nearly limitless electrical power. It's not " -"doing much good here though. Perhaps it could be salvaged for other " -"purposes." -msgstr "" -"Š­Ń‚Š¾Ń‚ Š²ŠæŠµŃ‡Š°Ń‚Š»ŃŃŽŃ‰ŠøŠ¹ Š°ŠæŠæŠ°Ń€Š°Ń‚ ŠæŠ¾Š“чŠøŠ½ŃŠµŃ‚ сŠøŠ»Ńƒ Š°Ń‚Š¾Š¼Š°. ŠžŃ‡ŠøщŠµŠ½Š½Š¾Šµ яŠ“ŠµŃ€Š½Š¾Šµ тŠ¾ŠæŠ»ŠøŠ²Š¾ " -"Ā«ŃŠ¶ŠøŠ³Š°ŠµŃ‚сяĀ» Š“Š»Ń ŠæŠ¾Š»ŃƒŃ‡ŠµŠ½Šøя ŠæрŠ°ŠŗтŠøчŠµŃŠŗŠø Š±ŠµŃŠŗŠ¾Š½ŠµŃ‡Š½Š¾Š¹ эŠ»ŠµŠŗтрŠ¾ŃŠ½ŠµŃ€Š³ŠøŠø. ŠžŠ“Š½Š°ŠŗŠ¾ тут" -" Š¾Š½, ŠæŠ¾Ń…Š¾Š¶Šµ, ŠæрŠ¾ŃŃ‚Š°ŠøŠ²Š°ŠµŃ‚ Š±ŠµŠ· тŠ¾Š»Šŗу. ŠŠ°Š²ŠµŃ€Š½Š¾, ŠµŠ³Š¾ Š¼Š¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š“Š»Ń Š“руŠ³Šøх " -"цŠµŠ»ŠµŠ¹." - #: lang/json/terrain_from_json.py msgid "telecom cabinet" msgstr "шŠŗŠ°Ń„ сŠ²ŃŠ·Šø" @@ -236669,46 +237673,6 @@ msgstr "ŠŗŠ¾Š½Š²ŠµŠ¹ŠµŃ€Š½Š°Ń Š»ŠµŠ½Ń‚Š°" msgid "A conveyor belt. Used to transport things." msgstr "ŠšŠ¾Š½Š²ŠµŠ¹ŠµŃ€Š½Š°Ń Š»ŠµŠ½Ń‚Š°. Š¢Ń€Š°Š½ŃŠæŠ¾Ń€Ń‚ŠøруŠµŃ‚ Š²ŠµŃ‰Šø." -#: lang/json/terrain_from_json.py -msgid "ting." -msgstr "тŠøŠ½ŃŒ." - -#: lang/json/terrain_from_json.py -msgid "light machinery" -msgstr "Š»Ń‘Š³ŠŗŠøŠµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹" - -#. ~ Description for light machinery -#: lang/json/terrain_from_json.py -msgid "Assorted light machinery. You could scavenge it for parts." -msgstr "Š Š°Š·Š½Š¾Š¾Š±Ń€Š°Š·Š½Ń‹Šµ Š»Ń‘Š³ŠŗŠøŠµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹. ŠœŠ¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š½Š° Š·Š°ŠæчŠ°ŃŃ‚Šø." - -#: lang/json/terrain_from_json.py -msgid "heavy machinery" -msgstr "тяŠ¶Ń‘Š»Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹" - -#. ~ Description for heavy machinery -#: lang/json/terrain_from_json.py -msgid "Assorted heavy machinery. You could scavenge it for parts." -msgstr "Š Š°Š·Š½Š¾Š¾Š±Ń€Š°Š·Š½Ń‹Šµ тяŠ¶Ń‘Š»Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹. ŠœŠ¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š½Š° Š·Š°ŠæчŠ°ŃŃ‚Šø." - -#: lang/json/terrain_from_json.py -msgid "old machinery" -msgstr "стŠ°Ń€Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹" - -#. ~ Description for old machinery -#: lang/json/terrain_from_json.py -msgid "Assorted old machinery. You could scavenge it for parts." -msgstr "Š Š°Š·Š½Š¾Š¾Š±Ń€Š°Š·Š½Ń‹Šµ стŠ°Ń€Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹. ŠœŠ¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š½Š° Š·Š°ŠæчŠ°ŃŃ‚Šø." - -#: lang/json/terrain_from_json.py -msgid "electronic machinery" -msgstr "эŠ»ŠµŠŗтрŠ¾Š½Š½Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹" - -#. ~ Description for electronic machinery -#: lang/json/terrain_from_json.py -msgid "Assorted electronic machinery. You could scavenge it for parts." -msgstr "Š Š°Š·Š½Š¾Š¾Š±Ń€Š°Š·Š½Ń‹Šµ эŠ»ŠµŠŗтрŠ¾Š½Š½Ń‹Šµ Š¼ŠµŃ…Š°Š½ŠøŠ·Š¼Ń‹. ŠœŠ¾Š¶Š½Š¾ рŠ°Š·Š¾Š±Ń€Š°Ń‚ŃŒ Š½Š° Š·Š°ŠæчŠ°ŃŃ‚Šø." - #: lang/json/terrain_from_json.py msgid "milking machine" msgstr "Š“Š¾ŠøŠ»ŃŒŠ½Ń‹Š¹ Š°ŠæŠæŠ°Ń€Š°Ń‚" @@ -236787,34 +237751,6 @@ msgstr "" "Š”Š°Š¼Š¾Š“ŠµŠ»ŃŒŠ½Š¾Šµ уŠŗрытŠøŠµ ŠøŠ· Š²Š¾Š“Š¾Š½ŠµŠæрŠ¾Š½ŠøцŠ°ŠµŠ¼Š¾Š³Š¾ Š±Ń€ŠµŠ·ŠµŠ½Ń‚Š°, Š² Š½Ń‘Š¼ Š¼Š¾Š¶Š½Š¾ сŠæрятŠ°Ń‚ŃŒŃŃ Š²" " Š½ŠµŠæŠ¾Š³Š¾Š“у ŠøŠ»Šø Š·Š°Ń‰ŠøтŠøть ŠŗŠ¾ŃŃ‚Ń‘Ń€ Š¾Ń‚ Š“Š¾Š¶Š“я." -#: lang/json/terrain_from_json.py -msgid "broken console" -msgstr "сŠ»Š¾Š¼Š°Š½Š½Ń‹Š¹ тŠµŃ€Š¼ŠøŠ½Š°Š»" - -#. ~ Description for broken console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It doesn't seem to be working. " -"It's the broken screen and shattered circuit boards that's telling you that." -msgstr "" -"ŠšŠ¾Š¼ŠæьютŠµŃ€Š½Ń‹Š¹ тŠµŃ€Š¼ŠøŠ½Š°Š». Š’ŠµŃ€Š¾ŃŃ‚Š½Š¾, Š¾Š½ Š±Š¾Š»ŃŒŃˆŠµ Š½Šµ рŠ°Š±Š¾Ń‚Š°ŠµŃ‚. Š’Š°Š¼ этŠ¾ ŠæŠ¾Š“сŠŗŠ°Š·Ń‹Š²Š°ŃŽŃ‚" -" рŠ°Š·Š±ŠøтыŠ¹ эŠŗрŠ°Š½ Šø ŠæŠ¾Š»Š¾Š¼Š°Š½Š½Ń‹Šµ схŠµŠ¼Ń‹." - -#: lang/json/terrain_from_json.py -msgid "computer console" -msgstr "тŠµŃ€Š¼ŠøŠ½Š°Š»" - -#. ~ Description for computer console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It can be used to view contents and" -" perform any allowed functions. It might even be possible to hack it, given" -" the skills." -msgstr "" -"ŠšŠ¾Š¼ŠæьютŠµŃ€Š½Ń‹Š¹ тŠµŃ€Š¼ŠøŠ½Š°Š». Š˜ŃŠæŠ¾Š»ŃŒŠ·ŃƒŠ¹Ń‚Šµ ŠµŠ³Š¾ Š“Š»Ń Š“Š¾ŃŃ‚ŃƒŠæŠ° Šŗ сŠ¾Š“ŠµŃ€Š¶ŠøŠ¼Š¾Š¼Ńƒ Šø " -"Š²Ń‹ŠæŠ¾Š»Š½ŠµŠ½Šøя Š»ŃŽŠ±Ń‹Ń… ŠæŠ¾Š·Š²Š¾Š»ŠµŠ½Š½Ń‹Ń… фуŠ½ŠŗцŠøŠ¹. Š•ŃŠ»Šø хŠ²Š°Ń‚Šøт Š½Š°Š²Ń‹ŠŗŠ¾Š², ŠµŠ³Š¾ Š“Š°Š¶Šµ Š¼Š¾Š¶Š½Š¾ " -"Š²Š·Š»Š¾Š¼Š°Ń‚ŃŒ." - #: lang/json/terrain_from_json.py msgid "mechanical winch" msgstr "Š¼ŠµŃ…Š°Š½ŠøчŠµŃŠŗŠ°Ń Š»ŠµŠ±Ń‘Š“ŠŗŠ°" @@ -239290,10 +240226,6 @@ msgstr "уŠŗŠ»Š¾Š½ Š²Š²ŠµŃ€Ń…" msgid "An upward facing slope." msgstr "Š£ŠŗŠ»Š¾Š½, Š²ŠµŠ“ущŠøŠ¹ Š²Š²ŠµŃ€Ń…." -#: lang/json/terrain_from_json.py -msgid "rope leading up" -msgstr "Š²ŠµŠ“ущŠ°Ń Š²Š²ŠµŃ€Ń… Š²ŠµŃ€Ń‘Š²ŠŗŠ°" - #. ~ Description for rope leading up #: lang/json/terrain_from_json.py msgid "A rope. You could climb up it." @@ -239978,6 +240910,10 @@ msgstr "Š°Š²Ń‚Š¾Š¼Š¾Š±ŠøŠ»ŃŒ" msgid "Car Chassis" msgstr "шŠ°ŃŃŠø Š°Š²Ń‚Š¾" +#: lang/json/vehicle_from_json.py +msgid "Hybrid Car" +msgstr "Š³ŠøŠ±Ń€ŠøŠ“Š½Ń‹Š¹ Š°Š²Ń‚Š¾Š¼Š¾Š±ŠøŠ»ŃŒ" + #: lang/json/vehicle_from_json.py msgid "City Car" msgstr "Š³Š¾Ń€Š¾Š“сŠŗŠ¾Š¹ Š°Š²Ń‚Š¾Š¼Š¾Š±ŠøŠ»ŃŒ" @@ -241887,6 +242823,26 @@ msgstr "" "ŠæŠ¾Š“Š°Ń‘Ń‚ сŠøŠ³Š½Š°Š» трŠµŠ²Š¾Š³Šø, ŠµŃŠ»Šø Š²Ń‹ ŠæŠ¾ŠæытŠ°ŠµŃ‚ŠµŃŃŒ этŠ¾ сŠ“ŠµŠ»Š°Ń‚ŃŒ. Š”ŠøŠ³Š½Š°Š»ŠøŠ·Š°Ń†Šøю Š¼Š¾Š¶Š½Š¾ " "ŠæŠ¾ŠæрŠ¾Š±Š¾Š²Š°Ń‚ŃŒ Š¾Ń‚ŠŗŠ»ŃŽŃ‡Šøть." +#: lang/json/vehicle_part_from_json.py +msgid "smart engine controller" +msgstr "сŠøстŠµŠ¼Š° уŠ¼Š½Š¾Š³Š¾ уŠæрŠ°Š²Š»ŠµŠ½Šøя Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø" + +#. ~ Description for {'str': 'smart engine controller'} +#: lang/json/vehicle_part_from_json.py +#, no-python-format +msgid "" +"Electronic module that automatically switches combustion and electric " +"engines on and off minimizing fuel consumption and optimizing power output " +"and battery charge rate. Must be turned on to work. Simplified ruleset: 1." +" When throttling, maximize acceleration. 2. Keep battery at 90%. 3. " +"Minimize fuel consumption." +msgstr "" +"Š­Š»ŠµŠŗтрŠ¾Š½Š½Ń‹Š¹ Š¼Š¾Š“уŠ»ŃŒ, Š°Š²Ń‚Š¾Š¼Š°Ń‚ŠøчŠµŃŠŗŠø ŠæŠµŃ€ŠµŠŗŠ»ŃŽŃ‡Š°ŃŽŃ‰ŠøŠ¹ŃŃ Š¼ŠµŠ¶Ńƒ Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø " +"Š²Š½ŃƒŃ‚Ń€ŠµŠ½Š½ŠµŠ³Š¾ сŠ³Š¾Ń€Š°Š½Šøя Šø эŠ»ŠµŠŗтрŠ¾Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø Š“Š»Ń эŠŗŠ¾Š½Š¾Š¼ŠøŠø тŠ¾ŠæŠ»ŠøŠ²Š° Šø ŠæŠ¾Š²Ń‹ŃˆŠµŠ½Šøя " +"Š¼Š¾Ń‰Š½Š¾ŃŃ‚Šø Šø сŠŗŠ¾Ń€Š¾ŃŃ‚Šø Š·Š°Ń€ŃŠ“ŠŗŠø Š±Š°Ń‚Š°Ń€ŠµŠø. Š”Š¾Š»Š¶ŠµŠ½ Š±Ń‹Ń‚ŃŒ Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½. чтŠ¾Š±Ń‹ рŠ°Š±Š¾Ń‚Š°Ń‚ŃŒ. " +"Š£ŠæрŠ¾Ń‰Ń‘Š½Š½Ń‹Š¹ Š½Š°Š±Š¾Ń€ ŠæрŠ°Š²ŠøŠ»: 1. ŠŸŃ€ŠøŠ¾Ń€ŠøтŠµŃ‚ усŠŗŠ¾Ń€ŠµŠ½Šøя ŠæрŠø Š½Š°Š±Š¾Ń€Šµ сŠŗŠ¾Ń€Š¾ŃŃ‚Šø. 2. " +"Š—Š°Ń€ŃŠ“ Š±Š°Ń‚Š°Ń€ŠµŠø Š“ŠµŃ€Š¶Šøтся Š½Šµ Š¼ŠµŠ½ŠµŠµ 90%. 3. ŠœŠøŠ½ŠøŠ¼ŠøŠ·Š°Ń†Šøя ŠæŠ¾Ń‚Ń€ŠµŠ±Š»ŠµŠ½Šøя тŠ¾ŠæŠ»ŠøŠ²Š°." + #: lang/json/vehicle_part_from_json.py msgid "5-point harness" msgstr "5-тŠ¾Ń‡ŠµŃ‡Š½Ń‹Š¹ рŠµŠ¼ŠµŠ½ŃŒ Š±ŠµŠ·Š¾ŠæŠ°ŃŠ½Š¾ŃŃ‚Šø" @@ -243228,6 +244184,66 @@ msgstr "ŠÆŠ“ы" msgid "Disgusting Diet" msgstr "ŠžŃ‚Š²Ń€Š°Ń‚ŠøтŠµŠ»ŃŒŠ½Š°Ń Š“ŠøŠµŃ‚Š°" +#: lang/json/vitamin_from_json.py +msgid "Blood" +msgstr "ŠšŃ€Š¾Š²ŃŒ" + +#: lang/json/vitamin_from_json.py +msgid "Red Blood Cells" +msgstr "ŠšŃ€Š°ŃŠ½Ń‹Šµ ŠŗрŠ¾Š²ŃŠ½Ń‹Šµ тŠµŠ»ŃŒŃ†Š°" + +#: lang/json/weather_type_from_json.py +msgid "NULL Weather - BUG" +msgstr "ŠŸŠ¾Š³Š¾Š“Š° NULL - ŠžŠØŠ˜Š‘ŠšŠ" + +#: lang/json/weather_type_from_json.py +msgid "Clear" +msgstr "ŠÆсŠ½Š¾" + +#: lang/json/weather_type_from_json.py +msgid "Sunny" +msgstr "Š”Š¾Š»Š½ŠµŃ‡Š½Š¾" + +#: lang/json/weather_type_from_json.py +msgid "Cloudy" +msgstr "ŠŸŠ°ŃŠ¼ŃƒŃ€Š½Š¾" + +#: lang/json/weather_type_from_json.py +msgid "Light Drizzle" +msgstr "Š›ŠµŠ³ŠŗŠ°Ń Š¼Š¾Ń€Š¾ŃŃŒ" + +#: lang/json/weather_type_from_json.py +msgid "Drizzle" +msgstr "ŠœŠ¾Ń€Š¾ŃŃŒ" + +#: lang/json/weather_type_from_json.py +msgid "Rain" +msgstr "Š”Š¾Š¶Š“ь" + +#: lang/json/weather_type_from_json.py +msgid "Thunder Storm" +msgstr "Š“Ń€Š¾Š·Š¾Š²Š¾Š¹ Š»ŠøŠ²ŠµŠ½ŃŒ" + +#: lang/json/weather_type_from_json.py +msgid "Acidic Drizzle" +msgstr "ŠšŠøсŠ»Š¾Ń‚Š½Š°Ń Š¼Š¾Ń€Š¾ŃŃŒ" + +#: lang/json/weather_type_from_json.py +msgid "Acid Rain" +msgstr "ŠšŠøсŠ»Š¾Ń‚Š½Ń‹Š¹ Š“Š¾Š¶Š“ь" + +#: lang/json/weather_type_from_json.py +msgid "Flurries" +msgstr "ŠœŠ¾Ń€Š¾ŃŃŃ‰ŠøŠ¹ сŠ½ŠµŠ³" + +#: lang/json/weather_type_from_json.py +msgid "Snowing" +msgstr "Š”Š½ŠµŠ³Š¾ŠæŠ°Š“" + +#: lang/json/weather_type_from_json.py +msgid "Snowstorm" +msgstr "ŠœŠµŃ‚ŠµŠ»ŃŒ" + #: src/achievement.cpp msgid "time of cataclysm" msgstr "с Š¼Š¾Š¼ŠµŠ½Ń‚Š° ŠšŠ°Ń‚Š°ŠŗŠ»ŠøŠ·Š¼Š°" @@ -243395,8 +244411,7 @@ msgstr "Š’Š°ŃˆŠ° эŠ½ŠµŃ€Š³Šøя ŠøстŠ¾Ń‰ŠµŠ½Š°!" msgid "You cannot hack this." msgstr "Š’Ń‹ Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ этŠ¾ Š²Š·Š»Š¾Š¼Š°Ń‚ŃŒ." -#: src/activity_actor.cpp src/computer_session.cpp src/computer_session.cpp -#: src/iuse.cpp src/map.cpp +#: src/activity_actor.cpp src/computer_session.cpp src/iuse.cpp src/map.cpp msgid "an alarm sound!" msgstr "Š·Š²ŃƒŠŗ сŠøŠ³Š½Š°Š»ŠøŠ·Š°Ń†ŠøŠø!" @@ -243541,6 +244556,16 @@ msgstr "ŠŸŃ€Š¾Š“Š¾Š»Š¶Šøть ŠæытŠ°Ń‚ŃŒŃŃ усŠ½ŃƒŃ‚ŃŒ." msgid "Continue trying to fall asleep and don't ask again." msgstr "ŠŸŃ€Š¾Š“Š¾Š»Š¶Šøть ŠæытŠ°Ń‚ŃŒŃŃ усŠ½ŃƒŃ‚ŃŒ Šø Š±Š¾Š»ŃŒŃˆŠµ Š½Šµ сŠæрŠ°ŃˆŠøŠ²Š°Ń‚ŃŒ." +#: src/activity_actor.cpp +#, c-format +msgid "You disassemble your %s." +msgstr "Š’Ń‹ рŠ°Š·Š±ŠøрŠ°ŠµŃ‚Šµ %s." + +#: src/activity_actor.cpp src/player.cpp +#, c-format +msgid "You unload your %s." +msgstr "Š’Ń‹ рŠ°Š·Ń€ŃŠ¶Š°ŠµŃ‚Šµ %s." + #: src/activity_actor.cpp msgid "You are too tired to exercise." msgstr "Š’Ń‹ сŠ»ŠøшŠŗŠ¾Š¼ устŠ°Š»Šø чтŠ¾Š±Ń‹ Š·Š°Š½ŠøŠ¼Š°Ń‚ŃŒŃŃ" @@ -244090,11 +245115,6 @@ msgstr[3] " Š·Š°ŠŗŠ¾Š½Ń‡ŠøŠ» рŠ°Š·Š“ŠµŠ»Šŗу труŠæŠ°." msgid "Can't reload the %s." msgstr "ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæŠµŃ€ŠµŠ·Š°Ń€ŃŠ“Šøть ŠæрŠµŠ“Š¼ŠµŃ‚ (%s)." -#: src/activity_handlers.cpp src/iexamine.cpp -#, c-format -msgid "You reload the %s." -msgstr "Š’Ń‹ ŠæŠµŃ€ŠµŠ·Š°Ń€ŃŠ“ŠøŠ»Šø ŠæрŠµŠ“Š¼ŠµŃ‚ (%s)." - #: src/activity_handlers.cpp #, c-format msgid "" @@ -244111,6 +245131,11 @@ msgstr "Š’Ń‹ Š²ŃŃ‚Š°Š²ŠøŠ»Šø Š¾Š“ŠøŠ½ Š·Š°Ń€ŃŠ“ (%2$s) Š² ŠæрŠµŠ“Š¼ŠµŃ‚ (%1$s msgid "You refill the %s." msgstr "Š’Ń‹ Š½Š°Š»ŠøŠ»Šø Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚ŃŒ Š² ŠŗŠ¾Š½Ń‚ŠµŠ¹Š½ŠµŃ€ (%s)." +#: src/activity_handlers.cpp +#, c-format +msgid "You reload the %1$s with %2$s." +msgstr "Š’Ń‹ ŠæŠµŃ€ŠµŠ·Š°Ń€ŃŠ“ŠøŠ»Šø ŠæрŠµŠ“Š¼ŠµŃ‚ (%1$s) - %2$s." + #: src/activity_handlers.cpp src/bionics.cpp msgid "There's nothing to light there." msgstr "Š—Š“ŠµŃŃŒ Š½ŠµŃ‡ŠµŠ³Š¾ ŠæŠ¾Š“Š¶ŠµŃ‡ŃŒ." @@ -244248,6 +245273,10 @@ msgstr "Š’Ń‹ Š±Š¾Š»ŃŒŃˆŠµ Š½ŠøчŠµŠ¼Ńƒ Š½Šµ Š½Š°ŃƒŃ‡ŠøтŠµŃŃŒ ŠæрŠø ŠæŠ¾Š¼Š¾Ń‰ msgid "%s %s\n" msgstr "%s ŠæрŠµŠ“Š¼ŠµŃ‚Š° (%s)\n" +#: src/activity_handlers.cpp src/magic.cpp +msgid "bionic power" +msgstr "Š±ŠøŠ¾Š½ŠøчŠµŃŠŗŠ°Ń эŠ½ŠµŃ€Š³Šøя" + #: src/activity_handlers.cpp #, c-format msgid "Charges: %s/%s %s (%s per use)\n" @@ -244645,16 +245674,6 @@ msgstr "Š’Ń‹ Š¾Ń‚ŠŗрыŠ»Šø сŠ²Š¾Š¹ Š½Š°Š±Š¾Ń€ Šø ŠæŠ¾Š±Ń€ŠøŠ»Šøсь." msgid "You give your hair a trim." msgstr "Š’Ń‹ ŠæŠ¾Š“стрŠøŠ³Š»Šøсь." -#: src/activity_handlers.cpp -#, c-format -msgid "You disassemble your %s." -msgstr "Š’Ń‹ рŠ°Š·Š±ŠøрŠ°ŠµŃ‚Šµ %s." - -#: src/activity_handlers.cpp src/player.cpp -#, c-format -msgid "You unload your %s." -msgstr "Š’Ń‹ рŠ°Š·Ń€ŃŠ¶Š°ŠµŃ‚Šµ %s." - #: src/activity_handlers.cpp #, c-format msgid "You have run out of %s." @@ -245741,7 +246760,7 @@ msgstr "Š­Ń‚Š¾ Š½Š°Ń…Š¾Š“Šøтся Š² Š¾ŠŗруŠ¶Š°ŃŽŃ‰ŠµŠ¹ Š²Š°Ń Š°ŃƒŃ€Šµ." msgid "Properties" msgstr "Š”Š²Š¾Š¹ŃŃ‚Š²Š°" -#: src/armor_layers.cpp +#: src/armor_layers.cpp src/item.cpp msgid "Coverage:" msgstr "ŠŸŠ¾ŠŗрытŠøŠµ:" @@ -247784,7 +248803,7 @@ msgstr "Š£ Š²Š°Ń Š½Šµ хŠ²Š°Ń‚Š°ŠµŃ‚ эŠ½ŠµŃ€Š³ŠøŠø Š“Š»Ń Š°ŠŗтŠøŠ²Š°Ń†ŠøŠø msgid "Deactivate your %s first!" msgstr "Š”ŠæŠµŃ€Š²Š° Š“ŠµŠ°ŠŗтŠøŠ²ŠøруŠ¹Ń‚Šµ ŠšŠ‘Šœ - %s!" -#: src/bionics.cpp src/player.cpp +#: src/bionics.cpp src/character.cpp #, c-format msgid "Stop wielding %s?" msgstr "ŠŸŃ€ŠµŠŗрŠ°Ń‚Šøть Š“ŠµŃ€Š¶Š°Ń‚ŃŒ Š² руŠŗŠ°Ń… Š¾Ń€ŃƒŠ¶ŠøŠµ (%s)?" @@ -249286,6 +250305,11 @@ msgstr "Š“Š“Šµ сŠæŠµŃˆŠøться?" msgid "You cannot dismount there!" msgstr "Š—Š“ŠµŃŃŒ Š½ŠµŠ»ŃŒŠ·Ń сŠæŠµŃˆŠøться!" +#: src/character.cpp +#, c-format +msgid "This task is too simple to train your %s beyond %d." +msgstr "Š­Ń‚Š° Š·Š°Š“Š°Ń‡Š° сŠ»ŠøшŠŗŠ¾Š¼ ŠæрŠ¾ŃŃ‚Š° Š“Š»Ń трŠµŠ½ŠøрŠ¾Š²ŠŗŠø Š½Š°Š²Ń‹ŠŗŠ° (%s) Š²Ń‹ŃˆŠµ %d урŠ¾Š²Š½Ń." + #: src/character.cpp msgid "You struggle to stand." msgstr "Š’Ń‹ ŠæытŠ°ŠµŃ‚ŠµŃŃŒ ŠæŠ¾Š“Š½ŃŃ‚ŃŒŃŃ." @@ -249457,6 +250481,17 @@ msgstr " Š²Ń‹ŠæŠ¾Š»Š·Š°ŠµŃ‚ ŠøŠ· яŠ¼Ń‹!" msgid "Your %s bionic comes back online." msgstr "Š’Š°ŃˆŠ° Š±ŠøŠ¾Š½ŠøŠŗŠ° (%s) сŠ½Š¾Š²Š° Š²ŠŗŠ»ŃŽŃ‡Š°ŠµŃ‚ся." +#: src/character.cpp +#, c-format +msgid "Your skill in %s has increased to %d!" +msgstr "Š’Š°Ńˆ Š½Š°Š²Ń‹Šŗ %s уŠ²ŠµŠ»ŠøчŠøŠ»ŃŃ Š“Š¾ %d!" + +#: src/character.cpp +#, c-format +msgid "You feel that %s tasks of this level are becoming trivial." +msgstr "" +"Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ, чтŠ¾ Š·Š°Š“Š°Ń‡Š° стŠ°Š»Š° сŠ»ŠøшŠŗŠ¾Š¼ ŠæрŠ¾ŃŃ‚Š¾Š¹ Š“Š»Ń трŠµŠ½ŠøрŠ¾Š²ŠŗŠø Š½Š°Š²Ń‹ŠŗŠ° (%s)." + #: src/character.cpp #, c-format msgid "You put on your %s." @@ -249578,6 +250613,16 @@ msgstr "" msgid "%s doesn't have any broken limbs this could help." msgstr "Š£ NPC (%s) Š½ŠµŃ‚ сŠ»Š¾Š¼Š°Š½Š½Ń‹Ń… ŠŗŠ¾Š½ŠµŃ‡Š½Š¾ŃŃ‚ŠµŠ¹, Šŗ ŠŗŠ¾Ń‚Š¾Ń€Ń‹Š¼ Š¼Š¾Š¶Š½Š¾ этŠ¾ ŠæрŠøŠ¼ŠµŠ½Šøть." +#: src/character.cpp +msgid "You don't need a tourniquet to stop the bleeding." +msgstr "Š’Š°Š¼ Š½Šµ Š½ŃƒŠ¶ŠµŠ½ Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Š¹ турŠ½ŠøŠŗŠµŃ‚ Š“Š»Ń Š¾ŃŃ‚Š°Š½Š¾Š²ŠŗŠø ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½Šøя." + +#: src/character.cpp +#, c-format +msgid "%s doesn't need a tourniquet to stop the bleeding." +msgstr "" +"%s Š¼Š¾Š¶ŠµŃ‚ Š¾Š±Š¾Š¹Ń‚Šøсь Š±ŠµŠ· Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Š¾Š³Š¾ турŠ½ŠøŠŗŠµŃ‚Š° Š“Š»Ń Š¾ŃŃ‚Š°Š½Š¾Š²ŠŗŠø ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½Šøя." + #: src/character.cpp msgid "You don't have enough arms to wear that." msgstr "Š£ Š²Š°Ń Š½Šµ хŠ²Š°Ń‚Š°ŠµŃ‚ руŠŗ, чтŠ¾Š±Ń‹ Š½Š°Š“ŠµŃ‚ŃŒ этŠ¾." @@ -249763,7 +250808,7 @@ msgstr "Š£Š¶Š°ŃŠ½Ń‹Š¹ Š³Š¾Š»Š¾Š“" msgid "ERROR!" msgstr "ŠžŠØŠ˜Š‘ŠšŠ!" -#: src/character.cpp src/npctalk.cpp +#: src/character.cpp src/talker_npc.cpp msgid "Exhausted" msgstr "ŠŸŠµŃ€ŠµŃƒŃ‚Š¾Š¼Š»ŠµŠ½ŠøŠµ" @@ -249807,7 +250852,7 @@ msgstr "Š’Š°Ń сŠŗрючŠøŠ²Š°ŠµŃ‚ Š¾Ń‚ ŠæŠ¾ŠæытŠŗŠø уŠ¼ŠµŃŃ‚Šøться Š² msgid "You have a sudden heart attack!" msgstr "Š£ Š²Š°Ń сŠ»ŃƒŃ‡ŠøŠ»ŃŃ сŠµŃ€Š“ŠµŃ‡Š½Ń‹Š¹ ŠæрŠøстуŠæ!" -#: src/character.cpp +#: src/character.cpp src/player_hardcoded_effects.cpp msgid " has a sudden heart attack!" msgstr "Š£ NPC () сŠµŃ€Š“ŠµŃ‡Š½Ń‹Š¹ ŠæрŠøстуŠæ!" @@ -250048,11 +251093,11 @@ msgstr "Š„Š¾Ń€Š¾ŃˆŠ¾" #: src/character.cpp #, c-format -msgid "Chance to stop: %d %%" -msgstr "ŠØŠ°Š½ŃŃ‹ Š¾ŃŃ‚Š°Š½Š¾Š²Šøть: %d %%" +msgid "Expected reduction of bleeding by: %d %%" +msgstr "ŠžŠ¶ŠøŠ“Š°ŠµŠ¼Š¾Šµ уŠ¼ŠµŠ½ŃŒŃˆŠµŠ½ŠøŠµ ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½Šøя: %d %%" #: src/character.cpp -msgid "This will not stop the bleeding." +msgid "This will not affect the bleeding." msgstr "Š­Ń‚Š¾ Š½Šµ Š¾ŃŃ‚Š°Š½Š¾Š²Šøт ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ." #: src/character.cpp @@ -250502,6 +251547,41 @@ msgstr "Š’Š°ŃˆŠµ сŠ½Š°Ń€ŃŠ¶ŠµŠ½ŠøŠµ (%1$s) %2$s ŠµŃ‰Ń‘ сŠøŠ»ŃŒŠ½ŠµŠµ!" msgid "Your %1$s is %2$s!" msgstr "Š’Š°ŃˆŠµ сŠ½Š°Ń€ŃŠ¶ŠµŠ½ŠøŠµ (%1$s) %2$s!" +#: src/character.cpp +msgid "Can't wield spilt liquids." +msgstr "ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š²Š·ŃŃ‚ŃŒ Š² руŠŗŠø ŠæрŠ¾Š»ŠøтыŠµ Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚Šø." + +#: src/character.cpp +msgid "You need at least one arm to even consider wielding something." +msgstr "Š§Ń‚Š¾Š±Ń‹ чтŠ¾-Š½ŠøŠ±ŃƒŠ“ь Š²Š·ŃŃ‚ŃŒ, Š²Š°Š¼ Š½ŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Š° хŠ¾Ń‚я Š±Ń‹ Š¾Š“Š½Š° руŠŗŠ°." + +#: src/character.cpp +#, c-format +msgid "The %s is preventing you from wielding the %s." +msgstr "%s Š½Šµ Š“Š°ŠµŃ‚ Š²Š°Š¼ Š²Š·ŃŃ‚ŃŒ Š² руŠŗŠø ŠæрŠµŠ“Š¼ŠµŃ‚ (%s)." + +#: src/character.cpp +msgid "Something you are wearing hinders the use of both hands." +msgstr "Š§Ń‚Š¾-тŠ¾, чтŠ¾ Š½Š°Š“ŠµŃ‚Š¾ Š½Š° Š²Š°Ń, Š¼ŠµŃˆŠ°ŠµŃ‚ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒŃŃ Š¾Š±ŠµŠøŠ¼Šø руŠŗŠ°Š¼Šø." + +#: src/character.cpp +#, c-format +msgid "The %s can't be wielded with only one arm." +msgstr "Š­Ń‚Š¾ (%s) Š½ŠµŠ»ŃŒŠ·Ń Š“ŠµŃ€Š¶Š°Ń‚ŃŒ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“Š½Š¾Š¹ руŠŗŠ¾Š¹." + +#: src/character.cpp +#, c-format +msgid "You are too weak to wield %s with only one arm." +msgstr "Š’Ń‹ сŠ»ŠøшŠŗŠ¾Š¼ сŠ»Š°Š±Ń‹, чтŠ¾Š±Ń‹ Š“ŠµŃ€Š¶Š°Ń‚ŃŒ этŠ¾ (%s) Š¾Š“Š½Š¾Š¹ руŠŗŠ¾Š¹." + +#: src/character.cpp +msgid " (empty)" +msgstr "(ŠæустŠ¾)" + +#: src/character.cpp src/npctalk.cpp +msgid "fists" +msgstr "ŠŗуŠ»Š°ŠŗŠø" + #: src/character.cpp #, c-format msgid "You are no longer able to wield your %s and drop it!" @@ -251071,6 +252151,11 @@ msgstr "Š£ŃŠæŠµŃˆŠ½Š°Ń Š°Š²Ń‚Š¾Ń€ŠøŠ·Š°Ń†Šøя. ŠŠ°Š¶Š¼ŠøтŠµ Š»ŃŽŠ±ŃƒŃŽ ŠŗŠ» msgid "%s - Root Menu" msgstr "%s ā€” Š“Š»Š°Š²Š½Š¾Šµ Š¼ŠµŠ½ŃŽ" +#: src/computer_session.cpp +#, c-format +msgid "%s (UNAVAILABLE)" +msgstr "%s (ŠŠ•Š”ŠžŠ”Š¢Š£ŠŸŠŠž)" + #: src/computer_session.cpp msgid "Password required." msgstr "Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠæŠ°Ń€Š¾Š»ŃŒ." @@ -251695,7 +252780,7 @@ msgstr "Š­Ń‚Š°Šæ/Š²Š°Ń€ŠøŠ°Š½Ń‚ #%d: " msgid "Result: " msgstr "Š ŠµŠ·ŃƒŠ»ŃŒŃ‚Š°Ń‚: " -#: src/construction.cpp +#: src/construction.cpp src/worldfactory.cpp msgid "N/A" msgstr "Š/Š”" @@ -252404,6 +253489,10 @@ msgstr "" "ŠŠµ хŠ²Š°Ń‚Š°ŠµŃ‚ Š·Š°Ń€ŃŠ“Š¾Š² Š“Š»Ń Š·Š°Š²ŠµŃ€ŃˆŠµŠ½Šøя ŠæрŠ¾ŠøŠ·Š²Š¾Š“стŠ²Š° - %s.\n" "Š’сё рŠ°Š²Š½Š¾ Š½Š°Ń‡Š°Ń‚ŃŒ ŠøŠ·Š³Š¾Ń‚Š¾Š²Š»ŠµŠ½ŠøŠµ?" +#: src/craft_command.cpp +msgid "You don't have the required proficiencies to craft this!" +msgstr "Š£ Š²Š°Ń Š½ŠµŃ‚ Š½ŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Ń‹Ń… уŠ¼ŠµŠ½Šøя Š“Š»Ń сŠ¾Š·Š“Š°Š½Šøя этŠ¾Š³Š¾!" + #: src/craft_command.cpp msgid "" "This craft will use rotten components.\n" @@ -252921,6 +254010,11 @@ msgstr "ŠžŃŠ½Š¾Š²Š½Š¾Š¹ Š½Š°Š²Ń‹Šŗ: %s" msgid "Other skills: %s" msgstr "ŠŸŃ€Š¾Ń‡ŠøŠµ Š½Š°Š²Ń‹ŠŗŠø: %s" +#: src/crafting_gui.cpp +#, c-format +msgid "Proficiencies Required: %s" +msgstr "Š¢Ń€ŠµŠ±ŃƒŠµŠ¼Ń‹Šµ уŠ¼ŠµŠ½Šøя: %s" + #: src/crafting_gui.cpp #, c-format msgid "Time to complete: %s" @@ -252968,6 +254062,13 @@ msgid "" msgstr "" "Š”Š»Ń сŠ¾Š·Š“Š°Š½Šøя Š½ŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Š¾ Š½ŠµŃŠŗŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“Š½Š¾Ń‚ŠøŠæŠ½Ń‹Ń… ŠŗŠ¾Š¼ŠæŠ¾Š½ŠµŠ½Ń‚Š¾Š²" +#: src/crafting_gui.cpp +msgid "" +"Cannot be crafted because you lack the required " +"proficiencies." +msgstr "" +"Š”Š»Ń сŠ¾Š·Š“Š°Š½Šøя Š²Š°Š¼ Š½Šµ хŠ²Š°Ń‚Š°ŠµŃ‚ сŠ¾Š¾Ń‚Š²ŠµŃ‚стŠ²ŃƒŃŽŃ‰Šøх уŠ¼ŠµŠ½ŠøŠ¹." + #: src/crafting_gui.cpp #, c-format msgid "v (%s for more)" @@ -253356,6 +254457,10 @@ msgstr "Š ŠµŠ“Š°ŠŗтŠøрŠ¾Š²Š°Ń‚ŃŒ ŠøŠ³Ń€Š¾ŠŗŠ°/NPC" msgid "Damage self" msgstr "Š Š°Š½Šøть сŠµŠ±Ń" +#: src/debug_menu.cpp +msgid "Bleed self" +msgstr "Š£ŃŃ‚Ń€Š¾Šøть сŠµŠ±Šµ ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ" + #: src/debug_menu.cpp msgid "Set automove route" msgstr "Š£ŃŃ‚Š°Š½Š¾Š²Šøть Š¼Š°Ń€ŃˆŃ€ŃƒŃ‚ Š°Š²Ń‚Š¾Š“Š²ŠøŠ¶ŠµŠ½Šøя" @@ -253488,6 +254593,14 @@ msgstr "Š’Ń‹Š¹Ń‚Šø Š² Š³Š»Š°Š²Š½Š¾Šµ Š¼ŠµŠ½ŃŽ" msgid "Gameā€¦" msgstr "Š˜Š³Ń€Š°..." +#: src/debug_menu.cpp +msgid "Change [b]attery charge" +msgstr "[b] Š˜Š·Š¼ŠµŠ½Šøть Š·Š°Ń€ŃŠ“ Š±Š°Ń‚Š°Ń€ŠµŠø" + +#: src/debug_menu.cpp +msgid "Vehicleā€¦" +msgstr "Š¢Ń€Š°Š½ŃŠæŠ¾Ń€Ń‚ā€¦" + #: src/debug_menu.cpp msgid "Teleport - short range" msgstr "Š¢ŠµŠ»ŠµŠæŠ¾Ń€Ń‚ Š½Š° Š½ŠµŠ±Š¾Š»ŃŒŃˆŠøŠµ рŠ°ŃŃŃ‚Š¾ŃŠ½Šøя" @@ -254123,12 +255236,8 @@ msgstr "ŠŸŠ¾Š»Š¾Š¶ŠµŠ½ŠøŠµ %d:%d Š½Š° %d:%d, %s\n" #: src/debug_menu.cpp #, c-format -msgid "" -"Current turn: %d.\n" -"%s\n" -msgstr "" -"Š„Š¾Š“: %d.\n" -"%s\n" +msgid "Current turn: %d.\n" +msgstr "Š¢ŠµŠŗущŠøŠ¹ хŠ¾Š“: %d.\n" #: src/debug_menu.cpp #, c-format @@ -254139,14 +255248,6 @@ msgstr[1] "%d сущŠµŃŃ‚Š²Š° ŠæрŠøсутстŠ²ŃƒŠµŃ‚.\n" msgstr[2] "%d сущŠµŃŃ‚Š² ŠæрŠøсутстŠ²ŃƒŃŽŃ‚.\n" msgstr[3] "%d сущŠµŃŃ‚Š² ŠæрŠøсутстŠ²ŃƒŃŽŃ‚.\n" -#: src/debug_menu.cpp -msgid "NPCs are going to spawn." -msgstr "NPC Š±ŃƒŠ“ут Š·Š°Ń€Š¾Š¶Š“Š°Ń‚ŃŒŃŃ." - -#: src/debug_menu.cpp -msgid "NPCs are NOT going to spawn." -msgstr "NPC Š½Šµ Š±ŃƒŠ“ут Š·Š°Ń€Š¾Š¶Š“Š°Ń‚ŃŒŃŃ." - #: src/debug_menu.cpp #, c-format msgid "%s: map ( %d:%d ) pos ( %d:%d )" @@ -254206,6 +255307,22 @@ msgstr "Š’Ń‹Š±ŠµŃ€ŠµŃ‚Šµ Š¼Š°ŃˆŠøŠ½Ńƒ Š“Š»Ń сŠ¾Š·Š“Š°Š½Šøя" msgid "%1$s (%2$s)" msgstr "%1$s (%2$s)" +#: src/debug_menu.cpp +msgid "Vehicle condition" +msgstr "Š”Š¾ŃŃ‚Š¾ŃŠ½ŠøŠµ трŠ°Š½ŃŠæŠ¾Ń€Ń‚Š°" + +#: src/debug_menu.cpp +msgid "Light damage" +msgstr "Š›ŠµŠ³ŠŗŠøŠµ ŠæŠ¾Š²Ń€ŠµŠ¶Š“ŠµŠ½Šøя" + +#: src/debug_menu.cpp +msgid "Undamaged" +msgstr "Š‘ŠµŠ· ŠæŠ¾Š²Ń€ŠµŠ¶Š“ŠµŠ½ŠøŠ¹" + +#: src/debug_menu.cpp +msgid "Disabled (tires or engine)" +msgstr "ŠŠµŃ€Š°Š±Š¾Ń‡ŠøŠ¹ (шŠøŠ½Ń‹ ŠøŠ»Šø Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŒ)" + #: src/debug_menu.cpp msgid "Martial arts debug." msgstr "ŠžŃ‚Š»Š°Š“ŠŗŠ° Š±Š¾ŠµŠ²Ń‹Ń… ŠøсŠŗусстŠ²" @@ -254269,6 +255386,10 @@ msgstr "ŠžŃŃ‚Š°Š²Šøть Š½Š¾Ń€Š¼Š°Š»ŃŒŠ½ŃƒŃŽ сŠŗŠ¾Ń€Š¾ŃŃ‚ŃŒ Š²ŠµŃ‚Ń€Š°" msgid "Damage self for how much? hp: %s" msgstr "ŠŠ°ŃŠŗŠ¾Š»ŃŒŠŗŠ¾ сŠøŠ»ŃŒŠ½Š¾ рŠ°Š½Šøть сŠµŠ±Ń? ŠžŠ—: %s" +#: src/debug_menu.cpp +msgid "Add bleeding duration in minutes, equal to intensity:" +msgstr "Š”Š¾Š±Š°Š²Šøть ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ, Š“Š»ŠøтŠµŠ»ŃŒŠ½Š¾ŃŃ‚ŃŒ Š² Š¼ŠøŠ½ŃƒŃ‚Š°Ń…, сŠ¾Š²ŠæŠ°Š“Š°ŠµŃ‚ с сŠøŠ»Š¾Š¹:" + #: src/debug_menu.cpp msgid "This binary was not compiled with tiles support." msgstr "Š­Ń‚Š¾Ń‚ ŠøсŠæŠ¾Š»Š½ŃŠµŠ¼Ń‹Š¹ фŠ°Š¹Š» Š±Ń‹Š» сŠŗŠ¾Š¼ŠæŠøŠ»ŠøрŠ¾Š²Š°Š½ Š±ŠµŠ· ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠŗŠø тŠ°Š¹Š»Š¾Š²." @@ -254405,6 +255526,14 @@ msgstr "Š–ŠµŠ»Š°ŠµŠ¼Ń‹Š¹ урŠ¾Š²ŠµŠ½ŃŒ Š·Š°ŠŗŠ»ŠøŠ½Š°Š½Šøя (тŠµŠŗущŠøŠ¹: %d msgid "%s is now level %d!" msgstr "%s тŠµŠæŠµŃ€ŃŒ Š½Š° урŠ¾Š²Š½Šµ %d!" +#: src/debug_menu.cpp src/iuse.cpp src/iuse.cpp +msgid "There's no vehicle there." +msgstr "Š¢ŃƒŃ‚ Š½ŠµŃ‚ Š¼Š°ŃˆŠøŠ½Ń‹." + +#: src/debug_menu.cpp +msgid "By how much? (in kJ, negative to discharge)" +msgstr "ŠŠ°ŃŠŗŠ¾Š»ŃŒŠŗŠ¾? (Š² ŠŗŠ”Š¶, Š¾Ń‚Ń€ŠøцŠ°Ń‚ŠµŠ»ŃŒŠ½Š¾Šµ Š·Š½Š°Ń‡ŠµŠ½Šøя Š“Š»Ń рŠ°Š·Ń€ŃŠ“ŠŗŠø)" + #: src/descriptions.cpp #, c-format msgid "" @@ -255133,6 +256262,22 @@ msgstr "ŠæрŠµŠŗрŠ°ŃŠ½Š¾" msgid "perfect" msgstr "ŠøŠ“ŠµŠ°Š»ŃŒŠ½Š¾" +#: src/effect.cpp +msgid "miniscule" +msgstr "Š¼ŠøŠ·ŠµŃ€Š½Ń‹Š¹" + +#: src/effect.cpp +msgid "small" +msgstr "Š½ŠµŠ±Š¾Š»ŃŒŃˆŠ¾Šµ" + +#: src/effect.cpp +msgid "moderate" +msgstr "срŠµŠ“Š½ŠøŠ¹" + +#: src/effect.cpp +msgid "excellent" +msgstr "ŠæрŠµŠ²Š¾ŃŃ…Š¾Š“Š½Ń‹Š¹" + #. ~ Default format for scores. %1$s is statistic description; %2$s is value. #: src/event_statistics.cpp #, c-format @@ -257938,6 +259083,12 @@ msgstr "ŠœŠµŃŃ‚Š¾Š½Š°Ń…Š¾Š¶Š“ŠµŠ½ŠøŠµ Š½Š° ŠŗŠ°Ń€Ń‚Šµ: %d, %d, %d" msgid "Your local position: %d, %d, %d" msgstr "Š›Š¾ŠŗŠ°Š»ŃŒŠ½Ń‹Šµ ŠŗŠ¾Š¾Ń€Š“ŠøŠ½Š°Ń‚Ń‹: %d, %d, %d" +#: src/game.cpp +#, c-format +msgid "Total NPCs within %d OMTs: %d. %d are static NPCs." +msgstr "" +"Š’сŠµŠ³Š¾ NPC Š² ŠæрŠµŠ“ŠµŠ»Š°Ń… %d ŠŗŠ»ŠµŃ‚Š¾Šŗ Š³Š»Š¾Š±Š°Š»ŃŒŠ½Š¾Š¹ ŠŗŠ°Ń€Ń‚Ń‹: %d. %d стŠ°Ń‚ŠøчŠµŃŠŗŠøх NPC." + #: src/game.cpp msgid "East:" msgstr "Š’Š¾ŃŃ‚Š¾Šŗ:" @@ -259761,12 +260912,12 @@ msgid "Your inventory is empty." msgstr "Š’Š°Ńˆ ŠøŠ½Š²ŠµŠ½Ń‚Š°Ń€ŃŒ Šæуст." #: src/game_inventory.cpp -msgid "ENCUMBRANCE" -msgstr "Š”ŠšŠžŠ’ŠŠŠŠžŠ”Š¢Š¬" +msgid "AVG ENCUMBRANCE" +msgstr "Š”Š Š” Š”ŠšŠžŠ’ŠŠŠŠžŠ”Š¢Š¬" #: src/game_inventory.cpp -msgid "COVERAGE" -msgstr "ŠŸŠžŠšŠ Š«Š¢Š˜Š•" +msgid "AVG COVERAGE" +msgstr "Š”Š Š” ŠŸŠžŠšŠ Š«Š¢Š˜Š•" #: src/game_inventory.cpp msgid "WARMTH" @@ -263019,6 +264170,11 @@ msgstr "%1$s: сŠŗŠ¾Š»ŃŒŠŗŠ¾ ŠæŠ¾Š»Š¾Š¶Šøть сюŠ“Š° (%2$s)?" msgid "The %1$s contains %2$d %3$s." msgstr "%1$s сŠ¾Š“ŠµŃ€Š¶Šøт %2$d %3$s." +#: src/iexamine.cpp +#, c-format +msgid "You reload the %s." +msgstr "Š’Ń‹ ŠæŠµŃ€ŠµŠ·Š°Ń€ŃŠ“ŠøŠ»Šø ŠæрŠµŠ“Š¼ŠµŃ‚ (%s)." + #: src/iexamine.cpp msgid "Do what with the curtains?" msgstr "Š§Ń‚Š¾ сŠ“ŠµŠ»Š°Ń‚ŃŒ сŠ¾ штŠ¾Ń€Š°Š¼Šø?" @@ -263943,6 +265099,10 @@ msgstr "Š¤ŠøŠ½Š°Š»ŠøŠ·Š°Ń†Šøя" msgid "Body parts" msgstr "Š§Š°ŃŃ‚Šø тŠµŠ»Š°" +#: src/init.cpp +msgid "Weather types" +msgstr "Š¢ŠøŠæы ŠæŠ¾Š³Š¾Š“ы" + #: src/init.cpp msgid "Field types" msgstr "Š¢ŠøŠæ Š¾Š±Š»Š°ŃŃ‚Šø" @@ -264800,10 +265960,6 @@ msgstr "Š³Š½ŠøŠµŠ½ŠøŠµ (хŠ¾Š“ы):" msgid "max rot (turns): " msgstr "Š¼Š°Šŗс Š³Š½ŠøŠµŠ½ŠøŠµ (хŠ¾Š“ы):" -#: src/item.cpp -msgid "last rot: " -msgstr "уст. ŠæŠ¾Ń€Ń‡.: " - #: src/item.cpp msgid "last temp: " msgstr "ŠæŠ¾ŃŠ» тŠµŠ¼Šæ:" @@ -265090,8 +266246,8 @@ msgid "Recommended strength (burst): " msgstr "Š ŠµŠŗŠ¾Š¼ŠµŠ½Š“Š¾Š²Š°Š½Š½Š°Ń сŠøŠ»Š° (Š¾Ń‡ŠµŃ€ŠµŠ“ь): " #: src/item.cpp -msgid " moves " -msgstr " хŠ¾Š“Š¾Š² " +msgid " moves" +msgstr " хŠ¾Š“Š¾Š²" #: src/item.cpp msgid "Skill used: " @@ -265130,10 +266286,6 @@ msgstr "Š Š°Š²Š½Ń‹Š¹ шŠ°Š½Ń Š½Š° хŠ¾Ń€Š¾ŃˆŠµŠµ ŠæŠ¾ŠæŠ°Š“Š°Š½ŠøŠµ Š½Š° Š“Šøс msgid "" msgstr "" -#: src/item.cpp -msgid " moves" -msgstr " хŠ¾Š“Š¾Š²" - #: src/item.cpp msgid "Time to reach aim level: " msgstr "Š’Ń€ŠµŠ¼Ń Š“Š¾ урŠ¾Š²Š½Ń ŠæрŠøцŠµŠ»ŠøŠ²Š°Š½Šøя: " @@ -265271,164 +266423,169 @@ msgstr "" "Š¾Ń‚Ń€ŠµŠ¼Š¾Š½Ń‚ŠøрŠ¾Š²Š°Š² этŠ¾Ń‚ ŠæрŠµŠ“Š¼ŠµŃ‚." #: src/item.cpp -msgid "Covers: " -msgstr "ŠŸŠ¾ŠŗрыŠ²Š°ŠµŃ‚: " +msgid "Covers:" +msgstr "ŠŸŠ¾ŠŗрыŠ²Š°ŠµŃ‚:" #: src/item.cpp -msgid "The head. " -msgstr "Š“Š¾Š»Š¾Š²Š°. " +msgid " The head." +msgstr " Š“Š¾Š»Š¾Š²Š°." #: src/item.cpp -msgid "The eyes. " -msgstr "Š“Š»Š°Š·Š°. " +msgid " The eyes." +msgstr " Š“Š»Š°Š·Š°." #: src/item.cpp -msgid "The mouth. " -msgstr "Š Š¾Ń‚. " +msgid " The mouth." +msgstr " Š Š¾Ń‚." #: src/item.cpp -msgid "The torso. " -msgstr "Š¢Š¾Ń€Ń. " +msgid " The torso." +msgstr " Š¢Š¾Ń€Ń." #: src/item.cpp -msgid "Either arm. " -msgstr "Š›ŃŽŠ±Š°Ń руŠŗŠ°. " +msgid " Either arm." +msgstr " Š›ŃŽŠ±Š°Ń руŠŗŠ°." #: src/item.cpp -msgid "The arms. " -msgstr "Š ŃƒŠŗŠø. " +msgid " The arms." +msgstr " Š ŃƒŠŗŠø." #: src/item.cpp -msgid "The left arm. " -msgstr "Š›ŠµŠ²Š°Ń руŠŗŠ°." +msgid " The left arm." +msgstr " Š›ŠµŠ²Š°Ń руŠŗŠ°." #: src/item.cpp -msgid "The right arm. " -msgstr "ŠŸŃ€Š°Š²Š°Ń руŠŗŠ°." +msgid " The right arm." +msgstr " ŠŸŃ€Š°Š²Š°Ń руŠŗŠ°." #: src/item.cpp -msgid "Either hand. " -msgstr "Š›ŃŽŠ±Š°Ń Š»Š°Š“Š¾Š½ŃŒ. " +msgid " Either hand." +msgstr " Š›ŃŽŠ±Š°Ń Š»Š°Š“Š¾Š½ŃŒ." #: src/item.cpp -msgid "The hands. " -msgstr "Š›Š°Š“Š¾Š½Šø. " +msgid " The hands." +msgstr " Š›Š°Š“Š¾Š½Šø." #: src/item.cpp -msgid "The left hand. " -msgstr "Š›ŠµŠ²Š°Ń Š»Š°Š“Š¾Š½ŃŒ. " +msgid " The left hand." +msgstr " Š›ŠµŠ²Š°Ń Š»Š°Š“Š¾Š½ŃŒ." #: src/item.cpp -msgid "The right hand. " -msgstr "ŠŸŃ€Š°Š²Š°Ń Š»Š°Š“Š¾Š½ŃŒ. " +msgid " The right hand." +msgstr " ŠŸŃ€Š°Š²Š°Ń Š»Š°Š“Š¾Š½ŃŒ." #: src/item.cpp -msgid "Either leg. " -msgstr "Š›ŃŽŠ±Š°Ń Š½Š¾Š³Š°." +msgid " Either leg." +msgstr " Š›ŃŽŠ±Š°Ń Š½Š¾Š³Š°." #: src/item.cpp -msgid "The legs. " -msgstr "ŠŠ¾Š³Šø. " +msgid " The legs." +msgstr " ŠŠ¾Š³Šø." #: src/item.cpp -msgid "The left leg. " -msgstr "Š›ŠµŠ²Š°Ń Š½Š¾Š³Š°." +msgid " The left leg." +msgstr " Š›ŠµŠ²Š°Ń Š½Š¾Š³Š°." #: src/item.cpp -msgid "The right leg. " -msgstr "ŠŸŃ€Š°Š²Š°Ń Š½Š¾Š³Š°." +msgid " The right leg." +msgstr " ŠŸŃ€Š°Š²Š°Ń Š½Š¾Š³Š°." #: src/item.cpp -msgid "Either foot. " -msgstr "Š›ŃŽŠ±Š°Ń стуŠæŠ½Ń." +msgid " Either foot." +msgstr " Š›ŃŽŠ±Š°Ń стуŠæŠ½Ń." #: src/item.cpp -msgid "The feet. " -msgstr "Š”туŠæŠ½Šø. " +msgid " The feet." +msgstr " Š”туŠæŠ½Šø." #: src/item.cpp -msgid "The left foot. " -msgstr "Š›ŠµŠ²Š°Ń стуŠæŠ½Ń." +msgid " The left foot." +msgstr " Š›ŠµŠ²Š°Ń стуŠæŠ½Ń." #: src/item.cpp -msgid "The right foot. " -msgstr "ŠŸŃ€Š°Š²Š°Ń стуŠæŠ½Ń." +msgid " The right foot." +msgstr " ŠŸŃ€Š°Š²Š°Ń стуŠæŠ½Ń." #: src/item.cpp -msgid "Nothing." -msgstr "Š½ŠµŃ‚." +msgid " Nothing." +msgstr " ŠŠøчŠµŠ³Š¾." #: src/item.cpp -msgid "Layer: " -msgstr "Š”Š»Š¾Š¹: " +msgid "Layer:" +msgstr "Š”Š»Š¾Š¹:" #: src/item.cpp -msgid "Personal aura. " -msgstr "Š›ŠøчŠ½Š°Ń Š°ŃƒŃ€Š°. " +msgid " Personal aura." +msgstr " Š›ŠøчŠ½Š°Ń Š°ŃƒŃ€Š°." #: src/item.cpp -msgid "Close to skin. " -msgstr "ŠŸŃ€ŠøŠ»ŠµŠ³Š°ŠµŃ‚ Šŗ тŠµŠ»Ńƒ. " +msgid " Close to skin." +msgstr " ŠŸŃ€ŠøŠ»ŠµŠ³Š°ŠµŃ‚ Šŗ тŠµŠ»Ńƒ." #: src/item.cpp -msgid "Strapped. " -msgstr "ŠŸŃ€ŠøстёŠ³ŠøŠ²Š°ŠµŃ‚ся. " +msgid " Strapped." +msgstr " ŠŸŃ€ŠøстёŠ³ŠøŠ²Š°ŠµŃ‚ся." #: src/item.cpp -msgid "Outer. " -msgstr "Š’Š½ŠµŃˆŠ½ŠøŠ¹. " +msgid " Outer." +msgstr " Š’Š½ŠµŃˆŠ½ŠøŠ¹." #: src/item.cpp -msgid "Waist. " -msgstr "ŠŸŠ¾ŃŃ. " +msgid " Waist." +msgstr " ŠŸŠ¾ŃŃ." #: src/item.cpp -msgid "Outer aura. " -msgstr "Š’Š½ŠµŃˆŠ½ŃŃ Š°ŃƒŃ€Š°. " +msgid " Outer aura." +msgstr " Š’Š½ŠµŃˆŠ½ŃŃ Š°ŃƒŃ€Š°." #: src/item.cpp -msgid "Normal. " -msgstr "ŠžŠ±Ń‹Ń‡Š½Ń‹Š¹. " +msgid " Normal." +msgstr " ŠžŠ±Ń‹Ń‡Š½Ń‹Š¹." #: src/item.cpp -msgid "Coverage: " -msgstr "ŠŸŠ¾ŠŗрытŠøŠµ: " +msgid "Average Coverage: " +msgstr "Š”рŠµŠ“Š½ŠµŠµ ŠæŠ¾ŠŗрытŠøŠµ: " #: src/item.cpp msgid "Warmth: " msgstr "Š¢ŠµŠæŠ»Š¾: " #: src/item.cpp -msgid " (fits)" -msgstr " (Š²ŠæŠ¾Ń€Ńƒ)" +msgid " (fits)" +msgstr " (Š²ŠæŠ¾Ń€Ńƒ)" #: src/item.cpp -msgid " (poor fit)" -msgstr " (Š½Šµ ŠæŠ¾ рŠ°Š·Š¼ŠµŃ€Ńƒ)" +msgid " (poor fit)" +msgstr " (Š½Šµ ŠæŠ¾ рŠ°Š·Š¼ŠµŃ€Ńƒ)" #: src/item.cpp -msgid " (too big)" -msgstr " (Š²ŠµŠ»ŠøŠŗŠ¾)" +msgid " (too big)" +msgstr " (Š²ŠµŠ»ŠøŠŗŠ¾)" #: src/item.cpp -msgid " (huge!)" -msgstr " (Š¾Š³Ń€Š¾Š¼Š½Š¾!)" +msgid " (huge!)" +msgstr " (Š¾Š³Ń€Š¾Š¼Š½Š¾!)" #: src/item.cpp -msgid " (too small)" -msgstr " (Š¼Š°Š»Š¾Š²Š°Ń‚Š¾)" +msgid " (too small)" +msgstr " (Š¼Š°Š»Š¾Š²Š°Ń‚Š¾)" #: src/item.cpp -msgid " (tiny!)" -msgstr " (ŠŗрŠ¾ŃˆŠµŃ‡Š½Š¾Šµ!)" +msgid " (tiny!)" +msgstr " (ŠŗрŠ¾ŃˆŠµŃ‡Š½Š¾Šµ!)" #: src/item.cpp -msgid "Encumbrance: " -msgstr "Š”ŠŗŠ¾Š²Š°Š½Š½Š¾ŃŃ‚ŃŒ: " +msgid "Encumbrance:" +msgstr "Š”ŠŗŠ¾Š²Š°Š½Š½Š¾ŃŃ‚ŃŒ:" + +#: src/item.cpp +#, c-format +msgid "%s:" +msgstr "%s:" #: src/item.cpp -msgid "Encumbrance when full: " -msgstr "Š”ŠŗŠ¾Š²Š°Š½Š½Š¾ŃŃ‚ŃŒ ŠæрŠø Š·Š°ŠæŠ¾Š»Š½ŠµŠ½ŠøŠø: " +msgid "When Full:" +msgstr "ŠšŠ¾Š³Š“Š° Š·Š°ŠæŠ¾Š»Š½ŠµŠ½Š¾:" #: src/item.cpp msgid "Weight capacity modifier: " @@ -265862,24 +267019,24 @@ msgid "Power Capacity:" msgstr "ŠœŠ¾Ń‰Š½Š¾ŃŃ‚ŃŒ: " #: src/item.cpp -msgid "Environmental Protection: " -msgstr "Š—Š°Ń‰ŠøтŠ° Š¾Ń‚ Š¾ŠŗруŠ¶Š°ŃŽŃ‰ŠµŠ¹ срŠµŠ“ы: " +msgid "Environmental Protection:" +msgstr "Š—Š°Ń‰ŠøтŠ° Š¾Ń‚ Š¾ŠŗруŠ¶Š°ŃŽŃ‰ŠµŠ¹ срŠµŠ“ы:" #: src/item.cpp -msgid "Bash Protection: " -msgstr "Š—Š°Ń‰ŠøтŠ° Š¾Ń‚ уŠ“Š°Ń€Š°: " +msgid "Bash Protection:" +msgstr "Š—Š°Ń‰ŠøтŠ° Š¾Ń‚ уŠ“Š°Ń€Š°:" #: src/item.cpp -msgid "Cut Protection: " -msgstr "Š—Š°Ń‰ŠøтŠ° Š¾Ń‚ ŠæŠ¾Ń€ŠµŠ·Š¾Š²: " +msgid "Cut Protection:" +msgstr "Š—Š°Ń‰ŠøтŠ° Š¾Ń‚ ŠæŠ¾Ń€ŠµŠ·Š¾Š²:" #: src/item.cpp -msgid "Ballistic Protection: " -msgstr "Š—Š°Ń‰ŠøтŠ° Š¾Ń‚ ŠæуŠ»ŃŒ: " +msgid "Ballistic Protection:" +msgstr "Š—Š°Ń‰ŠøтŠ° Š¾Ń‚ ŠæуŠ»ŃŒ:" #: src/item.cpp -msgid "Stat Bonus: " -msgstr "Š‘Š¾Š½ŃƒŃ Šŗ хŠ°Ń€-ŠŗŠµ: " +msgid "Stat Bonus:" +msgstr "Š‘Š¾Š½ŃƒŃ Šŗ хŠ°Ń€-ŠŗŠµ:" #: src/item.cpp msgid "Melee damage: " @@ -268063,10 +269220,6 @@ msgstr "Š”Š»Šøть Š¾Ń‚ŠŗуŠ“Š°?" msgid "There is nothing to siphon nearby." msgstr "Š—Š“ŠµŃŃŒ Š½ŠµŠ¾Ń‚ŠŗуŠ“Š° сŠ»Šøть чтŠ¾-Š½ŠøŠ±ŃƒŠ“ь." -#: src/iuse.cpp -msgid "There's no vehicle there." -msgstr "Š¢ŃƒŃ‚ Š½ŠµŃ‚ Š¼Š°ŃˆŠøŠ½Ń‹." - #: src/iuse.cpp msgid "With a snarl, the combat chainsaw screams to life!" msgstr "Š” рёŠ²Š¾Š¼ Š¾Š¶ŠøŠ²Š°ŠµŃ‚ Š²Š°ŃˆŠ° Š±Š¾ŠµŠ²Š°Ń Š±ŠµŠ½Š·Š¾ŠæŠøŠ»Š°!" @@ -271195,6 +272348,10 @@ msgstr "ŠŠ“сŠŗŠ°Ń Š±Š¾Š»ŃŒ!" msgid "It itches a little." msgstr "ŠŠµŠ¼Š½Š¾Š³Š¾ Š·ŃƒŠ“Šøт." +#: src/iuse_actor.cpp +msgid "Bleeding has not stopped completely!" +msgstr "ŠšŃ€Š¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ ŠæŠ¾Š»Š½Š¾ŃŃ‚ŃŒŃŽ Š¾ŃŃ‚Š°Š½Š¾Š²ŠøŠ»Š¾ŃŃŒ!" + #: src/iuse_actor.cpp msgid "You cannot cauterize while mounted." msgstr "ŠŠµŠ»ŃŒŠ·Ń ŠæрŠøŠ¶ŠøŠ³Š°Ń‚ŃŒ рŠ°Š½Ń‹, Š±ŃƒŠ“учŠø Š²ŠµŃ€Ń…Š¾Š¼." @@ -271524,12 +272681,24 @@ msgid "You stop the bleeding." msgstr "Š’Ń‹ Š¾ŃŃ‚Š°Š½Š¾Š²ŠøŠ»Šø ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ." #: src/iuse_actor.cpp -msgid "The wound still bleeds." -msgstr "Š Š°Š½Š° Š²ŃŃ‘ ŠµŃ‰Ń‘ ŠŗрŠ¾Š²Š¾Ń‚Š¾Ń‡Šøт." +msgid "You reduce the bleeding, but it's not stopped yet." +msgstr "Š’Ń‹ Š¾ŃŠ»Š°Š±Š»ŃŠµŃ‚Šµ ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ, Š½Š¾ Š¾Š½Š¾ ŠæŠ¾ŠŗŠ° чтŠ¾ ŠæрŠ¾Š“Š¾Š»Š¶Š°ŠµŃ‚ся." + +#: src/iuse_actor.cpp +msgid "The bleeding is reduced, but not stopped." +msgstr "ŠšŃ€Š¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ Š¾ŃŠ»Š°Š±Š»Š¾, Š½Š¾ Š½Šµ ŠæрŠµŠŗрŠ°Ń‚ŠøŠ»Š¾ŃŃŒ." + +#: src/iuse_actor.cpp +msgid "" +"Your dressing is too ineffective for a bleeding of this extent, and you fail" +" to stop it." +msgstr "" +"Š’Š°ŃˆŠ° ŠæŠµŃ€ŠµŠ²ŃŠ·ŠŗŠ° Š½Šµ ŠæŠ¾Š¼Š¾Š³Š°ŠµŃ‚ сŠæрŠ°Š²Šøться с ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµŠ¼ тŠ°ŠŗŠ¾Š¹ сŠøŠ»Ń‹, Šø Š²Ń‹ Š½Šµ " +"Š¾ŃŃ‚Š°Š½Š°Š²Š»ŠøŠ²Š°ŠµŃ‚Šµ ŠµŠ³Š¾." #: src/iuse_actor.cpp -msgid "You fail to stop the bleeding." -msgstr "Š’Š°Š¼ Š½Šµ уŠ“Š°Š»Š¾ŃŃŒ Š¾ŃŃ‚Š°Š½Š¾Š²Šøть ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ." +msgid "The wound still bleeds." +msgstr "Š Š°Š½Š° Š²ŃŃ‘ ŠµŃ‰Ń‘ ŠŗрŠ¾Š²Š¾Ń‚Š¾Ń‡Šøт." #: src/iuse_actor.cpp msgid "The wound is cleaned." @@ -271634,12 +272803,16 @@ msgid "Actual disinfecting quality: " msgstr "Š¤Š°ŠŗтŠøчŠµŃŠŗŠ¾Šµ ŠŗŠ°Ń‡ŠµŃŃ‚Š²Š¾ Š“ŠµŠ·ŠøŠ½Ń„ŠµŠŗцŠøŠø: " #: src/iuse_actor.cpp -msgid "Chance to heal (percent): " -msgstr "ŠØŠ°Š½Ń Š²Ń‹Š»ŠµŃ‡Šøть (Š² %): " +msgid "Effect on bleeding: " +msgstr "Š’Š¾Š·Š“ŠµŠ¹ŃŃ‚Š²ŠøŠµ Š½Š° ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ: " #: src/iuse_actor.cpp -msgid "* Bleeding: " -msgstr "* ŠšŃ€Š¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ: " +msgid "Actual effect on bleeding: " +msgstr "Š ŠµŠ°Š»ŃŒŠ½Š¾Šµ Š·Š“ŠµŠ¹ŃŃ‚Š²ŠøŠµ Š½Š° ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ: " + +#: src/iuse_actor.cpp +msgid "Chance to heal (percent): " +msgstr "ŠØŠ°Š½Ń Š²Ń‹Š»ŠµŃ‡Šøть (Š² %): " #: src/iuse_actor.cpp msgid "* Bite: " @@ -271705,8 +272878,8 @@ msgid "It's not a gun." msgstr "Š­Ń‚Š¾ Š½Šµ Š¾Š³Š½ŠµŃŃ‚Ń€ŠµŠ»ŃŒŠ½Š¾Šµ Š¾Ń€ŃƒŠ¶ŠøŠµ." #: src/iuse_actor.cpp -msgid "The barrel is too short." -msgstr "Š”тŠ²Š¾Š» Š¾Ń€ŃƒŠ¶Šøя сŠ»ŠøшŠŗŠ¾Š¼ ŠŗŠ¾Ń€Š¾Ń‚ŠŗŠøŠ¹." +msgid "The barrel is too small." +msgstr "Š”тŠ²Š¾Š» Š¾Ń€ŃƒŠ¶Šøя сŠ»ŠøшŠŗŠ¾Š¼ Š¼Š°Š»ŠµŠ½ŃŒŠŗŠøŠ¹." #: src/iuse_actor.cpp msgid "The barrel is already sawn-off." @@ -273248,10 +274421,6 @@ msgstr "Š¼Š°Š½Š°" msgid "stamina" msgstr "Š²Ń‹Š½Š¾ŃŠ»ŠøŠ²Š¾ŃŃ‚ŃŒ" -#: src/magic.cpp -msgid "bionic power" -msgstr "Š±ŠøŠ¾Š½ŠøчŠµŃŠŗŠ°Ń эŠ½ŠµŃ€Š³Šøя" - #: src/magic.cpp msgid "error: energy_type" msgstr "Š¾ŃˆŠøŠ±ŠŗŠ°: energy_type" @@ -275326,7 +276495,7 @@ msgstr "Š’Ń‹ Š±ŃŒŃ‘Ń‚Šµ ŠæрŠ¾Ń‚ŠøŠ²Š½ŠøŠŗŠ° (%s) ŠøŠ·Š¾ Š²ŃŠµŃ… сŠøŠ», тŠ°Šŗ msgid "You smash %s with all your might but %s remains in their hands!" msgstr "Š’Ń‹ Š±ŃŒŃ‘Ń‚Šµ ŠæрŠ¾Ń‚ŠøŠ²Š½ŠøŠŗŠ° (%s) ŠøŠ·Š¾ Š²ŃŠµŃ… сŠøŠ», Š½Š¾ %s Š¾ŃŃ‚Š°Ń‘Ń‚ŃŃ Š² руŠŗŠ°Ń…!" -#: src/melee.cpp src/npctalk.cpp +#: src/melee.cpp src/talker_npc.cpp #, c-format msgid "%s is hostile!" msgstr "%s - Š²Ń€Š°Š³!" @@ -276165,6 +277334,36 @@ msgctxt "memorial_female" msgid "Died of a drug overdose." msgstr "Š£Š¼ŠµŃ€Š»Š° Š¾Ń‚ ŠæŠµŃ€ŠµŠ“Š¾Š·ŠøрŠ¾Š²ŠŗŠø Š½Š°Ń€ŠŗŠ¾Ń‚ŠøŠŗŠ°Š¼Šø." +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Bled to death." +msgstr "Š˜ŃŃ‚Ń‘Šŗ ŠŗрŠ¾Š²ŃŒŃŽ Š“Š¾ сŠ¼ŠµŃ€Ń‚Šø." + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Bled to death." +msgstr "Š˜ŃŃ‚ŠµŠŗŠ»Š° ŠŗрŠ¾Š²ŃŒŃŽ Š“Š¾ сŠ¼ŠµŃ€Ń‚Šø." + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died of hypovolemic shock." +msgstr "Š£Š¼ŠµŃ€ Š¾Ń‚ Š³ŠøŠæŠ¾Š²Š¾Š»ŠµŠ¼ŠøчŠµŃŠŗŠ¾Š³Š¾ шŠ¾ŠŗŠ°." + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died of hypovolemic shock." +msgstr "Š£Š¼ŠµŃ€Š»Š° Š¾Ń‚ Š³ŠøŠæŠ¾Š²Š¾Š»ŠµŠ¼ŠøчŠµŃŠŗŠ¾Š³Š¾ шŠ¾ŠŗŠ°." + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died from loss of red blood cells." +msgstr "Š£Š¼ŠµŃ€ Š¾Ń‚ Š½ŠµŃ…Š²Š°Ń‚ŠŗŠø ŠŗрŠ°ŃŠ½Ń‹Ń… ŠŗрŠ¾Š²ŃŠ½Ń‹Ń… тŠµŠ»ŠµŃ†." + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died from loss of red blood cells." +msgstr "Š£Š¼ŠµŃ€Š»Š° Š¾Ń‚ Š½ŠµŃ…Š²Š°Ń‚ŠŗŠø ŠŗрŠ°ŃŠ½Ń‹Ń… ŠŗрŠ¾Š²ŃŠ½Ń‹Ń… тŠµŠ»ŠµŃ†." + #: src/memorial_logger.cpp msgctxt "memorial_male" msgid "Succumbed to the infection." @@ -280324,10 +281523,6 @@ msgctxt "Paralyze as an action" msgid "paralyze" msgstr "ŠæŠ°Ń€Š°Š»ŠøŠ·Š¾Š²Š°Ń‚ŃŒ" -#: src/monster.cpp -msgid "cause bleed" -msgstr "Š²Ń‹Š·Ń‹Š²Š°Ń‚ŃŒ ŠŗрŠ¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ" - #: src/monster.cpp msgid "It has a head." msgstr "Š£ Š½ŠµŠ³Š¾ ŠµŃŃ‚ŃŒ Š³Š¾Š»Š¾Š²Š°." @@ -281439,6 +282634,15 @@ msgstr "%s (Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾)" msgid "%s (activated)" msgstr "%s (Š°ŠŗтŠøŠ²ŠøрŠ¾Š²Š°Š½Š¾)" +#: src/newcharacter.cpp +msgid "Profession proficiencies:" +msgstr "Š£Š¼ŠµŠ½Šøя ŠæрŠ¾Ń„ŠµŃŃŠøŠø:" + +#: src/newcharacter.cpp +msgctxt "Profession has no proficiencies" +msgid "None" +msgstr "ŠŠøчŠµŠ³Š¾" + #: src/newcharacter.cpp msgid "Pets:" msgstr "ŠŸŠøтŠ¾Š¼Ń†Ń‹:" @@ -281731,8 +282935,12 @@ msgstr "" "шŠ°Š±Š»Š¾Š½." #: src/newcharacter.cpp -msgid "_______NO NAME ENTERED!_______" -msgstr "_______Š˜ŠœŠÆ ŠŠ• Š’Š’Š•Š”Š•ŠŠž!_______" +msgid "--- NO NAME ENTERED ---" +msgstr "--- Š˜ŠœŠÆ ŠŠ• Š’Š’Š•Š”Š•ŠŠž ---" + +#: src/newcharacter.cpp +msgid "--- RANDOM NAME ---" +msgstr "--- Š”Š›Š£Š§ŠŠ™ŠŠžŠ• Š˜ŠœŠÆ ---" #: src/newcharacter.cpp #, c-format @@ -281823,16 +283031,20 @@ msgid "Enter height in centimeters. Minimum 145, maximum 200" msgstr "Š’Š²ŠµŠ“ŠøтŠµ Š²Š°Ńˆ рŠ¾ŃŃ‚ Š² сŠ°Š½Ń‚ŠøŠ¼ŠµŃ‚Ń€Š°Ń…. ŠžŃ‚ 145 Š“Š¾ 200" #: src/newcharacter.cpp -msgid "Enter blood type (omit Rh):" -msgstr "Š’Š²ŠµŠ“ŠøтŠµ Š³Ń€ŃƒŠæŠæу ŠŗрŠ¾Š²Šø (Š±ŠµŠ· рŠµŠ·ŃƒŃ-фŠ°ŠŗтŠ¾Ń€Š°):" +msgid "Select blood type" +msgstr "Š’Ń‹Š±ŠµŃ€ŠøтŠµ Š³Ń€ŃƒŠæŠæу ŠŗрŠ¾Š²Šø" #: src/newcharacter.cpp -msgid "Invalid blood type." -msgstr "ŠŠµŠŗŠ¾Ń€Ń€ŠµŠŗтŠ½Š°Ń Š³Ń€ŃƒŠæŠæŠ° ŠŗрŠ¾Š²Šø." +msgid "Select Rh factor" +msgstr "Š’Ń‹Š±ŠµŃ€ŠøтŠµ рŠµŠ·ŃƒŃ-фŠ°ŠŗтŠ¾Ń€" #: src/newcharacter.cpp -msgid "Enter Rh factor:" -msgstr "Š’Š²ŠµŠ“ŠøтŠµ рŠµŠ·ŃƒŃ-фŠ°ŠŗтŠ¾Ń€:" +msgid "negative" +msgstr "Š¾Ń‚Ń€ŠøцŠ°Ń‚ŠµŠ»ŃŒŠ½Ń‹Š¹" + +#: src/newcharacter.cpp +msgid "positive" +msgstr "ŠæŠ¾Š»Š¾Š¶ŠøтŠµŠ»ŃŒŠ½Ń‹Š¹" #: src/newcharacter.cpp msgid "Name of template:" @@ -282219,6 +283431,25 @@ msgstr " усŠæŠ¾ŠŗŠ°ŠøŠ²Š°ŠµŃ‚ся." msgid " is no longer afraid." msgstr " Š±Š¾Š»ŃŒŃˆŠµ Š½Šµ Š±Š¾Šøтся." +#: src/npc.cpp +#, c-format +msgid "I'm holing up here for safety. Long term, %s" +msgstr "ŠÆ Š±ŃƒŠ“у Š·Š“ŠµŃŃŒ Š² Š±ŠµŠ·Š¾ŠæŠ°ŃŠ½Š¾ŃŃ‚Šø. Š”Š¾Š»Š³Š¾, %s" + +#: src/npc.cpp +msgid "I run the shop here." +msgstr "Š£ Š¼ŠµŠ½Ń Š·Š“ŠµŃŃŒ Š¼Š°Š³Š°Š·ŠøŠ½." + +#: src/npc.cpp +#, c-format +msgid "Currently, I'm guarding this location. Overall, %s" +msgstr "Š’ Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń я Š¾Ń…Ń€Š°Š½ŃŃŽ эту тŠµŃ€Ń€ŠøтŠ¾Ń€Šøю. Š’ цŠµŠ»Š¾Š¼, %s" + +#: src/npc.cpp +#, c-format +msgid "Right now, I'm . In general, %s" +msgstr "Š”ŠµŠ¹Ń‡Š°Ń я . Š’ Š¾ŃŠ½Š¾Š²Š½Š¾Š¼, %s" + #: src/npcmove.cpp msgid "" msgstr "" @@ -282372,6 +283603,15 @@ msgstr "" msgid "My %s is bleeding!" msgstr "%s: ŠøŠ“ёт ŠŗрŠ¾Š²ŃŒ!" +#: src/npcmove.cpp +#, c-format +msgid "My %s is bleeding badly!" +msgstr "Š£ Š¼ŠµŠ½Ń тут %s сŠøŠ»ŃŒŠ½Š¾ ŠŗрŠ¾Š²Š¾Ń‚Š¾Ń‡Šøт!" + +#: src/npcmove.cpp +msgid "I've lost lot of blood." +msgstr "Š£ Š¼ŠµŠ½Ń сŠøŠ»ŃŒŠ½Š°Ń ŠŗрŠ¾Š²Š¾ŠæŠ¾Ń‚ŠµŃ€Ń." + #: src/npcmove.cpp #, c-format msgid "%1$s reloads their %2$s." @@ -282625,11 +283865,6 @@ msgstr "Š’Ń‹ ŠŗрŠøчŠøтŠµ: %s" msgid "%s yelling %s" msgstr "%s ŠŗрŠøчŠøт: %s" -#: src/npctalk.cpp -#, c-format -msgid "%s is fleeing from you!" -msgstr "%s ŠøŠ·Š±ŠµŠ³Š°ŠµŃ‚ Š²Š°Ń!" - #: src/npctalk.cpp #, c-format msgid "%s talked to you." @@ -282688,39 +283923,6 @@ msgstr "Š˜Š·Š²ŠøŠ½Šø, Š½Š¾, суŠ“я ŠæŠ¾ Š²ŃŠµŠ¼Ńƒ, Š¼Š½Šµ Š½ŠµŃ‡ŠµŠ¼Ńƒ Š¾Š±Ńƒ msgid "Here's what I can teach youā€¦" msgstr "Š’Š¾Ń‚ чŠµŠ¼Ńƒ я Š¼Š¾Š³Ńƒ Š½Š°ŃƒŃ‡Šøть тŠµŠ±Ńā€¦" -#: src/npctalk.cpp -#, c-format -msgid "%d.%d miles." -msgstr "%d.%d Š¼ŠøŠ»ŃŒ." - -#: src/npctalk.cpp -#, c-format -msgid "%d foot." -msgid_plural "%d feet." -msgstr[0] "%d фут." -msgstr[1] "%d футŠ°." -msgstr[2] "%d футŠ¾Š²." -msgstr[3] "%d фут." - -#: src/npctalk.cpp -#, c-format -msgid "I'm holing up here for safety. Long term, %s" -msgstr "ŠÆ Š±ŃƒŠ“у Š·Š“ŠµŃŃŒ Š² Š±ŠµŠ·Š¾ŠæŠ°ŃŠ½Š¾ŃŃ‚Šø. Š”Š¾Š»Š³Š¾, %s" - -#: src/npctalk.cpp -msgid "I run the shop here." -msgstr "Š£ Š¼ŠµŠ½Ń Š·Š“ŠµŃŃŒ Š¼Š°Š³Š°Š·ŠøŠ½." - -#: src/npctalk.cpp -#, c-format -msgid "Currently, I'm guarding this location. Overall, %s" -msgstr "Š’ Š½Š°ŃŃ‚Š¾ŃŃ‰ŠµŠµ Š²Ń€ŠµŠ¼Ń я Š¾Ń…Ń€Š°Š½ŃŃŽ эту тŠµŃ€Ń€ŠøтŠ¾Ń€Šøю. Š’ цŠµŠ»Š¾Š¼, %s" - -#: src/npctalk.cpp -#, c-format -msgid "Right now, I'm . In general, %s" -msgstr "Š”ŠµŠ¹Ń‡Š°Ń я . Š’ Š¾ŃŠ½Š¾Š²Š½Š¾Š¼, %s" - #: src/npctalk.cpp msgid "&You yell, but can't hear yourself." msgstr "&Š’Ń‹ ŠŗрŠøчŠøтŠµ, Š½Š¾ Š½Šµ сŠ»Ń‹ŃˆŠøтŠµ сŠµŠ±Ń." @@ -282729,74 +283931,6 @@ msgstr "&Š’Ń‹ ŠŗрŠøчŠøтŠµ, Š½Š¾ Š½Šµ сŠ»Ń‹ŃˆŠøтŠµ сŠµŠ±Ń." msgid "&You yell." msgstr "&Š’Ń‹ ŠŗрŠøчŠøтŠµ." -#: src/npctalk.cpp -msgid "&You can't make anything out." -msgstr "&Š’Ń‹ Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ Š½ŠøчŠµŠ³Š¾ сŠ“ŠµŠ»Š°Ń‚ŃŒ." - -#: src/npctalk.cpp -#, c-format -msgid "Str %d - %d" -msgstr "Š”ŠøŠ» %d ā€” %d" - -#: src/npctalk.cpp -#, c-format -msgid " Dex %d - %d" -msgstr "Š›Š¾Š² %d ā€” %d" - -#: src/npctalk.cpp -#, c-format -msgid " Int %d - %d" -msgstr "Š˜Š½Ń‚ %d ā€” %d" - -#: src/npctalk.cpp -#, c-format -msgid " Per %d - %d" -msgstr "Š’Š¾Ń %d ā€” %d" - -#: src/npctalk.cpp -msgid "Dead tired" -msgstr "Š–ŃƒŃ‚ŠŗŠ°Ń устŠ°Š»Š¾ŃŃ‚ŃŒ" - -#: src/npctalk.cpp -msgid "Not tired" -msgstr "ŠŠµŃ‚ устŠ°Š»Š¾ŃŃ‚Šø" - -#: src/npctalk.cpp -msgid ". Will need sleep in " -msgstr ". ŠŸŠ¾Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ся сŠ¾Š½ чŠµŃ€ŠµŠ· " - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need water in " -msgstr "" -"\n" -"ŠŸŠ¾Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ся Š²Š¾Š“Š° чŠµŃ€ŠµŠ· " - -#: src/npctalk.cpp -msgid "" -"\n" -"Thirsty" -msgstr "" -"\n" -"Š•ŃŃ‚ŃŒ Š¶Š°Š¶Š“Š°" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need food in " -msgstr "" -"\n" -"ŠŸŠ¾Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠµŠ“Š° чŠµŃ€ŠµŠ· " - -#: src/npctalk.cpp -msgid "" -"\n" -"Hungry" -msgstr "" -"\n" -"Š•ŃŃ‚ŃŒ Š³Š¾Š»Š¾Š“" - #: src/npctalk.cpp msgid "YES, MASTER!" msgstr "Š”Š, Š„ŠžŠ—ŠÆŠ˜Š!" @@ -282810,34 +283944,6 @@ msgstr "Š£ Š¼ŠµŠ½Ń ŠµŃŃ‚ŃŒ Š½Š¾Š²Š¾ŃŃ‚Šø." msgid "Yes, let's resume training %s" msgstr "Š”Š°, Š“Š°Š²Š°Š¹ ŠæрŠ¾Š“Š¾Š»Š¶ŠøŠ¼ трŠµŠ½ŠøрŠ¾Š²Š°Ń‚ŃŒ %s" -#: src/npctalk.cpp -#, c-format -msgid "%s: 1 hour lesson (cost %s)" -msgstr "%s: 1 чŠ°ŃŠ¾Š²Š¾Š¹ урŠ¾Šŗ (стŠ¾ŠøŠ¼Š¾ŃŃ‚ŃŒ %s)" - -#: src/npctalk.cpp -#, c-format -msgid "%s: teaching spell knowledge (cost %s)" -msgstr "%s: цŠµŠ½Š° Š¾Š±ŃƒŃ‡ŠµŠ½Šøю Š·Š°ŠŗŠ»ŠøŠ½Š°Š½Šøя (стŠ¾Šøт %s)" - -#. ~Martial art style (cost in dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s ( cost $%d )" -msgstr "%s (цŠµŠ½Š° $%d)" - -#. ~Skill name: current level (exercise) -> next level (exercise) (cost in -#. dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" -msgstr "%s: %d (%d%%) -> %d (%d%%) (цŠµŠ½Š° $%d)" - -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%)" -msgstr "%s: %d (%d%%) -> %d (%d%%)" - #: src/npctalk.cpp msgid "Okay, thanks." msgstr "Š›Š°Š“Š½Š¾, сŠæŠ°ŃŠøŠ±Š¾." @@ -282850,10 +283956,6 @@ msgstr "Š”Š²ŠøŠ³Š°ŠµŠ¼ŃŃ Š“Š°Š»ŃŒŃˆŠµ." msgid "OBEY ME!" msgstr "ŠŸŠžŠ”Š§Š˜ŠŠÆŠ™Š”ŠÆ ŠœŠŠ•!" -#: src/npctalk.cpp src/player.cpp -msgid "fists" -msgstr "ŠŗуŠ»Š°ŠŗŠø" - #: src/npctalk.cpp msgid "BADAMMO" msgstr "BADAMMO" @@ -282925,7 +284027,7 @@ msgctxt "you say something" msgid "You: %s" msgstr "Š’Ń‹: %s" -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp msgid "You can't afford it!" msgstr "Š’Ń‹ Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ сŠµŠ±Šµ этŠ¾Š³Š¾ ŠæŠ¾Š·Š²Š¾Š»Šøть!" @@ -282936,7 +284038,7 @@ msgid "%1$s gives you a %2$s." msgstr "%1$s Š“Š°Ń‘Ń‚ Š²Š°Š¼: %2$s." #. ~ %1%s is the NPC name, %2$d is a number of items, %3$s are items -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp #, c-format msgid "%1$s gives you %2$d %3$s." msgstr "%1$s Š“Š°Ń‘Ń‚ Š²Š°Š¼: %2$d %3$s." @@ -282965,99 +284067,11 @@ msgstr "Š’Ń‹ Š“Š°Ń‘Ń‚Šµ NPC (%1$s): %2$d %3$s." msgid "%1$s doesn't have a %2$s!" msgstr "Š£ ŠæŠµŃ€ŃŠ¾Š½Š°Š¶Š° (%1$s) Š½ŠµŃ‚ этŠ¾Š³Š¾ (%2$s)!" -#: src/npctalk.cpp -#, c-format -msgid "%1$s gives you %2$s." -msgstr "%1$s Š“Š°Ń‘Ń‚ Š²Š°Š¼: %2$s." - #: src/npctalk.cpp #, c-format msgid "You learn how to craft %s." msgstr "Š’Ń‹ учŠøтŠµŃŃŒ, ŠŗŠ°Šŗ сŠ¾Š·Š“Š°Š²Š°Ń‚ŃŒ: %s." -#: src/npctalk.cpp -msgid "I don't trust you enough to eat THISā€¦" -msgstr "ŠÆ Š½Šµ Š²ŠµŃ€ŃŽ тŠµŠ±Šµ Š½Š°ŃŃ‚Š¾Š»ŃŒŠŗŠ¾, чтŠ¾Š±Ń‹, , ŠµŃŃ‚ŃŒ Š­Š¢Šžā€¦" - -#: src/npctalk.cpp -msgid "It doesn't look like a good idea to consume thisā€¦" -msgstr "ŠŠµ Š¾Ń‡ŠµŠ½ŃŒ хŠ¾Ń€Š¾ŃˆŠ°Ń ŠøŠ“ŠµŃ ā€” ŠµŃŃ‚ŃŒ этŠ¾ā€¦" - -#: src/npctalk.cpp -msgid "Thanks, that hit the spot." -msgstr "Š”ŠæŠ°ŃŠøŠ±Š¾, тŠ¾ чтŠ¾ Š½Š°Š“Š¾." - -#: src/npctalk.cpp -#, c-format -msgid "I need a %s to consume that!" -msgstr "ŠœŠ½Šµ Š½ŃƒŠ¶ŠµŠ½ ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ - %s, чтŠ¾Š±Ń‹ уŠæŠ¾Ń‚Ń€ŠµŠ±Šøть этŠ¾!" - -#: src/npctalk.cpp -msgid "Thanks, I feel better already." -msgstr "Š”ŠæŠ°ŃŠøŠ±Š¾, Š¼Š½Šµ уŠ¶Šµ стŠ°Š½Š¾Š²Šøтся Š»ŃƒŃ‡ŃˆŠµ." - -#: src/npctalk.cpp -msgid "Thanks, I used it." -msgstr "Š”ŠæŠ°ŃŠøŠ±Š¾, я ŠøсŠæŠ¾Š»ŃŒŠ·ŃƒŃŽ этŠ¾." - -#: src/npctalk.cpp -msgid "Offer what?" -msgstr "Š§Ń‚Š¾ ŠæрŠµŠ“Š»Š¾Š¶Šøть?" - -#: src/npctalk.cpp -msgid "You have no items to offer." -msgstr "Š’Š°Š¼ Š½ŠµŃ‡ŠµŠ³Š¾ ŠæрŠµŠ“Š»Š¾Š¶Šøть." - -#: src/npctalk.cpp -msgid "Changed your mind?" -msgstr "ŠŸŠµŃ€ŠµŠ“уŠ¼Š°Š»Šø?" - -#: src/npctalk.cpp -msgid "How?" -msgstr "ŠšŠ°Šŗ?" - -#: src/npctalk.cpp -msgid "Are you insane!?" -msgstr "Š¢Ń‹, , сŠ¾Š²ŃŠµŠ¼ Šŗу-Šŗу?!" - -#: src/npctalk.cpp -msgid "Thanks, I'll wield that now." -msgstr "Š”ŠæŠ°ŃŠøŠ±Š¾, я Š±ŃƒŠ“у ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ этŠ¾ Š² Š±Š¾ŃŽ." - -#: src/npctalk.cpp -msgid " Should I take something off?" -msgstr "ŠœŠ½Šµ Š½ŃƒŠ¶Š½Š¾ сŠ½ŃŃ‚ŃŒ чтŠ¾-тŠ¾?" - -#: src/npctalk.cpp -#, c-format -msgid "" -"My current weapon is better than this.\n" -"(new weapon value: %.1f vs %.1f)." -msgstr "" -"ŠœŠ¾Ń‘ тŠµŠŗущŠµŠµ Š¾Ń€ŃƒŠ¶ŠøŠµ Š»ŃƒŃ‡ŃˆŠµ, чŠµŠ¼ этŠ¾. \n" -"(ŠæŠ¾Š»ŠµŠ·Š½Š¾ŃŃ‚ŃŒ Š½Š¾Š²Š¾Š³Š¾ Š¾Ń€ŃƒŠ¶Šøя: %.1f ŠæрŠ¾Ń‚ŠøŠ² %.1f). " - -#: src/npctalk.cpp -msgid "Thanks, I'll carry that now." -msgstr "Š”ŠæŠ°ŃŠøŠ±Š¾, Š±ŃƒŠ“у ŠøŠ¼ŠµŃ‚ŃŒ этŠ¾ ŠæрŠø сŠµŠ±Šµ." - -#: src/npctalk.cpp -msgid "I have no space to store it." -msgstr "Š£ Š¼ŠµŠ½Ń Š½ŠµŃ‚Ńƒ Š¼ŠµŃŃ‚Š° Š“Š»Ń хрŠ°Š½ŠµŠ½Šøя." - -#: src/npctalk.cpp -#, c-format -msgid "I can only store %s %s more." -msgstr "ŠÆ Š¼Š¾Š³Ńƒ Š²Š·ŃŃ‚ŃŒ ŠµŃ‰Ń‘ тŠ¾Š»ŃŒŠŗŠ¾ %s %s." - -#: src/npctalk.cpp -msgid "ā€¦or to store anything else for that matter." -msgstr "ā€¦ ŠøŠ»Šø хрŠ°Š½Šøть чтŠ¾-Š½ŠøŠ±ŃƒŠ“ь ŠµŃ‰Ń‘, ŠµŃŠ»Šø Š½Š° тŠ¾ ŠæŠ¾ŃˆŠ»Š¾." - -#: src/npctalk.cpp -msgid "It is too heavy for me to carry." -msgstr "Š”Š»ŠøшŠŗŠ¾Š¼ тяŠ¶Ń‘Š»Š¾Šµ Š“Š»Ń Š¼ŠµŠ½Ń." - #: src/npctalk_funcs.cpp msgid "Reward" msgstr "ŠŠ°Š³Ń€Š°Š“Š°" @@ -284980,12 +285994,18 @@ msgid "A scaling factor that determines density of item spawns." msgstr "ŠœŠ½Š¾Š¶ŠøтŠµŠ»ŃŒ, Š¾ŠæрŠµŠ“ŠµŠ»ŃŃŽŃ‰ŠøŠ¹ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ Š³ŠµŠ½ŠµŃ€ŠøруŠµŠ¼Ń‹Ń… ŠæрŠµŠ“Š¼ŠµŃ‚Š¾Š²." #: src/options.cpp -msgid "NPC spawn rate scaling factor" -msgstr "ŠœŠ½Š¾Š¶ŠøтŠµŠ»ŃŒ Š³ŠµŠ½ŠµŃ€Š°Ń†ŠøŠø NPC" +msgid "Random NPC spawn time" +msgstr "Š’Ń€ŠµŠ¼Ń сŠæŠ°Š²Š½Š° сŠ»ŃƒŃ‡Š°Š¹Š½Ń‹Ń… NPC" #: src/options.cpp -msgid "A scaling factor that determines density of dynamic NPC spawns." -msgstr "ŠœŠ½Š¾Š¶ŠøтŠµŠ»ŃŒ, Š¾ŠæрŠµŠ“ŠµŠ»ŃŃŽŃ‰ŠøŠ¹ ŠŗŠ¾Š»ŠøчŠµŃŃ‚Š²Š¾ Š³ŠµŠ½ŠµŃ€ŠøруŠµŠ¼Ń‹Ń… Š“ŠøŠ½Š°Š¼ŠøчŠµŃŠŗŠøх NPC." +msgid "" +"Baseline average number of days between random NPC spawns. Average duration" +" goes up with the number of NPCs already spawned. Set to 0 days to disable " +"random NPCs." +msgstr "" +"Š‘Š°Š·Š¾Š²Š¾Šµ срŠµŠ“Š½ŠµŠµ Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ Š²Ń€ŠµŠ¼ŠµŠ½Šø Š² Š“Š½ŃŃ… Š¼ŠµŠ¶Š“у сŠæŠ°Š²Š½Š¾Š¼ сŠ»ŃƒŃ‡Š°Š¹Š½Ń‹Ń… NPC. Š”рŠµŠ“Š½ŠµŠµ" +" Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ рŠ°ŃŃ‚Ń‘Ń‚ Š²Š¼ŠµŃŃ‚Šµ с уŠ¶Šµ сŠ¾Š·Š“Š°Š½Š½Ń‹Š¼Šø NPC. Š£ŃŃ‚Š°Š½Š¾Š²ŠøтŠµ Š½Š° 0 Š“Š»Ń Š¾Ń‚ŠŗŠ»ŃŽŃ‡ŠµŠ½Šøя" +" сŠ»ŃƒŃ‡Š°Š¹Š½Ń‹Ń… NPC." #: src/options.cpp msgid "Monster evolution scaling factor" @@ -285130,43 +286150,6 @@ msgstr "" "Š•ŃŠ»Šø Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾, тŠ¾ Š·Š¾Š¼Š±Šø ŠæŠ¾ŃŠ²ŃŃ‚ся ŠæряŠ¼Š¾ Š² уŠ±ŠµŠ¶ŠøщŠµ, чтŠ¾ Š“ŠµŠ»Š°ŠµŃ‚ Š½Š°Ń‡Š°Š»Š¾ ŠøŠ³Ń€Ń‹ " "Š½Š°Š¼Š½Š¾Š³Š¾ сŠ»Š¾Š¶Š½ŠµŠµ." -#: src/options.cpp -msgid "Static NPCs" -msgstr "Š”тŠ°Ń‚ŠøчŠµŃŠŗŠøŠµ NPC" - -#: src/options.cpp -msgid "" -"If true, static NPCs will spawn at pre-defined locations. Requires world " -"reset." -msgstr "" -"Š•ŃŠ»Šø Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾, тŠ¾ стŠ°Ń‚ŠøчŠµŃŠŗŠøŠµ NPC сŠ¾Š·Š“Š°ŃŽŃ‚ся Š² ŠæрŠµŠ“Š¾ŠæрŠµŠ“ŠµŠ»Ń‘Š½Š½Ń‹Ń… Š»Š¾ŠŗŠ°Ń†Šøях. " -"Š¢Ń€ŠµŠ±ŃƒŠµŃ‚ ŠæŠµŃ€ŠµŠ·Š°Š³Ń€ŃƒŠ·ŠŗŠø Š¼ŠøрŠ°." - -#: src/options.cpp -msgid "Starting NPCs spawn" -msgstr "Š—Š°Ń€Š¾Š¶Š“ŠµŠ½ŠøŠµ стŠ°Ń€Ń‚Š¾Š²Ń‹Ń… NPC" - -#: src/options.cpp -msgid "" -"Determines whether starting NPCs should spawn, and if they do, how exactly." -msgstr "" -"ŠžŠæрŠµŠ“ŠµŠ»ŃŠµŃ‚, Š“Š¾Š»Š¶Š½Ń‹ Š»Šø Š·Š°Ń€Š¾Š¶Š“Š°Ń‚ŃŒŃŃ стŠ°Ń€Ń‚Š¾Š²Ń‹Šµ Š½ŠµŠøŠ³Ń€Š¾Š²Ń‹Šµ ŠæŠµŃ€ŃŠ¾Š½Š°Š¶Šø, Šø ŠµŃŠ»Šø Š“Š°, " -"тŠ¾ ŠŗŠ°ŠŗŠøŠ¼ ŠøŠ¼ŠµŠ½Š½Š¾ Š¾Š±Ń€Š°Š·Š¾Š¼." - -#: src/options.cpp -msgid "Scenario-based" -msgstr "ŠžŃŠ½Š¾Š²Š°Š½Š¾ Š½Š° сцŠµŠ½Š°Ń€ŠøŠø" - -#: src/options.cpp -msgid "Random NPCs" -msgstr "Š”Š»ŃƒŃ‡Š°Š¹Š½Ń‹Šµ NPC" - -#: src/options.cpp -msgid "If true, the game will randomly spawn NPCs during gameplay." -msgstr "" -"Š•ŃŠ»Šø Š²ŠŗŠ»ŃŽŃ‡ŠµŠ½Š¾, тŠ¾ NPC-ŠæŠµŃ€ŃŠ¾Š½Š°Š¶Šø ŠæŠ¾ŃŠ²Š»ŃŃŽŃ‚ся Š² сŠ»ŃƒŃ‡Š°Š¹Š½Š¾Š¼ ŠæŠ¾Ń€ŃŠ“ŠŗŠµ Š² тŠµŃ‡ŠµŠ½ŠøŠµ " -"ŠøŠ³Ń€Ń‹." - #: src/options.cpp msgid "Mutations by radiation" msgstr "ŠœŃƒŃ‚Š°Ń†ŠøŠø Š¾Ń‚ рŠ°Š“ŠøŠ°Ń†ŠøŠø" @@ -286942,6 +287925,46 @@ msgstr "Š’Ń‹ ŠæытŠ°ŠµŃ‚ŠµŃŃŒ ŠæŠ¾Ń‚ŃƒŃˆŠøть Š¾Š³Š¾Š½ŃŒ!" msgid " attempts to put out the fire on them!" msgstr " ŠæытŠ°ŠµŃ‚ся ŠæŠ¾Ń‚ŃƒŃˆŠøть Š¾Š³Š¾Š½ŃŒ!" +#: src/player.cpp +msgid "" +"Your broken limb significantly hampers your efforts to puting pressure on " +"the bleeding wound!" +msgstr "" +"Š’Š°ŃˆŠ° сŠ»Š¾Š¼Š°Š½Š½Š°Ń ŠŗŠ¾Š½ŠµŃ‡Š½Š¾ŃŃ‚ŃŒ сŠøŠ»ŃŒŠ½Š¾ Š¼ŠµŃˆŠ°ŠµŃ‚ ŠæŠ¾ŠæытŠŗŠ°Š¼ ŠæрŠøŠ¼ŠµŠ½Šøть Š“Š°Š²Š»ŠµŠ½ŠøŠµ Šŗ " +"ŠŗрŠ¾Š²Š¾Ń‚Š¾Ń‡Š°Ń‰ŠµŠ¹ рŠ°Š½Šµ!" + +#: src/player.cpp +msgid "" +"'s broken limb significantly hampers efforts of putting pressure on" +" the bleeding wound!" +msgstr "" +"Š”Š»Š¾Š¼Š°Š½Š½Š°Ń ŠŗŠ¾Š½ŠµŃ‡Š½Š¾ŃŃ‚ŃŒ NPC () сŠøŠ»ŃŒŠ½Š¾ Š¼ŠµŃˆŠ°ŠµŃ‚ ŠæŠ¾ŠæытŠŗŠ°Š¼ ŠæрŠøŠ¼ŠµŠ½Šøть " +"Š“Š°Š²Š»ŠµŠ½ŠøŠµ Šŗ ŠŗрŠ¾Š²Š¾Ń‚Š¾Ń‡Š°Ń‰ŠµŠ¹ рŠ°Š½Šµ!" + +#: src/player.cpp +msgid "" +"Your hands are too encumbred to effectivly put pressure on the bleeding " +"wound!" +msgstr "" +"Š’Š°ŃˆŠø руŠŗŠø сŠ»ŠøшŠŗŠ¾Š¼ сŠŗŠ¾Š²Š°Š½Š½Ń‹, чтŠ¾Š±Ń‹ эффŠµŠŗтŠøŠ²Š½Š¾ ŠæрŠøŠ¼ŠµŠ½Šøть Š“Š°Š²Š»ŠµŠ½ŠøŠµ Šŗ " +"ŠŗрŠ¾Š²Š¾Ń‚Š¾Ń‡Š°Ń‰ŠµŠ¹ рŠ°Š½Šµ!" + +#: src/player.cpp +msgid "" +"'s hands are too encumbred to effectivly put pressure on the " +"bleeding wound!" +msgstr "" +"Š ŃƒŠŗŠø NPC () сŠ»ŠøшŠŗŠ¾Š¼ сŠŗŠ¾Š²Š°Š½Š½Ń‹, чтŠ¾Š±Ń‹ эффŠµŠŗтŠøŠ²Š½Š¾ ŠæрŠøŠ¼ŠµŠ½Šøть Š“Š°Š²Š»ŠµŠ½ŠøŠµ Šŗ" +" ŠŗрŠ¾Š²Š¾Ń‚Š¾Ń‡Š°Ń‰ŠµŠ¹ рŠ°Š½Šµ!" + +#: src/player.cpp +msgid "You attempt to put pressure on the bleeding wound!" +msgstr "Š’Ń‹ ŠæытŠ°ŠµŃ‚ŠµŃŃŒ ŠæрŠøŠ¼ŠµŠ½Šøть Š“Š°Š²Š»ŠµŠ½ŠøŠµ Šŗ ŠŗрŠ¾Š²Š¾Ń‚Š¾Ń‡Š°Ń‰ŠµŠ¹ рŠ°Š½Šµ!" + +#: src/player.cpp +msgid " attempts to put pressure on the bleeding wound!" +msgstr " ŠæытŠ°ŠµŃ‚ся ŠæрŠøŠ¼ŠµŠ½Šøть Š“Š°Š²Š»ŠµŠ½ŠøŠµ Šŗ ŠŗрŠ¾Š²Š¾Ń‚Š¾Ń‡Š°Ń‰ŠµŠ¹ рŠ°Š½Šµ!" + #: src/player.cpp #, c-format msgid "Your ground sonar detected a %1$s to the %2$s!" @@ -287217,33 +288240,6 @@ msgstr "ŠŠµŃ‡ŠµŠ³Š¾ ŠæŠµŃ€ŠµŠ·Š°Ń€ŃŠ¶Š°Ń‚ŃŒ!" msgid "You don't have any %s to reload your %s!" msgstr "Š£ Š²Š°Ń Š½ŠµŃ‚ Š·Š°Ń€ŃŠ“Š¾Š² (%s), чтŠ¾Š±Ń‹ ŠæŠµŃ€ŠµŠ·Š°Ń€ŃŠ“Šøть Š¾Ń€ŃƒŠ¶ŠøŠµ (%s)!" -#: src/player.cpp -msgid "Can't wield spilt liquids." -msgstr "ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ Š²Š·ŃŃ‚ŃŒ Š² руŠŗŠø ŠæрŠ¾Š»ŠøтыŠµ Š¶ŠøŠ“ŠŗŠ¾ŃŃ‚Šø." - -#: src/player.cpp -msgid "You need at least one arm to even consider wielding something." -msgstr "Š§Ń‚Š¾Š±Ń‹ чтŠ¾-Š½ŠøŠ±ŃƒŠ“ь Š²Š·ŃŃ‚ŃŒ, Š²Š°Š¼ Š½ŠµŠ¾Š±Ń…Š¾Š“ŠøŠ¼Š° хŠ¾Ń‚я Š±Ń‹ Š¾Š“Š½Š° руŠŗŠ°." - -#: src/player.cpp -#, c-format -msgid "The %s is preventing you from wielding the %s." -msgstr "%s Š½Šµ Š“Š°ŠµŃ‚ Š²Š°Š¼ Š²Š·ŃŃ‚ŃŒ Š² руŠŗŠø ŠæрŠµŠ“Š¼ŠµŃ‚ (%s)." - -#: src/player.cpp -msgid "Something you are wearing hinders the use of both hands." -msgstr "Š§Ń‚Š¾-тŠ¾, чтŠ¾ Š½Š°Š“ŠµŃ‚Š¾ Š½Š° Š²Š°Ń, Š¼ŠµŃˆŠ°ŠµŃ‚ ŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒŃŃ Š¾Š±ŠµŠøŠ¼Šø руŠŗŠ°Š¼Šø." - -#: src/player.cpp -#, c-format -msgid "The %s can't be wielded with only one arm." -msgstr "Š­Ń‚Š¾ (%s) Š½ŠµŠ»ŃŒŠ·Ń Š“ŠµŃ€Š¶Š°Ń‚ŃŒ тŠ¾Š»ŃŒŠŗŠ¾ Š¾Š“Š½Š¾Š¹ руŠŗŠ¾Š¹." - -#: src/player.cpp -#, c-format -msgid "You are too weak to wield %s with only one arm." -msgstr "Š’Ń‹ сŠ»ŠøшŠŗŠ¾Š¼ сŠ»Š°Š±Ń‹, чтŠ¾Š±Ń‹ Š“ŠµŃ€Š¶Š°Ń‚ŃŒ этŠ¾ (%s) Š¾Š“Š½Š¾Š¹ руŠŗŠ¾Š¹." - #: src/player.cpp msgid "Keep hands free (off)" msgstr "Š”ŠµŃ€Š¶Š°Ń‚ŃŒ руŠŗŠø сŠ²Š¾Š±Š¾Š“Š½Ń‹Š¼Šø (Š²Ń‹ŠŗŠ»)" @@ -287431,15 +288427,6 @@ msgstr "ŠŸŃ€ŠµŠ“Š¼ŠµŃ‚ (%s) Š½Šµ Š·Š°Ń€ŃŠ¶ŠµŠ½." msgid "Your %s isn't loaded." msgstr "ŠŸŃ€ŠµŠ“Š¼ŠµŃ‚ (%s) Š½Šµ Š·Š°Ń€ŃŠ¶ŠµŠ½." -#: src/player.cpp -#, c-format -msgid "You recover %i unused plutonium." -msgstr "Š’Ń‹ ŠæŠ¾Š»ŃƒŃ‡Š°ŠµŃ‚Šµ %i Š½ŠµŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Š½Š½Š¾Š³Š¾ ŠæŠ»ŃƒŃ‚Š¾Š½Šøя." - -#: src/player.cpp -msgid "You can't remove partially depleted plutonium!" -msgstr "Š’Ń‹ Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ уŠ±Ń€Š°Ń‚ŃŒ чŠ°ŃŃ‚ŠøчŠ½Š¾ Š¾Š±ŠµŠ“Š½Ń‘Š½Š½Ń‹Š¹ урŠ°Š½!" - #. ~ %1$s - gunmod, %2$s - gun. #: src/player.cpp #, c-format @@ -287581,26 +288568,6 @@ msgstr "Š’ стŠøŠ¼ŃƒŠ»ŃŃ‚Š¾Ń€Šµ сŠ½Š° Š·Š°ŠŗŠ¾Š½Ń‡ŠøŠ»Š°ŃŃŒ эŠ½ŠµŃ€Š³Šøя!" msgid "Your soporific inducer starts back up." msgstr "Š”тŠøŠ¼ŃƒŠ»ŃŃ‚Š¾Ń€ сŠ½Š° Š½Š°Ń‡Š°Š» рŠ°Š±Š¾Ń‚Š°Ń‚ŃŒ." -#: src/player.cpp -#, c-format -msgid "Your skill in %s has increased to %d!" -msgstr "Š’Š°Ńˆ Š½Š°Š²Ń‹Šŗ %s уŠ²ŠµŠ»ŠøчŠøŠ»ŃŃ Š“Š¾ %d!" - -#: src/player.cpp -#, c-format -msgid "You feel that %s tasks of this level are becoming trivial." -msgstr "" -"Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ, чтŠ¾ Š·Š°Š“Š°Ń‡Š° стŠ°Š»Š° сŠ»ŠøшŠŗŠ¾Š¼ ŠæрŠ¾ŃŃ‚Š¾Š¹ Š“Š»Ń трŠµŠ½ŠøрŠ¾Š²ŠŗŠø Š½Š°Š²Ń‹ŠŗŠ° (%s)." - -#: src/player.cpp -#, c-format -msgid "This task is too simple to train your %s beyond %d." -msgstr "Š­Ń‚Š° Š·Š°Š“Š°Ń‡Š° сŠ»ŠøшŠŗŠ¾Š¼ ŠæрŠ¾ŃŃ‚Š° Š“Š»Ń трŠµŠ½ŠøрŠ¾Š²ŠŗŠø Š½Š°Š²Ń‹ŠŗŠ° (%s) Š²Ń‹ŃˆŠµ %d урŠ¾Š²Š½Ń." - -#: src/player.cpp -msgid " (empty)" -msgstr "(ŠæустŠ¾)" - #: src/player.cpp msgid "Wield what?" msgstr "Š§Ń‚Š¾ Š²Š·ŃŃ‚ŃŒ Š² руŠŗŠø?" @@ -287656,6 +288623,10 @@ msgstr "Š­Š¤Š¤Š•ŠšŠ¢Š«" msgid "SPEED" msgstr "Š”ŠšŠžŠ ŠžŠ”Š¢Š¬" +#: src/player_display.cpp +msgid "PROFICIENCIES" +msgstr "Š£ŠœŠ•ŠŠ˜ŠÆ" + #: src/player_display.cpp #, c-format msgid "Swimming movement point cost: %+d\n" @@ -288534,6 +289505,160 @@ msgstr "" "Š’Ń‹ рŠ°ŃŃ‚Š²Š¾Ń€ŃŠµŃ‚ŠµŃŃŒ Š² ŠæрŠµŠŗрŠ°ŃŠ½Ń‹Ń… Š²ŃŠæышŠŗŠ°Ń… эŠ½ŠµŃ€Š³ŠøŠø. Š–ŠøŠ·Š½ŃŒ ŠæŠ¾ŠŗŠøŠ“Š°ŠµŃ‚ Š²Š°ŃˆŠµ тŠµŠ»Š¾, Šø " "Š²Š°Ń Š±Š¾Š»ŃŒŃˆŠµ Š½ŠµŃ‚." +#: src/player_hardcoded_effects.cpp +msgid "You bleed to death!" +msgstr "Š’Ń‹ ŠøстŠµŠŗŠ»Šø ŠŗрŠ¾Š²ŃŒŃŽ Š“Š¾ сŠ¼ŠµŃ€Ń‚Šø!" + +#: src/player_hardcoded_effects.cpp +msgid " bleeds to death!" +msgstr " ŠøстŠµŠŗŠ°ŠµŃ‚ ŠŗрŠ¾Š²ŃŒŃŽ Š“Š¾ сŠ¼ŠµŃ€Ń‚Šø!" + +#: src/player_hardcoded_effects.cpp +msgid "Your heart can't keep up the pace and fails!" +msgstr "Š’Š°ŃˆŠµ сŠµŃ€Š“цŠµ Š½Šµ Š²Ń‹Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ рŠøтŠ¼ Šø Š¾ŃŃ‚Š°Š½Š°Š²Š»ŠøŠ²ŠµŃ‚ся!" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks pale and you feel anxious and thirsty. Blood loss?" +msgstr "Š’Š°ŃˆŠ° ŠŗŠ¾Š¶Š° ŠæŠ¾Š±Š»ŠµŠ“Š½ŠµŠ»Š°, Š²Ń‹ Š¾Ń‰ŃƒŃ‰Š°ŠµŃ‚Šµ Š±ŠµŃŠæŠ¾ŠŗŠ¾Š¹ŃŃ‚Š²Š¾ Šø Š¶Š°Š¶Š“у. ŠšŃ€Š¾Š²Š¾Ń‚ŠµŃ‡ŠµŠ½ŠøŠµ?" + +#: src/player_hardcoded_effects.cpp +msgid "" +"Your pale skin is sweating, your heart beats fast and you feel restless. " +"Maybe you lost too much blood?" +msgstr "" +"Š’Š°ŃˆŠ° Š±Š»ŠµŠ“Š½Š°Ń ŠŗŠ¾Š¶Š° ŠæŠ¾Ń‚ŠµŠµŃ‚, Š²Š°ŃˆŠµ сŠµŃ€Š“цŠµ Š±Ń‹ŃŃ‚Ń€Š¾ Š±ŃŒŠµŃ‚ся , Šø Š²Ń‹ Š¾Ń‰ŃƒŃ‰Š°ŠµŃ‚Šµ " +"Š±ŠµŃŠæŠ¾ŠŗŠ¾Š¹ŃŃ‚Š²Š¾. ŠœŠ¾Š¶ŠµŃ‚ Š±Ń‹Ń‚ŃŒ, Š²Ń‹ ŠæŠ¾Ń‚ŠµŃ€ŃŠ»Šø сŠ»ŠøшŠŗŠ¾Š¼ Š¼Š½Š¾Š³Š¾ ŠŗрŠ¾Š²Šø?" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You're unsettlingly white, but your fingetips are bluish. You are agitated " +"and your heart is racing. Your blood loss must be serious." +msgstr "" +"Š’Ń‹ Š²Ń‹Š³Š»ŃŠ“ŠøтŠµ ŠæуŠ³Š°ŃŽŃ‰Šµ Š±Š»ŠµŠ“Š½Š¾, Š½Š¾ ŠŗŠ¾Š½Ń‡ŠøŠŗŠø Š²Š°ŃˆŠøх ŠæŠ°Š»ŃŒŃ†ŠµŠ² ŠæŠ¾ŃŠøŠ½ŠµŠ»Šø. Š’Ń‹ " +"ŠøсŠæытыŠ²Š°ŠµŃ‚Šµ Š±ŠµŃŠæŠ¾ŠŗŠ¾Š¹ŃŃ‚Š²Š¾, Šø Š²Š°ŃˆŠµ сŠµŃ€Š“цŠµ ŠŗŠ¾Š»Š¾Ń‚Šøтся. ŠŸŠ¾Ń…Š¾Š¶Šµ, у Š²Š°Ń сŠµŃ€ŃŒŃ‘Š·Š½Š°Ń " +"ŠŗрŠ¾Š²Š¾ŠæŠ¾Ń‚ŠµŃ€Ń." + +#: src/player_hardcoded_effects.cpp +msgid "" +"You are pale as a ghost, dripping wet from the sweat, and sluggish despite " +"your heart racing like a train. You are on a brink of colapse from effects " +"of a bood loss." +msgstr "" +"Š’Ń‹ Š±Š»ŠµŠ“Š½Ń‹ ŠŗŠ°Šŗ ŠæрŠøŠ·Ń€Š°Šŗ, с Š²Š°Ń Š»ŃŒŃ‘Ń‚ŃŃ ŠæŠ¾Ń‚, Šø Š²Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ Š²ŃŠ»Š¾ŃŃ‚ŃŒ, Š½ŠµŃŠ¼Š¾Ń‚Ń€Ń " +"Š½Š° тŠ¾, чтŠ¾ Š²Š°ŃˆŠµ сŠµŃ€Š“цŠµ рŠµŠ²Ń‘Ń‚ ŠŗŠ°Šŗ ŠæŠ¾ŠµŠ·Š“. Š’Ń‹ Š½Š° Š³Ń€Š°Š½Šø ŠæŠ¾Ń‚ŠµŃ€Šø сŠ¾Š·Š½Š°Š½Šøя ŠøŠ·-Š·Š° " +"ŠŗрŠ¾Š²Š¾ŠæŠ¾Ń‚ŠµŃ€Šø." + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and lightheaded." +msgstr "Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ Š³Š¾Š»Š¾Š²Š¾ŠŗруŠ¶ŠµŠ½ŠøŠµ Šø ŠæустŠ¾Ń‚Ńƒ Š² Š³Š¾Š»Š¾Š²Šµ." + +#: src/player_hardcoded_effects.cpp +msgid "You feel tired and you breathe heavily." +msgstr "Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ устŠ°Š»Š¾ŃŃ‚ŃŒ Šø тяŠ¶ŠµŠ»Š¾ Š“ышŠøтŠµ." + +#: src/player_hardcoded_effects.cpp +msgid "You are anxcious and cannot collect your thoughts." +msgstr "Š’Ń‹ Š²Š¾Š»Š½ŃƒŠµŃ‚ŠµŃŃŒ Šø Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ сŠ¾Š±Ń€Š°Ń‚ŃŒŃŃ с Š¼Ń‹ŃŠ»ŃŠ¼Šø." + +#: src/player_hardcoded_effects.cpp +msgid "You are sweating profusely, but you feel cold." +msgstr "Š’Ń‹ сŠøŠ»ŃŒŠ½Š¾ ŠæŠ¾Ń‚ŠµŠµŃ‚Šµ, Š½Š¾ Š²Š°Š¼ хŠ¾Š»Š¾Š“Š½Š¾." + +#: src/player_hardcoded_effects.cpp +msgid "You huff and puff. Your breath is rapid and shallow." +msgstr "Š’Ń‹ ŠæыхтŠøтŠµ Šø хрŠøŠæŠøтŠµ. Š£ Š²Š°Ń Š±Ń‹ŃŃ‚Ń€Š¾Šµ Šø Š½ŠµŠ³Š»ŃƒŠ±Š¾ŠŗŠ¾Šµ Š“ыхŠ°Š½ŠøŠµ." + +#: src/player_hardcoded_effects.cpp +msgid "You drop to the ground, fighting to keep yourself conscious." +msgstr "Š’Ń‹ ŠæŠ°Š“Š°ŠµŃ‚Šµ, с труŠ“Š¾Š¼ сŠ¾Ń…Ń€Š°Š½ŃŃ сŠ¾Š·Š½Š°Š½ŠøŠµ." + +#: src/player_hardcoded_effects.cpp +msgid "Your mind slips away." +msgstr "Š’Š°Ńˆ рŠ°Š·ŃƒŠ¼ усŠŗŠ¾Š»ŃŒŠ·Š°ŠµŃ‚." + +#: src/player_hardcoded_effects.cpp +msgid "You cannot breathe and your body gives out!" +msgstr "Š’Ń‹ Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ Š“ышŠ°Ń‚ŃŒ, Šø Š²Š°ŃˆŠµ тŠµŠ»Š¾ сŠ“Š°Ń‘Ń‚ŃŃ!" + +#: src/player_hardcoded_effects.cpp +msgid " gasps for air and dies!" +msgstr " хŠ²Š°Ń‚Š°ŠµŃ‚ Š²Š¾Š·Š“ух ртŠ¾Š¼ Šø уŠ¼ŠøрŠ°ŠµŃ‚!" + +#: src/player_hardcoded_effects.cpp +msgid "Your hands feel unusually cold." +msgstr "Š’Š°ŃˆŠøŠ¼ Š»Š°Š“Š¾Š½ŃŠ¼ Š½ŠµŠ¾Š¾Š±Ń‹Ń‡Š½Š¾ хŠ¾Š»Š¾Š“Š½Š¾." + +#: src/player_hardcoded_effects.cpp +msgid "Your feet feel unusualy cold." +msgstr "Š’Š°ŃˆŠøŠ¼ стуŠæŠ½ŃŠ¼ Š½ŠµŠ¾Š±Ń‹Ń‡Š½Š¾ хŠ¾Š»Š¾Š“Š½Š¾." + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks very pale." +msgstr "Š’Š°ŃˆŠ° ŠŗŠ¾Š¶Š° Š²Ń‹Š³Š»ŃŠ“Šøт Š¾Ń‡ŠµŠ½ŃŒ Š±Š»ŠµŠ“Š½Š¾." + +#: src/player_hardcoded_effects.cpp +msgid "You feel weak. Where has your strength gone?" +msgstr "Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ сŠ»Š°Š±Š¾ŃŃ‚ŃŒ. ŠšŃƒŠ“Š° ŠæŠ¾Š“ŠµŠ²Š°Š»Š°ŃŃŒ Š²Š°ŃˆŠ° сŠøŠ»Š°?" + +#: src/player_hardcoded_effects.cpp +msgid "You feel feeble. A gust of wind could make you stumble." +msgstr "" +"Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ ŠŗрŠ°Š¹Š½ŃŽŃŽ сŠ»Š°Š±Š¾ŃŃ‚ŃŒ. Š”ŃƒŠ½Š¾Š²ŠµŠ½ŠøŠµ Š²ŠµŃ‚Ń€Š° Š¼Š¾Š¶ŠµŃ‚ сŠ±Šøть Š²Š°Ń с Š½Š¾Š³.." + +#: src/player_hardcoded_effects.cpp +msgid "There is an overwhelming aura of tiredness inside of you." +msgstr "Š’Š½ŃƒŃ‚Ń€Šø Š²Š°Ń Š²ŃŠµŠæŠ¾Š³Š»Š¾Ń‰Š°ŃŽŃ‰Š°Ń Š°ŃƒŃ€Š° устŠ°Š»Š¾ŃŃ‚Šø." + +#: src/player_hardcoded_effects.cpp +msgid "Rest is what you want. Rest is what you need." +msgstr "ŠžŃ‚Š“Š¾Ń…Š½ŃƒŃ‚ŃŒ - Š²Š¾Ń‚ чŠµŠ³Š¾ Š²Ń‹ хŠ¾Ń‚ŠøтŠµ, чтŠ¾ Š²Š°Š¼ Š½ŃƒŠ¶Š½Š¾." + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and can't coordinate movement of your feet." +msgstr "Š’Ń‹ Š¾Ń‰ŃƒŃ‰Š°ŠµŃ‚Šµ Š³Š¾Š»Š¾Š²Š¾ŠŗруŠ¶ŠµŠ½ŠøŠµ Šø ŠæутŠ°ŠµŃ‚ŠµŃŃŒ Š² сŠ¾Š±ŃŃ‚Š²ŠµŠ½Š½Ń‹Ń… Š½Š¾Š³Š°Ń…." + +#: src/player_hardcoded_effects.cpp +msgid "Your muscles are quivering." +msgstr "Š’Š°ŃˆŠø Š¼Ń‹ŃˆŃ†Ń‹ Š“рŠ¾Š¶Š°Ń‚." + +#: src/player_hardcoded_effects.cpp +msgid "You crave for ice. Dirt under your feet looks tasty too." +msgstr "" +"Š’Ń‹ Š¼ŠµŃ‡Ń‚Š°ŠµŃ‚Šµ Š¾ ŠŗусŠ¾Ń‡ŠŗŠµ Š»ŃŒŠ“Š°. Š“Ń€ŃŠ·ŃŒ ŠæŠ¾Š“ Š²Š°ŃˆŠøŠ¼Šø Š½Š¾Š³Š°Š¼Šø тŠ¾Š¶Šµ Š²Ń‹Š³Š»ŃŠ“Šøт Š°ŠæŠæŠµŃ‚ŠøтŠ½Š¾." + +#: src/player_hardcoded_effects.cpp +msgid "Your whole mouth is sore, and your tongue is swollen." +msgstr "Š’ŠµŃŃŒ Š²Š°Ńˆ рŠ¾Ń‚ Š±Š¾Š»Šøт, Š° яŠ·Ń‹Šŗ рŠ°ŃŠæух." + +#: src/player_hardcoded_effects.cpp +msgid "You feel lightheaded. And a migrane follows." +msgstr "Š£ Š²Š°Ń ŠŗруŠ¶Šøтся Š³Š¾Š»Š¾Š²Š°. Š—Š°Ń‚ŠµŠ¼ Š½Š°Ń‡ŠøŠ½Š°ŠµŃ‚ся Š¼ŠøŠ³Ń€ŠµŠ½ŃŒ." + +#: src/player_hardcoded_effects.cpp +msgid "Your legs are restless. Urge to move them is so strong." +msgstr "" +"Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ Š±ŠµŃŠæŠ¾ŠŗŠ¾Š¹ŃŃ‚Š²Š¾ Š² Š½Š¾Š³Š°Ń…. Š£ Š²Š°Ń сŠøŠ»ŃŒŠ½Š¾Šµ Š¶ŠµŠ»Š°Š½ŠøŠµ шŠµŠ²ŠµŠ»Šøть ŠøŠ¼Šøю" + +#: src/player_hardcoded_effects.cpp +msgid "You feel like you'd sleep on a rock." +msgstr "Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ сŠµŠ±Ń тŠ°Šŗ, сŠ»Š¾Š²Š½Š¾ сŠæŠ°Š»Šø Š½Š° ŠŗŠ°Š¼Š½Šµ." + +#: src/player_hardcoded_effects.cpp +msgid "You gasp for air!" +msgstr "Š’Ń‹ хŠ²Š°Ń‚Š°ŠµŃ‚Šµ Š²Š¾Š·Š“ух ртŠ¾Š¼!" + +#: src/player_hardcoded_effects.cpp +msgid "Can't breathe. Must rest." +msgstr "ŠŠµ ŠæŠ¾Š»ŃƒŃ‡Š°ŠµŃ‚ся Š“ышŠ°Ń‚ŃŒ. ŠŃƒŠ¶Š½Š¾ Š¾Ń‚Š“Š¾Ń…Š½ŃƒŃ‚ŃŒ." + +#: src/player_hardcoded_effects.cpp +msgid "You can't take it any more. Rest first, everything else later." +msgstr "Š’Ń‹ Š±Š¾Š»ŃŒŃˆŠµ Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ Š“ŠµŃ€Š¶Š°Ń‚ŃŒŃŃ. Š”Š½Š°Ń‡Š°Š»Š° Š¾Ń‚Š“ых, ŠæŠ¾Ń‚Š¾Š¼ Š²ŃŃ‘ Š¾ŃŃ‚Š°Š»ŃŒŠ½Š¾Šµ." + +#: src/player_hardcoded_effects.cpp +msgid "You must sit down for a moment. Just a moment." +msgstr "Š’Š°Š¼ Š½ŃƒŠ¶Š½Š¾ ŠæрŠøсŠµŃŃ‚ŃŒ Š½Š° сŠµŠŗуŠ½Š“у. Š’сŠµŠ³Š¾ Š½Š° сŠµŠŗуŠ½Š“у." + #. ~ %s is bodypart name. #: src/player_hardcoded_effects.cpp #, c-format @@ -289151,6 +290276,11 @@ msgstr "%s, Š·Š°Š“ŠµŃ€Š¶ŠŗŠ°: %i" msgid "Turrets in range: %d/%d" msgstr "Š¢ŃƒŃ€ŠµŠ»Šø Š² ŠæрŠµŠ“ŠµŠ»Š°Ń… Š“Š¾ŃŃŠ³Š°ŠµŠ¼Š¾ŃŃ‚Šø: %d/%d" +#: src/recipe.cpp +#, c-format +msgid "Proficiencies Used: %s" +msgstr "Š¢Ń€ŠµŠ±ŃƒŠµŠ¼Ń‹Šµ уŠ¼ŠµŠ½Šøя: %s" + #: src/recipe.cpp msgid "none" msgstr "Š½ŠµŃ‚" @@ -289965,6 +291095,14 @@ msgstr " ŠæŠ°Š“Š°ŠµŃ‚!" msgid "You fall over!" msgstr "Š’Ń‹ ŠæŠ°Š“Š°ŠµŃ‚Šµ!" +#: src/suffer.cpp +msgid "Your tourniquet hurts you." +msgstr "Š’Š°Ńˆ Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Ń‹Š¹ турŠ½ŠøŠŗŠµŃ‚ ŠæрŠøчŠøŠ½ŃŠµŃ‚ Š²Š°Š¼ урŠ¾Š½." + +#: src/suffer.cpp +msgid " is hurting from the tourniquet." +msgstr " чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚ урŠ¾Š½ ŠøŠ·-Š·Š° Š°Ń€Ń‚ŠµŃ€ŠøŠ°Š»ŃŒŠ½Š¾Š³Š¾ турŠ½ŠøŠŗŠµŃ‚Š°." + #: src/suffer.cpp #, c-format msgid "Your radiation badge changes from %1$s to %2$s!" @@ -289984,6 +291122,213 @@ msgstr "Š’Š¾Š“Š° сŠ¼Ń‹Š²Š°ŠµŃ‚ Š·Š°ŠæŠ°Ń…." msgid "You feel the water burning your skin." msgstr "Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ, ŠŗŠ°Šŗ Š²Š¾Š“Š° Š¶Š¶Ń‘Ń‚ Š²Š°ŃˆŃƒ ŠŗŠ¾Š¶Ńƒ." +#: src/talker_avatar.cpp +#, c-format +msgid "%s can't sell you any %s" +msgstr "%s Š½Šµ Š¼Š¾Š¶ŠµŃ‚ ŠæрŠ¾Š“Š°Ń‚ŃŒ Š²Š°Š¼: %s" + +#: src/talker_avatar.cpp +#, c-format +msgid "%1$s gives you %2$s." +msgstr "%1$s Š“Š°Ń‘Ń‚ Š²Š°Š¼: %2$s." + +#: src/talker_npc.cpp +#, c-format +msgid "%d.%d miles." +msgstr "%d.%d Š¼ŠøŠ»ŃŒ." + +#: src/talker_npc.cpp +#, c-format +msgid "%d foot." +msgid_plural "%d feet." +msgstr[0] "%d фут." +msgstr[1] "%d футŠ°." +msgstr[2] "%d футŠ¾Š²." +msgstr[3] "%d фут." + +#: src/talker_npc.cpp +#, c-format +msgid "%s is fleeing from you!" +msgstr "%s ŠøŠ·Š±ŠµŠ³Š°ŠµŃ‚ Š²Š°Ń!" + +#. ~Skill name: current level (exercise) -> next level (exercise) (cost in +#. dollars) +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" +msgstr "%s: %d (%d%%) -> %d (%d%%) (цŠµŠ½Š° $%d)" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%)" +msgstr "%s: %d (%d%%) -> %d (%d%%)" + +#: src/talker_npc.cpp +#, c-format +msgid "%s ( cost $%d )" +msgstr "%s (цŠµŠ½Š° $%d)" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: 1 hour lesson (cost %s)" +msgstr "%s: 1 чŠ°ŃŠ¾Š²Š¾Š¹ урŠ¾Šŗ (стŠ¾ŠøŠ¼Š¾ŃŃ‚ŃŒ %s)" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: teaching spell knowledge (cost %s)" +msgstr "%s: цŠµŠ½Š° Š¾Š±ŃƒŃ‡ŠµŠ½Šøю Š·Š°ŠŗŠ»ŠøŠ½Š°Š½Šøя (стŠ¾Šøт %s)" + +#: src/talker_npc.cpp +msgid "I don't trust you enough to eat THISā€¦" +msgstr "ŠÆ Š½Šµ Š²ŠµŃ€ŃŽ тŠµŠ±Šµ Š½Š°ŃŃ‚Š¾Š»ŃŒŠŗŠ¾, чтŠ¾Š±Ń‹, , ŠµŃŃ‚ŃŒ Š­Š¢Šžā€¦" + +#: src/talker_npc.cpp +msgid "It doesn't look like a good idea to consume thisā€¦" +msgstr "ŠŠµ Š¾Ń‡ŠµŠ½ŃŒ хŠ¾Ń€Š¾ŃˆŠ°Ń ŠøŠ“ŠµŃ ā€” ŠµŃŃ‚ŃŒ этŠ¾ā€¦" + +#: src/talker_npc.cpp +msgid "Thanks, that hit the spot." +msgstr "Š”ŠæŠ°ŃŠøŠ±Š¾, тŠ¾ чтŠ¾ Š½Š°Š“Š¾." + +#: src/talker_npc.cpp +#, c-format +msgid "I need a %s to consume that!" +msgstr "ŠœŠ½Šµ Š½ŃƒŠ¶ŠµŠ½ ŠøŠ½ŃŃ‚Ń€ŃƒŠ¼ŠµŠ½Ń‚ - %s, чтŠ¾Š±Ń‹ уŠæŠ¾Ń‚Ń€ŠµŠ±Šøть этŠ¾!" + +#: src/talker_npc.cpp +msgid "Thanks, I feel better already." +msgstr "Š”ŠæŠ°ŃŠøŠ±Š¾, Š¼Š½Šµ уŠ¶Šµ стŠ°Š½Š¾Š²Šøтся Š»ŃƒŃ‡ŃˆŠµ." + +#: src/talker_npc.cpp +msgid "Thanks, I used it." +msgstr "Š”ŠæŠ°ŃŠøŠ±Š¾, я ŠøсŠæŠ¾Š»ŃŒŠ·ŃƒŃŽ этŠ¾." + +#: src/talker_npc.cpp +msgid "Offer what?" +msgstr "Š§Ń‚Š¾ ŠæрŠµŠ“Š»Š¾Š¶Šøть?" + +#: src/talker_npc.cpp +msgid "You have no items to offer." +msgstr "Š’Š°Š¼ Š½ŠµŃ‡ŠµŠ³Š¾ ŠæрŠµŠ“Š»Š¾Š¶Šøть." + +#: src/talker_npc.cpp +msgid "Changed your mind?" +msgstr "ŠŸŠµŃ€ŠµŠ“уŠ¼Š°Š»Šø?" + +#: src/talker_npc.cpp +msgid "How?" +msgstr "ŠšŠ°Šŗ?" + +#: src/talker_npc.cpp +msgid "Are you insane!?" +msgstr "Š¢Ń‹, , сŠ¾Š²ŃŠµŠ¼ Šŗу-Šŗу?!" + +#: src/talker_npc.cpp +msgid "Thanks, I'll wield that now." +msgstr "Š”ŠæŠ°ŃŠøŠ±Š¾, я Š±ŃƒŠ“у ŠøсŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ этŠ¾ Š² Š±Š¾ŃŽ." + +#: src/talker_npc.cpp +msgid " Should I take something off?" +msgstr "ŠœŠ½Šµ Š½ŃƒŠ¶Š½Š¾ сŠ½ŃŃ‚ŃŒ чтŠ¾-тŠ¾?" + +#: src/talker_npc.cpp +#, c-format +msgid "" +"My current weapon is better than this.\n" +"(new weapon value: %.1f vs %.1f)." +msgstr "" +"ŠœŠ¾Ń‘ тŠµŠŗущŠµŠµ Š¾Ń€ŃƒŠ¶ŠøŠµ Š»ŃƒŃ‡ŃˆŠµ, чŠµŠ¼ этŠ¾. \n" +"(ŠæŠ¾Š»ŠµŠ·Š½Š¾ŃŃ‚ŃŒ Š½Š¾Š²Š¾Š³Š¾ Š¾Ń€ŃƒŠ¶Šøя: %.1f ŠæрŠ¾Ń‚ŠøŠ² %.1f). " + +#: src/talker_npc.cpp +msgid "Thanks, I'll carry that now." +msgstr "Š”ŠæŠ°ŃŠøŠ±Š¾, Š±ŃƒŠ“у ŠøŠ¼ŠµŃ‚ŃŒ этŠ¾ ŠæрŠø сŠµŠ±Šµ." + +#: src/talker_npc.cpp +msgid "I have no space to store it." +msgstr "Š£ Š¼ŠµŠ½Ń Š½ŠµŃ‚Ńƒ Š¼ŠµŃŃ‚Š° Š“Š»Ń хрŠ°Š½ŠµŠ½Šøя." + +#: src/talker_npc.cpp +#, c-format +msgid "I can only store %s %s more." +msgstr "ŠÆ Š¼Š¾Š³Ńƒ Š²Š·ŃŃ‚ŃŒ ŠµŃ‰Ń‘ тŠ¾Š»ŃŒŠŗŠ¾ %s %s." + +#: src/talker_npc.cpp +msgid "ā€¦or to store anything else for that matter." +msgstr "ā€¦ ŠøŠ»Šø хрŠ°Š½Šøть чтŠ¾-Š½ŠøŠ±ŃƒŠ“ь ŠµŃ‰Ń‘, ŠµŃŠ»Šø Š½Š° тŠ¾ ŠæŠ¾ŃˆŠ»Š¾." + +#: src/talker_npc.cpp +msgid "It is too heavy for me to carry." +msgstr "Š”Š»ŠøшŠŗŠ¾Š¼ тяŠ¶Ń‘Š»Š¾Šµ Š“Š»Ń Š¼ŠµŠ½Ń." + +#: src/talker_npc.cpp +msgid "&You can't make anything out." +msgstr "&Š’Ń‹ Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ Š½ŠøчŠµŠ³Š¾ сŠ“ŠµŠ»Š°Ń‚ŃŒ." + +#: src/talker_npc.cpp +#, c-format +msgid "Str %d - %d" +msgstr "Š”ŠøŠ» %d ā€” %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Dex %d - %d" +msgstr "Š›Š¾Š² %d ā€” %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Int %d - %d" +msgstr "Š˜Š½Ń‚ %d ā€” %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Per %d - %d" +msgstr "Š’Š¾Ń %d ā€” %d" + +#: src/talker_npc.cpp +msgid "Dead tired" +msgstr "Š–ŃƒŃ‚ŠŗŠ°Ń устŠ°Š»Š¾ŃŃ‚ŃŒ" + +#: src/talker_npc.cpp +msgid "Not tired" +msgstr "ŠŠµŃ‚ устŠ°Š»Š¾ŃŃ‚Šø" + +#: src/talker_npc.cpp +msgid ". Will need sleep in " +msgstr ". ŠŸŠ¾Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ся сŠ¾Š½ чŠµŃ€ŠµŠ· " + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need water in " +msgstr "" +"\n" +"ŠŸŠ¾Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ся Š²Š¾Š“Š° чŠµŃ€ŠµŠ· " + +#: src/talker_npc.cpp +msgid "" +"\n" +"Thirsty" +msgstr "" +"\n" +"Š•ŃŃ‚ŃŒ Š¶Š°Š¶Š“Š°" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need food in " +msgstr "" +"\n" +"ŠŸŠ¾Ń‚Ń€ŠµŠ±ŃƒŠµŃ‚ся ŠµŠ“Š° чŠµŃ€ŠµŠ· " + +#: src/talker_npc.cpp +msgid "" +"\n" +"Hungry" +msgstr "" +"\n" +"Š•ŃŃ‚ŃŒ Š³Š¾Š»Š¾Š“" + #: src/teleport.cpp msgid "You feel a strange, inwards force." msgstr "Š’Ń‹ чуŠ²ŃŃ‚Š²ŃƒŠµŃ‚Šµ стрŠ°Š½Š½ŃƒŃŽ Š²Š½ŃƒŃ‚Ń€ŠµŠ½Š½ŃŽŃŽ сŠøŠ»Ńƒ." @@ -291852,6 +293197,40 @@ msgstr ", %3.1f%% / чŠ°Ń, %s Š“Š¾ %s" msgid "pile-up" msgstr "Š·Š°Š²Š°Š»" +#: src/vehicle_move.cpp +msgid "Smart controller does not support flying vehicles." +msgstr "" +"Š£Š¼Š½Ń‹Š¹ Š¼Š¾Š“уŠ»ŃŒ уŠæрŠ°Š²Š»ŠµŠ½Šøя Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø Š½Šµ рŠ°Š±Š¾Ń‚Š°ŠµŃ‚ с Š»ŠµŃ‚Š°ŃŽŃ‰ŠøŠ¼Šø трŠ°Š½ŃŠæŠ¾Ń€Ń‚Š½Ń‹Š¼Šø " +"срŠµŠ“стŠ²Š°Š¼Šø." + +#: src/vehicle_move.cpp +msgid "Smart controller detects only a single controllable engine." +msgstr "Š£Š¼Š½Ń‹Š¹ Š¼Š¾Š“уŠ»ŃŒ уŠæрŠ°Š²Š»ŠµŠ½Šøя Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø Š¾Š±Š½Š°Ń€ŃƒŠ¶ŠøŠ» Š²ŃŠµŠ³Š¾ Š¾Š“ŠøŠ½ Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŒ." + +#: src/vehicle_move.cpp +msgid "Smart controller is designed to control more than one engine." +msgstr "" +"Š£Š¼Š½Ń‹Š¹ Š¼Š¾Š“уŠ»ŃŒ уŠæрŠ°Š²Š»ŠµŠ½Šøя Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø сŠ¾Š·Š“Š°Š½ Š“Š»Ń рŠ°Š±Š¾Ń‚Ń‹ с Š±Š¾Š»ŠµŠµ чŠµŠ¼ Š¾Š“Š½ŠøŠ¼ " +"Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŠµŠ¼." + +#: src/vehicle_move.cpp +msgid "Smart controller does not support more than five engines." +msgstr "" +"Š£Š¼Š½Ń‹Š¹ Š¼Š¾Š“уŠ»ŃŒ уŠæрŠ°Š²Š»ŠµŠ½Šøя Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø Š½Šµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ Š±Š¾Š»ŃŒŃˆŠµ ŠæятŠø Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŠµŠ¹ " +"Š¾Š“Š½Š¾Š²Ń€ŠµŠ¼ŠµŠ½Š½Š¾." + +#: src/vehicle_move.cpp +msgid "Smart controller is shutting down." +msgstr "Š£Š¼Š½Ń‹Š¹ Š¼Š¾Š“уŠ»ŃŒ уŠæрŠ°Š²Š»ŠµŠ½Šøя Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø Š¾Ń‚ŠŗŠ»ŃŽŃ‡Š°ŠµŃ‚ся." + +#: src/vehicle_move.cpp +msgid "Smart controller failed to start an engine." +msgstr "Š£Š¼Š½Ń‹Š¹ Š¼Š¾Š“уŠ»ŃŒ уŠæрŠ°Š²Š»ŠµŠ½Šøя Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø Š½Šµ сŠ¼Š¾Š³ Š·Š°ŠæустŠøть Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŒ." + +#: src/vehicle_move.cpp +msgid "Smart controller optimizes engine state." +msgstr "Š£Š¼Š½Ń‹Š¹ Š¼Š¾Š“уŠ»ŃŒ уŠæрŠ°Š²Š»ŠµŠ½Šøя Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø Š¾ŠæтŠøŠ¼ŠøŠ·ŠøруŠµŃ‚ рŠ°Š±Š¾Ń‚Ńƒ Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŠµŠ¹." + #: src/vehicle_move.cpp #, c-format msgid "The %s is too leaky!" @@ -292230,6 +293609,11 @@ msgctxt "electronics menu option" msgid "water purifier" msgstr "Š²Š¾Š“Š¾Š¾Ń‡ŠøстŠøтŠµŠ»ŃŒ" +#: src/vehicle_use.cpp +msgctxt "electronics menu option" +msgid "smart controller" +msgstr "уŠ¼Š½Ń‹Š¹ Š¼Š¾Š“уŠ»ŃŒ уŠæрŠ°Š²Š»ŠµŠ½Šøя Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŠ¼Šø" + #: src/vehicle_use.cpp msgid "Turn off camera system" msgstr "Š’Ń‹ŠŗŠ»ŃŽŃ‡Šøть сŠøстŠµŠ¼Ńƒ ŠŗŠ°Š¼ŠµŃ€" @@ -292885,50 +294269,18 @@ msgstr "" msgid "You purify the contents of the %1$s's %2$s" msgstr "Š’Ń‹ Š¾Ń‡ŠøщŠ°ŠµŃ‚Šµ сŠ¾Š“ŠµŃ€Š¶ŠøŠ¼Š¾Šµ ёŠ¼ŠŗŠ¾ŃŃ‚Šø (%2$s) Š² трŠ°Š½ŃŠæŠ¾Ń€Ń‚Šµ (%1$s)" -#: src/weather.cpp -msgid "You hear a distant rumble of thunder." -msgstr "Š’Ń‹ сŠ»Ń‹ŃˆŠøтŠµ Š¾Ń‚Š“Š°Š»Ń‘Š½Š½Ń‹Šµ рŠ°ŃŠŗŠ°Ń‚Ń‹ Š³Ń€Š¾Š¼Š°." - -#: src/weather.cpp -msgid "You hear a rumble of thunder from above." -msgstr "ŠŸŃ€ŃŠ¼Š¾ Š½Š°Š“ Š²Š°Š¼Šø рŠ°Š·Š“Š°ŃŽŃ‚ся рŠ°ŃŠŗŠ°Ń‚Ń‹ Š³Ń€Š¾Š¼Š°." - -#: src/weather.cpp -msgid "A flash of lightning illuminates your surroundings!" -msgstr "Š’сŠæышŠŗŠ° Š¼Š¾Š»Š½ŠøŠø Š¾ŃŠ²ŠµŃ‚ŠøŠ»Š° Š¾ŠŗрŠµŃŃ‚Š½Š¾ŃŃ‚Šø!" - #: src/weather.cpp #, c-format -msgid "Your %s protects you from the acidic drizzle." -msgstr "%s Š·Š°Ń‰ŠøщŠ°ŠµŃ‚ Š²Š°Ń Š¾Ń‚ ŠŗŠøсŠ»Š¾Ń‚Š½Š¾Š¹ Š¼Š¾Ń€Š¾ŃŠø." - -#: src/weather.cpp -msgid "Your clothing protects you from the acidic drizzle." -msgstr "ŠžŠ“ŠµŠ¶Š“Š° Š·Š°Ń‰ŠøщŠ°ŠµŃ‚ Š²Š°Ń Š¾Ń‚ ŠŗŠøсŠ»Š¾Ń‚Š½Š¾Š¹ Š¼Š¾Ń€Š¾ŃŠø." +msgid "Your %s protects you from the weather." +msgstr "ŠžŠ“ŠµŠ¶Š“Š° (%s) Š·Š°Ń‰ŠøщŠ°ŠµŃ‚ Š²Š°Ń Š¾Ń‚ ŠæŠ¾Š³Š¾Š“Š½Ń‹Ń… усŠ»Š¾Š²ŠøŠ¹." #: src/weather.cpp -msgid "Your power armor protects you from the acidic drizzle." -msgstr "Š”ŠøŠ»Š¾Š²Š°Ń Š±Ń€Š¾Š½Ń Š·Š°Ń‰ŠøщŠ°ŠµŃ‚ Š²Š°Ń Š¾Ń‚ ŠŗŠøсŠ»Š¾Ń‚Š½Š¾Š¹ Š¼Š¾Ń€Š¾ŃŠø." +msgid "Your clothing protects you from the weather." +msgstr "ŠžŠ“ŠµŠ¶Š“Š° Š·Š°Ń‰ŠøщŠ°ŠµŃ‚ Š²Š°Ń Š¾Ń‚ ŠæŠ¾Š³Š¾Š“Š½Ń‹Ń… усŠ»Š¾Š²ŠøŠ¹." #: src/weather.cpp -msgid "The acid rain stings, but is mostly harmless for nowā€¦" -msgstr "ŠšŠ°ŠæŠ»Šø ŠŗŠøсŠ»Š¾Ń‚Š½Š¾Š³Š¾ Š“Š¾Š¶Š“я сŠ»ŠµŠ³ŠŗŠ° Š¾Š±Š¶ŠøŠ³Š°ŃŽŃ‚, Š½Š¾ ŠæŠ¾ŠŗŠ° Š² Š¾ŃŠ½Š¾Š²Š½Š¾Š¼ Š±ŠµŠ·Š²Ń€ŠµŠ“Š½Ń‹ā€¦" - -#: src/weather.cpp -msgid "Your umbrella protects you from the acid rain." -msgstr "Š—Š¾Š½Ń‚ Š·Š°Ń‰ŠøщŠ°ŠµŃ‚ Š²Š°Ń Š¾Ń‚ ŠŗŠøсŠ»Š¾Ń‚Š½Š¾Š³Š¾ Š“Š¾Š¶Š“я." - -#: src/weather.cpp -msgid "Your clothing protects you from the acid rain." -msgstr "ŠžŠ“ŠµŠ¶Š“Š° Š·Š°Ń‰ŠøщŠ°ŠµŃ‚ Š²Š°Ń Š¾Ń‚ ŠŗŠøсŠ»Š¾Ń‚Š½Š¾Š³Š¾ Š“Š¾Š¶Š“я." - -#: src/weather.cpp -msgid "Your power armor protects you from the acid rain." -msgstr "Š”ŠøŠ»Š¾Š²Š°Ń Š±Ń€Š¾Š½Ń Š·Š°Ń‰ŠøщŠ°ŠµŃ‚ Š²Š°Ń Š¾Ń‚ ŠŗŠøсŠ»Š¾Ń‚Š½Š¾Š³Š¾ Š“Š¾Š¶Š“я." - -#: src/weather.cpp -msgid "The acid rain burns!" -msgstr "ŠšŠøсŠ»Š¾Ń‚Š½Ń‹Š¹ Š“Š¾Š¶Š“ь Š¾Š±Š¶ŠøŠ³Š°ŠµŃ‚!" +msgid "Your power armor protects you from the weather." +msgstr "Š”ŠøŠ»Š¾Š²Š°Ń Š±Ń€Š¾Š½Ń Š·Š°Ń‰ŠøщŠ°ŠµŃ‚ Š²Š°Ń Š¾Ń‚ ŠæŠ¾Š³Š¾Š“Š½Ń‹Ń… усŠ»Š¾Š²ŠøŠ¹." #: src/weather.cpp msgid "Monday" @@ -293105,54 +294457,6 @@ msgstr "Š£Ń€Š°Š³Š°Š½" msgid "The weather changed to %s!" msgstr "ŠŸŠ¾Š³Š¾Š“Š° сŠ¼ŠµŠ½ŠøŠ»Š°ŃŃŒ Š½Š° %s!" -#: src/weather_data.cpp -msgid "Clear" -msgstr "ŠÆсŠ½Š¾" - -#: src/weather_data.cpp -msgid "Sunny" -msgstr "Š”Š¾Š»Š½ŠµŃ‡Š½Š¾" - -#: src/weather_data.cpp -msgid "Cloudy" -msgstr "ŠŸŠ°ŃŠ¼ŃƒŃ€Š½Š¾" - -#: src/weather_data.cpp -msgid "Light Drizzle" -msgstr "Š›ŠµŠ³ŠŗŠ°Ń Š¼Š¾Ń€Š¾ŃŃŒ" - -#: src/weather_data.cpp -msgid "Drizzle" -msgstr "ŠœŠ¾Ń€Š¾ŃŃŒ" - -#: src/weather_data.cpp -msgid "Rain" -msgstr "Š”Š¾Š¶Š“ь" - -#: src/weather_data.cpp -msgid "Thunder Storm" -msgstr "Š“Ń€Š¾Š·Š¾Š²Š¾Š¹ Š»ŠøŠ²ŠµŠ½ŃŒ" - -#: src/weather_data.cpp -msgid "Acidic Drizzle" -msgstr "ŠšŠøсŠ»Š¾Ń‚Š½Š°Ń Š¼Š¾Ń€Š¾ŃŃŒ" - -#: src/weather_data.cpp -msgid "Acid Rain" -msgstr "ŠšŠøсŠ»Š¾Ń‚Š½Ń‹Š¹ Š“Š¾Š¶Š“ь" - -#: src/weather_data.cpp -msgid "Flurries" -msgstr "ŠœŠ¾Ń€Š¾ŃŃŃ‰ŠøŠ¹ сŠ½ŠµŠ³" - -#: src/weather_data.cpp -msgid "Snowing" -msgstr "Š”Š½ŠµŠ³Š¾ŠæŠ°Š“" - -#: src/weather_data.cpp -msgid "Snowstorm" -msgstr "ŠœŠµŃ‚ŠµŠ»ŃŒ" - #: src/wish.cpp msgid "Nonvalid" msgstr "Š’Ń€ŠµŠ“Š½Š°" @@ -293346,6 +294650,19 @@ msgstr "Š’Ń‹Š±ŠµŃ€ŠøтŠµ Š¼Šøр, чтŠ¾Š±Ń‹ Š½Š°Ń‡Š°Ń‚ŃŒ ŠøŠ³Ń€Ńƒ" msgid "last world info" msgstr "ŠøŠ½Ń„Š¾Ń€Š¼Š°Ń†Šøя Š¾ ŠæŠ¾ŃŠ»ŠµŠ“Š½ŠµŠ¼ Š¼ŠøрŠµ" +#: src/worldfactory.cpp +msgid "MISSING MODS" +msgstr "ŠžŠ¢Š”Š£Š¢Š”Š¢Š’Š£Š®Š©Š˜Š• ŠœŠžŠ”Š«" + +#: src/worldfactory.cpp +msgid "OBSOLETE MODS" +msgstr "Š£Š”Š¢ŠŠ Š•Š’ŠØŠ˜Š• ŠœŠžŠ”Š«" + +#: src/worldfactory.cpp +#, c-format +msgid " [%s]" +msgstr " [%s]" + #: src/worldfactory.cpp msgid " ACTIVE WORLD MODS " msgstr " ŠŠšŠ¢Š˜Š’ŠŠ«Š• ŠœŠžŠ”Š« ŠœŠ˜Š Š " diff --git a/lang/po/zh_CN.po b/lang/po/zh_CN.po index 051327a2a6dd3..1e11e072003a5 100644 --- a/lang/po/zh_CN.po +++ b/lang/po/zh_CN.po @@ -4,8 +4,8 @@ # dikai li , 2018 # Jin Zhang <610037437@qq.com>, 2018 # ę™Ø光 马 <448367875@qq.com>, 2018 -# Vimsucks Ho , 2018 # cellxiecao , 2018 +# Vimsucks Ho , 2018 # 4c6e1d75b9f86fe32f55f91342c2d6a6, 2018 # 高 åŠ±č“¤ <475964436@qq.com>, 2018 # Hua Liang , 2018 @@ -53,13 +53,14 @@ # ä½•ę–¹ē„žåœ£ 何 <1366003560@qq.com>, 2020 # Amans Tofu , 2020 # Aloxaf , 2020 +# AT, 2020 # cainiao , 2020 # msgid "" msgstr "" "Project-Id-Version: cataclysm-dda 0.E\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-07-08 10:07+0800\n" +"POT-Creation-Date: 2020-07-16 21:36+0800\n" "PO-Revision-Date: 2018-04-26 14:47+0000\n" "Last-Translator: cainiao , 2020\n" "Language-Team: Chinese (China) (https://www.transifex.com/cataclysm-dda-translators/teams/2217/zh_CN/)\n" @@ -6699,6 +6700,56 @@ msgid "" "designed to fit Huge survivors." msgstr "äø€äøŖē”ØäŗŽå›ŗ定和ēŸ«ę­£éŖØéŖ¼ä»„åø®åŠ©éŖØęŠ˜ę¢å¤ēš„å·„å…·ć€‚äø“é—Øč®¾č®”ē”ØäŗŽä»Žęœ«ę—„å¹ø存äø‹ę„ēš„å˜å¼‚č‚¢ä½“ć€‚" +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm)" +msgid_plural "tourniquets (arm)" +msgstr[0] "ę­¢č”€åø¦ļ¼ˆę‰‹č‡‚ļ¼‰" + +#. ~ Use action menu_text for {'str': 'tourniquet (arm)', 'str_pl': +#. 'tourniquets (arm)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (arm XL)', 'str_pl': +#. 'tourniquets (arm XL)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (leg)', 'str_pl': +#. 'tourniquets (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "Adjust" +msgstr "调节" + +#. ~ Use action msg for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'}. +#. ~ Use action msg for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'}. +#. ~ Use action msg for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "You adjust the tourniquet." +msgstr "ä½ č°ƒčŠ‚äŗ†ę­¢č”€åø¦ēš„å°ŗåÆø怂" + +#. ~ Description for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'} +#. ~ Description for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'} +#. ~ Description for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'} +#: lang/json/ARMOR_from_json.py +msgid "" +"First aid device used to apply pressure to a limb or extremity in order to " +"limit blood flow. Should be employed only to manage heavy bleedings, " +"because prolonged use will harm the limb. It can be adjusted in size to fit" +" different limbs." +msgstr "" +"äø€ę¬¾čƒ½å¤ŸåÆ¹å››č‚¢ęˆ–ę‰‹č¶³ę–½åŠ åŽ‹åŠ›ä»„é™åˆ¶č”€ę¶²ęµåŠØēš„ę€„ę•‘č£…ē½®ć€‚åŗ”当仅ē”ØäŗŽéžåøøäø„重ēš„å‡ŗ蔀ē—‡ēŠ¶ēš„ꀄꕑļ¼Œå› äøŗé•æꜟä½æē”Ø会åÆ¹å››č‚¢é€ ęˆä¼¤å®³ć€‚å®ƒåÆä»„č°ƒčŠ‚å°ŗåÆøļ¼Œä»„适åŗ”äøåŒå¤§å°ēš„č‚¢ä½“ć€‚" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm XL)" +msgid_plural "tourniquets (arm XL)" +msgstr[0] "ę­¢č”€åø¦ļ¼ˆę‰‹č‡‚ļ¼‰ļ¼ˆXLļ¼‰" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (leg)" +msgid_plural "tourniquets (leg)" +msgstr[0] "ę­¢č”€åø¦ļ¼ˆč…æéƒØļ¼‰" + #: lang/json/ARMOR_from_json.py msgid "blindfold" msgid_plural "blindfolds" @@ -22296,7 +22347,7 @@ msgstr "čæ™å ę–‡ä»¶äøŠēš„ę—„ꜟę˜Æč·å¤§ē¾å˜å‘ē”Ÿäø¤å‘Ø前ļ¼ŒčƦē»†åˆ†ęžäŗ† #: lang/json/BOOK_from_json.py msgid "lab journal-Dionne" msgid_plural "lab journals-Dionne" -msgstr[0] "ē ”ē©¶ę—„åæ—-čæŖēæ" +msgstr[0] "ē ”ē©¶ę—„åæ—ļ¼ˆčæŖēæļ¼‰" #. ~ Description for {'str': 'lab journal-Dionne', 'str_pl': 'lab journals- #. Dionne'} @@ -22324,7 +22375,7 @@ msgstr "čæ™ēÆ‡ę–‡ēŒ®åƹäø€ē§ę–°ēš„化学公式作äŗ†čƦē»†ēš„ꏏčæ°ļ¼Œå¹¶ē§°å…¶ #: lang/json/BOOK_from_json.py msgid "lab journal-Smythe" msgid_plural "lab journals-Smythe" -msgstr[0] "ē ”ē©¶ę—„åæ—-Smythe" +msgstr[0] "ē ”ē©¶ę—„åæ—ļ¼ˆę–Æčæˆę€ļ¼‰" #. ~ Description for {'str': 'lab journal-Smythe', 'str_pl': 'lab journals- #. Smythe'} @@ -22368,7 +22419,7 @@ msgstr "" #: lang/json/BOOK_from_json.py msgid "lab journal-x-|xp" msgid_plural "lab journals-x-|xp" -msgstr[0] "ē ”ē©¶ę—„åæ—-x-|xp" +msgstr[0] "ē ”ē©¶ę—„åæ—ļ¼ˆx-|xpļ¼‰" #. ~ Description for {'str': 'lab journal-x-|xp', 'str_pl': 'lab #. journals-x-|xp'} @@ -23126,7 +23177,7 @@ msgstr "čæ™ęœ¬å¹“é‰“é‡Œęœ‰č®ø多关äŗŽ\"äŗŗē±»čæē”Øē§‘ꊀč‡Ŗꈑå¼ŗ化ēš„ę–¹ę³•\ #: lang/json/BOOK_from_json.py msgid "lab journal-Herrera" msgid_plural "lab journals-Herrera" -msgstr[0] "ē ”ē©¶ę—„åæ—-åŸƒé›·ę‹‰" +msgstr[0] "ē ”ē©¶ę—„åæ—ļ¼ˆåŸƒé›·ę‹‰ļ¼‰" #. ~ Description for {'str': 'lab journal-Herrera', 'str_pl': 'lab journals- #. Herrera'} @@ -23516,7 +23567,7 @@ msgstr "" #: lang/json/BOOK_from_json.py msgid "lab journal-Gustav" msgid_plural "lab journals-Gustav" -msgstr[0] "ē ”ē©¶ę—„åæ—-Gustav" +msgstr[0] "ē ”ē©¶ę—„åæ—ļ¼ˆå¤ę–Æ唔夫ļ¼‰" #. ~ Description for {'str': 'lab journal-Gustav', 'str_pl': 'lab journals- #. Gustav'} @@ -23984,7 +24035,7 @@ msgstr "äø€ęœ¬ęœŗę¢°å­¦čæ›é˜¶ę‰‹å†Œļ¼Œę¶µē›–äŗ†å„ę–¹é¢ēš„äø»é¢˜ć€‚" #: lang/json/BOOK_from_json.py msgid "lab journal-Curie" msgid_plural "lab journals-Curie" -msgstr[0] "ē ”ē©¶ę—„åæ—-Curie" +msgstr[0] "ē ”ē©¶ę—„åæ—ļ¼ˆå±…里ļ¼‰" #. ~ Description for {'str': 'lab journal-Curie', 'str_pl': 'lab journals- #. Curie'} @@ -24101,7 +24152,7 @@ msgstr "äø€ęœ¬č–„č–„ēš„企划书ļ¼Œé‡Œé¢åˆ—äø¾äŗ†å¦‚何ē›˜ę“»äø€é—“大型农åœŗ msgid "" "This binder details the scheduled maintenance for several plumbing systems " "throughout the facility." -msgstr "čæ™äøŖę–‡ä»¶å¤¹é‡Œå…Øę˜Æꏏčæ°äŗ†ę•“äøŖč®¾ę–½äø­å‡ äøŖē®”道ē³»ē»Ÿēš„å®šęœŸē»“ęŠ¤ęƒ…å†µēš„ꖇ件怂" +msgstr "čæ™äøŖę—„åæ—内čƦē»†åˆ—å‡ŗäŗ†ęœŗęž„å†…ēš„ę•°å„—ē®”道ē³»ē»Ÿēš„ē»“ęŠ¤č®”åˆ’ć€‚" #: lang/json/BOOK_from_json.py msgid "book of essays" @@ -36482,6 +36533,19 @@ msgid "" "appetite, and is quite addictive." msgstr "医ē”Øēŗ§č‹Æäø™čƒŗē›ļ¼Œåøøē”ØäŗŽę²»ē–—ę³Øę„åŠ›åˆ†ę•£å’Œå¤šåŠØē—‡ć€‚å®ƒčƒ½ęŠ‘åˆ¶é£Ÿę¬²ļ¼Œč€Œäø”ę˜Æ非åøøå®¹ę˜“äøŠē˜¾ć€‚" +#: lang/json/COMESTIBLE_from_json.py +msgid "adhesive bandage" +msgid_plural "adhesive bandages" +msgstr[0] "创åÆč““" + +#. ~ Description for {'str': 'adhesive bandage'} +#: lang/json/COMESTIBLE_from_json.py +msgid "" +"A set of small medical dressings, each made of a piece of sterile cloth and " +"a sticky tape, used for small injuries not serious enough to require a full-" +"size bandage." +msgstr "äø€äŗ›å°åž‹åŒ»ē”Øę•·ę–™ļ¼ŒęƏ块都ē”±äø€å—ę— čŒåøƒå’Œčƒ¶åø¦ē»„ęˆļ¼Œē”ØäŗŽę²»ē–—é‚£äŗ›å°šäøäø„é‡åˆ°éœ€č¦å…Øå°ŗåÆøē»·åø¦ēš„å°ä¼¤å£ć€‚" + #: lang/json/COMESTIBLE_from_json.py msgid "syringe of adrenaline" msgid_plural "syringes of adrenaline" @@ -36559,8 +36623,10 @@ msgstr[0] "ē»·åø¦" #. ~ Description for {'str': 'bandage'} #: lang/json/COMESTIBLE_from_json.py -msgid "Simple cloth bandages. Used for healing small amounts of damage." -msgstr "äø€ę†ē®€å•ēš„医ē”Øē»·åø¦ļ¼ŒåÆ仄ē”Øę„åŒ…ę‰Žä¼¤å£å¹¶é˜»ę­¢ä¼¤å£ęµč”€ć€‚" +msgid "" +"Simple cloth bandages. Used for stopping bloodloss and protecting wounds " +"from external factors." +msgstr "äø€ę”ē®€å•ēš„åøƒē»·åø¦ļ¼ŒåÆ仄ē”ØäŗŽé˜»ę­¢ä¼¤å£å¤±č”€å¹¶äæęŠ¤ä¼¤å£äøå—外ē•Œå› ē“ å½±å“ć€‚" #: lang/json/COMESTIBLE_from_json.py msgid "makeshift bandage" @@ -45453,7 +45519,7 @@ msgstr "äø€äøŖēŽ©å®¶čÆ•å›¾ę‰¾å‡ŗę€å®³ē®”家ēš„å‡¶ę‰‹ēš„ęøøꈏ怂" #: lang/json/GENERIC_from_json.py msgid "animal" msgid_plural "none" -msgstr[0] "åŠØē‰©" +msgstr[0] "ē•œåŠ›" #: lang/json/GENERIC_from_json.py msgid "nearby fire" @@ -45667,7 +45733,7 @@ msgstr[0] "内几äøč“Øäø" #. endochitin'} #: lang/json/GENERIC_from_json.py msgid "A piece of an insect's endoskeleton." -msgstr "äø€å—ę˜†č™«å†…éŖØéŖ¼ć€‚" +msgstr "čæ™ę˜Æäø€å—ę˜†č™«ēš„内éŖØéŖ¼ć€‚" #: lang/json/GENERIC_from_json.py msgid "cluster of gas sacs" @@ -45755,9 +45821,9 @@ msgstr[0] "ęœØęæꍆ" #. planks'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten construction planks securely lashed together with a rope. Disassemble " -"to unpack." -msgstr "十ē‰‡č¢«ē»³å­ē“§ē“§åœ°ę†åœØäø€čµ·ä»„å­˜ę”¾ēš„ęœØęæļ¼ŒåÆę‹†č§£ć€‚" +"Ten construction planks securely tied together for easier transport. " +"Disassemble to untie them." +msgstr "十ē‰‡č¢«ē“§ē“§åœ°ę†åœØäø€čµ·ä»„å­˜ę”¾ēš„ęœØęæļ¼ŒåÆę‹†č§£ć€‚" #: lang/json/GENERIC_from_json.py msgid "bundle of stout branches" @@ -45768,9 +45834,22 @@ msgstr[0] "ē²—ę ‘ęžę†" #. stout branches'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten stout branches securely lashed together with a rope. Disassemble to " -"untie them." -msgstr "åę ¹č¢«ē»³å­ē“§ē“§åœ°ę†åœØäø€čµ·ä»„å­˜ę”¾ēš„ē²—ę ‘ęžļ¼ŒåÆę‹†č§£ć€‚" +"Ten stout branches securely tied together for easier transport. Disassemble" +" to untie them." +msgstr "åę ¹č¢«ē“§ē“§åœ°ę†åœØäø€čµ·ä»„å­˜ę”¾ēš„ē²—ę ‘ęžļ¼ŒåÆę‹†č§£ć€‚" + +#: lang/json/GENERIC_from_json.py +msgid "bundle of long stout branches" +msgid_plural "bundles of long stout branches" +msgstr[0] "é•æꠑꞝꍆ" + +#. ~ Description for {'str': 'bundle of long stout branches', 'str_pl': +#. 'bundles of long stout branches'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Five long stout branches securely tied together for easier transport. " +"Disassemble to untie them." +msgstr "äŗ”ę ¹č¢«ē“§ē“§åœ°ę†åœØäø€čµ·ä»„å­˜ę”¾ēš„é•æꠑꞝļ¼ŒåÆę‹†č§£ć€‚" #: lang/json/GENERIC_from_json.py msgid "t-substrate sample" @@ -46029,7 +46108,7 @@ msgstr[0] "å¼¹ē°§" #: lang/json/GENERIC_from_json.py msgid "" "A large, heavy-duty spring. Expands with significant force when compressed." -msgstr "å·Ø大ēš„å¼¹ē°§ć€‚åÆ仄ę‰æ受äøå°‘力ļ¼Œäø”å¼¹ę€§åč¶³ć€‚" +msgstr "äø€ę ¹å·Ø大ēš„å¼¹ē°§ć€‚åÆ仄ę‰æ受äøå°‘力ļ¼Œäø”å¼¹ę€§åč¶³ć€‚" #: lang/json/GENERIC_from_json.py msgid "lawnmower" @@ -46449,12 +46528,12 @@ msgstr "äø€ę ¹å†…å­˜ę”怂ē”ØäŗŽåˆ¶é€ é«˜ēŗ§ē”µå­č®¾å¤‡ć€‚" #: lang/json/GENERIC_from_json.py msgid "power converter" msgid_plural "power converters" -msgstr[0] "ē”µåŠ›å˜ę¢ē”µč·Æ" +msgstr[0] "功ēŽ‡å˜ę¢å™Ø" #. ~ Description for {'str': 'power converter'} #: lang/json/GENERIC_from_json.py msgid "A power supply unit. Useful in lots of electronics recipes." -msgstr "čæ™ę˜Æē”µęŗå•å…ƒć€‚ē”ØäŗŽåˆ¶é€ č®ø多ē”µå­č®¾å¤‡ć€‚" +msgstr "äø€äøŖ供ē”µęØ”å—ć€‚ē”ØäŗŽåˆ¶é€ č®ø多ē”µå­č®¾å¤‡ć€‚" #: lang/json/GENERIC_from_json.py msgid "amplifier circuit" @@ -46527,7 +46606,7 @@ msgstr[0] "高ęø…镜夓" msgid "" "A high-quality lens, useful for focusing or diffusing light. Might be " "useful for starting a fire." -msgstr "ę­¤äøŗ高品č“Ø镜夓ļ¼ŒåÆ仄ē”Øę„čšå…‰ęˆ–ę•£å…‰ć€‚ęˆ–č®øåÆ仄ē”Øę„ē”Ÿē«ć€‚" +msgstr "äø€äøŖ高品č“Ø镜夓ļ¼ŒåÆ仄ē”Øę„čšå…‰ęˆ–ę•£å…‰ć€‚ęˆ–č®øčæ˜åÆ仄ē”Øę„ē”Ÿē«ć€‚" #: lang/json/GENERIC_from_json.py msgid "small high-quality lens" @@ -46594,7 +46673,7 @@ msgid "" "data within was once clearly worth millions, but now, you are not sure if " "it's anything more than a fancy, high-tech paperweight." msgstr "" -"čæ™ę˜Æäø€äøŖ先čæ›å…‰å­¦å­˜å‚Øē³»ē»Ÿļ¼ŒåŒ…含äŗ†åˆ¶é€ å¤ę‚ē”…光子ē”µč·Æꉀåæ…é”»ēš„ęŒ‡ä»¤ć€‚é‡Œé¢ēš„ę•°ę®ę˜¾ē„¶ę›¾ē»ä»·å€¼åƒäø‡ļ¼Œä½†ę˜Æäŗ‹åˆ°å¦‚今ļ¼Œä½ äøēŸ„道它除äŗ†ę‹æę„å½“äøŖ花å“Øēš„高ē§‘ꊀ镇ēŗø之外čæ˜čƒ½ē”Øę„åšä»€ä¹ˆć€‚" +"äø€å„—ęœ€å…ˆčæ›ēš„光学存å‚Øē³»ē»Ÿļ¼ŒåŒ…含äŗ†åˆ¶é€ å¤ę‚ē”…光子ē”µč·Æꉀåæ…é”»ēš„ęŒ‡ä»¤ć€‚é‡Œé¢ēš„ę•°ę®ę˜¾ē„¶ę›¾ē»ä»·å€¼åƒäø‡ļ¼Œä½†ę˜Æäŗ‹åˆ°å¦‚今ļ¼Œä½ äøēŸ„道它除äŗ†ę‹æę„å½“äøŖ花å“Øēš„高ē§‘ꊀ镇ēŗø之外čæ˜čƒ½ē”Øę„åšä»€ä¹ˆć€‚" #: lang/json/GENERIC_from_json.py msgid "antenna" @@ -46628,7 +46707,7 @@ msgstr[0] "ē”µč·Æęæ" msgid "" "A printed card that supports and electrically connects electronic components" " on a non-conductive substrate." -msgstr "äø€å—印刷儽ēš„ęæ子ļ¼Œčƒ½å°†éžåƼē”µč”¬åŗ•äøŠēš„ē”µå­éƒØ件čæžęŽ„čµ·ę„" +msgstr "äø€å—印刷儽ēš„ē”µč·Æęæļ¼Œčƒ½å°†å®‰č£…åœØäøåƼē”µēš„蔬åŗ•äøŠēš„各äøŖē”µå­éƒØ件通čæ‡é‡‘属čæžēŗæčæžęŽ„čµ·ę„ć€‚" #: lang/json/GENERIC_from_json.py msgid "electronic scrap" @@ -46640,7 +46719,7 @@ msgstr[0] "ē”µå­åŗŸę–™" msgid "" "A random collection of resistors, capacitors, and diodes which have been " "stripped from printed circuits." -msgstr "äø€äøŖ从ē”µč·ÆęæäøŠę‰’äø‹ę„ēš„äø€å †ē”µé˜»å™Øļ¼Œē”µå®¹å™Ø和äŗŒęžē®”怂" +msgstr "äø€å †ä»Žå°åˆ·ē”µč·ÆęæäøŠę‹†äø‹ę„ēš„各ē§ē”µé˜»ć€ē”µå®¹å’ŒäŗŒęžē®”怂" #: lang/json/GENERIC_from_json.py msgid "radio repeater mod" @@ -46656,12 +46735,12 @@ msgstr "äø€äøŖč¢«č®¾č®”ē”Øę„å°†ę™®é€šēš„ę— ēŗæē”µē«™č½¬ę¢äøŗč‡ŖåŠØäø­ē»§å™Øēš„ #: lang/json/GENERIC_from_json.py msgid "desk fan" msgid_plural "desk fans" -msgstr[0] "å°é£Žę‰‡" +msgstr[0] "å°ę‰‡" #. ~ Description for {'str': 'desk fan'} #: lang/json/GENERIC_from_json.py msgid "A small fan, used to propel air around a room." -msgstr "äø€äøŖå°åž‹é£Žę‰‡ļ¼ŒåÆ仄ē”Øę„ä½æęˆæé—“ēš„ē©ŗ갔굁åŠØ怂" +msgstr "äø€å°å°åž‹é£Žę‰‡ļ¼ŒåÆ仄ē”Øę„ä½æęˆæé—“ēš„ē©ŗ갔굁åŠØ怂" #: lang/json/GENERIC_from_json.py msgid "ceramic armor plate" @@ -46696,7 +46775,7 @@ msgstr[0] "ę²¾č”€åøƒę”" #: lang/json/GENERIC_from_json.py msgid "" "A large rag, drenched in blood. It could be cleaned with boiling water." -msgstr "äø€å—ęµøę»”äŗ†č”€ę¶²ēš„ē “åøƒļ¼ŒåÆ仄ē”Øå¼€ę°“ęŠŠå®ƒę“—å¹²å‡€ć€‚" +msgstr "äø€å—ęµøę»”äŗ†č”€ę¶²ēš„åøƒę”ļ¼ŒåÆ仄ē”Øę²øę°“ęø…ę“—å¹²å‡€ć€‚" #: lang/json/GENERIC_from_json.py msgid "pipe cleaner" @@ -46731,7 +46810,7 @@ msgstr[0] "å‘ę”č£…ē½®" #. ~ Description for {'str_sp': 'clockworks'} #: lang/json/GENERIC_from_json.py msgid "A small assortment of gears and other clockwork gubbins." -msgstr "äø€å°å›¢é½æč½®å’Œå‘ę”č£…ē½®ć€‚" +msgstr "äø€å †å„å¼å„ę ·ēš„小型é½æč½®å’Œå‘ę”č£…ē½®ć€‚" #: lang/json/GENERIC_from_json.py msgid "SD-Memory card" @@ -46900,7 +46979,7 @@ msgstr[0] "ē –夓" #. ~ Description for {'str': 'brick'} #: lang/json/GENERIC_from_json.py msgid "A fire hardened building block used in masonry construction." -msgstr "ē»čæ‡ē«ēƒ¤ē”¬åŒ–后ēš„å»ŗē­‘ęę–™ļ¼Œē”ØåœØ各ē§ē –ēŸ³ē»“ęž„äø­ć€‚" +msgstr "äø€å—ē»čæ‡ē«ēƒ¤ē”¬åŒ–后ēš„å»ŗē­‘ęę–™ļ¼Œē”ØåœØ各ē§ē –ēŸ³ē»“ęž„äø­ć€‚" #: lang/json/GENERIC_from_json.py msgid "mortar" @@ -47650,6 +47729,11 @@ msgid "" "gutted for parts." msgstr "äø€ęž¶ęŸåēš„\"é¹°ēˆŖ\"åž‹ę— äŗŗč½¦ļ¼Œå®ƒēš„外壳ē “ꍟļ¼Œęœ‰ę¶²ä½“从äø­ęµå‡ŗ怂åÆä»„ę‹†č§£å¾—åˆ°éƒØ件怂" +#: lang/json/GENERIC_from_json.py +msgid "broken laser turret" +msgid_plural "broken laser turrets" +msgstr[0] "ęæ€å…‰ē‚®å””ļ¼ˆęŸåļ¼‰" + #: lang/json/GENERIC_from_json.py msgid "fire brick" msgid_plural "fire bricks" @@ -48195,11 +48279,6 @@ msgid "" "like it could support a reinforcing sheet, either." msgstr "čæ™ē§å¤Ŗé˜³čƒ½ē”µę± ęæę˜Æ尖ē«ÆꊀęœÆēš„äŗ§ē‰©ļ¼Œę‹„ęœ‰ęžé«˜ēš„å…‰ē”µč½¬ę¢ę•ˆčƒ½ć€‚但ę˜Æ它č”Øé¢č¦†ē›–ē‰¹ę®Šęę–™č®©å®ƒéžåøøč„†å¼±ļ¼ŒåŒę—¶ä¹Ÿę— ę³•čæ›č”Œå¼ŗ化加å›ŗ怂" -#: lang/json/GENERIC_from_json.py -msgid "broken laser turret" -msgid_plural "broken laser turrets" -msgstr[0] "ęæ€å…‰ē‚®å””ļ¼ˆęŸåļ¼‰" - #: lang/json/GENERIC_from_json.py msgid "TX-5LR Laser Cannon" msgid_plural "TX-5LR Laser Cannons" @@ -49015,9 +49094,9 @@ msgstr[0] "é…ø面团ļ¼ˆęœŖꈐē†Ÿļ¼‰" #. ~ Use action msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py msgid "" -"After feeding it and caring for it for weeks, your sourdough starter is " +"After feeding it and caring for it for a week, your sourdough starter is " "finally ready for the big leagues." -msgstr "åœØē»†åæƒå–‚养并ē…§ę–™å‡ äøŖę˜ŸęœŸåŽļ¼Œä½ ēš„é…ø面团ē»ˆäŗŽå‡†å¤‡å„½ļ¼Œčƒ½ę­£å¼ä½æē”Øäŗ†ć€‚" +msgstr "åœØē»†åæƒå–‚养并ē…§ę–™äø€äøŖę˜ŸęœŸåŽļ¼Œä½ ēš„é…ø面团ē»ˆäŗŽå‡†å¤‡å„½ļ¼Œčƒ½ę­£å¼ä½æē”Øäŗ†ć€‚" #. ~ Use action not_ready_msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py @@ -49052,8 +49131,8 @@ msgstr "é…ø面团čæ˜ę²”ę¢å¤ļ¼Œéœ€č¦ē­‰äø€ä¼šę‰čƒ½ē”Ø怂" #: lang/json/GENERIC_from_json.py msgid "" "This jar contains a floury paste with sourdough starter mixed in. It needs " -"a few hours to recover its strength before it can be used again." -msgstr "čæ™äøŖē½å­é‡Œč£…ē€äø€å›¢é¢ē³Šļ¼Œé‡Œé¢åŠ å…„äŗ†é…øé¢å›¢ć€‚å®ƒéœ€č¦ē»čæ‡å‡ äøŖå°ę—¶å‘é…µę„ę¢å¤åŠ›é‡ļ¼Œē„¶åŽę‰čƒ½å†ę¬”ä½æē”Ø怂" +"a day to recover its strength before it can be used again." +msgstr "čæ™äøŖē½å­é‡Œč£…ē€äø€å›¢é¢ē³Šļ¼Œé‡Œé¢åŠ å…„äŗ†é…øé¢å›¢ć€‚å®ƒéœ€č¦ē»čæ‡äø€å¤©å‘é…µę„ę¢å¤åŠ›é‡ļ¼Œē„¶åŽę‰čƒ½å†ę¬”ä½æē”Ø怂" #: lang/json/GENERIC_from_json.py msgid "sourdough starter" @@ -49104,10 +49183,23 @@ msgstr[0] "ꀄꕑē®±" #. ~ Description for {'str': 'first aid kit'} #: lang/json/GENERIC_from_json.py msgid "" -"A full medical kit, with bandages, local anesthetics, and rapid healing " -"agents. Used for healing large amounts of damage. Disassemble to get its " -"content." -msgstr "äø€äøŖå®Œę•“ēš„ę€„ę•‘åŒ…ļ¼Œé‡Œé¢ęœ‰ē»·åø¦ć€å±€éƒØéŗ»é†‰å‰‚ć€ä¼¤å£ę¢å¤čÆ怂ē”ØäŗŽäø„重伤害ēš„ę²»ē–—ć€‚ę‹†č§£å®ƒä»„čŽ·å–å†…å®¹ē‰©ć€‚" +"A typical universal first aid kit, one you'd see in a car or in a household." +" It contains a variety of common medical items stored in case of accidents " +"and injuries. Disassemble to get its content." +msgstr "äø€äøŖå…ø型ēš„通ē”Øꀄꕑē®±ļ¼Œå°±ę˜Æę±½č½¦åŽåŗ§ęˆ–家äø­åøø见ēš„é‚£ē§ć€‚它包含各ē§åøø见ēš„医ē–—ē‰©å“ļ¼Œä»„备äŗ‹ę•…ęˆ–å—ä¼¤ę—¶ä½æē”Øć€‚ę‹†č§£åÆčŽ·å–å†…å®¹ē‰©ć€‚" + +#: lang/json/GENERIC_from_json.py +msgid "IFAK" +msgid_plural "IFAKs" +msgstr[0] "å•å…µę€„ę•‘åŒ…" + +#. ~ Description for {'str': 'IFAK'} +#: lang/json/GENERIC_from_json.py +msgid "" +"An IFAK, or individual first aid kit, is a specialized set of wound " +"dressings and accessories, and being of military origin focuses on combat " +"trauma and preventing blood loss. Disassemble to get its content." +msgstr "äø€äøŖIFAKļ¼Œęˆ–ē§°å•å…µę€„ę•‘åŒ…ļ¼ŒåŒ…含äŗ†ē‰¹åˆ¶ēš„ä¼¤å£ę•·ę–™å’Œé…ä»¶ļ¼Œå…·ęœ‰å†›ē”Øčµ·ęŗļ¼Œäø“ę³ØäŗŽę²»ē–—ęˆ˜ę–—åˆ›ä¼¤å’Œé˜²ę­¢å¤§é‡å¤±č”€ć€‚ę‹†č§£åÆčŽ·å–å†…å®¹ē‰©ć€‚" #: lang/json/GENERIC_from_json.py msgid "MRE" @@ -53436,10 +53528,10 @@ msgstr "" #: lang/json/GENERIC_from_json.py msgid "inscribed metal plates" -msgid_plural "inscribed metal platess" +msgid_plural "inscribed metal plates" msgstr[0] "čš€åˆ»é‡‘å±žęæ" -#. ~ Description for {'str': 'inscribed metal plates'} +#. ~ Description for {'str_sp': 'inscribed metal plates'} #: lang/json/GENERIC_from_json.py msgid "" "This device looks electronic, but is unfamiliar. It is a series of tightly " @@ -53476,6 +53568,35 @@ msgid "" "work." msgstr "你通čæ‡é“œēŗæēš„ēŗæ圈和ēŖå‡ŗēš„ę“»å”žę„ēŒœęƒ³å®ƒę˜ÆꟐē§ē”µåŠØęœŗęˆ–å‘ē”µęœŗļ¼Œä½†ę˜Æ它ēš„č®¾č®”ēœ‹čµ·ę„å’Œä½ ä»„å‰č§čæ‡ēš„完å…Øäøäø€ę ·ļ¼Œä½ äøēŸ„é“å¦‚ä½•č®©å®ƒå·„ä½œć€‚" +#: lang/json/GENERIC_from_json.py +msgid "engraved parabolic dish" +msgid_plural "engraved parabolic dishes" +msgstr[0] "雕ē‰ˆęŠ›ē‰©å½¢ē¢Ÿé¢" + +#. ~ Description for {'str': 'engraved parabolic dish', 'str_pl': 'engraved +#. parabolic dishes'} +#: lang/json/GENERIC_from_json.py +msgid "" +"This hefty parabolic dish is engraved with an unrecognizable pattern of " +"symbols that might, at a guess, be some sort of circuitry pattern - or maybe" +" a religious incantation." +msgstr "čæ™äøŖę²‰é‡ēš„ꊛē‰©å½¢ē¢Ÿé¢äøŠę–¹é›•åˆ»ē€äø€å¤§å—ę— ę³•č¾Ø认ēš„ē¬¦å·å›¾ę”ˆļ¼ŒåÆčƒ½ę˜ÆꟐē§ē”µč·Æå›¾ę”ˆļ¼Œęˆ–者ę˜ÆꟐē§å®—ę•™å’’čÆ­ć€‚" + +#: lang/json/GENERIC_from_json.py +msgid "oblong device" +msgid_plural "oblong devices" +msgstr[0] "ę¤­åœ†č£…ē½®" + +#. ~ Description for {'str': 'oblong device'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Perfectly smooth, cool to the touch, and a dull blue-grey colour, this looks" +" almost like a perfect riverstone at first glance. Its artificial nature is" +" betrayed on closer inspection by a network of intricate patterns visible as" +" a slight difference in the reflection of light off its surface." +msgstr "" +"它外č”Ø非åøøå…‰ę»‘ļ¼Œę‰‹ę„Ÿå†°å‡‰ļ¼Œę•£å‘ē€ęš—č“ē°č‰²åœ°å…‰ę³½ļ¼Œä¹äø€ēœ‹å‡ ä¹Žåƒäø€äøŖ完ē¾Žēš„鹅卵ēŸ³ć€‚它ēš„äŗŗå·„ęœ¬č“ØåœØꛓčæ‘č·ē¦»ēš„观åÆŸę—¶ę‰ę˜¾éœ²å‡ŗę„ļ¼ŒäøŠé¢ęœ‰äø€äøŖå¤ę‚čŠ±ēŗ¹ęž„ęˆēš„ē½‘ē»œļ¼ŒčŠ±ēŗ¹č”Øé¢ę‰€åå°„ēš„å…‰ēŗæäøŽčƒŒę™Æ꜉ē»†å¾®ēš„å·®åˆ«ć€‚" + #: lang/json/GENERIC_from_json.py msgid "sheet of glass" msgid_plural "sheets of glass" @@ -62304,14 +62425,14 @@ msgstr "åœØēŽ°å®žäø»ä¹‰ēš„ęøøꈏäø­ę·»åŠ ę›“多ēš„ē§‘幻元ē“ ć€‚é•æꜟē›®ę ‡ę˜Æ #: lang/json/MOD_INFO_from_json.py msgid "Blaze Industries" -msgstr "变形ę€Ŗå·„äøš" +msgstr "Blaze č½½å…·å·„äøš" #. ~ Description for Blaze Industries #: lang/json/MOD_INFO_from_json.py msgid "" "Introduces the fictional corporation Blaze Industries, bringing advanced " "vehicle modification to the consumer." -msgstr "加兄äŗ†ä»‹ē»äŗ†č™šęž„ēš„变形ę€Ŗå·„äøšå…¬åøļ¼Œäøŗę¶ˆč“¹č€…åø¦ę„先čæ›ēš„č½½å…·ę”¹č£…ä»¶ć€‚" +msgstr "向ęøøꈏäø­ę·»åŠ äŗ†č™šęž„å…¬åø[Blaze č½½å…·å·„äøš],ę—ØåœØ将先čæ›ēš„ę±½č½¦ę”¹č£…ä»¶ęœåŠ”äŗŽę¶ˆč“¹č€…." #: lang/json/MOD_INFO_from_json.py msgid "C.R.I.T Expansion Mod" @@ -63104,6 +63225,22 @@ msgid "" msgstr "" "čæ™å°äøåÆ»åøøēš„č£…ē½®ēœ‹čµ·ę„像äø€äøŖ갔豔갔ēƒå’Œäø€äøŖ四ēæ¼ę— äŗŗęœŗēš„ē»„åˆä½“ć€‚åœØč£…ęœ‰éƒØ件ēš„大ē®±å­äø‹é¢ļ¼Œę‚¬ęŒ‚ē€äø€äøŖ小型ēš„é“°ęŽ„å¼č£…å¤‡ļ¼ŒäøŠé¢ęœ‰ęŠŠé›†ęˆę­„ęžŖć€‚å®ƒēš„čžŗꗋę”Ø偶尔ēŸ­ęš‚地开åÆļ¼Œč€ŒåŽå†ę¬”关闭ļ¼Œä½æ它äøå—ę°”ęµå½±å“ļ¼Œé•æꗶ闓äæęŒé™ę­¢ć€‚它ēœ‹čµ·ę„čƒ½å¤ŸåœØē©ŗäø­ę‚¬ęµ®å¾ˆé•æäø€ę®µę—¶é—“ę‰ä¼šč€—å°½ē”µåŠ›ć€‚" +#: lang/json/MONSTER_from_json.py +msgid "feral human" +msgid_plural "feral humans" +msgstr[0] "野ꀧē–Æäŗŗ" + +#. ~ Description for {'str': 'feral human'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pupils dilated and what remains to be seen of the iris and sclera are " +"bloodshot. It still breathes but the zombies treat it like one of them." +msgstr "ēž³å­”ę‰©å¤§ļ¼Œēœ¼äø­ę®‹å­˜ēš„č™¹č†œå’Œēœ¼ē™½å·²ē»å……č”€å˜å¾—é²œēŗ¢ć€‚它čæ˜čƒ½å‘¼åøļ¼Œä½†äø§å°ø们已ē»ęŠŠå®ƒå½“ęˆč‡Ŗå·±äø­ēš„äø€å‘˜ć€‚" + +#: lang/json/MONSTER_from_json.py +msgid "They throw a loose brick at you!" +msgstr "å®ƒå‘ä½ ęŠ•ęŽ·äŗ†äø€å—ē¢ŽēŸ³ļ¼" + #: lang/json/MONSTER_from_json.py msgid "alpha razorclaw" msgid_plural "alpha razorclaws" @@ -66509,6 +66646,20 @@ msgid "" "of infesting sewer lines." msgstr "čæ™ę˜Æäø€ē§å…·ęœ‰ę”»å‡»ę€§ēš„变异ē›²č›‡ļ¼Œåœ°äø‹ēš„ē”Ÿę“»čµ‹äŗˆäŗ†å…¶ę·”é»„č‰²ēš„čŗÆä½“ć€‚čæ™ē§ē”Ÿē‰©åœØ地äø‹ē”Ÿę“»ļ¼Œå¹¶ä»„其ē¾¤čšåœØäø‹ę°“道ēš„ä¹ ę€§č€Œå‘½åć€‚" +#: lang/json/MONSTER_from_json.py +msgid "prototype laser turret" +msgid_plural "prototype laser turrets" +msgstr[0] "原型ęæ€å…‰ē‚®å””" + +#. ~ Description for {'str': 'prototype laser turret'} +#: lang/json/MONSTER_from_json.py +msgid "" +"This appears to be a very experimental automated tower. Plating-less and " +"seemingly half-built, it's little more than an oversized laser emitter and a" +" camera, both welded to a swiveling platform." +msgstr "" +"它似乎ę˜Æäø€å°å®žéŖŒę€§ēš„č‡ŖåŠØ化ē‚®å””ć€‚å®ƒčæ˜ę²”č¢«å®‰č£…äøŠč£…ē”²ęæļ¼Œēœ‹čµ·ę„像ę˜ÆåŠęˆå“äø€čˆ¬ļ¼Œåƒę˜ÆåœØäø€å°åŠ å¤§å·ēš„ęæ€å…‰å‘å°„å™ØäøŠå®‰č£…äŗ†äø€äøŖę‘„åƒå¤“ļ¼Œäø¤č€…éƒ½č¢«ē„ŠęŽ„åœØäø€äøŖčƒ½å¤Ÿę—‹č½¬ēš„ē‚®å””åŗ•åŗ§äøŠć€‚" + #: lang/json/MONSTER_from_json.py msgid "blob" msgid_plural "blobs" @@ -67235,6 +67386,22 @@ msgid "" "and its eyes bulge with black goo." msgstr "äø€ę”ēœ‹ä¼¼ę­£åøøēš„ē¾Žę“²ē‹®ļ¼Œä½†ä»”ē»†č§‚åƟ会发ēŽ°å®ƒēš„后č…æč‚æäŗ†ļ¼Œēœ¼ē›å‡øčµ·å¹¶ęµē€é»‘č‰²ēš„ē²˜ę¶²ć€‚" +#: lang/json/MONSTER_from_json.py +msgid "zombie horse" +msgid_plural "zombie horses" +msgstr[0] "äø§å°ø马" + +#. ~ Description for {'str': 'zombie horse'} +#: lang/json/MONSTER_from_json.py +msgid "" +"From the looks of this zombie horse's ghastly features, with its protruding " +"ribs, whitish skull, and empty eyes, the exposed part of the internal organs" +" shows a seemingly lifeless color, and the black body fluid drips slowly. " +"The new strength makes the horse no longer dependent on its muscles, but it " +"can still pursue the enemy quickly." +msgstr "" +"čæ™åŒ¹äø§å°øé©¬ęœ‰ē€åÆꀕēš„外č”Øļ¼Œå®ƒēš„č‚‹éŖØēŖå‡ŗć€å¤“éŖØ发ē™½ć€ēœ¼ē›ē©ŗę“žļ¼Œč£ø露ēš„éƒØåˆ†å†…č„å‘ˆēŽ°å‡ŗäø€ē§ēœ‹ä¼¼ęÆ«ę— ē”Ÿę°”ēš„é¢œč‰²ļ¼Œé»‘č‰²ēš„ä½“ę¶²ē¼“ē¼“从čŗ«äøŠę»“äø‹ć€‚čæ™åŒ¹é©¬ę‰€čŽ·å¾—ēš„ę–°åŠ›é‡č®©å®ƒäøå†éœ€č¦ä¾é č‚Œč‚‰ļ¼Œä½†å®ƒä»čƒ½čæ…速čæ½å‡»ę•Œäŗŗ怂" + #: lang/json/MONSTER_from_json.py msgid "Tiger wight" msgid_plural "Tiger wights" @@ -67247,6 +67414,34 @@ msgid "" "eyes wide open and shining black." msgstr "čæ™åŖåŽŸęœ¬ēœ‹äøŠåŽ»å¾ˆę­£åøøēš„老虎走起č·Æę„ę‘‡ę‘‡ę™ƒę™ƒēš„ļ¼Œäø‹å·“ę¾å¼›ļ¼Œēœ¼ē›ēå¾—大大ēš„ļ¼Œę¼†é»‘ēš„ēœ¼ē›ę­£é—Ŗé—Ŗ发äŗ®ć€‚" +#: lang/json/MONSTER_from_json.py +msgid "zombie cow" +msgid_plural "zombie cows" +msgstr[0] "äø§å°øē‰›" + +#. ~ Description for {'str': 'zombie cow'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Once a placid cow, this leathery horror stumbles and shudders, its pulsing " +"black eyes scanning for prey beneath wicked horns. It is big and heavy and " +"murderous." +msgstr "ę›¾ē»ę˜Æäø€å¤“平静ēš„ęƍē‰›ļ¼Œčæ™åŖēš®é©åŒ…č£¹ēš„ꁐꀖę€Ŗē‰©č¹’č·šē€ļ¼Œé¢¤ęŠ–ē€ļ¼Œē”Ø它é‚Ŗꁶēš„ē‰›č§’äø‹ēŖå‡ŗēš„é»‘č‰²ēœ¼ē›äøę–­ęœåÆ»ē€ēŒŽē‰©ć€‚它又大又重ļ¼Œč€Œäø”非åøøå‡¶ę®‹ć€‚" + +#: lang/json/MONSTER_from_json.py +msgid "woodland wight" +msgid_plural "woodland wights" +msgstr[0] "ęž—åœ°å¹½ēµé¹æ" + +#. ~ Description for {'str': 'woodland wight'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pale, stumbling white-tailed deer with blackened eyes and drooling slime " +"down its neck. Its legs twist and bend in strange, haphazard directions, " +"but with unnatural strength and speed. Preys on coyotes, wolves, and giant " +"spider mutants." +msgstr "" +"äø€åŖč„øč‰²č‹ē™½ć€ę­„å±„č¹’č·šēš„ē™½å°¾é¹æļ¼Œå®ƒēš„ēœ¼ē›å‘黑ļ¼Œé»‘č‰²å£ę°“é”ŗē€č„–子äøę–­ę»“č½ć€‚å®ƒēš„å››č‚¢ę‰­åŠØå¼Æę›²ęˆå„‡ę€Ŗ而随ꄏēš„ęØ”ę ·ļ¼Œä½†å……ę»”äŗ†éžč‡Ŗē„¶ēš„力量和速åŗ¦ć€‚它ē”šč‡³čƒ½å¤ŸēŒŽę€éƒŠē‹¼ć€ē‹¼å’Œå·Ø型变ē§čœ˜č››ć€‚" + #: lang/json/MONSTER_from_json.py msgid "mass of zombie spiders" msgid_plural "mass of zombie spiderss" @@ -67994,11 +68189,11 @@ msgstr "" "äø€äøŖå…Øčŗ«č‚Œč‚‰éƒ½å‘ē”Ÿäŗ†å˜å¼‚ēš„č¶…å¤§å—å¤“äø§å°øļ¼Œä½“åž‹ēŗ¦äøŗ六äøŖäŗŗ大小ļ¼ŒåŒč‡‚ꞁäøŗå¼ŗ壮ļ¼ŒåŠ›é‡ä¹‹å¤§č¶³ä»„击ē¢Žå¢™å£ļ¼Œę„¤ę€’ēš„ē “åę¬²ę”Æ配ē€å®ƒē²‰ē¢Žē€ę‰€čƒ½č§åˆ°ēš„äø€åˆ‡ļ¼Œęžäøŗå±é™©ć€‚" #: lang/json/MONSTER_from_json.py -msgid "feral hunter" -msgid_plural "feral hunters" -msgstr[0] "野ꀧē‹©ēŒŽč€…" +msgid "zombie hunter" +msgid_plural "zombie hunters" +msgstr[0] "ē‹©ēŒŽč€…äø§å°ø" -#. ~ Description for {'str': 'feral hunter'} +#. ~ Description for {'str': 'zombie hunter'} #: lang/json/MONSTER_from_json.py msgid "" "This once-human body is barely recognizable, scrambling about on all fours, " @@ -68082,11 +68277,11 @@ msgstr "" "初ēœ‹äøŠåŽ»čæ™åŖę€Ŗē‰©ēœ‹čµ·ę„åŖäøčæ‡ę˜Æäø€äøŖę€Ŗå¼‚č€Œę²¹č…»ēš„ē©ŗ壳ļ¼Œęµ‘čŗ«č‚æ胀ļ¼Œč®øå¤šę·±é»‘č‰²ēš„č„“ē–±åˆŗē “äŗ†å®ƒēš„č”Øēš®ć€‚å½“ä½ čµ°čæ‘å®ƒę—¶ļ¼Œå®ƒēš„ēœ¼ē›å‘å‡ŗäŗ†ēŗ¢å…‰å¹¶éœ²å‡ŗäŗ†ē—›č‹¦ēš„ę€Ŗē¬‘ļ¼›å®ƒēš„ēš®č‚¤ę’•č£‚å¼€ļ¼Œå†…č„å……ę»”äŗ†ę— äøŽä¼¦ęƔēš„ē¹ę®–力ļ¼Œå®ƒēš„ē›®å…‰ęæ€å‘äŗ†ä½ åƹ它那å¹æå¤§ę— č¾¹č€Œåˆéžäŗŗ般ē‹‚å–œēš„ęęƒ§ć€‚" #: lang/json/MONSTER_from_json.py -msgid "feral runner" -msgid_plural "feral runners" -msgstr[0] "野ꀧčæ½ēŒŽč€…" +msgid "zombie runner" +msgid_plural "zombie runners" +msgstr[0] "čæ½ēŒŽč€…äø§å°ø" -#. ~ Description for {'str': 'feral runner'} +#. ~ Description for {'str': 'zombie runner'} #: lang/json/MONSTER_from_json.py msgid "" "This recently-risen body moves quickly, darting its head back and forth and " @@ -68094,11 +68289,11 @@ msgid "" msgstr "čæ™äøŖåˆšå¤ę“»äøä¹…ēš„äø§å°øč·‘å¾—å¾ˆåæ«ļ¼Œå®ƒēš„夓ē„žē»č“Øäø€ę ·ēš„前后äøę–­ę™ƒåŠØ并啮咬č‡Ŗå·±ēš„ꉋ怂" #: lang/json/MONSTER_from_json.py -msgid "feral predator" -msgid_plural "feral predators" -msgstr[0] "野ꀧꍕēŒŽč€…" +msgid "zombie predator" +msgid_plural "zombie predators" +msgstr[0] "ꍕēŒŽč€…äø§å°ø" -#. ~ Description for {'str': 'feral predator'} +#. ~ Description for {'str': 'zombie predator'} #: lang/json/MONSTER_from_json.py msgid "" "With its joints in odd places and angles, this humanoid creature prowls " @@ -72202,7 +72397,7 @@ msgstr "ē–¼ē—›" msgid "Increases pain" msgstr "ęå‡ē–¼ē—›" -#: lang/json/SPELL_from_json.py src/character.cpp src/npctalk.cpp +#: lang/json/SPELL_from_json.py src/character.cpp src/talker_npc.cpp msgid "Tired" msgstr "ē–²å€¦" @@ -73285,7 +73480,7 @@ msgstr "čæ™ä»Ŗ式会创造å‡ŗäø€å—äøŽé£Žęš“å”‘é€ č€…å…±éø£ēš„小ēŸ³å—ć€‚ä½ åÆ msgid "Lightning Blast" msgstr "é—Ŗē”µå†²å‡»" -#: lang/json/SPELL_from_json.py src/weather_data.cpp +#: lang/json/SPELL_from_json.py lang/json/weather_type_from_json.py msgid "Lightning Storm" msgstr "é—Ŗē”µé›·ęš“" @@ -74160,10 +74355,10 @@ msgstr[0] "RM XIII ęˆ˜ę–—č£…ē”²" #. ~ Description for {'str': 'RM13 combat armor'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. Use it to turn it on." -msgstr "čæ™å„—굁ēŗæé€ åž‹ć€åŒ…č¦†å…Øčŗ«ēš„é»‘č‰²å†›ē”Øč£…ē”²ä»£č”Øē€Rivtechēš„ęŸ”ę€§åŠØåŠ›č£…ē”²ęŠ€ęœÆēš„é”¶å³°ć€‚ä½æē”Øęœ€å¤šå†…ē½®ēš„十äøŖ钚ē‡ƒę–™ē”µę± ä¾›ē”µć€‚ęæ€ę“»å®ƒę„åÆåŠØ怂" +msgstr "čæ™å„—굁ēŗæé€ åž‹ć€åŒ…č¦†å…Øčŗ«ēš„é»‘č‰²å†›ē”Øč£…ē”²ä»£č”Øē€Rivtechēš„ęŸ”ę€§åŠØåŠ›č£…ē”²ęŠ€ęœÆēš„é”¶å³°ć€‚ä½æē”Øē‹¬å®¶äø“利ēš„内ē½®é’šē‡ƒę–™ē”µę± ä¾›ē”µć€‚ęæ€ę“»å®ƒę„åÆåŠØ怂" #: lang/json/TOOL_ARMOR_from_json.py msgid "RM13 combat armor (on)" @@ -74174,12 +74369,12 @@ msgstr[0] "RM XIII ęˆ˜ę–—č£…ē”²ļ¼ˆåÆåŠØļ¼‰" #. armors (on)'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. It is turned on, and continually draining " "power. Use it to turn it off." msgstr "" -"čæ™å„—굁ēŗæé€ åž‹ć€åŒ…č¦†å…Øčŗ«ēš„é»‘č‰²å†›ē”Øč£…ē”²ä»£č”Øē€Rivtechēš„ęŸ”ę€§åŠØåŠ›č£…ē”²ęŠ€ęœÆēš„é”¶å³°ć€‚ä½æē”Øęœ€å¤šå†…ē½®ēš„十äøŖ钚ē‡ƒę–™ē”µę± ä¾›ē”µć€‚ē›®å‰å·„作äø­ļ¼Œęæ€ę“»å®ƒę„å…³é—­ć€‚" +"čæ™å„—굁ēŗæé€ åž‹ć€åŒ…覆å…Øčŗ«ēš„é»‘č‰²å†›ē”Øč£…ē”²ä»£č”Øē€Rivtechēš„ęŸ”ę€§åŠØåŠ›č£…ē”²ęŠ€ęœÆēš„é”¶å³°ć€‚ä½æē”Øē‹¬å®¶äø“利ēš„内ē½®é’šē‡ƒę–™ē”µę± ä¾›ē”µć€‚ē›®å‰å·„作äø­ļ¼Œęæ€ę“»å®ƒę„å…³é—­ć€‚" #: lang/json/TOOL_ARMOR_from_json.py msgid "5-point anchor" @@ -75246,9 +75441,9 @@ msgstr[0] "å¤Ŗé˜³čƒ½čƒŒåŒ…ļ¼ˆęŠ˜å ļ¼‰" msgid "" "Personal portable charging system consisting of an array of solar panels " "neatly folded in a form of a large backpack. It can be worn as one, and has" -" an integrated cable to plug it into a cable charger system." +" an integrated cable to plug it into a cable charger system CBM." msgstr "" -"äø€å„—äøŖäŗŗä¾æęŗå¼å……čƒ½ē³»ē»Ÿļ¼Œē”±äø€ē³»åˆ—å¤Ŗé˜³čƒ½ē”µę± ęæē»„ęˆļ¼Œéƒ½č¢«ę•“é½åœ°ęŠ˜å å¹¶č£…å…„äø€äøŖå¤§čƒŒåŒ…ć€‚å®ƒåÆ仄äø€ä½“式ē©æē€åœØčŗ«äøŠļ¼Œå¹¶äø”é›†ęˆäŗ†äø€ę”åÆę’å…„ē”µē¼†å……ē”µå™Øēš„ē”µē¼†ć€‚" +"äø€å„—äøŖäŗŗä¾æęŗå¼å……čƒ½ē³»ē»Ÿļ¼Œē”±äø€ē³»åˆ—å¤Ŗé˜³čƒ½ē”µę± ęæē»„ęˆļ¼Œéƒ½č¢«ę•“é½åœ°ęŠ˜å å¹¶č£…å…„äø€äøŖå¤§čƒŒåŒ…ć€‚å®ƒåÆ仄äø€ä½“式ē©æē€åœØčŗ«äøŠļ¼Œå¹¶äø”é›†ęˆäŗ†äø€ę”åÆę’å…„ē”µē¼†å……ē”µå™ØCBMēš„ē”µē¼†ć€‚" #: lang/json/TOOL_ARMOR_from_json.py msgid "solar backpack (unfolded)" @@ -75260,8 +75455,8 @@ msgstr[0] "å¤Ŗé˜³čƒ½čƒŒåŒ…ļ¼ˆå±•å¼€ļ¼‰" #: lang/json/TOOL_ARMOR_from_json.py msgid "" "Unfolded array of portable solar panels ready to push some power into an " -"active cable charger system." -msgstr "äø€å„—å·²ē»å±•å¼€ēš„ä¾æęŗ式å¤Ŗé˜³čƒ½ē”µę± ęæ阵列ļ¼Œå‡†å¤‡å„½äøŗē”µē¼†å……ē”µå™Øęä¾›čƒ½é‡ć€‚" +"active cable charger system CBM." +msgstr "äø€å„—å·²ē»å±•å¼€ēš„ä¾æęŗ式å¤Ŗé˜³čƒ½ē”µę± ęæ阵列ļ¼Œå‡†å¤‡å„½äøŗē”µē¼†å……ē”µå™ØCBMęä¾›čƒ½é‡ć€‚" #: lang/json/TOOL_ARMOR_from_json.py msgid "riot helmet" @@ -79934,10 +80129,10 @@ msgstr "小型风åŠØ力ē£Øļ¼ŒåÆå°†å«ę·€ē²‰ēš„ē‰©å“åŠ å·„ęˆé¢ē²‰ć€‚通čæ‡å»ŗ msgid "" "This is an advanced version of the unified power supply, or UPS. This " "device has been significantly redesigned to provide better efficiency as " -"well as to consume plutonium fuel cells rather than batteries. Sadly, its " -"plutonium reactor can't be charged in UPS charging station." +"well as to consume plutonium fuel batteries rather than regular batteries. " +"Sadly, its plutonium reactor can't be charged in UPS charging station." msgstr "" -"čæ™ę˜Æē»Ÿäø€åŒ–ē”µęŗēš„å…ˆčæ›ē‰ˆęœ¬ć€‚ę­¤č£…ē½®č¢«å¤§å¹…é‡ę–°č®¾č®”ļ¼Œä»„ęä¾›ę›“é«˜ēš„ę•ˆēŽ‡ļ¼Œå¹¶ę”¹äøŗę¶ˆč€—é’šē‡ƒę–™ē”µę± ć€‚č€Œäø”ę›“č–„ć€ę›“č½»ć€‚åÆꃜēš„ę˜Æļ¼Œå®ƒēš„钚反åŗ”å †äøčƒ½åœØUPSē”µęŗå……ē”µē«™å……ē”µć€‚" +"čæ™ę˜ÆUPSē»Ÿäø€åŒ–ē”µęŗēš„升ēŗ§ē‰ˆęœ¬ć€‚ę­¤č£…ē½®č¢«å¤§å¹…é‡ę–°č®¾č®”ļ¼Œä»„ęä¾›ę›“é«˜ēš„ę•ˆēŽ‡ļ¼Œå¹¶ę”¹ē”Ø钚ē‡ƒę–™ē”µę± ä¾›ē”µć€‚åÆꃜēš„ę˜Æļ¼Œå®ƒēš„钚反åŗ”å †äøčƒ½åœØUPSē”µęŗå……ē”µē«™å……ē”µć€‚" #. ~ Description for {'str': 'camera'} #: lang/json/TOOL_from_json.py @@ -80768,12 +80963,13 @@ msgstr "ä½ ę‹‰å¼€äŗ†EMPꉋ雷ēš„äæé™©é”€ć€‚" #: lang/json/TOOL_from_json.py msgid "" "This is a grenade that generates an electromagnetic pulse with a low-" -"inductance capacitor bank discharged into a single-loop antenna. Use this " -"item to pull the pin and light the fuse, turning it into an active EMP " -"grenade. You will then have three turns before it detonates, creating an " -"EMP field that damages robots and drains bionic energy." +"inductance capacitor bank discharged into a single-loop antenna. It also " +"produces a mild electric shock cloud. Use this item to pull the pin and " +"light the fuse, turning it into an active EMP grenade. You will then have " +"three turns before it detonates, creating an EMP field that damages robots " +"and drains bionic energy." msgstr "" -"äø€äøŖä½æē”Ø低ē”µę„Ÿē”µå®¹čæžęŽ„单ēŽÆ天ēŗæę”¾ē”µę„äŗ§ē”Ÿē”µē£č„‰å†²ēš„EMPꉋ雷怂ꋔäø‹å®‰å…Øé”€ę„ä½æē”ØEMPꉋ雷ļ¼Œä½ ęœ‰äø‰å›žåˆę—¶é—“åŽ»ę‰”ęŽ‰å®ƒļ¼Œå®ƒä¼šäŗ§ē”Ÿäø€äøŖEMPē”µåœŗę„ē “坏ęœŗå™Øäŗŗå’Œę¶ˆč€—ē”ŸåŒ–čƒ½é‡ļ¼Œä»„ä½æ其å‘Ø囓ēš„ē”µå­č®¾å¤‡ē˜«ē—Ŗ怂" +"äø€äøŖä½æē”Ø低ē”µę„Ÿē”µå®¹čæžęŽ„单ēŽÆ天ēŗæę”¾ē”µę„äŗ§ē”Ÿē”µē£č„‰å†²ēš„EMPę‰‹é›·ć€‚ę”¾ē”µä¼šäŗ§ē”Ÿäø€å›¢ä¼šč½»å¾®ē”µå‡»ę•Œäŗŗēš„ē”µäŗ‘怂ꋔäø‹å®‰å…Øé”€ę„ä½æē”ØEMPꉋ雷ļ¼Œä½ ęœ‰äø‰å›žåˆę—¶é—“åŽ»ę‰”ęŽ‰å®ƒļ¼Œå®ƒä¼šäŗ§ē”Ÿäø€äøŖEMPē”µåœŗę„ē “坏ęœŗå™Øäŗŗå’Œę¶ˆč€—ē”ŸåŒ–čƒ½é‡ļ¼Œä»„ä½æ其å‘Ø囓ēš„ē”µå­č®¾å¤‡ē˜«ē—Ŗ怂" #: lang/json/TOOL_from_json.py msgid "active EMP grenade" @@ -80784,10 +80980,10 @@ msgstr[0] "EMPꉋ雷ļ¼ˆę— äæé™©ļ¼‰" #: lang/json/TOOL_from_json.py msgid "" "This EMP grenade is active, and will shortly detonate, creating a large EMP " -"field that damages robots and drains bionic energy. You may not want to be " -"holding it much longer." +"field that damages robots and drains bionic energy as well as a mild " +"electric shock cloud. You may not want to be holding it much longer." msgstr "" -"很儽ļ¼Œčæ™äøŖEMPę‰‹é›·å·²ē»č¢«ęæ€ę“»äŗ†ļ¼Œå¾ˆåæ«å°±ä¼šå¼•ēˆ†å¹¶äŗ§ē”Ÿē”µē£č„‰å†²ļ¼Œčæ™ä¼šē “坏附čæ‘ēš„ęœŗå™Øäŗŗå¹¶ęŸč€—ē”ŸåŒ–čƒ½é‡ć€‚ä½ éœ€č¦åšēš„å°±ę˜ÆęŠŠå®ƒē”Ø力äø¢å‡ŗ去ļ¼Œē„¶åŽå°±ē­‰ē€ēž§å§ć€‚" +"很儽ļ¼Œčæ™äøŖEMPę‰‹é›·å·²ē»č¢«ęæ€ę“»äŗ†ļ¼Œå¾ˆåæ«å°±ä¼šå¼•ēˆ†å¹¶äŗ§ē”Ÿē”µē£č„‰å†²ä»„及äø€å›¢ē”µäŗ‘ļ¼Œčæ™ä¼šē “坏附čæ‘ēš„ęœŗå™Øäŗŗå¹¶ęŸč€—ē”ŸåŒ–čƒ½é‡ć€‚ä½ éœ€č¦åšēš„å°±ę˜ÆęŠŠå®ƒē”Ø力äø¢å‡ŗ去ļ¼Œē„¶åŽå°±ē­‰ē€ēž§å§ć€‚" #: lang/json/TOOL_from_json.py msgid "incendiary grenade" @@ -82676,7 +82872,7 @@ msgstr[0] "铁钳" msgid "" "These are long, metal tongs. They are commonly used for cooking or in " "metalworking fabrication recipes." -msgstr "é•æ颈ēš„铝制ē«é’³ć€‚ę˜Æēƒ¹é„Ŗęˆ–é‡‘å±žåŠ å·„åˆ¶é€ ēš„åøøē”Øå·„å…·ć€‚" +msgstr "äø€ęŠŠé•æé•æēš„金属ē«é’³ć€‚ę˜Æēƒ¹é„Ŗęˆ–é‡‘å±žåŠ å·„åˆ¶é€ ēš„åøøē”Øå·„å…·ć€‚" #: lang/json/TOOL_from_json.py msgid "sandpaper" @@ -84864,8 +85060,8 @@ msgstr "ä½ č®¾ē½®äŗ†éœ°å¼¹ęžŖé™·é˜±ć€‚" #. ~ Description for {'str': 'shotgun trap'} #: lang/json/TOOL_from_json.py msgid "" -"This is a simple tripwire is attached to the trigger of a loaded double-" -"barreled shotgun. When pulled, the shotgun fires. Two shells are loaded; " +"This is a simple tripwire is attached to the trigger of a loaded double " +"slamfire shotgun. When pulled, the shotgun fires. Two shells are loaded; " "the first time the trigger is pulled, one or both shells may be discharged." msgstr "äø€ę ¹č½»å·§ēš„ę£‰ēŗæč½»ęŸ”åœ°čæžåœØäŗ†äø€ęŠŠåŒē®”霰弹ęžŖēš„ę‰³ęœŗ之äøŠļ¼ŒåŖč¦č½»č½»äø€ę‹Øļ¼Œéœ°å¼¹ęžŖ就会双ē®”齐发ļ¼Œē»™é‚£ä½äøå¹øēš„家伙äø€äøŖē—›åæ«ć€‚" @@ -85459,7 +85655,7 @@ msgstr[0] "ę‰‹é’³" msgid "" "This is a basic pair of slip-joint pliers, able to handle basic mechanical " "work. Anything too complex will require a wrench." -msgstr "čæ™ę˜Æäø€ęŠŠåŸŗęœ¬ēš„鲤鱼钳ļ¼Œčƒ½ē”Øę„åšäø€äŗ›åŸŗęœ¬ēš„ęœŗę¢°å·„ä½œļ¼Œå¦‚ęžœä½ č¦åšę›“å¤ę‚ēš„å·„作ļ¼Œé‚£å°±éœ€č¦äø€äøŖę‰³ę‰‹äŗ†ć€‚" +msgstr "äø€ęŠŠå¤–å½¢ē®€å•ēš„鲤鱼钳ļ¼ŒåŖčƒ½ē”Øę„åšäø€äŗ›åŸŗęœ¬ēš„ęœŗę¢°å·„ä½œļ¼Œå†å¤ę‚äø€ē‚¹ēš„ę“ä½œå°±éœ€č¦ē”Øę‰³ę‰‹äŗ†ć€‚" #: lang/json/TOOL_from_json.py msgid "electric polisher" @@ -88610,7 +88806,7 @@ msgstr "ē„ŠęŽ„" #: lang/json/activity_type_from_json.py msgid "cracking" -msgstr "č§£é”äæé™©ęŸœ" +msgstr "č§£é”äæé™©ē®±" #: lang/json/activity_type_from_json.py msgid "picking lock" @@ -91828,6 +92024,26 @@ msgstr "ē”Øē‚¹ē„ŠåŠ å›ŗåŗŸę—§é‡‘属墙" msgid "Build Junk Metal Floor" msgstr "å»ŗ造åŗŸę—§é‡‘属地ęæ" +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Bolts" +msgstr "ē”Øčžŗꠓå»ŗ造金属åŗŸę–™ę”„" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Welder" +msgstr "ē”Øē„ŠęžŖå»ŗ造金属åŗŸę–™ę”„" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bench" +msgstr "å»ŗ造金属åŗŸę–™å‡³" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Table" +msgstr "å»ŗ造金属åŗŸę–™ę”Œ" + +#: lang/json/construction_from_json.py +msgid "Lay down decorative ground cable" +msgstr "å»ŗé€ č£…é„°ē”Øē”µēŗæ" + #: lang/json/construction_from_json.py msgid "Build Pillow Fort" msgstr "å»ŗé€ ęž•å¤“å ”åž’" @@ -94225,6 +94441,15 @@ msgstr "ä½ ēŽ°åœØčƒ½é‡ę–°ęŽ§åˆ¶ä½ ēš„č‚Œč‚‰äŗ†ļ¼" msgid "Your muscles won't cooperate!" msgstr "ä½ ēš„č‚Œč‚‰äøå—ęŽ§åˆ¶äŗ†ļ¼" +#: lang/json/effects_from_json.py +msgid "Minor Bleeding" +msgstr "č½»åŗ¦å‡ŗ蔀" + +#. ~ Description of effect 'Minor Bleeding'. +#: lang/json/effects_from_json.py +msgid "Tis but a scratch." +msgstr "čæ™äøčæ‡ę˜Æē‚¹å°åˆ’ä¼¤č€Œå·²ļ¼" + #: lang/json/effects_from_json.py msgid "Bleeding" msgstr "굁蔀" @@ -94252,7 +94477,25 @@ msgstr "äø„é‡å¤±č”€" msgid "You are rapidly losing blood." msgstr "ä½ ę­£åœØčæ…é€Ÿęµå¤±č”€ę¶²ć€‚" -#. ~ Apply message for effect(s) 'Bleeding, Bad Bleeding, Heavy Bleeding'. +#: lang/json/effects_from_json.py +msgid "Heavy Arterial Bleeding" +msgstr "åŠØč„‰å¤§å‡ŗ蔀" + +#. ~ Description of effect 'Heavy Arterial Bleeding'. +#: lang/json/effects_from_json.py +msgid "Blood is gushing from you like a fountain." +msgstr "č”€åƒå–·ę³‰äø€ę ·ä»Žä½ čŗ«äøŠå–·ę¶Œč€Œå‡ŗ怂" + +#. ~ Apply message for effect(s) 'Minor Bleeding, Minor Bleeding, Minor +#. Bleeding, Minor Bleeding, Minor Bleeding, Bleeding, Bleeding, Bleeding, +#. Bleeding, Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, +#. Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad +#. Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, +#. Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy +#. Bleeding, Heavy Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding'. #: lang/json/effects_from_json.py msgid "You're bleeding!" msgstr "ä½ åœØ굁蔀ļ¼" @@ -95005,42 +95248,94 @@ msgstr "ä½ ēš„ē¼ŗ钙ē—‡ēŠ¶åæ«č¦č§£é™¤äŗ†ć€‚" msgid "Your bones become stronger as your calcium deficiency improves." msgstr "ä½ ēš„éŖØå¤“å˜å¾—ę›“å¼ŗ韧ļ¼Œå› äøŗä½ äøå†ē¼ŗ钙äŗ†ć€‚" +#: lang/json/effects_from_json.py +msgid "Early iron deficiency" +msgstr "ę—©ęœŸē¼ŗ铁ē—‡" + +#. ~ Description of effect 'Early iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"A lack of iron in your diet has hampered efficiency and regeneration of your" +" red blood cells." +msgstr "ä½ ēš„鄮食äø­é“ēš„ē¼ŗ乏阻ē¢äŗ†ēŗ¢ē»†čƒžēš„č¾“ę°§ę•ˆēŽ‡å’Œå†ē”Ÿé€Ÿåŗ¦ć€‚" + #: lang/json/effects_from_json.py msgid "Iron deficiency" msgstr "ē¼ŗ铁ē—‡" +#. ~ Description of effect 'Iron deficiency'. #: lang/json/effects_from_json.py -msgid "Early anemia" -msgstr "ę—©ęœŸč“«č”€" +msgid "" +"Prolonged lack of iron in your diet has compromised efficiency and " +"regeneration of your red blood cells." +msgstr "ä½ ēš„鄮食äø­é“ēš„é•æꜟē¼ŗä¹ęŸå®³äŗ†ēŗ¢ē»†čƒžēš„č¾“ę°§ę•ˆēŽ‡å’Œå†ē”Ÿé€Ÿåŗ¦ć€‚" #: lang/json/effects_from_json.py -msgid "Anemia" -msgstr "ē¼ŗ铁ꀧ蓫蔀" +msgid "Acute iron deficiency" +msgstr "Ꙛꜟē¼ŗ铁ē—‡" +#. ~ Description of effect 'Acute iron deficiency'. #: lang/json/effects_from_json.py msgid "" -"A lack of iron in your diet will result in progressively worsening anemia." -msgstr "ä½ ēš„鄮食äø­ē¼ŗ乏铁ļ¼Œä¼šåÆ¼č‡“ę—„ē›Šäø„重ēš„蓫蔀怂" +"Severe lack of iron in your diet results in your red blood cells dying " +"faster then they are regenerating." +msgstr "ä½ ēš„鄮食äø­é“ēš„äø„重ē¼ŗ乏ä½æ得ēŗ¢ē»†čƒžę­»äŗ”速åŗ¦ęƔ再ē”Ÿé€Ÿåŗ¦čæ˜åæ«ć€‚" -#. ~ Apply message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Apply message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#. ~ Apply message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You begin feeling increasingly tired and listless." msgstr "ä½ å¼€å§‹ę„Ÿåˆ°č¶Šę„č¶Šē–²å€¦å’Œę— ē²¾ę‰“采怂" -#. ~ Remove message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Remove message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. #: lang/json/effects_from_json.py -msgid "You no longer feel anemic." -msgstr "ä½ äøå†ę„Ÿåˆ°ä¹åŠ›ć€‚" +msgid "You are no longer in risk of becoming anemic." +msgstr "ä½ äøå†ęœ‰ē¼ŗ铁蓫蔀ēš„é£Žé™©ć€‚" -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. #: lang/json/effects_from_json.py -msgid "Your iron deficiency is nearly resolved." +msgid "Your irom deficiency is nearly resolved." msgstr "ä½ ēš„ē¼ŗ铁ē—‡ēŠ¶åæ«č¦č§£é™¤äŗ†ć€‚" -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your iron deficiency starts to improve." +msgstr "随ē€ä½ ēš„ē¼ŗ铁ē—‡ēŠ¶å¼€å§‹ę”¹å–„ļ¼Œä½ ę„Ÿč§‰ę›“加å¼ŗ壮äŗ†ć€‚" + +#: lang/json/effects_from_json.py +msgid "Early anemia" +msgstr "ę—©ęœŸč“«č”€ē—‡" + +#: lang/json/effects_from_json.py +msgid "Anemia" +msgstr "蓫蔀ē—‡" + +#: lang/json/effects_from_json.py +msgid "Acute anemia" +msgstr "ę™šęœŸč“«č”€ē—‡" + +#: lang/json/effects_from_json.py +msgid "Loss of red blood cells results in progressively worsening anemia." +msgstr "你失去äŗ†å¤§é‡ēŗ¢ē»†čƒžļ¼Œä¼šåÆ¼č‡“ę—„ē›Šäø„重ēš„蓫蔀怂" + +#. ~ Remove message for effect(s) 'Early anemia, Anemia, Acute anemia'. +#: lang/json/effects_from_json.py +msgid "You no longer feel anemic." +msgstr "ä½ äøå†ę„Ÿåˆ°č“«č”€ä¹åŠ›ć€‚" + +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. +#: lang/json/effects_from_json.py +msgid "Your anemia is nearly resolved." +msgstr "ä½ ēš„蓫蔀ē—‡ēŠ¶åæ«č¦č§£é™¤äŗ†ć€‚" + +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "Your feel stronger as your anemia starts to improve." -msgstr "随ē€ä½ ēš„č“«č”€å¼€å§‹ę”¹å–„ļ¼Œä½ ę„Ÿč§‰ę›“加å¼ŗ壮äŗ†ć€‚" +msgstr "随ē€ä½ ēš„蓫蔀ē—‡ēŠ¶å¼€å§‹ę”¹å–„ļ¼Œä½ ę„Ÿč§‰ę›“加å¼ŗ壮äŗ†ć€‚" #: lang/json/effects_from_json.py msgid "VitA deficiency" @@ -95225,6 +95520,77 @@ msgid "" "disgusting rations day in and day out?" msgstr "ę˜Æēš„ļ¼Œä½ ę“»äŗ†äø‹ę„ļ¼Œä½†čæ™ę ·ę“»ē€čæ˜ęœ‰ä»€ä¹ˆę„ä¹‰ļ¼Œę—„复äø€ę—„地吃ē€čæ™äŗ›ę¶åæƒēš„口ē²®ļ¼Ÿ" +#: lang/json/effects_from_json.py +msgid "Mild hypovolemic shock" +msgstr "č½»åŗ¦å¤±č”€ę€§ä¼‘å…‹" + +#. ~ Description of effect 'Mild hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost some blood and look somewhat pale." +msgstr "ä½ ęµäŗ†äøå°‘蔀ļ¼Œč„øč‰²ęœ‰ē‚¹č‹ē™½ć€‚" + +#: lang/json/effects_from_json.py +msgid "Moderate hypovolemic shock" +msgstr "äø­åŗ¦å¤±č”€ę€§ä¼‘å…‹" + +#. ~ Description of effect 'Moderate hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost large amount of blood, and you're not feeling well." +msgstr "ä½ å¤±č”€čæ‡å¤šļ¼Œę„Ÿč§‰äŗŗäøå¤Ŗ舒꜍怂" + +#: lang/json/effects_from_json.py +msgid "Advanced hypovolemic shock" +msgstr "äø„é‡å¤±č”€ę€§ä¼‘å…‹" + +#. ~ Description of effect 'Advanced hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost an awful lot of blood, and your condition is severe. Seek " +"medical attention." +msgstr "ä½ å¤±č”€čæ‡å¤šļ¼Œē—…ęƒ…äø„é‡ć€‚éœ€č¦ē«‹åˆ»åÆ»ę±‚åŒ»ē–—ę•‘ę²»ć€‚" + +#: lang/json/effects_from_json.py +msgid "Severe hypovolemic shock" +msgstr "重åŗ¦å¤±č”€ę€§ä¼‘å…‹" + +#. ~ Description of effect 'Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost tremendous amount of blood, and you're standing on death's door." +" Transfusion might save you." +msgstr "ä½ å¤±č”€čæ‡å¤šļ¼Œä½ ē«™åœØę­»äŗ”之é—ØäøŠć€‚ē«‹åˆ»č¾“č”€ä¹Ÿč®øčƒ½ę•‘ä½ äø€å‘½ć€‚" + +#. ~ Apply message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You have lost lot of blood, and your condition worsens." +msgstr "ä½ å¤±č”€čæ‡å¤šļ¼Œä¼‘å…‹ē—‡ēŠ¶å¼€å§‹ę¶åŒ–怂" + +#. ~ Remove message for effect(s) 'Mild hypovolemic shock, Moderate +#. hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You are no longer in shock." +msgstr "ä½ äøå†ęœ‰ä¼‘å…‹ēš„ē—‡ēŠ¶ć€‚" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your blood level increase, and you feel better, but still look pale." +msgstr "ä½ ēš„č”€é‡äøŠå‡ļ¼Œę„Ÿč§‰ä¼‘å…‹ēš„ē—‡ēŠ¶å„½å¤šäŗ†ļ¼Œä½†ä»ē„¶é¢č‰²č‹ē™½ć€‚" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your blood levels starts to improve." +msgstr "随ē€ä½ ēš„č”€é‡å¼€å§‹äøŠå‡ļ¼Œä½ ę„Ÿč§‰ę›“加å¼ŗ壮äŗ†ć€‚" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You're not dying from lack of blood, but you're not out of the woods yet." +msgstr "ä½ ē›®å‰äøä¼šå› äøŗå¤±č”€č€Œę­»ļ¼Œä½†ä½ čæ˜ę²”ęœ‰å®Œå…Ø脱ē¦»å±é™©ć€‚" + #: lang/json/effects_from_json.py msgid "Lit up" msgstr "č¢«ē…§äŗ®" @@ -97119,25 +97485,355 @@ msgid "mutated cactus" msgstr "变异ēš„ä»™äŗŗꎌ" #: lang/json/furniture_from_json.py -msgid "cooling unit" -msgstr "å†·å“č£…ē½®" +msgid "glowing tendril" +msgstr "发光卷锻" -#. ~ Description for cooling unit +#. ~ Description for glowing tendril #: lang/json/furniture_from_json.py msgid "" -"A large, blocky appliance encased in sheet metal. This commonplace fixture " -"is used for cooling large indoor areas." -msgstr "äø€å°åˆå¤§åˆę–¹č¢«åŒ…č£¹åœØ金属ęæ之äø­ēš„ē”µå™Ø怂čæ™ē§åøø见ēš„å›ŗå®šč£…ē½®ē”ØäŗŽå†·å“大型室内åŒŗåŸŸć€‚" +"A willowy tendril growing from the floor, gently waving back and forth. A " +"faint light spills from it." +msgstr "äø€ę ¹ęŸ”韧ēš„卷锻从地ęæäøŠé•æå‡ŗę„ļ¼Œč½»č½»åœ°å‰åŽę‘†åŠØē€ć€‚微弱ēš„äŗ®å…‰ä»Žé‡Œé¢å°„äŗ†å‡ŗę„ć€‚" + +#: lang/json/furniture_from_json.py +msgid "splorch!" +msgstr "咔ļ¼" #: lang/json/furniture_from_json.py lang/json/furniture_from_json.py #: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "metal screeching!" -msgstr "äø€å£°å°–锐ēš„é‡‘å±žę–­č£‚ēš„声音ļ¼" +msgid "whump!" +msgstr "哐嘔ļ¼" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py +msgid "wafting anemone" +msgstr "飘åŠØ굷葵" + +#. ~ Description for wafting anemone +#: lang/json/furniture_from_json.py +msgid "" +"A fleshy white protuberance growing from the floor, with a cluster of " +"tendrils pouring out of it. It looks almost exactly like a sea anemone, " +"even waving gently as though underwater." +msgstr "äø€äøŖ肉č“Øēš„ē™½č‰²ē”Ÿē‰©ä»Žåœ°é¢ēŖčµ·ļ¼Œäø€äø²å·é”»ä»Žč‚‰č“Øäø­ä¼øå‡ŗć€‚å®ƒēœ‹čµ·ę„å‡ ä¹Žå’Œęµ·č‘µäø€ęØ”äø€ę ·ļ¼Œē”šč‡³åƒåœØę°“é‡Œäø€ę ·č½»č½»åœ°ę‘†åŠØ怂" + +#: lang/json/furniture_from_json.py +msgid "gasping tube" +msgstr "肉č“Ø钟乳ēŸ³" + +#. ~ Description for gasping tube +#: lang/json/furniture_from_json.py +msgid "" +"This is a meaty green stalactite with a thickened hide like that of a " +"starfish, extending from the floor to the ceiling. In the center is a " +"series of ports somewhat like mouths, from which pour bursts of a vile-" +"smelling gas." +msgstr "äø€å—肉č“Øēš„ē»æč‰²é’Ÿä¹³ēŸ³ļ¼Œęœ‰åƒęµ·ę˜Ÿäø€ę ·ēš„厚ēš®ļ¼Œä»Žåœ°ęæäø€ē›“延ä¼øåˆ°å¤©čŠ±ęæ怂äø­åæƒę˜Æäø€ē³»åˆ—像嘓äø€ę ·ēš„开口ļ¼Œä»Žäø­å–·å‡ŗ阵阵难闻ēš„ę°”ä½“ć€‚" + +#: lang/json/furniture_from_json.py +msgid "twitching frond" +msgstr "ꑇꑆč•Ø叶" + +#. ~ Description for twitching frond +#: lang/json/furniture_from_json.py +msgid "" +"A spine resembling moth antennae juts from the ground, swaying gently in the" +" air. Every so often, a cascade of energy arcs along it and discharges into" +" the ceiling." +msgstr "äø€ę ¹åƒé£žč›¾č§¦é”»äø€ę ·ēš„åø¦ęƛ尖åˆŗ从地面ä¼øå‡ŗę„ļ¼ŒåœØē©ŗäø­č½»č½»ę‘‡ę‘†ć€‚ęƏ隔äø€ę®µę—¶é—“ļ¼Œå®ƒå°±ä¼šå‘å¤©čŠ±ęæ射å‡ŗ几道ē”µå¼§ć€‚" + +#: lang/json/furniture_from_json.py +msgid "scarred lump" +msgstr "伤ē—•ē“Æē“Æēš„č‚‰å—" + +#. ~ Description for scarred lump +#: lang/json/furniture_from_json.py +msgid "" +"This is a pile of nondescript alien flesh, twitching and belching strange " +"gases out of injured orifices." +msgstr "äø€å †ę— ę³•åˆ†č¾Øęø…ę„šēš„异ē•Œč”€č‚‰ļ¼Œå®ƒå—伤ēš„å­”ę“žę­£ęŠ½ęē€å‘往外喷å‡ŗ儇ę€Ŗēš„ę°”ä½“ć€‚" + +#: lang/json/furniture_from_json.py +msgid "splat!" +msgstr "å•Ŗļ¼" + +#: lang/json/furniture_from_json.py +msgid "slimy pod" +msgstr "é»ę»‘čšå›Š" + +#. ~ Description for slimy pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a slick, translucent pod suspended on a thin stalk. It is covered " +"in a thick mucus, obscuring whatever is floating in the gel-like substance " +"inside." +msgstr "čæ™ę˜Æäø€äøŖę‚¬ęŒ‚åœØē»†čŒŽäøŠēš„å…‰ę»‘ć€åŠé€ę˜Žčšå›Šć€‚éč¦†å…¶äøŠēš„åŽšé‡é»ę¶²ļ¼ŒęŽ©ē›–äŗ†å‡čƒ¶ēŠ¶ē‰©č“Øäø­ę‚¬ęµ®ēš„任何äøœč„æ怂" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "whump." +msgstr "å“å˜”ć€‚" + +#: lang/json/furniture_from_json.py +msgid "organ pod" +msgstr "å™Øå®˜čšå›Š" + +#. ~ Description for organ pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside you can see the" +" dimly outlined shape of human organs, floating in some kind of preservative" +" goo." +msgstr "čæ™ę˜Æäø€äøŖę‚¬ęŒ‚åœØē»†čŒŽäøŠēš„åŠé€ę˜Žčšå›Šć€‚å…¶äø­ä½ åÆ仄ēœ‹åˆ°äŗŗ体å™Ø官ēš„ęØ”ē³Šč½®å»“ļ¼Œę¼‚ęµ®åœØꟐē§é˜²ęŠ¤ę€§é»ę¶²äø­ć€‚" + +#: lang/json/furniture_from_json.py +msgid "resin pod" +msgstr "ę ‘č„‚čšå›Š" + +#. ~ Description for resin pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside is a clean, " +"clear resinous-looking fluid. You could fairly easily tear it from the " +"stalk and take it with you." +msgstr "čæ™ę˜Æäø€äøŖę‚¬ęŒ‚åœØē»†čŒŽäøŠēš„åŠé€ę˜Žčšå›Šć€‚é‡Œé¢ę˜Æ干净ļ¼Œęø…ę¾ˆēš„ę ‘č„‚ēŠ¶ę¶²ä½“ć€‚ä½ åÆä»„å¾ˆå®¹ę˜“åœ°ęŠŠå®ƒä»ŽčŒŽäøŠę‰Æäø‹ę„并随čŗ«ęŗåø¦ć€‚" + +#: lang/json/furniture_from_json.py +msgid "fleshy altar" +msgstr "蔀肉ē„­å›" + +#. ~ Description for fleshy altar +#: lang/json/furniture_from_json.py +msgid "" +"This pulsing protuberance juts from the floor, its sides covered in scaled, " +"oozing skin. The surface is flat, but undulates softly. A handful of " +"unidentifiable appendages reach from the sides, suggesting a sort of " +"nightmarish living autodoc." +msgstr "" +"čæ™äøŖ脉åŠØēš„ēŖčµ·ē‰©ä»Žåœ°ęæäøŠå‡øå‡ŗļ¼Œä¾§é¢č¦†ē›–ē€é³žē‰‡ēŠ¶ć€ę¹æ黏ēš„ēš®č‚¤ć€‚č”Ø面平坦ļ¼Œä½†å¾®å¾®č •åŠØē€ć€‚äø€ē°‡ę— ę³•čƆ别ēš„é™„č‚¢ä»Žäø¤ä¾§ä¼øå‡ŗļ¼Œęš—ē¤ŗ其äøŗꟐē§å™©ę¢¦čˆ¬ēš„ę“»ä½“å…Øč‡ŖåŠØ医ē–—ä»Ŗ怂" + +#: lang/json/furniture_from_json.py +msgid "scrap antenna" +msgstr "金属åŗŸę–™å¤©ēŗæ" + +#. ~ Description for scrap antenna +#: lang/json/furniture_from_json.py +msgid "" +"This contraption looks like some sort of cobbled-together transmitter or " +"receiver antenna. It consists of a number of mismatched blinking lights, " +"spinning servos, and dangling wires connected to a heft metal box." +msgstr "" +"čæ™äøŖč£…ē½®ēœ‹čµ·ę„像ę˜ÆꟐē§ē”Ø金属åŗŸę–™ę‹¼å‡‘čµ·ę„ēš„发射å™Øęˆ–ęŽ„ę”¶å™Ø天ēŗæć€‚å®ƒē”±č®ø多äŗ’äøåŒ¹é…ēš„é—ŖēƒęŒ‡ē¤ŗēÆć€ę—‹č½¬ēš„é©¬č¾¾å’ŒčæžęŽ„到äø€äøŖę²‰é‡é‡‘å±žē›’äøŠēš„åž‚ē›“天ēŗæē»„ęˆć€‚" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py msgid "clang!" msgstr "哐啷ļ¼" +#: lang/json/furniture_from_json.py +msgid "rack of robots" +msgstr "ęœŗå™Øäŗŗå±•ęž¶" + +#. ~ Description for rack of robots +#: lang/json/furniture_from_json.py +msgid "" +"This is a wire cage containing a number of robot parts, from chassis to " +"limbs, firmly clamped on to sturdy hanging rods. It looks like it would be " +"exceptionally difficult to open it and get at them without damaging them, " +"probably by design." +msgstr "" +"čæ™ę˜Æäø€äøŖ钢äøē¬¼ļ¼Œé‡Œé¢ęœ‰č®ø多ęœŗå™Øäŗŗ零件ļ¼Œä»Žåŗ•ē›˜åˆ°å››č‚¢ļ¼Œē‰¢ē‰¢åœ°å›ŗ定åœØ坚å›ŗēš„åŠę†äøŠć€‚很åÆčƒ½ę˜Æę•…ę„å¦‚ę­¤č®¾č®”ēš„ļ¼Œęƒ³č¦åœØäøęŸåéƒØ件ēš„ęƒ…å†µäø‹ę‰“å¼€å±•ęž¶å¹¶å–äø‹å®ƒä»¬ę˜Æ几乎äøåÆčƒ½ēš„怂" + +#: lang/json/furniture_from_json.py +msgid "spinning dish" +msgstr "äøę–­ę—‹č½¬ēš„ē¢Ÿå½¢å¤©ēŗæ" + +#. ~ Description for spinning dish +#: lang/json/furniture_from_json.py +msgid "" +"This is a slowly spinning parabolic dish engraved with an unrecognizable " +"pattern of symbols that might, at a guess, be some sort of circuitry pattern" +" - or maybe a religious incantation. It is mounted on a completely " +"mismatched electric motor that looks fairly mundane." +msgstr "" +"äø€äøŖę­£åœØē¼“ē¼“ę—‹č½¬ēš„ꊛē‰©å½¢ē¢Ÿå½¢å¤©ēŗæļ¼ŒäøŠé¢é›•åˆ»ē€äø€å¤§å—ę— ę³•č¾Ø认ēš„ē¬¦å·å›¾ę”ˆļ¼ŒåÆčƒ½ę˜ÆꟐē§ē”µč·Æå›¾ę”ˆļ¼Œęˆ–者ę˜ÆꟐē§å®—ę•™å’’čÆ­ć€‚å®ƒå®‰č£…åœØäø€äøŖē›øå½“ę™®é€šēš„ē”µåŠØęœŗäøŠļ¼Œēœ‹äøŠåŽ»å®Œå…ØäøåŒ¹é…ć€‚" + +#: lang/json/furniture_from_json.py +msgid "scavenged utility light" +msgstr "åŗŸē‰©åˆ©ē”Øēš„å·„作ēÆ" + +#. ~ Description for scavenged utility light +#: lang/json/furniture_from_json.py +msgid "" +"The bulbs emit an eery greenish glow, and some parts of it have a curved " +"appearance as though the metal were grown in a lab, but by and large this " +"isn't a particularly unusual looking area light." +msgstr "" +"它ēš„ēÆę³”å‘å‡ŗäø€č‚”ę€Ŗčƞēš„ē»æč‰²å…‰čŠ’ļ¼Œå®ƒēš„äø€éƒØåˆ†ęœ‰ē§å¼Æę›²ēš„å¤–č§‚ļ¼Œå°±å„½åƒé‡‘属ę˜ÆåœØ实éŖŒå®¤é‡Œē”Ÿé•æå‡ŗę„ēš„äø€čˆ¬ļ¼Œä½†ę€»ēš„ę„čÆ“ļ¼Œå®ƒå¹¶äøę˜Æäø€äøŖē‰¹åˆ«äøåÆ»åøøēš„å·„作ēÆ怂" + +#: lang/json/furniture_from_json.py +msgid "clanking fluid pump" +msgstr "咣当作响ēš„ę¶²ę³µ" + +#. ~ Description for clanking fluid pump +#: lang/json/furniture_from_json.py +msgid "" +"The huge sweating pipes and large tank reveal this clanking and tortuous " +"piece of equipment to be some sort of fluid pump. It is cobbled from " +"several apparently ill-fitting parts that have been fitted together with " +"some very strange looking but surprisingly clever adaptors." +msgstr "" +"外č”Ø凝ē»“äŗ†č®øå¤šę°“ē ēš„å·Ø大ē®”é“å’Œå¤§åž‹ę²¹ē½č”Ø꘎äŗ†čæ™å°ę­£åœØ咣当作响ēš„å¼Æå¼Æę›²ę›²ēš„č®¾å¤‡ę˜ÆꟐē§ę¶²ę³µć€‚它ēœ‹äøŠåŽ»ę˜Æē”±å‡ äøŖę˜Žę˜¾äøåŒ¹é…ēš„éƒØä»¶ę‹¼å‡‘č€Œęˆļ¼Œčæ™äŗ›éƒØ件之闓ē”±äø€äŗ›ēœ‹čµ·ę„非åøø儇ę€Ŗä½†ęž„ę€å“å‡ŗ儇巧妙ēš„č½¬ęŽ„å™Øē»„č£…åœØäø€čµ·ć€‚" + +#: lang/json/furniture_from_json.py +msgid "metalloid printer" +msgstr "ē±»é‡‘å±žę‰“å°ęœŗ" + +#. ~ Description for metalloid printer +#: lang/json/furniture_from_json.py +msgid "" +"This huge device actually resembles a 3D printer fairly closely, aside from " +"its industrial size. Huge spools of various thin metallic wires top it and " +"feed into what seems to be some sort of nozzle, and massive electrical " +"cables disappear into the wall behind it." +msgstr "" +"čæ™å°å·Ø大ēš„č®¾å¤‡å®žé™…ēœ‹čµ·ę„和3Dę‰“å°ęœŗ非åøøē›øä¼¼ļ¼Œé™¤äŗ†å®ƒēš„å·„äøšēŗ§å·Ø大å°ŗåÆø怂å·Ø大ēš„ēŗæč½“äøŠē¼ ē»•ē€å„ē§å„ę ·ēš„ē»†é‡‘属ēŗæļ¼Œé€čæ›äø€äøŖēœ‹čµ·ę„像ę˜ÆꟐē§å–·å˜“ēš„č£…ē½®ļ¼Œå·Ø大ēš„ē”µē¼†å»¶ä¼øę¶ˆå¤±åœØå®ƒčƒŒåŽēš„墙äø­ć€‚" + +#: lang/json/furniture_from_json.py +msgid "circuit printer" +msgstr "ē”µč·Æę‰“å°ęœŗ" + +#. ~ Description for circuit printer +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall device with a lattice of pipes and nozzles. Based on the " +"pile of products sitting in the output hopper, it looks like itā€™s used as a " +"printer for complex electronic components." +msgstr "čæ™å°é«˜é«˜ēš„č£…ē½®äøŠé¢ęœ‰äøŖē”±å„ē§ē®”道和喷嘓ē»„ęˆēš„ē½‘ę ¼ć€‚ę ¹ę®ę”¾åœØč¾“å‡ŗꖙꖗäø­ēš„那堆äŗ§å“ę„ēœ‹ļ¼Œå®ƒēœ‹čµ·ę„像ę˜Æäø€å°ē”Øę„ę‰“å°å¤ę‚ē”µå­å…ƒä»¶ēš„3Dę‰“å°ęœŗ怂" + +#: lang/json/furniture_from_json.py +msgid "Mavrik 10-101 power core" +msgstr "Mavrik 10-101 čƒ½ęŗę øåæƒ" + +#. ~ Description for Mavrik 10-101 power core +#: lang/json/furniture_from_json.py +msgid "" +"There is a faded metallic plaque on the side of this cylindrical device. The lettering is a strange combination of English and Cyrillic script. It reads:\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" +msgstr "" +"čæ™äøŖåœ†ęŸ±å½¢č£…ē½®ēš„ä¾§é¢ęœ‰äø€å—č¤Ŗč‰²ēš„金属ęæ怂äøŠé¢ēš„å­—ęƍę˜Æ英čƭ和č„æ里尔字ęƍēš„儇ę€Ŗē»„åˆć€‚å†™ē€ļ¼š\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "metal screeching!" +msgstr "äø€å£°å°–锐ēš„é‡‘å±žę–­č£‚ēš„声音ļ¼" + +#: lang/json/furniture_from_json.py +msgid "spherical generator" +msgstr "ēƒå½¢å‘ē”µęœŗ" + +#. ~ Description for spherical generator +#: lang/json/furniture_from_json.py +msgid "" +"This huge steel plated sphere gives off a soft hum as it, presumably, " +"generates power. A heavy lead plate bolted to the front might describe what" +" it is, but it is written in something that looks vaguely like cuneiform." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "fluidic generator" +msgstr "" + +#. ~ Description for fluidic generator +#: lang/json/furniture_from_json.py +msgid "" +"Twisting reams of copper and steel pipes wrap around a central core that " +"thrums softly. Although there are no labels in any language you recognize, " +"the cables connected to the base suggest that this is some sort of power " +"generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "rusty generator" +msgstr "" + +#. ~ Description for rusty generator +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall, unremarkable cylinder capped by a wide flat saucer. There " +"is heavy rusting at the base. A series of connected cables suggest that " +"it's some sort of power generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "personal charging station" +msgstr "" + +#. ~ Description for personal charging station +#: lang/json/furniture_from_json.py +msgid "" +"The cyborg equivalent of a bed, this is a custom-shaped near-vertical booth " +"designed to mount a heavy metal frame and connect it to a central power " +"supply and nutrient source." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp +msgid "crash!" +msgstr "ę’žå‡»å£°ļ¼" + +#: lang/json/furniture_from_json.py +msgid "simple charging station" +msgstr "" + +#. ~ Description for simple charging station +#: lang/json/furniture_from_json.py +msgid "" +"This is a simple, unadorned, corroded metal charging and refeeding station, " +"with hookups for two units somewhat larger than a human to stand side by " +"side and be recharged and refueled." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shimmering superstructure" +msgstr "" + +#. ~ Description for shimmering superstructure +#: lang/json/furniture_from_json.py +msgid "" +"A simple metal superstructure like you might see holding up a radio tower, " +"this one seems to give off just the faintest hint of shimmer, like heat " +"waves. The metal has a burnt, iridescent pattern. There is a boxy, " +"unimpressive looking device at the top of the tower." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "portal enclosure" +msgstr "" + +#. ~ Description for portal enclosure +#: lang/json/furniture_from_json.py +msgid "" +"A heavy metal ring attached to dozens of wires, charred by residue that " +"gives off an acrid, unfamiliar smell." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "cooling unit" +msgstr "å†·å“č£…ē½®" + +#. ~ Description for cooling unit +#: lang/json/furniture_from_json.py +msgid "" +"A large, blocky appliance encased in sheet metal. This commonplace fixture " +"is used for cooling large indoor areas." +msgstr "äø€å°åˆå¤§åˆę–¹č¢«åŒ…č£¹åœØ金属ęæ之äø­ēš„ē”µå™Ø怂čæ™ē§åøø见ēš„å›ŗå®šč£…ē½®ē”ØäŗŽå†·å“大型室内åŒŗåŸŸć€‚" + #: lang/json/furniture_from_json.py msgid "central air filter" msgstr "äø­å¤®ē©ŗ갔čæ‡ę»¤å™Ø" @@ -97298,8 +97994,7 @@ msgid "" "priceless tools, invaluable to any survivor." msgstr "äø€å„—光伏发ē”µč£…ē½®ļ¼Œå°†å¤Ŗé˜³č¾å°„čƒ½č½¬åŒ–äøŗåÆ利ē”Øēš„ē”µåŠ›ć€‚åœØ大ē¾å˜ä¹‹å‰å°±å·²ē»å¾ˆęœ‰ē”Øļ¼Œč€ŒēŽ°åœØå®ƒä»¬ę›“ę˜Æꈐäøŗē؀ē½•ēš„å·„具ļ¼Œåƹ任何å¹øå­˜č€…ę„čƓ都ę˜Æę— ä»·ä¹‹å®ć€‚" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py msgid "whack!" msgstr "喀啦ļ¼" @@ -97315,16 +98010,12 @@ msgid "" "little to stop a moving car." msgstr "äø€å¤§å—ęœØ制č·Æ障ļ¼Œē”Øę„é˜»ęŒ”č½¦č¾†é€ščæ‡ęŸę”道č·Æć€‚å®ƒå†…č”¬äŗ†äø€ę”反光åø¦ļ¼Œä»„å¢žåŠ čƒ½č§åŗ¦ć€‚和它ēš„名字äøå¤Ŗ匹配ēš„ę˜Æļ¼Œå®ƒå‡ ä¹Žę— ę³•é˜»ę­¢äø€č¾†č”Œé©¶äø­ēš„ę±½č½¦ć€‚" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -#: src/mapdata.cpp src/vehicle_move.cpp +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/map.cpp src/mapdata.cpp +#: src/vehicle_move.cpp msgid "smash!" msgstr "咔嚓ļ¼" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -msgid "whump." -msgstr "å“å˜”ć€‚" - #: lang/json/furniture_from_json.py msgid "earthbag barricade" msgstr "土包č·Æ障" @@ -97661,10 +98352,6 @@ msgid "" "them moving slightly. Gross." msgstr "äø€äŗ›å·Ø大ēš„ē™½č‰²åµå›Šć€‚ä»”ē»†č§‚åÆŸę—¶ļ¼Œä½ åÆ仄ēœ‹åˆ°å®ƒä»¬åœØ微微地ē§»åŠØ怂ēœŸę¶åæƒć€‚" -#: lang/json/furniture_from_json.py -msgid "splat!" -msgstr "å•Ŗļ¼" - #. ~ Description for spider egg sack #: lang/json/furniture_from_json.py msgid "" @@ -97743,16 +98430,6 @@ msgid "" "the smoke to the outside. Dangerous to leave unattended while lit." msgstr "äø€äøŖåøø见ēš„家具ļ¼Œē”ØäŗŽåœØ室内安å…Ø地ē”Ÿē«ļ¼Œčæ˜ęœ‰äø€äøŖēƒŸå›±å°†ēƒŸé›¾ęŽ’å‡ŗåˆ°å®¤å¤–ć€‚ä½†åœØē‚¹ē‡ƒę—¶å•ē‹¬ē¦»å¼€ä¹ŸåÆčƒ½ä¼šåÆ¼č‡“å±é™©ć€‚" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -msgid "crash!" -msgstr "ę’žå‡»å£°ļ¼" - -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "whump!" -msgstr "哐嘔ļ¼" - #: lang/json/furniture_from_json.py msgid "wood stove" msgstr "ē«ē‚‰" @@ -97912,8 +98589,9 @@ msgid "" "comfort or warmth." msgstr "äø€å¤§å †ę ‘叶ļ¼Œå¦‚ęžœä½ äøåœØä¹Žčˆ’é€‚å’Œęø©ęš–ļ¼Œä½ åÆ仄ē”åœØäøŠé¢ć€‚" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -#: src/iuse.cpp +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/iuse.cpp msgid "crunch!" msgstr "嘎嚓ļ¼" @@ -98077,6 +98755,78 @@ msgid "" " chemicals." msgstr "äø€äøŖē”ØäŗŽåˆęˆå¤§é‡åŒ–学品ēš„åø¦ęœ‰ęœŗåŠØę··åˆč£…ē½®ēš„å¤§ę”¶ć€‚" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken generator" +msgstr "发ē”µęœŗļ¼ˆęŸåļ¼‰" + +#. ~ Description for broken generator +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This generator is broken and will not help you produce usable electricity." +msgstr "čæ™å°å‘ē”µęœŗå·²ē»åäŗ†ļ¼Œäøčƒ½åø®ä½ å‘ē”µć€‚" + +#: lang/json/furniture_from_json.py +msgid "Compact Advanced Sterling Radioisotope Generator" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"This hefty lump of steel and lead is the housing unit for a small nuclear " +"reactor. It is plastered with warning signs. You could probably ignore " +"those and salvage the steel and lead shielding, what could possibly go " +"wrong?" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"Some insane fool has removed the outer containment on this small-scale " +"nuclear reactor. It is still fairly safe as it is: the reactor has " +"considerable built-in containment as well. Nevertheless, you probably don't" +" want to stand too close for too long." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "light machinery" +msgstr "č½»åž‹ęœŗę¢°" + +#. ~ Description for light machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted light machinery. You could scavenge it for parts." +msgstr "å„å¼č½»åž‹ęœŗę¢°ć€‚ä½ åÆä»„ę‹†č§£å®ƒčŽ·å¾—é›¶ä»¶ć€‚" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "ting." +msgstr "叮ļ¼" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "heavy machinery" +msgstr "重型ęœŗę¢°" + +#. ~ Description for heavy machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted heavy machinery. You could scavenge it for parts." +msgstr "各式重型ęœŗę¢°ć€‚ä½ åÆä»„ę‹†č§£å®ƒčŽ·å¾—é›¶ä»¶ć€‚" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "old machinery" +msgstr "ꗧęœŗę¢°" + +#. ~ Description for old machinery +#: lang/json/furniture_from_json.py +msgid "Assorted old, rusty machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "electronic machinery" +msgstr "ē”µå­ęœŗę¢°" + +#. ~ Description for electronic machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted electronic machinery. You could scavenge it for parts." +msgstr "各ē§ē”µå­ęœŗę¢°ć€‚ä½ åÆä»„ę‹†č§£å®ƒčŽ·å¾—é›¶ä»¶ć€‚" + #: lang/json/furniture_from_json.py msgid "robotic arm" msgstr "ęœŗå™Ø臂" @@ -98094,6 +98844,32 @@ msgstr "äø€äøŖē”ØäŗŽč£…配ēŗæēš„č‡ŖåŠØęœŗę¢°č‡‚ļ¼Œēœ‹čµ·ę„似乎ęƔäø“é—Øč®¾č®” msgid "thunk." msgstr "å’šć€‚" +#: lang/json/furniture_from_json.py +msgid "ground cable" +msgstr "" + +#. ~ Description for ground cable +#: lang/json/furniture_from_json.py +msgid "A bunch of loose cables snake along the floor." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shred!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "thud!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "capacitor bank" +msgstr "" + +#. ~ Description for capacitor bank +#: lang/json/furniture_from_json.py +msgid "A bank of heavy metal cylinders connected by large wires." +msgstr "" + #: lang/json/furniture_from_json.py msgid "Autodoc Mk. XI" msgstr "å…Øč‡ŖåŠØ医ē–—ä»Ŗ XI 型" @@ -98365,118 +99141,18 @@ msgstr "隐ē§åø˜ļ¼ˆå¼€ļ¼‰" msgid "Stop peeking!" msgstr "别偷ēœ‹äŗ†ļ¼" -#: lang/json/furniture_from_json.py -msgid "glowing tendril" -msgstr "发光卷锻" - -#. ~ Description for glowing tendril -#: lang/json/furniture_from_json.py -msgid "" -"A willowy tendril growing from the floor, gently waving back and forth. A " -"faint light spills from it." -msgstr "äø€ę ¹ęŸ”韧ēš„卷锻从地ęæäøŠé•æå‡ŗę„ļ¼Œč½»č½»åœ°å‰åŽę‘†åŠØē€ć€‚微弱ēš„äŗ®å…‰ä»Žé‡Œé¢å°„äŗ†å‡ŗę„ć€‚" - -#: lang/json/furniture_from_json.py -msgid "splorch!" -msgstr "咔ļ¼" - -#: lang/json/furniture_from_json.py -msgid "wafting anemone" -msgstr "飘åŠØ굷葵" - -#. ~ Description for wafting anemone -#: lang/json/furniture_from_json.py -msgid "" -"A fleshy white protuberance growing from the floor, with a cluster of " -"tendrils pouring out of it. It looks almost exactly like a sea anemone, " -"even waving gently as though underwater." -msgstr "äø€äøŖ肉č“Øēš„ē™½č‰²ē”Ÿē‰©ä»Žåœ°é¢ēŖčµ·ļ¼Œäø€äø²å·é”»ä»Žč‚‰č“Øäø­ä¼øå‡ŗć€‚å®ƒēœ‹čµ·ę„å‡ ä¹Žå’Œęµ·č‘µäø€ęØ”äø€ę ·ļ¼Œē”šč‡³åƒåœØę°“é‡Œäø€ę ·č½»č½»åœ°ę‘†åŠØ怂" - -#: lang/json/furniture_from_json.py -msgid "gasping tube" -msgstr "肉č“Ø钟乳ēŸ³" - -#. ~ Description for gasping tube -#: lang/json/furniture_from_json.py -msgid "" -"This is a meaty green stalactite with a thickened hide like that of a " -"starfish, extending from the floor to the ceiling. In the center is a " -"series of ports somewhat like mouths, from which pour bursts of a vile-" -"smelling gas." -msgstr "äø€å—肉č“Øēš„ē»æč‰²é’Ÿä¹³ēŸ³ļ¼Œęœ‰åƒęµ·ę˜Ÿäø€ę ·ēš„厚ēš®ļ¼Œä»Žåœ°ęæäø€ē›“延ä¼øåˆ°å¤©čŠ±ęæ怂äø­åæƒę˜Æäø€ē³»åˆ—像嘓äø€ę ·ēš„开口ļ¼Œä»Žäø­å–·å‡ŗ阵阵难闻ēš„ę°”ä½“ć€‚" - -#: lang/json/furniture_from_json.py -msgid "twitching frond" -msgstr "ꑇꑆč•Ø叶" - -#. ~ Description for twitching frond -#: lang/json/furniture_from_json.py -msgid "" -"A spine resembling moth antennae juts from the ground, swaying gently in the" -" air. Every so often, a cascade of energy arcs along it and discharges into" -" the ceiling." -msgstr "äø€ę ¹åƒé£žč›¾č§¦é”»äø€ę ·ēš„åø¦ęƛ尖åˆŗ从地面ä¼øå‡ŗę„ļ¼ŒåœØē©ŗäø­č½»č½»ę‘‡ę‘†ć€‚ęƏ隔äø€ę®µę—¶é—“ļ¼Œå®ƒå°±ä¼šå‘å¤©čŠ±ęæ射å‡ŗ几道ē”µå¼§ć€‚" - -#: lang/json/furniture_from_json.py -msgid "scarred lump" -msgstr "伤ē—•ē“Æē“Æēš„č‚‰å—" - -#. ~ Description for scarred lump -#: lang/json/furniture_from_json.py -msgid "" -"This is a pile of nondescript alien flesh, twitching and belching strange " -"gases out of injured orifices." -msgstr "äø€å †ę— ę³•åˆ†č¾Øęø…ę„šēš„异ē•Œč”€č‚‰ļ¼Œå®ƒå—伤ēš„å­”ę“žę­£ęŠ½ęē€å‘往外喷å‡ŗ儇ę€Ŗēš„ę°”ä½“ć€‚" - -#: lang/json/furniture_from_json.py -msgid "slimy pod" -msgstr "é»ę»‘čšå›Š" - -#. ~ Description for slimy pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a slick, translucent pod suspended on a thin stalk. It is covered " -"in a thick mucus, obscuring whatever is floating in the gel-like substance " -"inside." -msgstr "čæ™ę˜Æäø€äøŖę‚¬ęŒ‚åœØē»†čŒŽäøŠēš„å…‰ę»‘ć€åŠé€ę˜Žčšå›Šć€‚éč¦†å…¶äøŠēš„åŽšé‡é»ę¶²ļ¼ŒęŽ©ē›–äŗ†å‡čƒ¶ēŠ¶ē‰©č“Øäø­ę‚¬ęµ®ēš„任何äøœč„æ怂" - -#: lang/json/furniture_from_json.py -msgid "organ pod" -msgstr "å™Øå®˜čšå›Š" - -#. ~ Description for organ pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside you can see the" -" dimly outlined shape of human organs, floating in some kind of preservative" -" goo." -msgstr "čæ™ę˜Æäø€äøŖę‚¬ęŒ‚åœØē»†čŒŽäøŠēš„åŠé€ę˜Žčšå›Šć€‚å…¶äø­ä½ åÆ仄ēœ‹åˆ°äŗŗ体å™Ø官ēš„ęØ”ē³Šč½®å»“ļ¼Œę¼‚ęµ®åœØꟐē§é˜²ęŠ¤ę€§é»ę¶²äø­ć€‚" - -#: lang/json/furniture_from_json.py -msgid "resin pod" -msgstr "ę ‘č„‚čšå›Š" - -#. ~ Description for resin pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside is a clean, " -"clear resinous-looking fluid. You could fairly easily tear it from the " -"stalk and take it with you." -msgstr "čæ™ę˜Æäø€äøŖę‚¬ęŒ‚åœØē»†čŒŽäøŠēš„åŠé€ę˜Žčšå›Šć€‚é‡Œé¢ę˜Æ干净ļ¼Œęø…ę¾ˆēš„ę ‘č„‚ēŠ¶ę¶²ä½“ć€‚ä½ åÆä»„å¾ˆå®¹ę˜“åœ°ęŠŠå®ƒä»ŽčŒŽäøŠę‰Æäø‹ę„并随čŗ«ęŗåø¦ć€‚" - -#: lang/json/furniture_from_json.py -msgid "fleshy altar" -msgstr "蔀肉ē„­å›" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "centrifuge" +msgstr "ē¦»åæƒęœŗ" -#. ~ Description for fleshy altar +#. ~ Description for centrifuge #: lang/json/furniture_from_json.py msgid "" -"This pulsing protuberance juts from the floor, its sides covered in scaled, " -"oozing skin. The surface is flat, but undulates softly. A handful of " -"unidentifiable appendages reach from the sides, suggesting a sort of " -"nightmarish living autodoc." +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. For some reason, this one has an attached battery pack. It could be " +"used to analyze a medical fluid sample, such as blood, if a test tube was " +"placed in it." msgstr "" -"čæ™äøŖ脉åŠØēš„ēŖčµ·ē‰©ä»Žåœ°ęæäøŠå‡øå‡ŗļ¼Œä¾§é¢č¦†ē›–ē€é³žē‰‡ēŠ¶ć€ę¹æ黏ēš„ēš®č‚¤ć€‚č”Ø面平坦ļ¼Œä½†å¾®å¾®č •åŠØē€ć€‚äø€ē°‡ę— ę³•čƆ别ēš„é™„č‚¢ä»Žäø¤ä¾§ä¼øå‡ŗļ¼Œęš—ē¤ŗ其äøŗꟐē§å™©ę¢¦čˆ¬ēš„ę“»ä½“å…Øč‡ŖåŠØ医ē–—ä»Ŗ怂" #: lang/json/furniture_from_json.py msgid "bathtub" @@ -98976,6 +99652,17 @@ msgid "" " it's not particularly comfortable." msgstr "äø€ęŠŠåÆęŠ˜å ēš„čŗŗ꤅ļ¼Œē”±å®‰č£…åœØęœØꔆꞶäøŠēš„ē»‡ē‰©ęž„ęˆć€‚č™½ē„¶å®ƒę˜Æäøŗäŗ†ęˆ·å¤–ēŽÆå¢ƒč€Œå»ŗ造ēš„ļ¼Œč€Œäø”ęÆ”čµ·čŗŗåœØ地äøŠč¦å„½å¾—多ļ¼Œä½†å®ƒå…¶å®žäøå¤Ŗ舒适怂" +#: lang/json/furniture_from_json.py +msgid "metal bench" +msgstr "" + +#. ~ Description for metal bench +#: lang/json/furniture_from_json.py +msgid "" +"A bench made of scrap metal. Not the most comfortable furniture you've ever" +" seen." +msgstr "" + #: lang/json/furniture_from_json.py msgid "bulletin board" msgstr "公告ē‰Œ" @@ -99224,7 +99911,7 @@ msgstr "ēŽ»ē’ƒē “č£‚ēš„声音ļ¼" #: lang/json/furniture_from_json.py msgid "gun safe" -msgstr "ęžŖē”Øäæé™©ęŸœ" +msgstr "ęžŖē”Øäæé™©ē®±" #. ~ Description for gun safe #: lang/json/furniture_from_json.py @@ -99242,7 +99929,7 @@ msgstr "é‡‘å±žę’•č£‚ļ¼" #: lang/json/furniture_from_json.py msgid "jammed gun safe" -msgstr "ęžŖē”Øäæé™©ęŸœļ¼ˆå·²å”ę­»ļ¼‰" +msgstr "ęžŖē”Øäæé™©ē®±ļ¼ˆå·²å”ę­»ļ¼‰" #. ~ Description for jammed gun safe #: lang/json/furniture_from_json.py @@ -99250,11 +99937,11 @@ msgid "" "A heavy and durable metal safe for storing firearms and ammunition. " "Unfortunately, the lock is completely broken, and short of some pretty " "serious machinery, you have no possible way of opening it." -msgstr "äø€äøŖē”ØäŗŽå‚Ø存ęžŖę¢°å’Œå¼¹čÆēš„坚å›ŗ耐ē”Øēš„金属äæé™©ęŸœć€‚äøå¹øēš„ę˜Æļ¼Œé”å·²ē»å®Œå…Ø坏äŗ†ļ¼Œč€Œäø”ę²”꜉ē‰¹åˆ¶ēš„ęœŗå™Øļ¼Œä½ ę²”åÆčƒ½ę‰“å¼€å®ƒć€‚" +msgstr "äø€äøŖē”ØäŗŽå‚Ø存ęžŖę¢°å’Œå¼¹čÆēš„坚å›ŗ耐ē”Øēš„金属äæé™©ē®±ć€‚äøå¹øēš„ę˜Æļ¼Œé”å·²ē»å®Œå…Ø坏äŗ†ļ¼Œč€Œäø”ę²”꜉ē‰¹åˆ¶ēš„ęœŗå™Øļ¼Œä½ ę²”åÆčƒ½ę‰“å¼€å®ƒć€‚" #: lang/json/furniture_from_json.py msgid "electronic gun safe" -msgstr "ē”µå­ęžŖē”Øäæé™©ęŸœ" +msgstr "ē”µå­ęžŖē”Øäæé™©ē®±" #. ~ Description for electronic gun safe #: lang/json/furniture_from_json.py @@ -99480,6 +100167,35 @@ msgid "" "A huge metal tank that can be used to safely store large amounts of liquid." msgstr "äø€äøŖå·Ø大ēš„金属容å™Øļ¼ŒåÆ仄ē”Øę„å®‰å…Ø地å‚Øå­˜å¤§é‡ę¶²ä½“ć€‚" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "fuel tank" +msgstr "ę²¹ē½" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with gasoline." +msgstr "äø€äøŖč£…ę»”ę±½ę²¹ēš„ę²¹ē®±ć€‚" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken fuel tank" +msgstr "ę²¹ē½ļ¼ˆęŸåļ¼‰" + +#. ~ Description for broken fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with gasoline." +msgstr "äø€äøŖę›¾ē»č£…ę»”ę±½ę²¹ēš„åę²¹ē®±ć€‚" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with diesel." +msgstr "äø€äøŖč£…ę»”ęŸ“ę²¹ēš„ę²¹ē®±ć€‚" + +#. ~ Description for broken fuel tank +#. ~ Description for broken diesel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with diesel." +msgstr "äø€äøŖę›¾ē»č£…ę»”ęŸ“ę²¹ēš„åę²¹ē®±ć€‚" + #: lang/json/furniture_from_json.py msgid "dumpster" msgstr "垃圾ē®±" @@ -99503,6 +100219,42 @@ msgid "" "electricity, it is pedal-driven, allowing use without power." msgstr "äø€ę ¹ē”Øę„åˆ¶é€ é»„ę²¹ēš„内ē½®ę…ę‹Œå™Øēš„金属ē½å­ć€‚它äøéœ€č¦ē”µļ¼Œč€Œę˜Æ靠čøęæ驱åŠØļ¼Œč®©ä½ čƒ½åœØ停ē”µę—¶ä½æē”Ø怂" +#: lang/json/furniture_from_json.py +msgid "riveted metal crate" +msgstr "" + +#. ~ Description for riveted metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This huge box is made of a dull metal, riveted together. There is no " +"obvious opening mechanism, and the rivets don't match any of your tools. " +"The only way in would be to smash it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "sealed metal crate" +msgstr "" + +#. ~ Description for sealed metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This is a huge, tightly sealed storage crate made from welded and riveted " +"sheet metal. The sealing mechanism is too tight to open bare-handed and " +"would need some kind of prying instrument to release." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "open metal crate" +msgstr "" + +#. ~ Description for open metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This large metal crateā€™s lid is unsealed, and hinges open easily to reveal a" +" number of storage shelves inside. Once open, the side panels also swing " +"wider for easy access." +msgstr "" + #: lang/json/furniture_from_json.py msgid "counter" msgstr "ęŸœå°" @@ -99601,6 +100353,15 @@ msgstr "äø€äøŖåÆ仄åœØäøŠé¢ę”¾äøœč„æć€åšäŗ‹ęƒ…ć€åƒé„­ć€å†™å­—ć€å·„作ē­‰ msgid "a low table for livingrooms." msgstr "客厅ē”Øēš„ēŸ®ę”Œć€‚" +#: lang/json/furniture_from_json.py +msgid "metal table" +msgstr "" + +#. ~ Description for metal table +#: lang/json/furniture_from_json.py +msgid "A serviceable but simple table made of scrap metal." +msgstr "" + #: lang/json/furniture_from_json.py msgid "tatami mat" msgstr "ꦻꦻē±³" @@ -99830,6 +100591,17 @@ msgstr "é‡‘å±žę®‹éŖø" msgid "Pile of various bent and twisted metals." msgstr "äø€å †å„ē§å„ę ·ēš„å¼Æę›²å˜å½¢ēš„åŗŸé‡‘å±žć€‚" +#: lang/json/furniture_from_json.py +msgid "radioactive slag" +msgstr "" + +#. ~ Description for radioactive slag +#: lang/json/furniture_from_json.py +msgid "" +"A pile of melted slag from a destroyed nuclear reactor. What are you doing " +"looking at this? Get the hell out of here, you nutcase!" +msgstr "" + #: lang/json/furniture_from_json.py msgid "pile of ash" msgstr "ē°ēƒ¬" @@ -99903,6 +100675,39 @@ msgid "" "public utilities, but it doesn't work anymore." msgstr "äø€ę ¹ē”Øę„ę”Æ꒑Ꞷē©ŗč¾“ē”µēŗæå’Œå…¶ä»–å…¬å…±č®¾ę–½ēš„é•æęœØꔩļ¼Œä½†ę˜Æę²”ęœ‰ä¾›ē”µåŽå®ƒęÆ«ę— ē”Ø途怂" +#: lang/json/furniture_from_json.py +msgid "scrap metal bridge" +msgstr "" + +#. ~ Description for scrap metal bridge +#: lang/json/furniture_from_json.py +msgid "A simple bridge made of riveted sheet metal." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py +msgid "broken console" +msgstr "ē”µč„‘ļ¼ˆęŸåļ¼‰" + +#. ~ Description for broken console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It doesn't seem to be working. " +"It's the broken screen and shattered circuit boards that's telling you that." +msgstr "čæ™ę˜Æäø€äøŖē‹¬ē«‹ēš„č®”ē®—ęœŗē»ˆē«Æ怂ē “ē¢Žēš„屏幕和ē”µč·Æęæ告čƉ你它似乎已ē»ę— ę³•å·„作äŗ†ć€‚" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "computer console" +msgstr "ē”µč„‘äø»ęœŗ" + +#. ~ Description for computer console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It can be used to view contents and" +" perform any allowed functions. It might even be possible to hack it, given" +" the skills." +msgstr "čæ™ę˜Æäø€äøŖē‹¬ē«‹ēš„č®”ē®—ęœŗē»ˆē«Æć€‚å®ƒåÆ仄ē”Øę„ęŸ„ēœ‹å†…å®¹å¹¶ę‰§č”Œä»»ä½•å…č®øēš„åŠŸčƒ½ć€‚å¦‚ęžœä½ ęœ‰ē›øå…³ęŠ€čƒ½ļ¼Œä¹ŸåÆä»„ä¾µå…„å®ƒć€‚" + #: lang/json/furniture_from_json.py msgid "forge" msgstr "锻铁ē‚‰" @@ -100263,6 +101068,15 @@ msgid "" "you wouldn't need to pay at all!" msgstr "它已ē»åäŗ†ļ¼Œčæ™äøē”±å¾—č®©ä½ ę²‰ę€å¦‚ä½•ä»Žé‡Œé¢ä¹°äøœč„æć€‚ä¹Ÿč®øä½ åÆä»„å†ęŠŠå®ƒå¼„åäø€ē‚¹ļ¼Œčæ™ę ·ä½ čæžé’±éƒ½äøē”Øē»™äŗ†ļ¼" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "rope leading up" +msgstr "向äøŠē»³ē“¢" + +#. ~ Description for rope leading up +#: lang/json/furniture_from_json.py +msgid "A rope. You could climb it up." +msgstr "" + #: lang/json/furniture_from_json.py msgid "atomic butter churn on a stand" msgstr "åŽŸå­é»„ę²¹ę…ę‹Œęœŗļ¼ˆęž¶čµ·ļ¼‰" @@ -103899,6 +104713,20 @@ msgstr[0] "ę”¾ē”µå¼‚ē•Œč•Ø叶" msgid "Electricity unnaturally arcs from the tips of this alien frond." msgstr "čæ™ē‰‡å¼‚ē•Œę¤ē‰©ēš„叶子尖ē«Æ会发射å‡ŗäøč‡Ŗē„¶ēš„ē”µå¼§ć€‚" +#: lang/json/gun_from_json.py +msgid "hurled rubble" +msgid_plural "hurled rubbles" +msgstr[0] "ꊕå‡ŗēš„ē¢ŽēŸ³" + +#: lang/json/gun_from_json.py +msgid "Stone at the ready to crush that which isn't part of the blob." +msgstr "äø€å—ē¢ŽēŸ³ļ¼Œå‡†å¤‡ē²‰ē¢Žä»»ä½•čæ˜ęœŖč‡£ęœäŗŽå˜å½¢ę€Ŗēš„ē”Ÿē‰©ć€‚" + +#: lang/json/gun_from_json.py +msgctxt "gun_type_type" +msgid "throw" +msgstr "ꊕꎷ" + #: lang/json/gun_from_json.py msgid "nail gun" msgid_plural "nail guns" @@ -103953,7 +104781,7 @@ msgstr[0] "č‡Ŗåˆ¶ę ę†å¼éœ°å¼¹ęžŖ" msgid "" "A short homemade lever-action shotgun with a small internal tube magazine. " "While still a primitive pipe and 2x4 design, it is a formiddable shotgun in " -"it's own right with room for improvement." +"its own right with room for improvement." msgstr "" "äø€ęŠŠēŸ­å°ēš„č‡Ŗåˆ¶ę ę†å¼éœ°å¼¹ęžŖļ¼Œå†…ē½®äŗ†äø€äøŖ很小ēš„ē®”å¼å¼¹åŒ£ć€‚č™½ē„¶ä»ē„¶ę˜Æäø€äøŖē”±é’¢ē®”和2x4制式ęœØę–™ę‹¼å‡‘č€Œęˆēš„ē®€é™‹č®¾č®”ļ¼Œä½†å·²ē»ē®—å¾—äøŠäø€ęŠŠęˆåž‹ēš„霰弹ęžŖļ¼Œč€Œäø”čæ˜ęœ‰äŗ›ę”¹čæ›ēš„ē©ŗ闓怂" @@ -104303,9 +105131,9 @@ msgstr "" "霰弹ęžŖę˜Æé¦–ę‰¹åœØ商äøšäøŠęˆåŠŸēš„ę³µåŠØ霰弹ęžŖ之äø€ć€‚它ēš„\"å ‘å£•ęˆ˜\"型号已ē»ęˆäøŗäø€äøŖ高åŗ¦ęµŖę¼«åŒ–ēš„äø€ęˆ˜ē¾Žå›½č±”å¾ć€‚å®ƒēš„ęžŖå„—ć€åˆŗ刀協口和17英åÆøé•æēš„åˆŗ刀ļ¼Œę— åÆå¦č®¤ļ¼Œč®©čæ™ęŠŠéœ°å¼¹ęžŖēœ‹äøŠåŽ»ååˆ†éŖ‡äŗŗ怂ēŽ°åœØå·²ē»ę²”ęœ‰ęˆ˜å£•éœ€č¦ęø…ē†ļ¼Œä½†ę„äøŖå……ę»”äø§å°øēš„åŸŽé•‡ä¹Ÿč¶³å¤Ÿäŗ†ć€‚" #: lang/json/gun_from_json.py -msgid "four winds shotgun" -msgid_plural "four winds shotguns" -msgstr[0] "č‡Ŗ制ā€œå››é£Žā€éœ°å¼¹ęžŖ" +msgid "slam-fire pipe shotgun" +msgid_plural "slam-fire pipe shotguns" +msgstr[0] "č‡Ŗ制ēŒ›å‡»å‡»å‘式霰弹ęžŖ" #: lang/json/gun_from_json.py msgid "" @@ -104313,6 +105141,18 @@ msgid "" "The lack of sights make this weapon only useful at point-blank range." msgstr "äø€ęŠŠč‡Ŗ制ēš„ē®€ę˜“霰弹ęžŖļ¼Œē”±äø¤ę ¹åŽšé’¢ē®”态äø€äøŖ后ē›–å’Œäø€ę ¹é’‰å­ē»„ęˆć€‚ē”±äŗŽē¼ŗ乏ēž„å…·ļ¼Œčæ™ęŠŠę­¦å™ØåŖčƒ½åœØčæ‘č·ē¦»ä½æē”Ø怂" +#: lang/json/gun_from_json.py +msgid "double slam-fire pipe shotgun" +msgid_plural "double slam-fire pipe shotguns" +msgstr[0] "č‡Ŗ制双ē®”ēŒ›å‡»å‡»å‘式霰弹ęžŖ" + +#: lang/json/gun_from_json.py +msgid "" +"A crude shotgun, composed of four thick steel pipes, two end caps and two " +"nails. The lack of sights make this weapon only useful at point-blank " +"range." +msgstr "äø€ęŠŠč‡Ŗ制ēš„ē®€ę˜“霰弹ęžŖļ¼Œē”±å››ę ¹åŽšé’¢ē®”态äø¤äøŖ后ē›–å’Œäø¤ę ¹é’‰å­ē»„ęˆć€‚ē”±äŗŽē¼ŗ乏ēž„å…·ļ¼Œčæ™ęŠŠę­¦å™ØåŖčƒ½åœØčæ‘č·ē¦»ä½æē”Ø怂" + #: lang/json/gun_from_json.py msgid "flaregun" msgid_plural "flareguns" @@ -104725,11 +105565,6 @@ msgid "" " by hand." msgstr "äø€ę ¹ēš®åˆ¶ęŠ•ēŸ³ē“¢ļ¼ŒęÆ”čµ·ē›“ꎄē”Øꉋļ¼ŒåÆ仄ꊊēŸ³å¤“ęŠ•ęŽ·å¾—ę›“åæ«äø”ꛓčæœć€‚" -#: lang/json/gun_from_json.py -msgctxt "gun_type_type" -msgid "throw" -msgstr "ꊕꎷ" - #: lang/json/gun_from_json.py msgid "slingshot" msgid_plural "slingshots" @@ -109538,7 +110373,7 @@ msgstr "åø食" #: lang/json/item_action_from_json.py msgid "Apply" -msgstr "采ē”Ø" +msgstr "ä½æē”Ø" #: lang/json/item_action_from_json.py lang/json/keybinding_from_json.py msgid "Eat" @@ -109580,7 +110415,7 @@ msgstr "唫坑/å¤Æ实地面" #. ~ Mutation class name #: lang/json/item_action_from_json.py lang/json/mutation_category_from_json.py msgid "Fish" -msgstr "钓鱼" +msgstr "é±¼" #: lang/json/item_action_from_json.py msgid "Set" @@ -110353,6 +111188,11 @@ msgid "" "access the controls, or use the vehicle control key (default '^')." msgstr "ä½ åÆ仄åœØå®‰č£…åŗ§ę¤…ęˆ–éžåŗ§åŽåœØę­¤é©¾é©¶č½½å…·ļ¼Œä½ čƒ½ęŒ‰\"e\"ęŸ„ēœ‹ę­¤å¤„ę„ęŽ§åˆ¶č½½å…·ļ¼Œęˆ–č€…ęŒ‰äø‹č½½å…·ęŽ§åˆ¶é”®ļ¼ˆé»˜č®¤äøŗ\"^\"ļ¼‰ć€‚" +#. ~ Please leave anything in unchanged. +#: lang/json/json_flag_from_json.py +msgid "When active, turns engines on and off automatically." +msgstr "开åÆę—¶ļ¼Œę ¹ę®å‡ŗ力及ē‡ƒę–™ęƒ…况č‡ŖåŠØåˆ‡ę¢å¼•ę“Žć€‚" + #. ~ Please leave anything in unchanged. #: lang/json/json_flag_from_json.py msgid "Illuminated items in this space will not illuminate nearby squares." @@ -112047,6 +112887,10 @@ msgstr "开/å…³å‡€ę°“å™Ø" msgid "Toggle tracking" msgstr "开/关čæ½čøŖč£…ē½®" +#: lang/json/keybinding_from_json.py +msgid "Toggle smart engine controller" +msgstr "开/关ę™ŗčƒ½å¼•ę“ŽęŽ§åˆ¶" + #: lang/json/keybinding_from_json.py src/turret.cpp src/vehicle_use.cpp msgid "Set turret firing modes" msgstr "č®¾ē½®ē‚®å””射击ęؔ式" @@ -118851,7 +119695,7 @@ msgstr "é—Æå…„å†›ę¢°åŗ“取回家åŗ­ē…§" #: lang/json/mission_def_from_json.py msgid "I need you to get my family photo from the armory safe." -msgstr "ęˆ‘éœ€č¦ä½ ä»Žå†›ę¢°åŗ“ēš„äæé™©ęŸœäø­å–å‡ŗꈑēš„å…Ø家ē¦ē…§ē‰‡ć€‚" +msgstr "ęˆ‘éœ€č¦ä½ ä»Žå†›ę¢°åŗ“ēš„äæé™©ē®±äø­å–å›žęˆ‘ēš„å…Ø家ē¦ē…§ē‰‡ć€‚" #: lang/json/mission_def_from_json.py msgid "" @@ -118875,7 +119719,7 @@ msgstr "ä½ ēœ‹äøŠåŽ»å±žäŗŽé‚£ē§č¶³ę™ŗå¤šč°‹ēš„ē±»åž‹ļ¼Œä¹Ÿč®øä½ åÆ仄ē “č§£å®ƒ #: lang/json/mission_def_from_json.py msgid "Got the photo? Should've been in my gun safe." -msgstr "ę‰¾åˆ°ē…§ē‰‡äŗ†å—ļ¼Ÿå®ƒåŗ”čÆ„åœØꈑēš„ęžŖē”Øäæé™©ęŸœé‡Œć€‚" +msgstr "ę‰¾åˆ°ē…§ē‰‡äŗ†å—ļ¼Ÿå®ƒåŗ”čÆ„åœØꈑēš„ęžŖē”Øäæé™©ē®±é‡Œć€‚" #: lang/json/mission_def_from_json.py msgid "Thanks! I'll be sure to put in a good word for you around town." @@ -130428,17 +131272,6 @@ msgid "" "anything now is another question." msgstr "ä½ ę˜Æäø€åčŖ“čØ€ęå«ę³•å¾‹ēš„ę‰§ę³•č­¦åÆŸć€‚ę„Ÿč°¢å·žé™…åč®®ļ¼Œä½ ę‹„꜉åœØå…Øę–°č‹±ę ¼å…°ēš„ę‰§ę³•ęƒć€‚å½“ē„¶ļ¼Œčæ™čæ˜ęœ‰ę²”ęœ‰ę„ä¹‰ę˜Æ另外äø€å›žäŗ‹äŗ†ć€‚" -#: lang/json/mutation_from_json.py -msgid "Helicopter Pilot" -msgstr "ē›“升ęœŗ驾驶员" - -#. ~ Description for Helicopter Pilot -#: lang/json/mutation_from_json.py -msgid "" -"You are a trained helicopter pilot. This makes you one of the few living " -"people who can operate a helicopter after the Cataclysm." -msgstr "ä½ ę˜ÆäøŖ受čæ‡č®­ē»ƒēš„ē›“升ęœŗé£žč”Œå‘˜ć€‚čæ™ä½æä½ ęˆäøŗå°‘ę•°å‡ äøŖčƒ½åœØ大ē¾å˜ä¹‹åŽčƒ½ę“ēŗµē›“升ęœŗēš„äŗŗ之äø€ć€‚" - #: lang/json/mutation_from_json.py msgid "SWAT Officer" msgstr "SWATē‰¹č­¦" @@ -135376,6 +136209,10 @@ msgstr "ē±³Ā·ęˆˆä¾¦åÆŸå””" msgid "subway station?" msgstr "地铁ē«™ļ¼Ÿ" +#: lang/json/overmap_terrain_from_json.py +msgid "science lab reactor" +msgstr "" + #: lang/json/overmap_terrain_from_json.py msgid "lab" msgstr "实éŖŒå®¤" @@ -142852,6 +143689,18 @@ msgid "" "You have your whole life ahead of you and it's gonna be sweet!" msgstr "ä½ ę˜Æäø€äøŖ因äøŗꟐē§ęœŖēŸ„åŽŸå› č€Œč¢«čµ‹äŗˆäŗ†ē”Ÿå‘½ēš„äŗŗå½¢ē³–ęžœć€‚ä½ ēš„äŗŗē”Ÿčæ˜ęœ‰å¾ˆé•æēš„č·Æ要走ļ¼Œčæ™ä¼šå¾ˆē”œčœœēš„ļ¼" +#: lang/json/proficiency_from_json.py +msgid "Knapping" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Blacksmithing" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Helicopter Piloting" +msgstr "" + #. ~ Crafting recipes category name #: lang/json/recipe_category_from_json.py msgid "*" @@ -150822,7 +151671,7 @@ msgstr "地äøŠę”到ēš„儇ę€Ŗē²‰č‰²čÆē‰‡ļ¼Ÿę„Ÿč§‰ę²”什么问题ļ¼" msgid "Finally, something to take the edge off." msgstr "ē»ˆäŗŽčƒ½é‡Šę”¾äø€äø‹åŽ‹åŠ›äŗ†ć€‚" -#: lang/json/snippet_from_json.py src/npctalk.cpp +#: lang/json/snippet_from_json.py src/talker_npc.cpp msgid "No thanks, I'm good." msgstr "äøē”Øäŗ†ļ¼Œč°¢č°¢ļ¼Œęˆ‘å¾ˆå„½ć€‚" @@ -171020,6 +171869,18 @@ msgstr "ēŽ©å®¶ę‹„ęœ‰å±žę€§ļ¼ŒēŽ©å®¶ę¶ˆé™¤å±žę€§å›žåŗ”怂" msgid "This is a npc_has_var, npc_remove_var test response." msgstr "NPCę‹„ęœ‰å±žę€§ļ¼ŒNPCę¶ˆé™¤å±žę€§å›žåŗ”怂" +#: lang/json/talk_topic_from_json.py +msgid "This is a u_add_var time test response." +msgstr "ēŽ©å®¶ę·»åŠ å±žę€§ę—¶é—“굋čƕ回åŗ”怂" + +#: lang/json/talk_topic_from_json.py +msgid "This is a npc_add_var time test response." +msgstr "NPCę·»åŠ å±žę€§ę—¶é—“ęµ‹čƕ回åŗ”怂" + +#: lang/json/talk_topic_from_json.py +msgid "This is a u_compare_var time test response for > 3_days." +msgstr "u_compare_var > 3天 ꗶ闓굋čƕ回åŗ”怂" + #: lang/json/talk_topic_from_json.py msgid "This is a u_adjust_var test response that increments by 1." msgstr "u_adjust_var 加 1 굋čƕ回åŗ”怂" @@ -171120,6 +171981,10 @@ msgstr "é©¾é©¶ęµ‹čƕ回åŗ”怂" msgid "This is a low driving test response." msgstr "ä½Žé©¾é©¶ęŠ€čƒ½ęµ‹čƕ回åŗ”怂" +#: lang/json/talk_topic_from_json.py +msgid "This is an npc_first_topic test response." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "Greetings friend, it's nice to see you." msgstr "ä½ å„½ęœ‹å‹ļ¼Œå¾ˆé«˜å…“č§åˆ°ä½ ć€‚" @@ -179808,7 +180673,7 @@ msgid "Will do, thanks!" msgstr "会ēš„ļ¼Œč°¢č°¢ļ¼" #: lang/json/talk_topic_from_json.py lang/json/talk_topic_from_json.py -#: src/npctalk.cpp +#: src/talker.h src/talker_npc.cpp msgid "Nope." msgstr "äøč”Œć€‚" @@ -185762,6 +186627,36 @@ msgstr "ē”Ÿå‘½ä»ŽęžÆę­»ēš„č‰äø›äø­é‡ę–°ę¶Œå‘怂" msgid "The door opens forcefully!" msgstr "é—Øč¢«å¼ŗč”Œę‰“å¼€äŗ†ļ¼" +#: lang/json/terrain_from_json.py +msgid "broken diesel tank" +msgstr "" + +#. ~ Description for centrifuge +#: lang/json/terrain_from_json.py +msgid "" +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. It could be used to analyze a medical fluid sample, such as blood, if" +" a test tube was placed in it." +msgstr "äø€å°åø¦ęœ‰č‡ŖåŠØåˆ†ęžä»Ŗ单元ēš„ē¦»åæƒęœŗ怂 åÆå°†č£…ęœ‰åŒ»ē”Øę¶²ä½“ę ·ęœ¬ļ¼ˆä¾‹å¦‚č”€ę¶²ļ¼‰ēš„čƕē®”ę”¾å…„å…¶äø­čæ›č”Œåˆ†ęžć€‚" + +#: lang/json/terrain_from_json.py +msgid "plutonium generator" +msgstr "钚反åŗ”å †" + +#. ~ Description for plutonium generator +#: lang/json/terrain_from_json.py +msgid "" +"This imposing apparatus harnesses the power of the atom. Refined nuclear " +"fuel is 'burned' to provide nearly limitless electrical power. It's not " +"doing much good here though. Perhaps it could be salvaged for other " +"purposes." +msgstr "äø€å°čƒ½å¤Ÿåˆ©ē”ØåŽŸå­čƒ½ēš„å¼ŗå¤§č®¾å¤‡ć€‚ē»čæ‡ē²¾ē‚¼ēš„ę øē‡ƒę–™åœØ其äø­\"ē‡ƒēƒ§\"ä»„ęä¾›å‡ ä¹Žę— é™ēš„ē”µåŠ›ć€‚但ēŽ°åœØ它ē•™åœØčæ™é‡Œä»€ä¹ˆē”Øä¹Ÿę²”ęœ‰ć€‚ä¹Ÿč®øåÆä»„ę‹†å¼€å®ƒå›žę”¶äø€äŗ›éƒØ件怂" + +#. ~ Description for old machinery +#: lang/json/terrain_from_json.py +msgid "Assorted old machinery. You could scavenge it for parts." +msgstr "å„å¼č€ę—§ęœŗå™Øć€‚ä½ åÆä»„ę‹†č§£å®ƒčŽ·å¾—é›¶ä»¶ć€‚" + #: lang/json/terrain_from_json.py msgid "scorched earth" msgstr "ē„¦åœŸ" @@ -188518,24 +189413,6 @@ msgid "" "press them into basic shapes, ready for further crafting." msgstr "äø€å°ę¶²åŽ‹é©±åŠØēš„金属锻压ęœŗļ¼ŒåÆ仄将各ē§é‡‘å±žåˆ¶å“åŽ‹åˆ¶ęˆé‡‘å±žå—ļ¼Œä»„ē”ØäŗŽčæ›äø€ę­„åŠ å·„ć€‚" -#: lang/json/terrain_from_json.py -msgid "fuel tank" -msgstr "ę²¹ē½" - -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with gasoline." -msgstr "äø€äøŖč£…ę»”ę±½ę²¹ēš„ę²¹ē®±ć€‚" - -#: lang/json/terrain_from_json.py -msgid "broken fuel tank" -msgstr "ę²¹ē½ļ¼ˆęŸåļ¼‰" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with gasoline." -msgstr "äø€äøŖę›¾ē»č£…ę»”ę±½ę²¹ēš„åę²¹ē®±ć€‚" - #: lang/json/terrain_from_json.py msgid "gasoline pump" msgstr "ę±½ę²¹ę³µ" @@ -188561,16 +189438,6 @@ msgid "" "the liquid gold." msgstr "ꁐꀖļ¼čæ™äøŖę±½ę²¹ę³µč¢«ęƁäŗ†ļ¼Œä½ å†ä¹Ÿę— ę³•é€ščæ‡å®ƒčŽ·å¾—é‚£äŗ›ę¶²ä½“黄金äŗ†ć€‚" -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with diesel." -msgstr "äø€äøŖč£…ę»”ęŸ“ę²¹ēš„ę²¹ē®±ć€‚" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with diesel." -msgstr "äø€äøŖę›¾ē»č£…ę»”ęŸ“ę²¹ēš„åę²¹ē®±ć€‚" - #: lang/json/terrain_from_json.py msgid "diesel pump" msgstr "ęŸ“ę²¹ę³µ" @@ -188650,16 +189517,6 @@ msgid "" "airflow." msgstr "äø€å¤§é¢å®‰č£…åœØ墙äøŠēš„ē½‘ę ¼ļ¼ŒäøŠé¢åøƒę»”äŗ†ē”Øę„č°ƒčŠ‚ę°”ęµēš„č–„é‡‘å±žęæ怂" -#: lang/json/terrain_from_json.py -msgid "broken generator" -msgstr "发ē”µęœŗļ¼ˆęŸåļ¼‰" - -#. ~ Description for broken generator -#: lang/json/terrain_from_json.py -msgid "" -"This generator is broken and will not help you produce usable electricity." -msgstr "čæ™å°å‘ē”µęœŗå·²ē»åäŗ†ļ¼Œäøčƒ½åø®ä½ å‘ē”µć€‚" - #: lang/json/terrain_from_json.py msgid "missile" msgstr "åƼ弹" @@ -188717,18 +189574,6 @@ msgid "" "This unpowered pump previously would have moved fluids around in a hurry." msgstr "čæ™å°å·²ē»å¤±åŽ»åŠØ力ēš„ę³µę›¾ē»åÆ仄åæ«é€Ÿč¾“é€ę¶²ä½“ć€‚" -#: lang/json/terrain_from_json.py -msgid "centrifuge" -msgstr "ē¦»åæƒęœŗ" - -#. ~ Description for centrifuge -#: lang/json/terrain_from_json.py -msgid "" -"This is a centrifuge, a liquid separating device with an automated analyzer " -"unit. It could be used to analyze a medical fluid sample, such as blood, if" -" a test tube was placed in it." -msgstr "äø€å°åø¦ęœ‰č‡ŖåŠØåˆ†ęžä»Ŗ单元ēš„ē¦»åæƒęœŗ怂 åÆå°†č£…ęœ‰åŒ»ē”Øę¶²ä½“ę ·ęœ¬ļ¼ˆä¾‹å¦‚č”€ę¶²ļ¼‰ēš„čƕē®”ę”¾å…„å…¶äø­čæ›č”Œåˆ†ęžć€‚" - #: lang/json/terrain_from_json.py msgid "CVD machine" msgstr "åŒ–å­¦ę°”ē›øę²‰ē§Æ镀膜ęœŗ" @@ -188825,19 +189670,6 @@ msgstr "鄮갓ęœŗ" msgid "A machine with several taps that dispenses clean water." msgstr "äø€å°ęœ‰å‡ äøŖčƒ½ęµå‡ŗå‡€ę°“ēš„ę°“龙夓ēš„ęœŗå™Ø怂" -#: lang/json/terrain_from_json.py -msgid "plutonium generator" -msgstr "钚反åŗ”å †" - -#. ~ Description for plutonium generator -#: lang/json/terrain_from_json.py -msgid "" -"This imposing apparatus harnesses the power of the atom. Refined nuclear " -"fuel is 'burned' to provide nearly limitless electrical power. It's not " -"doing much good here though. Perhaps it could be salvaged for other " -"purposes." -msgstr "äø€å°čƒ½å¤Ÿåˆ©ē”ØåŽŸå­čƒ½ēš„å¼ŗå¤§č®¾å¤‡ć€‚ē»čæ‡ē²¾ē‚¼ēš„ę øē‡ƒę–™åœØ其äø­\"ē‡ƒēƒ§\"ä»„ęä¾›å‡ ä¹Žę— é™ēš„ē”µåŠ›ć€‚但ēŽ°åœØ它ē•™åœØčæ™é‡Œä»€ä¹ˆē”Øä¹Ÿę²”ęœ‰ć€‚ä¹Ÿč®øåÆä»„ę‹†å¼€å®ƒå›žę”¶äø€äŗ›éƒØ件怂" - #: lang/json/terrain_from_json.py msgid "telecom cabinet" msgstr "ē”µäæ”ęœŗꟜ" @@ -188952,46 +189784,6 @@ msgstr "传送åø¦" msgid "A conveyor belt. Used to transport things." msgstr "äø€ę”传送åø¦ć€‚ē”Øę„čæč¾“äøœč„æ怂" -#: lang/json/terrain_from_json.py -msgid "ting." -msgstr "叮ļ¼" - -#: lang/json/terrain_from_json.py -msgid "light machinery" -msgstr "č½»åž‹ęœŗę¢°" - -#. ~ Description for light machinery -#: lang/json/terrain_from_json.py -msgid "Assorted light machinery. You could scavenge it for parts." -msgstr "å„å¼č½»åž‹ęœŗę¢°ć€‚ä½ åÆä»„ę‹†č§£å®ƒčŽ·å¾—é›¶ä»¶ć€‚" - -#: lang/json/terrain_from_json.py -msgid "heavy machinery" -msgstr "重型ęœŗę¢°" - -#. ~ Description for heavy machinery -#: lang/json/terrain_from_json.py -msgid "Assorted heavy machinery. You could scavenge it for parts." -msgstr "各式重型ęœŗę¢°ć€‚ä½ åÆä»„ę‹†č§£å®ƒčŽ·å¾—é›¶ä»¶ć€‚" - -#: lang/json/terrain_from_json.py -msgid "old machinery" -msgstr "ꗧęœŗę¢°" - -#. ~ Description for old machinery -#: lang/json/terrain_from_json.py -msgid "Assorted old machinery. You could scavenge it for parts." -msgstr "å„å¼č€ę—§ęœŗå™Øć€‚ä½ åÆä»„ę‹†č§£å®ƒčŽ·å¾—é›¶ä»¶ć€‚" - -#: lang/json/terrain_from_json.py -msgid "electronic machinery" -msgstr "ē”µå­ęœŗę¢°" - -#. ~ Description for electronic machinery -#: lang/json/terrain_from_json.py -msgid "Assorted electronic machinery. You could scavenge it for parts." -msgstr "各ē§ē”µå­ęœŗę¢°ć€‚ä½ åÆä»„ę‹†č§£å®ƒčŽ·å¾—é›¶ä»¶ć€‚" - #: lang/json/terrain_from_json.py msgid "milking machine" msgstr "ęŒ¤å„¶ęœŗ" @@ -189062,29 +189854,6 @@ msgid "" "from the elements or to protect a campfire from the rain." msgstr "äø€äøŖč¢«é˜²ę°“åøƒč¦†ē›–ēš„é®č”½å¤„ļ¼ŒåÆē”Øę„čŗ²éæ大č‡Ŗē„¶ēš„å½±å“ęˆ–äæęŠ¤ēƝē«äøå—é›Øę°“ēš„ä¾µč¢­ć€‚" -#: lang/json/terrain_from_json.py -msgid "broken console" -msgstr "ē”µč„‘ļ¼ˆęŸåļ¼‰" - -#. ~ Description for broken console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It doesn't seem to be working. " -"It's the broken screen and shattered circuit boards that's telling you that." -msgstr "čæ™ę˜Æäø€äøŖē‹¬ē«‹ēš„č®”ē®—ęœŗē»ˆē«Æ怂ē “ē¢Žēš„屏幕和ē”µč·Æęæ告čƉ你它似乎已ē»ę— ę³•å·„作äŗ†ć€‚" - -#: lang/json/terrain_from_json.py -msgid "computer console" -msgstr "ē”µč„‘äø»ęœŗ" - -#. ~ Description for computer console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It can be used to view contents and" -" perform any allowed functions. It might even be possible to hack it, given" -" the skills." -msgstr "čæ™ę˜Æäø€äøŖē‹¬ē«‹ēš„č®”ē®—ęœŗē»ˆē«Æć€‚å®ƒåÆ仄ē”Øę„ęŸ„ēœ‹å†…å®¹å¹¶ę‰§č”Œä»»ä½•å…č®øēš„åŠŸčƒ½ć€‚å¦‚ęžœä½ ęœ‰ē›øå…³ęŠ€čƒ½ļ¼Œä¹ŸåÆä»„ä¾µå…„å®ƒć€‚" - #: lang/json/terrain_from_json.py msgid "mechanical winch" msgstr "ęœŗę¢°ē»žē›˜" @@ -191234,10 +192003,6 @@ msgstr "向äøŠę–œå”" msgid "An upward facing slope." msgstr "向äøŠēš„ę–œå”怂" -#: lang/json/terrain_from_json.py -msgid "rope leading up" -msgstr "向äøŠē»³ē“¢" - #. ~ Description for rope leading up #: lang/json/terrain_from_json.py msgid "A rope. You could climb up it." @@ -191516,7 +192281,7 @@ msgstr "化巄制造" #: lang/json/tool_quality_from_json.py msgid "smoking" -msgstr "ēƒŸē†" +msgstr "åøēƒŸ" #: lang/json/tool_quality_from_json.py msgid "distilling" @@ -191648,7 +192413,7 @@ msgstr "魔力ē¼–ē»‡" #: lang/json/tool_quality_from_json.py msgid "magic mutagen mixer" -msgstr "é­”ę³•čÆ±å˜å‰‚ę··åˆęœŗ" +msgstr "é­”ę³•ē‚¼é‡‘" #. ~ Trap-vehicle collision message for trap 'bubble wrap' #: lang/json/trap_from_json.py src/trapfunc.cpp @@ -191899,6 +192664,10 @@ msgstr "ę±½č½¦" msgid "Car Chassis" msgstr "ę±½č½¦åŗ•ē›˜" +#: lang/json/vehicle_from_json.py +msgid "Hybrid Car" +msgstr "ę··åŠØę±½č½¦" + #: lang/json/vehicle_from_json.py msgid "City Car" msgstr "都åø‚č½¦" @@ -193609,6 +194378,23 @@ msgid "" "disabled." msgstr "äø€å„—安å…Øč®¾å¤‡ļ¼Œä½æä½ åœØę²”é’„åŒ™ēš„ęƒ…å†µäø‹å¾ˆéš¾åÆåŠØč½¦č¾†ļ¼Œå¹¶äø”å¦‚ęžœä½ å°čƕå¼ŗč”Œę‰“ē«ļ¼Œå®ƒä¼šå“čµ·č­¦ęŠ„怂åÆä»„å…³é—­č­¦ęŠ„ć€‚" +#: lang/json/vehicle_part_from_json.py +msgid "smart engine controller" +msgstr "ę™ŗčƒ½å¼•ę“Žäø»ęŽ§" + +#. ~ Description for {'str': 'smart engine controller'} +#: lang/json/vehicle_part_from_json.py +#, no-python-format +msgid "" +"Electronic module that automatically switches combustion and electric " +"engines on and off minimizing fuel consumption and optimizing power output " +"and battery charge rate. Must be turned on to work. Simplified ruleset: 1." +" When throttling, maximize acceleration. 2. Keep battery at 90%. 3. " +"Minimize fuel consumption." +msgstr "" +"äø€äøŖå¤ę‚ēš„ē”µå­ęؔ块ļ¼ŒåÆę ¹ę®ęƒ…å†µč‡ŖåŠØę‰“å¼€ęˆ–å…³é—­å†…ē‡ƒå¼•ę“Žå’Œē”µåŠØå¼•ę“Žļ¼Œęœ€å¤§é™åŗ¦åœ°é™ä½Žę²¹č€—ļ¼Œä¼˜åŒ–č¾“å‡ŗ功ēŽ‡å’Œē”µę± å……ē”µåŠŸēŽ‡ć€‚åæ…锻开åÆåŽę‰čƒ½å·„ä½œć€‚ē®€åŒ–č§„åˆ™å¦‚äø‹ļ¼š1. " +"čø©äø‹ę²¹é—Øę—¶ļ¼Œå°½åÆčƒ½åŠ é€Ÿć€‚2. å°½åÆčƒ½äæęŒē”µę± ē”µé‡äøŗ90%怂3. å°½åÆčƒ½å‡å°‘ę²¹č€—ć€‚" + #: lang/json/vehicle_part_from_json.py msgid "5-point harness" msgstr "äŗ”ē‚¹å¼å®‰å…Øåø¦" @@ -194775,6 +195561,66 @@ msgstr "ęƒē“ " msgid "Disgusting Diet" msgstr "ꁶåæƒēš„鄮食" +#: lang/json/vitamin_from_json.py +msgid "Blood" +msgstr "" + +#: lang/json/vitamin_from_json.py +msgid "Red Blood Cells" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "NULL Weather - BUG" +msgstr "ę— ę•ˆå¤©ę°”ļ¼ˆBUGļ¼‰" + +#: lang/json/weather_type_from_json.py +msgid "Clear" +msgstr "ę™“ęœ—" + +#: lang/json/weather_type_from_json.py +msgid "Sunny" +msgstr "ꙓ" + +#: lang/json/weather_type_from_json.py +msgid "Cloudy" +msgstr "多äŗ‘" + +#: lang/json/weather_type_from_json.py +msgid "Light Drizzle" +msgstr "ęƛęƛé›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Drizzle" +msgstr "ē»†é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Rain" +msgstr "é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Thunder Storm" +msgstr "é›·ęš“" + +#: lang/json/weather_type_from_json.py +msgid "Acidic Drizzle" +msgstr "é…øꀧē»†é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Acid Rain" +msgstr "é…øé›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Flurries" +msgstr "小é›Ŗ" + +#: lang/json/weather_type_from_json.py +msgid "Snowing" +msgstr "é›Ŗ" + +#: lang/json/weather_type_from_json.py +msgid "Snowstorm" +msgstr "ęš“é›Ŗ" + #: src/achievement.cpp msgid "time of cataclysm" msgstr "ē¾å˜ä¹‹ę—„" @@ -194942,8 +195788,7 @@ msgstr "ä½ ēš„čƒ½é‡č¢«åøčµ°äŗ†ļ¼" msgid "You cannot hack this." msgstr "ä½ ę— ę³•å…„ä¾µå®ƒć€‚" -#: src/activity_actor.cpp src/computer_session.cpp src/computer_session.cpp -#: src/iuse.cpp src/map.cpp +#: src/activity_actor.cpp src/computer_session.cpp src/iuse.cpp src/map.cpp msgid "an alarm sound!" msgstr "äø€å£°č­¦ęŠ„ļ¼" @@ -195084,6 +195929,16 @@ msgstr "ē»§ē»­å°čÆ•å…„ē”怂" msgid "Continue trying to fall asleep and don't ask again." msgstr "ē»§ē»­å°čÆ•å…„ē”并äøå†ęē¤ŗ怂" +#: src/activity_actor.cpp +#, c-format +msgid "You disassemble your %s." +msgstr "ä½ ę‹†č§£äŗ†%s怂" + +#: src/activity_actor.cpp src/player.cpp +#, c-format +msgid "You unload your %s." +msgstr "ä½ ęø…ē©ŗäŗ†%s怂" + #: src/activity_actor.cpp msgid "You are too tired to exercise." msgstr "ä½ å¤Ŗē“Æäŗ†ļ¼Œę— ę³•é”»ē‚¼ć€‚" @@ -195573,11 +196428,6 @@ msgstr[0] " ꊊå°øä½“å¼„ęˆäŗ†äø€ę»©ēƒ‚ę³„怂" msgid "Can't reload the %s." msgstr "ę— ę³•é‡ę–°č£…å”«%s怂" -#: src/activity_handlers.cpp src/iexamine.cpp -#, c-format -msgid "You reload the %s." -msgstr "ä½ é‡ę–°č£…å”«äŗ†%s怂" - #: src/activity_handlers.cpp #, c-format msgid "" @@ -195594,6 +196444,11 @@ msgstr "你将äø€å‘ %2$s 唫兄 %1$s怂" msgid "You refill the %s." msgstr "ä½ é‡ę–°č£…å”«äŗ†%s怂" +#: src/activity_handlers.cpp +#, c-format +msgid "You reload the %1$s with %2$s." +msgstr "" + #: src/activity_handlers.cpp src/bionics.cpp msgid "There's nothing to light there." msgstr "čæ™é‡Œę²”꜉åÆ仄ē‚¹ē‡ƒēš„äøœč„æ怂" @@ -195720,6 +196575,10 @@ msgstr "ä½ ę— ę³•ä»Žäø­å­¦ä¹ åˆ°ę–°äøœč„æ怂" msgid "%s %s\n" msgstr "%s%s\n" +#: src/activity_handlers.cpp src/magic.cpp +msgid "bionic power" +msgstr "ē”ŸåŒ–čƒ½é‡" + #: src/activity_handlers.cpp #, c-format msgid "Charges: %s/%s %s (%s per use)\n" @@ -196098,16 +196957,6 @@ msgstr "ä½ ę‰“å¼€äŗ†ä½ ēš„åˆ®čƒ”刀巄具包ļ¼Œå¼€å§‹åˆ®čƒ”子" msgid "You give your hair a trim." msgstr "ä½ äæ®äŗ†äæ®ä½ ēš„ęÆ›å‘ć€‚" -#: src/activity_handlers.cpp -#, c-format -msgid "You disassemble your %s." -msgstr "ä½ ę‹†č§£äŗ†%s怂" - -#: src/activity_handlers.cpp src/player.cpp -#, c-format -msgid "You unload your %s." -msgstr "ä½ ęø…ē©ŗäŗ†%s怂" - #: src/activity_handlers.cpp #, c-format msgid "You have run out of %s." @@ -197084,7 +197933,7 @@ msgstr "čæ™ę˜Æä½ ēš„外éƒØ光ēŽÆ怂" msgid "Properties" msgstr "å±žę€§" -#: src/armor_layers.cpp +#: src/armor_layers.cpp src/item.cpp msgid "Coverage:" msgstr "覆ē›–ēŽ‡ļ¼š" @@ -199080,7 +199929,7 @@ msgstr "ä½ ę²”ęœ‰č¶³å¤Ÿčƒ½é‡ęæ€ę“»%s怂" msgid "Deactivate your %s first!" msgstr "čƷ先关闭你ēš„%sļ¼" -#: src/bionics.cpp src/player.cpp +#: src/bionics.cpp src/character.cpp #, c-format msgid "Stop wielding %s?" msgstr "åœę­¢ę‰‹ęŒ %sļ¼Ÿ" @@ -200481,6 +201330,11 @@ msgstr "åœØå“Ŗ里äø‹é©¬ļ¼Ÿ" msgid "You cannot dismount there!" msgstr "ä½ äøčƒ½åœØ那里äø‹é©¬ļ¼" +#: src/character.cpp +#, c-format +msgid "This task is too simple to train your %s beyond %d." +msgstr "čæ™åÆ¹ä½ ę„čÆ“č½»č€Œę˜“äø¾ļ¼Œę— ę³•č®­ē»ƒ %s ęŠ€čƒ½č¶…čæ‡ %d ēŗ§ć€‚" + #: src/character.cpp msgid "You struggle to stand." msgstr "ä½ ęŒ£ę‰Žäŗ†äø€ä¼šļ¼Œę²”čƒ½ē«™čµ·ę„怂" @@ -200651,6 +201505,16 @@ msgstr " 逃ē¦»äŗ†ę·±å‘ļ¼" msgid "Your %s bionic comes back online." msgstr "ä½ ēš„%sē”ŸåŒ–ę’ä»¶ę¢å¤ę­£åøø怂" +#: src/character.cpp +#, c-format +msgid "Your skill in %s has increased to %d!" +msgstr "ä½ ēš„ %s ęŠ€čƒ½å‡ēŗ§č‡³ē­‰ēŗ§ %dļ¼" + +#: src/character.cpp +#, c-format +msgid "You feel that %s tasks of this level are becoming trivial." +msgstr "ä½ ę„Ÿåˆ°čæ™äøŖēŗ§åˆ«ēš„ %s 巄作实åœØę˜Æå¤Ŗē®€å•äŗ†ć€‚" + #: src/character.cpp #, c-format msgid "You put on your %s." @@ -200765,6 +201629,15 @@ msgstr "ä½ ę²”ęœ‰ä»»ä½•éœ€č¦ä½æē”Ø它ēš„ę–­č‚¢ć€‚" msgid "%s doesn't have any broken limbs this could help." msgstr "%s ę²”ęœ‰ä»»ä½•éœ€č¦ä½æē”Ø它ēš„ę–­č‚¢ć€‚" +#: src/character.cpp +msgid "You don't need a tourniquet to stop the bleeding." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "%s doesn't need a tourniquet to stop the bleeding." +msgstr "" + #: src/character.cpp msgid "You don't have enough arms to wear that." msgstr "ä½ ę²”ęœ‰č¶³å¤Ÿēš„ę‰‹ę„ē©æčæ™äøŖ怂" @@ -200945,7 +201818,7 @@ msgstr "äø„重鄄é„æ" msgid "ERROR!" msgstr "错čÆÆļ¼" -#: src/character.cpp src/npctalk.cpp +#: src/character.cpp src/talker_npc.cpp msgid "Exhausted" msgstr "ē²¾ē–²åŠ›ē«­" @@ -200989,7 +201862,7 @@ msgstr "ä½ čœ·ē¼©čŗ«čŗÆꌤčæ›čæ™č¾†č½¦ć€‚" msgid "You have a sudden heart attack!" msgstr "ä½ ēŖē„¶å‘作åæƒč„ē—…ļ¼" -#: src/character.cpp +#: src/character.cpp src/player_hardcoded_effects.cpp msgid " has a sudden heart attack!" msgstr " ēŖē„¶åæƒč„ē—…发作ļ¼" @@ -201217,12 +202090,12 @@ msgstr "儽" #: src/character.cpp #, c-format -msgid "Chance to stop: %d %%" -msgstr "ę­¢č”€ę¦‚ēŽ‡ļ¼š%d%%" +msgid "Expected reduction of bleeding by: %d %%" +msgstr "" #: src/character.cpp -msgid "This will not stop the bleeding." -msgstr "čÆ„ē‰©å“ę— ę³•ē”ØäŗŽę­¢č”€ć€‚" +msgid "This will not affect the bleeding." +msgstr "" #: src/character.cpp #, c-format @@ -201654,6 +202527,41 @@ msgstr "ä½ ēš„ %1$s č¢«čæ›äø€ę­„ē “åęˆ %2$s äŗ†ļ¼" msgid "Your %1$s is %2$s!" msgstr "ä½ ēš„ %1$s č¢« %2$s äŗ†ļ¼" +#: src/character.cpp +msgid "Can't wield spilt liquids." +msgstr "ę— ę³•ę‰‹ęŒå·²ę“’å‡ŗēš„ę¶²ä½“" + +#: src/character.cpp +msgid "You need at least one arm to even consider wielding something." +msgstr "ä½ č‡³å°‘éœ€č¦äø€åŖčƒ½ē”Øēš„ę‰‹č‡‚ę‰čƒ½ę‰‹ęŒē‰©å“ć€‚" + +#: src/character.cpp +#, c-format +msgid "The %s is preventing you from wielding the %s." +msgstr "%s č®©ä½ ę— ę³•ę‰‹ęŒ %s怂" + +#: src/character.cpp +msgid "Something you are wearing hinders the use of both hands." +msgstr "ä½ ē©æē€ēš„č£…å¤‡é˜»ē¢äŗ†ę‰‹ēš„ä½æē”Ø怂" + +#: src/character.cpp +#, c-format +msgid "The %s can't be wielded with only one arm." +msgstr "ę— ę³•å•ę‰‹ęŒęœ‰ %s怂" + +#: src/character.cpp +#, c-format +msgid "You are too weak to wield %s with only one arm." +msgstr "你力量äøč¶³ļ¼Œę— ę³•å•ę‰‹ę‰‹ęŒ %s怂" + +#: src/character.cpp +msgid " (empty)" +msgstr "ļ¼ˆē©ŗļ¼‰" + +#: src/character.cpp src/npctalk.cpp +msgid "fists" +msgstr "ę‹³å¤“" + #: src/character.cpp #, c-format msgid "You are no longer able to wield your %s and drop it!" @@ -202202,6 +203110,11 @@ msgstr "ē™»å½•ęˆåŠŸć€‚čÆ·ęŒ‰ä»»ę„é”®ā€¦ā€¦" msgid "%s - Root Menu" msgstr "%s - ę ¹ē›®å½•" +#: src/computer_session.cpp +#, c-format +msgid "%s (UNAVAILABLE)" +msgstr "" + #: src/computer_session.cpp msgid "Password required." msgstr "éœ€č¦åƆē ć€‚" @@ -202807,7 +203720,7 @@ msgstr "ę­„éŖ¤/ę–¹ę³• #%dļ¼š" msgid "Result: " msgstr "ē»“ęžœļ¼š" -#: src/construction.cpp +#: src/construction.cpp src/worldfactory.cpp msgid "N/A" msgstr "ꗠ" @@ -203458,6 +204371,10 @@ msgstr "" "ä½ ę²”ęœ‰č¶³å¤Ÿēš„čƒ½é‡å®Œęˆ%s怂\n" "ä»č¦ē»§ē»­å—ļ¼Ÿ" +#: src/craft_command.cpp +msgid "You don't have the required proficiencies to craft this!" +msgstr "" + #: src/craft_command.cpp msgid "" "This craft will use rotten components.\n" @@ -203942,6 +204859,11 @@ msgstr "äø»č¦ęŠ€čƒ½ļ¼š%s" msgid "Other skills: %s" msgstr "å…¶ä»–ęŠ€čƒ½ļ¼š%s" +#: src/crafting_gui.cpp +#, c-format +msgid "Proficiencies Required: %s" +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "Time to complete: %s" @@ -203985,6 +204907,12 @@ msgid "" "components" msgstr "ē”±äŗŽęœ‰å¤šé”¹ęę–™č¦ę±‚éœ€č¦åŒäøŖē‰©å“ļ¼Œä½ ę— ę³•åˆ¶é€ čÆ„ē‰©å“" +#: src/crafting_gui.cpp +msgid "" +"Cannot be crafted because you lack the required " +"proficiencies." +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "v (%s for more)" @@ -204369,6 +205297,10 @@ msgstr "ē¼–č¾‘ēŽ©å®¶/NPC" msgid "Damage self" msgstr "č‡Ŗꮋ" +#: src/debug_menu.cpp +msgid "Bleed self" +msgstr "" + #: src/debug_menu.cpp msgid "Set automove route" msgstr "č‡ŖåŠØåÆ»č·Æč‡³ęŸē‚¹" @@ -204501,6 +205433,14 @@ msgstr "退å‡ŗč‡³äø»čœå•" msgid "Gameā€¦" msgstr "ęøøꈏ..." +#: src/debug_menu.cpp +msgid "Change [b]attery charge" +msgstr "äæ®ę”¹č½½å…·ē”µé‡" + +#: src/debug_menu.cpp +msgid "Vehicleā€¦" +msgstr "č½½å…·ā€¦ā€¦" + #: src/debug_menu.cpp msgid "Teleport - short range" msgstr "ēŸ­č·ä¼ é€" @@ -205136,12 +206076,8 @@ msgstr "地ē‚¹ %dļ¼š%d åœØ %dļ¼š%dļ¼Œ%s\n" #: src/debug_menu.cpp #, c-format -msgid "" -"Current turn: %d.\n" -"%s\n" -msgstr "" -"当前回合ļ¼š%d怂\n" -"%s\n" +msgid "Current turn: %d.\n" +msgstr "当前回合ļ¼š%d怂\n" #: src/debug_menu.cpp #, c-format @@ -205149,14 +206085,6 @@ msgid "%d creature exists.\n" msgid_plural "%d creatures exist.\n" msgstr[0] "%d åŖē”Ÿē‰©å­˜åœØ怂\n" -#: src/debug_menu.cpp -msgid "NPCs are going to spawn." -msgstr "NPC将会ē”Ÿęˆć€‚" - -#: src/debug_menu.cpp -msgid "NPCs are NOT going to spawn." -msgstr "NPC将äøä¼šē”Ÿęˆć€‚" - #: src/debug_menu.cpp #, c-format msgid "%s: map ( %d:%d ) pos ( %d:%d )" @@ -205216,6 +206144,22 @@ msgstr "é€‰ę‹©éœ€č¦åˆ·ę–°ēš„äŗ¤é€šå·„具" msgid "%1$s (%2$s)" msgstr "%1$sļ¼ˆ%2$sļ¼‰" +#: src/debug_menu.cpp +msgid "Vehicle condition" +msgstr "č½½å…·ēŠ¶å†µ" + +#: src/debug_menu.cpp +msgid "Light damage" +msgstr "č½»åŗ¦ęŸå" + +#: src/debug_menu.cpp +msgid "Undamaged" +msgstr "完儽" + +#: src/debug_menu.cpp +msgid "Disabled (tires or engine)" +msgstr "ę— ę³•ē§»åŠØļ¼ˆč½®čƒŽ/å¼•ę“Žę•…éšœļ¼‰" + #: src/debug_menu.cpp msgid "Martial arts debug." msgstr "调čÆ•ę­¦ęœÆ怂" @@ -205277,6 +206221,10 @@ msgstr "äæęŒę­£åøø风速" msgid "Damage self for how much? hp: %s" msgstr "åƹč‡Ŗå·±é€ ęˆå¤šå°‘ē‚¹ä¼¤å®³ļ¼Ÿå½“前ē”Ÿå‘½å€¼ļ¼š%s" +#: src/debug_menu.cpp +msgid "Add bleeding duration in minutes, equal to intensity:" +msgstr "" + #: src/debug_menu.cpp msgid "This binary was not compiled with tiles support." msgstr "当前ęøøꈏē؋åŗē¼–čÆ‘ę—¶ęœŖé€‰ę‹©å…¼å®¹å›¾åƒē‰ˆć€‚" @@ -205408,6 +206356,14 @@ msgstr "č®¾ē½®ę³•ęœÆē­‰ēŗ§ļ¼šļ¼ˆå½“前%dļ¼‰" msgid "%s is now level %d!" msgstr "%s å·²č®¾äøŗ %d ēŗ§ļ¼" +#: src/debug_menu.cpp src/iuse.cpp src/iuse.cpp +msgid "There's no vehicle there." +msgstr "é‚£é‡Œę²”ęœ‰č½½å…·ć€‚" + +#: src/debug_menu.cpp +msgid "By how much? (in kJ, negative to discharge)" +msgstr "增加多少ļ¼Ÿļ¼ˆå•ä½KJļ¼Œč“Ÿę•°äøŗ减少ļ¼‰" + #: src/descriptions.cpp #, c-format msgid "" @@ -205774,12 +206730,12 @@ msgstr "ę—‹č½¬" #: src/editmap.cpp msgctxt "map generator" msgid "Apply" -msgstr "ä½æē”Ø" +msgstr "åŗ”ē”Ø" #: src/editmap.cpp msgctxt "map generator" msgid "Change Overmap (Doesn't Apply)" -msgstr "ę”¹å˜å¤§åœ°å›¾ļ¼ˆč€Œäøé‡‡ē”Øļ¼‰" +msgstr "ę”¹å˜å¤§åœ°å›¾ļ¼ˆč€Œäøåŗ”ē”Øļ¼‰" #: src/editmap.cpp #, c-format @@ -206116,6 +207072,22 @@ msgstr "å‡ŗč‰²" msgid "perfect" msgstr "完ē¾Ž" +#: src/effect.cpp +msgid "miniscule" +msgstr "" + +#: src/effect.cpp +msgid "small" +msgstr "č¾ƒå°" + +#: src/effect.cpp +msgid "moderate" +msgstr "" + +#: src/effect.cpp +msgid "excellent" +msgstr "" + #. ~ Default format for scores. %1$s is statistic description; %2$s is value. #: src/event_statistics.cpp #, c-format @@ -208886,6 +209858,11 @@ msgstr "å½“å‰å¤§åœ°å›¾åę ‡ļ¼š %dļ¼Œ%dļ¼Œ%d" msgid "Your local position: %d, %d, %d" msgstr "å½“å‰å°åœ°å›¾åę ‡ļ¼š %dļ¼Œ%dļ¼Œ%d" +#: src/game.cpp +#, c-format +msgid "Total NPCs within %d OMTs: %d. %d are static NPCs." +msgstr "%d å¤§åœ°å›¾č·ē¦»å†…NPCꀻꕰļ¼š%dć€‚å…¶äø­ %d äøŖę˜Æ静ꀁNPC怂" + #: src/game.cpp msgid "East:" msgstr "äøœļ¼š" @@ -210626,12 +211603,12 @@ msgid "Your inventory is empty." msgstr "ä½ ēš„ē‰©å“ę ę˜Æē©ŗēš„怂" #: src/game_inventory.cpp -msgid "ENCUMBRANCE" -msgstr "ē“Æ赘åŗ¦" +msgid "AVG ENCUMBRANCE" +msgstr "" #: src/game_inventory.cpp -msgid "COVERAGE" -msgstr "覆ē›–ēŽ‡" +msgid "AVG COVERAGE" +msgstr "" #: src/game_inventory.cpp msgid "WARMTH" @@ -211640,7 +212617,7 @@ msgid "" "You're saving a tutorial - the tutorial world lacks certain features of " "normal worlds. Weird things might happen when you load this save. You have" " been warned." -msgstr "ä½ åœØę•™å­¦č™šę‹Ÿäø–ē•Œäø­å­˜ę”£äŗ†ļ¼- ę•™å­¦äø–ē•Œäøę˜ÆēœŸå®žäø–ē•Œļ¼Œē¼ŗ少č®ø多关键ē‰¹ę€§ć€‚čƻ取čæ™äøŖå­˜ę”£ä¼šå‘ē”ŸäøåÆ굋ēš„é—®é¢˜ć€‚čÆ„ę€Žä¹ˆåšä½ ę˜Žē™½äŗ†å—ļ¼Ÿ" +msgstr "ä½ åœØę•™å­¦č™šę‹Ÿäø–ē•Œäø­å­˜ę”£äŗ†ļ¼- ę•™å­¦äø–ē•Œäøę˜ÆēœŸå®žäø–ē•Œļ¼Œē¼ŗ少č®øå¤šå…³é”®åŠŸčƒ½ć€‚čƻ取čæ™äøŖå­˜ę”£ä¼šå‘ē”ŸäøåÆ굋ēš„é—®é¢˜ć€‚čÆ„ę€Žä¹ˆåšä½ ę˜Žē™½äŗ†å—ļ¼Ÿ" #: src/gates.cpp msgid "There's some buffoon in the way!" @@ -213787,6 +214764,11 @@ msgstr "将多少 %1$s ę”¾čæ› %2$sļ¼Ÿ" msgid "The %1$s contains %2$d %3$s." msgstr "%1$s ē”± %2$d äøŖ %3$s Ꞅꈐ怂" +#: src/iexamine.cpp +#, c-format +msgid "You reload the %s." +msgstr "ä½ é‡ę–°č£…å”«äŗ†%s怂" + #: src/iexamine.cpp msgid "Do what with the curtains?" msgstr "åƹēŖ—åø˜åšä»€ä¹ˆļ¼Ÿ" @@ -214641,6 +215623,10 @@ msgstr "å®Œęˆ" msgid "Body parts" msgstr "čŗ«ä½“éƒØ位" +#: src/init.cpp +msgid "Weather types" +msgstr "å¤©ę°”ē±»åž‹" + #: src/init.cpp msgid "Field types" msgstr "åœŗ地ē±»åž‹" @@ -215478,10 +216464,6 @@ msgstr "腐ēƒ‚ļ¼ˆå›žåˆļ¼‰ļ¼š" msgid "max rot (turns): " msgstr "č…åå›žåˆę•°ļ¼š" -#: src/item.cpp -msgid "last rot: " -msgstr "č…åå¼€å§‹å›žåˆļ¼ˆäæ®ę­£å€¼ļ¼‰ļ¼š" - #: src/item.cpp msgid "last temp: " msgstr "ęœ€åŽęµ‹ęø©å›žåˆļ¼š" @@ -215745,7 +216727,7 @@ msgid "Recommended strength (burst): " msgstr "å»ŗč®®å¼ŗåŗ¦ļ¼ˆčæžå‘ļ¼‰ļ¼š" #: src/item.cpp -msgid " moves " +msgid " moves" msgstr " č”ŒåŠØē‚¹" #: src/item.cpp @@ -215782,10 +216764,6 @@ msgstr "50%命äø­č·ē¦»ļ¼š" msgid "" msgstr "" -#: src/item.cpp -msgid " moves" -msgstr " č”ŒåŠØē‚¹" - #: src/item.cpp msgid "Time to reach aim level: " msgstr "ēž„准ē”Øę—¶ļ¼š" @@ -215913,164 +216891,169 @@ msgid "" msgstr "ē‰©å“é˜²ęŠ¤å› č€ä¹…åŗ¦č€Œ 降低ļ¼Œä½ åÆ仄通čæ‡ äæ®ē†čÆ„ē‰©å“ ę¢å¤é˜²ęŠ¤ć€‚" #: src/item.cpp -msgid "Covers: " -msgstr "覆ē›–ļ¼š" +msgid "Covers:" +msgstr "" #: src/item.cpp -msgid "The head. " -msgstr "夓éƒØ怂" +msgid " The head." +msgstr "" #: src/item.cpp -msgid "The eyes. " -msgstr "ēœ¼ē›ć€‚" +msgid " The eyes." +msgstr "" #: src/item.cpp -msgid "The mouth. " -msgstr "å˜“å·“ć€‚" +msgid " The mouth." +msgstr "" #: src/item.cpp -msgid "The torso. " -msgstr "čŗÆå¹²ć€‚" +msgid " The torso." +msgstr "" #: src/item.cpp -msgid "Either arm. " -msgstr "å·¦č‡‚/å³č‡‚ć€‚" +msgid " Either arm." +msgstr "" #: src/item.cpp -msgid "The arms. " -msgstr "ꉋ臂怂" +msgid " The arms." +msgstr "" #: src/item.cpp -msgid "The left arm. " -msgstr "å·¦č‡‚ć€‚" +msgid " The left arm." +msgstr "" #: src/item.cpp -msgid "The right arm. " -msgstr "å³č‡‚ć€‚" +msgid " The right arm." +msgstr "" #: src/item.cpp -msgid "Either hand. " -msgstr "å·¦ę‰‹/å³ę‰‹ć€‚" +msgid " Either hand." +msgstr "" #: src/item.cpp -msgid "The hands. " -msgstr "ꉋꎌ怂" +msgid " The hands." +msgstr "" #: src/item.cpp -msgid "The left hand. " -msgstr "å·¦ę‰‹ć€‚" +msgid " The left hand." +msgstr "" #: src/item.cpp -msgid "The right hand. " -msgstr "å³ę‰‹ć€‚" +msgid " The right hand." +msgstr "" #: src/item.cpp -msgid "Either leg. " -msgstr "å·¦č…æ/右č…æ怂" +msgid " Either leg." +msgstr "" #: src/item.cpp -msgid "The legs. " -msgstr "č…æéƒØ怂" +msgid " The legs." +msgstr "" #: src/item.cpp -msgid "The left leg. " -msgstr "å·¦č…æ怂" +msgid " The left leg." +msgstr "" #: src/item.cpp -msgid "The right leg. " -msgstr "右č…æ怂" +msgid " The right leg." +msgstr "" #: src/item.cpp -msgid "Either foot. " -msgstr "å·¦č„š/å³č„šć€‚" +msgid " Either foot." +msgstr "" #: src/item.cpp -msgid "The feet. " -msgstr "脚ꎌ怂" +msgid " The feet." +msgstr "" #: src/item.cpp -msgid "The left foot. " -msgstr "å·¦č„šć€‚" +msgid " The left foot." +msgstr "" #: src/item.cpp -msgid "The right foot. " -msgstr "å³č„šć€‚" +msgid " The right foot." +msgstr "" #: src/item.cpp -msgid "Nothing." -msgstr "ꗠ怂" +msgid " Nothing." +msgstr "" #: src/item.cpp -msgid "Layer: " -msgstr "č”£ē‰©å±‚ļ¼š" +msgid "Layer:" +msgstr "" #: src/item.cpp -msgid "Personal aura. " -msgstr "č‡Ŗ体光ēŽÆ怂" +msgid " Personal aura." +msgstr "" #: src/item.cpp -msgid "Close to skin. " -msgstr "č““čŗ«ć€‚" +msgid " Close to skin." +msgstr "" #: src/item.cpp -msgid "Strapped. " -msgstr "背ē³»ć€‚" +msgid " Strapped." +msgstr "" #: src/item.cpp -msgid "Outer. " -msgstr "å¤–å„—ć€‚" +msgid " Outer." +msgstr "" #: src/item.cpp -msgid "Waist. " -msgstr "腰éƒØ怂" +msgid " Waist." +msgstr "" #: src/item.cpp -msgid "Outer aura. " -msgstr "外éƒØ光ēŽÆ怂" +msgid " Outer aura." +msgstr "" #: src/item.cpp -msgid "Normal. " -msgstr "ꙮ通怂" +msgid " Normal." +msgstr "" #: src/item.cpp -msgid "Coverage: " -msgstr "覆ē›–ēŽ‡ļ¼š" +msgid "Average Coverage: " +msgstr "" #: src/item.cpp msgid "Warmth: " msgstr "äæęš–åŗ¦ļ¼š" #: src/item.cpp -msgid " (fits)" -msgstr "ļ¼ˆåˆčŗ«ļ¼‰" +msgid " (fits)" +msgstr "" #: src/item.cpp -msgid " (poor fit)" -msgstr "ļ¼ˆäøåˆčŗ«ļ¼‰" +msgid " (poor fit)" +msgstr "" #: src/item.cpp -msgid " (too big)" -msgstr "ļ¼ˆå¤Ŗ大ļ¼‰" +msgid " (too big)" +msgstr "" #: src/item.cpp -msgid " (huge!)" -msgstr "ļ¼ˆå·Ø大ļ¼ļ¼‰" +msgid " (huge!)" +msgstr "" #: src/item.cpp -msgid " (too small)" -msgstr "ļ¼ˆå¤Ŗ小ļ¼‰" +msgid " (too small)" +msgstr "" #: src/item.cpp -msgid " (tiny!)" -msgstr "ļ¼ˆęžå°ļ¼ļ¼‰" +msgid " (tiny!)" +msgstr "" #: src/item.cpp -msgid "Encumbrance: " -msgstr "ē“Æ赘åŗ¦ļ¼š" +msgid "Encumbrance:" +msgstr "" #: src/item.cpp -msgid "Encumbrance when full: " -msgstr "č£…ę»”ę—¶ē“Æ赘åŗ¦ļ¼š" +#, c-format +msgid "%s:" +msgstr "" + +#: src/item.cpp +msgid "When Full:" +msgstr "" #: src/item.cpp msgid "Weight capacity modifier: " @@ -216418,12 +217401,12 @@ msgstr "ę‹†č§£ éœ€č¦ %1$s 及 %2$s åÆčŽ·å¾—ļ¼š%3$s" msgid "" "Has level %1$d %2$s quality and is rated at %3$d " "%4$s" -msgstr "å…·ęœ‰ %1$d ēŗ§ %2$s ē‰¹ę€§äø”ę‰æ重äøŠé™äøŗ %3$d %4$s" +msgstr "å…·ęœ‰ %1$d ēŗ§ %2$s åŠŸčƒ½äø”ę‰æ重äøŠé™äøŗ %3$d %4$s" #: src/item.cpp #, c-format msgid "Has level %1$d %2$s quality." -msgstr "å…·ęœ‰ %1$d ēŗ§ %2$s ē‰¹ę€§ć€‚" +msgstr "å…·ęœ‰ %1$d ēŗ§ %2$s åŠŸčƒ½ć€‚" #: src/item.cpp msgid "Contains items with qualities:" @@ -216454,24 +217437,24 @@ msgid "Power Capacity:" msgstr "ē”ŸåŒ–čƒ½é‡å®¹é‡ļ¼š" #: src/item.cpp -msgid "Environmental Protection: " -msgstr "ēŽÆå¢ƒé˜²ęŠ¤ļ¼š" +msgid "Environmental Protection:" +msgstr "" #: src/item.cpp -msgid "Bash Protection: " -msgstr "é’å‡»é˜²ęŠ¤ļ¼š" +msgid "Bash Protection:" +msgstr "" #: src/item.cpp -msgid "Cut Protection: " -msgstr "ę–©å‡»é˜²ęŠ¤ļ¼š" +msgid "Cut Protection:" +msgstr "" #: src/item.cpp -msgid "Ballistic Protection: " -msgstr "å°„å‡»é˜²ęŠ¤ļ¼š" +msgid "Ballistic Protection:" +msgstr "" #: src/item.cpp -msgid "Stat Bonus: " -msgstr "å±žę€§åŠ ęˆļ¼š" +msgid "Stat Bonus:" +msgstr "" #: src/item.cpp msgid "Melee damage: " @@ -218532,10 +219515,6 @@ msgstr "从å“Ŗé‡ŒęŠ½å–ļ¼Ÿ" msgid "There is nothing to siphon nearby." msgstr "附čæ‘ę²”꜉åÆä»„ęŠ½å–ēš„åÆ¹č±”ć€‚" -#: src/iuse.cpp -msgid "There's no vehicle there." -msgstr "é‚£é‡Œę²”ęœ‰č½½å…·ć€‚" - #: src/iuse.cpp msgid "With a snarl, the combat chainsaw screams to life!" msgstr "随ē€äø€å£°ä½Žå¼ļ¼Œę ¼ę–—链é”ÆēŒ›ēƒˆēš„ę—‹åŠØčµ·ę„ļ¼" @@ -221564,6 +222543,10 @@ msgstr "čæ™åÆē–¼å¾—č¦å‘½ļ¼" msgid "It itches a little." msgstr "ä½ ę„Ÿåˆ°ęœ‰ē‚¹ē–¼ē—›ć€‚" +#: src/iuse_actor.cpp +msgid "Bleeding has not stopped completely!" +msgstr "" + #: src/iuse_actor.cpp msgid "You cannot cauterize while mounted." msgstr "äøčƒ½åœØéŖ‘ä¹˜ę—¶ē¼ēƒ§ä¼¤å£ć€‚" @@ -221887,12 +222870,22 @@ msgid "You stop the bleeding." msgstr "ä½ ę­¢ä½äŗ†č”€ć€‚" #: src/iuse_actor.cpp -msgid "The wound still bleeds." -msgstr "伤口仍åœØ굁蔀怂" +msgid "You reduce the bleeding, but it's not stopped yet." +msgstr "" #: src/iuse_actor.cpp -msgid "You fail to stop the bleeding." -msgstr "ä½ ę²”čƒ½ęˆåŠŸę­¢č”€ć€‚" +msgid "The bleeding is reduced, but not stopped." +msgstr "" + +#: src/iuse_actor.cpp +msgid "" +"Your dressing is too ineffective for a bleeding of this extent, and you fail" +" to stop it." +msgstr "" + +#: src/iuse_actor.cpp +msgid "The wound still bleeds." +msgstr "伤口仍åœØ굁蔀怂" #: src/iuse_actor.cpp msgid "The wound is cleaned." @@ -221995,12 +222988,16 @@ msgid "Actual disinfecting quality: " msgstr "å®žé™…ę¶ˆęƒļ¼š" #: src/iuse_actor.cpp -msgid "Chance to heal (percent): " -msgstr "ę²»ę„ˆå‡ ēŽ‡ļ¼ˆ%ļ¼‰ļ¼š" +msgid "Effect on bleeding: " +msgstr "" + +#: src/iuse_actor.cpp +msgid "Actual effect on bleeding: " +msgstr "" #: src/iuse_actor.cpp -msgid "* Bleeding: " -msgstr "* 굁蔀ļ¼š" +msgid "Chance to heal (percent): " +msgstr "ę²»ę„ˆå‡ ēŽ‡ļ¼ˆ%ļ¼‰ļ¼š" #: src/iuse_actor.cpp msgid "* Bite: " @@ -222066,8 +223063,8 @@ msgid "It's not a gun." msgstr "čæ™äøę˜ÆęžŖę¢°ć€‚" #: src/iuse_actor.cpp -msgid "The barrel is too short." -msgstr "ęžŖē®”čæ‡ēŸ­ć€‚" +msgid "The barrel is too small." +msgstr "" #: src/iuse_actor.cpp msgid "The barrel is already sawn-off." @@ -223572,10 +224569,6 @@ msgstr "魔力" msgid "stamina" msgstr "č€åŠ›" -#: src/magic.cpp -msgid "bionic power" -msgstr "ē”ŸåŒ–čƒ½é‡" - #: src/magic.cpp msgid "error: energy_type" msgstr "错čÆÆļ¼ščƒ½é‡ē±»åž‹" @@ -225594,7 +226587,7 @@ msgstr "ä½ ē”Øå°½å…Ø力ē‹ ę•² %s 让他们ēš„ %s ꎉåœØäø€ę—ļ¼" msgid "You smash %s with all your might but %s remains in their hands!" msgstr "ä½ å…Ø力ē‹ ę•² %s 但ę˜Æ %s 卓仍ē„¶åœØ他们ēš„ę‰‹é‡Œļ¼" -#: src/melee.cpp src/npctalk.cpp +#: src/melee.cpp src/talker_npc.cpp #, c-format msgid "%s is hostile!" msgstr "%s ę˜Æꕌåƹēš„ļ¼" @@ -226426,6 +227419,36 @@ msgctxt "memorial_female" msgid "Died of a drug overdose." msgstr "ę­»äŗŽčÆē‰©čæ‡é‡ć€‚" +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died from loss of red blood cells." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died from loss of red blood cells." +msgstr "" + #: src/memorial_logger.cpp msgctxt "memorial_male" msgid "Succumbed to the infection." @@ -230459,10 +231482,6 @@ msgctxt "Paralyze as an action" msgid "paralyze" msgstr "éŗ»ē—¹" -#: src/monster.cpp -msgid "cause bleed" -msgstr "굁蔀" - #: src/monster.cpp msgid "It has a head." msgstr "å®ƒęœ‰å¤“ć€‚" @@ -231521,6 +232540,15 @@ msgstr "%sļ¼ˆåˆ‡ę¢ļ¼‰" msgid "%s (activated)" msgstr "%sļ¼ˆęæ€ę“»ļ¼‰" +#: src/newcharacter.cpp +msgid "Profession proficiencies:" +msgstr "" + +#: src/newcharacter.cpp +msgctxt "Profession has no proficiencies" +msgid "None" +msgstr "ꗠ" + #: src/newcharacter.cpp msgid "Pets:" msgstr "å® ē‰©ļ¼š" @@ -231782,8 +232810,12 @@ msgid "" msgstr "ꌉ %s å°†ę­¤č§’č‰²å­˜äøŗęØ”ęæ怂" #: src/newcharacter.cpp -msgid "_______NO NAME ENTERED!_______" -msgstr "_______ęœŖč¾“å…„åå­—ļ¼_______" +msgid "--- NO NAME ENTERED ---" +msgstr "" + +#: src/newcharacter.cpp +msgid "--- RANDOM NAME ---" +msgstr "" #: src/newcharacter.cpp #, c-format @@ -231865,16 +232897,20 @@ msgid "Enter height in centimeters. Minimum 145, maximum 200" msgstr "č¾“å…„čŗ«é«˜ļ¼ˆåŽ˜ē±³ļ¼‰ć€‚ęœ€ä½Ž145ļ¼Œęœ€é«˜200" #: src/newcharacter.cpp -msgid "Enter blood type (omit Rh):" -msgstr "č¾“å…„č”€åž‹ļ¼š" +msgid "Select blood type" +msgstr "" + +#: src/newcharacter.cpp +msgid "Select Rh factor" +msgstr "" #: src/newcharacter.cpp -msgid "Invalid blood type." -msgstr "ꗠꕈēš„č”€åž‹ć€‚" +msgid "negative" +msgstr "" #: src/newcharacter.cpp -msgid "Enter Rh factor:" -msgstr "č¾“å…„Rhč”€åž‹ļ¼š" +msgid "positive" +msgstr "" #: src/newcharacter.cpp msgid "Name of template:" @@ -232254,6 +233290,25 @@ msgstr " 平静äø‹ę„怂" msgid " is no longer afraid." msgstr " äøå†å®³ę€•äŗ†ć€‚" +#: src/npc.cpp +#, c-format +msgid "I'm holing up here for safety. Long term, %s" +msgstr "ęˆ‘ęš‚ę—¶čŗ²åœØčæ™é‡Œę˜Æäøŗäŗ†å®‰å…Ø怂é•æꜟēœ‹ę„ļ¼Œ%s" + +#: src/npc.cpp +msgid "I run the shop here." +msgstr "ꈑåœØčæ™é‡Œē»č„商åŗ—怂" + +#: src/npc.cpp +#, c-format +msgid "Currently, I'm guarding this location. Overall, %s" +msgstr "ē›®å‰ęˆ‘åœØ守卫čæ™äøŖåœ°ę–¹ć€‚ę€»ä½“äøŠčÆ“ļ¼Œ%s" + +#: src/npc.cpp +#, c-format +msgid "Right now, I'm . In general, %s" +msgstr "ēŽ°åœØęˆ‘ę­£åœØ 怂äø€čˆ¬ę„čÆ“ļ¼Œ%s" + #: src/npcmove.cpp msgid "" msgstr "" @@ -232404,6 +233459,15 @@ msgstr "" msgid "My %s is bleeding!" msgstr "ꈑēš„ %s ę­£åœØ굁蔀ļ¼" +#: src/npcmove.cpp +#, c-format +msgid "My %s is bleeding badly!" +msgstr "" + +#: src/npcmove.cpp +msgid "I've lost lot of blood." +msgstr "" + #: src/npcmove.cpp #, c-format msgid "%1$s reloads their %2$s." @@ -232650,11 +233714,6 @@ msgstr "你大喊%s" msgid "%s yelling %s" msgstr "%s 大喊ļ¼š %s" -#: src/npctalk.cpp -#, c-format -msgid "%s is fleeing from you!" -msgstr "%s ę­£åœØ逃ē¦»ä½ ļ¼" - #: src/npctalk.cpp #, c-format msgid "%s talked to you." @@ -232712,36 +233771,6 @@ msgstr "åƹäøčµ·ļ¼Œä½ ę‡‚å¾—ęÆ”ęˆ‘å¤šå¤šäŗ†ļ¼Œčæ˜ę˜Æ另čÆ·é«˜ę˜Žå§ć€‚" msgid "Here's what I can teach youā€¦" msgstr "ęˆ‘čƒ½å¤Ÿē»™ä½ ä¼ ęŽˆäø€äŗ›äŗŗē”Ÿē»éŖŒā€¦ā€¦" -#: src/npctalk.cpp -#, c-format -msgid "%d.%d miles." -msgstr "%d.%d č‹±é‡Œć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "%d foot." -msgid_plural "%d feet." -msgstr[0] "%d 英å°ŗ怂" - -#: src/npctalk.cpp -#, c-format -msgid "I'm holing up here for safety. Long term, %s" -msgstr "ęˆ‘ęš‚ę—¶čŗ²åœØčæ™é‡Œę˜Æäøŗäŗ†å®‰å…Ø怂é•æꜟēœ‹ę„ļ¼Œ%s" - -#: src/npctalk.cpp -msgid "I run the shop here." -msgstr "ꈑåœØčæ™é‡Œē»č„商åŗ—怂" - -#: src/npctalk.cpp -#, c-format -msgid "Currently, I'm guarding this location. Overall, %s" -msgstr "ē›®å‰ęˆ‘åœØ守卫čæ™äøŖåœ°ę–¹ć€‚ę€»ä½“äøŠčÆ“ļ¼Œ%s" - -#: src/npctalk.cpp -#, c-format -msgid "Right now, I'm . In general, %s" -msgstr "ēŽ°åœØęˆ‘ę­£åœØ 怂äø€čˆ¬ę„čÆ“ļ¼Œ%s" - #: src/npctalk.cpp msgid "&You yell, but can't hear yourself." msgstr "&ä½ ę”¾å£°å¤§å–Šļ¼Œä½†ę˜Æ你听äøč§ä½ č‡Ŗå·±ēš„å£°éŸ³ć€‚" @@ -232750,74 +233779,6 @@ msgstr "&ä½ ę”¾å£°å¤§å–Šļ¼Œä½†ę˜Æ你听äøč§ä½ č‡Ŗå·±ēš„å£°éŸ³ć€‚" msgid "&You yell." msgstr "&ä½ ę”¾å£°å¤§å–Šć€‚" -#: src/npctalk.cpp -msgid "&You can't make anything out." -msgstr "&你什么äŗ‹ä¹Ÿå¹²äøęˆć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "Str %d - %d" -msgstr "力 %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Dex %d - %d" -msgstr "ꕏ %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Int %d - %d" -msgstr "ę™ŗ %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Per %d - %d" -msgstr "ꄟ %d - %d" - -#: src/npctalk.cpp -msgid "Dead tired" -msgstr "ē–²ęƒ«äøå Ŗ" - -#: src/npctalk.cpp -msgid "Not tired" -msgstr "ē²¾ē„žé„±ę»”" - -#: src/npctalk.cpp -msgid ". Will need sleep in " -msgstr "ć€‚å°†éœ€č¦ē”ēœ äŗŽ" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need water in " -msgstr "" -"\n" -"å°†éœ€č¦é„®ę°“äŗŽ" - -#: src/npctalk.cpp -msgid "" -"\n" -"Thirsty" -msgstr "" -"\n" -"口ęø“" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need food in " -msgstr "" -"\n" -"å°†éœ€č¦čæ›é£ŸäŗŽ" - -#: src/npctalk.cpp -msgid "" -"\n" -"Hungry" -msgstr "" -"\n" -"é„„é„æ" - #: src/npctalk.cpp msgid "YES, MASTER!" msgstr "ę˜Æēš„ļ¼Œäø»äŗŗļ¼" @@ -232831,34 +233792,6 @@ msgstr "ꈑ꜉äøŖ궈ęÆ怂" msgid "Yes, let's resume training %s" msgstr "ę˜Æēš„ļ¼Œč®©ęˆ‘们ē»§ē»­%sēš„č®­ē»ƒ" -#: src/npctalk.cpp -#, c-format -msgid "%s: 1 hour lesson (cost %s)" -msgstr "%sļ¼šäø€å°ę—¶ēš„čƾē؋ļ¼ˆčŠ±č“¹ %sļ¼‰" - -#: src/npctalk.cpp -#, c-format -msgid "%s: teaching spell knowledge (cost %s)" -msgstr "%sļ¼šä¼ ęŽˆę³•ęœÆēŸ„čƆļ¼ˆčŠ±č“¹ %sļ¼‰" - -#. ~Martial art style (cost in dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s ( cost $%d )" -msgstr "%s ļ¼ˆčŠ±č“¹ $%dļ¼‰" - -#. ~Skill name: current level (exercise) -> next level (exercise) (cost in -#. dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" -msgstr "%sļ¼š%dļ¼ˆ%d%%ļ¼‰ -> %dļ¼ˆ%d%%ļ¼‰ļ¼ˆčŠ±č“¹ $%dļ¼‰" - -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%)" -msgstr "%sļ¼š%dļ¼ˆ%d%%ļ¼‰ -> %dļ¼ˆ%d%%ļ¼‰" - #: src/npctalk.cpp msgid "Okay, thanks." msgstr "OKļ¼Œč°¢č°¢ć€‚" @@ -232871,10 +233804,6 @@ msgstr "ē»§ē»­čµ¶č·Æå§ć€‚" msgid "OBEY ME!" msgstr "[调čƕ]ęœä»Žęˆ‘ļ¼" -#: src/npctalk.cpp src/player.cpp -msgid "fists" -msgstr "ę‹³å¤“" - #: src/npctalk.cpp msgid "BADAMMO" msgstr "BADAMMO" @@ -232946,7 +233875,7 @@ msgctxt "you say something" msgid "You: %s" msgstr "ä½ ļ¼š%s" -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp msgid "You can't afford it!" msgstr "ä½ ä¹°äøčµ·ļ¼" @@ -232957,7 +233886,7 @@ msgid "%1$s gives you a %2$s." msgstr "%1$s ē»™äŗ†ä½ äø€äøŖ %2$s怂" #. ~ %1%s is the NPC name, %2$d is a number of items, %3$s are items -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp #, c-format msgid "%1$s gives you %2$d %3$s." msgstr "%1$s ē»™äŗ†ä½  %2$d äøŖ %3$s怂" @@ -232986,99 +233915,11 @@ msgstr "ä½ ē»™äŗ† %1$s %2$d äøŖ %3$s怂" msgid "%1$s doesn't have a %2$s!" msgstr "%1$s ę²”ęœ‰ %2$sļ¼" -#: src/npctalk.cpp -#, c-format -msgid "%1$s gives you %2$s." -msgstr "%1$s ē»™äŗ†ä½  %2$s怂" - #: src/npctalk.cpp #, c-format msgid "You learn how to craft %s." msgstr "ä½ ęŽŒę”äŗ†åˆ¶é€  %s ēš„ę–¹ę³•ć€‚" -#: src/npctalk.cpp -msgid "I don't trust you enough to eat THISā€¦" -msgstr "ꈑäøē›øäæ”ä½ ļ¼Œäøä¼šåƒēš„ā€¦ā€¦" - -#: src/npctalk.cpp -msgid "It doesn't look like a good idea to consume thisā€¦" -msgstr "吃čæ™äøŖäøåƒę˜ÆäøŖ儽äø»ę„ā€¦ā€¦" - -#: src/npctalk.cpp -msgid "Thanks, that hit the spot." -msgstr "č°¢č°¢ļ¼Œčæ™ę­£åˆęˆ‘å£å‘³ć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "I need a %s to consume that!" -msgstr "ē»™ęˆ‘äø€äøŖ %s ę„ä½æē”Ø它ļ¼" - -#: src/npctalk.cpp -msgid "Thanks, I feel better already." -msgstr "č°¢č°¢ļ¼Œęˆ‘ę„Ÿč§‰å„½å¤šäŗ†ć€‚" - -#: src/npctalk.cpp -msgid "Thanks, I used it." -msgstr "č°¢č°¢ļ¼ęˆ‘会ä½æē”Ø它ēš„怂" - -#: src/npctalk.cpp -msgid "Offer what?" -msgstr "ä½ č¦ē»™ä»€ä¹ˆļ¼Ÿ" - -#: src/npctalk.cpp -msgid "You have no items to offer." -msgstr "ä½ ę²”ęœ‰åÆä»„ęä¾›ēš„ē‰©å“ć€‚" - -#: src/npctalk.cpp -msgid "Changed your mind?" -msgstr "ę”¹å˜äø»ę„äŗ†ļ¼Ÿ" - -#: src/npctalk.cpp -msgid "How?" -msgstr "ꀎ꠷ļ¼Ÿ" - -#: src/npctalk.cpp -msgid "Are you insane!?" -msgstr "ä½  ē–Æäŗ†å—ļ¼ļ¼Ÿ" - -#: src/npctalk.cpp -msgid "Thanks, I'll wield that now." -msgstr "č°¢č°¢ļ¼Œęˆ‘čæ™å°±ę‹æäøŠå®ƒć€‚" - -#: src/npctalk.cpp -msgid " Should I take something off?" -msgstr "ꈑčÆ„č„±äø‹äŗ›ä»€ä¹ˆå—ļ¼Ÿ" - -#: src/npctalk.cpp -#, c-format -msgid "" -"My current weapon is better than this.\n" -"(new weapon value: %.1f vs %.1f)." -msgstr "" -"ꈑꉋäøŠēš„äøœč„æęÆ”å®ƒå„½ć€‚\n" -"ļ¼ˆę–°ę­¦å™Ø价值ļ¼š%.1fvs %.1fļ¼‰ć€‚" - -#: src/npctalk.cpp -msgid "Thanks, I'll carry that now." -msgstr "č°¢č°¢ļ¼Œęˆ‘čæ™å°±åø¦äøŠå®ƒć€‚" - -#: src/npctalk.cpp -msgid "I have no space to store it." -msgstr "ęˆ‘ę²”ęœ‰č¶³å¤Ÿēš„å‚Ø存ē©ŗé—“č£…äø‹å®ƒć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "I can only store %s %s more." -msgstr "ꈑåŖčƒ½å†č£… %s %s å·¦å³ć€‚" - -#: src/npctalk.cpp -msgid "ā€¦or to store anything else for that matter." -msgstr "ā€¦ā€¦å…¶å®žä¹Ÿę²”ē©ŗé—“ę”¾ä»»ä½•äøœč„æäŗ†ć€‚" - -#: src/npctalk.cpp -msgid "It is too heavy for me to carry." -msgstr "čæ™äøœč„æå¤Ŗ重äŗ†ęˆ‘ꐬäøåŠØ怂" - #: src/npctalk_funcs.cpp msgid "Reward" msgstr "ꊄ酬" @@ -234843,12 +235684,15 @@ msgid "A scaling factor that determines density of item spawns." msgstr "č®¾ē½®ē‰©å“ē”Ÿęˆēš„åƆåŗ¦ē³»ę•°ć€‚" #: src/options.cpp -msgid "NPC spawn rate scaling factor" -msgstr "NPCē”Ÿęˆē³»ę•°" +msgid "Random NPC spawn time" +msgstr "随ęœŗNPCē”Ÿęˆé—“隔" #: src/options.cpp -msgid "A scaling factor that determines density of dynamic NPC spawns." -msgstr "决定åŠØꀁNPCē”ŸęˆåƆåŗ¦ēš„ē³»ę•°ć€‚" +msgid "" +"Baseline average number of days between random NPC spawns. Average duration" +" goes up with the number of NPCs already spawned. Set to 0 days to disable " +"random NPCs." +msgstr "äø¤äøŖ随ęœŗNPCē”Ÿęˆä¹‹é—“é—“éš”ēš„åŸŗå‡†å¹³å‡å¤©ę•°ć€‚å¹³å‡é—“éš”ä¼šéšē€å·²ē”Ÿęˆēš„随ęœŗNPCꕰ量ēš„å¢žåŠ č€Œå¢žåŠ ć€‚č®¾ē½®äøŗ0天将ē¦ę­¢éšęœŗNPCē”Ÿęˆć€‚" #: src/options.cpp msgid "Monster evolution scaling factor" @@ -234972,37 +235816,6 @@ msgid "" "If true, spawn zombies at shelters. Makes the starting game a lot harder." msgstr "开åÆę—¶ļ¼Œåˆ™å°†åœØéæéš¾ę‰€å†…ē”Ÿęˆäø§å°øļ¼Œä½æęøøęˆčµ·å§‹ę—¶ęœŸę›“åŠ å›°éš¾ć€‚" -#: src/options.cpp -msgid "Static NPCs" -msgstr "ē”Ÿęˆé™ę€NPC" - -#: src/options.cpp -msgid "" -"If true, static NPCs will spawn at pre-defined locations. Requires world " -"reset." -msgstr "开åÆ后ļ¼Œä¼šåœØ创å»ŗęøøęˆę—¶ä¼šåœØ地图äøŠēš„äø€äŗ›å›ŗ定地ē‚¹ē”ŸęˆNPCļ¼Œéœ€č¦é‡ē½®äø–ē•Œę‰čƒ½ē”Ÿę•ˆć€‚" - -#: src/options.cpp -msgid "Starting NPCs spawn" -msgstr "čµ·å§‹NPCē”Ÿęˆ" - -#: src/options.cpp -msgid "" -"Determines whether starting NPCs should spawn, and if they do, how exactly." -msgstr "决定ę˜Æ否ē”Ÿęˆčµ·å§‹NPCļ¼Œä»„及如何ē”Ÿęˆä»–们怂" - -#: src/options.cpp -msgid "Scenario-based" -msgstr "ä¾ę®åœŗę™Æ" - -#: src/options.cpp -msgid "Random NPCs" -msgstr "ē”ŸęˆéšęœŗNPC" - -#: src/options.cpp -msgid "If true, the game will randomly spawn NPCs during gameplay." -msgstr "开åÆ后ļ¼Œä¼šåœØęøøꈏäø­éšęœŗē”Ÿęˆå››å¤„ęøøč”ēš„NPC怂" - #: src/options.cpp msgid "Mutations by radiation" msgstr "č¾å°„čƱ发变异" @@ -235602,7 +236415,7 @@ msgid "" "Applying option changesā€¦" msgstr "" "čÆ·ē­‰å¾…ā€¦ā€¦\n" -"åŗ”ē”Øé€‰é”¹ę›“ę”¹ā€¦ā€¦" +"äæå­˜äæ®ę”¹é€‰é”¹ā€¦ā€¦" #: src/options.cpp msgid "options" @@ -235969,7 +236782,7 @@ msgstr "ę—‹č½¬ [%s]" #: src/overmap_ui.cpp #, c-format msgid "[%s] Apply" -msgstr "ä½æē”Ø [%s]" +msgstr "åŗ”ē”Ø [%s]" #: src/overmap_ui.cpp msgid "[ESCAPE/Q] Cancel" @@ -236659,6 +237472,38 @@ msgstr "你尝čÆ•ę‰‘ē­čŗ«äøŠēš„ē«ē„°ļ¼" msgid " attempts to put out the fire on them!" msgstr " 尝čÆ•ę‰‘ē­čŗ«äøŠēš„ē«ē„°ļ¼" +#: src/player.cpp +msgid "" +"Your broken limb significantly hampers your efforts to puting pressure on " +"the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s broken limb significantly hampers efforts of putting pressure on" +" the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"Your hands are too encumbred to effectivly put pressure on the bleeding " +"wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s hands are too encumbred to effectivly put pressure on the " +"bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "You attempt to put pressure on the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid " attempts to put pressure on the bleeding wound!" +msgstr "" + #: src/player.cpp #, c-format msgid "Your ground sonar detected a %1$s to the %2$s!" @@ -236930,33 +237775,6 @@ msgstr "ę²”ęœ‰åÆä»„č£…å”«ēš„ē‰©å“ļ¼" msgid "You don't have any %s to reload your %s!" msgstr "ä½ ę²”ęœ‰ä»»ä½• %s ę„é‡ę–°č£…å”« %s怂" -#: src/player.cpp -msgid "Can't wield spilt liquids." -msgstr "ę— ę³•ę‰‹ęŒå·²ę“’å‡ŗēš„ę¶²ä½“" - -#: src/player.cpp -msgid "You need at least one arm to even consider wielding something." -msgstr "ä½ č‡³å°‘éœ€č¦äø€åŖčƒ½ē”Øēš„ę‰‹č‡‚ę‰čƒ½ę‰‹ęŒē‰©å“ć€‚" - -#: src/player.cpp -#, c-format -msgid "The %s is preventing you from wielding the %s." -msgstr "%s č®©ä½ ę— ę³•ę‰‹ęŒ %s怂" - -#: src/player.cpp -msgid "Something you are wearing hinders the use of both hands." -msgstr "ä½ ē©æē€ēš„č£…å¤‡é˜»ē¢äŗ†ę‰‹ēš„ä½æē”Ø怂" - -#: src/player.cpp -#, c-format -msgid "The %s can't be wielded with only one arm." -msgstr "ę— ę³•å•ę‰‹ęŒęœ‰ %s怂" - -#: src/player.cpp -#, c-format -msgid "You are too weak to wield %s with only one arm." -msgstr "你力量äøč¶³ļ¼Œę— ę³•å•ę‰‹ę‰‹ęŒ %s怂" - #: src/player.cpp msgid "Keep hands free (off)" msgstr "äæęŒē©ŗꉋļ¼ˆå…³ļ¼‰" @@ -237136,15 +237954,6 @@ msgstr "%s ę²”ęœ‰å……ē”µć€‚" msgid "Your %s isn't loaded." msgstr "%s ę²”ęœ‰č¢«č£…å”«ć€‚" -#: src/player.cpp -#, c-format -msgid "You recover %i unused plutonium." -msgstr "ä½ å›žę”¶äŗ† %i 单位ēš„钚怂" - -#: src/player.cpp -msgid "You can't remove partially depleted plutonium!" -msgstr "ä½ äøčƒ½ē§»é™¤éƒØåˆ†č€—å°½ēš„é’šļ¼" - #. ~ %1$s - gunmod, %2$s - gun. #: src/player.cpp #, c-format @@ -237279,25 +238088,6 @@ msgstr "ä½ ēš„催ēœ čƱåƼCBMč€—å°½äŗ†čƒ½é‡ć€‚" msgid "Your soporific inducer starts back up." msgstr "ä½ é‡ę–°åÆåŠØäŗ†å‚¬ēœ čƱåƼCBM怂" -#: src/player.cpp -#, c-format -msgid "Your skill in %s has increased to %d!" -msgstr "ä½ ēš„ %s ęŠ€čƒ½å‡ēŗ§č‡³ē­‰ēŗ§ %dļ¼" - -#: src/player.cpp -#, c-format -msgid "You feel that %s tasks of this level are becoming trivial." -msgstr "ä½ ę„Ÿåˆ°čæ™äøŖēŗ§åˆ«ēš„ %s 巄作实åœØę˜Æå¤Ŗē®€å•äŗ†ć€‚" - -#: src/player.cpp -#, c-format -msgid "This task is too simple to train your %s beyond %d." -msgstr "čæ™åÆ¹ä½ ę„čÆ“č½»č€Œę˜“äø¾ļ¼Œę— ę³•č®­ē»ƒ %s ęŠ€čƒ½č¶…čæ‡ %d ēŗ§ć€‚" - -#: src/player.cpp -msgid " (empty)" -msgstr "ļ¼ˆē©ŗļ¼‰" - #: src/player.cpp msgid "Wield what?" msgstr "ę‰‹ęŒä»€ä¹ˆļ¼Ÿ" @@ -237353,6 +238143,10 @@ msgstr "ꕈꞜ" msgid "SPEED" msgstr "速åŗ¦" +#: src/player_display.cpp +msgid "PROFICIENCIES" +msgstr "" + #: src/player_display.cpp #, c-format msgid "Swimming movement point cost: %+d\n" @@ -238193,6 +238987,149 @@ msgid "" "nebulae and you are no more." msgstr "ä½ čžåŒ–åˆ°äŗ†čæ™ä»½ē¾Žäø½č€Œęø©ęš–ēš„čƒ½é‡ä¹‹äø­ć€‚ē”Ÿå‘½åœØä½ čŗ«äøŠé€ęøę¶ˆé€ļ¼Œä½ äøå†å­˜åœØäŗ†ć€‚" +#: src/player_hardcoded_effects.cpp +msgid "You bleed to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " bleeds to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your heart can't keep up the pace and fails!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks pale and you feel anxious and thirsty. Blood loss?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"Your pale skin is sweating, your heart beats fast and you feel restless. " +"Maybe you lost too much blood?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You're unsettlingly white, but your fingetips are bluish. You are agitated " +"and your heart is racing. Your blood loss must be serious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You are pale as a ghost, dripping wet from the sweat, and sluggish despite " +"your heart racing like a train. You are on a brink of colapse from effects " +"of a bood loss." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and lightheaded." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel tired and you breathe heavily." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are anxcious and cannot collect your thoughts." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are sweating profusely, but you feel cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You huff and puff. Your breath is rapid and shallow." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You drop to the ground, fighting to keep yourself conscious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your mind slips away." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You cannot breathe and your body gives out!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " gasps for air and dies!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your hands feel unusually cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your feet feel unusualy cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks very pale." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel weak. Where has your strength gone?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel feeble. A gust of wind could make you stumble." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "There is an overwhelming aura of tiredness inside of you." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Rest is what you want. Rest is what you need." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and can't coordinate movement of your feet." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your muscles are quivering." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You crave for ice. Dirt under your feet looks tasty too." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your whole mouth is sore, and your tongue is swollen." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel lightheaded. And a migrane follows." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your legs are restless. Urge to move them is so strong." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel like you'd sleep on a rock." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You gasp for air!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Can't breathe. Must rest." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You can't take it any more. Rest first, everything else later." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You must sit down for a moment. Just a moment." +msgstr "" + #. ~ %s is bodypart name. #: src/player_hardcoded_effects.cpp #, c-format @@ -238801,6 +239738,11 @@ msgstr "%s 延čæŸļ¼š%i" msgid "Turrets in range: %d/%d" msgstr "射ē؋内ē‚®å””ļ¼š%d / %d" +#: src/recipe.cpp +#, c-format +msgid "Proficiencies Used: %s" +msgstr "" + #: src/recipe.cpp msgid "none" msgstr "ꗠ" @@ -239564,6 +240506,14 @@ msgstr " ēŖē„¶ę‘”倒äŗ†ļ¼" msgid "You fall over!" msgstr "ä½ ę‘”å€’äŗ†ļ¼" +#: src/suffer.cpp +msgid "Your tourniquet hurts you." +msgstr "" + +#: src/suffer.cpp +msgid " is hurting from the tourniquet." +msgstr "" + #: src/suffer.cpp #, c-format msgid "Your radiation badge changes from %1$s to %2$s!" @@ -239583,6 +240533,210 @@ msgstr "ę°“å†²ę“—ęŽ‰äŗ†č¦†ē›–åœØčŗ«ä½“äøŠēš„ę°”ęÆļ¼" msgid "You feel the water burning your skin." msgstr "ä½ č§‰å¾—ę°“ę­£åœØē¼ä¼¤ä½ ēš„ēš®č‚¤ć€‚" +#: src/talker_avatar.cpp +#, c-format +msgid "%s can't sell you any %s" +msgstr "" + +#: src/talker_avatar.cpp +#, c-format +msgid "%1$s gives you %2$s." +msgstr "%1$s ē»™äŗ†ä½  %2$s怂" + +#: src/talker_npc.cpp +#, c-format +msgid "%d.%d miles." +msgstr "%d.%d č‹±é‡Œć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "%d foot." +msgid_plural "%d feet." +msgstr[0] "%d 英å°ŗ怂" + +#: src/talker_npc.cpp +#, c-format +msgid "%s is fleeing from you!" +msgstr "%s ę­£åœØ逃ē¦»ä½ ļ¼" + +#. ~Skill name: current level (exercise) -> next level (exercise) (cost in +#. dollars) +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" +msgstr "%sļ¼š%dļ¼ˆ%d%%ļ¼‰ -> %dļ¼ˆ%d%%ļ¼‰ļ¼ˆčŠ±č“¹ $%dļ¼‰" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%)" +msgstr "%sļ¼š%dļ¼ˆ%d%%ļ¼‰ -> %dļ¼ˆ%d%%ļ¼‰" + +#: src/talker_npc.cpp +#, c-format +msgid "%s ( cost $%d )" +msgstr "%s ļ¼ˆčŠ±č“¹ $%dļ¼‰" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: 1 hour lesson (cost %s)" +msgstr "%sļ¼šäø€å°ę—¶ēš„čƾē؋ļ¼ˆčŠ±č“¹ %sļ¼‰" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: teaching spell knowledge (cost %s)" +msgstr "%sļ¼šä¼ ęŽˆę³•ęœÆēŸ„čƆļ¼ˆčŠ±č“¹ %sļ¼‰" + +#: src/talker_npc.cpp +msgid "I don't trust you enough to eat THISā€¦" +msgstr "ꈑäøē›øäæ”ä½ ļ¼Œäøä¼šåƒēš„ā€¦ā€¦" + +#: src/talker_npc.cpp +msgid "It doesn't look like a good idea to consume thisā€¦" +msgstr "吃čæ™äøŖäøåƒę˜ÆäøŖ儽äø»ę„ā€¦ā€¦" + +#: src/talker_npc.cpp +msgid "Thanks, that hit the spot." +msgstr "č°¢č°¢ļ¼Œčæ™ę­£åˆęˆ‘å£å‘³ć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "I need a %s to consume that!" +msgstr "ē»™ęˆ‘äø€äøŖ %s ę„ä½æē”Ø它ļ¼" + +#: src/talker_npc.cpp +msgid "Thanks, I feel better already." +msgstr "č°¢č°¢ļ¼Œęˆ‘ę„Ÿč§‰å„½å¤šäŗ†ć€‚" + +#: src/talker_npc.cpp +msgid "Thanks, I used it." +msgstr "č°¢č°¢ļ¼ęˆ‘会ä½æē”Ø它ēš„怂" + +#: src/talker_npc.cpp +msgid "Offer what?" +msgstr "ä½ č¦ē»™ä»€ä¹ˆļ¼Ÿ" + +#: src/talker_npc.cpp +msgid "You have no items to offer." +msgstr "ä½ ę²”ęœ‰åÆä»„ęä¾›ēš„ē‰©å“ć€‚" + +#: src/talker_npc.cpp +msgid "Changed your mind?" +msgstr "ę”¹å˜äø»ę„äŗ†ļ¼Ÿ" + +#: src/talker_npc.cpp +msgid "How?" +msgstr "ꀎ꠷ļ¼Ÿ" + +#: src/talker_npc.cpp +msgid "Are you insane!?" +msgstr "ä½  ē–Æäŗ†å—ļ¼ļ¼Ÿ" + +#: src/talker_npc.cpp +msgid "Thanks, I'll wield that now." +msgstr "č°¢č°¢ļ¼Œęˆ‘čæ™å°±ę‹æäøŠå®ƒć€‚" + +#: src/talker_npc.cpp +msgid " Should I take something off?" +msgstr "ꈑčÆ„č„±äø‹äŗ›ä»€ä¹ˆå—ļ¼Ÿ" + +#: src/talker_npc.cpp +#, c-format +msgid "" +"My current weapon is better than this.\n" +"(new weapon value: %.1f vs %.1f)." +msgstr "" +"ꈑꉋäøŠēš„äøœč„æęÆ”å®ƒå„½ć€‚\n" +"ļ¼ˆę–°ę­¦å™Ø价值ļ¼š%.1fvs %.1fļ¼‰ć€‚" + +#: src/talker_npc.cpp +msgid "Thanks, I'll carry that now." +msgstr "č°¢č°¢ļ¼Œęˆ‘čæ™å°±åø¦äøŠå®ƒć€‚" + +#: src/talker_npc.cpp +msgid "I have no space to store it." +msgstr "ęˆ‘ę²”ęœ‰č¶³å¤Ÿēš„å‚Ø存ē©ŗé—“č£…äø‹å®ƒć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "I can only store %s %s more." +msgstr "ꈑåŖčƒ½å†č£… %s %s å·¦å³ć€‚" + +#: src/talker_npc.cpp +msgid "ā€¦or to store anything else for that matter." +msgstr "ā€¦ā€¦å…¶å®žä¹Ÿę²”ē©ŗé—“ę”¾ä»»ä½•äøœč„æäŗ†ć€‚" + +#: src/talker_npc.cpp +msgid "It is too heavy for me to carry." +msgstr "čæ™äøœč„æå¤Ŗ重äŗ†ęˆ‘ꐬäøåŠØ怂" + +#: src/talker_npc.cpp +msgid "&You can't make anything out." +msgstr "&你什么äŗ‹ä¹Ÿå¹²äøęˆć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "Str %d - %d" +msgstr "力 %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Dex %d - %d" +msgstr "ꕏ %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Int %d - %d" +msgstr "ę™ŗ %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Per %d - %d" +msgstr "ꄟ %d - %d" + +#: src/talker_npc.cpp +msgid "Dead tired" +msgstr "ē–²ęƒ«äøå Ŗ" + +#: src/talker_npc.cpp +msgid "Not tired" +msgstr "ē²¾ē„žé„±ę»”" + +#: src/talker_npc.cpp +msgid ". Will need sleep in " +msgstr "ć€‚å°†éœ€č¦ē”ēœ äŗŽ" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need water in " +msgstr "" +"\n" +"å°†éœ€č¦é„®ę°“äŗŽ" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Thirsty" +msgstr "" +"\n" +"口ęø“" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need food in " +msgstr "" +"\n" +"å°†éœ€č¦čæ›é£ŸäŗŽ" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Hungry" +msgstr "" +"\n" +"é„„é„æ" + #: src/teleport.cpp msgid "You feel a strange, inwards force." msgstr "ä½ ę„Ÿåˆ°äø€é˜µå„‡ę€Ŗēš„向内ēš„åŠ›ć€‚" @@ -241137,7 +242291,7 @@ msgstr "" #: src/veh_type.cpp #, c-format msgid "Has level %1$d %2$s quality" -msgstr "å…·ęœ‰ %1$d ēŗ§ %2$s ē‰¹ę€§" +msgstr "å…·ęœ‰ %1$d ēŗ§ %2$s åŠŸčƒ½" #: src/veh_type.cpp #, c-format @@ -241397,6 +242551,34 @@ msgstr "ļ¼Œ%3.1f%%/å°ę—¶ļ¼Œ%s 后 %s" msgid "pile-up" msgstr "čæ½å°¾ę®‹éŖø" +#: src/vehicle_move.cpp +msgid "Smart controller does not support flying vehicles." +msgstr "ę™ŗčƒ½å¼•ę“Žäø»ęŽ§ę— ę³•ē”ØäŗŽé£žč”Œč½½å…·ć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller detects only a single controllable engine." +msgstr "ę™ŗčƒ½å¼•ę“Žäø»ęŽ§åŖę£€ęµ‹åˆ°äø€äøŖåÆä¾›ęŽ§åˆ¶ēš„å¼•ę“Žć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller is designed to control more than one engine." +msgstr "ę™ŗčƒ½å¼•ę“Žäø»ęŽ§éœ€č¦å¤šäøŖåÆä¾›ęŽ§åˆ¶ēš„å¼•ę“Žć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller does not support more than five engines." +msgstr "ę™ŗčƒ½å¼•ę“Žäø»ęŽ§ę— ę³•åŒę—¶ęŽ§åˆ¶č¶…čæ‡5äøŖå¼•ę“Žć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller is shutting down." +msgstr "ę™ŗčƒ½å¼•ę“Žäø»ęŽ§å·²å…³é—­ć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller failed to start an engine." +msgstr "ę™ŗčƒ½å¼•ę“Žäø»ęŽ§ę— ę³•åÆåŠØę‰€éœ€å¼•ę“Žć€‚" + +#: src/vehicle_move.cpp +msgid "Smart controller optimizes engine state." +msgstr "ę™ŗčƒ½å¼•ę“Žäø»ęŽ§ä¼˜åŒ–äŗ†å¼•ę“ŽēŠ¶ę€ć€‚" + #: src/vehicle_move.cpp #, c-format msgid "The %s is too leaky!" @@ -241771,6 +242953,11 @@ msgctxt "electronics menu option" msgid "water purifier" msgstr "å‡€ę°“å™Ø" +#: src/vehicle_use.cpp +msgctxt "electronics menu option" +msgid "smart controller" +msgstr "ę™ŗčƒ½å¼•ę“Žäø»ęŽ§" + #: src/vehicle_use.cpp msgid "Turn off camera system" msgstr "关闭ē›‘ꎧē³»ē»Ÿ" @@ -242394,50 +243581,18 @@ msgstr "ē”µåŠ›äøč¶³ä»„净化 %1$s ēš„ %2$s äø­ēš„ę¶²ä½“" msgid "You purify the contents of the %1$s's %2$s" msgstr "你净化äŗ† %1$s ēš„ %2$s äø­ēš„ę¶²ä½“" -#: src/weather.cpp -msgid "You hear a distant rumble of thunder." -msgstr "你听到čæœå¤„隆隆ēš„é›·å£°ć€‚" - -#: src/weather.cpp -msgid "You hear a rumble of thunder from above." -msgstr "你听到夓锶äøŠé›·å£°ę»šę»šć€‚" - -#: src/weather.cpp -msgid "A flash of lightning illuminates your surroundings!" -msgstr "äø€é“é—Ŗē”µē…§äŗ®äŗ†ä½ ēš„å‘Ø囓ļ¼" - #: src/weather.cpp #, c-format -msgid "Your %s protects you from the acidic drizzle." -msgstr "ä½ ēš„ %s äæęŠ¤ä½ å…å—é…øé›Øēš„ä¼¤å®³ć€‚" - -#: src/weather.cpp -msgid "Your clothing protects you from the acidic drizzle." -msgstr "ä½ ēš„č”£ęœäæęŠ¤ä½ å…å—é…øꀧē»†é›Øēš„ä¼¤å®³ć€‚" - -#: src/weather.cpp -msgid "Your power armor protects you from the acidic drizzle." -msgstr "ä½ ēš„åŠØåŠ›č£…ē”²äæęŠ¤ä½ å…å—é…øé›Øēš„ä¼¤å®³ć€‚" - -#: src/weather.cpp -msgid "The acid rain stings, but is mostly harmless for nowā€¦" -msgstr "é…øé›Øč®©ä½ ę„Ÿåˆ°ēš®č‚¤åˆŗē—›ļ¼Œä½†ē›®å‰čæ˜ē®—åÆ¹ä½ ę²”ęœ‰ä¼¤å®³ā€¦ā€¦" - -#: src/weather.cpp -msgid "Your umbrella protects you from the acid rain." -msgstr "ä½ ēš„é›Ø伞äæęŠ¤ä½ å…å—é…øé›Øä¼¤å®³ć€‚" - -#: src/weather.cpp -msgid "Your clothing protects you from the acid rain." -msgstr "ä½ ēš„č”£ęœäæęŠ¤ä½ å…å—é…øé›Øä¼¤å®³ć€‚" +msgid "Your %s protects you from the weather." +msgstr "" #: src/weather.cpp -msgid "Your power armor protects you from the acid rain." -msgstr "ä½ ēš„åŠØåŠ›č£…ē”²äæęŠ¤ä½ å…å—é…øé›Øēš„ä¼¤å®³ć€‚" +msgid "Your clothing protects you from the weather." +msgstr "" #: src/weather.cpp -msgid "The acid rain burns!" -msgstr "é…øé›Øē¼ēƒ§ē€ä½ ļ¼" +msgid "Your power armor protects you from the weather." +msgstr "" #: src/weather.cpp msgid "Monday" @@ -242612,54 +243767,6 @@ msgstr "飓风" msgid "The weather changed to %s!" msgstr "å¤©ę°”č½¬äøŗ %s ļ¼" -#: src/weather_data.cpp -msgid "Clear" -msgstr "ę™“ęœ—" - -#: src/weather_data.cpp -msgid "Sunny" -msgstr "ꙓ" - -#: src/weather_data.cpp -msgid "Cloudy" -msgstr "多äŗ‘" - -#: src/weather_data.cpp -msgid "Light Drizzle" -msgstr "ęƛęƛé›Ø" - -#: src/weather_data.cpp -msgid "Drizzle" -msgstr "ē»†é›Ø" - -#: src/weather_data.cpp -msgid "Rain" -msgstr "é›Ø" - -#: src/weather_data.cpp -msgid "Thunder Storm" -msgstr "é›·ęš“" - -#: src/weather_data.cpp -msgid "Acidic Drizzle" -msgstr "é…øꀧē»†é›Ø" - -#: src/weather_data.cpp -msgid "Acid Rain" -msgstr "é…øé›Ø" - -#: src/weather_data.cpp -msgid "Flurries" -msgstr "小é›Ŗ" - -#: src/weather_data.cpp -msgid "Snowing" -msgstr "é›Ŗ" - -#: src/weather_data.cpp -msgid "Snowstorm" -msgstr "ęš“é›Ŗ" - #: src/wish.cpp msgid "Nonvalid" msgstr "ꗠꕈ" @@ -242850,6 +243957,19 @@ msgstr "选ꋩäø€äøŖäø–ē•Œę„开始ęøøꈏ" msgid "last world info" msgstr "äøŠäøŖäø–ē•Œäæ”ęÆ" +#: src/worldfactory.cpp +msgid "MISSING MODS" +msgstr "" + +#: src/worldfactory.cpp +msgid "OBSOLETE MODS" +msgstr "" + +#: src/worldfactory.cpp +#, c-format +msgid " [%s]" +msgstr "" + #: src/worldfactory.cpp msgid " ACTIVE WORLD MODS " msgstr "当前äø–ē•ŒåÆē”ØęØ”ē»„" diff --git a/lang/po/zh_TW.po b/lang/po/zh_TW.po index 24e01c7440529..5a136d6a255d7 100644 --- a/lang/po/zh_TW.po +++ b/lang/po/zh_TW.po @@ -17,21 +17,21 @@ # HOXV , 2020 # 锞凱宇 , 2020 # Jeremy Wu , 2020 -# Hao JK , 2020 # kiddragon Chung , 2020 # Brett Dong , 2020 # Hsinyu Chan, 2020 # Laughing Man, 2020 -# xap, 2020 # Yangerine Yuan , 2020 +# xap, 2020 +# Hao JK , 2020 # msgid "" msgstr "" "Project-Id-Version: cataclysm-dda 0.E\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-07-08 10:07+0800\n" +"POT-Creation-Date: 2020-07-16 21:36+0800\n" "PO-Revision-Date: 2018-04-26 14:47+0000\n" -"Last-Translator: Yangerine Yuan , 2020\n" +"Last-Translator: Hao JK , 2020\n" "Language-Team: Chinese (Taiwan) (https://www.transifex.com/cataclysm-dda-translators/teams/2217/zh_TW/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -5005,7 +5005,7 @@ msgstr[0] "" msgid "" "A bulky assortment of small bits of scrap steel useful in all kinds of " "crafting." -msgstr "" +msgstr "各式ēخ锞ēš„å°å”Šé‡‘å±¬å»¢ę–™ļ¼ŒåœØē‰©å“č£½ä½œäøŠē›øē•¶ęœ‰ē”Ø怂" #: lang/json/AMMO_from_json.py msgid "bismuth" @@ -6572,6 +6572,55 @@ msgid "" "designed to fit Huge survivors." msgstr "äø€å€‹ē”Ø來將éŖØé ­å›ŗ定åœØ位子äøŠēš„å·„å…·ć€‚å®ƒē¶“過ē‰¹ę®ŠčØ­čØˆä»„é©ę‡‰ \"å·Ø大ēš„\" ē”Ÿå­˜č€…é«”åž‹ć€‚" +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm)" +msgid_plural "tourniquets (arm)" +msgstr[0] "" + +#. ~ Use action menu_text for {'str': 'tourniquet (arm)', 'str_pl': +#. 'tourniquets (arm)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (arm XL)', 'str_pl': +#. 'tourniquets (arm XL)'}. +#. ~ Use action menu_text for {'str': 'tourniquet (leg)', 'str_pl': +#. 'tourniquets (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "Adjust" +msgstr "" + +#. ~ Use action msg for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'}. +#. ~ Use action msg for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'}. +#. ~ Use action msg for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'}. +#: lang/json/ARMOR_from_json.py +msgid "You adjust the tourniquet." +msgstr "" + +#. ~ Description for {'str': 'tourniquet (arm)', 'str_pl': 'tourniquets +#. (arm)'} +#. ~ Description for {'str': 'tourniquet (arm XL)', 'str_pl': 'tourniquets +#. (arm XL)'} +#. ~ Description for {'str': 'tourniquet (leg)', 'str_pl': 'tourniquets +#. (leg)'} +#: lang/json/ARMOR_from_json.py +msgid "" +"First aid device used to apply pressure to a limb or extremity in order to " +"limit blood flow. Should be employed only to manage heavy bleedings, " +"because prolonged use will harm the limb. It can be adjusted in size to fit" +" different limbs." +msgstr "" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (arm XL)" +msgid_plural "tourniquets (arm XL)" +msgstr[0] "" + +#: lang/json/ARMOR_from_json.py +msgid "tourniquet (leg)" +msgid_plural "tourniquets (leg)" +msgstr[0] "" + #: lang/json/ARMOR_from_json.py msgid "blindfold" msgid_plural "blindfolds" @@ -26918,6 +26967,7 @@ msgid "" "wrote this was a terrible writer, and gleaning knowledge from the rants is a" " chore." msgstr "" +"äø€ęœ¬å›‰å—¦å’Œč¤‡é›œēš„ēš„ę›øļ¼Œ čŖŖę˜Žå¦‚ä½•åœØę› é‡Žå’ŒåŸŽåø‚ēš„ęœ€å£žęƒ…ę³äø‹ē”Ÿå­˜ć€‚é›–ē„¶å……ę–„č‘—å¤§é‡ęœ‰ē”Øēš„äæ”ęÆļ¼Œ 但åÆ«å‡ŗ這個ēš„ē˜‹å­ę–‡ē­†äøä½³ļ¼Œ č®“ä½ å¾ˆé›£å¾žč£”é¢å­ø到什éŗ¼ć€‚" #: lang/json/BOOK_from_json.py msgid "Through the Lens" @@ -35982,6 +36032,19 @@ msgid "" "appetite, and is quite addictive." msgstr "醫ē™‚ē“šå·¦ę—‹å®‰éžä»–å‘½čˆ‡å³ę—‹å®‰éžä»–å‘½ę··åˆ, åøøē”Øę–¼ę²»ē™‚ę³Øę„åŠ›äøč¶³éŽå‹•ē—‡ć€‚å®ƒęŠ‘åˆ¶é£Ÿę…¾, 而äø”å…·ęœ‰ē›øē•¶ēš„ęˆē™®ę€§ć€‚" +#: lang/json/COMESTIBLE_from_json.py +msgid "adhesive bandage" +msgid_plural "adhesive bandages" +msgstr[0] "" + +#. ~ Description for {'str': 'adhesive bandage'} +#: lang/json/COMESTIBLE_from_json.py +msgid "" +"A set of small medical dressings, each made of a piece of sterile cloth and " +"a sticky tape, used for small injuries not serious enough to require a full-" +"size bandage." +msgstr "" + #: lang/json/COMESTIBLE_from_json.py msgid "syringe of adrenaline" msgid_plural "syringes of adrenaline" @@ -36058,8 +36121,10 @@ msgstr[0] "" #. ~ Description for {'str': 'bandage'} #: lang/json/COMESTIBLE_from_json.py -msgid "Simple cloth bandages. Used for healing small amounts of damage." -msgstr "ē°”單ēš„ę£‰åøƒē¹ƒåø¶ć€‚ē”Øä¾†ę²»ē™‚少量ēš„å‚·å®³ć€‚" +msgid "" +"Simple cloth bandages. Used for stopping bloodloss and protecting wounds " +"from external factors." +msgstr "" #: lang/json/COMESTIBLE_from_json.py msgid "makeshift bandage" @@ -45161,8 +45226,8 @@ msgstr[0] "" #. planks'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten construction planks securely lashed together with a rope. Disassemble " -"to unpack." +"Ten construction planks securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" #: lang/json/GENERIC_from_json.py @@ -45174,8 +45239,21 @@ msgstr[0] "" #. stout branches'} #: lang/json/GENERIC_from_json.py msgid "" -"Ten stout branches securely lashed together with a rope. Disassemble to " -"untie them." +"Ten stout branches securely tied together for easier transport. Disassemble" +" to untie them." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "bundle of long stout branches" +msgid_plural "bundles of long stout branches" +msgstr[0] "" + +#. ~ Description for {'str': 'bundle of long stout branches', 'str_pl': +#. 'bundles of long stout branches'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Five long stout branches securely tied together for easier transport. " +"Disassemble to untie them." msgstr "" #: lang/json/GENERIC_from_json.py @@ -47052,6 +47130,11 @@ msgid "" "gutted for parts." msgstr "äø€å°ęęƀēš„ TALON ē„”äŗŗåœ°é¢č¼‰å…·ļ¼Œęœ‰č‘—ꐍęƀēš„å¤–ę®¼ļ¼Œē®”ē·šę¶²é«”ę»²å‡ŗäŗ‚굁怂åÆä»„ę‹†č§£å‡ŗéƒØ件怂" +#: lang/json/GENERIC_from_json.py +msgid "broken laser turret" +msgid_plural "broken laser turrets" +msgstr[0] "ꐍęƀēš„é›·å°„ē ²å””" + #: lang/json/GENERIC_from_json.py msgid "fire brick" msgid_plural "fire bricks" @@ -47596,11 +47679,6 @@ msgid "" "like it could support a reinforcing sheet, either." msgstr "é€™ę¬¾å¤Ŗé™½čƒ½ęæę˜Æ尖ē«Æē§‘ꊀēš„ē”¢ē‰©, ę“ęœ‰ę„µé«˜ēš„å…‰é›»č½‰ę›ę•ˆčƒ½ć€‚ä½†å®ƒč”Øé¢č¦†č“‹ēš„ē‰¹ę®Šē‰©ę–™éžåøøč„†å¼±, åŒę™‚ä¹Ÿē„”ę³•é€²č”Œå¼·åŒ–åŠ å›ŗ怂" -#: lang/json/GENERIC_from_json.py -msgid "broken laser turret" -msgid_plural "broken laser turrets" -msgstr[0] "ꐍęƀēš„é›·å°„ē ²å””" - #: lang/json/GENERIC_from_json.py msgid "TX-5LR Laser Cannon" msgid_plural "TX-5LR Laser Cannons" @@ -48416,9 +48494,9 @@ msgstr[0] "å¹¼å¹“č€éŗµēØ®" #. ~ Use action msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py msgid "" -"After feeding it and caring for it for weeks, your sourdough starter is " +"After feeding it and caring for it for a week, your sourdough starter is " "finally ready for the big leagues." -msgstr "餵養äø¦ē…§é”§å®ƒę•ø週之後ļ¼Œä½ ēš„老éŗµēØ®ēµ‚ę–¼ęŗ–備大展čŗ«ę‰‹äŗ†ć€‚" +msgstr "" #. ~ Use action not_ready_msg for {'str': 'juvenile sourdough starter'}. #: lang/json/GENERIC_from_json.py @@ -48453,8 +48531,8 @@ msgstr "éŗµēØ®é‚„ę²’ęŗ–å‚™å„½ć€‚" #: lang/json/GENERIC_from_json.py msgid "" "This jar contains a floury paste with sourdough starter mixed in. It needs " -"a few hours to recover its strength before it can be used again." -msgstr "這個ē½å­č£”é¢č£ęœ‰äø€ēØ®ę··åˆč‘—č€éŗµēØ®ēš„ē²‰ē‹€ē³Šē‹€ē‰©ć€‚éœ€č¦å¹¾å€‹å°ę™‚ę¢å¾©å®ƒēš„å¼·åŗ¦ę‰čƒ½å†ę¬”ä½æē”Ø怂" +"a day to recover its strength before it can be used again." +msgstr "" #: lang/json/GENERIC_from_json.py msgid "sourdough starter" @@ -48501,10 +48579,23 @@ msgstr[0] "ꀄꕑē®±" #. ~ Description for {'str': 'first aid kit'} #: lang/json/GENERIC_from_json.py msgid "" -"A full medical kit, with bandages, local anesthetics, and rapid healing " -"agents. Used for healing large amounts of damage. Disassemble to get its " -"content." -msgstr "äø€å€‹å®Œę•“ēš„醫ē™‚包, 包含ē¹ƒåø¶ć€å±€éƒØéŗ»é†‰åŠ‘č·Ÿåæ«é€Ÿē™’åˆåŠ‘ć€‚ē”Øę–¼ę²»ē™‚åš“重ēš„å‰µå‚·ć€‚ę‹†č§£å®ƒä»„取得內容ē‰©ć€‚" +"A typical universal first aid kit, one you'd see in a car or in a household." +" It contains a variety of common medical items stored in case of accidents " +"and injuries. Disassemble to get its content." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "IFAK" +msgid_plural "IFAKs" +msgstr[0] "" + +#. ~ Description for {'str': 'IFAK'} +#: lang/json/GENERIC_from_json.py +msgid "" +"An IFAK, or individual first aid kit, is a specialized set of wound " +"dressings and accessories, and being of military origin focuses on combat " +"trauma and preventing blood loss. Disassemble to get its content." +msgstr "" #: lang/json/GENERIC_from_json.py msgid "MRE" @@ -50994,7 +51085,7 @@ msgstr[0] "" #. ~ Description for {'str': 'short string'} #: lang/json/GENERIC_from_json.py msgid "A 6-inch (or about 15 cm) long piece of cotton string." -msgstr "" +msgstr "äø€ę®µ 6 英åÆøļ¼ˆęˆ–大ē“„ 15 公分ļ¼‰é•·ēš„ę£‰ē·šć€‚" #: lang/json/GENERIC_from_json.py msgid "long string" @@ -51004,7 +51095,7 @@ msgstr[0] "長ē¹©" #. ~ Description for {'str': 'long string'} #: lang/json/GENERIC_from_json.py msgid "A 3-foot (or about 90 cm) long piece of cotton string." -msgstr "" +msgstr "äø€ę®µ 3 英å°ŗļ¼ˆęˆ–大ē“„ 90 公分ļ¼‰é•·ēš„ę£‰ē·šć€‚" #: lang/json/GENERIC_from_json.py msgid "short rope" @@ -52764,10 +52855,10 @@ msgstr "" #: lang/json/GENERIC_from_json.py msgid "inscribed metal plates" -msgid_plural "inscribed metal platess" +msgid_plural "inscribed metal plates" msgstr[0] "" -#. ~ Description for {'str': 'inscribed metal plates'} +#. ~ Description for {'str_sp': 'inscribed metal plates'} #: lang/json/GENERIC_from_json.py msgid "" "This device looks electronic, but is unfamiliar. It is a series of tightly " @@ -52802,6 +52893,34 @@ msgid "" "work." msgstr "" +#: lang/json/GENERIC_from_json.py +msgid "engraved parabolic dish" +msgid_plural "engraved parabolic dishes" +msgstr[0] "" + +#. ~ Description for {'str': 'engraved parabolic dish', 'str_pl': 'engraved +#. parabolic dishes'} +#: lang/json/GENERIC_from_json.py +msgid "" +"This hefty parabolic dish is engraved with an unrecognizable pattern of " +"symbols that might, at a guess, be some sort of circuitry pattern - or maybe" +" a religious incantation." +msgstr "" + +#: lang/json/GENERIC_from_json.py +msgid "oblong device" +msgid_plural "oblong devices" +msgstr[0] "" + +#. ~ Description for {'str': 'oblong device'} +#: lang/json/GENERIC_from_json.py +msgid "" +"Perfectly smooth, cool to the touch, and a dull blue-grey colour, this looks" +" almost like a perfect riverstone at first glance. Its artificial nature is" +" betrayed on closer inspection by a network of intricate patterns visible as" +" a slight difference in the reflection of light off its surface." +msgstr "" + #: lang/json/GENERIC_from_json.py msgid "sheet of glass" msgid_plural "sheets of glass" @@ -61770,7 +61889,7 @@ msgstr "NPC ēŖč®Š" msgid "" "NPCs wandering the wasteland will occasionally have mutations --- your foes " "included. Beware!" -msgstr "" +msgstr "å¾˜å¾Šę–¼å»¢åœŸēš„ NPC 偶ēˆ¾ęœƒåø¶ęœ‰ēŖč®Šļ¼Œ 包含你ēš„ꕵäŗŗć€‚č«‹å°åæƒęé˜²ļ¼" #: lang/json/MOD_INFO_from_json.py msgid "My Sweet Cataclysm" @@ -62392,6 +62511,22 @@ msgid "" " before running out of power." msgstr "" +#: lang/json/MONSTER_from_json.py +msgid "feral human" +msgid_plural "feral humans" +msgstr[0] "" + +#. ~ Description for {'str': 'feral human'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pupils dilated and what remains to be seen of the iris and sclera are " +"bloodshot. It still breathes but the zombies treat it like one of them." +msgstr "" + +#: lang/json/MONSTER_from_json.py +msgid "They throw a loose brick at you!" +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "alpha razorclaw" msgid_plural "alpha razorclaws" @@ -63795,7 +63930,7 @@ msgstr[0] "å±±č²“" msgid "" "A spotted wild cat living across much of North America. It is not a serious" " threat to humans, but it can be aggressive when threatened." -msgstr "" +msgstr "大éƒØåˆ†ę£²ęÆę–¼åŒ—ē¾Žę“²ēš„ę–‘é»žé‡Žč²“ć€‚é›–ē„¶å°äŗŗ锞äøå¤Ŗ꧋ꈐåØč„…ļ¼Œ 但ę˜Æ受到åØč„…ę™‚åÆčƒ½ęœƒå±•ē¾ę”»ę“Šę€§ć€‚" #: lang/json/MONSTER_from_json.py msgid "shorthair kitten" @@ -65780,6 +65915,19 @@ msgid "" "of infesting sewer lines." msgstr "äø€å€‹ę”»ę“Šę€§å¼·ēš„ēŖč®Šč›‡, 因地äø‹ē”Ÿę“»č€Œå‘ˆē¾ę·”é»ƒč‰²ć€‚å®ƒēš„名ēرē”±ä¾†ę˜Æ因ē‚ŗ它ē›¤ę“šåœØ地åŗ•ēš„ēæ’ꀧ怂" +#: lang/json/MONSTER_from_json.py +msgid "prototype laser turret" +msgid_plural "prototype laser turrets" +msgstr[0] "" + +#. ~ Description for {'str': 'prototype laser turret'} +#: lang/json/MONSTER_from_json.py +msgid "" +"This appears to be a very experimental automated tower. Plating-less and " +"seemingly half-built, it's little more than an oversized laser emitter and a" +" camera, both welded to a swiveling platform." +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "blob" msgid_plural "blobs" @@ -66491,6 +66639,21 @@ msgid "" "and its eyes bulge with black goo." msgstr "äø€éš»ēœ‹čµ·ä¾†ę™®é€šēš„ē¾Žę“²ē…, 但ę˜Æ它ēš„å¾Œč…³č…«č„¹, äø¦äø”從ēœ¼ē›ęµå‡ŗé»‘č‰²ēš„é»ę¶²ć€‚" +#: lang/json/MONSTER_from_json.py +msgid "zombie horse" +msgid_plural "zombie horses" +msgstr[0] "" + +#. ~ Description for {'str': 'zombie horse'} +#: lang/json/MONSTER_from_json.py +msgid "" +"From the looks of this zombie horse's ghastly features, with its protruding " +"ribs, whitish skull, and empty eyes, the exposed part of the internal organs" +" shows a seemingly lifeless color, and the black body fluid drips slowly. " +"The new strength makes the horse no longer dependent on its muscles, but it " +"can still pursue the enemy quickly." +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "Tiger wight" msgid_plural "Tiger wights" @@ -66503,6 +66666,33 @@ msgid "" "eyes wide open and shining black." msgstr "" +#: lang/json/MONSTER_from_json.py +msgid "zombie cow" +msgid_plural "zombie cows" +msgstr[0] "" + +#. ~ Description for {'str': 'zombie cow'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Once a placid cow, this leathery horror stumbles and shudders, its pulsing " +"black eyes scanning for prey beneath wicked horns. It is big and heavy and " +"murderous." +msgstr "" + +#: lang/json/MONSTER_from_json.py +msgid "woodland wight" +msgid_plural "woodland wights" +msgstr[0] "" + +#. ~ Description for {'str': 'woodland wight'} +#: lang/json/MONSTER_from_json.py +msgid "" +"Pale, stumbling white-tailed deer with blackened eyes and drooling slime " +"down its neck. Its legs twist and bend in strange, haphazard directions, " +"but with unnatural strength and speed. Preys on coyotes, wolves, and giant " +"spider mutants." +msgstr "" + #: lang/json/MONSTER_from_json.py msgid "mass of zombie spiders" msgid_plural "mass of zombie spiderss" @@ -67238,11 +67428,11 @@ msgid "" msgstr "äø€å€‹äøēŸ„ē‚ŗä½•čƒ½é•·åˆ°6äŗŗ高ēš„å·Øå¤§ę®­å±, ę‰‹č‡‚č·Ÿå¤§åžƒåœ¾ę”¶äø€ęØ£ē²—怂" #: lang/json/MONSTER_from_json.py -msgid "feral hunter" -msgid_plural "feral hunters" -msgstr[0] "å‡¶ęš“ē‹©ēµč€…" +msgid "zombie hunter" +msgid_plural "zombie hunters" +msgstr[0] "" -#. ~ Description for {'str': 'feral hunter'} +#. ~ Description for {'str': 'zombie hunter'} #: lang/json/MONSTER_from_json.py msgid "" "This once-human body is barely recognizable, scrambling about on all fours, " @@ -67322,11 +67512,11 @@ msgid "" msgstr "" #: lang/json/MONSTER_from_json.py -msgid "feral runner" -msgid_plural "feral runners" -msgstr[0] "å‡¶ęš“čæ½é€č€…" +msgid "zombie runner" +msgid_plural "zombie runners" +msgstr[0] "" -#. ~ Description for {'str': 'feral runner'} +#. ~ Description for {'str': 'zombie runner'} #: lang/json/MONSTER_from_json.py msgid "" "This recently-risen body moves quickly, darting its head back and forth and " @@ -67334,11 +67524,11 @@ msgid "" msgstr "這具剛復ē”¦ēš„č»€é«”å‹•ä½œčæ…速, é ­éƒØ前後ę“ŗ動, 還åœØ啃č‡Ŗå·±ēš„ꉋ怂" #: lang/json/MONSTER_from_json.py -msgid "feral predator" -msgid_plural "feral predators" -msgstr[0] "å‡¶ęš“ęŽ é£Ÿč€…" +msgid "zombie predator" +msgid_plural "zombie predators" +msgstr[0] "" -#. ~ Description for {'str': 'feral predator'} +#. ~ Description for {'str': 'zombie predator'} #: lang/json/MONSTER_from_json.py msgid "" "With its joints in odd places and angles, this humanoid creature prowls " @@ -71356,7 +71546,7 @@ msgstr "ē–¼ē—›" msgid "Increases pain" msgstr "增加ē–¼ē—›" -#: lang/json/SPELL_from_json.py src/character.cpp src/npctalk.cpp +#: lang/json/SPELL_from_json.py src/character.cpp src/talker_npc.cpp msgid "Tired" msgstr "ē–²å€¦" @@ -72437,7 +72627,7 @@ msgstr "這個儀式創造äŗ†äø€å€‹čˆ‡é¢Øęš“å”‘å½¢č€…å„‘åˆēš„小ēŸ³å­ć€‚ä½ čƒ½ msgid "Lightning Blast" msgstr "閃電ēˆ†ē “" -#: lang/json/SPELL_from_json.py src/weather_data.cpp +#: lang/json/SPELL_from_json.py lang/json/weather_type_from_json.py msgid "Lightning Storm" msgstr "ęš“é›Ø" @@ -73309,10 +73499,10 @@ msgstr[0] "RM13 ęˆ°é¬„č£ē”²" #. ~ Description for {'str': 'RM13 combat armor'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. Use it to turn it on." -msgstr "這儗光äŗ®ēš„é»‘č‰²å…Øčŗ«č»ē”Øč£ē”²ę˜Æ Rivtech éžå‰›ę€§å‹•åŠ›č£ē”²ēš„巔峰之作, ęœ€å¤ščƒ½ä»„ 10 個鈽ē‡ƒę–™é›»ę± é€²č”Œå…§éƒØä¾›é›»ć€‚\"ä½æē”Ø\" ä»„å•Ÿå‹•å®ƒć€‚" +msgstr "" #: lang/json/TOOL_ARMOR_from_json.py msgid "RM13 combat armor (on)" @@ -73323,13 +73513,11 @@ msgstr[0] "RM13 ęˆ°é¬„č£ē”² (啟動)" #. armors (on)'} #: lang/json/TOOL_ARMOR_from_json.py msgid "" -"Internally powered by a maximum of ten plutonium fuel cells, this full-body " +"Internally powered by plutonium fuel batteries, exclusively, this full-body " "suit of sleek black military armor represents the pinnacle of Rivtech's non-" "rigid powered armor technology. It is turned on, and continually draining " "power. Use it to turn it off." msgstr "" -"這儗光äŗ®ēš„é»‘č‰²å…Øčŗ«č»ē”Øč£ē”²ę˜Æ Rivtech éžå‰›ę€§å‹•åŠ›č£ē”²ēš„巔峰之作, ęœ€å¤ščƒ½ä»„ 10 個鈽ē‡ƒę–™é›»ę± é€²č”Œå…§éƒØä¾›é›»ć€‚å®ƒå·²ē¶“å•Ÿå‹•, " -"äø¦äø”ęŒēŗŒę¶ˆč€—é›»åŠ›ć€‚\"ä½æē”Ø\" ä»„é—œé–‰å®ƒć€‚" #: lang/json/TOOL_ARMOR_from_json.py msgid "5-point anchor" @@ -74405,8 +74593,8 @@ msgstr[0] "å¤Ŗé™½čƒ½ęæčƒŒåŒ… (ꊘē–Š)" msgid "" "Personal portable charging system consisting of an array of solar panels " "neatly folded in a form of a large backpack. It can be worn as one, and has" -" an integrated cable to plug it into a cable charger system." -msgstr "個äŗŗä¾æę”œå¼å……é›»ē³»ēµ±, ē”±äø€ē³»åˆ—å¤Ŗé™½čƒ½ęæēµ„ęˆ, ę•“é½Šåœ°ęŠ˜ē–Šęˆå¤§čƒŒåŒ…ēš„å½¢å¼ć€‚å®ƒåÆē”±å–®äŗŗä½©ęˆ“, äø¦å…·ęœ‰äø€å€‹é›†ęˆé›»ēŗœ, åÆå°‡å…¶ę’å…„é›»ēŗœå……é›»å™Øē³»ēµ±ć€‚" +" an integrated cable to plug it into a cable charger system CBM." +msgstr "" #: lang/json/TOOL_ARMOR_from_json.py msgid "solar backpack (unfolded)" @@ -74418,8 +74606,8 @@ msgstr[0] "å¤Ŗé™½čƒ½ęæčƒŒåŒ… (展開)" #: lang/json/TOOL_ARMOR_from_json.py msgid "" "Unfolded array of portable solar panels ready to push some power into an " -"active cable charger system." -msgstr "展開ēš„å¤Ŗé™½čƒ½ęæ, 將電力č¼ø兄已開啟ēš„é›»ēŗœå……é›»ē³»ēµ±ć€‚" +"active cable charger system CBM." +msgstr "" #: lang/json/TOOL_ARMOR_from_json.py msgid "riot helmet" @@ -79049,11 +79237,9 @@ msgstr "" msgid "" "This is an advanced version of the unified power supply, or UPS. This " "device has been significantly redesigned to provide better efficiency as " -"well as to consume plutonium fuel cells rather than batteries. Sadly, its " -"plutonium reactor can't be charged in UPS charging station." +"well as to consume plutonium fuel batteries rather than regular batteries. " +"Sadly, its plutonium reactor can't be charged in UPS charging station." msgstr "" -"äø€å€‹é«˜éšŽē‰ˆēš„ēµ±äø€č¦ę ¼ä¾›é›»ē³»ēµ± (UPS)怂重ꖰčØ­č؈ēš„č¦ę ¼č®“å®ƒåÆ仄ä½æē”Øę›“ęœ‰ę•ˆēŽ‡åœ°éˆ½å…ƒē“ , 而äøę˜Æ傳ēµ±é›»ę± ć€‚éŗę†¾ēš„ę˜Æ它ēš„éˆ½åę‡‰å™Øē„”ę³•åœØ UPS " -"ē›ø容ēš„č»Šč¼‰å……é›»ē«™å…§å……電怂" #. ~ Description for {'str': 'camera'} #: lang/json/TOOL_from_json.py @@ -79881,10 +80067,11 @@ msgstr "ä½ ę‹‰é–‹äŗ†é›»å­č„ˆč”ę‰‹ę¦“彈ēš„ę’éŠ·ć€‚" #: lang/json/TOOL_from_json.py msgid "" "This is a grenade that generates an electromagnetic pulse with a low-" -"inductance capacitor bank discharged into a single-loop antenna. Use this " -"item to pull the pin and light the fuse, turning it into an active EMP " -"grenade. You will then have three turns before it detonates, creating an " -"EMP field that damages robots and drains bionic energy." +"inductance capacitor bank discharged into a single-loop antenna. It also " +"produces a mild electric shock cloud. Use this item to pull the pin and " +"light the fuse, turning it into an active EMP grenade. You will then have " +"three turns before it detonates, creating an EMP field that damages robots " +"and drains bionic energy." msgstr "" #: lang/json/TOOL_from_json.py @@ -79896,9 +80083,9 @@ msgstr[0] "啟動äø­é›»ē£č„ˆč”ę‰‹ę¦“彈" #: lang/json/TOOL_from_json.py msgid "" "This EMP grenade is active, and will shortly detonate, creating a large EMP " -"field that damages robots and drains bionic energy. You may not want to be " -"holding it much longer." -msgstr "這個電ē£č„ˆč”ę‰‹ę¦“彈已ē¶“å•Ÿå‹•, 很åæ«ēš„å°±ęœƒē‚ø開äø¦ē”¢ē”Ÿé›»ē£č„ˆč”ć€‚é€™å°‡ęœƒē “壞附čæ‘ēš„ę©Ÿå™Øäŗŗ仄及åø取ē”ŸåŒ–ę’ä»¶čƒ½é‡ć€‚ä½ ēµ•å°äøęœƒęƒ³č¦äø€ē›“ę”åœØꉋäøŠēš„怂" +"field that damages robots and drains bionic energy as well as a mild " +"electric shock cloud. You may not want to be holding it much longer." +msgstr "" #: lang/json/TOOL_from_json.py msgid "incendiary grenade" @@ -83947,8 +84134,8 @@ msgstr "ä½ čØ­ē½®äŗ†éœ°å½ˆę§é™·é˜±ć€‚" #. ~ Description for {'str': 'shotgun trap'} #: lang/json/TOOL_from_json.py msgid "" -"This is a simple tripwire is attached to the trigger of a loaded double-" -"barreled shotgun. When pulled, the shotgun fires. Two shells are loaded; " +"This is a simple tripwire is attached to the trigger of a loaded double " +"slamfire shotgun. When pulled, the shotgun fires. Two shells are loaded; " "the first time the trigger is pulled, one or both shells may be discharged." msgstr "" @@ -90862,6 +91049,26 @@ msgstr "ä½æē”Ø點ē„ŠåŠ å›ŗ廢金屬ē‰†" msgid "Build Junk Metal Floor" msgstr "å»ŗ造廢金屬地ęæ" +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Bolts" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bridge Using Welder" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Bench" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Build Scrap Metal Table" +msgstr "" + +#: lang/json/construction_from_json.py +msgid "Lay down decorative ground cable" +msgstr "" + #: lang/json/construction_from_json.py msgid "Build Pillow Fort" msgstr "å»ŗé€ ęž•é ­å ”" @@ -93254,6 +93461,15 @@ msgstr "" msgid "Your muscles won't cooperate!" msgstr "" +#: lang/json/effects_from_json.py +msgid "Minor Bleeding" +msgstr "" + +#. ~ Description of effect 'Minor Bleeding'. +#: lang/json/effects_from_json.py +msgid "Tis but a scratch." +msgstr "" + #: lang/json/effects_from_json.py msgid "Bleeding" msgstr "굁蔀" @@ -93281,7 +93497,25 @@ msgstr "åš“é‡ęµč”€" msgid "You are rapidly losing blood." msgstr "ä½ ę­£åœØåæ«é€Ÿå¤±č”€ć€‚" -#. ~ Apply message for effect(s) 'Bleeding, Bad Bleeding, Heavy Bleeding'. +#: lang/json/effects_from_json.py +msgid "Heavy Arterial Bleeding" +msgstr "" + +#. ~ Description of effect 'Heavy Arterial Bleeding'. +#: lang/json/effects_from_json.py +msgid "Blood is gushing from you like a fountain." +msgstr "" + +#. ~ Apply message for effect(s) 'Minor Bleeding, Minor Bleeding, Minor +#. Bleeding, Minor Bleeding, Minor Bleeding, Bleeding, Bleeding, Bleeding, +#. Bleeding, Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, +#. Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad Bleeding, Bad +#. Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, +#. Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy Bleeding, Heavy +#. Bleeding, Heavy Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding, Heavy Arterial Bleeding, +#. Heavy Arterial Bleeding, Heavy Arterial Bleeding'. #: lang/json/effects_from_json.py msgid "You're bleeding!" msgstr "ä½ åœØ굁蔀!" @@ -94034,10 +94268,64 @@ msgstr "ä½ ēš„鈣č³Ŗē¼ŗ乏已ē¶“åæ«č¦č§£ę±ŗäŗ†ć€‚" msgid "Your bones become stronger as your calcium deficiency improves." msgstr "éšØč‘—ä½ ēš„ē¼ŗéˆ£ęƒ…ę³ę”¹å–„, ä½ ēš„éŖØ頭逐ę¼øč®Šå¼·äø­ć€‚" +#: lang/json/effects_from_json.py +msgid "Early iron deficiency" +msgstr "" + +#. ~ Description of effect 'Early iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"A lack of iron in your diet has hampered efficiency and regeneration of your" +" red blood cells." +msgstr "" + #: lang/json/effects_from_json.py msgid "Iron deficiency" msgstr "鐵č³Ŗē¼ŗ乏" +#. ~ Description of effect 'Iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"Prolonged lack of iron in your diet has compromised efficiency and " +"regeneration of your red blood cells." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Acute iron deficiency" +msgstr "" + +#. ~ Description of effect 'Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "" +"Severe lack of iron in your diet results in your red blood cells dying " +"faster then they are regenerating." +msgstr "" + +#. ~ Apply message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#. ~ Apply message for effect(s) 'Early anemia, Anemia, Acute anemia'. +#: lang/json/effects_from_json.py +msgid "You begin feeling increasingly tired and listless." +msgstr "ä½ é–‹å§‹ę„Ÿåˆ°č¶Šä¾†č¶Šē–²å€¦å’Œē„”ē²¾ę‰“采怂" + +#. ~ Remove message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "You are no longer in risk of becoming anemic." +msgstr "" + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your irom deficiency is nearly resolved." +msgstr "" + +#. ~ Decay message for effect(s) 'Early iron deficiency, Iron deficiency, +#. Acute iron deficiency'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your iron deficiency starts to improve." +msgstr "" + #: lang/json/effects_from_json.py msgid "Early anemia" msgstr "ę—©ęœŸč²§č”€" @@ -94047,26 +94335,24 @@ msgid "Anemia" msgstr "č²§č”€ē—‡" #: lang/json/effects_from_json.py -msgid "" -"A lack of iron in your diet will result in progressively worsening anemia." -msgstr "ä½ ēš„飲食äø­ē¼ŗ乏鐵č³Ŗ, å°Žč‡“ä½ ēš„č²§č”€é€ę¼øęƒ”åŒ–ć€‚" +msgid "Acute anemia" +msgstr "" -#. ~ Apply message for effect(s) 'Iron deficiency, Early anemia, Anemia'. #: lang/json/effects_from_json.py -msgid "You begin feeling increasingly tired and listless." -msgstr "ä½ é–‹å§‹ę„Ÿåˆ°č¶Šä¾†č¶Šē–²å€¦å’Œē„”ē²¾ę‰“采怂" +msgid "Loss of red blood cells results in progressively worsening anemia." +msgstr "" -#. ~ Remove message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Remove message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "You no longer feel anemic." msgstr "ä½ äøå†ę„Ÿåˆ°č²§č”€ć€‚" -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py -msgid "Your iron deficiency is nearly resolved." -msgstr "ä½ ēš„鐵č³Ŗē¼ŗ乏已ē¶“åæ«č¦č§£ę±ŗäŗ†ć€‚" +msgid "Your anemia is nearly resolved." +msgstr "" -#. ~ Decay message for effect(s) 'Iron deficiency, Early anemia, Anemia'. +#. ~ Decay message for effect(s) 'Early anemia, Anemia, Acute anemia'. #: lang/json/effects_from_json.py msgid "Your feel stronger as your anemia starts to improve." msgstr "éšØč‘—ä½ ēš„ē¼ŗéµęƒ…ę³ę”¹å–„, ä½ ēš„č²§č”€é€ę¼øę¢å¾©äø­ć€‚" @@ -94254,6 +94540,77 @@ msgid "" "disgusting rations day in and day out?" msgstr "" +#: lang/json/effects_from_json.py +msgid "Mild hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Mild hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost some blood and look somewhat pale." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Moderate hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Moderate hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You've lost large amount of blood, and you're not feeling well." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Advanced hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Advanced hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost an awful lot of blood, and your condition is severe. Seek " +"medical attention." +msgstr "" + +#: lang/json/effects_from_json.py +msgid "Severe hypovolemic shock" +msgstr "" + +#. ~ Description of effect 'Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You've lost tremendous amount of blood, and you're standing on death's door." +" Transfusion might save you." +msgstr "" + +#. ~ Apply message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You have lost lot of blood, and your condition worsens." +msgstr "" + +#. ~ Remove message for effect(s) 'Mild hypovolemic shock, Moderate +#. hypovolemic shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "You are no longer in shock." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your blood level increase, and you feel better, but still look pale." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "Your feel stronger as your blood levels starts to improve." +msgstr "" + +#. ~ Decay message for effect(s) 'Mild hypovolemic shock, Moderate hypovolemic +#. shock, Advanced hypovolemic shock, Severe hypovolemic shock'. +#: lang/json/effects_from_json.py +msgid "" +"You're not dying from lack of blood, but you're not out of the woods yet." +msgstr "" + #: lang/json/effects_from_json.py msgid "Lit up" msgstr "ē™¼äŗ®" @@ -96140,25 +96497,343 @@ msgid "mutated cactus" msgstr "ēŖč®Šä»™äŗŗꎌ" #: lang/json/furniture_from_json.py -msgid "cooling unit" -msgstr "å†·ę°£ę©Ÿ" +msgid "glowing tendril" +msgstr "" -#. ~ Description for cooling unit +#. ~ Description for glowing tendril #: lang/json/furniture_from_json.py msgid "" -"A large, blocky appliance encased in sheet metal. This commonplace fixture " -"is used for cooling large indoor areas." +"A willowy tendril growing from the floor, gently waving back and forth. A " +"faint light spills from it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "splorch!" msgstr "" #: lang/json/furniture_from_json.py lang/json/furniture_from_json.py #: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "metal screeching!" -msgstr "é‡‘å±¬å˜Žå˜Žč²!" +msgid "whump!" +msgstr "呼!" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py +msgid "wafting anemone" +msgstr "" + +#. ~ Description for wafting anemone +#: lang/json/furniture_from_json.py +msgid "" +"A fleshy white protuberance growing from the floor, with a cluster of " +"tendrils pouring out of it. It looks almost exactly like a sea anemone, " +"even waving gently as though underwater." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "gasping tube" +msgstr "" + +#. ~ Description for gasping tube +#: lang/json/furniture_from_json.py +msgid "" +"This is a meaty green stalactite with a thickened hide like that of a " +"starfish, extending from the floor to the ceiling. In the center is a " +"series of ports somewhat like mouths, from which pour bursts of a vile-" +"smelling gas." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "twitching frond" +msgstr "" + +#. ~ Description for twitching frond +#: lang/json/furniture_from_json.py +msgid "" +"A spine resembling moth antennae juts from the ground, swaying gently in the" +" air. Every so often, a cascade of energy arcs along it and discharges into" +" the ceiling." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scarred lump" +msgstr "" + +#. ~ Description for scarred lump +#: lang/json/furniture_from_json.py +msgid "" +"This is a pile of nondescript alien flesh, twitching and belching strange " +"gases out of injured orifices." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "splat!" +msgstr "å•Ŗ啦!" + +#: lang/json/furniture_from_json.py +msgid "slimy pod" +msgstr "" + +#. ~ Description for slimy pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a slick, translucent pod suspended on a thin stalk. It is covered " +"in a thick mucus, obscuring whatever is floating in the gel-like substance " +"inside." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +msgid "whump." +msgstr "å‘¼ć€‚" + +#: lang/json/furniture_from_json.py +msgid "organ pod" +msgstr "" + +#. ~ Description for organ pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside you can see the" +" dimly outlined shape of human organs, floating in some kind of preservative" +" goo." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "resin pod" +msgstr "ęØ¹č„‚čŽ¢" + +#. ~ Description for resin pod +#: lang/json/furniture_from_json.py +msgid "" +"This is a translucent pod suspended on a thin stalk. Inside is a clean, " +"clear resinous-looking fluid. You could fairly easily tear it from the " +"stalk and take it with you." +msgstr "這ę˜ÆåŠé€ę˜Žēš„č±†čŽ¢ļ¼Œę‡øꎛåœØē“°čŽ–äøŠć€‚å…§éƒØę˜Æä¹¾ę·Ø透꘎ēš„ęØ¹č„‚ē‹€ę¶²é«”ć€‚ä½ åÆä»„č¼•é¬†åœ°å°‡å…¶å¾žčŽ–äøŠę‘˜äø‹äø¦éšØčŗ«ę”œåø¶ć€‚" + +#: lang/json/furniture_from_json.py +msgid "fleshy altar" +msgstr "" + +#. ~ Description for fleshy altar +#: lang/json/furniture_from_json.py +msgid "" +"This pulsing protuberance juts from the floor, its sides covered in scaled, " +"oozing skin. The surface is flat, but undulates softly. A handful of " +"unidentifiable appendages reach from the sides, suggesting a sort of " +"nightmarish living autodoc." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scrap antenna" +msgstr "" + +#. ~ Description for scrap antenna +#: lang/json/furniture_from_json.py +msgid "" +"This contraption looks like some sort of cobbled-together transmitter or " +"receiver antenna. It consists of a number of mismatched blinking lights, " +"spinning servos, and dangling wires connected to a heft metal box." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py msgid "clang!" msgstr "éŗ!" +#: lang/json/furniture_from_json.py +msgid "rack of robots" +msgstr "" + +#. ~ Description for rack of robots +#: lang/json/furniture_from_json.py +msgid "" +"This is a wire cage containing a number of robot parts, from chassis to " +"limbs, firmly clamped on to sturdy hanging rods. It looks like it would be " +"exceptionally difficult to open it and get at them without damaging them, " +"probably by design." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "spinning dish" +msgstr "" + +#. ~ Description for spinning dish +#: lang/json/furniture_from_json.py +msgid "" +"This is a slowly spinning parabolic dish engraved with an unrecognizable " +"pattern of symbols that might, at a guess, be some sort of circuitry pattern" +" - or maybe a religious incantation. It is mounted on a completely " +"mismatched electric motor that looks fairly mundane." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "scavenged utility light" +msgstr "" + +#. ~ Description for scavenged utility light +#: lang/json/furniture_from_json.py +msgid "" +"The bulbs emit an eery greenish glow, and some parts of it have a curved " +"appearance as though the metal were grown in a lab, but by and large this " +"isn't a particularly unusual looking area light." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "clanking fluid pump" +msgstr "" + +#. ~ Description for clanking fluid pump +#: lang/json/furniture_from_json.py +msgid "" +"The huge sweating pipes and large tank reveal this clanking and tortuous " +"piece of equipment to be some sort of fluid pump. It is cobbled from " +"several apparently ill-fitting parts that have been fitted together with " +"some very strange looking but surprisingly clever adaptors." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "metalloid printer" +msgstr "" + +#. ~ Description for metalloid printer +#: lang/json/furniture_from_json.py +msgid "" +"This huge device actually resembles a 3D printer fairly closely, aside from " +"its industrial size. Huge spools of various thin metallic wires top it and " +"feed into what seems to be some sort of nozzle, and massive electrical " +"cables disappear into the wall behind it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "circuit printer" +msgstr "" + +#. ~ Description for circuit printer +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall device with a lattice of pipes and nozzles. Based on the " +"pile of products sitting in the output hopper, it looks like itā€™s used as a " +"printer for complex electronic components." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "Mavrik 10-101 power core" +msgstr "" + +#. ~ Description for Mavrik 10-101 power core +#: lang/json/furniture_from_json.py +msgid "" +"There is a faded metallic plaque on the side of this cylindrical device. The lettering is a strange combination of English and Cyrillic script. It reads:\n" +"Mavrik 10-101\n" +"StabŠølŠøtŠø\n" +"SaфetŠø\n" +"A Š½yuclŠøar фyutuр Š²Šø bilŠøŠ² iŠ½" +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "metal screeching!" +msgstr "é‡‘å±¬å˜Žå˜Žč²!" + +#: lang/json/furniture_from_json.py +msgid "spherical generator" +msgstr "" + +#. ~ Description for spherical generator +#: lang/json/furniture_from_json.py +msgid "" +"This huge steel plated sphere gives off a soft hum as it, presumably, " +"generates power. A heavy lead plate bolted to the front might describe what" +" it is, but it is written in something that looks vaguely like cuneiform." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "fluidic generator" +msgstr "" + +#. ~ Description for fluidic generator +#: lang/json/furniture_from_json.py +msgid "" +"Twisting reams of copper and steel pipes wrap around a central core that " +"thrums softly. Although there are no labels in any language you recognize, " +"the cables connected to the base suggest that this is some sort of power " +"generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "rusty generator" +msgstr "" + +#. ~ Description for rusty generator +#: lang/json/furniture_from_json.py +msgid "" +"This is a tall, unremarkable cylinder capped by a wide flat saucer. There " +"is heavy rusting at the base. A series of connected cables suggest that " +"it's some sort of power generator." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "personal charging station" +msgstr "" + +#. ~ Description for personal charging station +#: lang/json/furniture_from_json.py +msgid "" +"The cyborg equivalent of a bed, this is a custom-shaped near-vertical booth " +"designed to mount a heavy metal frame and connect it to a central power " +"supply and nutrient source." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp +msgid "crash!" +msgstr "č½Ÿéš†!" + +#: lang/json/furniture_from_json.py +msgid "simple charging station" +msgstr "" + +#. ~ Description for simple charging station +#: lang/json/furniture_from_json.py +msgid "" +"This is a simple, unadorned, corroded metal charging and refeeding station, " +"with hookups for two units somewhat larger than a human to stand side by " +"side and be recharged and refueled." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shimmering superstructure" +msgstr "" + +#. ~ Description for shimmering superstructure +#: lang/json/furniture_from_json.py +msgid "" +"A simple metal superstructure like you might see holding up a radio tower, " +"this one seems to give off just the faintest hint of shimmer, like heat " +"waves. The metal has a burnt, iridescent pattern. There is a boxy, " +"unimpressive looking device at the top of the tower." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "portal enclosure" +msgstr "" + +#. ~ Description for portal enclosure +#: lang/json/furniture_from_json.py +msgid "" +"A heavy metal ring attached to dozens of wires, charred by residue that " +"gives off an acrid, unfamiliar smell." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "cooling unit" +msgstr "å†·ę°£ę©Ÿ" + +#. ~ Description for cooling unit +#: lang/json/furniture_from_json.py +msgid "" +"A large, blocky appliance encased in sheet metal. This commonplace fixture " +"is used for cooling large indoor areas." +msgstr "" + #: lang/json/furniture_from_json.py msgid "central air filter" msgstr "äø­å¤®ē©ŗę°£ęæ¾ęø…å™Ø" @@ -96316,8 +96991,7 @@ msgid "" "priceless tools, invaluable to any survivor." msgstr "" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py msgid "whack!" msgstr "嘩!" @@ -96333,16 +97007,12 @@ msgid "" "little to stop a moving car." msgstr "" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -#: src/mapdata.cpp src/vehicle_move.cpp +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/map.cpp src/mapdata.cpp +#: src/vehicle_move.cpp msgid "smash!" msgstr "ē¢°!" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -msgid "whump." -msgstr "å‘¼ć€‚" - #: lang/json/furniture_from_json.py msgid "earthbag barricade" msgstr "" @@ -96679,10 +97349,6 @@ msgid "" "them moving slightly. Gross." msgstr "" -#: lang/json/furniture_from_json.py -msgid "splat!" -msgstr "å•Ŗ啦!" - #. ~ Description for spider egg sack #: lang/json/furniture_from_json.py msgid "" @@ -96761,16 +97427,6 @@ msgid "" "the smoke to the outside. Dangerous to leave unattended while lit." msgstr "" -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py src/map.cpp -msgid "crash!" -msgstr "č½Ÿéš†!" - -#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py -#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py -msgid "whump!" -msgstr "呼!" - #: lang/json/furniture_from_json.py msgid "wood stove" msgstr "ęŸ“ēˆ" @@ -96929,8 +97585,9 @@ msgid "" "comfort or warmth." msgstr "äø€å¤§å †č‘‰å­ć€‚å¦‚ęžœä½ äøé—œåæƒčˆ’é©ęˆ–ęŗ«ęš–ļ¼Œä½ åÆ仄ē”åœØäøŠé¢ć€‚" -#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py -#: src/iuse.cpp +#: lang/json/furniture_from_json.py lang/json/furniture_from_json.py +#: lang/json/terrain_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py src/iuse.cpp msgid "crunch!" msgstr "匔噹!" @@ -97092,6 +97749,78 @@ msgid "" " chemicals." msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken generator" +msgstr "ęå£žēš„ē™¼é›»ę©Ÿ" + +#. ~ Description for broken generator +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This generator is broken and will not help you produce usable electricity." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "Compact Advanced Sterling Radioisotope Generator" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"This hefty lump of steel and lead is the housing unit for a small nuclear " +"reactor. It is plastered with warning signs. You could probably ignore " +"those and salvage the steel and lead shielding, what could possibly go " +"wrong?" +msgstr "" + +#. ~ Description for Compact Advanced Sterling Radioisotope Generator +#: lang/json/furniture_from_json.py +msgid "" +"Some insane fool has removed the outer containment on this small-scale " +"nuclear reactor. It is still fairly safe as it is: the reactor has " +"considerable built-in containment as well. Nevertheless, you probably don't" +" want to stand too close for too long." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "light machinery" +msgstr "č¼•åž‹ę©Ÿę¢°" + +#. ~ Description for light machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted light machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "ting." +msgstr "걀怂" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "heavy machinery" +msgstr "é‡åž‹ę©Ÿę¢°" + +#. ~ Description for heavy machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted heavy machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "old machinery" +msgstr "čˆŠę©Ÿę¢°" + +#. ~ Description for old machinery +#: lang/json/furniture_from_json.py +msgid "Assorted old, rusty machinery. You could scavenge it for parts." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "electronic machinery" +msgstr "é›»å­ę©Ÿę¢°" + +#. ~ Description for electronic machinery +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "Assorted electronic machinery. You could scavenge it for parts." +msgstr "" + #: lang/json/furniture_from_json.py msgid "robotic arm" msgstr "ę©Ÿę¢°ę‰‹č‡‚" @@ -97109,6 +97838,32 @@ msgstr "" msgid "thunk." msgstr "å’šć€‚" +#: lang/json/furniture_from_json.py +msgid "ground cable" +msgstr "" + +#. ~ Description for ground cable +#: lang/json/furniture_from_json.py +msgid "A bunch of loose cables snake along the floor." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "shred!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "thud!" +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "capacitor bank" +msgstr "" + +#. ~ Description for capacitor bank +#: lang/json/furniture_from_json.py +msgid "A bank of heavy metal cylinders connected by large wires." +msgstr "" + #: lang/json/furniture_from_json.py msgid "Autodoc Mk. XI" msgstr "å…Øč‡Ŗ動外ē§‘醫ē”Ÿ Mk. XI" @@ -97374,116 +98129,17 @@ msgstr "ꉓ開ēš„éš±ē§ēŖ—ē°¾" msgid "Stop peeking!" msgstr "刄偷ēœ‹ļ¼" -#: lang/json/furniture_from_json.py -msgid "glowing tendril" -msgstr "" - -#. ~ Description for glowing tendril -#: lang/json/furniture_from_json.py -msgid "" -"A willowy tendril growing from the floor, gently waving back and forth. A " -"faint light spills from it." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "splorch!" -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "wafting anemone" -msgstr "" - -#. ~ Description for wafting anemone -#: lang/json/furniture_from_json.py -msgid "" -"A fleshy white protuberance growing from the floor, with a cluster of " -"tendrils pouring out of it. It looks almost exactly like a sea anemone, " -"even waving gently as though underwater." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "gasping tube" -msgstr "" - -#. ~ Description for gasping tube -#: lang/json/furniture_from_json.py -msgid "" -"This is a meaty green stalactite with a thickened hide like that of a " -"starfish, extending from the floor to the ceiling. In the center is a " -"series of ports somewhat like mouths, from which pour bursts of a vile-" -"smelling gas." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "twitching frond" -msgstr "" - -#. ~ Description for twitching frond -#: lang/json/furniture_from_json.py -msgid "" -"A spine resembling moth antennae juts from the ground, swaying gently in the" -" air. Every so often, a cascade of energy arcs along it and discharges into" -" the ceiling." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "scarred lump" -msgstr "" - -#. ~ Description for scarred lump -#: lang/json/furniture_from_json.py -msgid "" -"This is a pile of nondescript alien flesh, twitching and belching strange " -"gases out of injured orifices." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "slimy pod" -msgstr "" - -#. ~ Description for slimy pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a slick, translucent pod suspended on a thin stalk. It is covered " -"in a thick mucus, obscuring whatever is floating in the gel-like substance " -"inside." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "organ pod" -msgstr "" - -#. ~ Description for organ pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside you can see the" -" dimly outlined shape of human organs, floating in some kind of preservative" -" goo." -msgstr "" - -#: lang/json/furniture_from_json.py -msgid "resin pod" -msgstr "ęØ¹č„‚čŽ¢" - -#. ~ Description for resin pod -#: lang/json/furniture_from_json.py -msgid "" -"This is a translucent pod suspended on a thin stalk. Inside is a clean, " -"clear resinous-looking fluid. You could fairly easily tear it from the " -"stalk and take it with you." -msgstr "這ę˜ÆåŠé€ę˜Žēš„č±†čŽ¢ļ¼Œę‡øꎛåœØē“°čŽ–äøŠć€‚å…§éƒØę˜Æä¹¾ę·Ø透꘎ēš„ęØ¹č„‚ē‹€ę¶²é«”ć€‚ä½ åÆä»„č¼•é¬†åœ°å°‡å…¶å¾žčŽ–äøŠę‘˜äø‹äø¦éšØčŗ«ę”œåø¶ć€‚" - -#: lang/json/furniture_from_json.py -msgid "fleshy altar" -msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "centrifuge" +msgstr "離åæƒę©Ÿ" -#. ~ Description for fleshy altar +#. ~ Description for centrifuge #: lang/json/furniture_from_json.py msgid "" -"This pulsing protuberance juts from the floor, its sides covered in scaled, " -"oozing skin. The surface is flat, but undulates softly. A handful of " -"unidentifiable appendages reach from the sides, suggesting a sort of " -"nightmarish living autodoc." +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. For some reason, this one has an attached battery pack. It could be " +"used to analyze a medical fluid sample, such as blood, if a test tube was " +"placed in it." msgstr "" #: lang/json/furniture_from_json.py @@ -97970,7 +98626,7 @@ msgstr "" #: lang/json/furniture_from_json.py msgid "deck chair" -msgstr "" +msgstr "čŗŗ꤅" #. ~ Description for deck chair #: lang/json/furniture_from_json.py @@ -97980,6 +98636,17 @@ msgid "" " it's not particularly comfortable." msgstr "" +#: lang/json/furniture_from_json.py +msgid "metal bench" +msgstr "" + +#. ~ Description for metal bench +#: lang/json/furniture_from_json.py +msgid "" +"A bench made of scrap metal. Not the most comfortable furniture you've ever" +" seen." +msgstr "" + #: lang/json/furniture_from_json.py msgid "bulletin board" msgstr "告ē¤ŗē‰Œ" @@ -98476,6 +99143,35 @@ msgid "" "A huge metal tank that can be used to safely store large amounts of liquid." msgstr "" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "fuel tank" +msgstr "" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with gasoline." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "broken fuel tank" +msgstr "" + +#. ~ Description for broken fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with gasoline." +msgstr "" + +#. ~ Description for fuel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A tank filled with diesel." +msgstr "" + +#. ~ Description for broken fuel tank +#. ~ Description for broken diesel tank +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "A broken tank which was filled with diesel." +msgstr "" + #: lang/json/furniture_from_json.py msgid "dumpster" msgstr "垃圾ē®±" @@ -98499,6 +99195,42 @@ msgid "" "electricity, it is pedal-driven, allowing use without power." msgstr "" +#: lang/json/furniture_from_json.py +msgid "riveted metal crate" +msgstr "" + +#. ~ Description for riveted metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This huge box is made of a dull metal, riveted together. There is no " +"obvious opening mechanism, and the rivets don't match any of your tools. " +"The only way in would be to smash it." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "sealed metal crate" +msgstr "" + +#. ~ Description for sealed metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This is a huge, tightly sealed storage crate made from welded and riveted " +"sheet metal. The sealing mechanism is too tight to open bare-handed and " +"would need some kind of prying instrument to release." +msgstr "" + +#: lang/json/furniture_from_json.py +msgid "open metal crate" +msgstr "" + +#. ~ Description for open metal crate +#: lang/json/furniture_from_json.py +msgid "" +"This large metal crateā€™s lid is unsealed, and hinges open easily to reveal a" +" number of storage shelves inside. Once open, the side panels also swing " +"wider for easy access." +msgstr "" + #: lang/json/furniture_from_json.py msgid "counter" msgstr "꫃ęŖÆ" @@ -98597,6 +99329,15 @@ msgstr "åƒę±č„æēš„ę™‚å€™č¦åå„½ļ¼" msgid "a low table for livingrooms." msgstr "客廳ēš„ēŸ®ę”Œć€‚" +#: lang/json/furniture_from_json.py +msgid "metal table" +msgstr "" + +#. ~ Description for metal table +#: lang/json/furniture_from_json.py +msgid "A serviceable but simple table made of scrap metal." +msgstr "" + #: lang/json/furniture_from_json.py msgid "tatami mat" msgstr "ꦻꦻē±³" @@ -98826,6 +99567,17 @@ msgstr "é‡‘å±¬ę®˜éŖø" msgid "Pile of various bent and twisted metals." msgstr "äø€å †å„ēØ®å½Žę›²å’Œę‰­ę›²ēš„é‡‘å±¬ć€‚" +#: lang/json/furniture_from_json.py +msgid "radioactive slag" +msgstr "" + +#. ~ Description for radioactive slag +#: lang/json/furniture_from_json.py +msgid "" +"A pile of melted slag from a destroyed nuclear reactor. What are you doing " +"looking at this? Get the hell out of here, you nutcase!" +msgstr "" + #: lang/json/furniture_from_json.py msgid "pile of ash" msgstr "ē°ē‡¼å †" @@ -98899,6 +99651,39 @@ msgid "" "public utilities, but it doesn't work anymore." msgstr "" +#: lang/json/furniture_from_json.py +msgid "scrap metal bridge" +msgstr "" + +#. ~ Description for scrap metal bridge +#: lang/json/furniture_from_json.py +msgid "A simple bridge made of riveted sheet metal." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +#: lang/json/terrain_from_json.py +msgid "broken console" +msgstr "å£žęŽ‰ēš„ęŽ§åˆ¶å°" + +#. ~ Description for broken console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It doesn't seem to be working. " +"It's the broken screen and shattered circuit boards that's telling you that." +msgstr "" + +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "computer console" +msgstr "é›»č…¦ęŽ§åˆ¶å°" + +#. ~ Description for computer console +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "" +"This is a standalone computer terminal. It can be used to view contents and" +" perform any allowed functions. It might even be possible to hack it, given" +" the skills." +msgstr "" + #: lang/json/furniture_from_json.py msgid "forge" msgstr "鍛造ēˆ" @@ -99259,6 +100044,15 @@ msgid "" "you wouldn't need to pay at all!" msgstr "å®ƒå£žęŽ‰äŗ†ļ¼Œä½ ęƒ³č‘—å¦‚ä½•č²·ę±č„æć€‚å¦‚ęžœč®“å®ƒå£žå¾—ę›“å¾¹åŗ•ļ¼Œä½ ę˜Æäøę˜Æå°±äøéœ€č¦ä»˜éŒ¢äŗ†å‘¢ļ¼" +#: lang/json/furniture_from_json.py lang/json/terrain_from_json.py +msgid "rope leading up" +msgstr "向äøŠå»¶ä¼øēš„ē¹©å­" + +#. ~ Description for rope leading up +#: lang/json/furniture_from_json.py +msgid "A rope. You could climb it up." +msgstr "" + #: lang/json/furniture_from_json.py msgid "atomic butter churn on a stand" msgstr "" @@ -102763,6 +103557,20 @@ msgstr[0] "" msgid "Electricity unnaturally arcs from the tips of this alien frond." msgstr "" +#: lang/json/gun_from_json.py +msgid "hurled rubble" +msgid_plural "hurled rubbles" +msgstr[0] "" + +#: lang/json/gun_from_json.py +msgid "Stone at the ready to crush that which isn't part of the blob." +msgstr "" + +#: lang/json/gun_from_json.py +msgctxt "gun_type_type" +msgid "throw" +msgstr "ęŠ•ę“²" + #: lang/json/gun_from_json.py msgid "nail gun" msgid_plural "nail guns" @@ -102816,7 +103624,7 @@ msgstr[0] "" msgid "" "A short homemade lever-action shotgun with a small internal tube magazine. " "While still a primitive pipe and 2x4 design, it is a formiddable shotgun in " -"it's own right with room for improvement." +"its own right with room for improvement." msgstr "" #: lang/json/gun_from_json.py @@ -103132,8 +103940,8 @@ msgid "" msgstr "" #: lang/json/gun_from_json.py -msgid "four winds shotgun" -msgid_plural "four winds shotguns" +msgid "slam-fire pipe shotgun" +msgid_plural "slam-fire pipe shotguns" msgstr[0] "" #: lang/json/gun_from_json.py @@ -103142,6 +103950,18 @@ msgid "" "The lack of sights make this weapon only useful at point-blank range." msgstr "" +#: lang/json/gun_from_json.py +msgid "double slam-fire pipe shotgun" +msgid_plural "double slam-fire pipe shotguns" +msgstr[0] "" + +#: lang/json/gun_from_json.py +msgid "" +"A crude shotgun, composed of four thick steel pipes, two end caps and two " +"nails. The lack of sights make this weapon only useful at point-blank " +"range." +msgstr "" + #: lang/json/gun_from_json.py msgid "flaregun" msgid_plural "flareguns" @@ -103546,11 +104366,6 @@ msgid "" " by hand." msgstr "" -#: lang/json/gun_from_json.py -msgctxt "gun_type_type" -msgid "throw" -msgstr "ęŠ•ę“²" - #: lang/json/gun_from_json.py msgid "slingshot" msgid_plural "slingshots" @@ -106770,6 +107585,7 @@ msgid "" "decay. Eating disgusting food, reading a boring technical book, killing a " "friendly NPC, or going through drug withdrawal are some prominent examples." msgstr "" +"åŒę™‚ä¹Ÿęœ‰čر多ē‹€ę³ęœƒč®“ä½ å£«ę°£ä½Žč½ļ¼Œ ęŽ’é™¤åŽŸęœ¬ēš„č‡Ŗē„¶ę²®å–Ŗć€‚åƒé›£åƒēš„食ē‰©ļ¼Œ 讀ē„”聊ēš„ꊀ蔓ę›øē±ļ¼Œ ę®ŗ害äŗ†ē„”č¾œēš„ NPCļ¼Œ ꈖę˜Æęˆ’é™¤č—„ē™®ļ¼Œ č«øå¦‚ę­¤é”žć€‚" #: lang/json/help_from_json.py msgid "" @@ -107381,6 +108197,9 @@ msgid "" "field. Finding or making a shelter with a place to sleep is very important " "to your survival." msgstr "" +"éšØę™‚č­¦ęƒ•å¤©ę°£ć€‚é¢Øé›Ø꜃ä½æå¤©ę°£ē‹€ę³ę›“加嚓峻ļ¼Œ ä½ č‹„ę˜Æę²’č¾¦ę³•ę‰æ受他們ļ¼Œ 就得åæ«é»žå°‹ę±‚é®č”½ē‰©ć€‚äæęŒä¹¾ēˆ½ę˜Æå¾ˆé‡č¦ēš„ļ¼Œ " +"尤其ę˜Æęƒ”åŠ£ēš„ę°£ęŗ«ē‹€ę³äø‹ęŗ¼ę°£åÆčƒ½ęœƒé€ ęˆå‡å‚·ć€‚č¢«é›Øę·‹ęæ•ēš„č©±å°±ę‹æę¢ęÆ›å·¾ęŠŠč‡Ŗå·±ę“¦ä¹¾ć€‚å¦‚ęžœä½ ē„”ę³•åœØę¼«ę¼«é•·å¤œäø­äæęŒęŗ«ęš–ļ¼Œ " +"ęŠŠč”£ē‰©å †åœØ地äøŠäø¦ē”åœØäøŠé¢å§ć€‚ē‚ŗä½ ēš„åŗŠę‰¾é”†ęž•é ­å’ŒęƛęÆÆ對你ēš„ē”ēœ å“č³Ŗ來čŖŖę°ø遠ę˜Æęœ€ä½³éøę“‡ć€‚å¦‚ęžœä½ ę‰¾äøåˆ°ēš„č©±å°±ę¹Šåˆäŗ›ļ¼Œå°±ē®—åœØ地äø‹å®¤ēš„ę¤…å­ä¹ŸęƔ野外ęæ•ę·‹ę·‹ēš„地äøŠå„½ć€‚å°‹ę‰¾ęˆ–å»ŗ造äø€å€‹ęœ‰åœ°ę–¹åÆ仄ē”č¦ŗēš„åŗ‡č­·ę‰€å°ä½ ēš„ē”Ÿå­˜ä¾†čŖŖ非åøøé‡č¦ć€‚" #: lang/json/help_from_json.py msgid "" @@ -108933,6 +109752,11 @@ msgid "" "access the controls, or use the vehicle control key (default '^')." msgstr "" +#. ~ Please leave anything in unchanged. +#: lang/json/json_flag_from_json.py +msgid "When active, turns engines on and off automatically." +msgstr "" + #. ~ Please leave anything in unchanged. #: lang/json/json_flag_from_json.py msgid "Illuminated items in this space will not illuminate nearby squares." @@ -110627,6 +111451,10 @@ msgstr "åˆ‡ę›ę·Øę°“å™Ø" msgid "Toggle tracking" msgstr "開關čæ½č¹¤č£ē½®" +#: lang/json/keybinding_from_json.py +msgid "Toggle smart engine controller" +msgstr "" + #: lang/json/keybinding_from_json.py src/turret.cpp src/vehicle_use.cpp msgid "Set turret firing modes" msgstr "čØ­å®šę§å””å°„ę“Šęؔ式" @@ -115917,17 +116745,17 @@ msgstr "å°‹ę‰¾åøå…„å™Ø" #: lang/json/mission_def_from_json.py msgid "I'mā€¦ shortā€¦ of breathā€¦" -msgstr "" +msgstr "ꈑā€¦ 透ā€¦ äøéŽā€¦ ę°£ā€¦" #: lang/json/mission_def_from_json.py msgid "I'm asthmatic. I need you to get an inhaler for meā€¦" -msgstr "" +msgstr "ęˆ‘ęœ‰ę°£å–˜ć€‚ęˆ‘éœ€č¦ä½ å¹«ęˆ‘ę‹æåøå…„å™Øā€¦" #: lang/json/mission_def_from_json.py msgid "" "Oh, thank god, thank you so much! I won't last more than a couple of days, " "so hurryā€¦" -msgstr "" +msgstr "喔ļ¼Œ ę„Ÿč¬č€å¤©ēˆŗļ¼Œ ēœŸę˜Æč¬č¬ä½ ļ¼ ęˆ‘ä¹ŸčرåŖčƒ½å†ę’å¹¾å¤©č€Œå·²äŗ†ļ¼Œ ꉀ仄請趕åæ«ā€¦" #: lang/json/mission_def_from_json.py msgid "What?! Please, without your help!" @@ -117608,7 +118436,7 @@ msgstr "" msgid "" "We could use some seeds for the next planting season. Can you bring me 20 " "bee balm seeds?" -msgstr "" +msgstr "ęˆ‘å€‘åÆ仄åœØäø‹å€‹ę’­ēخ季ē”ØäøŠäø€äŗ›ēØ®å­ć€‚ä½ čƒ½åø¶ä¾† 20 個ē®”čœ‚é¦™č‰ēخ子嗎?" #: lang/json/mission_def_from_json.py msgid "" @@ -128470,17 +129298,6 @@ msgid "" "anything now is another question." msgstr "ä½ ę˜Æ個宣čŖ“ę•ˆåæ éŽēš„åŸ·ę³•č­¦å®˜ć€‚å› ē‚ŗ州際ēš„合ē“„ę•ˆåŠ›č€Œę“ęœ‰ę–°č‹±ę ¼č˜­åœ°å€ēš„ē®”č½„ę¬Šć€‚ē„¶č€Œē®”č½„ę¬Šē¾åœØå·²ē¶“ę˜Æ另外ēš„å•é”Œć€‚" -#: lang/json/mutation_from_json.py -msgid "Helicopter Pilot" -msgstr "" - -#. ~ Description for Helicopter Pilot -#: lang/json/mutation_from_json.py -msgid "" -"You are a trained helicopter pilot. This makes you one of the few living " -"people who can operate a helicopter after the Cataclysm." -msgstr "" - #: lang/json/mutation_from_json.py msgid "SWAT Officer" msgstr "SWATē‰¹č­¦" @@ -133407,6 +134224,10 @@ msgstr "ē±³ęˆˆę–„候ēž­ęœ›å””" msgid "subway station?" msgstr "地äø‹éµļ¼Ÿ" +#: lang/json/overmap_terrain_from_json.py +msgid "science lab reactor" +msgstr "" + #: lang/json/overmap_terrain_from_json.py msgid "lab" msgstr "åƦ驗室" @@ -140715,6 +141536,18 @@ msgid "" "You have your whole life ahead of you and it's gonna be sweet!" msgstr "" +#: lang/json/proficiency_from_json.py +msgid "Knapping" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Blacksmithing" +msgstr "" + +#: lang/json/proficiency_from_json.py +msgid "Helicopter Piloting" +msgstr "" + #. ~ Crafting recipes category name #: lang/json/recipe_category_from_json.py msgid "*" @@ -146019,7 +146852,7 @@ msgid "" "Since birth, your sole purpose in life has been the advancement of genetic " "science, willingly or not. Once the Cataclysm struck, you left the lab, and" " wandered aimlessly, ending up in a forest." -msgstr "" +msgstr "č‡Ŗä½ å‡ŗäø–仄來ļ¼Œ ä½ ēš„ē”Ø途就ę˜Æē”Øä¾†é€²č”ŒåŸŗ因ē§‘å­øēš„åƦ驗品ļ¼Œ äøē®”你锘äøé”˜ę„ć€‚ē•¶ē½č®Šēˆ†ē™¼ļ¼Œ 你離開äŗ†åƦ驗室ļ¼Œ ę¼«ē„”ē›®ēš„ēš„åœØę£®ęž—éŠč•©ć€‚" #. ~ Description for scenario 'Experiment' for a female character. #: lang/json/scenario_from_json.py @@ -146028,7 +146861,7 @@ msgid "" "Since birth, your sole purpose in life has been the advancement of genetic " "science, willingly or not. Once the Cataclysm struck, you left the lab, and" " wandered aimlessly, ending up in a forest." -msgstr "" +msgstr "č‡Ŗä½ å‡ŗäø–仄來ļ¼Œ ä½ ēš„ē”Ø途就ę˜Æē”Øä¾†é€²č”ŒåŸŗ因ē§‘å­øēš„åƦ驗品ļ¼Œ äøē®”你锘äøé”˜ę„ć€‚ē•¶ē½č®Šēˆ†ē™¼ļ¼Œ 你離開äŗ†åƦ驗室ļ¼Œ ę¼«ē„”ē›®ēš„ēš„åœØę£®ęž—éŠč•©ć€‚" #. ~ Name for scenario 'The Mascot Rises' for a male character #: lang/json/scenario_from_json.py @@ -148566,6 +149399,7 @@ msgid "" " a difference. And pick a spot well, even a chair or a bench is better than" " a cold ground." msgstr "" +"ꈑēŸ„道這ꈖčرäøę˜Æęœ€å„½ēš„ę™‚ę©Ÿļ¼ŒäøéŽč©¦č‘—儽儽ē”č¦ŗć€‚å¦‚ęžœä½ ēš„ē”ēœ č¢«å‰å„Ŗäŗ†ļ¼Œä½ å°‡ē„”ę³•äæęŒč‡Ŗęˆ‘ć€‚ę‰¾é”†ęž•é ­å’ŒęÆÆå­ć€‚å¦‚ęžœåšäøåˆ°ļ¼Œäø€éš»ę³°čæŖē†Šå¢ŠåœØé ­äø‹å’Œäø€ē–Ščƒ½äæęŒęŗ«ęš–ēš„č”£ęœå°±ęœ‰å¾ˆå¤§ēš„區刄怂äø¦äø”ę…Žéø地點ļ¼Œå°±ē®—äø€å¼µę¤…å­ęˆ–é•·ę¤…ä¹Ÿå„½éŽå†°å†·ēš„地ęæ怂" #: lang/json/snippet_from_json.py msgid "" @@ -148651,7 +149485,7 @@ msgstr "" msgid "Finally, something to take the edge off." msgstr "" -#: lang/json/snippet_from_json.py src/npctalk.cpp +#: lang/json/snippet_from_json.py src/talker_npc.cpp msgid "No thanks, I'm good." msgstr "" @@ -158710,7 +159544,7 @@ msgstr "" #: lang/json/snippet_from_json.py msgid "So much death around. Why not add some more?" -msgstr "" +msgstr "å‘Ø圍充ę»æäŗ†ę­»äŗ”ć€‚ä½•äøå¤šę®ŗäø€é»žå‘¢?" #: lang/json/snippet_from_json.py msgid "You lick your lips, in anticipation for dead trophies." @@ -168211,6 +169045,18 @@ msgstr "這ę˜Æu_has_var态u_remove_varęø¬č©¦å›žę‡‰ć€‚" msgid "This is a npc_has_var, npc_remove_var test response." msgstr "這ę˜Ænpc_has_var态npc_remove_var ęø¬č©¦å›žę‡‰ć€‚" +#: lang/json/talk_topic_from_json.py +msgid "This is a u_add_var time test response." +msgstr "" + +#: lang/json/talk_topic_from_json.py +msgid "This is a npc_add_var time test response." +msgstr "" + +#: lang/json/talk_topic_from_json.py +msgid "This is a u_compare_var time test response for > 3_days." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "This is a u_adjust_var test response that increments by 1." msgstr "" @@ -168311,6 +169157,10 @@ msgstr "" msgid "This is a low driving test response." msgstr "" +#: lang/json/talk_topic_from_json.py +msgid "This is an npc_first_topic test response." +msgstr "" + #: lang/json/talk_topic_from_json.py msgid "Greetings friend, it's nice to see you." msgstr "ęœ‹å‹ä½ å„½ļ¼Œå¾ˆé«˜čˆˆč¦‹åˆ°ä½ ć€‚" @@ -169194,7 +170044,7 @@ msgid "" "I spent a lot of time rummaging for rhubarb and bits of vegetables in the " "forest before I found the courage to start picking off some of those dead " "monsters. I guess I was getting desperate." -msgstr "" +msgstr "åœØęˆ‘ę‹¾čµ·å‹‡ę°£å–čµ°é‚£äŗ›ę­»ęŽ‰ēš„ę€Ŗē‰©ä¹‹å‰ļ¼Œęˆ‘花äŗ†å¾ˆå¤šę™‚é–“åœØę£®ęž—å°‹ę‰¾å¤§é»ƒå’Œå…¶ä»–äø€é»žč”¬čœć€‚ęˆ‘ēŒœęˆ‘å·²ē¶“ę„Ÿåˆ°ēµ•ęœ›äŗ†ć€‚" #: lang/json/talk_topic_from_json.py msgid "And that's it? You spent months just living off the land?" @@ -176604,7 +177454,7 @@ msgid "Will do, thanks!" msgstr "å¤Ŗ儽äŗ†, č¬äŗ†!" #: lang/json/talk_topic_from_json.py lang/json/talk_topic_from_json.py -#: src/npctalk.cpp +#: src/talker.h src/talker_npc.cpp msgid "Nope." msgstr "äøć€‚" @@ -182525,6 +183375,36 @@ msgstr "" msgid "The door opens forcefully!" msgstr "" +#: lang/json/terrain_from_json.py +msgid "broken diesel tank" +msgstr "" + +#. ~ Description for centrifuge +#: lang/json/terrain_from_json.py +msgid "" +"This is a centrifuge, a liquid separating device with an automated analyzer " +"unit. It could be used to analyze a medical fluid sample, such as blood, if" +" a test tube was placed in it." +msgstr "" + +#: lang/json/terrain_from_json.py +msgid "plutonium generator" +msgstr "鈽ē™¼é›»ę©Ÿ" + +#. ~ Description for plutonium generator +#: lang/json/terrain_from_json.py +msgid "" +"This imposing apparatus harnesses the power of the atom. Refined nuclear " +"fuel is 'burned' to provide nearly limitless electrical power. It's not " +"doing much good here though. Perhaps it could be salvaged for other " +"purposes." +msgstr "" + +#. ~ Description for old machinery +#: lang/json/terrain_from_json.py +msgid "Assorted old machinery. You could scavenge it for parts." +msgstr "" + #: lang/json/terrain_from_json.py msgid "scorched earth" msgstr "ē„¦åœŸ" @@ -183948,12 +184828,12 @@ msgstr "ęæ•ę»‘ēš„ę³„ęæ˜å€åŸŸć€‚" #: lang/json/terrain_from_json.py msgid "moss" -msgstr "" +msgstr "苔ē™¬" #. ~ Description for moss #: lang/json/terrain_from_json.py msgid "Moist spongy moss." -msgstr "" +msgstr "ęæ•č»Ÿēš„č‹”č˜š" #: lang/json/terrain_from_json.py msgid "clay" @@ -185261,24 +186141,6 @@ msgid "" "press them into basic shapes, ready for further crafting." msgstr "" -#: lang/json/terrain_from_json.py -msgid "fuel tank" -msgstr "" - -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with gasoline." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "broken fuel tank" -msgstr "" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with gasoline." -msgstr "" - #: lang/json/terrain_from_json.py msgid "gasoline pump" msgstr "ę±½ę²¹ę³µ" @@ -185303,16 +186165,6 @@ msgid "" "the liquid gold." msgstr "" -#. ~ Description for fuel tank -#: lang/json/terrain_from_json.py -msgid "A tank filled with diesel." -msgstr "" - -#. ~ Description for broken fuel tank -#: lang/json/terrain_from_json.py -msgid "A broken tank which was filled with diesel." -msgstr "" - #: lang/json/terrain_from_json.py msgid "diesel pump" msgstr "ęŸ“ę²¹ę³µ" @@ -185390,16 +186242,6 @@ msgid "" "airflow." msgstr "" -#: lang/json/terrain_from_json.py -msgid "broken generator" -msgstr "ęå£žēš„ē™¼é›»ę©Ÿ" - -#. ~ Description for broken generator -#: lang/json/terrain_from_json.py -msgid "" -"This generator is broken and will not help you produce usable electricity." -msgstr "" - #: lang/json/terrain_from_json.py msgid "missile" msgstr "飛彈" @@ -185457,18 +186299,6 @@ msgid "" "This unpowered pump previously would have moved fluids around in a hurry." msgstr "" -#: lang/json/terrain_from_json.py -msgid "centrifuge" -msgstr "離åæƒę©Ÿ" - -#. ~ Description for centrifuge -#: lang/json/terrain_from_json.py -msgid "" -"This is a centrifuge, a liquid separating device with an automated analyzer " -"unit. It could be used to analyze a medical fluid sample, such as blood, if" -" a test tube was placed in it." -msgstr "" - #: lang/json/terrain_from_json.py msgid "CVD machine" msgstr "化å­øę°£ē›øę²‰ē©ę©Ÿ" @@ -185564,19 +186394,6 @@ msgstr "é£²ę°“ę©Ÿ" msgid "A machine with several taps that dispenses clean water." msgstr "äø€å°ęœ‰č‘—ę•øå€‹ę°“é¾é ­äø¦čƒ½ä¾›ę‡‰ę·Øę°“ēš„ę©Ÿå™Ø怂" -#: lang/json/terrain_from_json.py -msgid "plutonium generator" -msgstr "鈽ē™¼é›»ę©Ÿ" - -#. ~ Description for plutonium generator -#: lang/json/terrain_from_json.py -msgid "" -"This imposing apparatus harnesses the power of the atom. Refined nuclear " -"fuel is 'burned' to provide nearly limitless electrical power. It's not " -"doing much good here though. Perhaps it could be salvaged for other " -"purposes." -msgstr "" - #: lang/json/terrain_from_json.py msgid "telecom cabinet" msgstr "通äæ”꫃" @@ -185691,46 +186508,6 @@ msgstr "č¼ø送åø¶" msgid "A conveyor belt. Used to transport things." msgstr "" -#: lang/json/terrain_from_json.py -msgid "ting." -msgstr "걀怂" - -#: lang/json/terrain_from_json.py -msgid "light machinery" -msgstr "č¼•åž‹ę©Ÿę¢°" - -#. ~ Description for light machinery -#: lang/json/terrain_from_json.py -msgid "Assorted light machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "heavy machinery" -msgstr "é‡åž‹ę©Ÿę¢°" - -#. ~ Description for heavy machinery -#: lang/json/terrain_from_json.py -msgid "Assorted heavy machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "old machinery" -msgstr "čˆŠę©Ÿę¢°" - -#. ~ Description for old machinery -#: lang/json/terrain_from_json.py -msgid "Assorted old machinery. You could scavenge it for parts." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "electronic machinery" -msgstr "é›»å­ę©Ÿę¢°" - -#. ~ Description for electronic machinery -#: lang/json/terrain_from_json.py -msgid "Assorted electronic machinery. You could scavenge it for parts." -msgstr "" - #: lang/json/terrain_from_json.py msgid "milking machine" msgstr "ę“ å„¶ę©Ÿ" @@ -185801,29 +186578,6 @@ msgid "" "from the elements or to protect a campfire from the rain." msgstr "" -#: lang/json/terrain_from_json.py -msgid "broken console" -msgstr "å£žęŽ‰ēš„ęŽ§åˆ¶å°" - -#. ~ Description for broken console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It doesn't seem to be working. " -"It's the broken screen and shattered circuit boards that's telling you that." -msgstr "" - -#: lang/json/terrain_from_json.py -msgid "computer console" -msgstr "é›»č…¦ęŽ§åˆ¶å°" - -#. ~ Description for computer console -#: lang/json/terrain_from_json.py -msgid "" -"This is a standalone computer terminal. It can be used to view contents and" -" perform any allowed functions. It might even be possible to hack it, given" -" the skills." -msgstr "" - #: lang/json/terrain_from_json.py msgid "mechanical winch" msgstr "ę©Ÿę¢°ēµžē›¤" @@ -187962,10 +188716,6 @@ msgstr "äøŠå”" msgid "An upward facing slope." msgstr "向äøŠēš„ę–œå”怂" -#: lang/json/terrain_from_json.py -msgid "rope leading up" -msgstr "向äøŠå»¶ä¼øēš„ē¹©å­" - #. ~ Description for rope leading up #: lang/json/terrain_from_json.py msgid "A rope. You could climb up it." @@ -188625,6 +189375,10 @@ msgstr "ę±½č»Š" msgid "Car Chassis" msgstr "ę±½č»Šåŗ•ē›¤" +#: lang/json/vehicle_from_json.py +msgid "Hybrid Car" +msgstr "" + #: lang/json/vehicle_from_json.py msgid "City Car" msgstr "" @@ -190325,6 +191079,21 @@ msgid "" "disabled." msgstr "äø€å †é›»å­čح備, č®“ä½ ę²’ęœ‰ę­£ē¢ŗēš„é‘°åŒ™ę™‚ē„”ę³•ē™¼å‹•č»Šč¼›, å¦‚ęžœä½ å˜—č©¦ē™¼å‹•ēš„č©±ęœƒē™¼å‡ŗč­¦å ±ć€‚č­¦å ±čƒ½č¢«ē¦ē”Ø怂" +#: lang/json/vehicle_part_from_json.py +msgid "smart engine controller" +msgstr "" + +#. ~ Description for {'str': 'smart engine controller'} +#: lang/json/vehicle_part_from_json.py +#, no-python-format +msgid "" +"Electronic module that automatically switches combustion and electric " +"engines on and off minimizing fuel consumption and optimizing power output " +"and battery charge rate. Must be turned on to work. Simplified ruleset: 1." +" When throttling, maximize acceleration. 2. Keep battery at 90%. 3. " +"Minimize fuel consumption." +msgstr "" + #: lang/json/vehicle_part_from_json.py msgid "5-point harness" msgstr "äŗ”點式安å…Øåø¶" @@ -191488,6 +192257,66 @@ msgstr "" msgid "Disgusting Diet" msgstr "" +#: lang/json/vitamin_from_json.py +msgid "Blood" +msgstr "" + +#: lang/json/vitamin_from_json.py +msgid "Red Blood Cells" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "NULL Weather - BUG" +msgstr "" + +#: lang/json/weather_type_from_json.py +msgid "Clear" +msgstr "ę™“ęœ—" + +#: lang/json/weather_type_from_json.py +msgid "Sunny" +msgstr "č±”é™½" + +#: lang/json/weather_type_from_json.py +msgid "Cloudy" +msgstr "多雲" + +#: lang/json/weather_type_from_json.py +msgid "Light Drizzle" +msgstr "ęƛęƛē“°é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Drizzle" +msgstr "ē“°é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Rain" +msgstr "äø‹é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Thunder Storm" +msgstr "雷é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Acidic Drizzle" +msgstr "é…øꀧē“°é›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Acid Rain" +msgstr "é…øé›Ø" + +#: lang/json/weather_type_from_json.py +msgid "Flurries" +msgstr "小é›Ŗ" + +#: lang/json/weather_type_from_json.py +msgid "Snowing" +msgstr "äø‹é›Ŗ" + +#: lang/json/weather_type_from_json.py +msgid "Snowstorm" +msgstr "ęš“é¢Øé›Ŗ" + #: src/achievement.cpp msgid "time of cataclysm" msgstr "" @@ -191653,8 +192482,7 @@ msgstr "ä½ ēš„čƒ½é‡ęµå¤±äŗ†!" msgid "You cannot hack this." msgstr "" -#: src/activity_actor.cpp src/computer_session.cpp src/computer_session.cpp -#: src/iuse.cpp src/map.cpp +#: src/activity_actor.cpp src/computer_session.cpp src/iuse.cpp src/map.cpp msgid "an alarm sound!" msgstr "č­¦å ±č²å¤§ä½œ!" @@ -191792,6 +192620,16 @@ msgstr "ē¹¼ēŗŒå˜—č©¦å…„ē”怂" msgid "Continue trying to fall asleep and don't ask again." msgstr "ē¹¼ēŗŒå˜—č©¦å…„ē”ļ¼Œäøå†č©¢å•ć€‚" +#: src/activity_actor.cpp +#, c-format +msgid "You disassemble your %s." +msgstr "ä½ ę‹†č§£äŗ†ä½ ēš„ %s怂" + +#: src/activity_actor.cpp src/player.cpp +#, c-format +msgid "You unload your %s." +msgstr "ä½ ęø…ē©ŗä½ ēš„ %s怂" + #: src/activity_actor.cpp msgid "You are too tired to exercise." msgstr "" @@ -192281,11 +193119,6 @@ msgstr[0] " ęŠŠå±é«”ę‰“ēˆ›äŗ†ć€‚" msgid "Can't reload the %s." msgstr "ē„”ę³•č£å”« %s怂" -#: src/activity_handlers.cpp src/iexamine.cpp -#, c-format -msgid "You reload the %s." -msgstr "ä½ č£å”«äŗ† %s怂" - #: src/activity_handlers.cpp #, c-format msgid "" @@ -192302,6 +193135,11 @@ msgstr "" msgid "You refill the %s." msgstr "ä½ č£å”«äŗ† %s怂" +#: src/activity_handlers.cpp +#, c-format +msgid "You reload the %1$s with %2$s." +msgstr "" + #: src/activity_handlers.cpp src/bionics.cpp msgid "There's nothing to light there." msgstr "é€™č£”ę²’ęœ‰čƒ½é»žē‡ƒēš„ę±č„æ怂" @@ -192428,6 +193266,10 @@ msgstr "你這ęأ做äøęœƒå­øåˆ°ę›“å¤šę±č„æ怂" msgid "%s %s\n" msgstr "%s %s\n" +#: src/activity_handlers.cpp src/magic.cpp +msgid "bionic power" +msgstr "ē”ŸåŒ–čƒ½é‡" + #: src/activity_handlers.cpp #, c-format msgid "Charges: %s/%s %s (%s per use)\n" @@ -192806,16 +193648,6 @@ msgstr "ä½ ę‰“é–‹äŗ†å·„å…·åŒ…é–‹å§‹åˆ®é¬å­ć€‚" msgid "You give your hair a trim." msgstr "ä½ äæ®å‰Ŗä½ ēš„頭髮怂" -#: src/activity_handlers.cpp -#, c-format -msgid "You disassemble your %s." -msgstr "ä½ ę‹†č§£äŗ†ä½ ēš„ %s怂" - -#: src/activity_handlers.cpp src/player.cpp -#, c-format -msgid "You unload your %s." -msgstr "ä½ ęø…ē©ŗä½ ēš„ %s怂" - #: src/activity_handlers.cpp #, c-format msgid "You have run out of %s." @@ -193805,7 +194637,7 @@ msgstr "這ę˜Æäø€å±¤éˆę°£åœē¹žč‘—ä½ ć€‚" msgid "Properties" msgstr "å±¬ę€§" -#: src/armor_layers.cpp +#: src/armor_layers.cpp src/item.cpp msgid "Coverage:" msgstr "覆蓋ēŽ‡:" @@ -195775,7 +196607,7 @@ msgstr "ä½ ę²’ęœ‰čƒ½é‡ä¾†å•Ÿå‹•ä½ ēš„ %s怂" msgid "Deactivate your %s first!" msgstr "č«‹å…ˆé—œé–‰ä½ ēš„ %s!" -#: src/bionics.cpp src/player.cpp +#: src/bionics.cpp src/character.cpp #, c-format msgid "Stop wielding %s?" msgstr "åœę­¢ę‰‹ęŒ %s?" @@ -197173,6 +198005,11 @@ msgstr "äø‹é¦¬åˆ°ä½•č™•ļ¼Ÿ" msgid "You cannot dismount there!" msgstr "ä½ ē„”ę³•äø‹é¦¬åˆ°é‚£é‚Šļ¼" +#: src/character.cpp +#, c-format +msgid "This task is too simple to train your %s beyond %d." +msgstr "這äŗ‹ęƒ…å¤Ŗē°”å–®č€Œē„”ę³•č®“ä½ čؓē·“ %s 超過 %d怂" + #: src/character.cpp msgid "You struggle to stand." msgstr "ä½ ęŽ™ę‰Žč©¦č‘—ē«™čµ·ć€‚" @@ -197343,6 +198180,16 @@ msgstr " 逃å‡ŗ坑äŗ†!" msgid "Your %s bionic comes back online." msgstr "" +#: src/character.cpp +#, c-format +msgid "Your skill in %s has increased to %d!" +msgstr "ä½ ēš„ %s ęŠ€čƒ½äøŠå‡åˆ° %d!" + +#: src/character.cpp +#, c-format +msgid "You feel that %s tasks of this level are becoming trivial." +msgstr "ä½ č¦ŗ得åœØ這個ē­‰ē“šēš„ %s å·„ä½œč®Šå¾—ę²’ęŒ‘ęˆ°ę€§äŗ†ć€‚" + #: src/character.cpp #, c-format msgid "You put on your %s." @@ -197457,6 +198304,15 @@ msgstr "" msgid "%s doesn't have any broken limbs this could help." msgstr "" +#: src/character.cpp +msgid "You don't need a tourniquet to stop the bleeding." +msgstr "" + +#: src/character.cpp +#, c-format +msgid "%s doesn't need a tourniquet to stop the bleeding." +msgstr "" + #: src/character.cpp msgid "You don't have enough arms to wear that." msgstr "" @@ -197637,7 +198493,7 @@ msgstr "ꄵåŗ¦é£¢é¤“" msgid "ERROR!" msgstr "" -#: src/character.cpp src/npctalk.cpp +#: src/character.cpp src/talker_npc.cpp msgid "Exhausted" msgstr "ē­‹ē–²åŠ›ē«­" @@ -197681,7 +198537,7 @@ msgstr "ä½ čœ·ę›²čŗ«č»€ę“ é€²é€™č»Šč¼›ć€‚" msgid "You have a sudden heart attack!" msgstr "ä½ ēŖē„¶åæƒč‡Ÿē—…ē™¼!" -#: src/character.cpp +#: src/character.cpp src/player_hardcoded_effects.cpp msgid " has a sudden heart attack!" msgstr "" @@ -197909,12 +198765,12 @@ msgstr "č‰Æ儽" #: src/character.cpp #, c-format -msgid "Chance to stop: %d %%" -msgstr "ę­¢č”€ēš„ę©ŸēŽ‡: %d%%" +msgid "Expected reduction of bleeding by: %d %%" +msgstr "" #: src/character.cpp -msgid "This will not stop the bleeding." -msgstr "é€™å°ę­¢č”€ę²’ęœ‰å¹«åŠ©ć€‚" +msgid "This will not affect the bleeding." +msgstr "" #: src/character.cpp #, c-format @@ -198346,6 +199202,41 @@ msgstr "ä½ ēš„ %1$s 進äø€ę­„ēš„ %2$s!" msgid "Your %1$s is %2$s!" msgstr "ä½ ēš„ %1$s %2$säŗ†!" +#: src/character.cpp +msgid "Can't wield spilt liquids." +msgstr "äøčƒ½ę®ē‘ęŗ¢å‡ŗēš„ę¶²é«”ć€‚" + +#: src/character.cpp +msgid "You need at least one arm to even consider wielding something." +msgstr "ä½ éœ€č¦č‡³å°‘äø€éš»ę‰‹ę‰čƒ½ęŒę”ę±č„æ怂" + +#: src/character.cpp +#, c-format +msgid "The %s is preventing you from wielding the %s." +msgstr "" + +#: src/character.cpp +msgid "Something you are wearing hinders the use of both hands." +msgstr "ä½ ē©æꈓēš„ę±č„æ阻ē¤™äŗ†ä½æē”Ø雙ꉋ怂" + +#: src/character.cpp +#, c-format +msgid "The %s can't be wielded with only one arm." +msgstr "ä½ åƒ…ęœ‰ēš„äø€ę”Æꉋę‹æäøäŗ† %s怂" + +#: src/character.cpp +#, c-format +msgid "You are too weak to wield %s with only one arm." +msgstr "ä½ åƒ…ęœ‰ēš„äø€ę”Æę‰‹åŠ›é‡äøč¶³, ę‹æäøäŗ† %s怂" + +#: src/character.cpp +msgid " (empty)" +msgstr "" + +#: src/character.cpp src/npctalk.cpp +msgid "fists" +msgstr "ę‹³é ­" + #: src/character.cpp #, c-format msgid "You are no longer able to wield your %s and drop it!" @@ -198894,6 +199785,11 @@ msgstr "ē™»å…„ęˆåŠŸć€‚č«‹ęŒ‰ä»»ę„éµā€¦" msgid "%s - Root Menu" msgstr "" +#: src/computer_session.cpp +#, c-format +msgid "%s (UNAVAILABLE)" +msgstr "" + #: src/computer_session.cpp msgid "Password required." msgstr "éœ€č¦åƆē¢¼" @@ -199498,7 +200394,7 @@ msgstr "" msgid "Result: " msgstr "å»ŗ造ēµęžœ: " -#: src/construction.cpp +#: src/construction.cpp src/worldfactory.cpp msgid "N/A" msgstr "N/A" @@ -200147,6 +201043,10 @@ msgid "" "Start crafting anyway?" msgstr "" +#: src/craft_command.cpp +msgid "You don't have the required proficiencies to craft this!" +msgstr "" + #: src/craft_command.cpp msgid "" "This craft will use rotten components.\n" @@ -200618,6 +201518,11 @@ msgstr "" msgid "Other skills: %s" msgstr "å…¶ä»–ęŠ€čƒ½: %s" +#: src/crafting_gui.cpp +#, c-format +msgid "Proficiencies Required: %s" +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "Time to complete: %s" @@ -200661,6 +201566,12 @@ msgid "" "components" msgstr "" +#: src/crafting_gui.cpp +msgid "" +"Cannot be crafted because you lack the required " +"proficiencies." +msgstr "" + #: src/crafting_gui.cpp #, c-format msgid "v (%s for more)" @@ -201046,6 +201957,10 @@ msgstr "ē·Øč¼ÆēŽ©å®¶/NPC" msgid "Damage self" msgstr "č‡Ŗꮘ" +#: src/debug_menu.cpp +msgid "Bleed self" +msgstr "" + #: src/debug_menu.cpp msgid "Set automove route" msgstr "čØ­ē½®č‡Ŗ動ē§»å‹•č·Æ徑" @@ -201178,6 +202093,14 @@ msgstr "čæ”回äø»éø單" msgid "Gameā€¦" msgstr "" +#: src/debug_menu.cpp +msgid "Change [b]attery charge" +msgstr "" + +#: src/debug_menu.cpp +msgid "Vehicleā€¦" +msgstr "" + #: src/debug_menu.cpp msgid "Teleport - short range" msgstr "傳送 - ēŸ­č·" @@ -201813,12 +202736,8 @@ msgstr "位ē½® %d:%d åœØ %d:%d, %s\n" #: src/debug_menu.cpp #, c-format -msgid "" -"Current turn: %d.\n" -"%s\n" +msgid "Current turn: %d.\n" msgstr "" -"ē•¶å‰å›žåˆ: %d怂\n" -"%s\n" #: src/debug_menu.cpp #, c-format @@ -201826,14 +202745,6 @@ msgid "%d creature exists.\n" msgid_plural "%d creatures exist.\n" msgstr[0] "尚存 %d 個ē”Ÿē‰©ć€‚\n" -#: src/debug_menu.cpp -msgid "NPCs are going to spawn." -msgstr "NPC å°‡ęœƒē”¢ē”Ÿć€‚" - -#: src/debug_menu.cpp -msgid "NPCs are NOT going to spawn." -msgstr "NPC 將äøęœƒē”¢ē”Ÿć€‚" - #: src/debug_menu.cpp #, c-format msgid "%s: map ( %d:%d ) pos ( %d:%d )" @@ -201889,6 +202800,22 @@ msgstr "éø꓇要ē”¢ē”Ÿēš„č»Šč¼›" msgid "%1$s (%2$s)" msgstr "%1$s (%2$s)" +#: src/debug_menu.cpp +msgid "Vehicle condition" +msgstr "" + +#: src/debug_menu.cpp +msgid "Light damage" +msgstr "" + +#: src/debug_menu.cpp +msgid "Undamaged" +msgstr "" + +#: src/debug_menu.cpp +msgid "Disabled (tires or engine)" +msgstr "" + #: src/debug_menu.cpp msgid "Martial arts debug." msgstr "ꭦ蔓除éŒÆ怂" @@ -201950,6 +202877,10 @@ msgstr "äæęŒę­£åøøé¢Ø速" msgid "Damage self for how much? hp: %s" msgstr "" +#: src/debug_menu.cpp +msgid "Add bleeding duration in minutes, equal to intensity:" +msgstr "" + #: src/debug_menu.cpp msgid "This binary was not compiled with tiles support." msgstr "é€™å€‹åŸ·č”ŒęŖ”äø¦ę²’ęœ‰ē·Øč­Æꈐę”Æę“åœ–åƒć€‚" @@ -202081,6 +203012,14 @@ msgstr "" msgid "%s is now level %d!" msgstr "" +#: src/debug_menu.cpp src/iuse.cpp src/iuse.cpp +msgid "There's no vehicle there." +msgstr "é‚£č£”ę²’ęœ‰č»Šč¼›" + +#: src/debug_menu.cpp +msgid "By how much? (in kJ, negative to discharge)" +msgstr "" + #: src/descriptions.cpp #, c-format msgid "" @@ -202789,6 +203728,22 @@ msgstr "傑å‡ŗ" msgid "perfect" msgstr "完ē¾Ž" +#: src/effect.cpp +msgid "miniscule" +msgstr "" + +#: src/effect.cpp +msgid "small" +msgstr "小" + +#: src/effect.cpp +msgid "moderate" +msgstr "" + +#: src/effect.cpp +msgid "excellent" +msgstr "" + #. ~ Default format for scores. %1$s is statistic description; %2$s is value. #: src/event_statistics.cpp #, c-format @@ -205509,6 +206464,11 @@ msgstr "ä½ ēš„大地圖位ē½®: %d, %d, %d" msgid "Your local position: %d, %d, %d" msgstr "ä½ ēš„區域位ē½®: %d, %d, %d" +#: src/game.cpp +#, c-format +msgid "Total NPCs within %d OMTs: %d. %d are static NPCs." +msgstr "" + #: src/game.cpp msgid "East:" msgstr "ę±:" @@ -207251,12 +208211,12 @@ msgid "Your inventory is empty." msgstr "ä½ ēš„ē‰©å“ę¬„ę˜Æē©ŗēš„怂" #: src/game_inventory.cpp -msgid "ENCUMBRANCE" -msgstr "ē“Æč“…" +msgid "AVG ENCUMBRANCE" +msgstr "" #: src/game_inventory.cpp -msgid "COVERAGE" -msgstr "覆蓋ēŽ‡" +msgid "AVG COVERAGE" +msgstr "" #: src/game_inventory.cpp msgid "WARMTH" @@ -210411,6 +211371,11 @@ msgstr "č¦ęŠŠå¤šå°‘ēš„ %1$s ę”¾å…„ %2$s?" msgid "The %1$s contains %2$d %3$s." msgstr "%1$s ē”± %2$d 個 %3$s ꧋ꈐ怂" +#: src/iexamine.cpp +#, c-format +msgid "You reload the %s." +msgstr "ä½ č£å”«äŗ† %s怂" + #: src/iexamine.cpp msgid "Do what with the curtains?" msgstr "對ēŖ—ē°¾åšä»€éŗ¼?" @@ -211263,6 +212228,10 @@ msgstr "꜀ēµ‚處ē†" msgid "Body parts" msgstr "čŗ«é«”éƒØ位" +#: src/init.cpp +msgid "Weather types" +msgstr "" + #: src/init.cpp msgid "Field types" msgstr "地形锞刄" @@ -212098,10 +213067,6 @@ msgstr "" msgid "max rot (turns): " msgstr "" -#: src/item.cpp -msgid "last rot: " -msgstr "腐ꕗꭷꙂ: " - #: src/item.cpp msgid "last temp: " msgstr "" @@ -212365,8 +213330,8 @@ msgid "Recommended strength (burst): " msgstr "å»ŗč­°åŠ›é‡ (連ē™¼): " #: src/item.cpp -msgid " moves " -msgstr " č”Œå‹•å€¼" +msgid " moves" +msgstr "" #: src/item.cpp msgid "Skill used: " @@ -212402,10 +213367,6 @@ msgstr "å°é•·č·é›¢ē›®ęؙēš„平均命äø­ēŽ‡: " msgid "" msgstr "" -#: src/item.cpp -msgid " moves" -msgstr "" - #: src/item.cpp msgid "Time to reach aim level: " msgstr "ēž„ęŗ–ę‰€éœ€ę™‚é–“: " @@ -212533,164 +213494,169 @@ msgid "" msgstr "é˜²č­·å€¼ęœƒå› ęå‚·č€Œęø›å°‘ļ¼Œä½ åÆ仄透過äæ®å¾©åŽ»ę”¹å–„怂" #: src/item.cpp -msgid "Covers: " +msgid "Covers:" msgstr "" #: src/item.cpp -msgid "The head. " -msgstr "é ­éƒØ怂" +msgid " The head." +msgstr "" #: src/item.cpp -msgid "The eyes. " -msgstr "ēœ¼ē›ć€‚" +msgid " The eyes." +msgstr "" #: src/item.cpp -msgid "The mouth. " -msgstr "å˜“å·“ć€‚" +msgid " The mouth." +msgstr "" #: src/item.cpp -msgid "The torso. " -msgstr "č»€å¹¹ć€‚" +msgid " The torso." +msgstr "" #: src/item.cpp -msgid "Either arm. " -msgstr "å·¦č‡‚/å³č‡‚ć€‚" +msgid " Either arm." +msgstr "" #: src/item.cpp -msgid "The arms. " -msgstr "ꉋ臂怂" +msgid " The arms." +msgstr "" #: src/item.cpp -msgid "The left arm. " -msgstr "å·¦č‡‚ć€‚" +msgid " The left arm." +msgstr "" #: src/item.cpp -msgid "The right arm. " -msgstr "å³č‡‚ć€‚" +msgid " The right arm." +msgstr "" #: src/item.cpp -msgid "Either hand. " -msgstr "å·¦ę‰‹/å³ę‰‹ć€‚" +msgid " Either hand." +msgstr "" #: src/item.cpp -msgid "The hands. " -msgstr "ꉋꎌ怂" +msgid " The hands." +msgstr "" #: src/item.cpp -msgid "The left hand. " -msgstr "å·¦ę‰‹ć€‚" +msgid " The left hand." +msgstr "" #: src/item.cpp -msgid "The right hand. " -msgstr "å³ę‰‹ć€‚" +msgid " The right hand." +msgstr "" #: src/item.cpp -msgid "Either leg. " -msgstr "å·¦č…æ/右č…æ怂" +msgid " Either leg." +msgstr "" #: src/item.cpp -msgid "The legs. " -msgstr "č…æéƒØ怂" +msgid " The legs." +msgstr "" #: src/item.cpp -msgid "The left leg. " -msgstr "å·¦č…æ怂" +msgid " The left leg." +msgstr "" #: src/item.cpp -msgid "The right leg. " -msgstr "右č…æ怂" +msgid " The right leg." +msgstr "" #: src/item.cpp -msgid "Either foot. " -msgstr "å·¦č…³/å³č…³ć€‚" +msgid " Either foot." +msgstr "" #: src/item.cpp -msgid "The feet. " -msgstr "č…³ęŽŒć€‚" +msgid " The feet." +msgstr "" #: src/item.cpp -msgid "The left foot. " -msgstr "å·¦č…³ć€‚" +msgid " The left foot." +msgstr "" #: src/item.cpp -msgid "The right foot. " -msgstr "å³č…³ć€‚" +msgid " The right foot." +msgstr "" #: src/item.cpp -msgid "Nothing." -msgstr "ę²’ęœ‰ć€‚" +msgid " Nothing." +msgstr "" #: src/item.cpp -msgid "Layer: " -msgstr "č”£ē‰©å±¤ē“š: " +msgid "Layer:" +msgstr "" #: src/item.cpp -msgid "Personal aura. " -msgstr "č‡Ŗčŗ«éˆę°£å±¤ć€‚" +msgid " Personal aura." +msgstr "" #: src/item.cpp -msgid "Close to skin. " -msgstr "č²¼čŗ«ć€‚" +msgid " Close to skin." +msgstr "" #: src/item.cpp -msgid "Strapped. " -msgstr "ē¹«ēµć€‚" +msgid " Strapped." +msgstr "" #: src/item.cpp -msgid "Outer. " -msgstr "å¤–å±¤ć€‚" +msgid " Outer." +msgstr "" #: src/item.cpp -msgid "Waist. " -msgstr "腰éƒØ怂" +msgid " Waist." +msgstr "" #: src/item.cpp -msgid "Outer aura. " -msgstr "外éƒØéˆę°£å±¤ć€‚" +msgid " Outer aura." +msgstr "" #: src/item.cpp -msgid "Normal. " -msgstr "äø€čˆ¬ć€‚" +msgid " Normal." +msgstr "" #: src/item.cpp -msgid "Coverage: " -msgstr "覆蓋ēŽ‡: " +msgid "Average Coverage: " +msgstr "" #: src/item.cpp msgid "Warmth: " msgstr "äæęš–åŗ¦: " #: src/item.cpp -msgid " (fits)" -msgstr " (合čŗ«)" +msgid " (fits)" +msgstr "" #: src/item.cpp -msgid " (poor fit)" -msgstr " (äøåˆčŗ«)" +msgid " (poor fit)" +msgstr "" #: src/item.cpp -msgid " (too big)" -msgstr " ļ¼ˆå¤Ŗ大ļ¼‰" +msgid " (too big)" +msgstr "" #: src/item.cpp -msgid " (huge!)" -msgstr " ļ¼ˆę„µå¤§ļ¼ļ¼‰" +msgid " (huge!)" +msgstr "" #: src/item.cpp -msgid " (too small)" -msgstr " ļ¼ˆå¤Ŗ小ļ¼‰" +msgid " (too small)" +msgstr "" #: src/item.cpp -msgid " (tiny!)" +msgid " (tiny!)" msgstr "" #: src/item.cpp -msgid "Encumbrance: " -msgstr "ē“Æč“…: " +msgid "Encumbrance:" +msgstr "" #: src/item.cpp -msgid "Encumbrance when full: " -msgstr "č£ę»æꙂēš„ē“Æč“…: " +#, c-format +msgid "%s:" +msgstr "" + +#: src/item.cpp +msgid "When Full:" +msgstr "" #: src/item.cpp msgid "Weight capacity modifier: " @@ -213072,23 +214038,23 @@ msgid "Power Capacity:" msgstr "" #: src/item.cpp -msgid "Environmental Protection: " -msgstr "ē’°å¢ƒå‚·å®³é˜²č­·ļ¼š" +msgid "Environmental Protection:" +msgstr "" #: src/item.cpp -msgid "Bash Protection: " +msgid "Bash Protection:" msgstr "" #: src/item.cpp -msgid "Cut Protection: " +msgid "Cut Protection:" msgstr "" #: src/item.cpp -msgid "Ballistic Protection: " +msgid "Ballistic Protection:" msgstr "" #: src/item.cpp -msgid "Stat Bonus: " +msgid "Stat Bonus:" msgstr "" #: src/item.cpp @@ -215150,10 +216116,6 @@ msgstr "從å“Ŗé‚ŠęŠ½å–?" msgid "There is nothing to siphon nearby." msgstr "" -#: src/iuse.cpp -msgid "There's no vehicle there." -msgstr "é‚£č£”ę²’ęœ‰č»Šč¼›" - #: src/iuse.cpp msgid "With a snarl, the combat chainsaw screams to life!" msgstr "éšØ著äø€é™£å’†å“®, ęˆ°é¬„éˆé‹ø啟動äŗ†!" @@ -218170,6 +219132,10 @@ msgstr "ē—›ēš„č¦å‘½!" msgid "It itches a little." msgstr "ęœ‰é»žē™¢ć€‚" +#: src/iuse_actor.cpp +msgid "Bleeding has not stopped completely!" +msgstr "" + #: src/iuse_actor.cpp msgid "You cannot cauterize while mounted." msgstr "éØŽä¹˜ę™‚äøčƒ½ē¼ē‡’å‚·å£ć€‚" @@ -218493,12 +219459,22 @@ msgid "You stop the bleeding." msgstr "ä½ ę­¢č”€äŗ†ć€‚" #: src/iuse_actor.cpp -msgid "The wound still bleeds." -msgstr "傷口仍åœØ굁蔀怂" +msgid "You reduce the bleeding, but it's not stopped yet." +msgstr "" #: src/iuse_actor.cpp -msgid "You fail to stop the bleeding." -msgstr "ä½ ē„”ę³•ę­¢č”€ć€‚" +msgid "The bleeding is reduced, but not stopped." +msgstr "" + +#: src/iuse_actor.cpp +msgid "" +"Your dressing is too ineffective for a bleeding of this extent, and you fail" +" to stop it." +msgstr "" + +#: src/iuse_actor.cpp +msgid "The wound still bleeds." +msgstr "傷口仍åœØ굁蔀怂" #: src/iuse_actor.cpp msgid "The wound is cleaned." @@ -218601,12 +219577,16 @@ msgid "Actual disinfecting quality: " msgstr "" #: src/iuse_actor.cpp -msgid "Chance to heal (percent): " +msgid "Effect on bleeding: " +msgstr "" + +#: src/iuse_actor.cpp +msgid "Actual effect on bleeding: " msgstr "" #: src/iuse_actor.cpp -msgid "* Bleeding: " -msgstr "* 굁蔀:" +msgid "Chance to heal (percent): " +msgstr "" #: src/iuse_actor.cpp msgid "* Bite: " @@ -218672,8 +219652,8 @@ msgid "It's not a gun." msgstr "這äøę˜Æ꧍怂" #: src/iuse_actor.cpp -msgid "The barrel is too short." -msgstr "這꧍ē®”å¤ŖēŸ­äŗ†ć€‚" +msgid "The barrel is too small." +msgstr "" #: src/iuse_actor.cpp msgid "The barrel is already sawn-off." @@ -220174,10 +221154,6 @@ msgstr "ę³•åŠ›å€¼" msgid "stamina" msgstr "č€åŠ›å€¼" -#: src/magic.cpp -msgid "bionic power" -msgstr "ē”ŸåŒ–čƒ½é‡" - #: src/magic.cpp msgid "error: energy_type" msgstr "éŒÆčŖ¤ļ¼ščƒ½é‡é”žåˆ„" @@ -222196,7 +223172,7 @@ msgstr "ä½ ē”Øē›”å…Ø力ē ø꓊ %s, ä½æ得他ēš„ %s ꎉåœØ附čæ‘äŗ†!" msgid "You smash %s with all your might but %s remains in their hands!" msgstr "ä½ ē”Øē›”å…Ø力ē ø꓊ %s, 但 %s 仍åœØ他ēš„ꉋäøŠ!" -#: src/melee.cpp src/npctalk.cpp +#: src/melee.cpp src/talker_npc.cpp #, c-format msgid "%s is hostile!" msgstr "%s čˆ‡ä½ ę•µå°!" @@ -223028,6 +224004,36 @@ msgctxt "memorial_female" msgid "Died of a drug overdose." msgstr "ę­»ę–¼ē”Øč—„éŽé‡ć€‚" +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Bled to death." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died of hypovolemic shock." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_male" +msgid "Died from loss of red blood cells." +msgstr "" + +#: src/memorial_logger.cpp +msgctxt "memorial_female" +msgid "Died from loss of red blood cells." +msgstr "" + #: src/memorial_logger.cpp msgctxt "memorial_male" msgid "Succumbed to the infection." @@ -227049,10 +228055,6 @@ msgctxt "Paralyze as an action" msgid "paralyze" msgstr "éŗ»ē—ŗ" -#: src/monster.cpp -msgid "cause bleed" -msgstr "é€ ęˆęµč”€" - #: src/monster.cpp msgid "It has a head." msgstr "å®ƒęœ‰é ­ć€‚" @@ -228108,6 +229110,15 @@ msgstr "" msgid "%s (activated)" msgstr "" +#: src/newcharacter.cpp +msgid "Profession proficiencies:" +msgstr "" + +#: src/newcharacter.cpp +msgctxt "Profession has no proficiencies" +msgid "None" +msgstr "ē„”" + #: src/newcharacter.cpp msgid "Pets:" msgstr "åƵē‰©ļ¼š" @@ -228359,8 +229370,12 @@ msgid "" msgstr "" #: src/newcharacter.cpp -msgid "_______NO NAME ENTERED!_______" -msgstr "________ ę²’ęœ‰č¼ø兄名字! ________" +msgid "--- NO NAME ENTERED ---" +msgstr "" + +#: src/newcharacter.cpp +msgid "--- RANDOM NAME ---" +msgstr "" #: src/newcharacter.cpp #, c-format @@ -228440,15 +229455,19 @@ msgid "Enter height in centimeters. Minimum 145, maximum 200" msgstr "" #: src/newcharacter.cpp -msgid "Enter blood type (omit Rh):" +msgid "Select blood type" +msgstr "" + +#: src/newcharacter.cpp +msgid "Select Rh factor" msgstr "" #: src/newcharacter.cpp -msgid "Invalid blood type." +msgid "negative" msgstr "" #: src/newcharacter.cpp -msgid "Enter Rh factor:" +msgid "positive" msgstr "" #: src/newcharacter.cpp @@ -228829,6 +229848,25 @@ msgstr " 冷靜äø‹ä¾†äŗ†ć€‚" msgid " is no longer afraid." msgstr " äøå†č†½ę€Æäŗ†ć€‚" +#: src/npc.cpp +#, c-format +msgid "I'm holing up here for safety. Long term, %s" +msgstr "ꈑåœØé€™č£”ē¶­č­·å®‰å…Øć€‚é•·ęœŸä¾†ēœ‹ļ¼Œ%s" + +#: src/npc.cpp +msgid "I run the shop here." +msgstr "ꈑåœØé€™č£”ē¶“ē‡Ÿå•†åŗ—怂" + +#: src/npc.cpp +#, c-format +msgid "Currently, I'm guarding this location. Overall, %s" +msgstr "ē›®å‰ļ¼Œęˆ‘ę­£åœØå®ˆč”›é€™å€‹åœ°é»žć€‚ēø½é«”č€Œč؀ļ¼Œ%s" + +#: src/npc.cpp +#, c-format +msgid "Right now, I'm . In general, %s" +msgstr "ē¾åœØļ¼Œęˆ‘ę­£åœØ 怂äø€čˆ¬ä¾†čŖŖļ¼Œ%s" + #: src/npcmove.cpp msgid "" msgstr "" @@ -228979,6 +230017,15 @@ msgstr "" msgid "My %s is bleeding!" msgstr "ꈑēš„ %s ę­£åœØ굁蔀!" +#: src/npcmove.cpp +#, c-format +msgid "My %s is bleeding badly!" +msgstr "" + +#: src/npcmove.cpp +msgid "I've lost lot of blood." +msgstr "" + #: src/npcmove.cpp #, c-format msgid "%1$s reloads their %2$s." @@ -229225,11 +230272,6 @@ msgstr "你大喊 %s" msgid "%s yelling %s" msgstr "%s大喊%s" -#: src/npctalk.cpp -#, c-format -msgid "%s is fleeing from you!" -msgstr "%s ę­£åœØ逃離你!" - #: src/npctalk.cpp #, c-format msgid "%s talked to you." @@ -229287,36 +230329,6 @@ msgstr "ꊱꭉ, ēœ‹ä¾†ęˆ‘ę²’ęœ‰ä»€éŗ¼čƒ½ę•™ä½ ēš„äŗ†ć€‚" msgid "Here's what I can teach youā€¦" msgstr "這äŗ›ę˜Æęˆ‘čƒ½ę•™ä½ ēš„ā€¦" -#: src/npctalk.cpp -#, c-format -msgid "%d.%d miles." -msgstr "%d.%d č‹±é‡Œć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "%d foot." -msgid_plural "%d feet." -msgstr[0] "%d å‘Žć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "I'm holing up here for safety. Long term, %s" -msgstr "ꈑåœØé€™č£”ē¶­č­·å®‰å…Øć€‚é•·ęœŸä¾†ēœ‹ļ¼Œ%s" - -#: src/npctalk.cpp -msgid "I run the shop here." -msgstr "ꈑåœØé€™č£”ē¶“ē‡Ÿå•†åŗ—怂" - -#: src/npctalk.cpp -#, c-format -msgid "Currently, I'm guarding this location. Overall, %s" -msgstr "ē›®å‰ļ¼Œęˆ‘ę­£åœØå®ˆč”›é€™å€‹åœ°é»žć€‚ēø½é«”č€Œč؀ļ¼Œ%s" - -#: src/npctalk.cpp -#, c-format -msgid "Right now, I'm . In general, %s" -msgstr "ē¾åœØļ¼Œęˆ‘ę­£åœØ 怂äø€čˆ¬ä¾†čŖŖļ¼Œ%s" - #: src/npctalk.cpp msgid "&You yell, but can't hear yourself." msgstr "&ä½ ę”¾č²å¤§å–Š, 但ę˜Æä½ č½äøč¦‹ä½ č‡Ŗå·±ēš„č²éŸ³ć€‚" @@ -229325,74 +230337,6 @@ msgstr "&ä½ ę”¾č²å¤§å–Š, 但ę˜Æä½ č½äøč¦‹ä½ č‡Ŗå·±ēš„č²éŸ³ć€‚" msgid "&You yell." msgstr "&ä½ ę”¾č²å¤§å–Šć€‚" -#: src/npctalk.cpp -msgid "&You can't make anything out." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "Str %d - %d" -msgstr "力量 %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Dex %d - %d" -msgstr "ę•ę· %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Int %d - %d" -msgstr "ę™ŗ力 %d - %d" - -#: src/npctalk.cpp -#, c-format -msgid " Per %d - %d" -msgstr "ꄟēŸ„ %d - %d" - -#: src/npctalk.cpp -msgid "Dead tired" -msgstr "ē“Æå¾—åŠę­»" - -#: src/npctalk.cpp -msgid "Not tired" -msgstr "äøē“Æ" - -#: src/npctalk.cpp -msgid ". Will need sleep in " -msgstr "怂 äæęŒęø…醒ēš„Ꙃ間 " - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need water in " -msgstr "" -"\n" -"äæęŒę°“åˆ†å……č¶³ēš„Ꙃ間" - -#: src/npctalk.cpp -msgid "" -"\n" -"Thirsty" -msgstr "" -"\n" -"口ęø“" - -#: src/npctalk.cpp -msgid "" -"\n" -"Will need food in " -msgstr "" -"\n" -"äæęŒé£½č…¹ē‹€ę…‹ēš„Ꙃ間" - -#: src/npctalk.cpp -msgid "" -"\n" -"Hungry" -msgstr "" -"\n" -"飢餓" - #: src/npctalk.cpp msgid "YES, MASTER!" msgstr "ę˜Æēš„, äø»äŗŗ!" @@ -229406,34 +230350,6 @@ msgstr "ęˆ‘ęœ‰ę–°ę¶ˆęÆ怂" msgid "Yes, let's resume training %s" msgstr "" -#: src/npctalk.cpp -#, c-format -msgid "%s: 1 hour lesson (cost %s)" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "%s: teaching spell knowledge (cost %s)" -msgstr "" - -#. ~Martial art style (cost in dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s ( cost $%d )" -msgstr "%s (čŠ±č²» $%d)" - -#. ~Skill name: current level (exercise) -> next level (exercise) (cost in -#. dollars) -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" -msgstr "%sļ¼š%dļ¼ˆ%d %%ļ¼‰ -> %dļ¼ˆ%d %%ļ¼‰ļ¼ˆčŠ±č²» $%dļ¼‰" - -#: src/npctalk.cpp -#, c-format -msgid "%s: %d (%d%%) -> %d (%d%%)" -msgstr "%sļ¼š%dļ¼ˆ%d%%ļ¼‰-> %dļ¼ˆ%d%%ļ¼‰" - #: src/npctalk.cpp msgid "Okay, thanks." msgstr "儽啦, č¬äŗ†ć€‚" @@ -229446,10 +230362,6 @@ msgstr "ęˆ‘å€‘ē¹¼ēŗŒč”Œå‹•å§ć€‚" msgid "OBEY ME!" msgstr "é †å¾žęˆ‘!" -#: src/npctalk.cpp src/player.cpp -msgid "fists" -msgstr "ę‹³é ­" - #: src/npctalk.cpp msgid "BADAMMO" msgstr "協彈" @@ -229521,7 +230433,7 @@ msgctxt "you say something" msgid "You: %s" msgstr "ä½ : %s" -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp msgid "You can't afford it!" msgstr "ä½ č² ę“”äøčµ·ļ¼" @@ -229532,7 +230444,7 @@ msgid "%1$s gives you a %2$s." msgstr "%1$s ēµ¦äŗ†ä½  %2$s 怂" #. ~ %1%s is the NPC name, %2$d is a number of items, %3$s are items -#: src/npctalk.cpp +#: src/npctalk.cpp src/talker_avatar.cpp #, c-format msgid "%1$s gives you %2$d %3$s." msgstr "%1$s ēµ¦ä½  %2$d 個 %3$s怂" @@ -229561,97 +230473,11 @@ msgstr "ä½ ēµ¦ %1$s %2$d 個 %3$s怂" msgid "%1$s doesn't have a %2$s!" msgstr "%1$s äø¦ę²’ęœ‰ %2$sļ¼" -#: src/npctalk.cpp -#, c-format -msgid "%1$s gives you %2$s." -msgstr "%1$s ēµ¦ä½  %2$s怂" - #: src/npctalk.cpp #, c-format msgid "You learn how to craft %s." msgstr "ä½ å­øęœƒå¦‚ä½•č£½ä½œ %s怂" -#: src/npctalk.cpp -msgid "I don't trust you enough to eat THISā€¦" -msgstr "ęˆ‘é‚„ę²’ ē›øäæ”ä½ åˆ°č¦åƒé‚£å€‹ę±č„æ..." - -#: src/npctalk.cpp -msgid "It doesn't look like a good idea to consume thisā€¦" -msgstr "吃äø‹å®ƒäø¦äøę˜Æ個儽äø»ę„..." - -#: src/npctalk.cpp -msgid "Thanks, that hit the spot." -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "I need a %s to consume that!" -msgstr "ęˆ‘éœ€č¦ %s ę‰čƒ½é£Ÿē”Ø它!" - -#: src/npctalk.cpp -msgid "Thanks, I feel better already." -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I used it." -msgstr "" - -#: src/npctalk.cpp -msgid "Offer what?" -msgstr "čƒ½ęä¾›å“Ŗäŗ›?" - -#: src/npctalk.cpp -msgid "You have no items to offer." -msgstr "ä½ ę²’ęœ‰åÆä»„ęä¾›ēš„ę±č„æ怂" - -#: src/npctalk.cpp -msgid "Changed your mind?" -msgstr "ę”¹č®Šåæƒę„äŗ†å—Ž?" - -#: src/npctalk.cpp -msgid "How?" -msgstr "ꀎęØ£?" - -#: src/npctalk.cpp -msgid "Are you insane!?" -msgstr "ä½ ē˜‹äŗ†å—Ž!?" - -#: src/npctalk.cpp -msgid "Thanks, I'll wield that now." -msgstr "" - -#: src/npctalk.cpp -msgid " Should I take something off?" -msgstr "" - -#: src/npctalk.cpp -#, c-format -msgid "" -"My current weapon is better than this.\n" -"(new weapon value: %.1f vs %.1f)." -msgstr "" - -#: src/npctalk.cpp -msgid "Thanks, I'll carry that now." -msgstr "" - -#: src/npctalk.cpp -msgid "I have no space to store it." -msgstr "ęˆ‘ę²’ęœ‰ē©ŗé–“åŽ»å­˜ę”¾å®ƒäŗ†ć€‚" - -#: src/npctalk.cpp -#, c-format -msgid "I can only store %s %s more." -msgstr "ꈑåŖčƒ½å†č£ %s %s怂" - -#: src/npctalk.cpp -msgid "ā€¦or to store anything else for that matter." -msgstr "...ꈖē‚ŗę­¤å„²å­˜å„ēخ其他ē‰©å“ć€‚" - -#: src/npctalk.cpp -msgid "It is too heavy for me to carry." -msgstr "é€™ę±č„æå°ęˆ‘ä¾†čŖŖå¤Ŗ重äŗ†ć€‚" - #: src/npctalk_funcs.cpp msgid "Reward" msgstr "ēŽč³ž" @@ -231415,12 +232241,15 @@ msgid "A scaling factor that determines density of item spawns." msgstr "čح定ē‰©å“ē”¢ē”Ÿēš„åƆåŗ¦ć€‚" #: src/options.cpp -msgid "NPC spawn rate scaling factor" -msgstr "NPC ē”¢ē”ŸęƔēŽ‡" +msgid "Random NPC spawn time" +msgstr "" #: src/options.cpp -msgid "A scaling factor that determines density of dynamic NPC spawns." -msgstr "čØ­å®šå‹•ę…‹ NPC ē”¢ē”Ÿēš„åƆåŗ¦ć€‚" +msgid "" +"Baseline average number of days between random NPC spawns. Average duration" +" goes up with the number of NPCs already spawned. Set to 0 days to disable " +"random NPCs." +msgstr "" #: src/options.cpp msgid "Monster evolution scaling factor" @@ -231542,37 +232371,6 @@ msgid "" "If true, spawn zombies at shelters. Makes the starting game a lot harder." msgstr "čح定ē‚ŗ [ę˜Æ], ꜃åœØéæé›£ę‰€å…§ē”¢ē”Ÿę®­å±ć€‚č®“éŠęˆ²åˆå§‹éšŽę®µēš„難åŗ¦å¤§å¢žć€‚" -#: src/options.cpp -msgid "Static NPCs" -msgstr "靜ꅋ NPC" - -#: src/options.cpp -msgid "" -"If true, static NPCs will spawn at pre-defined locations. Requires world " -"reset." -msgstr "čح定ē‚ŗ [ę˜Æ] ļ¼Œéœę…‹ NPC ꜃åœØ預先定ē¾©ēš„地點ē”Ÿęˆć€‚åæ…須重ē½®äø–ē•Œę‰ęœƒē”Ÿę•ˆć€‚" - -#: src/options.cpp -msgid "Starting NPCs spawn" -msgstr "初始 NPC ē”¢ē”Ÿę–¹å¼" - -#: src/options.cpp -msgid "" -"Determines whether starting NPCs should spawn, and if they do, how exactly." -msgstr "čح定ę˜Æ否ē”¢ē”Ÿåˆå§‹ NPC, 仄及具體如何ē”¢ē”Ÿć€‚" - -#: src/options.cpp -msgid "Scenario-based" -msgstr "åŸŗę–¼åŠ‡ęƒ…" - -#: src/options.cpp -msgid "Random NPCs" -msgstr "éšØę©Ÿē”¢ē”Ÿ NPC" - -#: src/options.cpp -msgid "If true, the game will randomly spawn NPCs during gameplay." -msgstr "čح定ē‚ŗ [ę˜Æ], éŠęˆ²ęœƒåœØé€²č”Œę™‚éšØę©Ÿē”¢ē”Ÿ NPC怂" - #: src/options.cpp msgid "Mutations by radiation" msgstr "å—č¼»å°„å½±éŸæēŖč®Š" @@ -233236,6 +234034,38 @@ msgstr "ä½ ęˆåŠŸę’²ę»…čŗ«äøŠēš„ē«ē‚Ž!" msgid " attempts to put out the fire on them!" msgstr " å˜—č©¦ę’²ę»…ä»–čŗ«äøŠēš„ē«ē‚Ž!" +#: src/player.cpp +msgid "" +"Your broken limb significantly hampers your efforts to puting pressure on " +"the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s broken limb significantly hampers efforts of putting pressure on" +" the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"Your hands are too encumbred to effectivly put pressure on the bleeding " +"wound!" +msgstr "" + +#: src/player.cpp +msgid "" +"'s hands are too encumbred to effectivly put pressure on the " +"bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid "You attempt to put pressure on the bleeding wound!" +msgstr "" + +#: src/player.cpp +msgid " attempts to put pressure on the bleeding wound!" +msgstr "" + #: src/player.cpp #, c-format msgid "Your ground sonar detected a %1$s to the %2$s!" @@ -233507,33 +234337,6 @@ msgstr "ę²’ęœ‰ę±č„æč¦é‡ę–°č£å”«!" msgid "You don't have any %s to reload your %s!" msgstr "ä½ ę²’ęœ‰ %s ä¾†č£å”«ä½ ēš„ %s!" -#: src/player.cpp -msgid "Can't wield spilt liquids." -msgstr "äøčƒ½ę®ē‘ęŗ¢å‡ŗēš„ę¶²é«”ć€‚" - -#: src/player.cpp -msgid "You need at least one arm to even consider wielding something." -msgstr "ä½ éœ€č¦č‡³å°‘äø€éš»ę‰‹ę‰čƒ½ęŒę”ę±č„æ怂" - -#: src/player.cpp -#, c-format -msgid "The %s is preventing you from wielding the %s." -msgstr "" - -#: src/player.cpp -msgid "Something you are wearing hinders the use of both hands." -msgstr "ä½ ē©æꈓēš„ę±č„æ阻ē¤™äŗ†ä½æē”Ø雙ꉋ怂" - -#: src/player.cpp -#, c-format -msgid "The %s can't be wielded with only one arm." -msgstr "ä½ åƒ…ęœ‰ēš„äø€ę”Æꉋę‹æäøäŗ† %s怂" - -#: src/player.cpp -#, c-format -msgid "You are too weak to wield %s with only one arm." -msgstr "ä½ åƒ…ęœ‰ēš„äø€ę”Æę‰‹åŠ›é‡äøč¶³, ę‹æäøäŗ† %s怂" - #: src/player.cpp msgid "Keep hands free (off)" msgstr "äæęŒē©ŗꉋ (關閉)" @@ -233713,15 +234516,6 @@ msgstr "ä½ ēš„ %s ę²’ęœ‰é›»ć€‚" msgid "Your %s isn't loaded." msgstr "ä½ ēš„ %s ę²’ęœ‰č£å”«ć€‚" -#: src/player.cpp -#, c-format -msgid "You recover %i unused plutonium." -msgstr "ä½ å›žę”¶ %i ęœŖä½æē”Ø過ēš„éˆ½ć€‚" - -#: src/player.cpp -msgid "You can't remove partially depleted plutonium!" -msgstr "ä½ äøčƒ½ē§»é™¤č€—ē”Ø到äø€åŠēš„鈽!" - #. ~ %1$s - gunmod, %2$s - gun. #: src/player.cpp #, c-format @@ -233856,25 +234650,6 @@ msgstr "ä½ ēš„助ēœ čŖ˜å°Žę’件ē”Øå…‰čƒ½é‡äŗ†ļ¼" msgid "Your soporific inducer starts back up." msgstr "ä½ ēš„助ēœ čŖ˜å°Žę’ä»¶é–‹å§‹åŠ å¼·ć€‚" -#: src/player.cpp -#, c-format -msgid "Your skill in %s has increased to %d!" -msgstr "ä½ ēš„ %s ęŠ€čƒ½äøŠå‡åˆ° %d!" - -#: src/player.cpp -#, c-format -msgid "You feel that %s tasks of this level are becoming trivial." -msgstr "ä½ č¦ŗ得åœØ這個ē­‰ē“šēš„ %s å·„ä½œč®Šå¾—ę²’ęŒ‘ęˆ°ę€§äŗ†ć€‚" - -#: src/player.cpp -#, c-format -msgid "This task is too simple to train your %s beyond %d." -msgstr "這äŗ‹ęƒ…å¤Ŗē°”å–®č€Œē„”ę³•č®“ä½ čؓē·“ %s 超過 %d怂" - -#: src/player.cpp -msgid " (empty)" -msgstr "" - #: src/player.cpp msgid "Wield what?" msgstr "ę‰‹ęŒä»€éŗ¼?" @@ -233930,6 +234705,10 @@ msgstr "ꕈꞜ" msgid "SPEED" msgstr "速åŗ¦" +#: src/player_display.cpp +msgid "PROFICIENCIES" +msgstr "" + #: src/player_display.cpp #, c-format msgid "Swimming movement point cost: %+d\n" @@ -234773,6 +235552,149 @@ msgid "" "nebulae and you are no more." msgstr "ä½ åˆ†č§£ęˆäŗ†ē¾Žéŗ—ēš„é™£é™£čƒ½é‡ć€‚ä½ ēš„ē”Ÿå‘½ę¼øę¼øę¶ˆé€ć€‚" +#: src/player_hardcoded_effects.cpp +msgid "You bleed to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " bleeds to death!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your heart can't keep up the pace and fails!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks pale and you feel anxious and thirsty. Blood loss?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"Your pale skin is sweating, your heart beats fast and you feel restless. " +"Maybe you lost too much blood?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You're unsettlingly white, but your fingetips are bluish. You are agitated " +"and your heart is racing. Your blood loss must be serious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "" +"You are pale as a ghost, dripping wet from the sweat, and sluggish despite " +"your heart racing like a train. You are on a brink of colapse from effects " +"of a bood loss." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and lightheaded." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel tired and you breathe heavily." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are anxcious and cannot collect your thoughts." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You are sweating profusely, but you feel cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You huff and puff. Your breath is rapid and shallow." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You drop to the ground, fighting to keep yourself conscious." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your mind slips away." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You cannot breathe and your body gives out!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid " gasps for air and dies!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your hands feel unusually cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your feet feel unusualy cold." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your skin looks very pale." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel weak. Where has your strength gone?" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel feeble. A gust of wind could make you stumble." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "There is an overwhelming aura of tiredness inside of you." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Rest is what you want. Rest is what you need." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel dizzy and can't coordinate movement of your feet." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your muscles are quivering." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You crave for ice. Dirt under your feet looks tasty too." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your whole mouth is sore, and your tongue is swollen." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel lightheaded. And a migrane follows." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Your legs are restless. Urge to move them is so strong." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You feel like you'd sleep on a rock." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You gasp for air!" +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "Can't breathe. Must rest." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You can't take it any more. Rest first, everything else later." +msgstr "" + +#: src/player_hardcoded_effects.cpp +msgid "You must sit down for a moment. Just a moment." +msgstr "" + #. ~ %s is bodypart name. #: src/player_hardcoded_effects.cpp #, c-format @@ -235379,6 +236301,11 @@ msgstr "%s, 延遲: %i" msgid "Turrets in range: %d/%d" msgstr "" +#: src/recipe.cpp +#, c-format +msgid "Proficiencies Used: %s" +msgstr "" + #: src/recipe.cpp msgid "none" msgstr "ē„”" @@ -236135,6 +237062,14 @@ msgstr " č·Œå€’äŗ†ļ¼" msgid "You fall over!" msgstr "ä½ č·Œå€’äŗ†!" +#: src/suffer.cpp +msgid "Your tourniquet hurts you." +msgstr "" + +#: src/suffer.cpp +msgid " is hurting from the tourniquet." +msgstr "" + #: src/suffer.cpp #, c-format msgid "Your radiation badge changes from %1$s to %2$s!" @@ -236154,6 +237089,208 @@ msgstr "" msgid "You feel the water burning your skin." msgstr "ä½ ę„Ÿč¦ŗåˆ°ę°“åœØē¼å‚·ä½ ēš„ēš®č†šć€‚" +#: src/talker_avatar.cpp +#, c-format +msgid "%s can't sell you any %s" +msgstr "" + +#: src/talker_avatar.cpp +#, c-format +msgid "%1$s gives you %2$s." +msgstr "%1$s ēµ¦ä½  %2$s怂" + +#: src/talker_npc.cpp +#, c-format +msgid "%d.%d miles." +msgstr "%d.%d č‹±é‡Œć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "%d foot." +msgid_plural "%d feet." +msgstr[0] "%d å‘Žć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "%s is fleeing from you!" +msgstr "%s ę­£åœØ逃離你!" + +#. ~Skill name: current level (exercise) -> next level (exercise) (cost in +#. dollars) +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%) (cost $%d)" +msgstr "%sļ¼š%dļ¼ˆ%d %%ļ¼‰ -> %dļ¼ˆ%d %%ļ¼‰ļ¼ˆčŠ±č²» $%dļ¼‰" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: %d (%d%%) -> %d (%d%%)" +msgstr "%sļ¼š%dļ¼ˆ%d%%ļ¼‰-> %dļ¼ˆ%d%%ļ¼‰" + +#: src/talker_npc.cpp +#, c-format +msgid "%s ( cost $%d )" +msgstr "%s (čŠ±č²» $%d)" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: 1 hour lesson (cost %s)" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "%s: teaching spell knowledge (cost %s)" +msgstr "" + +#: src/talker_npc.cpp +msgid "I don't trust you enough to eat THISā€¦" +msgstr "ęˆ‘é‚„ę²’ ē›øäæ”ä½ åˆ°č¦åƒé‚£å€‹ę±č„æ..." + +#: src/talker_npc.cpp +msgid "It doesn't look like a good idea to consume thisā€¦" +msgstr "吃äø‹å®ƒäø¦äøę˜Æ個儽äø»ę„..." + +#: src/talker_npc.cpp +msgid "Thanks, that hit the spot." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "I need a %s to consume that!" +msgstr "ęˆ‘éœ€č¦ %s ę‰čƒ½é£Ÿē”Ø它!" + +#: src/talker_npc.cpp +msgid "Thanks, I feel better already." +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I used it." +msgstr "" + +#: src/talker_npc.cpp +msgid "Offer what?" +msgstr "čƒ½ęä¾›å“Ŗäŗ›?" + +#: src/talker_npc.cpp +msgid "You have no items to offer." +msgstr "ä½ ę²’ęœ‰åÆä»„ęä¾›ēš„ę±č„æ怂" + +#: src/talker_npc.cpp +msgid "Changed your mind?" +msgstr "ę”¹č®Šåæƒę„äŗ†å—Ž?" + +#: src/talker_npc.cpp +msgid "How?" +msgstr "ꀎęØ£?" + +#: src/talker_npc.cpp +msgid "Are you insane!?" +msgstr "ä½ ē˜‹äŗ†å—Ž!?" + +#: src/talker_npc.cpp +msgid "Thanks, I'll wield that now." +msgstr "" + +#: src/talker_npc.cpp +msgid " Should I take something off?" +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "" +"My current weapon is better than this.\n" +"(new weapon value: %.1f vs %.1f)." +msgstr "" + +#: src/talker_npc.cpp +msgid "Thanks, I'll carry that now." +msgstr "" + +#: src/talker_npc.cpp +msgid "I have no space to store it." +msgstr "ęˆ‘ę²’ęœ‰ē©ŗé–“åŽ»å­˜ę”¾å®ƒäŗ†ć€‚" + +#: src/talker_npc.cpp +#, c-format +msgid "I can only store %s %s more." +msgstr "ꈑåŖčƒ½å†č£ %s %s怂" + +#: src/talker_npc.cpp +msgid "ā€¦or to store anything else for that matter." +msgstr "...ꈖē‚ŗę­¤å„²å­˜å„ēخ其他ē‰©å“ć€‚" + +#: src/talker_npc.cpp +msgid "It is too heavy for me to carry." +msgstr "é€™ę±č„æå°ęˆ‘ä¾†čŖŖå¤Ŗ重äŗ†ć€‚" + +#: src/talker_npc.cpp +msgid "&You can't make anything out." +msgstr "" + +#: src/talker_npc.cpp +#, c-format +msgid "Str %d - %d" +msgstr "力量 %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Dex %d - %d" +msgstr "ę•ę· %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Int %d - %d" +msgstr "ę™ŗ力 %d - %d" + +#: src/talker_npc.cpp +#, c-format +msgid " Per %d - %d" +msgstr "ꄟēŸ„ %d - %d" + +#: src/talker_npc.cpp +msgid "Dead tired" +msgstr "ē“Æå¾—åŠę­»" + +#: src/talker_npc.cpp +msgid "Not tired" +msgstr "äøē“Æ" + +#: src/talker_npc.cpp +msgid ". Will need sleep in " +msgstr "怂 äæęŒęø…醒ēš„Ꙃ間 " + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need water in " +msgstr "" +"\n" +"äæęŒę°“åˆ†å……č¶³ēš„Ꙃ間" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Thirsty" +msgstr "" +"\n" +"口ęø“" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Will need food in " +msgstr "" +"\n" +"äæęŒé£½č…¹ē‹€ę…‹ēš„Ꙃ間" + +#: src/talker_npc.cpp +msgid "" +"\n" +"Hungry" +msgstr "" +"\n" +"飢餓" + #: src/teleport.cpp msgid "You feel a strange, inwards force." msgstr "" @@ -237963,6 +239100,34 @@ msgstr ", %3.1f%% / å°ę™‚, %s ē›“到 %s" msgid "pile-up" msgstr "ꮘéŖø堆" +#: src/vehicle_move.cpp +msgid "Smart controller does not support flying vehicles." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller detects only a single controllable engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller is designed to control more than one engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller does not support more than five engines." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller is shutting down." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller failed to start an engine." +msgstr "" + +#: src/vehicle_move.cpp +msgid "Smart controller optimizes engine state." +msgstr "" + #: src/vehicle_move.cpp #, c-format msgid "The %s is too leaky!" @@ -238337,6 +239502,11 @@ msgctxt "electronics menu option" msgid "water purifier" msgstr "ę·Øę°“å™Ø" +#: src/vehicle_use.cpp +msgctxt "electronics menu option" +msgid "smart controller" +msgstr "" + #: src/vehicle_use.cpp msgid "Turn off camera system" msgstr "é—œé–‰ę”å½±ē³»ēµ±" @@ -238960,50 +240130,18 @@ msgstr "電力äøč¶³ä»„ę·Ø化 %1$s äø­ēš„ %2$s" msgid "You purify the contents of the %1$s's %2$s" msgstr "ä½ ę·Ø化äŗ† %1$s äø­ēš„ %2$s" -#: src/weather.cpp -msgid "You hear a distant rumble of thunder." -msgstr "ę‚Øč½č¦‹é č™•éš†éš†ēš„é›·č²ć€‚" - -#: src/weather.cpp -msgid "You hear a rumble of thunder from above." -msgstr "ę‚Øč½č¦‹å¤©äøŠéš†éš†ēš„é›·č²ć€‚" - -#: src/weather.cpp -msgid "A flash of lightning illuminates your surroundings!" -msgstr "äø€é“閃電ē…§äŗ®ä½ ēš„å‘Ø圍!" - #: src/weather.cpp #, c-format -msgid "Your %s protects you from the acidic drizzle." -msgstr "ä½ ēš„ %s é˜²č­·äŗ†é…øé›Øēš„傷害!" - -#: src/weather.cpp -msgid "Your clothing protects you from the acidic drizzle." -msgstr "ä½ ēš„č”£ē‰©äæč­·äŗ†ä½ äøč¢«é…øé›Øå‚·å®³ć€‚" - -#: src/weather.cpp -msgid "Your power armor protects you from the acidic drizzle." -msgstr "ä½ ēš„å‹•åŠ›č£ē”²äæč­·äŗ†ä½ äøå—é…øé›Øå‚·å®³ć€‚" - -#: src/weather.cpp -msgid "The acid rain stings, but is mostly harmless for nowā€¦" -msgstr "é…øé›Øåˆŗē—›äŗ†ä½ ēš„ēš®č†šļ¼Œ 但ē›®å‰é‚„ę²’ęœ‰ä»€éŗ¼å½±éŸæā€¦" - -#: src/weather.cpp -msgid "Your umbrella protects you from the acid rain." -msgstr "ä½ ēš„é›Ø傘äæč­·äŗ†ä½ äøč¢«é…øé›Øå‚·å®³ć€‚" - -#: src/weather.cpp -msgid "Your clothing protects you from the acid rain." -msgstr "ä½ ēš„č”£ē‰©äæč­·äŗ†ä½ äøč¢«é…øé›Øå‚·å®³ć€‚" +msgid "Your %s protects you from the weather." +msgstr "" #: src/weather.cpp -msgid "Your power armor protects you from the acid rain." -msgstr "ä½ ēš„å‹•åŠ›č£ē”²äæč­·äŗ†ä½ äøå—é…øé›Øå‚·å®³ć€‚" +msgid "Your clothing protects you from the weather." +msgstr "" #: src/weather.cpp -msgid "The acid rain burns!" -msgstr "é…øé›Øē¼å‚·äŗ†ä½ !" +msgid "Your power armor protects you from the weather." +msgstr "" #: src/weather.cpp msgid "Monday" @@ -239178,54 +240316,6 @@ msgstr "颶é¢Ø" msgid "The weather changed to %s!" msgstr "å¤©ę°£č½‰č®Šē‚ŗ %s!" -#: src/weather_data.cpp -msgid "Clear" -msgstr "ę™“ęœ—" - -#: src/weather_data.cpp -msgid "Sunny" -msgstr "č±”é™½" - -#: src/weather_data.cpp -msgid "Cloudy" -msgstr "多雲" - -#: src/weather_data.cpp -msgid "Light Drizzle" -msgstr "ęƛęƛē“°é›Ø" - -#: src/weather_data.cpp -msgid "Drizzle" -msgstr "ē“°é›Ø" - -#: src/weather_data.cpp -msgid "Rain" -msgstr "äø‹é›Ø" - -#: src/weather_data.cpp -msgid "Thunder Storm" -msgstr "雷é›Ø" - -#: src/weather_data.cpp -msgid "Acidic Drizzle" -msgstr "é…øꀧē“°é›Ø" - -#: src/weather_data.cpp -msgid "Acid Rain" -msgstr "é…øé›Ø" - -#: src/weather_data.cpp -msgid "Flurries" -msgstr "小é›Ŗ" - -#: src/weather_data.cpp -msgid "Snowing" -msgstr "äø‹é›Ŗ" - -#: src/weather_data.cpp -msgid "Snowstorm" -msgstr "ęš“é¢Øé›Ŗ" - #: src/wish.cpp msgid "Nonvalid" msgstr "ē„”ꕈēš„" @@ -239416,6 +240506,19 @@ msgstr "éø꓇äø€å€‹č¦é€²å…„éŠęˆ²ēš„äø–ē•Œć€‚" msgid "last world info" msgstr "äøŠę¬”ēš„äø–ē•Œēš„č³‡č؊" +#: src/worldfactory.cpp +msgid "MISSING MODS" +msgstr "" + +#: src/worldfactory.cpp +msgid "OBSOLETE MODS" +msgstr "" + +#: src/worldfactory.cpp +#, c-format +msgid " [%s]" +msgstr "" + #: src/worldfactory.cpp msgid " ACTIVE WORLD MODS " msgstr " 啟ē”Øäø­ēš„ęØ”ēµ„ " From 249a2be7ecc616bdec2159c553625b47bee6b3ec Mon Sep 17 00:00:00 2001 From: DialoMalison Date: Fri, 17 Jul 2020 13:01:22 -0400 Subject: [PATCH 097/151] Correct test tube volume --- data/json/items/containers.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/items/containers.json b/data/json/items/containers.json index ea20682ce26fc..f9c3e85980598 100644 --- a/data/json/items/containers.json +++ b/data/json/items/containers.json @@ -900,7 +900,7 @@ "looks_like": "flask_glass", "description": "A 10ml laboratory cylindrical test tube, with a rubber stopper.", "weight": "36 g", - "volume": "92 ml", + "volume": "13 ml", "longest_side": "100 mm", "price": 300, "price_postapoc": 10, From 792f0562c6a9be66e45f8dd28f0c4111182e6733 Mon Sep 17 00:00:00 2001 From: DialoMalison Date: Fri, 17 Jul 2020 13:21:49 -0400 Subject: [PATCH 098/151] more volume fixes --- data/json/items/containers.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data/json/items/containers.json b/data/json/items/containers.json index f9c3e85980598..ece91d098b736 100644 --- a/data/json/items/containers.json +++ b/data/json/items/containers.json @@ -256,11 +256,11 @@ "looks_like": "bottle_plastic", "description": "A resealable glass bottle, holds 750 ml of liquid.", "weight": "450 g", - "volume": "1734 ml", + "volume": "1318 ml", "longest_side": "276 mm", "price": 0, "price_postapoc": 10, - "to_hit": 1, + "to_hit": 1,Fglass "bashing": 2, "material": [ "glass" ], "ascii_picture": "glass_bottle", @@ -872,7 +872,7 @@ "looks_like": "bottle_glass", "description": "A 250 ml laboratory conical flask, with a rubber bung.", "weight": "48 g", - "volume": "700 ml", + "volume": "360 ml", "longest_side": "132 mm", "price": 400, "price_postapoc": 10, @@ -928,7 +928,7 @@ "looks_like": "flask_glass", "description": "A 250ml laboratory beaker. Basically a cup with delusions of grandeur.", "weight": "150 g", - "volume": "383 ml", + "volume": "141 ml", "longest_side": "72 mm", "price": 500, "price_postapoc": 10, @@ -956,7 +956,7 @@ "looks_like": "flask_glass", "description": "A tall, narrow glass cylinder with precise markings for measuring fluid quantities. An important science tool, it is also useful for anal retentive chefs.", "weight": "150 g", - "volume": "528 ml", + "volume": "177 ml", "longest_side": "25 cm", "price": 500, "price_postapoc": 10, @@ -1041,7 +1041,7 @@ "looks_like": "jar_glass", "description": "A three-liter glass jar with a metal screw top lid, used for canning.", "weight": "365 g", - "volume": "3352 ml", + "volume": "3852 ml", "longest_side": "298 mm", "price": 0, "price_postapoc": 10, @@ -1088,7 +1088,7 @@ "looks_like": "jar_glass", "description": "A half-liter glass jar with a metal screw top lid, used for canning.", "weight": "150 g", - "volume": "704 ml", + "volume": "680 ml", "longest_side": "132 mm", "price": 0, "bashing": 4, From 30f92e9926886347e014afc4bd9c5561eb5f0b8e Mon Sep 17 00:00:00 2001 From: DialoMalison Date: Fri, 17 Jul 2020 13:26:16 -0400 Subject: [PATCH 099/151] Typo fix --- data/json/items/containers.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/items/containers.json b/data/json/items/containers.json index ece91d098b736..9eb516d2ecf68 100644 --- a/data/json/items/containers.json +++ b/data/json/items/containers.json @@ -260,7 +260,7 @@ "longest_side": "276 mm", "price": 0, "price_postapoc": 10, - "to_hit": 1,Fglass + "to_hit": 1, "bashing": 2, "material": [ "glass" ], "ascii_picture": "glass_bottle", From 2ef8971308c5964631ee9c1162e6d9c11777877e Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Sat, 18 Jul 2020 04:38:40 +0000 Subject: [PATCH 100/151] Make game::stats() private --- src/game.cpp | 5 +++++ src/game.h | 3 ++- src/memorial_logger.cpp | 10 +++++----- src/stats_tracker.h | 2 ++ tests/stats_tracker_test.cpp | 4 ++-- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 820092761ccae..7b9d36b0c1f82 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -12628,3 +12628,8 @@ void set_scenario( const scenario *new_scenario ) { g->scen = new_scenario; } + +stats_tracker &get_stats() +{ + return g->stats(); +} diff --git a/src/game.h b/src/game.h index 33ccc7dc6f270..a5af8a8c5455c 100644 --- a/src/game.h +++ b/src/game.h @@ -156,6 +156,7 @@ class game friend weather_manager &get_weather(); friend const scenario *get_scenario(); friend void set_scenario( const scenario *new_scenario ); + friend stats_tracker &get_stats(); public: game(); ~game(); @@ -974,6 +975,7 @@ class game pimpl memorial_logger_ptr; pimpl spell_events_ptr; + stats_tracker &stats(); map &m; event_bus &events(); public: @@ -981,7 +983,6 @@ class game scent_map &scent; timed_event_manager &timed_events; - stats_tracker &stats(); achievements_tracker &achievements(); memorial_logger &memorial(); spell_events &spell_events_subscriber(); diff --git a/src/memorial_logger.cpp b/src/memorial_logger.cpp index 6442b7ca7e568..9ed787cd8cf53 100644 --- a/src/memorial_logger.cpp +++ b/src/memorial_logger.cpp @@ -413,8 +413,8 @@ void memorial_logger::write_text_memorial( std::ostream &file, //Lifetime stats file << _( "Lifetime Stats and Scores" ) << eol; - for( const score *scr : g->stats().valid_scores() ) { - file << indent << scr->description( g->stats() ) << eol; + for( const score *scr : get_stats().valid_scores() ) { + file << indent << scr->description( get_stats() ) << eol; } file << eol; @@ -430,11 +430,11 @@ void memorial_logger::write_json_memorial( std::ostream &memorial_file ) const jsout.member( "memorial_version", 0 ); jsout.member( "log", log ); jsout.member( "achievements", g->achievements() ); - jsout.member( "stats", g->stats() ); + jsout.member( "stats", get_stats() ); std::map, cata_variant> scores; - for( const score *scr : g->stats().valid_scores() ) { - scores.emplace( scr->id, scr->value( g->stats() ) ); + for( const score *scr : get_stats().valid_scores() ) { + scores.emplace( scr->id, scr->value( get_stats() ) ); } jsout.member( "scores", scores ); diff --git a/src/stats_tracker.h b/src/stats_tracker.h index 4fe44744a8de4..3f8d203f9496c 100644 --- a/src/stats_tracker.h +++ b/src/stats_tracker.h @@ -213,4 +213,6 @@ class stats_tracker : public event_subscriber std::unordered_set> initial_scores; }; +stats_tracker &get_stats(); + #endif // CATA_SRC_STATS_TRACKER_H diff --git a/tests/stats_tracker_test.cpp b/tests/stats_tracker_test.cpp index b58772eb04ee2..ca4ae73ea3d37 100644 --- a/tests/stats_tracker_test.cpp +++ b/tests/stats_tracker_test.cpp @@ -849,10 +849,10 @@ TEST_CASE( "achievments_tracker", "[stats]" ) TEST_CASE( "stats_tracker_in_game", "[stats]" ) { - g->stats().clear(); + get_stats().clear(); cata::event e = cata::event::make(); get_event_bus().send( e ); - CHECK( g->stats().get_events( e.type() ).count( e.data() ) == 1 ); + CHECK( get_stats().get_events( e.type() ).count( e.data() ) == 1 ); } struct test_subscriber : public event_subscriber { From f970fec828787a5887e7004b2f3c048322d98a20 Mon Sep 17 00:00:00 2001 From: LaVeyanFiend Date: Sat, 18 Jul 2020 13:53:43 -0400 Subject: [PATCH 101/151] Make rebar long --- data/json/items/generic.json | 1 + 1 file changed, 1 insertion(+) diff --git a/data/json/items/generic.json b/data/json/items/generic.json index b182e41840127..69ff3cf15c9cc 100644 --- a/data/json/items/generic.json +++ b/data/json/items/generic.json @@ -715,6 +715,7 @@ "material": [ "steel" ], "weight": "908 g", "volume": "1500 ml", + "longest_side": "80 cm", "bashing": 12, "to_hit": -1, "qualities": [ [ "HAMMER", 1 ] ] From 46eee20b0c1f7066190b68ab2f5fddd377106b2d Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Sat, 18 Jul 2020 04:07:09 +0000 Subject: [PATCH 102/151] Remove last game::u references and make it private --- src/animation.cpp | 24 ++++++++++++++---------- src/cata_tiles.cpp | 6 +++--- src/descriptions.cpp | 2 +- src/fungal_effects.cpp | 38 ++++++++++++++++++++++---------------- src/game.h | 5 +++-- 5 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/animation.cpp b/src/animation.cpp index 42d3bb5bfeceb..183825d5ebef1 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -119,7 +119,7 @@ void draw_explosion_curses( game &g, const tripoint ¢er, const int r, return; } // TODO: Make it look different from above/below - const tripoint p = relative_view_pos( g.u, center ); + const tripoint p = relative_view_pos( get_avatar(), center ); explosion_animation anim; @@ -171,8 +171,9 @@ constexpr explosion_neighbors operator ^ ( explosion_neighbors lhs, explosion_ne void draw_custom_explosion_curses( game &g, const std::list< std::map > &layers ) { + avatar &player_character = get_avatar(); // calculate screen offset relative to player + view offset position - const tripoint center = g.u.pos() + g.u.view_offset; + const tripoint center = player_character.pos() + player_character.view_offset; const tripoint topleft( center.x - getmaxx( g.w_terrain ) / 2, center.y - getmaxy( g.w_terrain ) / 2, 0 ); @@ -565,11 +566,11 @@ void game::draw_hit_mon( const tripoint &p, const monster &m, const bool dead ) namespace { -void draw_hit_player_curses( const game &g, const Character &p, const int dam ) +void draw_hit_player_curses( const game &/* g */, const Character &p, const int dam ) { nc_color const col = !dam ? yellow_background( p.symbol_color() ) : red_background( p.symbol_color() ); - hit_animation( g.u, p.pos(), col, p.symbol() ); + hit_animation( get_avatar(), p.pos(), col, p.symbol() ); } } //namespace @@ -614,13 +615,14 @@ namespace void draw_line_curses( game &g, const tripoint ¢er, const std::vector &ret, bool noreveal ) { + avatar &player_character = get_avatar(); for( const tripoint &p : ret ) { const auto critter = g.critter_at( p, true ); // NPCs and monsters get drawn with inverted colors - if( critter && g.u.sees( *critter ) ) { + if( critter && player_character.sees( *critter ) ) { critter->draw( g.w_terrain, center, true ); - } else if( noreveal && !g.u.sees( p ) ) { + } else if( noreveal && !player_character.sees( p ) ) { // Draw a meaningless symbol. Avoids revealing tile, but keeps feedback const char sym = '?'; const nc_color col = c_dark_gray; @@ -630,7 +632,7 @@ void draw_line_curses( game &g, const tripoint ¢er, const std::vector &points ) { + avatar &player_character = get_avatar(); map &here = get_map(); for( const tripoint &p : points ) { - here.drawsq( g.w_terrain, g.u, p, true, true ); + here.drawsq( g.w_terrain, player_character, p, true, true ); } const tripoint p = points.empty() ? tripoint {POSX, POSY, 0} : - relative_view_pos( g.u, points.back() ); + relative_view_pos( player_character, points.back() ); mvwputch( g.w_terrain, p.xy(), c_white, 'X' ); } } //namespace @@ -749,7 +752,8 @@ namespace { void draw_sct_curses( const game &g ) { - const tripoint off = relative_view_pos( g.u, tripoint_zero ); + avatar &player_character = get_avatar(); + const tripoint off = relative_view_pos( player_character, tripoint_zero ); for( const auto &text : SCT.vSCT ) { const int dy = off.y + text.getPosY(); diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index d9da726652137..16837ff7e39d8 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -2801,7 +2801,7 @@ bool cata_tiles::draw_critter_at( const tripoint &p, lit_level ll, int &height_3 result = draw_from_id_string( chosen_id, ent_category, ent_subcategory, p, subtile, rot_facing, ll, false, height_3d ); sees_player = m->sees( player_character ); - attitude = m->attitude_to( g-> u ); + attitude = m->attitude_to( player_character ); } } const player *pl = dynamic_cast( &critter ); @@ -2811,8 +2811,8 @@ bool cata_tiles::draw_critter_at( const tripoint &p, lit_level ll, int &height_3 if( pl->is_player() ) { is_player = true; } else { - sees_player = pl->sees( g-> u ); - attitude = pl->attitude_to( g-> u ); + sees_player = pl->sees( player_character ); + attitude = pl->attitude_to( player_character ); } } } else { diff --git a/src/descriptions.cpp b/src/descriptions.cpp index d8b7e9ffbecb6..cf723312e2a3e 100644 --- a/src/descriptions.cpp +++ b/src/descriptions.cpp @@ -30,7 +30,7 @@ enum class description_target : int { static const Creature *seen_critter( const game &g, const tripoint &p ) { const Creature *critter = g.critter_at( p, true ); - if( critter != nullptr && g.u.sees( *critter ) ) { + if( critter != nullptr && get_player_character().sees( *critter ) ) { return critter; } diff --git a/src/fungal_effects.cpp b/src/fungal_effects.cpp index e5350e16da4fa..e301d9c54925c 100644 --- a/src/fungal_effects.cpp +++ b/src/fungal_effects.cpp @@ -61,9 +61,10 @@ fungal_effects::fungal_effects( game &g, map &mp ) void fungal_effects::fungalize( const tripoint &p, Creature *origin, double spore_chance ) { + Character &player_character = get_player_character(); if( monster *const mon_ptr = g->critter_at( p ) ) { monster &critter = *mon_ptr; - if( gm.u.sees( p ) && + if( player_character.sees( p ) && !critter.type->in_species( species_FUNGUS ) ) { add_msg( _( "The %s is covered in tiny spores!" ), critter.name() ); } @@ -72,25 +73,29 @@ void fungal_effects::fungalize( const tripoint &p, Creature *origin, double spor critter.add_effect( effect_stunned, rng( 1_turns, 3_turns ) ); critter.apply_damage( origin, bodypart_id( "torso" ), rng( 25, 50 ) ); } - } else if( gm.u.pos() == p ) { + } else if( player_character.pos() == p ) { // TODO: Make this accept NPCs when they understand fungals - player &pl = gm.u; ///\EFFECT_DEX increases chance of knocking fungal spores away with your TAIL_CATTLE ///\EFFECT_MELEE increases chance of knocking fungal sports away with your TAIL_CATTLE - if( pl.has_trait( trait_TAIL_CATTLE ) && - one_in( 20 - pl.dex_cur - pl.get_skill_level( skill_melee ) ) ) { - pl.add_msg_if_player( - _( "The spores land on you, but you quickly swat them off with your tail!" ) ); + if( player_character.has_trait( trait_TAIL_CATTLE ) && + one_in( 20 - player_character.dex_cur - player_character.get_skill_level( skill_melee ) ) ) { + add_msg( _( "The spores land on you, but you quickly swat them off with your tail!" ) ); return; } // Spores hit the player--is there any hope? bool hit = false; - hit |= one_in( 4 ) && pl.add_env_effect( effect_spores, bp_head, 3, 9_minutes, bp_head ); - hit |= one_in( 2 ) && pl.add_env_effect( effect_spores, bp_torso, 3, 9_minutes, bp_torso ); - hit |= one_in( 4 ) && pl.add_env_effect( effect_spores, bp_arm_l, 3, 9_minutes, bp_arm_l ); - hit |= one_in( 4 ) && pl.add_env_effect( effect_spores, bp_arm_r, 3, 9_minutes, bp_arm_r ); - hit |= one_in( 4 ) && pl.add_env_effect( effect_spores, bp_leg_l, 3, 9_minutes, bp_leg_l ); - hit |= one_in( 4 ) && pl.add_env_effect( effect_spores, bp_leg_r, 3, 9_minutes, bp_leg_r ); + hit |= one_in( 4 ) && + player_character.add_env_effect( effect_spores, bp_head, 3, 9_minutes, bp_head ); + hit |= one_in( 2 ) && + player_character.add_env_effect( effect_spores, bp_torso, 3, 9_minutes, bp_torso ); + hit |= one_in( 4 ) && + player_character.add_env_effect( effect_spores, bp_arm_l, 3, 9_minutes, bp_arm_l ); + hit |= one_in( 4 ) && + player_character.add_env_effect( effect_spores, bp_arm_r, 3, 9_minutes, bp_arm_r ); + hit |= one_in( 4 ) && + player_character.add_env_effect( effect_spores, bp_leg_l, 3, 9_minutes, bp_leg_l ); + hit |= one_in( 4 ) && + player_character.add_env_effect( effect_spores, bp_leg_r, 3, 9_minutes, bp_leg_r ); if( hit ) { add_msg( m_warning, _( "You're covered in tiny spores!" ) ); } @@ -100,7 +105,7 @@ void fungal_effects::fungalize( const tripoint &p, Creature *origin, double spor if( origin_mon != nullptr ) { spore->make_ally( *origin_mon ); } else if( origin != nullptr && origin->is_player() && - gm.u.has_trait( trait_THRESH_MYCUS ) ) { + player_character.has_trait( trait_THRESH_MYCUS ) ) { spore->friendly = 1000; } } @@ -137,6 +142,7 @@ void fungal_effects::spread_fungus_one_tile( const tripoint &p, const int growth { bool converted = false; // Terrain conversion + Character &player_character = get_player_character(); if( m.has_flag_ter( flag_DIGGABLE, p ) ) { if( x_in_y( growth * 10, 100 ) ) { m.ter_set( p, t_fungus ); @@ -177,7 +183,7 @@ void fungal_effects::spread_fungus_one_tile( const tripoint &p, const int growth if( m.get_field_intensity( p, fd_fungal_haze ) != 0 ) { if( x_in_y( growth * 10, 800 ) ) { // young trees are vulnerable m.ter_set( p, t_fungus ); - if( gm.place_critter_at( mon_fungal_blossom, p ) && gm.u.sees( p ) ) { + if( gm.place_critter_at( mon_fungal_blossom, p ) && player_character.sees( p ) ) { add_msg( m_warning, _( "The young tree blooms forth into a fungal blossom!" ) ); } } else if( x_in_y( growth * 10, 400 ) ) { @@ -193,7 +199,7 @@ void fungal_effects::spread_fungus_one_tile( const tripoint &p, const int growth if( m.get_field_intensity( p, fd_fungal_haze ) != 0 ) { if( x_in_y( growth * 10, 100 ) ) { m.ter_set( p, t_fungus ); - if( gm.place_critter_at( mon_fungal_blossom, p ) && gm.u.sees( p ) ) { + if( gm.place_critter_at( mon_fungal_blossom, p ) && player_character.sees( p ) ) { add_msg( m_warning, _( "The tree blooms forth into a fungal blossom!" ) ); } } else if( x_in_y( growth * 10, 600 ) ) { diff --git a/src/game.h b/src/game.h index a5af8a8c5455c..da2924a2a458e 100644 --- a/src/game.h +++ b/src/game.h @@ -975,11 +975,12 @@ class game pimpl memorial_logger_ptr; pimpl spell_events_ptr; - stats_tracker &stats(); map &m; + avatar &u; + event_bus &events(); + stats_tracker &stats(); public: - avatar &u; scent_map &scent; timed_event_manager &timed_events; From a6b1636da94419dbdd20459d9e9b226a3794a6db Mon Sep 17 00:00:00 2001 From: andrei <68240139+andrei8l@users.noreply.github.com> Date: Sat, 18 Jul 2020 22:15:38 +0300 Subject: [PATCH 103/151] activity: fix triggering pit trap after digging it (#42197) --- src/activity_actor.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index fd18516ad571e..e95c4d4010dc6 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -344,13 +344,14 @@ void dig_activity_actor::start( player_activity &act, Character & ) act.moves_left = moves_total; } -void dig_activity_actor::do_turn( player_activity &, Character & ) +void dig_activity_actor::do_turn( player_activity &, Character &who ) { sfx::play_activity_sound( "tool", "shovel", sfx::get_heard_volume( location ) ); if( calendar::once_every( 1_minutes ) ) { //~ Sound of a shovel digging a pit at work! sounds::sound( location, 10, sounds::sound_t::activity, _( "hsh!" ) ); } + get_map().maybe_trigger_trap( location, who, true ); } void dig_activity_actor::finish( player_activity &act, Character &who ) @@ -406,8 +407,6 @@ void dig_activity_actor::finish( player_activity &act, Character &who ) } act.set_to_null(); - - here.maybe_trigger_trap( location, who, true ); } void dig_activity_actor::serialize( JsonOut &jsout ) const @@ -447,13 +446,14 @@ void dig_channel_activity_actor::start( player_activity &act, Character & ) act.moves_left = moves_total; } -void dig_channel_activity_actor::do_turn( player_activity &, Character & ) +void dig_channel_activity_actor::do_turn( player_activity &, Character &who ) { sfx::play_activity_sound( "tool", "shovel", sfx::get_heard_volume( location ) ); if( calendar::once_every( 1_minutes ) ) { //~ Sound of a shovel digging a pit at work! sounds::sound( location, 10, sounds::sound_t::activity, _( "hsh!" ) ); } + get_map().maybe_trigger_trap( location, who, true ); } void dig_channel_activity_actor::finish( player_activity &act, Character &who ) @@ -474,8 +474,6 @@ void dig_channel_activity_actor::finish( player_activity &act, Character &who ) here.ter( location ).obj().name() ); act.set_to_null(); - - here.maybe_trigger_trap( location, who, true ); } void dig_channel_activity_actor::serialize( JsonOut &jsout ) const From 37fa71b86d35470d5166a5850344d2cd9b1d8002 Mon Sep 17 00:00:00 2001 From: andrei <68240139+andrei8l@users.noreply.github.com> Date: Sat, 18 Jul 2020 22:19:00 +0300 Subject: [PATCH 104/151] Fix npc crash in decide_needs() (#42231) * npc: fix ammo-related crash in decide_needs() fixes crashes for wierd guns with no ammo Fixes #42229 * json: add USES_BIONIC_POWER to bio guns --- data/json/items/gun/bio.json | 6 +++--- src/npc.cpp | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/data/json/items/gun/bio.json b/data/json/items/gun/bio.json index fd4409a01e1b5..36719d0145e2e 100644 --- a/data/json/items/gun/bio.json +++ b/data/json/items/gun/bio.json @@ -44,7 +44,7 @@ "loudness": 20, "modes": [ [ "DEFAULT", "semi-auto", 1 ], [ "AUTO", "auto", 5 ] ], "ammo_effects": [ "DRAW_AS_LINE", "WIDE", "EMP" ], - "flags": [ "NEVER_JAMS", "NO_UNLOAD", "TRADER_AVOID" ] + "flags": [ "NEVER_JAMS", "NO_UNLOAD", "TRADER_AVOID", "USES_BIONIC_POWER" ] }, { "id": "bio_laser_gun", @@ -64,7 +64,7 @@ "durability": 10, "loudness": 7, "ammo_effects": [ "LASER", "INCENDIARY" ], - "flags": [ "NEVER_JAMS", "TRADER_AVOID", "FIRESTARTER" ] + "flags": [ "NEVER_JAMS", "TRADER_AVOID", "FIRESTARTER", "USES_BIONIC_POWER" ] }, { "id": "bio_lightning", @@ -84,7 +84,7 @@ "durability": 10, "loudness": 10, "ammo_effects": [ "LIGHTNING", "BOUNCE" ], - "flags": [ "NEVER_JAMS", "TRADER_AVOID" ] + "flags": [ "NEVER_JAMS", "TRADER_AVOID", "USES_BIONIC_POWER" ] }, { "id": "mut_quills", diff --git a/src/npc.cpp b/src/npc.cpp index 790f831febeed..b09f9c5eabf76 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -1496,7 +1496,10 @@ void npc::decide_needs() charges_of( itype_UPS_off, ups_drain ); needrank[need_ammo] = static_cast( ups_charges ) / ups_drain; } else { - needrank[need_ammo] = get_ammo( ammotype( *weapon.type->gun->ammo.begin() ) ).size(); + const ammotype ammo_type = weapon.ammo_type(); + if( ammo_type != ammotype::NULL_ID() ) { + needrank[need_ammo] = get_ammo( ammo_type ).size(); + } } needrank[need_ammo] *= 5; } From 1363418bba105efd956029cc745adf4ed258a35e Mon Sep 17 00:00:00 2001 From: Qrox Date: Sat, 18 Jul 2020 15:24:31 +0800 Subject: [PATCH 105/151] Fix double prompt when eating while full --- src/activity_actor.cpp | 31 ++++++++++++++++--------------- src/activity_actor.h | 4 ++-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index e95c4d4010dc6..8fc9207bc27ee 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -1139,25 +1139,24 @@ void consume_activity_actor::start( player_activity &act, Character &guy ) if( consume_location ) { const auto ret = player_character.will_eat( *consume_location, true ); if( !ret.success() ) { + canceled = true; consume_menu_selections = std::vector(); consume_menu_filter = std::string(); return; - } else { - force = true; } moves = to_moves( guy.get_consume_time( *consume_location ) ); } else if( !consume_item.is_null() ) { const auto ret = player_character.will_eat( consume_item, true ); if( !ret.success() ) { + canceled = true; consume_menu_selections = std::vector(); consume_menu_filter = std::string(); return; - } else { - force = true; } moves = to_moves( guy.get_consume_time( consume_item ) ); } else { debugmsg( "Item/location to be consumed should not be null." ); + canceled = true; return; } @@ -1173,15 +1172,17 @@ void consume_activity_actor::finish( player_activity &act, Character & ) act.interruptable = false; avatar &player_character = get_avatar(); - if( consume_location ) { - player_character.consume( consume_location, force ); - } else if( !consume_item.is_null() ) { - player_character.consume( consume_item, force ); - } else { - debugmsg( "Item location/name to be consumed should not be null." ); - } - if( player_character.get_value( "THIEF_MODE_KEEP" ) != "YES" ) { - player_character.set_value( "THIEF_MODE", "THIEF_ASK" ); + if( !canceled ) { + if( consume_location ) { + player_character.consume( consume_location, /*force=*/true ); + } else if( !consume_item.is_null() ) { + player_character.consume( consume_item, /*force=*/true ); + } else { + debugmsg( "Item location/name to be consumed should not be null." ); + } + if( player_character.get_value( "THIEF_MODE_KEEP" ) != "YES" ) { + player_character.set_value( "THIEF_MODE", "THIEF_ASK" ); + } } //setting act to null clears these so back them up std::vector temp_selections = consume_menu_selections; @@ -1211,7 +1212,7 @@ void consume_activity_actor::serialize( JsonOut &jsout ) const jsout.member( "consume_item", consume_item ); jsout.member( "consume_menu_selections", consume_menu_selections ); jsout.member( "consume_menu_filter", consume_menu_filter ); - jsout.member( "force", force ); + jsout.member( "canceled", canceled ); jsout.end_object(); } @@ -1227,7 +1228,7 @@ std::unique_ptr consume_activity_actor::deserialize( JsonIn &jsi data.read( "consume_item", actor.consume_item ); data.read( "consume_menu_selections", actor.consume_menu_selections ); data.read( "consume_menu_filter", actor.consume_menu_filter ); - data.read( "force", actor.force ); + data.read( "canceled", actor.canceled ); return actor.clone(); } diff --git a/src/activity_actor.h b/src/activity_actor.h index d8406d5ad2ff5..dc2a52020e960 100644 --- a/src/activity_actor.h +++ b/src/activity_actor.h @@ -516,14 +516,14 @@ class consume_activity_actor : public activity_actor item consume_item; std::vector consume_menu_selections; std::string consume_menu_filter; - bool force = false; + bool canceled = false; /** * @pre @p other is a consume_activity_actor */ bool can_resume_with_internal( const activity_actor &other, const Character & ) const override { const consume_activity_actor &c_actor = static_cast( other ); return ( consume_location == c_actor.consume_location && - force == c_actor.force && &consume_item == &c_actor.consume_item ); + canceled == c_actor.canceled && &consume_item == &c_actor.consume_item ); } public: consume_activity_actor( const item_location &consume_location, From a41794b80220d2b89f9580913ae6cd092aba389d Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 18 Jul 2020 12:52:53 +0200 Subject: [PATCH 106/151] Set all parts to 0 Instead of applying 500 dmg --- src/player_hardcoded_effects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/player_hardcoded_effects.cpp b/src/player_hardcoded_effects.cpp index 9e51d91638418..0ba5be7e9f77e 100644 --- a/src/player_hardcoded_effects.cpp +++ b/src/player_hardcoded_effects.cpp @@ -1250,7 +1250,7 @@ void player::hardcoded_effects( effect &it ) if( dur > 1_days ) { add_msg_if_player( m_bad, _( "You succumb to the infection." ) ); get_event_bus().send( getID() ); - hurtall( 500, nullptr ); + set_all_parts_hp_cur( 0 ); } else if( has_effect( effect_strong_antibiotic ) ) { it.mod_duration( -1_turns ); } else if( has_effect( effect_antibiotic ) ) { From 36ba9f872faccd1a0d59953f9ba5950b4d3945a9 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 18 Jul 2020 14:14:34 +0200 Subject: [PATCH 107/151] Only damage main bodypart --- src/activity_handlers.cpp | 10 +++++----- src/character.cpp | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index de0c442561e1d..20795b47e6e35 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -4379,14 +4379,14 @@ static void blood_magic( player *p, int cost ) std::vector uile; std::vector parts; int i = 0; - for( const std::pair &part : p->get_body() ) { - const int hp_cur = part.second.get_hp_cur(); - uilist_entry entry( i, hp_cur > cost, i + 49, body_part_hp_bar_ui_text( part.first.id() ) ); + for( const bodypart_id &bp : p->get_all_body_parts( true ) ) { + const int hp_cur = p->get_part_hp_cur( bp ); + uilist_entry entry( i, hp_cur > cost, i + 49, body_part_hp_bar_ui_text( bp ) ); - const std::pair &hp = get_hp_bar( hp_cur, part.second.get_hp_max() ); + const std::pair &hp = get_hp_bar( hp_cur, p->get_part_hp_max( bp ) ); entry.ctxt = colorize( hp.first, hp.second ); uile.emplace_back( entry ); - parts.push_back( part.first.id() ); + parts.push_back( bp ); i++; } int action = -1; diff --git a/src/character.cpp b/src/character.cpp index f7836e2a6fec2..3a481e6746ff5 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -8985,9 +8985,9 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam, const mod_pain( dam / 2 ); - const int dam_to_bodypart = std::min( dam, get_part_hp_cur( hurt ) ); + const int dam_to_bodypart = std::min( dam, get_part_hp_cur( hurt->main_part ) ); - mod_part_hp_cur( hurt, - dam_to_bodypart ); + mod_part_hp_cur( hurt->main_part, - dam_to_bodypart ); get_event_bus().send( getID(), dam_to_bodypart ); if( !weapon.is_null() && !as_player()->can_wield( weapon ).success() && @@ -8997,9 +8997,9 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam, const put_into_vehicle_or_drop( *this, item_drop_reason::tumbling, { weapon } ); i_rem( &weapon ); } - if( has_effect( effect_mending, hurt->token ) && ( source == nullptr || + if( has_effect( effect_mending, hurt->main_part->token ) && ( source == nullptr || !source->is_hallucination() ) ) { - effect &e = get_effect( effect_mending, hurt->token ); + effect &e = get_effect( effect_mending, hurt->main_part->token ); float remove_mend = dam / 20.0f; e.mod_duration( -e.get_max_duration() * remove_mend ); } @@ -9011,11 +9011,11 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam, const if( !bypass_med ) { // remove healing effects if damaged int remove_med = roll_remainder( dam / 5.0f ); - if( remove_med > 0 && has_effect( effect_bandaged, hurt->token ) ) { - remove_med -= reduce_healing_effect( effect_bandaged, remove_med, hurt ); + if( remove_med > 0 && has_effect( effect_bandaged, hurt->main_part->token ) ) { + remove_med -= reduce_healing_effect( effect_bandaged, remove_med, hurt->main_part ); } - if( remove_med > 0 && has_effect( effect_disinfected, hurt->token ) ) { - reduce_healing_effect( effect_disinfected, remove_med, hurt ); + if( remove_med > 0 && has_effect( effect_disinfected, hurt->main_part->token ) ) { + reduce_healing_effect( effect_disinfected, remove_med, hurt->main_part ); } } } @@ -9223,7 +9223,7 @@ void Character::hurtall( int dam, Creature *source, bool disturb /*= true*/ ) return; } - for( const bodypart_id &bp : get_all_body_parts() ) { + for( const bodypart_id &bp : get_all_body_parts( true ) ) { // Don't use apply_damage here or it will annoy the player with 6 queries const int dam_to_bodypart = std::min( dam, get_part_hp_cur( bp ) ); mod_part_hp_cur( bp, - dam_to_bodypart ); From 65cdc386f6537324935bc6767130cb971132b338 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 18 Jul 2020 23:01:26 +0200 Subject: [PATCH 108/151] Clean up --- src/character.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index 3a481e6746ff5..22814ae1fa2b3 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -8985,9 +8985,11 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam, const mod_pain( dam / 2 ); - const int dam_to_bodypart = std::min( dam, get_part_hp_cur( hurt->main_part ) ); + const bodypart_id &part_to_damage = hurt->main_part; - mod_part_hp_cur( hurt->main_part, - dam_to_bodypart ); + const int dam_to_bodypart = std::min( dam, get_part_hp_cur( part_to_damage ) ); + + mod_part_hp_cur( part_to_damage, - dam_to_bodypart ); get_event_bus().send( getID(), dam_to_bodypart ); if( !weapon.is_null() && !as_player()->can_wield( weapon ).success() && @@ -8997,9 +8999,9 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam, const put_into_vehicle_or_drop( *this, item_drop_reason::tumbling, { weapon } ); i_rem( &weapon ); } - if( has_effect( effect_mending, hurt->main_part->token ) && ( source == nullptr || + if( has_effect( effect_mending, part_to_damage->token ) && ( source == nullptr || !source->is_hallucination() ) ) { - effect &e = get_effect( effect_mending, hurt->main_part->token ); + effect &e = get_effect( effect_mending, part_to_damage->token ); float remove_mend = dam / 20.0f; e.mod_duration( -e.get_max_duration() * remove_mend ); } @@ -9011,11 +9013,11 @@ void Character::apply_damage( Creature *source, bodypart_id hurt, int dam, const if( !bypass_med ) { // remove healing effects if damaged int remove_med = roll_remainder( dam / 5.0f ); - if( remove_med > 0 && has_effect( effect_bandaged, hurt->main_part->token ) ) { - remove_med -= reduce_healing_effect( effect_bandaged, remove_med, hurt->main_part ); + if( remove_med > 0 && has_effect( effect_bandaged, part_to_damage->token ) ) { + remove_med -= reduce_healing_effect( effect_bandaged, remove_med, part_to_damage ); } - if( remove_med > 0 && has_effect( effect_disinfected, hurt->main_part->token ) ) { - reduce_healing_effect( effect_disinfected, remove_med, hurt->main_part ); + if( remove_med > 0 && has_effect( effect_disinfected, part_to_damage->token ) ) { + reduce_healing_effect( effect_disinfected, remove_med, part_to_damage ); } } } From f89e9be2843828fd9a03476e139b3db2452b99bc Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 18 Jul 2020 23:31:33 +0200 Subject: [PATCH 109/151] Don't decrease field intensity if you're immune --- src/map_field.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/map_field.cpp b/src/map_field.cpp index cb3860690ad10..6664b5e5dfda5 100644 --- a/src/map_field.cpp +++ b/src/map_field.cpp @@ -1718,10 +1718,6 @@ void map::creature_in_field( Creature &critter ) const field_type_id cur_field_id = cur_field_entry.get_field_type(); for( const auto &fe : cur_field_entry.field_effects() ) { - // the field is decreased even if you are in a vehicle - if( cur_field_id->decrease_intensity_on_contact ) { - cur_field_entry.mod_field_intensity( -1 ); - } if( in_vehicle && fe.immune_in_vehicle ) { continue; } @@ -1755,6 +1751,9 @@ void map::creature_in_field( Creature &critter ) if( effect_added ) { critter.add_msg_player_or_npc( fe.env_message_type, fe.get_message(), fe.get_message_npc() ); } + if( cur_field_id->decrease_intensity_on_contact ) { + cur_field_entry.mod_field_intensity( -1 ); + } } } } From 2b237d4ba8cff406040b61a8768206d1c2f76a8a Mon Sep 17 00:00:00 2001 From: Curtis Merrill Date: Sat, 18 Jul 2020 18:05:26 -0400 Subject: [PATCH 110/151] Reimplement original behavior for default magazines for nested containers (#42225) --- src/item.cpp | 25 +++---------------------- src/item_contents.cpp | 10 ++++++++++ src/item_contents.h | 2 ++ src/item_pocket.cpp | 13 +++++++++++++ src/item_pocket.h | 4 ++++ tests/battery_mod_test.cpp | 5 ++--- tests/reload_magazine_test.cpp | 4 ++-- 7 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 7a456a9bd914e..2f16b27b03045 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -7543,28 +7543,9 @@ bool item::magazine_integral() const return contents.has_pocket_type( item_pocket::pocket_type::MAGAZINE ); } -itype_id item::magazine_default( bool conversion ) const -{ - if( !magazine_compatible( conversion ).empty() ) { - if( conversion ) { - for( const item *m : is_gun() ? gunmods() : toolmods() ) { - if( !m->type->mod->magazine_adaptor.empty() ) { - auto mags = m->type->mod->magazine_adaptor.find( ammotype( *ammo_types( conversion ).begin() ) ); - if( mags != m->type->mod->magazine_adaptor.end() ) { - return *( mags->second.begin() ); - } - } - } - } - if( !ammo_types( conversion ).empty() ) { - auto mag = type->magazine_default.find( ammotype( *ammo_types( conversion ).begin() ) ); - if( mag != type->magazine_default.end() ) { - return mag->second; - } - } - return *magazine_compatible( conversion ).begin(); - } - return itype_id::NULL_ID(); +itype_id item::magazine_default( bool /* conversion */ ) const +{ + return contents.magazine_default(); } std::set item::magazine_compatible( bool /* conversion */ ) const diff --git a/src/item_contents.cpp b/src/item_contents.cpp index 8444a9e7484d7..0390702d1bf5e 100644 --- a/src/item_contents.cpp +++ b/src/item_contents.cpp @@ -1150,6 +1150,16 @@ std::set item_contents::magazine_compatible() const return ret; } +itype_id item_contents::magazine_default() const +{ + for( const item_pocket &pocket : contents ) { + if( pocket.is_type( item_pocket::pocket_type::MAGAZINE_WELL ) ) { + return pocket.magazine_default(); + } + } + return itype_id::NULL_ID(); +} + units::mass item_contents::total_container_weight_capacity() const { units::mass total_weight = 0_gram; diff --git a/src/item_contents.h b/src/item_contents.h index 6152a79240323..f32bad219e725 100644 --- a/src/item_contents.h +++ b/src/item_contents.h @@ -91,6 +91,8 @@ class item_contents // all magazines compatible with any pockets. // this only checks MAGAZINE_WELL std::set magazine_compatible() const; + // returns the default magazine; assumes only one MAGAZINE_WELL. returns NULL_ID if not a magazine well or no compatible magazines. + itype_id magazine_default() const; /** * This function is to aid migration to using nested containers. * The call sites of this function need to be updated to search the diff --git a/src/item_pocket.cpp b/src/item_pocket.cpp index 2c039a2fd070c..e6c760d14764f 100644 --- a/src/item_pocket.cpp +++ b/src/item_pocket.cpp @@ -97,6 +97,11 @@ void pocket_data::load( const JsonObject &jo ) optional( jo, was_loaded, "pocket_type", type, item_pocket::pocket_type::CONTAINER ); optional( jo, was_loaded, "ammo_restriction", ammo_restriction ); optional( jo, was_loaded, "item_restriction", item_id_restriction ); + if( !item_id_restriction.empty() ) { + std::vector item_restriction; + mandatory( jo, was_loaded, "item_restriction", item_restriction ); + default_magazine = item_restriction.front(); + } // ammo_restriction is a type of override, making the mandatory members not mandatory and superfluous // putting it in an if statement like this should allow for report_unvisited_member to work here if( ammo_restriction.empty() ) { @@ -506,6 +511,14 @@ item *item_pocket::magazine_current() return iter != contents.end() ? &*iter : nullptr; } +itype_id item_pocket::magazine_default() const +{ + if( is_type( item_pocket::pocket_type::MAGAZINE_WELL ) ) { + return data->default_magazine; + } + return itype_id::NULL_ID(); +} + int item_pocket::ammo_consume( int qty ) { int need = qty; diff --git a/src/item_pocket.h b/src/item_pocket.h index 48755168ee0a5..87d19fc953c11 100644 --- a/src/item_pocket.h +++ b/src/item_pocket.h @@ -172,6 +172,8 @@ class item_pocket std::vector gunmods() const; cata::flat_set item_type_restrictions() const; item *magazine_current(); + // returns the default magazine if MAGAZINE_WELL, otherwise NULL_ID + itype_id magazine_default() const; // returns amount of ammo consumed int ammo_consume( int qty ); // returns all allowable ammotypes @@ -361,6 +363,8 @@ class pocket_data // items stored are restricted to these item ids. // this takes precedence over the other two restrictions cata::flat_set item_id_restriction; + // the first in the json array for item_id_restriction when loaded + itype_id default_magazine = itype_id::NULL_ID(); // container's size and encumbrance does not change based on contents. bool rigid = false; diff --git a/tests/battery_mod_test.cpp b/tests/battery_mod_test.cpp index 4fe26e66fea28..da1d6de7b2007 100644 --- a/tests/battery_mod_test.cpp +++ b/tests/battery_mod_test.cpp @@ -99,7 +99,7 @@ TEST_CASE( "battery tool mod test", "[battery][mod]" ) // FIXME: Required to fix #40948 itype_id mag_default = flashlight.magazine_default( false ); CHECK_FALSE( mag_default.is_null() ); - CHECK( mag_default.str() == "medium_atomic_battery_cell" ); + CHECK( mag_default.str() == "medium_battery_cell" ); } THEN( "light batteries no longer fit" ) { @@ -233,8 +233,7 @@ TEST_CASE( "battery and tool properties", "[battery][tool][properties]" ) SECTION( "has a default magazine" ) { itype_id mag_default = flashlight.magazine_default( false ); CHECK_FALSE( mag_default.is_null() ); - // FIXME: Required to fix #40800 - CHECK( mag_default.str() == "light_atomic_battery_cell" ); + CHECK( mag_default.str() == "light_disposable_cell" ); } SECTION( "can use battery ammo" ) { diff --git a/tests/reload_magazine_test.cpp b/tests/reload_magazine_test.cpp index 855efa8e9e516..610a9c8615098 100644 --- a/tests/reload_magazine_test.cpp +++ b/tests/reload_magazine_test.cpp @@ -20,9 +20,9 @@ TEST_CASE( "reload_magazine", "[magazine] [visitable] [item] [item_location]" ) const itype_id ammo_id( "556" ); // any type of compatible ammo const itype_id alt_ammo( "223" ); // any alternative type of compatible ammo const itype_id bad_ammo( "9mm" ); // any type of incompatible ammo - const itype_id mag_id( "stanag10" ); // must be set to default magazine + const itype_id mag_id( "stanag30" ); // must be set to default magazine const itype_id bad_mag( "glockmag" ); // any incompatible magazine - const int mag_cap = 10; // amount of bullets that fit into default magazine + const int mag_cap = 30; // amount of bullets that fit into default magazine CHECK( ammo_id != alt_ammo ); CHECK( ammo_id != bad_ammo ); From c22a4b1cd26a7998917900ff37b109591f96dc22 Mon Sep 17 00:00:00 2001 From: andrei Date: Sun, 19 Jul 2020 01:11:46 +0300 Subject: [PATCH 111/151] bionics: fix battery system CBM for NPCs --- src/npcmove.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/npcmove.cpp b/src/npcmove.cpp index e8cd5640876e0..16e9e4463579c 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -1675,7 +1675,7 @@ bool npc::recharge_cbm() } else { const std::function fuel_filter = [bid]( const item & it ) { for( const itype_id &fid : bid->fuel_opts ) { - return it.typeId() == fid; + return ( it.typeId() == fid ) || ( it.is_magazine() && it.ammo_current() == fid ); } return false; }; From 40da61bbf8cd5b7f1207d98e0fa2cbc9192feff3 Mon Sep 17 00:00:00 2001 From: andrei Date: Sat, 18 Jul 2020 23:57:01 +0300 Subject: [PATCH 112/151] bionics: fix CBM default safe threshold replace flag with sign check --- src/bionics.cpp | 26 +++++++++----------------- src/bionics.h | 2 +- src/bionics_ui.cpp | 5 ++--- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/bionics.cpp b/src/bionics.cpp index e7b1df2f87f95..133318552e76d 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -202,7 +202,6 @@ static const std::string flag_NO_STERILE( "NO_STERILE" ); static const std::string flag_NO_UNWIELD( "NO_UNWIELD" ); static const std::string flag_PERPETUAL( "PERPETUAL" ); static const std::string flag_PERSONAL( "PERSONAL" ); -static const std::string flag_SAFE_FUEL_OFF( "SAFE_FUEL_OFF" ); static const std::string flag_SEALED( "SEALED" ); static const std::string flag_SEMITANGIBLE( "SEMITANGIBLE" ); @@ -1318,7 +1317,7 @@ bool Character::burn_fuel( int b, bool start ) current_fuel_stock = std::stoi( get_value( fuel.str() ) ); } - if( !bio.has_flag( flag_SAFE_FUEL_OFF ) && + if( bio.get_safe_fuel_thresh() > 0 && ( ( get_power_level() + units::from_kilojoule( fuel_energy ) * effective_efficiency > get_max_power_level() ) || ( ( ( get_power_level() + units::from_kilojoule( fuel_energy ) * effective_efficiency ) > @@ -2879,13 +2878,7 @@ bool bionic::is_this_fuel_powered( const itype_id &this_fuel ) const void bionic::toggle_safe_fuel_mod() { - if( info().fuel_opts.empty() && !info().is_remote_fueled ) { - return; - } - if( !has_flag( flag_SAFE_FUEL_OFF ) ) { - set_flag( flag_SAFE_FUEL_OFF ); - set_safe_fuel_thresh( 2.0 ); - } else { + if( !info().fuel_opts.empty() || info().is_remote_fueled ) { uilist tmenu; tmenu.text = _( "Chose Safe Fuel Level Threshold" ); tmenu.addentry( 1, true, 'o', _( "Full Power" ) ); @@ -2898,25 +2891,24 @@ void bionic::toggle_safe_fuel_mod() if( get_auto_start_thresh() < 0.30 ) { tmenu.addentry( 4, true, 's', _( "Above 30 %%" ) ); } + tmenu.addentry( 5, true, 'd', _( "Disabled" ) ); tmenu.query(); switch( tmenu.ret ) { case 1: - remove_flag( flag_SAFE_FUEL_OFF ); - set_safe_fuel_thresh( 1.0 ); + set_safe_fuel_thresh( 1.0f ); break; case 2: - remove_flag( flag_SAFE_FUEL_OFF ); - set_safe_fuel_thresh( 0.80 ); + set_safe_fuel_thresh( 0.80f ); break; case 3: - remove_flag( flag_SAFE_FUEL_OFF ); - set_safe_fuel_thresh( 0.55 ); + set_safe_fuel_thresh( 0.55f ); break; case 4: - remove_flag( flag_SAFE_FUEL_OFF ); - set_safe_fuel_thresh( 0.30 ); + set_safe_fuel_thresh( 0.30f ); break; + case 5: + set_safe_fuel_thresh( -1.0f ); default: break; } diff --git a/src/bionics.h b/src/bionics.h index b8dd19c7d3a80..791d9286bf96d 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -192,7 +192,7 @@ struct bionic { // generic bionic specific flags cata::flat_set bionic_tags; float auto_start_threshold = -1.0; - float safe_fuel_threshold = -1.0; + float safe_fuel_threshold = 1.0; }; // A simpler wrapper to allow forward declarations of it. std::vector can not diff --git a/src/bionics_ui.cpp b/src/bionics_ui.cpp index 5bac6b8558d13..f42bc94ef37fa 100644 --- a/src/bionics_ui.cpp +++ b/src/bionics_ui.cpp @@ -20,7 +20,6 @@ #include "units.h" static const std::string flag_PERPETUAL( "PERPETUAL" ); -static const std::string flag_SAFE_FUEL_OFF( "SAFE_FUEL_OFF" ); // '!', '-' and '=' are uses as default bindings in the menu const invlet_wrapper @@ -192,8 +191,8 @@ static std::string build_bionic_poweronly_string( const bionic &bio ) if( bio.incapacitated_time > 0_turns ) { properties.push_back( _( "(incapacitated)" ) ); } - if( !bio.has_flag( flag_SAFE_FUEL_OFF ) && ( !bio.info().fuel_opts.empty() || - bio.info().is_remote_fueled ) ) { + if( bio.get_safe_fuel_thresh() > 0 && ( !bio.info().fuel_opts.empty() || + bio.info().is_remote_fueled ) ) { //properties.push_back( _( "(fuel saving ON)" ) ); const std::string label = string_format( _( "(fuel saving ON > %d %%)" ), static_cast( bio.get_safe_fuel_thresh() * 100 ) ); From 4bc736c5add69231577e1ab2981bfd1d9776d378 Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Sat, 18 Jul 2020 16:31:33 -0600 Subject: [PATCH 113/151] 100% Artifical food 100% fake food Update cheap_food.json --- .../Aftershock/itemgroups/item_groups.json | 2 - .../itemgroups/vending_machine_group.json | 28 +++ .../items/comestibles/cheap_food.json | 182 ++++++++++++++++++ .../items/{ => comestibles}/comestibles.json | 51 ----- data/mods/Aftershock/maps/mapgen/s_gas.json | 20 +- 5 files changed, 220 insertions(+), 63 deletions(-) create mode 100644 data/mods/Aftershock/itemgroups/vending_machine_group.json create mode 100644 data/mods/Aftershock/items/comestibles/cheap_food.json rename data/mods/Aftershock/items/{ => comestibles}/comestibles.json (55%) diff --git a/data/mods/Aftershock/itemgroups/item_groups.json b/data/mods/Aftershock/itemgroups/item_groups.json index 5c4387a424d0b..9cd0073c35550 100644 --- a/data/mods/Aftershock/itemgroups/item_groups.json +++ b/data/mods/Aftershock/itemgroups/item_groups.json @@ -32,8 +32,6 @@ "id": "rare", "type": "item_group", "items": [ - [ "afs_calorie_pill", 10 ], - [ "afs_sundew", 10 ], [ "afs_bag_of_holding", 1 ], [ "afs_atomic_smartphone", 5 ], [ "laser_pack", 10 ], diff --git a/data/mods/Aftershock/itemgroups/vending_machine_group.json b/data/mods/Aftershock/itemgroups/vending_machine_group.json new file mode 100644 index 0000000000000..018531ee119e8 --- /dev/null +++ b/data/mods/Aftershock/itemgroups/vending_machine_group.json @@ -0,0 +1,28 @@ +[ + { + "type": "item_group", + "subtype": "collection", + "id": "afs_vending_false_meals", + "entries": [ + { "group": "afs_vending_false_meal_items", "count-min": 5, "count-max": 20 }, + { "group": "afs_vending_false_meal_items", "prob": 66, "count-min": 5, "count-max": 25 }, + { "group": "afs_vending_false_meal_items", "prob": 20, "count-min": 5, "count-max": 25 } + ] + }, + { + "type": "item_group", + "id": "afs_vending_false_meal_items", + "items": [ + [ "afs_h2o", 90 ], + [ "afs_sundew", 50 ], + [ "afs_food_to_go", 50 ], + [ "afs_calorie_pill", 10 ], + [ "afs_food_cube", 50 ], + [ "afs_cee_wafers", 50 ], + [ "afs_beefsim", 50 ], + [ "afs_soup_27", 50 ], + [ "afs_caffex", 50 ], + [ "afs_loop_fruit", 50 ] + ] + } +] diff --git a/data/mods/Aftershock/items/comestibles/cheap_food.json b/data/mods/Aftershock/items/comestibles/cheap_food.json new file mode 100644 index 0000000000000..fcb7be17dc631 --- /dev/null +++ b/data/mods/Aftershock/items/comestibles/cheap_food.json @@ -0,0 +1,182 @@ +[ + { + "id": "afs_calorie_pill", + "type": "COMESTIBLE", + "name": "nutriment", + "weight": "10 g", + "color": "white", + "comestible_type": "FOOD", + "symbol": "%", + "calories": 2000, + "healthy": 3, + "quench": -5, + "description": "A crumbly white pill half the size of your thumb, packed with vitamins and calories. Provides a whole day's nutrition in portable form, but it's a little hard to keep down, thanks to the rancid taste and chalky texture.", + "price": 10000, + "volume": 0, + "charges": 5, + "looks_like": "vitamins", + "fun": -8, + "freezing_point": -9999, + "vitamins": [ + [ "calcium", 24, 48 ], + [ "iron", 24, 48 ], + [ "vitA", 24, 48 ], + [ "vitB", 24, 48 ], + [ "vitC", 24, 48 ], + [ "bad_food", 10 ] + ] + }, + { + "id": "afs_calorie_water", + "type": "COMESTIBLE", + "name": "nutriment water", + "copy-from": "water_clean", + "comestible_type": "DRINK", + "color": "white", + "calories": 2000, + "healthy": 3, + "description": "Nutriment that has been dissolved in water to dilute its taste. Unnervingly resembles spoiled milk.", + "price": 10000, + "looks_like": "bleach", + "fun": -2, + "vitamins": [ + [ "calcium", 24, 48 ], + [ "iron", 24, 48 ], + [ "vitA", 24, 48 ], + [ "vitB", 24, 48 ], + [ "vitC", 24, 48 ], + [ "bad_food", 10 ] + ] + }, + { + "id": "afs_sundew", + "type": "COMESTIBLE", + "name": "sundew classic", + "copy-from": "water_clean", + "weight": "10 g", + "color": "yellow", + "healthy": 2, + "description": "An golden can of sundew, the leading soft drink of the world. Staring at the can, you feel a carving so intense that you are unsure whether its genuine, or if it has been carefully engineered and implanted into your mind.", + "price": 1000, + "looks_like": "diesel", + "container": "can_drink", + "fun": 10, + "stim": 4, + "vitamins": [ [ "bad_food", -6 ] ], + "flags": [ "LIGHT_2", "EATEN_HOT" ], + "freezing_point": -9999 + }, + { + "id": "afs_h2o", + "type": "COMESTIBLE", + "name": "Hā‚‚Oā„¢", + "copy-from": "water_clean", + "container": "can_drink", + "description": "When Thistle Industries successfully trademarked the chemical formula of water, you thought the world had gone irreparably insane, but things have only gotten worse since." + }, + { + "id": "afs_food_cube", + "type": "COMESTIBLE", + "name": "food cubes", + "symbol": "f", + "container": "bag_plastic", + "copy-from": "protein_bar_evac", + "color": "white", + "calories": 700, + "healthy": 3, + "charges": 2, + "description": "Smoothly blended edibles, neatly shaped into cubes for maximum enjoyment.", + "fun": 2, + "freezing_point": -9999, + "vitamins": [ [ "calcium", 30 ], [ "iron", 30 ], [ "vitA", 30 ], [ "vitB", 30 ], [ "vitC", 30 ], [ "bad_food", 1 ] ] + }, + { + "id": "afs_food_to_go", + "type": "COMESTIBLE", + "name": "Foodplace's Food-to-goā„¢", + "container": "bag_plastic", + "symbol": "f", + "copy-from": "protein_bar_evac", + "color": "magenta", + "calories": 500, + "healthy": 3, + "charges": 2, + "description": "Foodplaceā„¢ easy-storage Food-to-goā„¢ the choice Foodā„¢ for the contemporary Foodmanā„¢.", + "fun": 2, + "freezing_point": -9999 + }, + { + "id": "afs_loop_fruit", + "type": "COMESTIBLE", + "name": "loop 'fruit'", + "container": "bag_plastic", + "copy-from": "protein_bar_evac", + "color": "white", + "calories": 200, + "healthy": 3, + "description": "Rings of caramelized yellow colorant, tasting not exactly like apple.", + "fun": 2, + "freezing_point": -9999, + "vitamins": [ [ "iron", 1 ], [ "vitA", 1 ], [ "vitC", 10 ] ] + }, + { + "id": "afs_cee_wafers", + "type": "COMESTIBLE", + "name": "cee wafers", + "container": "can_food", + "copy-from": "protein_bar_evac", + "color": "white", + "material": [ "veggy" ], + "calories": 150, + "healthy": 3, + "charges": 3, + "description": "Smooth crackers colored grayish-green. Used to be perfectly edible seaweed, or so the wrapper claims.", + "fun": 2, + "freezing_point": -9999, + "vitamins": [ [ "calcium", 5 ], [ "iron", 5 ], [ "vitC", 10 ], [ "bad_food", 1 ] ] + }, + { + "id": "afs_beefsim", + "type": "COMESTIBLE", + "name": "beefsim", + "container": "can_food", + "copy-from": "protein_bar_evac", + "color": "red", + "calories": 250, + "material": [ "flesh", "veggy" ], + "healthy": 3, + "description": "Soy or pureed rat? Better not to know. \n(But its probably both.) ", + "fun": 0, + "charges": 2, + "freezing_point": -9999, + "vitamins": [ [ "calcium", 5 ], [ "iron", 5 ], [ "vitC", 10 ], [ "vitB", 10 ], [ "bad_food", 1 ] ] + }, + { + "id": "afs_soup_27", + "type": "COMESTIBLE", + "name": "soup, flavor 27", + "copy-from": "soup_cullenskink", + "container": "can_food", + "color": "red", + "calories": 450, + "material": [ "flesh", "veggy" ], + "healthy": 3, + "description": "Yellow chunks float on creamy liquid, like flotsam on a filthy summer pond. Branding implies at least 26 other flavors, but you have neither seen or heard about any of them.", + "fun": 0, + "freezing_point": -9999, + "vitamins": [ [ "calcium", 1 ], [ "iron", 10 ], [ "vitC", 5 ], [ "vitB", 10 ], [ "vitA", 5 ], [ "bad_food", 1 ] ] + }, + { + "id": "afs_caffex", + "type": "COMESTIBLE", + "name": "caffex", + "copy-from": "coffee", + "container": "can_drink", + "calories": 150, + "healthy": -3, + "description": "A dark and soapy beverage, pre-brewed and loaded with synthetic caffeine.", + "fun": 6, + "freezing_point": -9999, + "vitamins": [ [ "bad_food", 1 ] ] + } +] diff --git a/data/mods/Aftershock/items/comestibles.json b/data/mods/Aftershock/items/comestibles/comestibles.json similarity index 55% rename from data/mods/Aftershock/items/comestibles.json rename to data/mods/Aftershock/items/comestibles/comestibles.json index 635e8bb42b274..48d704dcbd5e9 100644 --- a/data/mods/Aftershock/items/comestibles.json +++ b/data/mods/Aftershock/items/comestibles/comestibles.json @@ -1,55 +1,4 @@ [ - { - "id": "afs_calorie_pill", - "type": "COMESTIBLE", - "name": "nutriment", - "weight": "10 g", - "color": "white", - "comestible_type": "FOOD", - "symbol": "%", - "calories": 2000, - "healthy": 3, - "quench": -5, - "description": "A crumbly white pill half the size of your thumb, packed with vitamins and calories. Provides a whole day's nutrition in portable form, but it's a little hard to keep down, thanks to the rancid taste and chalky texture.", - "price": 10000, - "volume": "0 L", - "charges": 5, - "looks_like": "vitamins", - "fun": -8, - "freezing_point": -9999, - "vitamins": [ [ "calcium", 24, 48 ], [ "iron", 24, 48 ], [ "vitA", 24, 48 ], [ "vitB", 24, 48 ], [ "vitC", 24, 48 ] ] - }, - { - "id": "afs_calorie_water", - "type": "COMESTIBLE", - "name": "nutriment water", - "copy-from": "water_clean", - "comestible_type": "DRINK", - "color": "white", - "calories": 2000, - "healthy": 3, - "description": "Nutriment that has been dissolved in water to dilute its taste. Unnervingly resembles spoiled milk.", - "price": 10000, - "looks_like": "bleach", - "fun": -2, - "vitamins": [ [ "calcium", 24, 48 ], [ "iron", 24, 48 ], [ "vitA", 24, 48 ], [ "vitB", 24, 48 ], [ "vitC", 24, 48 ] ] - }, - { - "id": "afs_sundew", - "type": "COMESTIBLE", - "name": "sundew", - "copy-from": "water_clean", - "weight": "10 g", - "color": "yellow", - "healthy": 2, - "description": "Water treated with some sort of chemical compound. It's incapable of freezing, is very light, and glows faintly. Drinking it seems to sharpen the senses.", - "price": 1000, - "looks_like": "diesel", - "container": "flask_glass", - "stim": 4, - "flags": [ "LIGHT_2", "EATEN_HOT" ], - "freezing_point": -9999 - }, { "id": "afs_sungel", "type": "COMESTIBLE", diff --git a/data/mods/Aftershock/maps/mapgen/s_gas.json b/data/mods/Aftershock/maps/mapgen/s_gas.json index da39a0ed5cc19..b51586a082fbd 100644 --- a/data/mods/Aftershock/maps/mapgen/s_gas.json +++ b/data/mods/Aftershock/maps/mapgen/s_gas.json @@ -19,11 +19,11 @@ "_sssssssss|V|kkk kkk|,", "_||=======||| |,", "_| th + kkkk |,", - "_|hth lll | rrrr F|,", - "_| |||+| F|,", - "_|h h |r c F|,", - "_|ddd |r c F|,", - "_| h |r | kkkk F|,", + "_|hth lll | rrrr Ʊ|,", + "_| |||+| Ʊ|,", + "_|h h |r c Ʊ|,", + "_|ddd |r c Ʊ|,", + "_| h |r | kkkk Ʊ|,", "_||||||3||||| kkkk |,", "________:& i| r|,", "________| + rrrr r|,", @@ -42,20 +42,20 @@ "toilets": { "&": { } }, "gaspumps": { "G": { } }, "items": { - "F": { "item": "fridgesnacks", "chance": 50, "repeat": [ 1, 2 ] }, "d": { "item": "office", "chance": 33, "repeat": [ 1, 2 ] }, "k": { "item": "snacks", "chance": 33, "repeat": [ 1, 2 ] } }, "place_loot": [ - { "item": "plut_cell", "x": 10, "y": 9, "chance": 80 }, - { "item": "plut_cell", "x": 10, "y": 9, "chance": 20, "repeat": [ 0, 1 ] }, - { "item": "plut_cell", "x": 10, "y": 9, "chance": 3, "repeat": [ 2, 5 ] }, + { "item": "plut_cell", "x": 11, "y": 9, "chance": 80 }, + { "item": "plut_cell", "x": 11, "y": 9, "chance": 20, "repeat": [ 0, 1 ] }, + { "item": "plut_cell", "x": 11, "y": 9, "chance": 3, "repeat": [ 2, 5 ] }, { "group": "behindcounter", "x": 9, "y": [ 14, 16 ], "chance": 80, "repeat": [ 0, 2 ] }, { "group": "road", "x": [ 15, 18 ], "y": 12, "chance": 33, "repeat": [ 0, 1 ] }, { "group": "magazines", "x": 9, "y": [ 14, 16 ], "chance": 90 }, { "group": "softdrugs", "x": [ 15, 18 ], "y": [ 20, 19 ], "chance": 80, "repeat": [ 0, 2 ] } ], - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.1 } ] + "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.1 } ], + "vendingmachines": { "Ʊ": { "item_group": "afs_vending_false_meals", "reinforced": true } } } } ] From 54e9ee1682060c74ff5b04a97de043b5aebdfc40 Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Sat, 18 Jul 2020 21:04:12 -0600 Subject: [PATCH 114/151] Update cheap_food.json --- data/mods/Aftershock/items/comestibles/cheap_food.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/mods/Aftershock/items/comestibles/cheap_food.json b/data/mods/Aftershock/items/comestibles/cheap_food.json index fcb7be17dc631..4d5c710e0828f 100644 --- a/data/mods/Aftershock/items/comestibles/cheap_food.json +++ b/data/mods/Aftershock/items/comestibles/cheap_food.json @@ -56,7 +56,7 @@ "weight": "10 g", "color": "yellow", "healthy": 2, - "description": "An golden can of sundew, the leading soft drink of the world. Staring at the can, you feel a carving so intense that you are unsure whether its genuine, or if it has been carefully engineered and implanted into your mind.", + "description": "An golden can of sundew, the leading soft drink of the world. Staring at the can, you feel a craving so intense that you are unsure whether its genuine, or if it has been carefully engineered and implanted into your mind.", "price": 1000, "looks_like": "diesel", "container": "can_drink", From caad75cf633c9aa25a00e66dd215643b09054d5c Mon Sep 17 00:00:00 2001 From: Qrox Date: Sat, 18 Jul 2020 20:13:39 +0800 Subject: [PATCH 115/151] Fix gas station console not working --- src/iexamine.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 47adc4fe784bc..ad4c129c0e23b 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -4046,11 +4046,13 @@ cata::optional iexamine::getNearFilledGasTank( const tripoint ¢er, auto check_for_fuel_tank = here.furn( tmp ); if( fuel_type == "gasoline" ) { - if( check_for_fuel_tank != furn_str_id( "f_gas_tank" ) ) { + if( check_for_fuel_tank != furn_str_id( "f_gas_tank" ) && + here.ter( tmp ) != ter_str_id( "t_gas_tank" ) ) { continue; } } else if( fuel_type == "diesel" ) { - if( check_for_fuel_tank != furn_str_id( "f_diesel_tank" ) ) { + if( check_for_fuel_tank != furn_str_id( "f_diesel_tank" ) && + here.ter( tmp ) != ter_str_id( "t_diesel_tank" ) ) { continue; } } From 70028b7295ebaa7a805607295db89157c2f9df34 Mon Sep 17 00:00:00 2001 From: GGgatherer <56833396+GGgatherer@users.noreply.github.com> Date: Sun, 19 Jul 2020 11:43:24 +0700 Subject: [PATCH 116/151] Fix #41550 - Favorite pockets menu - move options section before contents section * fix fav.pockets interface Move priority/white/blacklists section before pocket contents section. Otherwise it cannot be seen if there are many items in a pocket. * Update item_contents.cpp --- src/item_contents.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/item_contents.cpp b/src/item_contents.cpp index 0390702d1bf5e..970e0cd309f12 100644 --- a/src/item_contents.cpp +++ b/src/item_contents.cpp @@ -65,12 +65,16 @@ void pocket_favorite_callback::refresh( uilist *menu ) colorize( whitelist ? _( "whitelist" ) : _( "blacklist" ), c_light_blue ) ) ); selected_pocket->general_info( info, menu->selected + 1, true ); - selected_pocket->contents_info( info, menu->selected + 1, true ); starty += fold_and_print( menu->window, point( startx, starty ), width, - c_light_gray, format_item_info( info, {} ) ) + 2; + c_light_gray, format_item_info( info, {} ) ) + 1; info.clear(); selected_pocket->favorite_info( info ); + starty += fold_and_print( menu->window, point( startx, starty ), width, + c_light_gray, format_item_info( info, {} ) ) + 1; + + info.clear(); + selected_pocket->contents_info( info, menu->selected + 1, true ); fold_and_print( menu->window, point( startx, starty ), width, c_light_gray, format_item_info( info, {} ) ); } From 84c016c8d5085138a0f5df5010886961f8e45408 Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Sun, 19 Jul 2020 08:49:47 +0100 Subject: [PATCH 117/151] CI fixes 20200718 (#42262) * Don't compare bool to int This was giving a warning on Visual Studio. * Make memorial test platform-independent It failed on platforms with a different newline character. --- tests/battery_mod_test.cpp | 2 +- tests/memorial_test.cpp | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/tests/battery_mod_test.cpp b/tests/battery_mod_test.cpp index da1d6de7b2007..9ddd364f5a4c0 100644 --- a/tests/battery_mod_test.cpp +++ b/tests/battery_mod_test.cpp @@ -92,7 +92,7 @@ TEST_CASE( "battery tool mod test", "[battery][mod]" ) CHECK( mag_compats.count( itype_id( "medium_plus_battery_cell" ) ) == 1 ); CHECK( mag_compats.count( itype_id( "medium_atomic_battery_cell" ) ) == 1 ); CHECK( mag_compats.count( itype_id( "medium_disposable_cell" ) ) == 1 ); - CHECK( flashlight.contents.has_pocket_type( item_pocket::pocket_type::MAGAZINE_WELL ) == 1 ); + CHECK( flashlight.contents.has_pocket_type( item_pocket::pocket_type::MAGAZINE_WELL ) ); } THEN( "medium battery is now the default" ) { diff --git a/tests/memorial_test.cpp b/tests/memorial_test.cpp index bbda4972f5f05..22783d4213d7b 100644 --- a/tests/memorial_test.cpp +++ b/tests/memorial_test.cpp @@ -9,6 +9,7 @@ #include "character_id.h" #include "debug_menu.h" #include "event.h" +#include "filesystem.h" #include "game.h" #include "memorial_logger.h" #include "mutation.h" @@ -287,10 +288,14 @@ TEST_CASE( "memorials", "[memorial]" ) TEST_CASE( "convert_legacy_memorial_log", "[memorial]" ) { + std::string eol = cata_files::eol(); + // Verify that the old format can be transformed into the new format const std::string input = - "| Year 1, Spring, day 0 0800.00 | prison | Hubert 'Daffy' Mullin began their journey into the Cataclysm.\n" - "| Year 1, Spring, day 0 0800.05 | prison | Gained the mutation 'Debug Invincibility'.\n"; + "| Year 1, Spring, day 0 0800.00 | prison | " + "Hubert 'Daffy' Mullin began their journey into the Cataclysm." + eol + + "| Year 1, Spring, day 0 0800.05 | prison | Gained the mutation 'Debug Invincibility'." + + eol; const std::string json_value = R"([{"preformatted":"| Year 1, Spring, day 0 0800.00 | prison | Hubert 'Daffy' Mullin began their journey into the Cataclysm."},{"preformatted":"| Year 1, Spring, day 0 0800.05 | prison | Gained the mutation 'Debug Invincibility'."}])"; @@ -318,12 +323,16 @@ TEST_CASE( "convert_legacy_memorial_log", "[memorial]" ) TEST_CASE( "memorial_log_dumping", "[memorial]" ) { + std::string eol = cata_files::eol(); + // An example log file with one legacy and one "modern" entry const std::string json_value = R"([{"preformatted":"| Year 1, Spring, day 0 0800.00 | refugee center | Apolonia Trout began their journey into the Cataclysm."},{"time":15614,"oter_id":"cabin_isherwood","oter_name":"forest","message":"Used the debug menu (ENABLE_ACHIEVEMENTS)."}])"; const std::string expected_output = - "| Year 1, Spring, day 0 0800.00 | refugee center | Apolonia Trout began their journey into the Cataclysm.\n" - "| Year 1, Spring, day 1 4:20:14 AM | forest | Used the debug menu (ENABLE_ACHIEVEMENTS).\n"; + "| Year 1, Spring, day 0 0800.00 | refugee center | " + "Apolonia Trout began their journey into the Cataclysm." + eol + + "| Year 1, Spring, day 1 4:20:14 AM | forest | Used the debug menu (ENABLE_ACHIEVEMENTS)." + + eol; memorial_logger logger; std::istringstream is( json_value ); From 6e2952812428448c6cb119656fb9cc686c4a5fdb Mon Sep 17 00:00:00 2001 From: nexusmrsep <39925111+nexusmrsep@users.noreply.github.com> Date: Sun, 19 Jul 2020 10:22:52 +0200 Subject: [PATCH 118/151] Re-colorize achievements UI (#42228) --- src/achievement.cpp | 19 ++++++++++++------- src/scores_ui.cpp | 10 ++++++---- tests/stats_tracker_test.cpp | 4 ++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/achievement.cpp b/src/achievement.cpp index b96b914ff4815..dd5904dc778e2 100644 --- a/src/achievement.cpp +++ b/src/achievement.cpp @@ -124,11 +124,11 @@ std::string enum_to_string( requirement_visibility data } // namespace io -static nc_color color_from_completion( bool is_conduct, achievement_completion comp ) +static nc_color color_from_completion( bool is_conduct, achievement_completion comp, bool is_title ) { switch( comp ) { case achievement_completion::pending: - return is_conduct ? c_light_green : c_yellow; + return is_conduct ? c_light_green : ( is_title ? c_white : c_light_cyan ); case achievement_completion::completed: return c_light_green; case achievement_completion::failed: @@ -325,7 +325,7 @@ std::string achievement::time_bound::ui_text( bool is_conduct ) const time_point now = calendar::turn; achievement_completion comp = completed(); - nc_color c = color_from_completion( is_conduct, comp ); + nc_color c = color_from_completion( is_conduct, comp, false ); auto translate_epoch = []( epoch e ) { switch( e ) { @@ -570,8 +570,9 @@ std::string enum_to_string( achievement_completion data std::string achievement_state::ui_text( const achievement *ach ) const { // First: the achievement name and description - nc_color c = color_from_completion( ach->is_conduct(), completion ); - std::string result = colorize( ach->name(), c ) + "\n"; + nc_color c = color_from_completion( ach->is_conduct(), completion, false ); + nc_color c_title = color_from_completion( ach->is_conduct(), completion, true ); + std::string result = colorize( ach->name(), c_title ) + "\n"; if( !ach->description().empty() ) { result += " " + colorize( ach->description(), c ) + "\n"; } @@ -696,8 +697,12 @@ std::string achievement_tracker::ui_text() const // First: the achievement name and description nc_color c = color_from_completion( achievement_->is_conduct(), - achievement_completion::pending ); - std::string result = colorize( achievement_->name(), c ) + "\n"; + achievement_completion::pending, + false ); + nc_color c_title = color_from_completion( achievement_->is_conduct(), + achievement_completion::pending, + true ); + std::string result = colorize( achievement_->name(), c_title ) + "\n"; if( !achievement_->description().empty() ) { result += " " + colorize( achievement_->description(), c ) + "\n"; } diff --git a/src/scores_ui.cpp b/src/scores_ui.cpp index 5dab52482da32..7de86caa72296 100644 --- a/src/scores_ui.cpp +++ b/src/scores_ui.cpp @@ -19,7 +19,7 @@ #include "ui_manager.h" static std::string get_achievements_text( const achievements_tracker &achievements, - bool use_conducts ) + bool use_conducts, int width ) { std::string thing_name = use_conducts ? _( "conducts" ) : _( "achievements" ); std::string cap_thing_name = use_conducts ? _( "Conducts" ) : _( "Achievements" ); @@ -47,8 +47,10 @@ static std::string get_achievements_text( const achievements_tracker &achievemen return std::make_tuple( comp, ach->name().translated(), ach ); } ); std::sort( sortable_achievements.begin(), sortable_achievements.end(), localized_compare ); + char ch = string_from_int( LINE_OXOX ).at( 0 ); for( const sortable_achievement &ach : sortable_achievements ) { - os += achievements.ui_text_for( std::get( ach ) ) + "\n"; + os += achievements.ui_text_for( std::get( ach ) ); + os += colorize( std::string( width, ch ), c_magenta ); } if( valid_achievements.empty() ) { os += string_format( _( "This game has no valid %s.\n" ), thing_name ); @@ -132,10 +134,10 @@ void show_scores_ui( const achievements_tracker &achievements, stats_tracker &st if( new_tab ) { switch( tab ) { case tab_mode::achievements: - view.set_text( get_achievements_text( achievements, false ) ); + view.set_text( get_achievements_text( achievements, false, getmaxx( w ) - 2 ) ); break; case tab_mode::conducts: - view.set_text( get_achievements_text( achievements, true ) ); + view.set_text( get_achievements_text( achievements, true, getmaxx( w ) - 2 ) ); break; case tab_mode::scores: view.set_text( get_scores_text( stats ) ); diff --git a/tests/stats_tracker_test.cpp b/tests/stats_tracker_test.cpp index ca4ae73ea3d37..2266f9fefa2ad 100644 --- a/tests/stats_tracker_test.cpp +++ b/tests/stats_tracker_test.cpp @@ -638,11 +638,11 @@ TEST_CASE( "achievments_tracker", "[stats]" ) send_game_start( b, u_id ); CHECK( a.ui_text_for( &*a_kill_zombie ) == - "One down, billions to goā€¦\n" + "One down, billions to goā€¦\n" " 0/1 zombie killed\n" ); if( time_since_game_start < 1_minutes ) { CHECK( a.ui_text_for( &*a_kill_in_first_minute ) == - "Rude awakening\n" + "Rude awakening\n" " Within 1 minute of start of game (30 seconds remaining)\n" " 0/1 monster killed\n" ); } else { From 101ca0d7a3f52aed94303945d50c7053c9662ddd Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Sun, 19 Jul 2020 21:18:49 +0000 Subject: [PATCH 119/151] Migrate path accessors from game to path_info --- src/auto_note.cpp | 6 +++--- src/auto_pickup.cpp | 9 ++++----- src/clzones.cpp | 5 +++-- src/debug_menu.cpp | 3 ++- src/game.cpp | 27 ++++++++++++++------------- src/game.h | 10 ---------- src/mapbuffer.cpp | 5 +++-- src/overmapbuffer.cpp | 5 +++-- src/path_info.h | 2 ++ src/safemode_ui.cpp | 7 +++---- 10 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/auto_note.cpp b/src/auto_note.cpp index b03648b593946..140f50b5f9c5a 100644 --- a/src/auto_note.cpp +++ b/src/auto_note.cpp @@ -7,13 +7,13 @@ #include "color.h" #include "cursesdef.h" #include "filesystem.h" -#include "game.h" #include "generic_factory.h" #include "input.h" #include "json.h" #include "map_extras.h" #include "options.h" #include "output.h" +#include "path_info.h" #include "point.h" #include "translations.h" #include "ui_manager.h" @@ -22,7 +22,7 @@ namespace auto_notes { std::string auto_note_settings::build_save_path() const { - return g->get_player_base_save_path() + ".ano.json"; + return PATH_INFO::player_base_save_path() + ".ano.json"; } void auto_note_settings::clear() @@ -32,7 +32,7 @@ void auto_note_settings::clear() bool auto_note_settings::save() { - if( !file_exist( g->get_player_base_save_path() + ".sav" ) ) { + if( !file_exist( PATH_INFO::player_base_save_path() + ".sav" ) ) { return true; } diff --git a/src/auto_pickup.cpp b/src/auto_pickup.cpp index 7d8a4a917653e..9a944b89f03bd 100644 --- a/src/auto_pickup.cpp +++ b/src/auto_pickup.cpp @@ -12,7 +12,6 @@ #include "cursesdef.h" #include "debug.h" #include "filesystem.h" -#include "game.h" #include "input.h" #include "item.h" #include "item_factory.h" @@ -718,9 +717,9 @@ bool player_settings::save( const bool bCharacter ) auto savefile = PATH_INFO::autopickup(); if( bCharacter ) { - savefile = g->get_player_base_save_path() + ".apu.json"; + savefile = PATH_INFO::player_base_save_path() + ".apu.json"; - const std::string player_save = g->get_player_base_save_path() + ".sav"; + const std::string player_save = PATH_INFO::player_base_save_path() + ".sav"; //Character not saved yet. if( !file_exist( player_save ) ) { return true; @@ -747,7 +746,7 @@ void player_settings::load( const bool bCharacter ) { std::string sFile = PATH_INFO::autopickup(); if( bCharacter ) { - sFile = g->get_player_base_save_path() + ".apu.json"; + sFile = PATH_INFO::player_base_save_path() + ".apu.json"; } if( !read_from_file_optional_json( sFile, [&]( JsonIn & jsin ) { @@ -806,7 +805,7 @@ bool player_settings::load_legacy( const bool bCharacter ) std::string sFile = PATH_INFO::legacy_autopickup2(); if( bCharacter ) { - sFile = g->get_player_base_save_path() + ".apu.txt"; + sFile = PATH_INFO::player_base_save_path() + ".apu.txt"; } invalidate(); diff --git a/src/clzones.cpp b/src/clzones.cpp index 620bfad839580..95eb8929978b6 100644 --- a/src/clzones.cpp +++ b/src/clzones.cpp @@ -26,6 +26,7 @@ #include "map.h" #include "map_iterator.h" #include "output.h" +#include "path_info.h" #include "player.h" #include "string_formatter.h" #include "string_input_popup.h" @@ -1156,7 +1157,7 @@ void zone_data::deserialize( JsonIn &jsin ) bool zone_manager::save_zones() { - std::string savefile = g->get_player_base_save_path() + ".zones.json"; + std::string savefile = PATH_INFO::player_base_save_path() + ".zones.json"; added_vzones.clear(); changed_vzones.clear(); @@ -1169,7 +1170,7 @@ bool zone_manager::save_zones() void zone_manager::load_zones() { - std::string savefile = g->get_player_base_save_path() + ".zones.json"; + std::string savefile = PATH_INFO::player_base_save_path() + ".zones.json"; read_from_file_optional( savefile, [&]( std::istream & fin ) { JsonIn jsin( fin ); diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index 31bdcf905d998..dbc9d3f1adc3c 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -72,6 +72,7 @@ #include "overmap.h" #include "overmap_ui.h" #include "overmapbuffer.h" +#include "path_info.h" #include "pimpl.h" #include "player.h" #include "pldata.h" @@ -1851,7 +1852,7 @@ void debug() #if defined(TILES) // check that the current '/screenshots' directory exists std::stringstream map_directory; - map_directory << g->get_world_base_save_path() << "/screenshots/"; + map_directory << PATH_INFO::world_base_save_path() << "/screenshots/"; assure_dir_exist( map_directory.str() ); // build file name: /screenshots/[]_.png diff --git a/src/game.cpp b/src/game.cpp index 7b9d36b0c1f82..32536589bc78c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2809,7 +2809,7 @@ void game::death_screen() void game::move_save_to_graveyard() { - const std::string &save_dir = get_world_base_save_path(); + const std::string &save_dir = PATH_INFO::world_base_save_path(); const std::string &graveyard_dir = PATH_INFO::graveyarddir(); const std::string &prefix = base64_encode( u.name ) + "."; @@ -2843,7 +2843,7 @@ void game::move_save_to_graveyard() void game::load_master() { using namespace std::placeholders; - const auto datafile = get_world_base_save_path() + "/" + SAVE_MASTER; + const auto datafile = PATH_INFO::world_base_save_path() + "/" + SAVE_MASTER; read_from_file_optional( datafile, std::bind( &game::unserialize_master, this, _1 ) ); } @@ -2881,7 +2881,7 @@ bool game::load( const save_t &name ) using namespace std::placeholders; - const std::string worldpath = get_world_base_save_path() + "/"; + const std::string worldpath = PATH_INFO::world_base_save_path() + "/"; const std::string playerpath = worldpath + name.base_path(); // Now load up the master game data; factions (and more?) @@ -2924,7 +2924,8 @@ bool game::load( const save_t &name ) get_auto_notes_settings().load(); // Load character auto notes settings get_safemode().load_character(); // Load character safemode rules zone_manager::get_manager().load_zones(); // Load character world zones - read_from_file_optional( get_world_base_save_path() + "/uistate.json", []( std::istream & stream ) { + read_from_file_optional( PATH_INFO::world_base_save_path() + "/uistate.json", []( + std::istream & stream ) { JsonIn jsin( stream ); uistate.deserialize( jsin ); } ); @@ -2996,7 +2997,7 @@ void game::load_world_modfiles( loading_ui &ui ) mods.insert( mods.begin(), mod_id( "dda" ) ); } - load_artifacts( get_world_base_save_path() + "/" + SAVE_ARTIFACTS ); + load_artifacts( PATH_INFO::world_base_save_path() + "/" + SAVE_ARTIFACTS ); // this code does not care about mod dependencies, // it assumes that those dependencies are static and // are resolved during the creation of the world. @@ -3005,7 +3006,7 @@ void game::load_world_modfiles( loading_ui &ui ) load_packs( _( "Loading files" ), mods, ui ); // Load additional mods from that world-specific folder - load_data_from_dir( get_world_base_save_path() + "/mods", "custom", ui ); + load_data_from_dir( PATH_INFO::world_base_save_path() + "/mods", "custom", ui ); DynamicDataLoader::get_instance().finalize_loaded_data( ui ); } @@ -3081,7 +3082,7 @@ void game::reset_npc_dispositions() //Saves all factions and missions and npcs. bool game::save_factions_missions_npcs() { - std::string masterfile = get_world_base_save_path() + "/" + SAVE_MASTER; + std::string masterfile = PATH_INFO::world_base_save_path() + "/" + SAVE_MASTER; return write_to_file( masterfile, [&]( std::ostream & fout ) { serialize_master( fout ); }, _( "factions data" ) ); @@ -3089,7 +3090,7 @@ bool game::save_factions_missions_npcs() bool game::save_artifacts() { - std::string artfilename = get_world_base_save_path() + "/" + SAVE_ARTIFACTS; + std::string artfilename = PATH_INFO::world_base_save_path() + "/" + SAVE_ARTIFACTS; return ::save_artifacts( artfilename ); } @@ -3108,7 +3109,7 @@ bool game::save_maps() bool game::save_player_data() { - const std::string playerfile = get_player_base_save_path(); + const std::string playerfile = PATH_INFO::player_base_save_path(); const bool saved_data = write_to_file( playerfile + SAVE_EXTENSION, [&]( std::ostream & fout ) { serialize( fout ); @@ -3176,7 +3177,7 @@ bool game::save() !get_auto_pickup().save_character() || !get_auto_notes_settings().save() || !get_safemode().save_character() || - !write_to_file( get_world_base_save_path() + "/uistate.json", [&]( std::ostream & fout ) { + !write_to_file( PATH_INFO::world_base_save_path() + "/uistate.json", [&]( std::ostream & fout ) { JsonOut jsout( fout ); uistate.serialize( jsout ); }, _( "uistate data" ) ) ) { @@ -12495,12 +12496,12 @@ Creature *game::get_creature_if( const std::function & return nullptr; } -std::string game::get_player_base_save_path() const +std::string PATH_INFO::player_base_save_path() { - return get_world_base_save_path() + "/" + base64_encode( u.name ); + return PATH_INFO::world_base_save_path() + "/" + base64_encode( get_player_character().name ); } -std::string game::get_world_base_save_path() const +std::string PATH_INFO::world_base_save_path() { if( world_generator->active_world == nullptr ) { return PATH_INFO::savedir(); diff --git a/src/game.h b/src/game.h index da2924a2a458e..7697f646c5be6 100644 --- a/src/game.h +++ b/src/game.h @@ -179,16 +179,6 @@ class game /** Loads core data and mods from the active world. May throw. */ void load_world_modfiles( loading_ui &ui ); - /** - * Base path for saving player data. Just add a suffix (unique for - * the thing you want to save) and use the resulting path. - * Example: `save_ui_data(get_player_base_save_path()+".ui")` - */ - std::string get_player_base_save_path() const; - /** - * Base path for saving world data. This yields a path to a folder. - */ - std::string get_world_base_save_path() const; /** * Load content packs * @param msg string to display whilst loading prompt diff --git a/src/mapbuffer.cpp b/src/mapbuffer.cpp index 68a2ce922ede6..8b9dd9d1cbec8 100644 --- a/src/mapbuffer.cpp +++ b/src/mapbuffer.cpp @@ -17,6 +17,7 @@ #include "json.h" #include "map.h" #include "output.h" +#include "path_info.h" #include "popup.h" #include "string_formatter.h" #include "submap.h" @@ -33,7 +34,7 @@ static std::string find_quad_path( const std::string &dirname, const tripoint &o static std::string find_dirname( const tripoint &om_addr ) { const tripoint segment_addr = omt_to_seg_copy( om_addr ); - return string_format( "%s/maps/%d.%d.%d", g->get_world_base_save_path(), segment_addr.x, + return string_format( "%s/maps/%d.%d.%d", PATH_INFO::world_base_save_path(), segment_addr.x, segment_addr.y, segment_addr.z ); } @@ -104,7 +105,7 @@ submap *mapbuffer::lookup_submap( const tripoint &p ) void mapbuffer::save( bool delete_after_save ) { - assure_dir_exist( g->get_world_base_save_path() + "/maps" ); + assure_dir_exist( PATH_INFO::world_base_save_path() + "/maps" ); int num_saved_submaps = 0; int num_total_submaps = submaps.size(); diff --git a/src/overmapbuffer.cpp b/src/overmapbuffer.cpp index 9e210862e1eae..bf79c3af809e8 100644 --- a/src/overmapbuffer.cpp +++ b/src/overmapbuffer.cpp @@ -29,6 +29,7 @@ #include "overmap.h" #include "overmap_connection.h" #include "overmap_types.h" +#include "path_info.h" #include "rng.h" #include "simple_pathfinding.h" #include "string_formatter.h" @@ -61,12 +62,12 @@ int camp_reference::get_distance_from_bounds() const std::string overmapbuffer::terrain_filename( const point &p ) { - return string_format( "%s/o.%d.%d", g->get_world_base_save_path(), p.x, p.y ); + return string_format( "%s/o.%d.%d", PATH_INFO::world_base_save_path(), p.x, p.y ); } std::string overmapbuffer::player_filename( const point &p ) { - return string_format( "%s.seen.%d.%d", g->get_player_base_save_path(), p.x, p.y ); + return string_format( "%s.seen.%d.%d", PATH_INFO::player_base_save_path(), p.x, p.y ); } overmap &overmapbuffer::get( const point &p ) diff --git a/src/path_info.h b/src/path_info.h index 79923a7041ac0..be819f7ff8757 100644 --- a/src/path_info.h +++ b/src/path_info.h @@ -46,6 +46,7 @@ std::string jsondir(); std::string moddir(); std::string options(); std::string panel_options(); +std::string player_base_save_path(); std::string safemode(); std::string savedir(); std::string sokoban(); @@ -53,6 +54,7 @@ std::string templatedir(); std::string user_dir(); std::string user_keybindings(); std::string user_moddir(); +std::string world_base_save_path(); std::string worldoptions(); std::string crash(); std::string tileset_conf(); diff --git a/src/safemode_ui.cpp b/src/safemode_ui.cpp index bc2f4f7285b8e..62c91d522f3b1 100644 --- a/src/safemode_ui.cpp +++ b/src/safemode_ui.cpp @@ -15,7 +15,6 @@ #include "cursesdef.h" #include "debug.h" #include "filesystem.h" -#include "game.h" #include "input.h" #include "json.h" #include "monstergenerator.h" @@ -763,8 +762,8 @@ bool safemode::save( const bool is_character_in ) auto file = PATH_INFO::safemode(); if( is_character ) { - file = g->get_player_base_save_path() + ".sfm.json"; - if( !file_exist( g->get_player_base_save_path() + ".sav" ) ) { + file = PATH_INFO::player_base_save_path() + ".sfm.json"; + if( !file_exist( PATH_INFO::player_base_save_path() + ".sav" ) ) { return true; //Character not saved yet. } } @@ -796,7 +795,7 @@ void safemode::load( const bool is_character_in ) std::ifstream fin; std::string file = PATH_INFO::safemode(); if( is_character ) { - file = g->get_player_base_save_path() + ".sfm.json"; + file = PATH_INFO::player_base_save_path() + ".sfm.json"; } fin.open( file.c_str(), std::ifstream::in | std::ifstream::binary ); From 12e8c9b84945abcee1a5a1a45e966a243935d695 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Sun, 19 Jul 2020 23:11:05 +0000 Subject: [PATCH 120/151] Fix beaker volume. --- data/json/items/containers.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/items/containers.json b/data/json/items/containers.json index 9eb516d2ecf68..676653c61342d 100644 --- a/data/json/items/containers.json +++ b/data/json/items/containers.json @@ -928,7 +928,7 @@ "looks_like": "flask_glass", "description": "A 250ml laboratory beaker. Basically a cup with delusions of grandeur.", "weight": "150 g", - "volume": "141 ml", + "volume": "251 ml", "longest_side": "72 mm", "price": 500, "price_postapoc": 10, From 0ab011f57e9263d6f21ae830cfa972cb64439de6 Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Sun, 19 Jul 2020 05:38:07 -0400 Subject: [PATCH 121/151] Use common flag enum operator overloads We had various overloads of operator&, operator|, etc. for flag enums. These operators are annoying to write (they involve a lot of stat_casts and are easy to get copy-paste errors in) so write one common implementation in enum_traits.h and allow enums to opt-in via specializaing enum_traits accordingly. --- src/craft_command.h | 7 +----- src/crafting.h | 10 +++++--- src/enum_traits.h | 59 +++++++++++++++++++++++++++++++++++++++++++++ src/faction_camp.h | 9 ++++--- src/item.h | 31 +++++++----------------- src/name.h | 17 ++++++------- src/recipe.h | 9 +++---- src/requirements.h | 10 +++----- src/vehicle.h | 13 ++++------ 9 files changed, 100 insertions(+), 65 deletions(-) diff --git a/src/craft_command.h b/src/craft_command.h index f05f6e1362fde..4f746f14bc753 100644 --- a/src/craft_command.h +++ b/src/craft_command.h @@ -32,14 +32,9 @@ enum class usage_from : int { template<> struct enum_traits { static constexpr usage_from last = usage_from::num_usages_from; + static constexpr bool is_flag_enum = true; }; -inline bool operator&( usage_from l, usage_from r ) -{ - using I = std::underlying_type_t; - return static_cast( l ) & static_cast( r ); -} - /** * Struct that represents a selection of a component for crafting. */ diff --git a/src/crafting.h b/src/crafting.h index 0b03d28eb56b2..503aff8631d72 100644 --- a/src/crafting.h +++ b/src/crafting.h @@ -4,6 +4,8 @@ #include +#include "enum_traits.h" + class Character; class item; class player; @@ -13,10 +15,10 @@ enum class craft_flags : int { start_only = 1, // Only require 5% (plus remainder) of tool charges }; -inline constexpr craft_flags operator&( craft_flags l, craft_flags r ) -{ - return static_cast( static_cast( l ) & static_cast( r ) ); -} +template<> +struct enum_traits { + static constexpr bool is_flag_enum = true; +}; // removes any (removable) ammo from the item and stores it in the // players inventory. diff --git a/src/enum_traits.h b/src/enum_traits.h index f89069b1619ae..8fbfa7a21b6f9 100644 --- a/src/enum_traits.h +++ b/src/enum_traits.h @@ -21,4 +21,63 @@ struct has_enum_traits : std::false_type {}; template struct has_enum_traits> : std::true_type {}; +template +struct is_flag_enum : std::false_type {}; + +template +struct is_flag_enum::is_flag_enum>> : + std::true_type {}; + +// Annoyingly, you cannot overload conversions for enums, and we want +// operator& to be convertible to bool, so we have it return a helper struct +// which can be treated as a bool or an enum value. +template +struct enum_test_result { + E value; + + operator E() const { + return value; + } + bool operator!() const { + using I = std::underlying_type_t; + return !static_cast( value ); + } + explicit operator bool() const { + return !!*this; + } +}; + +template::value>> +inline enum_test_result operator&( E l, E r ) +{ + using I = std::underlying_type_t; + return { static_cast( static_cast( l ) & static_cast( r ) ) }; +} + +template::value>> +inline E operator|( E l, E r ) +{ + using I = std::underlying_type_t; + return static_cast( static_cast( l ) | static_cast( r ) ); +} + +template::value>> +inline E & operator&=( E &l, E r ) +{ + return l = l & r; +} + +template::value>> +inline E & operator|=( E &l, E r ) +{ + return l = l | r; +} + +template::value>> +inline bool operator!( E e ) +{ + using I = std::underlying_type_t; + return !static_cast( e ); +} + #endif // CATA_SRC_ENUM_TRAITS_H diff --git a/src/faction_camp.h b/src/faction_camp.h index 05ea8883892c1..6c10344d87414 100644 --- a/src/faction_camp.h +++ b/src/faction_camp.h @@ -22,10 +22,11 @@ enum class farm_ops : int { plant = 2, harvest = 4 }; -inline bool operator&( const farm_ops &rhs, const farm_ops &lhs ) -{ - return static_cast( rhs ) & static_cast( lhs ); -} + +template<> +struct enum_traits { + static constexpr bool is_flag_enum = true; +}; std::string get_mission_action_string( const std::string &input_mission ); diff --git a/src/item.h b/src/item.h index dc07a7f90a016..a773124ee1417 100644 --- a/src/item.h +++ b/src/item.h @@ -157,22 +157,16 @@ struct iteminfo { iteminfo( const std::string &Type, const std::string &Name, double Value ); }; +template<> +struct enum_traits { + static constexpr bool is_flag_enum = true; +}; + iteminfo vol_to_info( const std::string &type, const std::string &left, const units::volume &vol, int decimal_places = 2 ); iteminfo weight_to_info( const std::string &type, const std::string &left, const units::mass &weight, int decimal_places = 2 ); -inline iteminfo::flags operator|( iteminfo::flags l, iteminfo::flags r ) -{ - using I = std::underlying_type::type; - return static_cast( static_cast( l ) | r ); -} - -inline iteminfo::flags &operator|=( iteminfo::flags &l, iteminfo::flags r ) -{ - return l = l | r; -} - inline bool is_crafting_component( const item &component ); class item : public visitable @@ -2288,17 +2282,10 @@ class item : public visitable void update_clothing_mod_val(); }; -inline item::encumber_flags operator&( item::encumber_flags l, item::encumber_flags r ) -{ - using I = std::underlying_type_t; - return static_cast( static_cast( l ) & static_cast( r ) ); -} - -inline bool operator!( item::encumber_flags f ) -{ - using I = std::underlying_type_t; - return !static_cast( f ); -} +template<> +struct enum_traits { + static constexpr bool is_flag_enum = true; +}; bool item_compare_by_charges( const item &left, const item &right ); bool item_ptr_compare_by_charges( const item *left, const item *right ); diff --git a/src/name.h b/src/name.h index 1b5b5a0305651..7bb32ab6cda4b 100644 --- a/src/name.h +++ b/src/name.h @@ -4,6 +4,8 @@ #include +#include "enum_traits.h" + enum class nameFlags : int { IsMaleName = 1 << 0, IsFemaleName = 1 << 1, @@ -16,6 +18,11 @@ enum class nameFlags : int { IsWorldName = 1 << 7 }; +template<> +struct enum_traits { + static constexpr bool is_flag_enum = true; +}; + namespace Name { /// Load names from given json file to use for generation @@ -31,14 +38,4 @@ std::string generate( bool is_male ); void clear(); } // namespace Name -inline nameFlags operator|( nameFlags l, nameFlags r ) -{ - return static_cast( static_cast( l ) | static_cast( r ) ); -} - -inline nameFlags operator&( nameFlags l, nameFlags r ) -{ - return static_cast( static_cast( l ) & static_cast( r ) ); -} - #endif // CATA_SRC_NAME_H diff --git a/src/recipe.h b/src/recipe.h index 752b98ee86617..3abbd1748b893 100644 --- a/src/recipe.h +++ b/src/recipe.h @@ -25,11 +25,10 @@ enum class recipe_filter_flags : int { no_rotten = 1, }; -inline constexpr recipe_filter_flags operator&( recipe_filter_flags l, recipe_filter_flags r ) -{ - return static_cast( - static_cast( l ) & static_cast( r ) ); -} +template<> +struct enum_traits { + static constexpr bool is_flag_enum = true; +}; struct recipe_proficiency { proficiency_id id; diff --git a/src/requirements.h b/src/requirements.h index ecb8067770860..a33191d52b9cd 100644 --- a/src/requirements.h +++ b/src/requirements.h @@ -163,12 +163,10 @@ enum class requirement_display_flags : int { no_unavailable = 1, }; -inline constexpr requirement_display_flags operator&( requirement_display_flags l, - requirement_display_flags r ) -{ - return static_cast( - static_cast( l ) & static_cast( r ) ); -} +template<> +struct enum_traits { + static constexpr bool is_flag_enum = true; +}; /** * The *_vector members represent list of alternatives requirements: diff --git a/src/vehicle.h b/src/vehicle.h index 234b195b8d5fb..e90a1f750f595 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -83,14 +83,11 @@ enum class part_status_flag : int { available = 1 << 1, enabled = 1 << 2 }; -part_status_flag inline operator|( const part_status_flag &rhs, const part_status_flag &lhs ) -{ - return static_cast( static_cast( lhs ) | static_cast( rhs ) ); -} -int inline operator&( const part_status_flag &rhs, const part_status_flag &lhs ) -{ - return static_cast( lhs ) & static_cast( rhs ); -} + +template<> +struct enum_traits { + static constexpr bool is_flag_enum = true; +}; enum veh_coll_type : int { veh_coll_nothing, // 0 - nothing, From 0a769ddb98860d76fcd59e432fe058bf6eabc179 Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Sun, 19 Jul 2020 06:01:31 -0400 Subject: [PATCH 122/151] Document enum_traits --- src/enum_traits.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/enum_traits.h b/src/enum_traits.h index 8fbfa7a21b6f9..2ccef7d7aed0a 100644 --- a/src/enum_traits.h +++ b/src/enum_traits.h @@ -4,6 +4,43 @@ #include +// enum_traits is a template you can specialize for your enum types. It serves +// two purposes: +// * Picking out the special "last" enumerator if you have one. This is used +// by various generic code to iterate over all the enumerators. Most notably +// it enables io::string_to_enum and thereby string-based json serialization. +// * Specifying that your enum is a flag enum, and therefore that you want +// bitwise operators to work for it. This saves everyone from implemetning +// those operators independently. +// +// Usage examples: +// +// For a 'regular' enum +// +// enum ordinal { +// first, +// second, +// third, +// last +// }; +// +// template<> +// struct enum_traits { +// static constexpr ordinal last = ordinal::last; +// }; +// +// For a flag enum +// +// enum my_flags { +// option_one = 1 << 0, +// option_two = 1 << 1, +// }; +// +// template<> +// struct enum_traits { +// static constexpr bool is_flag_enum = true; +// }; + template struct enum_traits; From 00baf2b753250ed51c9537aed8e8e34142cf921e Mon Sep 17 00:00:00 2001 From: Fris0uman <41293484+Fris0uman@users.noreply.github.com> Date: Mon, 20 Jul 2020 03:09:33 +0200 Subject: [PATCH 123/151] Move remaining enum arrays to bodypart (#41877) --- data/json/body_parts.json | 13 +++ doc/JSON_INFO.md | 2 + src/bodypart.cpp | 89 ++++++++++++++ src/bodypart.h | 29 ++++- src/character.cpp | 194 ++++++++++++++----------------- src/character.h | 7 +- src/character_oracle.cpp | 4 +- src/creature.cpp | 108 +++++++++++++++++ src/creature.h | 25 +++- src/effect.h | 2 +- src/game.cpp | 11 +- src/iuse.cpp | 2 +- src/panels.cpp | 50 ++++---- src/player.cpp | 23 ++-- src/player_display.cpp | 32 +++-- src/player_hardcoded_effects.cpp | 34 +++--- src/savegame_json.cpp | 96 ++++++++++++--- src/suffer.cpp | 31 +++-- src/weather.cpp | 5 +- tests/iuse_test.cpp | 24 ++-- tests/player_test.cpp | 22 ++-- 21 files changed, 544 insertions(+), 259 deletions(-) diff --git a/data/json/body_parts.json b/data/json/body_parts.json index c55f0943ac93b..fd41e44d69423 100644 --- a/data/json/body_parts.json +++ b/data/json/body_parts.json @@ -20,6 +20,7 @@ "cold_morale_mod": 2, "squeamish_penalty": 6, "base_hp": 60, + "drench_capacity": 40, "bionic_slots": 80 }, { @@ -43,6 +44,7 @@ "cold_morale_mod": 2, "squeamish_penalty": 7, "base_hp": 60, + "drench_capacity": 7, "bionic_slots": 18 }, { @@ -63,6 +65,7 @@ "stylish_bonus": 2, "squeamish_penalty": 8, "base_hp": 60, + "drench_capacity": 1, "bionic_slots": 4 }, { @@ -85,6 +88,7 @@ "cold_morale_mod": 2, "squeamish_penalty": 9, "base_hp": 60, + "drench_capacity": 1, "bionic_slots": 4 }, { @@ -111,6 +115,7 @@ "squeamish_penalty": 5, "is_limb": true, "base_hp": 60, + "drench_capacity": 10, "bionic_slots": 20 }, { @@ -136,6 +141,7 @@ "squeamish_penalty": 5, "is_limb": true, "base_hp": 60, + "drench_capacity": 10, "bionic_slots": 20 }, { @@ -160,6 +166,7 @@ "cold_morale_mod": 0.5, "squeamish_penalty": 3, "base_hp": 60, + "drench_capacity": 3, "bionic_slots": 5 }, { @@ -184,6 +191,7 @@ "cold_morale_mod": 0.5, "squeamish_penalty": 3, "base_hp": 60, + "drench_capacity": 3, "bionic_slots": 5 }, { @@ -210,6 +218,7 @@ "squeamish_penalty": 5, "is_limb": true, "base_hp": 60, + "drench_capacity": 11, "bionic_slots": 30 }, { @@ -236,6 +245,7 @@ "squeamish_penalty": 5, "is_limb": true, "base_hp": 60, + "drench_capacity": 11, "bionic_slots": 30 }, { @@ -260,6 +270,7 @@ "cold_morale_mod": 0.5, "squeamish_penalty": 3, "base_hp": 60, + "drench_capacity": 3, "bionic_slots": 7 }, { @@ -284,6 +295,7 @@ "cold_morale_mod": 0.5, "squeamish_penalty": 3, "base_hp": 60, + "drench_capacity": 3, "bionic_slots": 7 }, { @@ -301,6 +313,7 @@ "hit_difficulty": 0, "side": "both", "base_hp": 60, + "drench_capacity": 1, "legacy_id": "NUM_BP" } ] diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 912ebcf3bf586..509c0d6874bf8 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -475,6 +475,7 @@ This section describes each json file and their contents. Each json has their ow | hit_size | (_mandatory_) Size of the body part when doing an unweighted selection. | hit_size_relative | (_mandatory_) Hit sizes for attackers who are smaller, equal in size, and bigger. | hit_difficulty | (_mandatory_) How hard is it to hit a given body part, assuming "owner" is hit. Higher number means good hits will veer towards this part, lower means this part is unlikely to be hit by inaccurate attacks. Formula is `chance *= pow(hit_roll, hit_difficulty)` +| drench_capacity | (_mandatory_) How wet this part can get before being 100% drenched. | stylish_bonus | (_optional_) Mood bonus associated with wearing fancy clothing on this part. (default: `0`) | hot_morale_mod | (_optional_) Mood effect of being too hot on this part. (default: `0`) | cold_morale_mod | (_optional_) Mood effect of being too cold on this part. (default: `0`) @@ -505,6 +506,7 @@ This section describes each json file and their contents. Each json has their ow "cold_morale_mod": 2, "squeamish_penalty": 6, "base_hp": 60, + "drench_capacity": 40, "stat_hp_mods": { "int_mod": 4.0, "dex_mod": 1.0, "str_mod": 1.0, "per_mod": 1.0, "health_mod": 1.0 }, "bionic_slots": 80 } diff --git a/src/bodypart.cpp b/src/bodypart.cpp index 69528fb67a020..883cd9a227822 100644 --- a/src/bodypart.cpp +++ b/src/bodypart.cpp @@ -223,7 +223,10 @@ void body_part_type::load( const JsonObject &jo, const std::string & ) mandatory( jo, was_loaded, "base_hp", base_hp ); optional( jo, was_loaded, "stat_hp_mods", hp_mods ); + mandatory( jo, was_loaded, "drench_capacity", drench_max ); + optional( jo, was_loaded, "is_limb", is_limb, false ); + mandatory( jo, was_loaded, "drench_capacity", drench_max ); mandatory( jo, was_loaded, "legacy_id", legacy_id ); token = legacy_id_to_enum( legacy_id ); @@ -408,6 +411,11 @@ bool bodypart::is_at_max_hp() const return hp_cur == hp_max; } +float bodypart::get_wetness_percentage() const +{ + return static_cast( wetness ) / drench_capacity; +} + int bodypart::get_hp_cur() const { return hp_cur; @@ -438,6 +446,31 @@ encumbrance_data bodypart::get_encumbrance_data() const return encumb_data; } +int bodypart::get_drench_capacity() const +{ + return drench_capacity; +} + +int bodypart::get_wetness() const +{ + return wetness; +} + +int bodypart::get_frotbite_timer() const +{ + return frostbite_timer; +} + +int bodypart::get_temp_cur() const +{ + return temp_cur; +} + +int bodypart::get_temp_conv() const +{ + return temp_conv; +} + void bodypart::set_hp_cur( int set ) { hp_cur = set; @@ -468,6 +501,31 @@ void bodypart::set_encumbrance_data( encumbrance_data set ) encumb_data = set; } +void bodypart::set_wetness( int set ) +{ + wetness = set; +} + +void bodypart::set_drench_capacity( int set ) +{ + drench_capacity = set; +} + +void bodypart::set_temp_cur( int set ) +{ + temp_cur = set; +} + +void bodypart::set_temp_conv( int set ) +{ + temp_conv = set; +} + +void bodypart::set_frostbite_timer( int set ) +{ + frostbite_timer = set; +} + void bodypart::mod_hp_cur( int mod ) { hp_cur += mod; @@ -493,6 +551,26 @@ void bodypart::mod_damage_disinfected( int mod ) damage_disinfected += mod; } +void bodypart::mod_wetness( int mod ) +{ + wetness += mod; +} + +void bodypart::mod_temp_cur( int mod ) +{ + temp_cur += mod; +} + +void bodypart::mod_temp_conv( int mod ) +{ + temp_conv += mod; +} + +void bodypart::mod_frostbite_timer( int mod ) +{ + frostbite_timer += mod; +} + void bodypart::serialize( JsonOut &json ) const { json.start_object(); @@ -501,6 +579,12 @@ void bodypart::serialize( JsonOut &json ) const json.member( "hp_max", hp_max ); json.member( "damage_bandaged", damage_bandaged ); json.member( "damage_disinfected", damage_disinfected ); + + json.member( "wetness", wetness ); + json.member( "temp_cur", temp_cur ); + json.member( "temp_conv", temp_conv ); + json.member( "frostbite_timer", frostbite_timer ); + json.end_object(); } @@ -512,6 +596,11 @@ void bodypart::deserialize( JsonIn &jsin ) jo.read( "hp_max", hp_max, true ); jo.read( "damage_bandaged", damage_bandaged, true ); jo.read( "damage_disinfected", damage_disinfected, true ); + + jo.read( "wetness", wetness, true ); + jo.read( "temp_cur", temp_cur, true ); + jo.read( "temp_conv", temp_conv, true ); + jo.read( "frostbite_timer", frostbite_timer, true ); } void stat_hp_mods::load( const JsonObject &jsobj ) diff --git a/src/bodypart.h b/src/bodypart.h index 90ad88715973a..d8786137d7d93 100644 --- a/src/bodypart.h +++ b/src/bodypart.h @@ -132,6 +132,8 @@ struct body_part_type { bool is_limb = false; + int drench_max; + void load( const JsonObject &jo, const std::string &src ); void finalize(); void check() const; @@ -200,6 +202,12 @@ class bodypart int hp_cur; int hp_max; + int drench_capacity; + int wetness = 0; + int temp_cur = 5000; // BODYTEMP_NORM = 5000 + int temp_conv = 5000; + int frostbite_timer = 0; + int healed_total = 0; int damage_bandaged = 0; int damage_disinfected = 0; @@ -207,19 +215,27 @@ class bodypart encumbrance_data encumb_data; public: - bodypart(): id( bodypart_str_id( "num_bp" ) ), hp_cur( 0 ), hp_max( 0 ) {} - bodypart( bodypart_str_id id ): id( id ), hp_cur( id->base_hp ), hp_max( id->base_hp ) {} + bodypart(): id( bodypart_str_id( "num_bp" ) ), hp_cur( 0 ), hp_max( 0 ), drench_capacity( 1 ) {} + bodypart( bodypart_str_id id ): id( id ), hp_cur( id->base_hp ), hp_max( id->base_hp ), + drench_capacity( id->drench_max ) {} bodypart_id get_id() const; void set_hp_to_max(); bool is_at_max_hp() const; + float get_wetness_percentage() const; + int get_hp_cur() const; int get_hp_max() const; int get_healed_total() const; int get_damage_bandaged() const; int get_damage_disinfected() const; + int get_drench_capacity() const; + int get_wetness() const; + int get_frotbite_timer() const; + int get_temp_cur() const; + int get_temp_conv() const; encumbrance_data get_encumbrance_data() const; @@ -228,6 +244,11 @@ class bodypart void set_healed_total( int set ); void set_damage_bandaged( int set ); void set_damage_disinfected( int set ); + void set_wetness( int set ); + void set_drench_capacity( int set ); + void set_temp_cur( int set ); + void set_temp_conv( int set ); + void set_frostbite_timer( int set ); void set_encumbrance_data( encumbrance_data set ); @@ -236,6 +257,10 @@ class bodypart void mod_healed_total( int mod ); void mod_damage_bandaged( int mod ); void mod_damage_disinfected( int mod ); + void mod_wetness( int mod ); + void mod_temp_cur( int mod ); + void mod_temp_conv( int mod ); + void mod_frostbite_timer( int mod ); void serialize( JsonOut &json ) const; void deserialize( JsonIn &jsin ); diff --git a/src/character.cpp b/src/character.cpp index f34183bb86741..580e812c81c22 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -449,24 +449,6 @@ Character::Character() : move_mode = move_mode_id( "walk" ); next_expected_position = cata::nullopt; - temp_cur.fill( BODYTEMP_NORM ); - frostbite_timer.fill( 0 ); - temp_conv.fill( BODYTEMP_NORM ); - - body_wetness.fill( 0 ); - - drench_capacity[bp_eyes] = 1; - drench_capacity[bp_mouth] = 1; - drench_capacity[bp_head] = 7; - drench_capacity[bp_leg_l] = 11; - drench_capacity[bp_leg_r] = 11; - drench_capacity[bp_foot_l] = 3; - drench_capacity[bp_foot_r] = 3; - drench_capacity[bp_arm_l] = 10; - drench_capacity[bp_arm_r] = 10; - drench_capacity[bp_hand_l] = 3; - drench_capacity[bp_hand_r] = 3; - drench_capacity[bp_torso] = 40; } // *INDENT-ON* @@ -5611,8 +5593,8 @@ HURRICANE : 185 mph (880 hPa) [Ref: Hurricane Wilma] void Character::update_bodytemp() { if( has_trait( trait_DEBUG_NOTEMP ) ) { - temp_cur.fill( BODYTEMP_NORM ); - temp_conv.fill( BODYTEMP_NORM ); + set_all_parts_temp_conv( BODYTEMP_NORM ); + set_all_parts_temp_cur( BODYTEMP_NORM ); return; } /* Cache calls to g->get_temperature( player position ), used in several places in function */ @@ -5697,7 +5679,7 @@ void Character::update_bodytemp() // Represents the fact that the body generates heat when it is cold. // TODO: : should this increase hunger? double scaled_temperature = logarithmic_range( BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, - temp_cur[bp->token] ); + get_part_temp_cur( bp ) ); // Produces a smooth curve between 30.0 and 60.0. double homeostasis_adjustement = 30.0 * ( 1.0 + scaled_temperature ); int clothing_warmth_adjustement = static_cast( homeostasis_adjustement * warmth( bp ) ); @@ -5727,20 +5709,20 @@ void Character::update_bodytemp() // Convergent temperature is affected by ambient temperature, // clothing warmth, and body wetness. - temp_conv[bp->token] = BODYTEMP_NORM + adjusted_temp + windchill * 100 + - clothing_warmth_adjustement; + set_part_temp_conv( bp, BODYTEMP_NORM + adjusted_temp + windchill * 100 + + clothing_warmth_adjustement ); // HUNGER / STARVATION - temp_conv[bp->token] += hunger_warmth; + mod_part_temp_conv( bp, hunger_warmth ); // FATIGUE - temp_conv[bp->token] += fatigue_warmth; + mod_part_temp_conv( bp, fatigue_warmth ); // Mutations - temp_conv[bp->token] += mutation_heat_low; + mod_part_temp_conv( bp, mutation_heat_low ); // DIRECT HEAT SOURCES (generates body heat, helps fight frostbite) // Bark : lowers blister count to -5; harder to get blisters int blister_count = ( has_bark ? -5 : 0 ); // If the counter is high, your skin starts to burn - if( frostbite_timer[bp->token] > 0 ) { - frostbite_timer[bp->token] -= std::max( 5, h_radiation ); + if( get_part_frostbite_timer( bp ) > 0 ) { + mod_part_frostbite_timer( bp, -std::max( 5, h_radiation ) ); } // 111F (44C) is a temperature in which proteins break down: https://en.wikipedia.org/wiki/Burn blister_count += h_radiation - 111 > 0 ? @@ -5763,16 +5745,16 @@ void Character::update_bodytemp() rem_morale( MORALE_PYROMANIA_NOFIRE ); } - temp_conv[bp->token] += sunlight_warmth; + mod_part_temp_conv( bp, sunlight_warmth ); // DISEASES if( bp == bodypart_id( "head" ) && has_effect( effect_flu ) ) { - temp_conv[bp->token] += 1500; + mod_part_temp_conv( bp, 1500 ); } if( has_common_cold ) { - temp_conv[bp->token] -= 750; + mod_part_temp_conv( bp, -750 ); } // Loss of blood results in loss of body heat, 1% bodyheat lost per 2% hp lost - temp_conv[bp->token] -= blood_loss( bp ) * temp_conv[bp->token] / 200; + mod_part_temp_conv( bp, - blood_loss( bp ) * get_part_temp_conv( bp ) / 200 ); // EQUALIZATION if( bp == bodypart_id( "torso" ) ) { @@ -5812,7 +5794,7 @@ void Character::update_bodytemp() // Climate Control eases the effects of high and low ambient temps if( has_climate_control ) { - temp_conv[bp->token] = temp_corrected_by_climate_control( temp_conv[bp->token] ); + set_part_temp_conv( bp, temp_corrected_by_climate_control( get_part_temp_conv( bp ) ) ); } // FINAL CALCULATION : Increments current body temperature towards convergent. @@ -5857,21 +5839,21 @@ void Character::update_bodytemp() if( bonus_warmth > 0 ) { // Approximate temp_conv needed to reach comfortable temperature in this very turn // Basically inverted formula for temp_cur below - int desired = 501 * BODYTEMP_NORM - 499 * temp_cur[bp->token]; + int desired = 501 * BODYTEMP_NORM - 499 * get_part_temp_conv( bp ); if( std::abs( BODYTEMP_NORM - desired ) < 1000 ) { desired = BODYTEMP_NORM; // Ensure that it converges } else if( desired > BODYTEMP_HOT ) { desired = BODYTEMP_HOT; // Cap excess at sane temperature } - if( desired < temp_conv[bp->token] ) { + if( desired < get_part_temp_conv( bp ) ) { // Too hot, can't help here - } else if( desired < temp_conv[bp->token] + bonus_warmth ) { + } else if( desired < get_part_temp_conv( bp ) + bonus_warmth ) { // Use some heat, but not all of it - temp_conv[bp->token] = desired; + set_part_temp_conv( bp, desired ); } else { // Use all the heat - temp_conv[bp->token] += bonus_warmth; + mod_part_temp_conv( bp, bonus_warmth ); } // Morale bonus for comfiness - only if actually comfy (not too warm/cold) @@ -5882,13 +5864,14 @@ void Character::update_bodytemp() ( 1_minutes * bp->token ) / to_turns( 1_minutes * num_bp ) && get_effect_int( effect_cold, num_bp ) == 0 && get_effect_int( effect_hot, num_bp ) == 0 && - temp_cur[bp->token] > BODYTEMP_COLD && temp_cur[bp->token] <= BODYTEMP_NORM ) { + get_part_temp_conv( bp ) > BODYTEMP_COLD && get_part_temp_conv( bp ) <= BODYTEMP_NORM ) { add_morale( MORALE_COMFY, 1, 10, 2_minutes, 1_minutes, true ); } } - int temp_before = temp_cur[bp->token]; - int temp_difference = temp_before - temp_conv[bp->token]; // Negative if the player is warming up. + const int temp_before = get_part_temp_cur( bp ); + const int cur_temp_conv = get_part_temp_conv( bp ); + int temp_difference = temp_before - cur_temp_conv; // Negative if the player is warming up. // exp(-0.001) : half life of 60 minutes, exp(-0.002) : half life of 30 minutes, // exp(-0.003) : half life of 20 minutes, exp(-0.004) : half life of 15 minutes int rounding_error = 0; @@ -5896,59 +5879,54 @@ void Character::update_bodytemp() if( temp_difference < 0 && temp_difference > -600 ) { rounding_error = 1; } - if( temp_cur[bp->token] != temp_conv[bp->token] ) { - temp_cur[bp->token] = static_cast( temp_difference * std::exp( -0.002 ) + temp_conv[bp->token] - + - rounding_error ); + if( temp_before != cur_temp_conv ) { + set_part_temp_cur( bp, static_cast( temp_difference * std::exp( -0.002 ) + cur_temp_conv + + rounding_error ) ); } // This statement checks if we should be wearing our bonus warmth. // If, after all the warmth calculations, we should be, then we have to recalculate the temperature. if( clothing_warmth_adjusted_bonus != 0 && - ( ( temp_conv[bp->token] + clothing_warmth_adjusted_bonus ) < BODYTEMP_HOT || - temp_cur[bp->token] < BODYTEMP_COLD ) ) { - temp_conv[bp->token] += clothing_warmth_adjusted_bonus; + ( ( cur_temp_conv + clothing_warmth_adjusted_bonus ) < BODYTEMP_HOT || + get_part_temp_cur( bp ) < BODYTEMP_COLD ) ) { + mod_part_temp_conv( bp, clothing_warmth_adjusted_bonus ); rounding_error = 0; if( temp_difference < 0 && temp_difference > -600 ) { rounding_error = 1; } - if( temp_before != temp_conv[bp->token] ) { - temp_difference = temp_before - temp_conv[bp->token]; - temp_cur[bp->token] = static_cast( temp_difference * std::exp( -0.002 ) + temp_conv[bp->token] - + - rounding_error ); + const int new_temp_conv = get_part_temp_conv( bp ); + if( temp_before != new_temp_conv ) { + temp_difference = get_part_temp_cur( bp ) - new_temp_conv; + set_part_temp_cur( bp, static_cast( temp_difference * std::exp( -0.002 ) + new_temp_conv + + rounding_error ) ); } } - int temp_after = temp_cur[bp->token]; + const int temp_after = get_part_temp_cur( bp ); // PENALTIES - if( temp_cur[bp->token] < BODYTEMP_FREEZING ) { + if( temp_after < BODYTEMP_FREEZING ) { add_effect( effect_cold, 1_turns, bp->token, true, 3 ); - } else if( temp_cur[bp->token] < BODYTEMP_VERY_COLD ) { + } else if( temp_after < BODYTEMP_VERY_COLD ) { add_effect( effect_cold, 1_turns, bp->token, true, 2 ); - } else if( temp_cur[bp->token] < BODYTEMP_COLD ) { + } else if( temp_after < BODYTEMP_COLD ) { add_effect( effect_cold, 1_turns, bp->token, true, 1 ); - } else if( temp_cur[bp->token] > BODYTEMP_SCORCHING ) { + } else if( temp_after > BODYTEMP_SCORCHING ) { add_effect( effect_hot, 1_turns, bp->token, true, 3 ); - if( mutate_to_main_part( bp->token ) == bp->token ) { + if( bp->main_part == bp.id() ) { add_effect( effect_hot_speed, 1_turns, bp->token, true, 3 ); } - } else if( temp_cur[bp->token] > BODYTEMP_VERY_HOT ) { + } else if( temp_after > BODYTEMP_VERY_HOT ) { add_effect( effect_hot, 1_turns, bp->token, true, 2 ); - if( mutate_to_main_part( bp->token ) == bp->token ) { + if( bp->main_part == bp.id() ) { add_effect( effect_hot_speed, 1_turns, bp->token, true, 2 ); } - } else if( temp_cur[bp->token] > BODYTEMP_HOT ) { + } else if( temp_after > BODYTEMP_HOT ) { add_effect( effect_hot, 1_turns, bp->token, true, 1 ); - if( mutate_to_main_part( bp->token ) == bp->token ) { + if( bp->main_part == bp.id() ) { add_effect( effect_hot_speed, 1_turns, bp->token, true, 1 ); } } else { - if( temp_cur[bp->token] >= BODYTEMP_COLD ) { - remove_effect( effect_cold, bp->token ); - } - if( temp_cur[bp->token] <= BODYTEMP_HOT ) { - remove_effect( effect_hot, bp->token ); - remove_effect( effect_hot_speed, bp->token ); - } + remove_effect( effect_cold, bp->token ); + remove_effect( effect_hot, bp->token ); + remove_effect( effect_hot_speed, bp->token ); } // FROSTBITE - only occurs to hands, feet, face /** @@ -5981,7 +5959,7 @@ void Character::update_bodytemp() bp == bodypart_id( "foot_l" ) || bp == bodypart_id( "hand_r" ) || bp == bodypart_id( "hand_l" ) ) { // Handle the frostbite timer // Need temps in F, windPower already in mph - int wetness_percentage = 100 * body_wetness[bp->token] / drench_capacity[bp->token]; // 0 - 100 + int wetness_percentage = 100 * get_part_wetness_percentage( bp ); // 0 - 100 // Warmth gives a slight buff to temperature resistance // Wetness gives a heavy nerf to temperature resistance double adjusted_warmth = warmth( bp ) - wetness_percentage; @@ -5994,64 +5972,65 @@ void Character::update_bodytemp() // This has been broken down into 8 zones // Low risk zones (stops at frostnip) - if( temp_cur[bp->token] < BODYTEMP_COLD && - ( ( Ftemperature < 30 && Ftemperature >= 10 ) || - ( Ftemperature < 10 && Ftemperature >= -5 && - FBwindPower < 20 && -4 * Ftemperature + 3 * FBwindPower - 20 >= 0 ) ) ) { - if( frostbite_timer[bp->token] < 2000 ) { - frostbite_timer[bp->token] += 3; + if( temp_after < BODYTEMP_COLD && ( ( Ftemperature < 30 && Ftemperature >= 10 ) || + ( Ftemperature < 10 && Ftemperature >= -5 && FBwindPower < 20 && + -4 * Ftemperature + 3 * FBwindPower - 20 >= 0 ) ) ) { + if( get_part_frostbite_timer( bp ) < 2000 ) { + mod_part_frostbite_timer( bp, 3 ); } if( one_in( 100 ) && !has_effect( effect_frostbite, bp->token ) ) { add_msg( m_warning, _( "Your %s will be frostnipped in the next few hours." ), body_part_name( bp ) ); } // Medium risk zones - } else if( temp_cur[bp->token] < BODYTEMP_COLD && + } else if( temp_after < BODYTEMP_COLD && ( ( Ftemperature < 10 && Ftemperature >= -5 && FBwindPower < 20 && -4 * Ftemperature + 3 * FBwindPower - 20 < 0 ) || ( Ftemperature < 10 && Ftemperature >= -5 && FBwindPower >= 20 ) || ( Ftemperature < -5 && FBwindPower < 10 ) || ( Ftemperature < -5 && FBwindPower >= 10 && -4 * Ftemperature + 3 * FBwindPower - 170 >= 0 ) ) ) { - frostbite_timer[bp->token] += 8; + mod_part_frostbite_timer( bp, 8 ); if( one_in( 100 ) && intense < 2 ) { add_msg( m_warning, _( "Your %s will be frostbitten within the hour!" ), body_part_name( bp ) ); } // High risk zones - } else if( temp_cur[bp->token] < BODYTEMP_COLD && + } else if( temp_after < BODYTEMP_COLD && ( ( Ftemperature < -5 && FBwindPower >= 10 && -4 * Ftemperature + 3 * FBwindPower - 170 < 0 ) || ( Ftemperature < -35 && FBwindPower >= 10 ) ) ) { - frostbite_timer[bp->token] += 72; + mod_part_frostbite_timer( bp, 72 ); if( one_in( 100 ) && intense < 2 ) { add_msg( m_warning, _( "Your %s will be frostbitten any minute now!" ), body_part_name( bp ) ); } // Risk free, so reduce frostbite timer } else { - frostbite_timer[bp->token] -= 3; + mod_part_frostbite_timer( bp, - 3 ); } + int frostbite_timer = get_part_frostbite_timer( bp ); // Handle the bestowing of frostbite - if( frostbite_timer[bp->token] < 0 ) { - frostbite_timer[bp->token] = 0; - } else if( frostbite_timer[bp->token] > 4200 ) { + if( frostbite_timer < 0 ) { + set_part_frostbite_timer( bp, 0 ); + } else if( frostbite_timer > 4200 ) { // This ensures that the player will recover in at most 3 hours. - frostbite_timer[bp->token] = 4200; + set_part_frostbite_timer( bp, 4200 ); } + frostbite_timer = get_part_frostbite_timer( bp ); // Frostbite, no recovery possible - if( frostbite_timer[bp->token] >= 3600 ) { + if( frostbite_timer >= 3600 ) { add_effect( effect_frostbite, 1_turns, bp->token, true, 2 ); remove_effect( effect_frostbite_recovery, bp->token ); // Else frostnip, add recovery if we were frostbitten - } else if( frostbite_timer[bp->token] >= 1800 ) { + } else if( frostbite_timer >= 1800 ) { if( intense == 2 ) { add_effect( effect_frostbite_recovery, 1_turns, bp->token, true ); } add_effect( effect_frostbite, 1_turns, bp->token, true, 1 ); // Else fully recovered - } else if( frostbite_timer[bp->token] == 0 ) { + } else if( frostbite_timer == 0 ) { remove_effect( effect_frostbite, bp->token ); remove_effect( effect_frostbite_recovery, bp->token ); } @@ -6089,27 +6068,27 @@ void Character::update_bodytemp() // Otherwise, if any other body part is BODYTEMP_VERY_COLD, or 31C // AND you have frostbite, then that also prevents you from sleeping if( in_sleep_state() ) { - int curr_temperature = temp_cur[bp->token]; - if( bp == bodypart_id( "torso" ) && curr_temperature <= BODYTEMP_COLD ) { + if( bp == bodypart_id( "torso" ) && temp_after <= BODYTEMP_COLD ) { add_msg( m_warning, _( "Your shivering prevents you from sleeping." ) ); wake_up(); - } else if( bp != bodypart_id( "torso" ) && curr_temperature <= BODYTEMP_VERY_COLD && + } else if( bp != bodypart_id( "torso" ) && temp_after <= BODYTEMP_VERY_COLD && has_effect( effect_frostbite ) ) { add_msg( m_warning, _( "You are too cold. Your frostbite prevents you from sleeping." ) ); wake_up(); } } + const int conv_temp = get_part_temp_conv( bp ); // Warn the player that wind is going to be a problem. // But only if it can be a problem, no need to spam player with "wind chills your scorching body" - if( temp_conv[bp->token] <= BODYTEMP_COLD && windchill < -10 && one_in( 200 ) ) { + if( conv_temp <= BODYTEMP_COLD && windchill < -10 && one_in( 200 ) ) { add_msg( m_bad, _( "The wind is making your %s feel quite cold." ), body_part_name( bp ) ); - } else if( temp_conv[bp->token] <= BODYTEMP_COLD && windchill < -20 && one_in( 100 ) ) { + } else if( conv_temp <= BODYTEMP_COLD && windchill < -20 && one_in( 100 ) ) { add_msg( m_bad, _( "The wind is very strong, you should find some more wind-resistant clothing for your %s." ), body_part_name( bp ) ); - } else if( temp_conv[bp->token] <= BODYTEMP_COLD && windchill < -30 && one_in( 50 ) ) { + } else if( conv_temp <= BODYTEMP_COLD && windchill < -30 && one_in( 50 ) ) { add_msg( m_bad, _( "Your clothing is not providing enough protection from the wind for your %s!" ), body_part_name( bp ) ); } @@ -6120,9 +6099,9 @@ void Character::temp_equalizer( const bodypart_id &bp1, const bodypart_id &bp2 ) { // Body heat is moved around. // Shift in one direction only, will be shifted in the other direction separately. - int diff = static_cast( ( temp_cur[bp2->token] - temp_cur[bp1->token] ) * + int diff = static_cast( ( get_part_temp_cur( bp2 ) - get_part_temp_cur( bp1 ) ) * 0.0001 ); // If bp1 is warmer, it will lose heat - temp_cur[bp1->token] += diff; + mod_part_temp_cur( bp1, diff ); } Character::comfort_response_t Character::base_comfort_value( const tripoint &p ) const @@ -9996,7 +9975,7 @@ int Character::warmth( const bodypart_id &bp ) const // Wool items do not lose their warmth due to being wet. // Warmth is reduced by 0 - 66% based on wetness. if( !i.made_of( material_id( "wool" ) ) ) { - warmth *= 1.0 - 0.66 * body_wetness[bp->token] / drench_capacity[bp->token]; + warmth *= 1.0 - 0.66 * get_part_wetness_percentage( bp ); } ret += warmth; } @@ -11134,24 +11113,25 @@ bool Character::sees( const Creature &critter ) const return Creature::sees( critter ); } -nc_color Character::bodytemp_color( int bp ) const +nc_color Character::bodytemp_color( const bodypart_id &bp ) const { nc_color color = c_light_gray; // default - if( bp == bp_eyes ) { + const int temp_conv = get_part_temp_conv( bp ); + if( bp == bodypart_id( "eyes" ) ) { color = c_light_gray; // Eyes don't count towards warmth - } else if( temp_conv[bp] > BODYTEMP_SCORCHING ) { + } else if( temp_conv > BODYTEMP_SCORCHING ) { color = c_red; - } else if( temp_conv[bp] > BODYTEMP_VERY_HOT ) { + } else if( temp_conv > BODYTEMP_VERY_HOT ) { color = c_light_red; - } else if( temp_conv[bp] > BODYTEMP_HOT ) { + } else if( temp_conv > BODYTEMP_HOT ) { color = c_yellow; - } else if( temp_conv[bp] > BODYTEMP_COLD ) { + } else if( temp_conv > BODYTEMP_COLD ) { color = c_green; - } else if( temp_conv[bp] > BODYTEMP_VERY_COLD ) { + } else if( temp_conv > BODYTEMP_VERY_COLD ) { color = c_light_blue; - } else if( temp_conv[bp] > BODYTEMP_FREEZING ) { + } else if( temp_conv > BODYTEMP_FREEZING ) { color = c_cyan; - } else if( temp_conv[bp] <= BODYTEMP_FREEZING ) { + } else { color = c_blue; } return color; diff --git a/src/character.h b/src/character.h index 041c78e592965..57d24a0a6c29a 100644 --- a/src/character.h +++ b/src/character.h @@ -2357,7 +2357,7 @@ class Character : public Creature, public visitable bool knows_trap( const tripoint &pos ) const; void add_known_trap( const tripoint &pos, const trap &t ); /** Define color for displaying the body temperature */ - nc_color bodytemp_color( int bp ) const; + nc_color bodytemp_color( const bodypart_id &bp ) const; // see Creature::sees bool sees( const tripoint &t, bool is_player = false, int range_mod = 0 ) const override; @@ -2569,11 +2569,6 @@ class Character : public Creature, public visitable std::unordered_map overmap_time; public: - // TODO: make these private - std::array temp_cur, frostbite_timer, temp_conv; - std::array body_wetness; - std::array drench_capacity; - time_point next_climate_control_check; bool last_climate_control_ret; }; diff --git a/src/character_oracle.cpp b/src/character_oracle.cpp index 2e930b8ff06a2..50b1eb356d75d 100644 --- a/src/character_oracle.cpp +++ b/src/character_oracle.cpp @@ -24,8 +24,8 @@ namespace behavior status_t character_oracle_t::needs_warmth_badly( const std::string & ) const { // Use player::temp_conv to predict whether the Character is "in trouble". - for( const body_part bp : all_body_parts ) { - if( subject->temp_conv[ bp ] <= BODYTEMP_VERY_COLD ) { + for( const bodypart_id &bp : subject->get_all_body_parts() ) { + if( subject->get_part_temp_conv( bp ) <= BODYTEMP_VERY_COLD ) { return status_t::running; } } diff --git a/src/creature.cpp b/src/creature.cpp index 12354974733d5..9c54f0f91659c 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -1473,6 +1473,13 @@ void Creature::set_body() } } +void Creature::init_parts_drench_capacity() +{ + for( std::pair &elem : body ) { + elem.second.set_drench_capacity( elem.first->drench_max ); + } +} + void Creature::calc_all_parts_hp( float hp_mod, float hp_adjustment, int str_max, int dex_max, int per_max, int int_max, int healthy_mod, int fat_to_max_hp ) { @@ -1547,6 +1554,36 @@ encumbrance_data Creature::get_part_encumbrance_data( const bodypart_id &id ) co return get_part( id ).get_encumbrance_data(); } +int Creature::get_part_drench_capacity( const bodypart_id &id ) const +{ + return get_part( id ).get_drench_capacity(); +} + +int Creature::get_part_wetness( const bodypart_id &id ) const +{ + return get_part( id ).get_wetness(); +} + +int Creature::get_part_temp_cur( const bodypart_id &id ) const +{ + return get_part( id ).get_temp_cur(); +} + +int Creature::get_part_temp_conv( const bodypart_id &id ) const +{ + return get_part( id ).get_temp_conv();; +} + +int Creature::get_part_frostbite_timer( const bodypart_id &id ) const +{ + return get_part( id ).get_frotbite_timer(); +} + +float Creature::get_part_wetness_percentage( const bodypart_id &id ) const +{ + return get_part( id ).get_wetness_percentage(); +} + void Creature::set_part_hp_cur( const bodypart_id &id, int set ) { get_part( id )->set_hp_cur( set ); @@ -1577,6 +1614,26 @@ void Creature::set_part_encumbrance_data( const bodypart_id &id, encumbrance_dat get_part( id )->set_encumbrance_data( set ); } +void Creature::set_part_wetness( const bodypart_id &id, int set ) +{ + get_part( id )->set_wetness( set ); +} + +void Creature::set_part_temp_cur( const bodypart_id &id, int set ) +{ + get_part( id )->set_temp_cur( set ); +} + +void Creature::set_part_temp_conv( const bodypart_id &id, int set ) +{ + get_part( id )->set_temp_conv( set ); +} + +void Creature::set_part_frostbite_timer( const bodypart_id &id, int set ) +{ + get_part( id )->set_frostbite_timer( set ); +} + void Creature::mod_part_hp_cur( const bodypart_id &id, int mod ) { get_part( id )->mod_hp_cur( mod ); @@ -1602,6 +1659,47 @@ void Creature::mod_part_damage_bandaged( const bodypart_id &id, int mod ) get_part( id )->mod_damage_bandaged( mod ); } +void Creature::mod_part_wetness( const bodypart_id &id, int mod ) +{ + get_part( id )->mod_wetness( mod ); +} + +void Creature::mod_part_temp_cur( const bodypart_id &id, int mod ) +{ + get_part( id )->mod_temp_cur( mod ); +} + +void Creature::mod_part_temp_conv( const bodypart_id &id, int mod ) +{ + get_part( id )->mod_temp_conv( mod ); +} + +void Creature::mod_part_frostbite_timer( const bodypart_id &id, int mod ) +{ + get_part( id )->mod_frostbite_timer( mod ); +} + +void Creature::set_all_parts_temp_cur( int set ) +{ + for( std::pair &elem : body ) { + elem.second.set_temp_cur( set ); + } +} + +void Creature::set_all_parts_temp_conv( int set ) +{ + for( std::pair &elem : body ) { + elem.second.set_temp_conv( set ); + } +} + +void Creature::set_all_parts_wetness( int set ) +{ + for( std::pair &elem : body ) { + elem.second.set_wetness( set ); + } +} + void Creature::set_all_parts_hp_cur( const int set ) { for( std::pair &elem : body ) { @@ -1616,6 +1714,16 @@ void Creature::set_all_parts_hp_to_max() } } +bool Creature::has_atleast_one_wet_part() +{ + for( std::pair &elem : body ) { + if( elem.second.get_wetness() > 0 ) { + return true; + } + } + return false; +} + bodypart_id Creature::get_random_body_part( bool main ) const { diff --git a/src/creature.h b/src/creature.h index cd622e94ea74e..3b3effe61754c 100644 --- a/src/creature.h +++ b/src/creature.h @@ -607,6 +607,7 @@ class Creature std::map get_body() const; void set_body(); + void init_parts_drench_capacity(); void calc_all_parts_hp( float hp_mod = 0.0, float hp_adjust = 0.0, int str_max = 0, int dex_max = 0, int per_max = 0, int int_max = 0, int healthy_mod = 0, int fat_to_max_hp = 0 ); @@ -619,6 +620,13 @@ class Creature int get_part_healed_total( const bodypart_id &id ) const; int get_part_damage_disinfected( const bodypart_id &id ) const; int get_part_damage_bandaged( const bodypart_id &id ) const; + int get_part_drench_capacity( const bodypart_id &id ) const; + int get_part_wetness( const bodypart_id &id ) const; + int get_part_temp_cur( const bodypart_id &id ) const; + int get_part_temp_conv( const bodypart_id &id ) const; + int get_part_frostbite_timer( const bodypart_id &id )const; + + float get_part_wetness_percentage( const bodypart_id &id ) const; encumbrance_data get_part_encumbrance_data( const bodypart_id &id )const; @@ -630,16 +638,29 @@ class Creature void set_part_encumbrance_data( const bodypart_id &id, encumbrance_data set ); + void set_part_wetness( const bodypart_id &id, int set ); + void set_part_temp_cur( const bodypart_id &id, int set ); + void set_part_temp_conv( const bodypart_id &id, int set ); + void set_part_frostbite_timer( const bodypart_id &id, int set ); + void mod_part_hp_cur( const bodypart_id &id, int mod ); void mod_part_hp_max( const bodypart_id &id, int mod ); void mod_part_healed_total( const bodypart_id &id, int mod ); void mod_part_damage_disinfected( const bodypart_id &id, int mod ); void mod_part_damage_bandaged( const bodypart_id &id, int mod ); - - + void mod_part_wetness( const bodypart_id &id, int mod ); + void mod_part_temp_cur( const bodypart_id &id, int mod ); + void mod_part_temp_conv( const bodypart_id &id, int mod ); + void mod_part_frostbite_timer( const bodypart_id &id, int mod ); + + void set_all_parts_temp_cur( int set ); + void set_all_parts_temp_conv( int set ); + void set_all_parts_wetness( int set ); void set_all_parts_hp_cur( int set ); void set_all_parts_hp_to_max(); + bool has_atleast_one_wet_part(); + virtual int get_speed_base() const; virtual int get_speed_bonus() const; virtual int get_block_bonus() const; diff --git a/src/effect.h b/src/effect.h index dde40ad1c6727..b583b405042eb 100644 --- a/src/effect.h +++ b/src/effect.h @@ -139,7 +139,7 @@ class effect_type class effect { public: - effect() : eff_type( nullptr ), duration( 0_turns ), bp( num_bp ), + effect() : eff_type( nullptr ), duration( 0_turns ), bp( body_part::num_bp ), permanent( false ), intensity( 1 ), start_time( calendar::turn_zero ) { } effect( const effect_type *peff_type, const time_duration &dur, body_part part, diff --git a/src/game.cpp b/src/game.cpp index 32536589bc78c..e6c8ca95affe7 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -12066,10 +12066,7 @@ bool check_art_charge_req( item &it ) reqsmet = ( ( here.get_radiation( p.pos() ) > 0 ) || ( p.get_rad() > 0 ) ); break; case( ACR_WET ): - reqsmet = std::any_of( p.body_wetness.begin(), p.body_wetness.end(), - []( const int w ) { - return w != 0; - } ); + reqsmet = p.has_atleast_one_wet_part(); if( !reqsmet && sum_conditions( calendar::turn - 1_turns, calendar::turn, p.pos() ).rain_amount > 0 && !( p.in_vehicle && here.veh_at( p.pos() )->is_inside() ) ) { reqsmet = true; @@ -12534,12 +12531,14 @@ bool game::slip_down( bool check_for_traps ) // Climbing is difficult with wet hands and feet. float wet_penalty = 1.0f; - if( u.body_wetness[bp_foot_l] > 0 || u.body_wetness[bp_foot_r] > 0 ) { + if( u.get_part_wetness( bodypart_id( "foot_l" ) ) > 0 || + u.get_part_wetness( bodypart_id( "foot_r" ) ) > 0 ) { wet_penalty += .5; add_msg( m_info, _( "Your wet feet make it harder to climb." ) ); } - if( u.body_wetness[bp_hand_l] > 0 || u.body_wetness[bp_hand_r] > 0 ) { + if( u.get_part_wetness( bodypart_id( "hand_l" ) ) > 0 || + u.get_part_wetness( bodypart_id( "hand_r" ) ) > 0 ) { wet_penalty += .5; add_msg( m_info, _( "Your wet hands make it harder to climb." ) ); } diff --git a/src/iuse.cpp b/src/iuse.cpp index 27dade3b52518..0f8ebac2e2861 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -5880,7 +5880,7 @@ int iuse::towel_common( Character *p, item *it, bool t ) // dry off from being wet } else if( std::abs( p->has_morale( MORALE_WET ) ) ) { p->rem_morale( MORALE_WET ); - p->body_wetness.fill( 0 ); + p->set_all_parts_wetness( 0 ); p->add_msg_if_player( _( "You use the %s to dry off, saturating it with water!" ), name ); diff --git a/src/panels.cpp b/src/panels.cpp index 532566d129a75..8cfe448a708e2 100644 --- a/src/panels.cpp +++ b/src/panels.cpp @@ -540,18 +540,18 @@ static std::pair morale_stat( const avatar &u ) return std::make_pair( morale_color, morale_int ); } -static std::pair temp_delta( const avatar &u ) -{ - int current_bp_extreme = 0; - int conv_bp_extreme = 0; - for( int i = 0; i < num_bp; i++ ) { - if( std::abs( u.temp_cur[i] - BODYTEMP_NORM ) > - std::abs( u.temp_cur[current_bp_extreme] - BODYTEMP_NORM ) ) { - current_bp_extreme = i; +static std::pair temp_delta( const avatar &u ) +{ + bodypart_id current_bp_extreme( "torso" ); + bodypart_id conv_bp_extreme( "torso" ); + for( const bodypart_id &bp : u.get_all_body_parts() ) { + if( std::abs( u.get_part_temp_cur( bp ) - BODYTEMP_NORM ) > + std::abs( u.get_part_temp_cur( current_bp_extreme ) - BODYTEMP_NORM ) ) { + current_bp_extreme = bp; } - if( std::abs( u.temp_conv[i] - BODYTEMP_NORM ) > - std::abs( u.temp_conv[conv_bp_extreme] - BODYTEMP_NORM ) ) { - conv_bp_extreme = i; + if( std::abs( u.get_part_temp_conv( bp ) - BODYTEMP_NORM ) > + std::abs( u.get_part_temp_conv( conv_bp_extreme ) - BODYTEMP_NORM ) ) { + conv_bp_extreme = bp; } } return std::make_pair( current_bp_extreme, conv_bp_extreme ); @@ -578,10 +578,10 @@ static int define_temp_level( const int lvl ) static std::string temp_delta_string( const avatar &u ) { std::string temp_message; - std::pair temp_pair = temp_delta( u ); + std::pair temp_pair = temp_delta( u ); // Assign zones for comparisons - const int cur_zone = define_temp_level( u.temp_cur[temp_pair.first] ); - const int conv_zone = define_temp_level( u.temp_conv[temp_pair.second] ); + const int cur_zone = define_temp_level( u.get_part_temp_cur( temp_pair.first ) ); + const int conv_zone = define_temp_level( u.get_part_temp_conv( temp_pair.second ) ); // delta will be positive if temp_cur is rising const int delta = conv_zone - cur_zone; @@ -608,10 +608,10 @@ static std::pair temp_delta_arrows( const avatar &u ) { std::string temp_message; nc_color temp_color = c_white; - std::pair temp_pair = temp_delta( u ); + std::pair temp_pair = temp_delta( u ); // Assign zones for comparisons - const int cur_zone = define_temp_level( u.temp_cur[temp_pair.first] ); - const int conv_zone = define_temp_level( u.temp_conv[temp_pair.second] ); + const int cur_zone = define_temp_level( u.get_part_temp_cur( temp_pair.first ) ); + const int conv_zone = define_temp_level( u.get_part_temp_conv( temp_pair.second ) ); // delta will be positive if temp_cur is rising const int delta = conv_zone - cur_zone; @@ -645,30 +645,30 @@ static std::pair temp_stat( const avatar &u ) { /// Find hottest/coldest bodypart // Calculate the most extreme body temperatures - int current_bp_extreme = temp_delta( u ).first; + const bodypart_id ¤t_bp_extreme = temp_delta( u ).first; // printCur the hottest/coldest bodypart std::string temp_string; nc_color temp_color = c_yellow; - if( u.temp_cur[current_bp_extreme] > BODYTEMP_SCORCHING ) { + if( u.get_part_temp_cur( current_bp_extreme ) > BODYTEMP_SCORCHING ) { temp_color = c_red; temp_string = _( "Scorching!" ); - } else if( u.temp_cur[current_bp_extreme] > BODYTEMP_VERY_HOT ) { + } else if( u.get_part_temp_cur( current_bp_extreme ) > BODYTEMP_VERY_HOT ) { temp_color = c_light_red; temp_string = _( "Very hot!" ); - } else if( u.temp_cur[current_bp_extreme] > BODYTEMP_HOT ) { + } else if( u.get_part_temp_cur( current_bp_extreme ) > BODYTEMP_HOT ) { temp_color = c_yellow; temp_string = _( "Warm" ); - } else if( u.temp_cur[current_bp_extreme] > BODYTEMP_COLD ) { + } else if( u.get_part_temp_cur( current_bp_extreme ) > BODYTEMP_COLD ) { temp_color = c_green; temp_string = _( "Comfortable" ); - } else if( u.temp_cur[current_bp_extreme] > BODYTEMP_VERY_COLD ) { + } else if( u.get_part_temp_cur( current_bp_extreme ) > BODYTEMP_VERY_COLD ) { temp_color = c_light_blue; temp_string = _( "Chilly" ); - } else if( u.temp_cur[current_bp_extreme] > BODYTEMP_FREEZING ) { + } else if( u.get_part_temp_cur( current_bp_extreme ) > BODYTEMP_FREEZING ) { temp_color = c_cyan; temp_string = _( "Very cold!" ); - } else if( u.temp_cur[current_bp_extreme] <= BODYTEMP_FREEZING ) { + } else if( u.get_part_temp_cur( current_bp_extreme ) <= BODYTEMP_FREEZING ) { temp_color = c_blue; temp_string = _( "Freezing!" ); } diff --git a/src/player.cpp b/src/player.cpp index 4933769586d5c..664e7fcd5465b 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -293,7 +293,7 @@ void player::normalize() recalc_hp(); - temp_conv.fill( BODYTEMP_NORM ); + set_all_parts_temp_conv( BODYTEMP_NORM ); set_stamina( get_stamina_max() ); } @@ -1752,21 +1752,22 @@ void player::update_body_wetness( const w_point &weather ) // To make drying uniform, make just one roll and reuse it const int drying_roll = rng( 1, 80 ); - for( const body_part bp : all_body_parts ) { - if( body_wetness[bp] == 0 ) { + for( const bodypart_id &bp : get_all_body_parts() ) { + if( get_part_wetness( bp ) == 0 ) { continue; } // This is to normalize drying times - int drying_chance = drench_capacity[bp]; + int drying_chance = get_part_drench_capacity( bp ); + const int temp_conv = get_part_temp_conv( bp ); // Body temperature affects duration of wetness // Note: Using temp_conv rather than temp_cur, to better approximate environment - if( temp_conv[bp] >= BODYTEMP_SCORCHING ) { + if( temp_conv >= BODYTEMP_SCORCHING ) { drying_chance *= 2; - } else if( temp_conv[bp] >= BODYTEMP_VERY_HOT ) { + } else if( temp_conv >= BODYTEMP_VERY_HOT ) { drying_chance = drying_chance * 3 / 2; - } else if( temp_conv[bp] >= BODYTEMP_HOT ) { + } else if( temp_conv >= BODYTEMP_HOT ) { drying_chance = drying_chance * 4 / 3; - } else if( temp_conv[bp] > BODYTEMP_COLD ) { + } else if( temp_conv > BODYTEMP_COLD ) { // Comfortable, doesn't need any changes } else { // Evaporation doesn't change that much at lower temp @@ -1779,9 +1780,9 @@ void player::update_body_wetness( const w_point &weather ) // TODO: Make evaporation reduce body heat if( drying_chance >= drying_roll ) { - body_wetness[bp] -= 1; - if( body_wetness[bp] < 0 ) { - body_wetness[bp] = 0; + mod_part_wetness( bp, 1 ); + if( get_part_wetness( bp ) < 0 ) { + set_part_wetness( bp, 0 ); } } } diff --git a/src/player_display.cpp b/src/player_display.cpp index d05907fa943d7..a7cc558cced6f 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -50,11 +50,6 @@ static int temperature_print_rescaling( int temp ) return ( temp / 100.0 ) * 2 - 100; } -static bodypart_id other_part( const bodypart_id &bp ) -{ - return bp->opposite_part; -} - static bool should_combine_bps( const player &p, const bodypart_id &l, const bodypart_id &r, const item *selected_clothing ) { @@ -62,14 +57,14 @@ static bool should_combine_bps( const player &p, const bodypart_id &l, const bod const encumbrance_data enc_r = p.get_part_encumbrance_data( r ); return l != r && // are different parts - l == other_part( r ) && r == other_part( l ) && // are complementary parts + l == r->opposite_part && r == l->opposite_part && // are complementary parts // same encumberance & temperature enc_l == enc_r && - temperature_print_rescaling( p.temp_conv[l->token] ) == temperature_print_rescaling( - p.temp_conv[r->token] ) && + temperature_print_rescaling( p.get_part_temp_conv( l ) ) == temperature_print_rescaling( + p.get_part_temp_conv( r ) ) && // selected_clothing covers both or neither parts - ( !selected_clothing || - ( selected_clothing->covers( l ) == selected_clothing->covers( r ) ) ); + ( !selected_clothing || ( selected_clothing->covers( l ) == selected_clothing->covers( r ) ) ); + } static std::vector> list_and_combine_bps( const player &p, @@ -79,12 +74,13 @@ static std::vector> list_and_combine_bps( const pla std::vector> bps; for( const bodypart_id &bp : p.get_all_body_parts() ) { // assuming that a body part has at most one other half - if( other_part( other_part( bp ) ) != bp ) { + if( bp->opposite_part->opposite_part != bp.id() ) { debugmsg( "Bodypart %d has more than one other half!", bp.id().c_str() ); } - if( should_combine_bps( p, bp, other_part( bp ), selected_clothing ) ) { - if( bp < other_part( bp ) ) { - // only add the earlier one + if( should_combine_bps( p, bp, bp->opposite_part.id(), selected_clothing ) ) { + if( std::find( bps.begin(), bps.end(), std::pair( bp->opposite_part.id(), + true ) ) == bps.end() ) { + // only add one bps.emplace_back( bp, true ); } } else { @@ -121,9 +117,11 @@ void player::print_encumbrance( const catacurses::window &win, const int line, if( static_cast( thisline ) >= bps.size() ) { break; } - const bodypart_id bp = bps[thisline].first; + + const bodypart_id &bp = bps[thisline].first; const bool combine = bps[thisline].second; const encumbrance_data &e = get_part_encumbrance_data( bp ); + const bool highlighted = selected_clothing ? selected_clothing->covers( bp ) : false; std::string out = body_part_name_as_heading( bp, combine ? 2 : 1 ); if( utf8_width( out ) > 7 ) { @@ -144,8 +142,8 @@ void player::print_encumbrance( const catacurses::window &win, const int line, // take into account the new encumbrance system for layers mvwprintz( win, point( 12, 1 + i ), encumb_color( e.encumbrance ), "%-3d", e.layer_penalty ); // print warmth, tethered to right hand side of the window - mvwprintz( win, point( width - 6, 1 + i ), bodytemp_color( bp->token ), "(% 3d)", - temperature_print_rescaling( temp_conv[bp->token] ) ); + mvwprintz( win, point( width - 6, 1 + i ), bodytemp_color( bp ), "(% 3d)", + temperature_print_rescaling( get_part_temp_conv( bp ) ) ); } if( draw_scrollbar ) { diff --git a/src/player_hardcoded_effects.cpp b/src/player_hardcoded_effects.cpp index 0ba5be7e9f77e..a486fdffc9ef4 100644 --- a/src/player_hardcoded_effects.cpp +++ b/src/player_hardcoded_effects.cpp @@ -441,7 +441,8 @@ static void eff_fun_hot( player &u, effect &it ) } // Hothead effects are a special snowflake if( bp == bp_head && intense >= 2 ) { - if( one_in( std::max( 25, std::min( 89500, 90000 - u.temp_cur[bp_head] ) ) ) ) { + if( one_in( std::max( 25, std::min( 89500, + 90000 - u.get_part_temp_cur( bodypart_id( "head" ) ) ) ) ) ) { u.vomit(); } if( !u.has_effect( effect_sleep ) && one_in( 2400 ) ) { @@ -973,10 +974,10 @@ void player::hardcoded_effects( effect &it ) break; case 4: warning = _( "You are sweating profusely, but you feel cold." ); - temp_conv[bp_hand_l] -= 1000 * intense; - temp_conv[bp_hand_r] -= 1000 * intense; - temp_conv[bp_foot_l] -= 1000 * intense; - temp_conv[bp_foot_r] -= 1000 * intense; + mod_part_temp_conv( bodypart_id( "hand_l" ), - 1000 * intense ); + mod_part_temp_conv( bodypart_id( "hand_r" ), -1000 * intense ); + mod_part_temp_conv( bodypart_id( "foot_l" ), -1000 * intense ); + mod_part_temp_conv( bodypart_id( "foot_r" ), -1000 * intense ); break; case 5: warning = _( "You huff and puff. Your breath is rapid and shallow." ); @@ -1029,13 +1030,13 @@ void player::hardcoded_effects( effect &it ) switch( dice( 1, 9 ) ) { case 1: add_msg_if_player( m_bad, _( "Your hands feel unusually cold." ) ); - temp_conv[bp_hand_l] -= 2000; - temp_conv[bp_hand_r] -= 2000; + mod_part_temp_conv( bodypart_id( "hand_l" ), -2000 ); + mod_part_temp_conv( bodypart_id( "hand_r" ), -2000 ); break; case 2: add_msg_if_player( m_bad, _( "Your feet feel unusualy cold." ) ); - temp_conv[bp_foot_l] -= 2000; - temp_conv[bp_foot_r] -= 2000; + mod_part_temp_conv( bodypart_id( "foot_l" ), -2000 ); + mod_part_temp_conv( bodypart_id( "foot_r" ), -2000 ); break; case 3: add_msg_if_player( m_bad, _( "Your skin looks very pale." ) ); @@ -1424,25 +1425,26 @@ void player::hardcoded_effects( effect &it ) if( !woke_up && !has_effect( effect_narcosis ) ) { // Cold or heat may wake you up. // Player will sleep through cold or heat if fatigued enough - for( const body_part bp : all_body_parts ) { - if( temp_cur[bp] < BODYTEMP_VERY_COLD - get_fatigue() / 2 ) { + for( const bodypart_id &bp : get_all_body_parts() ) { + const int curr_temp = get_part_temp_cur( bp ); + if( curr_temp < BODYTEMP_VERY_COLD - get_fatigue() / 2 ) { if( one_in( 30000 ) ) { add_msg_if_player( _( "You toss and turn trying to keep warm." ) ); } - if( temp_cur[bp] < BODYTEMP_FREEZING - get_fatigue() / 2 || - one_in( temp_cur[bp] * 6 + 30000 ) ) { + if( curr_temp < BODYTEMP_FREEZING - get_fatigue() / 2 || + one_in( curr_temp * 6 + 30000 ) ) { add_msg_if_player( m_bad, _( "It's too cold to sleep." ) ); // Set ourselves up for removal it.set_duration( 0_turns ); woke_up = true; break; } - } else if( temp_cur[bp] > BODYTEMP_VERY_HOT + get_fatigue() / 2 ) { + } else if( curr_temp > BODYTEMP_VERY_HOT + get_fatigue() / 2 ) { if( one_in( 30000 ) ) { add_msg_if_player( _( "You toss and turn in the heat." ) ); } - if( temp_cur[bp] > BODYTEMP_SCORCHING + get_fatigue() / 2 || - one_in( 90000 - temp_cur[bp] ) ) { + if( curr_temp > BODYTEMP_SCORCHING + get_fatigue() / 2 || + one_in( 90000 - curr_temp ) ) { add_msg_if_player( m_bad, _( "It's too hot to sleep." ) ); // Set ourselves up for removal it.set_duration( 0_turns ); diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 50b0c520e43ac..0c6596740dfa4 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -545,19 +545,6 @@ void Character::load( const JsonObject &data ) data.read( "healthy", healthy ); data.read( "healthy_mod", healthy_mod ); - // status - temp_cur.fill( 5000 ); - data.read( "temp_cur", temp_cur ); - - temp_conv.fill( 5000 ); - data.read( "temp_conv", temp_conv ); - - frostbite_timer.fill( 0 ); - data.read( "frostbite_timer", frostbite_timer ); - - body_wetness.fill( 0 ); - data.read( "body_wetness", body_wetness ); - // Remove check after 0.F if( savegame_loading_version >= 30 ) { data.read( "proficiencies", _proficiencies ); @@ -690,6 +677,83 @@ void Character::load( const JsonObject &data ) set_part_healed_total( bodypart_id( "leg_l" ), healed_total[4] ); set_part_healed_total( bodypart_id( "leg_r" ), healed_total[5] ); } + if( data.has_array( "body_wetness" ) ) { + set_anatomy( anatomy_id( "human_anatomy" ) ); + set_body(); + init_parts_drench_capacity(); + std::array body_wetness; + body_wetness.fill( 0 ); + data.read( "body_wetness", body_wetness ); + set_part_wetness( bodypart_id( "torso" ), body_wetness[0] ); + set_part_wetness( bodypart_id( "head" ), body_wetness[1] ); + set_part_wetness( bodypart_id( "eyes" ), body_wetness[2] ); + set_part_wetness( bodypart_id( "mouth" ), body_wetness[3] ); + set_part_wetness( bodypart_id( "arm_l" ), body_wetness[4] ); + set_part_wetness( bodypart_id( "arm_r" ), body_wetness[5] ); + set_part_wetness( bodypart_id( "hand_l" ), body_wetness[6] ); + set_part_wetness( bodypart_id( "hand_r" ), body_wetness[7] ); + set_part_wetness( bodypart_id( "leg_l" ), body_wetness[8] ); + set_part_wetness( bodypart_id( "leg_r" ), body_wetness[9] ); + set_part_wetness( bodypart_id( "foot_l" ), body_wetness[10] ); + set_part_wetness( bodypart_id( "foot_r" ), body_wetness[11] ); + } + if( data.has_array( "temp_cur" ) ) { + set_anatomy( anatomy_id( "human_anatomy" ) ); + set_body(); + std::array temp_cur; + temp_cur.fill( BODYTEMP_NORM ); + data.read( "temp_cur", temp_cur ); + set_part_temp_cur( bodypart_id( "torso" ), temp_cur[0] ); + set_part_temp_cur( bodypart_id( "head" ), temp_cur[1] ); + set_part_temp_cur( bodypart_id( "eyes" ), temp_cur[2] ); + set_part_temp_cur( bodypart_id( "mouth" ), temp_cur[3] ); + set_part_temp_cur( bodypart_id( "arm_l" ), temp_cur[4] ); + set_part_temp_cur( bodypart_id( "arm_r" ), temp_cur[5] ); + set_part_temp_cur( bodypart_id( "hand_l" ), temp_cur[6] ); + set_part_temp_cur( bodypart_id( "hand_r" ), temp_cur[7] ); + set_part_temp_cur( bodypart_id( "leg_l" ), temp_cur[8] ); + set_part_temp_cur( bodypart_id( "leg_r" ), temp_cur[9] ); + set_part_temp_cur( bodypart_id( "foot_l" ), temp_cur[10] ); + set_part_temp_cur( bodypart_id( "foot_r" ), temp_cur[11] ); + } + if( data.has_array( "temp_conv" ) ) { + set_anatomy( anatomy_id( "human_anatomy" ) ); + set_body(); + std::array temp_conv; + temp_conv.fill( BODYTEMP_NORM ); + data.read( "temp_conv", temp_conv ); + set_part_temp_conv( bodypart_id( "torso" ), temp_conv[0] ); + set_part_temp_conv( bodypart_id( "head" ), temp_conv[1] ); + set_part_temp_conv( bodypart_id( "eyes" ), temp_conv[2] ); + set_part_temp_conv( bodypart_id( "mouth" ), temp_conv[3] ); + set_part_temp_conv( bodypart_id( "arm_l" ), temp_conv[4] ); + set_part_temp_conv( bodypart_id( "arm_r" ), temp_conv[5] ); + set_part_temp_conv( bodypart_id( "hand_l" ), temp_conv[6] ); + set_part_temp_conv( bodypart_id( "hand_r" ), temp_conv[7] ); + set_part_temp_conv( bodypart_id( "leg_l" ), temp_conv[8] ); + set_part_temp_conv( bodypart_id( "leg_r" ), temp_conv[9] ); + set_part_temp_conv( bodypart_id( "foot_l" ), temp_conv[10] ); + set_part_temp_conv( bodypart_id( "foot_r" ), temp_conv[11] ); + } + if( data.has_array( "frostbite_timer" ) ) { + set_anatomy( anatomy_id( "human_anatomy" ) ); + set_body(); + std::array frostbite_timer; + frostbite_timer.fill( 0 ); + data.read( "frostbite_timer", frostbite_timer ); + set_part_frostbite_timer( bodypart_id( "torso" ), frostbite_timer[0] ); + set_part_frostbite_timer( bodypart_id( "head" ), frostbite_timer[1] ); + set_part_frostbite_timer( bodypart_id( "eyes" ), frostbite_timer[2] ); + set_part_frostbite_timer( bodypart_id( "mouth" ), frostbite_timer[3] ); + set_part_frostbite_timer( bodypart_id( "arm_l" ), frostbite_timer[4] ); + set_part_frostbite_timer( bodypart_id( "arm_r" ), frostbite_timer[5] ); + set_part_frostbite_timer( bodypart_id( "hand_l" ), frostbite_timer[6] ); + set_part_frostbite_timer( bodypart_id( "hand_r" ), frostbite_timer[7] ); + set_part_frostbite_timer( bodypart_id( "leg_l" ), frostbite_timer[8] ); + set_part_frostbite_timer( bodypart_id( "leg_r" ), frostbite_timer[9] ); + set_part_frostbite_timer( bodypart_id( "foot_l" ), frostbite_timer[10] ); + set_part_frostbite_timer( bodypart_id( "foot_r" ), frostbite_timer[11] ); + } inv.clear(); if( data.has_member( "inv" ) ) { @@ -816,12 +880,6 @@ void Character::store( JsonOut &json ) const json.member( "healthy", healthy ); json.member( "healthy_mod", healthy_mod ); - // status - json.member( "temp_cur", temp_cur ); - json.member( "temp_conv", temp_conv ); - json.member( "frostbite_timer", frostbite_timer ); - json.member( "body_wetness", body_wetness ); - // needs json.member( "thirst", thirst ); json.member( "hunger", hunger ); diff --git a/src/suffer.cpp b/src/suffer.cpp index 2525c93577d52..74ab342ec8510 100644 --- a/src/suffer.cpp +++ b/src/suffer.cpp @@ -180,8 +180,7 @@ static float addiction_scaling( float at_min, float at_max, float add_lvl ) void Character::suffer_water_damage( const mutation_branch &mdata ) { for( const std::pair &elem : get_body() ) { - const float wetness_percentage = static_cast( body_wetness[elem.first->token] ) / - drench_capacity[elem.first->token]; + const float wetness_percentage = elem.second.get_wetness_percentage(); const int dmg = mdata.weakness_to_water * wetness_percentage; if( dmg > 0 ) { apply_damage( nullptr, elem.first, dmg ); @@ -407,19 +406,19 @@ void Character::suffer_from_chemimbalance() if( one_turn_in( 6_hours ) ) { if( one_in( 3 ) ) { add_msg_if_player( m_bad, _( "You suddenly feel very cold." ) ); - temp_cur.fill( BODYTEMP_VERY_COLD ); + set_all_parts_temp_cur( BODYTEMP_VERY_COLD ); } else { add_msg_if_player( m_bad, _( "You suddenly feel cold." ) ); - temp_cur.fill( BODYTEMP_COLD ); + set_all_parts_temp_cur( BODYTEMP_COLD ); } } if( one_turn_in( 6_hours ) ) { if( one_in( 3 ) ) { add_msg_if_player( m_bad, _( "You suddenly feel very hot." ) ); - temp_cur.fill( BODYTEMP_VERY_HOT ); + set_all_parts_temp_cur( BODYTEMP_VERY_HOT ); } else { add_msg_if_player( m_bad, _( "You suddenly feel hot." ) ); - temp_cur.fill( BODYTEMP_HOT ); + set_all_parts_temp_cur( BODYTEMP_HOT ); } } } @@ -1741,7 +1740,7 @@ void Character::drench( int saturation, const body_part_set &flags, bool ignore_ // Different body parts have different size, they can only store so much water int bp_wetness_max = 0; if( flags.test( bp.id() ) ) { - bp_wetness_max = drench_capacity[bp->token]; + bp_wetness_max = get_part_drench_capacity( bp ); } if( bp_wetness_max == 0 ) { @@ -1752,12 +1751,13 @@ void Character::drench( int saturation, const body_part_set &flags, bool ignore_ int wetness_increment = ignore_waterproof ? 100 : 2; // Respect maximums const int wetness_max = std::min( source_wet_max, bp_wetness_max ); - if( body_wetness[bp->token] < wetness_max ) { - body_wetness[bp->token] = std::min( wetness_max, body_wetness[bp->token] + wetness_increment ); + const int curr_wetness = get_part_wetness( bp ); + if( curr_wetness < wetness_max ) { + set_part_wetness( bp, std::min( wetness_max, curr_wetness + wetness_increment ) ); } } - - if( body_wetness[bp_torso] >= drench_capacity[bp_torso] / 2.0 && + const int torso_wetness = get_part_wetness( bodypart_id( "torso" ) ); + if( torso_wetness >= torso_wetness / 2.0 && has_effect( effect_masked_scent ) && get_value( "waterproof_scent" ).empty() ) { add_msg_if_player( m_info, _( "The water wash away the scent." ) ); @@ -1778,10 +1778,7 @@ void Character::apply_wetness_morale( int temperature ) { // First, a quick check if we have any wetness to calculate morale from // Faster than checking all worn items for friendliness - if( !std::any_of( body_wetness.begin(), body_wetness.end(), - []( const int w ) { - return w != 0; -} ) ) { + if( !has_atleast_one_wet_part() ) { return; } @@ -1793,7 +1790,7 @@ void Character::apply_wetness_morale( int temperature ) const auto wet_friendliness = exclusive_flag_coverage( "WATER_FRIENDLY" ); for( const bodypart_id &bp : get_all_body_parts() ) { // Sum of body wetness can go up to 103 - const int part_drench = body_wetness[bp->token]; + const int part_drench = get_part_wetness( bp ); if( part_drench == 0 ) { continue; } @@ -1825,7 +1822,7 @@ void Character::apply_wetness_morale( int temperature ) // Clamp to [COLD,HOT] and cast to double const double part_temperature = - std::min( BODYTEMP_HOT, std::max( BODYTEMP_COLD, temp_cur[bp->token] ) ); + std::min( BODYTEMP_HOT, std::max( BODYTEMP_COLD, get_part_temp_cur( bp ) ) ); // 0.0 at COLD, 1.0 at HOT const double part_mod = ( part_temperature - BODYTEMP_COLD ) / ( BODYTEMP_HOT - BODYTEMP_COLD ); diff --git a/src/weather.cpp b/src/weather.cpp index 29b899a944a0b..a497ee78a8a45 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -418,10 +418,9 @@ void wet( Character &target, int amount ) return; } - const auto &wet = target.body_wetness; - const auto &capacity = target.drench_capacity; body_part_set drenched_parts{ { bodypart_str_id( "torso" ), bodypart_str_id( "arm_l" ), bodypart_str_id( "arm_r" ), bodypart_str_id( "head" ) } }; - if( wet[bp_torso] * 100 >= capacity[bp_torso] * 50 ) { + if( get_player_character().get_part_wetness( bodypart_id( "torso" ) ) * 100 >= + get_player_character().get_part_drench_capacity( bodypart_id( "torso" ) ) * 50 ) { // Once upper body is 50%+ drenched, start soaking the legs too drenched_parts.unify_set( { { bodypart_str_id( "leg_l" ), bodypart_str_id( "leg_r" ) } } ); } diff --git a/tests/iuse_test.cpp b/tests/iuse_test.cpp index 19134bd4f9f7a..f7af1d1adb09d 100644 --- a/tests/iuse_test.cpp +++ b/tests/iuse_test.cpp @@ -326,10 +326,10 @@ TEST_CASE( "towel", "[iuse][towel]" ) // Saturate torso, head, and both arms dummy.drench( 100, { bodypart_str_id( "torso" ), bodypart_str_id( "head" ), bodypart_str_id( "arm_l" ), bodypart_str_id( "arm_r" ) }, false ); - REQUIRE( dummy.body_wetness[bp_torso] > 0 ); - REQUIRE( dummy.body_wetness[bp_head] > 0 ); - REQUIRE( dummy.body_wetness[bp_arm_l] > 0 ); - REQUIRE( dummy.body_wetness[bp_arm_r] > 0 ); + REQUIRE( dummy.get_part_wetness( bodypart_id( "torso" ) ) > 0 ); + REQUIRE( dummy.get_part_wetness( bodypart_id( "head" ) ) > 0 ); + REQUIRE( dummy.get_part_wetness( bodypart_id( "arm_l" ) ) > 0 ); + REQUIRE( dummy.get_part_wetness( bodypart_id( "arm_r" ) ) > 0 ); // FIXME: Morale alone is the trigger for drying off! // Without the morale modifier, towel_common thinks you're dry @@ -340,10 +340,10 @@ TEST_CASE( "towel", "[iuse][towel]" ) dummy.invoke_item( &towel ); THEN( "it dries them off" ) { - CHECK( dummy.body_wetness[bp_torso] == 0 ); - CHECK( dummy.body_wetness[bp_head] == 0 ); - CHECK( dummy.body_wetness[bp_arm_l] == 0 ); - CHECK( dummy.body_wetness[bp_arm_r] == 0 ); + CHECK( dummy.get_part_wetness( bodypart_id( "torso" ) ) == 0 ); + CHECK( dummy.get_part_wetness( bodypart_id( "head" ) ) == 0 ); + CHECK( dummy.get_part_wetness( bodypart_id( "arm_l" ) ) == 0 ); + CHECK( dummy.get_part_wetness( bodypart_id( "arm_r" ) ) == 0 ); AND_THEN( "the towel becomes wet" ) { CHECK( towel.typeId().str() == "towel_wet" ); @@ -357,10 +357,10 @@ TEST_CASE( "towel", "[iuse][towel]" ) dummy.invoke_item( &towel ); THEN( "it does not dry them off" ) { - CHECK( dummy.body_wetness[bp_torso] > 0 ); - CHECK( dummy.body_wetness[bp_head] > 0 ); - CHECK( dummy.body_wetness[bp_arm_l] > 0 ); - CHECK( dummy.body_wetness[bp_arm_r] > 0 ); + CHECK( dummy.get_part_wetness( bodypart_id( "torso" ) ) > 0 ); + CHECK( dummy.get_part_wetness( bodypart_id( "head" ) ) > 0 ); + CHECK( dummy.get_part_wetness( bodypart_id( "arm_l" ) ) > 0 ); + CHECK( dummy.get_part_wetness( bodypart_id( "arm_r" ) ) > 0 ); } } } diff --git a/tests/player_test.cpp b/tests/player_test.cpp index 15e64c69d73a2..f367782d16647 100644 --- a/tests/player_test.cpp +++ b/tests/player_test.cpp @@ -14,29 +14,27 @@ // core body temperature settles. static void temperature_check( Character *p, const int ambient_temp, const int target_temp ) { + p->set_body(); get_weather().temperature = ambient_temp; - for( int i = 0 ; i < num_bp; i++ ) { - p->temp_cur[i] = BODYTEMP_NORM; - } - for( int i = 0 ; i < num_bp; i++ ) { - p->temp_conv[i] = BODYTEMP_NORM; - } + p->set_all_parts_temp_cur( BODYTEMP_NORM ); + p->set_all_parts_temp_conv( BODYTEMP_NORM ); int prev_temp = 0; int prev_diff = 0; for( int i = 0; i < 10000; i++ ) { - if( prev_diff != prev_temp - p->temp_cur[0] ) { - prev_diff = prev_temp - p->temp_cur[0]; - } else if( prev_temp == p->temp_cur[0] ) { + const int torso_temp_cur = p->get_part_temp_cur( bodypart_id( "torso" ) ); + if( prev_diff != prev_temp - torso_temp_cur ) { + prev_diff = prev_temp - torso_temp_cur; + } else if( prev_temp == torso_temp_cur ) { break; } - prev_temp = p->temp_cur[0]; + prev_temp = torso_temp_cur; p->update_bodytemp(); } int high = target_temp + 100; int low = target_temp - 100; - CHECK( low < p->temp_cur[0] ); - CHECK( high > p->temp_cur[0] ); + CHECK( low < p->get_part_temp_cur( bodypart_id( "torso" ) ) ); + CHECK( high > p->get_part_temp_cur( bodypart_id( "torso" ) ) ); } static void equip_clothing( Character *p, const std::string &clothing ) From 42167a15c2ff2df3779ff070043dde61aa9f895b Mon Sep 17 00:00:00 2001 From: curstwist <39442864+curstwist@users.noreply.github.com> Date: Sat, 18 Jul 2020 09:19:17 -0400 Subject: [PATCH 124/151] Mi-go structure balance --- data/json/emit.json | 6 +- data/json/field_type.json | 12 +-- .../furniture-alien.json | 2 +- .../furniture_and_terrain/terrain-migo.json | 4 +- data/json/mapgen/mi-go/mi-go_encampment.json | 8 +- data/json/mapgen/mi-go/mi-go_nested.json | 98 +++++++++---------- data/json/mapgen/mi-go/mi-go_scout_tower.json | 40 ++++---- data/json/mapgen_palettes/mi-go_palette.json | 4 +- 8 files changed, 88 insertions(+), 86 deletions(-) diff --git a/data/json/emit.json b/data/json/emit.json index ccdb67bb86dca..18ba7cb8d6ab5 100644 --- a/data/json/emit.json +++ b/data/json/emit.json @@ -247,15 +247,15 @@ "id": "emit_hot_air_migo_seep", "type": "emit", "field": "fd_hot_air_sauna", - "intensity": 3, - "qty": 50 + "intensity": 2, + "qty": 60 }, { "id": "emit_hot_air_migo_blast", "type": "emit", "field": "fd_hot_air_sauna", "intensity": 3, - "qty": 300 + "qty": 150 }, { "id": "emit_migo_atmosphere", diff --git a/data/json/field_type.json b/data/json/field_type.json index d0439ec43ce28..4e1220480130f 100644 --- a/data/json/field_type.json +++ b/data/json/field_type.json @@ -1295,15 +1295,15 @@ "id": "fd_hot_air_sauna", "type": "field_type", "intensity_levels": [ - { "name": "hot air sauna", "sym": "&", "convection_temperature_mod": 65 }, - { "color": "yellow", "convection_temperature_mod": 68 }, - { "color": "red", "convection_temperature_mod": 71 } + { "name": "hot air sauna", "sym": "&", "convection_temperature_mod": 60 }, + { "color": "yellow", "convection_temperature_mod": 70 }, + { "color": "red", "convection_temperature_mod": 80 } ], "decay_amount_factor": 5, - "percent_spread": 100, - "outdoor_age_speedup": "100 minutes", + "percent_spread": 40, + "outdoor_age_speedup": "30 minutes", "priority": -1, - "half_life": "50 minutes", + "half_life": "5 minutes", "phase": "gas", "display_field": true }, diff --git a/data/json/furniture_and_terrain/furniture-alien.json b/data/json/furniture_and_terrain/furniture-alien.json index 000bc9d0ade37..7908f7256d13a 100644 --- a/data/json/furniture_and_terrain/furniture-alien.json +++ b/data/json/furniture_and_terrain/furniture-alien.json @@ -144,7 +144,7 @@ "coverage": 40, "required_str": -1, "flags": [ "TRANSPARENT", "EASY_DECONSTRUCT" ], - "deconstruct": { "items": [ { "item": "alien_pod_resin", "charges": [ 2, 6 ] } ] }, + "deconstruct": { "items": [ { "item": "alien_pod_resin", "count": [ 6, 8 ] } ] }, "bash": { "str_min": 25, "str_max": 60, "sound": "splorch!", "sound_fail": "whump." } }, { diff --git a/data/json/furniture_and_terrain/terrain-migo.json b/data/json/furniture_and_terrain/terrain-migo.json index c7eb7f193b73a..a09ee8905c47a 100644 --- a/data/json/furniture_and_terrain/terrain-migo.json +++ b/data/json/furniture_and_terrain/terrain-migo.json @@ -9,7 +9,7 @@ "move_cost": 0, "coverage": 100, "roof": "t_resin_roof", - "flags": [ "NOITEM", "SUPPORTS_ROOF", "WALL", "NO_SCENT", "AUTO_WALL_SYMBOL", "BLOCK_WIND" ], + "flags": [ "NOITEM", "PERMEABLE", "SUPPORTS_ROOF", "WALL", "NO_SCENT", "AUTO_WALL_SYMBOL", "BLOCK_WIND" ], "bash": { "str_min": 250, "str_max": 700, @@ -65,6 +65,7 @@ "description": "This nearly opaque, plastic-like floor is smooth and flat. The material is hard, warm to the touch, and slightly damp.", "symbol": "~", "color": "light_gray", + "looks_like": "t_floor_resin", "move_cost": 1, "flags": [ "TRANSPARENT", "COLLAPSES", "FLAT", "ROAD", "NONFLAMMABLE" ], "bash": { @@ -84,6 +85,7 @@ "symbol": "~", "color": "dark_gray", "move_cost": 2, + "looks_like": "t_floor_resin", "flags": [ "TRANSPARENT", "FLAT", "NONFLAMMABLE" ], "bash": { "str_min": 250, diff --git a/data/json/mapgen/mi-go/mi-go_encampment.json b/data/json/mapgen/mi-go/mi-go_encampment.json index 54511edd1dc9e..d3c08a119951f 100644 --- a/data/json/mapgen/mi-go/mi-go_encampment.json +++ b/data/json/mapgen/mi-go/mi-go_encampment.json @@ -25,8 +25,8 @@ "...|||||||| ||||+||| + ||...", "....||11 || || || ||| |||....", ".|||| + | | 14 |||||||| ||......", - "||10| { |+|| + 13 | ||......||||.......", - "|{ + |15||||| |||||..................", + "||10| & |+|| + 13 | ||......||||.......", + "|& + |15||||| |||||..................", "| || || || ||......................", "|| ||||+||| ||||||||.......................", ".|||+|.||16 ||||||...||.........................", @@ -70,8 +70,8 @@ "__vvvvvv__________vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv", "__vvvv|||___________vvvvvvvv|||||vvvvvvvvvvvvvvv", "___v|||i||___________vvvvvv||OOO||vvvppppvvvvvvv", - "____|> <|___________vvvvv||{ >|vpp,,,,,,Fvvvv", - "___|| {|______||____vvvv|P i V|vp,,,,,,,,,vvv", + "____|> <|___________vvvvv||& >|vpp,,,,,,Fvvvv", + "___|| &|______||____vvvv|P i i|vp,,,,,,,,,vvv", "___|PPPP||______||____vvvv|P |||p,,,,,,,,,,,vv", "___||||||_____________vvvv|P + ,,,,,,,,,,,,,vv", "______________________vvvv|||O + ,,,,,,,,,,,,,vv", diff --git a/data/json/mapgen/mi-go/mi-go_nested.json b/data/json/mapgen/mi-go/mi-go_nested.json index 44d2ac23da002..edcd6a8181630 100644 --- a/data/json/mapgen/mi-go/mi-go_nested.json +++ b/data/json/mapgen/mi-go/mi-go_nested.json @@ -8,10 +8,10 @@ "rotation": [ 0, 3 ], "rows": [ ".||||@@", - "||V +@@", - "|V {|@@", + "||T +@@", + "|& P|@@", "|| |@@", - ".| V|@@", + ".| T|@@", ".| ||@@", ".|+||@@" ], @@ -30,7 +30,7 @@ ".||||||.", "||PPPP||", "+ i P|", - "| { +", + "| & +", "|P P|", "||PPPP||", "|||||||@", @@ -50,7 +50,7 @@ "rows": [ "||#@@@@|", "+ #####|", - "| iV+", + "| iT+", "||PFPV||", "@||||||@", "@@@@@@@@", @@ -72,7 +72,7 @@ "rows": [ "..||...", "||||||.", - "| # ||", + "|V # ||", "|# # |", "@#####|", "@@@@@@@", @@ -102,10 +102,10 @@ "rotation": [ 0, 3 ], "rows": [ ".|||||@", - "|| { @", + "|| P @", "+ @", - "| F @", - "| { @", + "| &F @", + "| P @", "|| i@", "@|+|||@" ], @@ -126,16 +126,16 @@ "......||||||......", "....|||PPPP|||....", "..|||PP #1|||..", - "|||PP i ### ||.", - "|< { #2 |.", - "|| VnV i ###||", + "|||&P i ### ||.", + "|< P #2 |.", + "|| TnT i ###||", "@|i nnn #3|", - "@|i nnn i # |", - "@+ VnV ###||", + "@|i nnn &i # |", + "@+ TnT ###||", "|| i #4 |.", - "|P { ### ###|.", + "|P P ### ###|.", "+ i # ####5||.", - "|||PPPP #7#6 |||..", + "|||VPPP #7#6 |||..", "@@||||||||# ||....", "@||......||||.....", "@@@@@@@@@@@@@@@@@@", @@ -167,9 +167,9 @@ "rows": [ ".|+|||||", "|| ||", - "|V i |", - "|i {i |", - "|V +", + "|T i |", + "|i &i |", + "|T +", "||PPPP||", ".|||||||", "@@@@@@@@" @@ -190,8 +190,8 @@ "|||| |||", "|| ### |", "|P ###", - "|P iV # ", - "|P i{ #|", + "|P iT # ", + "|P &P #|", "+ ||", "|###|+|@", "|| ||@@@" @@ -218,11 +218,11 @@ "|||P|+|||", "|P PPP", "|P P i ", - "| V ", - "| { ", - "|V { ", - "|||V { ", - "@@|||V ", + "| T ", + "| & ", + "|T P ", + "|||T P ", + "@@|||T V ", "@@@@||||+" ], "place_monsters": [ { "monster": "GROUP_MI-GO_BASE_COMMON", "x": [ 1, 8 ], "y": [ 3, 5 ], "density": 0.01, "repeat": [ 0, 2 ] } ], @@ -241,11 +241,11 @@ "|||.||@@@", "PP|||<@@@", " P||@@@", - "i PVP|@@@", - " P P|@@@", + "i PTP|@@@", + "V P P|@@@", "i +@@@", " PP||@@@", - "P |||@@@@", + "P&|||@@@@", "|||@+@@@@" ], "place_monsters": [ { "monster": "GROUP_MI-GO_BASE_COMMON", "x": [ 0, 3 ], "y": [ 2, 5 ], "density": 0.01, "repeat": [ 0, 2 ] } ], @@ -262,8 +262,8 @@ "rotation": [ 0, 3 ], "rows": [ ".||||@", - "||Vi|@", - "|{ +@", + "||Ti|@", + "|V +@", "| ||", "||i |", ".|||+|" @@ -280,11 +280,11 @@ "rotation": [ 0, 3 ], "rows": [ "|||||||@", - "||ViV ||", - "| V +", + "||TiT ||", + "| & +", "| || |", "+ i|", - "||{ ||", + "||P V ||", "@||||+||", "@@@@@@@@" ], @@ -303,9 +303,9 @@ "@|+|P|||@@", "|| |||", "|P i P|", - "|| i{i ||", + "|| i&i ||", "@+ |@", - "@|+||V +@", + "@|+||T +@", "@|@@|||||@", "@@@@@@@@@@", "@@@@@@@@@@", @@ -324,11 +324,11 @@ "rotation": [ 0, 3 ], "rows": [ "@||||+||", - "||V ||", - "| {V |", - "+ i |", - "| {V |", - "||V ||", + "||T ||", + "| PT |", + "+ i& |", + "| PT |", + "||T ||", "|||||||.", "@@@@@@@@" ], @@ -347,7 +347,7 @@ "@|||@@", "|| +@@", "|##|||", - "|1 {|", + "|1 P|", "| 1||", "|||||." ], @@ -407,16 +407,16 @@ "vvvvvv||||||vvvvvv", "vvvv|||PPPP|||vvvv", "vv|||PP #1|||vv", - "|||PP i ### ||v", - "|< { #2 |v", - "|> VnV i ###||", + "|||VP i ### ||v", + "|< P #2 |v", + "|> TnT i ###||", "@|i nnn #3|", - "@|i nnn i # |", - "@+ VnV ###||", + "@|i nnn & # |", + "@| TnT ###||", "|| i #4 |v", - "|P { ### ###|v", + "|P P ### ###|v", "| i # ####5||v", - "|||PPPP #7#6 |||vv", + "|||VPPP #7#6 |||vv", "@@||||||||# ||vvvv", "@||vvvvvv||||vvvvv", "@vvv@@@@@@@@@@@@@@", diff --git a/data/json/mapgen/mi-go/mi-go_scout_tower.json b/data/json/mapgen/mi-go/mi-go_scout_tower.json index ec101401e862d..91c6542ff3b32 100644 --- a/data/json/mapgen/mi-go/mi-go_scout_tower.json +++ b/data/json/mapgen/mi-go/mi-go_scout_tower.json @@ -12,19 +12,19 @@ "............||..........", "..........||||||........", "........|||TPTP|||......", - "......||| |||....", - "....||| T||...", + "......||| V|||....", + "....|||V T||...", "...||< T |...", "...||| P P ||..", - "....|| T T|..", + "....|| & T|..", ".....| P P T|..", ".....+ ||..", "....|| TPTP TPTP|...", - "..||| |...", - "||| + TPTP ||...", + "..|||V |...", + "||| + TPTP V ||...", "|| ||| TPTP |||....", "|| 14 ||||||||TT||......", - ".| ||......||||.......", + ".|& ||......||||.......", ".|||||..................", "........................", "........................", @@ -49,18 +49,18 @@ "vvvvvvvvvvvv||vvvvvvvvvv", "vvvvvvvvvv||||||vvvvvvvv", "vvvvvvvv||| O|||vvvvvv", - "vvvvvv||| O{O |||vvvv", + "vvvvvv||| OTO |||vvvv", "vvvv|||i O O i O||vvv", - "vvv||> O{O O{O|vvv", + "vvv||> OTO OTO|vvv", "vvv||< O O O ||vv", - "vvvv||i F O{O i|vv", + "vvvv||i F OTO i|vv", "vvvvv| O O O |vv", - "vvvvv| O{O O{O ||vv", + "vvvvv| OTO OTO ||vv", "vvvv|| i O O O |vvv", - "vv||| O{O {V|vvv", - "||| + F V O ||vvv", - "||{ ||| i F|||vvvv", - "||V i||||||||iV||vvvvvv", + "vv||| OTO T |vvv", + "||| + F & O V||vvv", + "||T ||| i F|||vvvv", + "|| i||||||||ii||vvvvvv", "v|PPP||vvvvvv||||vvvvvvv", "v|||||vvvvvvvvvvvvvvvvvv", "vvvvvvvvvvvvvvvvvvvvvvvv", @@ -124,20 +124,20 @@ "vvvvvvvvvvvvvvvvvvvvvvvv", "vvvvvvvvvvvv##vvvvvvvvvv", "vvvvvvvvvv######vvvvvvvv", - "vvvvvvvv###_iV_###vvvvvv", + "vvvvvvvv###_ii_###vvvvvv", "vvvvvv###________###vvvv", "vvvv###____________##vvv", "vvv##>___T__________#vvv", - "vvv##_______________##vv", + "vvv##&_______&______##vv", "vvvv##_______________ivv", "vvvvvi_______T________vv", "vvvvv_________________vv", "vvvvi____________T___vvv", - "vv###_______________ivvv", + "vv###________&______ivvv", "###_+____T_________##vvv", - "##{_###__________###vvvv", - "##V__i#i____i___##vvvvvv", - "v#VV_##vvvvvv####vvvvvvv", + "##T_###__________###vvvv", + "##P__i#i____i___##vvvvvv", + "v#iP_##vvvvvv####vvvvvvv", "v#####vvvvvvvvvvvvvvvvvv", "vvvvvvvvvvvvvvvvvvvvvvvv", "vvvvvvvvvvvvvvvvvvvvvvvv", diff --git a/data/json/mapgen_palettes/mi-go_palette.json b/data/json/mapgen_palettes/mi-go_palette.json index 9aa197311db2c..888ca25f50de4 100644 --- a/data/json/mapgen_palettes/mi-go_palette.json +++ b/data/json/mapgen_palettes/mi-go_palette.json @@ -32,9 +32,9 @@ "i": "f_alien_tendril", "n": "f_alien_table", "V": "f_alien_anemone", - "{": "f_alien_gasper", + "&": "f_alien_gasper", "F": "f_alien_zapper", - "T": [ "f_alien_zapper", [ "f_alien_gasper", 2 ], [ "f_alien_tendril", 4 ], [ "f_alien_anemone", 2 ] ], + "T": [ "f_alien_zapper", [ "f_alien_tendril", 4 ] ], "P": [ [ "f_alien_pod", 2 ], [ "f_alien_pod_organ", 2 ], "f_alien_pod_resin" ], "p": [ [ "f_alien_pod", 2 ], [ "f_alien_pod_organ", 2 ], "f_alien_pod_resin" ], "O": "f_alien_pod_resin" From 3312299c1f3d09eb4e329d5412673f7c0d8356c2 Mon Sep 17 00:00:00 2001 From: olanti-p Date: Sun, 19 Jul 2020 04:09:44 +0300 Subject: [PATCH 125/151] Clean up aim_activity_actor --- src/activity_actor.cpp | 85 ++++++++++++------------------------------ src/activity_actor.h | 19 +++------- 2 files changed, 28 insertions(+), 76 deletions(-) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index 8fc9207bc27ee..e98ea82b2868c 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -62,33 +62,6 @@ static const quality_id qual_LOCKPICK( "LOCKPICK" ); static const activity_id ACT_EAT_MENU( "ACT_EAT_MENU" ); -template<> -struct enum_traits { - static constexpr aim_activity_actor::WeaponSource last = - aim_activity_actor::WeaponSource::NumWeaponSources; -}; - -namespace io -{ -using WS = aim_activity_actor::WeaponSource; - -template<> -std::string enum_to_string( WS data ) -{ - switch( data ) { - // *INDENT-OFF* - case WS::Wielded: return "Wielded"; - case WS::Bionic: return "Bionic"; - case WS::Mutation: return "Mutation"; - // *INDENT-ON* - case WS::NumWeaponSources: - break; - } - debugmsg( "Invalid weapon source" ); - abort(); -} -} // namespace io - aim_activity_actor::aim_activity_actor() { initial_view_offset = get_avatar().view_offset; @@ -103,17 +76,15 @@ aim_activity_actor aim_activity_actor::use_bionic( const item &fake_gun, const units::energy &cost_per_shot ) { aim_activity_actor act = aim_activity_actor(); - act.weapon_source = WeaponSource::Bionic; act.bp_cost_per_shot = cost_per_shot; - act.fake_weapon = make_shared_fast( fake_gun ); + act.fake_weapon = fake_gun; return act; } aim_activity_actor aim_activity_actor::use_mutation( const item &fake_gun ) { aim_activity_actor act = aim_activity_actor(); - act.weapon_source = WeaponSource::Mutation; - act.fake_weapon = make_shared_fast( fake_gun ); + act.fake_weapon = fake_gun; return act; } @@ -127,14 +98,10 @@ void aim_activity_actor::start( player_activity &act, Character &/*who*/ ) void aim_activity_actor::do_turn( player_activity &act, Character &who ) { - if( aborted || finished ) { - // A shortcut that allows terminating this activity by setting 'aborted' or 'finished' - act.moves_left = 0; - return; - } if( !who.is_avatar() ) { debugmsg( "ACT_AIM not implemented for NPCs" ); aborted = true; + act.moves_left = 0; return; } avatar &you = get_avatar(); @@ -142,6 +109,7 @@ void aim_activity_actor::do_turn( player_activity &act, Character &who ) item *weapon = get_weapon(); if( !weapon || !avatar_action::can_fire_weapon( you, get_map(), *weapon ) ) { aborted = true; + act.moves_left = 0; return; } @@ -149,6 +117,7 @@ void aim_activity_actor::do_turn( player_activity &act, Character &who ) if( first_turn && gun->has_flag( flag_RELOAD_AND_SHOOT ) && !gun->ammo_remaining() ) { if( !load_RAS_weapon() ) { aborted = true; + act.moves_left = 0; return; } } @@ -157,10 +126,12 @@ void aim_activity_actor::do_turn( player_activity &act, Character &who ) target_handler::trajectory trajectory = target_handler::mode_fire( you, *this ); g->reenter_fullscreen(); - if( !aborted ) { + if( aborted ) { + act.moves_left = 0; + } else { if( !trajectory.empty() ) { - finished = true; fin_trajectory = trajectory; + act.moves_left = 0; } // If aborting on the first turn, keep 'first_turn' as 'true'. // This allows refunding moves spent on unloading RELOAD_AND_SHOOT weapons @@ -173,6 +144,10 @@ void aim_activity_actor::finish( player_activity &act, Character &who ) { act.set_to_null(); restore_view(); + item *weapon = get_weapon(); + if( !weapon ) { + return; + } if( aborted ) { unload_RAS_weapon(); if( reload_requested ) { @@ -184,7 +159,6 @@ void aim_activity_actor::finish( player_activity &act, Character &who ) } // Fire! - item *weapon = get_weapon(); gun_mode gun = weapon->gun_current_mode(); int shots_fired = static_cast( &who )->fire_gun( fin_trajectory.back(), gun.qty, *gun ); @@ -204,10 +178,7 @@ void aim_activity_actor::serialize( JsonOut &jsout ) const { jsout.start_object(); - jsout.member( "weapon_source", weapon_source ); - if( weapon_source == WeaponSource::Bionic || weapon_source == WeaponSource::Mutation ) { - jsout.member( "fake_weapon", *fake_weapon ); - } + jsout.member( "fake_weapon", fake_weapon ); jsout.member( "bp_cost_per_shot", bp_cost_per_shot ); jsout.member( "first_turn", first_turn ); jsout.member( "action", action ); @@ -224,11 +195,7 @@ std::unique_ptr aim_activity_actor::deserialize( JsonIn &jsin ) JsonObject data = jsin.get_object(); - data.read( "weapon_source", actor.weapon_source ); - if( actor.weapon_source == WeaponSource::Bionic || actor.weapon_source == WeaponSource::Mutation ) { - actor.fake_weapon = make_shared_fast(); - data.read( "fake_weapon", *actor.fake_weapon ); - } + data.read( "fake_weapon", actor.fake_weapon ); data.read( "bp_cost_per_shot", actor.bp_cost_per_shot ); data.read( "first_turn", actor.first_turn ); data.read( "action", actor.action ); @@ -241,20 +208,14 @@ std::unique_ptr aim_activity_actor::deserialize( JsonIn &jsin ) item *aim_activity_actor::get_weapon() { - switch( weapon_source ) { - case WeaponSource::Wielded: { - Character &player_character = get_player_character(); - // Check for lost gun (e.g. yanked by zombie technician) - // TODO: check that this is the same gun that was used to start aiming - return player_character.weapon.is_null() ? nullptr : &player_character.weapon; - } - case WeaponSource::Bionic: - case WeaponSource::Mutation: - // TODO: check if the player lost relevant bionic/mutation - return fake_weapon.get(); - default: - debugmsg( "Invalid weapon source value" ); - return nullptr; + if( fake_weapon.has_value() ) { + // TODO: check if the player lost relevant bionic/mutation + return &fake_weapon.value(); + } else { + // Check for lost gun (e.g. yanked by zombie technician) + // TODO: check that this is the same gun that was used to start aiming + item *weapon = &get_player_character().weapon; + return weapon->is_null() ? nullptr : weapon; } } diff --git a/src/activity_actor.h b/src/activity_actor.h index dc2a52020e960..b8a6cc3f00fdf 100644 --- a/src/activity_actor.h +++ b/src/activity_actor.h @@ -11,7 +11,6 @@ #include "clone_ptr.h" #include "item_location.h" #include "item.h" -#include "memory_fast.h" #include "point.h" #include "type_id.h" #include "units.h" @@ -109,17 +108,12 @@ class activity_actor class aim_activity_actor : public activity_actor { - public: - enum class WeaponSource : int { - Wielded, - Bionic, - Mutation, - NumWeaponSources - }; - - WeaponSource weapon_source = WeaponSource::Wielded; - shared_ptr_fast fake_weapon = nullptr; + private: + cata::optional fake_weapon; units::energy bp_cost_per_shot = 0_J; + std::vector fin_trajectory; + + public: bool first_turn = true; std::string action = ""; bool snap_to_target = false; @@ -127,14 +121,11 @@ class aim_activity_actor : public activity_actor tripoint initial_view_offset; /** Target UI requested to abort aiming */ bool aborted = false; - /** Target UI requested to fire */ - bool finished = false; /** * Target UI requested to abort aiming and reload weapon * Implies aborted = true */ bool reload_requested = false; - std::vector fin_trajectory; aim_activity_actor(); From d512f02d92b5b9483bda2adaa3dbfb8b7ef3fd41 Mon Sep 17 00:00:00 2001 From: Qrox Date: Sun, 19 Jul 2020 13:12:15 +0800 Subject: [PATCH 126/151] Fix moving all from inventory or worn items always dropping to vehicle/ground regardless of destination --- src/advanced_inv.cpp | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/advanced_inv.cpp b/src/advanced_inv.cpp index 0339993e8eb2f..05a2db48cb938 100644 --- a/src/advanced_inv.cpp +++ b/src/advanced_inv.cpp @@ -851,6 +851,19 @@ bool advanced_inventory::move_all_items( bool nested_call ) map &here = get_map(); if( spane.get_area() == AIM_INVENTORY || spane.get_area() == AIM_WORN ) { + if( dpane.get_area() == AIM_INVENTORY ) { + popup( _( "You try to put you bags into themselves, but physics won't let you." ) ); + return false; + } else if( dpane.get_area() == AIM_WORN ) { + // TODO: implement this + popup( _( "Putting on everything from you inventory would be tricky." ) ); + return false; + } else if( dpane.get_area() == AIM_CONTAINER ) { + // TODO: implement this + popup( _( "Putting everything into the container would be tricky." ) ); + return false; + } + drop_locations dropped; // keep a list of favorites separated, only drop non-fav first if they exist drop_locations dropped_favorite; @@ -896,7 +909,24 @@ bool advanced_inventory::move_all_items( bool nested_call ) dropped = dropped_favorite; } - player_character.drop( dropped, player_character.pos() + darea.off ); + // make sure advanced inventory is reopened after activity completion. + do_return_entry(); + + player_character.assign_activity( ACT_DROP ); + player_character.activity.placement = darea.off; + + // in case there is vehicle cargo space at dest but the player wants to drop to ground + if( !dpane.in_vehicle() ) { + player_character.activity.str_values.push_back( "force_ground" ); + } + + for( const std::pair &it : dropped ) { + player_character.activity.targets.emplace_back( it.first ); + player_character.activity.values.emplace_back( it.second ); + } + + // exit so that the activity can be carried out + exit = true; } else { if( dpane.get_area() == AIM_INVENTORY || dpane.get_area() == AIM_WORN ) { player_character.activity.coords.push_back( player_character.pos() ); From 477f2b4ab46071b975b7b440ac6a15b61b398e07 Mon Sep 17 00:00:00 2001 From: UrbanCMC Date: Sun, 19 Jul 2020 13:46:00 +0200 Subject: [PATCH 127/151] character: Remove comestibles after using last charge --- src/character.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/character.cpp b/src/character.cpp index 17bc119d9b0e7..8aec01012455c 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -7877,7 +7877,7 @@ bool Character::invoke_item( item *used, const std::string &method, const tripoi return true; } else if( used->is_comestible() ) { const bool ret = consume_effects( *used ); - used->charges -= charges_used; + consume_charges( *used, charges_used ); return ret; } From c7e03e15c4d44481ba1161fc531789d14ab9a340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Karlsson?= Date: Mon, 20 Jul 2020 04:23:16 +0200 Subject: [PATCH 128/151] Audit guns 22lr (#42285) * Review values for American-180 * Review Marlin 39A values * Review Mossberg Brownie values * Review longest_side for pipe rifle * Review Ruger 10/22 values * Review SIG Mosquito values * Review S&W 22A values * Review Jennings J-22 values * Review Walther P22 values --- data/json/items/gun/22.json | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/data/json/items/gun/22.json b/data/json/items/gun/22.json index 97d7ebdbfa5be..d16f355b601ae 100644 --- a/data/json/items/gun/22.json +++ b/data/json/items/gun/22.json @@ -6,8 +6,9 @@ "reload_noise_volume": 10, "name": { "str_sp": "American-180" }, "description": "The American-180 is a submachine gun developed in the 1960's that fires .22 LR, unusual for an SMG. Though the round is low-powered, the high rate of fire and large magazine makes the 180 a formidable weapon.", - "weight": "2600 g", - "volume": "1250 ml", + "weight": "2585 g", + "volume": "2200 ml", + "longest_side": "905 mm", "price": 163000, "price_postapoc": 2500, "to_hit": -2, @@ -56,7 +57,8 @@ "name": { "str_sp": "Marlin 39A" }, "description": "The oldest and longest-produced shoulder firearm in the world. Though it fires the weak .22 round, it is highly accurate and damaging, and has essentially no recoil.", "weight": "2948 g", - "volume": "2500 ml", + "volume": "2180 ml", + "longest_side": "1029 mm", "price": 23000, "price_postapoc": 2000, "to_hit": -1, @@ -105,8 +107,9 @@ "type": "GUN", "name": { "str_sp": "Mossberg Brownie" }, "description": "The first gun produced by O.F. Mossberg & Sons. A small pocket pistol, marketed to trappers during the early 20th century. Its four barrels can accept .22 Short and .22 LR cartridges.", - "weight": "280 g", - "volume": "137ml", + "weight": "286 g", + "volume": "100 ml", + "longest_side": "129 mm", "price": 110000, "price_postapoc": 500, "to_hit": -1, @@ -142,6 +145,7 @@ "description": "A home-made rifle. It is simply a pipe attached to a stock, with a hammer to strike the single round it holds.", "weight": "1953 g", "volume": "1750 ml", + "longest_side": "1000 mm", "price": 10000, "price_postapoc": 500, "to_hit": -1, @@ -181,7 +185,8 @@ "name": { "str_sp": "Ruger 10/22" }, "description": "A combination of negligible recoil, high customization, and inexpensive ammunition made the Ruger 10/22 a popular choice among enthusiasts and small game hunters. Even though it fires the weak .22 round, it's perfectly capable of killing.", "weight": "2270 g", - "volume": "2500 ml", + "volume": "2120 ml", + "longest_side": "942 mm", "price": 27000, "price_postapoc": 750, "to_hit": -1, @@ -240,8 +245,9 @@ "reload_noise_volume": 10, "name": { "str_sp": "SIG Mosquito" }, "description": "A popular, small .22 LR pistol. One of the many polymer frame pistols produced during the latter 20th-early 21st centuries; it has an underbarrel rail.", - "weight": "700 g", - "volume": "250 ml", + "weight": "720 g", + "volume": "450 ml", + "longest_side": "214 mm", "price": 36000, "price_postapoc": 750, "to_hit": -2, @@ -287,8 +293,9 @@ "type": "GUN", "name": { "str_sp": "S&W 22A" }, "description": "A popular .22 pistol.", - "weight": "1000 g", - "volume": "500 ml", + "weight": "975 g", + "volume": "560 ml", + "longest_side": "259 mm", "price": 35000, "price_postapoc": 750, "to_hit": -2, @@ -317,8 +324,9 @@ "type": "GUN", "name": { "str": "Jennings J-22" }, "description": "One of the quintessential 'saturday night specials', the Jennings J-22 was very affordably priced with its injection molded zinc slide and frame. Intended to fill the void left after small pocket pistols were banned from import, these were more commonly used by criminals unfazed by their glaring safety issues.", - "weight": "370 g", - "volume": "123ml", + "weight": "340 g", + "volume": "80 ml", + "longest_side": "141 mm", "price": 7000, "price_postapoc": 750, "to_hit": -3, @@ -348,8 +356,9 @@ "type": "GUN", "name": { "str": "Walther P22" }, "description": "The Walther P22 is a blowback operated semi-automatic pistol. It is about half the size of most Walthers. It is made mostly with plastic, with the slide and key components being made of die-cast zinc alloy", - "weight": "450 g", - "volume": "263 ml", + "weight": "480 g", + "volume": "290 ml", + "longest_side": "183 mm", "price": 8500, "price_postapoc": 750, "to_hit": -3, From 309e58a0e1a927c08e4799d3cf5912e1d4b85976 Mon Sep 17 00:00:00 2001 From: eso Date: Sun, 19 Jul 2020 15:19:20 -0700 Subject: [PATCH 129/151] add trader_keep and trader_keep_equipped flags because sometimes a thing is just to precious to sell --- doc/JSON_FLAGS.md | 2 ++ src/npc.cpp | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index c586b27509bfc..3d0a35e22c74f 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -699,6 +699,8 @@ List of known flags, used in both `terrain.json` and `furniture.json`. - ```TIE_UP``` ... Item can be used to tie up a creature. - ```TINDER``` ... This item can be used as tinder for lighting a fire with a REQUIRES_TINDER flagged firestarter. - ```TRADER_AVOID``` ... NPCs will not start with this item. Use this for active items (e.g. flashlight (on)), dangerous items (e.g. active bomb), fake item or unusual items (e.g. unique quest item). +- ```TRADER_KEEP``` ... NPCs will not trade this item away under any circumstances. +- ```TRADER_KEEP_EQUIPPED``` ... NPCs will only trade this item if they aren't currently wearing or wielding it. - ```UNBREAKABLE_MELEE``` ... Does never get damaged when used as melee weapon. - ```UNRECOVERABLE``` ... Cannot be recovered from a disassembly. diff --git a/src/npc.cpp b/src/npc.cpp index b09f9c5eabf76..c3c628eeb759f 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -1581,9 +1581,14 @@ bool npc::wants_to_sell( const item &it ) const return wants_to_sell( it, value( it, market_price ), market_price ); } -bool npc::wants_to_sell( const item &/*it*/, int at_price, int market_price ) const +bool npc::wants_to_sell( const item &it, int at_price, int market_price ) const { if( mission == NPC_MISSION_SHOPKEEP ) { + // keep items that we either never want to trade, or don't want to trade while in use + if( it.has_flag( "TRADER_KEEP" ) || + ( it.has_flag( "TRADER_KEEP_EQUIPPED" ) && ( is_worn( it ) || is_wielding( it ) ) ) ) { + return false; + } return true; } From 7dd0906872a8d25479c7617acd4c793284e3bec3 Mon Sep 17 00:00:00 2001 From: DialoMalison Date: Thu, 16 Jul 2020 14:00:00 -0400 Subject: [PATCH 130/151] Add disassembly recipes --- data/json/recipes/recipe_deconstruction.json | 50 +++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index 23af20c6dda2a..a034195973caf 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -2051,7 +2051,7 @@ "result": "glass", "type": "uncraft", "time": "1 s", - "components": [ [ [ "glass_shard", 4 ] ] ] + "components": [ [ [ "glass_shard", 3 ] ] ] }, { "result": "glass_bowl", @@ -2065,6 +2065,54 @@ "time": "1 s", "components": [ [ [ "glass_shard", 4 ] ] ] }, + { + "result": "jar_3l_glass", + "type": "uncraft", + "time": "1 s", + "components": [ [ [ "glass_shard", 10 ] ] ] + }, + { + "result": "bottle_glass", + "type": "uncraft", + "time": "1 s", + "components": [ [ [ "glass_shard", 3 ] ] ] + }, + { + "result": "flask_glass", + "type": "uncraft", + "time": "1 s", + "components": [ [ [ "glass_shard", 2 ] ] ] + }, + { + "result": "jar_glass", + "type": "uncraft", + "time": "1 s", + "components": [ [ [ "glass_shard", 4 ] ] ] + }, + { + "result": "beaker", + "type": "uncraft", + "time": "1 s", + "components": [ [ [ "glass_shard", 2 ] ] ] + }, + { + "result": "gradcylinder", + "type": "uncraft", + "time": "1 s", + "components": [ [ [ "glass_shard", 2 ] ] ] + }, + { + "result": "fish_bowl", + "type": "uncraft", + "time": "1 s", + "components": [ [ [ "glass_shard", 7 ] ] ] + }, + { + "result": "mirror", + "type": "uncraft", + "time": "1 s", + "components": [ [ [ "glass_shard", 3 ] ] ] + }, { "result": "glass_sheet", "type": "uncraft", From bd4ded9a1b87be69cc8762594dad5906c3c7bb5a Mon Sep 17 00:00:00 2001 From: ussdefiant Date: Sat, 18 Jul 2020 10:45:15 -0600 Subject: [PATCH 131/151] change red fox harvest_type --- data/json/monsters/mammal.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/json/monsters/mammal.json b/data/json/monsters/mammal.json index bb559d79c4962..e7c9eab5ad0cd 100644 --- a/data/json/monsters/mammal.json +++ b/data/json/monsters/mammal.json @@ -1626,7 +1626,7 @@ "melee_cut": 2, "dodge": 6, "vision_night": 5, - "harvest": "mammal_tiny", + "harvest": "mammal_small_fur", "anger_triggers": [ "FRIEND_ATTACKED", "FRIEND_DIED" ], "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], "placate_triggers": [ "MEAT" ], From 798a3ed0ef3fce7df5c82e430c55670c2e35d6e8 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Sat, 18 Jul 2020 13:13:50 -0500 Subject: [PATCH 132/151] dialogue: don't clear training without need Confirm that a skill, style, or spell is being trained before clearing a previous response's stored training option. This will fix the bug that prevented NPCs from training the avatar. --- src/dialogue.h | 4 ++-- src/dialogue_chatbin.cpp | 11 +++++++---- src/npctalk_funcs.cpp | 31 ++++++++++++++++--------------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/dialogue.h b/src/dialogue.h index 728a550c4028f..a0bebee5d01df 100644 --- a/src/dialogue.h +++ b/src/dialogue.h @@ -204,8 +204,8 @@ struct talk_response { * The following values are forwarded to the chatbin of the NPC (see @ref npc_chatbin). */ mission *mission_selected = nullptr; - skill_id skill = skill_id::NULL_ID(); - matype_id style = matype_id::NULL_ID(); + skill_id skill = skill_id(); + matype_id style = matype_id(); spell_id dialogue_spell = spell_id(); talk_effect_t success; diff --git a/src/dialogue_chatbin.cpp b/src/dialogue_chatbin.cpp index 7332e91e96c36..7500628030423 100644 --- a/src/dialogue_chatbin.cpp +++ b/src/dialogue_chatbin.cpp @@ -23,10 +23,13 @@ void dialogue_chatbin::check_missions() void dialogue_chatbin::store_chosen_training( const skill_id &c_skill, const matype_id &c_style, const spell_id &c_spell ) { + if( c_skill == skill_id() && c_style == matype_id() && c_spell == spell_id() ) { + return; + } clear_training(); - if( c_skill ) { + if( c_skill != skill_id() ) { skill = c_skill; - } else if( c_style ) { + } else if( c_style != matype_id() ) { style = c_style; } else if( c_spell != spell_id() ) { dialogue_spell = c_spell; @@ -35,8 +38,8 @@ void dialogue_chatbin::store_chosen_training( const skill_id &c_skill, const mat void dialogue_chatbin::clear_training() { - style = matype_id::NULL_ID(); - skill = skill_id::NULL_ID(); + style = matype_id(); + skill = skill_id(); dialogue_spell = spell_id(); } diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index ec84410e5fcc8..218c627dcb265 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -920,24 +920,26 @@ void talk_function::start_training( npc &p ) const matype_id &style = p.chatbin.style; const spell_id &sp_id = p.chatbin.dialogue_spell; int expert_multiplier = 1; - Character &player_character = get_player_character(); - if( skill.is_valid() && player_character.get_skill_level( skill ) < p.get_skill_level( skill ) ) { + Character &you = get_player_character(); + if( skill != skill_id() && + you.get_skill_level( skill ) < p.get_skill_level( skill ) ) { cost = calc_skill_training_cost( p, skill ); time = calc_skill_training_time( p, skill ); name = skill.str(); - } else if( p.chatbin.style.is_valid() && - !player_character.martial_arts_data.has_martialart( style ) ) { + } else if( p.chatbin.style != matype_id() && + !you.martial_arts_data.has_martialart( style ) ) { cost = calc_ma_style_training_cost( p, style ); time = calc_ma_style_training_time( p, style ); name = p.chatbin.style.str(); // already checked if can learn this spell in npctalk.cpp - } else if( p.chatbin.dialogue_spell.is_valid() ) { + } else if( p.chatbin.dialogue_spell != spell_id() ) { const spell &temp_spell = p.magic.get_spell( sp_id ); - const bool knows = player_character.magic.knows_spell( sp_id ); - cost = p.calc_spell_training_cost( knows, temp_spell.get_difficulty(), temp_spell.get_level() ); + const bool knows = you.magic.knows_spell( sp_id ); + cost = p.calc_spell_training_cost( knows, temp_spell.get_difficulty(), + temp_spell.get_level() ); name = temp_spell.id().str(); - expert_multiplier = knows ? temp_spell.get_level() - player_character.magic.get_spell( - sp_id ).get_level() : 1; + expert_multiplier = knows ? temp_spell.get_level() - + you.magic.get_spell( sp_id ).get_level() : 1; // quicker to learn with instruction as opposed to books. // if this is a known spell, then there is a set time to gain some exp. // if player doesn't know this spell, then the NPC will teach all of it @@ -947,9 +949,8 @@ void talk_function::start_training( npc &p ) if( knows ) { time = 1_hours; } else { - time = time_duration::from_seconds( clamp( player_character.magic.time_to_learn_spell( - player_character, sp_id ) / 50, 7200, - 21600 ) ); + const int time_int = you.magic.time_to_learn_spell( you, sp_id ) / 50; + time = time_duration::from_seconds( clamp( time_int, 7200, 21600 ) ); } } else { debugmsg( "start_training with no valid skill or style set" ); @@ -957,8 +958,8 @@ void talk_function::start_training( npc &p ) } mission *miss = p.chatbin.mission_selected; - if( miss != nullptr && miss->get_assigned_player_id() == player_character.getID() && - miss->is_complete( player_character.getID() ) ) { + if( miss != nullptr && miss->get_assigned_player_id() == you.getID() && + miss->is_complete( you.getID() ) ) { clear_mission( p ); } else if( !npc_trading::pay_npc( p, cost ) ) { return; @@ -966,7 +967,7 @@ void talk_function::start_training( npc &p ) player_activity act = player_activity( ACT_TRAIN, to_moves( time ), p.getID().get_value(), 0, name ); act.values.push_back( expert_multiplier ); - player_character.assign_activity( act ); + you.assign_activity( act ); p.add_effect( effect_asked_to_train, 6_hours ); } From b47c984c9a2b0f6672f6bf32863748b56c10ec1d Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Sun, 19 Jul 2020 20:30:51 -0400 Subject: [PATCH 133/151] Use --min-duration when running tests To reduce the test output spam while still allowing us to see the very slow tests, only display the time taken for tests taking more than 0.2s. --- .appveyor.yml | 2 +- build-scripts/build.sh | 4 ++-- tests/Makefile | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index ee4818c7917e0..8842739492a15 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -12,4 +12,4 @@ build: parallel: true verbosity: minimal test_script: - - cmd: Cataclysm-test-vcpkg-static-Release-x64.exe --rng-seed time + - cmd: Cataclysm-test-vcpkg-static-Release-x64.exe --rng-seed time --min-duration 0.2 diff --git a/build-scripts/build.sh b/build-scripts/build.sh index eebe7f135dedc..c89f6b78bf4ba 100755 --- a/build-scripts/build.sh +++ b/build-scripts/build.sh @@ -8,8 +8,8 @@ num_jobs=3 function run_tests { - # The grep suppresses lines that begin with "0.0## s:", which are timing lines for tests with a very short duration. - $WINE "$@" -d yes --use-colour yes --rng-seed time $EXTRA_TEST_OPTS | grep -Ev "^0\.0[0-9]{2} s:" + # --min-duration shows timing lines for tests with a duration of at least that many seconds. + $WINE "$@" --min-duration 0.2 --use-colour yes --rng-seed time $EXTRA_TEST_OPTS } # We might need binaries installed via pip, so ensure that our personal bin dir is on the PATH diff --git a/tests/Makefile b/tests/Makefile index 96fb3204a6749..3864baad0bdd3 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -36,7 +36,7 @@ $(TEST_TARGET): $(OBJS) $(CATA_LIB) # Iterate over all the individual tests. check: $(TEST_TARGET) - cd .. && tests/$(TEST_TARGET) -d yes --rng-seed time + cd .. && tests/$(TEST_TARGET) --min-duration 0.2 --rng-seed time clean: rm -rf *obj *objwin From e3818333b115b3ad6b16819cfbf17cc100d347a7 Mon Sep 17 00:00:00 2001 From: LaVeyanFiend Date: Sun, 19 Jul 2020 22:40:27 -0400 Subject: [PATCH 134/151] Tornskin spell --- data/mods/Magiclysm/Spells/druid.json | 36 +++++++++++++++++++ data/mods/Magiclysm/effects/effects.json | 15 ++++++++ .../mods/Magiclysm/itemgroups/itemgroups.json | 3 +- .../mods/Magiclysm/itemgroups/spellbooks.json | 1 + data/mods/Magiclysm/items/spell_scrolls.json | 8 +++++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/data/mods/Magiclysm/Spells/druid.json b/data/mods/Magiclysm/Spells/druid.json index 211ed3e6336d9..592f89a40c5eb 100644 --- a/data/mods/Magiclysm/Spells/druid.json +++ b/data/mods/Magiclysm/Spells/druid.json @@ -294,5 +294,41 @@ "min_range": 2, "max_range": 4, "range_increment": 0.2 + }, + { + "id": "druid_tornskin", + "type": "SPELL", + "name": "Tornskin", + "description": "This spell, which resembles Thornskin through the sap & needles covering the page, seemed to involve thorns and bleeding wounds. The marred words may have altered the function.", + "valid_targets": [ "hostile", "ground", "ally", "self" ], + "flags": [ "SOMATIC" ], + "effect": "projectile_attack", + "effect_str": "tornskin_pain", + "affected_body_parts": [ "HEAD", "TORSO", "MOUTH", "EYES", "ARM_L", "ARM_R", "HAND_R", "HAND_L", "LEG_L", "FOOT_L", "FOOT_R" ], + "min_dot": 1, + "max_dot": 4, + "dot_increment": 0.3, + "spell_class": "DRUID", + "base_casting_time": 300, + "base_energy_cost": 100, + "energy_source": "MANA", + "difficulty": 4, + "max_level": 10, + "min_damage": 1, + "max_damage": 4, + "damage_increment": 0.3, + "min_aoe": 1, + "max_aoe": 2, + "aoe_increment": 0.1, + "min_range": 1, + "max_range": 2, + "range_increment": 0.1, + "min_duration": 200, + "max_duration": 600, + "duration_increment": 40, + "min_pierce": 0, + "max_pierce": 3, + "pierce_increment": 0.3, + "damage_type": "cut" } ] diff --git a/data/mods/Magiclysm/effects/effects.json b/data/mods/Magiclysm/effects/effects.json index 6b5cee401c516..15bd1cd76a3b0 100644 --- a/data/mods/Magiclysm/effects/effects.json +++ b/data/mods/Magiclysm/effects/effects.json @@ -259,5 +259,20 @@ "int_dur_factor": "30 s", "base_mods": { "str_mod": [ -1 ], "dex_mod": [ -0.17 ], "speed_mod": [ -3 ] }, "scaling_mods": { "str_mod": [ -0.07 ], "dex_mod": [ -0.17 ], "speed_mod": [ -3 ] } + }, + { + "type": "effect_type", + "id": "tornskin_pain", + "name": [ "Sharp Thorns" ], + "desc": [ "Thorns are whirling around you, regularly causing cuts into you." ], + "apply_message": "Thorns in the wind begin slicing into you!", + "remove_message": "The thorns fall to the ground.", + "rating": "bad", + "max_duration": "12 s", + "base_mods": { + "pain_min": [ 1 ], + "pain_chance": [ 6 ], + "speed_mod": [ -1 ] + } } ] diff --git a/data/mods/Magiclysm/itemgroups/itemgroups.json b/data/mods/Magiclysm/itemgroups/itemgroups.json index c51bf4d0e0d7b..ecc231b2ef304 100644 --- a/data/mods/Magiclysm/itemgroups/itemgroups.json +++ b/data/mods/Magiclysm/itemgroups/itemgroups.json @@ -103,7 +103,7 @@ { "id": "trash", "type": "item_group", - "items": [ [ "summon_scroll_smudged", 5 ] ] + "items": [ [ "summon_scroll_smudged", 5 ], [ "spell_scroll_tornskin", 5 ] ] }, { "type": "item_group", @@ -937,6 +937,7 @@ "distribution": [ { "item": "spell_scroll_druid_woodshaft", "prob": 30 }, { "item": "summon_scroll_smudged", "prob": 2 }, + { "item": "spell_scroll_tornskin", "prob": 2 }, { "item": "spell_scroll_summon_cats", "prob": 50 } ], "prob": 45 diff --git a/data/mods/Magiclysm/itemgroups/spellbooks.json b/data/mods/Magiclysm/itemgroups/spellbooks.json index 3806b2c6bef61..8a9b27f143ee8 100644 --- a/data/mods/Magiclysm/itemgroups/spellbooks.json +++ b/data/mods/Magiclysm/itemgroups/spellbooks.json @@ -4,6 +4,7 @@ "type": "item_group", "items": [ [ "summon_scroll_smudged", 10 ], + [ "spell_scroll_tornskin", 10 ], [ "spell_scroll_smite", 40 ], [ "spell_scroll_summon_zombie", 25 ], [ "spell_scroll_light_healing", 50 ], diff --git a/data/mods/Magiclysm/items/spell_scrolls.json b/data/mods/Magiclysm/items/spell_scrolls.json index a688d765d5743..b31061bde855f 100644 --- a/data/mods/Magiclysm/items/spell_scrolls.json +++ b/data/mods/Magiclysm/items/spell_scrolls.json @@ -909,5 +909,13 @@ "name": { "str": "Scroll of Repelling Arc", "str_pl": "Scrolls of Repelling Arc" }, "description": "You manifest an aura of crackling electricity around you to strike attackers with baleful lightning.", "use_action": { "type": "learn_spell", "spells": [ "stormshaper_repelling_arc" ] } + }, + { + "type": "BOOK", + "copy-from": "spell_scroll", + "id": "spell_scroll_tornskin", + "name": { "str": "Sappy Scroll" }, + "description": "This scroll is covered in sap and rose thorns. You can still make out some of the writings, but it probably won't work the same.", + "use_action": { "type": "learn_spell", "spells": [ "druid_tornskin" ] } } ] From c77ce2e49c9bfedd527248a4b4d41da2cc6dffa2 Mon Sep 17 00:00:00 2001 From: harison86 <32041963+harison86@users.noreply.github.com> Date: Mon, 20 Jul 2020 01:35:51 -0400 Subject: [PATCH 135/151] Unobsolete the coilgun and nail magazine (#41965) * Change flechette stats * Unobsolete coilgun, nailmag, vpart_mounted_coilgun * Unobsolete coilgun, nailmag * Add nailmag back to item group * Add back coilgun Slightly adjusted stats * Add back nail.json and nailmag Slightly adjusted nailmag description * Add back nailgun recipe Significantly expanded upon * Add back nailmag recipe * Add back mounted_coilgun * Rename nailmag * Add longest side to coilgun * Add pocket data to nailmag * Increase coilgun length and UPS consumption * Change damage type * Linting * Linting * Linting * Linting * Remove the obsolete reliability * Nail and combatnail stats adjusted * Linting --- .../Weapons_Mods_Ammo/magazines.json | 2 +- data/json/items/ammo/nail.json | 12 +++- data/json/items/gun/nail.json | 42 +++++++++++++ data/json/items/magazine/nail.json | 20 +++++++ data/json/items/obsolete.json | 59 ------------------- data/json/obsolete.json | 24 -------- data/json/recipes/recipe_weapon.json | 26 ++++++++ data/json/recipes/weapon/magazines.json | 13 ++++ data/json/vehicleparts/turret.json | 14 +++++ 9 files changed, 125 insertions(+), 87 deletions(-) create mode 100644 data/json/items/magazine/nail.json diff --git a/data/json/itemgroups/Weapons_Mods_Ammo/magazines.json b/data/json/itemgroups/Weapons_Mods_Ammo/magazines.json index 5147a375f7f3f..1b71170921bb3 100644 --- a/data/json/itemgroups/Weapons_Mods_Ammo/magazines.json +++ b/data/json/itemgroups/Weapons_Mods_Ammo/magazines.json @@ -307,7 +307,7 @@ "type": "item_group", "id": "mags_other_makeshift", "//": "Makeshift or otherwise poor quality magazines that have no better category.", - "items": [ [ "pressurized_tank_chem", 5 ], [ "aux_pressurized_tank", 10 ] ] + "items": [ [ "nailmag", 20 ], [ "pressurized_tank_chem", 5 ], [ "aux_pressurized_tank", 10 ] ] }, { "type": "item_group", diff --git a/data/json/items/ammo/nail.json b/data/json/items/ammo/nail.json index 06d499b25ca4a..7cb4a0a6f068c 100644 --- a/data/json/items/ammo/nail.json +++ b/data/json/items/ammo/nail.json @@ -8,7 +8,13 @@ "material": [ "steel" ], "symbol": "=", "color": "dark_gray", - "proportional": { "price": 3, "damage": { "damage_type": "stab", "amount": 3.0, "armor_penetration": 3.0 } } + "proportional": { + "price": 3, + "range": 2.0, + "damage": { "damage_type": "bullet", "amount": 2.0 }, + "armor_penetration": 3.0, + "dispersion": 0.5 + } }, { "id": "nail", @@ -27,8 +33,8 @@ "stack_size": 100, "ammo_type": "nail", "range": 3, - "damage": { "damage_type": "stab", "amount": 4, "armor_penetration": 3 }, - "dispersion": 120, + "damage": { "damage_type": "bullet", "amount": 3, "armor_penetration": 1 }, + "dispersion": 180, "effects": [ "NON-FOULING" ] } ] diff --git a/data/json/items/gun/nail.json b/data/json/items/gun/nail.json index 6b0b9c1eaf650..fb152a76b352d 100644 --- a/data/json/items/gun/nail.json +++ b/data/json/items/gun/nail.json @@ -24,5 +24,47 @@ "reload": 50, "valid_mod_locations": [ [ "grip mount", 1 ], [ "rail mount", 1 ], [ "sights mount", 1 ], [ "stock mount", 1 ], [ "underbarrel mount", 1 ] ], "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "nail": 20 } } ] + }, + { + "id": "coilgun", + "copy-from": "gun_base", + "looks_like": "ar15", + "type": "GUN", + "name": { "str": "coilgun" }, + "//": "Hard to make, plentiful and cheap ammo, and silent - people will want this thing.", + "description": "A homemade gun, using electromagnets to accelerate a ferromagnetic projectile to high velocity. Powered by UPS.", + "weight": "2041 g", + "volume": "2750 ml", + "longest_side": "80 cm", + "price": 75000, + "price_postapoc": 5000, + "to_hit": -2, + "bashing": 10, + "material": [ "copper", "steel" ], + "ammo": [ "nail" ], + "skill": "rifle", + "range": 12, + "ranged_damage": { "damage_type": "bullet", "amount": 1 }, + "dispersion": 180, + "durability": 5, + "ups_charges": 2, + "valid_mod_locations": [ + [ "accessories", 4 ], + [ "grip", 1 ], + [ "sights", 1 ], + [ "sling", 1 ], + [ "stock", 1 ], + [ "rail mount", 1 ], + [ "underbarrel mount", 1 ] + ], + "pocket_data": [ + { + "pocket_type": "MAGAZINE_WELL", + "holster": true, + "max_contains_volume": "20 L", + "max_contains_weight": "20 kg", + "item_restriction": [ "nailmag" ] + } + ] } ] diff --git a/data/json/items/magazine/nail.json b/data/json/items/magazine/nail.json new file mode 100644 index 0000000000000..9a02aadd530dd --- /dev/null +++ b/data/json/items/magazine/nail.json @@ -0,0 +1,20 @@ +[ + { + "id": "nailmag", + "looks_like": "stanag30", + "type": "MAGAZINE", + "name": { "str": "coilgun magazine" }, + "description": "An improvised magazine for use with a coilgun. Little more than a metal box, spring and some duct tape it is awkward to reload.", + "weight": "60 g", + "volume": "250 ml", + "price": 1920, + "material": "steel", + "symbol": "#", + "color": "light_gray", + "ammo_type": "nail", + "capacity": 50, + "reload_time": 300, + "flags": [ "MAG_COMPACT" ], + "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "nail": 50 } } ] + } +] diff --git a/data/json/items/obsolete.json b/data/json/items/obsolete.json index 51786c71aace5..1b0da29acfb48 100644 --- a/data/json/items/obsolete.json +++ b/data/json/items/obsolete.json @@ -2219,47 +2219,6 @@ "ammo_effects": [ "INCENDIARY", "TRAIL" ], "pocket_data": [ { "pocket_type": "MAGAZINE", "ammo_restriction": { "metal_rail": 1 } } ] }, - { - "id": "coilgun", - "copy-from": "gun_base", - "looks_like": "ar15", - "type": "GUN", - "name": { "str": "coilgun" }, - "//": "Hard to make, plentiful and cheap ammo, and silent - people will want this thing.", - "description": "A homemade gun, using electromagnets to accelerate a ferromagnetic projectile to high velocity. Powered by UPS.", - "weight": "3341 g", - "volume": "2750 ml", - "price": 75000, - "price_postapoc": 5000, - "to_hit": -2, - "bashing": 10, - "material": [ "copper", "steel" ], - "ammo": [ "nail" ], - "skill": "rifle", - "range": 12, - "ranged_damage": { "damage_type": "stab", "amount": 4, "armor_penetration": 20 }, - "dispersion": 180, - "durability": 5, - "ups_charges": 5, - "valid_mod_locations": [ - [ "accessories", 4 ], - [ "grip", 1 ], - [ "sights", 1 ], - [ "sling", 1 ], - [ "stock", 1 ], - [ "rail mount", 1 ], - [ "underbarrel mount", 1 ] - ], - "pocket_data": [ - { - "pocket_type": "MAGAZINE_WELL", - "holster": true, - "max_contains_volume": "20 L", - "max_contains_weight": "20 kg", - "item_restriction": [ "nailmag" ] - } - ] - }, { "id": "nailrifle", "copy-from": "nailgun", @@ -2294,24 +2253,6 @@ } ] }, - { - "id": "nailmag", - "looks_like": "stanag30", - "type": "MAGAZINE", - "name": { "str": "nail rifle magazine" }, - "description": "An improvised magazine for use with a nail rifle. Little more than a tin can, spring and some duct tape it is awkward to reload and not especially reliable.", - "weight": "60 g", - "volume": "250 ml", - "price": 1920, - "material": [ "steel" ], - "symbol": "#", - "color": "light_gray", - "ammo_type": [ "nail" ], - "capacity": 50, - "reload_time": 300, - "flags": [ "MAG_COMPACT" ], - "pocket_data": [ { "pocket_type": "MAGAZINE", "ammo_restriction": { "nail": 50 } } ] - }, { "id": "recipe_mininuke_launch", "type": "BOOK", diff --git a/data/json/obsolete.json b/data/json/obsolete.json index 411006155d94f..2cc5fe5a56cd0 100644 --- a/data/json/obsolete.json +++ b/data/json/obsolete.json @@ -1159,21 +1159,11 @@ "result": "heavy_rail_rifle", "obsolete": true }, - { - "type": "recipe", - "result": "coilgun", - "obsolete": true - }, { "result": "nailrifle", "type": "recipe", "obsolete": true }, - { - "result": "nailmag", - "type": "recipe", - "obsolete": true - }, { "type": "recipe", "result": "mininuke_mod", @@ -1218,20 +1208,6 @@ "removal": { "skills": [ [ "mechanics", 3 ] ] } } }, - { - "id": "mounted_coilgun", - "copy-from": "turret", - "type": "vehicle_part", - "name": { "str": "mounted coilgun" }, - "item": "coilgun", - "color": "magenta", - "broken_color": "magenta", - "breaks_into": [ { "item": "scrap", "count": 13 }, { "item": "steel_chunk", "count": 4 }, { "item": "steel_lump", "count": 1 } ], - "requirements": { - "install": { "skills": [ [ "mechanics", 5 ], [ "electronics", 5 ] ] }, - "removal": { "skills": [ [ "mechanics", 3 ] ] } - } - }, { "type": "terrain", "id": "t_gas_tank", diff --git a/data/json/recipes/recipe_weapon.json b/data/json/recipes/recipe_weapon.json index 172aec4516695..f28e8aedff28f 100644 --- a/data/json/recipes/recipe_weapon.json +++ b/data/json/recipes/recipe_weapon.json @@ -2568,5 +2568,31 @@ "autolearn": true, "qualities": [ { "id": "CUT", "level": 1 }, { "id": "HAMMER", "level": 1 } ], "components": [ [ [ "leather", 30 ], [ "rope_superior_short", 2, "LIST" ] ], [ [ "scrap", 9 ], [ "razor_blade", 9 ] ] ] + }, + { + "type": "recipe", + "result": "coilgun", + "category": "CC_WEAPON", + "subcategory": "CSC_WEAPON_RANGED", + "skill_used": "electronics", + "skills_required": [ [ "computer", 3 ], [ "fabrication", 3 ] ], + "difficulty": 5, + "time": "4 h", + "reversible": true, + "book_learn": [ [ "advanced_electronics", 5 ], [ "textbook_electronics", 5 ], [ "textbook_anarch", 6 ] ], + "using": [ [ "soldering_standard", 20 ], [ "surface_heat", 10 ] ], + "qualities": [ { "id": "SAW_M_FINE", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "SCREW_FINE", "level": 1 } ], + "tools": [ [ [ "mold_plastic", -1 ] ], [ [ "laptop", -1 ] ] ], + "components": [ + [ [ "plastic_chunk", 10 ] ], + [ [ "superglue", 1 ] ], + [ [ "processor", 1 ] ], + [ [ "circuit", 2 ] ], + [ [ "power_supply", 2 ] ], + [ [ "amplifier", 1 ] ], + [ [ "e_scrap", 30 ] ], + [ [ "scrap", 10 ] ], + [ [ "cable", 100 ] ] + ] } ] diff --git a/data/json/recipes/weapon/magazines.json b/data/json/recipes/weapon/magazines.json index d3e28282f013f..f3e478ecbfee6 100644 --- a/data/json/recipes/weapon/magazines.json +++ b/data/json/recipes/weapon/magazines.json @@ -362,5 +362,18 @@ "using": [ [ "welding_standard", 2 ] ], "qualities": [ { "id": "HAMMER", "level": 2 } ], "components": [ [ [ "metal_tank_little", 1 ] ] ] + }, + { + "result": "nailmag", + "type": "recipe", + "category": "CC_WEAPON", + "subcategory": "CSC_WEAPON_MAGAZINES", + "skill_used": "fabrication", + "difficulty": 1, + "time": "8 m", + "autolearn": true, + "tools": [ [ [ "coilgun", -1 ] ], [ [ "nail", -1 ], [ "combatnail", -1 ] ] ], + "qualities": [ { "id": "HAMMER", "level": 2 }, { "id": "SAW_M", "level": 1 } ], + "components": [ [ [ "sheet_metal_small", 1 ] ], [ [ "spring", 1 ] ], [ [ "scrap", 1 ] ], [ [ "duct_tape", 20 ] ] ] } ] diff --git a/data/json/vehicleparts/turret.json b/data/json/vehicleparts/turret.json index 6dea634dfc789..c663a179644ef 100644 --- a/data/json/vehicleparts/turret.json +++ b/data/json/vehicleparts/turret.json @@ -260,5 +260,19 @@ "breaks_into": [ { "item": "scrap", "count": 40 }, { "item": "steel_chunk", "count": 30 }, { "item": "steel_lump", "count": 13 } ], "requirements": { "install": { "skills": [ [ "mechanics", 4 ] ] }, "removal": { "skills": [ [ "mechanics", 2 ] ] } }, "extend": { "flags": [ "USE_TANKS" ] } + }, + { + "id": "mounted_coilgun", + "copy-from": "turret", + "type": "vehicle_part", + "name": { "str": "mounted coilgun" }, + "item": "coilgun", + "color": "magenta", + "broken_color": "magenta", + "breaks_into": [ { "item": "scrap", "count": 13 }, { "item": "steel_chunk", "count": 4 }, { "item": "steel_lump", "count": 1 } ], + "requirements": { + "install": { "skills": [ [ "mechanics", 5 ], [ "electronics", 5 ] ] }, + "removal": { "skills": [ [ "mechanics", 3 ] ] } + } } ] From 74119ab14006744157b3a522e9bde3437448b9c7 Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Thu, 16 Jul 2020 01:08:12 -0400 Subject: [PATCH 136/151] container item itemgroup --- .../agriculture.json | 2 +- .../itemgroups/Clothing_Gear/clothing.json | 4 +-- data/json/itemgroups/Clothing_Gear/gear.json | 2 +- .../Locations_MapExtras/locations.json | 14 ++++----- .../locations_commercial.json | 4 +-- .../monster_drops_lairs.json | 4 +-- data/json/itemgroups/military.json | 2 +- data/json/itemgroups/science_and_tech.json | 2 +- data/json/itemgroups/tools.json | 23 +++++++++++--- .../itemgroups/vehicles_fuel_related.json | 2 +- data/json/items/tool/workshop.json | 21 ++----------- data/json/mapgen/cs_open_sewer_small.json | 2 +- data/json/mapgen/farm_dairy.json | 2 +- data/json/npcs/items_generic.json | 2 +- .../NPC_free_merchant_shopkeep.json | 2 +- data/json/obsolete.json | 31 +++++++++++++++++++ data/json/recipes/recipe_others.json | 14 ++------- .../mods/Magiclysm/itemgroups/itemgroups.json | 4 +-- .../mods/National_Guard_Camp/item_groups.json | 6 ++-- src/item_factory.cpp | 3 ++ src/item_group.cpp | 25 ++++++++++++++- src/item_group.h | 5 +++ 22 files changed, 114 insertions(+), 62 deletions(-) diff --git a/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json b/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json index 849a27f150137..2aa922cdb00f3 100644 --- a/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json +++ b/data/json/itemgroups/Agriculture_Forage_Excavation/agriculture.json @@ -55,7 +55,7 @@ [ "insecticide", 30 ], { "item": "chem_saltpetre", "prob": 15, "charges-min": 10, "charges-max": 50 }, [ "sickle", 40 ], - [ "toolbox", 10 ], + { "group": "tools_toolbox", "prob": 10 }, [ "bullwhip", 30 ], [ "distaff_spindle", 2 ], [ "carding_paddles", 2 ], diff --git a/data/json/itemgroups/Clothing_Gear/clothing.json b/data/json/itemgroups/Clothing_Gear/clothing.json index 2fbd985965b90..38632d30a80de 100644 --- a/data/json/itemgroups/Clothing_Gear/clothing.json +++ b/data/json/itemgroups/Clothing_Gear/clothing.json @@ -2074,7 +2074,7 @@ { "group": "ammo_any_batteries_full", "prob": 50 }, { "item": "flashlight", "prob": 40 }, { "item": "boots_rubber", "prob": 20 }, - { "item": "toolbox", "prob": 1 }, + { "group": "tools_toolbox", "prob": 1 }, { "item": "apron_leather", "prob": 10 } ] }, @@ -2400,7 +2400,7 @@ [ "grapnel", 6 ], [ "misc_repairkit", 8 ], [ "survival_kit", 3 ], - [ "toolbox", 1 ], + { "group": "tools_toolbox", "prob": 1 }, [ "survivor_belt", 2 ], [ "survivor_machete", 2 ], [ "spear_survivor", 2 ], diff --git a/data/json/itemgroups/Clothing_Gear/gear.json b/data/json/itemgroups/Clothing_Gear/gear.json index 5ee14c38c1ce9..bcd3a2efdcc3a 100644 --- a/data/json/itemgroups/Clothing_Gear/gear.json +++ b/data/json/itemgroups/Clothing_Gear/gear.json @@ -138,7 +138,7 @@ [ "throw_extinguisher", 10 ], [ "grapnel", 5 ], [ "wearable_light", 5 ], - [ "toolbox", 1 ], + { "group": "tools_toolbox", "prob": 1 }, [ "smoxygen_tank", 35 ], [ "watercannon", 10 ], [ "l-stick", 1 ], diff --git a/data/json/itemgroups/Locations_MapExtras/locations.json b/data/json/itemgroups/Locations_MapExtras/locations.json index 2b9d4821172fe..3888b1f69ced8 100644 --- a/data/json/itemgroups/Locations_MapExtras/locations.json +++ b/data/json/itemgroups/Locations_MapExtras/locations.json @@ -394,7 +394,7 @@ { "group": "ammo_pocket_batteries", "prob": 50 }, [ "flashlight", 40 ], [ "boots_rubber", 20 ], - [ "toolbox", 5 ], + { "group": "tools_toolbox", "prob": 5 }, [ "apron_leather", 10 ] ] }, @@ -904,7 +904,7 @@ [ "foodperson_mask", 1 ], [ "55gal_drum", 10 ], [ "30gal_drum", 15 ], - [ "toolbox", 1 ], + { "group": "tools_toolbox", "prob": 1 }, [ "recipe_elfa", 2 ] ] }, @@ -922,7 +922,7 @@ { "item": "55gal_drum", "prob": 10 }, { "item": "30gal_drum", "prob": 15 }, { "item": "grapnel", "prob": 1 }, - { "item": "toolbox", "prob": 1 }, + { "group": "tools_toolbox", "prob": 1 }, { "item": "apron_leather", "prob": 5 } ] }, @@ -1183,7 +1183,7 @@ [ "boots_rubber", 20 ], [ "sm_extinguisher", 10 ], [ "grapnel", 1 ], - [ "toolbox", 5 ], + { "group": "tools_toolbox", "prob": 5 }, [ "apron_leather", 10 ], [ "bio_meteorologist", 10 ], [ "chem_aluminium_sulphate", 20 ], @@ -1199,7 +1199,7 @@ [ "pickaxe", 2 ], [ "bucket", 20 ], [ "rock", 40 ], - [ "toolbox", 5 ], + { "group": "tools_toolbox", "prob": 5 }, [ "coal_lump", 20 ], [ "material_shrd_limestone", 40 ], [ "material_niter", 5 ], @@ -1261,7 +1261,7 @@ [ "miner_hat", 40 ], [ "bucket", 10 ], [ "grapnel", 1 ], - [ "toolbox", 1 ], + { "group": "tools_toolbox", "prob": 1 }, [ "apron_leather", 10 ], [ "tool_anfo_charge", 1 ], [ "remotevehcontrol", 10 ] @@ -1612,7 +1612,7 @@ [ "antiparasitic", 5 ], [ "diazepam", 5 ], [ "misc_repairkit", 5 ], - [ "toolbox", 2 ], + { "group": "tools_toolbox", "prob": 2 }, [ "apron_leather", 10 ], [ "bio_meteorologist", 3 ], [ "thermometer", 3 ], diff --git a/data/json/itemgroups/Locations_MapExtras/locations_commercial.json b/data/json/itemgroups/Locations_MapExtras/locations_commercial.json index 978634fba5b7b..e82d12c017b7c 100644 --- a/data/json/itemgroups/Locations_MapExtras/locations_commercial.json +++ b/data/json/itemgroups/Locations_MapExtras/locations_commercial.json @@ -1053,7 +1053,7 @@ { "item": "manual_fabrication", "prob": 20 }, { "item": "duct_tape", "prob": 70 }, { "item": "misc_repairkit", "prob": 15 }, - { "item": "toolbox", "prob": 2 } + { "group": "tools_toolbox", "prob": 2 } ] }, { @@ -1109,7 +1109,7 @@ { "item": "screwdriver_set", "prob": 20 }, { "item": "duct_tape", "prob": 50 }, { "item": "misc_repairkit", "prob": 25 }, - { "item": "toolbox", "prob": 2 } + { "group": "tools_toolbox", "prob": 2 } ] } ] diff --git a/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json b/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json index 2ff16832415d1..e20b4ca70a724 100644 --- a/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json +++ b/data/json/itemgroups/Monsters_Animals_Lairs/monster_drops_lairs.json @@ -258,7 +258,7 @@ { "item": "fire_ax", "prob": 5 }, { "item": "miner_hat", "prob": 10 }, { "item": "grapnel", "prob": 2 }, - { "item": "toolbox", "prob": 1 }, + { "group": "tools_toolbox", "prob": 1 }, { "item": "pur_tablets", "prob": 10 }, { "item": "pastaextruder", "prob": 10 }, { "item": "can_sealer", "prob": 10 }, @@ -333,7 +333,7 @@ { "item": "lsd", "prob": 1 }, { "item": "gum", "prob": 20 }, { "item": "caff_gum", "prob": 8 }, - { "item": "toolbox", "prob": 1 }, + { "group": "tools_toolbox", "prob": 1 }, { "item": "nic_gum", "prob": 5 }, { "item": "radio_car_box", "prob": 2 }, { "item": "radiocontrol", "prob": 15 }, diff --git a/data/json/itemgroups/military.json b/data/json/itemgroups/military.json index 2569db5a1b919..0443804e759fc 100644 --- a/data/json/itemgroups/military.json +++ b/data/json/itemgroups/military.json @@ -261,7 +261,7 @@ { "item": "bucket", "prob": 4 }, { "item": "sheath", "prob": 13 }, { "item": "bootsheath", "prob": 8 }, - { "item": "toolbox", "prob": 1 }, + { "group": "tools_toolbox", "prob": 1 }, { "item": "knife_rm42", "prob": 4 }, { "item": "survnote", "prob": 1 }, { "item": "rm11b_sniper_rifle", "prob": 1 }, diff --git a/data/json/itemgroups/science_and_tech.json b/data/json/itemgroups/science_and_tech.json index 3b7b925a68b33..1ae2b6b3a21d0 100644 --- a/data/json/itemgroups/science_and_tech.json +++ b/data/json/itemgroups/science_and_tech.json @@ -114,7 +114,7 @@ [ "holo_cloak", 1 ], [ "antiparasitic", 2 ], [ "survnote", 1 ], - [ "toolbox", 1 ], + { "group": "tools_toolbox", "prob": 1 }, [ "diazepam", 1 ], [ "magnifying_glass", 1 ], [ "material_quicklime", 10 ], diff --git a/data/json/itemgroups/tools.json b/data/json/itemgroups/tools.json index dfc33889d2b0c..d82081a5b38c2 100644 --- a/data/json/itemgroups/tools.json +++ b/data/json/itemgroups/tools.json @@ -24,7 +24,7 @@ [ "hand_drill", 20 ], [ "nailgun", 100 ], [ "chisel", 10 ], - [ "toolbox", 12 ], + { "group": "tools_toolbox", "prob": 12 }, [ "toolbox_workshop", 3 ], [ "sandpaper", 100 ] ] @@ -40,7 +40,7 @@ [ "elec_jackhammer", 40 ], [ "metal_smoother", 90 ], [ "jackhammer", 40 ], - [ "toolbox", 20 ], + { "group": "tools_toolbox", "prob": 20 }, [ "toolbox_workshop", 5 ], [ "recharge_station", 10 ], [ "angle_grinder", 30 ] @@ -77,6 +77,21 @@ [ "rake_plastic", 25 ] ] }, + { + "id": "tools_toolbox", + "type": "item_group", + "//": "A typical toolbox filled with tools.", + "subtype": "collection", + "container-item": "toolbox_empty", + "items": [ + [ "hammer", 80 ], + [ "screwdriver_set", 65 ], + [ "wrench", 75 ], + [ "funnel", 50 ], + [ "metal_file", 40 ], + [ "sandpaper", 65 ] + ] + }, { "id": "tools_general", "type": "item_group", @@ -229,7 +244,7 @@ { "group": "tools_common", "prob": 100 }, { "group": "tools_lighting", "prob": 50 }, { "group": "tools_tailor", "prob": 50 }, - [ "toolbox", 4 ], + { "group": "tools_toolbox", "prob": 4 }, [ "toolbox_workshop", 1 ] ] }, @@ -459,7 +474,7 @@ [ "light_battery_cell", 10 ], [ "goggles_welding", 20 ], [ "sm_extinguisher", 10 ], - [ "toolbox", 5 ], + { "group": "tools_toolbox", "prob": 5 }, [ "tool_belt", 10 ], [ "clamp", 10 ], [ "wrench", 10 ] diff --git a/data/json/itemgroups/vehicles_fuel_related.json b/data/json/itemgroups/vehicles_fuel_related.json index e6c573fdddfb9..e57b3074b6ac3 100644 --- a/data/json/itemgroups/vehicles_fuel_related.json +++ b/data/json/itemgroups/vehicles_fuel_related.json @@ -33,7 +33,7 @@ [ "screwdriver", 8 ], [ "screwdriver_set", 2 ], [ "hd_tow_cable", 5 ], - [ "toolbox", 1 ] + { "group": "tools_toolbox", "prob": 1 } ] }, { diff --git a/data/json/items/tool/workshop.json b/data/json/items/tool/workshop.json index 28322a5f4e7b1..425740aa33ef9 100644 --- a/data/json/items/tool/workshop.json +++ b/data/json/items/tool/workshop.json @@ -876,10 +876,10 @@ ] }, { - "id": "toolbox", + "id": "toolbox_empty", "type": "TOOL", "name": { "str": "toolbox", "str_pl": "toolboxes" }, - "description": "This is a stout metal box containing a complete tool kit suitable for most household maintenance and construction activities.", + "description": "This is a stout metal box for containing tools. It has a handle on the top and a latch on the front.", "weight": "3522 g", "volume": "2500 ml", "price": 12999, @@ -889,22 +889,7 @@ "material": [ "steel" ], "symbol": ";", "color": "red", - "qualities": [ - [ "CUT", 1 ], - [ "HAMMER", 3 ], - [ "SAW_M", 2 ], - [ "SAW_W", 2 ], - [ "AXE", 1 ], - [ "WRENCH", 2 ], - [ "SCREW", 1 ], - [ "PRY", 1 ], - [ "HAMMER_FINE", 1 ], - [ "SAW_M_FINE", 1 ], - [ "WRENCH_FINE", 1 ], - [ "SCREW_FINE", 1 ], - [ "BUTCHER", 11 ] - ], - "use_action": [ "HAMMER", "CROWBAR" ] + "pocket_data": [ { "max_contains_volume": "2400 ml", "max_contains_weight": "10 kg" } ] }, { "id": "toolbox_workshop", diff --git a/data/json/mapgen/cs_open_sewer_small.json b/data/json/mapgen/cs_open_sewer_small.json index 0f43a09004a27..d750ef96bbd8a 100644 --- a/data/json/mapgen/cs_open_sewer_small.json +++ b/data/json/mapgen/cs_open_sewer_small.json @@ -42,7 +42,7 @@ [ "folding_poncho", 40 ], [ "radio", 40 ], [ "well_pump", 10 ], - [ "toolbox", 5 ], + { "group": "tools_toolbox", "prob": 5 }, [ "wrench", 15 ], [ "bag_canvas", 40 ], [ "jumper_cable", 40 ], diff --git a/data/json/mapgen/farm_dairy.json b/data/json/mapgen/farm_dairy.json index 2b502ae9a4f5d..7f3f86a875fde 100644 --- a/data/json/mapgen/farm_dairy.json +++ b/data/json/mapgen/farm_dairy.json @@ -462,7 +462,6 @@ "A": { "item": "wheel_wood", "chance": 100 }, "C": { "item": "bucket", "chance": 100 }, "j": { "item": "jerrycan", "chance": 100 }, - "e": { "item": "toolbox", "chance": 100 }, "h": { "item": "2x4", "chance": 100, "repeat": 2 }, "o": { "item": "straw_pile", "chance": 100, "repeat": [ 5, 10 ] }, "q": { "item": "pitchfork", "chance": 100 }, @@ -470,6 +469,7 @@ "W": { "item": "box_medium", "chance": 100 } }, "items": { + "e": { "item": "tools_toolbox", "chance": 100 }, "m": { "item": "SUS_junk_drawer", "chance": 100 }, ")": { "item": "SUS_bathroom_sink", "chance": 70, "repeat": 2 }, "_": [ { "item": "SUS_toilet", "chance": 90 }, { "item": "SUS_bathroom_cabinet", "chance": 90 } ], diff --git a/data/json/npcs/items_generic.json b/data/json/npcs/items_generic.json index 674dfc10f1654..183f6127c3f91 100644 --- a/data/json/npcs/items_generic.json +++ b/data/json/npcs/items_generic.json @@ -1096,7 +1096,7 @@ [ "tomato", 3 ], [ "tongs", 2 ], [ "tool_belt", 8 ], - [ "toolbox", 4 ], + { "group": "tools_toolbox", "prob": 4 }, [ "touristmap", 6 ], [ "towel", 4 ], [ "tramadol", 4 ], diff --git a/data/json/npcs/refugee_center/surface_staff/NPC_free_merchant_shopkeep.json b/data/json/npcs/refugee_center/surface_staff/NPC_free_merchant_shopkeep.json index c549babbe622e..785d954298f55 100644 --- a/data/json/npcs/refugee_center/surface_staff/NPC_free_merchant_shopkeep.json +++ b/data/json/npcs/refugee_center/surface_staff/NPC_free_merchant_shopkeep.json @@ -155,7 +155,7 @@ [ "small_repairkit", 20 ], [ "grapnel", 5 ], [ "misc_repairkit", 15 ], - [ "toolbox", 20 ], + { "group": "tools_toolbox", "prob": 20 }, [ "crowbar", 25 ], [ "machete", 25 ], [ "ax", 25 ], diff --git a/data/json/obsolete.json b/data/json/obsolete.json index 2cc5fe5a56cd0..c34a3cef45bb4 100644 --- a/data/json/obsolete.json +++ b/data/json/obsolete.json @@ -38,6 +38,37 @@ ], "pocket_data": [ { "pocket_type": "MAGAZINE", "ammo_restriction": { "3006": 1 } } ] }, + { + "id": "toolbox", + "type": "TOOL", + "name": { "str": "toolbox", "str_pl": "toolboxes" }, + "description": "This is a stout metal box containing a complete tool kit suitable for most household maintenance and construction activities.", + "weight": "3522 g", + "volume": "2500 ml", + "price": 12999, + "price_postapoc": 3000, + "to_hit": -2, + "bashing": 8, + "material": [ "steel" ], + "symbol": ";", + "color": "red", + "qualities": [ + [ "CUT", 1 ], + [ "HAMMER", 3 ], + [ "SAW_M", 2 ], + [ "SAW_W", 2 ], + [ "AXE", 1 ], + [ "WRENCH", 2 ], + [ "SCREW", 1 ], + [ "PRY", 1 ], + [ "HAMMER_FINE", 1 ], + [ "SAW_M_FINE", 1 ], + [ "WRENCH_FINE", 1 ], + [ "SCREW_FINE", 1 ], + [ "BUTCHER", 11 ] + ], + "use_action": [ "HAMMER", "CROWBAR" ] + }, { "id": "combination_gun_shotgun_pipe", "type": "GUNMOD", diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index 66fe43d4018d8..40584ac057983 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -3320,7 +3320,7 @@ }, { "type": "recipe", - "result": "toolbox", + "result": "toolbox_empty", "category": "CC_OTHER", "subcategory": "CSC_OTHER_TOOLS", "skill_used": "fabrication", @@ -3329,17 +3329,7 @@ "time": "4 m", "reversible": true, "autolearn": true, - "components": [ - [ [ "sheet_metal_small", 5 ] ], - [ [ "nail", 11 ] ], - [ [ "wire", 1 ] ], - [ [ "pockknife", 1 ], [ "primitive_knife", 1 ], [ "copper_knife", 1 ] ], - [ [ "screwdriver_set", 1 ] ], - [ [ "hacksaw", 1 ] ], - [ [ "wrench", 1 ] ], - [ [ "saw", 1 ] ], - [ [ "hammer", 1 ] ] - ] + "components": [ [ [ "sheet_metal_small", 5 ] ], [ [ "nail", 11 ] ], [ [ "wire", 1 ] ] ] }, { "type": "recipe", diff --git a/data/mods/Magiclysm/itemgroups/itemgroups.json b/data/mods/Magiclysm/itemgroups/itemgroups.json index c51bf4d0e0d7b..cb12872800fd7 100644 --- a/data/mods/Magiclysm/itemgroups/itemgroups.json +++ b/data/mods/Magiclysm/itemgroups/itemgroups.json @@ -188,7 +188,7 @@ }, { "item": "bone_human", "prob": 60, "count-min": 1, "count-max": 5 }, [ "cauldron_orichalcum", 10 ], - [ "toolbox", 10 ] + { "group": "tools_toolbox", "prob": 10 } ] }, { @@ -223,7 +223,7 @@ { "group": "tools_common", "prob": 60 }, { "group": "paint", "prob": 20 }, { "group": "supplies_fuel", "prob": 35 }, - [ "toolbox", 10 ], + { "group": "tools_toolbox", "prob": 10 }, [ "mop", 100 ], [ "broom", 100 ], [ "battery_car", 35 ] diff --git a/data/mods/National_Guard_Camp/item_groups.json b/data/mods/National_Guard_Camp/item_groups.json index 61585910d9082..1e43fe79c5244 100644 --- a/data/mods/National_Guard_Camp/item_groups.json +++ b/data/mods/National_Guard_Camp/item_groups.json @@ -27,7 +27,7 @@ [ "sm_extinguisher", 10 ], [ "flashlight", 20 ], [ "hat_hard", 50 ], - [ "toolbox", 5 ], + { "group": "tools_toolbox", "prob": 5 }, [ "textbook_chemistry", 20 ], [ "iodine", 20 ], [ "prussian_blue", 20 ], @@ -49,7 +49,7 @@ { "item": "water", "prob": 20, "container-item": "55gal_drum", "charges-min": 350, "charges-max": 800 }, { "item": "plut_cell", "prob": 30, "container-item": "30gal_drum", "charges-min": 5, "charges-max": 25 }, { "item": "plut_cell", "prob": 10, "charges-min": 1, "charges-max": 5 }, - [ "toolbox", 5 ] + { "group": "tools_toolbox", "prob": 5 } ] }, { @@ -143,7 +143,7 @@ [ "jar_glass", 30 ], [ "adv_chemistry", 25 ], [ "radio", 10 ], - [ "toolbox", 10 ], + { "group": "tools_toolbox", "prob": 10 }, [ "textbook_chemistry", 20 ], [ "gunpowder", 40 ], [ "incendiary", 10 ], diff --git a/src/item_factory.cpp b/src/item_factory.cpp index efd7653583191..98b8d19d970b3 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -3229,6 +3229,9 @@ void Item_factory::load_item_group( const JsonObject &jsobj, const Group_tag &gr } } } + if( jsobj.has_string( "container-item" ) ) { + ig->set_container_item( itype_id( jsobj.get_string( "container-item" ) ) ); + } } void Item_factory::set_use_methods_from_json( const JsonObject &jo, const std::string &member, diff --git a/src/item_group.cpp b/src/item_group.cpp index 10bb167b12919..6c7a89535e857 100644 --- a/src/item_group.cpp +++ b/src/item_group.cpp @@ -81,6 +81,9 @@ item Single_item_creator::create_single( const time_point &birthday, RecursionLi // TODO: change the spawn lists to contain proper references to containers tmp = tmp.in_its_container( qty ); } + if( container_item ) { + tmp = tmp.in_container( *container_item, tmp.charges ); + } return tmp; } @@ -121,6 +124,13 @@ Item_spawn_data::ItemList Single_item_creator::create( const time_point &birthda result.insert( result.end(), tmplist.begin(), tmplist.end() ); } } + if( container_item ) { + item ctr( *container_item, birthday ); + for( const item &it : result ) { + ctr.put_in( it, item_pocket::pocket_type::CONTAINER ); + } + result = ItemList{ ctr }; + } return result; } @@ -546,6 +556,11 @@ void Item_group::check_consistency( const std::string &context ) const } } +void Item_spawn_data::set_container_item( const itype_id &container ) +{ + container_item = container; +} + bool Item_group::remove_item( const itype_id &itemid ) { for( prop_list::iterator a = items.begin(); a != items.end(); ) { @@ -593,7 +608,15 @@ item_group::ItemList item_group::items_from( const Group_tag &group_id, const ti if( group == nullptr ) { return ItemList(); } - return group->create( birthday ); + ItemList created = group->create( birthday ); + if( group->container_item ) { + item ctr( *group->container_item, birthday ); + for( const item &it : created ) { + ctr.put_in( it, item_pocket::pocket_type::CONTAINER ); + } + created = ItemList{ ctr }; + } + return created; } item_group::ItemList item_group::items_from( const Group_tag &group_id ) diff --git a/src/item_group.h b/src/item_group.h index 1288a4c186421..3387fc215aac6 100644 --- a/src/item_group.h +++ b/src/item_group.h @@ -135,11 +135,16 @@ class Item_spawn_data virtual bool remove_item( const itype_id &itemid ) = 0; virtual bool replace_item( const itype_id &itemid, const itype_id &replacementid ) = 0; virtual bool has_item( const itype_id &itemid ) const = 0; + void set_container_item( const itype_id &container ); virtual std::set every_item() const = 0; /** probability, used by the parent object. */ int probability; + /** + * The group spawns contained in this item + */ + cata::optional container_item; }; /** * Creates a single item, but can change various aspects From 08113fe67e8d876cbfd71fe5910dda902acc40cf Mon Sep 17 00:00:00 2001 From: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> Date: Mon, 20 Jul 2020 03:15:45 -0400 Subject: [PATCH 137/151] Fix 40x53mm copy-from issues (#42292) * Fix 40x53mm grenade volumes * Trim casing from file --- data/json/items/ammo/40x53mm.json | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/data/json/items/ammo/40x53mm.json b/data/json/items/ammo/40x53mm.json index 3bdc78b2740d2..9a3170ca6088b 100644 --- a/data/json/items/ammo/40x53mm.json +++ b/data/json/items/ammo/40x53mm.json @@ -3,6 +3,8 @@ "abstract": "40x53mm_grenade", "type": "AMMO", "name": { "str": "40x53mm grenade" }, + "weight": "340 g", + "volume": "137 ml", "longest_side": "112 mm", "price": 10000, "price_postapoc": 6000, @@ -17,6 +19,7 @@ "damage": { "damage_type": "bullet", "amount": 80 }, "dispersion": 30, "recoil": 225, + "casing": "40x53mm_m169_casing", "effects": [ "COOKOFF", "NEVER_MISFIRES" ] }, { @@ -25,11 +28,8 @@ "type": "AMMO", "name": { "str": "40x53mm M1001" }, "description": "40x53mm canister shot loaded with 17 grain flechettes.", - "weight": "340 g", - "volume": "137 ml", "damage": { "damage_type": "bullet", "amount": 150, "armor_penetration": 10 }, "recoil": 1000, - "casing": "40x53mm_m169_casing", "extend": { "effects": [ "SHOT" ] } }, { @@ -38,10 +38,8 @@ "type": "AMMO", "name": { "str": "40x53mm M430A1" }, "description": "A high velocity 40x53mm HEDP grenade. It can penetrate 3 inches of steel armor and fragmentation of the projectile body also makes it suitable for use against infantry.", - "weight": "340 g", "volume": "132 ml", "damage": { "damage_type": "bullet", "amount": 250, "armor_penetration": 45 }, - "casing": "40x53mm_m169_casing", "extend": { "effects": [ "EXPLOSIVE_m430a1" ] } }, { @@ -50,11 +48,9 @@ "type": "AMMO", "name": { "str": "40x53mm buckshot" }, "description": "An improvised 40x53mm buckshot load somewhat resembling M576.", - "weight": "340 g", "range": 10, "damage": { "damage_type": "bullet", "amount": 100, "armor_penetration": 4 }, "recoil": 1200, - "casing": "40x53mm_m169_casing", "extend": { "effects": [ "SHOT" ] } }, { @@ -63,11 +59,9 @@ "type": "AMMO", "name": { "str": "40x53mm slug" }, "description": "An improvised 40x53mm load resembling an oversized shotgun slug.", - "weight": "340 g", "range": 10, "damage": { "damage_type": "bullet", "amount": 130, "armor_penetration": 6 }, - "recoil": 1200, - "casing": "40x53mm_m169_casing" + "recoil": 1200 }, { "id": "40x53mm_flechette_m169", @@ -75,11 +69,9 @@ "type": "AMMO", "name": { "str": "40x53mm flechette" }, "description": "An improvised 40x53mm flechette load containing 100 steel darts.", - "weight": "340 g", "range": 10, "damage": { "damage_type": "bullet", "amount": 85, "armor_penetration": 6 }, "recoil": 1200, - "casing": "40x53mm_m169_casing", "extend": { "effects": [ "SHOT" ] } } ] From dd7305fb0ab39d9833ec0979a2721798adcf35f7 Mon Sep 17 00:00:00 2001 From: Fris0uman <41293484+Fris0uman@users.noreply.github.com> Date: Mon, 20 Jul 2020 09:18:37 +0200 Subject: [PATCH 138/151] Don't wake up characters under anesthesia (#42270) --- src/activity_handlers.cpp | 2 +- src/bionics.cpp | 2 +- src/character.cpp | 9 +++++++-- src/suffer.cpp | 4 ++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 20795b47e6e35..da00ab1768d9c 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -3436,7 +3436,7 @@ void activity_handlers::operation_do_turn( player_activity *act, player *p ) // Makes sure NPC is still under anesthesia if( p->has_effect( effect_narcosis ) ) { const time_duration remaining_time = p->get_effect_dur( effect_narcosis ); - if( remaining_time <= time_left ) { + if( remaining_time < time_left ) { const time_duration top_off_time = time_left - remaining_time; p->add_effect( effect_narcosis, top_off_time ); p->add_effect( effect_sleep, top_off_time ); diff --git a/src/bionics.cpp b/src/bionics.cpp index 133318552e76d..c2ed5f9e8b29e 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -3103,7 +3103,7 @@ void Character::introduce_into_anesthesia( const time_duration &duration, player if( has_effect( effect_narcosis ) ) { const time_duration remaining_time = get_effect_dur( effect_narcosis ); - if( remaining_time <= duration ) { + if( remaining_time < duration ) { const time_duration top_off_time = duration - remaining_time; add_effect( effect_narcosis, top_off_time ); fall_asleep( top_off_time ); diff --git a/src/character.cpp b/src/character.cpp index 8aec01012455c..99aee5f823f6f 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -6067,7 +6067,7 @@ void Character::update_bodytemp() // constant shivering will prevent the player from falling asleep. // Otherwise, if any other body part is BODYTEMP_VERY_COLD, or 31C // AND you have frostbite, then that also prevents you from sleeping - if( in_sleep_state() ) { + if( in_sleep_state() && !has_effect( effect_narcosis ) ) { if( bp == bodypart_id( "torso" ) && temp_after <= BODYTEMP_COLD ) { add_msg( m_warning, _( "Your shivering prevents you from sleeping." ) ); wake_up(); @@ -8158,6 +8158,11 @@ void Character::cough( bool harmful, int loudness ) void Character::wake_up() { + //Can't wake up if under anesthesia + if( has_effect( effect_narcosis ) ) { + return; + } + // Do not remove effect_sleep or effect_alarm_clock now otherwise it invalidates an effect // iterator in player::process_effects(). // We just set it for later removal (also happening in player::process_effects(), so no side @@ -9227,7 +9232,7 @@ void Character::on_hurt( Creature *source, bool disturb /*= true*/ ) } if( disturb ) { - if( has_effect( effect_sleep ) && !has_effect( effect_narcosis ) ) { + if( has_effect( effect_sleep ) ) { wake_up(); } if( !is_npc() && !has_effect( effect_narcosis ) ) { diff --git a/src/suffer.cpp b/src/suffer.cpp index 74ab342ec8510..5638080994987 100644 --- a/src/suffer.cpp +++ b/src/suffer.cpp @@ -756,7 +756,7 @@ void Character::suffer_in_sunlight() if( has_trait( trait_SUNBURN ) && one_in( 10 ) ) { if( !( weapon.has_flag( "RAIN_PROTECT" ) ) ) { add_msg_if_player( m_bad, _( "The sunlight burns your skin!" ) ); - if( has_effect( effect_sleep ) && !has_effect( effect_narcosis ) ) { + if( has_effect( effect_sleep ) ) { wake_up(); } mod_pain( 1 ); @@ -870,7 +870,7 @@ void Character::suffer_from_albinism() add_msg_if_player( m_bad, _( "The sunlight is really irritating your %s." ), bp_name ); //apply effects - if( has_effect( effect_sleep ) && !has_effect( effect_narcosis ) ) { + if( has_effect( effect_sleep ) ) { wake_up(); } if( one_turn_in( 1_minutes ) ) { From 25e319d07b70d4ff02101393197cd110194d254e Mon Sep 17 00:00:00 2001 From: John Candlebury Date: Mon, 20 Jul 2020 01:19:04 -0600 Subject: [PATCH 139/151] Fd_clairvoyant reveals creatures (#42275) --- src/character.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/character.cpp b/src/character.cpp index 99aee5f823f6f..01b965642d1c2 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -178,6 +178,8 @@ static const efftype_id effect_took_xanax( "took_xanax" ); static const efftype_id effect_webbed( "webbed" ); static const efftype_id effect_winded( "winded" ); +static const field_type_str_id field_fd_clairvoyant( "fd_clairvoyant" ); + static const itype_id itype_adv_UPS_off( "adv_UPS_off" ); static const itype_id itype_apparatus( "apparatus" ); static const itype_id itype_beartrap( "beartrap" ); @@ -11116,7 +11118,10 @@ bool Character::sees( const Creature &critter ) const if( dist <= 3 && has_active_mutation( trait_ANTENNAE ) ) { return true; } - + if( field_fd_clairvoyant.is_valid() && + get_map().get_field( critter.pos(), field_fd_clairvoyant ) ) { + return true; + } return Creature::sees( critter ); } From 439b8a63f3179d06a864f5338fa290886ce9cdff Mon Sep 17 00:00:00 2001 From: curstwist <39442864+curstwist@users.noreply.github.com> Date: Mon, 20 Jul 2020 03:19:38 -0400 Subject: [PATCH 140/151] mainline urban_dev house 7 (#42258) --- .../mapgen/house/urban_7_house_garden.json | 211 +++++++++++++++ .../house_general_palette.json | 5 +- .../overmap/multitile_city_buildings.json | 16 ++ .../overmap_terrain_residential.json | 14 +- data/json/regional_map_settings.json | 1 + .../building_jsons/urban_7_house_garden.json | 256 ------------------ .../Urban_Development/overmap_specials.json | 14 - .../Urban_Development/overmap_terrain.json | 60 ---- .../Urban_Development/regional_overlay.json | 1 - 9 files changed, 242 insertions(+), 336 deletions(-) create mode 100644 data/json/mapgen/house/urban_7_house_garden.json delete mode 100644 data/mods/Urban_Development/building_jsons/urban_7_house_garden.json diff --git a/data/json/mapgen/house/urban_7_house_garden.json b/data/json/mapgen/house/urban_7_house_garden.json new file mode 100644 index 0000000000000..d05a8f732ce33 --- /dev/null +++ b/data/json/mapgen/house/urban_7_house_garden.json @@ -0,0 +1,211 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ [ "urban_7_1", "urban_7_2" ] ], + "weight": 250, + "object": { + "fill_ter": "t_floor", + "rows": [ + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%", + "%.....YY#########################%.............%", + "%.....``#W}Z|F12O354, yy|UUUUU#%.............%", + "%...````* +,,,,,,,, +'''''*`````.........%", + "%...`%``#gQQ|,,JJJ,,, ||||6'q'q#%..``..%%%....%", + "%...`...#||||,,AAA,,, + >|6'q'q#%..``..%X%....%", + "%...`...#TRR ,,,,,,,, ###########...``..%%%....%", + "%...`...oy #%%%%%........``.........%", + "%.%%`...orE hhh yo%.......`````````.......%", + "%.%%`%%.or fff yo%....```````````````....%", + "%...`%%.# hhh yo%....````````````````...%", + "%.%%`..^#| ||+|||| #%...````...%%%...````...%", + "%.%%`%%.#R R|~S|< *```````...%%%%%...```...%", + "%...`%%.#R R|~t|< *```````...%%%%%...```...%", + "%.%%`...#| ||||||| L#%...````...%%%...````...%", + "%.%%`%%.#M HHH o%....````````````````...%", + "%...`%%.o lll E yo%....```````````````....%", + "%.%%`...o E 'o%......%%```````%%......%", + "%.%%`%%.# s xxxy 'k#%......%%```````%%......%", + "%...`%%.##ooo#####ooo##..........`````.........%", + "%...`....%%%%%...%%%^%............```..........%", + "%...`````````````````````````````````..........%", + "%.................................```..........%", + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%```%%%%%%%%%%%" + ], + "palettes": [ "standard_domestic_palette" ], + "terrain": { + "%": [ "t_region_shrub", "t_region_shrub_fruit", "t_region_shrub_decorative" ], + "[": [ [ "t_region_tree_fruit", 2 ], [ "t_region_tree_nut", 2 ], "t_region_tree_shade" ], + "!": "t_region_groundcover_urban", + "#": "t_adobe_brick_wall", + "_": "t_pavement", + "'": "t_thconc_floor", + "q": "t_thconc_floor", + "N": "t_thconc_floor", + "U": "t_thconc_floor", + "k": "t_thconc_floor", + "6": "t_thconc_floor", + "`": "t_concrete", + "Y": "t_concrete", + ",": "t_linoleum_white", + "A": "t_linoleum_white", + "O": "t_linoleum_white", + "F": "t_linoleum_white", + "1": "t_linoleum_white", + "2": "t_linoleum_white", + "3": "t_linoleum_white", + "4": "t_linoleum_white", + "5": "t_linoleum_white", + "7": "t_linoleum_white", + "0": "t_linoleum_white", + "n": "t_linoleum_white", + "J": "t_linoleum_white", + "~": "t_linoleum_gray", + "B": "t_linoleum_gray", + "8": "t_linoleum_gray", + "S": "t_linoleum_gray", + "9": "t_linoleum_gray", + "t": "t_linoleum_gray" + }, + "furniture": { "!": "f_region_flower", "0": "f_stool", "}": "f_counter" }, + "place_loot": [ + { "item": "television", "x": 15, "y": 18, "chance": 100 }, + { "item": "stereo", "x": 16, "y": 18, "chance": 100 }, + { "item": "hose", "x": 38, "y": 3, "chance": 100 }, + { "item": "lawnmower", "x": 38, "y": 5, "chance": 100 } + ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ [ "urban_7_3", "urban_7_4" ] ], + "weight": 250, + "object": { + "fill_ter": "t_floor", + "rows": [ + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~##o#o###########&&&&&&&##~~~~~~~~~~~~~~~", + "~~~~~~~~oTIIy +D|w U|g+ KG yyā‚øK&~~~~~~~~~~~~~~~", + "~~~~~~~~# h ||||+|||# G y&~~~~~~~~~~~~~~~", + "~~~~~~~~#@ | + ā‚øKā‚ø &~~~~~~~~~~~~~~~", + "~~~~~~~~#@ + ||||||# yyyyyy y&~~~~~~~~~~~~~~~", + "~~~~~~~~#I | | s@ T##&&&&&&&##~~~~~~~~~~~~~~~", + "~~~~~~~~oR ds| | @ #~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~#|||||| + o~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~#Q88S8| |Ih Ro~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~#B,,,,+ |III R#~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~#B,t,,| ||||||#~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~^#|||||| >|S,B#~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~#D D| >|t,B#~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~#||+|||+||||+|#~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~#I b D| y#~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~o@@@ HHso~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~o@@@ o~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~#I y sT|E k#~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~#####o#####o###~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + ], + "palettes": [ "standard_domestic_palette" ], + "terrain": { + "~": "t_open_air", + "#": "t_adobe_brick_wall", + "&": "t_screened_porch_wall", + "B": "t_linoleum_gray", + "Q": "t_linoleum_gray", + "S": "t_linoleum_gray", + "t": "t_linoleum_gray", + "8": "t_linoleum_gray", + ",": "t_linoleum_gray" + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ [ "urban_7_5", "urban_7_6" ] ], + "weight": 250, + "object": { + "fill_ter": "t_shingle_flat_roof", + "rows": [ + " ", + " |222222222222222222222223 ", + " |............X..........3 ", + " |.......................3 ", + " |.......................3 ", + " |.......................3 ", + " |.............3---------3 ", + " |...=.........3 ", + " |.............3 ", + " |.............3 ", + " |......&......3 ", + " |.............3 ", + " 5.............3 ", + " |.............3 ", + " |.............3 ", + " |........=....3 ", + " |.............3 ", + " |.............3 ", + " |............~3 ", + " -----------5--3 ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ".": "t_shingle_flat_roof" } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ [ "urban_7_1_basement", "urban_7_2_basement" ] ], + "weight": 250, + "object": { + "fill_ter": "t_thconc_floor", + "rows": [ + " ", + " ||||||||||||||||||||||||| ", + " |2.......z....%..UUU..F.| ", + " |.............%.........| ", + " |..........z..+.......zz| ", + " |.........z...%..<...z..| ", + " |%%%%%%%+%%%%%||||||||||| ", + " |1............| ", + " |.............| ", + " |.............| ", + " |.............| ", + " |.............| ", + " |.............| ", + " |.............| ", + " |.............| ", + " |.............| ", + " |.............| ", + " |.............| ", + " |.............| ", + " ||||||||||||||| ", + " ", + " ", + " ", + " " + ], + "palettes": [ "basement_empty" ], + "nested": { + "1": { + "chunks": [ + [ "recroom_12x12", 20 ], + [ "tvroom_12x12", 20 ], + [ "workoutroom_12x12", 20 ], + [ "11x11_gym_open", 20 ], + [ "11x11_recroom_open", 20 ] + ] + }, + "2": { "chunks": [ [ "null", 40 ], [ "home_office_4x4_N", 60 ], [ "home_office_4x4_S", 60 ] ] } + } + } + } +] diff --git a/data/json/mapgen_palettes/house_general_palette.json b/data/json/mapgen_palettes/house_general_palette.json index 0078a6b98f6a0..960af4b4df944 100644 --- a/data/json/mapgen_palettes/house_general_palette.json +++ b/data/json/mapgen_palettes/house_general_palette.json @@ -65,6 +65,7 @@ "8": "f_counter", "9": "f_shower", "@": "f_bed", + "ā‚ø": "f_deckchair", "Ƙ": "f_pinball_machine", "Ɔ": "f_arcade_machine", "Ź­": "f_ladder" @@ -166,7 +167,7 @@ { "item": "bed", "chance": 30, "repeat": [ 1, 2 ] } ], "R": { "item": "homebooks", "chance": 30, "repeat": [ 1, 4 ] }, - "S": [ { "item": "SUS_bathroom_sink", "chance": 80 }, { "item": "SUS_bathroom_medicine", "chance": 20 } ], + "S": [ { "item": "SUS_bathroom_sink", "chance": 80 }, { "item": "SUS_bathroom_medicine", "chance": 60 } ], "U": [ { "item": "home_hw", "chance": 20, "repeat": [ 1, 2 ] }, { "item": "cleaning", "chance": 40, "repeat": [ 1, 2 ] }, @@ -184,7 +185,7 @@ "8": [ { "item": "SUS_hair_drawer", "chance": 30 }, { "item": "SUS_bathroom_cabinet", "chance": 30 }, - { "item": "SUS_bathroom_medicine", "chance": 30 }, + { "item": "SUS_bathroom_medicine", "chance": 40 }, { "item": "harddrugs", "chance": 2 } ], "9": { "item": "shower", "chance": 30, "repeat": [ 1, 2 ] }, diff --git a/data/json/overmap/multitile_city_buildings.json b/data/json/overmap/multitile_city_buildings.json index 6a10ccb5e13ce..3ff2f83b36e23 100644 --- a/data/json/overmap/multitile_city_buildings.json +++ b/data/json/overmap/multitile_city_buildings.json @@ -105,6 +105,22 @@ "locations": [ "land" ], "flags": [ "CLASSIC" ] }, + { + "type": "city_building", + "id": "urban_7_house_garden", + "overmaps": [ + { "point": [ 1, 0, 0 ], "overmap": "urban_7_1_south" }, + { "point": [ 0, 0, 0 ], "overmap": "urban_7_2_south" }, + { "point": [ 1, 0, -1 ], "overmap": "urban_7_1_basement_south" }, + { "point": [ 0, 0, -1 ], "overmap": "urban_7_2_basement_south" }, + { "point": [ 1, 0, 1 ], "overmap": "urban_7_3_south" }, + { "point": [ 0, 0, 1 ], "overmap": "urban_7_4_south" }, + { "point": [ 1, 0, 2 ], "overmap": "urban_7_5_south" }, + { "point": [ 0, 0, 2 ], "overmap": "urban_7_6_south" } + ], + "locations": [ "land" ], + "flags": [ "CLASSIC" ] + }, { "type": "city_building", "id": "urban_13_dense_house_apt_house", diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_residential.json b/data/json/overmap/overmap_terrain/overmap_terrain_residential.json index b9a00dff11f61..a1cf0fa57c395 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_residential.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_residential.json @@ -167,7 +167,9 @@ "urban_5_1", "urban_5_2", "urban_6_1", - "urban_6_2" + "urban_6_2", + "urban_7_1", + "urban_7_2" ], "copy-from": "generic_city_house", "see_cost": 10 @@ -194,7 +196,11 @@ "urban_6_3", "urban_6_4", "urban_6_5", - "urban_6_6" + "urban_6_6", + "urban_7_3", + "urban_7_4", + "urban_7_5", + "urban_7_6" ], "copy-from": "generic_city_house_no_sidewalk", "see_cost": 10 @@ -398,7 +404,9 @@ "urban_5_1_basement", "urban_5_2_basement", "urban_6_1_basement", - "urban_6_2_basement" + "urban_6_2_basement", + "urban_7_1_basement", + "urban_7_2_basement" ], "copy-from": "generic_city_house_basement" }, diff --git a/data/json/regional_map_settings.json b/data/json/regional_map_settings.json index 3b0ec60531d91..0f11c4ad75d67 100644 --- a/data/json/regional_map_settings.json +++ b/data/json/regional_map_settings.json @@ -664,6 +664,7 @@ "urban_4_house_basement": 50, "urban_5_house": 50, "urban_6_house": 50, + "urban_7_house_garden": 50, "emptyresidentiallot": 20, "house_vacant": 20, "house_vacant2": 20, diff --git a/data/mods/Urban_Development/building_jsons/urban_7_house_garden.json b/data/mods/Urban_Development/building_jsons/urban_7_house_garden.json deleted file mode 100644 index 2d064290a2371..0000000000000 --- a/data/mods/Urban_Development/building_jsons/urban_7_house_garden.json +++ /dev/null @@ -1,256 +0,0 @@ -[ - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_7_1" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "########################", - "#,,,,,qq|---|-----------", - "#,,,,,;;|W D|ffCoCSC2 ", - "#,,,;;;;! +22222222 ", - "#,,,;#;;|rrr|22CCC222 ", - "#,,,;,,,|---|22CCC222 ", - "#,,,;,,,|AtA 22222222 |-", - "#,,,;,,,w |#", - "#,##;,,,w A w#", - "#,##;##,w At w#", - "#,,,;##,| w#", - "#,##;,,,|- -|+-|-| |#", - "#,##;##,|O O|2S|> !;", - "#,,,;##,|O O|2T|> !;", - "#,##;,,,|- -|--|-| |#", - "#,##;##,|c cw#", - "#,,,;##,wc httth cw#", - "#,##;,,,wc httth cw#", - "#,##;##,|c c|#", - "#,,,;##,|-www-----www-|,", - "#,,,;,,,,#####,,,#####,,", - "#,,,;;;;;;;;;;;;;;;;;;;;", - "#,,,,,,,,,,,,,,,,,,,,,,,", - "########################" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "A": { "item": "livingroom", "chance": 15 }, - "C": { "item": "kitchen", "chance": 25 }, - "O": { "item": "homebooks", "chance": 60 }, - "c": { "item": "livingroom", "chance": 25 }, - "f": { "item": "fridge", "chance": 70 }, - "o": { "item": "oven", "chance": 30 }, - "q": { "item": "trash", "chance": 50 }, - "r": { "item": "cannedfood", "chance": 60 }, - "t": { "item": "dining", "chance": 25 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_7_2" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "########################", - "--|-----|#,,,,,,,,,,,,,#", - "OO|rrrrr|#,,,,,,,,,,,,,#", - " 1 !;;;;;,,,,,,,,,#", - " |r r r|#,,;;,,###,,,,#", - " |r r r|#,,;;,,#^#,,,,#", - "--|-----|,,,;;,,###,,,,#", - "####,,,,,,,,;;,,,,,,,,,#", - ",,,,,,,;;;;;;;;;,,,,,,,#", - ",,,,;;;;;;;;;;;;;;;,,,,#", - ",,,,;;;;;;;;;;;;;;;;,,,#", - ",,,;;;;,,,###,,,;;;;,,,#", - ";;;;;;,,,#####,,,;;;,,,#", - ";;;;;;,,,#####,,,;;;,,,#", - ",,,;;;;,,,###,,,;;;;,,,#", - ",,,,;;;;;;;;;;;;;;;;,,,#", - ",,,,;;;;;;;;;;;;;;;,,,,#", - ",,,,,,##;;;;;;;##,,,,,,#", - ",,,,,,##;;;;;;;##,,,,,,#", - ",,,,,,,,,;;;;;,,,,,,,,,#", - ",,,,,,,,,,;;;,,,,,,,,,,#", - ";;;;;;;;;;;;;,,,,,,,,,,#", - ",,,,,,,,,,;;;,,,,,,,,,,#", - "##########;;;###########" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "O": { "item": "homebooks", "chance": 60 }, - "r": { "item": "farming_seeds", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 22 ], "y": [ 1, 22 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_7_3" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........|-w-w-|-|---|-|-", - "........w +r|u u|r+ ", - "........| |-|-+-|-| ", - "........|b | + ", - "........|b + |-----| ", - "........|e | | bbe|-", - "........w OO| | |.", - "........|-----| + w.", - "........|2TCSC| |dh ew.", - "........|B2222+ |6dd e|.", - "........|B2222| |-|---|.", - "........|-----| <|S2B|.", - "........|r r| <|T2B|.", - "........|--+--|+--|-+-|.", - "........|e |.", - "........we bbb w.", - "........w bbb w.", - "........| ebbbe OO|.", - "........|-------------|.", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "toilets": { "T": { } }, - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "2": { "item": "softdrugs", "chance": 10 }, - "@": { "item": "magazines", "chance": 10 }, - "O": { "item": "homebooks", "chance": 60 }, - "b": { "item": "bed", "chance": 60 }, - "e": { "item": "dresser", "chance": 60 }, - "r": { "item": "bedroom", "chance": 60 }, - "u": { "item": "cleaning", "chance": 60 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 9, 19 ], "y": [ 2, 18 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_7_4" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "vvvvvvv-|...............", - " tA At|...............", - " A v...............", - " v...............", - " AtA |...............", - "vvvvvvv-|...............", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ], - "items": { - " ": { "item": "livingroom", "chance": 2 }, - "A": { "item": "livingroom", "chance": 15 }, - "t": { "item": "coffee_table", "chance": 25 } - }, - "place_monsters": [ { "monster": "GROUP_ZOMBIE", "x": [ 1, 7 ], "y": [ 2, 5 ], "density": 0.09 } ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_7_5" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "........RRRRRRRRRRRRRRRR", - "........RRRRRRRRRRRRRRRR", - "........RRRRRRRRRRRRRRRR", - "........RRRRRRRRRRRRRRRR", - "........RRRRRRRRRRRRRRRR", - "........RRRRRRRRRRRRRRRR", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........RRRRRRRRRRRRRRR.", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - }, - { - "type": "mapgen", - "method": "json", - "om_terrain": [ "urban_7_6" ], - "weight": 250, - "object": { - "fill_ter": "t_floor", - "rows": [ - "........................", - "RRRRRRRRR...............", - "RRRRRRRRR...............", - "RRRRRRRRR...............", - "RRRRRRRRR...............", - "RRRRRRRRR...............", - "RRRRRRRRR...............", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "palettes": [ "acidia_residential_commercial_palette" ] - } - } -] diff --git a/data/mods/Urban_Development/overmap_specials.json b/data/mods/Urban_Development/overmap_specials.json index bcb44b443e174..3a34d9404bc94 100644 --- a/data/mods/Urban_Development/overmap_specials.json +++ b/data/mods/Urban_Development/overmap_specials.json @@ -1,18 +1,4 @@ [ - { - "type": "city_building", - "id": "urban_7_house_garden", - "overmaps": [ - { "point": [ 1, 0, 0 ], "overmap": "urban_7_1_south" }, - { "point": [ 0, 0, 0 ], "overmap": "urban_7_2_south" }, - { "point": [ 1, 0, 1 ], "overmap": "urban_7_3_south" }, - { "point": [ 0, 0, 1 ], "overmap": "urban_7_4_south" }, - { "point": [ 1, 0, 2 ], "overmap": "urban_7_5_south" }, - { "point": [ 0, 0, 2 ], "overmap": "urban_7_6_south" } - ], - "locations": [ "land" ], - "flags": [ "CLASSIC" ] - }, { "type": "city_building", "id": "urban_8_house_brick_garden", diff --git a/data/mods/Urban_Development/overmap_terrain.json b/data/mods/Urban_Development/overmap_terrain.json index 663ba45bff300..eefd3f4d8103a 100644 --- a/data/mods/Urban_Development/overmap_terrain.json +++ b/data/mods/Urban_Development/overmap_terrain.json @@ -1,64 +1,4 @@ [ - { - "id": "urban_7_1", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_7_2", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_7_3", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_7_4", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_7_5", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, - { - "id": "urban_7_6", - "type": "overmap_terrain", - "name": "house", - "sym": "v", - "color": "light_green", - "see_cost": 10, - "mondensity": 2, - "flags": [ "SIDEWALK" ] - }, { "id": "urban_8_1", "type": "overmap_terrain", diff --git a/data/mods/Urban_Development/regional_overlay.json b/data/mods/Urban_Development/regional_overlay.json index 5472553fd6cd9..8c2be5c0c09e9 100644 --- a/data/mods/Urban_Development/regional_overlay.json +++ b/data/mods/Urban_Development/regional_overlay.json @@ -4,7 +4,6 @@ "regions": [ "all" ], "city": { "houses": { - "urban_7_house_garden": 30, "urban_8_house_brick_garden": 30, "urban_9_house_garage_loft": 30, "urban_10_house_brick_pool": 30, From 4867d6ecbdec4acf1e0c565b88c9faf871ae35b7 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Mon, 20 Jul 2020 07:19:59 +0000 Subject: [PATCH 141/151] Silence a clang tidy readability warning. --- src/npc.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/npc.cpp b/src/npc.cpp index c3c628eeb759f..ab2e481e7234f 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -1584,12 +1584,12 @@ bool npc::wants_to_sell( const item &it ) const bool npc::wants_to_sell( const item &it, int at_price, int market_price ) const { if( mission == NPC_MISSION_SHOPKEEP ) { - // keep items that we either never want to trade, or don't want to trade while in use - if( it.has_flag( "TRADER_KEEP" ) || - ( it.has_flag( "TRADER_KEEP_EQUIPPED" ) && ( is_worn( it ) || is_wielding( it ) ) ) ) { + // Keep items that we never want to trade. + if( it.has_flag( "TRADER_KEEP" ) ) { return false; } - return true; + // Also ones we don't want to trade while in use. + return !( it.has_flag( "TRADER_KEEP_EQUIPPED" ) && ( is_worn( it ) || is_wielding( it ) ) ); } if( is_player_ally() ) { From ea5decc8de28a1c2e0d0276c7c08a0e44118ef5c Mon Sep 17 00:00:00 2001 From: curstwist <39442864+curstwist@users.noreply.github.com> Date: Mon, 20 Jul 2020 03:20:02 -0400 Subject: [PATCH 142/151] add freshwater research station and associated terrain/furniture. (#42107) --- .../furniture-decorative.json | 20 ++ .../furniture-industrial.json | 51 ++++ .../furniture-storage.json | 51 ++++ .../terrain-bridges-docks.json | 113 +++++++ .../furniture_and_terrain/terrain-doors.json | 44 +++ .../terrain-liquids.json | 80 +++++ .../furniture_and_terrain/terrain-walls.json | 25 ++ .../terrain-windows.json | 25 ++ data/json/itemgroups/Clothing_Gear/gear.json | 34 +++ .../freshwater_reserach_station.json | 277 ++++++++++++++++++ .../underwater_structures_palette.json | 52 ++++ .../overmap/overmap_special/specials.json | 25 ++ .../overmap_terrain_public_institutional.json | 15 + 13 files changed, 812 insertions(+) create mode 100644 data/json/mapgen/lake_buildings/freshwater_reserach_station.json create mode 100644 data/json/mapgen_palettes/underwater_structures_palette.json diff --git a/data/json/furniture_and_terrain/furniture-decorative.json b/data/json/furniture_and_terrain/furniture-decorative.json index e279727ada83e..1648308dde1a5 100644 --- a/data/json/furniture_and_terrain/furniture-decorative.json +++ b/data/json/furniture_and_terrain/furniture-decorative.json @@ -58,6 +58,26 @@ }, "flags": [ "TRANSPARENT", "MOUNTABLE", "SHORT" ] }, + { + "id": "f_cleat", + "type": "furniture", + "name": "cleat", + "description": "A small horn cleat with two ā€œhornsā€ extending parallel to the deck or the axis of the spar, and resembling a small anvil. They are used to secure mooring lines, ropes, and similar.", + "symbol": "B", + "color": "light_gray", + "looks_like": "f_bitts", + "move_cost_mod": 2, + "coverage": 30, + "required_str": 0, + "bash": { + "str_min": 80, + "str_max": 200, + "sound": "metal screeching!", + "sound_fail": "clang!", + "items": [ { "item": "steel_chunk", "count": [ 1, 3 ] } ] + }, + "flags": [ "TRANSPARENT", "SHORT" ] + }, { "type": "furniture", "id": "f_shackle", diff --git a/data/json/furniture_and_terrain/furniture-industrial.json b/data/json/furniture_and_terrain/furniture-industrial.json index d41e378ec97ff..c4649ab2896c8 100644 --- a/data/json/furniture_and_terrain/furniture-industrial.json +++ b/data/json/furniture_and_terrain/furniture-industrial.json @@ -471,5 +471,56 @@ { "item": "metal_tank_little", "count": [ 0, 6 ] } ] } + }, + { + "type": "furniture", + "id": "f_control_station", + "name": "control station", + "description": "Assorted electronic interfaces and screens. You could scavenge it for parts.", + "symbol": "$", + "color": "yellow", + "looks_like": "t_machinery_electronic", + "move_cost_mod": 8, + "coverage": 55, + "required_str": -1, + "flags": [ "TRANSPARENT", "BASHABLE", "FLAMMABLE", "PLACE_ITEM" ], + "deconstruct": { + "items": [ + { "item": "wire", "count": [ 1, 3 ] }, + { "item": "pipe", "count": [ 1, 2 ] }, + { "item": "steel_chunk", "count": [ 1, 4 ] }, + { "item": "processor", "count": 1 }, + { "item": "RAM", "count": [ 1, 4 ] }, + { "item": "cable", "charges": [ 1, 4 ] }, + { "item": "small_lcd_screen", "count": 1 }, + { "item": "e_scrap", "count": [ 5, 10 ] }, + { "item": "circuit", "count": [ 3, 8 ] }, + { "item": "power_supply", "count": [ 1, 3 ] }, + { "item": "amplifier", "count": [ 1, 3 ] }, + { "item": "plastic_chunk", "count": [ 2, 8 ] }, + { "item": "scrap", "count": [ 1, 5 ] } + ] + }, + "bash": { + "str_min": 10, + "str_max": 80, + "sound": "clang!", + "sound_fail": "ting.", + "items": [ + { "item": "wire", "prob": 40 }, + { "item": "pipe", "prob": 40 }, + { "item": "steel_chunk", "prob": 40 }, + { "item": "processor", "prob": 40 }, + { "item": "RAM", "count": [ 1, 2 ] }, + { "item": "cable", "charges": [ 1, 2 ] }, + { "item": "small_lcd_screen", "prob": 40 }, + { "item": "e_scrap", "count": [ 3, 8 ] }, + { "item": "circuit", "count": [ 1, 3 ] }, + { "item": "power_supply", "prob": 40 }, + { "item": "amplifier", "prob": 40 }, + { "item": "plastic_chunk", "count": [ 2, 8 ] }, + { "item": "scrap", "count": [ 3, 8 ] } + ] + } } ] diff --git a/data/json/furniture_and_terrain/furniture-storage.json b/data/json/furniture_and_terrain/furniture-storage.json index 120f285782beb..6e8b7464816b4 100644 --- a/data/json/furniture_and_terrain/furniture-storage.json +++ b/data/json/furniture_and_terrain/furniture-storage.json @@ -1100,5 +1100,56 @@ { "item": "sheet_metal_small", "count": [ 2, 10 ] } ] } + }, + { + "type": "furniture", + "id": "f_chest", + "description": "A sealed wooden storage container. Lacking any labels, it could hold just about anything inside. It has a simple metal latch.", + "name": "wooden chest", + "symbol": "X", + "color": "white", + "move_cost_mod": -1, + "coverage": 60, + "required_str": 12, + "looks_like": "f_crate_c", + "flags": [ "TRANSPARENT", "CONTAINER", "FLAMMABLE", "PLACE_ITEM", "ORGANIC", "MOUNTABLE", "SHORT" ], + "deconstruct": { + "items": [ { "item": "wood_panel", "count": 5 }, { "item": "hinge", "count": 2 }, { "item": "nail", "charges": [ 6, 10 ] } ] + }, + "bash": { + "str_min": 12, + "str_max": 40, + "sound": "smash!", + "sound_fail": "wham!", + "items": [ { "item": "2x4", "count": [ 1, 5 ] }, { "item": "hinge", "count": 2 }, { "item": "nail", "charges": [ 2, 10 ] } ] + } + }, + { + "type": "furniture", + "id": "f_foot_locker", + "name": "metal foot locker", + "description": "An metal stoarge box, capable of holding any number of things. The lid has has a small lock.", + "symbol": "O", + "color": "white", + "move_cost_mod": -1, + "coverage": 60, + "required_str": 10, + "looks_like": "f_crate_c", + "flags": [ "TRANSPARENT", "CONTAINER", "PLACE_ITEM", "ORGANIC", "MOUNTABLE", "SHORT" ], + "deconstruct": { + "items": [ { "item": "sheet_metal_small", "count": 6 }, { "item": "lock", "count": 1 }, { "item": "hinge", "charges": 2 } ] + }, + "bash": { + "str_min": 12, + "str_max": 40, + "sound": "smash!", + "sound_fail": "wham!", + "items": [ + { "item": "sheet_metal_small", "count": [ 2, 4 ] }, + { "item": "lock", "count": [ 0, 1 ] }, + { "item": "scrap", "count": [ 2, 6 ] }, + { "item": "hinge", "charges": 2 } + ] + } } ] diff --git a/data/json/furniture_and_terrain/terrain-bridges-docks.json b/data/json/furniture_and_terrain/terrain-bridges-docks.json index f1fac6d6baaa1..02113de936363 100644 --- a/data/json/furniture_and_terrain/terrain-bridges-docks.json +++ b/data/json/furniture_and_terrain/terrain-bridges-docks.json @@ -216,5 +216,118 @@ "ter_set": "t_water_dp", "items": [ { "item": "rock", "count": [ 4, 20 ] }, { "item": "rebar", "count": [ 10, 20 ] } ] } + }, + { + "type": "terrain", + "id": "t_metal_dock", + "name": "dock", + "description": "A metal platform held by a support made of concrete set into the ground.", + "symbol": "8", + "looks_like": "t_metal_floor", + "color": "light_gray", + "move_cost": 2, + "flags": [ "TRANSPARENT", "FLAT" ], + "deconstruct": { + "ter_set": "t_water_sh", + "items": [ { "item": "scrap", "charges": [ 3, 6 ] }, { "item": "sheet_metal", "count": 2 } ] + }, + "bash": { + "str_min": 20, + "str_max": 80, + "sound": "smash!", + "sound_fail": "whump!", + "ter_set": "t_water_moving_sh", + "items": [ { "item": "sheet_metal", "count": 2, "prob": 35 }, { "item": "scrap", "count": [ 2, 4 ] } ] + } + }, + { + "type": "terrain", + "id": "t_concrete_dock_deep_pile", + "name": "deep dock pile", + "description": "A sturdy pile made of poured concrete extending all the way to the riverbed. A metal frame will be required to support a surface.", + "looks_like": "t_concrete_wall", + "symbol": "|", + "color": "light_gray", + "move_cost": 8, + "flags": [ "TRANSPARENT", "LIQUID", "SWIMMABLE", "DEEP_WATER", "FISHABLE" ], + "deconstruct": { + "ter_set": "t_water_moving_dp", + "items": [ { "item": "rebar", "count": [ 4, 6 ] }, { "item": "rock", "count": [ 6, 10 ] } ] + }, + "bash": { + "str_min": 50, + "str_max": 120, + "sound": "smash!", + "sound_fail": "whump!", + "ter_set": "t_water_moving_dp", + "items": [ + { "item": "rock", "count": [ 6, 10 ] }, + { "item": "rebar", "count": [ 2, 4 ] }, + { "item": "scrap", "count": [ 2, 4 ] } + ] + } + }, + { + "type": "terrain", + "id": "t_metal_dock_deep_frame", + "name": "deep dock frame", + "description": "A metal frame secured atop a concrete pile. Adding a metal surface will make this into a proper dock section.", + "symbol": "#", + "color": "light_gray", + "move_cost": 6, + "flags": [ "TRANSPARENT", "NOITEM", "THIN_OBSTACLE", "MOUNTABLE", "TINY", "AUTO_WALL_SYMBOL", "UNSTABLE" ], + "deconstruct": { "ter_set": "t_concrete_dock_deep_pile", "items": [ { "item": "spike", "count": 8 }, { "item": "pipe", "count": 4 } ] }, + "looks_like": "t_sconc_wall_halfway", + "bash": { + "str_min": 12, + "str_max": 100, + "sound": "clang!", + "sound_fail": "smash!", + "ter_set": "t_concrete_dock_deep_pile", + "items": [ { "item": "pipe", "count": 4, "prob": 25 }, { "item": "scrap", "count": [ 4, 8 ] } ] + } + }, + { + "type": "terrain", + "id": "t_metal_dock_deep", + "name": "deep dock", + "description": "A metal platform held by a tall metal pile that extends to the riverbed. Very sturdy, and likely to outlast you.", + "symbol": "8", + "color": "light_gray", + "move_cost": 2, + "flags": [ "TRANSPARENT", "FLAT" ], + "deconstruct": { + "ter_set": "t_metal_dock_deep_frame", + "items": [ { "item": "nail", "charges": [ 12, 24 ] }, { "item": "sheet_metal", "count": 4 } ] + }, + "looks_like": "t_grate", + "bash": { + "str_min": 20, + "str_max": 100, + "sound": "clang!", + "sound_fail": "clang!", + "ter_set": "t_concrete_dock_deep_pile", + "items": [ { "item": "sheet_metal", "count": 4, "prob": 25 }, { "item": "scrap", "count": [ 8, 16 ] } ] + } + }, + { + "type": "terrain", + "id": "t_metal_pontoon_dp", + "name": "metal floating dock", + "description": "A floating temporary dock, anchored to keep it from drifting away.", + "looks_like": "t_grate", + "symbol": "8", + "color": "light_gray", + "move_cost": 2, + "flags": [ "TRANSPARENT", "FLAT" ], + "deconstruct": { "ter_set": "t_water_dp", "items": [ { "item": "sheet_metal", "count": [ 2, 4 ] }, { "item": "scrap", "count": 8 } ] }, + "bash": { + "str_min": 20, + "str_max": 80, + "sound": "clang!", + "sound_fail": "clang!", + "ter_set": "t_water_dp", + "items": [ { "item": "sheet_metal", "count": 2, "prob": 25 }, { "item": "scrap", "count": [ 2, 4 ] } ] + } } ] diff --git a/data/json/furniture_and_terrain/terrain-doors.json b/data/json/furniture_and_terrain/terrain-doors.json index 6d380f4ce9828..a593589469adf 100644 --- a/data/json/furniture_and_terrain/terrain-doors.json +++ b/data/json/furniture_and_terrain/terrain-doors.json @@ -2420,5 +2420,49 @@ "flags": [ "TRANSPARENT", "FLAT", "CONNECT_TO_WALL", "ROAD" ], "close": "t_door_glass_frosted_lab_c", "copy-from": "t_door_glass_lab_o" + }, + { + "type": "terrain", + "id": "t_door_metal_bulkhead_c", + "name": "closed bulkhead door", + "description": "An extremely resilient door of cast metal, it is watertight and opened using the fly wheel.", + "symbol": "+", + "looks_like": "t_door_metal_c", + "color": "light_gray", + "move_cost": 0, + "coverage": 95, + "roof": "t_metal_flat_roof", + "flags": [ "NOITEM", "DOOR", "CONNECT_TO_WALL", "MINEABLE", "BLOCK_WIND" ], + "open": "t_door_metal_bulkhead_o", + "bash": { + "str_min": 80, + "str_max": 250, + "sound": "metal screeching!", + "sound_fail": "clang!", + "ter_set": "t_mdoor_frame", + "items": [ { "item": "scrap", "count": [ 12, 24 ] }, { "item": "steel_plate", "prob": 75 } ] + } + }, + { + "type": "terrain", + "id": "t_door_metal_bulkhead_o", + "name": "open bulkhead door", + "description": "An extremely resilient door of cast metal, it is watertight and opened using the fly wheel.", + "symbol": "+", + "looks_like": "t_door_metal_o", + "color": "light_gray", + "move_cost": 1, + "coverage": 95, + "roof": "t_metal_flat_roof", + "flags": [ "NOITEM", "DOOR", "CONNECT_TO_WALL", "MINEABLE", "BLOCK_WIND" ], + "close": "t_door_metal_bulkhead_c", + "bash": { + "str_min": 80, + "str_max": 250, + "sound": "metal screeching!", + "sound_fail": "clang!", + "ter_set": "t_mdoor_frame", + "items": [ { "item": "scrap", "count": [ 12, 24 ] }, { "item": "steel_plate", "prob": 75 } ] + } } ] diff --git a/data/json/furniture_and_terrain/terrain-liquids.json b/data/json/furniture_and_terrain/terrain-liquids.json index 68a44fe3912b4..68ed18fbec4f2 100644 --- a/data/json/furniture_and_terrain/terrain-liquids.json +++ b/data/json/furniture_and_terrain/terrain-liquids.json @@ -311,5 +311,85 @@ "flags": [ "TRANSPARENT", "LIQUID", "NO_SCENT", "SWIMMABLE", "DEEP_WATER", "GOES_UP" ], "connects_to": "WATER", "examine_action": "water_source" + }, + { + "type": "terrain", + "id": "t_bulkhead_roof", + "//": "for eventual use with water z levels. Currently non-functional. Roof for submerged structures.", + "name": "bulkhead", + "description": "The top of a submerged structure. With a watertight container, you could gather fresh water from here. Not safe to drink as is.", + "symbol": "#", + "looks_like": "t_metal_flat_roof", + "color": "light_gray", + "move_cost": 8, + "flags": [ "TRANSPARENT", "LIQUID", "NO_SCENT", "SWIMMABLE", "DEEP_WATER", "GOES_UP", "MINEABLE" ], + "connects_to": "WATER", + "examine_action": "water_source" + }, + { + "type": "terrain", + "id": "t_bulkhead_floor", + "//": "for eventual use with water z levels. Currently non-functional. Roof for submerged structures.", + "name": "bulkhead", + "description": "The bottom of a submerged structure.", + "symbol": "#", + "looks_like": "t_metal_floor", + "color": "light_gray", + "move_cost": 8, + "flags": [ "TRANSPARENT", "SUPPORTS_ROOF", "INDOORS", "FLAT", "ROAD", "MINEABLE" ], + "bash": { + "sound": "thump", + "ter_set": "t_null", + "str_min": 200, + "str_max": 500, + "str_min_supported": 200, + "items": [ + { "item": "steel_lump", "count": [ 1, 4 ] }, + { "item": "steel_chunk", "count": [ 3, 12 ] }, + { "item": "scrap", "count": [ 9, 36 ] } + ] + } + }, + { + "type": "terrain", + "id": "t_lake_bed_concrete", + "//": "for eventual use with water z levels. Currently non-functional. Cement on the lake floor.", + "name": "submerged concrete", + "description": "You are standing at the bottom of a body of fresh water on a pad of concrete. With a watertight container, you could gather fresh water from here. Not safe to drink as is.", + "symbol": "~", + "looks_like": "t_concrete", + "color": "white", + "move_cost": 8, + "flags": [ "TRANSPARENT", "LIQUID", "NO_SCENT", "SWIMMABLE", "DEEP_WATER", "GOES_UP", "MINEABLE" ], + "bash": { + "ter_set": "t_lake_bed", + "str_min": 50, + "str_max": 400, + "str_min_supported": 100, + "items": [ { "item": "rock", "count": [ 2, 10 ] } ] + }, + "connects_to": "WATER", + "examine_action": "water_source" + }, + { + "type": "terrain", + "id": "t_lake_bed_concrete_yellow", + "//": "for eventual use with water z levels. Currently non-functional. Cement on the lake floor.", + "name": "submerged concrete", + "description": "You are standing at the bottom of a body of fresh water on a pad of concrete with yelllow paint. With a watertight container, you could gather fresh water from here. Not safe to drink as is.", + "symbol": "#", + "looks_like": "t_pavement_y", + "color": "yellow", + "move_cost": 8, + "flags": [ "TRANSPARENT", "LIQUID", "NO_SCENT", "SWIMMABLE", "DEEP_WATER", "GOES_UP", "MINEABLE" ], + "bash": { + "ter_set": "t_lake_bed", + "str_min": 50, + "str_max": 400, + "str_min_supported": 100, + "items": [ { "item": "rock", "count": [ 2, 10 ] } ] + }, + "connects_to": "WATER", + "examine_action": "water_source" } ] diff --git a/data/json/furniture_and_terrain/terrain-walls.json b/data/json/furniture_and_terrain/terrain-walls.json index 85b99df7262e5..cc776336caabd 100644 --- a/data/json/furniture_and_terrain/terrain-walls.json +++ b/data/json/furniture_and_terrain/terrain-walls.json @@ -443,6 +443,31 @@ ] } }, + { + "type": "terrain", + "id": "t_wall_bulkhead", + "name": "bulkhead", + "description": "An industrially fabricated thick sheet carefully positioned, this wall is capable of resisting extreme elements as well as hostile forces.", + "symbol": "LINE_OXOX", + "color": "light_gray", + "move_cost": 0, + "coverage": 100, + "looks_like": "t_wall_metal", + "roof": "t_metal_flat_roof", + "flags": [ "NOITEM", "SUPPORTS_ROOF", "WALL", "NO_SCENT", "AUTO_WALL_SYMBOL", "MINEABLE", "BLOCK_WIND" ], + "bash": { + "str_min": 200, + "str_max": 600, + "sound": "metal screeching!", + "sound_fail": "clang!", + "ter_set": "t_null", + "items": [ + { "item": "steel_lump", "count": [ 1, 4 ] }, + { "item": "steel_chunk", "count": [ 3, 12 ] }, + { "item": "scrap", "count": [ 9, 36 ] } + ] + } + }, { "type": "terrain", "id": "t_sconc_wall", diff --git a/data/json/furniture_and_terrain/terrain-windows.json b/data/json/furniture_and_terrain/terrain-windows.json index 9fd2f50d99e54..34eb1fd9a6eec 100644 --- a/data/json/furniture_and_terrain/terrain-windows.json +++ b/data/json/furniture_and_terrain/terrain-windows.json @@ -3110,5 +3110,30 @@ "ter_set": "t_window_frame", "items": [ { "item": "glass_shard", "count": [ 68, 100 ] } ] } + }, + { + "type": "terrain", + "id": "t_porthole", + "name": "porthole", + "description": "A thick round window surrounded with a strong metal frame, the window is sealed closed.", + "looks_like": "t_laminated_glass", + "symbol": "o", + "color": "light_gray", + "move_cost": 0, + "roof": "t_metal_flat_roof", + "flags": [ "TRANSPARENT", "NOITEM", "CONNECT_TO_WALL", "THIN_OBSTACLE", "BLOCK_WIND", "REDUCE_SCENT" ], + "bash": { + "str_min": 50, + "str_max": 75, + "sound": "metal screeching!", + "sound_fail": "clang!", + "ter_set": "t_metal_floor", + "items": [ + { "item": "steel_lump", "prob": 55 }, + { "item": "steel_chunk", "count": [ 1, 4 ] }, + { "item": "scrap", "count": [ 1, 5 ] }, + { "item": "glass_shard", "count": [ 20, 50 ] } + ] + } } ] diff --git a/data/json/itemgroups/Clothing_Gear/gear.json b/data/json/itemgroups/Clothing_Gear/gear.json index bcd3a2efdcc3a..26d926bcb6787 100644 --- a/data/json/itemgroups/Clothing_Gear/gear.json +++ b/data/json/itemgroups/Clothing_Gear/gear.json @@ -159,5 +159,39 @@ [ "prussian_blue", 25 ], [ "iodine", 50 ] ] + }, + { + "id": "SUS_scuba_gear", + "type": "item_group", + "//": "This group is for an area storing diving equipment. SUS item groups are collections that contain a reasonable realistic distribution of items that might spawn in a given storage furniture.", + "subtype": "collection", + "entries": [ + { "distribution": [ { "item": "c_fishspear", "prob": 50 }, { "item": "m_fishspear", "prob": 50 } ], "prob": 65 }, + { "group": "swimmer_head", "prob": 100 }, + { "group": "swimmer_torso", "prob": 100 }, + { "group": "swimmer_pants", "prob": 100 }, + { "group": "swimmer_wetsuit", "prob": 100 }, + { "item": "dive_bag", "prob": 100 }, + { "item": "wetsuit_gloves", "prob": 70 }, + { "item": "wetsuit_booties", "prob": 70 }, + { "item": "swim_fins", "prob": 100 }, + { + "distribution": [ + { "item": "airspeargun", "prob": 20 }, + { "item": "doublespeargun", "prob": 10 }, + { "item": "minispeargun", "prob": 30 }, + { "item": "speargun", "prob": 40 } + ], + "prob": 65 + }, + { + "collection": [ { "item": "small_scuba_tank", "prob": 40 }, { "item": "scuba_tank", "prob": 60 } ], + "prob": 85 + }, + { + "collection": [ { "item": "rebreather_filter", "prob": 50 }, { "item": "rebreather", "prob": 90 } ], + "prob": 20 + } + ] } ] diff --git a/data/json/mapgen/lake_buildings/freshwater_reserach_station.json b/data/json/mapgen/lake_buildings/freshwater_reserach_station.json new file mode 100644 index 0000000000000..fce221b3dc6a6 --- /dev/null +++ b/data/json/mapgen/lake_buildings/freshwater_reserach_station.json @@ -0,0 +1,277 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": "sealab_small_surface", + "object": { + "fill_ter": "t_metal_pontoon_dp", + "rows": [ + "~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~&~~~~#~~~~~~~~~", + "~~~~~~~~~#~~~~#~~~~~~~~~", + "~~~~~~~~~#~~~~&~~~~~~~~~", + "~~~~~~~~~#~~~~#~~~~~~~~~", + "~~~~~~~~########~~~~~~~~", + "~~~~~~~~##||o|##~~~~~~~~", + "~~~~~~~~##|>A|##~~~~~~~~", + "~~~~~~~~##+..|##~~~~~~~~", + "~~~~~~~~##||o|##~~~~~~~~", + "~~~~~~~~########~~~~~~~~", + "~~~~~~~~~#~~~~#~~~~~~~~~", + "~~~~~~~~~&~~~~&~~~~~~~~~", + "~~~~~~~~~#~~~~#~~~~~~~~~", + "~~~~~~~~~#~~~~#~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~", + "~~~~~~~~~~~~~~~~~~~~~~~~" + ], + "palettes": [ "underwater_structure" ], + "place_loot": [ + { "item": "rope_30", "x": 9, "y": [ 7, 9 ], "chance": 100 }, + { "item": "rope_30", "x": 14, "y": [ 7, 9 ], "chance": 100 }, + { "item": "rope_30", "x": 9, "y": [ 13, 15 ], "chance": 100 }, + { "item": "rope_30", "x": 14, "y": [ 13, 15 ], "chance": 100 } + ], + "items": { "#": { "item": "fishing_items", "chance": 10 } }, + "place_vehicles": [ + { "vehicle": "boat_motor_single", "x": 11, "y": 9, "rotation": 270, "chance": 70, "status": 3 }, + { "vehicle": "kayak", "x": 10, "y": 8, "rotation": 270, "chance": 10, "status": 0 }, + { "vehicle": "canoe", "x": 10, "y": 17, "rotation": 90, "chance": 30, "status": 0 }, + { "vehicle": "kayak_racing", "x": 13, "y": 17, "rotation": 90, "chance": 10, "status": 0 }, + { "vehicle": "portable_generator", "x": 11, "y": 13, "rotation": 0, "chance": 100, "status": 0 } + ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "sealab_small_-1", + "object": { + "fill_ter": "t_bulkhead_floor", + "rows": [ + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "----------||||----------", + "----------|<>|----------", + "----------||||----------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------" + ], + "palettes": [ "underwater_structure" ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "sealab_small_-2", + "object": { + "fill_ter": "t_bulkhead_floor", + "rows": [ + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "---------`````----------", + "--------```````---------", + "-------`````````--------", + "-------`````````--------", + "-------`````````--------", + "-------`````````--------", + "-------`````````--------", + "-------```||||``--------", + "-------```|><|``--------", + "-------```||||``--------", + "-------`````````--------", + "-------`````````--------", + "-------`````````--------", + "-------`````````--------", + "-------`````````--------", + "--------```````---------", + "---------`````----------", + "------------------------", + "------------------------", + "------------------------" + ], + "palettes": [ "underwater_structure" ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "sealab_small_-3", + "object": { + "fill_ter": "t_bulkhead_floor", + "rows": [ + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "---------||o||----------", + "--------||S t||---------", + "-------||||+||||--------", + "-------|@@l @|--------", + "-------ol @o--------", + "-------|@ l|--------", + "-------|@ l@@|--------", + "------`||||+||||```-----", + "-----``|b <> Q|````----", + "----```|b Q|`````---", + "```````||||+||||`````---", + "```````|hh C|`````---", + "```````off GCo`````---", + "----```|hh C|`````---", + "-----``||W K||````----", + "------``||ccc||````-----", + "---------||o||----------", + "------------------------", + "------------------------", + "------------------------" + ], + "palettes": [ "underwater_structure" ], + "place_loot": [ + { "item": "microwave", "x": 10, "y": 19, "chance": 100 }, + { "item": "toaster", "x": 11, "y": 19, "chance": 100 }, + { "item": "hotplate", "x": 12, "y": 19, "chance": 100 } + ], + "items": { + "S": [ { "item": "SUS_bathroom_sink", "chance": 80 }, { "item": "SUS_bathroom_medicine", "chance": 60 } ], + "t": { "item": "SUS_toilet", "chance": 10, "repeat": [ 1, 3 ] }, + "f": [ + { "item": "dishes_dining", "chance": 30 }, + { "item": "tea_dishes", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "baked_goods", "chance": 5 }, + { "item": "groce_condiment", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "dining", "chance": 10 } + ], + "b": { "item": "homebooks", "chance": 30 }, + "K": { "item": "SUS_fridge", "chance": 100 }, + "Q": [ + { "item": "SUS_pantry", "chance": 40 }, + { "item": "SUS_breakfast_cupboard", "chance": 30 }, + { "item": "SUS_coffee_cupboard", "chance": 30 }, + { "item": "cannedfood", "chance": 20, "repeat": [ 1, 2 ] } + ], + "@": { "item": "bed", "chance": 100 }, + "c": [ + { "item": "SUS_utensils", "chance": 50 }, + { "item": "SUS_cookware", "chance": 50 }, + { "item": "SUS_knife_drawer", "chance": 50 } + ], + "l": [ + { "item": "SUS_dresser_mens", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "SUS_dresser_womens", "chance": 50, "repeat": [ 1, 2 ] } + ] + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "sealab_small_-4", + "object": { + "fill_ter": "t_bulkhead_floor", + "rows": [ + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "------------------------", + "-----------P------------", + "------------------------", + "--------P-----P---------", + "------------------------", + "------------------------", + "------------------------", + "------|||o||||o||||-----", + "-----||UJQQ|": "t_ladder_down", + "<": "t_ladder_up", + "|": "t_wall_bulkhead", + "+": "t_door_metal_bulkhead_c", + "o": "t_porthole", + "P": "t_concrete_dock_deep_pile", + "`": "t_bulkhead_roof", + "^": "t_lake_bed_concrete", + "y": "t_lake_bed_concrete_yellow", + ";": "t_lake_bed", + "2": "t_machinery_electronic" + }, + "furniture": { + "1": "f_control_station", + "A": "f_air_compressor", + "B": "f_sample_freezer", + "C": "f_workbench", + "E": "f_shaker", + "G": "f_stool", + "H": "f_counter", + "I": "f_IV_pole", + "J": "f_curtain", + "K": "f_fridge", + "S": "f_sink", + "Q": "f_rack", + "U": "f_shower", + "W": "f_water_purifier", + "b": "f_bench", + "c": "f_cupboard", + "f": "f_tourist_table", + "h": "f_camp_chair", + "l": "f_foot_locker", + "@": "f_bed", + "&": "f_cleat" + }, + "toilets": { "t": { } }, + "gaspumps": { "!": { } }, + "vendingmachines": { "D": { "item_group": "vending_drink" }, "F": { "item_group": "vending_food" } } + } +] diff --git a/data/json/overmap/overmap_special/specials.json b/data/json/overmap/overmap_special/specials.json index cf1b46c120bae..4708ad086acc6 100644 --- a/data/json/overmap/overmap_special/specials.json +++ b/data/json/overmap/overmap_special/specials.json @@ -7157,5 +7157,30 @@ "city_sizes": [ 1, 12 ], "occurrences": [ 0, 3 ], "flags": [ "CLASSIC" ] + }, + { + "type": "overmap_special", + "id": "Freshwater Research Station", + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "lake_surface" }, + { "point": [ 1, 0, 0 ], "overmap": "lake_surface" }, + { "point": [ 2, 0, 0 ], "overmap": "lake_surface" }, + { "point": [ 0, 1, 0 ], "overmap": "lake_surface" }, + { "point": [ 1, 1, 0 ], "overmap": "sealab_small_surface_north" }, + { "point": [ 1, 1, -1 ], "overmap": "sealab_small_-1_north" }, + { "point": [ 1, 1, -2 ], "overmap": "sealab_small_-2_north" }, + { "point": [ 1, 1, -3 ], "overmap": "sealab_small_-3_north" }, + { "point": [ 1, 1, -4 ], "overmap": "sealab_small_-4_north" }, + { "point": [ 1, 1, -5 ], "overmap": "sealab_small_-5_north" }, + { "point": [ 2, 1, 0 ], "overmap": "lake_surface" }, + { "point": [ 0, 2, 0 ], "overmap": "lake_surface" }, + { "point": [ 1, 2, 0 ], "overmap": "lake_surface" }, + { "point": [ 2, 2, 0 ], "overmap": "lake_surface" } + ], + "locations": [ "lake_surface" ], + "city_distance": [ 3, -1 ], + "city_sizes": [ 4, 12 ], + "occurrences": [ 0, 2 ], + "flags": [ "CLASSIC", "LAKE", "WILDERNESS" ] } ] diff --git a/data/json/overmap/overmap_terrain/overmap_terrain_public_institutional.json b/data/json/overmap/overmap_terrain/overmap_terrain_public_institutional.json index 0ad3993e462e1..8eb4e9c0f2e10 100644 --- a/data/json/overmap/overmap_terrain/overmap_terrain_public_institutional.json +++ b/data/json/overmap/overmap_terrain/overmap_terrain_public_institutional.json @@ -356,5 +356,20 @@ "color": "light_blue", "see_cost": 2, "mondensity": 2 + }, + { + "type": "overmap_terrain", + "id": [ + "sealab_small_surface", + "sealab_small_-1", + "sealab_small_-2", + "sealab_small_-3", + "sealab_small_-4", + "sealab_small_-5" + ], + "name": "freshwater research station", + "sym": "~", + "color": "yellow", + "see_cost": 1 } ] From 346d4c19fadf9f1b1b0387a5e1b3b5010138a204 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Mon, 20 Jul 2020 00:20:58 -0700 Subject: [PATCH 143/151] Make several more members private in game (#42255) * Make scent_map private in game * Make timed events private in game. * Make achievements tracker private in game * Make memoial tracker private in game * Make scenario variable private in game --- src/achievement.h | 2 ++ src/activity_actor.cpp | 12 ++++---- src/bionics.cpp | 2 +- src/cata_tiles.cpp | 4 +-- src/character.cpp | 12 ++++---- src/computer_session.cpp | 10 +++--- src/debug_menu.cpp | 2 +- src/editmap.cpp | 2 +- src/game.cpp | 24 +++++++++++++-- src/game.h | 12 +++++--- src/gamemode_tutorial.cpp | 2 +- src/iexamine.cpp | 10 +++--- src/iuse.cpp | 12 ++++---- src/magic_spell_effect.cpp | 2 +- src/main_menu.cpp | 2 +- src/map.cpp | 12 ++++---- src/map_field.cpp | 2 +- src/memorial_logger.cpp | 2 +- src/memorial_logger.h | 2 ++ src/monattack.cpp | 7 +++-- src/mondeath.cpp | 2 +- src/monmove.cpp | 12 ++++---- src/mutation.cpp | 6 ++-- src/newcharacter.cpp | 60 ++++++++++++++++++------------------ src/savegame_json.cpp | 12 ++++---- src/scent_map.h | 2 ++ src/timed_event.cpp | 14 ++++----- src/timed_event.h | 2 ++ src/trapfunc.cpp | 2 +- tests/memorial_test.cpp | 3 +- tests/stats_tracker_test.cpp | 3 +- 31 files changed, 142 insertions(+), 111 deletions(-) diff --git a/src/achievement.h b/src/achievement.h index 609caa4e2149f..6e38576ff9e46 100644 --- a/src/achievement.h +++ b/src/achievement.h @@ -212,4 +212,6 @@ class achievements_tracker : public event_subscriber std::unordered_map achievements_status_; }; +achievements_tracker &get_achievements(); + #endif // CATA_SRC_ACHIEVEMENT_H diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index e98ea82b2868c..5d959a4d894b9 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -582,9 +582,9 @@ void hacking_activity_actor::finish( player_activity &act, Character &who ) get_event_bus().send( who.getID() ); sounds::sound( who.pos(), 60, sounds::sound_t::music, _( "an alarm sound!" ), true, "environment", "alarm" ); - if( examp.z > 0 && !g->timed_events.queued( timed_event_type::WANTED ) ) { - g->timed_events.add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, - who.global_sm_location() ); + if( examp.z > 0 && !get_timed_events().queued( timed_event_type::WANTED ) ) { + get_timed_events().add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, + who.global_sm_location() ); } break; case hack_result::NOTHING: @@ -956,9 +956,9 @@ void lockpick_activity_actor::finish( player_activity &act, Character &who ) if( !perfect && ter_type == t_door_locked_alarm && ( lock_roll + dice( 1, 30 ) ) > pick_roll ) { sounds::sound( who.pos(), 40, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment", "alarm" ); - if( !g->timed_events.queued( timed_event_type::WANTED ) ) { - g->timed_events.add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, - who.global_sm_location() ); + if( !get_timed_events().queued( timed_event_type::WANTED ) ) { + get_timed_events().add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, + who.global_sm_location() ); } } diff --git a/src/bionics.cpp b/src/bionics.cpp index c2ed5f9e8b29e..842c962937a2a 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -2600,7 +2600,7 @@ void Character::bionics_install_failure( const bionic_id &bid, const std::string set_max_power_level( units::from_kilojoule( rng( 0, units::to_kilojoule( get_max_power_level() ) - 25 ) ) ); if( is_player() ) { - g->memorial().add( + get_memorial().add( pgettext( "memorial_male", "Lost %d units of power capacity." ), pgettext( "memorial_female", "Lost %d units of power capacity." ), units::to_kilojoule( old_power - get_max_power_level() ) ); diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index 16837ff7e39d8..4aa448c8ef275 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -1128,7 +1128,7 @@ void cata_tiles::draw( const point &dest, const tripoint ¢er, int width, int // Add scent value to the overlay_strings list for every visible tile when displaying scent if( g->display_overlay_state( ACTION_DISPLAY_SCENT ) && !invisible[0] ) { - const int scent_value = g->scent.get( pos ); + const int scent_value = get_scent().get( pos ); if( scent_value > 0 ) { overlay_strings.emplace( player_to_screen( point( x, y ) ) + point( tile_width / 2, 0 ), formatted_text( std::to_string( scent_value ), 8 + catacurses::yellow, @@ -1138,7 +1138,7 @@ void cata_tiles::draw( const point &dest, const tripoint ¢er, int width, int // Add scent type to the overlay_strings list for every visible tile when displaying scent if( g->display_overlay_state( ACTION_DISPLAY_SCENT_TYPE ) && !invisible[0] ) { - const scenttype_id scent_type = g->scent.get_type( pos ); + const scenttype_id scent_type = get_scent().get_type( pos ); if( !scent_type.is_empty() ) { overlay_strings.emplace( player_to_screen( point( x, y ) ) + point( tile_width / 2, 0 ), formatted_text( scent_type.c_str(), 8 + catacurses::yellow, diff --git a/src/character.cpp b/src/character.cpp index 01b965642d1c2..78da70b9a9ba9 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -1223,7 +1223,7 @@ void Character::forced_dismount() add_msg_if_player( m_bad, _( "You hurt yourself!" ) ); deal_damage( nullptr, hit, damage_instance( DT_BASH, damage ) ); if( is_avatar() ) { - g->memorial().add( + get_memorial().add( pgettext( "memorial_male", "Fell off a mount." ), pgettext( "memorial_female", "Fell off a mount." ) ); } @@ -8553,7 +8553,7 @@ void Character::passive_absorb_hit( const bodypart_id &bp, damage_unit &du ) con static void destroyed_armor_msg( Character &who, const std::string &pre_damage_name ) { if( who.is_avatar() ) { - g->memorial().add( + get_memorial().add( //~ %s is armor name pgettext( "memorial_male", "Worn %s was completely destroyed." ), pgettext( "memorial_female", "Worn %s was completely destroyed." ), @@ -9273,7 +9273,7 @@ void Character::update_type_of_scent( bool init ) } if( !init && new_scent != get_type_of_scent() ) { - g->scent.reset(); + get_scent().reset(); } set_type_of_scent( new_scent ); } @@ -9284,7 +9284,7 @@ void Character::update_type_of_scent( const trait_id &mut, bool gain ) if( mut_scent ) { if( gain && mut_scent.value() != get_type_of_scent() ) { set_type_of_scent( mut_scent.value() ); - g->scent.reset(); + get_scent().reset(); } else { update_type_of_scent(); } @@ -9884,8 +9884,8 @@ void Character::fall_asleep() if( has_active_mutation( trait_HIBERNATE ) && get_kcal_percent() > 0.8f ) { if( is_avatar() ) { - g->memorial().add( pgettext( "memorial_male", "Entered hibernation." ), - pgettext( "memorial_female", "Entered hibernation." ) ); + get_memorial().add( pgettext( "memorial_male", "Entered hibernation." ), + pgettext( "memorial_female", "Entered hibernation." ) ); } // some days worth of round-the-clock Snooze. Cata seasons default to 91 days. fall_asleep( 10_days ); diff --git a/src/computer_session.cpp b/src/computer_session.cpp index 0c4a284c38c03..14fa14bbe710a 100644 --- a/src/computer_session.cpp +++ b/src/computer_session.cpp @@ -743,7 +743,7 @@ void computer_session::action_amigara_log() void computer_session::action_amigara_start() { - g->timed_events.add( timed_event_type::AMIGARA, calendar::turn + 1_minutes ); + get_timed_events().add( timed_event_type::AMIGARA, calendar::turn + 1_minutes ); Character &player_character = get_player_character(); if( !player_character.has_artifact_with( AEP_PSYSHIELD ) ) { player_character.add_effect( effect_amigara, 2_minutes ); @@ -1349,9 +1349,9 @@ void computer_session::failure_alarm() sounds::sound( player_character.pos(), 60, sounds::sound_t::alarm, _( "an alarm sound!" ), false, "environment", "alarm" ); - if( g->get_levz() > 0 && !g->timed_events.queued( timed_event_type::WANTED ) ) { - g->timed_events.add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, - player_character.global_sm_location() ); + if( g->get_levz() > 0 && !get_timed_events().queued( timed_event_type::WANTED ) ) { + get_timed_events().add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, + player_character.global_sm_location() ); } } @@ -1436,7 +1436,7 @@ void computer_session::failure_pump_leak() void computer_session::failure_amigara() { - g->timed_events.add( timed_event_type::AMIGARA, calendar::turn + 30_seconds ); + get_timed_events().add( timed_event_type::AMIGARA, calendar::turn + 30_seconds ); get_player_character().add_effect( effect_amigara, 2_minutes ); explosion_handler::explosion( tripoint( rng( 0, MAPSIZE_X ), rng( 0, MAPSIZE_Y ), g->get_levz() ), 10, diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index dbc9d3f1adc3c..f9ec736f14fec 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -1197,7 +1197,7 @@ void debug() cata::optional action = debug_menu_uilist( debug_menu_has_hotkey ); // For the "cheaty" options, disable achievements when used - achievements_tracker &achievements = g->achievements(); + achievements_tracker &achievements = get_achievements(); static const std::unordered_set non_cheaty_options = { debug_menu_index::SAVE_SCREENSHOT, debug_menu_index::GAME_REPORT, diff --git a/src/editmap.cpp b/src/editmap.cpp index 5e254ed4bd9a2..a53e90d186dd7 100644 --- a/src/editmap.cpp +++ b/src/editmap.cpp @@ -738,7 +738,7 @@ void editmap::update_view_with_help( const std::string &txt, const std::string & Character &player_character = get_player_character(); const std::string u_see_msg = player_character.sees( target ) ? _( "yes" ) : _( "no" ); mvwprintw( w_info, point( 1, off++ ), _( "dist: %d u_see: %s veh: %s scent: %d" ), - rl_dist( player_character.pos(), target ), u_see_msg, veh_msg, g->scent.get( target ) ); + rl_dist( player_character.pos(), target ), u_see_msg, veh_msg, get_scent().get( target ) ); mvwprintw( w_info, point( 1, off++ ), _( "sight_range: %d, daylight_sight_range: %d," ), player_character.sight_range( g->light_level( player_character.posz() ) ), player_character.sight_range( current_daylight_level( calendar::turn ) ) ); diff --git a/src/game.cpp b/src/game.cpp index e6c8ca95affe7..8ea825f04ccee 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -709,14 +709,14 @@ bool game::start_game() get_auto_notes_settings().default_initialize(); // spawn the starting NPC, assuming it's not disallowed by the scenario - if( !g->scen->has_flag( "LONE_START" ) ) { + if( !get_scenario()->has_flag( "LONE_START" ) ) { create_starting_npcs(); } //Load NPCs. Set nearby npcs to active. load_npcs(); // Spawn the monsters const bool spawn_near = - get_option( "BLACK_ROAD" ) || g->scen->has_flag( "SUR_START" ); + get_option( "BLACK_ROAD" ) || get_scenario()->has_flag( "SUR_START" ); // Surrounded start ones if( spawn_near ) { start_loc.surround_with_monsters( omtstart, mongroup_id( "GROUP_ZOMBIE" ), 70 ); @@ -12600,6 +12600,11 @@ void game_ui::init_ui() g->init_ui( true ); } +achievements_tracker &get_achievements() +{ + return g->achievements(); +} + Character &get_player_character() { return g->u; @@ -12620,6 +12625,11 @@ event_bus &get_event_bus() return g->events(); } +memorial_logger &get_memorial() +{ + return g->memorial(); +} + const scenario *get_scenario() { return g->scen; @@ -12629,7 +12639,17 @@ void set_scenario( const scenario *new_scenario ) g->scen = new_scenario; } +scent_map &get_scent() +{ + return g->scent; +} + stats_tracker &get_stats() { return g->stats(); } + +timed_event_manager &get_timed_events() +{ + return g->timed_events; +} diff --git a/src/game.h b/src/game.h index 7697f646c5be6..9b69c53353312 100644 --- a/src/game.h +++ b/src/game.h @@ -149,6 +149,7 @@ class game friend class editmap; friend class advanced_inventory; friend class main_menu; + friend achievements_tracker &get_achievements(); friend event_bus &get_event_bus(); friend map &get_map(); friend Character &get_player_character(); @@ -157,6 +158,9 @@ class game friend const scenario *get_scenario(); friend void set_scenario( const scenario *new_scenario ); friend stats_tracker &get_stats(); + friend scent_map &get_scent(); + friend timed_event_manager &get_timed_events(); + friend memorial_logger &get_memorial(); public: game(); ~game(); @@ -967,15 +971,16 @@ class game map &m; avatar &u; + scent_map &scent; + const scenario *scen = nullptr; event_bus &events(); stats_tracker &stats(); - public: - scent_map &scent; timed_event_manager &timed_events; - achievements_tracker &achievements(); memorial_logger &memorial(); + public: + spell_events &spell_events_subscriber(); pimpl critter_tracker; @@ -986,7 +991,6 @@ class game /** True if the game has just started or loaded, else false. */ bool new_game = false; - const scenario *scen; std::vector coming_to_stairs; int monstairz = 0; diff --git a/src/gamemode_tutorial.cpp b/src/gamemode_tutorial.cpp index 044fe89f2c51c..6c5048c63c9ea 100644 --- a/src/gamemode_tutorial.cpp +++ b/src/gamemode_tutorial.cpp @@ -111,7 +111,7 @@ bool tutorial_game::init() // Start at noon calendar::turn = calendar::turn_zero + 12_hours; tutorials_seen.clear(); - g->scent.reset(); + get_scent().reset(); get_weather().temperature = 65; // We use a Z-factor of 10 so that we don't plop down tutorial rooms in the // middle of the "real" game world diff --git a/src/iexamine.cpp b/src/iexamine.cpp index ad4c129c0e23b..8d0aec3dec5ab 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1540,8 +1540,8 @@ void iexamine::pedestal_wyrm( player &p, const tripoint &examp ) sounds::sound( examp, 80, sounds::sound_t::combat, _( "an ominous grinding noiseā€¦" ), true, "misc", "stones_grinding" ); here.ter_set( examp, t_rock_floor ); - g->timed_events.add( timed_event_type::SPAWN_WYRMS, - calendar::turn + rng( 30_seconds, 60_seconds ) ); + get_timed_events().add( timed_event_type::SPAWN_WYRMS, + calendar::turn + rng( 30_seconds, 60_seconds ) ); } /** @@ -1555,13 +1555,13 @@ void iexamine::pedestal_temple( player &p, const tripoint &examp ) add_msg( _( "The pedestal sinks into the groundā€¦" ) ); here.ter_set( examp, t_dirt ); here.i_clear( examp ); - g->timed_events.add( timed_event_type::TEMPLE_OPEN, calendar::turn + 10_seconds ); + get_timed_events().add( timed_event_type::TEMPLE_OPEN, calendar::turn + 10_seconds ); } else if( p.has_amount( itype_petrified_eye, 1 ) && query_yn( _( "Place your petrified eye on the pedestal?" ) ) ) { p.use_amount( itype_petrified_eye, 1 ); add_msg( _( "The pedestal sinks into the groundā€¦" ) ); here.ter_set( examp, t_dirt ); - g->timed_events.add( timed_event_type::TEMPLE_OPEN, calendar::turn + 10_seconds ); + get_timed_events().add( timed_event_type::TEMPLE_OPEN, calendar::turn + 10_seconds ); } else { add_msg( _( "This pedestal is engraved in eye-shaped diagrams, and has a " "large semi-spherical indentation at the top." ) ); @@ -1665,7 +1665,7 @@ void iexamine::fswitch( player &p, const tripoint &examp ) } } add_msg( m_warning, _( "You hear the rumble of rock shifting." ) ); - g->timed_events.add( timed_event_type::TEMPLE_SPAWN, calendar::turn + 3_turns ); + get_timed_events().add( timed_event_type::TEMPLE_SPAWN, calendar::turn + 3_turns ); } /** diff --git a/src/iuse.cpp b/src/iuse.cpp index 0f8ebac2e2861..6fced8977ae9c 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -1402,7 +1402,7 @@ static void marloss_common( player &p, item &it, const trait_id ¤t_color ) p.add_msg_if_player( m_bad, _( "You feel a familiar warmth, but suddenly it surges into an excruciating burn as you convulse, vomiting, and black outā€¦" ) ); if( p.is_avatar() ) { - g->memorial().add( + get_memorial().add( pgettext( "memorial_male", "Suffered Marloss Rejection." ), pgettext( "memorial_female", "Suffered Marloss Rejection." ) ); } @@ -2610,9 +2610,9 @@ int iuse::crowbar( player *p, item *it, bool, const tripoint &pos ) get_event_bus().send( p->getID() ); sounds::sound( p->pos(), 40, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment", "alarm" ); - if( !g->timed_events.queued( timed_event_type::WANTED ) ) { - g->timed_events.add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, - p->global_sm_location() ); + if( !get_timed_events().queued( timed_event_type::WANTED ) ) { + get_timed_events().add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, + p->global_sm_location() ); } } } else { @@ -5554,7 +5554,7 @@ int iuse::artifact( player *p, item *it, bool, const tripoint & ) case AEA_LIGHT: p->add_msg_if_player( _( "The %s glows brightly!" ), it->tname() ); - g->timed_events.add( timed_event_type::ARTIFACT_LIGHT, calendar::turn + 3_minutes ); + get_timed_events().add( timed_event_type::ARTIFACT_LIGHT, calendar::turn + 3_minutes ); break; case AEA_GROWTH: { @@ -5633,7 +5633,7 @@ int iuse::artifact( player *p, item *it, bool, const tripoint & ) case AEA_DIM: p->add_msg_if_player( _( "The sky starts to dim." ) ); - g->timed_events.add( timed_event_type::DIM, calendar::turn + 5_minutes ); + get_timed_events().add( timed_event_type::DIM, calendar::turn + 5_minutes ); break; case AEA_FLASH: diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index 6116154f6ff24..67201ecc00dec 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -845,7 +845,7 @@ void spell_effect::timed_event( const spell &sp, Creature &caster, const tripoin } sp.make_sound( caster.pos() ); - g->timed_events.add( spell_event, calendar::turn + sp.duration_turns() ); + get_timed_events().add( spell_event, calendar::turn + sp.duration_turns() ); } static bool is_summon_friendly( const spell &sp ) diff --git a/src/main_menu.cpp b/src/main_menu.cpp index 2a85ea8f4a641..65012aff3301b 100644 --- a/src/main_menu.cpp +++ b/src/main_menu.cpp @@ -977,7 +977,7 @@ bool main_menu::new_character_tab() } // end while if( start ) { - add_msg( g->scen->description( player_character.male ) ); + add_msg( get_scenario()->description( player_character.male ) ); world_generator->last_world_name = world_generator->active_world->world_name; world_generator->last_character_name = player_character.name; diff --git a/src/map.cpp b/src/map.cpp index 050c15e492168..f4493f51f6792 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2588,7 +2588,7 @@ void map::decay_fields_and_scent( const time_duration &amount ) // TODO: Make this happen on all z-levels // Decay scent separately, so that later we can use field count to skip empty submaps - g->scent.decay(); + get_scent().decay(); // Coordinate code copied from lightmap calculations // TODO: Z @@ -3095,7 +3095,7 @@ void map::bash_ter_furn( const tripoint &p, bash_params ¶ms ) } // TODO: what if silent is true? - if( has_flag( "ALARMED", p ) && !g->timed_events.queued( timed_event_type::WANTED ) ) { + if( has_flag( "ALARMED", p ) && !get_timed_events().queued( timed_event_type::WANTED ) ) { sounds::sound( p, 40, sounds::sound_t::alarm, _( "an alarm go off!" ), false, "environment", "alarm" ); Character &player_character = get_player_character(); @@ -3103,8 +3103,8 @@ void map::bash_ter_furn( const tripoint &p, bash_params ¶ms ) if( rl_dist( player_character.pos(), p ) <= 3 ) { get_event_bus().send( player_character.getID() ); const point abs = ms_to_sm_copy( getabs( p.xy() ) ); - g->timed_events.add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, - tripoint( abs, p.z ) ); + get_timed_events().add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, + tripoint( abs, p.z ) ); } } @@ -3517,11 +3517,11 @@ void map::shoot( const tripoint &p, projectile &proj, const bool hit_items ) float dam = initial_damage; const auto &ammo_effects = proj.proj_effects; - if( has_flag( "ALARMED", p ) && !g->timed_events.queued( timed_event_type::WANTED ) ) { + if( has_flag( "ALARMED", p ) && !get_timed_events().queued( timed_event_type::WANTED ) ) { sounds::sound( p, 30, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment", "alarm" ); const tripoint abs = ms_to_sm_copy( getabs( p ) ); - g->timed_events.add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, abs ); + get_timed_events().add( timed_event_type::WANTED, calendar::turn + 30_minutes, 0, abs ); } const bool inc = ammo_effects.count( "INCENDIARY" ); diff --git a/src/map_field.cpp b/src/map_field.cpp index 6664b5e5dfda5..b42b2fbebe2b7 100644 --- a/src/map_field.cpp +++ b/src/map_field.cpp @@ -388,7 +388,7 @@ If you need to insert a new field behavior per unit time add a case statement in bool map::process_fields_in_submap( submap *const current_submap, const tripoint &submap ) { - scent_block sblk( submap, g->scent ); + scent_block sblk( submap, get_scent() ); // This should be true only when the field changes transparency // More correctly: not just when the field is opaque, but when it changes state diff --git a/src/memorial_logger.cpp b/src/memorial_logger.cpp index 9ed787cd8cf53..0b3a6d04f1153 100644 --- a/src/memorial_logger.cpp +++ b/src/memorial_logger.cpp @@ -429,7 +429,7 @@ void memorial_logger::write_json_memorial( std::ostream &memorial_file ) const jsout.start_object(); jsout.member( "memorial_version", 0 ); jsout.member( "log", log ); - jsout.member( "achievements", g->achievements() ); + jsout.member( "achievements", get_achievements() ); jsout.member( "stats", get_stats() ); std::map, cata_variant> scores; diff --git a/src/memorial_logger.h b/src/memorial_logger.h index c0657124f1c6e..2536a057e07d5 100644 --- a/src/memorial_logger.h +++ b/src/memorial_logger.h @@ -75,4 +75,6 @@ class memorial_logger : public event_subscriber std::vector log; }; +memorial_logger &get_memorial(); + #endif // CATA_SRC_MEMORIAL_LOGGER_H diff --git a/src/monattack.cpp b/src/monattack.cpp index 09bded69be960..8cd7ac21fe07a 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -2018,7 +2018,7 @@ bool mattack::fungus_fortify( monster *z ) player_character.set_mutation( trait_THRESH_MARLOSS ); here.ter_set( player_character.pos(), t_marloss ); // We only show you the door. You walk through it on your own. - g->memorial().add( + get_memorial().add( pgettext( "memorial_male", "Was shown to the Marloss Gateway." ), pgettext( "memorial_female", "Was shown to the Marloss Gateway." ) ); add_msg( m_good, @@ -3327,8 +3327,9 @@ bool mattack::photograph( monster *z ) } const SpeechBubble &speech = get_speech( z->type->id.str() ); sounds::sound( z->pos(), speech.volume, sounds::sound_t::alert, speech.text.translated() ); - g->timed_events.add( timed_event_type::ROBOT_ATTACK, calendar::turn + rng( 15_turns, 30_turns ), 0, - player_character.global_sm_location() ); + get_timed_events().add( timed_event_type::ROBOT_ATTACK, calendar::turn + rng( 15_turns, 30_turns ), + 0, + player_character.global_sm_location() ); return true; } diff --git a/src/mondeath.cpp b/src/mondeath.cpp index a5b1e24074df3..4662693000d8f 100644 --- a/src/mondeath.cpp +++ b/src/mondeath.cpp @@ -361,7 +361,7 @@ void mdeath::triffid_heart( monster &z ) if( get_player_character().sees( z ) ) { add_msg( m_warning, _( "The surrounding roots begin to crack and crumble." ) ); } - g->timed_events.add( timed_event_type::ROOTS_DIE, calendar::turn + 10_minutes ); + get_timed_events().add( timed_event_type::ROOTS_DIE, calendar::turn + 10_minutes ); } void mdeath::fungus( monster &z ) diff --git a/src/monmove.cpp b/src/monmove.cpp index c7b5f7c7cffcd..43f6940624364 100644 --- a/src/monmove.cpp +++ b/src/monmove.cpp @@ -1148,19 +1148,19 @@ tripoint monster::scent_move() Character &player_character = get_player_character(); const bool fleeing = is_fleeing( player_character ); if( fleeing ) { - bestsmell = g->scent.get( pos() ); + bestsmell = get_scent().get( pos() ); } tripoint next( -1, -1, posz() ); - if( ( !fleeing && g->scent.get( pos() ) > smell_threshold ) || + if( ( !fleeing && get_scent().get( pos() ) > smell_threshold ) || ( fleeing && bestsmell == 0 ) ) { return next; } const bool can_bash = bash_skill() > 0; map &here = get_map(); for( const auto &dest : here.points_in_radius( pos(), 1, SCENT_MAP_Z_REACH ) ) { - int smell = g->scent.get( dest ); - const scenttype_id &type_scent = g->scent.get_type( dest ); + int smell = get_scent().get( dest ); + const scenttype_id &type_scent = get_scent().get_type( dest ); bool right_scent = false; // is the monster tracking this scent @@ -1960,8 +1960,8 @@ bool monster::will_reach( const point &p ) return false; } - if( has_flag( MF_SMELLS ) && g->scent.get( pos() ) > 0 && - g->scent.get( { p, posz() } ) > g->scent.get( pos() ) ) { + if( has_flag( MF_SMELLS ) && get_scent().get( pos() ) > 0 && + get_scent().get( { p, posz() } ) > get_scent().get( pos() ) ) { return true; } diff --git a/src/mutation.cpp b/src/mutation.cpp index 9045b2a456ce3..b8a9c87726cf8 100644 --- a/src/mutation.cpp +++ b/src/mutation.cpp @@ -1434,7 +1434,7 @@ static mutagen_rejection try_reject_mutagen( Character &guy, const item &it, boo guy.add_msg_if_player( m_good, _( "We decontaminate it with spores." ) ); get_map().ter_set( guy.pos(), t_fungus ); if( guy.is_avatar() ) { - g->memorial().add( + get_memorial().add( pgettext( "memorial_male", "Destroyed a harmful invader." ), pgettext( "memorial_female", "Destroyed a harmful invader." ) ); } @@ -1465,7 +1465,7 @@ static mutagen_rejection try_reject_mutagen( Character &guy, const item &it, boo _( "It was probably that marloss -- how did you know to call it \"marloss\" anyway?" ) ); guy.add_msg_if_player( m_warning, _( "Best to stay clear of that alien crap in future." ) ); if( guy.is_avatar() ) { - g->memorial().add( + get_memorial().add( pgettext( "memorial_male", "Burned out a particularly nasty fungal infestation." ), pgettext( "memorial_female", @@ -1476,7 +1476,7 @@ static mutagen_rejection try_reject_mutagen( Character &guy, const item &it, boo _( "That was some toxic %s! Let's stick with Marloss next time, that's safe." ), it.tname() ); if( guy.is_avatar() ) { - g->memorial().add( + get_memorial().add( pgettext( "memorial_male", "Suffered a toxic marloss/mutagen reaction." ), pgettext( "memorial_female", "Suffered a toxic marloss/mutagen reaction." ) ); } diff --git a/src/newcharacter.cpp b/src/newcharacter.cpp index b384a66abd36f..753eccd22eaa8 100644 --- a/src/newcharacter.cpp +++ b/src/newcharacter.cpp @@ -24,7 +24,6 @@ #include "character_martial_arts.h" #include "color.h" #include "cursesdef.h" -#include "game.h" #include "game_constants.h" #include "ime.h" #include "input.h" @@ -199,13 +198,13 @@ void avatar::randomize( const bool random_scenario, points_left &points, bool pl scenarios.emplace_back( &scen ); } } - g->scen = random_entry( scenarios ); + set_scenario( random_entry( scenarios ) ); } else if( !cities_enabled ) { static const string_id wilderness_only_scenario( "wilderness" ); - g->scen = &wilderness_only_scenario.obj(); + set_scenario( &wilderness_only_scenario.obj() ); } - prof = g->scen->weighted_random_profession(); + prof = get_scenario()->weighted_random_profession(); random_start_location = true; str_max = rng( 6, HIGH_STAT - 2 ); @@ -213,7 +212,7 @@ void avatar::randomize( const bool random_scenario, points_left &points, bool pl int_max = rng( 6, HIGH_STAT - 2 ); per_max = rng( 6, HIGH_STAT - 2 ); points.stat_points = points.stat_points - str_max - dex_max - int_max - per_max; - points.skill_points = points.skill_points - prof->point_cost() - g->scen->point_cost(); + points.skill_points = points.skill_points - prof->point_cost() - get_scenario()->point_cost(); // The default for each stat is 8, and that default does not cost any points. // Values below give points back, values above require points. The line above has removed // to many points, therefore they are added back. @@ -408,7 +407,7 @@ bool avatar::create( character_type type, const std::string &tempname ) weapon = item(); prof = profession::generic(); - g->scen = scenario::generic(); + set_scenario( scenario::generic() ); const bool interactive = type != character_type::NOW && type != character_type::FULL_RANDOM; @@ -570,8 +569,8 @@ bool avatar::create( character_type type, const std::string &tempname ) starting_pets.push_back( elem ); } - if( g->scen->vehicle() != vproto_id::NULL_ID() ) { - starting_vehicle = g->scen->vehicle(); + if( get_scenario()->vehicle() != vproto_id::NULL_ID() ) { + starting_vehicle = get_scenario()->vehicle(); } else { starting_vehicle = prof->vehicle(); } @@ -1022,7 +1021,7 @@ tab_direction set_traits( avatar &u, points_left &points ) continue; } - const std::set scentraits = g->scen->get_locked_traits(); + const std::set scentraits = get_scenario()->get_locked_traits(); const bool is_scentrait = std::find( scentraits.begin(), scentraits.end(), traits_iter.id ) != scentraits.end(); @@ -1032,7 +1031,7 @@ tab_direction set_traits( avatar &u, points_left &points ) traits_iter.id ) != proftraits.end(); // We show all starting traits, even if we can't pick them, to keep the interface consistent. - if( traits_iter.startingtrait || g->scen->traitquery( traits_iter.id ) || is_proftrait ) { + if( traits_iter.startingtrait || get_scenario()->traitquery( traits_iter.id ) || is_proftrait ) { if( traits_iter.points > 0 ) { vStartingTraits[0].push_back( traits_iter.id ); @@ -1191,7 +1190,7 @@ tab_direction set_traits( avatar &u, points_left &points ) cLine = hi_on; } } else { - if( u.has_conflicting_trait( cur_trait ) || g->scen->is_forbidden_trait( cur_trait ) ) { + if( u.has_conflicting_trait( cur_trait ) || get_scenario()->is_forbidden_trait( cur_trait ) ) { cLine = c_dark_gray; } else if( u.has_trait( cur_trait ) ) { @@ -1201,7 +1200,8 @@ tab_direction set_traits( avatar &u, points_left &points ) } else if( u.has_trait( cur_trait ) ) { cLine = col_on_pas; - } else if( u.has_conflicting_trait( cur_trait ) || g->scen->is_forbidden_trait( cur_trait ) ) { + } else if( u.has_conflicting_trait( cur_trait ) || + get_scenario()->is_forbidden_trait( cur_trait ) ) { cLine = c_light_gray; } @@ -1255,10 +1255,10 @@ tab_direction set_traits( avatar &u, points_left &points ) inc_type = -1; - if( g->scen->is_locked_trait( cur_trait ) ) { + if( get_scenario()->is_locked_trait( cur_trait ) ) { inc_type = 0; popup( _( "Your scenario of %s prevents you from removing this trait." ), - g->scen->gender_appropriate_name( u.male ) ); + get_scenario()->gender_appropriate_name( u.male ) ); } else if( u.prof->is_locked_trait( cur_trait ) ) { inc_type = 0; popup( _( "Your profession of %s prevents you from removing this trait." ), @@ -1266,7 +1266,7 @@ tab_direction set_traits( avatar &u, points_left &points ) } } else if( u.has_conflicting_trait( cur_trait ) ) { popup( _( "You already picked a conflicting trait!" ) ); - } else if( g->scen->is_forbidden_trait( cur_trait ) ) { + } else if( get_scenario()->is_forbidden_trait( cur_trait ) ) { popup( _( "The scenario you picked prevents you from taking this trait!" ) ); } else if( u.prof->is_forbidden_trait( cur_trait ) ) { popup( _( "Your profession of %s prevents you from taking this trait." ), @@ -1621,7 +1621,7 @@ tab_direction set_profession( avatar &u, points_left &points, do { if( recalc_profs ) { - sorted_profs = g->scen->permitted_professions(); + sorted_profs = get_scenario()->permitted_professions(); const auto new_end = std::remove_if( sorted_profs.begin(), sorted_profs.end(), [&]( const string_id &arg ) { return !lcmatch( arg->gender_appropriate_name( u.male ), filterstring ); @@ -2038,8 +2038,8 @@ tab_direction set_scenario( avatar &u, points_left &points, werase( w_description ); if( cur_id_is_valid ) { - int netPointCost = sorted_scens[cur_id]->point_cost() - g->scen->point_cost(); - bool can_pick = sorted_scens[cur_id]->can_pick( *g->scen, points.skill_points_left() ); + int netPointCost = sorted_scens[cur_id]->point_cost() - get_scenario()->point_cost(); + bool can_pick = sorted_scens[cur_id]->can_pick( *get_scenario(), points.skill_points_left() ); const std::string clear_line( getmaxx( w_description ), ' ' ); // Clear the bottom of the screen and header. @@ -2094,7 +2094,7 @@ tab_direction set_scenario( avatar &u, points_left &points, mvwprintz( w, point( 2, 5 + i - iStartPos ), c_light_gray, " " ); nc_color col; - if( g->scen != sorted_scens[i] ) { + if( get_scenario() != sorted_scens[i] ) { if( cur_id_is_valid && sorted_scens[i] == sorted_scens[cur_id] && sorted_scens[i]->has_flag( "CITY_START" ) && !scenario_sorter.cities_enabled ) { col = h_dark_gray; @@ -2246,7 +2246,7 @@ tab_direction set_scenario( avatar &u, points_left &points, std::stable_sort( sorted_scens.begin(), sorted_scens.end(), scenario_sorter ); // If city size is 0 but the current scenario requires cities reset the scenario - if( !scenario_sorter.cities_enabled && g->scen->has_flag( "CITY_START" ) ) { + if( !scenario_sorter.cities_enabled && get_scenario()->has_flag( "CITY_START" ) ) { reset_scenario( u, sorted_scens[0] ); points.init_from_options(); points.skill_points -= sorted_scens[cur_id]->point_cost(); @@ -2254,7 +2254,7 @@ tab_direction set_scenario( avatar &u, points_left &points, // Select the current scenario, if possible. for( int i = 0; i < scens_length; ++i ) { - if( sorted_scens[i]->ident() == g->scen->ident() ) { + if( sorted_scens[i]->ident() == get_scenario()->ident() ) { cur_id = i; break; } @@ -2413,12 +2413,12 @@ tab_direction set_description( avatar &you, const bool allow_reroll, const std::string random_start_location_text = string_format( ngettext( "* Random location * (%d variant)", "* Random location * (%d variants)", - g->scen->start_location_targets_count() ), g->scen->start_location_targets_count() ); + get_scenario()->start_location_targets_count() ), get_scenario()->start_location_targets_count() ); uilist_entry entry_random_start_location( RANDOM_START_LOC_ENTRY, true, -1, random_start_location_text ); select_location.entries.emplace_back( entry_random_start_location ); for( const auto &loc : start_locations::get_all() ) { - if( g->scen->allowed_start( loc.id ) ) { + if( get_scenario()->allowed_start( loc.id ) ) { uilist_entry entry( loc.id.get_cid().to_i(), true, -1, string_format( ngettext( "%s (%d variant)", "%s (%d variants)", @@ -2627,7 +2627,7 @@ tab_direction set_description( avatar &you, const bool allow_reroll, werase( w_vehicle ); mvwprintz( w_vehicle, point_zero, c_light_gray, _( "Starting Vehicle: " ) ); - const vproto_id scen_veh = g->scen->vehicle(); + const vproto_id scen_veh = get_scenario()->vehicle(); const vproto_id prof_veh = you.prof->vehicle(); if( scen_veh ) { wprintz( w_vehicle, c_light_green, scen_veh->name ); @@ -2638,7 +2638,7 @@ tab_direction set_description( avatar &you, const bool allow_reroll, werase( w_scenario ); mvwprintz( w_scenario, point_zero, COL_HEADER, _( "Scenario: " ) ); - wprintz( w_scenario, c_light_gray, g->scen->gender_appropriate_name( you.male ) ); + wprintz( w_scenario, c_light_gray, get_scenario()->gender_appropriate_name( you.male ) ); wnoutrefresh( w_scenario ); werase( w_profession ); @@ -2945,7 +2945,7 @@ void Character::add_traits( points_left &points ) points.trait_points += tr->points; } } - for( const trait_id &tr : g->scen->get_locked_traits() ) { + for( const trait_id &tr : get_scenario()->get_locked_traits() ) { if( !has_trait( tr ) ) { toggle_trait( tr ); } @@ -2957,7 +2957,7 @@ trait_id Character::random_good_trait() std::vector vTraitsGood; for( auto &traits_iter : mutation_branch::get_all() ) { - if( traits_iter.points >= 0 && g->scen->traitquery( traits_iter.id ) ) { + if( traits_iter.points >= 0 && get_scenario()->traitquery( traits_iter.id ) ) { vTraitsGood.push_back( traits_iter.id ); } } @@ -2970,7 +2970,7 @@ trait_id Character::random_bad_trait() std::vector vTraitsBad; for( auto &traits_iter : mutation_branch::get_all() ) { - if( traits_iter.points < 0 && g->scen->traitquery( traits_iter.id ) ) { + if( traits_iter.points < 0 && get_scenario()->traitquery( traits_iter.id ) ) { vTraitsBad.push_back( traits_iter.id ); } } @@ -3072,7 +3072,7 @@ bool avatar::load_template( const std::string &template_name, points_left &point random_start_location = jobj.get_bool( "random_start_location", true ); const std::string jobj_start_location = jobj.get_string( "start_location", "" ); - // g->scen->allowed_start( loc.ident() ) is checked once scenario loads in avatar::load() + // get_scenario()->allowed_start( loc.ident() ) is checked once scenario loads in avatar::load() for( const auto &loc : start_locations::get_all() ) { if( loc.id.str() == jobj_start_location ) { random_start_location = false; @@ -3111,7 +3111,7 @@ void reset_scenario( avatar &u, const scenario *scen ) u.dex_max = 8; u.int_max = 8; u.per_max = 8; - g->scen = scen; + set_scenario( scen ); u.prof = &default_prof.obj(); for( auto &t : u.get_mutations() ) { if( t.obj().hp_modifier != 0 ) { diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 0c6596740dfa4..0b26d0019ebe2 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -1160,8 +1160,8 @@ void avatar::store( JsonOut &json ) const if( prof != nullptr ) { json.member( "profession", prof->ident() ); } - if( g->scen != nullptr ) { - json.member( "scenario", g->scen->ident() ); + if( get_scenario() != nullptr ) { + json.member( "scenario", get_scenario()->ident() ); } // someday, npcs may drive json.member( "controlling_vehicle", controlling_vehicle ); @@ -1264,10 +1264,10 @@ void avatar::load( const JsonObject &data ) drench_mut_calc(); std::string scen_ident = "(null)"; if( data.read( "scenario", scen_ident ) && string_id( scen_ident ).is_valid() ) { - g->scen = &string_id( scen_ident ).obj(); + set_scenario( &string_id( scen_ident ).obj() ); - if( !g->scen->allowed_start( start_location ) ) { - start_location = g->scen->random_start_location(); + if( !get_scenario()->allowed_start( start_location ) ) { + start_location = get_scenario()->random_start_location(); } } else { const scenario *generic_scenario = scenario::generic(); @@ -1276,7 +1276,7 @@ void avatar::load( const JsonObject &data ) debugmsg( "Tried to use non-existent scenario '%s'. Setting to generic '%s'.", scen_ident.c_str(), generic_scenario->ident().c_str() ); } - g->scen = generic_scenario; + set_scenario( generic_scenario ); } data.read( "learned_recipes", *learned_recipes ); diff --git a/src/scent_map.h b/src/scent_map.h index e370b8e450db6..f9f9e2dbdc1bc 100644 --- a/src/scent_map.h +++ b/src/scent_map.h @@ -83,4 +83,6 @@ class scent_map bool inbounds( const point &p ) const; }; +scent_map &get_scent(); + #endif // CATA_SRC_SCENT_MAP_H diff --git a/src/timed_event.cpp b/src/timed_event.cpp index 46dfafca2ddbb..a3277b1957180 100644 --- a/src/timed_event.cpp +++ b/src/timed_event.cpp @@ -73,7 +73,7 @@ void timed_event::actualize() if( g->get_levz() >= 0 ) { return; } - g->memorial().add( + get_memorial().add( pgettext( "memorial_male", "Drew the attention of more dark wyrms!" ), pgettext( "memorial_female", "Drew the attention of more dark wyrms!" ) ); int num_wyrms = rng( 1, 4 ); @@ -94,8 +94,8 @@ void timed_event::actualize() } // They just keep coming! if( !one_in( 25 ) ) { - g->timed_events.add( timed_event_type::SPAWN_WYRMS, - calendar::turn + rng( 1_minutes, 3_minutes ) ); + get_timed_events().add( timed_event_type::SPAWN_WYRMS, + calendar::turn + rng( 1_minutes, 3_minutes ) ); } } break; @@ -208,13 +208,13 @@ void timed_event::actualize() player_character.pos() ) ) { if( flood_buf[player_character.posx()][player_character.posy()] == t_water_sh ) { add_msg( m_warning, _( "Water quickly floods up to your knees." ) ); - g->memorial().add( + get_memorial().add( pgettext( "memorial_male", "Water level reached knees." ), pgettext( "memorial_female", "Water level reached knees." ) ); } else { // Must be deep water! add_msg( m_warning, _( "Water fills nearly to the ceiling!" ) ); - g->memorial().add( + get_memorial().add( pgettext( "memorial_male", "Water level reached the ceiling." ), pgettext( "memorial_female", "Water level reached the ceiling." ) ); avatar_action::swim( here, player_character, player_character.pos() ); @@ -224,8 +224,8 @@ void timed_event::actualize() for( const tripoint &p : here.points_on_zlevel() ) { here.ter_set( p, flood_buf[p.x][p.y] ); } - g->timed_events.add( timed_event_type::TEMPLE_FLOOD, - calendar::turn + rng( 2_turns, 3_turns ) ); + get_timed_events().add( timed_event_type::TEMPLE_FLOOD, + calendar::turn + rng( 2_turns, 3_turns ) ); } break; diff --git a/src/timed_event.h b/src/timed_event.h index bb03edf019566..d408fa06477c2 100644 --- a/src/timed_event.h +++ b/src/timed_event.h @@ -66,4 +66,6 @@ class timed_event_manager void process(); }; +timed_event_manager &get_timed_events(); + #endif // CATA_SRC_TIMED_EVENT_H diff --git a/src/trapfunc.cpp b/src/trapfunc.cpp index fb1144d3d8bf5..4c5e8436f1dab 100644 --- a/src/trapfunc.cpp +++ b/src/trapfunc.cpp @@ -1255,7 +1255,7 @@ bool trapfunc::temple_flood( const tripoint &p, Creature *c, item * ) } } } - g->timed_events.add( timed_event_type::TEMPLE_FLOOD, calendar::turn + 3_turns ); + get_timed_events().add( timed_event_type::TEMPLE_FLOOD, calendar::turn + 3_turns ); return true; } return false; diff --git a/tests/memorial_test.cpp b/tests/memorial_test.cpp index 22783d4213d7b..2fd80d5d1a78d 100644 --- a/tests/memorial_test.cpp +++ b/tests/memorial_test.cpp @@ -10,7 +10,6 @@ #include "debug_menu.h" #include "event.h" #include "filesystem.h" -#include "game.h" #include "memorial_logger.h" #include "mutation.h" #include "output.h" @@ -53,7 +52,7 @@ void check_memorial( memorial_logger &m, event_bus &b, const std::string &ref, A TEST_CASE( "memorials", "[memorial]" ) { - memorial_logger &m = g->memorial(); + memorial_logger &m = get_memorial(); m.clear(); clear_avatar(); diff --git a/tests/stats_tracker_test.cpp b/tests/stats_tracker_test.cpp index 2266f9fefa2ad..cd88cdb03f695 100644 --- a/tests/stats_tracker_test.cpp +++ b/tests/stats_tracker_test.cpp @@ -10,7 +10,6 @@ #include "event.h" #include "event_bus.h" #include "event_statistics.h" -#include "game.h" #include "optional.h" #include "stats_tracker.h" #include "string_id.h" @@ -868,7 +867,7 @@ struct test_subscriber : public event_subscriber { TEST_CASE( "achievements_tracker_in_game", "[stats]" ) { - g->achievements().clear(); + get_achievements().clear(); test_subscriber sub; get_event_bus().subscribe( &sub ); From b8080baa66fe42fc65022012a6199646edf0feb6 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Mon, 20 Jul 2020 00:24:50 -0700 Subject: [PATCH 144/151] Cache relative encumbrance (#40745) * Add an on_contents_changed method to item_location * Adjust best_pocket() to return an item_location pointing at the target item * Cache the relative encumbrance level for each item. --- src/character.cpp | 43 +++++++++++++++++++++++-------------------- src/character.h | 2 +- src/item.cpp | 19 ++++++++++++------- src/item.h | 3 ++- src/item_contents.cpp | 23 ++++++++++++----------- src/item_contents.h | 5 +++-- src/item_location.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/item_location.h | 3 +++ 8 files changed, 95 insertions(+), 42 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index 78da70b9a9ba9..ec0a007198fb5 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -966,7 +966,7 @@ bool Character::is_on_ground() const bool Character::can_stash( const item &it ) { - return best_pocket( it, nullptr ) != nullptr; + return best_pocket( it, nullptr ).second != nullptr; } void Character::cancel_stashed_activity() @@ -2439,25 +2439,22 @@ std::vector Character::nearby( const return res; } -item_pocket *Character::best_pocket( const item &it, const item *avoid ) +std::pair Character::best_pocket( const item &it, const item *avoid ) { - item_pocket *ret = nullptr; + item_location weapon_loc( *this, &weapon ); + std::pair ret = std::make_pair( item_location(), nullptr ); if( &weapon != &it && &weapon != avoid ) { - ret = weapon.best_pocket( it ); + ret = weapon.best_pocket( it, weapon_loc ); } for( item &worn_it : worn ) { if( &worn_it == &it || &worn_it == avoid ) { continue; } - item_pocket *internal_pocket = worn_it.best_pocket( it ); - if( internal_pocket != nullptr ) { - if( ret == nullptr ) { - ret = internal_pocket; - } else { - if( ret->better_pocket( *internal_pocket, it ) ) { - ret = internal_pocket; - } - } + item_location loc( *this, &worn_it ); + std::pair internal_pocket = worn_it.best_pocket( it, loc ); + if( internal_pocket.second != nullptr && + ( ret.second == nullptr || ret.second->better_pocket( *internal_pocket.second, it ) ) ) { + ret = internal_pocket; } } return ret; @@ -2478,17 +2475,20 @@ item *Character::try_add( item it, const item *avoid, const bool allow_wield ) break; } } - item_pocket *pocket = best_pocket( it, avoid ); + std::pair pocket = best_pocket( it, avoid ); item *ret = nullptr; - if( pocket == nullptr ) { + if( pocket.second == nullptr ) { if( has_weapon() ) { if( avoid != nullptr && is_wielding( *avoid ) ) { return nullptr; } - item_pocket *weapon_pocket = weapon.best_pocket( it ); - if( weapon_pocket != nullptr ) { - weapon_pocket->add( it ); - ret = &weapon_pocket->back(); + item_location weapon_location( *this, &weapon ); + std::pair weapon_pocket = weapon.best_pocket( it, weapon_location ); + if( weapon_pocket.second != nullptr ) { + weapon_pocket.second->add( it ); + ret = &weapon_pocket.second->back(); + weapon_pocket.first.on_contents_changed(); + weapon_pocket.second->on_contents_changed(); return ret; } else { return nullptr; @@ -2502,7 +2502,10 @@ item *Character::try_add( item it, const item *avoid, const bool allow_wield ) } } else { // this will set ret to either it, or to stack where it was placed - pocket->add( it, &ret ); + pocket.second->add( it, &ret ); + pocket.first.on_contents_changed(); + pocket.second->on_contents_changed(); + ret = &pocket.second->back(); } if( keep_invlet ) { diff --git a/src/character.h b/src/character.h index 57d24a0a6c29a..b2e6af506ffc8 100644 --- a/src/character.h +++ b/src/character.h @@ -942,7 +942,7 @@ class Character : public Creature, public visitable * What is the best pocket to put @it into? * the pockets in @avoid do not count */ - item_pocket *best_pocket( const item &it, const item *avoid ); + std::pair best_pocket( const item &it, const item *avoid ); protected: void do_skill_rust(); diff --git a/src/item.cpp b/src/item.cpp index 2f16b27b03045..0cd08812e311a 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -4433,6 +4433,7 @@ void item::on_pickup( Character &p ) void item::on_contents_changed() { contents.update_open_pockets(); + cached_relative_encumbrance.reset(); encumbrance_update_ = true; } @@ -5702,11 +5703,13 @@ int item::get_encumber( const Character &p, const bodypart_id &bodypart, } int encumber = 0; - + float relative_encumbrance = 1.0; // Additional encumbrance from non-rigid pockets - float relative_encumbrance = 1; if( !( flags & encumber_flags::assume_full ) ) { - relative_encumbrance = contents.relative_encumbrance(); + if( !cached_relative_encumbrance ) { + cached_relative_encumbrance = contents.relative_encumbrance(); + } + relative_encumbrance = *cached_relative_encumbrance; } if( cata::optional portion_data = portion_for_bodypart( bodypart ) ) { @@ -6957,9 +6960,10 @@ bool item::can_contain_partial( const item &it ) const return can_contain( i_copy ); } -item_pocket *item::best_pocket( const item &it ) +std::pair item::best_pocket( const item &it, item_location &parent ) { - return contents.best_pocket( it, false ); + item_location nested_location( parent, this ); + return contents.best_pocket( it, nested_location, false ); } bool item::spill_contents( Character &c ) @@ -8480,7 +8484,8 @@ int item::fill_with( const itype &contained, const int amount ) contained_item.charges = 1; } - item_pocket *pocket = best_pocket( contained_item ); + item_location loc; + item_pocket *pocket = best_pocket( contained_item, loc ).second; if( pocket == nullptr ) { debugmsg( "tried to put an item (%s) in a container (%s) that cannot contain it", contained_item.typeId().str(), typeId().str() ); @@ -8494,7 +8499,7 @@ int item::fill_with( const itype &contained, const int amount ) } num_contained++; if( !pocket->can_contain( contained_item ).success() ) { - pocket = best_pocket( contained_item ); + pocket = best_pocket( contained_item, loc ).second; } } return num_contained; diff --git a/src/item.h b/src/item.h index a773124ee1417..d0dddf55ba29d 100644 --- a/src/item.h +++ b/src/item.h @@ -1230,7 +1230,7 @@ class item : public visitable bool can_contain( const itype &tp ) const; bool can_contain_partial( const item &it ) const; /*@}*/ - item_pocket *best_pocket( const item &it ); + std::pair best_pocket( const item &it, item_location &parent ); /** * Is it ever possible to reload this item? @@ -2270,6 +2270,7 @@ class item : public visitable mutable faction_id old_owner = faction_id::NULL_ID(); int damage_ = 0; light_emission light = nolight; + mutable cata::optional cached_relative_encumbrance; public: char invlet = 0; // Inventory letter diff --git a/src/item_contents.cpp b/src/item_contents.cpp index 970e0cd309f12..dfc4e5a352dc8 100644 --- a/src/item_contents.cpp +++ b/src/item_contents.cpp @@ -451,12 +451,14 @@ void item_contents::fill_with( const item &contained ) } } -item_pocket *item_contents::best_pocket( const item &it, bool nested ) +std::pair item_contents::best_pocket( const item &it, + item_location &parent, bool nested ) { if( !can_contain( it ).success() ) { - return nullptr; + return { item_location(), nullptr }; } - item_pocket *ret = nullptr; + std::pair ret; + ret.second = nullptr; for( item_pocket &pocket : contents ) { if( !pocket.is_type( item_pocket::pocket_type::CONTAINER ) ) { // best pocket is for picking stuff up. @@ -471,15 +473,14 @@ item_pocket *item_contents::best_pocket( const item &it, bool nested ) // that needs to be something a player explicitly does continue; } - if( ret == nullptr ) { - if( pocket.can_contain( it ).success() ) { - ret = &pocket; - } - } else if( pocket.can_contain( it ).success() && ret->better_pocket( pocket, it ) ) { - ret = &pocket; + if( ( ret.second == nullptr && pocket.can_contain( it ).success() ) || + ( pocket.can_contain( it ).success() && ret.second->better_pocket( pocket, it ) ) ) { + ret.first = parent; + ret.second = &pocket; for( item *contained : all_items_top( item_pocket::pocket_type::CONTAINER ) ) { - item_pocket *internal_pocket = contained->contents.best_pocket( it, nested ); - if( internal_pocket != nullptr && ret->better_pocket( pocket, it ) ) { + std::pair internal_pocket = + contained->contents.best_pocket( it, parent, true ); + if( internal_pocket.second != nullptr && ret.second->better_pocket( pocket, it ) ) { ret = internal_pocket; } } diff --git a/src/item_contents.h b/src/item_contents.h index f32bad219e725..6ee396496a48c 100644 --- a/src/item_contents.h +++ b/src/item_contents.h @@ -39,10 +39,11 @@ class item_contents item_contents( const std::vector &pockets ); /** - * returns a pointer to the best pocket that can contain the item @it + * returns an item_location and pointer to the best pocket that can contain the item @it * only checks CONTAINER pocket type */ - item_pocket *best_pocket( const item &it, bool nested ); + std::pair best_pocket( const item &it, item_location &parent, + bool nested ); ret_val can_contain_rigid( const item &it ) const; ret_val can_contain( const item &it ) const; bool can_contain_liquid( bool held_or_ground ) const; diff --git a/src/item_location.cpp b/src/item_location.cpp index 0474e4034b4ff..8d5d5b719ae2c 100644 --- a/src/item_location.cpp +++ b/src/item_location.cpp @@ -78,6 +78,7 @@ class item_location::impl virtual item_location obtain( Character &, int ) = 0; virtual int obtain_cost( const Character &, int ) const = 0; virtual void remove_item() = 0; + virtual void on_contents_changed() = 0; virtual void serialize( JsonOut &js ) const = 0; virtual item *unpack( int ) const = 0; @@ -143,6 +144,10 @@ class item_location::impl::nowhere : public item_location::impl debugmsg( "invalid use of nowhere item_location" ); } + void on_contents_changed() override { + debugmsg( "invalid use of nowhere item_location" ); + } + item *unpack( int ) const override { return nullptr; } @@ -194,6 +199,7 @@ class item_location::impl::item_on_map : public item_location::impl item_location obtain( Character &ch, int qty ) override { ch.moves -= obtain_cost( ch, qty ); + on_contents_changed(); item obj = target()->split( qty ); if( !obj.is_null() ) { return item_location( ch, &ch.i_add( obj, should_stack ) ); @@ -224,8 +230,13 @@ class item_location::impl::item_on_map : public item_location::impl } void remove_item() override { + on_contents_changed(); cur.remove_item( *what ); } + + void on_contents_changed() override { + target()->on_contents_changed(); + } }; class item_location::impl::item_on_person : public item_location::impl @@ -312,6 +323,7 @@ class item_location::impl::item_on_person : public item_location::impl item_location obtain( Character &ch, int qty ) override { ch.mod_moves( -obtain_cost( ch, qty ) ); + on_contents_changed(); if( &ch.i_at( ch.get_item_position( target() ) ) == target() ) { // item already in target characters inventory at base of stack return item_location( ch, target() ); @@ -359,9 +371,14 @@ class item_location::impl::item_on_person : public item_location::impl if( !ensure_who_unpacked() ) { return; } + on_contents_changed(); who->remove_item( *what ); } + void on_contents_changed() override { + target()->on_contents_changed(); + } + bool valid() const override { ensure_who_unpacked(); ensure_unpacked(); @@ -421,6 +438,7 @@ class item_location::impl::item_on_vehicle : public item_location::impl item_location obtain( Character &ch, int qty ) override { ch.moves -= obtain_cost( ch, qty ); + on_contents_changed(); item obj = target()->split( qty ); if( !obj.is_null() ) { return item_location( ch, &ch.i_add( obj, should_stack ) ); @@ -451,12 +469,17 @@ class item_location::impl::item_on_vehicle : public item_location::impl } void remove_item() override { + on_contents_changed(); item &base = cur.veh.part( cur.part ).base; if( &base == target() ) { cur.veh.remove_part( cur.part ); // vehicle_part::base } else { cur.remove_item( *target() ); // item within CARGO } + } + + void on_contents_changed() override { + target()->on_contents_changed(); cur.veh.invalidate_mass(); } }; @@ -527,12 +550,19 @@ class item_location::impl::item_in_container : public item_location::impl } void remove_item() override { + on_contents_changed(); container->remove_item( *target() ); } + void on_contents_changed() override { + target()->on_contents_changed(); + container->on_contents_changed(); + } + item_location obtain( Character &ch, int qty ) override { ch.mod_moves( -obtain_cost( ch, qty ) ); + on_contents_changed(); item obj = target()->split( qty ); if( !obj.is_null() ) { return item_location( ch, &ch.i_add( obj, should_stack ) ); @@ -734,6 +764,15 @@ void item_location::remove_item() ptr.reset( new impl::nowhere() ); } +void item_location::on_contents_changed() +{ + if( !ptr->valid() ) { + debugmsg( "item location does not point to valid item" ); + return; + } + ptr->on_contents_changed(); +} + item *item_location::get_item() { return ptr->target(); diff --git a/src/item_location.h b/src/item_location.h index c97c868ece86b..1c6033a71b9c0 100644 --- a/src/item_location.h +++ b/src/item_location.h @@ -81,6 +81,9 @@ class item_location * @warning all further operations using this class are invalid */ void remove_item(); + /** Handles updates to the item location, mostly for caching. */ + void on_contents_changed(); + /** Gets the selected item or nullptr */ item *get_item(); const item *get_item() const; From 3346a43f2ef5413b3fba6785cd1adb8594e3060b Mon Sep 17 00:00:00 2001 From: anothersimulacrum <42699974+anothersimulacrum@users.noreply.github.com> Date: Fri, 17 Jul 2020 12:14:09 -0700 Subject: [PATCH 145/151] Provide activity feedback in calorie diary While the calorie diary is useful in diagnosing food consumption problems, it's use is limited by lacking reporting of what the player did to lose the calories that they did. To fix this, add activity tracking to the diary - Show how much time they spent at each level of activity (logged when calories are consumed) Add functions to daily_calories to save and load this calorie data, because the built in json handling cannot serialize a map of floats to ints. Initialize some values in daily calories as well, which I don't think were causing problems, but had potential to. The output formatting is a little gnarly, but I think it's good enough for a debug only display. --- src/avatar.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++-- src/avatar.h | 22 ++++++++++++++++++-- src/character.cpp | 1 + src/character.h | 2 ++ 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/avatar.cpp b/src/avatar.cpp index 8675026dfabc3..391b928bd8611 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -1654,12 +1654,61 @@ void avatar::add_gained_calories( int cal ) calorie_diary.front().gained += cal; } +void avatar::log_activity_level( float level ) +{ + calorie_diary.front().activity_levels[level]++; +} + +static const std::map activity_levels_str = { + { NO_EXERCISE, "NO_EXERCISE" }, + { LIGHT_EXERCISE, "LIGHT_EXERCISE" }, + { MODERATE_EXERCISE, "MODERATE_EXERCISE" }, + { ACTIVE_EXERCISE, "ACTIVE_EXERCISE" }, + { EXTRA_EXERCISE, "EXTRA_EXERCISE" } +}; +void avatar::daily_calories::save_activity( JsonOut &json ) const +{ + json.member( "activity" ); + json.start_object(); + for( const std::pair &level : activity_levels ) { + json.member( activity_levels_str.at( level.first ), level.second ); + } + json.end_object(); +} + +void avatar::daily_calories::read_activity( JsonObject &data ) +{ + JsonObject jo = data.get_object( "activity" ); + for( const std::pair &member : activity_levels_str ) { + int times; + jo.read( member.second, times ); + activity_levels.at( member.first ) = times; + } +} + std::string avatar::total_daily_calories_string() const { - std::string ret = " gained spent total\n"; + std::string ret = + " E: Extra exercise\n A: Active exercise\n" + " M: Moderate exercise\n L: Light exercise\n" + " N: No exercise\n" + " Each number refers to 5 minutes\n" + " gained spent total\n"; int num_day = 1; for( const daily_calories &day : calorie_diary ) { - ret += string_format( "%2d %6d %6d %6d\n", num_day++, day.gained, day.spent, day.total() ); + // Each row is 32 columns long - for the first row, it's + // 5 for the day and the offset from it, + // 18 for the numbers, and 9 for the spacing between them + // For the second, 4 offset + 5 labels + 8 spacing leaves 15 for the levels + std::string activity_str = string_format( "%3dE %3dA %3dM %3dL %3dN", + day.activity_levels.at( EXTRA_EXERCISE ), day.activity_levels.at( ACTIVE_EXERCISE ), + day.activity_levels.at( MODERATE_EXERCISE ), day.activity_levels.at( LIGHT_EXERCISE ), + day.activity_levels.at( NO_EXERCISE ) ); + std::string act_stats = string_format( " %1s %s", colorize( ">", c_light_gray ), + colorize( activity_str, c_yellow ) ); + std::string calorie_stats = string_format( "%2d %6d %6d %6d", num_day++, day.gained, + day.spent, day.total() ); + ret += string_format( "%s\n%s\n", calorie_stats, act_stats ); } return ret; } diff --git a/src/avatar.h b/src/avatar.h index 76a25872284a0..fedab511163ec 100644 --- a/src/avatar.h +++ b/src/avatar.h @@ -230,17 +230,19 @@ class avatar : public player } struct daily_calories { - int spent; - int gained; + int spent = 0; + int gained = 0; int total() const { return gained - spent; } + std::map activity_levels; void serialize( JsonOut &json ) const { json.start_object(); json.member( "spent", spent ); json.member( "gained", gained ); + save_activity( json ); json.end_object(); }; @@ -249,13 +251,29 @@ class avatar : public player data.read( "spent", spent ); data.read( "gained", gained ); + if( data.has_member( "activity" ) ) { + read_activity( data ); + } }; + + daily_calories() { + activity_levels.emplace( NO_EXERCISE, 0 ); + activity_levels.emplace( LIGHT_EXERCISE, 0 ); + activity_levels.emplace( MODERATE_EXERCISE, 0 ); + activity_levels.emplace( ACTIVE_EXERCISE, 0 ); + activity_levels.emplace( EXTRA_EXERCISE, 0 ); + } + + void save_activity( JsonOut &json ) const; + void read_activity( JsonObject &data ); + }; // called once a day; adds a new daily_calories to the // front of the list and pops off the back if there are more than 30 void advance_daily_calories(); void add_spent_calories( int cal ) override; void add_gained_calories( int cal ) override; + void log_activity_level( float level ) override; std::string total_daily_calories_string() const; private: diff --git a/src/character.cpp b/src/character.cpp index ec0a007198fb5..18f88431be7c9 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -4976,6 +4976,7 @@ void Character::update_stomach( const time_point &from, const time_point &to ) // Apply nutrients, unless this is an NPC and NO_NPC_FOOD is enabled. if( !is_npc() || !get_option( "NO_NPC_FOOD" ) ) { mod_stored_kcal( digested_to_body.nutr.kcal ); + log_activity_level( activity_level ); vitamins_mod( digested_to_body.nutr.vitamins, false ); } if( !foodless && rates.hunger > 0.0f ) { diff --git a/src/character.h b/src/character.h index b2e6af506ffc8..78c82d9c980f1 100644 --- a/src/character.h +++ b/src/character.h @@ -1819,6 +1819,8 @@ class Character : public Creature, public visitable virtual void add_spent_calories( int /* cal */ ) {}; // add gained calories to calorie diary (if avatar) virtual void add_gained_calories( int /* gained */ ) {}; + // log the activity level in the calorie diary (if avatar) + virtual void log_activity_level( float /*level*/ ) {}; // Reset age and height to defaults for consistent test results void reset_chargen_attributes(); // age in years, determined at character creation From e28e48a014c98eb41fa0e8b0413eccac390ee54f Mon Sep 17 00:00:00 2001 From: Curtis Merrill Date: Mon, 20 Jul 2020 03:45:56 -0400 Subject: [PATCH 146/151] migrate old artifacts to new (#42137) --- src/game.cpp | 9 --------- src/game.h | 2 -- src/savegame_json.cpp | 31 +++++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 8ea825f04ccee..f88631c123960 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -983,8 +983,6 @@ bool game::cleanup_at_end() // Save the factions', missions and set the NPC's overmap coordinates // Npcs are saved in the overmap. save_factions_missions_npcs(); //missions need to be saved as they are global for all saves. - // save artifacts. - save_artifacts(); // and the overmap, and the local map. save_maps(); //Omap also contains the npcs who need to be saved. @@ -3088,12 +3086,6 @@ bool game::save_factions_missions_npcs() }, _( "factions data" ) ); } -bool game::save_artifacts() -{ - std::string artfilename = PATH_INFO::world_base_save_path() + "/" + SAVE_ARTIFACTS; - return ::save_artifacts( artfilename ); -} - bool game::save_maps() { try { @@ -3172,7 +3164,6 @@ bool game::save() try { if( !save_player_data() || !save_factions_missions_npcs() || - !save_artifacts() || !save_maps() || !get_auto_pickup().save_character() || !get_auto_notes_settings().save() || diff --git a/src/game.h b/src/game.h index 9b69c53353312..61c40fd6b7b61 100644 --- a/src/game.h +++ b/src/game.h @@ -767,8 +767,6 @@ class game void reset_npc_dispositions(); void serialize_master( std::ostream &fout ); // returns false if saving failed for whatever reason - bool save_artifacts(); - // returns false if saving failed for whatever reason bool save_maps(); #if defined(__ANDROID__) void save_shortcuts( std::ostream &fout ); diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 0b26d0019ebe2..43fcb62ea783b 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -2522,10 +2522,41 @@ void item::deserialize( JsonIn &jsin ) } } } + + // Remove after 0.F: artifact migration code + if( typeId().str().substr( 0, 9 ) == "artifact_" ) { + static const relic_procgen_id proc_cult( "cult" ); + relic_procgen_data::generation_rules rules; + rules.max_attributes = 5; + rules.max_negative_power = -1000; + rules.power_level = 2000; + + item_contents temp_migrate( contents ); + + *this = proc_cult->create_item( rules ); + + if( !temp_migrate.empty() ) { + for( const item *it : temp_migrate.all_items_top() ) { + contents.insert_item( *it, item_pocket::pocket_type::MIGRATION ); + } + } + } } void item::serialize( JsonOut &json ) const { + // Remove after 0.F: artifact migration code + if( typeId().str().substr( 0, 9 ) == "artifact_" ) { + static const relic_procgen_id proc_cult( "cult" ); + relic_procgen_data::generation_rules rules; + rules.max_attributes = 5; + rules.max_negative_power = -1000; + rules.power_level = 2000; + + proc_cult->create_item( rules ).serialize( json ); + return; + } + io::JsonObjectOutputArchive archive( json ); const_cast( this )->io( archive ); if( !contents.empty_real() ) { From 3c67e804d7ba0095fc71c09df6abd487ce785b00 Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Mon, 20 Jul 2020 09:27:11 +0100 Subject: [PATCH 147/151] Refactor overmap-scale code to new point types (#41693) Put the new point types through their paces by changing the types for overmap and overmapbuffer, and dealing with all the consequent fallout. Involves more changes than I originally anticipated, but serves as a good demonstration of the new point type features. Fixed some bugs along the way that were discovered by this new point type safety. The ones I remember are: * The evacuation shelter now correctly calculates the distance and direction to the refugee center, previously it was mostly nonsense (this only affects the message it prints out). * Weather conditions for NPC-planted crops are calculated more reasonably. Previously they were passing an overmap location as a map-square location, which could have caused all sorts of strangeness. * Translocators were similarly confusing map_square and overmap_terrain scales, so they might not have been working properly. * Two places were using map::points_in_radius which truncates to the map boundaries, but were using it for overmap-scale points, so it would only have worked correctly for some regions of the overmap. --- src/activity_handlers.cpp | 14 +- src/avatar.cpp | 2 +- src/avatar.h | 2 +- src/basecamp.cpp | 18 +- src/basecamp.h | 31 +- src/character.cpp | 28 +- src/character.h | 13 +- src/computer_session.cpp | 14 +- src/condition.cpp | 2 +- src/coordinates.h | 11 + src/debug_menu.cpp | 38 +- src/editmap.cpp | 32 +- src/editmap.h | 5 +- src/faction.cpp | 23 +- src/faction_camp.cpp | 271 +++++------ src/faction_camp.h | 8 +- src/flood_fill.h | 12 +- src/game.cpp | 162 ++++--- src/game.h | 9 +- src/gamemode_defense.cpp | 10 +- src/gamemode_defense.h | 2 +- src/gamemode_tutorial.cpp | 10 +- src/iexamine.cpp | 8 +- src/item.cpp | 8 +- src/iuse.cpp | 19 +- src/iuse_actor.cpp | 8 +- src/iuse_actor.h | 6 +- src/magic_spell_effect.cpp | 4 +- src/magic_teleporter_list.cpp | 45 +- src/magic_teleporter_list.h | 13 +- src/map.cpp | 38 +- src/map.h | 4 +- src/map_extras.cpp | 44 +- src/map_field.cpp | 7 +- src/mapgen.cpp | 33 +- src/mapgen.h | 2 +- src/mapgen_functions.h | 5 +- src/mapgendata.cpp | 19 +- src/mapgendata.h | 6 +- src/memorial_logger.cpp | 4 +- src/mission.cpp | 10 +- src/mission.h | 44 +- src/mission_companion.cpp | 89 ++-- src/mission_companion.h | 11 +- src/mission_place.cpp | 5 +- src/mission_start.cpp | 213 +++++---- src/mission_ui.cpp | 6 +- src/mission_util.cpp | 125 ++--- src/missiondef.cpp | 7 +- src/mongroup.h | 14 +- src/monster.cpp | 3 +- src/npc.cpp | 43 +- src/npc.h | 29 +- src/npcmove.cpp | 33 +- src/npctalk.cpp | 2 +- src/npctalk_funcs.cpp | 36 +- src/omdata.h | 5 +- src/overmap.cpp | 831 +++++++++++++++++----------------- src/overmap.h | 182 ++++---- src/overmap_noise.cpp | 20 +- src/overmap_noise.h | 23 +- src/overmap_ui.cpp | 302 ++++++------ src/overmap_ui.h | 21 +- src/overmapbuffer.cpp | 487 ++++++++++---------- src/overmapbuffer.h | 190 ++++---- src/panels.cpp | 34 +- src/panels.h | 4 +- src/player.cpp | 10 +- src/player.h | 2 - src/point.h | 8 +- src/rng.h | 8 +- src/savegame.cpp | 89 ++-- src/savegame_json.cpp | 44 +- src/simple_pathfinding.h | 2 +- src/sounds.cpp | 5 +- src/start_location.cpp | 42 +- src/start_location.h | 11 +- src/talker.h | 2 +- src/talker_character.cpp | 2 +- src/talker_character.h | 2 +- src/trapfunc.cpp | 2 +- src/vehicle.cpp | 28 +- src/vehicle.h | 5 +- src/weather.cpp | 22 +- src/weather.h | 9 +- tests/map_extra_test.cpp | 23 +- tests/npc_talk_test.cpp | 4 +- tests/overmap_noise_test.cpp | 6 +- tests/overmap_test.cpp | 6 +- tests/test_main.cpp | 4 +- 90 files changed, 2200 insertions(+), 1895 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index da00ab1768d9c..f4014cf45b4b7 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -3006,7 +3006,9 @@ void activity_handlers::travel_do_turn( player_activity *act, player *p ) return; } map &here = get_map(); - tripoint sm_tri = here.getlocal( sm_to_ms_copy( omt_to_sm_copy( p->omt_path.back() ) ) ); + // TODO: fix point types + tripoint sm_tri = here.getlocal( + project_to( p->omt_path.back() ).raw() ); tripoint centre_sub = sm_tri + point( SEEX, SEEY ); if( !here.passable( centre_sub ) ) { tripoint_range candidates = here.points_in_radius( centre_sub, 2 ); @@ -4336,16 +4338,16 @@ void activity_handlers::tree_communion_do_turn( player_activity *act, player *p return; } // Breadth-first search forest tiles until one reveals new overmap tiles. - std::queue q; - std::unordered_set seen; - tripoint loc = p->global_omt_location(); + std::queue q; + std::unordered_set seen; + tripoint_abs_omt loc = p->global_omt_location(); q.push( loc ); seen.insert( loc ); const std::function filter = []( const oter_id & ter ) { return ter.obj().is_wooded() || ter.obj().get_name() == "field"; }; while( !q.empty() ) { - tripoint tpt = q.front(); + tripoint_abs_omt tpt = q.front(); if( overmap_buffer.reveal( tpt, 3, filter ) ) { if( p->has_trait( trait_SPIRITUAL ) ) { p->add_morale( MORALE_TREE_COMMUNION, 2, 30, 8_hours, 6_hours ); @@ -4358,7 +4360,7 @@ void activity_handlers::tree_communion_do_turn( player_activity *act, player *p } return; } - for( const tripoint &neighbor : points_in_radius( tpt, 1 ) ) { + for( const tripoint_abs_omt &neighbor : points_in_radius( tpt, 1 ) ) { if( seen.find( neighbor ) != seen.end() ) { continue; } diff --git a/src/avatar.cpp b/src/avatar.cpp index 391b928bd8611..e2a23d8cca891 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -220,7 +220,7 @@ void avatar::reset_all_misions() failed_missions.clear(); } -tripoint avatar::get_active_mission_target() const +tripoint_abs_omt avatar::get_active_mission_target() const { if( active_mission == nullptr ) { return overmap::invalid_tripoint; diff --git a/src/avatar.h b/src/avatar.h index fedab511163ec..a8a84a1885ee1 100644 --- a/src/avatar.h +++ b/src/avatar.h @@ -125,7 +125,7 @@ class avatar : public player * Returns the target of the active mission or @ref overmap::invalid_tripoint if there is * no active mission. */ - tripoint get_active_mission_target() const; + tripoint_abs_omt get_active_mission_target() const; /** * Set which mission is active. The mission must be listed in @ref active_missions. */ diff --git a/src/basecamp.cpp b/src/basecamp.cpp index 5b73156bf110e..cee2920a8d3ff 100644 --- a/src/basecamp.cpp +++ b/src/basecamp.cpp @@ -111,7 +111,7 @@ int base_camps::max_upgrade_by_type( const std::string &type ) basecamp::basecamp() = default; -basecamp::basecamp( const std::string &name_, const tripoint &omt_pos_ ): name( name_ ), +basecamp::basecamp( const std::string &name_, const tripoint_abs_omt &omt_pos_ ): name( name_ ), omt_pos( omt_pos_ ) { } @@ -138,7 +138,8 @@ void basecamp::set_by_radio( bool access_by_radio ) // find the last underbar, strip off the prefix of faction_base_ (which is 13 chars), // and the pull out the $TYPE and $CURLEVEL // This is legacy support for existing camps; future camps don't use cur_level at all -expansion_data basecamp::parse_expansion( const std::string &terrain, const tripoint &new_pos ) +expansion_data basecamp::parse_expansion( const std::string &terrain, + const tripoint_abs_omt &new_pos ) { expansion_data e; int last_bar = terrain.find_last_of( '_' ); @@ -148,7 +149,7 @@ expansion_data basecamp::parse_expansion( const std::string &terrain, const trip return e; } -void basecamp::add_expansion( const std::string &terrain, const tripoint &new_pos ) +void basecamp::add_expansion( const std::string &terrain, const tripoint_abs_omt &new_pos ) { if( terrain.find( base_camps::prefix ) == std::string::npos ) { return; @@ -162,7 +163,7 @@ void basecamp::add_expansion( const std::string &terrain, const tripoint &new_po directions.push_back( dir ); } -void basecamp::add_expansion( const std::string &bldg, const tripoint &new_pos, +void basecamp::add_expansion( const std::string &bldg, const tripoint_abs_omt &new_pos, const point &dir ) { expansion_data e; @@ -175,13 +176,13 @@ void basecamp::add_expansion( const std::string &bldg, const tripoint &new_pos, update_resources( bldg ); } -void basecamp::define_camp( const tripoint &p, const std::string &camp_type ) +void basecamp::define_camp( const tripoint_abs_omt &p, const std::string &camp_type ) { query_new_name(); omt_pos = p; const oter_id &omt_ref = overmap_buffer.ter( omt_pos ); // purging the regions guarantees all entries will start with faction_base_ - for( const std::pair &expansion : + for( const std::pair &expansion : talk_function::om_building_region( omt_pos, 1, true ) ) { add_expansion( expansion.first, expansion.second ); } @@ -665,7 +666,7 @@ void basecamp::form_crafting_inventory() { if( by_radio ) { tinymap target_map; - target_map.load( tripoint( omt_pos.x * 2, omt_pos.y * 2, omt_pos.z ), false ); + target_map.load( project_to( omt_pos ), false ); form_crafting_inventory( target_map ); } else { form_crafting_inventory( get_map() ); @@ -749,7 +750,8 @@ void basecamp_action_components::consume_components() map *target_map = &get_map(); if( base_.by_radio ) { map_ = std::make_unique(); - map_->load( omt_to_sm_copy( base_.camp_omt_pos() ), false ); + // TODO: fix point types + map_->load( project_to( base_.camp_omt_pos() ).raw(), false ); target_map = map_.get(); } const tripoint &origin = target_map->getlocal( base_.get_dumping_spot() ); diff --git a/src/basecamp.h b/src/basecamp.h index fdce5800e5bc4..067edd38a5b4b 100644 --- a/src/basecamp.h +++ b/src/basecamp.h @@ -35,7 +35,7 @@ struct expansion_data { std::string type; std::map provides; std::map in_progress; - tripoint pos; + tripoint_abs_omt pos; // legacy camp level, replaced by provides map and set to -1 int cur_level; @@ -116,13 +116,13 @@ class basecamp { public: basecamp(); - basecamp( const std::string &name_, const tripoint &omt_pos ); + basecamp( const std::string &name_, const tripoint_abs_omt &omt_pos ); basecamp( const std::string &name_, const tripoint &bb_pos_, const std::vector &directions_, const std::map &expansions_ ); inline bool is_valid() const { - return !name.empty() && omt_pos != tripoint_zero; + return !name.empty() && omt_pos != tripoint_abs_omt(); } inline int board_x() const { return bb_pos.x; @@ -130,7 +130,7 @@ class basecamp inline int board_y() const { return bb_pos.y; } - inline tripoint camp_omt_pos() const { + inline tripoint_abs_omt camp_omt_pos() const { return omt_pos; } inline const std::string &camp_name() const { @@ -151,7 +151,7 @@ class basecamp std::string board_name() const; std::vector directions; - std::vector fortifications; + std::vector fortifications; std::string name; void faction_display( const catacurses::window &fac_w, int width ) const; @@ -159,10 +159,10 @@ class basecamp void set_name( const std::string &new_name ); void query_new_name(); void abandon_camp(); - void add_expansion( const std::string &terrain, const tripoint &new_pos ); - void add_expansion( const std::string &bldg, const tripoint &new_pos, + void add_expansion( const std::string &terrain, const tripoint_abs_omt &new_pos ); + void add_expansion( const std::string &bldg, const tripoint_abs_omt &new_pos, const point &dir ); - void define_camp( const tripoint &p, const std::string &camp_type = "default" ); + void define_camp( const tripoint_abs_omt &p, const std::string &camp_type = "default" ); std::string expansion_tab( const point &dir ) const; // upgrade levels @@ -185,7 +185,8 @@ class basecamp // confirm there is at least 1 loot destination and 1 unsorted loot zone in the camp bool validate_sort_points(); // Validates the expansion data - expansion_data parse_expansion( const std::string &terrain, const tripoint &new_pos ); + expansion_data parse_expansion( const std::string &terrain, + const tripoint_abs_omt &new_pos ); /** * Invokes the zone manager and validates that the necessary sort zones exist. */ @@ -243,9 +244,9 @@ class basecamp /// Provides a "guess" for some of the things your gatherers will return with /// to upgrade the camp std::string gathering_description( const std::string &bldg ); - /// Returns a string for the number of plants that are harvestable, plots ready to plany, + /// Returns a string for the number of plants that are harvestable, plots ready to plant, /// and ground that needs tilling - std::string farm_description( const tripoint &farm_pos, size_t &plots_count, + std::string farm_description( const tripoint_abs_omt &farm_pos, size_t &plots_count, farm_ops operation ); /// Returns the description of a camp crafting options. converts fire charges to charcoal, /// allows dark crafting @@ -287,8 +288,8 @@ class basecamp void start_fortifications( std::string &bldg_exp ); void start_combat_mission( const std::string &miss ); /// Called when a companion starts a chop shop @ref task mission - bool start_garage_chop( const point &dir, const tripoint &omt_tgt ); - void start_farm_op( const point &dir, const tripoint &omt_tgt, farm_ops op ); + bool start_garage_chop( const point &dir, const tripoint_abs_omt &omt_tgt ); + void start_farm_op( const point &dir, const tripoint_abs_omt &omt_tgt, farm_ops op ); ///Display items listed in @ref equipment to let the player pick what to give the departing ///NPC, loops until quit or empty. std::vector give_equipment( std::vector equipment, const std::string &msg ); @@ -325,7 +326,7 @@ class basecamp * @param omt_tgt the overmap pos3 of the farm_ops * @param op whether to plow, plant, or harvest */ - bool farm_return( const std::string &task, const tripoint &omt_tgt, farm_ops op ); + bool farm_return( const std::string &task, const tripoint_abs_omt &omt_tgt, farm_ops op ); void fortifications_return(); void combat_mission_return( const std::string &miss ); @@ -347,7 +348,7 @@ class basecamp void add_resource( const itype_id &camp_resource ); bool resources_updated = false; // omt pos - tripoint omt_pos; + tripoint_abs_omt omt_pos; std::vector assigned_npcs; // location of associated bulletin board in abs coords tripoint bb_pos; diff --git a/src/character.cpp b/src/character.cpp index 18f88431be7c9..44adbd05edc32 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -21,6 +21,7 @@ #include "colony.h" #include "construction.h" #include "coordinate_conversions.h" +#include "coordinates.h" #include "debug.h" #include "disease.h" #include "effect.h" @@ -754,19 +755,21 @@ int Character::unimpaired_range() const return std::min( sight_max, 60 ); } -bool Character::overmap_los( const tripoint &omt, int sight_points ) +bool Character::overmap_los( const tripoint_abs_omt &omt, int sight_points ) { - const tripoint ompos = global_omt_location(); - if( omt.x < ompos.x - sight_points || omt.x > ompos.x + sight_points || - omt.y < ompos.y - sight_points || omt.y > ompos.y + sight_points ) { + const tripoint_abs_omt ompos = global_omt_location(); + const point_rel_omt offset = omt.xy() - ompos.xy(); + if( offset.x() < -sight_points || offset.x() > sight_points || + offset.y() < -sight_points || offset.y() > sight_points ) { // Outside maximum sight range return false; } - const std::vector line = line_to( ompos, omt, 0, 0 ); + // TODO: fix point types + const std::vector line = line_to( ompos.raw(), omt.raw(), 0, 0 ); for( size_t i = 0; i < line.size() && sight_points >= 0; i++ ) { const tripoint &pt = line[i]; - const oter_id &ter = overmap_buffer.ter( pt ); + const oter_id &ter = overmap_buffer.ter( tripoint_abs_omt( pt ) ); sight_points -= static_cast( ter->get_see_cost() ); if( sight_points < 0 ) { return false; @@ -6782,9 +6785,10 @@ tripoint Character::global_sm_location() const return ms_to_sm_copy( global_square_location() ); } -tripoint Character::global_omt_location() const +tripoint_abs_omt Character::global_omt_location() const { - return ms_to_omt_copy( global_square_location() ); + // TODO: fix point types + return tripoint_abs_omt( ms_to_omt_copy( global_square_location() ) ); } bool Character::is_blind() const @@ -9640,11 +9644,11 @@ void Character::apply_persistent_morale() } // Nomads get a morale penalty if they stay near the same overmap tiles too long. if( has_trait( trait_NOMAD ) || has_trait( trait_NOMAD2 ) || has_trait( trait_NOMAD3 ) ) { - const tripoint ompos = global_omt_location(); + const tripoint_abs_omt ompos = global_omt_location(); float total_time = 0; // Check how long we've stayed in any overmap tile within 5 of us. const int max_dist = 5; - for( const tripoint &pos : points_in_radius( ompos, max_dist ) ) { + for( const tripoint_abs_omt &pos : points_in_radius( ompos, max_dist ) ) { const float dist = rl_dist( ompos, pos ); if( dist > max_dist ) { continue; @@ -10823,10 +10827,10 @@ void Character::place_corpse() here.add_item_or_charges( pos(), body ); } -void Character::place_corpse( const tripoint &om_target ) +void Character::place_corpse( const tripoint_abs_omt &om_target ) { tinymap bay; - bay.load( tripoint( om_target.x * 2, om_target.y * 2, om_target.z ), false ); + bay.load( project_to( om_target ), false ); point fin( rng( 1, SEEX * 2 - 2 ), rng( 1, SEEX * 2 - 2 ) ); // This makes no sense at all. It may find a random tile without furniture, but // if the first try to find one fails, it will go through all tiles of the map diff --git a/src/character.h b/src/character.h index 78c82d9c980f1..abb29f2d20ae6 100644 --- a/src/character.h +++ b/src/character.h @@ -24,6 +24,7 @@ #include "character_id.h" #include "character_martial_arts.h" #include "color.h" +#include "coordinates.h" #include "creature.h" #include "damage.h" #include "enums.h" @@ -468,7 +469,7 @@ class Character : public Creature, public visitable /** Returns the player maximum vision range factoring in mutations, diseases, and other effects */ int unimpaired_range() const; /** Returns true if overmap tile is within player line-of-sight */ - bool overmap_los( const tripoint &omt, int sight_points ); + bool overmap_los( const tripoint_abs_omt &omt, int sight_points ); /** Returns the distance the player can see on the overmap */ int overmap_sight_range( int light_level ) const; /** Returns the distance the player can see through walls */ @@ -931,7 +932,7 @@ class Character : public Creature, public visitable /** * Returns the location of the player in global overmap terrain coordinates. */ - tripoint global_omt_location() const; + tripoint_abs_omt global_omt_location() const; private: /** Retrieves a stat mod of a mutation. */ @@ -1089,7 +1090,7 @@ class Character : public Creature, public visitable /**Get stat bonus from bionic*/ int get_mod_stat_from_bionic( const character_stat &Stat ) const; // route for overmap-scale traveling - std::vector omt_path; + std::vector omt_path; /** Handles bionic effects over time of the entered bionic */ void process_bionic( int b ); @@ -1728,7 +1729,7 @@ class Character : public Creature, public visitable cata::optional last_target_pos; // Save favorite ammo location item_location ammo_location; - std::set camps; + std::set camps; /* crafting inventory cached time */ time_point cached_time; @@ -1966,7 +1967,7 @@ class Character : public Creature, public visitable // Put corpse+inventory on map at the place where this is. void place_corpse(); // Put corpse+inventory on defined om tile - void place_corpse( const tripoint &om_target ); + void place_corpse( const tripoint_abs_omt &om_target ); /** Returns the player's modified base movement cost */ int run_cost( int base_cost, bool diag = false ) const; @@ -2568,7 +2569,7 @@ class Character : public Creature, public visitable mutable decltype( _skills ) valid_autolearn_skills; /** Amount of time the player has spent in each overmap tile. */ - std::unordered_map overmap_time; + std::unordered_map overmap_time; public: time_point next_climate_control_check; diff --git a/src/computer_session.cpp b/src/computer_session.cpp index 14fa14bbe710a..5cafbcccb52b3 100644 --- a/src/computer_session.cpp +++ b/src/computer_session.cpp @@ -580,7 +580,7 @@ void computer_session::action_maps() { Character &player_character = get_player_character(); player_character.moves -= 30; - const tripoint center = player_character.global_omt_location(); + const tripoint_abs_omt center = player_character.global_omt_location(); overmap_buffer.reveal( center.xy(), 40, 0 ); query_any( _( "Surface map data downloaded. Local anomalous-access error logged. Press any keyā€¦" ) ); @@ -592,7 +592,7 @@ void computer_session::action_map_sewer() { Character &player_character = get_player_character(); player_character.moves -= 30; - const tripoint center = player_character.global_omt_location(); + const tripoint_abs_omt center = player_character.global_omt_location(); for( int i = -60; i <= 60; i++ ) { for( int j = -60; j <= 60; j++ ) { point offset( i, j ); @@ -611,7 +611,7 @@ void computer_session::action_map_subway() { Character &player_character = get_player_character(); player_character.moves -= 30; - const tripoint center = player_character.global_omt_location(); + const tripoint_abs_omt center = player_character.global_omt_location(); for( int i = -60; i <= 60; i++ ) { for( int j = -60; j <= 60; j++ ) { point offset( i, j ); @@ -1503,7 +1503,7 @@ void computer_session::action_emerg_ref_center() print_line( _( "SEARCHING FOR NEAREST REFUGEE CENTER, PLEASE WAITā€¦" ) ); const mission_type_id &mission_type = mission_type_id( "MISSION_REACH_REFUGEE_CENTER" ); - tripoint mission_target; + tripoint_abs_omt mission_target; avatar &player_character = get_avatar(); // Check completed missions too, so people can't repeatedly get the mission. const std::vector completed_missions = player_character.get_completed_missions(); @@ -1534,8 +1534,10 @@ void computer_session::action_emerg_ref_center() "4PM AT 555-0164.\n" "\n" "IF YOU WOULD LIKE TO SPEAK WITH SOMEONE IN PERSON OR WOULD LIKE\n" - "TO WRITE US A LETTER PLEASE SEND IT TOā€¦\n" ), rl_dist( player_character.pos(), mission_target ), - direction_name_short( direction_from( player_character.pos(), mission_target ) ) ); + "TO WRITE US A LETTER PLEASE SEND IT TOā€¦\n" ), + rl_dist( player_character.global_omt_location(), mission_target ), + direction_name_short( + direction_from( player_character.global_omt_location(), mission_target ) ) ); query_any( _( "Press any key to continueā€¦" ) ); reset_terminal(); diff --git a/src/condition.cpp b/src/condition.cpp index 4916a3fb5d9e0..41f082d557ff9 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -321,7 +321,7 @@ void conditional_t::set_at_om_location( const JsonObject &jo, const std::stri { const std::string &location = jo.get_string( member ); condition = [location, is_npc]( const T & d ) { - const tripoint omt_pos = d.actor( is_npc )->global_omt_location(); + const tripoint_abs_omt omt_pos = d.actor( is_npc )->global_omt_location(); const oter_id &omt_ref = overmap_buffer.ter( omt_pos ); if( location == "FACTION_CAMP_ANY" ) { diff --git a/src/coordinates.h b/src/coordinates.h index 9e2daaae88649..e2c6b107b652a 100644 --- a/src/coordinates.h +++ b/src/coordinates.h @@ -2,7 +2,9 @@ #ifndef CATA_SRC_COORDINATES_H #define CATA_SRC_COORDINATES_H +#include #include +#include #include "coordinate_conversions.h" #include "enums.h" @@ -445,18 +447,23 @@ using point_omt_ms = coords::coord_point; using point_omt_sm = coords::coord_point; using point_om_sm = coords::coord_point; +using point_rel_omt = coords::coord_point; using point_abs_omt = coords::coord_point; using point_om_omt = coords::coord_point; using point_abs_seg = coords::coord_point; +using point_rel_om = coords::coord_point; using point_abs_om = coords::coord_point; using tripoint_rel_ms = coords::coord_point; using tripoint_abs_ms = coords::coord_point; using tripoint_sm_ms = coords::coord_point; using tripoint_omt_ms = coords::coord_point; +using tripoint_rel_sm = coords::coord_point; using tripoint_abs_sm = coords::coord_point; using tripoint_om_sm = coords::coord_point; +using tripoint_rel_omt = coords::coord_point; using tripoint_abs_omt = coords::coord_point; +using tripoint_om_omt = coords::coord_point; using tripoint_abs_seg = coords::coord_point; using tripoint_abs_om = coords::coord_point; /*@}*/ @@ -611,6 +618,10 @@ struct real_coords { fromabs( omt_to_ms_copy( a ) ); } + point_abs_omt abs_omt() const { + return project_to( point_abs_sm( abs_sub ) ); + } + // helper functions to return abs_pos of submap/overmap tile/overmap's start point begin_sub() { diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index f9ec736f14fec..aaab17a0c8e0b 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -35,6 +35,7 @@ #include "color.h" #include "compatibility.h" #include "coordinate_conversions.h" +#include "coordinates.h" #include "cursesdef.h" #include "debug.h" #include "dialogue_chatbin.h" @@ -418,12 +419,12 @@ void teleport_short() void teleport_long() { - const tripoint where( ui::omap::choose_point() ); + const tripoint_abs_omt where( ui::omap::choose_point() ); if( where == overmap::invalid_tripoint ) { return; } g->place_player_overmap( where ); - add_msg( _( "You teleport to submap (%d,%d,%d)." ), where.x, where.y, where.z ); + add_msg( _( "You teleport to submap (%s)." ), where.to_string() ); } void teleport_overmap() @@ -435,12 +436,13 @@ void teleport_overmap() Character &player_character = get_player_character(); const tripoint offset( OMAPX * dir_->x, OMAPY * dir_->y, dir_->z ); - const tripoint where( player_character.global_omt_location() + offset ); + const tripoint_abs_omt where = player_character.global_omt_location() + offset; g->place_player_overmap( where ); - const tripoint new_pos( omt_to_om_copy( player_character.global_omt_location() ) ); - add_msg( _( "You teleport to overmap (%d,%d,%d)." ), new_pos.x, new_pos.y, new_pos.z ); + const tripoint_abs_om new_pos = + project_to( player_character.global_omt_location() ); + add_msg( _( "You teleport to overmap %s." ), new_pos.to_string() ); } void spawn_nested_mapgen() @@ -460,13 +462,14 @@ void spawn_nested_mapgen() } map &here = get_map(); - const tripoint abs_ms = here.getabs( *where ); - const tripoint abs_omt = ms_to_omt_copy( abs_ms ); - const tripoint abs_sub = ms_to_sm_copy( abs_ms ); + const tripoint_abs_ms abs_ms( here.getabs( *where ) ); + const tripoint_abs_omt abs_omt = project_to( abs_ms ); + const tripoint_abs_sm abs_sub = project_to( abs_ms ); map target_map; target_map.load( abs_sub, true ); - const tripoint local_ms = target_map.getlocal( abs_ms ); + // TODO: fix point types + const tripoint local_ms = target_map.getlocal( abs_ms.raw() ); mapgendata md( abs_omt, target_map, 0.0f, calendar::turn, nullptr ); const auto &ptr = nested_mapgen[nest_str[nest_choice]].pick(); if( ptr == nullptr ) { @@ -515,9 +518,9 @@ void character_edit_menu() << "; " << "api: " << np->get_faction_ver() << std::endl; if( np->has_destination() ) { - data << string_format( _( "Destination: %d:%d:%d (%s)" ), - np->goal.x, np->goal.y, np->goal.z, - overmap_buffer.ter( np->goal )->get_name() ) << std::endl; + data << string_format( + _( "Destination: %s %s" ), np->goal.to_string(), + overmap_buffer.ter( np->goal )->get_name() ) << std::endl; } else { data << _( "No destination." ) << std::endl; } @@ -1000,7 +1003,7 @@ std::string mission_debug::describe( const mission &m ) data << _( " Status:" ) << mission_status_string( m.status ); data << _( " ID:" ) << m.uid; data << _( " NPC ID:" ) << m.npc_id; - data << _( " Target:" ) << m.target.x << "," << m.target.y << "," << m.target.z; + data << _( " Target:" ) << m.target.to_string(); data << _( "Player ID:" ) << m.player_id; return data.str(); @@ -1783,12 +1786,13 @@ void debug() mx_menu.query(); int mx_choice = mx_menu.ret; if( mx_choice >= 0 && mx_choice < static_cast( mx_str.size() ) ) { - const tripoint where_omt( ui::omap::choose_point() ); + const tripoint_abs_omt where_omt( ui::omap::choose_point() ); if( where_omt != overmap::invalid_tripoint ) { - tripoint where_sm = omt_to_sm_copy( where_omt ); + tripoint_abs_sm where_sm = project_to( where_omt ); tinymap mx_map; - mx_map.load( where_sm, false ); - MapExtras::apply_function( mx_str[mx_choice], mx_map, where_sm ); + // TODO: fix point types + mx_map.load( where_sm.raw(), false ); + MapExtras::apply_function( mx_str[mx_choice], mx_map, where_sm.raw() ); g->load_npcs(); here.invalidate_map_cache( g->get_levz() ); } diff --git a/src/editmap.cpp b/src/editmap.cpp index a53e90d186dd7..f82d4b9d55a09 100644 --- a/src/editmap.cpp +++ b/src/editmap.cpp @@ -1776,8 +1776,8 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu ) hilights["mapgentgt"].points[target + point( 1 + SEEX, -SEEY )] = 1; // Coordinates of the overmap terrain that should be generated. - const point omt_pos2 = ms_to_omt_copy( tc.abs_pos ); - const tripoint omt_pos( omt_pos2, target.z ); + const point_abs_omt omt_pos2 = tc.abs_omt(); + const tripoint_abs_omt omt_pos( omt_pos2, target.z ); const oter_id &omt_ref = overmap_buffer.ter( omt_pos ); // Copy to store the original value, to restore it upon canceling const oter_id orig_oters = omt_ref; @@ -1785,7 +1785,9 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu ) tinymap tmpmap; // TODO: add a do-not-save-generated-submaps parameter // TODO: keep track of generated submaps to delete them properly and to avoid memory leaks - tmpmap.generate( tripoint( omt_pos.x * 2, omt_pos.y * 2, target.z ), calendar::turn ); + // TODO: fix point types + tmpmap.generate( tripoint( project_to( omt_pos.xy() ).raw(), target.z ), + calendar::turn ); gmenu.border_color = c_light_gray; gmenu.hilight_color = c_black_white; @@ -1828,7 +1830,10 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu ) lastsel = gmenu.selected; overmap_buffer.ter_set( omt_pos, oter_id( gmenu.selected ) ); cleartmpmap( tmpmap ); - tmpmap.generate( tripoint( omt_pos.x * 2, omt_pos.y * 2, target.z ), calendar::turn ); + // TODO: fix point types + tmpmap.generate( + tripoint( project_to( omt_pos.xy() ).raw(), target.z ), + calendar::turn ); } if( showpreview ) { @@ -1852,7 +1857,10 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu ) if( gpmenu.ret == 0 ) { cleartmpmap( tmpmap ); - tmpmap.generate( tripoint( omt_pos.x * 2, omt_pos.y * 2, target.z ), calendar::turn ); + // TODO: fix point types + tmpmap.generate( + tripoint( project_to( omt_pos.xy() ).raw(), target.z ), + calendar::turn ); } else if( gpmenu.ret == 1 ) { tmpmap.rotate( 1 ); } else if( gpmenu.ret == 2 ) { @@ -1925,10 +1933,10 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu ) cleartmpmap( tmpmap ); } -vehicle *editmap::mapgen_veh_query( const tripoint &omt_tgt ) +vehicle *editmap::mapgen_veh_query( const tripoint_abs_omt &omt_tgt ) { tinymap target_bay; - target_bay.load( tripoint( omt_tgt.x * 2, omt_tgt.y * 2, omt_tgt.z ), false ); + target_bay.load( project_to( omt_tgt ), false ); std::vector possible_vehicles; for( int x = 0; x < 2; x++ ) { @@ -1959,20 +1967,20 @@ vehicle *editmap::mapgen_veh_query( const tripoint &omt_tgt ) return nullptr; } -bool editmap::mapgen_veh_destroy( const tripoint &omt_tgt, vehicle *car_target ) +bool editmap::mapgen_veh_destroy( const tripoint_abs_omt &omt_tgt, vehicle *car_target ) { map &here = get_map(); tinymap target_bay; - target_bay.load( tripoint( omt_tgt.x * 2, omt_tgt.y * 2, omt_tgt.z ), false ); + target_bay.load( project_to( omt_tgt ), false ); for( int x = 0; x < 2; x++ ) { for( int y = 0; y < 2; y++ ) { submap *destsm = target_bay.get_submap_at_grid( { x, y, target.z } ); for( auto &z : destsm->vehicles ) { if( z.get() == car_target ) { std::unique_ptr old_veh = target_bay.detach_vehicle( z.get() ); - here.clear_vehicle_cache( omt_tgt.z ); - here.reset_vehicle_cache( omt_tgt.z ); - here.clear_vehicle_list( omt_tgt.z ); + here.clear_vehicle_cache( omt_tgt.z() ); + here.reset_vehicle_cache( omt_tgt.z() ); + here.clear_vehicle_list( omt_tgt.z() ); //Rebuild vehicle_list? return true; } diff --git a/src/editmap.h b/src/editmap.h index 9231fbf25a4da..444594acec2e3 100644 --- a/src/editmap.h +++ b/src/editmap.h @@ -7,6 +7,7 @@ #include #include +#include "coordinates.h" #include "optional.h" #include "color.h" #include "cursesdef.h" @@ -63,8 +64,8 @@ class editmap void edit_mapgen(); void cleartmpmap( tinymap &tmpmap ); void mapgen_preview( const real_coords &tc, uilist &gmenu ); - vehicle *mapgen_veh_query( const tripoint &omt_tgt ); - bool mapgen_veh_destroy( const tripoint &omt_tgt, vehicle *car_target ); + vehicle *mapgen_veh_query( const tripoint_abs_omt &omt_tgt ); + bool mapgen_veh_destroy( const tripoint_abs_omt &omt_tgt, vehicle *car_target ); void mapgen_retarget(); int select_shape( shapetype shape, int mode = -1 ); diff --git a/src/faction.cpp b/src/faction.cpp index 6f185f8245179..deb2431dae39c 100644 --- a/src/faction.cpp +++ b/src/faction.cpp @@ -465,14 +465,14 @@ void basecamp::faction_display( const catacurses::window &fac_w, const int width int y = 2; const nc_color col = c_white; Character &player_character = get_player_character(); - const tripoint player_abspos = player_character.global_omt_location(); - tripoint camp_pos = camp_omt_pos(); + const tripoint_abs_omt player_abspos = player_character.global_omt_location(); + tripoint_abs_omt camp_pos = camp_omt_pos(); std::string direction = direction_name( direction_from( player_abspos, camp_pos ) ); mvwprintz( fac_w, point( width, ++y ), c_light_gray, _( "Press enter to rename this camp" ) ); if( direction != "center" ) { mvwprintz( fac_w, point( width, ++y ), c_light_gray, _( "Direction: to the " ) + direction ); } - mvwprintz( fac_w, point( width, ++y ), col, _( "Location: (%d, %d)" ), camp_pos.x, camp_pos.y ); + mvwprintz( fac_w, point( width, ++y ), col, _( "Location: %s" ), camp_pos.to_string() ); faction *yours = player_character.get_faction(); std::string food_text = string_format( _( "Food Supply: %s %d calories" ), yours->food_supply_text(), yours->food_supply ); @@ -499,14 +499,14 @@ int npc::faction_display( const catacurses::window &fac_w, const int width ) con int y = 2; const nc_color col = c_white; Character &player_character = get_player_character(); - const tripoint player_abspos = player_character.global_omt_location(); + const tripoint_abs_omt player_abspos = player_character.global_omt_location(); //get NPC followers, status, direction, location, needs, weapon, etc. mvwprintz( fac_w, point( width, ++y ), c_light_gray, _( "Press enter to talk to this follower " ) ); std::string mission_string; if( has_companion_mission() ) { std::string dest_string; - cata::optional dest = get_mission_destination(); + cata::optional dest = get_mission_destination(); if( dest ) { basecamp *dest_camp; cata::optional temp_camp = overmap_buffer.find_camp( dest->xy() ); @@ -514,7 +514,7 @@ int npc::faction_display( const catacurses::window &fac_w, const int width ) con dest_camp = *temp_camp; dest_string = _( "traveling to: " ) + dest_camp->camp_name(); } else { - dest_string = string_format( _( "traveling to: (%d, %d)" ), dest->x, dest->y ); + dest_string = string_format( _( "traveling to: %s" ), dest->to_string() ); } mission_string = _( "Current Mission: " ) + dest_string; } else { @@ -524,7 +524,7 @@ int npc::faction_display( const catacurses::window &fac_w, const int width ) con } } fold_and_print( fac_w, point( width, ++y ), getmaxx( fac_w ) - width - 2, col, mission_string ); - tripoint guy_abspos = global_omt_location(); + tripoint_abs_omt guy_abspos = global_omt_location(); basecamp *temp_camp = nullptr; if( assigned_camp ) { cata::optional bcp = overmap_buffer.find_camp( ( *assigned_camp ).xy() ); @@ -540,11 +540,10 @@ int npc::faction_display( const catacurses::window &fac_w, const int width ) con mvwprintz( fac_w, point( width, ++y ), col, _( "Direction: Nearby" ) ); } if( is_stationed ) { - mvwprintz( fac_w, point( width, ++y ), col, _( "Location: (%d, %d), at camp: %s" ), guy_abspos.x, - guy_abspos.y, temp_camp->camp_name() ); + mvwprintz( fac_w, point( width, ++y ), col, _( "Location: %s, at camp: %s" ), + guy_abspos.to_string(), temp_camp->camp_name() ); } else { - mvwprintz( fac_w, point( width, ++y ), col, _( "Location: (%d, %d)" ), guy_abspos.x, - guy_abspos.y ); + mvwprintz( fac_w, point( width, ++y ), col, _( "Location: %s" ), guy_abspos.to_string() ); } std::string can_see; nc_color see_color; @@ -843,7 +842,7 @@ void faction_manager::display() const camp = nullptr; // create a list of faction camps camps.clear(); - for( auto elem : player_character.camps ) { + for( tripoint_abs_omt elem : player_character.camps ) { cata::optional p = overmap_buffer.find_camp( elem.xy() ); if( !p ) { continue; diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index 7b32ebd923cb9..e288ff194c8cc 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -21,6 +21,7 @@ #include "color.h" #include "compatibility.h" // needed for the workaround for the std::to_string bug in some compilers #include "coordinate_conversions.h" +#include "coordinates.h" #include "cursesdef.h" #include "debug.h" #include "editmap.h" @@ -370,15 +371,17 @@ int om_harvest_furn_est( npc &comp, const tripoint &omt_tgt, const furn_id &f, i int om_harvest_furn_break( npc &comp, const tripoint &omt_tgt, const furn_id &f, int chance = 100 ); /// Exact same as om_harvest_furn but functions on terrain -int om_harvest_ter( npc &comp, const tripoint &omt_tgt, const ter_id &t, int chance = 100, +int om_harvest_ter( npc &comp, const tripoint_abs_omt &omt_tgt, const ter_id &t, int chance = 100, bool estimate = false, bool bring_back = true ); // om_harvest_furn helper function that counts the furniture instances -int om_harvest_ter_est( npc &comp, const tripoint &omt_tgt, const ter_id &t, int chance = 100 ); -int om_harvest_ter_break( npc &comp, const tripoint &omt_tgt, const ter_id &t, int chance = 100 ); +int om_harvest_ter_est( npc &comp, const tripoint_abs_omt &omt_tgt, const ter_id &t, + int chance = 100 ); +int om_harvest_ter_break( npc &comp, const tripoint_abs_omt &omt_tgt, const ter_id &t, + int chance = 100 ); /// Collects all items in @ref omt_tgt with a @ref chance between 0 - 1.0, returns total /// mass and volume /// @ref take, whether you take the item or count it -mass_volume om_harvest_itm( const npc_ptr &comp, const tripoint &omt_tgt, int chance = 100, +mass_volume om_harvest_itm( const npc_ptr &comp, const tripoint_abs_omt &omt_tgt, int chance = 100, bool take = true ); void apply_camp_ownership( const tripoint &camp_pos, int radius ); /* @@ -388,14 +391,14 @@ void apply_camp_ownership( const tripoint &camp_pos, int radius ); * @param estimate if true, non-destructive count of trees * @force_cut_trunk if true and estimate is false, chop tree trunks into logs */ -int om_cutdown_trees( const tripoint &omt_tgt, int chance = 100, bool estimate = false, +int om_cutdown_trees( const tripoint_abs_omt &omt_tgt, int chance = 100, bool estimate = false, bool force_cut_trunk = true ); -int om_cutdown_trees_est( const tripoint &omt_tgt, int chance = 100 ); -int om_cutdown_trees_logs( const tripoint &omt_tgt, int chance = 100 ); -int om_cutdown_trees_trunks( const tripoint &omt_tgt, int chance = 100 ); +int om_cutdown_trees_est( const tripoint_abs_omt &omt_tgt, int chance = 100 ); +int om_cutdown_trees_logs( const tripoint_abs_omt &omt_tgt, int chance = 100 ); +int om_cutdown_trees_trunks( const tripoint_abs_omt &omt_tgt, int chance = 100 ); /// Creates an improvised shelter at @ref omt_tgt and dumps the @ref itms into the building -bool om_set_hide_site( npc &comp, const tripoint &omt_tgt, const std::vector &itms, +bool om_set_hide_site( npc &comp, const tripoint_abs_omt &omt_tgt, const std::vector &itms, const std::vector &itms_rem = {} ); /** * Opens the overmap so that you can select points for missions or constructions. @@ -408,17 +411,18 @@ bool om_set_hide_site( npc &comp, const tripoint &omt_tgt, const std::vector &possible_om_types = {}, - bool must_see = true, bool popup_notice = true, - const tripoint &source = tripoint( -999, -999, -999 ), - bool bounce = false ); -void om_range_mark( const tripoint &origin, int range, bool add_notes = true, +tripoint_abs_omt om_target_tile( + const tripoint_abs_omt &omt_pos, int min_range = 1, int range = 1, + const std::vector &possible_om_types = {}, bool must_see = true, + bool popup_notice = true, const tripoint_abs_omt &source = tripoint_abs_omt( -999, -999, -999 ), + bool bounce = false ); +void om_range_mark( const tripoint_abs_omt &origin, int range, bool add_notes = true, const std::string &message = "Y;X: MAX RANGE" ); -void om_line_mark( const tripoint &origin, const tripoint &dest, bool add_notes = true, - const std::string &message = "R;X: PATH" ); -std::vector om_companion_path( const tripoint &start, int range_start = 90, - bool bounce = true ); +void om_line_mark( + const tripoint_abs_omt &origin, const tripoint_abs_omt &dest, bool add_notes = true, + const std::string &message = "R;X: PATH" ); +std::vector om_companion_path( + const tripoint_abs_omt &start, int range_start = 90, bool bounce = true ); /** * Can be used to calculate total trip time for an NPC mission or just the traveling portion. * Doesn't use the pathingalgorithms yet. @@ -427,10 +431,11 @@ std::vector om_companion_path( const tripoint &start, int range_start * @param work how much time the NPC will stay at the target * @param trips how many trips back and forth the NPC will make */ -time_duration companion_travel_time_calc( const tripoint &omt_pos, const tripoint &omt_tgt, +time_duration companion_travel_time_calc( const tripoint_abs_omt &pos, const tripoint_abs_omt &tgt, time_duration work, int trips = 1, int haulage = 0 ); -time_duration companion_travel_time_calc( const std::vector &journey, time_duration work, - int trips = 1, int haulage = 0 ); +time_duration companion_travel_time_calc( + const std::vector &journey, time_duration work, int trips = 1, + int haulage = 0 ); /// Determines how many round trips a given NPC @ref comp will take to move all of the /// items @ref itms int om_carry_weight_to_trips( const std::vector &itms, const npc_ptr &comp = nullptr ); @@ -506,7 +511,7 @@ static bool update_time_fixed( std::string &entry, const comp_list &npc_list, static cata::optional get_basecamp( npc &p, const std::string &camp_type = "default" ) { - tripoint omt_pos = p.global_omt_location(); + tripoint_abs_omt omt_pos = p.global_omt_location(); cata::optional bcp = overmap_buffer.find_camp( omt_pos.xy() ); if( bcp ) { return bcp; @@ -545,7 +550,7 @@ recipe_id base_camps::select_camp_option( const std::map void talk_function::start_camp( npc &p ) { - const tripoint omt_pos = p.global_omt_location(); + const tripoint_abs_omt omt_pos = p.global_omt_location(); const oter_id &omt_ref = overmap_buffer.ter( omt_pos ); const auto &pos_camps = recipe_group::get_recipes_by_id( "all_faction_base_types", @@ -560,7 +565,8 @@ void talk_function::start_camp( npc &p ) return; } - std::vector> om_region = om_building_region( omt_pos, 1 ); + std::vector> om_region = + om_building_region( omt_pos, 1 ); int near_fields = 0; for( const auto &om_near : om_region ) { const oter_id &om_type = oter_id( om_near.first ); @@ -568,7 +574,8 @@ void talk_function::start_camp( npc &p ) near_fields += 1; } } - std::vector> om_region_ext = om_building_region( omt_pos, 3 ); + std::vector> om_region_ext = + om_building_region( omt_pos, 3 ); int forests = 0; int waters = 0; for( const auto &om_near : om_region_ext ) { @@ -610,7 +617,7 @@ void talk_function::start_camp( npc &p ) void talk_function::recover_camp( npc &p ) { - const tripoint omt_pos = p.global_omt_location(); + const tripoint_abs_omt omt_pos = p.global_omt_location(); const std::string &omt_ref = overmap_buffer.ter( omt_pos ).id().c_str(); if( omt_ref.find( "faction_base_camp" ) == std::string::npos ) { popup( _( "There is no faction camp here to recover!" ) ); @@ -634,7 +641,7 @@ void talk_function::remove_overseer( npc &p ) void talk_function::basecamp_mission( npc &p ) { const std::string title = _( "Base Missions" ); - const tripoint omt_pos = p.global_omt_location(); + const tripoint_abs_omt omt_pos = p.global_omt_location(); mission_data mission_key; cata::optional temp_camp = get_basecamp( p ); @@ -690,7 +697,7 @@ void basecamp::get_available_missions_by_dir( mission_data &mission_key, const p const std::string dir_id = base_camps::all_directions.at( dir ).id; const std::string dir_abbr = base_camps::all_directions.at( dir ).bracket_abbr.translated(); - const tripoint omt_trg = omt_pos + dir; + const tripoint_abs_omt omt_trg = omt_pos + dir; if( dir != base_camps::base_dir ) { // return legacy workers @@ -1476,7 +1483,7 @@ bool basecamp::handle_mission( const std::string &miss_id, const std::string base_dir_id = base_camps::all_directions.at( base_camps::base_dir ).id; const std::string miss_dir_id = base_camps::all_directions.at( miss_dir ).id; - const tripoint omt_trg = omt_pos + miss_dir; + const tripoint_abs_omt omt_trg = omt_pos + miss_dir; if( miss_id.substr( 0, 18 + miss_dir_id.size() ) == miss_dir_id + " Expansion Upgrade" ) { const std::string bldg = miss_id.substr( 18 + miss_dir_id.size() ); @@ -1903,8 +1910,8 @@ void basecamp::start_cut_logs() { std::vector log_sources = { "forest", "forest_thick", "forest_water" }; popup( _( "Forests and swamps are the only valid cutting locations." ) ); - tripoint forest = om_target_tile( omt_pos, 1, 50, log_sources ); - if( forest != tripoint( -999, -999, -999 ) ) { + tripoint_abs_omt forest = om_target_tile( omt_pos, 1, 50, log_sources ); + if( forest != tripoint_abs_omt( -999, -999, -999 ) ) { standard_npc sample_npc( "Temp" ); sample_npc.set_fake( true ); int tree_est = om_cutdown_trees_est( forest, 50 ); @@ -1950,8 +1957,8 @@ void basecamp::start_clearcut() { std::vector log_sources = { "forest", "forest_thick" }; popup( _( "Forests are the only valid cutting locations." ) ); - tripoint forest = om_target_tile( omt_pos, 1, 50, log_sources ); - if( forest != tripoint( -999, -999, -999 ) ) { + tripoint_abs_omt forest = om_target_tile( omt_pos, 1, 50, log_sources ); + if( forest != tripoint_abs_omt( -999, -999, -999 ) ) { standard_npc sample_npc( "Temp" ); sample_npc.set_fake( true ); int tree_est = om_cutdown_trees_est( forest, 95 ); @@ -1987,9 +1994,9 @@ void basecamp::start_setup_hide_site() "field" }; popup( _( "Forests, swamps, and fields are valid hide site locations." ) ); - tripoint forest = om_target_tile( omt_pos, 10, 90, hide_locations, true, true, - omt_pos, true ); - if( forest != tripoint( -999, -999, -999 ) ) { + tripoint_abs_omt forest = om_target_tile( omt_pos, 10, 90, hide_locations, true, true, + omt_pos, true ); + if( forest != tripoint_abs_omt( -999, -999, -999 ) ) { int dist = rl_dist( forest.xy(), omt_pos.xy() ); inventory tgt_inv = get_player_character().inv; std::vector pos_inv = tgt_inv.items_with( []( const item & itm ) { @@ -2030,9 +2037,9 @@ void basecamp::start_relay_hide_site() { std::vector hide_locations = { "faction_hide_site_0" }; popup( _( "You must select an existing hide site." ) ); - tripoint forest = om_target_tile( omt_pos, 10, 90, hide_locations, true, true, - omt_pos, true ); - if( forest != tripoint( -999, -999, -999 ) ) { + tripoint_abs_omt forest = om_target_tile( omt_pos, 10, 90, hide_locations, true, true, + omt_pos, true ); + if( forest != tripoint_abs_omt( -999, -999, -999 ) ) { int dist = rl_dist( forest.xy(), omt_pos.xy() ); inventory tgt_inv = get_player_character().inv; std::vector pos_inv = tgt_inv.items_with( []( const item & itm ) { @@ -2046,7 +2053,7 @@ void basecamp::start_relay_hide_site() } //Check items in improvised shelters at hide site tinymap target_bay; - target_bay.load( tripoint( forest.x * 2, forest.y * 2, forest.z ), false ); + target_bay.load( project_to( forest ), false ); std::vector hide_inv; for( item &i : target_bay.i_at( point( 11, 10 ) ) ) { hide_inv.push_back( &i ); @@ -2098,19 +2105,20 @@ void basecamp::start_fortifications( std::string &bldg_exp ) popup( _( "Select a start and end point. Line must be straight. Fields, forests, and " "swamps are valid fortification locations. In addition to existing fortification " "constructions." ) ); - tripoint start = om_target_tile( omt_pos, 2, 90, allowed_locations ); + tripoint_abs_omt start = om_target_tile( omt_pos, 2, 90, allowed_locations ); popup( _( "Select an end point." ) ); - tripoint stop = om_target_tile( omt_pos, 2, 90, allowed_locations, true, false, start ); - if( start != tripoint( -999, -999, -999 ) && stop != tripoint( -999, -999, -999 ) ) { + tripoint_abs_omt stop = om_target_tile( omt_pos, 2, 90, allowed_locations, true, false, start ); + if( start != tripoint_abs_omt( -999, -999, -999 ) && + stop != tripoint_abs_omt( -999, -999, -999 ) ) { const recipe &making = recipe_id( bldg_exp ).obj(); - bool change_x = ( start.x != stop.x ); - bool change_y = ( start.y != stop.y ); + bool change_x = ( start.x() != stop.x() ); + bool change_y = ( start.y() != stop.y() ); if( change_x && change_y ) { popup( "Construction line must be straight!" ); return; } if( bldg_exp == "faction_wall_level_N_1" ) { - std::vector tmp_line = line_to( stop, start, 0 ); + std::vector tmp_line = line_to( stop, start ); int line_count = tmp_line.size(); int yes_count = 0; for( auto elem : tmp_line ) { @@ -2123,15 +2131,15 @@ void basecamp::start_fortifications( std::string &bldg_exp ) return; } } - std::vector fortify_om; - if( ( change_x && stop.x < start.x ) || ( change_y && stop.y < start.y ) ) { + std::vector fortify_om; + if( ( change_x && stop.x() < start.x() ) || ( change_y && stop.y() < start.y() ) ) { //line_to doesn't include the origin point fortify_om.push_back( stop ); - std::vector tmp_line = line_to( stop, start, 0 ); + std::vector tmp_line = line_to( stop, start ); fortify_om.insert( fortify_om.end(), tmp_line.begin(), tmp_line.end() ); } else { fortify_om.push_back( start ); - std::vector tmp_line = line_to( start, stop, 0 ); + std::vector tmp_line = line_to( start, stop ); fortify_om.insert( fortify_om.end(), tmp_line.begin(), tmp_line.end() ); } int trips = 0; @@ -2191,8 +2199,8 @@ void basecamp::start_combat_mission( const std::string &miss ) { popup( _( "Select checkpoints until you reach maximum range or select the last point again " "to end." ) ); - tripoint start = omt_pos; - std::vector scout_points = om_companion_path( start, 90, true ); + tripoint_abs_omt start = omt_pos; + std::vector scout_points = om_companion_path( start, 90, true ); if( scout_points.empty() ) { return; } @@ -2274,7 +2282,7 @@ static bool farm_valid_seed( const item &itm ) return itm.is_seed() && itm.typeId() != itype_marloss_seed && itm.typeId() != itype_fungal_seeds; } -static std::pair farm_action( const tripoint &omt_tgt, farm_ops op, +static std::pair farm_action( const tripoint_abs_omt &omt_tgt, farm_ops op, const npc_ptr &comp = nullptr ) { size_t plots_cnt = 0; @@ -2296,12 +2304,13 @@ static std::pair farm_action( const tripoint &omt_tgt, farm //farm_json is what the area should look like according to jsons tinymap farm_json; - farm_json.generate( tripoint( omt_tgt.x * 2, omt_tgt.y * 2, omt_tgt.z ), calendar::turn ); + // TODO: fix point types + farm_json.generate( project_to( omt_tgt ).raw(), calendar::turn ); //farm_map is what the area actually looks like tinymap farm_map; - farm_map.load( tripoint( omt_tgt.x * 2, omt_tgt.y * 2, omt_tgt.z ), false ); - tripoint mapmin = tripoint( 0, 0, omt_tgt.z ); - tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, omt_tgt.z ); + farm_map.load( project_to( omt_tgt ), false ); + tripoint mapmin = tripoint( 0, 0, omt_tgt.z() ); + tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, omt_tgt.z() ); bool done_planting = false; Character &player_character = get_player_character(); map &here = get_map(); @@ -2394,7 +2403,7 @@ static std::pair farm_action( const tripoint &omt_tgt, farm return std::make_pair( plots_cnt, crops ); } -void basecamp::start_farm_op( const point &dir, const tripoint &omt_tgt, farm_ops op ) +void basecamp::start_farm_op( const point &dir, const tripoint_abs_omt &omt_tgt, farm_ops op ) { const std::string &dir_id = base_camps::all_directions.at( dir ).id; std::pair farm_data = farm_action( omt_tgt, op ); @@ -2442,7 +2451,7 @@ void basecamp::start_farm_op( const point &dir, const tripoint &omt_tgt, farm_op } } -bool basecamp::start_garage_chop( const point &dir, const tripoint &omt_tgt ) +bool basecamp::start_garage_chop( const point &dir, const tripoint_abs_omt &omt_tgt ) { editmap edit; vehicle *car = edit.mapgen_veh_query( omt_tgt ); @@ -2610,7 +2619,7 @@ bool basecamp::upgrade_return( const point &dir, const std::string &miss, if( e == expansions.end() ) { return false; } - const tripoint upos = e->second.pos; + const tripoint_abs_omt upos = e->second.pos; const recipe &making = recipe_id( bldg ).obj(); time_duration work_days = base_camps::to_workdays( making.batch_duration( @@ -2738,8 +2747,8 @@ void basecamp::fortifications_return() } std::string build_first = build_e; std::string build_second = build_w; - bool build_dir_NS = comp->companion_mission_points[0].y != - comp->companion_mission_points[1].y; + bool build_dir_NS = comp->companion_mission_points[0].y() != + comp->companion_mission_points[1].y(); if( build_dir_NS ) { build_first = build_s; build_second = build_n; @@ -2757,7 +2766,7 @@ void basecamp::fortifications_return() run_mapgen_update_func( build_second, build_point[pt] ); } if( comp->companion_mission_role_id == "faction_wall_level_N_0" ) { - tripoint fort_point = build_point[pt]; + tripoint_abs_omt fort_point = build_point[pt]; fortifications.push_back( fort_point ); } } @@ -2930,7 +2939,7 @@ bool basecamp::survey_return() } popup( _( "Select a tile up to %d tiles away." ), 1 ); - const tripoint where( ui::omap::choose_point() ); + const tripoint_abs_omt where( ui::omap::choose_point() ); if( where == overmap::invalid_tripoint ) { return false; } @@ -2940,7 +2949,7 @@ bool basecamp::survey_return() popup( _( "You must select a tile within %d range of the camp" ), 1 ); return false; } - if( omt_pos.z != where.z ) { + if( omt_pos.z() != where.z() ) { popup( _( "Expansions must be on the same level as the camp" ) ); return false; } @@ -2974,7 +2983,7 @@ bool basecamp::survey_return() return true; } -bool basecamp::farm_return( const std::string &task, const tripoint &omt_tgt, farm_ops op ) +bool basecamp::farm_return( const std::string &task, const tripoint_abs_omt &omt_tgt, farm_ops op ) { const std::string msg = _( "returns from working your fieldsā€¦" ); npc_ptr comp = companion_choose_return( task, 15_minutes ); @@ -3022,8 +3031,9 @@ void talk_function::draw_camp_tabs( const catacurses::window &win, wnoutrefresh( win ); } -std::string talk_function::name_mission_tabs( const tripoint &omt_pos, const std::string &role_id, - const std::string &cur_title, base_camps::tab_mode cur_tab ) +std::string talk_function::name_mission_tabs( + const tripoint_abs_omt &omt_pos, const std::string &role_id, + const std::string &cur_title, base_camps::tab_mode cur_tab ) { if( role_id != base_camps::id ) { return cur_title; @@ -3170,24 +3180,24 @@ int om_harvest_furn( npc &comp, const tripoint &omt_tgt, const furn_id &f, int c return total; } -int om_harvest_ter_est( npc &comp, const tripoint &omt_tgt, const ter_id &t, int chance ) +int om_harvest_ter_est( npc &comp, const tripoint_abs_omt &omt_tgt, const ter_id &t, int chance ) { return om_harvest_ter( comp, omt_tgt, t, chance, true, false ); } -int om_harvest_ter_break( npc &comp, const tripoint &omt_tgt, const ter_id &t, int chance ) +int om_harvest_ter_break( npc &comp, const tripoint_abs_omt &omt_tgt, const ter_id &t, int chance ) { return om_harvest_ter( comp, omt_tgt, t, chance, false, false ); } -int om_harvest_ter( npc &comp, const tripoint &omt_tgt, const ter_id &t, int chance, +int om_harvest_ter( npc &comp, const tripoint_abs_omt &omt_tgt, const ter_id &t, int chance, bool estimate, bool bring_back ) { const ter_t &ter_tgt = t.obj(); tinymap target_bay; - target_bay.load( tripoint( omt_tgt.x * 2, omt_tgt.y * 2, omt_tgt.z ), false ); + target_bay.load( project_to( omt_tgt ), false ); int harvested = 0; int total = 0; - tripoint mapmin = tripoint( 0, 0, omt_tgt.z ); - tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, omt_tgt.z ); + tripoint mapmin = tripoint( 0, 0, omt_tgt.z() ); + tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, omt_tgt.z() ); for( const tripoint &p : target_bay.points_in_rectangle( mapmin, mapmax ) ) { if( target_bay.ter( p ) == t && x_in_y( chance, 100 ) ) { total++; @@ -3211,26 +3221,27 @@ int om_harvest_ter( npc &comp, const tripoint &omt_tgt, const ter_id &t, int cha return total; } -int om_cutdown_trees_est( const tripoint &omt_tgt, int chance ) +int om_cutdown_trees_est( const tripoint_abs_omt &omt_tgt, int chance ) { return om_cutdown_trees( omt_tgt, chance, true, false ); } -int om_cutdown_trees_logs( const tripoint &omt_tgt, int chance ) +int om_cutdown_trees_logs( const tripoint_abs_omt &omt_tgt, int chance ) { return om_cutdown_trees( omt_tgt, chance, false, true ); } -int om_cutdown_trees_trunks( const tripoint &omt_tgt, int chance ) +int om_cutdown_trees_trunks( const tripoint_abs_omt &omt_tgt, int chance ) { return om_cutdown_trees( omt_tgt, chance, false, false ); } -int om_cutdown_trees( const tripoint &omt_tgt, int chance, bool estimate, bool force_cut_trunk ) +int om_cutdown_trees( const tripoint_abs_omt &omt_tgt, int chance, bool estimate, + bool force_cut_trunk ) { tinymap target_bay; - target_bay.load( tripoint( omt_tgt.x * 2, omt_tgt.y * 2, omt_tgt.z ), false ); + target_bay.load( project_to( omt_tgt ), false ); int harvested = 0; int total = 0; - tripoint mapmin = tripoint( 0, 0, omt_tgt.z ); - tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, omt_tgt.z ); + tripoint mapmin = tripoint( 0, 0, omt_tgt.z() ); + tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, omt_tgt.z() ); for( const tripoint &p : target_bay.points_in_rectangle( mapmin, mapmax ) ) { if( target_bay.ter( p ).obj().has_flag( flag_TREE ) && rng( 0, 100 ) < chance ) { total++; @@ -3239,7 +3250,7 @@ int om_cutdown_trees( const tripoint &omt_tgt, int chance, bool estimate, bool f } // get a random number that is either 1 or -1 point dir( 3 * ( 2 * rng( 0, 1 ) - 1 ) + rng( -1, 1 ), 3 * rng( -1, 1 ) + rng( -1, 1 ) ); - tripoint to = p + tripoint( dir, omt_tgt.z ); + tripoint to = p + tripoint( dir, omt_tgt.z() ); std::vector tree = line_to( p, to, rng( 1, 8 ) ); for( auto &elem : tree ) { target_bay.destroy( elem ); @@ -3268,18 +3279,19 @@ int om_cutdown_trees( const tripoint &omt_tgt, int chance, bool estimate, bool f return harvested; } -mass_volume om_harvest_itm( const npc_ptr &comp, const tripoint &omt_tgt, int chance, bool take ) +mass_volume om_harvest_itm( const npc_ptr &comp, const tripoint_abs_omt &omt_tgt, int chance, + bool take ) { tinymap target_bay; - target_bay.load( tripoint( omt_tgt.x * 2, omt_tgt.y * 2, omt_tgt.z ), false ); + target_bay.load( project_to( omt_tgt ), false ); units::mass harvested_m = 0_gram; units::volume harvested_v = 0_ml; units::mass total_m = 0_gram; units::volume total_v = 0_ml; int total_num = 0; int harvested_num = 0; - tripoint mapmin = tripoint( 0, 0, omt_tgt.z ); - tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, omt_tgt.z ); + tripoint mapmin = tripoint( 0, 0, omt_tgt.z() ); + tripoint mapmax = tripoint( 2 * SEEX - 1, 2 * SEEY - 1, omt_tgt.z() ); for( const tripoint &p : target_bay.points_in_rectangle( mapmin, mapmax ) ) { for( const item &i : target_bay.i_at( p ) ) { total_m += i.weight( true ); @@ -3312,9 +3324,9 @@ mass_volume om_harvest_itm( const npc_ptr &comp, const tripoint &omt_tgt, int ch return results; } -tripoint om_target_tile( const tripoint &omt_pos, int min_range, int range, - const std::vector &possible_om_types, bool must_see, - bool popup_notice, const tripoint &source, bool bounce ) +tripoint_abs_omt om_target_tile( const tripoint_abs_omt &omt_pos, int min_range, int range, + const std::vector &possible_om_types, bool must_see, + bool popup_notice, const tripoint_abs_omt &source, bool bounce ) { bool errors = false; if( popup_notice ) { @@ -3323,10 +3335,10 @@ tripoint om_target_tile( const tripoint &omt_pos, int min_range, int range, std::vector bounce_locations = { "faction_hide_site_0" }; - tripoint where; + tripoint_abs_omt where; om_range_mark( omt_pos, range ); om_range_mark( omt_pos, min_range, true, "Y;X: MIN RANGE" ); - if( source == tripoint( -999, -999, -999 ) ) { + if( source == tripoint_abs_omt( -999, -999, -999 ) ) { where = ui::omap::choose_point(); } else { where = ui::omap::choose_point( source ); @@ -3335,7 +3347,7 @@ tripoint om_target_tile( const tripoint &omt_pos, int min_range, int range, om_range_mark( omt_pos, min_range, false, "Y;X: MIN RANGE" ); if( where == overmap::invalid_tripoint ) { - return tripoint( -999, -999, -999 ); + return tripoint_abs_omt( -999, -999, -999 ); } int dist = rl_dist( where.xy(), omt_pos.xy() ); if( dist > range || dist < min_range ) { @@ -3344,7 +3356,7 @@ tripoint om_target_tile( const tripoint &omt_pos, int min_range, int range, errors = true; } - tripoint omt_tgt = tripoint( where ); + tripoint_abs_omt omt_tgt = where; const oter_id &omt_ref = overmap_buffer.ter( omt_tgt ); @@ -3358,8 +3370,9 @@ tripoint om_target_tile( const tripoint &omt_pos, int min_range, int range, if( bounce && omt_ref.id().c_str() == pos_om && range > 5 ) { if( query_yn( _( "Do you want to bounce off this location to extend range?" ) ) ) { om_line_mark( omt_pos, omt_tgt ); - tripoint dest = om_target_tile( omt_tgt, 2, range * .75, possible_om_types, - true, false, omt_tgt, true ); + tripoint_abs_omt dest = + om_target_tile( omt_tgt, 2, range * .75, possible_om_types, true, false, + omt_tgt, true ); om_line_mark( omt_pos, omt_tgt, false ); return dest; } @@ -3380,25 +3393,25 @@ tripoint om_target_tile( const tripoint &omt_pos, int min_range, int range, return om_target_tile( omt_pos, min_range, range, possible_om_types ); } -void om_range_mark( const tripoint &origin, int range, bool add_notes, +void om_range_mark( const tripoint_abs_omt &origin, int range, bool add_notes, const std::string &message ) { - std::vector note_pts; + std::vector note_pts; //North Limit - for( int x = origin.x - range; x < origin.x + range + 1; x++ ) { - note_pts.push_back( tripoint( x, origin.y - range, origin.z ) ); + for( int x = origin.x() - range; x < origin.x() + range + 1; x++ ) { + note_pts.push_back( tripoint_abs_omt( x, origin.y() - range, origin.z() ) ); } //South - for( int x = origin.x - range; x < origin.x + range + 1; x++ ) { - note_pts.push_back( tripoint( x, origin.y + range, origin.z ) ); + for( int x = origin.x() - range; x < origin.x() + range + 1; x++ ) { + note_pts.push_back( tripoint_abs_omt( x, origin.y() + range, origin.z() ) ); } //West - for( int y = origin.y - range; y < origin.y + range + 1; y++ ) { - note_pts.push_back( tripoint( origin.x - range, y, origin.z ) ); + for( int y = origin.y() - range; y < origin.y() + range + 1; y++ ) { + note_pts.push_back( tripoint_abs_omt( origin.x() - range, y, origin.z() ) ); } //East - for( int y = origin.y - range; y < origin.y + range + 1; y++ ) { - note_pts.push_back( tripoint( origin.x + range, y, origin.z ) ); + for( int y = origin.y() - range; y < origin.y() + range + 1; y++ ) { + note_pts.push_back( tripoint_abs_omt( origin.x() + range, y, origin.z() ) ); } for( auto pt : note_pts ) { @@ -3414,10 +3427,10 @@ void om_range_mark( const tripoint &origin, int range, bool add_notes, } } -void om_line_mark( const tripoint &origin, const tripoint &dest, bool add_notes, +void om_line_mark( const tripoint_abs_omt &origin, const tripoint_abs_omt &dest, bool add_notes, const std::string &message ) { - std::vector note_pts = line_to( origin, dest ); + std::vector note_pts = line_to( origin, dest ); for( auto pt : note_pts ) { if( add_notes ) { @@ -3439,12 +3452,12 @@ std::string get_mission_action_string( const std::string &input_mission ) } -bool om_set_hide_site( npc &comp, const tripoint &omt_tgt, +bool om_set_hide_site( npc &comp, const tripoint_abs_omt &omt_tgt, const std::vector &itms, const std::vector &itms_rem ) { tinymap target_bay; - target_bay.load( tripoint( omt_tgt.x * 2, omt_tgt.y * 2, omt_tgt.z ), false ); + target_bay.load( project_to( omt_tgt ), false ); target_bay.ter_set( point( 11, 10 ), t_improvised_shelter ); for( auto i : itms_rem ) { comp.companion_mission_inv.add_item( *i ); @@ -3464,14 +3477,14 @@ bool om_set_hide_site( npc &comp, const tripoint &omt_tgt, } // path and travel time -time_duration companion_travel_time_calc( const tripoint &omt_pos, - const tripoint &omt_tgt, time_duration work, int trips, int haulage ) +time_duration companion_travel_time_calc( const tripoint_abs_omt &omt_pos, + const tripoint_abs_omt &omt_tgt, time_duration work, int trips, int haulage ) { - std::vector journey = line_to( omt_pos, omt_tgt ); + std::vector journey = line_to( omt_pos, omt_tgt ); return companion_travel_time_calc( journey, work, trips, haulage ); } -time_duration companion_travel_time_calc( const std::vector &journey, +time_duration companion_travel_time_calc( const std::vector &journey, time_duration work, int trips, int haulage ) { int one_way = 0; @@ -3522,23 +3535,23 @@ int om_carry_weight_to_trips( const std::vector &itms, const npc_ptr &co return om_carry_weight_to_trips( total_m, total_v, max_m, max_v ); } -std::vector om_companion_path( const tripoint &start, int range_start, +std::vector om_companion_path( const tripoint_abs_omt &start, int range_start, bool bounce ) { - std::vector scout_points; - tripoint last = start; + std::vector scout_points; + tripoint_abs_omt last = start; int range = range_start; int def_range = range_start; while( range > 3 ) { - tripoint spt = om_target_tile( last, 0, range, {}, false, true, last, false ); - if( spt == tripoint( -999, -999, -999 ) ) { + tripoint_abs_omt spt = om_target_tile( last, 0, range, {}, false, true, last, false ); + if( spt == tripoint_abs_omt( -999, -999, -999 ) ) { scout_points.clear(); return scout_points; } if( last == spt ) { break; } - std::vector note_pts = line_to( last, spt ); + std::vector note_pts = line_to( last, spt ); scout_points.insert( scout_points.end(), note_pts.begin(), note_pts.end() ); om_line_mark( last, spt ); range -= rl_dist( spt.xy(), last.xy() ); @@ -3619,11 +3632,11 @@ bool basecamp::set_sort_points() } // camp analysis functions -std::vector> talk_function::om_building_region( - const tripoint &omt_pos, int range, bool purge ) +std::vector> talk_function::om_building_region( + const tripoint_abs_omt &omt_pos, int range, bool purge ) { - std::vector> om_camp_region; - for( const tripoint &omt_near_pos : points_in_radius( omt_pos, range ) ) { + std::vector> om_camp_region; + for( const tripoint_abs_omt &omt_near_pos : points_in_radius( omt_pos, range ) ) { const oter_id &omt_rnear = overmap_buffer.ter( omt_near_pos ); std::string om_rnear_id = omt_rnear.id().c_str(); if( !purge || ( om_rnear_id.find( "faction_base_" ) != std::string::npos && @@ -3634,9 +3647,11 @@ std::vector> talk_function::om_building_region( return om_camp_region; } -point talk_function::om_simple_dir( const tripoint &omt_pos, const tripoint &omt_tar ) +point talk_function::om_simple_dir( const tripoint_abs_omt &omt_pos, + const tripoint_abs_omt &omt_tar ) { - return { clamp( omt_tar.x - omt_pos.x, -1, 1 ), clamp( omt_tar.y - omt_pos.y, -1, 1 ) }; + point_rel_omt diff = omt_tar.xy() - omt_pos.xy(); + return { clamp( diff.x(), -1, 1 ), clamp( diff.y(), -1, 1 ) }; } // mission descriptions @@ -3796,7 +3811,7 @@ std::string basecamp::gathering_description( const std::string &bldg ) return output; } -std::string basecamp::farm_description( const tripoint &farm_pos, size_t &plots_count, +std::string basecamp::farm_description( const tripoint_abs_omt &farm_pos, size_t &plots_count, farm_ops operation ) { std::pair farm_data = farm_action( farm_pos, operation ); @@ -4008,7 +4023,7 @@ void basecamp::place_results( const item &result ) { if( by_radio ) { tinymap target_bay; - target_bay.load( tripoint( omt_pos.x * 2, omt_pos.y * 2, omt_pos.z ), false ); + target_bay.load( project_to( omt_pos ), false ); const tripoint &new_spot = target_bay.getlocal( get_dumping_spot() ); target_bay.add_item_or_charges( new_spot, result, true ); apply_camp_ownership( new_spot, 10 ); diff --git a/src/faction_camp.h b/src/faction_camp.h index 6c10344d87414..cc33b399a86e4 100644 --- a/src/faction_camp.h +++ b/src/faction_camp.h @@ -45,13 +45,13 @@ void remove_overseer( npc & ); void draw_camp_tabs( const catacurses::window &win, base_camps::tab_mode cur_tab, const std::vector> &entries ); -std::string name_mission_tabs( const tripoint &omt_pos, const std::string &role_id, +std::string name_mission_tabs( const tripoint_abs_omt &omt_pos, const std::string &role_id, const std::string &cur_title, base_camps::tab_mode cur_tab ); /// Returns the OM tiles surrounding the camp, @ref purge removes all tiles that aren't expansions -std::vector> om_building_region( const tripoint &omt_pos, - int range, bool purge = false ); +std::vector> om_building_region( + const tripoint_abs_omt &omt_pos, int range, bool purge = false ); /// Returns the x and y coordinates of ( omt_tar - omt_pos ), clamped to [-1, 1] -point om_simple_dir( const tripoint &omt_pos, const tripoint &omt_tar ); +point om_simple_dir( const tripoint_abs_omt &omt_pos, const tripoint_abs_omt &omt_tar ); } // namespace talk_function #endif // CATA_SRC_FACTION_CAMP_H diff --git a/src/flood_fill.h b/src/flood_fill.h index 595266242754f..65ee3709b3d60 100644 --- a/src/flood_fill.h +++ b/src/flood_fill.h @@ -22,15 +22,15 @@ namespace ff * @param predicate UnaryPredicate that will be provided with a point for evaluation as to whether or * not the point should be filled. */ -template -std::vector point_flood_fill_4_connected( const point &starting_point, - std::unordered_set &visited, UnaryPredicate predicate ) +template +std::vector point_flood_fill_4_connected( const Point &starting_point, + std::unordered_set &visited, UnaryPredicate predicate ) { - std::vector filled_points; - std::queue to_check; + std::vector filled_points; + std::queue to_check; to_check.push( starting_point ); while( !to_check.empty() ) { - const point current_point = to_check.front(); + const Point current_point = to_check.front(); to_check.pop(); if( visited.find( current_point ) != visited.end() ) { diff --git a/src/game.cpp b/src/game.cpp index f88631c123960..2352ae8d3d951 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -633,6 +633,12 @@ special_game_type game::gametype() const } void game::load_map( const tripoint &pos_sm ) +{ + // TODO: fix point types + m.load( pos_sm, true ); +} + +void game::load_map( const tripoint_abs_sm &pos_sm ) { m.load( pos_sm, true ); } @@ -665,7 +671,7 @@ bool game::start_game() const start_location &start_loc = u.random_start_location ? scen->random_start_location().obj() : u.start_location.obj(); - const tripoint omtstart = start_loc.find_player_initial_location(); + const tripoint_abs_omt omtstart = start_loc.find_player_initial_location(); if( omtstart == overmap::invalid_tripoint ) { return false; } @@ -677,7 +683,8 @@ bool game::start_game() start_loc.add_map_extra( omtstart, scen->get_map_extra() ); } - tripoint lev = omt_to_sm_copy( omtstart ); + // TODO: fix point types + tripoint lev = project_to( omtstart ).raw(); // The player is centered in the map, but lev[xyz] refers to the top left point of the map lev.x -= HALF_MAPSIZE; lev.y -= HALF_MAPSIZE; @@ -817,14 +824,15 @@ bool game::start_game() u.custom_profession, getVersionString() ); time_played_at_last_load = std::chrono::seconds( 0 ); time_of_last_load = std::chrono::steady_clock::now(); - tripoint abs_omt = u.global_omt_location(); + tripoint_abs_omt abs_omt = u.global_omt_location(); const oter_id &cur_ter = overmap_buffer.ter( abs_omt ); - get_event_bus().send( abs_omt, cur_ter ); + get_event_bus().send( abs_omt.raw(), cur_ter ); return true; } -vehicle *game::place_vehicle_nearby( const vproto_id &id, const point &origin, int min_distance, - int max_distance, const std::vector &omt_search_types ) +vehicle *game::place_vehicle_nearby( + const vproto_id &id, const point_abs_omt &origin, int min_distance, + int max_distance, const std::vector &omt_search_types ) { std::vector search_types = omt_search_types; if( search_types.empty() ) { @@ -848,12 +856,12 @@ vehicle *game::place_vehicle_nearby( const vproto_id &id, const point &origin, i find_params.min_distance = min_distance; find_params.search_range = max_distance; // if player spawns underground, park their car on the surface. - const tripoint omt_origin( origin, 0 ); - for( const tripoint &goal : overmap_buffer.find_all( omt_origin, find_params ) ) { + const tripoint_abs_omt omt_origin( origin, 0 ); + for( const tripoint_abs_omt &goal : overmap_buffer.find_all( omt_origin, find_params ) ) { // try place vehicle there. tinymap target_map; - target_map.load( omt_to_sm_copy( goal ), false ); - const tripoint tinymap_center( SEEX, SEEY, goal.z ); + target_map.load( project_to( goal ), false ); + const tripoint tinymap_center( SEEX, SEEY, goal.z() ); static const std::vector angles = {0, 90, 180, 270}; vehicle *veh = target_map.add_vehicle( id, tinymap_center, random_entry( angles ), rng( 50, 80 ), 0, false ); @@ -1946,7 +1954,7 @@ void game::validate_camps() if( camp.is_valid() ) { overmap_buffer.add_camp( camp ); m.remove_submap_camp( u.pos() ); - } else if( camp.camp_omt_pos() != tripoint_zero ) { + } else if( camp.camp_omt_pos() != tripoint_abs_omt() ) { std::string camp_name = _( "Faction Camp" ); camp.set_name( camp_name ); overmap_buffer.add_camp( camp ); @@ -3302,13 +3310,13 @@ void game::display_faction_epilogues() } struct npc_dist_to_player { - const tripoint ppos{}; + const tripoint_abs_omt ppos{}; npc_dist_to_player() : ppos( get_player_character().global_omt_location() ) { } // Operator overload required to leverage sort API. bool operator()( const shared_ptr_fast &a, const shared_ptr_fast &b ) const { - const tripoint apos = a->global_omt_location(); - const tripoint bpos = b->global_omt_location(); + const tripoint_abs_omt apos = a->global_omt_location(); + const tripoint_abs_omt bpos = b->global_omt_location(); return square_dist( ppos.xy(), apos.xy() ) < square_dist( ppos.xy(), bpos.xy() ); } @@ -3316,7 +3324,7 @@ struct npc_dist_to_player { void game::disp_NPCs() { - const tripoint ppos = u.global_omt_location(); + const tripoint_abs_omt ppos = u.global_omt_location(); const tripoint &lpos = u.pos(); const int scan_range = 120; std::vector> npcs = overmap_buffer.get_npcs_near_player( scan_range ); @@ -3333,11 +3341,9 @@ void game::disp_NPCs() ui.mark_resize(); ui.on_redraw( [&]( const ui_adaptor & ) { werase( w ); - mvwprintz( w, point_zero, c_white, _( "Your overmap position: %d, %d, %d" ), ppos.x, ppos.y, - ppos.z ); + mvwprintz( w, point_zero, c_white, _( "Your overmap position: %s" ), ppos.to_string() ); // NOLINTNEXTLINE(cata-use-named-point-constants) - mvwprintz( w, point( 0, 1 ), c_white, _( "Your local position: %d, %d, %d" ), lpos.x, lpos.y, - lpos.z ); + mvwprintz( w, point( 0, 1 ), c_white, _( "Your local position: %s" ), lpos.to_string() ); size_t i; int static_npc_count = 0; for( i = 0; i < npcs.size(); i++ ) { @@ -3349,9 +3355,9 @@ void game::disp_NPCs() mvwprintz( w, point( 0, 2 ), c_white, _( "Total NPCs within %d OMTs: %d. %d are static NPCs." ), scan_range, npcs.size(), static_npc_count ); for( i = 0; i < 20 && i < npcs.size(); i++ ) { - const tripoint apos = npcs[i]->global_omt_location(); - mvwprintz( w, point( 0, i + 4 ), c_white, "%s: %d, %d, %d", npcs[i]->name, - apos.x, apos.y, apos.z ); + const tripoint_abs_omt apos = npcs[i]->global_omt_location(); + mvwprintz( w, point( 0, i + 4 ), c_white, "%s: %s", npcs[i]->name, + apos.to_string() ); } for( const monster &m : all_monsters() ) { mvwprintz( w, point( 0, i + 4 ), c_white, "%s: %d, %d, %d", m.name(), @@ -3761,16 +3767,16 @@ void game::draw_minimap() werase( w_minimap ); draw_border( w_minimap ); - const tripoint curs = u.global_omt_location(); - const point curs2( curs.xy() ); - const tripoint targ = u.get_active_mission_target(); + const tripoint_abs_omt curs = u.global_omt_location(); + const point_abs_omt curs2( curs.xy() ); + const tripoint_abs_omt targ = u.get_active_mission_target(); bool drew_mission = targ == overmap::invalid_tripoint; for( int i = -2; i <= 2; i++ ) { for( int j = -2; j <= 2; j++ ) { - const point om( curs2 + point( i, j ) ); + const point_abs_omt om( curs2 + point( i, j ) ); nc_color ter_color; - tripoint omp( om, get_levz() ); + tripoint_abs_omt omp( om, get_levz() ); std::string ter_sym; const bool seen = overmap_buffer.seen( omp ); const bool vehicle_here = overmap_buffer.has_vehicle( omp ); @@ -3896,11 +3902,11 @@ void game::draw_minimap() // Print arrow to mission if we have one! if( !drew_mission ) { - double slope = ( curs2.x != targ.x ) ? static_cast( targ.y - curs2.y ) / static_cast - ( targ.x - curs2.x ) : 4; + double slope = curs2.x() != targ.x() ? + static_cast( targ.y() - curs2.y() ) / ( targ.x() - curs2.x() ) : 4; - if( curs2.x == targ.x || std::fabs( slope ) > 3.5 ) { // Vertical slope - if( targ.y > curs2.y ) { + if( curs2.x() == targ.x() || std::fabs( slope ) > 3.5 ) { // Vertical slope + if( targ.y() > curs2.y() ) { mvwputch( w_minimap, point( 3, 6 ), c_red, "*" ); } else { mvwputch( w_minimap, point( 3, 0 ), c_red, "*" ); @@ -3909,8 +3915,9 @@ void game::draw_minimap() int arrowx = -1; int arrowy = -1; if( std::fabs( slope ) >= 1. ) { // y diff is bigger! - arrowy = ( targ.y > curs2.y ? 6 : 0 ); - arrowx = static_cast( 3 + 3 * ( targ.y > curs2.y ? slope : ( 0 - slope ) ) ); + arrowy = targ.y() > curs2.y() ? 6 : 0; + arrowx = + static_cast( 3 + 3 * ( targ.y() > curs2.y() ? slope : ( 0 - slope ) ) ); if( arrowx < 0 ) { arrowx = 0; } @@ -3918,8 +3925,8 @@ void game::draw_minimap() arrowx = 6; } } else { - arrowx = ( targ.x > curs2.x ? 6 : 0 ); - arrowy = static_cast( 3 + 3 * ( targ.x > curs2.x ? slope : ( 0 - slope ) ) ); + arrowx = targ.x() > curs2.x() ? 6 : 0; + arrowy = static_cast( 3 + 3 * ( targ.x() > curs2.x() ? slope : -slope ) ); if( arrowy < 0 ) { arrowy = 0; } @@ -3928,9 +3935,9 @@ void game::draw_minimap() } } char glyph = '*'; - if( targ.z > u.posz() ) { + if( targ.z() > u.posz() ) { glyph = '^'; - } else if( targ.z < u.posz() ) { + } else if( targ.z() < u.posz() ) { glyph = 'v'; } @@ -3946,15 +3953,10 @@ void game::draw_minimap() if( i > -3 && i < 3 && j > -3 && j < 3 ) { continue; // only do hordes on the border, skip inner map } - const int omx = curs2.x + i; - const int omy = curs2.y + j; - tripoint omp( omx, omy, get_levz() ); + const tripoint_abs_omt omp( curs2 + point( i, j ), get_levz() ); if( overmap_buffer.get_horde_size( omp ) >= HORDE_VISIBILITY_SIZE ) { - const tripoint cur_pos { - omx, omy, get_levz() - }; if( overmap_buffer.seen( omp ) - && player_character.overmap_los( cur_pos, sight_points ) ) { + && player_character.overmap_los( omp, sight_points ) ) { mvwputch( w_minimap, point( i + 3, j + 3 ), c_green, overmap_buffer.get_horde_size( omp ) > HORDE_VISIBILITY_SIZE * 2 ? 'Z' : 'z' ); } @@ -4657,7 +4659,9 @@ void game::overmap_npc_move() if( elem->omt_path.back() == elem->global_omt_location() ) { elem->omt_path.pop_back(); } - elem->travel_overmap( omt_to_sm_copy( elem->omt_path.back() ) ); + // TODO: fix point types + elem->travel_overmap( + project_to( elem->omt_path.back() ).raw() ); } reload_npcs(); } @@ -6864,8 +6868,9 @@ void game::zones_manager() } else if( action == "SHOW_ZONE_ON_MAP" ) { //show zone position on overmap; - tripoint player_overmap_position = ms_to_omt_copy( m.getabs( u.pos() ) ); - tripoint zone_overmap = ms_to_omt_copy( zones[active_index].get().get_center_point() ); + tripoint_abs_omt player_overmap_position = u.global_omt_location(); + // TODO: fix point types + tripoint_abs_omt zone_overmap( ms_to_omt_copy( zones[active_index].get().get_center_point() ) ); ui::omap::display_zones( player_overmap_position, zone_overmap, active_index ); } else if( action == "ENABLE_ZONE" ) { @@ -6926,7 +6931,9 @@ void game::pre_print_all_tile_info( const tripoint &lp, const catacurses::window const visibility_variables &cache ) { // get global area info according to look_around caret position - const oter_id &cur_ter_m = overmap_buffer.ter( ms_to_omt_copy( m.getabs( lp ) ) ); + // TODO: fix point types + const oter_id &cur_ter_m = overmap_buffer.ter( tripoint_abs_omt( ms_to_omt_copy( m.getabs( + lp ) ) ) ); // we only need the area name and then pass it to print_all_tile_info() function below const std::string area_name = cur_ter_m->get_name(); print_all_tile_info( lp, w_info, area_name, 1, first_line, last_line, cache ); @@ -9960,7 +9967,7 @@ point game::place_player( const tripoint &dest_loc ) return submap_shift; } -void game::place_player_overmap( const tripoint &om_dest ) +void game::place_player_overmap( const tripoint_abs_omt &om_dest ) { // if player is teleporting around, they don't bring their horse with them if( u.is_mounted() ) { @@ -9985,10 +9992,11 @@ void game::place_player_overmap( const tripoint &om_dest ) m.access_cache( get_levz() ).map_memory_seen_cache.reset(); // offset because load_map expects the coordinates of the top left corner, but the // player will be centered in the middle of the map. - const tripoint map_om_pos( tripoint( 2 * om_dest.x, 2 * om_dest.y, - om_dest.z ) + point( -HALF_MAPSIZE, -HALF_MAPSIZE ) ); - const tripoint player_pos( u.pos().xy(), map_om_pos.z ); - load_map( map_om_pos ); + // TODO: fix point types + const tripoint map_sm_pos( + project_to( om_dest ).raw() + point( -HALF_MAPSIZE, -HALF_MAPSIZE ) ); + const tripoint player_pos( u.pos().xy(), map_sm_pos.z ); + load_map( map_sm_pos ); load_npcs(); m.spawn_monsters( true ); // Static monsters update_overmap_seen(); @@ -11127,9 +11135,9 @@ void game::vertical_notes( int z_before, int z_after ) // Figure out where we know there are up/down connectors // Fill in all the tiles we know about (e.g. subway stations) static const int REVEAL_RADIUS = 40; - for( const tripoint &p : points_in_radius( u.global_omt_location(), REVEAL_RADIUS ) ) { - const tripoint cursp_before( p.xy(), z_before ); - const tripoint cursp_after( p.xy(), z_after ); + for( const tripoint_abs_omt &p : points_in_radius( u.global_omt_location(), REVEAL_RADIUS ) ) { + const tripoint_abs_omt cursp_before( p.xy(), z_before ); + const tripoint_abs_omt cursp_after( p.xy(), z_after ); if( !overmap_buffer.seen( cursp_before ) ) { continue; @@ -11253,26 +11261,27 @@ point game::update_map( int &x, int &y ) void game::update_overmap_seen() { - const tripoint ompos = u.global_omt_location(); + const tripoint_abs_omt ompos = u.global_omt_location(); const int dist = u.overmap_sight_range( light_level( u.posz() ) ); const int dist_squared = dist * dist; // We can always see where we're standing overmap_buffer.set_seen( ompos, true ); - for( const tripoint &p : points_in_radius( ompos, dist ) ) { - const point delta = p.xy() - ompos.xy(); - const int h_squared = delta.x * delta.x + delta.y * delta.y; + for( const tripoint_abs_omt &p : points_in_radius( ompos, dist ) ) { + const point_rel_omt delta = p.xy() - ompos.xy(); + const int h_squared = delta.x() * delta.x() + delta.y() * delta.y(); if( trigdist && h_squared > dist_squared ) { continue; } - if( delta == point_zero ) { + if( delta == point_rel_omt() ) { // 1. This case is already handled outside of the loop // 2. Calculating multiplier would cause division by zero continue; } // If circular distances are enabled, scale overmap distances by the diagonality of the sight line. - const float multiplier = trigdist ? std::sqrt( h_squared ) / std::max( std::abs( delta.x ), - std::abs( delta.y ) ) : 1; - const std::vector line = line_to( ompos, p, 0 ); + point abs_delta = delta.raw().abs(); + int max_delta = std::max( abs_delta.x, abs_delta.y ); + const float multiplier = trigdist ? std::sqrt( h_squared ) / max_delta : 1; + const std::vector line = line_to( ompos, p ); float sight_points = dist; for( auto it = line.begin(); it != line.end() && sight_points >= 0; ++it ) { @@ -11280,11 +11289,11 @@ void game::update_overmap_seen() sight_points -= static_cast( ter->get_see_cost() ) * multiplier; } if( sight_points >= 0 ) { - tripoint seen( p ); + tripoint_abs_omt seen( p ); do { overmap_buffer.set_seen( seen, true ); - --seen.z; - } while( seen.z >= 0 ); + --seen.z(); + } while( seen.z() >= 0 ); } } } @@ -11583,16 +11592,16 @@ void game::perhaps_add_random_npc() return; } bool spawn_allowed = false; - tripoint spawn_point; + tripoint_abs_omt spawn_point; int counter = 0; while( !spawn_allowed ) { if( counter >= 10 ) { return; } - const tripoint u_omt = u.global_omt_location(); + const tripoint_abs_omt u_omt = u.global_omt_location(); spawn_point = u_omt + point( rng( -radius_spawn_range, radius_spawn_range ), rng( -radius_spawn_range, radius_spawn_range ) ); - spawn_point.z = 0; + spawn_point.z() = 0; const oter_id oter = overmap_buffer.ter( spawn_point ); // shouldn't spawn on lakes or rivers. if( !is_river_or_lake( oter ) ) { @@ -11611,7 +11620,8 @@ void game::perhaps_add_random_npc() tmp->set_fac( new_solo_fac ? new_solo_fac->id : faction_id( "no_faction" ) ); // adds the npc to the correct overmap. // Only spawn random NPCs on z-level 0 - tripoint submap_spawn = omt_to_sm_copy( spawn_point ); + // TODO: fix point types + tripoint submap_spawn = omt_to_sm_copy( spawn_point.raw() ); tmp->spawn_at_sm( tripoint( submap_spawn.xy(), 0 ) ); overmap_buffer.insert_npc( tmp ); tmp->form_opinion( u ); @@ -12370,7 +12380,8 @@ overmap &game::get_cur_om() const // The player is located in the middle submap of the map. const tripoint sm = m.get_abs_sub() + tripoint( HALF_MAPSIZE, HALF_MAPSIZE, 0 ); const tripoint pos_om = sm_to_om_copy( sm ); - return overmap_buffer.get( pos_om.xy() ); + // TODO: fix point types + return overmap_buffer.get( point_abs_om( pos_om.xy() ) ); } std::vector game::allies() @@ -12577,11 +12588,12 @@ void avatar_moves( const tripoint &old_abs_pos, const avatar &u, const map &m ) get_event_bus().send( mount_type, m.ter( new_pos ).id(), u.current_movement_mode(), u.is_underwater(), new_pos.z ); - const tripoint old_abs_omt = ms_to_omt_copy( old_abs_pos ); - const tripoint new_abs_omt = ms_to_omt_copy( new_abs_pos ); + // TODO: fix point types + const tripoint_abs_omt old_abs_omt( ms_to_omt_copy( old_abs_pos ) ); + const tripoint_abs_omt new_abs_omt( ms_to_omt_copy( new_abs_pos ) ); if( old_abs_omt != new_abs_omt ) { const oter_id &cur_ter = overmap_buffer.ter( new_abs_omt ); - get_event_bus().send( new_abs_omt, cur_ter ); + get_event_bus().send( new_abs_omt.raw(), cur_ter ); } } } // namespace cata_event_dispatch diff --git a/src/game.h b/src/game.h index 61c40fd6b7b61..b8f15bbaddb9b 100644 --- a/src/game.h +++ b/src/game.h @@ -19,6 +19,7 @@ #include "action.h" #include "calendar.h" #include "character_id.h" +#include "coordinates.h" #include "creature.h" #include "cursesdef.h" #include "enums.h" @@ -652,6 +653,7 @@ class game * coordinates. */ void load_map( const tripoint &pos_sm ); + void load_map( const tripoint_abs_sm &pos_sm ); /** * The overmap which contains the center submap of the reality bubble. */ @@ -775,8 +777,9 @@ class game void init_autosave(); // Initializes autosave parameters void create_starting_npcs(); // Creates NPCs that start near you // create vehicle nearby, for example; for a profession vehicle. - vehicle *place_vehicle_nearby( const vproto_id &id, const point &origin, int min_distance, - int max_distance, const std::vector &omt_search_types = {} ); + vehicle *place_vehicle_nearby( + const vproto_id &id, const point_abs_omt &origin, int min_distance, + int max_distance, const std::vector &omt_search_types = {} ); // V Menu Functions and helpers: void list_items_monsters(); // Called when you invoke the `V`-menu @@ -819,7 +822,7 @@ class game void reload_weapon( bool try_everything = true ); // Reload a wielded gun/tool 'r' // Places the player at the specified point; hurts feet, lists items etc. point place_player( const tripoint &dest ); - void place_player_overmap( const tripoint &om_dest ); + void place_player_overmap( const tripoint_abs_omt &om_dest ); unsigned int get_seed() const; diff --git a/src/gamemode_defense.cpp b/src/gamemode_defense.cpp index 6e572aa61a9bf..f0bac731c537f 100644 --- a/src/gamemode_defense.cpp +++ b/src/gamemode_defense.cpp @@ -122,7 +122,7 @@ bool defense_game::init() setup(); player_character.cash = initial_cash; // TODO: support multiple defense games? clean up old defense game - defloc_pos = tripoint( 50, 50, 0 ); + defloc_pos = tripoint_om_omt( 50, 50, 0 ); init_map(); caravan(); return true; @@ -229,10 +229,10 @@ void defense_game::init_map() ui_manager::redraw(); refresh_display(); - auto &starting_om = overmap_buffer.get( point_zero ); + auto &starting_om = overmap_buffer.get( point_abs_om() ); for( int x = 0; x < OMAPX; x++ ) { for( int y = 0; y < OMAPY; y++ ) { - tripoint p( x, y, 0 ); + tripoint_om_omt p( x, y, 0 ); starting_om.ter_set( p, oter_id( "field" ) ); starting_om.seen( p ) = true; } @@ -294,7 +294,9 @@ void defense_game::init_map() } } - g->load_map( omt_to_sm_copy( defloc_pos ) ); + // For this mode assume we always want overmap zero. + tripoint_abs_omt abs_defloc_pos = project_combine( point_abs_om(), defloc_pos ); + g->load_map( project_to( abs_defloc_pos ) ); Character &player_character = get_player_character(); player_character.setx( SEEX ); player_character.sety( SEEY ); diff --git a/src/gamemode_defense.h b/src/gamemode_defense.h index 548e6328645bc..bf4f304c5a5da 100644 --- a/src/gamemode_defense.h +++ b/src/gamemode_defense.h @@ -124,7 +124,7 @@ struct defense_game : public special_game { bool allow_save = false; // Start defence location position on overmap - tripoint defloc_pos; + tripoint_om_omt defloc_pos; // Defense location special overmap_special_id defloc_special; diff --git a/src/gamemode_tutorial.cpp b/src/gamemode_tutorial.cpp index 6c5048c63c9ea..73e35c2719e61 100644 --- a/src/gamemode_tutorial.cpp +++ b/src/gamemode_tutorial.cpp @@ -129,11 +129,13 @@ bool tutorial_game::init() player_character.name = _( "John Smith" ); player_character.prof = profession::generic(); // overmap terrain coordinates - const tripoint lp( 50, 50, 0 ); - auto &starting_om = overmap_buffer.get( point_zero ); + const tripoint_om_omt lp( 50, 50, 0 ); + // Assume overmap zero + const tripoint_abs_omt lp_abs = project_combine( point_abs_om(), lp ); + auto &starting_om = overmap_buffer.get( point_abs_om() ); for( int i = 0; i < OMAPX; i++ ) { for( int j = 0; j < OMAPY; j++ ) { - tripoint p( i, j, 0 ); + tripoint_om_omt p( i, j, 0 ); starting_om.ter_set( p + tripoint_below, rock ); // Start with the overmap revealed starting_om.seen( p ) = true; @@ -149,7 +151,7 @@ bool tutorial_game::init() player_character.inv.add_item( lighter, true, false ); player_character.set_skill_level( skill_gun, 5 ); player_character.set_skill_level( skill_melee, 5 ); - g->load_map( omt_to_sm_copy( lp ) ); + g->load_map( project_to( lp_abs ) ); player_character.setx( 2 ); player_character.sety( 4 ); diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 8d0aec3dec5ab..56c46a19afe64 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -373,9 +373,10 @@ void iexamine::gaspump( player &p, const tripoint &examp ) void iexamine::translocator( player &, const tripoint &examp ) { - const tripoint omt_loc = ms_to_omt_copy( get_map().getabs( examp ) ); + // TODO: fix point types + const tripoint_abs_omt omt_loc( ms_to_omt_copy( get_map().getabs( examp ) ) ); avatar &player_character = get_avatar(); - const bool activated = player_character.translocators.knows_translocator( examp ); + const bool activated = player_character.translocators.knows_translocator( omt_loc ); if( !activated ) { player_character.translocators.activate_teleporter( omt_loc, examp ); add_msg( m_info, _( "Translocator gate active." ) ); @@ -1487,7 +1488,8 @@ void iexamine::bulletin_board( player &p, const tripoint &examp ) { g->validate_camps(); map &here = get_map(); - point omt = ms_to_omt_copy( here.getabs( examp.xy() ) ); + // TODO: fix point types + point_abs_omt omt( ms_to_omt_copy( here.getabs( examp.xy() ) ) ); cata::optional bcp = overmap_buffer.find_camp( omt ); if( bcp ) { basecamp *temp_camp = *bcp; diff --git a/src/item.cpp b/src/item.cpp index 0cd08812e311a..24ddd6d44621c 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -4819,8 +4819,12 @@ std::string item::display_name( unsigned int quantity ) const // HACK: This is a hack to prevent possible crashing when displaying maps as items during character creation if( is_map() && calendar::turn != calendar::turn_zero ) { - const city *c = overmap_buffer.closest_city( omt_to_sm_copy( get_var( "reveal_map_center_omt", - player_character.global_omt_location() ) ) ).city; + // TODO: fix point types + tripoint map_pos_omt = + get_var( "reveal_map_center_omt", player_character.global_omt_location().raw() ); + tripoint_abs_sm map_pos = + project_to( tripoint_abs_omt( map_pos_omt ) ); + const city *c = overmap_buffer.closest_city( map_pos ).city; if( c != nullptr ) { name = string_format( "%s %s", c->name, name ); } diff --git a/src/iuse.cpp b/src/iuse.cpp index 6fced8977ae9c..3ae531d430c78 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -1829,7 +1829,9 @@ static bool good_fishing_spot( tripoint pos, player *p ) std::vector fishables = g->get_fishable_monsters( fishable_locations ); map &here = get_map(); // isolated little body of water with no definite fish population - const oter_id &cur_omt = overmap_buffer.ter( ms_to_omt_copy( here.getabs( pos ) ) ); + // TODO: fix point types + const oter_id &cur_omt = + overmap_buffer.ter( tripoint_abs_omt( ms_to_omt_copy( here.getabs( pos ) ) ) ); std::string om_id = cur_omt.id().c_str(); if( fishables.empty() && !here.has_flag( "CURRENT", pos ) && om_id.find( "river_" ) == std::string::npos && !cur_omt->is_lake() && !cur_omt->is_lake_shore() ) { @@ -2258,9 +2260,9 @@ int iuse::directional_antenna( player *p, item *it, bool, const tripoint & ) return 0; } // Report direction. - const auto player_pos = p->global_sm_location(); - direction angle = direction_from( player_pos.xy(), - tref.abs_sm_pos ); + // TODO: fix point types + const tripoint_abs_sm player_pos( p->global_sm_location() ); + direction angle = direction_from( player_pos.xy(), tref.abs_sm_pos ); add_msg( _( "The signal seems strongest to the %s." ), direction_name( angle ) ); return it->type->charges_to_use(); } @@ -5443,9 +5445,8 @@ int iuse::artifact( player *p, item *it, bool, const tripoint & ) break; case AEA_MAP: { - const tripoint center = p->global_omt_location(); - const bool new_map = overmap_buffer.reveal( - center.xy(), 20, center.z ); + const tripoint_abs_omt center = p->global_omt_location(); + const bool new_map = overmap_buffer.reveal( center.xy(), 20, center.z() ); if( new_map ) { p->add_msg_if_player( m_warning, _( "You have a vision of the surrounding areaā€¦" ) ); p->moves -= to_moves( 1_seconds ); @@ -7601,7 +7602,9 @@ static extended_photo_def photo_def_for_camera_point( const tripoint &aim_point, obj_list ); } - const oter_id &cur_ter = overmap_buffer.ter( ms_to_omt_copy( here.getabs( aim_point ) ) ); + // TODO: fix point types + const oter_id &cur_ter = + overmap_buffer.ter( tripoint_abs_omt( ms_to_omt_copy( here.getabs( aim_point ) ) ) ); std::string overmap_desc = string_format( _( "In the background you can see a %s" ), colorize( cur_ter->get_name(), cur_ter->get_color() ) ); if( outside_tiles_num == total_tiles_num ) { diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index a3ca3671f5b33..85e64371565bf 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -1171,7 +1171,7 @@ void reveal_map_actor::load( const JsonObject &obj ) } } -void reveal_map_actor::reveal_targets( const tripoint ¢er, +void reveal_map_actor::reveal_targets( const tripoint_abs_omt ¢er, const std::pair &target, int reveal_distance ) const { @@ -1195,11 +1195,11 @@ int reveal_map_actor::use( player &p, item &it, bool, const tripoint & ) const p.add_msg_if_player( _( "It's too dark to read." ) ); return 0; } - const tripoint ¢er = it.get_var( "reveal_map_center_omt", - p.global_omt_location() ); + const tripoint_abs_omt center( it.get_var( "reveal_map_center_omt", + p.global_omt_location().raw() ) ); for( auto &omt : omt_types ) { for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) { - reveal_targets( tripoint( center.xy(), z ), omt, 0 ); + reveal_targets( tripoint_abs_omt( center.xy(), z ), omt, 0 ); } } if( !message.empty() ) { diff --git a/src/iuse_actor.h b/src/iuse_actor.h index dccd8013f536d..0adf4bd3878ee 100644 --- a/src/iuse_actor.h +++ b/src/iuse_actor.h @@ -11,6 +11,7 @@ #include #include "color.h" +#include "coordinates.h" #include "damage.h" #include "enums.h" #include "explosion.h" @@ -449,8 +450,9 @@ class reveal_map_actor : public iuse_actor */ std::string message; - void reveal_targets( const tripoint ¢er, const std::pair &target, - int reveal_distance ) const; + void reveal_targets( + const tripoint_abs_omt ¢er, const std::pair &target, + int reveal_distance ) const; reveal_map_actor( const std::string &type = "reveal_map" ) : iuse_actor( type ) {} diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index 67201ecc00dec..29274ea7be7bf 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -1011,8 +1011,8 @@ void spell_effect::map( const spell &sp, Creature &caster, const tripoint & ) // revealing the map only makes sense for the avatar return; } - const tripoint center = you->global_omt_location(); - overmap_buffer.reveal( center.xy(), sp.aoe(), center.z ); + const tripoint_abs_omt center = you->global_omt_location(); + overmap_buffer.reveal( center.xy(), sp.aoe(), center.z() ); } void spell_effect::morale( const spell &sp, Creature &caster, const tripoint &target ) diff --git a/src/magic_teleporter_list.cpp b/src/magic_teleporter_list.cpp index 3de08f1fa71db..d41b734acf11f 100644 --- a/src/magic_teleporter_list.cpp +++ b/src/magic_teleporter_list.cpp @@ -12,6 +12,7 @@ #include "character.h" #include "color.h" #include "coordinate_conversions.h" +#include "coordinates.h" #include "enums.h" #include "game.h" #include "json.h" @@ -40,7 +41,7 @@ static bool popup_string( std::string &result, std::string &title ) return true; } -bool teleporter_list::activate_teleporter( const tripoint &omt_pt, const tripoint & ) +bool teleporter_list::activate_teleporter( const tripoint_abs_omt &omt_pt, const tripoint & ) { std::string point_name; std::string title = _( "Name this gate." ); @@ -48,21 +49,22 @@ bool teleporter_list::activate_teleporter( const tripoint &omt_pt, const tripoin return known_teleporters.emplace( omt_pt, point_name ).second; } -void teleporter_list::deactivate_teleporter( const tripoint &omt_pt, const tripoint & ) +void teleporter_list::deactivate_teleporter( const tripoint_abs_omt &omt_pt, const tripoint & ) { known_teleporters.erase( omt_pt ); } // returns the first valid teleport location near a teleporter // returns map square (global coordinates) -static cata::optional find_valid_teleporters_omt( const tripoint &omt_pt ) +static cata::optional find_valid_teleporters_omt( const tripoint_abs_omt &omt_pt ) { // this is the top left hand square of the global absolute coordinate // of the overmap terrain we want to try to teleport to. // an OMT is SEEX * SEEY in size - const tripoint sm_pt = omt_to_sm_copy( omt_pt ); + const tripoint_abs_sm sm_pt = project_to( omt_pt ); tinymap checker; - checker.load( sm_pt, true ); + // TODO: fix point types + checker.load( sm_pt.raw(), true ); for( const tripoint &p : checker.points_on_zlevel() ) { if( checker.has_flag_furn( "TRANSLOCATOR", p ) ) { return checker.getabs( p ); @@ -71,11 +73,12 @@ static cata::optional find_valid_teleporters_omt( const tripoint &omt_ return cata::nullopt; } -bool teleporter_list::place_avatar_overmap( Character &you, const tripoint &omt_pt ) const +bool teleporter_list::place_avatar_overmap( Character &you, const tripoint_abs_omt &omt_pt ) const { tinymap omt_dest( 2, true ); - tripoint sm_dest = omt_to_sm_copy( omt_pt ); - omt_dest.load( sm_dest, true ); + tripoint_abs_sm sm_dest = project_to( omt_pt ); + // TODO: fix point types + omt_dest.load( sm_dest.raw(), true ); cata::optional global_dest = find_valid_teleporters_omt( omt_pt ); if( !global_dest ) { return false; @@ -94,7 +97,7 @@ void teleporter_list::translocate( const std::set &targets ) add_msg( m_bad, _( "No translocator target known." ) ); return; } - cata::optional omt_dest = choose_teleport_location(); + cata::optional omt_dest = choose_teleport_location(); if( !omt_dest ) { add_msg( _( "Teleport canceled." ) ); return; @@ -118,7 +121,7 @@ void teleporter_list::translocate( const std::set &targets ) } } -bool teleporter_list::knows_translocator( const tripoint &omt_pos ) const +bool teleporter_list::knows_translocator( const tripoint_abs_omt &omt_pos ) const { return known_teleporters.find( omt_pos ) != known_teleporters.end(); } @@ -129,7 +132,7 @@ void teleporter_list::serialize( JsonOut &json ) const json.member( "known_teleporters" ); json.start_array(); - for( std::pair pair : known_teleporters ) { + for( std::pair pair : known_teleporters ) { json.start_object(); json.member( "position", pair.first ); json.member( "name", pair.second ); @@ -145,7 +148,7 @@ void teleporter_list::deserialize( JsonIn &jsin ) JsonObject data = jsin.get_object(); for( JsonObject jo : data.get_array( "known_teleporters" ) ) { - tripoint temp_pos; + tripoint_abs_omt temp_pos; jo.read( "position", temp_pos ); std::string name; jo.read( "name", name ); @@ -158,9 +161,9 @@ class teleporter_callback : public uilist_callback { private: // to make it easier to get the callback from the known_teleporters - std::map index_pairs; + std::map index_pairs; public: - teleporter_callback( std::map &ip ) : index_pairs( ip ) {} + teleporter_callback( std::map &ip ) : index_pairs( ip ) {} void refresh( uilist *menu ) override { const int entnum = menu->selected; const int start_x = menu->w_width - menu->pad_right; @@ -174,26 +177,26 @@ class teleporter_callback : public uilist_callback overmap_ui::draw_overmap_chunk( menu->window, player_character, index_pairs[entnum], point( start_x + 1, 1 ), 29, 21 ); + int dist = rl_dist( player_character.global_omt_location(), index_pairs[entnum] ); mvwprintz( menu->window, point( start_x + 2, 1 ), c_white, - string_format( _( "Distance: %d (%d, %d)" ), - rl_dist( ms_to_omt_copy( get_map().getabs( player_character.pos() ) ), index_pairs[entnum] ), - index_pairs[entnum].x, index_pairs[entnum].y ) ); + string_format( _( "Distance: %d %s" ), dist, + index_pairs[entnum].to_string() ) ); } wnoutrefresh( menu->window ); } }; -cata::optional teleporter_list::choose_teleport_location() +cata::optional teleporter_list::choose_teleport_location() { - cata::optional ret = cata::nullopt; + cata::optional ret = cata::nullopt; uilist teleport_selector; teleport_selector.w_height_setup = 24; int index = 0; int column_width = 25; - std::map index_pairs; - for( const std::pair &gate : known_teleporters ) { + std::map index_pairs; + for( const std::pair &gate : known_teleporters ) { teleport_selector.addentry( index, true, 0, gate.second ); column_width = std::max( column_width, utf8_width( gate.second ) ); index_pairs.emplace( index, gate.first ); diff --git a/src/magic_teleporter_list.h b/src/magic_teleporter_list.h index f06d7c8a7bd2c..c3ba271c83852 100644 --- a/src/magic_teleporter_list.h +++ b/src/magic_teleporter_list.h @@ -6,6 +6,7 @@ #include #include +#include "coordinates.h" #include "optional.h" #include "point.h" @@ -17,18 +18,18 @@ class teleporter_list { private: // OMT locations of all known teleporters - std::map known_teleporters; + std::map known_teleporters; // ui for selection of desired teleport location. // returns overmap tripoint, or nullopt if canceled - cata::optional choose_teleport_location(); + cata::optional choose_teleport_location(); // returns true if a teleport is successful // does not do any loading or unloading - bool place_avatar_overmap( Character &you, const tripoint &omt_pt ) const; + bool place_avatar_overmap( Character &you, const tripoint_abs_omt &omt_pt ) const; public: - bool knows_translocator( const tripoint &omt_pos ) const; + bool knows_translocator( const tripoint_abs_omt &omt_pos ) const; // adds teleporter to known_teleporters and does any other activation necessary - bool activate_teleporter( const tripoint &omt_pt, const tripoint &local_pt ); - void deactivate_teleporter( const tripoint &omt_pt, const tripoint &local_pt ); + bool activate_teleporter( const tripoint_abs_omt &omt_pt, const tripoint &local_pt ); + void deactivate_teleporter( const tripoint_abs_omt &omt_pt, const tripoint &local_pt ); // calls the necessary functions to select translocator location // and teleports the target(s) there diff --git a/src/map.cpp b/src/map.cpp index f4493f51f6792..c1bc76126142b 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -5433,12 +5433,13 @@ computer *map::computer_at( const tripoint &p ) bool map::point_within_camp( const tripoint &point_check ) const { - const tripoint omt_check = ms_to_omt_copy( point_check ); - const point p( omt_check.xy() ); - for( int x2 = p.x - 2; x2 < p.x + 2; x2++ ) { - for( int y2 = p.y - 2; y2 < p.y + 2; y2++ ) { - if( cata::optional bcp = overmap_buffer.find_camp( point( x2, y2 ) ) ) { - return ( *bcp )->camp_omt_pos().z == point_check.z; + // TODO: fix point types + const tripoint_abs_omt omt_check( ms_to_omt_copy( point_check ) ); + const point_abs_omt p = omt_check.xy(); + for( int x2 = -2; x2 < 2; x2++ ) { + for( int y2 = -2; y2 < 2; y2++ ) { + if( cata::optional bcp = overmap_buffer.find_camp( p + point( x2, y2 ) ) ) { + return ( *bcp )->camp_omt_pos().z() == point_check.z; } } } @@ -5456,7 +5457,7 @@ basecamp map::hoist_submap_camp( const tripoint &p ) return pcamp ? *pcamp : basecamp(); } -void map::add_camp( const tripoint &omt_pos, const std::string &name ) +void map::add_camp( const tripoint_abs_omt &omt_pos, const std::string &name ) { basecamp temp_camp = basecamp( name, omt_pos ); overmap_buffer.add_camp( temp_camp ); @@ -5508,7 +5509,8 @@ void map::update_visibility_cache( const int zlev ) if( sm_squares_seen[gridx][gridy] > 36 ) { // 25% of the submap is visible const tripoint sm( gridx, gridy, 0 ); const auto abs_sm = map::abs_sub + sm; - const auto abs_omt = sm_to_omt_copy( abs_sm ); + // TODO: fix point types + const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sm ) ); overmap_buffer.set_seen( abs_omt, true ); } } @@ -6420,6 +6422,12 @@ void map::load( const tripoint &w, const bool update_vehicle ) } } +void map::load( const tripoint_abs_sm &w, const bool update_vehicle ) +{ + // TODO: fix point types + load( w.raw(), update_vehicle ); +} + void map::shift_traps( const tripoint &shift ) { // Offset needs to have sign opposite to shift direction @@ -6701,8 +6709,9 @@ void map::loadn( const tripoint &grid, const bool update_vehicles ) // Each overmap square is two nonants; to prevent overlap, generate only at // squares divisible by 2. - const tripoint grid_abs_omt = sm_to_omt_copy( grid_abs_sub ); - const tripoint grid_abs_sub_rounded = omt_to_sm_copy( grid_abs_omt ); + // TODO: fix point types + const tripoint_abs_omt grid_abs_omt( sm_to_omt_copy( grid_abs_sub ) ); + const tripoint grid_abs_sub_rounded = omt_to_sm_copy( grid_abs_omt.raw() ); const oter_id terrain_type = overmap_buffer.ter( grid_abs_omt ); @@ -7292,7 +7301,8 @@ void map::spawn_monsters_submap_group( const tripoint &gp, mongroup &group, bool } // Find horde's target submap - tripoint horde_target( tripoint( -abs_sub.x, -abs_sub.y, abs_sub.z ) + group.target.xy() ); + // TODO: fix point types + tripoint horde_target( tripoint( -abs_sub.xy(), abs_sub.z ) + group.target.xy().raw() ); sm_to_ms( horde_target ); for( auto &tmp : group.monsters ) { for( int tries = 0; tries < 10 && !locations.empty(); tries++ ) { @@ -7324,10 +7334,12 @@ void map::spawn_monsters_submap_group( const tripoint &gp, mongroup &group, bool void map::spawn_monsters_submap( const tripoint &gp, bool ignore_sight ) { // Load unloaded monsters - overmap_buffer.spawn_monster( gp + abs_sub.xy() ); + // TODO: fix point types + overmap_buffer.spawn_monster( tripoint_abs_sm( gp + abs_sub.xy() ) ); // Only spawn new monsters after existing monsters are loaded. - auto groups = overmap_buffer.groups_at( gp + abs_sub.xy() ); + // TODO: fix point types + auto groups = overmap_buffer.groups_at( tripoint_abs_sm( gp + abs_sub.xy() ) ); for( auto &mgp : groups ) { spawn_monsters_submap_group( gp, *mgp, ignore_sight ); } diff --git a/src/map.h b/src/map.h index eb87ff3d23a22..23e470186d4c2 100644 --- a/src/map.h +++ b/src/map.h @@ -21,6 +21,7 @@ #include "calendar.h" #include "cata_utility.h" #include "colony.h" +#include "coordinates.h" #include "enums.h" #include "game_constants.h" #include "item.h" @@ -363,6 +364,7 @@ class map * @param update_vehicles If true, add vehicles to the vehicle cache. */ void load( const tripoint &w, bool update_vehicles ); + void load( const tripoint_abs_sm &w, bool update_vehicles ); /** * Shift the map along the vector s. * This is like loading the map with coordinates derived from the current @@ -1302,7 +1304,7 @@ class map computer *add_computer( const tripoint &p, const std::string &name, int security ); // Camps - void add_camp( const tripoint &omt_pos, const std::string &name ); + void add_camp( const tripoint_abs_omt &omt_pos, const std::string &name ); void remove_submap_camp( const tripoint & ); basecamp hoist_submap_camp( const tripoint &p ); bool point_within_camp( const tripoint &point_check ) const; diff --git a/src/map_extras.cpp b/src/map_extras.cpp index 8295fb44505e0..d1685c4b4cc07 100644 --- a/src/map_extras.cpp +++ b/src/map_extras.cpp @@ -16,6 +16,7 @@ #include "character_id.h" #include "colony.h" #include "coordinate_conversions.h" +#include "coordinates.h" #include "debug.h" #include "enum_conversions.h" #include "enums.h" @@ -619,7 +620,8 @@ static bool mx_collegekids( map &m, const tripoint & ) static bool mx_roadblock( map &m, const tripoint &abs_sub ) { - const tripoint abs_omt = sm_to_omt_copy( abs_sub ); + // TODO: fix point types + const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sub ) ); const oter_id &north = overmap_buffer.ter( abs_omt + point_north ); const oter_id &south = overmap_buffer.ter( abs_omt + point_south ); const oter_id &west = overmap_buffer.ter( abs_omt + point_west ); @@ -813,7 +815,7 @@ static bool mx_marloss_pilgrimage( map &m, const tripoint &abs_sub ) static bool mx_bandits_block( map &m, const tripoint &abs_sub ) { - const tripoint abs_omt = sm_to_omt_copy( abs_sub ); + const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sub ) ); const oter_id &north = overmap_buffer.ter( abs_omt + point_north ); const oter_id &south = overmap_buffer.ter( abs_omt + point_south ); const oter_id &west = overmap_buffer.ter( abs_omt + point_west ); @@ -1101,7 +1103,7 @@ static bool mx_portal( map &m, const tripoint &abs_sub ) static bool mx_minefield( map &, const tripoint &abs_sub ) { - const tripoint abs_omt = sm_to_omt_copy( abs_sub ); + const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sub ) ); const oter_id ¢er = overmap_buffer.ter( abs_omt ); const oter_id &north = overmap_buffer.ter( abs_omt + point_north ); const oter_id &south = overmap_buffer.ter( abs_omt + point_south ); @@ -1131,7 +1133,7 @@ static bool mx_minefield( map &, const tripoint &abs_sub ) tinymap m; if( bridge_at_north && bridgehead_at_center && road_at_south ) { - m.load( omt_to_sm_copy( abs_omt + point_south ), false ); + m.load( project_to( abs_omt + point_south ), false ); //Sandbag block at the left edge line_furn( &m, f_sandbag_half, point( 3, 4 ), point( 3, 7 ) ); @@ -1231,7 +1233,7 @@ static bool mx_minefield( map &, const tripoint &abs_sub ) } if( bridge_at_south && bridgehead_at_center && road_at_north ) { - m.load( omt_to_sm_copy( abs_omt + point_north ), false ); + m.load( project_to( abs_omt + point_north ), false ); //Two horizontal lines of sandbags line_furn( &m, f_sandbag_half, point( 5, 15 ), point( 10, 15 ) ); line_furn( &m, f_sandbag_half, point( 13, 15 ), point( 18, 15 ) ); @@ -1333,7 +1335,7 @@ static bool mx_minefield( map &, const tripoint &abs_sub ) } if( bridge_at_west && bridgehead_at_center && road_at_east ) { - m.load( omt_to_sm_copy( abs_omt + point_east ), false ); + m.load( project_to( abs_omt + point_east ), false ); //Draw walls of first tent square_furn( &m, f_canvas_wall, point( 0, 3 ), point( 4, 13 ) ); @@ -1480,7 +1482,7 @@ static bool mx_minefield( map &, const tripoint &abs_sub ) } if( bridge_at_east && bridgehead_at_center && road_at_west ) { - m.load( omt_to_sm_copy( abs_omt + point_west ), false ); + m.load( project_to( abs_omt + point_west ), false ); //Spawn military cargo truck blocking the entry m.add_vehicle( vproto_id( "military_cargo_truck" ), point( 15, 11 ), 270, 70, 1 ); @@ -2292,7 +2294,7 @@ static bool mx_roadworks( map &m, const tripoint &abs_sub ) // equipment in a box // (curved roads & intersections excluded, perhaps TODO) - const tripoint abs_omt = sm_to_omt_copy( abs_sub ); + const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sub ) ); const oter_id &north = overmap_buffer.ter( abs_omt + point_north ); const oter_id &south = overmap_buffer.ter( abs_omt + point_south ); const oter_id &west = overmap_buffer.ter( abs_omt + point_west ); @@ -2996,21 +2998,23 @@ static bool mx_grave( map &m, const tripoint &abs_sub ) static bool mx_city_trap( map &/*m*/, const tripoint &abs_sub ) { //First, find a city - const city_reference c = overmap_buffer.closest_city( abs_sub ); - const tripoint city_center_omt = sm_to_omt_copy( c.abs_sm_pos ); + // TODO: fix point types + const city_reference c = overmap_buffer.closest_city( tripoint_abs_sm( abs_sub ) ); + const tripoint_abs_omt city_center_omt = + project_to( c.abs_sm_pos ); //Then fill vector with all roads inside the city radius - std::vector valid_omt; - for( const tripoint &p : points_in_radius( city_center_omt, c.city->size ) ) { + std::vector valid_omt; + for( const tripoint_abs_omt &p : points_in_radius( city_center_omt, c.city->size ) ) { if( overmap_buffer.check_ot( "road", ot_match_type::prefix, p ) ) { valid_omt.push_back( p ); } } - const tripoint road_omt = random_entry( valid_omt, city_center_omt ); + const tripoint_abs_omt road_omt = random_entry( valid_omt, city_center_omt ); tinymap compmap; - compmap.load( tripoint( road_omt.x * 2, road_omt.y * 2, road_omt.z ), false ); + compmap.load( project_to( road_omt ), false ); const tripoint trap_center = { SEEX + rng( -5, 5 ), SEEY + rng( -5, 5 ), abs_sub.z }; bool empty_3x3_square = false; @@ -3104,12 +3108,14 @@ void apply_function( const string_id &id, map &m, const tripoint &abs break; } case map_extra_method::mapgen: { - mapgendata dat( sm_to_omt_copy( abs_sub ), m, 0.0f, calendar::turn, nullptr ); + mapgendata dat( tripoint_abs_omt( sm_to_omt_copy( abs_sub ) ), m, 0.0f, calendar::turn, + nullptr ); applied_successfully = run_mapgen_func( extra.generator_id, dat ); break; } case map_extra_method::update_mapgen: { - mapgendata dat( sm_to_omt_copy( abs_sub ), m, 0.0f, calendar::start_of_cataclysm, nullptr ); + mapgendata dat( tripoint_abs_omt( sm_to_omt_copy( abs_sub ) ), m, 0.0f, + calendar::start_of_cataclysm, nullptr ); applied_successfully = run_mapgen_update_func( extra.generator_id, dat ); break; } @@ -3122,7 +3128,8 @@ void apply_function( const string_id &id, map &m, const tripoint &abs return; } - overmap_buffer.add_extra( sm_to_omt_copy( abs_sub ), id ); + // TODO: fix point types + overmap_buffer.add_extra( tripoint_abs_omt( sm_to_omt_copy( abs_sub ) ), id ); auto_notes::auto_note_settings &autoNoteSettings = get_auto_notes_settings(); @@ -3139,7 +3146,8 @@ void apply_function( const string_id &id, map &m, const tripoint &abs get_note_string_from_color( extra.color ), extra.name(), extra.description() ); - overmap_buffer.add_note( sm_to_omt_copy( abs_sub ), mx_note ); + // TODO: fix point types + overmap_buffer.add_note( tripoint_abs_omt( sm_to_omt_copy( abs_sub ) ), mx_note ); } } } diff --git a/src/map_field.cpp b/src/map_field.cpp index b42b2fbebe2b7..87321e7314313 100644 --- a/src/map_field.cpp +++ b/src/map_field.cpp @@ -255,7 +255,9 @@ void map::spread_gas( field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk ) { map &here = get_map(); - const oter_id &cur_om_ter = overmap_buffer.ter( ms_to_omt_copy( here.getabs( p ) ) ); + // TODO: fix point types + const oter_id &cur_om_ter = + overmap_buffer.ter( tripoint_abs_omt( ms_to_omt_copy( here.getabs( p ) ) ) ); const bool sheltered = g->is_sheltered( p ); const int winddirection = g->weather.winddirection; const int windpower = get_local_windpower( g->weather.windspeed, cur_om_ter, p, winddirection, @@ -881,7 +883,8 @@ bool map::process_fire_field_in_submap( maptile &map_tile, const tripoint &p, field_entry *tmpfld = nullptr; cur.set_field_age( std::max( -24_hours, cur.get_field_age() ) ); // Entire objects for ter/frn for flags - const oter_id &cur_om_ter = overmap_buffer.ter( ms_to_omt_copy( here.getabs( p ) ) ); + const oter_id &cur_om_ter = overmap_buffer.ter( tripoint_abs_omt( ms_to_omt_copy( here.getabs( + p ) ) ) ); bool sheltered = g->is_sheltered( p ); int winddirection = g->weather.winddirection; int windpower = get_local_windpower( g->weather.windspeed, cur_om_ter, p, winddirection, diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 1ce7a6db69db8..abebf4646267e 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -129,7 +129,8 @@ void map::generate( const tripoint &p, const time_point &when ) } } // x, and y are submap coordinates, convert to overmap terrain coordinates - tripoint abs_omt = sm_to_omt_copy( p ); + // TODO: fix point types + tripoint_abs_omt abs_omt( sm_to_omt_copy( p ) ); oter_id terrain_type = overmap_buffer.ter( abs_omt ); // This attempts to scale density of zombies inversely with distance from the nearest city. @@ -935,7 +936,8 @@ class jmapgen_sign : public jmapgen_piece std::string cityname = "illegible city name"; tripoint abs_sub = dat.m.get_abs_sub(); - const city *c = overmap_buffer.closest_city( abs_sub ).city; + // TODO: fix point types + const city *c = overmap_buffer.closest_city( tripoint_abs_sm( abs_sub ) ).city; if( c != nullptr ) { cityname = c->name; } @@ -986,7 +988,8 @@ class jmapgen_graffiti : public jmapgen_piece std::string cityname = "illegible city name"; tripoint abs_sub = dat.m.get_abs_sub(); - const city *c = overmap_buffer.closest_city( abs_sub ).city; + // TODO: fix point types + const city *c = overmap_buffer.closest_city( tripoint_abs_sm( abs_sub ) ).city; if( c != nullptr ) { cityname = c->name; } @@ -5595,7 +5598,8 @@ void map::place_spawns( const mongroup_id &group, const int chance, const bool individual, const bool friendly, const std::string &name, const int mission_id ) { if( !group.is_valid() ) { - const tripoint omt = sm_to_omt_copy( get_abs_sub() ); + // TODO: fix point types + const tripoint_abs_omt omt( sm_to_omt_copy( get_abs_sub() ) ); const oter_id &oid = overmap_buffer.ter( omt ); debugmsg( "place_spawns: invalid mongroup '%s', om_terrain = '%s' (%s)", group.c_str(), oid.id().c_str(), oid->get_mapgen_id().c_str() ); @@ -5718,7 +5722,8 @@ std::vector map::place_items( const items_location &loc, const int chanc return res; } if( !item_group::group_is_defined( loc ) ) { - const tripoint omt = sm_to_omt_copy( get_abs_sub() ); + // TODO: fix point types + const tripoint_abs_omt omt( sm_to_omt_copy( get_abs_sub() ) ); const oter_id &oid = overmap_buffer.ter( omt ); debugmsg( "place_items: invalid item group '%s', om_terrain = '%s' (%s)", loc.c_str(), oid.id().c_str(), oid->get_mapgen_id().c_str() ); @@ -6015,8 +6020,9 @@ void map::rotate( int turns, const bool setpos_safe ) // TODO: This radius can be smaller - how small? const int radius = HALF_MAPSIZE + 3; // uses submap coordinates - const std::vector> npcs = overmap_buffer.get_npcs_near( abs_sub, - radius ); + // TODO: fix point types + const std::vector> npcs = + overmap_buffer.get_npcs_near( tripoint_abs_sm( abs_sub ), radius ); for( const shared_ptr_fast &i : npcs ) { npc &np = *i; const tripoint sq = np.global_square_location(); @@ -6915,7 +6921,7 @@ bool update_mapgen_function_json::setup_internal( const JsonObject &/*jo*/ ) return true; } -bool update_mapgen_function_json::update_map( const tripoint &omt_pos, const point &offset, +bool update_mapgen_function_json::update_map( const tripoint_abs_omt &omt_pos, const point &offset, mission *miss, bool verify ) const { if( omt_pos == overmap::invalid_tripoint ) { @@ -6923,7 +6929,8 @@ bool update_mapgen_function_json::update_map( const tripoint &omt_pos, const poi return false; } tinymap update_tmap; - const tripoint sm_pos = omt_to_sm_copy( omt_pos ); + // TODO: fix point types + const tripoint sm_pos = project_to( omt_pos ).raw(); update_tmap.load( sm_pos, true ); mapgendata md( omt_pos, update_tmap, 0.0f, calendar::start_of_cataclysm, miss ); @@ -6980,7 +6987,7 @@ mapgen_update_func add_mapgen_update_func( const JsonObject &jo, bool &defer ) { if( jo.has_string( "mapgen_update_id" ) ) { const std::string mapgen_update_id = jo.get_string( "mapgen_update_id" ); - const auto update_function = [mapgen_update_id]( const tripoint & omt_pos, + const auto update_function = [mapgen_update_id]( const tripoint_abs_omt & omt_pos, mission * miss ) { run_mapgen_update_func( mapgen_update_id, omt_pos, miss, false ); }; @@ -6990,11 +6997,11 @@ mapgen_update_func add_mapgen_update_func( const JsonObject &jo, bool &defer ) update_mapgen_function_json json_data( "" ); mapgen_defer::defer = defer; if( !json_data.setup_update( jo ) ) { - const auto null_function = []( const tripoint &, mission * ) { + const auto null_function = []( const tripoint_abs_omt &, mission * ) { }; return null_function; } - const auto update_function = [json_data]( const tripoint & omt_pos, mission * miss ) { + const auto update_function = [json_data]( const tripoint_abs_omt & omt_pos, mission * miss ) { json_data.update_map( omt_pos, point_zero, miss ); }; defer = mapgen_defer::defer; @@ -7002,7 +7009,7 @@ mapgen_update_func add_mapgen_update_func( const JsonObject &jo, bool &defer ) return update_function; } -bool run_mapgen_update_func( const std::string &update_mapgen_id, const tripoint &omt_pos, +bool run_mapgen_update_func( const std::string &update_mapgen_id, const tripoint_abs_omt &omt_pos, mission *miss, bool cancel_on_collision ) { const auto update_function = update_mapgen.find( update_mapgen_id ); diff --git a/src/mapgen.h b/src/mapgen.h index b70a0660c5b86..c0f1a973ab15c 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -369,7 +369,7 @@ class update_mapgen_function_json : public mapgen_function_json_base void setup(); bool setup_update( const JsonObject &jo ); void check( const std::string &oter_name ) const; - bool update_map( const tripoint &omt_pos, const point &offset, + bool update_map( const tripoint_abs_omt &omt_pos, const point &offset, mission *miss, bool verify = false ) const; bool update_map( mapgendata &md, const point &offset = point_zero, bool verify = false ) const; diff --git a/src/mapgen_functions.h b/src/mapgen_functions.h index cc719b05c4f1f..c0346981ad1a8 100644 --- a/src/mapgen_functions.h +++ b/src/mapgen_functions.h @@ -7,6 +7,7 @@ #include #include +#include "coordinates.h" #include "type_id.h" class map; @@ -15,7 +16,7 @@ class mission; struct point; struct tripoint; -using mapgen_update_func = std::function; +using mapgen_update_func = std::function; class JsonObject; /** @@ -81,7 +82,7 @@ void mtrap_set( map *m, const point &, trap_id type ); void madd_field( map *m, const point &, field_type_id type, int intensity ); mapgen_update_func add_mapgen_update_func( const JsonObject &jo, bool &defer ); -bool run_mapgen_update_func( const std::string &update_mapgen_id, const tripoint &omt_pos, +bool run_mapgen_update_func( const std::string &update_mapgen_id, const tripoint_abs_omt &omt_pos, mission *miss = nullptr, bool cancel_on_collision = true ); bool run_mapgen_update_func( const std::string &update_mapgen_id, mapgendata &dat, bool cancel_on_collision = true ); diff --git a/src/mapgendata.cpp b/src/mapgendata.cpp index 64b54a7f51dbe..66366321d8899 100644 --- a/src/mapgendata.cpp +++ b/src/mapgendata.cpp @@ -24,14 +24,19 @@ mapgendata::mapgendata( oter_id north, oter_id east, oter_id south, oter_id west { } -mapgendata::mapgendata( const tripoint &over, map &m, const float density, const time_point &when, - ::mission *const miss ) +mapgendata::mapgendata( const tripoint_abs_omt &over, map &m, const float density, + const time_point &when, ::mission *const miss ) : mapgendata( overmap_buffer.ter( over + tripoint_north ), - overmap_buffer.ter( over + tripoint_east ), overmap_buffer.ter( over + tripoint_south ), - overmap_buffer.ter( over + tripoint_west ), overmap_buffer.ter( over + tripoint_north_east ), - overmap_buffer.ter( over + tripoint_south_east ), overmap_buffer.ter( over + tripoint_south_west ), - overmap_buffer.ter( over + tripoint_north_west ), overmap_buffer.ter( over + tripoint_above ), - overmap_buffer.ter( over + tripoint_below ), over.z, overmap_buffer.get_settings( over ), m, + overmap_buffer.ter( over + tripoint_east ), + overmap_buffer.ter( over + tripoint_south ), + overmap_buffer.ter( over + tripoint_west ), + overmap_buffer.ter( over + tripoint_north_east ), + overmap_buffer.ter( over + tripoint_south_east ), + overmap_buffer.ter( over + tripoint_south_west ), + overmap_buffer.ter( over + tripoint_north_west ), + overmap_buffer.ter( over + tripoint_above ), + overmap_buffer.ter( over + tripoint_below ), + over.z(), overmap_buffer.get_settings( over ), m, overmap_buffer.ter( over ), density, when, miss ) { } diff --git a/src/mapgendata.h b/src/mapgendata.h index e7f0162c80749..cd973be64bdec 100644 --- a/src/mapgendata.h +++ b/src/mapgendata.h @@ -2,8 +2,9 @@ #ifndef CATA_SRC_MAPGENDATA_H #define CATA_SRC_MAPGENDATA_H -#include "type_id.h" #include "calendar.h" +#include "coordinates.h" +#include "type_id.h" #include "weighted_list.h" struct point; @@ -66,7 +67,8 @@ class mapgendata oter_id up, oter_id down, int z, const regional_settings &rsettings, map &mp, const oter_id &terrain_type, float density, const time_point &when, ::mission *miss ); - mapgendata( const tripoint &over, map &m, float density, const time_point &when, ::mission *miss ); + mapgendata( const tripoint_abs_omt &over, map &m, float density, const time_point &when, + ::mission *miss ); /** * Creates a copy of this mapgen data, but stores a different @ref terrain_type. diff --git a/src/memorial_logger.cpp b/src/memorial_logger.cpp index 0b3a6d04f1153..0ae9f2c4007f2 100644 --- a/src/memorial_logger.cpp +++ b/src/memorial_logger.cpp @@ -234,7 +234,9 @@ void memorial_logger::write_text_memorial( std::ostream &file, profession_name = string_format( _( "a %s" ), u.prof->gender_appropriate_name( u.male ) ); } - const std::string locdesc = overmap_buffer.get_description_at( u.global_sm_location() ); + // TODO: fix point types + const std::string locdesc = + overmap_buffer.get_description_at( tripoint_abs_sm( u.global_sm_location() ) ); //~ First parameter is a pronoun ("He"/"She"), second parameter is a description //~ that designates the location relative to its surroundings. const std::string kill_place = string_format( _( "%1$s was killed in a %2$s." ), diff --git a/src/mission.cpp b/src/mission.cpp index d11187dc33990..c4b86934fe424 100644 --- a/src/mission.cpp +++ b/src/mission.cpp @@ -200,7 +200,7 @@ void mission::on_talk_with_npc( const character_id &npc_id ) } } -mission *mission::reserve_random( const mission_origin origin, const tripoint &p, +mission *mission::reserve_random( const mission_origin origin, const tripoint_abs_omt &p, const character_id &npc_id ) { const auto type = mission_type::get_random_id( origin, p ); @@ -349,7 +349,7 @@ bool mission::is_complete( const character_id &_npc_id ) const avatar &player_character = get_avatar(); switch( type->goal ) { case MGOAL_GO_TO: { - const tripoint cur_pos = player_character.global_omt_location(); + const tripoint_abs_omt cur_pos = player_character.global_omt_location(); return ( rl_dist( cur_pos, target ) <= 1 ); } @@ -527,7 +527,7 @@ bool mission::has_target() const return target != overmap::invalid_tripoint; } -const tripoint &mission::get_target() const +const tripoint_abs_omt &mission::get_target() const { return target; } @@ -605,7 +605,7 @@ bool mission::has_generic_rewards() const return type->has_generic_rewards; } -void mission::set_target( const tripoint &p ) +void mission::set_target( const tripoint_abs_omt &p ) { target = p; } @@ -687,7 +687,7 @@ mission::mission() status = mission_status::yet_to_start; value = 0; uid = -1; - target = tripoint_min; + target = tripoint_abs_omt( tripoint_min ); item_id = itype_id::NULL_ID(); item_count = 1; target_id = string_id::NULL_ID(); diff --git a/src/mission.h b/src/mission.h index 555ecf2d2b490..d8e08c4a20d09 100644 --- a/src/mission.h +++ b/src/mission.h @@ -86,13 +86,13 @@ struct enum_traits { struct mission_place { // Return true if the place (global overmap terrain coordinate) is valid for starting a mission - static bool never( const tripoint & ) { + static bool never( const tripoint_abs_omt & ) { return false; } - static bool always( const tripoint & ) { + static bool always( const tripoint_abs_omt & ) { return true; } - static bool near_town( const tripoint & ); + static bool near_town( const tripoint_abs_omt & ); }; /* mission_start functions are first run when a mission is accepted; this @@ -146,7 +146,7 @@ struct mission_target_params { mission *mission_pointer; bool origin_u = true; - cata::optional offset; + cata::optional offset; cata::optional replaceable_overmap_terrain; cata::optional overmap_special; cata::optional reveal_radius; @@ -163,21 +163,25 @@ struct mission_target_params { namespace mission_util { -tripoint random_house_in_closest_city(); -tripoint target_closest_lab_entrance( const tripoint &origin, int reveal_rad, mission *miss ); -bool reveal_road( const tripoint &source, const tripoint &dest, overmapbuffer &omb ); -tripoint reveal_om_ter( const std::string &omter, int reveal_rad, bool must_see, int target_z = 0 ); -tripoint target_om_ter( const std::string &omter, int reveal_rad, mission *miss, bool must_see, - int target_z = 0 ); -tripoint target_om_ter_random( const std::string &omter, int reveal_rad, mission *miss, - bool must_see, int range, tripoint loc = overmap::invalid_tripoint ); +tripoint_abs_omt random_house_in_closest_city(); +tripoint_abs_omt target_closest_lab_entrance( const tripoint_abs_omt &origin, int reveal_rad, + mission *miss ); +bool reveal_road( const tripoint_abs_omt &source, const tripoint_abs_omt &dest, + overmapbuffer &omb ); +tripoint_abs_omt reveal_om_ter( const std::string &omter, int reveal_rad, bool must_see, + int target_z = 0 ); +tripoint_abs_omt target_om_ter( const std::string &omter, int reveal_rad, mission *miss, + bool must_see, int target_z = 0 ); +tripoint_abs_omt target_om_ter_random( + const std::string &omter, int reveal_rad, mission *miss, bool must_see, int range, + tripoint_abs_omt loc = overmap::invalid_tripoint ); void set_reveal( const std::string &terrain, std::vector> &funcs ); void set_reveal_any( const JsonArray &ja, std::vector> &funcs ); mission_target_params parse_mission_om_target( const JsonObject &jo ); -cata::optional assign_mission_target( const mission_target_params ¶ms ); -tripoint get_om_terrain_pos( const mission_target_params ¶ms ); +cata::optional assign_mission_target( const mission_target_params ¶ms ); +tripoint_abs_omt get_om_terrain_pos( const mission_target_params ¶ms ); void set_assign_om_target( const JsonObject &jo, std::vector> &funcs ); bool set_update_mapgen( const JsonObject &jo, @@ -240,7 +244,7 @@ struct mission_type { string_id target_id; mission_type_id follow_up = mission_type_id( "MISSION_NULL" ); - std::function place = mission_place::always; + std::function place = mission_place::always; std::function start = mission_start::standard; std::function end = mission_end::standard; std::function fail = mission_fail::standard; @@ -267,7 +271,7 @@ struct mission_type { * around tripoint p, see @ref mission_start. * Returns @ref MISSION_NULL if no suitable type could be found. */ - static mission_type_id get_random_id( mission_origin origin, const tripoint &p ); + static mission_type_id get_random_id( mission_origin origin, const tripoint_abs_omt &p ); /** * Get all mission types at once. */ @@ -316,7 +320,7 @@ class mission int uid; // Marked on the player's map. (INT_MIN, INT_MIN) for none, // global overmap terrain coordinates. - tripoint target; + tripoint_abs_omt target; // Item that needs to be found (or whatever) itype_id item_id; // The number of above items needed @@ -361,7 +365,7 @@ class mission time_point get_deadline() const; std::string get_description() const; bool has_target() const; - const tripoint &get_target() const; + const tripoint_abs_omt &get_target() const; const mission_type &get_type() const; bool has_follow_up() const; mission_type_id get_follow_up() const; @@ -386,7 +390,7 @@ class mission /** * Simple setters, no checking if the values is performed. */ /*@{*/ - void set_target( const tripoint &p ); + void set_target( const tripoint_abs_omt &p ); void set_target_npc_id( const character_id &npc_id ); /*@}*/ @@ -418,7 +422,7 @@ class mission * Returns the new mission. */ static mission *reserve_new( const mission_type_id &type, const character_id &npc_id ); - static mission *reserve_random( mission_origin origin, const tripoint &p, + static mission *reserve_random( mission_origin origin, const tripoint_abs_omt &p, const character_id &npc_id ); /** * Returns the mission with the matching id (@ref uid). Returns NULL if no mission with that diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index 636d60e214aa9..4f82e864228a1 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -20,6 +20,7 @@ #include "color.h" #include "compatibility.h" // needed for the workaround for the std::to_string bug in some compilers #include "coordinate_conversions.h" +#include "coordinates.h" #include "creature.h" #include "cursesdef.h" #include "debug.h" @@ -113,7 +114,7 @@ void talk_function::companion_mission( npc &p ) mission_data mission_key; std::string role_id = p.companion_mission_role_id; - const tripoint omt_pos = p.global_omt_location(); + const tripoint_abs_omt omt_pos = p.global_omt_location(); std::string title = _( "Outpost Missions" ); if( role_id == "SCAVENGER" ) { title = _( "Junk Shop Missions" ); @@ -363,8 +364,9 @@ void talk_function::commune_refuge_caravan( mission_data &mission_key, npc &p ) } } -bool talk_function::display_and_choose_opts( mission_data &mission_key, const tripoint &omt_pos, - const std::string &role_id, const std::string &title ) +bool talk_function::display_and_choose_opts( + mission_data &mission_key, const tripoint_abs_omt &omt_pos, const std::string &role_id, + const std::string &title ) { if( mission_key.entries.empty() ) { popup( _( "There are no missions at this colony. Press Spacebarā€¦" ) ); @@ -678,11 +680,11 @@ npc_ptr talk_function::individual_mission( npc &p, const std::string &desc, const std::string &miss_id, bool group, const std::vector &equipment, const std::map &required_skills ) { - const tripoint omt_pos = p.global_omt_location(); + const tripoint_abs_omt omt_pos = p.global_omt_location(); return individual_mission( omt_pos, p.companion_mission_role_id, desc, miss_id, group, equipment, required_skills ); } -npc_ptr talk_function::individual_mission( const tripoint &omt_pos, +npc_ptr talk_function::individual_mission( const tripoint_abs_omt &omt_pos, const std::string &role_id, const std::string &desc, const std::string &miss_id, bool group, const std::vector &equipment, const std::map &required_skills ) @@ -742,9 +744,9 @@ void talk_function::caravan_depart( npc &p, const std::string &dest, const std:: int talk_function::caravan_dist( const std::string &dest ) { Character &player_character = get_player_character(); - const tripoint site = overmap_buffer.find_closest( player_character.global_omt_location(), dest, 0, - false ); - int distance = rl_dist( player_character.pos(), site ); + const tripoint_abs_omt site = + overmap_buffer.find_closest( player_character.global_omt_location(), dest, 0, false ); + int distance = rl_dist( player_character.global_omt_location(), site ); return distance; } @@ -922,10 +924,11 @@ void talk_function::field_build_1( npc &p ) } p.set_mutation( trait_NPC_CONSTRUCTION_LEV_1 ); player_character.cash += -100000; - const tripoint site = overmap_buffer.find_closest( player_character.global_omt_location(), - "ranch_camp_63", 20, false ); + const tripoint_abs_omt site = + overmap_buffer.find_closest( player_character.global_omt_location(), "ranch_camp_63", 20, + false ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.draw_square_ter( t_dirt, point( 5, 4 ), point( 15, 14 ) ); bay.draw_square_ter( t_dirtmound, point( 6, 5 ), point( 6, 13 ) ); bay.draw_square_ter( t_dirtmound, point( 8, 5 ), point( 8, 13 ) ); @@ -947,11 +950,11 @@ void talk_function::field_build_2( npc &p ) } p.set_mutation( trait_NPC_CONSTRUCTION_LEV_2 ); player_character.cash += -550000; - const tripoint site = overmap_buffer.find_closest( player_character.global_omt_location(), - "ranch_camp_63", - 20, false ); + const tripoint_abs_omt site = + overmap_buffer.find_closest( player_character.global_omt_location(), "ranch_camp_63", 20, + false ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.draw_square_ter( t_fence, point( 4, 3 ), point( 16, 3 ) ); bay.draw_square_ter( t_fence, point( 4, 15 ), point( 16, 15 ) ); bay.draw_square_ter( t_fence, point( 4, 3 ), point( 4, 15 ) ); @@ -1007,10 +1010,10 @@ void talk_function::field_plant( npc &p, const std::string &place ) } //Now we need to find how many free plots we have to plant in... - const tripoint site = overmap_buffer.find_closest( player_character.global_omt_location(), place, - 20, false ); + const tripoint_abs_omt site = overmap_buffer.find_closest( + player_character.global_omt_location(), place, 20, false ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); for( const tripoint &plot : bay.points_on_zlevel() ) { if( bay.ter( plot ) == t_dirtmound ) { empty_plots++; @@ -1062,14 +1065,14 @@ void talk_function::field_harvest( npc &p, const std::string &place ) { Character &player_character = get_player_character(); //First we need a list of plants that can be harvested... - const tripoint site = overmap_buffer.find_closest( player_character.global_omt_location(), place, - 20, false ); + const tripoint_abs_omt site = overmap_buffer.find_closest( + player_character.global_omt_location(), place, 20, false ); tinymap bay; item tmp; std::vector seed_types; std::vector plant_types; std::vector plant_names; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); for( const tripoint &plot : bay.points_on_zlevel() ) { map_stack items = bay.i_at( plot ); if( bay.furn( plot ) == furn_str_id( "f_plant_harvest" ) && !items.empty() ) { @@ -1284,12 +1287,12 @@ bool talk_function::scavenging_raid_return( npc &p ) } Character &player_character = get_player_character(); //The loot value needs to be added to the faction - what the player is payed - tripoint loot_location = player_character.global_omt_location(); + tripoint_abs_omt loot_location = player_character.global_omt_location(); // Only check at the ground floor. - loot_location.z = 0; + loot_location.z() = 0; for( int i = 0; i < rng( 2, 3 ); i++ ) { - const tripoint site = overmap_buffer.find_closest( loot_location, "house", 0, false, - ot_match_type::prefix ); + const tripoint_abs_omt site = overmap_buffer.find_closest( + loot_location, "house", 0, false, ot_match_type::prefix ); overmap_buffer.reveal( site, 2 ); loot_building( site ); } @@ -1497,35 +1500,29 @@ bool talk_function::forage_return( npc &p ) } bool talk_function::companion_om_combat_check( const std::vector &group, - const tripoint &om_tgt, bool try_engage ) + const tripoint_abs_omt &om_tgt, bool try_engage ) { if( overmap_buffer.is_safe( om_tgt ) ) { //Should work but is_safe is always returning true regardless of what is there. //return true; } - //If the map isn't generated we need to do that... - if( MAPBUFFER.lookup_submap( om_to_sm_copy( om_tgt ) ) == nullptr ) { - //This doesn't gen monsters... - //tinymap tmpmap; - //tmpmap.generate( om_tgt.x * 2, om_tgt.y * 2, om_tgt.z, calendar::turn ); - //tmpmap.save(); - } + tripoint_abs_sm sm_tgt = project_to( om_tgt ); tinymap target_bay; - target_bay.load( tripoint( om_tgt.x * 2, om_tgt.y * 2, om_tgt.z ), false ); + target_bay.load( sm_tgt, false ); std::vector< monster * > monsters_around; for( int x = 0; x < 2; x++ ) { for( int y = 0; y < 2; y++ ) { - point sm( ( om_tgt.x * 2 ) + x, ( om_tgt.x * 2 ) + y ); - const point omp = sm_to_om_remain( sm ); + tripoint_abs_sm sm = sm_tgt + point( x, y ); + point_abs_om omp; + tripoint_om_sm local_sm; + std::tie( omp, local_sm ) = project_remain( sm ); overmap &omi = overmap_buffer.get( omp ); - const tripoint current_submap_loc( tripoint( 2 * om_tgt.x, 2 * om_tgt.y, om_tgt.z ) + point( x, - y ) ); - auto monster_bucket = omi.monster_map.equal_range( current_submap_loc ); + auto monster_bucket = omi.monster_map.equal_range( local_sm ); std::for_each( monster_bucket.first, - monster_bucket.second, [&]( std::pair &monster_entry ) { + monster_bucket.second, [&]( std::pair &monster_entry ) { monster &this_monster = monster_entry.second; monsters_around.push_back( &this_monster ); } ); @@ -1762,7 +1759,7 @@ std::vector talk_function::companion_list( const npc &p, const std::str bool contains ) { std::vector available; - const tripoint omt_pos = p.global_omt_location(); + const tripoint_abs_omt omt_pos = p.global_omt_location(); for( const auto &elem : overmap_buffer.get_companion_mission_npcs() ) { npc_companion_mission c_mission = elem->get_companion_mission(); if( c_mission.position == omt_pos && c_mission.mission_id == mission_id && @@ -1907,7 +1904,7 @@ npc_ptr talk_function::companion_choose( const std::map &required available.push_back( guy ); } } else { - const tripoint &guy_omt_pos = guy->global_omt_location(); + const tripoint_abs_omt guy_omt_pos = guy->global_omt_location(); cata::optional guy_camp = overmap_buffer.find_camp( guy_omt_pos.xy() ); if( guy_camp ) { // get NPCs assigned to guard a remote base @@ -1990,11 +1987,11 @@ npc_ptr talk_function::companion_choose( const std::map &required npc_ptr talk_function::companion_choose_return( const npc &p, const std::string &mission_id, const time_point &deadline ) { - const tripoint omt_pos = p.global_omt_location(); + const tripoint_abs_omt omt_pos = p.global_omt_location(); const std::string &role_id = p.companion_mission_role_id; return companion_choose_return( omt_pos, role_id, mission_id, deadline ); } -npc_ptr talk_function::companion_choose_return( const tripoint &omt_pos, +npc_ptr talk_function::companion_choose_return( const tripoint_abs_omt &omt_pos, const std::string &role_id, const std::string &mission_id, const time_point &deadline, @@ -2041,10 +2038,10 @@ npc_ptr talk_function::companion_choose_return( const tripoint &omt_pos, } //Smash stuff, steal valuables, and change map maker -void talk_function::loot_building( const tripoint &site ) +void talk_function::loot_building( const tripoint_abs_omt &site ) { tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); for( const tripoint &p : bay.points_on_zlevel() ) { const ter_id t = bay.ter( p ); //Open all the doors, doesn't need to be exhaustive diff --git a/src/mission_companion.h b/src/mission_companion.h index 4c515e6e9c76e..ade0d15b4596e 100644 --- a/src/mission_companion.h +++ b/src/mission_companion.h @@ -7,6 +7,7 @@ #include #include "calendar.h" +#include "coordinates.h" #include "memory_fast.h" #include "optional.h" #include "point.h" @@ -71,7 +72,7 @@ namespace talk_function void companion_mission( npc &p ); // Display the available missions and let the player choose one -bool display_and_choose_opts( mission_data &mission_key, const tripoint &omt_pos, +bool display_and_choose_opts( mission_data &mission_key, const tripoint_abs_omt &omt_pos, const std::string &role_id, const std::string &title ); /** @@ -86,7 +87,7 @@ bool display_and_choose_opts( mission_data &mission_key, const tripoint &omt_pos npc_ptr individual_mission( npc &p, const std::string &desc, const std::string &miss_id, bool group = false, const std::vector &equipment = {}, const std::map &required_skills = {} ); -npc_ptr individual_mission( const tripoint &omt_pos, const std::string &role_id, +npc_ptr individual_mission( const tripoint_abs_omt &omt_pos, const std::string &role_id, const std::string &desc, const std::string &miss_id, bool group = false, const std::vector &equipment = {}, const std::map &required_skills = {} ); @@ -112,7 +113,7 @@ void companion_skill_trainer( npc &comp, const std::string &skill_tested = "", void companion_skill_trainer( npc &comp, const skill_id &skill_tested, time_duration time_worked = 1_hours, int difficulty = 1 ); //Combat functions -bool companion_om_combat_check( const comp_list &group, const tripoint &om_tgt, +bool companion_om_combat_check( const comp_list &group, const tripoint_abs_omt &om_tgt, bool try_engage = false ); void force_on_force( const comp_list &defender, const std::string &def_desc, const comp_list &attacker, const std::string &att_desc, int advantage ); @@ -137,7 +138,7 @@ std::vector companion_rank( const comp_list &available, bool adj = tr npc_ptr companion_choose( const std::map &required_skills = {} ); npc_ptr companion_choose_return( const npc &p, const std::string &mission_id, const time_point &deadline ); -npc_ptr companion_choose_return( const tripoint &omt_pos, const std::string &role_id, +npc_ptr companion_choose_return( const tripoint_abs_omt &omt_pos, const std::string &role_id, const std::string &mission_id, const time_point &deadline, bool by_mission = true ); @@ -145,7 +146,7 @@ npc_ptr companion_choose_return( const tripoint &omt_pos, const std::string &rol void companion_return( npc &comp ); //Smash stuff, steal valuables, and change map maker // TODO: Make this return the loot gained -void loot_building( const tripoint &site ); +void loot_building( const tripoint_abs_omt &site ); } // namespace talk_function #endif // CATA_SRC_MISSION_COMPANION_H diff --git a/src/mission_place.cpp b/src/mission_place.cpp index 1ead37ec217d3..5101c9971a096 100644 --- a/src/mission_place.cpp +++ b/src/mission_place.cpp @@ -1,3 +1,4 @@ +#include "coordinates.h" #include "mission.h" // IWYU pragma: associated #include "coordinate_conversions.h" @@ -5,9 +6,9 @@ #include "overmapbuffer.h" // Input position is in global overmap terrain coordinates! -bool mission_place::near_town( const tripoint &pos_omt ) +bool mission_place::near_town( const tripoint_abs_omt &pos_omt ) { - const auto pos_sm = omt_to_sm_copy( pos_omt ); + const tripoint_abs_sm pos_sm = project_to( pos_omt ); const auto cref = overmap_buffer.closest_city( pos_sm ); if( !cref ) { return false; // no nearby city at all. diff --git a/src/mission_start.cpp b/src/mission_start.cpp index ea1e282519b30..546d1a3cf65a2 100644 --- a/src/mission_start.cpp +++ b/src/mission_start.cpp @@ -1,3 +1,4 @@ +#include "coordinates.h" #include "mission.h" // IWYU pragma: associated #include @@ -51,7 +52,7 @@ void mission_start::standard( mission * ) void mission_start::place_dog( mission *miss ) { - const tripoint house = mission_util::random_house_in_closest_city(); + const tripoint_abs_omt house = mission_util::random_house_in_closest_city(); npc *dev = g->find_npc( miss->npc_id ); if( dev == nullptr ) { debugmsg( "Couldn't find NPC! %d", miss->npc_id.get_value() ); @@ -64,21 +65,21 @@ void mission_start::place_dog( mission *miss ) overmap_buffer.reveal( house, 6 ); tinymap doghouse; - doghouse.load( tripoint( house.x * 2, house.y * 2, house.z ), false ); - doghouse.add_spawn( mon_dog, 1, { SEEX, SEEY, house.z }, true, -1, miss->uid ); + doghouse.load( project_to( house ), false ); + doghouse.add_spawn( mon_dog, 1, { SEEX, SEEY, house.z() }, true, -1, miss->uid ); doghouse.save(); } void mission_start::place_zombie_mom( mission *miss ) { - const tripoint house = mission_util::random_house_in_closest_city(); + const tripoint_abs_omt house = mission_util::random_house_in_closest_city(); miss->target = house; overmap_buffer.reveal( house, 6 ); tinymap zomhouse; - zomhouse.load( tripoint( house.x * 2, house.y * 2, house.z ), false ); - zomhouse.add_spawn( mon_zombie, 1, { SEEX, SEEY, house.z }, false, -1, miss->uid, + zomhouse.load( project_to( house ), false ); + zomhouse.add_spawn( mon_zombie, 1, { SEEX, SEEY, house.z() }, false, -1, miss->uid, Name::get( nameFlags::IsFemaleName | nameFlags::IsGivenName ) ); zomhouse.save(); } @@ -93,8 +94,8 @@ void mission_start::kill_horde_master( mission *miss ) // Npc joins you p->set_attitude( NPCATT_FOLLOW ); // Pick one of the below locations for the horde to haunt - const auto center = p->global_omt_location(); - tripoint site = overmap_buffer.find_closest( center, "office_tower_1", 0, false ); + const tripoint_abs_omt center = p->global_omt_location(); + tripoint_abs_omt site = overmap_buffer.find_closest( center, "office_tower_1", 0, false ); if( site == overmap::invalid_tripoint ) { site = overmap_buffer.find_closest( center, "hotel_tower_1_8", 0, false ); } @@ -107,22 +108,20 @@ void mission_start::kill_horde_master( mission *miss ) miss->target = site; overmap_buffer.reveal( site, 6 ); tinymap tile; - tile.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); - tile.add_spawn( mon_zombie_master, 1, { SEEX, SEEY, site.z }, false, -1, miss->uid, + tile.load( project_to( site ), false ); + tile.add_spawn( mon_zombie_master, 1, { SEEX, SEEY, site.z() }, false, -1, miss->uid, _( "Demonic Soul" ) ); - tile.add_spawn( mon_zombie_brute, 3, { SEEX, SEEY, site.z } ); - tile.add_spawn( mon_zombie_dog, 3, { SEEX, SEEY, site.z } ); + tile.add_spawn( mon_zombie_brute, 3, { SEEX, SEEY, site.z() } ); + tile.add_spawn( mon_zombie_dog, 3, { SEEX, SEEY, site.z() } ); - if( overmap::inbounds( tripoint( SEEX, SEEY, 0 ), 1 ) ) { - for( int x = SEEX - 1; x <= SEEX + 1; x++ ) { - for( int y = SEEY - 1; y <= SEEY + 1; y++ ) { - tile.add_spawn( mon_zombie, rng( 3, 10 ), { x, y, site.z } ); - } - tile.add_spawn( mon_zombie_dog, rng( 0, 2 ), { SEEX, SEEY, site.z } ); + for( int x = SEEX - 1; x <= SEEX + 1; x++ ) { + for( int y = SEEY - 1; y <= SEEY + 1; y++ ) { + tile.add_spawn( mon_zombie, rng( 3, 10 ), { x, y, site.z() } ); } + tile.add_spawn( mon_zombie_dog, rng( 0, 2 ), { SEEX, SEEY, site.z() } ); } - tile.add_spawn( mon_zombie_necro, 2, { SEEX, SEEY, site.z } ); - tile.add_spawn( mon_zombie_hulk, 1, { SEEX, SEEY, site.z } ); + tile.add_spawn( mon_zombie_necro, 2, { SEEX, SEEY, site.z() } ); + tile.add_spawn( mon_zombie_hulk, 1, { SEEX, SEEY, site.z() } ); tile.save(); } @@ -209,7 +208,7 @@ void mission_start::place_npc_software( mission *miss ) miss->item_id = itype_software_useless; } - tripoint place; + tripoint_abs_omt place; if( type == "house" ) { place = mission_util::random_house_in_closest_city(); } else { @@ -219,7 +218,7 @@ void mission_start::place_npc_software( mission *miss ) overmap_buffer.reveal( place, 6 ); tinymap compmap; - compmap.load( tripoint( place.x * 2, place.y * 2, place.z ), false ); + compmap.load( project_to( place ), false ); tripoint comppoint; oter_id oter = overmap_buffer.ter( place ); @@ -238,11 +237,11 @@ void mission_start::place_npc_software( mission *miss ) void mission_start::place_priest_diary( mission *miss ) { - const tripoint place = mission_util::random_house_in_closest_city(); + const tripoint_abs_omt place = mission_util::random_house_in_closest_city(); miss->target = place; overmap_buffer.reveal( place, 2 ); tinymap compmap; - compmap.load( tripoint( place.x * 2, place.y * 2, place.z ), false ); + compmap.load( project_to( place ), false ); std::vector valid; for( const tripoint &p : compmap.points_on_zlevel() ) { @@ -251,7 +250,7 @@ void mission_start::place_priest_diary( mission *miss ) valid.push_back( p ); } } - const tripoint fallback( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), place.z ); + const tripoint fallback( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), place.z() ); const tripoint comppoint = random_entry( valid, fallback ); compmap.spawn_item( comppoint, "priest_diary" ); compmap.save(); @@ -266,7 +265,8 @@ void mission_start::place_deposit_box( mission *miss ) } // Npc joins you p->set_attitude( NPCATT_FOLLOW ); - tripoint site = overmap_buffer.find_closest( p->global_omt_location(), "bank", 0, false ); + tripoint_abs_omt site = + overmap_buffer.find_closest( p->global_omt_location(), "bank", 0, false ); if( site == overmap::invalid_tripoint ) { site = overmap_buffer.find_closest( p->global_omt_location(), "office_tower_1", 0, false ); } @@ -280,7 +280,7 @@ void mission_start::place_deposit_box( mission *miss ) overmap_buffer.reveal( site, 2 ); tinymap compmap; - compmap.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + compmap.load( project_to( site ), false ); std::vector valid; for( const tripoint &p : compmap.points_on_zlevel() ) { if( compmap.ter( p ) == t_floor ) { @@ -292,7 +292,7 @@ void mission_start::place_deposit_box( mission *miss ) } } } - const tripoint fallback( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), site.z ); + const tripoint fallback( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), site.z() ); const tripoint comppoint = random_entry( valid, fallback ); compmap.spawn_item( comppoint, "safe_box" ); compmap.save(); @@ -300,28 +300,28 @@ void mission_start::place_deposit_box( mission *miss ) void mission_start::find_safety( mission *miss ) { - const tripoint place = get_player_character().global_omt_location(); + const tripoint_abs_omt place = get_player_character().global_omt_location(); for( int radius = 0; radius <= 20; radius++ ) { for( int dist = 0 - radius; dist <= radius; dist++ ) { int offset = rng( 0, 3 ); // Randomizes the direction we check first for( int i = 0; i <= 3; i++ ) { // Which direction? - tripoint check = place; + tripoint_abs_omt check = place; switch( ( offset + i ) % 4 ) { case 0: - check.x += dist; - check.y -= radius; + check.x() += dist; + check.y() -= radius; break; case 1: - check.x += dist; - check.y += radius; + check.x() += dist; + check.y() += radius; break; case 2: - check.y += dist; - check.x -= radius; + check.y() += dist; + check.x() -= radius; break; case 3: - check.y += dist; - check.x += radius; + check.y() += dist; + check.x() += radius; break; } if( overmap_buffer.is_safe( check ) ) { @@ -353,9 +353,10 @@ const int RANCH_SIZE = 5; void mission_start::ranch_nurse_1( mission *miss ) { //Improvements to clinic... - tripoint site = mission_util::target_om_ter_random( "ranch_camp_59", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_59", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.draw_square_furn( f_rack, point( 16, 9 ), point( 17, 9 ) ); bay.spawn_item( point( 16, 9 ), "bandages", rng( 1, 3 ) ); bay.spawn_item( point( 17, 9 ), "aspirin", rng( 1, 2 ) ); @@ -365,9 +366,10 @@ void mission_start::ranch_nurse_1( mission *miss ) void mission_start::ranch_nurse_2( mission *miss ) { //Improvements to clinic... - tripoint site = mission_util::target_om_ter_random( "ranch_camp_59", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_59", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.draw_square_furn( f_counter, point( 3, 7 ), point( 5, 7 ) ); bay.draw_square_furn( f_rack, point( 8, 4 ), point( 8, 5 ) ); bay.spawn_item( point( 8, 4 ), "manual_first_aid" ); @@ -377,16 +379,17 @@ void mission_start::ranch_nurse_2( mission *miss ) void mission_start::ranch_nurse_3( mission *miss ) { //Improvements to clinic... - tripoint site = mission_util::target_om_ter_random( "ranch_camp_50", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_50", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.draw_square_ter( t_dirt, point( 2, 16 ), point( 9, 23 ) ); bay.draw_square_ter( t_dirt, point( 13, 16 ), point( 20, 23 ) ); bay.draw_square_ter( t_dirt, point( 10, 17 ), point( 12, 23 ) ); bay.save(); site = mission_util::target_om_ter_random( "ranch_camp_59", 1, miss, false, RANCH_SIZE ); - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.draw_square_ter( t_dirt, point( 2, 0 ), point( 20, 2 ) ); bay.draw_square_ter( t_dirt, point( 10, 3 ), point( 12, 4 ) ); bay.save(); @@ -395,9 +398,10 @@ void mission_start::ranch_nurse_3( mission *miss ) void mission_start::ranch_nurse_4( mission *miss ) { //Improvements to clinic... - tripoint site = mission_util::target_om_ter_random( "ranch_camp_50", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_50", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.draw_square_ter( t_wall_half, point( 2, 16 ), point( 9, 23 ) ); bay.draw_square_ter( t_dirt, point( 3, 17 ), point( 8, 22 ) ); bay.draw_square_ter( t_wall_half, point( 13, 16 ), point( 20, 23 ) ); @@ -409,7 +413,7 @@ void mission_start::ranch_nurse_4( mission *miss ) bay.save(); site = mission_util::target_om_ter_random( "ranch_camp_59", 1, miss, false, RANCH_SIZE ); - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.draw_square_ter( t_wall_half, point( 4, 0 ), point( 18, 2 ) ); bay.draw_square_ter( t_wall_half, point( 10, 3 ), point( 12, 4 ) ); bay.draw_square_ter( t_dirt, point( 5, 0 ), point( 8, 2 ) ); @@ -423,9 +427,10 @@ void mission_start::ranch_nurse_4( mission *miss ) void mission_start::ranch_nurse_5( mission *miss ) { //Improvements to clinic... - tripoint site = mission_util::target_om_ter_random( "ranch_camp_50", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_50", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.translate( t_wall_half, t_wall_wood ); bay.ter_set( point( 2, 21 ), t_window_frame ); bay.ter_set( point( 2, 18 ), t_window_frame ); @@ -435,7 +440,7 @@ void mission_start::ranch_nurse_5( mission *miss ) bay.save(); site = mission_util::target_om_ter_random( "ranch_camp_59", 1, miss, false, RANCH_SIZE ); - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.translate( t_wall_half, t_wall_wood ); bay.draw_square_ter( t_dirt, point( 10, 0 ), point( 12, 4 ) ); bay.save(); @@ -444,9 +449,10 @@ void mission_start::ranch_nurse_5( mission *miss ) void mission_start::ranch_nurse_6( mission *miss ) { //Improvements to clinic... - tripoint site = mission_util::target_om_ter_random( "ranch_camp_50", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_50", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.translate( t_window_frame, t_window_boarded_noglass ); bay.translate( t_door_frame, t_door_c ); bay.draw_square_ter( t_dirtfloor, point( 3, 17 ), point( 8, 22 ) ); @@ -455,7 +461,7 @@ void mission_start::ranch_nurse_6( mission *miss ) bay.save(); site = mission_util::target_om_ter_random( "ranch_camp_59", 1, miss, false, RANCH_SIZE ); - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.translate( t_door_frame, t_door_c ); bay.draw_square_ter( t_dirtfloor, point( 5, 0 ), point( 8, 2 ) ); bay.draw_square_ter( t_dirtfloor, point( 10, 0 ), point( 12, 4 ) ); @@ -466,14 +472,15 @@ void mission_start::ranch_nurse_6( mission *miss ) void mission_start::ranch_nurse_7( mission *miss ) { //Improvements to clinic... - tripoint site = mission_util::target_om_ter_random( "ranch_camp_50", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_50", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.translate( t_dirtfloor, t_floor ); bay.save(); site = mission_util::target_om_ter_random( "ranch_camp_59", 1, miss, false, RANCH_SIZE ); - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.translate( t_dirtfloor, t_floor ); bay.draw_square_ter( t_floor, point( 10, 5 ), point( 12, 5 ) ); bay.draw_square_furn( f_rack, point( 17, 0 ), point( 17, 2 ) ); @@ -483,9 +490,10 @@ void mission_start::ranch_nurse_7( mission *miss ) void mission_start::ranch_nurse_8( mission *miss ) { //Improvements to clinic... - tripoint site = mission_util::target_om_ter_random( "ranch_camp_50", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_50", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.draw_square_furn( f_makeshift_bed, point( 4, 21 ), point( 4, 22 ) ); bay.draw_square_furn( f_makeshift_bed, point( 7, 21 ), point( 7, 22 ) ); bay.draw_square_furn( f_makeshift_bed, point( 15, 21 ), point( 15, 22 ) ); @@ -497,7 +505,7 @@ void mission_start::ranch_nurse_8( mission *miss ) bay.save(); site = mission_util::target_om_ter_random( "ranch_camp_59", 1, miss, false, RANCH_SIZE ); - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.translate( t_dirtfloor, t_floor ); bay.place_items( "cleaning", 75, point( 17, 0 ), point( 17, 2 ), true, calendar::start_of_cataclysm ); @@ -509,9 +517,10 @@ void mission_start::ranch_nurse_8( mission *miss ) void mission_start::ranch_nurse_9( mission *miss ) { //Improvements to clinic... - tripoint site = mission_util::target_om_ter_random( "ranch_camp_50", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_50", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.furn_set( point( 3, 22 ), f_dresser ); bay.furn_set( point( 8, 22 ), f_dresser ); bay.furn_set( point( 14, 22 ), f_dresser ); @@ -528,16 +537,17 @@ void mission_start::ranch_nurse_9( mission *miss ) void mission_start::ranch_scavenger_1( mission *miss ) { - tripoint site = mission_util::target_om_ter_random( "ranch_camp_48", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_48", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.draw_square_ter( t_chainfence, point( 15, 13 ), point( 15, 22 ) ); bay.draw_square_ter( t_chainfence, point( 16, 13 ), point( 23, 13 ) ); bay.draw_square_ter( t_chainfence, point( 16, 22 ), point( 23, 22 ) ); bay.save(); site = mission_util::target_om_ter_random( "ranch_camp_49", 1, miss, false, RANCH_SIZE ); - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.place_items( "mechanics", 65, point( 9, 13 ), point( 10, 16 ), true, 0 ); bay.draw_square_ter( t_chainfence, point( 0, 22 ), point( 7, 22 ) ); bay.draw_square_ter( t_dirt, point( 2, 22 ), point( 3, 22 ) ); @@ -547,9 +557,10 @@ void mission_start::ranch_scavenger_1( mission *miss ) void mission_start::ranch_scavenger_2( mission *miss ) { - tripoint site = mission_util::target_om_ter_random( "ranch_camp_48", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_48", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.add_vehicle( vproto_id( "car_chassis" ), point( 20, 15 ), 0 ); bay.draw_square_ter( t_wall_half, point( 18, 19 ), point( 21, 22 ) ); bay.draw_square_ter( t_dirt, point( 19, 20 ), point( 20, 21 ) ); @@ -557,7 +568,7 @@ void mission_start::ranch_scavenger_2( mission *miss ) bay.save(); site = mission_util::target_om_ter_random( "ranch_camp_49", 1, miss, false, RANCH_SIZE ); - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.place_items( "mischw", 65, point( 12, 13 ), point( 13, 16 ), true, calendar::start_of_cataclysm ); bay.draw_square_ter( t_chaingate_l, point( 2, 22 ), point( 3, 22 ) ); @@ -567,9 +578,10 @@ void mission_start::ranch_scavenger_2( mission *miss ) void mission_start::ranch_scavenger_3( mission *miss ) { - tripoint site = mission_util::target_om_ter_random( "ranch_camp_48", 1, miss, false, RANCH_SIZE ); + tripoint_abs_omt site = mission_util::target_om_ter_random( + "ranch_camp_48", 1, miss, false, RANCH_SIZE ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.translate( t_door_frame, t_door_locked ); bay.translate( t_wall_half, t_wall_wood ); bay.draw_square_ter( t_dirtfloor, point( 19, 20 ), point( 20, 21 ) ); @@ -582,7 +594,7 @@ void mission_start::ranch_scavenger_3( mission *miss ) bay.save(); site = mission_util::target_om_ter_random( "ranch_camp_49", 1, miss, false, RANCH_SIZE ); - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.place_items( "mischw", 65, point( 2, 10 ), point( 4, 10 ), true, calendar::start_of_cataclysm ); bay.place_items( "mischw", 65, point( 2, 13 ), point( 4, 13 ), true, calendar::start_of_cataclysm ); bay.furn_set( point( 1, 15 ), f_fridge ); @@ -604,17 +616,17 @@ void mission_start::reveal_refugee_center( mission *miss ) t.search_range = 0; t.reveal_radius = 3; - const cata::optional target_pos = mission_util::assign_mission_target( t ); + const cata::optional target_pos = mission_util::assign_mission_target( t ); if( !target_pos ) { add_msg( _( "You don't know where the address could beā€¦" ) ); return; } - const tripoint source_road = overmap_buffer.find_closest( - get_player_character().global_omt_location(), "road", - 3, false ); - const tripoint dest_road = overmap_buffer.find_closest( *target_pos, "road", 3, false ); + const tripoint_abs_omt source_road = overmap_buffer.find_closest( + get_player_character().global_omt_location(), "road", + 3, false ); + const tripoint_abs_omt dest_road = overmap_buffer.find_closest( *target_pos, "road", 3, false ); if( overmap_buffer.reveal_route( source_road, dest_road, 1, true ) ) { add_msg( _( "You mark the refugee center and the road that leads to itā€¦" ) ); @@ -624,16 +636,17 @@ void mission_start::reveal_refugee_center( mission *miss ) } // Creates multiple lab consoles near tripoint place, which must have its z-level set to where consoles should go. -void static create_lab_consoles( mission *miss, const tripoint &place, const std::string &otype, - int security, - const std::string &comp_name, const std::string &download_name ) +void static create_lab_consoles( + mission *miss, const tripoint_abs_omt &place, const std::string &otype, int security, + const std::string &comp_name, const std::string &download_name ) { // Drop four computers in nearby lab spaces so the player can stumble upon one of them. for( int i = 0; i < 4; ++i ) { - tripoint om_place = mission_util::target_om_ter_random( otype, -1, miss, false, 4, place ); + tripoint_abs_omt om_place = mission_util::target_om_ter_random( + otype, -1, miss, false, 4, place ); tinymap compmap; - compmap.load( tripoint( om_place.x * 2, om_place.y * 2, om_place.z ), false ); + compmap.load( project_to( om_place ), false ); tripoint comppoint = find_potential_computer_point( compmap ); @@ -652,15 +665,15 @@ void mission_start::create_lab_console( mission *miss ) { Character &player_character = get_player_character(); // Pick a lab that has spaces on z = -1: e.g., in hidden labs. - tripoint loc = player_character.global_omt_location(); - loc.z = -1; - const tripoint place = overmap_buffer.find_closest( loc, "lab", 0, false ); + tripoint_abs_omt loc = player_character.global_omt_location(); + loc.z() = -1; + const tripoint_abs_omt place = overmap_buffer.find_closest( loc, "lab", 0, false ); create_lab_consoles( miss, place, "lab", 2, translate_marker( "Workstation" ), translate_marker( "Download Memory Contents" ) ); // Target the lab entrance. - const tripoint target = mission_util::target_closest_lab_entrance( place, 2, miss ); + const tripoint_abs_omt target = mission_util::target_closest_lab_entrance( place, 2, miss ); mission_util::reveal_road( player_character.global_omt_location(), target, overmap_buffer ); } @@ -668,17 +681,17 @@ void mission_start::create_hidden_lab_console( mission *miss ) { Character &player_character = get_player_character(); // Pick a hidden lab entrance. - tripoint loc = player_character.global_omt_location(); - loc.z = -1; - tripoint place = mission_util::target_om_ter_random( "basement_hidden_lab_stairs", -1, miss, false, - 0, loc ); - place.z = -2; // then go down 1 z-level to place consoles. + tripoint_abs_omt loc = player_character.global_omt_location(); + loc.z() = -1; + tripoint_abs_omt place = + mission_util::target_om_ter_random( "basement_hidden_lab_stairs", -1, miss, false, 0, loc ); + place.z() = -2; // then go down 1 z-level to place consoles. create_lab_consoles( miss, place, "lab", 3, translate_marker( "Workstation" ), translate_marker( "Download Encryption Routines" ) ); // Target the lab entrance. - const tripoint target = mission_util::target_closest_lab_entrance( place, 2, miss ); + const tripoint_abs_omt target = mission_util::target_closest_lab_entrance( place, 2, miss ); mission_util::reveal_road( player_character.global_omt_location(), target, overmap_buffer ); } @@ -686,15 +699,15 @@ void mission_start::create_ice_lab_console( mission *miss ) { Character &player_character = get_player_character(); // Pick an ice lab with spaces on z = -4. - tripoint loc = player_character.global_omt_location(); - loc.z = -4; - const tripoint place = overmap_buffer.find_closest( loc, "ice_lab", 0, false ); + tripoint_abs_omt loc = player_character.global_omt_location(); + loc.z() = -4; + const tripoint_abs_omt place = overmap_buffer.find_closest( loc, "ice_lab", 0, false ); create_lab_consoles( miss, place, "ice_lab", 3, translate_marker( "Durable Storage Archive" ), translate_marker( "Download Archives" ) ); // Target the lab entrance. - const tripoint target = mission_util::target_closest_lab_entrance( place, 2, miss ); + const tripoint_abs_omt target = mission_util::target_closest_lab_entrance( place, 2, miss ); mission_util::reveal_road( player_character.global_omt_location(), target, overmap_buffer ); } @@ -702,12 +715,12 @@ void mission_start::reveal_lab_train_depot( mission *miss ) { Character &player_character = get_player_character(); // Find and prepare lab location. - tripoint loc = player_character.global_omt_location(); - loc.z = -4; // tunnels are at z = -4 - const tripoint place = overmap_buffer.find_closest( loc, "lab_train_depot", 0, false ); + tripoint_abs_omt loc = player_character.global_omt_location(); + loc.z() = -4; // tunnels are at z = -4 + const tripoint_abs_omt place = overmap_buffer.find_closest( loc, "lab_train_depot", 0, false ); tinymap compmap; - compmap.load( tripoint( place.x * 2, place.y * 2, place.z ), false ); + compmap.load( project_to( place ), false ); cata::optional comppoint; for( const tripoint &point : compmap.points_on_zlevel() ) { @@ -729,6 +742,6 @@ void mission_start::reveal_lab_train_depot( mission *miss ) compmap.save(); // Target the lab entrance. - const tripoint target = mission_util::target_closest_lab_entrance( place, 2, miss ); + const tripoint_abs_omt target = mission_util::target_closest_lab_entrance( place, 2, miss ); mission_util::reveal_road( player_character.global_omt_location(), target, overmap_buffer ); } diff --git a/src/mission_ui.cpp b/src/mission_ui.cpp index bc6bfeaeb3278..fd720454e8589 100644 --- a/src/mission_ui.cpp +++ b/src/mission_ui.cpp @@ -141,10 +141,10 @@ void game::list_missions() } } if( miss->has_target() ) { - const tripoint pos = u.global_omt_location(); + const tripoint_abs_omt pos = u.global_omt_location(); // TODO: target does not contain a z-component, targets are assumed to be on z=0 - mvwprintz( w_missions, point( 31, ++y ), c_white, _( "Target: (%d, %d) You: (%d, %d)" ), - miss->get_target().x, miss->get_target().y, pos.x, pos.y ); + mvwprintz( w_missions, point( 31, ++y ), c_white, _( "Target: %s You: %s" ), + miss->get_target().to_string(), pos.to_string() ); } } else { static const std::map< tab_mode, std::string > nope = { diff --git a/src/mission_util.cpp b/src/mission_util.cpp index 1b9b8c07bdad3..9b3974c84da70 100644 --- a/src/mission_util.cpp +++ b/src/mission_util.cpp @@ -30,10 +30,11 @@ #include "translations.h" #include "type_id.h" -static tripoint reveal_destination( const std::string &type ) +static tripoint_abs_omt reveal_destination( const std::string &type ) { - const tripoint your_pos = get_player_character().global_omt_location(); - const tripoint center_pos = overmap_buffer.find_random( your_pos, type, rng( 40, 80 ), false ); + const tripoint_abs_omt your_pos = get_player_character().global_omt_location(); + const tripoint_abs_omt center_pos = + overmap_buffer.find_random( your_pos, type, rng( 40, 80 ), false ); if( center_pos != overmap::invalid_tripoint ) { overmap_buffer.reveal( center_pos, 2 ); @@ -43,7 +44,7 @@ static tripoint reveal_destination( const std::string &type ) return overmap::invalid_tripoint; } -static void reveal_route( mission *miss, const tripoint &destination ) +static void reveal_route( mission *miss, const tripoint_abs_omt &destination ) { const npc *p = g->find_npc( miss->get_npc_id() ); if( p == nullptr ) { @@ -51,10 +52,10 @@ static void reveal_route( mission *miss, const tripoint &destination ) return; } - const tripoint source = get_player_character().global_omt_location(); + const tripoint_abs_omt source = get_player_character().global_omt_location(); - const tripoint source_road = overmap_buffer.find_closest( source, "road", 3, false ); - const tripoint dest_road = overmap_buffer.find_closest( destination, "road", 3, false ); + const tripoint_abs_omt source_road = overmap_buffer.find_closest( source, "road", 3, false ); + const tripoint_abs_omt dest_road = overmap_buffer.find_closest( destination, "road", 3, false ); if( overmap_buffer.reveal_route( source_road, dest_road ) ) { add_msg( _( "%s also marks the road that leads to itā€¦" ), p->name ); @@ -69,7 +70,7 @@ static void reveal_target( mission *miss, const std::string &omter_id ) return; } - const tripoint destination = reveal_destination( omter_id ); + const tripoint_abs_omt destination = reveal_destination( omter_id ); if( destination != overmap::invalid_tripoint ) { const oter_id oter = overmap_buffer.ter( destination ); add_msg( _( "%s has marked the only %s known to them on your map." ), p->name, @@ -86,23 +87,24 @@ static void reveal_any_target( mission *miss, const std::vector &om reveal_target( miss, random_entry( omter_ids ) ); } -bool mission_util::reveal_road( const tripoint &source, const tripoint &dest, overmapbuffer &omb ) +bool mission_util::reveal_road( const tripoint_abs_omt &source, const tripoint_abs_omt &dest, + overmapbuffer &omb ) { - const tripoint source_road = overmap_buffer.find_closest( source, "road", 3, false ); - const tripoint dest_road = overmap_buffer.find_closest( dest, "road", 3, false ); + const tripoint_abs_omt source_road = overmap_buffer.find_closest( source, "road", 3, false ); + const tripoint_abs_omt dest_road = overmap_buffer.find_closest( dest, "road", 3, false ); return omb.reveal_route( source_road, dest_road ); } /** * Reveal the cloest overmap terrain of a type and return the its location */ -tripoint mission_util::reveal_om_ter( const std::string &omter, int reveal_rad, bool must_see, - int target_z ) +tripoint_abs_omt mission_util::reveal_om_ter( const std::string &omter, int reveal_rad, + bool must_see, int target_z ) { // Missions are normally on z-level 0, but allow an optional argument. - tripoint loc = get_player_character().global_omt_location(); - loc.z = target_z; - const tripoint place = overmap_buffer.find_closest( loc, omter, 0, must_see ); + tripoint_abs_omt loc = get_player_character().global_omt_location(); + loc.z() = target_z; + const tripoint_abs_omt place = overmap_buffer.find_closest( loc, omter, 0, must_see ); if( place != overmap::invalid_tripoint && reveal_rad >= 0 ) { overmap_buffer.reveal( place, reveal_rad ); } @@ -113,11 +115,13 @@ tripoint mission_util::reveal_om_ter( const std::string &omter, int reveal_rad, * Given a (valid!) city reference, select a random house within the city borders. * @return global overmap terrain coordinates of the house. */ -static tripoint random_house_in_city( const city_reference &cref ) +static tripoint_abs_omt random_house_in_city( const city_reference &cref ) { - const tripoint city_center_omt = sm_to_omt_copy( cref.abs_sm_pos ); - std::vector valid; - for( const tripoint &p : points_in_radius( city_center_omt, cref.city->size ) ) { + // TODO: fix point types + const tripoint_abs_omt city_center_omt = + project_to( cref.abs_sm_pos ); + std::vector valid; + for( const tripoint_abs_omt &p : points_in_radius( city_center_omt, cref.city->size ) ) { if( overmap_buffer.check_ot( "house", ot_match_type::prefix, p ) ) { valid.push_back( p ); } @@ -125,10 +129,11 @@ static tripoint random_house_in_city( const city_reference &cref ) return random_entry( valid, city_center_omt ); // center of the city is a good fallback } -tripoint mission_util::random_house_in_closest_city() +tripoint_abs_omt mission_util::random_house_in_closest_city() { Character &player_character = get_player_character(); - const tripoint center = player_character.global_sm_location(); + // TODO: fix point types + const tripoint_abs_sm center( player_character.global_sm_location() ); const city_reference cref = overmap_buffer.closest_city( center ); if( !cref ) { debugmsg( "could not find closest city" ); @@ -137,21 +142,22 @@ tripoint mission_util::random_house_in_closest_city() return random_house_in_city( cref ); } -tripoint mission_util::target_closest_lab_entrance( const tripoint &origin, int reveal_rad, - mission *miss ) +tripoint_abs_omt mission_util::target_closest_lab_entrance( + const tripoint_abs_omt &origin, int reveal_rad, mission *miss ) { - tripoint testpoint = tripoint( origin ); + tripoint_abs_omt testpoint = origin; // Get the surface locations for labs and for spaces above hidden lab stairs. - testpoint.z = 0; - tripoint surface = overmap_buffer.find_closest( testpoint, "lab_stairs", 0, false, - ot_match_type::contains ); + testpoint.z() = 0; + tripoint_abs_omt surface = overmap_buffer.find_closest( testpoint, "lab_stairs", 0, false, + ot_match_type::contains ); - testpoint.z = -1; - tripoint underground = overmap_buffer.find_closest( testpoint, "hidden_lab_stairs", 0, false, - ot_match_type::contains ); - underground.z = 0; + testpoint.z() = -1; + tripoint_abs_omt underground = + overmap_buffer.find_closest( testpoint, "hidden_lab_stairs", 0, false, + ot_match_type::contains ); + underground.z() = 0; - tripoint closest; + tripoint_abs_omt closest; if( square_dist( surface.xy(), origin.xy() ) <= square_dist( underground.xy(), origin.xy() ) ) { closest = surface; } else { @@ -165,10 +171,10 @@ tripoint mission_util::target_closest_lab_entrance( const tripoint &origin, int return closest; } -static cata::optional find_or_create_om_terrain( const tripoint &origin_pos, - const mission_target_params ¶ms ) +static cata::optional find_or_create_om_terrain( + const tripoint_abs_omt &origin_pos, const mission_target_params ¶ms ) { - tripoint target_pos = overmap::invalid_tripoint; + tripoint_abs_omt target_pos = overmap::invalid_tripoint; omt_find_params find_params; std::vector> temp_types; @@ -247,10 +253,10 @@ static cata::optional find_or_create_om_terrain( const tripoint &origi return target_pos; } -static tripoint get_mission_om_origin( const mission_target_params ¶ms ) +static tripoint_abs_omt get_mission_om_origin( const mission_target_params ¶ms ) { // use the player or NPC's current position, adjust for the z value if any - tripoint origin_pos = get_player_character().global_omt_location(); + tripoint_abs_omt origin_pos = get_player_character().global_omt_location(); if( !params.origin_u ) { npc *guy = nullptr; @@ -264,17 +270,18 @@ static tripoint get_mission_om_origin( const mission_target_params ¶ms ) } } if( params.z ) { - origin_pos.z = *params.z; + origin_pos.z() = *params.z; } return origin_pos; } -cata::optional mission_util::assign_mission_target( const mission_target_params ¶ms ) +cata::optional mission_util::assign_mission_target( + const mission_target_params ¶ms ) { // use the player or NPC's current position, adjust for the z value if any - tripoint origin_pos = get_mission_om_origin( params ); + tripoint_abs_omt origin_pos = get_mission_om_origin( params ); - cata::optional target_pos = find_or_create_om_terrain( origin_pos, params ); + cata::optional target_pos = find_or_create_om_terrain( origin_pos, params ); if( target_pos ) { if( params.offset ) { @@ -293,14 +300,14 @@ cata::optional mission_util::assign_mission_target( const mission_targ return target_pos; } -tripoint mission_util::get_om_terrain_pos( const mission_target_params ¶ms ) +tripoint_abs_omt mission_util::get_om_terrain_pos( const mission_target_params ¶ms ) { // use the player or NPC's current position, adjust for the z value if any - tripoint origin_pos = get_mission_om_origin( params ); + tripoint_abs_omt origin_pos = get_mission_om_origin( params ); - tripoint target_pos = origin_pos; + tripoint_abs_omt target_pos = origin_pos; if( !params.overmap_terrain.empty() ) { - cata::optional temp_pos = find_or_create_om_terrain( origin_pos, params ); + cata::optional temp_pos = find_or_create_om_terrain( origin_pos, params ); if( temp_pos ) { target_pos = *temp_pos; } @@ -323,16 +330,16 @@ tripoint mission_util::get_om_terrain_pos( const mission_target_params ¶ms ) * reveal the area around it (uses reveal with reveal_rad), * and returns the mission target. */ -tripoint mission_util::target_om_ter( const std::string &omter, int reveal_rad, mission *miss, - bool must_see, int target_z ) +tripoint_abs_omt mission_util::target_om_ter( + const std::string &omter, int reveal_rad, mission *miss, bool must_see, int target_z ) { - const tripoint place = reveal_om_ter( omter, reveal_rad, must_see, target_z ); + const tripoint_abs_omt place = reveal_om_ter( omter, reveal_rad, must_see, target_z ); miss->set_target( place ); return place; } -tripoint mission_util::target_om_ter_random( const std::string &omter, int reveal_rad, - mission *miss, bool must_see, int range, tripoint loc ) +tripoint_abs_omt mission_util::target_om_ter_random( const std::string &omter, int reveal_rad, + mission *miss, bool must_see, int range, tripoint_abs_omt loc ) { Character &player_character = get_player_character(); if( loc == overmap::invalid_tripoint ) { @@ -346,14 +353,14 @@ tripoint mission_util::target_om_ter_random( const std::string &omter, int revea const overmap *loc_om = overmap_buffer.get_existing_om_global( loc ).om; assert( loc_om ); - std::vector places_om; + std::vector places_om; for( auto &i : places ) { if( loc_om == overmap_buffer.get_existing_om_global( i ).om ) { places_om.push_back( i ); } } - const tripoint place = random_entry( places_om ); + const tripoint_abs_omt place = random_entry( places_om ); if( reveal_rad >= 0 ) { overmap_buffer.reveal( place, reveal_rad ); } @@ -401,15 +408,15 @@ mission_target_params mission_util::parse_mission_om_target( const JsonObject &j p.min_distance = std::max( 1, jo.get_int( "min_distance" ) ); } if( jo.has_member( "offset_x" ) || jo.has_member( "offset_y" ) || jo.has_member( "offset_z" ) ) { - tripoint offset; + tripoint_rel_omt offset; if( jo.has_member( "offset_x" ) ) { - offset.x = jo.get_int( "offset_x" ); + offset.x() = jo.get_int( "offset_x" ); } if( jo.has_member( "offset_y" ) ) { - offset.y = jo.get_int( "offset_y" ); + offset.y() = jo.get_int( "offset_y" ); } if( jo.has_member( "offset_z" ) ) { - offset.z = jo.get_int( "offset_z" ); + offset.z() = jo.get_int( "offset_z" ); } p.offset = offset; } @@ -466,13 +473,13 @@ bool mission_util::set_update_mapgen( const JsonObject &jo, if( jo.has_member( "om_terrain" ) ) { const std::string om_terrain = jo.get_string( "om_terrain" ); const auto mission_func = [update_map, om_terrain]( mission * miss ) { - tripoint update_pos3 = mission_util::reveal_om_ter( om_terrain, 1, false ); + tripoint_abs_omt update_pos3 = mission_util::reveal_om_ter( om_terrain, 1, false ); update_map( update_pos3, miss ); }; funcs.emplace_back( mission_func ); } else { const auto mission_func = [update_map]( mission * miss ) { - tripoint update_pos3 = miss->get_target(); + tripoint_abs_omt update_pos3 = miss->get_target(); update_map( update_pos3, miss ); }; funcs.emplace_back( mission_func ); diff --git a/src/missiondef.cpp b/src/missiondef.cpp index f6da779457fcd..176c0134b358e 100644 --- a/src/missiondef.cpp +++ b/src/missiondef.cpp @@ -132,8 +132,8 @@ static const std::map> mission_fun } }; -static const std::map> tripoint_function_map -= {{ +static const std::map> +tripoint_function_map = {{ { "never", mission_place::never }, { "always", mission_place::always }, { "near_town", mission_place::near_town } @@ -459,7 +459,8 @@ const std::vector &mission_type::get_all() return mission_type_factory.get_all(); } -mission_type_id mission_type::get_random_id( const mission_origin origin, const tripoint &p ) +mission_type_id mission_type::get_random_id( const mission_origin origin, + const tripoint_abs_omt &p ) { std::vector valid; for( auto &t : get_all() ) { diff --git a/src/mongroup.h b/src/mongroup.h index a19e581e79187..4fe0f5301a6d8 100644 --- a/src/mongroup.h +++ b/src/mongroup.h @@ -84,10 +84,10 @@ struct mongroup { mongroup_id type; // Note: position is not saved as such in the json // Instead, a vector of positions is saved for - tripoint pos = tripoint_zero; + tripoint_om_sm pos; unsigned int radius = 1; unsigned int population = 1; - tripoint target = tripoint_zero; // location the horde is interested in. + tripoint_om_sm target; // location the horde is interested in. int interest = 0; //interest to target in percents bool dying = false; bool horde = false; @@ -112,6 +112,10 @@ struct mongroup { , radius( prad ) , population( ppop ) { } + mongroup( const mongroup_id &ptype, const tripoint_om_sm &ppos, + unsigned int prad, unsigned int ppop ) : + // TODO: fix point types + mongroup( ptype, ppos.raw(), prad, ppop ) {} mongroup( const std::string &ptype, tripoint ppos, unsigned int prad, unsigned int ppop, tripoint ptarget, int pint, bool pdie, bool phorde, bool pdiff ) : type( ptype ), pos( ppos ), radius( prad ), population( ppop ), target( ptarget ), @@ -120,9 +124,9 @@ struct mongroup { bool is_safe() const; bool empty() const; void clear(); - void set_target( const point &p ) { - target.x = p.x; - target.y = p.y; + void set_target( const point_om_sm &p ) { + target.x() = p.x(); + target.y() = p.y(); } void wander( const overmap & ); void inc_interest( int inc ) { diff --git a/src/monster.cpp b/src/monster.cpp index 5cb16b4b2b711..44a731defb067 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -2261,7 +2261,8 @@ void monster::die( Creature *nkiller ) const tripoint abssub = ms_to_sm_copy( here.getabs( pos() ) ); // Do it for overmap above/below too for( const tripoint &p : points_in_radius( abssub, HALF_MAPSIZE, 1 ) ) { - for( auto &mgp : overmap_buffer.groups_at( p ) ) { + // TODO: fix point types + for( auto &mgp : overmap_buffer.groups_at( tripoint_abs_sm( p ) ) ) { if( MonsterGroupManager::IsMonsterInGroup( mgp->type, type->id ) ) { mgp->dying = true; } diff --git a/src/npc.cpp b/src/npc.cpp index c3c628eeb759f..45476428cc369 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -144,9 +144,9 @@ npc::npc() position.z = 500; last_player_seen_pos = cata::nullopt; last_seen_player_turn = 999; - wanted_item_pos = no_goal_point; - guard_pos = no_goal_point; - goal = no_goal_point; + wanted_item_pos = tripoint_min; + guard_pos = tripoint_min; + goal = tripoint_abs_omt( tripoint_min ); fetching_item = false; has_new_items = true; worst_item_value = 0; @@ -682,10 +682,11 @@ void npc::set_known_to_u( bool known ) void npc::setpos( const tripoint &pos ) { position = pos; - const point pos_om_old = sm_to_om_copy( submap_coords ); + const point_abs_om pos_om_old( sm_to_om_copy( submap_coords ) ); submap_coords.x = g->get_levx() + pos.x / SEEX; submap_coords.y = g->get_levy() + pos.y / SEEY; - const point pos_om_new = sm_to_om_copy( submap_coords ); + // TODO: fix point types + const point_abs_om pos_om_new( sm_to_om_copy( submap_coords ) ); if( !is_fake() && pos_om_old != pos_om_new ) { overmap &om_old = overmap_buffer.get( pos_om_old ); overmap &om_new = overmap_buffer.get( pos_om_new ); @@ -701,9 +702,10 @@ void npc::setpos( const tripoint &pos ) void npc::travel_overmap( const tripoint &pos ) { - const point pos_om_old = sm_to_om_copy( submap_coords ); + // TODO: fix point types + const point_abs_om pos_om_old( sm_to_om_copy( submap_coords ) ); spawn_at_sm( pos ); - const point pos_om_new = sm_to_om_copy( submap_coords ); + const point_abs_om pos_om_new( sm_to_om_copy( submap_coords ) ); if( global_omt_location() == goal ) { reach_omt_destination(); } @@ -2044,10 +2046,11 @@ bool npc::is_leader() const bool npc::within_boundaries_of_camp() const { - const point p( global_omt_location().xy() ); - for( int x2 = p.x - 3; x2 < p.x + 3; x2++ ) { - for( int y2 = p.y - 3; y2 < p.y + 3; y2++ ) { - cata::optional bcp = overmap_buffer.find_camp( point( x2, y2 ) ); + const point_abs_omt p( global_omt_location().xy() ); + for( int x2 = -3; x2 < 3; x2++ ) { + for( int y2 = -3; y2 < 3; y2++ ) { + const point_abs_omt nearby = p + point( x2, y2 ); + cata::optional bcp = overmap_buffer.find_camp( nearby ); if( bcp ) { return true; } @@ -2448,8 +2451,8 @@ void npc::reboot() path.clear(); last_player_seen_pos = cata::nullopt; last_seen_player_turn = 999; - wanted_item_pos = no_goal_point; - guard_pos = no_goal_point; + wanted_item_pos = tripoint_min; + guard_pos = tripoint_min; goal = no_goal_point; fetching_item = false; has_new_items = true; @@ -2765,7 +2768,7 @@ void npc::on_load() } } -constexpr tripoint npc::no_goal_point; +constexpr tripoint_abs_omt npc::no_goal_point; bool npc::query_yn( const std::string &/*msg*/ ) const { @@ -3047,7 +3050,7 @@ std::string npc::get_epilogue() const void npc::set_companion_mission( npc &p, const std::string &mission_id ) { - const tripoint omt_pos = p.global_omt_location(); + const tripoint_abs_omt omt_pos = p.global_omt_location(); set_companion_mission( omt_pos, p.companion_mission_role_id, mission_id ); } @@ -3083,7 +3086,7 @@ std::pair npc::hp_description() const } return std::make_pair( damage_info, col ); } -void npc::set_companion_mission( const tripoint &omt_pos, const std::string &role_id, +void npc::set_companion_mission( const tripoint_abs_omt &omt_pos, const std::string &role_id, const std::string &mission_id ) { comp_mission.position = omt_pos; @@ -3091,8 +3094,8 @@ void npc::set_companion_mission( const tripoint &omt_pos, const std::string &rol comp_mission.role_id = role_id; } -void npc::set_companion_mission( const tripoint &omt_pos, const std::string &role_id, - const std::string &mission_id, const tripoint &destination ) +void npc::set_companion_mission( const tripoint_abs_omt &omt_pos, const std::string &role_id, + const std::string &mission_id, const tripoint_abs_omt &destination ) { comp_mission.position = omt_pos; comp_mission.mission_id = mission_id; @@ -3102,7 +3105,7 @@ void npc::set_companion_mission( const tripoint &omt_pos, const std::string &rol void npc::reset_companion_mission() { - comp_mission.position = tripoint( -999, -999, -999 ); + comp_mission.position = tripoint_abs_omt( -999, -999, -999 ); comp_mission.mission_id.clear(); comp_mission.role_id.clear(); if( comp_mission.destination ) { @@ -3110,7 +3113,7 @@ void npc::reset_companion_mission() } } -cata::optional npc::get_mission_destination() const +cata::optional npc::get_mission_destination() const { if( comp_mission.destination ) { return comp_mission.destination; diff --git a/src/npc.h b/src/npc.h index d7ba3928f2aa7..919d3d1b0ff70 100644 --- a/src/npc.h +++ b/src/npc.h @@ -197,9 +197,9 @@ enum npc_mission : int { struct npc_companion_mission { std::string mission_id; - tripoint position; + tripoint_abs_omt position; std::string role_id; - cata::optional destination; + cata::optional destination; }; std::string npc_class_name( const npc_class_id & ); @@ -1222,7 +1222,7 @@ class npc : public player std::string idz; // A temp variable used to link to the correct mission std::vector miss_ids; - cata::optional assigned_camp = cata::nullopt; + cata::optional assigned_camp = cata::nullopt; private: npc_attitude attitude; // What we want to do to the player @@ -1264,14 +1264,14 @@ class npc : public player int last_seen_player_turn = 0; // Timeout to forgetting tripoint wanted_item_pos; // The square containing an item we want tripoint guard_pos; // These are the local coordinates that a guard will return to inside of their goal tripoint - tripoint chair_pos = no_goal_point; // This is the spot the NPC wants to move to to sit and relax. - cata::optional base_location; // our faction base location in OMT coords. + tripoint chair_pos = tripoint_min; // This is the spot the NPC wants to move to to sit and relax. + cata::optional base_location; // our faction base location in OMT coords. /** * Global overmap terrain coordinate, where we want to get to * if no goal exist, this is no_goal_point. */ - tripoint goal; - tripoint wander_pos = no_goal_point; + tripoint_abs_omt goal; + tripoint wander_pos = tripoint_min; int wander_time = 0; item *known_stolen_item = nullptr; // the item that the NPC wants the player to drop or barter for. /** @@ -1287,8 +1287,8 @@ class npc : public player // Personality & other defining characteristics std::string companion_mission_role_id; //Set mission source or squad leader for a patrol - std::vector - companion_mission_points; //Mission leader use to determine item sorting, patrols use for points + //Mission leader use to determine item sorting, patrols use for points + std::vector companion_mission_points; time_point companion_mission_time; //When you left for ongoing/repeating missions time_point companion_mission_time_ret; //When you are expected to return for calculated/variable mission returns @@ -1306,7 +1306,7 @@ class npc : public player std::vector needs; cata::optional confident_range_cache; // Dummy point that indicates that the goal is invalid. - static constexpr tripoint no_goal_point = tripoint_min; + static constexpr tripoint_abs_omt no_goal_point{ tripoint_min }; job_data job; time_point last_updated; /** @@ -1328,13 +1328,14 @@ class npc : public player /// Set up (start) a companion mission. void set_companion_mission( npc &p, const std::string &mission_id ); - void set_companion_mission( const tripoint &omt_pos, const std::string &role_id, + void set_companion_mission( const tripoint_abs_omt &omt_pos, const std::string &role_id, const std::string &mission_id ); - void set_companion_mission( const tripoint &omt_pos, const std::string &role_id, - const std::string &mission_id, const tripoint &destination ); + void set_companion_mission( + const tripoint_abs_omt &omt_pos, const std::string &role_id, + const std::string &mission_id, const tripoint_abs_omt &destination ); /// Unset a companion mission. Precondition: `!has_companion_mission()` void reset_companion_mission(); - cata::optional get_mission_destination() const; + cata::optional get_mission_destination() const; bool has_companion_mission() const; npc_companion_mission get_companion_mission() const; attitude_group get_attitude_group( npc_attitude att ) const; diff --git a/src/npcmove.cpp b/src/npcmove.cpp index 16e9e4463579c..b8e7de35fc344 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -2575,7 +2575,7 @@ void npc::worker_downtime() return; } // already know of a chair, go there - if( chair_pos != no_goal_point ) { + if( chair_pos != tripoint_min ) { if( here.has_flag_furn( "CAN_SIT", here.getlocal( chair_pos ) ) ) { update_path( here.getlocal( chair_pos ) ); if( pos() == here.getlocal( chair_pos ) || path.empty() ) { @@ -2584,10 +2584,10 @@ void npc::worker_downtime() } else { move_to_next(); } - wander_pos = no_goal_point; + wander_pos = tripoint_min; return; } else { - chair_pos = no_goal_point; + chair_pos = tripoint_min; } } else { // find a chair @@ -2604,13 +2604,13 @@ void npc::worker_downtime() } // we got here if there are no chairs available. // wander back to near the bulletin board of the camp. - if( wander_pos != no_goal_point ) { + if( wander_pos != tripoint_min ) { update_path( here.getlocal( wander_pos ) ); if( pos() == here.getlocal( wander_pos ) || path.empty() ) { move_pause(); path.clear(); if( one_in( 30 ) ) { - wander_pos = no_goal_point; + wander_pos = tripoint_min; } } else { move_to_next(); @@ -3831,7 +3831,7 @@ bool npc::consume_food_from_camp() } Character &player_character = get_player_character(); cata::optional potential_bc; - for( const tripoint &camp_pos : player_character.camps ) { + for( const tripoint_abs_omt &camp_pos : player_character.camps ) { if( rl_dist( camp_pos, global_omt_location() ) < 3 ) { potential_bc = overmap_buffer.find_camp( camp_pos.xy() ); if( potential_bc ) { @@ -4088,7 +4088,7 @@ void npc::reach_omt_destination() if( path.size() > 1 ) { // No point recalculating the path to get home move_to_next(); - } else if( guard_pos != no_goal_point ) { + } else if( guard_pos != tripoint_min ) { update_path( here.getlocal( guard_pos ) ); move_to_next(); } else { @@ -4121,9 +4121,9 @@ void npc::set_omt_destination() return; } - tripoint surface_omt_loc = global_omt_location(); + tripoint_abs_omt surface_omt_loc = global_omt_location(); // We need that, otherwise find_closest won't work properly - surface_omt_loc.z = 0; + surface_omt_loc.z() = 0; // also, don't bother looking if the CITY_SIZE is 0, just go somewhere at random const int city_size = get_option( "CITY_SIZE" ); @@ -4181,7 +4181,7 @@ void npc::set_omt_destination() DebugLog( D_INFO, DC_ALL ) << "npc::set_omt_destination - new goal for NPC [" << get_name() << "] with [" << get_need_str_id( needs.front() ) << "] is [" << dest_type << - "] in [" << goal.x << "," << goal.y << "," << goal.z << "]."; + "] in " << goal.to_string() << "."; } void npc::go_to_omt_destination() @@ -4201,7 +4201,7 @@ void npc::go_to_omt_destination() reach_omt_destination(); return; } - const tripoint omt_pos = global_omt_location(); + const tripoint_abs_omt omt_pos = global_omt_location(); if( goal == omt_pos ) { // We're at our desired map square! Pause to keep the NPC infinite loop counter happy move_pause(); @@ -4219,8 +4219,8 @@ void npc::go_to_omt_destination() omt_path.pop_back(); } if( !omt_path.empty() ) { - point omt_diff = omt_path.back().xy() - omt_pos.xy(); - if( omt_diff.x > 3 || omt_diff.x < -3 || omt_diff.y > 3 || omt_diff.y < -3 ) { + point_rel_omt omt_diff = omt_path.back().xy() - omt_pos.xy(); + if( omt_diff.x() > 3 || omt_diff.x() < -3 || omt_diff.y() > 3 || omt_diff.y() < -3 ) { // we've gone wandering somehow, reset destination. if( !is_player_ally() ) { set_omt_destination(); @@ -4230,7 +4230,9 @@ void npc::go_to_omt_destination() return; } } - tripoint sm_tri = here.getlocal( sm_to_ms_copy( omt_to_sm_copy( omt_path.back() ) ) ); + // TODO: fix point types + tripoint sm_tri = + here.getlocal( project_to( omt_path.back() ).raw() ); tripoint centre_sub = sm_tri + point( SEEX, SEEY ); if( !here.passable( centre_sub ) ) { auto candidates = here.points_in_radius( centre_sub, 2 ); @@ -4242,8 +4244,7 @@ void npc::go_to_omt_destination() } } path = here.route( pos(), centre_sub, get_pathfinding_settings(), get_path_avoid() ); - add_msg( m_debug, "%s going (%d,%d,%d)->(%d,%d,%d)", name, - omt_pos.x, omt_pos.y, omt_pos.z, goal.x, goal.y, goal.z ); + add_msg( m_debug, "%s going %s->%s", name, omt_pos.to_string(), goal.to_string() ); if( !path.empty() ) { move_to_next(); diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 872d8eae32412..9b77a6c1d29ad 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -1886,7 +1886,7 @@ void talk_effect_fun_t::set_mapgen_update( const JsonObject &jo, const std::stri function = [target_params, update_ids]( const dialogue & d ) { mission_target_params update_params = target_params; update_params.guy = d.beta->get_npc(); - const tripoint omt_pos = mission_util::get_om_terrain_pos( update_params ); + const tripoint_abs_omt omt_pos = mission_util::get_om_terrain_pos( update_params ); for( const std::string &mapgen_update_id : update_ids ) { run_mapgen_update_func( mapgen_update_id, omt_pos, d.beta->selected_mission() ); } diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index 218c627dcb265..c16cad61f5045 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -302,7 +302,7 @@ void talk_function::goto_location( npc &p ) uilist selection_menu; selection_menu.text = _( "Select a destination" ); std::vector camps; - tripoint destination; + tripoint_abs_omt destination; Character &player_character = get_player_character(); for( auto elem : player_character.camps ) { if( elem == p.global_omt_location() ) { @@ -317,8 +317,8 @@ void talk_function::goto_location( npc &p ) } for( auto iter : camps ) { //~ %1$s: camp name, %2$d and %3$d: coordinates - selection_menu.addentry( i++, true, MENU_AUTOASSIGN, pgettext( "camp", "%1$s at (%2$d, %3$d)" ), - iter->camp_name(), iter->camp_omt_pos().x, iter->camp_omt_pos().y ); + selection_menu.addentry( i++, true, MENU_AUTOASSIGN, pgettext( "camp", "%1$s at %2$s" ), + iter->camp_name(), iter->camp_omt_pos().to_string() ); } selection_menu.addentry( i++, true, MENU_AUTOASSIGN, _( "My current location" ) ); selection_menu.addentry( i, true, MENU_AUTOASSIGN, _( "Cancel" ) ); @@ -337,7 +337,7 @@ void talk_function::goto_location( npc &p ) } p.goal = destination; p.omt_path = overmap_buffer.get_npc_path( p.global_omt_location(), p.goal ); - if( destination == tripoint_zero || destination == overmap::invalid_tripoint || + if( destination == tripoint_abs_omt() || destination == overmap::invalid_tripoint || p.omt_path.empty() ) { p.goal = npc::no_goal_point; p.omt_path.clear(); @@ -346,7 +346,7 @@ void talk_function::goto_location( npc &p ) } p.set_mission( NPC_MISSION_TRAVELLING ); p.chatbin.first_topic = "TALK_FRIEND_GUARD"; - p.guard_pos = npc::no_goal_point; + p.guard_pos = tripoint_min; p.set_attitude( NPCATT_NULL ); } @@ -410,7 +410,7 @@ void talk_function::stop_guard( npc &p ) } p.chatbin.first_topic = "TALK_FRIEND"; p.goal = npc::no_goal_point; - p.guard_pos = npc::no_goal_point; + p.guard_pos = tripoint_min; if( p.assigned_camp ) { if( cata::optional bcp = overmap_buffer.find_camp( ( *p.assigned_camp ).xy() ) ) { ( *bcp )->remove_assignee( p.getID() ); @@ -682,23 +682,24 @@ void talk_function::morale_chat_activity( npc &p ) void talk_function::buy_10_logs( npc &p ) { - std::vector places = overmap_buffer.find_all( - get_player_character().global_omt_location(), "ranch_camp_67", 1, false ); + std::vector places = + overmap_buffer.find_all( get_player_character().global_omt_location(), "ranch_camp_67", 1, + false ); if( places.empty() ) { debugmsg( "Couldn't find %s", "ranch_camp_67" ); return; } const auto &cur_om = g->get_cur_om(); - std::vector places_om; - for( auto &i : places ) { + std::vector places_om; + for( const tripoint_abs_omt &i : places ) { if( &cur_om == overmap_buffer.get_existing_om_global( i ).om ) { places_om.push_back( i ); } } - const tripoint site = random_entry( places_om ); + const tripoint_abs_omt site = random_entry( places_om ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.spawn_item( point( 7, 15 ), "log", 10 ); bay.save(); @@ -708,23 +709,24 @@ void talk_function::buy_10_logs( npc &p ) void talk_function::buy_100_logs( npc &p ) { - std::vector places = overmap_buffer.find_all( - get_player_character().global_omt_location(), "ranch_camp_67", 1, false ); + std::vector places = + overmap_buffer.find_all( get_player_character().global_omt_location(), "ranch_camp_67", 1, + false ); if( places.empty() ) { debugmsg( "Couldn't find %s", "ranch_camp_67" ); return; } const auto &cur_om = g->get_cur_om(); - std::vector places_om; + std::vector places_om; for( auto &i : places ) { if( &cur_om == overmap_buffer.get_existing_om_global( i ).om ) { places_om.push_back( i ); } } - const tripoint site = random_entry( places_om ); + const tripoint_abs_omt site = random_entry( places_om ); tinymap bay; - bay.load( tripoint( site.x * 2, site.y * 2, site.z ), false ); + bay.load( project_to( site ), false ); bay.spawn_item( point( 7, 15 ), "log", 100 ); bay.save(); diff --git a/src/omdata.h b/src/omdata.h index b30b590582b6a..14ff264da02c8 100644 --- a/src/omdata.h +++ b/src/omdata.h @@ -14,6 +14,7 @@ #include "catacharset.h" #include "color.h" #include "common_types.h" +#include "coordinates.h" #include "enum_bitset.h" #include "int_id.h" #include "point.h" @@ -439,7 +440,7 @@ class overmap_special /** @returns true if this special requires a city */ bool requires_city() const; /** @returns whether the special at specified tripoint can belong to the specified city. */ - bool can_belong_to_city( const tripoint &p, const city &cit ) const; + bool can_belong_to_city( const tripoint_om_omt &p, const city &cit ) const; overmap_special_id id; std::list terrains; @@ -499,7 +500,7 @@ void reset(); const std::vector &get_all(); -overmap_special_batch get_default_batch( const point &origin ); +overmap_special_batch get_default_batch( const point_abs_om &origin ); /** * Generates a simple special from a building id. */ diff --git a/src/overmap.cpp b/src/overmap.cpp index 02f7bc2afa154..b76b84f3fab17 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -1,3 +1,4 @@ +#include "coordinates.h" #include "omdata.h" // IWYU pragma: associated #include "overmap.h" // IWYU pragma: associated @@ -212,16 +213,16 @@ bool overmap_special_id::is_valid() const return specials.is_valid( *this ); } -city::city( const point &P, int const S ) +city::city( const point_om_omt &P, int const S ) : pos( P ) , size( S ) , name( Name::get( nameFlags::IsTownName ) ) { } -int city::get_distance_from( const tripoint &p ) const +int city::get_distance_from( const tripoint_om_omt &p ) const { - return std::max( static_cast( trig_dist( p, { pos, 0 } ) ) - size, 0 ); + return std::max( static_cast( trig_dist( p, tripoint_om_omt{ pos, 0 } ) ) - size, 0 ); } std::map radio_type_names = @@ -440,7 +441,7 @@ const std::vector &overmap_specials::get_all() return specials.get_all(); } -overmap_special_batch overmap_specials::get_default_batch( const point &origin ) +overmap_special_batch overmap_specials::get_default_batch( const point_abs_om &origin ) { const int city_size = get_option( "CITY_SIZE" ); std::vector res; @@ -855,7 +856,7 @@ bool overmap_special::requires_city() const return city_size.min > 0 || city_distance.max < std::max( OMAPX, OMAPY ); } -bool overmap_special::can_belong_to_city( const tripoint &p, const city &cit ) const +bool overmap_special::can_belong_to_city( const tripoint_om_omt &p, const city &cit ) const { if( !requires_city() ) { return true; @@ -1035,13 +1036,13 @@ void overmap_special::check() const } // *** BEGIN overmap FUNCTIONS *** -overmap::overmap( const point &p ) : loc( p ) +overmap::overmap( const point_abs_om &p ) : loc( p ) { const std::string rsettings_id = get_option( "DEFAULT_REGION" ); t_regional_settings_map_citr rsit = region_settings_map.find( rsettings_id ); if( rsit == region_settings_map.end() ) { - debugmsg( "overmap(%d,%d): can't find region '%s'", p.x, p.y, + debugmsg( "overmap%s: can't find region '%s'", p.to_string(), rsettings_id.c_str() ); // gonna die now =[ } settings = rsit->second; @@ -1056,7 +1057,7 @@ void overmap::populate( overmap_special_batch &enabled_specials ) try { open( enabled_specials ); } catch( const std::exception &err ) { - debugmsg( "overmap (%d,%d) failed to load: %s", loc.x, loc.y, err.what() ); + debugmsg( "overmap (%d,%d) failed to load: %s", loc.x(), loc.y(), err.what() ); } } @@ -1135,65 +1136,65 @@ void overmap::init_layers() } } -void overmap::ter_set( const tripoint &p, const oter_id &id ) +void overmap::ter_set( const tripoint_om_omt &p, const oter_id &id ) { if( !inbounds( p ) ) { /// TODO: Add a debug message reporting this, but currently there are way too many place that would trigger it. return; } - layer[p.z + OVERMAP_DEPTH].terrain[p.x][p.y] = id; + layer[p.z() + OVERMAP_DEPTH].terrain[p.x()][p.y()] = id; } -const oter_id &overmap::ter( const tripoint &p ) const +const oter_id &overmap::ter( const tripoint_om_omt &p ) const { if( !inbounds( p ) ) { /// TODO: Add a debug message reporting this, but currently there are way too many place that would trigger it. return ot_null; } - return layer[p.z + OVERMAP_DEPTH].terrain[p.x][p.y]; + return layer[p.z() + OVERMAP_DEPTH].terrain[p.x()][p.y()]; } -bool &overmap::seen( const tripoint &p ) +bool &overmap::seen( const tripoint_om_omt &p ) { if( !inbounds( p ) ) { nullbool = false; return nullbool; } - return layer[p.z + OVERMAP_DEPTH].visible[p.x][p.y]; + return layer[p.z() + OVERMAP_DEPTH].visible[p.x()][p.y()]; } -bool overmap::seen( const tripoint &p ) const +bool overmap::seen( const tripoint_om_omt &p ) const { if( !inbounds( p ) ) { return false; } - return layer[p.z + OVERMAP_DEPTH].visible[p.x][p.y]; + return layer[p.z() + OVERMAP_DEPTH].visible[p.x()][p.y()]; } -bool &overmap::explored( const tripoint &p ) +bool &overmap::explored( const tripoint_om_omt &p ) { if( !inbounds( p ) ) { nullbool = false; return nullbool; } - return layer[p.z + OVERMAP_DEPTH].explored[p.x][p.y]; + return layer[p.z() + OVERMAP_DEPTH].explored[p.x()][p.y()]; } -bool overmap::is_explored( const tripoint &p ) const +bool overmap::is_explored( const tripoint_om_omt &p ) const { if( !inbounds( p ) ) { return false; } - return layer[p.z + OVERMAP_DEPTH].explored[p.x][p.y]; + return layer[p.z() + OVERMAP_DEPTH].explored[p.x()][p.y()]; } bool overmap::mongroup_check( const mongroup &candidate ) const { const auto matching_range = zg.equal_range( candidate.pos ); return std::find_if( matching_range.first, matching_range.second, - [candidate]( const std::pair &match ) { + [candidate]( const std::pair &match ) { // This is extra strict since we're using it to test serialization. return candidate.type == match.second.type && candidate.pos == match.second.pos && candidate.radius == match.second.radius && @@ -1206,11 +1207,11 @@ bool overmap::mongroup_check( const mongroup &candidate ) const } ) != matching_range.second; } -bool overmap::monster_check( const std::pair &candidate ) const +bool overmap::monster_check( const std::pair &candidate ) const { const auto matching_range = monster_map.equal_range( candidate.first ); return std::find_if( matching_range.first, matching_range.second, - [candidate]( const std::pair &match ) { + [candidate]( const std::pair &match ) { return candidate.second.pos() == match.second.pos() && candidate.second.type == match.second.type; } ) != matching_range.second; @@ -1250,13 +1251,13 @@ std::vector> overmap::get_npcs( const return result; } -bool overmap::has_note( const tripoint &p ) const +bool overmap::has_note( const tripoint_om_omt &p ) const { - if( p.z < -OVERMAP_DEPTH || p.z > OVERMAP_HEIGHT ) { + if( p.z() < -OVERMAP_DEPTH || p.z() > OVERMAP_HEIGHT ) { return false; } - for( auto &i : layer[p.z + OVERMAP_DEPTH].notes ) { + for( auto &i : layer[p.z() + OVERMAP_DEPTH].notes ) { if( i.p == p.xy() ) { return true; } @@ -1264,9 +1265,9 @@ bool overmap::has_note( const tripoint &p ) const return false; } -bool overmap::is_marked_dangerous( const tripoint &p ) const +bool overmap::is_marked_dangerous( const tripoint_om_omt &p ) const { - for( auto &i : layer[p.z + OVERMAP_DEPTH].notes ) { + for( auto &i : layer[p.z() + OVERMAP_DEPTH].notes ) { if( !i.dangerous ) { continue; } else if( p.xy() == i.p ) { @@ -1278,7 +1279,7 @@ bool overmap::is_marked_dangerous( const tripoint &p ) const } for( int x = -radius; x <= radius; x++ ) { for( int y = -radius; y <= radius; y++ ) { - const tripoint rad_point = tripoint( i.p, p.z ) + point( x, y ); + const tripoint_om_omt rad_point = tripoint_om_omt( i.p, p.z() ) + point( x, y ); if( p.xy() == rad_point.xy() ) { return true; } @@ -1288,15 +1289,15 @@ bool overmap::is_marked_dangerous( const tripoint &p ) const return false; } -const std::string &overmap::note( const tripoint &p ) const +const std::string &overmap::note( const tripoint_om_omt &p ) const { static const std::string fallback {}; - if( p.z < -OVERMAP_DEPTH || p.z > OVERMAP_HEIGHT ) { + if( p.z() < -OVERMAP_DEPTH || p.z() > OVERMAP_HEIGHT ) { return fallback; } - const auto ¬es = layer[p.z + OVERMAP_DEPTH].notes; + const auto ¬es = layer[p.z() + OVERMAP_DEPTH].notes; const auto it = std::find_if( begin( notes ), end( notes ), [&]( const om_note & n ) { return n.p == p.xy(); } ); @@ -1304,14 +1305,14 @@ const std::string &overmap::note( const tripoint &p ) const return ( it != std::end( notes ) ) ? it->text : fallback; } -void overmap::add_note( const tripoint &p, std::string message ) +void overmap::add_note( const tripoint_om_omt &p, std::string message ) { - if( p.z < -OVERMAP_DEPTH || p.z > OVERMAP_HEIGHT ) { - debugmsg( "Attempting to add not to overmap for blank layer %d", p.z ); + if( p.z() < -OVERMAP_DEPTH || p.z() > OVERMAP_HEIGHT ) { + debugmsg( "Attempting to add not to overmap for blank layer %d", p.z() ); return; } - auto ¬es = layer[p.z + OVERMAP_DEPTH].notes; + auto ¬es = layer[p.z() + OVERMAP_DEPTH].notes; const auto it = std::find_if( begin( notes ), end( notes ), [&]( const om_note & n ) { return n.p == p.xy(); } ); @@ -1325,9 +1326,9 @@ void overmap::add_note( const tripoint &p, std::string message ) } } -void overmap::mark_note_dangerous( const tripoint &p, int radius, bool is_dangerous ) +void overmap::mark_note_dangerous( const tripoint_om_omt &p, int radius, bool is_dangerous ) { - for( auto &i : layer[p.z + OVERMAP_DEPTH].notes ) { + for( auto &i : layer[p.z() + OVERMAP_DEPTH].notes ) { if( p.xy() == i.p ) { i.dangerous = is_dangerous; i.danger_radius = radius; @@ -1336,30 +1337,30 @@ void overmap::mark_note_dangerous( const tripoint &p, int radius, bool is_danger } } -void overmap::delete_note( const tripoint &p ) +void overmap::delete_note( const tripoint_om_omt &p ) { add_note( p, std::string{} ); } -std::vector overmap::find_notes( const int z, const std::string &text ) +std::vector overmap::find_notes( const int z, const std::string &text ) { - std::vector note_locations; + std::vector note_locations; map_layer &this_layer = layer[z + OVERMAP_DEPTH]; for( const auto ¬e : this_layer.notes ) { if( match_include_exclude( note.text, text ) ) { - note_locations.push_back( global_base_point() + note.p ); + note_locations.push_back( project_combine( pos(), note.p ) ); } } return note_locations; } -bool overmap::has_extra( const tripoint &p ) const +bool overmap::has_extra( const tripoint_om_omt &p ) const { - if( p.z < -OVERMAP_DEPTH || p.z > OVERMAP_HEIGHT ) { + if( p.z() < -OVERMAP_DEPTH || p.z() > OVERMAP_HEIGHT ) { return false; } - for( auto &i : layer[p.z + OVERMAP_DEPTH].extras ) { + for( auto &i : layer[p.z() + OVERMAP_DEPTH].extras ) { if( i.p == p.xy() ) { return true; } @@ -1367,15 +1368,15 @@ bool overmap::has_extra( const tripoint &p ) const return false; } -const string_id &overmap::extra( const tripoint &p ) const +const string_id &overmap::extra( const tripoint_om_omt &p ) const { static const string_id fallback{}; - if( p.z < -OVERMAP_DEPTH || p.z > OVERMAP_HEIGHT ) { + if( p.z() < -OVERMAP_DEPTH || p.z() > OVERMAP_HEIGHT ) { return fallback; } - const auto &extras = layer[p.z + OVERMAP_DEPTH].extras; + const auto &extras = layer[p.z() + OVERMAP_DEPTH].extras; const auto it = std::find_if( begin( extras ), end( extras ), [&]( const om_map_extra & n ) { return n.p == p.xy(); @@ -1384,14 +1385,14 @@ const string_id &overmap::extra( const tripoint &p ) const return ( it != std::end( extras ) ) ? it->id : fallback; } -void overmap::add_extra( const tripoint &p, const string_id &id ) +void overmap::add_extra( const tripoint_om_omt &p, const string_id &id ) { - if( p.z < -OVERMAP_DEPTH || p.z > OVERMAP_HEIGHT ) { - debugmsg( "Attempting to add not to overmap for blank layer %d", p.z ); + if( p.z() < -OVERMAP_DEPTH || p.z() > OVERMAP_HEIGHT ) { + debugmsg( "Attempting to add not to overmap for blank layer %d", p.z() ); return; } - auto &extras = layer[p.z + OVERMAP_DEPTH].extras; + auto &extras = layer[p.z() + OVERMAP_DEPTH].extras; const auto it = std::find_if( begin( extras ), end( extras ), [&]( const om_map_extra & n ) { return n.p == p.xy(); @@ -1406,25 +1407,25 @@ void overmap::add_extra( const tripoint &p, const string_id &id ) } } -void overmap::delete_extra( const tripoint &p ) +void overmap::delete_extra( const tripoint_om_omt &p ) { add_extra( p, string_id::NULL_ID() ); } -std::vector overmap::find_extras( const int z, const std::string &text ) +std::vector overmap::find_extras( const int z, const std::string &text ) { - std::vector extra_locations; + std::vector extra_locations; map_layer &this_layer = layer[z + OVERMAP_DEPTH]; for( const auto &extra : this_layer.extras ) { const std::string extra_text = extra.id.c_str(); if( match_include_exclude( extra_text, text ) ) { - extra_locations.push_back( global_base_point() + extra.p ); + extra_locations.push_back( project_combine( pos(), extra.p ) ); } } return extra_locations; } -bool overmap::inbounds( const tripoint &p, int clearance ) +bool overmap::inbounds( const tripoint_om_omt &p, int clearance ) { static constexpr tripoint overmap_boundary_min( 0, 0, -OVERMAP_DEPTH ); static constexpr tripoint overmap_boundary_max( OMAPX, OMAPY, OVERMAP_HEIGHT + 1 ); @@ -1433,10 +1434,11 @@ bool overmap::inbounds( const tripoint &p, int clearance ) half_open_box stricter_boundaries = overmap_boundaries; stricter_boundaries.shrink( tripoint( clearance, clearance, 0 ) ); - return stricter_boundaries.contains( p ); + // TODO: fix point types + return stricter_boundaries.contains( p.raw() ); } -const scent_trace &overmap::scent_at( const tripoint &loc ) const +const scent_trace &overmap::scent_at( const tripoint_abs_omt &loc ) const { static const scent_trace null_scent; const auto &scent_found = scents.find( loc ); @@ -1446,7 +1448,7 @@ const scent_trace &overmap::scent_at( const tripoint &loc ) const return null_scent; } -void overmap::set_scent( const tripoint &loc, const scent_trace &new_scent ) +void overmap::set_scent( const tripoint_abs_omt &loc, const scent_trace &new_scent ) { // TODO: increase strength of scent trace when applied repeatedly in a short timespan. scents[loc] = new_scent; @@ -1504,17 +1506,17 @@ void overmap::generate( const overmap *north, const overmap *east, bool overmap::generate_sub( const int z ) { bool requires_sub = false; - std::vector subway_points; - std::vector sewer_points; + std::vector subway_points; + std::vector sewer_points; std::vector ant_points; std::vector goo_points; std::vector lab_points; std::vector ice_lab_points; std::vector central_lab_points; - std::vector lab_train_points; - std::vector central_lab_train_points; - std::vector shaft_points; + std::vector lab_train_points; + std::vector central_lab_train_points; + std::vector shaft_points; std::vector mine_points; // These are so common that it's worth checking first as int. const oter_id skip_above[5] = { @@ -1524,9 +1526,9 @@ bool overmap::generate_sub( const int z ) for( int i = 0; i < OMAPX; i++ ) { for( int j = 0; j < OMAPY; j++ ) { - tripoint p( i, j, z ); + tripoint_om_omt p( i, j, z ); const oter_id oter_above = ter( p + tripoint_above ); - const oter_id oter_ground = ter( tripoint( p.xy(), 0 ) ); + const oter_id oter_ground = ter( tripoint_om_omt( p.xy(), 0 ) ); if( is_ot_match( "microlab_sub_connector", ter( p ), ot_match_type::type ) ) { om_direction::type rotation = ter( p )->get_dir(); @@ -1594,8 +1596,7 @@ bool overmap::generate_sub( const int z ) // but at this point we don't know requires_sub = true; } else if( oter_above == "mine_finale" ) { - map &here = get_map(); - for( auto &q : here.points_in_radius( p, 1, 0 ) ) { + for( auto &q : points_in_radius( p, 1, 0 ) ) { ter_set( q, oter_id( "spiral" ) ); } ter_set( p, oter_id( "spiral_hub" ) ); @@ -1605,7 +1606,7 @@ bool overmap::generate_sub( const int z ) } for( auto &i : goo_points ) { - requires_sub |= build_slimepit( tripoint( i.pos, z ), i.size ); + requires_sub |= build_slimepit( tripoint_om_omt( i.pos, z ), i.size ); } const string_id sewer_tunnel( "sewer_tunnel" ); connect_closest_points( sewer_points, z, *sewer_tunnel ); @@ -1621,34 +1622,36 @@ bool overmap::generate_sub( const int z ) } for( auto &i : lab_points ) { - bool lab = build_lab( tripoint( i.pos, z ), i.size, &lab_train_points, "", lab_train_odds ); + bool lab = build_lab( tripoint_om_omt( i.pos, z ), i.size, &lab_train_points, "", lab_train_odds ); requires_sub |= lab; - if( !lab && ter( tripoint( i.pos, z ) ) == "lab_core" ) { - ter_set( tripoint( i.pos, z ), oter_id( "lab" ) ); + if( !lab && ter( tripoint_om_omt( i.pos, z ) ) == "lab_core" ) { + ter_set( tripoint_om_omt( i.pos, z ), oter_id( "lab" ) ); } } for( auto &i : ice_lab_points ) { - bool ice_lab = build_lab( tripoint( i.pos, z ), i.size, &lab_train_points, "ice_", lab_train_odds ); + bool ice_lab = build_lab( tripoint_om_omt( i.pos, z ), i.size, &lab_train_points, "ice_", + lab_train_odds ); requires_sub |= ice_lab; - if( !ice_lab && ter( tripoint( i.pos, z ) ) == "ice_lab_core" ) { - ter_set( tripoint( i.pos, z ), oter_id( "ice_lab" ) ); + if( !ice_lab && ter( tripoint_om_omt( i.pos, z ) ) == "ice_lab_core" ) { + ter_set( tripoint_om_omt( i.pos, z ), oter_id( "ice_lab" ) ); } } for( auto &i : central_lab_points ) { - bool central_lab = build_lab( tripoint( i.pos, z ), i.size, ¢ral_lab_train_points, + bool central_lab = build_lab( tripoint_om_omt( i.pos, z ), i.size, ¢ral_lab_train_points, "central_", lab_train_odds ); requires_sub |= central_lab; - if( !central_lab && ter( tripoint( i.pos, z ) ) == "central_lab_core" ) { - ter_set( tripoint( i.pos, z ), oter_id( "central_lab" ) ); + if( !central_lab && ter( tripoint_om_omt( i.pos, z ) ) == "central_lab_core" ) { + ter_set( tripoint_om_omt( i.pos, z ), oter_id( "central_lab" ) ); } } - const auto create_real_train_lab_points = [this, z]( const std::vector &train_points, - std::vector &real_train_points ) { + const auto create_real_train_lab_points = [this, z]( + const std::vector &train_points, + std::vector &real_train_points ) { bool is_first_in_pair = true; for( auto &p : train_points ) { - tripoint i( p, z ); - const std::vector nearby_locations { + tripoint_om_omt i( p, z ); + const std::vector nearby_locations { i + point_north, i + point_south, i + point_east, @@ -1672,7 +1675,8 @@ bool overmap::generate_sub( const int z ) is_first_in_pair = !is_first_in_pair; } }; - std::vector subway_lab_train_points; // real points for subway, excluding train depot points + std::vector + subway_lab_train_points; // real points for subway, excluding train depot points create_real_train_lab_points( lab_train_points, subway_lab_train_points ); create_real_train_lab_points( central_lab_train_points, subway_lab_train_points ); @@ -1683,26 +1687,26 @@ bool overmap::generate_sub( const int z ) connect_closest_points( subway_points, z, *subway_tunnel ); // If on z = 4 and central lab is present, be sure to connect normal labs and central labs (just in case). if( z == -4 && !central_lab_points.empty() ) { - std::vector extra_route; + std::vector extra_route; extra_route.push_back( subway_lab_train_points.back() ); connect_closest_points( extra_route, z, *subway_tunnel ); } for( auto &i : subway_points ) { - if( is_ot_match( "sub_station", ter( tripoint( i, z + 2 ) ), ot_match_type::type ) ) { - ter_set( tripoint( i, z ), oter_id( "underground_sub_station" ) ); + if( is_ot_match( "sub_station", ter( tripoint_om_omt( i, z + 2 ) ), ot_match_type::type ) ) { + ter_set( tripoint_om_omt( i, z ), oter_id( "underground_sub_station" ) ); } } // The first lab point is adjacent to a lab, set it a depot (as long as track was actually laid). const auto create_train_depots = [this, z, &subway_tunnel]( const oter_id & train_type, - const std::vector &train_points ) { + const std::vector &train_points ) { bool is_first_in_pair = true; - std::vector extra_route; + std::vector extra_route; for( auto &p : train_points ) { - tripoint i( p, z ); + tripoint_om_omt i( p, z ); if( is_first_in_pair ) { - const std::vector subway_possible_loc { + const std::vector subway_possible_loc { i + point_north, i + point_south, i + point_east, @@ -1733,8 +1737,8 @@ bool overmap::generate_sub( const int z ) create_train_depots( oter_id( "central_lab_train_depot" ), central_lab_train_points ); for( auto &i : cities ) { - tripoint omt_pos( i.pos, z ); - tripoint sm_pos = omt_to_sm_copy( omt_pos ); + tripoint_om_omt omt_pos( i.pos, z ); + tripoint_om_sm sm_pos = project_to( omt_pos ); // Sewers and city subways are present at z == -1 and z == -2. Don't spawn CHUD on other z-levels. if( ( z == -1 || z == -2 ) && one_in( 3 ) ) { add_mon_group( mongroup( GROUP_CHUD, @@ -1748,22 +1752,23 @@ bool overmap::generate_sub( const int z ) } for( auto &i : mine_points ) { - build_mine( tripoint( i.pos, z ), i.size ); + build_mine( tripoint_om_omt( i.pos, z ), i.size ); } for( auto &i : shaft_points ) { - ter_set( tripoint( i, z ), oter_id( "mine_shaft" ) ); + ter_set( tripoint_om_omt( i, z ), oter_id( "mine_shaft" ) ); requires_sub = true; } for( auto &i : ant_points ) { - const tripoint p_loc = tripoint( i.pos, z ); + const tripoint_om_omt p_loc( i.pos, z ); if( ter( p_loc ) != "empty_rock" ) { continue; } mongroup_id ant_group( ter( p_loc + tripoint_above ) == "anthill" ? "GROUP_ANT" : "GROUP_ANT_ACID" ); - add_mon_group( mongroup( ant_group, tripoint( i.pos.x * 2, i.pos.y * 2, z ), - ( i.size * 3 ) / 2, rng( 6000, 8000 ) ) ); + add_mon_group( + mongroup( ant_group, tripoint_om_sm( project_to( i.pos ), z ), + ( i.size * 3 ) / 2, rng( 6000, 8000 ) ) ); build_anthill( p_loc, i.size ); } @@ -1773,7 +1778,7 @@ bool overmap::generate_sub( const int z ) bool overmap::generate_over( const int z ) { bool requires_over = false; - std::vector bridge_points; + std::vector bridge_points; // These are so common that it's worth checking first as int. const std::set skip_below = { @@ -1784,9 +1789,9 @@ bool overmap::generate_over( const int z ) if( z == 1 ) { for( int i = 0; i < OMAPX; i++ ) { for( int j = 0; j < OMAPY; j++ ) { - tripoint p( i, j, z ); + tripoint_om_omt p( i, j, z ); const oter_id oter_below = ter( p + tripoint_below ); - const oter_id oter_ground = ter( tripoint( p.xy(), 0 ) ); + const oter_id oter_ground = ter( tripoint_om_omt( p.xy(), 0 ) ); // implicitly skip skip_below oter_ids if( skip_below.find( oter_below ) != skip_below.end() ) { @@ -1795,7 +1800,7 @@ bool overmap::generate_over( const int z ) if( is_ot_match( "bridge", oter_ground, ot_match_type::type ) ) { ter_set( p, oter_id( "bridge_road" + oter_get_rotation_string( oter_ground ) ) ); - bridge_points.emplace_back( i, j ); + bridge_points.push_back( p.xy() ); } } } @@ -1806,15 +1811,15 @@ bool overmap::generate_over( const int z ) return requires_over; } -void overmap::generate_bridgeheads( const std::vector &bridge_points ) +void overmap::generate_bridgeheads( const std::vector &bridge_points ) { - std::vector> bridgehead_points; - for( const point &bp : bridge_points ) { - //const oter_id oter_ground = ter( tripoint( bp, 0 ) ); - const oter_id oter_ground_north = ter( tripoint( bp, 0 ) + tripoint_north ); - const oter_id oter_ground_south = ter( tripoint( bp, 0 ) + tripoint_south ); - const oter_id oter_ground_east = ter( tripoint( bp, 0 ) + tripoint_east ); - const oter_id oter_ground_west = ter( tripoint( bp, 0 ) + tripoint_west ); + std::vector> bridgehead_points; + for( const point_om_omt &bp : bridge_points ) { + //const oter_id oter_ground = ter( tripoint_om_omt( bp, 0 ) ); + const oter_id oter_ground_north = ter( tripoint_om_omt( bp, 0 ) + tripoint_north ); + const oter_id oter_ground_south = ter( tripoint_om_omt( bp, 0 ) + tripoint_south ); + const oter_id oter_ground_east = ter( tripoint_om_omt( bp, 0 ) + tripoint_east ); + const oter_id oter_ground_west = ter( tripoint_om_omt( bp, 0 ) + tripoint_west ); const bool is_bridge_north = is_ot_match( "bridge", oter_ground_north, ot_match_type::type ); const bool is_bridge_south = is_ot_match( "bridge", oter_ground_south, ot_match_type::type ); const bool is_bridge_east = is_ot_match( "bridge", oter_ground_east, ot_match_type::type ); @@ -1834,29 +1839,29 @@ void overmap::generate_bridgeheads( const std::vector &bridge_points ) bridgehead_points.emplace_back( bp, ramp_facing ); } } - for( const std::pair &bhp : bridgehead_points ) { - tripoint p( bhp.first, 0 ); + for( const std::pair &bhp : bridgehead_points ) { + tripoint_om_omt p( bhp.first, 0 ); ter_set( p, oter_id( "bridgehead_ground" + bhp.second ) ); ter_set( p + tripoint_above, oter_id( "bridgehead_ramp" + bhp.second ) ); } } -std::vector overmap::find_terrain( const std::string &term, int zlevel ) +std::vector overmap::find_terrain( const std::string &term, int zlevel ) { - std::vector found; + std::vector found; for( int x = 0; x < OMAPX; x++ ) { for( int y = 0; y < OMAPY; y++ ) { - tripoint p( x, y, zlevel ); + tripoint_om_omt p( x, y, zlevel ); if( seen( p ) && lcmatch( ter( p )->get_name(), term ) ) { - found.push_back( global_base_point() + p.xy() ); + found.push_back( project_combine( pos(), p.xy() ) ); } } } return found; } -const city &overmap::get_nearest_city( const tripoint &p ) const +const city &overmap::get_nearest_city( const tripoint_om_omt &p ) const { int distance = 999; const city *res = nullptr; @@ -1874,20 +1879,21 @@ const city &overmap::get_nearest_city( const tripoint &p ) const return invalid_city; } -tripoint overmap::find_random_omt( const std::pair &target ) const +tripoint_om_omt overmap::find_random_omt( const std::pair &target ) +const { - std::vector valid; + std::vector valid; for( int i = 0; i < OMAPX; i++ ) { for( int j = 0; j < OMAPY; j++ ) { for( int k = -OVERMAP_DEPTH; k <= OVERMAP_HEIGHT; k++ ) { - tripoint p( i, j, k ); + tripoint_om_omt p( i, j, k ); if( is_ot_match( target.first, ter( p ), target.second ) ) { valid.push_back( p ); } } } } - return random_entry( valid, invalid_tripoint ); + return random_entry( valid, tripoint_om_omt( tripoint_min ) ); } void overmap::process_mongroups() @@ -1924,7 +1930,7 @@ void overmap::clear_connections_out() connections_out.clear(); } -void overmap::place_special_forced( const overmap_special_id &special_id, const tripoint &p, +void overmap::place_special_forced( const overmap_special_id &special_id, const tripoint_om_omt &p, om_direction::type dir ) { static city invalid_city; @@ -1940,7 +1946,8 @@ void mongroup::wander( const overmap &om ) // Find a nearby city to return to.. for( const city &check_city : om.cities ) { // Check if this is the nearest city so far. - int distance = rl_dist( point( check_city.pos.x * 2, check_city.pos.y * 2 ), pos.xy() ); + int distance = rl_dist( project_to( check_city.pos ), + pos.xy() ); if( !target_city || distance < target_distance ) { target_distance = distance; target_city = &check_city; @@ -1952,12 +1959,12 @@ void mongroup::wander( const overmap &om ) // TODO: somehow use the same algorithm that distributes zombie // density at world gen to spread the hordes over the actual // city, rather than the center city tile - target.x = target_city->pos.x * 2 + rng( -target_city->size * 2, target_city->size * 2 ); - target.y = target_city->pos.y * 2 + rng( -target_city->size * 2, target_city->size * 2 ); + target.x() = target_city->pos.x() * 2 + rng( -target_city->size * 2, target_city->size * 2 ); + target.y() = target_city->pos.y() * 2 + rng( -target_city->size * 2, target_city->size * 2 ); interest = 100; } else { - target.x = pos.x + rng( -10, 10 ); - target.y = pos.y + rng( -10, 10 ); + target.x() = pos.x() + rng( -10, 10 ); + target.y() = pos.y() + rng( -10, 10 ); interest = 30; } } @@ -1981,12 +1988,12 @@ void overmap::move_hordes() // Gradually decrease interest. mg.dec_interest( 1 ); - if( ( mg.pos.x == mg.target.x && mg.pos.y == mg.target.y ) || mg.interest <= 15 ) { + if( ( mg.pos.xy() == mg.target.xy() ) || mg.interest <= 15 ) { mg.wander( *this ); } // Decrease movement chance according to the terrain we're currently on. - const oter_id &walked_into = ter( mg.pos ); + const oter_id &walked_into = ter( project_to( mg.pos ) ); int movement_chance = 1; if( walked_into == ot_forest || walked_into == ot_forest_water ) { movement_chance = 3; @@ -2006,21 +2013,21 @@ void overmap::move_hordes() // or one space per 5 minutes. if( one_in( movement_chance ) && rng( 0, 100 ) < mg.interest && rng( 0, 200 ) < mg.avg_speed() ) { // TODO: Handle moving to adjacent overmaps. - if( mg.pos.x > mg.target.x ) { - mg.pos.x--; + if( mg.pos.x() > mg.target.x() ) { + mg.pos.x()--; } - if( mg.pos.x < mg.target.x ) { - mg.pos.x++; + if( mg.pos.x() < mg.target.x() ) { + mg.pos.x()++; } - if( mg.pos.y > mg.target.y ) { - mg.pos.y--; + if( mg.pos.y() > mg.target.y() ) { + mg.pos.y()--; } - if( mg.pos.y < mg.target.y ) { - mg.pos.y++; + if( mg.pos.y() < mg.target.y() ) { + mg.pos.y()++; } // Erase the group at it's old location, add the group with the new location - tmpzg.insert( std::pair( mg.pos, mg ) ); + tmpzg.insert( std::pair( mg.pos, mg ) ); zg.erase( it++ ); } else { ++it; @@ -2039,7 +2046,7 @@ void overmap::move_hordes() auto &this_monster = monster_map_it->second; // Only zombies on z-level 0 may join hordes. - if( p.z != 0 ) { + if( p.z() != 0 ) { monster_map_it++; continue; } @@ -2063,7 +2070,7 @@ void overmap::move_hordes() auto group_bucket = zg.equal_range( p ); std::vector::size_type add_to_horde_size = 0; std::for_each( group_bucket.first, group_bucket.second, - [&]( std::pair &horde_entry ) { + [&]( std::pair &horde_entry ) { mongroup &horde = horde_entry.second; // We only absorb zombies into GROUP_ZOMBIE hordes @@ -2099,11 +2106,12 @@ void overmap::move_hordes() } /** -* @param p location of signal +* @param p location of signal relative to this overmap origin * @param sig_power - power of signal or max distance for reaction of zombies */ -void overmap::signal_hordes( const tripoint &p, const int sig_power ) +void overmap::signal_hordes( const tripoint_rel_sm &p_rel, const int sig_power ) { + tripoint_om_sm p( p_rel.raw() ); for( auto &elem : zg ) { mongroup &mg = elem.second; if( !mg.horde ) { @@ -2125,7 +2133,7 @@ void overmap::signal_hordes( const tripoint &p, const int sig_power ) const int targ_dist = rl_dist( p, mg.target ); // TODO: Base this on targ_dist:dist ratio. if( targ_dist < 5 ) { // If signal source already pursued by horde - mg.set_target( point( ( mg.target.x + p.x ) / 2, ( mg.target.y + p.y ) / 2 ) ); + mg.set_target( midpoint( mg.target.xy(), p.xy() ) ); const int min_inc_inter = 3; // Min interest increase to already targeted source const int inc_roll = rng( min_inc_inter, calculated_inter ); mg.inc_interest( inc_roll ); @@ -2142,19 +2150,20 @@ void overmap::signal_hordes( const tripoint &p, const int sig_power ) void overmap::populate_connections_out_from_neighbors( const overmap *north, const overmap *east, const overmap *south, const overmap *west ) { - const auto populate_for_side = [&]( const overmap * adjacent, - const std::function &should_include, - const std::function &build_point ) { + const auto populate_for_side = + [&]( const overmap * adjacent, + const std::function &should_include, + const std::function &build_point ) { if( adjacent == nullptr ) { return; } - for( const std::pair, std::vector> &kv : + for( const std::pair, std::vector> &kv : adjacent->connections_out ) { - std::vector &out = connections_out[kv.first]; + std::vector &out = connections_out[kv.first]; const auto adjacent_out = adjacent->connections_out.find( kv.first ); if( adjacent_out != adjacent->connections_out.end() ) { - for( const tripoint &p : adjacent_out->second ) { + for( const tripoint_om_omt &p : adjacent_out->second ) { if( should_include( p ) ) { out.push_back( build_point( p ) ); } @@ -2163,44 +2172,44 @@ void overmap::populate_connections_out_from_neighbors( const overmap *north, con } }; - populate_for_side( north, []( const tripoint & p ) { - return p.y == OMAPY - 1; - }, []( const tripoint & p ) { - return tripoint( p.x, 0, p.z ); + populate_for_side( north, []( const tripoint_om_omt & p ) { + return p.y() == OMAPY - 1; + }, []( const tripoint_om_omt & p ) { + return tripoint_om_omt( p.x(), 0, p.z() ); } ); - populate_for_side( west, []( const tripoint & p ) { - return p.x == OMAPX - 1; - }, []( const tripoint & p ) { - return tripoint( 0, p.y, p.z ); + populate_for_side( west, []( const tripoint_om_omt & p ) { + return p.x() == OMAPX - 1; + }, []( const tripoint_om_omt & p ) { + return tripoint_om_omt( 0, p.y(), p.z() ); } ); - populate_for_side( south, []( const tripoint & p ) { - return p.y == 0; - }, []( const tripoint & p ) { - return tripoint( p.x, OMAPY - 1, p.z ); + populate_for_side( south, []( const tripoint_om_omt & p ) { + return p.y() == 0; + }, []( const tripoint_om_omt & p ) { + return tripoint_om_omt( p.x(), OMAPY - 1, p.z() ); } ); - populate_for_side( east, []( const tripoint & p ) { - return p.x == 0; - }, []( const tripoint & p ) { - return tripoint( OMAPX - 1, p.y, p.z ); + populate_for_side( east, []( const tripoint_om_omt & p ) { + return p.x() == 0; + }, []( const tripoint_om_omt & p ) { + return tripoint_om_omt( OMAPX - 1, p.y(), p.z() ); } ); } void overmap::place_forest_trails() { - std::unordered_set visited; + std::unordered_set visited; - const auto is_forest = [&]( const point & p ) { + const auto is_forest = [&]( const point_om_omt & p ) { if( !inbounds( p, 1 ) ) { return false; } - const auto current_terrain = ter( tripoint( p, 0 ) ); + const auto current_terrain = ter( tripoint_om_omt( p, 0 ) ); return current_terrain == "forest" || current_terrain == "forest_thick" || current_terrain == "forest_water"; }; for( int i = 0; i < OMAPX; i++ ) { for( int j = 0; j < OMAPY; j++ ) { - tripoint seed_point( i, j, 0 ); + tripoint_om_omt seed_point( i, j, 0 ); oter_id oter = ter( seed_point ); if( !is_ot_match( "forest", oter, ot_match_type::prefix ) ) { @@ -2214,7 +2223,7 @@ void overmap::place_forest_trails() } // Get the contiguous forest from this point. - std::vector forest_points = + std::vector forest_points = ff::point_flood_fill_4_connected( seed_point.xy(), visited, is_forest ); // If we don't have enough points to build a trail, move on. @@ -2231,37 +2240,38 @@ void overmap::place_forest_trails() // Get the north and south most points in the forest. auto north_south_most = std::minmax_element( forest_points.begin(), - forest_points.end(), []( const point & lhs, const point & rhs ) { - return lhs.y < rhs.y; + forest_points.end(), []( const point_om_omt & lhs, const point_om_omt & rhs ) { + return lhs.y() < rhs.y(); } ); // Get the west and east most points in the forest. auto west_east_most = std::minmax_element( forest_points.begin(), - forest_points.end(), []( const point & lhs, const point & rhs ) { - return lhs.x < rhs.x; + forest_points.end(), []( const point_om_omt & lhs, const point_om_omt & rhs ) { + return lhs.x() < rhs.x(); } ); // We'll use these points later as points that are guaranteed to be // at a boundary and will form a good foundation for the trail system. - point northmost = *north_south_most.first; - point southmost = *north_south_most.second; - point westmost = *west_east_most.first; - point eastmost = *west_east_most.second; + point_om_omt northmost = *north_south_most.first; + point_om_omt southmost = *north_south_most.second; + point_om_omt westmost = *west_east_most.first; + point_om_omt eastmost = *west_east_most.second; // Do a simplistic calculation of the center of the forest (rather than // calculating the actual centroid--it's not that important) to have another // good point to form the foundation of the trail system. - point center( westmost.x + ( eastmost.x - westmost.x ) / 2, - northmost.y + ( southmost.y - northmost.y ) / 2 ); + point_om_omt center( westmost.x() + ( eastmost.x() - westmost.x() ) / 2, + northmost.y() + ( southmost.y() - northmost.y() ) / 2 ); - point center_point = center; + point_om_omt center_point = center; // Because we didn't do the centroid of a concave polygon, there's no // guarantee that our center point is actually within the bounds of the // forest. Just find the point within our set that is closest to our // center point and use that. - point actual_center_point = *std::min_element( forest_points.begin(), - forest_points.end(), [¢er_point]( const point & lhs, const point & rhs ) { + point_om_omt actual_center_point = + *std::min_element( forest_points.begin(), forest_points.end(), + [¢er_point]( const point_om_omt & lhs, const point_om_omt & rhs ) { return square_dist( lhs, center_point ) < square_dist( rhs, center_point ); } ); @@ -2273,7 +2283,7 @@ void overmap::place_forest_trails() max_random_points = std::min( max_random_points, settings.forest_trail.random_point_max ); // Start with the center... - std::vector chosen_points = { actual_center_point }; + std::vector chosen_points = { actual_center_point }; // ...and then add our random points. int random_point_count = 0; @@ -2321,9 +2331,9 @@ void overmap::place_forest_trailheads() // 3. rng rolls a success for our trailhead_chance from the configuration // 4. the trailhead special we've picked can be placed in the selected location - const auto trailhead_close_to_road = [&]( const tripoint & trailhead ) { + const auto trailhead_close_to_road = [&]( const tripoint_om_omt & trailhead ) { bool close = false; - for( const tripoint &nearby_point : closest_points_first( + for( const tripoint_om_omt &nearby_point : closest_points_first( trailhead, settings.forest_trail.trailhead_road_distance ) ) { @@ -2334,9 +2344,9 @@ void overmap::place_forest_trailheads() return close; }; - const auto try_place_trailhead_special = [&]( const tripoint & trail_end, + const auto try_place_trailhead_special = [&]( const tripoint_om_omt & trail_end, const om_direction::type & dir ) { - const tripoint potential_trailhead = trail_end + om_direction::displace( dir, 1 ); + const tripoint_om_omt potential_trailhead = trail_end + om_direction::displace( dir, 1 ); overmap_special_id trailhead = settings.forest_trail.trailheads.pick(); if( one_in( settings.forest_trail.trailhead_chance ) && trailhead_close_to_road( potential_trailhead ) && @@ -2348,7 +2358,7 @@ void overmap::place_forest_trailheads() for( int i = 2; i < OMAPX - 2; i++ ) { for( int j = 2; j < OMAPY - 2; j++ ) { - const tripoint p( i, j, 0 ); + const tripoint_om_omt p( i, j, 0 ); oter_id oter = ter( p ); if( is_ot_match( "forest_trail_end", oter, ot_match_type::prefix ) ) { try_place_trailhead_special( p, oter->get_dir() ); @@ -2367,7 +2377,7 @@ void overmap::place_forests() for( int x = 0; x < OMAPX; x++ ) { for( int y = 0; y < OMAPY; y++ ) { - const tripoint p( x, y, 0 ); + const tripoint_om_omt p( x, y, 0 ); const oter_id &oter = ter( p ); // At this point in the process, we only want to consider converting the terrain into @@ -2392,7 +2402,7 @@ void overmap::place_lakes() { const om_noise::om_noise_layer_lake f( global_base_point(), g->get_seed() ); - const auto is_lake = [&]( const point & p ) { + const auto is_lake = [&]( const point_om_omt & p ) { return f.noise_at( p ) > settings.overmap_lake.noise_threshold_lake; }; @@ -2402,11 +2412,11 @@ void overmap::place_lakes() const oter_id lake_bed( "lake_bed" ); // We'll keep track of our visited lake points so we don't repeat the work. - std::unordered_set visited; + std::unordered_set visited; for( int i = 0; i < OMAPX; i++ ) { for( int j = 0; j < OMAPY; j++ ) { - point seed_point( i, j ); + point_om_omt seed_point( i, j ); if( visited.find( seed_point ) != visited.end() ) { continue; } @@ -2418,7 +2428,8 @@ void overmap::place_lakes() // We're going to flood-fill our lake so that we can consider the entire lake when evaluating it // for placement, even when the lake runs off the edge of the current overmap. - std::vector lake_points = ff::point_flood_fill_4_connected( seed_point, visited, is_lake ); + std::vector lake_points = + ff::point_flood_fill_4_connected( seed_point, visited, is_lake ); // If this lake doesn't exceed our minimum size threshold, then skip it. We can use this to // exclude the tiny lakes that don't provide interesting map features and exist mostly as a @@ -2432,14 +2443,14 @@ void overmap::place_lakes() // we just found AND all of the rivers on the map, because we want our lakes to write // over any rivers that are placed already. Note that the assumption here is that river // overmap generation (e.g. place_rivers) runs BEFORE lake overmap generation. - std::unordered_set lake_set; + std::unordered_set lake_set; for( auto &p : lake_points ) { lake_set.emplace( p ); } for( int x = 0; x < OMAPX; x++ ) { for( int y = 0; y < OMAPY; y++ ) { - const tripoint p( x, y, 0 ); + const tripoint_om_omt p( x, y, 0 ); if( ter( p )->is_river() ) { lake_set.emplace( p.xy() ); } @@ -2460,36 +2471,36 @@ void overmap::place_lakes() bool shore = false; for( int ni = -1; ni <= 1 && !shore; ni++ ) { for( int nj = -1; nj <= 1 && !shore; nj++ ) { - const int nx = p.x + ni; - const int ny = p.y + nj; - if( lake_set.find( { nx, ny } ) == lake_set.end() ) { + const point_om_omt n = p + point( ni, nj ); + if( lake_set.find( n ) == lake_set.end() ) { shore = true; } } } - ter_set( tripoint( p, 0 ), shore ? lake_shore : lake_surface ); + ter_set( tripoint_om_omt( p, 0 ), shore ? lake_shore : lake_surface ); // If this is not a shore, we'll make our subsurface lake cubes and beds. if( !shore ) { for( int z = -1; z > settings.overmap_lake.lake_depth; z-- ) { - ter_set( tripoint( p, z ), lake_water_cube ); + ter_set( tripoint_om_omt( p, z ), lake_water_cube ); } - ter_set( tripoint( p, settings.overmap_lake.lake_depth ), lake_bed ); + ter_set( tripoint_om_omt( p, settings.overmap_lake.lake_depth ), lake_bed ); } } // We're going to attempt to connect some points on this lake to the nearest river. - const auto connect_lake_to_closest_river = [&]( const point & lake_connection_point ) { + const auto connect_lake_to_closest_river = + [&]( const point_om_omt & lake_connection_point ) { int closest_distance = -1; - point closest_point; + point_om_omt closest_point; for( int x = 0; x < OMAPX; x++ ) { for( int y = 0; y < OMAPY; y++ ) { - const tripoint p( x, y, 0 ); + const tripoint_om_omt p( x, y, 0 ); if( !ter( p )->is_river() ) { continue; } - const int distance = square_dist( lake_connection_point, point( x, y ) ); + const int distance = square_dist( lake_connection_point, p.xy() ); if( distance < closest_distance || closest_distance < 0 ) { closest_point = p.xy(); closest_distance = distance; @@ -2503,13 +2514,13 @@ void overmap::place_lakes() }; // Get the north and south most points in our lake. - auto north_south_most = std::minmax_element( lake_points.begin(), - lake_points.end(), []( const point & lhs, const point & rhs ) { - return lhs.y < rhs.y; + auto north_south_most = std::minmax_element( lake_points.begin(), lake_points.end(), + []( const point_om_omt & lhs, const point_om_omt & rhs ) { + return lhs.y() < rhs.y(); } ); - point northmost = *north_south_most.first; - point southmost = *north_south_most.second; + point_om_omt northmost = *north_south_most.first; + point_om_omt southmost = *north_south_most.second; // It's possible that our northmost/southmost points in the lake are not on this overmap, because our // lake may extend across multiple overmaps. @@ -2533,9 +2544,9 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove int river_chance = static_cast( std::max( 1.0, 1.0 / settings.river_scale ) ); int river_scale = static_cast( std::max( 1.0, settings.river_scale ) ); // West/North endpoints of rivers - std::vector river_start; + std::vector river_start; // East/South endpoints of rivers - std::vector river_end; + std::vector river_end; // Determine points where rivers & roads should connect w/ adjacent maps // optimized comparison. @@ -2543,8 +2554,8 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove if( north != nullptr ) { for( int i = 2; i < OMAPX - 2; i++ ) { - const tripoint p_neighbour( i, OMAPY - 1, 0 ); - const tripoint p_mine( i, 0, 0 ); + const tripoint_om_omt p_neighbour( i, OMAPY - 1, 0 ); + const tripoint_om_omt p_mine( i, 0, 0 ); if( is_river( north->ter( p_neighbour ) ) ) { ter_set( p_mine, river_center ); @@ -2553,7 +2564,7 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove is_river( north->ter( p_neighbour + point_east ) ) && is_river( north->ter( p_neighbour + point_west ) ) ) { if( one_in( river_chance ) && ( river_start.empty() || - river_start[river_start.size() - 1].x < ( i - 6 ) * river_scale ) ) { + river_start[river_start.size() - 1].x() < ( i - 6 ) * river_scale ) ) { river_start.push_back( p_mine.xy() ); } } @@ -2562,8 +2573,8 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove size_t rivers_from_north = river_start.size(); if( west != nullptr ) { for( int i = 2; i < OMAPY - 2; i++ ) { - const tripoint p_neighbour( OMAPX - 1, i, 0 ); - const tripoint p_mine( 0, i, 0 ); + const tripoint_om_omt p_neighbour( OMAPX - 1, i, 0 ); + const tripoint_om_omt p_mine( 0, i, 0 ); if( is_river( west->ter( p_neighbour ) ) ) { ter_set( p_mine, river_center ); @@ -2572,7 +2583,7 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove is_river( west->ter( p_neighbour + point_north ) ) && is_river( west->ter( p_neighbour + point_south ) ) ) { if( one_in( river_chance ) && ( river_start.size() == rivers_from_north || - river_start[river_start.size() - 1].y < ( i - 6 ) * river_scale ) ) { + river_start[river_start.size() - 1].y() < ( i - 6 ) * river_scale ) ) { river_start.push_back( p_mine.xy() ); } } @@ -2580,8 +2591,8 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove } if( south != nullptr ) { for( int i = 2; i < OMAPX - 2; i++ ) { - const tripoint p_neighbour( i, 0, 0 ); - const tripoint p_mine( i, OMAPY - 1, 0 ); + const tripoint_om_omt p_neighbour( i, 0, 0 ); + const tripoint_om_omt p_mine( i, OMAPY - 1, 0 ); if( is_river( south->ter( p_neighbour ) ) ) { ter_set( p_mine, river_center ); @@ -2590,7 +2601,7 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove is_river( south->ter( p_neighbour + point_east ) ) && is_river( south->ter( p_neighbour + point_west ) ) ) { if( river_end.empty() || - river_end[river_end.size() - 1].x < i - 6 ) { + river_end[river_end.size() - 1].x() < i - 6 ) { river_end.push_back( p_mine.xy() ); } } @@ -2599,8 +2610,8 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove size_t rivers_to_south = river_end.size(); if( east != nullptr ) { for( int i = 2; i < OMAPY - 2; i++ ) { - const tripoint p_neighbour( 0, i, 0 ); - const tripoint p_mine( OMAPX - 1, i, 0 ); + const tripoint_om_omt p_neighbour( 0, i, 0 ); + const tripoint_om_omt p_mine( OMAPX - 1, i, 0 ); if( is_river( east->ter( p_neighbour ) ) ) { ter_set( p_mine, river_center ); @@ -2609,7 +2620,7 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove is_river( east->ter( p_neighbour + point_north ) ) && is_river( east->ter( p_neighbour + point_south ) ) ) { if( river_end.size() == rivers_to_south || - river_end[river_end.size() - 1].y < i - 6 ) { + river_end[river_end.size() - 1].y() < i - 6 ) { river_end.push_back( p_mine.xy() ); } } @@ -2618,15 +2629,15 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove // Even up the start and end points of rivers. (difference of 1 is acceptable) // Also ensure there's at least one of each. - std::vector new_rivers; + std::vector new_rivers; if( north == nullptr || west == nullptr ) { while( river_start.empty() || river_start.size() + 1 < river_end.size() ) { new_rivers.clear(); if( north == nullptr && one_in( river_chance ) ) { - new_rivers.push_back( point( rng( 10, OMAPX - 11 ), 0 ) ); + new_rivers.push_back( point_om_omt( rng( 10, OMAPX - 11 ), 0 ) ); } if( west == nullptr && one_in( river_chance ) ) { - new_rivers.push_back( point( 0, rng( 10, OMAPY - 11 ) ) ); + new_rivers.push_back( point_om_omt( 0, rng( 10, OMAPY - 11 ) ) ); } river_start.push_back( random_entry( new_rivers ) ); } @@ -2635,10 +2646,10 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove while( river_end.empty() || river_end.size() + 1 < river_start.size() ) { new_rivers.clear(); if( south == nullptr && one_in( river_chance ) ) { - new_rivers.push_back( point( rng( 10, OMAPX - 11 ), OMAPY - 1 ) ); + new_rivers.push_back( point_om_omt( rng( 10, OMAPX - 11 ), OMAPY - 1 ) ); } if( east == nullptr && one_in( river_chance ) ) { - new_rivers.push_back( point( OMAPX - 1, rng( 10, OMAPY - 11 ) ) ); + new_rivers.push_back( point_om_omt( OMAPX - 1, rng( 10, OMAPY - 11 ) ) ); } river_end.push_back( random_entry( new_rivers ) ); } @@ -2646,9 +2657,9 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove // Now actually place those rivers. if( river_start.size() > river_end.size() && !river_end.empty() ) { - std::vector river_end_copy = river_end; + std::vector river_end_copy = river_end; while( !river_start.empty() ) { - const point start = random_entry_removed( river_start ); + const point_om_omt start = random_entry_removed( river_start ); if( !river_end.empty() ) { place_river( start, river_end[0] ); river_end.erase( river_end.begin() ); @@ -2657,9 +2668,9 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove } } } else if( river_end.size() > river_start.size() && !river_start.empty() ) { - std::vector river_start_copy = river_start; + std::vector river_start_copy = river_start; while( !river_end.empty() ) { - const point end = random_entry_removed( river_end ); + const point_om_omt end = random_entry_removed( river_end ); if( !river_start.empty() ) { place_river( river_start[0], end ); river_start.erase( river_start.begin() ); @@ -2669,8 +2680,8 @@ void overmap::place_rivers( const overmap *north, const overmap *east, const ove } } else if( !river_end.empty() ) { if( river_start.size() != river_end.size() ) { - river_start.push_back( point( rng( OMAPX / 4, ( OMAPX * 3 ) / 4 ), - rng( OMAPY / 4, ( OMAPY * 3 ) / 4 ) ) ); + river_start.push_back( point_om_omt( rng( OMAPX / 4, ( OMAPX * 3 ) / 4 ), + rng( OMAPY / 4, ( OMAPY * 3 ) / 4 ) ) ); } for( size_t i = 0; i < river_start.size(); i++ ) { place_river( river_start[i], river_end[i] ); @@ -2686,17 +2697,18 @@ void overmap::place_swamps() std::vector> floodplain( OMAPX, std::vector( OMAPY, 0 ) ); for( int x = 0; x < OMAPX; x++ ) { for( int y = 0; y < OMAPY; y++ ) { - const tripoint pos( x, y, 0 ); + const tripoint_om_omt pos( x, y, 0 ); if( is_ot_match( "river", ter( pos ), ot_match_type::contains ) ) { - std::vector buffered_points = closest_points_first( pos.xy(), - rng( - settings.overmap_forest.river_floodplain_buffer_distance_min, - settings.overmap_forest.river_floodplain_buffer_distance_max ) ); - for( const point &p : buffered_points ) { + std::vector buffered_points = + closest_points_first( + pos.xy(), + rng( settings.overmap_forest.river_floodplain_buffer_distance_min, + settings.overmap_forest.river_floodplain_buffer_distance_max ) ); + for( const point_om_omt &p : buffered_points ) { if( !inbounds( p ) ) { continue; } - floodplain[p.x][p.y] += 1; + floodplain[p.x()][p.y()] += 1; } } } @@ -2709,7 +2721,7 @@ void overmap::place_swamps() for( int x = 0; x < OMAPX; x++ ) { for( int y = 0; y < OMAPY; y++ ) { - const tripoint pos( x, y, 0 ); + const tripoint_om_omt pos( x, y, 0 ); // If this location isn't a forest, there's nothing to do here. We'll only grow swamps in existing // forest terrain. if( !is_ot_match( "forest", ter( pos ), ot_match_type::contains ) ) { @@ -2736,39 +2748,39 @@ void overmap::place_roads( const overmap *north, const overmap *east, const over const overmap *west ) { const string_id local_road( "local_road" ); - std::vector &roads_out = connections_out[local_road]; + std::vector &roads_out = connections_out[local_road]; // Ideally we should have at least two exit points for roads, on different sides if( roads_out.size() < 2 ) { - std::vector viable_roads; - tripoint tmp; + std::vector viable_roads; + tripoint_om_omt tmp; // Populate viable_roads with one point for each neighborless side. // Make sure these points don't conflict with rivers. // TODO: In theory this is a potential infinite loop... if( north == nullptr ) { do { - tmp = tripoint( rng( 10, OMAPX - 11 ), 0, 0 ); + tmp = tripoint_om_omt( rng( 10, OMAPX - 11 ), 0, 0 ); } while( is_river( ter( tmp ) ) || is_river( ter( tmp + point_east ) ) || is_river( ter( tmp + point_west ) ) ); viable_roads.push_back( tmp ); } if( east == nullptr ) { do { - tmp = tripoint( OMAPX - 1, rng( 10, OMAPY - 11 ), 0 ); + tmp = tripoint_om_omt( OMAPX - 1, rng( 10, OMAPY - 11 ), 0 ); } while( is_river( ter( tmp ) ) || is_river( ter( tmp + point_north ) ) || is_river( ter( tmp + point_south ) ) ); viable_roads.push_back( tmp ); } if( south == nullptr ) { do { - tmp = tripoint( rng( 10, OMAPX - 11 ), OMAPY - 1, 0 ); + tmp = tripoint_om_omt( rng( 10, OMAPX - 11 ), OMAPY - 1, 0 ); } while( is_river( ter( tmp ) ) || is_river( ter( tmp + point_east ) ) || is_river( ter( tmp + point_west ) ) ); viable_roads.push_back( tmp ); } if( west == nullptr ) { do { - tmp = tripoint( 0, rng( 10, OMAPY - 11 ), 0 ); + tmp = tripoint_om_omt( 0, rng( 10, OMAPY - 11 ), 0 ); } while( is_river( ter( tmp ) ) || is_river( ter( tmp + point_north ) ) || is_river( ter( tmp + point_south ) ) ); viable_roads.push_back( tmp ); @@ -2778,7 +2790,7 @@ void overmap::place_roads( const overmap *north, const overmap *east, const over } } - std::vector road_points; // cities and roads_out together + std::vector road_points; // cities and roads_out together // Compile our master list of roads; it's less messy if roads_out is first road_points.reserve( roads_out.size() + cities.size() ); for( const auto &elem : roads_out ) { @@ -2792,78 +2804,78 @@ void overmap::place_roads( const overmap *north, const overmap *east, const over connect_closest_points( road_points, 0, *local_road ); } -void overmap::place_river( point pa, point pb ) +void overmap::place_river( point_om_omt pa, point_om_omt pb ) { const oter_id river_center( "river_center" ); int river_chance = static_cast( std::max( 1.0, 1.0 / settings.river_scale ) ); int river_scale = static_cast( std::max( 1.0, settings.river_scale ) ); - point p2( pa ); + point_om_omt p2( pa ); do { - p2.x += rng( -1, 1 ); - p2.y += rng( -1, 1 ); - if( p2.x < 0 ) { - p2.x = 0; + p2.x() += rng( -1, 1 ); + p2.y() += rng( -1, 1 ); + if( p2.x() < 0 ) { + p2.x() = 0; } - if( p2.x > OMAPX - 1 ) { - p2.x = OMAPX - 1; + if( p2.x() > OMAPX - 1 ) { + p2.x() = OMAPX - 1; } - if( p2.y < 0 ) { - p2.y = 0; + if( p2.y() < 0 ) { + p2.y() = 0; } - if( p2.y > OMAPY - 1 ) { - p2.y = OMAPY - 1; + if( p2.y() > OMAPY - 1 ) { + p2.y() = OMAPY - 1; } for( int i = -1 * river_scale; i <= 1 * river_scale; i++ ) { for( int j = -1 * river_scale; j <= 1 * river_scale; j++ ) { - if( p2.y + i >= 0 && p2.y + i < OMAPY && p2.x + j >= 0 && p2.x + j < OMAPX ) { - tripoint p( p2.x + j, p2.y + i, 0 ); + tripoint_om_omt p( p2 + point( j, i ), 0 ); + if( p.y() >= 0 && p.y() < OMAPY && p.x() >= 0 && p.x() < OMAPX ) { if( !ter( p )->is_lake() && one_in( river_chance ) ) { ter_set( p, river_center ); } } } } - if( pb.x > p2.x && ( rng( 0, static_cast( OMAPX * 1.2 ) - 1 ) < pb.x - p2.x || - ( rng( 0, static_cast( OMAPX * 0.2 ) - 1 ) > pb.x - p2.x && - rng( 0, static_cast( OMAPY * 0.2 ) - 1 ) > std::abs( pb.y - p2.y ) ) ) ) { - p2.x++; + if( pb.x() > p2.x() && ( rng( 0, static_cast( OMAPX * 1.2 ) - 1 ) < pb.x() - p2.x() || + ( rng( 0, static_cast( OMAPX * 0.2 ) - 1 ) > pb.x() - p2.x() && + rng( 0, static_cast( OMAPY * 0.2 ) - 1 ) > std::abs( pb.y() - p2.y() ) ) ) ) { + p2.x()++; } - if( pb.x < p2.x && ( rng( 0, static_cast( OMAPX * 1.2 ) - 1 ) < p2.x - pb.x || - ( rng( 0, static_cast( OMAPX * 0.2 ) - 1 ) > p2.x - pb.x && - rng( 0, static_cast( OMAPY * 0.2 ) - 1 ) > std::abs( pb.y - p2.y ) ) ) ) { - p2.x--; + if( pb.x() < p2.x() && ( rng( 0, static_cast( OMAPX * 1.2 ) - 1 ) < p2.x() - pb.x() || + ( rng( 0, static_cast( OMAPX * 0.2 ) - 1 ) > p2.x() - pb.x() && + rng( 0, static_cast( OMAPY * 0.2 ) - 1 ) > std::abs( pb.y() - p2.y() ) ) ) ) { + p2.x()--; } - if( pb.y > p2.y && ( rng( 0, static_cast( OMAPY * 1.2 ) - 1 ) < pb.y - p2.y || - ( rng( 0, static_cast( OMAPY * 0.2 ) - 1 ) > pb.y - p2.y && - rng( 0, static_cast( OMAPX * 0.2 ) - 1 ) > std::abs( p2.x - pb.x ) ) ) ) { - p2.y++; + if( pb.y() > p2.y() && ( rng( 0, static_cast( OMAPY * 1.2 ) - 1 ) < pb.y() - p2.y() || + ( rng( 0, static_cast( OMAPY * 0.2 ) - 1 ) > pb.y() - p2.y() && + rng( 0, static_cast( OMAPX * 0.2 ) - 1 ) > std::abs( p2.x() - pb.x() ) ) ) ) { + p2.y()++; } - if( pb.y < p2.y && ( rng( 0, static_cast( OMAPY * 1.2 ) - 1 ) < p2.y - pb.y || - ( rng( 0, static_cast( OMAPY * 0.2 ) - 1 ) > p2.y - pb.y && - rng( 0, static_cast( OMAPX * 0.2 ) - 1 ) > std::abs( p2.x - pb.x ) ) ) ) { - p2.y--; + if( pb.y() < p2.y() && ( rng( 0, static_cast( OMAPY * 1.2 ) - 1 ) < p2.y() - pb.y() || + ( rng( 0, static_cast( OMAPY * 0.2 ) - 1 ) > p2.y() - pb.y() && + rng( 0, static_cast( OMAPX * 0.2 ) - 1 ) > std::abs( p2.x() - pb.x() ) ) ) ) { + p2.y()--; } - p2.x += rng( -1, 1 ); - p2.y += rng( -1, 1 ); - if( p2.x < 0 ) { - p2.x = 0; + p2.x() += rng( -1, 1 ); + p2.y() += rng( -1, 1 ); + if( p2.x() < 0 ) { + p2.x() = 0; } - if( p2.x > OMAPX - 1 ) { - p2.x = OMAPX - 2; + if( p2.x() > OMAPX - 1 ) { + p2.x() = OMAPX - 2; } - if( p2.y < 0 ) { - p2.y = 0; + if( p2.y() < 0 ) { + p2.y() = 0; } - if( p2.y > OMAPY - 1 ) { - p2.y = OMAPY - 1; + if( p2.y() > OMAPY - 1 ) { + p2.y() = OMAPY - 1; } for( int i = -1 * river_scale; i <= 1 * river_scale; i++ ) { for( int j = -1 * river_scale; j <= 1 * river_scale; j++ ) { // We don't want our riverbanks touching the edge of the map for many reasons - if( inbounds( tripoint( p2.x + j, p2.y + i, 0 ), 1 ) || + tripoint_om_omt p( p2 + point( j, i ), 0 ); + if( inbounds( p, 1 ) || // UNLESS, of course, that's where the river is headed! - ( std::abs( pb.y - ( p2.y + i ) ) < 4 && std::abs( pb.x - ( p2.x + j ) ) < 4 ) ) { - tripoint p( p2.x + j, p2.y + i, 0 ); + ( std::abs( pb.y() - p.y() ) < 4 && std::abs( pb.x() - p.x() ) < 4 ) ) { if( !inbounds( p ) ) { continue; } @@ -2874,7 +2886,7 @@ void overmap::place_river( point pa, point pb ) } } } - } while( pb.x != p2.x || pb.y != p2.y ); + } while( pb != p2 ); } /*: the root is overmap::place_cities() @@ -2936,8 +2948,8 @@ void overmap::place_cities() // TODO: put cities closer to the edge when they can span overmaps // don't draw cities across the edge of the map, they will get clipped - point c( rng( size - 1, OMAPX - size ), rng( size - 1, OMAPY - size ) ); - const tripoint p( c, 0 ); + point_om_omt c( rng( size - 1, OMAPX - size ), rng( size - 1, OMAPY - size ) ); + const tripoint_om_omt p( c, 0 ); if( ter( p ) == settings.default_oter ) { ter_set( p, oter_id( "road_nesw" ) ); // every city starts with an intersection @@ -2981,9 +2993,9 @@ overmap_special_id overmap::pick_random_building_to_place( int town_dist ) const } } -void overmap::place_building( const tripoint &p, om_direction::type dir, const city &town ) +void overmap::place_building( const tripoint_om_omt &p, om_direction::type dir, const city &town ) { - const tripoint building_pos = p + om_direction::displace( dir ); + const tripoint_om_omt building_pos = p + om_direction::displace( dir ); const om_direction::type building_dir = om_direction::opposite( dir ); const int town_dist = ( trig_dist( building_pos.xy(), town.pos ) * 100 ) / std::max( town.size, 1 ); @@ -2998,8 +3010,9 @@ void overmap::place_building( const tripoint &p, om_direction::type dir, const c } } -void overmap::build_city_street( const overmap_connection &connection, const point &p, int cs, - om_direction::type dir, const city &town, int block_width ) +void overmap::build_city_street( + const overmap_connection &connection, const point_om_omt &p, int cs, + om_direction::type dir, const city &town, int block_width ) { int c = cs; int croad = cs; @@ -3009,7 +3022,7 @@ void overmap::build_city_street( const overmap_connection &connection, const poi return; } - const pf::path street_path = lay_out_street( connection, p, dir, cs + 1 ); + const pf::path street_path = lay_out_street( connection, p, dir, cs + 1 ); if( street_path.nodes.size() <= 1 ) { return; // Don't bother. @@ -3026,7 +3039,7 @@ void overmap::build_city_street( const overmap_connection &connection, const poi for( auto iter = from; iter != to; ++iter ) { --c; - const tripoint rp( iter->pos, 0 ); + const tripoint_om_omt rp( iter->pos, 0 ); if( c >= 2 && c < croad - block_width ) { croad = c; int left = cs - rng( 1, 3 ); @@ -3076,10 +3089,11 @@ void overmap::build_city_street( const overmap_connection &connection, const poi } } -bool overmap::build_lab( const tripoint &p, int s, std::vector *lab_train_points, - const std::string &prefix, int train_odds ) +bool overmap::build_lab( + const tripoint_om_omt &p, int s, std::vector *lab_train_points, + const std::string &prefix, int train_odds ) { - std::vector generated_lab; + std::vector generated_lab; const oter_id labt( prefix + "lab" ); const oter_id labt_stairs( labt.id().str() + "_stairs" ); const oter_id labt_core( labt.id().str() + "_core" ); @@ -3092,10 +3106,10 @@ bool overmap::build_lab( const tripoint &p, int s, std::vector *lab_train // maintain a list of potential new lab maps // grows outwards from previously placed lab maps - std::set candidates; + std::set candidates; candidates.insert( { p + point_north, p + point_east, p + point_south, p + point_west } ); while( !candidates.empty() ) { - const tripoint cand = *candidates.begin(); + const tripoint_om_omt cand = *candidates.begin(); candidates.erase( candidates.begin() ); if( !inbounds( cand ) ) { continue; @@ -3115,7 +3129,7 @@ bool overmap::build_lab( const tripoint &p, int s, std::vector *lab_train generated_lab.push_back( cand ); // add new candidates, don't backtrack for( const point &offset : four_adjacent_offsets ) { - const tripoint new_cand = cand + offset; + const tripoint_om_omt new_cand = cand + offset; const int new_dist = manhattan_dist( p.xy(), new_cand.xy() ); if( ter( new_cand ) != labt && new_dist > dist ) { candidates.insert( new_cand ); @@ -3126,7 +3140,7 @@ bool overmap::build_lab( const tripoint &p, int s, std::vector *lab_train } bool generate_stairs = true; - for( tripoint &elem : generated_lab ) { + for( tripoint_om_omt &elem : generated_lab ) { // Use a check for "_stairs" to catch the hidden_lab_stairs tiles. if( is_ot_match( "_stairs", ter( elem + tripoint_above ), ot_match_type::contains ) ) { generate_stairs = false; @@ -3136,8 +3150,8 @@ bool overmap::build_lab( const tripoint &p, int s, std::vector *lab_train std::shuffle( generated_lab.begin(), generated_lab.end(), rng_get_engine() ); // we want a spot where labs are above, but we'll settle for the last element if necessary. - tripoint lab_pos; - for( tripoint elem : generated_lab ) { + tripoint_om_omt lab_pos; + for( tripoint_om_omt elem : generated_lab ) { lab_pos = elem; if( ter( lab_pos + tripoint_above ) == labt ) { break; @@ -3150,7 +3164,7 @@ bool overmap::build_lab( const tripoint &p, int s, std::vector *lab_train int numstairs = 0; if( s > 0 ) { // Build stairs going down while( !one_in( 6 ) ) { - tripoint stair; + tripoint_om_omt stair; int tries = 0; do { stair = p + point( rng( -s, s ), rng( -s, s ) ); @@ -3168,8 +3182,8 @@ bool overmap::build_lab( const tripoint &p, int s, std::vector *lab_train } // We need a finale on the bottom of labs. Central labs have a chance of additional finales. - if( numstairs == 0 || ( prefix == "central_" && one_in( -p.z - 1 ) ) ) { - tripoint finale; + if( numstairs == 0 || ( prefix == "central_" && one_in( -p.z() - 1 ) ) ) { + tripoint_om_omt finale; int tries = 0; do { finale = p + point( rng( -s, s ), rng( -s, s ) ); @@ -3179,7 +3193,7 @@ bool overmap::build_lab( const tripoint &p, int s, std::vector *lab_train } if( train_odds > 0 && one_in( train_odds ) ) { - tripoint train; + tripoint_om_omt train; int tries = 0; int adjacent_labs; @@ -3211,8 +3225,8 @@ bool overmap::build_lab( const tripoint &p, int s, std::vector *lab_train } // 4th story of labs is a candidate for lab escape, as long as there's no train or finale. - if( prefix.empty() && p.z == -4 && train_odds == 0 && numstairs > 0 ) { - tripoint cell; + if( prefix.empty() && p.z() == -4 && train_odds == 0 && numstairs > 0 ) { + tripoint_om_omt cell; int tries = 0; int adjacent_labs = 0; @@ -3241,7 +3255,7 @@ bool overmap::build_lab( const tripoint &p, int s, std::vector *lab_train return numstairs > 0; } -void overmap::build_anthill( const tripoint &p, int s ) +void overmap::build_anthill( const tripoint_om_omt &p, int s ) { for( om_direction::type dir : om_direction::all ) { build_tunnel( p, s - rng( 0, 3 ), dir ); @@ -3249,10 +3263,10 @@ void overmap::build_anthill( const tripoint &p, int s ) // TODO: This should follow the tunnel network, // as of now it can pick a tile from an adjacent ant network. - std::vector queenpoints; + std::vector queenpoints; for( int i = -s; i <= s; i++ ) { for( int j = -s; j <= s; j++ ) { - const tripoint qp = p + point( i, j ); + const tripoint_om_omt qp = p + point( i, j ); if( check_ot( "ants", ot_match_type::type, qp ) ) { queenpoints.push_back( qp ); } @@ -3261,21 +3275,21 @@ void overmap::build_anthill( const tripoint &p, int s ) if( queenpoints.empty() ) { debugmsg( "No queenpoints when building anthill, anthill over %s", ter( p ).id().str() ); } - const tripoint target = random_entry( queenpoints ); + const tripoint_om_omt target = random_entry( queenpoints ); ter_set( target, oter_id( "ants_queen" ) ); const oter_id root_id( "ants_isolated" ); for( int i = -s; i <= s; i++ ) { for( int j = -s; j <= s; j++ ) { - const tripoint root = p + point( i, j ); + const tripoint_om_omt root = p + point( i, j ); if( !inbounds( root ) ) { continue; } if( root_id == ter( root )->id ) { const oter_id &oter = ter( root ); for( om_direction::type dir : om_direction::all ) { - const tripoint neighbor = root + om_direction::displace( dir ); + const tripoint_om_omt neighbor = root + om_direction::displace( dir ); if( check_ot( "ants", ot_match_type::prefix, neighbor ) ) { size_t line = oter->get_line(); line = om_lines::set_segment( line, dir ); @@ -3289,7 +3303,7 @@ void overmap::build_anthill( const tripoint &p, int s ) } } -void overmap::build_tunnel( const tripoint &p, int s, om_direction::type dir ) +void overmap::build_tunnel( const tripoint_om_omt &p, int s, om_direction::type dir ) { if( s <= 0 ) { return; @@ -3313,7 +3327,7 @@ void overmap::build_tunnel( const tripoint &p, int s, om_direction::type dir ) std::vector valid; valid.reserve( om_direction::size ); for( om_direction::type r : om_direction::all ) { - const tripoint cand = p + om_direction::displace( r ); + const tripoint_om_omt cand = p + om_direction::displace( r ); if( !check_ot( "ants", ot_match_type::type, cand ) && is_ot_match( "empty_rock", ter( cand ), ot_match_type::type ) ) { valid.push_back( r ); @@ -3322,10 +3336,11 @@ void overmap::build_tunnel( const tripoint &p, int s, om_direction::type dir ) const oter_id ants_food( "ants_food" ); const oter_id ants_larvae( "ants_larvae" ); - const tripoint next = s != 1 ? p + om_direction::displace( dir ) : tripoint( -1, -1, -1 ); + const tripoint_om_omt next = + s != 1 ? p + om_direction::displace( dir ) : tripoint_om_omt( -1, -1, -1 ); for( auto r : valid ) { - const tripoint cand = p + om_direction::displace( r ); + const tripoint_om_omt cand = p + om_direction::displace( r ); if( !inbounds( cand ) ) { continue; } @@ -3347,17 +3362,17 @@ void overmap::build_tunnel( const tripoint &p, int s, om_direction::type dir ) build_tunnel( next, s - 1, dir ); } -bool overmap::build_slimepit( const tripoint &origin, int s ) +bool overmap::build_slimepit( const tripoint_om_omt &origin, int s ) { const oter_id slimepit_down( "slimepit_down" ); const oter_id slimepit( "slimepit" ); bool requires_sub = false; - for( auto p : get_map().points_in_radius( origin, s + origin.z + 1, 0 ) ) { + for( auto p : points_in_radius( origin, s + origin.z() + 1, 0 ) ) { int dist = square_dist( origin.xy(), p.xy() ); if( one_in( 2 * dist ) ) { chip_rock( p ); - if( one_in( 8 ) && origin.z > -OVERMAP_DEPTH ) { + if( one_in( 8 ) && origin.z() > -OVERMAP_DEPTH ) { ter_set( p, slimepit_down ); requires_sub = true; } else { @@ -3369,7 +3384,7 @@ bool overmap::build_slimepit( const tripoint &origin, int s ) return requires_sub; } -void overmap::build_mine( const tripoint &origin, int s ) +void overmap::build_mine( const tripoint_om_omt &origin, int s ) { bool finale = s <= rng( 1, 3 ); const oter_id mine( "mine" ); @@ -3380,10 +3395,10 @@ void overmap::build_mine( const tripoint &origin, int s ) if( s < 2 ) { s = 2; } - tripoint p = origin; + tripoint_om_omt p = origin; while( built < s ) { ter_set( p, mine ); - std::vector next; + std::vector next; for( const point &offset : four_adjacent_offsets ) { if( ter( p + offset ) == empty_rock ) { next.push_back( p + offset ); @@ -3399,12 +3414,13 @@ void overmap::build_mine( const tripoint &origin, int s ) ter_set( p, mine_finale_or_down ); } -pf::path overmap::lay_out_connection( - const overmap_connection &connection, const point &source, const point &dest, int z, - const bool must_be_unexplored ) const +pf::path overmap::lay_out_connection( + const overmap_connection &connection, const point_om_omt &source, const point_om_omt &dest, + int z, const bool must_be_unexplored ) const { - const auto estimate = [&]( const pf::node &cur, const pf::node *prev ) { - const auto &id( ter( tripoint( cur.pos, z ) ) ); + const auto estimate = + [&]( const pf::node &cur, const pf::node *prev ) { + const auto &id( ter( tripoint_om_omt( cur.pos, z ) ) ); const overmap_connection::subtype *subtype = connection.pick_subtype_for( id ); @@ -3417,7 +3433,7 @@ pf::path overmap::lay_out_connection( // Only do this check if it needs to be unexplored and there isn't already a connection. if( must_be_unexplored && !existing_connection ) { // If this must be unexplored, check if we've already got a submap generated. - const bool existing_submap = is_omt_generated( tripoint( cur.pos, z ) ); + const bool existing_submap = is_omt_generated( tripoint_om_omt( cur.pos, z ) ); // If there is an existing submap, this area has already been explored and this // isn't a valid placement. @@ -3432,7 +3448,7 @@ pf::path overmap::lay_out_connection( } if( prev && prev->dir != cur.dir ) { // Direction has changed. - const oter_id &prev_id = ter( tripoint( prev->pos, z ) ); + const oter_id &prev_id = ter( tripoint_om_omt( prev->pos, z ) ); const overmap_connection::subtype *prev_subtype = connection.pick_subtype_for( prev_id ); if( !prev_subtype || !prev_subtype->allows_turns() ) { @@ -3448,15 +3464,16 @@ pf::path overmap::lay_out_connection( return existency_mult * dist + subtype->basic_cost; }; - return pf::find_path( source, dest, point( OMAPX, OMAPY ), estimate ); + return pf::find_path( source, dest, point_om_omt( OMAPX, OMAPY ), estimate ); } -pf::path overmap::lay_out_street( const overmap_connection &connection, const point &source, - om_direction::type dir, size_t len ) const +pf::path overmap::lay_out_street( + const overmap_connection &connection, const point_om_omt &source, om_direction::type dir, + size_t len ) const { - const tripoint from( source, 0 ); + const tripoint_om_omt from( source, 0 ); // See if we need to make another one "step" further. - const tripoint en_pos = from + om_direction::displace( dir, len + 1 ); + const tripoint_om_omt en_pos = from + om_direction::displace( dir, len + 1 ); if( inbounds( en_pos, 1 ) && connection.has( ter( en_pos ) ) ) { ++len; } @@ -3464,7 +3481,7 @@ pf::path overmap::lay_out_street( const overmap_connection &connection, c size_t actual_len = 0; while( actual_len < len ) { - const tripoint pos = from + om_direction::displace( dir, actual_len ); + const tripoint_om_omt pos = from + om_direction::displace( dir, actual_len ); if( !inbounds( pos, 1 ) ) { break; // Don't approach overmap bounds. @@ -3483,7 +3500,7 @@ pf::path overmap::lay_out_street( const overmap_connection &connection, c break; } for( int j = -1; j <= 1; j++ ) { - const tripoint checkp = pos + tripoint( i, j, 0 ); + const tripoint_om_omt checkp = pos + tripoint( i, j, 0 ); if( checkp != pos + om_direction::displace( dir, 1 ) && checkp != pos + om_direction::displace( om_direction::opposite( dir ), 1 ) && @@ -3514,8 +3531,9 @@ pf::path overmap::lay_out_street( const overmap_connection &connection, c return pf::straight_path( source, static_cast( dir ), actual_len ); } -void overmap::build_connection( const overmap_connection &connection, const pf::path &path, - int z, const om_direction::type &initial_dir ) +void overmap::build_connection( + const overmap_connection &connection, const pf::path &path, int z, + const om_direction::type &initial_dir ) { if( path.nodes.empty() ) { return; @@ -3523,11 +3541,11 @@ void overmap::build_connection( const overmap_connection &connection, const pf:: om_direction::type prev_dir = initial_dir; - const pf::node start = path.nodes.front(); - const pf::node end = path.nodes.back(); + const pf::node start = path.nodes.front(); + const pf::node end = path.nodes.back(); for( const auto &node : path.nodes ) { - const tripoint pos( node.pos, z ); + const tripoint_om_omt pos( node.pos, z ); const oter_id &ter_id = ter( pos ); // TODO: Make 'node' support 'om_direction'. const om_direction::type new_dir( static_cast( node.dir ) ); @@ -3551,7 +3569,7 @@ void overmap::build_connection( const overmap_connection &connection, const pf:: } for( const om_direction::type dir : om_direction::all ) { - const tripoint np( pos + om_direction::displace( dir ) ); + const tripoint_om_omt np( pos + om_direction::displace( dir ) ); if( inbounds( np ) ) { const oter_id &near_id = ter( np ); @@ -3575,9 +3593,9 @@ void overmap::build_connection( const overmap_connection &connection, const pf:: new_line = om_lines::set_segment( new_line, dir ); // Add this connection point to our connections out. - std::vector &outs = connections_out[connection.id]; + std::vector &outs = connections_out[connection.id]; const auto existing_out = std::find_if( outs.begin(), - outs.end(), [pos]( const tripoint & c ) { + outs.end(), [pos]( const tripoint_om_omt & c ) { return c == pos; } ); if( existing_out == outs.end() ) { @@ -3600,15 +3618,16 @@ void overmap::build_connection( const overmap_connection &connection, const pf:: } } -void overmap::build_connection( const point &source, const point &dest, int z, +void overmap::build_connection( const point_om_omt &source, const point_om_omt &dest, int z, const overmap_connection &connection, const bool must_be_unexplored, const om_direction::type &initial_dir ) { - build_connection( connection, lay_out_connection( connection, source, dest, z, must_be_unexplored ), - z, initial_dir ); + build_connection( + connection, lay_out_connection( connection, source, dest, z, must_be_unexplored ), + z, initial_dir ); } -void overmap::connect_closest_points( const std::vector &points, int z, +void overmap::connect_closest_points( const std::vector &points, int z, const overmap_connection &connection ) { if( points.size() == 1 ) { @@ -3640,7 +3659,7 @@ void overmap::polish_river() } // Changes neighboring empty rock to partial rock -void overmap::chip_rock( const tripoint &p ) +void overmap::chip_rock( const tripoint_om_omt &p ) { const oter_id rock( "rock" ); const oter_id empty_rock( "empty_rock" ); @@ -3653,7 +3672,7 @@ void overmap::chip_rock( const tripoint &p ) } bool overmap::check_ot( const std::string &otype, ot_match_type match_type, - const tripoint &p ) const + const tripoint_om_omt &p ) const { /// TODO: this check should be done by the caller. Probably. if( !inbounds( p ) ) { @@ -3664,7 +3683,7 @@ bool overmap::check_ot( const std::string &otype, ot_match_type match_type, } bool overmap::check_overmap_special_type( const overmap_special_id &id, - const tripoint &location ) const + const tripoint_om_omt &location ) const { // Try and find the special associated with this location. auto found_id = overmap_special_placements.find( location ); @@ -3678,12 +3697,12 @@ bool overmap::check_overmap_special_type( const overmap_special_id &id, return found_id->second == id; } -void overmap::good_river( const tripoint &p ) +void overmap::good_river( const tripoint_om_omt &p ) { if( !is_ot_match( "river", ter( p ), ot_match_type::prefix ) ) { return; } - if( ( p.x == 0 ) || ( p.x == OMAPX - 1 ) ) { + if( ( p.x() == 0 ) || ( p.x() == OMAPX - 1 ) ) { if( !is_river_or_lake( ter( p + point_north ) ) ) { ter_set( p, oter_id( "river_north" ) ); } else if( !is_river_or_lake( ter( p + point_south ) ) ) { @@ -3693,7 +3712,7 @@ void overmap::good_river( const tripoint &p ) } return; } - if( ( p.y == 0 ) || ( p.y == OMAPY - 1 ) ) { + if( ( p.y() == 0 ) || ( p.y() == OMAPY - 1 ) ) { if( !is_river_or_lake( ter( p + point_west ) ) ) { ter_set( p, oter_id( "river_west" ) ); } else if( !is_river_or_lake( ter( p + point_east ) ) ) { @@ -3886,7 +3905,7 @@ bool om_direction::are_parallel( type dir1, type dir2 ) } om_direction::type overmap::random_special_rotation( const overmap_special &special, - const tripoint &p, const bool must_be_unexplored ) const + const tripoint_om_omt &p, const bool must_be_unexplored ) const { std::vector rotations( om_direction::size ); const auto first = rotations.begin(); @@ -3899,7 +3918,7 @@ om_direction::type overmap::random_special_rotation( const overmap_special &spec bool valid = true; for( const auto &con : special.connections ) { - const tripoint rp = p + om_direction::rotate( con.p, r ); + const tripoint_om_omt rp = p + om_direction::rotate( con.p, r ); if( !inbounds( rp ) ) { valid = false; break; @@ -3936,10 +3955,9 @@ om_direction::type overmap::random_special_rotation( const overmap_special &spec return rotation != last ? *rotation : om_direction::type::invalid; } -bool overmap::can_place_special( const overmap_special &special, const tripoint &p, +bool overmap::can_place_special( const overmap_special &special, const tripoint_om_omt &p, om_direction::type dir, const bool must_be_unexplored ) const { - assert( p != invalid_tripoint ); assert( dir != om_direction::type::invalid ); if( !special.id ) { @@ -3948,7 +3966,7 @@ bool overmap::can_place_special( const overmap_special &special, const tripoint return std::all_of( special.terrains.begin(), special.terrains.end(), [&]( const overmap_special_terrain & elem ) { - const tripoint rp = p + om_direction::rotate( elem.p, dir ); + const tripoint_om_omt rp = p + om_direction::rotate( elem.p, dir ); if( !inbounds( rp, 1 ) ) { return false; @@ -3967,19 +3985,19 @@ bool overmap::can_place_special( const overmap_special &special, const tripoint const oter_id &tid = ter( rp ); - if( rp.z == 0 ) { + if( rp.z() == 0 ) { return elem.can_be_placed_on( tid ); } else { - return tid == get_default_terrain( rp.z ); + return tid == get_default_terrain( rp.z() ); } } ); } // checks around the selected point to see if the special can be placed there -void overmap::place_special( const overmap_special &special, const tripoint &p, - om_direction::type dir, const city &cit, const bool must_be_unexplored, const bool force ) +void overmap::place_special( + const overmap_special &special, const tripoint_om_omt &p, om_direction::type dir, + const city &cit, const bool must_be_unexplored, const bool force ) { - assert( p != invalid_tripoint ); assert( dir != om_direction::type::invalid ); if( !force ) { assert( can_place_special( special, p, dir, must_be_unexplored ) ); @@ -3988,7 +4006,7 @@ void overmap::place_special( const overmap_special &special, const tripoint &p, const bool blob = special.flags.count( "BLOB" ) > 0; for( const auto &elem : special.terrains ) { - const tripoint location = p + om_direction::rotate( elem.p, dir ); + const tripoint_om_omt location = p + om_direction::rotate( elem.p, dir ); const oter_id tid = elem.terrain->get_rotated( dir ); overmap_special_placements[location] = special.id; @@ -3997,7 +4015,7 @@ void overmap::place_special( const overmap_special &special, const tripoint &p, if( blob ) { for( int x = -2; x <= 2; x++ ) { for( int y = -2; y <= 2; y++ ) { - const tripoint nearby_pos = location + point( x, y ); + const tripoint_om_omt nearby_pos = location + point( x, y ); if( !inbounds( nearby_pos ) ) { continue; } @@ -4012,7 +4030,7 @@ void overmap::place_special( const overmap_special &special, const tripoint &p, if( cit ) { for( const auto &elem : special.connections ) { if( elem.connection ) { - const tripoint rp( p + om_direction::rotate( elem.p, dir ) ); + const tripoint_om_omt rp = p + om_direction::rotate( elem.p, dir ); om_direction::type initial_dir = elem.initial_dir; if( initial_dir != om_direction::type::invalid ) { @@ -4029,13 +4047,13 @@ void overmap::place_special( const overmap_special &special, const tripoint &p, const overmap_special_spawns &spawns = special.spawns; const int pop = rng( spawns.population.min, spawns.population.max ); const int rad = rng( spawns.radius.min, spawns.radius.max ); - add_mon_group( mongroup( spawns.group, tripoint( p.x * 2, p.y * 2, p.z ), rad, pop ) ); + add_mon_group( mongroup( spawns.group, project_to( p ), rad, pop ) ); } } om_special_sectors get_sectors( const int sector_width ) { - std::vector res; + std::vector res; res.reserve( ( OMAPX / sector_width ) * ( OMAPY / sector_width ) ); for( int x = 0; x < OMAPX; x += sector_width ) { @@ -4044,16 +4062,17 @@ om_special_sectors get_sectors( const int sector_width ) } } std::shuffle( res.begin(), res.end(), rng_get_engine() ); - return { res, sector_width }; + return om_special_sectors{ res, sector_width }; } -bool overmap::place_special_attempt( overmap_special_batch &enabled_specials, - const point §or, const int sector_width, const bool place_optional, - const bool must_be_unexplored ) +bool overmap::place_special_attempt( + overmap_special_batch &enabled_specials, const point_om_omt §or, + const int sector_width, const bool place_optional, const bool must_be_unexplored ) { - const point p2( sector ); + const point_om_omt p2( sector ); - const tripoint p( rng( p2.x, p2.x + sector_width - 1 ), rng( p2.y, p2.y + sector_width - 1 ), 0 ); + const tripoint_om_omt p( rng( p2.x(), p2.x() + sector_width - 1 ), + rng( p2.y(), p2.y() + sector_width - 1 ), 0 ); const city &nearest_city = get_nearest_city( p ); std::shuffle( enabled_specials.begin(), enabled_specials.end(), rng_get_engine() ); @@ -4182,10 +4201,10 @@ void overmap::place_specials( overmap_special_batch &enabled_specials ) } ) ) { // Randomly select from among the nearest uninitialized overmap positions. int previous_distance = 0; - std::vector nearest_candidates; + std::vector nearest_candidates; // Since this starts at enabled_specials::origin, it will only place new overmaps // in the 5x5 area surrounding the initial overmap, bounding the amount of work we will do. - for( const point &candidate_addr : closest_points_first( + for( const point_abs_om &candidate_addr : closest_points_first( custom_overmap_specials.get_origin(), 2 ) ) { if( !overmap_buffer.has( candidate_addr ) ) { int current_distance = square_dist( pos(), candidate_addr ); @@ -4199,7 +4218,7 @@ void overmap::place_specials( overmap_special_batch &enabled_specials ) } if( !nearest_candidates.empty() ) { std::shuffle( nearest_candidates.begin(), nearest_candidates.end(), rng_get_engine() ); - point new_om_addr = nearest_candidates.front(); + point_abs_om new_om_addr = nearest_candidates.front(); overmap_buffer.create_custom_overmap( new_om_addr, custom_overmap_specials ); } else { add_msg( _( "Unable to place all configured specials, some missions may fail to initialize." ) ); @@ -4251,11 +4270,11 @@ void overmap::place_specials( overmap_special_batch &enabled_specials ) void overmap::place_mongroups() { // Cities are full of zombies - for( auto &elem : cities ) { + for( city &elem : cities ) { if( get_option( "WANDER_SPAWNS" ) ) { if( !one_in( 16 ) || elem.size > 5 ) { mongroup m( GROUP_ZOMBIE, - tripoint( elem.pos.x * 2, elem.pos.y * 2, 0 ), + tripoint_om_sm( project_to( elem.pos ), 0 ), static_cast( elem.size * 2.5 ), elem.size * 80 ); // m.set_target( zg.back().posx, zg.back().posy ); @@ -4313,9 +4332,9 @@ void overmap::place_mongroups() } } -point overmap::global_base_point() const +point_abs_omt overmap::global_base_point() const { - return point( loc.x * OMAPX, loc.y * OMAPY ); + return project_to( loc ); } void overmap::place_radios() @@ -4326,8 +4345,8 @@ void overmap::place_radios() std::string message; for( int i = 0; i < OMAPX; i++ ) { for( int j = 0; j < OMAPY; j++ ) { - tripoint pos_omt( i, j, 0 ); - point pos_sm = omt_to_sm_copy( pos_omt.xy() ); + tripoint_om_omt pos_omt( i, j, 0 ); + point_om_sm pos_sm = project_to( pos_omt.xy() ); if( ter( pos_omt ) == "radio_tower" ) { int choice = rng( 0, 2 ); @@ -4402,7 +4421,7 @@ void overmap::add_mon_group( const mongroup &group ) // makes the diffuse setting obsolete (as it only controls how the radius // is interpreted) - it's only used when adding monster groups with function. if( group.radius == 1 ) { - zg.insert( std::pair( group.pos, group ) ); + zg.insert( std::pair( group.pos, group ) ); return; } // diffuse groups use a circular area, non-diffuse groups use a rectangular area @@ -4449,8 +4468,7 @@ void overmap::add_mon_group( const mongroup &group ) // for a single-submap group. mongroup tmp( group ); tmp.radius = 1; - tmp.pos.x += x; - tmp.pos.y += y; + tmp.pos += point( x, y ); tmp.population = p; // This *can* create groups outside of the area of this overmap. // As this function is called during generating the overmap, the @@ -4489,7 +4507,7 @@ shared_ptr_fast overmap::find_npc( const character_id &id ) const return nullptr; } -cata::optional overmap::find_camp( const point &p ) +cata::optional overmap::find_camp( const point_abs_omt &p ) { for( auto &v : camps ) { if( v.camp_omt_pos().xy() == p ) { @@ -4499,7 +4517,7 @@ cata::optional overmap::find_camp( const point &p ) return cata::nullopt; } -bool overmap::is_omt_generated( const tripoint &loc ) const +bool overmap::is_omt_generated( const tripoint_om_omt &loc ) const { if( !inbounds( loc ) ) { return false; @@ -4507,10 +4525,11 @@ bool overmap::is_omt_generated( const tripoint &loc ) const // Location is local to this overmap, but we need global submap coordinates // for the mapbuffer lookup. - tripoint global_sm_loc = omt_to_sm_copy( loc ) + om_to_sm_copy( tripoint( pos(), - loc.z ) ); + tripoint_abs_sm global_sm_loc = + project_to( project_combine( pos(), loc ) ); - const bool is_generated = MAPBUFFER.lookup_submap( global_sm_loc ) != nullptr; + // TODO: fix point types + const bool is_generated = MAPBUFFER.lookup_submap( global_sm_loc.raw() ) != nullptr; return is_generated; } @@ -4554,7 +4573,7 @@ std::string enum_to_string( ot_match_type data ) } } // namespace io -constexpr tripoint overmap::invalid_tripoint; +constexpr tripoint_abs_omt overmap::invalid_tripoint; std::string oter_no_dir( const oter_id &oter ) { diff --git a/src/overmap.h b/src/overmap.h index 1277b2bb806fa..51f2e84d734da 100644 --- a/src/overmap.h +++ b/src/overmap.h @@ -16,6 +16,7 @@ #include #include "basecamp.h" +#include "coordinates.h" #include "enums.h" #include "game_constants.h" #include "memory_fast.h" @@ -46,32 +47,32 @@ struct path; struct city { // location of the city (in overmap terrain coordinates) - point pos; + point_om_omt pos; int size; std::string name; - city( const point &P = point_zero, int S = -1 ); + city( const point_om_omt &P = point_om_omt(), int S = -1 ); operator bool() const { return size >= 0; } - int get_distance_from( const tripoint &p ) const; + int get_distance_from( const tripoint_om_omt &p ) const; }; struct om_note { std::string text; - point p; + point_om_omt p; bool dangerous = false; int danger_radius = 0; }; struct om_map_extra { string_id id; - point p; + point_om_omt p; }; struct om_vehicle { - point p; // overmap coordinates of tracked vehicle + point_om_omt p; // overmap coordinates of tracked vehicle std::string name; }; @@ -87,12 +88,12 @@ static constexpr int RADIO_MAX_STRENGTH = 200; struct radio_tower { // local (to the containing overmap) submap coordinates - point pos; + point_om_sm pos; int strength; radio_type type; std::string message; int frequency; - radio_tower( const point &p, int S = -1, const std::string &M = "", + radio_tower( const point_om_sm &p, int S = -1, const std::string &M = "", radio_type T = radio_type::MESSAGE_BROADCAST ) : pos( p ), strength( S ), type( T ), message( M ) { frequency = rng( 0, INT_MAX ); @@ -108,7 +109,7 @@ struct map_layer { }; struct om_special_sectors { - std::vector sectors; + std::vector sectors; int sector_width; }; @@ -122,8 +123,9 @@ struct overmap_special_placement { class overmap_special_batch { public: - overmap_special_batch( const point &origin ) : origin_overmap( origin ) {} - overmap_special_batch( const point &origin, const std::vector &specials ) : + overmap_special_batch( const point_abs_om &origin ) : origin_overmap( origin ) {} + overmap_special_batch( const point_abs_om &origin, + const std::vector &specials ) : origin_overmap( origin ) { std::transform( specials.begin(), specials.end(), std::back_inserter( placements ), []( const overmap_special * elem ) { @@ -147,13 +149,13 @@ class overmap_special_batch return placements.empty(); } - point get_origin() const { + point_abs_om get_origin() const { return origin_overmap; } private: std::vector placements; - point origin_overmap; + point_abs_om origin_overmap; }; static const std::map oter_flags_map = { @@ -198,7 +200,7 @@ class overmap public: overmap( const overmap & ) = default; overmap( overmap && ) = default; - overmap( const point &p ); + overmap( const point_abs_om &p ); ~overmap(); overmap &operator=( const overmap & ) = default; @@ -209,7 +211,7 @@ class overmap void populate( overmap_special_batch &enabled_specials ); void populate(); - const point &pos() const { + const point_abs_om &pos() const { return loc; } @@ -220,9 +222,9 @@ class overmap * chosen place on the overmap with the specific overmap terrain. * Returns @ref invalid_tripoint if no suitable place has been found. */ - tripoint find_random_omt( const std::pair &target ) const; - tripoint find_random_omt( const std::string &omt_base_type, - ot_match_type match_type = ot_match_type::type ) const { + tripoint_om_omt find_random_omt( const std::pair &target ) const; + tripoint_om_omt find_random_omt( const std::string &omt_base_type, + ot_match_type match_type = ot_match_type::type ) const { return find_random_omt( std::make_pair( omt_base_type, match_type ) ); } /** @@ -231,73 +233,73 @@ class overmap * @returns A vector of terrain coordinates (absolute overmap terrain * coordinates), or empty vector if no matching terrain is found. */ - std::vector find_terrain( const std::string &term, int zlevel ); - - void ter_set( const tripoint &p, const oter_id &id ); - const oter_id &ter( const tripoint &p ) const; - bool &seen( const tripoint &p ); - bool seen( const tripoint &p ) const; - bool &explored( const tripoint &p ); - bool is_explored( const tripoint &p ) const; - - bool has_note( const tripoint &p ) const; - bool is_marked_dangerous( const tripoint &p ) const; - const std::string ¬e( const tripoint &p ) const; - void add_note( const tripoint &p, std::string message ); - void delete_note( const tripoint &p ); - void mark_note_dangerous( const tripoint &p, int radius, bool is_dangerous ); - - bool has_extra( const tripoint &p ) const; - const string_id &extra( const tripoint &p ) const; - void add_extra( const tripoint &p, const string_id &id ); - void delete_extra( const tripoint &p ); + std::vector find_terrain( const std::string &term, int zlevel ); + + void ter_set( const tripoint_om_omt &p, const oter_id &id ); + const oter_id &ter( const tripoint_om_omt &p ) const; + bool &seen( const tripoint_om_omt &p ); + bool seen( const tripoint_om_omt &p ) const; + bool &explored( const tripoint_om_omt &p ); + bool is_explored( const tripoint_om_omt &p ) const; + + bool has_note( const tripoint_om_omt &p ) const; + bool is_marked_dangerous( const tripoint_om_omt &p ) const; + const std::string ¬e( const tripoint_om_omt &p ) const; + void add_note( const tripoint_om_omt &p, std::string message ); + void delete_note( const tripoint_om_omt &p ); + void mark_note_dangerous( const tripoint_om_omt &p, int radius, bool is_dangerous ); + + bool has_extra( const tripoint_om_omt &p ) const; + const string_id &extra( const tripoint_om_omt &p ) const; + void add_extra( const tripoint_om_omt &p, const string_id &id ); + void delete_extra( const tripoint_om_omt &p ); /** * Getter for overmap scents. * @returns a reference to a scent_trace from the requested location. */ - const scent_trace &scent_at( const tripoint &loc ) const; + const scent_trace &scent_at( const tripoint_abs_omt &loc ) const; /** * Setter for overmap scents, stores the provided scent at the provided location. */ - void set_scent( const tripoint &loc, const scent_trace &new_scent ); + void set_scent( const tripoint_abs_omt &loc, const scent_trace &new_scent ); /** * @returns Whether @param p is within desired bounds of the overmap * @param clearance Minimal distance from the edges of the overmap */ - static bool inbounds( const tripoint &p, int clearance = 0 ); - static bool inbounds( const point &p, int clearance = 0 ) { - return inbounds( tripoint( p, 0 ), clearance ); + static bool inbounds( const tripoint_om_omt &p, int clearance = 0 ); + static bool inbounds( const point_om_omt &p, int clearance = 0 ) { + return inbounds( tripoint_om_omt( p, 0 ), clearance ); } /** * Dummy value, used to indicate that a point returned by a function is invalid. */ - static constexpr tripoint invalid_tripoint = tripoint_min; + static constexpr tripoint_abs_omt invalid_tripoint{ tripoint_min }; /** * Return a vector containing the absolute coordinates of * every matching note on the current z level of the current overmap. * @returns A vector of note coordinates (absolute overmap terrain * coordinates), or empty vector if no matching notes are found. */ - std::vector find_notes( int z, const std::string &text ); + std::vector find_notes( int z, const std::string &text ); /** * Return a vector containing the absolute coordinates of * every matching map extra on the current z level of the current overmap. * @returns A vector of map extra coordinates (absolute overmap terrain * coordinates), or empty vector if no matching map extras are found. */ - std::vector find_extras( int z, const std::string &text ); + std::vector find_extras( int z, const std::string &text ); /** * Returns whether or not the location has been generated (e.g. mapgen has run). * @param loc Location to check. * @returns True if param @loc has been generated. */ - bool is_omt_generated( const tripoint &loc ) const; + bool is_omt_generated( const tripoint_om_omt &loc ) const; /** Returns the (0, 0) corner of the overmap in the global coordinates. */ - point global_base_point() const; + point_abs_omt global_base_point() const; // TODO: Should depend on coordinates const regional_settings &get_settings() const { @@ -308,22 +310,22 @@ class overmap void clear_overmap_special_placements(); void clear_cities(); void clear_connections_out(); - void place_special_forced( const overmap_special_id &special_id, const tripoint &p, + void place_special_forced( const overmap_special_id &special_id, const tripoint_om_omt &p, om_direction::type dir ); private: - std::multimap zg; + std::multimap zg; public: /** Unit test enablers to check if a given mongroup is present. */ bool mongroup_check( const mongroup &candidate ) const; - bool monster_check( const std::pair &candidate ) const; + bool monster_check( const std::pair &candidate ) const; // TODO: make private std::vector radios; std::map vehicles; std::vector camps; std::vector cities; - std::map, std::vector> connections_out; - cata::optional find_camp( const point &p ); + std::map, std::vector> connections_out; + cata::optional find_camp( const point_abs_omt &p ); /// Adds the npc to the contained list of npcs ( @ref npcs ). void insert_npc( const shared_ptr_fast &who ); /// Removes the npc and returns it ( or returns nullptr if not found ). @@ -347,15 +349,15 @@ class overmap std::vector> npcs; bool nullbool = false; - point loc = point_zero; + point_abs_om loc; std::array layer; - std::unordered_map scents; + std::unordered_map scents; // Records the locations where a given overmap special was placed, which // can be used after placement to lookup whether a given location was created // as part of a special. - std::unordered_map overmap_special_placements; + std::unordered_map overmap_special_placements; regional_settings settings; @@ -373,7 +375,7 @@ class overmap * (adding it to the creature tracker and putting it onto the map). * This stores each submap worth of monsters in a different bucket of the multimap. */ - std::unordered_multimap monster_map; + std::unordered_multimap monster_map; // parse data in an opened overmap file void unserialize( std::istream &fin ); @@ -390,19 +392,20 @@ class overmap bool generate_sub( int z ); bool generate_over( int z ); // Check and put bridgeheads - void generate_bridgeheads( const std::vector &bridge_points ); + void generate_bridgeheads( const std::vector &bridge_points ); - const city &get_nearest_city( const tripoint &p ) const; + const city &get_nearest_city( const tripoint_om_omt &p ) const; - void signal_hordes( const tripoint &p, int sig_power ); + void signal_hordes( const tripoint_rel_sm &p, int sig_power ); void process_mongroups(); void move_hordes(); static bool obsolete_terrain( const std::string &ter ); - void convert_terrain( const std::unordered_map &needs_conversion ); + void convert_terrain( + const std::unordered_map &needs_conversion ); // Overall terrain - void place_river( point pa, point pb ); + void place_river( point_om_omt pa, point_om_omt pb ); void place_forests(); void place_lakes(); void place_rivers( const overmap *north, const overmap *east, const overmap *south, @@ -421,48 +424,52 @@ class overmap overmap_special_id pick_random_building_to_place( int town_dist ) const; void place_cities(); - void place_building( const tripoint &p, om_direction::type dir, const city &town ); + void place_building( const tripoint_om_omt &p, om_direction::type dir, const city &town ); - void build_city_street( const overmap_connection &connection, const point &p, int cs, + void build_city_street( const overmap_connection &connection, const point_om_omt &p, int cs, om_direction::type dir, const city &town, int block_width = 2 ); - bool build_lab( const tripoint &p, int s, std::vector *lab_train_points, + bool build_lab( const tripoint_om_omt &p, int s, std::vector *lab_train_points, const std::string &prefix, int train_odds ); - void build_anthill( const tripoint &p, int s ); - void build_tunnel( const tripoint &p, int s, om_direction::type dir ); - bool build_slimepit( const tripoint &origin, int s ); - void build_mine( const tripoint &origin, int s ); + void build_anthill( const tripoint_om_omt &p, int s ); + void build_tunnel( const tripoint_om_omt &p, int s, om_direction::type dir ); + bool build_slimepit( const tripoint_om_omt &origin, int s ); + void build_mine( const tripoint_om_omt &origin, int s ); // Connection laying - pf::path lay_out_connection( - const overmap_connection &connection, const point &source, - const point &dest, int z, bool must_be_unexplored ) const; - pf::path lay_out_street( const overmap_connection &connection, const point &source, - om_direction::type dir, size_t len ) const; + pf::path lay_out_connection( + const overmap_connection &connection, const point_om_omt &source, + const point_om_omt &dest, int z, bool must_be_unexplored ) const; + pf::path lay_out_street( + const overmap_connection &connection, const point_om_omt &source, + om_direction::type dir, size_t len ) const; void build_connection( - const overmap_connection &connection, const pf::path &path, int z, + const overmap_connection &connection, const pf::path &path, int z, const om_direction::type &initial_dir = om_direction::type::invalid ); - void build_connection( const point &source, const point &dest, int z, + void build_connection( const point_om_omt &source, const point_om_omt &dest, int z, const overmap_connection &connection, bool must_be_unexplored, const om_direction::type &initial_dir = om_direction::type::invalid ); - void connect_closest_points( const std::vector &points, int z, + void connect_closest_points( const std::vector &points, int z, const overmap_connection &connection ); // Polishing - bool check_ot( const std::string &otype, ot_match_type match_type, const tripoint &p ) const; - bool check_overmap_special_type( const overmap_special_id &id, const tripoint &location ) const; - void chip_rock( const tripoint &p ); + bool check_ot( const std::string &otype, ot_match_type match_type, + const tripoint_om_omt &p ) const; + bool check_overmap_special_type( const overmap_special_id &id, + const tripoint_om_omt &location ) const; + void chip_rock( const tripoint_om_omt &p ); void polish_river(); - void good_river( const tripoint &p ); + void good_river( const tripoint_om_omt &p ); om_direction::type random_special_rotation( const overmap_special &special, - const tripoint &p, bool must_be_unexplored ) const; + const tripoint_om_omt &p, bool must_be_unexplored ) const; - bool can_place_special( const overmap_special &special, const tripoint &p, + bool can_place_special( const overmap_special &special, const tripoint_om_omt &p, om_direction::type dir, bool must_be_unexplored ) const; - void place_special( const overmap_special &special, const tripoint &p, om_direction::type dir, - const city &cit, bool must_be_unexplored, bool force ); + void place_special( + const overmap_special &special, const tripoint_om_omt &p, om_direction::type dir, + const city &cit, bool must_be_unexplored, bool force ); /** * Iterate over the overmap and place the quota of specials. * If the stated minimums are not reached, it will spawn a new nearby overmap @@ -485,8 +492,9 @@ class overmap * @param sector sector identifies the location where specials are being placed. * @param place_optional restricts attempting to place specials that have met their minimum count in the first pass. */ - bool place_special_attempt( overmap_special_batch &enabled_specials, - const point §or, int sector_width, bool place_optional, bool must_be_unexplored ); + bool place_special_attempt( + overmap_special_batch &enabled_specials, const point_om_omt §or, int sector_width, + bool place_optional, bool must_be_unexplored ); void place_mongroups(); void place_radios(); diff --git a/src/overmap_noise.cpp b/src/overmap_noise.cpp index fd4c7f976088c..b8da54253a534 100644 --- a/src/overmap_noise.cpp +++ b/src/overmap_noise.cpp @@ -7,30 +7,30 @@ namespace om_noise { -float om_noise_layer_forest::noise_at( const point &local_omt_pos ) const +float om_noise_layer_forest::noise_at( const point_om_omt &local_omt_pos ) const { - const point p = global_omt_pos( local_omt_pos ); - float r = scaled_octave_noise_3d( 8, 0.5, 0.03, 0, 1, p.x, p.y, get_seed() ); + const point_abs_omt p = global_omt_pos( local_omt_pos ); + float r = scaled_octave_noise_3d( 8, 0.5, 0.03, 0, 1, p.x(), p.y(), get_seed() ); r = std::pow( r, 2.0f ); - float d = scaled_octave_noise_3d( 12, 0.5, 0.07, 0, 1, p.x, p.y, get_seed() ); + float d = scaled_octave_noise_3d( 12, 0.5, 0.07, 0, 1, p.x(), p.y(), get_seed() ); d = std::pow( d, 3.0f ); return std::max( 0.0f, r - d * 0.5f ); } -float om_noise_layer_floodplain::noise_at( const point &local_omt_pos ) const +float om_noise_layer_floodplain::noise_at( const point_om_omt &local_omt_pos ) const { - const point p = global_omt_pos( local_omt_pos ); - float r = scaled_octave_noise_3d( 8, 0.5, 0.05, 0, 1, p.x, p.y, get_seed() ); + const point_abs_omt p = global_omt_pos( local_omt_pos ); + float r = scaled_octave_noise_3d( 8, 0.5, 0.05, 0, 1, p.x(), p.y(), get_seed() ); r = std::pow( r, 2.0f ); return r; } -float om_noise_layer_lake::noise_at( const point &local_omt_pos ) const +float om_noise_layer_lake::noise_at( const point_om_omt &local_omt_pos ) const { - const point p = global_omt_pos( local_omt_pos ); - float r = scaled_octave_noise_3d( 16, 0.5, 0.002, 0, 1, p.x, p.y, get_seed() ); + const point_abs_omt p = global_omt_pos( local_omt_pos ); + float r = scaled_octave_noise_3d( 16, 0.5, 0.002, 0, 1, p.x(), p.y(), get_seed() ); r = std::pow( r, 4.0f ); return r; } diff --git a/src/overmap_noise.h b/src/overmap_noise.h index efbb18fe812b0..6d022a78ec8b1 100644 --- a/src/overmap_noise.h +++ b/src/overmap_noise.h @@ -2,6 +2,7 @@ #ifndef CATA_SRC_OVERMAP_NOISE_H #define CATA_SRC_OVERMAP_NOISE_H +#include "coordinates.h" #include "game_constants.h" #include "point.h" @@ -19,7 +20,7 @@ class om_noise_layer * Noise value at the provided overmap terrain location. * @param omt_local point location in overmap terrain local coordinates. */ - virtual float noise_at( const point &omt_local ) const = 0; + virtual float noise_at( const point_om_omt &omt_local ) const = 0; virtual ~om_noise_layer() = default; protected: /** @@ -28,14 +29,14 @@ class om_noise_layer * @param global_base_point the (0, 0) corner of the overmap in global coordinates. * @param seed the seed to use for seeding the noise--conventionally the game's seed. */ - om_noise_layer( const point &global_base_point, const unsigned seed ) : + om_noise_layer( const point_abs_omt &global_base_point, const unsigned seed ) : om_global_base_point( global_base_point ), // Narrowing conversion into float, as the noise functions we use only accept floats. seed( seed % SIMPLEX_NOISE_RANDOM_SEED_LIMIT ) { } - point global_omt_pos( const point &local_omt_pos ) const { - return om_global_base_point + local_omt_pos; + point_abs_omt global_omt_pos( const point_om_omt &local_omt_pos ) const { + return om_global_base_point + local_omt_pos.raw(); } float get_seed() const { @@ -43,38 +44,38 @@ class om_noise_layer } private: - point om_global_base_point; + point_abs_omt om_global_base_point; float seed; }; class om_noise_layer_forest : public om_noise_layer { public: - om_noise_layer_forest( const point &global_base_point, unsigned seed ) + om_noise_layer_forest( const point_abs_omt &global_base_point, unsigned seed ) : om_noise_layer( global_base_point, seed ) { } - float noise_at( const point &local_omt_pos ) const override; + float noise_at( const point_om_omt &local_omt_pos ) const override; }; class om_noise_layer_floodplain : public om_noise_layer { public: - om_noise_layer_floodplain( const point &global_base_point, unsigned seed ) + om_noise_layer_floodplain( const point_abs_omt &global_base_point, unsigned seed ) : om_noise_layer( global_base_point, seed ) { } - float noise_at( const point &local_omt_pos ) const override; + float noise_at( const point_om_omt &local_omt_pos ) const override; }; class om_noise_layer_lake : public om_noise_layer { public: - om_noise_layer_lake( const point &global_base_point, unsigned seed ) + om_noise_layer_lake( const point_abs_omt &global_base_point, unsigned seed ) : om_noise_layer( global_base_point, seed ) { } - float noise_at( const point &local_omt_pos ) const override; + float noise_at( const point_om_omt &local_omt_pos ) const override; }; } // namespace om_noise diff --git a/src/overmap_ui.cpp b/src/overmap_ui.cpp index 85311fe3a4fec..9ecefeafe8b63 100644 --- a/src/overmap_ui.cpp +++ b/src/overmap_ui.cpp @@ -24,6 +24,7 @@ #include "color.h" #include "compatibility.h" #include "coordinate_conversions.h" +#include "coordinates.h" #include "cursesdef.h" #include "enums.h" #include "game.h" @@ -127,14 +128,15 @@ static std::tuple get_note_display_info( const std::stri } static std::array, npm_width *npm_height> get_overmap_neighbors( - const tripoint ¤t ) + const tripoint_abs_omt ¤t ) { const bool has_debug_vision = get_player_character().has_trait( trait_DEBUG_NIGHTVISION ); std::array, npm_width *npm_height> map_around; int index = 0; const point shift( npm_width / 2, npm_height / 2 ); - for( const tripoint &dest : tripoint_range( current - shift, current + shift ) ) { + for( const tripoint_abs_omt &dest : + tripoint_range( current - shift, current + shift ) ) { nc_color ter_color = c_black; std::string ter_sym = " "; const bool see = has_debug_vision || overmap_buffer.seen( dest ); @@ -197,10 +199,10 @@ static void update_note_preview( const std::string ¬e, wnoutrefresh( *w_preview_map ); } -static weather_type_id get_weather_at_point( const tripoint &pos ) +static weather_type_id get_weather_at_point( const tripoint_abs_omt &pos ) { // Weather calculation is a bit expensive, so it's cached here. - static std::map weather_cache; + static std::map weather_cache; static time_point last_weather_display = calendar::before_time_starts; if( last_weather_display != calendar::turn ) { last_weather_display = calendar::turn; @@ -208,7 +210,8 @@ static weather_type_id get_weather_at_point( const tripoint &pos ) } auto iter = weather_cache.find( pos ); if( iter == weather_cache.end() ) { - const tripoint abs_ms_pos = sm_to_ms_copy( omt_to_sm_copy( pos ) ); + // TODO: fix point types + const tripoint abs_ms_pos = project_to( pos ).raw(); const auto &wgen = overmap_buffer.get_settings( pos ).weather; const auto weather = wgen.get_weather_conditions( abs_ms_pos, calendar::turn, g->get_seed() ); iter = weather_cache.insert( std::make_pair( pos, weather ) ).first; @@ -216,7 +219,8 @@ static weather_type_id get_weather_at_point( const tripoint &pos ) return iter->second; } -static bool get_scent_glyph( const tripoint &pos, nc_color &ter_color, std::string &ter_sym ) +static bool get_scent_glyph( const tripoint_abs_omt &pos, nc_color &ter_color, + std::string &ter_sym ) { auto possible_scent = overmap_buffer.scent_at( pos ); if( possible_scent.creation_time != calendar::before_time_starts ) { @@ -241,7 +245,7 @@ static bool get_scent_glyph( const tripoint &pos, nc_color &ter_color, std::stri return false; } -static void draw_city_labels( const catacurses::window &w, const tripoint ¢er ) +static void draw_city_labels( const catacurses::window &w, const tripoint_abs_omt ¢er ) { const int win_x_max = getmaxx( w ); const int win_y_max = getmaxy( w ); @@ -249,14 +253,16 @@ static void draw_city_labels( const catacurses::window &w, const tripoint ¢e const point screen_center_pos( win_x_max / 2, win_y_max / 2 ); - for( const auto &element : overmap_buffer.get_cities_near( omt_to_sm_copy( center ), sm_radius ) ) { - const point city_pos( sm_to_omt_copy( element.abs_sm_pos.xy() ) ); - const point screen_pos( city_pos - center.xy() + screen_center_pos ); + for( const auto &element : overmap_buffer.get_cities_near( + project_to( center ), sm_radius ) ) { + const point_abs_omt city_pos = + project_to( element.abs_sm_pos.xy() ); + const point_rel_omt screen_pos( city_pos - center.xy() + screen_center_pos ); const int text_width = utf8_width( element.city->name, true ); - const int text_x_min = screen_pos.x - text_width / 2; + const int text_x_min = screen_pos.x() - text_width / 2; const int text_x_max = text_x_min + text_width; - const int text_y = screen_pos.y; + const int text_y = screen_pos.y(); if( text_x_min < 0 || text_x_max > win_x_max || @@ -272,7 +278,7 @@ static void draw_city_labels( const catacurses::window &w, const tripoint ¢e continue; // right under the cursor. } - if( !overmap_buffer.seen( tripoint( city_pos, center.z ) ) ) { + if( !overmap_buffer.seen( tripoint_abs_omt( city_pos, center.z() ) ) ) { continue; // haven't seen it. } @@ -280,7 +286,7 @@ static void draw_city_labels( const catacurses::window &w, const tripoint ¢e } } -static void draw_camp_labels( const catacurses::window &w, const tripoint ¢er ) +static void draw_camp_labels( const catacurses::window &w, const tripoint_abs_omt ¢er ) { const int win_x_max = getmaxx( w ); const int win_y_max = getmaxy( w ); @@ -288,9 +294,10 @@ static void draw_camp_labels( const catacurses::window &w, const tripoint ¢e const point screen_center_pos( win_x_max / 2, win_y_max / 2 ); - for( const auto &element : overmap_buffer.get_camps_near( omt_to_sm_copy( center ), sm_radius ) ) { - const point camp_pos( element.camp->camp_omt_pos().xy() ); - const point screen_pos( camp_pos - center.xy() + screen_center_pos ); + for( const auto &element : overmap_buffer.get_camps_near( + project_to( center ), sm_radius ) ) { + const point_abs_omt camp_pos( element.camp->camp_omt_pos().xy() ); + const point screen_pos( ( camp_pos - center.xy() ).raw() + screen_center_pos ); const int text_width = utf8_width( element.camp->name, true ); const int text_x_min = screen_pos.x - text_width / 2; const int text_x_max = text_x_min + text_width; @@ -310,7 +317,7 @@ static void draw_camp_labels( const catacurses::window &w, const tripoint ¢e continue; // right under the cursor. } - if( !overmap_buffer.seen( tripoint( camp_pos, center.z ) ) ) { + if( !overmap_buffer.seen( tripoint_abs_omt( camp_pos, center.z() ) ) ) { continue; // haven't seen it. } @@ -331,11 +338,11 @@ class map_notes_callback : public uilist_callback std::tuple preview_windows; ui_adaptor ui; - point point_selected() { + point_abs_omt point_selected() { return _notes[_selected].first; } - tripoint note_location() { - return tripoint( point_selected(), _z ); + tripoint_abs_omt note_location() { + return tripoint_abs_omt( point_selected(), _z ); } public: map_notes_callback( const overmapbuffer::t_notes_vector ¬es, int z ) @@ -353,7 +360,7 @@ class map_notes_callback : public uilist_callback ui.on_redraw( [this]( const ui_adaptor & ) { if( _selected >= 0 && static_cast( _selected ) < _notes.size() ) { - const tripoint note_pos = note_location(); + const tripoint_abs_omt note_pos = note_location(); const auto map_around = get_overmap_neighbors( note_pos ); update_note_preview( overmap_buffer.note( note_pos ), map_around, preview_windows ); } else { @@ -409,9 +416,9 @@ class map_notes_callback : public uilist_callback } }; -static point draw_notes( const tripoint &origin ) +static point_abs_omt draw_notes( const tripoint_abs_omt &origin ) { - point result = point_min; + point_abs_omt result( point_min ); bool refresh = true; uilist nmenu; @@ -433,11 +440,11 @@ static point draw_notes( const tripoint &origin ) colorize( "ESCAPE", c_yellow ) ); int row = 0; - overmapbuffer::t_notes_vector notes = overmap_buffer.get_all_notes( origin.z ); + overmapbuffer::t_notes_vector notes = overmap_buffer.get_all_notes( origin.z() ); nmenu.title = string_format( _( "Map notes (%d)" ), notes.size() ); for( const auto &point_with_note : notes ) { - const point p = point_with_note.first; - if( p.x == origin.x && p.y == origin.y ) { + const point_abs_omt p = point_with_note.first; + if( p == origin.xy() ) { nmenu.selected = row; } const std::string ¬e = point_with_note.second; @@ -445,25 +452,28 @@ static point draw_notes( const tripoint &origin ) const nc_color note_color = std::get<1>( om_symbol ); const std::string note_symbol = std::string( 1, std::get<0>( om_symbol ) ); const std::string note_text = note.substr( std::get<2>( om_symbol ), std::string::npos ); - point p_omt( p ); - const point p_player = get_player_character().global_omt_location().xy(); + point_abs_omt p_omt( p ); + const point_abs_omt p_player = get_player_character().global_omt_location().xy(); const int distance_player = rl_dist( p_player, p_omt ); - const point sm_pos = omt_to_sm_copy( p_omt ); - const point p_om = omt_to_om_remain( p_omt ); + const point_abs_sm sm_pos = project_to( p_omt ); + const point_abs_om p_om = project_to( p_omt ); const std::string location_desc = - overmap_buffer.get_description_at( tripoint( sm_pos, origin.z ) ); - const bool is_dangerous = overmap_buffer.is_marked_dangerous( tripoint( p, origin.z ) ); - nmenu.addentry_desc( string_format( _( "[%s] %s" ), colorize( note_symbol, note_color ), - note_text ), - string_format( - _( "LEVEL %i, %d'%d, %d'%d: %s (Distance: %d) %s" ), - origin.z, p_om.x, p_omt.x, p_om.y, p_omt.y, location_desc, distance_player, - is_dangerous ? "DANGEROUS AREA!" : "" ) ); - nmenu.entries[row].ctxt = string_format( - _( "Distance: %d" ), distance_player ); + overmap_buffer.get_description_at( tripoint_abs_sm( sm_pos, origin.z() ) ); + const bool is_dangerous = + overmap_buffer.is_marked_dangerous( tripoint_abs_omt( p, origin.z() ) ); + nmenu.addentry_desc( + string_format( _( "[%s] %s" ), colorize( note_symbol, note_color ), note_text ), + string_format( + _( "LEVEL %i, %d'%d, %d'%d: %s " + "(Distance: %d) %s" ), + origin.z(), p_om.x(), p_omt.x(), p_om.y(), p_omt.y(), location_desc, + distance_player, is_dangerous ? "DANGEROUS AREA!" : "" ) ); + nmenu.entries[row].ctxt = + string_format( _( "Distance: %d" ), + distance_player ); row++; } - map_notes_callback cb( notes, origin.z ); + map_notes_callback cb( notes, origin.z() ); nmenu.callback = &cb; nmenu.query(); if( nmenu.ret == UILIST_MAP_NOTE_DELETED || nmenu.ret == UILIST_MAP_NOTE_EDITED ) { @@ -476,19 +486,21 @@ static point draw_notes( const tripoint &origin ) return result; } -void draw( const catacurses::window &w, const catacurses::window &wbar, const tripoint ¢er, - const tripoint &orig, bool blink, bool show_explored, bool fast_scroll, input_context *inp_ctxt, - const draw_data_t &data ) +void draw( + const catacurses::window &w, const catacurses::window &wbar, const tripoint_abs_omt ¢er, + const tripoint_abs_omt &orig, bool blink, bool show_explored, bool fast_scroll, + input_context *inp_ctxt, const draw_data_t &data ) { const int om_map_width = OVERMAP_WINDOW_WIDTH; const int om_map_height = OVERMAP_WINDOW_HEIGHT; const int om_half_width = om_map_width / 2; const int om_half_height = om_map_height / 2; - const bool viewing_weather = ( ( data.debug_weather || data.visible_weather ) && center.z == 10 ); + const bool viewing_weather = + ( ( data.debug_weather || data.visible_weather ) && center.z() == 10 ); avatar &player_character = get_avatar(); // Target of current mission - const tripoint target = player_character.get_active_mission_target(); + const tripoint_abs_omt target = player_character.get_active_mission_target(); const bool has_target = target != overmap::invalid_tripoint; // seen status & terrain of center position bool csee = false; @@ -505,13 +517,15 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr const oter_id forest = oter_str_id( "forest" ).id(); std::string sZoneName; - tripoint tripointZone = tripoint( -1, -1, -1 ); + tripoint_abs_omt tripointZone( -1, -1, -1 ); const auto &zones = zone_manager::get_manager(); if( data.iZoneIndex != -1 ) { const auto &zone = zones.get_zones()[data.iZoneIndex].get(); sZoneName = zone.get_name(); - tripointZone = ms_to_omt_copy( zone.get_center_point() ); + // TODO: fix point types + tripointZone = project_to( + tripoint_abs_ms( zone.get_center_point() ) ); } // If we're debugging monster groups, find the monster group we've selected @@ -533,7 +547,7 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr std::array, cache_size> cache {{}}; size_t cache_next = 0; - const auto set_color_and_symbol = [&]( const oter_id & cur_ter, const tripoint & omp, + const auto set_color_and_symbol = [&]( const oter_id & cur_ter, const tripoint_abs_omt & omp, std::string & ter_sym, nc_color & ter_color ) { // First see if we have the oter_t cached oter_t const *info = nullptr; @@ -557,27 +571,28 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr } }; - const tripoint corner = center - point( om_half_width, om_half_height ); + const tripoint_abs_omt corner = center - point( om_half_width, om_half_height ); // For use with place_special: cache the color and symbol of each submap // and record the bounds to optimize lookups below - std::unordered_map> special_cache; + std::unordered_map> special_cache; - point s_begin; - point s_end; + point_rel_omt s_begin; + point_rel_omt s_end; if( blink && uistate.place_special ) { for( const auto &s_ter : uistate.place_special->terrains ) { if( s_ter.p.z == 0 ) { - const point rp = om_direction::rotate( s_ter.p.xy(), uistate.omedit_rotation ); + // TODO: fix point types + const point_rel_omt rp( om_direction::rotate( s_ter.p.xy(), uistate.omedit_rotation ) ); const oter_id oter = s_ter.terrain->get_rotated( uistate.omedit_rotation ); special_cache.insert( std::make_pair( rp, std::make_pair( oter->get_symbol(), oter->get_color() ) ) ); - s_begin.x = std::min( s_begin.x, rp.x ); - s_begin.y = std::min( s_begin.y, rp.y ); - s_end.x = std::max( s_end.x, rp.x ); - s_end.y = std::max( s_end.y, rp.y ); + s_begin.x() = std::min( s_begin.x(), rp.x() ); + s_begin.y() = std::min( s_begin.y(), rp.y() ); + s_end.x() = std::max( s_end.x(), rp.x() ); + s_end.y() = std::max( s_end.y(), rp.y() ); } } } @@ -587,18 +602,18 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr nc_color color; size_t count = 0; }; - std::vector path_route; - std::vector player_path_route; - std::unordered_map npc_color; + std::vector path_route; + std::vector player_path_route; + std::unordered_map npc_color; if( blink ) { // get seen NPCs const auto &npcs = overmap_buffer.get_npcs_near_player( sight_points ); for( const auto &np : npcs ) { - if( np->posz() != center.z ) { + if( np->posz() != center.z() ) { continue; } - const tripoint pos = np->global_omt_location(); + const tripoint_abs_omt pos = np->global_omt_location(); if( has_debug_vision || overmap_buffer.seen( pos ) ) { auto iter = npc_color.find( pos ); nc_color np_color = np->basic_symbol_color(); @@ -631,19 +646,19 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr npc *npc_to_add = elem.get(); if( npc_to_add->mission == NPC_MISSION_TRAVELLING && !npc_to_add->omt_path.empty() ) { for( auto &elem : npc_to_add->omt_path ) { - path_route.push_back( tripoint( elem.xy(), npc_to_add->posz() ) ); + path_route.push_back( tripoint_abs_omt( elem.xy(), npc_to_add->posz() ) ); } } } for( auto &elem : player_character.omt_path ) { - tripoint tri_to_add = tripoint( elem.xy(), player_character.posz() ); + tripoint_abs_omt tri_to_add( elem.xy(), player_character.posz() ); player_path_route.push_back( tri_to_add ); } for( const auto &np : followers ) { - if( np->posz() != center.z ) { + if( np->posz() != center.z() ) { continue; } - const tripoint pos = np->global_omt_location(); + const tripoint_abs_omt pos = np->global_omt_location(); auto iter = npc_color.find( pos ); nc_color np_color = np->basic_symbol_color(); if( iter == npc_color.end() ) { @@ -660,7 +675,7 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr for( int i = 0; i < om_map_width; ++i ) { for( int j = 0; j < om_map_height; ++j ) { - const tripoint omp = corner + point( i, j ); + const tripoint_abs_omt omp = corner + point( i, j ); oter_id cur_ter = oter_str_id::NULL_ID(); nc_color ter_color = c_black; @@ -677,8 +692,8 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr const bool los_sky = player_character.overmap_los( omp, sight_points * 2 ); int mycount = std::count( path_route.begin(), path_route.end(), omp ); bool player_path_count = false; - std::vector::iterator it; - it = std::find( player_path_route.begin(), player_path_route.end(), omp ); + std::vector::iterator it = + std::find( player_path_route.begin(), player_path_route.end(), omp ); if( it != player_path_route.end() ) { player_path_count = true; } @@ -696,9 +711,9 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr // Mission target, display always, player should know where it is anyway. ter_color = c_red; ter_sym = "*"; - if( target.z > center.z ) { + if( target.z() > center.z() ) { ter_sym = "^"; - } else if( target.z < center.z ) { + } else if( target.z() < center.z() ) { ter_sym = "v"; } } else if( blink && uistate.overmap_show_map_notes && overmap_buffer.has_note( omp ) ) { @@ -747,9 +762,11 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr // Check if this tile is the target of the currently selected group // Convert to position within overmap - point omp_in_om( omp.xy() ); - omt_to_om_remain( omp_in_om ); - if( mgroup && sm_to_omt_copy( mgroup->target.xy() ) == omp_in_om ) { + point_abs_om abs_om; + point_om_omt omp_in_om; + std::tie( abs_om, omp_in_om ) = project_remain( omp.xy() ); + if( mgroup && project_to( mgroup->target.xy() ) == + omp_in_om ) { ter_color = c_red; ter_sym = "x"; } else { @@ -785,9 +802,9 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr ter_color = uistate.place_terrain->get_color(); ter_sym = uistate.place_terrain->get_symbol(); } else if( blink && uistate.place_special ) { - const point from_center = omp.xy() - center.xy(); - if( from_center.x >= s_begin.x && from_center.x <= s_end.x && - from_center.y >= s_begin.y && from_center.y <= s_end.y ) { + const point_rel_omt from_center = omp.xy() - center.xy(); + if( from_center.x() >= s_begin.x() && from_center.x() <= s_end.x() && + from_center.y() >= s_begin.y() && from_center.y() <= s_end.y() ) { const auto sm = special_cache.find( from_center ); if( sm != special_cache.end() ) { @@ -797,8 +814,8 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr } } // Highlight areas that already have been generated - if( MAPBUFFER.lookup_submap( - omt_to_sm_copy( omp ) ) ) { + // TODO: fix point types + if( MAPBUFFER.lookup_submap( project_to( omp ).raw() ) ) { ter_color = red_background( ter_color ); } } @@ -813,16 +830,17 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr } } - if( center.z == 0 && uistate.overmap_show_city_labels ) { + if( center.z() == 0 && uistate.overmap_show_city_labels ) { draw_city_labels( w, center ); draw_camp_labels( w, center ); } - half_open_rectangle screen_bounds( corner.xy(), - corner.xy() + point( om_map_width, om_map_height ) ); + // TODO: fix point types + half_open_rectangle screen_bounds( corner.xy().raw(), + corner.xy().raw() + point( om_map_width, om_map_height ) ); - if( has_target && blink && !screen_bounds.contains( target.xy() ) ) { - point marker = clamp( target.xy(), screen_bounds ) - corner.xy(); + if( has_target && blink && !screen_bounds.contains( target.xy().raw() ) ) { + point marker = clamp( target.xy().raw(), screen_bounds ) - corner.xy().raw(); std::string marker_sym = " "; switch( direction_from( center.xy(), target.xy() ) ) { @@ -953,13 +971,13 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr mvwprintz( wbar, point( 3, line_number++ ), c_blue, " Interest: %d", mgroup->interest ); mvwprintz( wbar, point( 3, line_number ), - c_blue, " Target: %d, %d", mgroup->target.x, mgroup->target.y ); + c_blue, " Target: %s", mgroup->target.to_string() ); mvwprintz( wbar, point( 3, line_number++ ), c_red, "x" ); } } else { const auto &ter = ccur_ter.obj(); - const auto sm_pos = omt_to_sm_copy( center ); + const auto sm_pos = project_to( center ); // NOLINTNEXTLINE(cata-use-named-point-constants) mvwputch( wbar, point( 1, 1 ), ter.get_color(), ter.get_symbol() ); @@ -994,7 +1012,7 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr mvwprintz( wbar, point( 1, ++lines ), c_white, _( "Distance to active mission:" ) ); mvwprintz( wbar, point( 1, ++lines ), c_white, _( "%d tiles" ), distance ); - const int above_below = target.z - orig.z; + const int above_below = target.z() - orig.z(); std::string msg; if( above_below > 0 ) { msg = _( "Above us" ); @@ -1055,10 +1073,12 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr print_hint( "QUIT" ); } - point omt = center.xy(); - const point om = omt_to_om_remain( omt ); + point_abs_omt abs_omt = center.xy(); + point_abs_om om; + point_om_omt omt; + std::tie( om, omt ) = project_remain( abs_omt ); mvwprintz( wbar, point( 1, getmaxy( wbar ) - 1 ), c_red, - _( "LEVEL %i, %d'%d, %d'%d" ), center.z, om.x, omt.x, om.y, omt.y ); + _( "LEVEL %i, %d'%d, %d'%d" ), center.z(), om.x(), omt.x(), om.y(), omt.y() ); // draw nice crosshair around the cursor if( blink && !uistate.place_terrain && !uistate.place_special ) { @@ -1073,7 +1093,7 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr wnoutrefresh( w ); } -void create_note( const tripoint &curs ) +void create_note( const tripoint_abs_omt &curs ) { std::string color_notes = _( "Color codes: " ); for( const std::pair &color_pair : get_note_color_names() ) { @@ -1156,7 +1176,7 @@ void create_note( const tripoint &curs ) } // if false, search yielded no results -static bool search( const ui_adaptor &om_ui, tripoint &curs, const tripoint &orig ) +static bool search( const ui_adaptor &om_ui, tripoint_abs_omt &curs, const tripoint_abs_omt &orig ) { std::string term = string_input_popup() .title( _( "Search term:" ) ) @@ -1166,27 +1186,27 @@ static bool search( const ui_adaptor &om_ui, tripoint &curs, const tripoint &ori return false; } - std::vector locations; - std::vector overmap_checked; + std::vector locations; + std::vector overmap_checked; const int radius = OMAPX; // arbitrary - for( const tripoint &p : points_in_radius( curs, radius ) ) { + for( const tripoint_abs_omt &p : points_in_radius( curs, radius ) ) { overmap_with_local_coords om_loc = overmap_buffer.get_existing_om_global( p ); if( om_loc ) { - tripoint om_relative = om_loc.local; - point om_cache = omt_to_om_copy( p.xy() ); + tripoint_om_omt om_relative = om_loc.local; + point_abs_om om_cache = project_to( p.xy() ); if( std::find( overmap_checked.begin(), overmap_checked.end(), om_cache ) == overmap_checked.end() ) { overmap_checked.push_back( om_cache ); - std::vector notes = om_loc.om->find_notes( curs.z, term ); + std::vector notes = om_loc.om->find_notes( curs.z(), term ); locations.insert( locations.end(), notes.begin(), notes.end() ); } if( om_loc.om->seen( om_relative ) && match_include_exclude( om_loc.om->ter( om_relative )->get_name(), term ) ) { - locations.push_back( om_loc.om->global_base_point() + om_relative.xy() ); + locations.push_back( project_combine( om_loc.om->pos(), om_relative.xy() ) ); } } } @@ -1197,13 +1217,15 @@ static bool search( const ui_adaptor &om_ui, tripoint &curs, const tripoint &ori return false; } - std::sort( locations.begin(), locations.end(), [&]( const point & lhs, const point & rhs ) { - return trig_dist( curs, tripoint( lhs, curs.z ) ) < trig_dist( curs, tripoint( rhs, curs.z ) ); + std::sort( locations.begin(), locations.end(), + [&]( const point_abs_omt & lhs, const point_abs_omt & rhs ) { + return trig_dist( curs, tripoint_abs_omt( lhs, curs.z() ) ) < + trig_dist( curs, tripoint_abs_omt( rhs, curs.z() ) ); } ); int i = 0; //Navigate through results - const tripoint prev_curs = curs; + const tripoint_abs_omt prev_curs = curs; catacurses::window w_search; @@ -1235,8 +1257,8 @@ static bool search( const ui_adaptor &om_ui, tripoint &curs, const tripoint &ori mvwprintz( w_search, point( 1, 3 ), c_light_blue, _( "Direction:" ) ); mvwprintz( w_search, point( 14, 3 ), c_white, "%*d %s", - 5, static_cast( trig_dist( orig, tripoint( locations[i], orig.z ) ) ), - direction_name_short( direction_from( orig, tripoint( locations[i], orig.z ) ) ) + 5, static_cast( trig_dist( orig, tripoint_abs_omt( locations[i], orig.z() ) ) ), + direction_name_short( direction_from( orig, tripoint_abs_omt( locations[i], orig.z() ) ) ) ); mvwprintz( w_search, point( 1, 6 ), c_white, _( "'<-' '->' Cycle targets." ) ); @@ -1248,8 +1270,8 @@ static bool search( const ui_adaptor &om_ui, tripoint &curs, const tripoint &ori std::string action; do { - curs.x = locations[i].x; - curs.y = locations[i].y; + curs.x() = locations[i].x(); + curs.y() = locations[i].y(); om_ui.invalidate_ui(); ui_manager::redraw(); action = ctxt.handle_input( BLINK_SPEED ); @@ -1268,7 +1290,7 @@ static bool search( const ui_adaptor &om_ui, tripoint &curs, const tripoint &ori return true; } -static void place_ter_or_special( const ui_adaptor &om_ui, tripoint &curs, +static void place_ter_or_special( const ui_adaptor &om_ui, tripoint_abs_omt &curs, const std::string &om_action ) { uilist pmenu; @@ -1380,8 +1402,7 @@ static void place_ter_or_special( const ui_adaptor &om_ui, tripoint &curs, action = ctxt.handle_input( BLINK_SPEED ); if( const cata::optional vec = ctxt.get_direction( action ) ) { - curs.x += vec->x; - curs.y += vec->y; + curs += vec->xy(); } else if( action == "CONFIRM" ) { // Actually modify the overmap if( terrain ) { overmap_buffer.ter_set( curs, uistate.place_terrain->id.id() ); @@ -1389,7 +1410,8 @@ static void place_ter_or_special( const ui_adaptor &om_ui, tripoint &curs, } else { overmap_buffer.place_special( *uistate.place_special, curs, uistate.omedit_rotation, false, true ); for( const overmap_special_terrain &s_ter : uistate.place_special->terrains ) { - const tripoint pos = curs + om_direction::rotate( s_ter.p, uistate.omedit_rotation ); + const tripoint_abs_omt pos = + curs + om_direction::rotate( s_ter.p, uistate.omedit_rotation ); overmap_buffer.set_seen( pos, true ); } } @@ -1410,7 +1432,8 @@ static void place_ter_or_special( const ui_adaptor &om_ui, tripoint &curs, } } -static tripoint display( const tripoint &orig, const draw_data_t &data = draw_data_t() ) +static tripoint_abs_omt display( const tripoint_abs_omt &orig, + const draw_data_t &data = draw_data_t() ) { background_pane bg_pane; @@ -1434,11 +1457,11 @@ static tripoint display( const tripoint &orig, const draw_data_t &data = draw_da } ); ui.mark_resize(); - tripoint ret = overmap::invalid_tripoint; - tripoint curs( orig ); + tripoint_abs_omt ret = overmap::invalid_tripoint; + tripoint_abs_omt curs( orig ); - if( data.select != tripoint( -1, -1, -1 ) ) { - curs = tripoint( data.select ); + if( data.select != tripoint_abs_omt( -1, -1, -1 ) ) { + curs = data.select; } // Configure input context for navigating the map. input_context ictxt( "OVERMAP" ); @@ -1501,8 +1524,7 @@ static tripoint display( const tripoint &orig, const draw_data_t &data = draw_da #endif if( const cata::optional vec = ictxt.get_direction( action ) ) { int scroll_d = fast_scroll ? fast_scroll_offset : 1; - curs.x += vec->x * scroll_d; - curs.y += vec->y * scroll_d; + curs += vec->xy() * scroll_d; } else if( action == "MOUSE_MOVE" || action == "TIMEOUT" ) { tripoint edge_scroll = g->mouse_edge_scrolling_overmap( ictxt ); if( edge_scroll != tripoint_zero ) { @@ -1512,14 +1534,13 @@ static tripoint display( const tripoint &orig, const draw_data_t &data = draw_da curs += edge_scroll; } } else if( action == "SELECT" && ( mouse_pos = ictxt.get_coordinates( g->w_overmap ) ) ) { - curs.x += mouse_pos->x; - curs.y += mouse_pos->y; + curs += mouse_pos->xy(); } else if( action == "CENTER" ) { curs = orig; - } else if( action == "LEVEL_DOWN" && curs.z > -OVERMAP_DEPTH ) { - curs.z -= 1; - } else if( action == "LEVEL_UP" && curs.z < OVERMAP_HEIGHT ) { - curs.z += 1; + } else if( action == "LEVEL_DOWN" && curs.z() > -OVERMAP_DEPTH ) { + curs.z() -= 1; + } else if( action == "LEVEL_UP" && curs.z() < OVERMAP_HEIGHT ) { + curs.z() += 1; } else if( action == "CONFIRM" ) { ret = curs; } else if( action == "QUIT" ) { @@ -1531,10 +1552,10 @@ static tripoint display( const tripoint &orig, const draw_data_t &data = draw_da overmap_buffer.delete_note( curs ); } } else if( action == "LIST_NOTES" ) { - const point p = draw_notes( curs ); - if( p != point_min ) { - curs.x = p.x; - curs.y = p.y; + const point_abs_omt p = draw_notes( curs ); + if( p != point_abs_omt( point_min ) ) { + curs.x() = p.x(); + curs.y() = p.y(); } } else if( action == "CHOOSE_DESTINATION" ) { path_type ptype; @@ -1560,7 +1581,7 @@ static tripoint display( const tripoint &orig, const draw_data_t &data = draw_da ptype.amphibious = true; } } - const tripoint player_omt_pos = player_character.global_omt_location(); + const tripoint_abs_omt player_omt_pos = player_character.global_omt_location(); if( !player_character.omt_path.empty() && player_character.omt_path.front() == curs ) { std::string confirm_msg; if( player_character.weight_carried() > player_character.weight_capacity() ) { @@ -1659,8 +1680,8 @@ void ui::omap::display_weather() { overmap_ui::draw_data_t data; data.debug_weather = true; - tripoint pos = get_player_character().global_omt_location(); - pos.z = 10; + tripoint_abs_omt pos = get_player_character().global_omt_location(); + pos.z() = 10; overmap_ui::display( pos, data ); } @@ -1668,8 +1689,8 @@ void ui::omap::display_visible_weather() { overmap_ui::draw_data_t data; data.visible_weather = true; - tripoint pos = get_player_character().global_omt_location(); - pos.z = 10; + tripoint_abs_omt pos = get_player_character().global_omt_location(); + pos.z() = 10; overmap_ui::display( pos, data ); } @@ -1687,7 +1708,8 @@ void ui::omap::display_editor() overmap_ui::display( get_player_character().global_omt_location(), data ); } -void ui::omap::display_zones( const tripoint ¢er, const tripoint &select, const int iZoneIndex ) +void ui::omap::display_zones( const tripoint_abs_omt ¢er, const tripoint_abs_omt &select, + const int iZoneIndex ) { overmap_ui::draw_data_t data; data.select = select; @@ -1695,19 +1717,19 @@ void ui::omap::display_zones( const tripoint ¢er, const tripoint &select, co overmap_ui::display( center, data ); } -tripoint ui::omap::choose_point() +tripoint_abs_omt ui::omap::choose_point() { return overmap_ui::display( get_player_character().global_omt_location() ); } -tripoint ui::omap::choose_point( const tripoint &origin ) +tripoint_abs_omt ui::omap::choose_point( const tripoint_abs_omt &origin ) { return overmap_ui::display( origin ); } -tripoint ui::omap::choose_point( int z ) +tripoint_abs_omt ui::omap::choose_point( int z ) { - tripoint loc = get_player_character().global_omt_location(); - loc.z = z; + tripoint_abs_omt loc = get_player_character().global_omt_location(); + loc.z() = z; return overmap_ui::display( loc ); } diff --git a/src/overmap_ui.h b/src/overmap_ui.h index 19388a6ab2b52..400d38e90a47f 100644 --- a/src/overmap_ui.h +++ b/src/overmap_ui.h @@ -2,6 +2,7 @@ #ifndef CATA_SRC_OVERMAP_UI_H #define CATA_SRC_OVERMAP_UI_H +#include "coordinates.h" #include "point.h" namespace catacurses @@ -40,7 +41,8 @@ void display_scents(); /** * Display overmap like with @ref display() and display the given zone. */ -void display_zones( const tripoint ¢er, const tripoint &select, int iZoneIndex ); +void display_zones( const tripoint_abs_omt ¢er, const tripoint_abs_omt &select, + int iZoneIndex ); /** * Display overmap like with @ref display() and enable the overmap editor. */ @@ -52,20 +54,20 @@ void display_editor(); * @returns The absolute coordinates of the chosen point or * invalid_point if canceled with Escape (or similar key). */ -tripoint choose_point(); +tripoint_abs_omt choose_point(); /** * Same as above but start at z-level z instead of players * current z-level, x and y are taken from the players position. */ -tripoint choose_point( int z ); +tripoint_abs_omt choose_point( int z ); /** * Interactive point choosing; used as the map screen. * The map is initially centered on the @ref origin. * @returns The absolute coordinates of the chosen point or * invalid_point if canceled with Escape (or similar key). */ -tripoint choose_point( const tripoint &origin ); +tripoint_abs_omt choose_point( const tripoint_abs_omt &origin ); } // namespace omap @@ -86,13 +88,14 @@ struct draw_data_t { // draw scent traces. bool debug_scent = false; // draw zone location. - tripoint select = tripoint( -1, -1, -1 ); + tripoint_abs_omt select = tripoint_abs_omt( -1, -1, -1 ); int iZoneIndex = -1; }; -void draw( const catacurses::window &w, const catacurses::window &wbar, const tripoint ¢er, - const tripoint &orig, bool blink, bool show_explored, bool fast_scroll, input_context *inp_ctxt, - const draw_data_t &data ); -void create_note( const tripoint &curs ); +void draw( + const catacurses::window &w, const catacurses::window &wbar, const tripoint_abs_omt ¢er, + const tripoint_abs_omt &orig, bool blink, bool show_explored, bool fast_scroll, + input_context *inp_ctxt, const draw_data_t &data ); +void create_note( const tripoint_abs_omt &curs ); } // namespace overmap_ui #endif // CATA_SRC_OVERMAP_UI_H diff --git a/src/overmapbuffer.cpp b/src/overmapbuffer.cpp index bf79c3af809e8..acb72571b12f3 100644 --- a/src/overmapbuffer.cpp +++ b/src/overmapbuffer.cpp @@ -15,6 +15,7 @@ #include "color.h" #include "common_types.h" #include "coordinate_conversions.h" +#include "coordinates.h" #include "debug.h" #include "filesystem.h" #include "game.h" @@ -46,7 +47,7 @@ overmapbuffer::overmapbuffer() { } -const city_reference city_reference::invalid{ nullptr, tripoint(), -1 }; +const city_reference city_reference::invalid{ nullptr, tripoint_abs_sm(), -1 }; int city_reference::get_distance_from_bounds() const { @@ -60,17 +61,17 @@ int camp_reference::get_distance_from_bounds() const return distance - omt_to_sm_copy( 4 ); } -std::string overmapbuffer::terrain_filename( const point &p ) +std::string overmapbuffer::terrain_filename( const point_abs_om &p ) { - return string_format( "%s/o.%d.%d", PATH_INFO::world_base_save_path(), p.x, p.y ); + return string_format( "%s/o.%d.%d", PATH_INFO::world_base_save_path(), p.x(), p.y() ); } -std::string overmapbuffer::player_filename( const point &p ) +std::string overmapbuffer::player_filename( const point_abs_om &p ) { - return string_format( "%s.seen.%d.%d", PATH_INFO::player_base_save_path(), p.x, p.y ); + return string_format( "%s.seen.%d.%d", PATH_INFO::player_base_save_path(), p.x(), p.y() ); } -overmap &overmapbuffer::get( const point &p ) +overmap &overmapbuffer::get( const point_abs_om &p ) { if( last_requested_overmap != nullptr && last_requested_overmap->pos() == p ) { return *last_requested_overmap; @@ -93,7 +94,7 @@ overmap &overmapbuffer::get( const point &p ) return new_om; } -void overmapbuffer::create_custom_overmap( const point &p, overmap_special_batch &specials ) +void overmapbuffer::create_custom_overmap( const point_abs_om &p, overmap_special_batch &specials ) { if( last_requested_overmap != nullptr ) { auto om_iter = overmaps.find( p ); @@ -116,12 +117,15 @@ void overmapbuffer::fix_mongroups( overmap &new_overmap ) continue; } // Inside the bounds of the overmap? - if( mg.pos.x >= 0 && mg.pos.y >= 0 && mg.pos.x < OMAPX * 2 && mg.pos.y < OMAPY * 2 ) { + if( mg.pos.x() >= 0 && mg.pos.y() >= 0 && mg.pos.x() < OMAPX * 2 && + mg.pos.y() < OMAPY * 2 ) { ++it; continue; } - point smabs = mg.pos.xy() + om_to_sm_copy( new_overmap.pos() ); - point omp = sm_to_om_remain( smabs ); + point_abs_sm smabs = project_combine( new_overmap.pos(), mg.pos.xy() ); + point_abs_om omp; + point_om_sm sm_rem; + std::tie( omp, sm_rem ) = project_remain( smabs ); if( !has( omp ) ) { // Don't generate new overmaps, as this can be called from the // overmap-generating code. @@ -129,8 +133,7 @@ void overmapbuffer::fix_mongroups( overmap &new_overmap ) continue; } overmap &om = get( omp ); - mg.pos.x = smabs.x; - mg.pos.y = smabs.y; + mg.pos = tripoint_om_sm( sm_rem, mg.pos.z() ); om.add_mon_group( mg ); new_overmap.zg.erase( it++ ); } @@ -144,9 +147,9 @@ void overmapbuffer::fix_npcs( overmap &new_overmap ) decltype( overmap::npcs ) to_relocate; for( auto it = new_overmap.npcs.begin(); it != new_overmap.npcs.end(); ) { npc &np = **it; - const tripoint npc_omt_pos = np.global_omt_location(); - const point npc_om_pos = omt_to_om_copy( npc_omt_pos.xy() ); - const point &loc = new_overmap.pos(); + const tripoint_abs_omt npc_omt_pos = np.global_omt_location(); + const point_abs_om npc_om_pos = project_to( npc_omt_pos.xy() ); + const point_abs_om loc = new_overmap.pos(); if( npc_om_pos == loc ) { // Nothing to do ++it; @@ -163,20 +166,22 @@ void overmapbuffer::fix_npcs( overmap &new_overmap ) // involve loading new overmaps). for( auto &ptr : to_relocate ) { npc &np = *ptr; - const tripoint npc_omt_pos = np.global_omt_location(); - const point npc_om_pos = omt_to_om_copy( npc_omt_pos.xy() ); - const point &loc = new_overmap.pos(); + const tripoint_abs_omt npc_omt_pos = np.global_omt_location(); + const point_abs_om npc_om_pos = project_to( npc_omt_pos.xy() ); + const point_abs_om loc = new_overmap.pos(); if( !has( npc_om_pos ) ) { // This can't really happen without save editing // We have no sane option here, just place the NPC on the edge - debugmsg( "NPC %s is out of bounds, on non-generated overmap %d,%d", - np.name, loc.x, loc.y ); - point npc_sm = om_to_sm_copy( npc_om_pos ); - point min = om_to_sm_copy( loc ); - point max = om_to_sm_copy( loc + point_south_east ) - point_south_east; - npc_sm.x = clamp( npc_sm.x, min.x, max.x ); - npc_sm.y = clamp( npc_sm.y, min.y, max.y ); - np.spawn_at_sm( tripoint( npc_sm, np.posz() ) ); + debugmsg( "NPC %s is out of bounds, on non-generated overmap %s", + np.name, loc.to_string() ); + point_abs_sm npc_sm = project_to( npc_om_pos ); + point_abs_sm min = project_to( loc ); + point_abs_sm max = + project_to( loc + point_south_east ) - point_south_east; + npc_sm.x() = clamp( npc_sm.x(), min.x(), max.x() ); + npc_sm.y() = clamp( npc_sm.y(), min.y(), max.y() ); + // TODO: fix point types + np.spawn_at_sm( tripoint_abs_sm( npc_sm, np.posz() ).raw() ); new_overmap.npcs.push_back( ptr ); continue; } @@ -201,19 +206,19 @@ void overmapbuffer::clear() last_requested_overmap = nullptr; } -const regional_settings &overmapbuffer::get_settings( const tripoint &p ) +const regional_settings &overmapbuffer::get_settings( const tripoint_abs_omt &p ) { overmap *om = get_om_global( p ).om; return om->get_settings(); } -void overmapbuffer::add_note( const tripoint &p, const std::string &message ) +void overmapbuffer::add_note( const tripoint_abs_omt &p, const std::string &message ) { overmap_with_local_coords om_loc = get_om_global( p ); om_loc.om->add_note( om_loc.local, message ); } -void overmapbuffer::delete_note( const tripoint &p ) +void overmapbuffer::delete_note( const tripoint_abs_omt &p ) { if( has_note( p ) ) { overmap_with_local_coords om_loc = get_om_global( p ); @@ -221,7 +226,7 @@ void overmapbuffer::delete_note( const tripoint &p ) } } -void overmapbuffer::mark_note_dangerous( const tripoint &p, int radius, bool is_dangerous ) +void overmapbuffer::mark_note_dangerous( const tripoint_abs_omt &p, int radius, bool is_dangerous ) { if( has_note( p ) ) { overmap_with_local_coords om_loc = get_om_global( p ); @@ -229,13 +234,13 @@ void overmapbuffer::mark_note_dangerous( const tripoint &p, int radius, bool is_ } } -void overmapbuffer::add_extra( const tripoint &p, const string_id &id ) +void overmapbuffer::add_extra( const tripoint_abs_omt &p, const string_id &id ) { overmap_with_local_coords om_loc = get_om_global( p ); om_loc.om->add_extra( om_loc.local, id ); } -void overmapbuffer::delete_extra( const tripoint &p ) +void overmapbuffer::delete_extra( const tripoint_abs_omt &p ) { if( has_extra( p ) ) { overmap_with_local_coords om_loc = get_om_global( p ); @@ -243,7 +248,7 @@ void overmapbuffer::delete_extra( const tripoint &p ) } } -overmap *overmapbuffer::get_existing( const point &p ) +overmap *overmapbuffer::get_existing( const point_abs_om &p ) { if( last_requested_overmap && last_requested_overmap->pos() == p ) { return last_requested_overmap; @@ -272,46 +277,48 @@ overmap *overmapbuffer::get_existing( const point &p ) return nullptr; } -bool overmapbuffer::has( const point &p ) +bool overmapbuffer::has( const point_abs_om &p ) { return get_existing( p ) != nullptr; } overmap_with_local_coords -overmapbuffer::get_om_global( const point &p ) +overmapbuffer::get_om_global( const point_abs_omt &p ) { - return get_om_global( tripoint( p, 0 ) ); + return get_om_global( tripoint_abs_omt( p, 0 ) ); } overmap_with_local_coords -overmapbuffer::get_om_global( const tripoint &p ) +overmapbuffer::get_om_global( const tripoint_abs_omt &p ) { - point xy = p.xy(); - const point om_pos = omt_to_om_remain( xy ); + point_abs_om om_pos; + point_om_omt local; + std::tie( om_pos, local ) = project_remain( p.xy() ); overmap *om = &get( om_pos ); - return { om, tripoint( xy, p.z ) }; + return { om, tripoint_om_omt( local, p.z() ) }; } overmap_with_local_coords -overmapbuffer::get_existing_om_global( const point &p ) +overmapbuffer::get_existing_om_global( const point_abs_omt &p ) { - return get_existing_om_global( tripoint( p, 0 ) ); + return get_existing_om_global( tripoint_abs_omt( p, 0 ) ); } overmap_with_local_coords -overmapbuffer::get_existing_om_global( const tripoint &p ) +overmapbuffer::get_existing_om_global( const tripoint_abs_omt &p ) { - point xy = p.xy(); - const point om_pos = omt_to_om_remain( xy ); + point_abs_om om_pos; + point_om_omt local; + std::tie( om_pos, local ) = project_remain( p.xy() ); overmap *om = get_existing( om_pos ); if( om == nullptr ) { - return overmap_with_local_coords{ nullptr, tripoint_zero }; + return overmap_with_local_coords{ nullptr, tripoint_om_omt() }; } - return overmap_with_local_coords{ om, tripoint( xy, p.z ) }; + return overmap_with_local_coords{ om, tripoint_om_omt( local, p.z() ) }; } -bool overmapbuffer::is_omt_generated( const tripoint &loc ) +bool overmapbuffer::is_omt_generated( const tripoint_abs_omt &loc ) { if( overmap_with_local_coords om_loc = get_existing_om_global( loc ) ) { return om_loc.om->is_omt_generated( om_loc.local ); @@ -322,7 +329,7 @@ bool overmapbuffer::is_omt_generated( const tripoint &loc ) return false; } -bool overmapbuffer::has_note( const tripoint &p ) +bool overmapbuffer::has_note( const tripoint_abs_omt &p ) { if( const overmap_with_local_coords om_loc = get_existing_om_global( p ) ) { return om_loc.om->has_note( om_loc.local ); @@ -330,7 +337,7 @@ bool overmapbuffer::has_note( const tripoint &p ) return false; } -bool overmapbuffer::is_marked_dangerous( const tripoint &p ) +bool overmapbuffer::is_marked_dangerous( const tripoint_abs_omt &p ) { if( const overmap_with_local_coords om_loc = get_existing_om_global( p ) ) { return om_loc.om->is_marked_dangerous( om_loc.local ); @@ -338,7 +345,7 @@ bool overmapbuffer::is_marked_dangerous( const tripoint &p ) return false; } -const std::string &overmapbuffer::note( const tripoint &p ) +const std::string &overmapbuffer::note( const tripoint_abs_omt &p ) { if( const overmap_with_local_coords om_loc = get_existing_om_global( p ) ) { return om_loc.om->note( om_loc.local ); @@ -347,7 +354,7 @@ const std::string &overmapbuffer::note( const tripoint &p ) return empty_string; } -bool overmapbuffer::has_extra( const tripoint &p ) +bool overmapbuffer::has_extra( const tripoint_abs_omt &p ) { if( const overmap_with_local_coords om_loc = get_existing_om_global( p ) ) { return om_loc.om->has_extra( om_loc.local ); @@ -355,7 +362,7 @@ bool overmapbuffer::has_extra( const tripoint &p ) return false; } -const string_id &overmapbuffer::extra( const tripoint &p ) +const string_id &overmapbuffer::extra( const tripoint_abs_omt &p ) { if( const overmap_with_local_coords om_loc = get_existing_om_global( p ) ) { return om_loc.om->extra( om_loc.local ); @@ -364,7 +371,7 @@ const string_id &overmapbuffer::extra( const tripoint &p ) return id; } -bool overmapbuffer::is_explored( const tripoint &p ) +bool overmapbuffer::is_explored( const tripoint_abs_omt &p ) { if( const overmap_with_local_coords om_loc = get_existing_om_global( p ) ) { return om_loc.om->is_explored( om_loc.local ); @@ -372,13 +379,13 @@ bool overmapbuffer::is_explored( const tripoint &p ) return false; } -void overmapbuffer::toggle_explored( const tripoint &p ) +void overmapbuffer::toggle_explored( const tripoint_abs_omt &p ) { const overmap_with_local_coords om_loc = get_om_global( p ); om_loc.om->explored( om_loc.local ) = !om_loc.om->explored( om_loc.local ); } -bool overmapbuffer::has_horde( const tripoint &p ) +bool overmapbuffer::has_horde( const tripoint_abs_omt &p ) { for( const auto &m : overmap_buffer.monsters_at( p ) ) { if( m->horde ) { @@ -389,7 +396,7 @@ bool overmapbuffer::has_horde( const tripoint &p ) return false; } -int overmapbuffer::get_horde_size( const tripoint &p ) +int overmapbuffer::get_horde_size( const tripoint_abs_omt &p ) { int horde_size = 0; for( const auto &m : overmap_buffer.monsters_at( p ) ) { @@ -409,9 +416,9 @@ int overmapbuffer::get_horde_size( const tripoint &p ) return horde_size; } -bool overmapbuffer::has_camp( const tripoint &p ) +bool overmapbuffer::has_camp( const tripoint_abs_omt &p ) { - if( p.z ) { + if( p.z() ) { return false; } @@ -421,7 +428,7 @@ bool overmapbuffer::has_camp( const tripoint &p ) } for( const auto &v : om_loc.om->camps ) { - if( v.camp_omt_pos().xy() == om_loc.local.xy() ) { + if( v.camp_omt_pos().xy() == p.xy() ) { return true; } } @@ -429,9 +436,9 @@ bool overmapbuffer::has_camp( const tripoint &p ) return false; } -bool overmapbuffer::has_vehicle( const tripoint &p ) +bool overmapbuffer::has_vehicle( const tripoint_abs_omt &p ) { - if( p.z ) { + if( p.z() ) { return false; } @@ -449,10 +456,10 @@ bool overmapbuffer::has_vehicle( const tripoint &p ) return false; } -std::vector overmapbuffer::get_vehicle( const tripoint &p ) +std::vector overmapbuffer::get_vehicle( const tripoint_abs_omt &p ) { std::vector result; - if( p.z != 0 ) { + if( p.z() != 0 ) { return result; } const overmap_with_local_coords om_loc = get_existing_om_global( p ); @@ -467,12 +474,12 @@ std::vector overmapbuffer::get_vehicle( const tripoint &p ) return result; } -void overmapbuffer::signal_hordes( const tripoint ¢er, const int sig_power ) +void overmapbuffer::signal_hordes( const tripoint_abs_sm ¢er, const int sig_power ) { const auto radius = sig_power; for( auto &om : get_overmaps_near( center, radius ) ) { - const point abs_pos_om = om_to_sm_copy( om->pos() ); - const tripoint rel_pos( -abs_pos_om + center ); + const point_abs_sm abs_pos_om = project_to( om->pos() ); + const tripoint_rel_sm rel_pos = center - abs_pos_om; // overmap::signal_hordes expects a coordinate relative to the overmap, this is easier // for processing as the monster group stores is location as relative coordinates, too. om->signal_hordes( rel_pos, sig_power ); @@ -483,7 +490,8 @@ void overmapbuffer::process_mongroups() { // arbitrary radius to include nearby overmaps (aside from the current one) const auto radius = MAPSIZE * 2; - const auto center = get_player_character().global_sm_location(); + // TODO: fix point types + const tripoint_abs_sm center( get_player_character().global_sm_location() ); for( auto &om : get_overmaps_near( center, radius ) ) { om->process_mongroups(); } @@ -493,17 +501,18 @@ void overmapbuffer::move_hordes() { // arbitrary radius to include nearby overmaps (aside from the current one) const auto radius = MAPSIZE * 2; - const auto center = get_player_character().global_sm_location(); + // TODO: fix point types + const tripoint_abs_sm center( get_player_character().global_sm_location() ); for( auto &om : get_overmaps_near( center, radius ) ) { om->move_hordes(); } } -std::vector overmapbuffer::monsters_at( const tripoint &p ) +std::vector overmapbuffer::monsters_at( const tripoint_abs_omt &p ) { // (x,y) are overmap terrain coordinates, they spawn 2x2 submaps, // but monster groups are defined with submap coordinates. - tripoint p_sm = omt_to_sm_copy( p ); + tripoint_abs_sm p_sm = project_to( p ); std::vector result; for( const point &offset : std::array { { { point_zero }, { point_south }, { point_east }, { point_south_east } } } ) { std::vector tmp = groups_at( p_sm + offset ); @@ -512,16 +521,17 @@ std::vector overmapbuffer::monsters_at( const tripoint &p ) return result; } -std::vector overmapbuffer::groups_at( const tripoint &p ) +std::vector overmapbuffer::groups_at( const tripoint_abs_sm &p ) { std::vector result; - point sm_within_om( p.xy() ); - const point omp = sm_to_om_remain( sm_within_om ); + point_om_sm sm_within_om; + point_abs_om omp; + std::tie( omp, sm_within_om ) = project_remain( p.xy() ); if( !has( omp ) ) { return result; } overmap &om = get( omp ); - auto groups_range = om.zg.equal_range( tripoint( sm_within_om, p.z ) ); + auto groups_range = om.zg.equal_range( tripoint_om_sm( sm_within_om, p.z() ) ); for( auto it = groups_range.first; it != groups_range.second; ++it ) { mongroup &mg = it->second; if( mg.empty() ) { @@ -532,15 +542,14 @@ std::vector overmapbuffer::groups_at( const tripoint &p ) return result; } -std::array, 3> overmapbuffer::scents_near( const tripoint &origin ) +std::array, 3> overmapbuffer::scents_near( const tripoint_abs_omt + &origin ) { std::array, 3> found_traces; - tripoint iter; - int x; - int y; - for( x = 0, iter.x = origin.x - 1; x <= 2 ; ++iter.x, ++x ) { - for( y = 0, iter.y = origin.y - 1; y <= 2; ++iter.y, ++y ) { + for( int x = -1; x <= 1 ; ++x ) { + for( int y = -1; y <= 1; ++y ) { + tripoint_abs_omt iter = origin + point( x, y ); found_traces[x][y] = scent_at( iter ); } } @@ -548,7 +557,7 @@ std::array, 3> overmapbuffer::scents_near( const trip return found_traces; } -scent_trace overmapbuffer::scent_at( const tripoint &p ) +scent_trace overmapbuffer::scent_at( const tripoint_abs_omt &p ) { if( const overmap_with_local_coords om_loc = get_existing_om_global( p ) ) { return om_loc.om->scent_at( p ); @@ -556,18 +565,19 @@ scent_trace overmapbuffer::scent_at( const tripoint &p ) return scent_trace(); } -void overmapbuffer::set_scent( const tripoint &loc, int strength ) +void overmapbuffer::set_scent( const tripoint_abs_omt &loc, int strength ) { const overmap_with_local_coords om_loc = get_om_global( loc ); scent_trace new_scent( calendar::turn, strength ); om_loc.om->set_scent( loc, new_scent ); } -void overmapbuffer::move_vehicle( vehicle *veh, const point &old_msp ) +void overmapbuffer::move_vehicle( vehicle *veh, const point_abs_ms &old_msp ) { - const point new_msp = get_map().getabs( veh->global_pos3().xy() ); - const point old_omt = ms_to_omt_copy( old_msp ); - const point new_omt = ms_to_omt_copy( new_msp ); + // TODO: fix point types + const point_abs_ms new_msp( get_map().getabs( veh->global_pos3().xy() ) ); + const point_abs_omt old_omt = project_to( old_msp ); + const point_abs_omt new_omt = project_to( new_msp ); const overmap_with_local_coords old_om_loc = get_om_global( old_omt ); const overmap_with_local_coords new_om_loc = get_om_global( new_omt ); if( old_om_loc.om == new_om_loc.om ) { @@ -580,7 +590,7 @@ void overmapbuffer::move_vehicle( vehicle *veh, const point &old_msp ) void overmapbuffer::remove_camp( const basecamp &camp ) { - const point omt = camp.camp_omt_pos().xy(); + const point_abs_omt omt = camp.camp_omt_pos().xy(); const overmap_with_local_coords om_loc = get_om_global( omt ); std::vector &camps = om_loc.om->camps; for( auto it = camps.begin(); it != camps.end(); ++it ) { @@ -593,7 +603,8 @@ void overmapbuffer::remove_camp( const basecamp &camp ) void overmapbuffer::remove_vehicle( const vehicle *veh ) { - const point omt = ms_to_omt_copy( get_map().getabs( veh->global_pos3().xy() ) ); + // TODO: fix point types + const point_abs_omt omt( ms_to_omt_copy( get_map().getabs( veh->global_pos3().xy() ) ) ); const overmap_with_local_coords om_loc = get_om_global( omt ); om_loc.om->vehicles.erase( veh->om_id ); } @@ -601,7 +612,8 @@ void overmapbuffer::remove_vehicle( const vehicle *veh ) void overmapbuffer::add_vehicle( vehicle *veh ) { const point abs_pos = get_map().getabs( veh->global_pos3().xy() ); - const point omt = ms_to_omt_copy( abs_pos ); + // TODO: fix point types + const point_abs_omt omt( ms_to_omt_copy( abs_pos ) ); const overmap_with_local_coords om_loc = get_om_global( omt ); int id = om_loc.om->vehicles.size() + 1; // this *should* be unique but just in case @@ -616,12 +628,12 @@ void overmapbuffer::add_vehicle( vehicle *veh ) void overmapbuffer::add_camp( const basecamp &camp ) { - const point omt = camp.camp_omt_pos().xy(); + const point_abs_omt omt = camp.camp_omt_pos().xy(); const overmap_with_local_coords om_loc = get_om_global( omt ); om_loc.om->camps.push_back( camp ); } -bool overmapbuffer::seen( const tripoint &p ) +bool overmapbuffer::seen( const tripoint_abs_omt &p ) { if( const overmap_with_local_coords om_loc = get_existing_om_global( p ) ) { return om_loc.om->seen( om_loc.local ); @@ -629,44 +641,44 @@ bool overmapbuffer::seen( const tripoint &p ) return false; } -void overmapbuffer::set_seen( const tripoint &p, bool seen ) +void overmapbuffer::set_seen( const tripoint_abs_omt &p, bool seen ) { const overmap_with_local_coords om_loc = get_om_global( p ); om_loc.om->seen( om_loc.local ) = seen; } -const oter_id &overmapbuffer::ter( const tripoint &p ) +const oter_id &overmapbuffer::ter( const tripoint_abs_omt &p ) { const overmap_with_local_coords om_loc = get_om_global( p ); return om_loc.om->ter( om_loc.local ); } -void overmapbuffer::ter_set( const tripoint &p, const oter_id &id ) +void overmapbuffer::ter_set( const tripoint_abs_omt &p, const oter_id &id ) { const overmap_with_local_coords om_loc = get_om_global( p ); return om_loc.om->ter_set( om_loc.local, id ); } -bool overmapbuffer::reveal( const point ¢er, int radius, int z ) +bool overmapbuffer::reveal( const point_abs_omt ¢er, int radius, int z ) { - return reveal( tripoint( center, z ), radius ); + return reveal( tripoint_abs_omt( center, z ), radius ); } -bool overmapbuffer::reveal( const tripoint ¢er, int radius ) +bool overmapbuffer::reveal( const tripoint_abs_omt ¢er, int radius ) { return reveal( center, radius, []( const oter_id & ) { return true; } ); } -bool overmapbuffer::reveal( const tripoint ¢er, int radius, +bool overmapbuffer::reveal( const tripoint_abs_omt ¢er, int radius, const std::function &filter ) { int radius_squared = radius * radius; bool result = false; for( int i = -radius; i <= radius; i++ ) { for( int j = -radius; j <= radius; j++ ) { - const tripoint p = center + point( i, j ); + const tripoint_abs_omt p = center + point( i, j ); if( seen( p ) ) { continue; } @@ -683,34 +695,37 @@ bool overmapbuffer::reveal( const tripoint ¢er, int radius, return result; } -std::vector overmapbuffer::get_npc_path( const tripoint &src, const tripoint &dest ) +std::vector overmapbuffer::get_npc_path( const tripoint_abs_omt &src, + const tripoint_abs_omt &dest ) { path_type ptype; return get_npc_path( src, dest, ptype ); } -std::vector overmapbuffer::get_npc_path( const tripoint &src, const tripoint &dest, - path_type &ptype ) +std::vector overmapbuffer::get_npc_path( + const tripoint_abs_omt &src, const tripoint_abs_omt &dest, path_type &ptype ) { - std::vector path; + std::vector path; static const int RADIUS = 4; // Maximal radius of search (in overmaps) - static const point O( RADIUS * OMAPX, RADIUS * OMAPY ); // half-height of the area to search in + static const point_rel_omt O( RADIUS * OMAPX, + RADIUS * OMAPY ); // half-height of the area to search in if( src == overmap::invalid_tripoint || dest == overmap::invalid_tripoint ) { return path; } // Local source - center of the local area - const point start( O ); + const point_rel_omt start( O ); // To convert local coordinates to global ones - const tripoint base = src - start; + const tripoint_abs_omt base = src - start; // Local destination - relative to base - const point finish = ( dest - base ).xy(); + const point_rel_omt finish = ( dest - base ).xy(); - const auto get_ter_at = [&]( const point & p ) { + const auto get_ter_at = [&]( const point_rel_omt & p ) { return ter( base + p ); }; - const auto estimate = [&]( const pf::node &cur, const pf::node * ) { - const tripoint convert_result = base + tripoint( cur.pos, 0 ); + const auto estimate = + [&]( const pf::node &cur, const pf::node * ) { + const tripoint_abs_omt convert_result = base + tripoint_rel_omt( cur.pos, 0 ); if( ptype.only_known_by_player && !seen( convert_result ) ) { return pf::rejected; } @@ -760,33 +775,34 @@ std::vector overmapbuffer::get_npc_path( const tripoint &src, const tr return res; }; - pf::path route = pf::find_path( start, finish, point( 2 * O.x, 2 * O.y ), estimate ); + pf::path route = pf::find_path( start, finish, 2 * O, estimate ); for( auto node : route.nodes ) { - tripoint convert_result = base + tripoint( node.pos, 0 ); - convert_result.z = base.z; + tripoint_abs_omt convert_result = base + tripoint_rel_omt( node.pos, 0 ); + convert_result.z() = base.z(); path.push_back( convert_result ); } return path; } -bool overmapbuffer::reveal_route( const tripoint &source, const tripoint &dest, int radius, - bool road_only ) +bool overmapbuffer::reveal_route( const tripoint_abs_omt &source, const tripoint_abs_omt &dest, + int radius, bool road_only ) { static const int RADIUS = 4; // Maximal radius of search (in overmaps) - static const point O( RADIUS * OMAPX, RADIUS * OMAPY ); // half-height of the area to search in + static const point_rel_omt O( RADIUS * OMAPX, + RADIUS * OMAPY ); // half-height of the area to search in if( source == overmap::invalid_tripoint || dest == overmap::invalid_tripoint ) { return false; } // Local source - center of the local area - const point start( O ); + const point_rel_omt start( O ); // To convert local coordinates to global ones - const tripoint base = source - start; + const tripoint_abs_omt base = source - start; // Local destination - relative to base - const point finish = ( dest - base ).xy(); + const point_rel_omt finish = ( dest - base ).xy(); - const auto get_ter_at = [&]( const point & p ) { + const auto get_ter_at = [&]( const point_rel_omt & p ) { return ter( base + p ); }; @@ -797,7 +813,8 @@ bool overmapbuffer::reveal_route( const tripoint &source, const tripoint &dest, return false; } - const auto estimate = [&]( const pf::node &cur, const pf::node * ) { + const auto estimate = + [&]( const pf::node &cur, const pf::node * ) { int res = 0; const oter_id oter = get_ter_at( cur.pos ); @@ -820,7 +837,7 @@ bool overmapbuffer::reveal_route( const tripoint &source, const tripoint &dest, return res; }; - const auto path = pf::find_path( start, finish, point( 2 * O.x, 2 * O.y ), estimate ); + const auto path = pf::find_path( start, finish, 2 * O, estimate ); for( const auto &node : path.nodes ) { reveal( base + node.pos, radius ); @@ -829,7 +846,7 @@ bool overmapbuffer::reveal_route( const tripoint &source, const tripoint &dest, } bool overmapbuffer::check_ot_existing( const std::string &type, ot_match_type match_type, - const tripoint &loc ) + const tripoint_abs_omt &loc ) { const overmap_with_local_coords om_loc = get_existing_om_global( loc ); if( !om_loc ) { @@ -839,7 +856,7 @@ bool overmapbuffer::check_ot_existing( const std::string &type, ot_match_type ma } bool overmapbuffer::check_overmap_special_type_existing( - const overmap_special_id &id, const tripoint &loc ) + const overmap_special_id &id, const tripoint_abs_omt &loc ) { const overmap_with_local_coords om_loc = get_existing_om_global( loc ); if( !om_loc ) { @@ -848,13 +865,15 @@ bool overmapbuffer::check_overmap_special_type_existing( return om_loc.om->check_overmap_special_type( id, om_loc.local ); } -bool overmapbuffer::check_ot( const std::string &type, ot_match_type match_type, const tripoint &p ) +bool overmapbuffer::check_ot( const std::string &type, ot_match_type match_type, + const tripoint_abs_omt &p ) { const overmap_with_local_coords om_loc = get_om_global( p ); return om_loc.om->check_ot( type, match_type, om_loc.local ); } -bool overmapbuffer::check_overmap_special_type( const overmap_special_id &id, const tripoint &loc ) +bool overmapbuffer::check_overmap_special_type( const overmap_special_id &id, + const tripoint_abs_omt &loc ) { const overmap_with_local_coords om_loc = get_om_global( loc ); return om_loc.om->check_overmap_special_type( id, om_loc.local ); @@ -879,7 +898,8 @@ static omt_find_params assign_params( return params; } -bool overmapbuffer::is_findable_location( const tripoint &location, const omt_find_params ¶ms ) +bool overmapbuffer::is_findable_location( const tripoint_abs_omt &location, + const omt_find_params ¶ms ) { bool type_matches = false; if( params.existing_only ) { @@ -923,18 +943,18 @@ bool overmapbuffer::is_findable_location( const tripoint &location, const omt_fi return true; } -tripoint overmapbuffer::find_closest( const tripoint &origin, const std::string &type, - int const radius, bool must_be_seen, - ot_match_type match_type, - bool existing_overmaps_only, - const cata::optional &om_special ) +tripoint_abs_omt overmapbuffer::find_closest( + const tripoint_abs_omt &origin, const std::string &type, int const radius, bool must_be_seen, + ot_match_type match_type, bool existing_overmaps_only, + const cata::optional &om_special ) { const omt_find_params params = assign_params( type, radius, must_be_seen, match_type, existing_overmaps_only, om_special ); return find_closest( origin, params ); } -tripoint overmapbuffer::find_closest( const tripoint &origin, const omt_find_params ¶ms ) +tripoint_abs_omt overmapbuffer::find_closest( const tripoint_abs_omt &origin, + const omt_find_params ¶ms ) { // Check the origin before searching adjacent tiles! if( params.min_distance == 0 && is_findable_location( origin, params ) ) { @@ -959,10 +979,10 @@ tripoint overmapbuffer::find_closest( const tripoint &origin, const omt_find_par const int min_dist = params.min_distance; const int max_dist = params.search_range ? params.search_range : OMAPX * 5; - std::vector result; + std::vector result; cata::optional found_dist; - for( const point &loc_xy : closest_points_first( origin.xy(), min_dist, max_dist ) ) { + for( const point_abs_omt &loc_xy : closest_points_first( origin.xy(), min_dist, max_dist ) ) { const int dist_xy = square_dist( origin.xy(), loc_xy ); if( found_dist && *found_dist < dist_xy ) { @@ -970,7 +990,7 @@ tripoint overmapbuffer::find_closest( const tripoint &origin, const omt_find_par } for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) { - const tripoint loc = { loc_xy, z }; + const tripoint_abs_omt loc( loc_xy, z ); const int dist = square_dist( origin, loc ); if( found_dist && *found_dist < dist ) { @@ -987,15 +1007,15 @@ tripoint overmapbuffer::find_closest( const tripoint &origin, const omt_find_par return random_entry( result, overmap::invalid_tripoint ); } -std::vector overmapbuffer::find_all( const tripoint &origin, +std::vector overmapbuffer::find_all( const tripoint_abs_omt &origin, const omt_find_params ¶ms ) { - std::vector result; + std::vector result; // dist == 0 means search a whole overmap diameter. const int min_dist = params.min_distance; const int max_dist = params.search_range ? params.search_range : OMAPX; - for( const tripoint &loc : closest_points_first( origin, min_dist, max_dist ) ) { + for( const tripoint_abs_omt &loc : closest_points_first( origin, min_dist, max_dist ) ) { if( is_findable_location( loc, params ) ) { result.push_back( loc ); } @@ -1004,24 +1024,26 @@ std::vector overmapbuffer::find_all( const tripoint &origin, return result; } -std::vector overmapbuffer::find_all( const tripoint &origin, const std::string &type, - int dist, bool must_be_seen, ot_match_type match_type, - bool existing_overmaps_only, - const cata::optional &om_special ) +std::vector overmapbuffer::find_all( + const tripoint_abs_omt &origin, const std::string &type, int dist, bool must_be_seen, + ot_match_type match_type, bool existing_overmaps_only, + const cata::optional &om_special ) { const omt_find_params params = assign_params( type, dist, must_be_seen, match_type, existing_overmaps_only, om_special ); return find_all( origin, params ); } -tripoint overmapbuffer::find_random( const tripoint &origin, const omt_find_params ¶ms ) +tripoint_abs_omt overmapbuffer::find_random( const tripoint_abs_omt &origin, + const omt_find_params ¶ms ) { return random_entry( find_all( origin, params ), overmap::invalid_tripoint ); } -tripoint overmapbuffer::find_random( const tripoint &origin, const std::string &type, - int dist, bool must_be_seen, ot_match_type match_type, - bool existing_overmaps_only, - const cata::optional &om_special ) + +tripoint_abs_omt overmapbuffer::find_random( + const tripoint_abs_omt &origin, const std::string &type, int dist, bool must_be_seen, + ot_match_type match_type, bool existing_overmaps_only, + const cata::optional &om_special ) { const omt_find_params params = assign_params( type, dist, must_be_seen, match_type, existing_overmaps_only, om_special ); @@ -1038,13 +1060,13 @@ shared_ptr_fast overmapbuffer::find_npc( character_id id ) return nullptr; } -cata::optional overmapbuffer::find_camp( const point &p ) +cata::optional overmapbuffer::find_camp( const point_abs_omt &p ) { for( auto &it : overmaps ) { - const point p2( p ); - for( int x2 = p2.x - 3; x2 < p2.x + 3; x2++ ) { - for( int y2 = p2.y - 3; y2 < p2.y + 3; y2++ ) { - if( cata::optional camp = it.second->find_camp( point( x2, y2 ) ) ) { + const point_abs_omt p2( p ); + for( int x2 = p2.x() - 3; x2 < p2.x() + 3; x2++ ) { + for( int y2 = p2.y() - 3; y2 < p2.y() + 3; y2++ ) { + if( cata::optional camp = it.second->find_camp( point_abs_omt( x2, y2 ) ) ) { return camp; } } @@ -1056,8 +1078,8 @@ cata::optional overmapbuffer::find_camp( const point &p ) void overmapbuffer::insert_npc( const shared_ptr_fast &who ) { assert( who ); - const tripoint npc_omt_pos = who->global_omt_location(); - const point npc_om_pos = omt_to_om_copy( npc_omt_pos.xy() ); + const tripoint_abs_omt npc_omt_pos = who->global_omt_location(); + const point_abs_om npc_om_pos = project_to( npc_omt_pos.xy() ); get( npc_om_pos ).insert_npc( who ); } @@ -1074,49 +1096,51 @@ shared_ptr_fast overmapbuffer::remove_npc( const character_id &id ) std::vector> overmapbuffer::get_npcs_near_player( int radius ) { - tripoint plpos = get_player_character().global_omt_location(); + tripoint_abs_omt plpos_omt = get_player_character().global_omt_location(); // get_npcs_near needs submap coordinates - omt_to_sm( plpos.x, plpos.y ); + tripoint_abs_sm plpos = project_to( plpos_omt ); // INT_MIN is a (a bit ugly) way to inform get_npcs_near not to filter by z-level - const int zpos = get_map().has_zlevels() ? INT_MIN : plpos.z; - return get_npcs_near( tripoint( plpos.xy(), zpos ), radius ); + const int zpos = get_map().has_zlevels() ? INT_MIN : plpos.z(); + return get_npcs_near( tripoint_abs_sm( plpos.xy(), zpos ), radius ); } -std::vector overmapbuffer::get_overmaps_near( const tripoint &location, +std::vector overmapbuffer::get_overmaps_near( const tripoint_abs_sm &location, const int radius ) { // Grab the corners of a square around the target location at distance radius. // Convert to overmap coordinates and iterate from the minimum to the maximum. - const point start = sm_to_om_copy( location.xy() + point( -radius, -radius ) ); - const point end = sm_to_om_copy( location.xy() + point( radius, radius ) ); - const point offset = end - start; + const point_abs_om start = + project_to( location.xy() + point( -radius, -radius ) ); + const point_abs_om end = + project_to( location.xy() + point( radius, radius ) ); + const point_rel_om offset = end - start; std::vector result; - result.reserve( ( offset.x + 1 ) * ( offset.y + 1 ) ); + result.reserve( ( offset.x() + 1 ) * ( offset.y() + 1 ) ); - for( int x = start.x; x <= end.x; ++x ) { - for( int y = start.y; y <= end.y; ++y ) { - if( overmap *existing_om = get_existing( point( x, y ) ) ) { + for( int x = start.x(); x <= end.x(); ++x ) { + for( int y = start.y(); y <= end.y(); ++y ) { + if( overmap *existing_om = get_existing( point_abs_om( x, y ) ) ) { result.emplace_back( existing_om ); } } } // Sort the resulting overmaps so that the closest ones are first. - const tripoint center = sm_to_om_copy( location ); + const tripoint_abs_om center = project_to( location ); std::sort( result.begin(), result.end(), [¢er]( const overmap * lhs, const overmap * rhs ) { - const tripoint lhs_pos( lhs->pos(), 0 ); - const tripoint rhs_pos( rhs->pos(), 0 ); + const tripoint_abs_om lhs_pos( lhs->pos(), 0 ); + const tripoint_abs_om rhs_pos( rhs->pos(), 0 ); return trig_dist( center, lhs_pos ) < trig_dist( center, rhs_pos ); } ); return result; } -std::vector overmapbuffer::get_overmaps_near( const point &p, const int radius ) +std::vector overmapbuffer::get_overmaps_near( const point_abs_sm &p, const int radius ) { - return get_overmaps_near( tripoint( p, 0 ), radius ); + return get_overmaps_near( tripoint_abs_sm( p, 0 ), radius ); } std::vector> overmapbuffer::get_companion_mission_npcs( int range ) @@ -1132,15 +1156,16 @@ std::vector> overmapbuffer::get_companion_mission_npcs( int } // If z == INT_MIN, allow all z-levels -std::vector> overmapbuffer::get_npcs_near( const tripoint &p, +std::vector> overmapbuffer::get_npcs_near( const tripoint_abs_sm &p, int radius ) { std::vector> result; for( auto &it : get_overmaps_near( p.xy(), radius ) ) { auto temp = it->get_npcs( [&]( const npc & guy ) { // Global position of NPC, in submap coordinates - const tripoint pos = guy.global_sm_location(); - if( p.z != INT_MIN && pos.z != p.z ) { + // TODO: fix point types + const tripoint_abs_sm pos( guy.global_sm_location() ); + if( p.z() != INT_MIN && pos.z() != p.z() ) { return false; } return square_dist( p.xy(), pos.xy() ) <= radius; @@ -1151,15 +1176,15 @@ std::vector> overmapbuffer::get_npcs_near( const tripoint & } // If z == INT_MIN, allow all z-levels -std::vector> overmapbuffer::get_npcs_near_omt( const tripoint &p, +std::vector> overmapbuffer::get_npcs_near_omt( const tripoint_abs_omt &p, int radius ) { std::vector> result; - for( auto &it : get_overmaps_near( omt_to_sm_copy( p.xy() ), radius ) ) { + for( auto &it : get_overmaps_near( project_to( p.xy() ), radius ) ) { auto temp = it->get_npcs( [&]( const npc & guy ) { // Global position of NPC, in submap coordinates - tripoint pos = guy.global_omt_location(); - if( p.z != INT_MIN && pos.z != p.z ) { + tripoint_abs_omt pos = guy.global_omt_location(); + if( p.z() != INT_MIN && pos.z() != p.z() ) { return false; } return square_dist( p.xy(), pos.xy() ) <= radius; @@ -1170,17 +1195,18 @@ std::vector> overmapbuffer::get_npcs_near_omt( const tripoi } static radio_tower_reference create_radio_tower_reference( const overmap &om, radio_tower &t, - const tripoint ¢er ) + const tripoint_abs_sm ¢er ) { // global submap coordinates, same as center is - const point pos = t.pos + om_to_sm_copy( om.pos() ); - const int strength = t.strength - rl_dist( tripoint( pos, 0 ), center ); + const point_abs_sm pos = project_combine( om.pos(), t.pos ); + const int strength = t.strength - rl_dist( tripoint_abs_sm( pos, 0 ), center ); return radio_tower_reference{ &t, pos, strength }; } radio_tower_reference overmapbuffer::find_radio_station( const int frequency ) { - const auto center = get_player_character().global_sm_location(); + // TODO: fix point types + const tripoint_abs_sm center( get_player_character().global_sm_location() ); for( auto &om : get_overmaps_near( center, RADIO_MAX_STRENGTH ) ) { for( auto &tower : om->radios ) { const auto rref = create_radio_tower_reference( *om, tower, center ); @@ -1189,13 +1215,14 @@ radio_tower_reference overmapbuffer::find_radio_station( const int frequency ) } } } - return radio_tower_reference{ nullptr, point_zero, 0 }; + return radio_tower_reference{ nullptr, point_abs_sm(), 0 }; } std::vector overmapbuffer::find_all_radio_stations() { std::vector result; - const auto center = get_player_character().global_sm_location(); + // TODO: fix point types + const tripoint_abs_sm center( get_player_character().global_sm_location() ); // perceived signal strength is distance (in submaps) - signal strength, so towers // further than RADIO_MAX_STRENGTH submaps away can never be received at all. const int radius = RADIO_MAX_STRENGTH; @@ -1210,20 +1237,19 @@ std::vector overmapbuffer::find_all_radio_stations() return result; } -std::vector overmapbuffer::get_camps_near( const tripoint &location, int radius ) +std::vector overmapbuffer::get_camps_near( const tripoint_abs_sm &location, + int radius ) { std::vector result; for( const auto om : get_overmaps_near( location, radius ) ) { - const auto abs_pos_om = om_to_sm_copy( om->pos() ); result.reserve( result.size() + om->camps.size() ); std::transform( om->camps.begin(), om->camps.end(), std::back_inserter( result ), [&]( basecamp & element ) { - const point camp_pt = element.camp_omt_pos().xy(); - const auto rel_pos_camp = omt_to_sm_copy( camp_pt ); - const auto abs_pos_camp = tripoint( rel_pos_camp + abs_pos_om, 0 ); - const auto distance = rl_dist( abs_pos_camp, location ); + const tripoint_abs_omt camp_pt = element.camp_omt_pos(); + const tripoint_abs_sm camp_sm = project_to( camp_pt ); + const auto distance = rl_dist( camp_sm, location ); - return camp_reference{ &element, abs_pos_camp, distance }; + return camp_reference{ &element, camp_sm, distance }; } ); } std::sort( result.begin(), result.end(), []( const camp_reference & lhs, @@ -1245,17 +1271,18 @@ std::vector> overmapbuffer::get_overmap_npcs() return result; } -std::vector overmapbuffer::get_cities_near( const tripoint &location, int radius ) +std::vector overmapbuffer::get_cities_near( const tripoint_abs_sm &location, + int radius ) { std::vector result; for( const auto om : get_overmaps_near( location, radius ) ) { - const auto abs_pos_om = om_to_sm_copy( om->pos() ); result.reserve( result.size() + om->cities.size() ); std::transform( om->cities.begin(), om->cities.end(), std::back_inserter( result ), [&]( city & element ) { - const auto rel_pos_city = omt_to_sm_copy( element.pos ); - const auto abs_pos_city = tripoint( rel_pos_city + abs_pos_om, 0 ); + const auto rel_pos_city = project_to( element.pos ); + const auto abs_pos_city = + tripoint_abs_sm( project_combine( om->pos(), rel_pos_city ), 0 ); const auto distance = rl_dist( abs_pos_city, location ); return city_reference{ &element, abs_pos_city, distance }; @@ -1270,7 +1297,7 @@ std::vector overmapbuffer::get_cities_near( const tripoint &loca return result; } -city_reference overmapbuffer::closest_city( const tripoint ¢er ) +city_reference overmapbuffer::closest_city( const tripoint_abs_sm ¢er ) { const auto cities = get_cities_near( center, omt_to_sm_copy( OMAPX ) ); @@ -1281,12 +1308,12 @@ city_reference overmapbuffer::closest_city( const tripoint ¢er ) return city_reference::invalid; } -city_reference overmapbuffer::closest_known_city( const tripoint ¢er ) +city_reference overmapbuffer::closest_known_city( const tripoint_abs_sm ¢er ) { const auto cities = get_cities_near( center, omt_to_sm_copy( OMAPX ) ); const auto it = std::find_if( cities.begin(), cities.end(), [this]( const city_reference & elem ) { - const tripoint p = sm_to_omt_copy( elem.abs_sm_pos ); + const tripoint_abs_omt p = project_to( elem.abs_sm_pos ); return seen( p ); } ); @@ -1297,13 +1324,13 @@ city_reference overmapbuffer::closest_known_city( const tripoint ¢er ) return city_reference::invalid; } -std::string overmapbuffer::get_description_at( const tripoint &where ) +std::string overmapbuffer::get_description_at( const tripoint_abs_sm &where ) { - const auto oter = ter( sm_to_omt_copy( where ) ); + const auto oter = ter( project_to( where ) ); const nc_color ter_color = oter->get_color(); const std::string ter_name = colorize( oter->get_name(), ter_color ); - if( where.z != 0 ) { + if( where.z() != 0 ) { return ter_name; } @@ -1351,16 +1378,18 @@ std::string overmapbuffer::get_description_at( const tripoint &where ) return string_format( format_string, ter_name, dir_name, closest_city_name ); } -void overmapbuffer::spawn_monster( const tripoint &p ) +void overmapbuffer::spawn_monster( const tripoint_abs_sm &p ) { // Create a copy, so we can reuse x and y later - point sm = p.xy(); - const point omp = sm_to_om_remain( sm ); + point_abs_sm abs_sm = p.xy(); + point_om_sm sm; + point_abs_om omp; + std::tie( omp, sm ) = project_remain( abs_sm ); overmap &om = get( omp ); - const tripoint current_submap_loc( tripoint( sm, p.z ) ); + const tripoint_om_sm current_submap_loc( sm, p.z() ); auto monster_bucket = om.monster_map.equal_range( current_submap_loc ); std::for_each( monster_bucket.first, monster_bucket.second, - [&]( std::pair &monster_entry ) { + [&]( std::pair &monster_entry ) { monster &this_monster = monster_entry.second; // The absolute position in map squares, (x,y) is already global, but it's a // submap coordinate, so translate it and add the exact monster position on @@ -1370,10 +1399,11 @@ void overmapbuffer::spawn_monster( const tripoint &p ) point ms( modulo( this_monster.posx(), SEEX ), modulo( this_monster.posy(), SEEY ) ); assert( ms.x >= 0 && ms.x < SEEX ); assert( ms.y >= 0 && ms.y < SEEX ); - ms += sm_to_ms_copy( p.xy() ); + // TODO: fix point types + ms += project_to( p.xy() ).raw(); const map &here = get_map(); // The monster position must be local to the main map when added to the game - const tripoint local = tripoint( here.getlocal( ms ), p.z ); + const tripoint local = tripoint( here.getlocal( ms ), p.z() ); assert( here.inbounds( local ) ); monster *const placed = g->place_critter_at( make_shared_fast( this_monster ), local ); @@ -1387,9 +1417,12 @@ void overmapbuffer::spawn_monster( const tripoint &p ) void overmapbuffer::despawn_monster( const monster &critter ) { // Get absolute coordinates of the monster in map squares, translate to submap position - tripoint sm = ms_to_sm_copy( get_map().getabs( critter.pos() ) ); + // TODO: fix point types + tripoint_abs_sm abs_sm( ms_to_sm_copy( get_map().getabs( critter.pos() ) ) ); // Get the overmap coordinates and get the overmap, sm is now local to that overmap - const point omp = sm_to_om_remain( sm.x, sm.y ); + point_abs_om omp; + tripoint_om_sm sm; + std::tie( omp, sm ) = project_remain( abs_sm ); overmap &om = get( omp ); // Store the monster using coordinates local to the overmap. om.monster_map.insert( std::make_pair( sm, critter ) ); @@ -1400,10 +1433,10 @@ overmapbuffer::t_notes_vector overmapbuffer::get_notes( int z, const std::string t_notes_vector result; for( auto &it : overmaps ) { const overmap &om = *it.second; - const point offset( om.pos().x * OMAPX, om.pos().y * OMAPY ); for( int i = 0; i < OMAPX; i++ ) { for( int j = 0; j < OMAPY; j++ ) { - const std::string ¬e = om.note( { i, j, z } ); + tripoint_om_omt p( i, j, z ); + const std::string ¬e = om.note( p ); if( note.empty() ) { continue; } @@ -1412,8 +1445,8 @@ overmapbuffer::t_notes_vector overmapbuffer::get_notes( int z, const std::string continue; } result.push_back( t_point_with_note( - offset + point( i, j ), - om.note( { i, j, z } ) + project_combine( om.pos(), p.xy() ), + om.note( p ) ) ); } } @@ -1426,10 +1459,9 @@ overmapbuffer::t_extras_vector overmapbuffer::get_extras( int z, const std::stri overmapbuffer::t_extras_vector result; for( auto &it : overmaps ) { const overmap &om = *it.second; - const point offset = om_to_omt_copy( om.pos() ); for( int i = 0; i < OMAPX; i++ ) { for( int j = 0; j < OMAPY; j++ ) { - tripoint p( i, j, z ); + tripoint_om_omt p( i, j, z ); const string_id &extra = om.extra( p ); if( extra.is_null() ) { continue; @@ -1440,7 +1472,7 @@ overmapbuffer::t_extras_vector overmapbuffer::get_extras( int z, const std::stri continue; } result.push_back( t_point_with_extra( - p.xy() + offset, + project_combine( om.pos(), p.xy() ), om.extra( p ) ) ); } @@ -1449,7 +1481,7 @@ overmapbuffer::t_extras_vector overmapbuffer::get_extras( int z, const std::stri return result; } -bool overmapbuffer::is_safe( const tripoint &p ) +bool overmapbuffer::is_safe( const tripoint_abs_omt &p ) { for( auto &mongrp : monsters_at( p ) ) { if( !mongrp->is_safe() ) { @@ -1460,7 +1492,7 @@ bool overmapbuffer::is_safe( const tripoint &p ) } bool overmapbuffer::place_special( - const overmap_special &special, const tripoint &p, om_direction::type dir, + const overmap_special &special, const tripoint_abs_omt &p, om_direction::type dir, const bool must_be_unexplored, const bool force ) { const overmap_with_local_coords om_loc = get_om_global( p ); @@ -1484,8 +1516,8 @@ bool overmapbuffer::place_special( return placed; } -bool overmapbuffer::place_special( const overmap_special_id &special_id, const tripoint ¢er, - int radius ) +bool overmapbuffer::place_special( const overmap_special_id &special_id, + const tripoint_abs_omt ¢er, int radius ) { // First find the requested special. If it doesn't exist, we're done here. bool found = false; @@ -1533,7 +1565,8 @@ bool overmapbuffer::place_special( const overmap_special_id &special_id, const t om_special_sectors sectors = get_sectors( longest_side ); // Get all of the overmaps within the defined radius of the center. - for( const auto &om : get_overmaps_near( omt_to_sm_copy( center ), omt_to_sm_copy( radius ) ) ) { + for( const auto &om : get_overmaps_near( + project_to( center ), omt_to_sm_copy( radius ) ) ) { // Build an overmap_special_batch for the special on this overmap. std::vector specials; @@ -1543,10 +1576,10 @@ bool overmapbuffer::place_special( const overmap_special_id &special_id, const t // Filter the sectors to those which are in in range of our center point, so // that we don't end up creating specials in areas that are outside of our radius, // since the whole point is to create a special that is within the parameters. - std::vector sector_points_in_range; + std::vector sector_points_in_range; std::copy_if( sectors.sectors.begin(), sectors.sectors.end(), - std::back_inserter( sector_points_in_range ), [&]( point & p ) { - const point global_sector_point = om->global_base_point() + p; + std::back_inserter( sector_points_in_range ), [&]( point_om_omt & p ) { + const point_abs_omt global_sector_point = project_combine( om->pos(), p ); // We'll include this sector if it's within our radius. We reduce the radius by // the length of the longest side of our special so that we don't end up in a // scenario where one overmap terrain of the special is within the radius but the diff --git a/src/overmapbuffer.h b/src/overmapbuffer.h index 99fb0b765ccea..bf4d5cfc365aa 100644 --- a/src/overmapbuffer.h +++ b/src/overmapbuffer.h @@ -11,6 +11,7 @@ #include #include +#include "coordinates.h" #include "enums.h" #include "memory_fast.h" #include "omdata.h" @@ -43,7 +44,7 @@ struct radio_tower_reference { /** The radio tower itself, points into @ref overmap::radios */ radio_tower *tower; /** The global absolute position of the tower (in submap coordinates) */ - point abs_sm_pos; + point_abs_sm abs_sm_pos; /** Perceived signal strength (tower output strength minus distance) */ int signal_strength; operator bool() const { @@ -56,7 +57,7 @@ struct city_reference { /** The city itself, points into @ref overmap::cities */ const struct city *city; /** The global absolute position of the city (in submap coordinates!) */ - tripoint abs_sm_pos; + tripoint_abs_sm abs_sm_pos; /** Distance to center of the search */ int distance; @@ -72,7 +73,7 @@ struct camp_reference { /** The camp itself, points into @ref overmap::camps */ basecamp *camp; /** The global absolute position of the camp (in submap coordinates!) */ - tripoint abs_sm_pos; + tripoint_abs_sm abs_sm_pos; /** Distance to center of the search */ int distance; @@ -85,7 +86,7 @@ struct camp_reference { struct overmap_with_local_coords { overmap *om; - tripoint local; + tripoint_om_omt local; bool operator!() const { return !om; @@ -124,47 +125,47 @@ class overmapbuffer public: overmapbuffer(); - static std::string terrain_filename( const point & ); - static std::string player_filename( const point & ); + static std::string terrain_filename( const point_abs_om & ); + static std::string player_filename( const point_abs_om & ); /** * Uses overmap coordinates, that means x and y are directly * compared with the position of the overmap. */ - overmap &get( const point & ); + overmap &get( const point_abs_om & ); void save(); void clear(); - void create_custom_overmap( const point &, overmap_special_batch &specials ); + void create_custom_overmap( const point_abs_om &, overmap_special_batch &specials ); /** * Uses global overmap terrain coordinates, creates the * overmap if needed. */ - const oter_id &ter( const tripoint &p ); - void ter_set( const tripoint &p, const oter_id &id ); + const oter_id &ter( const tripoint_abs_omt &p ); + void ter_set( const tripoint_abs_omt &p, const oter_id &id ); /** * Uses global overmap terrain coordinates. */ - bool has_note( const tripoint &p ); - bool is_marked_dangerous( const tripoint &p ); - const std::string ¬e( const tripoint &p ); - void add_note( const tripoint &, const std::string &message ); - void delete_note( const tripoint &p ); - void mark_note_dangerous( const tripoint &p, int radius, bool is_dangerous ); - bool has_extra( const tripoint &p ); - const string_id &extra( const tripoint &p ); - void add_extra( const tripoint &p, const string_id &id ); - void delete_extra( const tripoint &p ); - bool is_explored( const tripoint &p ); - void toggle_explored( const tripoint &p ); - bool seen( const tripoint &p ); - void set_seen( const tripoint &p, bool seen = true ); - bool has_camp( const tripoint &p ); - bool has_vehicle( const tripoint &p ); - bool has_horde( const tripoint &p ); - int get_horde_size( const tripoint &p ); - std::vector get_vehicle( const tripoint &p ); - const regional_settings &get_settings( const tripoint &p ); + bool has_note( const tripoint_abs_omt &p ); + bool is_marked_dangerous( const tripoint_abs_omt &p ); + const std::string ¬e( const tripoint_abs_omt &p ); + void add_note( const tripoint_abs_omt &, const std::string &message ); + void delete_note( const tripoint_abs_omt &p ); + void mark_note_dangerous( const tripoint_abs_omt &p, int radius, bool is_dangerous ); + bool has_extra( const tripoint_abs_omt &p ); + const string_id &extra( const tripoint_abs_omt &p ); + void add_extra( const tripoint_abs_omt &p, const string_id &id ); + void delete_extra( const tripoint_abs_omt &p ); + bool is_explored( const tripoint_abs_omt &p ); + void toggle_explored( const tripoint_abs_omt &p ); + bool seen( const tripoint_abs_omt &p ); + void set_seen( const tripoint_abs_omt &p, bool seen = true ); + bool has_camp( const tripoint_abs_omt &p ); + bool has_vehicle( const tripoint_abs_omt &p ); + bool has_horde( const tripoint_abs_omt &p ); + int get_horde_size( const tripoint_abs_omt &p ); + std::vector get_vehicle( const tripoint_abs_omt &p ); + const regional_settings &get_settings( const tripoint_abs_omt &p ); /** * Accessors for horde introspection into overmaps. * Probably also useful for NPC overmap-scale navigation. @@ -173,23 +174,23 @@ class overmapbuffer * Returns the 3x3 array of scent values surrounding the origin point. * @param origin is in world-global omt coordinates. */ - std::array, 3> scents_near( const tripoint &origin ); + std::array, 3> scents_near( const tripoint_abs_omt &origin ); /** * Method to retrieve the scent at a given location. **/ - scent_trace scent_at( const tripoint &pos ); + scent_trace scent_at( const tripoint_abs_omt &pos ); /** * Method to set a scent trace. * @param loc is in world-global omt coordinates. * @param strength sets the intensity of the scent trace, * used for determining if a monster can detect the scent. */ - void set_scent( const tripoint &loc, int strength ); + void set_scent( const tripoint_abs_omt &loc, int strength ); /** * Check for any dangerous monster groups at the global overmap terrain coordinates. * If there are any, it's not safe. */ - bool is_safe( const tripoint &p ); + bool is_safe( const tripoint_abs_omt &p ); /** * Move the tracking mark of the given vehicle. @@ -200,7 +201,7 @@ class overmapbuffer * used to remove the vehicle from the old overmap if the new position is * on another overmap. */ - void move_vehicle( vehicle *veh, const point &old_msp ); + void move_vehicle( vehicle *veh, const point_abs_ms &old_msp ); /** * Add the vehicle to be tracked in the overmap. */ @@ -218,7 +219,7 @@ class overmapbuffer */ void add_camp( const basecamp &camp ); - cata::optional find_camp( const point &p ); + cata::optional find_camp( const point_abs_omt &p ); /** * Get all npcs in a area with given radius around given central point. * Only npcs on the given z-level are considered. @@ -230,7 +231,7 @@ class overmapbuffer * specific submap. */ - std::vector> get_npcs_near( const tripoint &p, int radius ); + std::vector> get_npcs_near( const tripoint_abs_sm &p, int radius ); /** * Get all (currently loaded!) npcs that have a companion * mission set. @@ -242,7 +243,7 @@ class overmapbuffer * A radius of 0 returns all npcs that are on that specific * overmap terrain tile. */ - std::vector> get_npcs_near_omt( const tripoint &p, int radius ); + std::vector> get_npcs_near_omt( const tripoint_abs_omt &p, int radius ); /** * Same as @ref get_npcs_near(int,int,int,int) but uses * player position as center. @@ -277,11 +278,13 @@ class overmapbuffer * @param origin Location of search * see omt_find_params for definitions of the terms */ - std::vector find_all( const tripoint &origin, const omt_find_params ¶ms ); - std::vector find_all( const tripoint &origin, const std::string &type, - int dist, bool must_be_seen, ot_match_type match_type = ot_match_type::type, - bool existing_overmaps_only = false, - const cata::optional &om_special = cata::nullopt ); + std::vector find_all( const tripoint_abs_omt &origin, + const omt_find_params ¶ms ); + std::vector find_all( + const tripoint_abs_omt &origin, const std::string &type, + int dist, bool must_be_seen, ot_match_type match_type = ot_match_type::type, + bool existing_overmaps_only = false, + const cata::optional &om_special = cata::nullopt ); /** * Returns a random point of specific terrain type among those found in certain search @@ -290,11 +293,13 @@ class overmapbuffer * @param origin Location of search * see omt_find_params for definitions of the terms */ - tripoint find_random( const tripoint &origin, const omt_find_params ¶ms ); - tripoint find_random( const tripoint &origin, const std::string &type, - int dist, bool must_be_seen, ot_match_type match_type = ot_match_type::type, - bool existing_overmaps_only = false, - const cata::optional &om_special = cata::nullopt ); + tripoint_abs_omt find_random( const tripoint_abs_omt &origin, + const omt_find_params ¶ms ); + tripoint_abs_omt find_random( + const tripoint_abs_omt &origin, const std::string &type, int dist, + bool must_be_seen, ot_match_type match_type = ot_match_type::type, + bool existing_overmaps_only = false, + const cata::optional &om_special = cata::nullopt ); /** * Mark a square area around center on Z-level z * as seen. @@ -305,24 +310,27 @@ class overmapbuffer * @param z Z level to make area on * @return true if something has actually been revealed. */ - bool reveal( const point ¢er, int radius, int z ); - bool reveal( const tripoint ¢er, int radius ); - bool reveal( const tripoint ¢er, int radius, + bool reveal( const point_abs_omt ¢er, int radius, int z ); + bool reveal( const tripoint_abs_omt ¢er, int radius ); + bool reveal( const tripoint_abs_omt ¢er, int radius, const std::function &filter ); - std::vector get_npc_path( const tripoint &src, const tripoint &dest ); - std::vector get_npc_path( const tripoint &src, const tripoint &dest, path_type &ptype ); - bool reveal_route( const tripoint &source, const tripoint &dest, int radius = 0, - bool road_only = false ); + std::vector get_npc_path( const tripoint_abs_omt &src, + const tripoint_abs_omt &dest ); + std::vector get_npc_path( + const tripoint_abs_omt &src, const tripoint_abs_omt &dest, path_type &ptype ); + bool reveal_route( const tripoint_abs_omt &source, const tripoint_abs_omt &dest, + int radius = 0, bool road_only = false ); /** * Returns the closest point of terrain type. * @param origin Location of search * see omt_find_params for definitions of the terms */ - tripoint find_closest( const tripoint &origin, const omt_find_params ¶ms ); - tripoint find_closest( const tripoint &origin, const std::string &type, int radius, - bool must_be_seen, ot_match_type match_type = ot_match_type::type, - bool existing_overmaps_only = false, - const cata::optional &om_special = cata::nullopt ); + tripoint_abs_omt find_closest( const tripoint_abs_omt &origin, + const omt_find_params ¶ms ); + tripoint_abs_omt find_closest( + const tripoint_abs_omt &origin, const std::string &type, int radius, bool must_be_seen, + ot_match_type match_type = ot_match_type::type, bool existing_overmaps_only = false, + const cata::optional &om_special = cata::nullopt ); /* These functions return the overmap that contains the given * overmap terrain coordinate, and the local coordinates of that point @@ -332,32 +340,32 @@ class overmapbuffer * { nullptr, tripoint_zero }. * get_om_global creates a new overmap if needed. */ - overmap_with_local_coords get_existing_om_global( const point &p ); - overmap_with_local_coords get_existing_om_global( const tripoint &p ); - overmap_with_local_coords get_om_global( const point &p ); - overmap_with_local_coords get_om_global( const tripoint &p ); + overmap_with_local_coords get_existing_om_global( const point_abs_omt &p ); + overmap_with_local_coords get_existing_om_global( const tripoint_abs_omt &p ); + overmap_with_local_coords get_om_global( const point_abs_omt &p ); + overmap_with_local_coords get_om_global( const tripoint_abs_omt &p ); /** * Pass global overmap coordinates (same as @ref get). * @returns true if the buffer has a overmap with * the given coordinates. */ - bool has( const point &p ); + bool has( const point_abs_om &p ); /** * Get an existing overmap, does not create a new one * and may return NULL if the requested overmap does not * exist. * (x,y) are global overmap coordinates (same as @ref get). */ - overmap *get_existing( const point &p ); + overmap *get_existing( const point_abs_om &p ); /** * Returns whether or not the location has been generated (e.g. mapgen has run). * @param loc is in world-global omt coordinates. * @returns True if the location has been generated. */ - bool is_omt_generated( const tripoint &loc ); + bool is_omt_generated( const tripoint_abs_omt &loc ); - using t_point_with_note = std::pair; + using t_point_with_note = std::pair; using t_notes_vector = std::vector; t_notes_vector get_all_notes( int z ) { return get_notes( z, nullptr ); // NULL => don't filter notes @@ -365,7 +373,7 @@ class overmapbuffer t_notes_vector find_notes( int z, const std::string &pattern ) { return get_notes( z, &pattern ); // filter with pattern } - using t_point_with_extra = std::pair>; + using t_point_with_extra = std::pair>; using t_extras_vector = std::vector; t_extras_vector get_all_extras( int z ) { return get_extras( z, nullptr ); // NULL => don't filter extras @@ -379,7 +387,7 @@ class overmapbuffer * to there. In global submap coordinates. * @param sig_power The signal strength, higher values means it visible farther away. */ - void signal_hordes( const tripoint ¢er, int sig_power ); + void signal_hordes( const tripoint_abs_sm ¢er, int sig_power ); /** * Process nearby monstergroups (dying mostly). */ @@ -390,18 +398,18 @@ class overmapbuffer */ void move_hordes(); // hordes -- this uses overmap terrain coordinates! - std::vector monsters_at( const tripoint &p ); + std::vector monsters_at( const tripoint_abs_omt &p ); /** * Monster groups at p - absolute submap coordinates. * Groups with no population are not included. */ - std::vector groups_at( const tripoint &p ); + std::vector groups_at( const tripoint_abs_sm &p ); /** * Spawn monsters from the overmap onto the main map (game::m). * p is an absolute *submap* coordinate. */ - void spawn_monster( const tripoint &p ); + void spawn_monster( const tripoint_abs_sm &p ); /** * Despawn the monster back onto the overmap. The monsters position * (monster::pos()) is interpreted as relative to the main map. @@ -419,22 +427,22 @@ class overmapbuffer * All entries in the returned vector are valid (have a valid tower pointer). */ std::vector find_all_radio_stations(); - std::vector get_camps_near( const tripoint &location, int radius ); + std::vector get_camps_near( const tripoint_abs_sm &location, int radius ); /** * Find all cities within the specified @ref radius. * Result is sorted by proximity to @ref location in ascending order. */ - std::vector get_cities_near( const tripoint &location, int radius ); + std::vector get_cities_near( const tripoint_abs_sm &location, int radius ); /** * Find the closest city. If no city is close, returns an object with city set to nullptr. * @param center The center of the search, the distance for determining the closest city is * calculated as distance to this point. In global submap coordinates! */ - city_reference closest_city( const tripoint ¢er ); + city_reference closest_city( const tripoint_abs_sm ¢er ); - city_reference closest_known_city( const tripoint ¢er ); + city_reference closest_known_city( const tripoint_abs_sm ¢er ); - std::string get_description_at( const tripoint &where ); + std::string get_description_at( const tripoint_abs_sm &where ); /** * Place the specified overmap special directly on the map using the provided location and rotation. @@ -448,7 +456,7 @@ class overmapbuffer * @param force If true, placement will bypass the checks for valid placement. * @returns True if the special was placed, else false. */ - bool place_special( const overmap_special &special, const tripoint &p, + bool place_special( const overmap_special &special, const tripoint_abs_omt &p, om_direction::type dir, bool must_be_unexplored, bool force ); /** @@ -461,7 +469,8 @@ class overmapbuffer * @param radius Used in conjunction with center. Absolute overmap terrain units. * @returns True if the special was placed, else false. */ - bool place_special( const overmap_special_id &special_id, const tripoint ¢er, int radius ); + bool place_special( const overmap_special_id &special_id, const tripoint_abs_omt ¢er, + int radius ); private: /** @@ -470,14 +479,14 @@ class overmapbuffer * @param location Location of search * see omt_find_params for definitions of the terms */ - bool is_findable_location( const tripoint &location, const omt_find_params ¶ms ); + bool is_findable_location( const tripoint_abs_omt &location, const omt_find_params ¶ms ); - std::unordered_map< point, std::unique_ptr< overmap > > overmaps; + std::unordered_map< point_abs_om, std::unique_ptr< overmap > > overmaps; /** * Set of overmap coordinates of overmaps that are known * to not exist on disk. See @ref get_existing for usage. */ - mutable std::set known_non_existing; + mutable std::set known_non_existing; // Cached result of previous call to overmapbuffer::get_existing overmap mutable *last_requested_overmap; @@ -501,15 +510,18 @@ class overmapbuffer * overmap terrain coordinates. * This function may create a new overmap if needed. */ - bool check_ot( const std::string &otype, ot_match_type match_type, const tripoint &p ); - bool check_overmap_special_type( const overmap_special_id &id, const tripoint &loc ); + bool check_ot( const std::string &otype, ot_match_type match_type, + const tripoint_abs_omt &p ); + bool check_overmap_special_type( const overmap_special_id &id, const tripoint_abs_omt &loc ); /** * These versions of the check_* methods will only check existing overmaps, and * return false if the overmap doesn't exist. They do not create new overmaps. */ - bool check_ot_existing( const std::string &otype, ot_match_type match_type, const tripoint &loc ); - bool check_overmap_special_type_existing( const overmap_special_id &id, const tripoint &loc ); + bool check_ot_existing( const std::string &otype, ot_match_type match_type, + const tripoint_abs_omt &loc ); + bool check_overmap_special_type_existing( const overmap_special_id &id, + const tripoint_abs_omt &loc ); private: /** * Go thorough the monster groups of the overmap and move out-of-bounds @@ -525,8 +537,8 @@ class overmapbuffer * The location is in absolute submap coordinates, the radius is in the same system. * The overmaps are returned sorted by distance from the provided location (closest first). */ - std::vector get_overmaps_near( const point &p, int radius ); - std::vector get_overmaps_near( const tripoint &location, int radius ); + std::vector get_overmaps_near( const point_abs_sm &p, int radius ); + std::vector get_overmaps_near( const tripoint_abs_sm &location, int radius ); }; extern overmapbuffer overmap_buffer; diff --git a/src/panels.cpp b/src/panels.cpp index 8cfe448a708e2..47868985ce6d7 100644 --- a/src/panels.cpp +++ b/src/panels.cpp @@ -209,18 +209,18 @@ std::string window_panel::get_name() const } void overmap_ui::draw_overmap_chunk( const catacurses::window &w_minimap, const avatar &you, - const tripoint &global_omt, const point &start_input, + const tripoint_abs_omt &global_omt, const point &start_input, const int width, const int height ) { - const point curs( global_omt.xy() ); - const tripoint targ = you.get_active_mission_target(); + const point_abs_omt curs = global_omt.xy(); + const tripoint_abs_omt targ = you.get_active_mission_target(); bool drew_mission = targ == overmap::invalid_tripoint; const int start_y = start_input.y + ( height / 2 ) - 2; const int start_x = start_input.x + ( width / 2 ) - 2; for( int i = -( width / 2 ); i <= width - ( width / 2 ) - 1; i++ ) { for( int j = -( height / 2 ); j <= height - ( height / 2 ) - 1; j++ ) { - const tripoint omp( curs.x + i, curs.y + j, g->get_levz() ); + const tripoint_abs_omt omp( curs + point( i, j ), g->get_levz() ); nc_color ter_color; std::string ter_sym; const bool seen = overmap_buffer.seen( omp ); @@ -347,11 +347,11 @@ void overmap_ui::draw_overmap_chunk( const catacurses::window &w_minimap, const // Print arrow to mission if we have one! if( !drew_mission ) { - double slope = ( curs.x != targ.x ) ? static_cast( targ.y - curs.y ) / static_cast - ( targ.x - curs.x ) : 4; + double slope = curs.x() != targ.x() ? + static_cast( targ.y() - curs.y() ) / ( targ.x() - curs.x() ) : 4; - if( curs.x == targ.x || std::fabs( slope ) > 3.5 ) { // Vertical slope - if( targ.y > curs.y ) { + if( curs.x() == targ.x() || std::fabs( slope ) > 3.5 ) { // Vertical slope + if( targ.y() > curs.y() ) { mvwputch( w_minimap, point( 3 + start_x, 6 + start_y ), c_red, '*' ); } else { mvwputch( w_minimap, point( 3 + start_x, 0 + start_y ), c_red, '*' ); @@ -360,8 +360,8 @@ void overmap_ui::draw_overmap_chunk( const catacurses::window &w_minimap, const int arrowx = -1; int arrowy = -1; if( std::fabs( slope ) >= 1. ) { // y diff is bigger! - arrowy = ( targ.y > curs.y ? 6 : 0 ); - arrowx = static_cast( 3 + 3 * ( targ.y > curs.y ? slope : ( 0 - slope ) ) ); + arrowy = ( targ.y() > curs.y() ? 6 : 0 ); + arrowx = static_cast( 3 + 3 * ( targ.y() > curs.y() ? slope : ( 0 - slope ) ) ); if( arrowx < 0 ) { arrowx = 0; } @@ -369,8 +369,8 @@ void overmap_ui::draw_overmap_chunk( const catacurses::window &w_minimap, const arrowx = 6; } } else { - arrowx = ( targ.x > curs.x ? 6 : 0 ); - arrowy = static_cast( 3 + 3 * ( targ.x > curs.x ? slope : ( 0 - slope ) ) ); + arrowx = ( targ.x() > curs.x() ? 6 : 0 ); + arrowy = static_cast( 3 + 3 * ( targ.x() > curs.x() ? slope : ( 0 - slope ) ) ); if( arrowy < 0 ) { arrowy = 0; } @@ -379,9 +379,9 @@ void overmap_ui::draw_overmap_chunk( const catacurses::window &w_minimap, const } } char glyph = '*'; - if( targ.z > you.posz() ) { + if( targ.z() > you.posz() ) { glyph = '^'; - } else if( targ.z < you.posz() ) { + } else if( targ.z() < you.posz() ) { glyph = 'v'; } @@ -396,7 +396,7 @@ void overmap_ui::draw_overmap_chunk( const catacurses::window &w_minimap, const if( i > -3 && i < 3 && j > -3 && j < 3 ) { continue; // only do hordes on the border, skip inner map } - const tripoint omp( curs.x + i, curs.y + j, g->get_levz() ); + const tripoint_abs_omt omp( curs + point( i, j ), g->get_levz() ); int horde_size = overmap_buffer.get_horde_size( omp ); if( horde_size >= HORDE_VISIBILITY_SIZE ) { if( overmap_buffer.seen( omp ) @@ -411,7 +411,7 @@ void overmap_ui::draw_overmap_chunk( const catacurses::window &w_minimap, const static void draw_minimap( const avatar &u, const catacurses::window &w_minimap ) { - const tripoint curs = u.global_omt_location(); + const tripoint_abs_omt curs = u.global_omt_location(); overmap_ui::draw_overmap_chunk( w_minimap, u, curs, point_zero, 5, 5 ); } @@ -1351,7 +1351,7 @@ static void draw_loc_labels( const avatar &u, const catacurses::window &w, bool } if( minimap ) { const int offset = getmaxx( w ) - 6; - const tripoint curs = u.global_omt_location(); + const tripoint_abs_omt curs = u.global_omt_location(); overmap_ui::draw_overmap_chunk( w, u, curs, point( offset, -1 ), 5, 5 ); } wnoutrefresh( w ); diff --git a/src/panels.h b/src/panels.h index 45c9b06cf0ebf..d3d64a22bc59b 100644 --- a/src/panels.h +++ b/src/panels.h @@ -8,6 +8,8 @@ #include #include +#include "coordinates.h" + class avatar; class JsonIn; class JsonOut; @@ -30,7 +32,7 @@ enum face_type : int { namespace overmap_ui { void draw_overmap_chunk( const catacurses::window &w_minimap, const avatar &you, - const tripoint &global_omt, const point &start, int width, + const tripoint_abs_omt &global_omt, const point &start, int width, int height ); } // namespace overmap_ui diff --git a/src/player.cpp b/src/player.cpp index 664e7fcd5465b..b83f0d6bd7851 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -400,8 +400,8 @@ void player::process_turn() if( !is_npc() && ( has_trait( trait_NOMAD ) || has_trait( trait_NOMAD2 ) || has_trait( trait_NOMAD3 ) ) && !has_effect( effect_sleep ) && !has_effect( effect_narcosis ) ) { - const tripoint ompos = global_omt_location(); - const point pos = ompos.xy(); + const tripoint_abs_omt ompos = global_omt_location(); + const point_abs_omt pos = ompos.xy(); if( overmap_time.find( pos ) == overmap_time.end() ) { overmap_time[pos] = 1_turns; } else { @@ -410,7 +410,7 @@ void player::process_turn() } // Decay time spent in other overmap tiles. if( !is_npc() && calendar::once_every( 1_hours ) ) { - const tripoint ompos = global_omt_location(); + const tripoint_abs_omt ompos = global_omt_location(); const time_point now = calendar::turn; time_duration decay_time = 0_days; if( has_trait( trait_NOMAD ) ) { @@ -422,12 +422,12 @@ void player::process_turn() } auto it = overmap_time.begin(); while( it != overmap_time.end() ) { - if( it->first.x == ompos.x && it->first.y == ompos.y ) { + if( it->first == ompos.xy() ) { it++; continue; } // Find the amount of time passed since the player touched any of the overmap tile's submaps. - const tripoint tpt = tripoint( it->first, 0 ); + const tripoint_abs_omt tpt( it->first, 0 ); const time_point last_touched = overmap_buffer.scent_at( tpt ).creation_time; const time_duration since_visit = now - last_touched; // If the player has spent little time in this overmap tile, let it decay after just an hour instead of the usual extended decay time. diff --git a/src/player.h b/src/player.h index 001a8a0ec2a93..1e9866ee586cc 100644 --- a/src/player.h +++ b/src/player.h @@ -564,8 +564,6 @@ class player : public Character */ void disarm( npc &target ); - std::set camps; - protected: void store( JsonOut &json ) const; diff --git a/src/point.h b/src/point.h index 2dcd7a3eebd20..1dd4d5ea39f3b 100644 --- a/src/point.h +++ b/src/point.h @@ -127,10 +127,14 @@ struct point { inline int divide_round_to_minus_infinity( int n, int d ) { + // The NOLINT comments here are to suppress a clang-tidy warning that seems + // to be a clang-tidy bug. I'd like to get rid of them if the bug is ever + // fixed. The warning comes via a project_remain call in + // mission_companion.cpp. if( n >= 0 ) { - return n / d; + return n / d; // NOLINT(clang-analyzer-core.DivideZero) } - return ( n - d + 1 ) / d; + return ( n - d + 1 ) / d; // NOLINT(clang-analyzer-core.DivideZero) } inline point multiply_xy( const point &p, int f ) diff --git a/src/rng.h b/src/rng.h index b98d2461d317e..5d364404aa3c5 100644 --- a/src/rng.h +++ b/src/rng.h @@ -11,7 +11,11 @@ #include "optional.h" +class map; class time_duration; +template +class tripoint_range; +struct tripoint; // All PRNG functions use an engine, see the C++11 header // By default, that engine is seeded by time on first call to such a function. @@ -159,10 +163,6 @@ inline V random_entry_removed( C &container ) container.erase( iter ); return result; } -class map; -template -class tripoint_range; -struct tripoint; /// Returns a range enclosing all valid points of the map. tripoint_range points_in_range( const map &m ); diff --git a/src/savegame.cpp b/src/savegame.cpp index f0c2d207e9ffe..eb0ce8e3244fb 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -334,11 +334,12 @@ bool overmap::obsolete_terrain( const std::string &ter ) * Complex conversion of outdated overmap terrain ids. * This is used when loading saved games with old oter_ids. */ -void overmap::convert_terrain( const std::unordered_map &needs_conversion ) +void overmap::convert_terrain( + const std::unordered_map &needs_conversion ) { - std::vector bridge_points; + std::vector bridge_points; for( const auto &convert : needs_conversion ) { - const tripoint pos = convert.first; + const tripoint_om_omt pos = convert.first; const std::string old = convert.second; struct convert_nearby { @@ -357,7 +358,7 @@ void overmap::convert_terrain( const std::unordered_map & ter_set( pos, oter_id( old + "_north" ) ); } else if( old.compare( 0, 6, "bridge" ) == 0 ) { ter_set( pos, oter_id( old ) ); - const oter_id oter_ground = ter( tripoint( pos.xy(), 0 ) ); + const oter_id oter_ground = ter( tripoint_om_omt( pos.xy(), 0 ) ); const oter_id oter_above = ter( pos + tripoint_above ); if( is_ot_match( "bridge", oter_ground, ot_match_type::type ) && !is_ot_match( "bridge_road", oter_above, ot_match_type::type ) ) { @@ -396,7 +397,7 @@ void overmap::load_monster_groups( JsonIn &jsin ) new_group.deserialize( jsin ); jsin.start_array(); - tripoint temp; + tripoint_om_sm temp; while( !jsin.end_array() ) { temp.deserialize( jsin ); new_group.pos = temp; @@ -426,7 +427,7 @@ void overmap::unserialize( std::istream &fin ) while( !jsin.end_object() ) { const std::string name = jsin.get_member_name(); if( name == "layers" ) { - std::unordered_map needs_conversion; + std::unordered_map needs_conversion; jsin.start_array(); for( int z = 0; z < OVERMAP_LAYERS; ++z ) { jsin.start_array(); @@ -442,8 +443,8 @@ void overmap::unserialize( std::istream &fin ) jsin.end_array(); if( obsolete_terrain( tmp_ter ) ) { for( int p = i; p < i + count; p++ ) { - needs_conversion.emplace( tripoint( p, j, z - OVERMAP_DEPTH ), - tmp_ter ); + needs_conversion.emplace( + tripoint_om_omt( p, j, z - OVERMAP_DEPTH ), tmp_ter ); } tmp_otid = oter_id( 0 ); } else if( oter_str_id( tmp_ter ).is_valid() ) { @@ -485,9 +486,9 @@ void overmap::unserialize( std::istream &fin ) if( city_member_name == "name" ) { jsin.read( new_city.name ); } else if( city_member_name == "x" ) { - jsin.read( new_city.pos.x ); + jsin.read( new_city.pos.x() ); } else if( city_member_name == "y" ) { - jsin.read( new_city.pos.y ); + jsin.read( new_city.pos.y() ); } else if( city_member_name == "size" ) { jsin.read( new_city.size ); } @@ -499,17 +500,18 @@ void overmap::unserialize( std::istream &fin ) } else if( name == "roads_out" ) { // Legacy data, superceded by that stored in the "connections_out" member. A load and save // cycle will migrate this to "connections_out". - std::vector &roads_out = connections_out[string_id( "local_road" )]; + std::vector &roads_out = + connections_out[string_id( "local_road" )]; jsin.start_array(); while( !jsin.end_array() ) { jsin.start_object(); - tripoint new_road; + tripoint_om_omt new_road; while( !jsin.end_object() ) { std::string road_member_name = jsin.get_member_name(); if( road_member_name == "x" ) { - jsin.read( new_road.x ); + jsin.read( new_road.x() ); } else if( road_member_name == "y" ) { - jsin.read( new_road.y ); + jsin.read( new_road.y() ); } } roads_out.push_back( new_road ); @@ -518,7 +520,7 @@ void overmap::unserialize( std::istream &fin ) jsin.start_array(); while( !jsin.end_array() ) { jsin.start_object(); - radio_tower new_radio( point_min ); + radio_tower new_radio{ point_om_sm( point_min ) }; while( !jsin.end_object() ) { const std::string radio_member_name = jsin.get_member_name(); if( radio_member_name == "type" ) { @@ -532,9 +534,9 @@ void overmap::unserialize( std::istream &fin ) new_radio.type = mapping->first; } } else if( radio_member_name == "x" ) { - jsin.read( new_radio.pos.x ); + jsin.read( new_radio.pos.x() ); } else if( radio_member_name == "y" ) { - jsin.read( new_radio.pos.y ); + jsin.read( new_radio.pos.y() ); } else if( radio_member_name == "strength" ) { jsin.read( new_radio.strength ); } else if( radio_member_name == "message" ) { @@ -546,7 +548,7 @@ void overmap::unserialize( std::istream &fin ) } else if( name == "monster_map" ) { jsin.start_array(); while( !jsin.end_array() ) { - tripoint monster_location; + tripoint_om_sm monster_location; monster new_monster; monster_location.deserialize( jsin ); new_monster.deserialize( jsin ); @@ -564,9 +566,9 @@ void overmap::unserialize( std::istream &fin ) if( tracker_member_name == "id" ) { jsin.read( id ); } else if( tracker_member_name == "x" ) { - jsin.read( new_tracker.p.x ); + jsin.read( new_tracker.p.x() ); } else if( tracker_member_name == "y" ) { - jsin.read( new_tracker.p.y ); + jsin.read( new_tracker.p.y() ); } else if( tracker_member_name == "name" ) { jsin.read( new_tracker.name ); } @@ -577,7 +579,7 @@ void overmap::unserialize( std::istream &fin ) jsin.start_array(); while( !jsin.end_array() ) { jsin.start_object(); - tripoint pos; + tripoint_abs_omt pos; time_point time = calendar::before_time_starts; int strength = 0; while( !jsin.end_object() ) { @@ -628,7 +630,7 @@ void overmap::unserialize( std::istream &fin ) jsin.start_array(); while( !jsin.end_array() ) { jsin.start_object(); - tripoint p; + tripoint_om_omt p; while( !jsin.end_object() ) { std::string name = jsin.get_member_name(); if( name == "p" ) { @@ -696,8 +698,8 @@ void overmap::unserialize_view( std::istream &fin ) while( !jsin.end_array() ) { om_note tmp; jsin.start_array(); - jsin.read( tmp.p.x ); - jsin.read( tmp.p.y ); + jsin.read( tmp.p.x() ); + jsin.read( tmp.p.y() ); jsin.read( tmp.text ); jsin.read( tmp.dangerous ); jsin.read( tmp.danger_radius ); @@ -714,8 +716,8 @@ void overmap::unserialize_view( std::istream &fin ) while( !jsin.end_array() ) { om_map_extra tmp; jsin.start_array(); - jsin.read( tmp.p.x ); - jsin.read( tmp.p.y ); + jsin.read( tmp.p.x() ); + jsin.read( tmp.p.y() ); jsin.read( tmp.id ); jsin.end_array(); @@ -786,8 +788,8 @@ void overmap::serialize_view( std::ostream &fout ) const json.start_array(); for( auto &i : layer[z].notes ) { json.start_array(); - json.write( i.p.x ); - json.write( i.p.y ); + json.write( i.p.x() ); + json.write( i.p.y() ); json.write( i.text ); json.write( i.dangerous ); json.write( i.danger_radius ); @@ -804,8 +806,8 @@ void overmap::serialize_view( std::ostream &fout ) const json.start_array(); for( auto &i : layer[z].extras ) { json.start_array(); - json.write( i.p.x ); - json.write( i.p.y ); + json.write( i.p.x() ); + json.write( i.p.y() ); json.write( i.id ); json.end_array(); fout << std::endl; @@ -856,12 +858,13 @@ void overmap::save_monster_groups( JsonOut &jout ) const jout.member( "monster_groups" ); jout.start_array(); // Bin groups by their fields, except positions and monsters - std::unordered_map, mongroup_hash, mongroup_bin_eq> binned_groups; + std::unordered_map, mongroup_hash, mongroup_bin_eq> + binned_groups; binned_groups.reserve( zg.size() ); for( const auto &pos_group : zg ) { // Each group in bin adds only position // so that 100 identical groups are 1 group data and 100 tripoints - std::list &positions = binned_groups[pos_group.second]; + std::list &positions = binned_groups[pos_group.second]; positions.emplace_back( pos_group.first ); } @@ -871,7 +874,7 @@ void overmap::save_monster_groups( JsonOut &jout ) const // The position is stored separately, in the list // TODO: Do it without the copy mongroup saved_group = group_bin.first; - saved_group.pos = tripoint_zero; + saved_group.pos = tripoint_om_sm(); jout.write( saved_group ); jout.write( group_bin.second ); jout.end_array(); @@ -933,8 +936,8 @@ void overmap::serialize( std::ostream &fout ) const for( auto &i : cities ) { json.start_object(); json.member( "name", i.name ); - json.member( "x", i.pos.x ); - json.member( "y", i.pos.y ); + json.member( "x", i.pos.x() ); + json.member( "y", i.pos.y() ); json.member( "size", i.size ); json.end_object(); } @@ -948,8 +951,8 @@ void overmap::serialize( std::ostream &fout ) const json.start_array(); for( auto &i : radios ) { json.start_object(); - json.member( "x", i.pos.x ); - json.member( "y", i.pos.y ); + json.member( "x", i.pos.x() ); + json.member( "y", i.pos.y() ); json.member( "strength", i.strength ); json.member( "type", radio_type_names[i.type] ); json.member( "message", i.message ); @@ -973,8 +976,8 @@ void overmap::serialize( std::ostream &fout ) const json.start_object(); json.member( "id", i.first ); json.member( "name", i.second.name ); - json.member( "x", i.second.p.x ); - json.member( "y", i.second.p.y ); + json.member( "x", i.second.p.x() ); + json.member( "y", i.second.p.y() ); json.end_object(); } json.end_array(); @@ -1010,7 +1013,7 @@ void overmap::serialize( std::ostream &fout ) const // Condense the overmap special placements so that all placements of a given special // are grouped under a single key for that special. - std::map> condensed_overmap_special_placements; + std::map> condensed_overmap_special_placements; for( const auto &placement : overmap_special_placements ) { condensed_overmap_special_placements[placement.second].emplace_back( placement.first ); } @@ -1028,7 +1031,7 @@ void overmap::serialize( std::ostream &fout ) const json.start_object(); json.member( "points" ); json.start_array(); - for( const tripoint &pos : placement.second ) { + for( const tripoint_om_omt &pos : placement.second ) { json.start_object(); json.member( "p", pos ); json.end_object(); @@ -1051,13 +1054,13 @@ template void mongroup::io( Archive &archive ) { archive.io( "type", type ); - archive.io( "pos", pos, tripoint_zero ); + archive.io( "pos", pos, tripoint_om_sm() ); archive.io( "radius", radius, 1u ); archive.io( "population", population, 1u ); archive.io( "diffuse", diffuse, false ); archive.io( "dying", dying, false ); archive.io( "horde", horde, false ); - archive.io( "target", target, tripoint_zero ); + archive.io( "target", target, tripoint_om_sm() ); archive.io( "interest", interest, 0 ); archive.io( "horde_behaviour", horde_behaviour, io::empty_default_tag() ); archive.io( "monsters", monsters, io::empty_default_tag() ); diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 43fcb62ea783b..61d81dea4f957 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -823,7 +823,7 @@ void Character::load( const JsonObject &data ) JsonArray overmap_time_array = data.get_array( "overmap_time" ); overmap_time.clear(); while( overmap_time_array.has_more() ) { - point pt; + point_abs_omt pt; overmap_time_array.read_next( pt ); time_duration tdr = 0_turns; overmap_time_array.read_next( tdr ); @@ -956,7 +956,7 @@ void Character::store( JsonOut &json ) const if( !overmap_time.empty() ) { json.member( "overmap_time" ); json.start_array(); - for( const std::pair &pr : overmap_time ) { + for( const std::pair &pr : overmap_time ) { json.write( pr.first ); json.write( pr.second ); } @@ -1047,7 +1047,7 @@ void player::store( JsonOut &json ) const json.member( "camps" ); json.start_array(); - for( const tripoint &bcpt : camps ) { + for( const tripoint_abs_omt &bcpt : camps ) { json.start_object(); json.member( "pos", bcpt ); json.end_object(); @@ -1134,7 +1134,7 @@ void player::load( const JsonObject &data ) data.read( "destination_point", destination_point ); camps.clear(); for( JsonObject bcdata : data.get_array( "camps" ) ) { - tripoint bcpt; + tripoint_abs_omt bcpt; bcdata.read( "pos", bcpt ); camps.insert( bcpt ); } @@ -1625,7 +1625,7 @@ void npc::load( const JsonObject &data ) std::string facID; std::string comp_miss_id; std::string comp_miss_role; - tripoint comp_miss_pt; + tripoint_abs_omt comp_miss_pt; std::string classid; std::string companion_mission_role; time_point companion_mission_t = 0; @@ -1679,9 +1679,9 @@ void npc::load( const JsonObject &data ) data.read( "last_player_seen_pos", last_player_seen_pos ); } - data.read( "goalx", goal.x ); - data.read( "goaly", goal.y ); - data.read( "goalz", goal.z ); + data.read( "goalx", goal.x() ); + data.read( "goaly", goal.y() ); + data.read( "goalz", goal.z() ); data.read( "guardx", guard_pos.x ); data.read( "guardy", guard_pos.y ); @@ -1780,7 +1780,7 @@ void npc::load( const JsonObject &data ) companion_mission_role_id = companion_mission_role; } - std::vector companion_mission_pts; + std::vector companion_mission_pts; data.read( "companion_mission_points", companion_mission_pts ); if( !companion_mission_pts.empty() ) { for( auto pt : companion_mission_pts ) { @@ -1861,9 +1861,9 @@ void npc::store( JsonOut &json ) const json.member( "last_player_seen_pos", last_player_seen_pos ); - json.member( "goalx", goal.x ); - json.member( "goaly", goal.y ); - json.member( "goalz", goal.z ); + json.member( "goalx", goal.x() ); + json.member( "goaly", goal.y() ); + json.member( "goalz", goal.z() ); json.member( "guardx", guard_pos.x ); json.member( "guardy", guard_pos.y ); @@ -3042,12 +3042,12 @@ void mission::deserialize( JsonIn &jsin ) jo.read( "uid", uid ); JsonArray ja = jo.get_array( "target" ); if( ja.size() == 3 ) { - target.x = ja.get_int( 0 ); - target.y = ja.get_int( 1 ); - target.z = ja.get_int( 2 ); + target.x() = ja.get_int( 0 ); + target.y() = ja.get_int( 1 ); + target.z() = ja.get_int( 2 ); } else if( ja.size() == 2 ) { - target.x = ja.get_int( 0 ); - target.y = ja.get_int( 1 ); + target.x() = ja.get_int( 0 ); + target.y() = ja.get_int( 1 ); } if( jo.has_int( "follow_up" ) ) { @@ -3103,9 +3103,9 @@ void mission::serialize( JsonOut &json ) const json.member( "target" ); json.start_array(); - json.write( target.x ); - json.write( target.y ); - json.write( target.z ); + json.write( target.x() ); + json.write( target.y() ); + json.write( target.z() ); json.end_array(); json.member( "item_id", item_id ); @@ -3564,7 +3564,7 @@ static void deserialize( quality_requirement &value, JsonIn &jsin ) // basecamp void basecamp::serialize( JsonOut &json ) const { - if( omt_pos != tripoint_zero ) { + if( omt_pos != tripoint_abs_omt() ) { json.start_object(); json.member( "name", name ); json.member( "pos", omt_pos ); @@ -3656,7 +3656,7 @@ void basecamp::deserialize( JsonIn &jsin ) } } for( JsonObject edata : data.get_array( "fortifications" ) ) { - tripoint restore_pos; + tripoint_abs_omt restore_pos; edata.read( "pos", restore_pos ); fortifications.push_back( restore_pos ); } diff --git a/src/simple_pathfinding.h b/src/simple_pathfinding.h index 1afdc3a7163f1..2d49bb2b7985e 100644 --- a/src/simple_pathfinding.h +++ b/src/simple_pathfinding.h @@ -15,7 +15,7 @@ namespace pf static const int rejected = std::numeric_limits::min(); -template +template struct node { Point pos; int dir; diff --git a/src/sounds.cpp b/src/sounds.cpp index c12da23fb3722..b40b5b1c883cd 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -315,8 +315,9 @@ void sounds::process_sounds() if( sig_power > 0 ) { const point abs_ms = get_map().getabs( source.xy() ); - const point abs_sm = ms_to_sm_copy( abs_ms ); - const tripoint target( abs_sm, source.z ); + // TODO: fix point types + const point_abs_sm abs_sm( ms_to_sm_copy( abs_ms ) ); + const tripoint_abs_sm target( abs_sm, source.z ); overmap_buffer.signal_hordes( target, sig_power ); } // Alert all monsters (that can hear) to the sound. diff --git a/src/start_location.cpp b/src/start_location.cpp index 17060dc6a3d2d..e6e157b80932c 100644 --- a/src/start_location.cpp +++ b/src/start_location.cpp @@ -7,6 +7,7 @@ #include "avatar.h" #include "calendar.h" #include "coordinate_conversions.h" +#include "coordinates.h" #include "debug.h" #include "enum_conversions.h" #include "field_type.h" @@ -195,16 +196,16 @@ void start_location::prepare_map( tinymap &m ) const } } -tripoint start_location::find_player_initial_location() const +tripoint_abs_omt start_location::find_player_initial_location() const { // Spiral out from the world origin scanning for a compatible starting location, // creating overmaps as necessary. const int radius = 3; - for( const point &omp : closest_points_first( point_zero, radius ) ) { + for( const point_abs_om &omp : closest_points_first( point_abs_om(), radius ) ) { overmap &omap = overmap_buffer.get( omp ); - const tripoint omtstart = omap.find_random_omt( random_target() ); - if( omtstart != overmap::invalid_tripoint ) { - return omtstart + point( omp.x * OMAPX, omp.y * OMAPY ); + const tripoint_om_omt omtstart = omap.find_random_omt( random_target() ); + if( omtstart.raw() != tripoint_min ) { + return project_combine( omp, omtstart ); } } // Should never happen, if it does we messed up. @@ -212,12 +213,13 @@ tripoint start_location::find_player_initial_location() const return overmap::invalid_tripoint; } -void start_location::prepare_map( const tripoint &omtstart ) const +void start_location::prepare_map( const tripoint_abs_omt &omtstart ) const { // Now prepare the initial map (change terrain etc.) - const point player_location = omt_to_sm_copy( omtstart.xy() ); + const tripoint_abs_sm player_location = project_to( omtstart ); tinymap player_start; - player_start.load( tripoint( player_location, omtstart.z ), false ); + // TODO: fix point types + player_start.load( player_location.raw(), false ); prepare_map( player_start ); player_start.save(); } @@ -350,9 +352,10 @@ void start_location::place_player( player &u ) const } } -void start_location::burn( const tripoint &omtstart, const size_t count, const int rad ) const +void start_location::burn( const tripoint_abs_omt &omtstart, const size_t count, + const int rad ) const { - const tripoint player_location = omt_to_sm_copy( omtstart ); + const tripoint_abs_sm player_location = project_to( omtstart ); tinymap m; m.load( player_location, false ); m.build_outside_cache( m.get_abs_sub().z ); @@ -376,13 +379,15 @@ void start_location::burn( const tripoint &omtstart, const size_t count, const i m.save(); } -void start_location::add_map_extra( const tripoint &omtstart, const std::string &map_extra ) const +void start_location::add_map_extra( const tripoint_abs_omt &omtstart, + const std::string &map_extra ) const { - const tripoint player_location = omt_to_sm_copy( omtstart ); + const tripoint_abs_sm player_location = project_to( omtstart ); tinymap m; m.load( player_location, false ); - MapExtras::apply_function( map_extra, m, player_location ); + // TODO: fix point types + MapExtras::apply_function( map_extra, m, player_location.raw() ); m.save(); } @@ -417,9 +422,10 @@ void start_location::handle_heli_crash( player &u ) const } } -static void add_monsters( const tripoint &omtstart, const mongroup_id &type, float expected_points ) +static void add_monsters( const tripoint_abs_omt &omtstart, const mongroup_id &type, + float expected_points ) { - const tripoint spawn_location = omt_to_sm_copy( omtstart ); + const tripoint_abs_sm spawn_location = project_to( omtstart ); tinymap m; m.load( spawn_location, false ); // map::place_spawns internally multiplies density by rng(10, 50) @@ -428,10 +434,10 @@ static void add_monsters( const tripoint &omtstart, const mongroup_id &type, flo m.save(); } -void start_location::surround_with_monsters( const tripoint &omtstart, const mongroup_id &type, - float expected_points ) const +void start_location::surround_with_monsters( + const tripoint_abs_omt &omtstart, const mongroup_id &type, float expected_points ) const { - for( const tripoint &p : points_in_radius( omtstart, 1 ) ) { + for( const tripoint_abs_omt &p : points_in_radius( omtstart, 1 ) ) { if( p != omtstart ) { add_monsters( p, type, roll_remainder( expected_points / 8.0f ) ); } diff --git a/src/start_location.h b/src/start_location.h index d28829d4bbb5b..7b0ca539a80cf 100644 --- a/src/start_location.h +++ b/src/start_location.h @@ -9,6 +9,7 @@ #include #include +#include "coordinates.h" #include "enums.h" #include "translations.h" #include "type_id.h" @@ -38,12 +39,12 @@ class start_location * It may return `overmap::invalid_tripoint` if no suitable starting location could be found * in the world. */ - tripoint find_player_initial_location() const; + tripoint_abs_omt find_player_initial_location() const; /** * Initialize the map at players start location using @ref prepare_map. * @param omtstart Global overmap terrain coordinates where the player is to be spawned. */ - void prepare_map( const tripoint &omtstart ) const; + void prepare_map( const tripoint_abs_omt &omtstart ) const; /** * Place the player somewhere in the reality bubble (g->m). */ @@ -55,11 +56,11 @@ class start_location * @param rad safe radius area to prevent player spawn next to burning wall. * @param count number of fire on the map. */ - void burn( const tripoint &omtstart, size_t count, int rad ) const; + void burn( const tripoint_abs_omt &omtstart, size_t count, int rad ) const; /** * Adds a map extra, see map_extras.h and map_extras.cpp. Look at the namespace MapExtras and class map_extras. */ - void add_map_extra( const tripoint &omtstart, const std::string &map_extra ) const; + void add_map_extra( const tripoint_abs_omt &omtstart, const std::string &map_extra ) const; void handle_heli_crash( player &u ) const; @@ -67,7 +68,7 @@ class start_location * Adds surround start monsters. * @param expected_points Expected value of "monster points" (map tiles times density from @ref map::place_spawns). */ - void surround_with_monsters( const tripoint &omtstart, const mongroup_id &type, + void surround_with_monsters( const tripoint_abs_omt &omtstart, const mongroup_id &type, float expected_points ) const; private: translation _name; diff --git a/src/talker.h b/src/talker.h index 3c5196243bf7c..586ca95e0400a 100644 --- a/src/talker.h +++ b/src/talker.h @@ -51,7 +51,7 @@ class talker virtual int posy() const = 0; virtual int posz() const = 0; virtual tripoint pos() const = 0; - virtual tripoint global_omt_location() const = 0; + virtual tripoint_abs_omt global_omt_location() const = 0; virtual std::string distance_to_goal() const { return ""; } diff --git a/src/talker_character.cpp b/src/talker_character.cpp index 11e71f4291170..59309b98da434 100644 --- a/src/talker_character.cpp +++ b/src/talker_character.cpp @@ -62,7 +62,7 @@ tripoint talker_character::pos() const return me_chr->pos(); } -tripoint talker_character::global_omt_location() const +tripoint_abs_omt talker_character::global_omt_location() const { return me_chr->global_omt_location(); } diff --git a/src/talker_character.h b/src/talker_character.h index 105c6bc3a979c..06dcdc64ded16 100644 --- a/src/talker_character.h +++ b/src/talker_character.h @@ -39,7 +39,7 @@ class talker_character: public talker int posy() const override; int posz() const override; tripoint pos() const override; - tripoint global_omt_location() const override; + tripoint_abs_omt global_omt_location() const override; // stats, skills, traits, bionics, and magic int str_cur() const override; diff --git a/src/trapfunc.cpp b/src/trapfunc.cpp index 4c5e8436f1dab..eff9255389684 100644 --- a/src/trapfunc.cpp +++ b/src/trapfunc.cpp @@ -1398,7 +1398,7 @@ bool trapfunc::map_regen( const tripoint &p, Creature *c, item * ) if( n ) { map &here = get_map(); n->add_msg_if_player( m_warning, _( "Your surroundings shift!" ) ); - const tripoint &omt_pos = n->global_omt_location(); + tripoint_abs_omt omt_pos = n->global_omt_location(); const std::string ®en_mapgen = here.tr_at( p ).map_regen_target(); here.remove_trap( p ); if( !run_mapgen_update_func( regen_mapgen, omt_pos, nullptr, false ) ) { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index dfb77aedb70a5..d128eedfba2dd 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -956,7 +956,8 @@ void vehicle::do_autodrive() Character &player_character = get_player_character(); map &here = get_map(); tripoint vehpos = global_pos3(); - tripoint veh_omt_pos = ms_to_omt_copy( here.getabs( vehpos ) ); + // TODO: fix point types + tripoint_abs_omt veh_omt_pos( ms_to_omt_copy( here.getabs( vehpos ) ) ); // we're at or close to the waypoint, pop it out and look for the next one. if( ( is_autodriving && !player_character.omt_path.empty() && !omt_path.empty() ) && veh_omt_pos == omt_path.back() ) { @@ -968,31 +969,31 @@ void vehicle::do_autodrive() return; } - point omt_diff = omt_path.back().xy() - veh_omt_pos.xy(); - if( omt_diff.x > 3 || omt_diff.x < -3 || omt_diff.y > 3 || omt_diff.y < -3 ) { + point_rel_omt omt_diff = omt_path.back().xy() - veh_omt_pos.xy(); + if( omt_diff.x() > 3 || omt_diff.x() < -3 || omt_diff.y() > 3 || omt_diff.y() < -3 ) { // we've gone walkabout somehow, call off the whole thing stop_autodriving(); return; } point side; - if( omt_diff.x > 0 ) { + if( omt_diff.x() > 0 ) { side.x = 2 * SEEX - 1; - } else if( omt_diff.x < 0 ) { + } else if( omt_diff.x() < 0 ) { side.x = 0; } else { side.x = SEEX; } - if( omt_diff.y > 0 ) { + if( omt_diff.y() > 0 ) { side.y = 2 * SEEY - 1; - } else if( omt_diff.y < 0 ) { + } else if( omt_diff.y() < 0 ) { side.y = 0; } else { side.y = SEEY; } // get the shared border mid-point of the next path omt - tripoint global_a = tripoint( veh_omt_pos.x * ( 2 * SEEX ), veh_omt_pos.y * ( 2 * SEEY ), - veh_omt_pos.z ); - tripoint autodrive_temp_target = ( global_a + tripoint( side, + tripoint_abs_ms global_a = project_to( veh_omt_pos ); + // TODO: fix point types + tripoint autodrive_temp_target = ( global_a.raw() + tripoint( side, sm_pos.z ) - here.getabs( vehpos ) ) + vehpos; autodrive_local_target = here.getabs( autodrive_temp_target ); drive_to_local_target( autodrive_local_target, false ); @@ -3186,7 +3187,8 @@ void vehicle::set_submap_moved( const tripoint &p ) if( !tracking_on ) { return; } - overmap_buffer.move_vehicle( this, old_msp ); + // TODO: fix point types + overmap_buffer.move_vehicle( this, point_abs_ms( old_msp ) ); } units::mass vehicle::total_mass() const @@ -4717,7 +4719,9 @@ int vehicle::total_solar_epower_w() const int vehicle::total_wind_epower_w() const { map &here = get_map(); - const oter_id &cur_om_ter = overmap_buffer.ter( ms_to_omt_copy( here.getabs( global_pos3() ) ) ); + // TODO: fix point types + const oter_id &cur_om_ter = + overmap_buffer.ter( tripoint_abs_omt( ms_to_omt_copy( here.getabs( global_pos3() ) ) ) ); weather_manager &weather = get_weather(); const w_point weatherPoint = *weather.weather_precise; int epower_w = 0; diff --git a/src/vehicle.h b/src/vehicle.h index e90a1f750f595..4fc77e6ca892b 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -19,6 +19,7 @@ #include "character_id.h" #include "clzones.h" #include "colony.h" +#include "coordinates.h" #include "damage.h" #include "game_constants.h" #include "item.h" @@ -574,7 +575,7 @@ class turret_data */ struct label : public point { label() = default; - label( const point &p ) : point( p ) {} + explicit label( const point &p ) : point( p ) {} label( const point &p, std::string text ) : point( p ), text( std::move( text ) ) {} std::string text; @@ -1779,7 +1780,7 @@ class vehicle // make sure the vehicle is supported across z-levels or on the same z-level bool level_vehicle(); - std::vector omt_path; // route for overmap-scale auto-driving + std::vector omt_path; // route for overmap-scale auto-driving std::vector alternators; // List of alternator indices std::vector engines; // List of engine indices std::vector reactors; // List of reactor indices diff --git a/src/weather.cpp b/src/weather.cpp index a497ee78a8a45..337d89cc19dfc 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -14,6 +14,7 @@ #include "character.h" #include "colony.h" #include "coordinate_conversions.h" +#include "coordinates.h" #include "enums.h" #include "game.h" #include "game_constants.h" @@ -189,7 +190,8 @@ weather_sum sum_conditions( const time_point &start, const time_point &end, weather_type_id wtype = current_weather( location, t ); proc_weather_sum( wtype, data, t, tick_size ); data.wind_amount += get_local_windpower( g->weather.windspeed, - overmap_buffer.ter( ms_to_omt_copy( location ) ), + // TODO: fix point types + overmap_buffer.ter( tripoint_abs_omt( ms_to_omt_copy( location ) ) ), location, g->weather.winddirection, false ) * to_turns( tick_size ); } @@ -656,11 +658,11 @@ static std::string print_time_just_hour( const time_point &p ) /** * Generate textual weather forecast for the specified radio tower. */ -std::string weather_forecast( const point &abs_sm_pos ) +std::string weather_forecast( const point_abs_sm &abs_sm_pos ) { std::string weather_report; // Local conditions - const auto cref = overmap_buffer.closest_city( tripoint( abs_sm_pos, 0 ) ); + const auto cref = overmap_buffer.closest_city( tripoint_abs_sm( abs_sm_pos, 0 ) ); const std::string city_name = cref ? cref.city->name : std::string( _( "middle of nowhere" ) ); // Current time weather_report += string_format( @@ -687,7 +689,9 @@ std::string weather_forecast( const point &abs_sm_pos ) // int weather_proportions[NUM_WEATHER_TYPES] = {0}; double high = -100.0; double low = 100.0; - const tripoint abs_ms_pos = tripoint( sm_to_ms_copy( abs_sm_pos ), 0 ); + // TODO: fix point types + const tripoint abs_ms_pos = + tripoint( project_to( abs_sm_pos ).raw(), 0 ); // TODO: wind direction and speed const time_point last_hour = calendar::turn - ( calendar::turn - calendar::turn_zero ) % 1_hours; @@ -1017,6 +1021,11 @@ bool warm_enough_to_plant( const tripoint &pos ) return get_weather().get_temperature( pos ) >= 50; } +bool warm_enough_to_plant( const tripoint_abs_omt &pos ) +{ + return g->weather.get_temperature( pos ) >= 50; +} + weather_manager::weather_manager() { lightning_active = false; @@ -1104,6 +1113,11 @@ int weather_manager::get_temperature( const tripoint &location ) return temp; } +int weather_manager::get_temperature( const tripoint_abs_omt &location ) +{ + return location.z() < 0 ? AVERAGE_ANNUAL_TEMPERATURE : temperature; +} + void weather_manager::clear_temp_cache() { temperature_cache.clear(); diff --git a/src/weather.h b/src/weather.h index dd93db6bfede6..61c16423d619f 100644 --- a/src/weather.h +++ b/src/weather.h @@ -3,6 +3,7 @@ #define CATA_SRC_WEATHER_H #include "color.h" +#include "coordinates.h" #include "optional.h" #include "pimpl.h" #include "point.h" @@ -75,7 +76,7 @@ std::string get_shortdirstring( int angle ); std::string get_dirstring( int angle ); -std::string weather_forecast( const point &abs_sm_pos ); +std::string weather_forecast( const point_abs_sm &abs_sm_pos ); // Returns input value (in Fahrenheit) converted to whatever temperature scale set in options. // @@ -123,8 +124,12 @@ int get_hourly_rotpoints_at_temp( int temp ); /** * Is it warm enough to plant seeds? + * + * The first overload is in map-square coords, the second for larger scale + * queries. */ bool warm_enough_to_plant( const tripoint &pos ); +bool warm_enough_to_plant( const tripoint_abs_omt &pos ); bool is_wind_blocker( const tripoint &location ); @@ -169,6 +174,8 @@ class weather_manager std::unordered_map< tripoint, int > temperature_cache; // Returns outdoor or indoor temperature of given location (in absolute (@ref map::getabs)) int get_temperature( const tripoint &location ); + // Returns outdoor or indoor temperature of given location + int get_temperature( const tripoint_abs_omt &location ); void clear_temp_cache(); }; diff --git a/tests/map_extra_test.cpp b/tests/map_extra_test.cpp index 283d94e9a8d25..c6c64667520d3 100644 --- a/tests/map_extra_test.cpp +++ b/tests/map_extra_test.cpp @@ -2,6 +2,7 @@ #include "coordinate_conversions.h" #include "catch/catch.hpp" +#include "coordinates.h" #include "overmapbuffer.h" #include "map_extras.h" @@ -9,31 +10,31 @@ TEST_CASE( "mx_minefield real spawn", "[map_extra][overmap]" ) { // Pick a point in the middle of the overmap so we don't generate quite so // many overmaps when searching. - const tripoint origin = tripoint( 90, 90, 0 ); + const tripoint_abs_omt origin( 90, 90, 0 ); // Find all of the bridgeheads within a 180 OMT radius of this location. omt_find_params find_params; find_params.types = {{"bridgehead_ground", ot_match_type::type}}; find_params.search_range = 180; - const std::vector bridges = overmap_buffer.find_all( origin, find_params ); + const std::vector bridges = overmap_buffer.find_all( origin, find_params ); // The rest of this check is pointless if there are no bridges. REQUIRE( !bridges.empty() ); // For every single bridge we found, run mapgen (which will select and apply a map extra). - for( const tripoint &p : bridges ) { + for( const tripoint_abs_omt &p : bridges ) { tinymap tm; - tm.load( omt_to_sm_copy( p ), false ); + tm.load( project_to( p ), false ); } // Get all of the map extras that have been generated. - const std::vector>> extras = overmap_buffer.get_all_extras( - origin.z ); + const std::vector>> extras = + overmap_buffer.get_all_extras( origin.z() ); // Count the number of mx_minefield map extras that have been generated. const string_id mx_minefield( "mx_minefield" ); int successes = std::count_if( extras.begin(), - extras.end(), [&mx_minefield]( const std::pair> &e ) { + extras.end(), [&mx_minefield]( const std::pair> &e ) { return e.second == mx_minefield; } ); @@ -43,7 +44,7 @@ TEST_CASE( "mx_minefield real spawn", "[map_extra][overmap]" ) TEST_CASE( "mx_minefield theoretical spawn", "[map_extra][overmap]" ) { - overmap &om = overmap_buffer.get( point_zero ); + overmap &om = overmap_buffer.get( point_abs_om() ); const oter_id road( "road_ns" ); const oter_id bridgehead( "bridgehead_ground_north" ); @@ -53,7 +54,7 @@ TEST_CASE( "mx_minefield theoretical spawn", "[map_extra][overmap]" ) // three OMTs--a bridgehead, then a road, then a road once again. // It does this for four rotations, with the road on the north, south, east, // and west of the target point. - const auto setup_terrain_and_generate = [&]( const tripoint & center, + const auto setup_terrain_and_generate = [&]( const tripoint_om_omt & center, om_direction::type bridge_direction ) { om.ter_set( center, bridgehead ); om.ter_set( center + om_direction::displace( bridge_direction, 1 ), bridge ); @@ -61,7 +62,7 @@ TEST_CASE( "mx_minefield theoretical spawn", "[map_extra][overmap]" ) road ); tinymap tm; - tm.load( omt_to_sm_copy( center ), false ); + tm.load( project_combine( om.pos(), project_to( center ) ), false ); const string_id mx_minefield( "mx_minefield" ); const map_extra_pointer mx_func = MapExtras::get_function( mx_minefield.str() ); @@ -71,7 +72,7 @@ TEST_CASE( "mx_minefield theoretical spawn", "[map_extra][overmap]" ) // Pick a point in the middle of the overmap so we don't go out of bounds when setting up // our terrains. - const tripoint target( 90, 90, 0 ); + const tripoint_om_omt target( 90, 90, 0 ); // Check that for each direction (north, south, east, west) the map extra generates successfully. for( om_direction::type dir : om_direction::all ) { diff --git a/tests/npc_talk_test.cpp b/tests/npc_talk_test.cpp index 1c4c36f0e26b5..3ff0c386b585c 100644 --- a/tests/npc_talk_test.cpp +++ b/tests/npc_talk_test.cpp @@ -87,7 +87,9 @@ static std::string gen_dynamic_line( dialogue &d ) static void change_om_type( const std::string &new_type ) { - const tripoint omt_pos = ms_to_omt_copy( get_map().getabs( get_player_character().pos() ) ); + // TODO: fix point types + const tripoint_abs_omt omt_pos( ms_to_omt_copy( get_map().getabs( + get_player_character().pos() ) ) ); overmap_buffer.ter_set( omt_pos, oter_id( new_type ) ); } diff --git a/tests/overmap_noise_test.cpp b/tests/overmap_noise_test.cpp index 5e4419905d97f..f0bf41f36e7ec 100644 --- a/tests/overmap_noise_test.cpp +++ b/tests/overmap_noise_test.cpp @@ -51,19 +51,19 @@ static void export_interpreted_noise( TEST_CASE( "om_noise_layer_forest_export", "[.]" ) { - const om_noise::om_noise_layer_forest f( point_zero, 1920237457 ); + const om_noise::om_noise_layer_forest f( point_abs_omt(), 1920237457 ); export_raw_noise( "forest-map-raw.pgm", f, OMAPX, OMAPY ); } TEST_CASE( "om_noise_layer_floodplain_export", "[.]" ) { - const om_noise::om_noise_layer_floodplain f( point_zero, 1920237457 ); + const om_noise::om_noise_layer_floodplain f( point_abs_omt(), 1920237457 ); export_raw_noise( "floodplain-map-raw.pgm", f, OMAPX, OMAPY ); } TEST_CASE( "om_noise_layer_lake_export", "[.]" ) { - const om_noise::om_noise_layer_lake f( point_zero, 1920237457 ); + const om_noise::om_noise_layer_lake f( point_abs_omt(), 1920237457 ); export_raw_noise( "lake-map-raw.pgm", f, OMAPX * 5, OMAPY * 5 ); export_interpreted_noise( "lake-map-interp.pgm", f, OMAPX * 5, OMAPY * 5, 0.25 ); } diff --git a/tests/overmap_test.cpp b/tests/overmap_test.cpp index d5eefd442f40c..c2bae9a734323 100644 --- a/tests/overmap_test.cpp +++ b/tests/overmap_test.cpp @@ -16,7 +16,7 @@ TEST_CASE( "set_and_get_overmap_scents" ) { - std::unique_ptr test_overmap = std::make_unique( point_zero ); + std::unique_ptr test_overmap = std::make_unique( point_abs_om() ); // By default there are no scents set. for( int x = 0; x < 180; ++x ) { @@ -36,7 +36,7 @@ TEST_CASE( "set_and_get_overmap_scents" ) TEST_CASE( "default_overmap_generation_always_succeeds", "[slow]" ) { int overmaps_to_construct = 10; - for( const point &candidate_addr : closest_points_first( point_zero, 10 ) ) { + for( const point_abs_om &candidate_addr : closest_points_first( point_abs_om(), 10 ) ) { // Skip populated overmaps. if( overmap_buffer.has( candidate_addr ) ) { continue; @@ -57,7 +57,7 @@ TEST_CASE( "default_overmap_generation_always_succeeds", "[slow]" ) TEST_CASE( "default_overmap_generation_has_non_mandatory_specials_at_origin", "[slow]" ) { - const point origin{}; + const point_abs_om origin{}; overmap_special mandatory; overmap_special optional; diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 758a99316668b..e00597a6d40a0 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -146,8 +146,8 @@ static void init_global_game_state( const std::vector &mods, get_map() = map(); - overmap_special_batch empty_specials( point_zero ); - overmap_buffer.create_custom_overmap( point_zero, empty_specials ); + overmap_special_batch empty_specials( point_abs_om{} ); + overmap_buffer.create_custom_overmap( point_abs_om{}, empty_specials ); get_map().load( tripoint( g->get_levx(), g->get_levy(), g->get_levz() ), false ); From 213691562c27830b3a80bf68254eaaa5ad62d68e Mon Sep 17 00:00:00 2001 From: LyleSY Date: Mon, 20 Jul 2020 05:54:36 -0400 Subject: [PATCH 148/151] [DinoMod] Add Tyruckusaurus Rex and Goliath Rex (#42289) --- data/mods/DinoMod/monstergroups/dinosaur.json | 9 ++++ .../DinoMod/monsters/zinosaur_upgrade.json | 46 ++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/data/mods/DinoMod/monstergroups/dinosaur.json b/data/mods/DinoMod/monstergroups/dinosaur.json index d1543cede0246..86a2941eedeeb 100644 --- a/data/mods/DinoMod/monstergroups/dinosaur.json +++ b/data/mods/DinoMod/monstergroups/dinosaur.json @@ -168,6 +168,15 @@ { "monster": "mon_zutahraptor_brute", "freq": 23, "cost_multiplier": 5 } ] }, + { + "type": "monstergroup", + "name": "GROUP_zyrannosaurus_BRUTE", + "default": "mon_zyrannosaurus_hulk", + "monsters": [ + { "monster": "mon_zyrannosaurus_hulk", "freq": 100, "cost_multiplier": 10 }, + { "monster": "mon_zyrannosaurus_truck", "freq": 70, "cost_multiplier": 10 } + ] + }, { "type": "monstergroup", "name": "GROUP_ZOMBIE", diff --git a/data/mods/DinoMod/monsters/zinosaur_upgrade.json b/data/mods/DinoMod/monsters/zinosaur_upgrade.json index 0ec03170a5bf2..70e097a052cc2 100644 --- a/data/mods/DinoMod/monsters/zinosaur_upgrade.json +++ b/data/mods/DinoMod/monsters/zinosaur_upgrade.json @@ -96,6 +96,7 @@ "id": "mon_zyrannosaurus_brute", "name": { "str": "Rage Rex" }, "copy-from": "mon_zyrannosaurus", + "looks_like": "mon_zyrannosaurus", "description": "Massive piles of ragged, stinking flesh lifting enormous teeth. Its entire body bulges with distended muscles and swollen, festering wounds.", "diff": 2, "color": "red", @@ -109,7 +110,7 @@ "armor_bullet": 5, "vision_night": 1 }, - "upgrades": { }, + "upgrades": { "half_life": 21, "into_group": "GROUP_zyrannosaurus_BRUTE" }, "special_attacks": [ [ "SMASH", 30 ] ], "extend": { "flags": [ "GROUP_BASH", "PUSH_MON", "PUSH_VEH" ] }, "categories": [ "DINOSAUR" ] @@ -119,6 +120,7 @@ "id": "mon_zalbertosaurus_brute", "name": { "str": "Alberta Anvil" }, "copy-from": "mon_zalbertosaurus", + "looks_like": "mon_zyrannosaurus", "description": "Massive jaws and grabbing claws lifting by a body bulging with distended muscles and swollen, festering wounds.", "diff": 2, "color": "red", @@ -234,6 +236,7 @@ "id": "mon_zeratosaurus_brute", "name": { "str": "Draco Titan" }, "copy-from": "mon_zeratosaurus", + "looks_like": "mon_zyrannosaurus", "description": "This zombie is enormous, scaly, studded with bony spikes, and it moves with horrible speed. Its colorful horns and bone spikes sit on a body bulging with distended muscles and swollen, festering wounds.", "diff": 2, "color": "red", @@ -422,6 +425,7 @@ "id": "mon_zyrannosaurus_shady", "name": { "str": "Shady Z-Rex" }, "copy-from": "mon_zyrannosaurus", + "looks_like": "mon_zyrannosaurus", "color": "light_gray", "description": "An uncanny shadow envelops this dinosaur. You can make out the outline of a huge bipedal dinosaur with feathery edges. The head looks big, lots of big teeth would fit in it.", "upgrades": { }, @@ -473,6 +477,7 @@ "id": "mon_syrannosaurus", "name": { "str": "S-Rex", "str_pl": "S-Rexes" }, "copy-from": "mon_zyrannosaurus", + "looks_like": "mon_zyrannosaurus", "color": "white", "material": [ "bone" ], "armor_bash": 0, @@ -498,6 +503,7 @@ "id": "mon_salbertosaurus", "name": { "str": "Skeletal Albertosaurus" }, "copy-from": "mon_zalbertosaurus", + "looks_like": "mon_zyrannosaurus", "color": "white", "material": [ "bone" ], "armor_bash": 0, @@ -523,6 +529,7 @@ "id": "mon_seratosaurus", "name": { "str": "Bone Dragon" }, "copy-from": "mon_zeratosaurus", + "looks_like": "mon_zyrannosaurus", "color": "white", "material": [ "bone" ], "armor_bash": 0, @@ -592,5 +599,42 @@ "extend": { "flags": [ "HARDTOSHOOT" ] }, "harvest": "mr_bones", "categories": [ "DINOSAUR" ] + }, + { + "type": "MONSTER", + "id": "mon_zyrannosaurus_truck", + "name": { "str": "Tyruckusaurus Rex" }, + "copy-from": "mon_zyrannosaurus_brute", + "looks_like": "mon_zyrannosaurus", + "description": "Massive piles of ragged, stinking flesh lifting enormous teeth and what looks like a fully loaded long haul truck with mounted flamethrowers and robotic arms.", + "diff": 10, + "color": "dark_gray_red", + "luminance": 20, + "proportional": { "hp": 1.5, "speed": 0.8 }, + "relative": { "armor_bash": 30, "armor_cut": 37 }, + "extend": { "flags": [ "DRIPS_GASOLINE" ] }, + "special_attacks": [ [ "GRAB", 30 ], [ "FLAMETHROWER", 30 ] ], + "upgrades": { }, + "death_drops": [ + { "item": "wheel", "count": 4 }, + { "group": "supplies_spares_vehicle", "count": 10 }, + { "group": "supplies_mechanics", "count": 10 }, + { "group": "supplies_metal", "count": 10 } + ], + "death_function": [ "FIREBALL" ] + }, + { + "type": "MONSTER", + "id": "mon_zyrannosaurus_hulk", + "name": { "str": "Goliath Rex" }, + "copy-from": "mon_zyrannosaurus_brute", + "looks_like": "mon_zyrannosaurus", + "description": "A hideously swollen zombified tyrannosaurus body towering into the sky. Its massive body bulges with distended muscles and swollen, festering wounds.", + "diff": 5, + "weight": "55000 kg", + "color": "white_magenta", + "proportional": { "hp": 4, "speed": 1.25 }, + "relative": { "melee_dice": 1, "melee_cut": -4, "armor_bash": 4, "armor_cut": 6, "armor_bullet": 5 }, + "special_attacks": [ [ "SMASH", 20 ] ] } ] From a7f5aa9af6240038e5043108d7aa3b6c0571a7d1 Mon Sep 17 00:00:00 2001 From: eso Date: Mon, 20 Jul 2020 09:14:21 -0700 Subject: [PATCH 149/151] [magiclysm] add magic boots which are for shouting "parkour" in (#42284) --- data/mods/Magiclysm/itemgroups/itemgroups.json | 1 + data/mods/Magiclysm/items/enchanted_boots.json | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/data/mods/Magiclysm/itemgroups/itemgroups.json b/data/mods/Magiclysm/itemgroups/itemgroups.json index cb12872800fd7..47de93f0d0a3d 100644 --- a/data/mods/Magiclysm/itemgroups/itemgroups.json +++ b/data/mods/Magiclysm/itemgroups/itemgroups.json @@ -465,6 +465,7 @@ { "item": "mboots_haste", "prob": 10 }, { "item": "mboots_sevenleague", "prob": 10 }, { "item": "mboots_escape", "prob": 10 }, + { "item": "mboots_freerunner", "prob": 10 }, { "item": "mboots_grounding", "prob": 10 } ] }, diff --git a/data/mods/Magiclysm/items/enchanted_boots.json b/data/mods/Magiclysm/items/enchanted_boots.json index ebe454afdcd40..3f550994d0687 100644 --- a/data/mods/Magiclysm/items/enchanted_boots.json +++ b/data/mods/Magiclysm/items/enchanted_boots.json @@ -50,6 +50,24 @@ "environmental_protection": 3, "flags": [ "WATERPROOF", "STURDY" ] }, + { + "id": "mboots_freerunner", + "type": "ARMOR", + "copy-from": "boots_hiking", + "name": { "str": "freerunner's boots", "str_pl": "freerunner's boots" }, + "looks_like": "boots_hiking", + "description": "Rugged yet extremely comfortable and well fitting boots of worn leather and steel, seeming a bit more flexible and breathable than typical for their materials. The enchantment they bear helps guide their wearer in their motions, to make movement around and over obstacles much more fluid and efficient.", + "relic_data": { + "passive_effects": [ + { "has": "WORN", "condition": "ALWAYS", "mutations": [ "PARKOUR" ], "values": [ { "value": "MOVE_COST", "add": -5 } ] } + ] + }, + "encumbrance": 8, + "warmth": 15, + "material_thickness": 3, + "environmental_protection": 3, + "flags": [ "WATERPROOF", "STURDY" ] + }, { "id": "mboots_grounding", "type": "ARMOR", From ab856d46eca3db1dc81277b431b3a14ab078e91c Mon Sep 17 00:00:00 2001 From: Maleclypse <54345792+Maleclypse@users.noreply.github.com> Date: Mon, 20 Jul 2020 11:23:29 -0500 Subject: [PATCH 150/151] [Magiclysm] Forge of wonders (#41577) * draft of location and itemgroups needed so far * Added glassteel for transparent vault walls * mobs * factions and forgedwellers * monster group and spawns * Update forge_of_wonders.json * Update itemgroups.json * Update data/mods/Magiclysm/itemgroups/itemgroups.json Co-authored-by: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> * Update data/mods/Magiclysm/monsters/forgedwellers.json Co-authored-by: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> * itemgroups armor and monster attacks * Update forgedwellers.json * Update forgedwellers.json * forgeborn body and deconstruction * fire and aggression fix * Update monster_attacks.json * Update forge_of_wonders.json * improvements * Update forge_of_wonders.json * Update forge_of_wonders.json * excess comma * itemgroups and mapfix * linting * Create TALK_FORGE_MERCHANT.json * Update forge_of_wonders.json * Update forge_of_wonders.json * Update TALK_FORGE_MERCHANT.json * cloak, clothes, extra furniture for forge * removed collection subtype from enchanted misc and added counts to forge merchant store * fixed clothes. maybe broke trade list need to double check the mon_faction for Forge. * vault kruft, faction wealth, protecting the npc * linting * lighting additions need to be added to palette * ci fixes * syntax error from move * add lighting * fix furniture * lighting and fixes * placements and life * fix groups and finalize * Update data/mods/Magiclysm/items/enchanted.json Co-authored-by: Curtis Merrill * Update data/mods/Magiclysm/npc/TALK_FORGE_MERCHANT.json Co-authored-by: Curtis Merrill * Update data/mods/Magiclysm/npc/TALK_FORGE_MERCHANT.json Co-authored-by: Curtis Merrill * Fix cloak cost, add trade items in reach. * fixes item ownership and trading * Update enchanted.json Co-authored-by: LaVeyanFiend <51099123+LaVeyanFiend@users.noreply.github.com> Co-authored-by: Curtis Merrill --- data/mods/Magiclysm/furniture.json | 18 ++ .../mods/Magiclysm/itemgroups/itemgroups.json | 68 ++++- data/mods/Magiclysm/items/constructs.json | 16 + data/mods/Magiclysm/items/enchanted.json | 19 ++ data/mods/Magiclysm/items/tools.json | 10 + data/mods/Magiclysm/materials.json | 20 ++ data/mods/Magiclysm/monster_attacks.json | 17 ++ data/mods/Magiclysm/monster_factions.json | 6 + data/mods/Magiclysm/monstergroups.json | 30 ++ .../Magiclysm/monsters/forgedwellers.json | 131 +++++++++ .../Magiclysm/npc/TALK_FORGE_MERCHANT.json | 94 ++++++ data/mods/Magiclysm/npc/factions.json | 61 ++++ .../Magiclysm/recipes/deconstruction.json | 9 + data/mods/Magiclysm/terrain.json | 45 +++ .../Magiclysm/worldgen/forge_of_wonders.json | 274 ++++++++++++++++++ 15 files changed, 817 insertions(+), 1 deletion(-) create mode 100644 data/mods/Magiclysm/monsters/forgedwellers.json create mode 100644 data/mods/Magiclysm/npc/TALK_FORGE_MERCHANT.json create mode 100644 data/mods/Magiclysm/worldgen/forge_of_wonders.json diff --git a/data/mods/Magiclysm/furniture.json b/data/mods/Magiclysm/furniture.json index 2e3a26ccf7adb..45f2002db084a 100644 --- a/data/mods/Magiclysm/furniture.json +++ b/data/mods/Magiclysm/furniture.json @@ -227,5 +227,23 @@ "sound_fail": "whump.", "items": [ { "item": "demon_chitin_piece", "count": [ 20, 30 ] } ] } + }, + { + "type": "furniture", + "id": "f_everburning_candelabra", + "name": "candelabra of everlasting candles", + "description": "A candelabra, strangely the candles never seem to burn down. Smashing it doesn't seem like it'd produce any worthwhile salvage.", + "symbol": ".", + "color": "white", + "move_cost_mod": -1, + "required_str": 12, + "light_emitted": 40, + "flags": [ "TRANSPARENT", "BASHABLE" ], + "bash": { + "sound": "SMASH!", + "str_min": 20, + "str_max": 40, + "items": [ { "item": "splinter", "count": [ 2, 8 ] }, { "item": "nail", "charges": [ 5, 10 ] } ] + } } ] diff --git a/data/mods/Magiclysm/itemgroups/itemgroups.json b/data/mods/Magiclysm/itemgroups/itemgroups.json index 47de93f0d0a3d..c93d739ae4483 100644 --- a/data/mods/Magiclysm/itemgroups/itemgroups.json +++ b/data/mods/Magiclysm/itemgroups/itemgroups.json @@ -292,7 +292,6 @@ "id": "enchanted_misc", "type": "item_group", "//": "all enchanted miscellanious items", - "subtype": "collection", "items": [ { "item": "heat_cube", "prob": 100 }, { "item": "mkey_opening", "prob": 100 }, @@ -1133,5 +1132,72 @@ "//": "the things that would be on the same tile as a cookpot, such as fuel and one pot.", "subtype": "collection", "items": [ { "group": "cookpot", "prob": 100 }, { "group": "wood_fuel", "prob": 80 } ] + }, + { + "type": "item_group", + "id": "magic_smith", + "//": "the things that would be on the same tile as a magicians anvil, such as tools and one product.", + "subtype": "collection", + "items": [ { "group": "enchanted_combat_items", "prob": 100 }, { "group": "tools_anvil", "prob": 80, "count": [ 2, 5 ] } ] + }, + { + "id": "tools_anvil", + "type": "item_group", + "//": "Tools commonly used by blacksmiths on top of an anvil", + "items": [ + [ "chisel", 90 ], + [ "crucible", 30 ], + [ "swage", 60 ], + [ "tongs", 90 ], + [ "hammer", 90 ], + [ "sandpaper", 90 ], + [ "small_mana_crystal", 180 ] + ] + }, + { + "id": "forge_vault_items", + "//": "Items that can be traded for at the forge of wonders.", + "type": "item_group", + "subtype": "distribution", + "items": [ + { "group": "enchanted_combat_items", "prob": 40 }, + { "group": "enchanted_misc", "prob": 50 }, + { "group": "enchanted_rings_unusual", "prob": 20 }, + { "group": "enchanted_rings_rare", "prob": 30 }, + { "group": "enchanted_wands_greater", "prob": 30 }, + { "group": "enchanted_wands_lesser", "prob": 20 }, + { "group": "lair_black_dragon_treasure", "prob": 5 }, + { "group": "enchanted_melee_weapons_plus2", "prob": 20 }, + { "group": "demon_spider_lair_treasure", "prob": 10 } + ] + }, + { + "id": "forge_life", + "type": "item_group", + "//": "Clothing and gear for forgedwellers", + "items": [ + [ "apron_leather", 90 ], + [ "pants_leather", 80 ], + [ "leathersandals", 60 ], + [ "kilt_leather", 90 ], + [ "hammer", 90 ], + [ "armor_demonchitin", 1 ], + [ "armguard_demonchitin", 8 ], + [ "gauntlets_demonchitin", 14 ] + ] + }, + { + "id": "forge_vault_money", + "//": "Items that can be traded for at the forge of wonders.", + "type": "item_group", + "subtype": "distribution", + "items": [ + { "item": "RobofacCoin", "prob": 40, "count": [ 1, 3 ] }, + { "item": "FMCNote", "prob": 50, "count": [ 10, 36 ] }, + { "item": "signed_chit", "prob": 20, "count": [ 12, 39 ] }, + { "item": "icon", "prob": 30, "count": [ 1, 13 ] }, + { "item": "gold_small", "prob": 20, "count": [ 120, 390 ] }, + { "item": "silver_small", "prob": 5, "count": [ 68, 560 ] } + ] } ] diff --git a/data/mods/Magiclysm/items/constructs.json b/data/mods/Magiclysm/items/constructs.json index 910cb33bc7760..e1288be2576b5 100644 --- a/data/mods/Magiclysm/items/constructs.json +++ b/data/mods/Magiclysm/items/constructs.json @@ -65,5 +65,21 @@ "bashing": 30, "to_hit": -5, "flags": [ "TRADER_AVOID", "NO_REPAIR" ] + }, + { + "type": "GENERIC", + "id": "broken_forgeborn", + "symbol": "x", + "color": "dark_gray", + "name": "broken forge born", + "category": "other", + "description": "A broken forge born, with all orichalcum you would possibly ever need. Could be smashed for orichalcum.", + "price": 100000, + "material": [ "orichalcum_metal" ], + "weight": "945 kg", + "volume": "120 L", + "bashing": 30, + "to_hit": -5, + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] } ] diff --git a/data/mods/Magiclysm/items/enchanted.json b/data/mods/Magiclysm/items/enchanted.json index b8594f46805a2..743d4b7736ef3 100644 --- a/data/mods/Magiclysm/items/enchanted.json +++ b/data/mods/Magiclysm/items/enchanted.json @@ -72,5 +72,24 @@ } ] } + }, + { + "id": "cloak_morthylla", + "type": "ARMOR", + "copy-from": "cloak_wool", + "name": { "str": "Cloak of Morthylla the Lamia" }, + "description": "This cloak seems to absorb light except for the pinpricks of stars that move across its surface.", + "price": 1500000, + "price_postapoc": 360000, + "material": [ "black_dragon_hide" ], + "symbol": "[", + "color": "dark_gray", + "covers": [ "TORSO", "HEAD", "ARMS", "LEGS" ], + "coverage": 85, + "encumbrance": 4, + "warmth": 30, + "material_thickness": 3, + "flags": [ "HOOD", "OUTER", "NO_REPAIR", "SUPER_FANCY", "STURDY" ], + "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "BONUS_DODGE", "add": 1 } ] } ] } } ] diff --git a/data/mods/Magiclysm/items/tools.json b/data/mods/Magiclysm/items/tools.json index d70976c0e1a84..3dde5c9959677 100644 --- a/data/mods/Magiclysm/items/tools.json +++ b/data/mods/Magiclysm/items/tools.json @@ -149,5 +149,15 @@ "clothing_mods": [ "leather_padded", "steel_padded", "kevlar_padded", "furred", "wooled" ] } ] + }, + { + "type": "TOOL", + "id": "glassteel_shard", + "copy-from": "glass_shard", + "name": { "str": "glassteel shard" }, + "category": "other", + "description": "A broken shard of glassteel covered in sharp edges. You could use it as a weapon, but you might want to wear gloves.", + "material": [ "glassteel" ], + "cutting": 7 } ] diff --git a/data/mods/Magiclysm/materials.json b/data/mods/Magiclysm/materials.json index c05a926842f5a..42b973fc9d80f 100644 --- a/data/mods/Magiclysm/materials.json +++ b/data/mods/Magiclysm/materials.json @@ -88,5 +88,25 @@ "cut_dmg_verb": "scratched", "burn_products": [ [ "scrap_bronze", 1 ] ], "compacts_into": [ "orichalcum_lump", "orichalcum_sliver" ] + }, + { + "type": "material", + "ident": "glassteel", + "name": "Glassteel", + "density": 40, + "specific_heat_liquid": 0.82, + "specific_heat_solid": 0.45, + "latent_heat": 273, + "bash_resist": 10, + "cut_resist": 6, + "bullet_resist": 19, + "acid_resist": 6, + "fire_resist": 0, + "elec_resist": 10, + "chip_resist": 30, + "repaired_with": "scrap", + "dmg_adj": [ "scratched", "cut", "cracked", "shattered" ], + "bash_dmg_verb": "cracked", + "cut_dmg_verb": "scratched" } ] diff --git a/data/mods/Magiclysm/monster_attacks.json b/data/mods/Magiclysm/monster_attacks.json index 3c59d0f081983..7e534a4cc7292 100644 --- a/data/mods/Magiclysm/monster_attacks.json +++ b/data/mods/Magiclysm/monster_attacks.json @@ -26,5 +26,22 @@ "hit_dmg_npc": "The %1$s crushes 's %2$s with its greatclub!", "no_dmg_msg_u": "The %1$s tries to crush your %2$s with its greatclub, but swings wide and stumbles.", "no_dmg_msg_npc": "The %1$s tries to crush 's %2$s with its greatclub, but swings wide and stumbles." + }, + { + "type": "SPELL", + "id": "demon_breath_fire", + "name": { "str": "Hellfire Belch" }, + "description": "Spits supernatural napalm from your mouth.", + "valid_targets": [ "hostile", "ally", "ground" ], + "damage_type": "fire", + "max_level": 30, + "min_damage": 6, + "max_damage": 180, + "damage_increment": 6.0, + "min_range": 8, + "max_range": 12, + "range_increment": 0.1, + "effect": "line_attack", + "flags": [ "VERBAL", "NO_HANDS", "NO_LEGS" ] } ] diff --git a/data/mods/Magiclysm/monster_factions.json b/data/mods/Magiclysm/monster_factions.json index ffdbd33889bbb..ec6afb031e300 100644 --- a/data/mods/Magiclysm/monster_factions.json +++ b/data/mods/Magiclysm/monster_factions.json @@ -21,5 +21,11 @@ { "type": "MONSTER_FACTION", "name": "goblin" + }, + { + "type": "MONSTER_FACTION", + "name": "wonder_forge", + "hate": [ "zombie", "fungus" ], + "friendly": "forge_lords" } ] diff --git a/data/mods/Magiclysm/monstergroups.json b/data/mods/Magiclysm/monstergroups.json index 9fcfdc9297c13..41c6926c1ce41 100644 --- a/data/mods/Magiclysm/monstergroups.json +++ b/data/mods/Magiclysm/monstergroups.json @@ -139,5 +139,35 @@ "name": "GROUP_GOBLIN_ADVANCED", "default": "mon_goblin_chieftain", "monsters": [ { "monster": "mon_goblin_chieftain", "freq": 40, "cost_multiplier": 1 } ] + }, + { + "type": "monstergroup", + "name": "GROUP_FORGE_STANDARD", + "default": "mon_null", + "monsters": [ + { "monster": "mon_forgeborn", "freq": 10, "cost_multiplier": 10 }, + { "monster": "mon_forgemaster1", "freq": 3, "cost_multiplier": 10 }, + { "monster": "mon_forgemaster2", "freq": 3, "cost_multiplier": 10 }, + { "monster": "mon_forgemaster3", "freq": 3, "cost_multiplier": 10 }, + { "monster": "mon_forgedwarves", "freq": 3, "cost_multiplier": 10 } + ] + }, + { + "type": "monstergroup", + "name": "GROUP_FORGEDEMONS", + "default": "mon_forgedemons", + "monsters": [ { "monster": "mon_forgedemons", "freq": 100, "cost_multiplier": 3 } ] + }, + { + "type": "monstergroup", + "name": "GROUP_FORGE_DWARVES", + "default": "mon_forgedwarves", + "monsters": [ { "monster": "mon_forgedwarves", "freq": 100, "cost_multiplier": 3 } ] + }, + { + "type": "monstergroup", + "name": "GROUP_FORGE_AUTOMATA", + "default": "mon_forgeborn", + "monsters": [ { "monster": "mon_forgeborn", "freq": 100, "cost_multiplier": 3 } ] } ] diff --git a/data/mods/Magiclysm/monsters/forgedwellers.json b/data/mods/Magiclysm/monsters/forgedwellers.json new file mode 100644 index 0000000000000..977ff0fcbd79c --- /dev/null +++ b/data/mods/Magiclysm/monsters/forgedwellers.json @@ -0,0 +1,131 @@ +[ + { + "id": "mon_forgeborn", + "type": "MONSTER", + "name": { "str": "forge born" }, + "description": "The most elaborate, gaudy and overwrought clockwork creature that you've ever seen. Each one has its face designed in a mask displaying a single emotion. Blades extend from the wrists in combat.", + "default_faction": "wonder_forge", + "bodytype": "human", + "species": [ "ROBOT" ], + "diff": 2, + "volume": "120 L", + "weight": "945 kg", + "hp": 350, + "speed": 80, + "material": [ "orichalcum_metal" ], + "symbol": "Y", + "color": "dark_gray", + "aggression": 0, + "morale": 100, + "melee_skill": 6, + "melee_dice": 3, + "melee_dice_sides": 10, + "melee_cut": 9, + "armor_bash": 32, + "armor_cut": 32, + "armor_bullet": 26, + "armor_fire": 30, + "dodge": 0, + "vision_day": 40, + "vision_night": 40, + "special_attacks": [ { "type": "spell", "spell_data": { "id": "manatouched_seeker_bolts", "min_level": 5 }, "cooldown": 60 } ], + "anger_triggers": [ "FRIEND_ATTACKED", "HURT" ], + "death_function": [ "BROKEN" ], + "flags": [ "SEES", "NO_BREATHE", "PATH_AVOID_DANGER_2", "LOUDMOVES" ] + }, + { + "id": "mon_forgemaster1", + "type": "MONSTER", + "copy-from": "mon_goblin_chieftain", + "name": { "str": "goblin forgemaster" }, + "default_faction": "wonder_forge", + "aggression": 0, + "armor_fire": 40, + "description": "A goblin like none you've ever seen before. He directs workers and automatons with confidence and style.", + "death_drops": { "subtype": "collection", "groups": [ [ "forge_life", 40 ], [ "bedroom", 1 ], [ "dresser", 5 ], [ "ammo", 18 ] ] } + }, + { + "id": "mon_forgemaster2", + "type": "MONSTER", + "name": { "str": "lizardfolk forgemaster" }, + "description": "Lizardfolk rarely live outside of their tribes. This one has found freedom and purpose beyond serving their draconic masters.", + "copy-from": "mon_lizardfolk_shaman", + "default_faction": "wonder_forge", + "aggression": 0, + "armor_fire": 40, + "special_attacks": [ { "type": "spell", "spell_data": { "id": "laze" }, "cooldown": 10 }, [ "scratch", 5 ] ], + "death_drops": { "subtype": "collection", "groups": [ [ "forge_life", 40 ], [ "bedroom", 1 ], [ "dresser", 5 ], [ "ammo", 18 ] ] } + }, + { + "id": "mon_forgemaster3", + "type": "MONSTER", + "name": { "str": "gracken forgemaster" }, + "description": "This is some form of eldritch monstrosity; an uncouth black being with smooth, oily, skin and unpleasant horns that curve inward toward each other. Tall and thin, the shadows cling unnaturally to its vaguely defined humanoid form as it shuffles along, its hands twitching and spasming so rapidly as to appear a little more than a black blur of claws. This one politely asks you to mind your step as this is a working environment.", + "default_faction": "wonder_forge", + "copy-from": "mon_gracke", + "special_attacks": [ { "type": "spell", "spell_data": { "id": "eshaper_shardspray", "min_level": 5 }, "cooldown": 10 } ], + "armor_fire": 40, + "death_drops": { "subtype": "collection", "groups": [ [ "forge_life", 40 ], [ "bedroom", 1 ], [ "dresser", 5 ], [ "ammo", 18 ] ] } + }, + { + "id": "mon_forgedemons", + "type": "MONSTER", + "name": { "str": "forge demon" }, + "description": "The first thing you notice is that this creature has five arms. The next is that it walks on three legs. It walks amongst the vault until it notices you then throws itself at the walls screaming bloody murder. Its mere presence fills you with an unfathomable dread.", + "default_faction": "wonder_forge", + "bodytype": "human", + "species": [ "NETHER" ], + "diff": 5, + "volume": "62500 ml", + "weight": "81500 g", + "hp": 400, + "speed": 80, + "material": [ "arcane_skin" ], + "symbol": "&", + "color": "white", + "aggression": 100, + "morale": 100, + "melee_skill": 7, + "melee_dice": 5, + "melee_dice_sides": 6, + "melee_cut": 6, + "dodge": 4, + "vision_day": 30, + "armor_fire": 30, + "harvest": "demihuman_large_fur", + "special_attacks": [ { "type": "spell", "spell_data": { "id": "demon_breath_fire", "min_level": 7 }, "cooldown": 10 }, [ "scratch", 15 ] ], + "death_function": [ "NORMAL" ], + "flags": [ "SEES", "SMELLS", "HEARS", "WARM", "BASHES", "ANIMAL", "PATH_AVOID_DANGER_1", "NO_BREATHE" ] + }, + { + "id": "mon_forgedwarves", + "type": "MONSTER", + "name": { "str": "forge worker" }, + "description": "A squat humanoid that looks quite sturdily built. They style their hair in mohawks and other strange fashions that seem to be dictated by what parts of their skin aren't scarred from burns. Their clothes are designed to protect them from the intense environment they work in.", + "default_faction": "wonder_forge", + "bodytype": "human", + "species": [ "MUTANT" ], + "volume": "62500 ml", + "weight": "81500 g", + "hp": 80, + "speed": 130, + "material": [ "flesh" ], + "symbol": "@", + "color": "light_red", + "aggression": 3, + "morale": 40, + "melee_skill": 5, + "melee_dice": 2, + "melee_dice_sides": 5, + "melee_cut": 4, + "dodge": 2, + "armor_bash": 23, + "armor_cut": 32, + "armor_bullet": 26, + "armor_fire": 35, + "harvest": "demihuman", + "death_drops": { "subtype": "collection", "groups": [ [ "forge_life", 40 ], [ "bedroom", 1 ], [ "dresser", 5 ], [ "ammo", 18 ] ] }, + "death_function": [ "NORMAL" ], + "flags": [ "SEES", "HEARS", "WARM", "BASHES", "GROUP_BASH", "HUMAN", "PATH_AVOID_DANGER_2" ] + } +] diff --git a/data/mods/Magiclysm/npc/TALK_FORGE_MERCHANT.json b/data/mods/Magiclysm/npc/TALK_FORGE_MERCHANT.json new file mode 100644 index 0000000000000..22f07f8af59b6 --- /dev/null +++ b/data/mods/Magiclysm/npc/TALK_FORGE_MERCHANT.json @@ -0,0 +1,94 @@ +[ + { + "type": "npc", + "id": "forge_lord_merchant", + "//": "The Lord of the Forge of Wonders.", + "name_unique": "Valzain of Psiom", + "name_suffix": "Forge Lord", + "class": "NC_FORGE_LORD", + "attitude": 0, + "mission": 3, + "chat": "TALK_FORGE_LORD", + "faction": "forge_lords" + }, + { + "type": "npc_class", + "id": "NC_FORGE_LORD", + "name": { "str": "Wondrous Dreamer" }, + "job_description": "I created this place from dreams and magic.", + "traits": [ { "group": "NPC_starting_traits" }, { "group": "Appearance_demographics" } ], + "//": "This is a unique NPC who doesn't get randomly selected background traits", + "common": false, + "bonus_int": { "one_in": 4 }, + "bonus_per": { "one_in": 4 }, + "shopkeeper_item_group": "NC_FORGE_LORD_STORE", + "worn_override": "NC_FORGE_LORD_clothes", + "skills": [ + { + "skill": "ALL", + "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": -2 }, { "one_in": 4 } ] } ] } + }, + { "skill": "mechanics", "bonus": { "one_in": 2 } }, + { "skill": "computer", "bonus": { "one_in": 2 } }, + { "skill": "electronics", "bonus": { "rng": [ 0, 2 ] } }, + { "skill": "speech", "bonus": { "rng": [ 1, 3 ] } }, + { "skill": "barter", "bonus": { "rng": [ 3, 5 ] } } + ] + }, + { + "type": "item_group", + "id": "NC_FORGE_LORD_clothes", + "subtype": "collection", + "entries": [ + { "item": "mbelt_pockets_greater", "prob": 100 }, + { "item": "cloak_morthylla", "prob": 100 }, + { "item": "mboots_escape", "prob": 100 }, + { "item": "breeches", "prob": 100 }, + { "item": "polo_shirt", "prob": 100 } + ] + }, + { + "type": "item_group", + "subtype": "collection", + "id": "NC_FORGE_LORD_STORE", + "items": [ + { "group": "enchanted_combat_items", "count": [ 3, 8 ], "prob": 40 }, + { "group": "enchanted_misc", "count": [ 1, 3 ], "prob": 50 }, + { "group": "enchanted_rings_unusual", "count": [ 1, 2 ], "prob": 20 }, + { "group": "enchanted_rings_rare", "count": [ 1, 2 ], "prob": 30 }, + { "group": "enchanted_wands_greater", "count": [ 1, 2 ], "prob": 30 }, + { "group": "enchanted_wands_lesser", "count": [ 5, 8 ], "prob": 20 }, + { "group": "lair_black_dragon_treasure", "count": [ 1, 3 ], "prob": 5 }, + { "group": "enchanted_melee_weapons_plus2", "prob": 20 }, + { "group": "demon_spider_lair_treasure", "prob": 10 } + ] + }, + { + "id": "TALK_FORGE_LORD", + "type": "talk_topic", + "dynamic_line": { + "u_is_wearing": "badge_marshal", + "yes": [ + "The government doesn't subsidize your purchases here anymore.", + "Do you have any tales of adventure I could write down?", + "In case you were wondering, we no longer respect any pre-existing weapon laws." + ], + "no": [ "Welcome to the Forge of Wonders.", "Here to trade, I hope?", "Bring me tales and we can trade." ] + }, + "responses": [ + { "text": "Let's trade.", "effect": "start_trade", "topic": "TALK_FORGE_LORD" }, + { "text": "What are you doing here?", "topic": "TALK_FORGE_LORD_DOING" }, + { "text": "Well, bye.", "topic": "TALK_DONE" } + ] + }, + { + "id": "TALK_FORGE_LORD_DOING", + "type": "talk_topic", + "dynamic_line": { + "u_is_wearing": "badge_marshal", + "yes": "Well here and now I am the law, and the law here is that people purchase my goods, they take them out into the world and they die; or they return to buy more of my goods. Either way, I write poetry about them.", + "no": "Once I was lost in the throes of love, now I've built an empire of material goods." + }, + "responses": [ { "text": "Good day, sir.", "topic": "TALK_FORGE_LORD" } ] + } +] diff --git a/data/mods/Magiclysm/npc/factions.json b/data/mods/Magiclysm/npc/factions.json index 397dbe5f64a60..63dde7893a8c2 100644 --- a/data/mods/Magiclysm/npc/factions.json +++ b/data/mods/Magiclysm/npc/factions.json @@ -119,5 +119,66 @@ } }, "description": "A collection of those cursed by the cataclysm. They have sworn to rid this world of its curse and will stop at nothing to accomplish their task." + }, + { + "type": "faction", + "id": "forge_lords", + "name": "The Forge Lords", + "mon_faction": "wonder_forge", + "likes_u": 0, + "respects_u": 0, + "known_by_u": false, + "size": 5, + "power": 100, + "food_supply": 115200, + "wealth": 1000000, + "relations": { + "lobby_beggars": { + "kill on sight": false, + "watch your back": false, + "share my stuff": false, + "guard your stuff": false, + "lets you in": false, + "defends your space": false, + "knows your voice": true + }, + "free_merchants": { + "kill on sight": false, + "watch your back": false, + "share my stuff": false, + "guard your stuff": false, + "lets you in": false, + "defends your space": false, + "knows your voice": true + }, + "old_guard": { + "kill on sight": false, + "watch your back": false, + "share my stuff": false, + "guard your stuff": false, + "lets you in": false, + "defends your space": false, + "knows your voice": true + }, + "no_faction": { + "kill on sight": false, + "watch your back": false, + "share my stuff": false, + "guard your stuff": false, + "lets you in": false, + "defends your space": false, + "knows your voice": true + }, + "wasteland_scavengers": { + "kill on sight": false, + "watch your back": false, + "share my stuff": false, + "guard your stuff": false, + "lets you in": false, + "defends your space": false, + "knows your voice": true + } + }, + "description": "Builders and merchants of magical wonders. They expect to weather this Cataclysm through trade and innovation. They will take any coin from any land." } ] diff --git a/data/mods/Magiclysm/recipes/deconstruction.json b/data/mods/Magiclysm/recipes/deconstruction.json index 5fe9ad10e4cdd..317ab91f1e9b9 100644 --- a/data/mods/Magiclysm/recipes/deconstruction.json +++ b/data/mods/Magiclysm/recipes/deconstruction.json @@ -25,5 +25,14 @@ "time": "6 h", "qualities": [ { "id": "HAMMER", "level": 1 }, { "id": "SAW_M", "level": 1 } ], "components": [ [ [ "scrap", 800 ] ], [ [ "steel_lump", 200 ] ] ] + }, + { + "result": "broken_forgeborn", + "type": "uncraft", + "skill_used": "spellcraft", + "difficulty": 8, + "time": "6 h", + "qualities": [ { "id": "HAMMER", "level": 2 }, { "id": "SAW_M", "level": 2 } ], + "components": [ [ [ "orichalcum_sliver", 80 ] ], [ [ "orichalcum_lump", 20 ] ] ] } ] diff --git a/data/mods/Magiclysm/terrain.json b/data/mods/Magiclysm/terrain.json index 5d90160216ef6..61db387ca61df 100644 --- a/data/mods/Magiclysm/terrain.json +++ b/data/mods/Magiclysm/terrain.json @@ -60,5 +60,50 @@ "flags": [ "TRANSPARENT", "DIGGABLE", "FLAT" ], "looks_like": "t_dirt", "bash": { "sound": "thump", "ter_set": "t_null", "str_min": 50, "str_max": 100, "str_min_supported": 100, "bash_below": true } + }, + { + "type": "terrain", + "id": "t_wall_glassteel_alarm", + "alias": [ "t_wall_glassteel_h_alarm", "t_wall_glassteel_v_alarm" ], + "looks_like": "t_wall_glass", + "name": "glassteel vault wall", + "description": "A barrier made of glassteel, it's nothing complicated, and looks extremely fragile. It is most definitely not fragile and it's probably alarmed in the event that someone does break through it.", + "symbol": "LINE_OXOX", + "color": "light_cyan", + "move_cost": 0, + "roof": "t_flat_roof", + "flags": [ "TRANSPARENT", "ALARMED", "NOITEM", "WALL", "NO_SCENT", "AUTO_WALL_SYMBOL", "BLOCK_WIND" ], + "bash": { + "str_min": 200, + "str_max": 600, + "sound": "a cross between steel bending and glass shattering!", + "sound_fail": "whunk!", + "sound_vol": 16, + "sound_fail_vol": 10, + "ter_set": "t_floor", + "items": [ { "item": "glassteel_shard", "count": [ 42, 84 ] } ] + } + }, + { + "type": "terrain", + "id": "t_thconc_floor_echandelier", + "name": "concrete floor, everburning chandelier", + "description": "A bare and cold concrete floor with an elaborate chandelier above it filled with everburning candles.", + "symbol": ".", + "color": "white", + "move_cost": 2, + "light_emitted": 90, + "roof": "t_flat_roof", + "flags": [ "TRANSPARENT", "SUPPORTS_ROOF", "INDOORS", "FLAT", "ROAD" ], + "bash": { + "str_min": 4, + "str_max": 12, + "sound": "glass breaking!", + "sound_fail": "whack!", + "sound_vol": 16, + "sound_fail_vol": 10, + "ter_set": "t_thconc_floor", + "items": [ { "item": "glass_shard", "count": [ 8, 16 ] } ] + } } ] diff --git a/data/mods/Magiclysm/worldgen/forge_of_wonders.json b/data/mods/Magiclysm/worldgen/forge_of_wonders.json new file mode 100644 index 0000000000000..8e906a1401a13 --- /dev/null +++ b/data/mods/Magiclysm/worldgen/forge_of_wonders.json @@ -0,0 +1,274 @@ +[ + { + "type": "mapgen", + "method": "json", + "om_terrain": [ + [ "forge_1A", "forge_2A", "forge_3A", "forge_4A", "forge_5A" ], + [ "forge_1B", "forge_2B", "forge_3B", "forge_4B", "forge_5B" ] + ], + "object": { + "faction_owner": [ + { "id": "forge_lords", "x": [ 0, 23 ], "y": [ 0, 23 ] }, + { "id": "forge_lords", "x": [ 24, 47 ], "y": [ 0, 23 ] }, + { "id": "forge_lords", "x": [ 48, 71 ], "y": [ 0, 23 ] }, + { "id": "forge_lords", "x": [ 72, 94 ], "y": [ 0, 23 ] }, + { "id": "forge_lords", "x": [ 96, 117 ], "y": [ 0, 23 ] }, + { "id": "forge_lords", "x": [ 0, 23 ], "y": [ 24, 47 ] }, + { "id": "forge_lords", "x": [ 24, 47 ], "y": [ 24, 47 ] }, + { "id": "forge_lords", "x": [ 48, 71 ], "y": [ 24, 47 ] }, + { "id": "forge_lords", "x": [ 72, 94 ], "y": [ 24, 47 ] }, + { "id": "forge_lords", "x": [ 96, 117 ], "y": [ 24, 47 ] } + ], + "fill_ter": "t_dirt", + "rows": [ + " T 2 ++++++ 2 ", + " T +++++++ Y ", + " Y ++++++++ T ", + " +++++++ ", + " ########||||#########################||&&&&&&&||###############||||##############||||############### ", + " #..................................##...........##............................4............4.......# ", + " #..4.@.@...........................##...........##..................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.# ", + " #...fffff.................2........##...........##..................X$$$$$$$$$$$$$$$$$$$$$$$$$$$$X.# ", + " #...fffff..........................##...........##..................#$$$$$$$$$$$$$$$$$$$$$$$$$$$$X.# ", + " #....@.@.........................................................XXX#$$$$$$$$$$$$$$$$$$$$$$$$$$$$X.| ", + " #........................................44......................X94#$$$$$$$$$$$$$$$$$$$$$$$$$$$$X.| ", + " #............4...........................44......................X99#$$$$$$$$$$$$$$$$$$$$$$$$$$$$X.| ", + " #................................................................X94#$$$$$$$$$$$$$$$$$$$$$$$$$$$$X.| ", + " #...........@.@..................................................XXX#$$$$$$$$$$$$$$$$$$$$$$$$$$$$X.| ", + " #.........zZZZZZ....................................................#$$$$$$$$$$$$$$$$$$$$$$$$$$$$X.# ", + " #..........ZZZZZz...................................##...........##.X$$$$$$$$$$$$$$$$$$$$$$$$$$$$X.# ", + " |...........@.@............4...................2....##...........##.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.# ", + " |...................................................##...........##.....4...............4..........# ", + " |...................................#####|||##########||&&&&&&&||##################|||############## ", + " |...................................# +++++++ ", + " |...................................# ++++++++ 2 ", + " #...................................# 2 +++++++ ", + " #.......................4...........# ++++++++ 2 ", + " #...................................# ++++++++ Y ", + " #.........2.........................# +++++++++ ", + " #...................................# +++++++++ + + + ", + " #...................................# +++++++++++++++++++++ ", + " #.......4...........................# +++++++++++++++++ ", + " #....h!..........................2..# Y 2 ++++++++++++++++ ", + " |..333333...........................| ++++++++++++++++ ", + " |..333l33h..........................| ", + " |.233ll33!..........................| Y ", + " |..33l333h..........................| ", + " |..333333...........................| wwwwwWWWWWWwwwwwww ", + " #....!h..........................2..# wwwwwwwWWWWWWWWWWWWwwwww ", + " #...................................# wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww ", + " #...................................# wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww ", + " #...................................#wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww ", + " #...............4...........33333333tWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWwwwwwwww ", + " #.......................!..hll333333tWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWwwww ", + " #.......................!..hll333333tWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWwwwwwww ", + " #...........................33333333twwwwwwwwwwwwwwwwwwWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWwwwww ", + " #...................................# wWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWwwwwwww ", + " #.....4..................4..........# wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww ", + " #...................................# wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww ", + " #...................................# wwww w ww ww w ", + " ############||||||||||############### ", + " " + ], + "palettes": [ "wonder_forge_palette" ], + "place_npcs": [ { "class": "forge_lord_merchant", "x": 75, "y": 11 } ], + "place_monsters": [ + { "monster": "GROUP_FISH", "x": [ 77, 82 ], "y": [ 32, 42 ], "density": 0.3, "repeat": [ 1, 3 ] }, + { "monster": "GROUP_FORGE_STANDARD", "x": [ 24, 47 ], "y": [ 8, 23 ], "density": 0.8, "repeat": [ 5, 8 ] }, + { "monster": "GROUP_FORGE_STANDARD", "x": [ 48, 71 ], "y": [ 8, 23 ], "density": 0.8, "repeat": [ 5, 8 ] }, + { "monster": "GROUP_FORGE_STANDARD", "x": [ 24, 47 ], "y": [ 24, 46 ], "density": 0.8, "repeat": [ 5, 8 ] }, + { "monster": "GROUP_FORGE_AUTOMATA", "x": [ 31, 47 ], "y": [ 0, 3 ], "density": 0.1, "repeat": [ 2, 4 ] }, + { "monster": "GROUP_FORGE_DWARVES", "x": [ 77, 82 ], "y": [ 24, 30 ], "density": 0.1, "repeat": [ 3, 6 ] }, + { "monster": "GROUP_FORGE_DWARVES", "x": [ 24, 47 ], "y": [ 40, 45 ], "density": 0.1, "repeat": [ 3, 6 ] }, + { "monster": "GROUP_FORGEDEMONS", "x": [ 80, 90 ], "y": [ 8, 14 ], "density": 0.1, "repeat": [ 3, 6 ] } + ] + } + }, + { + "type": "palette", + "id": "wonder_forge_palette", + "terrain": { + "w": "t_water_sh", + "l": "t_lava", + "#": "t_strconc_wall", + "t": "t_ov_reb_cage", + "W": "t_water_dp", + "3": "t_water_moving_sh_underground", + " ": "t_region_groundcover_forest", + "T": "t_trunk", + "&": "t_ballistic_door_glass_c", + "|": "t_window_stained_green", + "X": "t_wall_glassteel_alarm", + ".": "t_strconc_floor", + "h": "t_strconc_floor", + "!": "t_strconc_floor", + "~": "t_strconc_floor", + "1": "t_strconc_floor", + "z": "t_strconc_floor", + "Z": "t_strconc_floor", + "$": "t_strconc_floor", + "f": "t_strconc_floor", + "F": "t_strconc_floor", + "9": "t_strconc_floor", + "2": "t_strconc_floor", + "4": "t_thconc_floor_echandelier", + "+": "t_railroad_rubble" + }, + "furniture": { + "h": "f_demon_forge", + "@": "f_logstool", + "c": "f_orrery", + "Y": [ [ "f_boulder_small", 5 ], "f_boulder_medium", "f_boulder_large", "f_glow_boulder" ], + "=": "f_huge_mana_crystal", + "z": "f_alembic", + "Z": "f_magic_bench", + "!": "f_anvil", + "f": "f_table", + "2": "f_everburning_candelabra" + }, + "items": { + "!": { "item": "magic_smith", "chance": 40, "repeat": [ 1, 2 ] }, + "9": { "item": "NC_FORGE_LORD_STORE", "chance": 100, "repeat": [ 5, 8 ] }, + "$": [ + { "item": "forge_vault_items", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "forge_vault_money", "chance": 95, "repeat": [ 1, 3 ] } + ] + } + }, + { + "type": "overmap_special", + "id": "forge_of_wonders", + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "forge_1A_north" }, + { "point": [ 0, 0, 1 ], "overmap": "forge_1A_roof_north" }, + { "point": [ 1, 0, 0 ], "overmap": "forge_2A_north" }, + { "point": [ 1, 0, 1 ], "overmap": "forge_2A_roof_north" }, + { "point": [ 2, 0, 0 ], "overmap": "forge_3A_north" }, + { "point": [ 2, 0, 1 ], "overmap": "forge_3A_roof_north" }, + { "point": [ 3, 0, 0 ], "overmap": "forge_4A_north" }, + { "point": [ 3, 0, 1 ], "overmap": "forge_4A_roof_north" }, + { "point": [ 4, 0, 0 ], "overmap": "forge_5A_north" }, + { "point": [ 4, 0, 1 ], "overmap": "forge_5A_roof_north" }, + { "point": [ 0, 1, 0 ], "overmap": "forge_1B_north" }, + { "point": [ 0, 1, 1 ], "overmap": "forge_1B_roof_north" }, + { "point": [ 1, 1, 0 ], "overmap": "forge_2B_north" }, + { "point": [ 1, 1, 1 ], "overmap": "forge_2B_roof_north" }, + { "point": [ 2, 1, 0 ], "overmap": "forge_3B_north" }, + { "point": [ 2, 1, 1 ], "overmap": "forge_3B_roof_north" }, + { "point": [ 3, 1, 0 ], "overmap": "forge_4B_north" }, + { "point": [ 3, 1, 1 ], "overmap": "forge_4B_roof_north" }, + { "point": [ 4, 1, 0 ], "overmap": "forge_5B_north" }, + { "point": [ 4, 1, 1 ], "overmap": "forge_5B_roof_north" } + ], + "locations": [ "wilderness" ], + "city_distance": [ 20, -1 ], + "city_sizes": [ 0, 20 ], + "occurrences": [ 0, 1 ] + }, + { + "type": "overmap_terrain", + "id": [ + "forge_1A", + "forge_2A", + "forge_3A", + "forge_4A", + "forge_5A", + "forge_1B", + "forge_2B", + "forge_3B", + "forge_4B", + "forge_5B", + "forge_1A_roof", + "forge_2A_roof", + "forge_3A_roof", + "forge_4A_roof", + "forge_5A_roof", + "forge_1B_roof", + "forge_2B_roof", + "forge_3B_roof", + "forge_4B_roof", + "forge_5B_roof" + ], + "name": "forge of wonders", + "sym": "$", + "color": "red", + "see_cost": 5 + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ + [ "forge_1A_roof", "forge_2A_roof", "forge_3A_roof", "forge_4A_roof", "forge_5A_roof" ], + [ "forge_1B_roof", "forge_2B_roof", "forge_3B_roof", "forge_4B_roof", "forge_5B_roof" ] + ], + "object": { + "fill_ter": "t_shingle_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " .................................................................................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " ..................................... ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ">": "t_ladder_down" } + } + }, + { + "id": "achievement_reach_forge_of_wonder", + "type": "achievement", + "name": "Everything can be had for a priceā€¦", + "requirements": [ + { + "event_statistic": "last_oter_type_avatar_entered", + "is": "==", + "target": [ "oter_type_str_id", "forge_1B" ], + "visible": "when_achievement_completed", + "description": "See the Forge of Wonders" + } + ] + } +] From a79cb418c3e74e07623319f4a9e5ac020bc1f3bc Mon Sep 17 00:00:00 2001 From: KorGgenT Date: Mon, 20 Jul 2020 12:29:58 -0400 Subject: [PATCH 151/151] lint --- data/mods/Magiclysm/Spells/druid.json | 14 +++++++------- data/mods/Magiclysm/effects/effects.json | 8 ++------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/data/mods/Magiclysm/Spells/druid.json b/data/mods/Magiclysm/Spells/druid.json index 592f89a40c5eb..dc73eb7d54b8c 100644 --- a/data/mods/Magiclysm/Spells/druid.json +++ b/data/mods/Magiclysm/Spells/druid.json @@ -303,21 +303,21 @@ "valid_targets": [ "hostile", "ground", "ally", "self" ], "flags": [ "SOMATIC" ], "effect": "projectile_attack", - "effect_str": "tornskin_pain", + "effect_str": "tornskin_pain", "affected_body_parts": [ "HEAD", "TORSO", "MOUTH", "EYES", "ARM_L", "ARM_R", "HAND_R", "HAND_L", "LEG_L", "FOOT_L", "FOOT_R" ], - "min_dot": 1, - "max_dot": 4, - "dot_increment": 0.3, + "min_dot": 1, + "max_dot": 4, + "dot_increment": 0.3, "spell_class": "DRUID", "base_casting_time": 300, "base_energy_cost": 100, "energy_source": "MANA", "difficulty": 4, "max_level": 10, - "min_damage": 1, + "min_damage": 1, "max_damage": 4, "damage_increment": 0.3, - "min_aoe": 1, + "min_aoe": 1, "max_aoe": 2, "aoe_increment": 0.1, "min_range": 1, @@ -329,6 +329,6 @@ "min_pierce": 0, "max_pierce": 3, "pierce_increment": 0.3, - "damage_type": "cut" + "damage_type": "cut" } ] diff --git a/data/mods/Magiclysm/effects/effects.json b/data/mods/Magiclysm/effects/effects.json index 15bd1cd76a3b0..901e76ee15958 100644 --- a/data/mods/Magiclysm/effects/effects.json +++ b/data/mods/Magiclysm/effects/effects.json @@ -265,14 +265,10 @@ "id": "tornskin_pain", "name": [ "Sharp Thorns" ], "desc": [ "Thorns are whirling around you, regularly causing cuts into you." ], - "apply_message": "Thorns in the wind begin slicing into you!", + "apply_message": "Thorns in the wind begin slicing into you!", "remove_message": "The thorns fall to the ground.", "rating": "bad", "max_duration": "12 s", - "base_mods": { - "pain_min": [ 1 ], - "pain_chance": [ 6 ], - "speed_mod": [ -1 ] - } + "base_mods": { "pain_min": [ 1 ], "pain_chance": [ 6 ], "speed_mod": [ -1 ] } } ]