From 0d7e5a5192d634fdc29890d157285ed39c24b8a6 Mon Sep 17 00:00:00 2001 From: actually-a-cat <102094270+actually-a-cat@users.noreply.github.com> Date: Wed, 21 Sep 2022 09:27:55 +0200 Subject: [PATCH] Unhardcode climate control --- data/json/bionics.json | 2 +- data/json/enchantments.json | 2 +- .../armor/bespoke_armor/custom_bodysuits.json | 9 +++-- data/json/items/armor/power_armor.json | 15 ++++++-- data/json/items/armor/suits_protection.json | 24 +++++++++---- data/json/items/tool_armor.json | 5 +-- .../items/armor/exosuit/exosuit_frame.json | 11 ++++-- .../armor/exosuit/exosuit_underlayers.json | 34 ++++++++++++------ .../Aftershock/items/armor/winter_masks.json | 13 ++++--- .../Aftershock/items/armor/winter_suits.json | 12 ++++--- data/mods/Aftershock/items/ethereal.json | 35 +++++++------------ data/mods/Aftershock/items/obsolete.json | 15 +++----- data/mods/Aftershock/items/tool_armor.json | 5 ++- .../CRT_EXPANSION/crt_gear/advanced_gear.json | 5 ++- data/mods/TEST_DATA/items.json | 5 ++- doc/MAGIC.md | 3 +- src/character.cpp | 31 ++++++++-------- src/character.h | 6 ++-- src/character_attire.cpp | 13 ------- src/character_attire.h | 1 - src/character_body.cpp | 7 ++-- src/flag.cpp | 1 - src/flag.h | 1 - src/magic_enchantment.cpp | 1 + src/magic_enchantment.h | 1 + 25 files changed, 147 insertions(+), 110 deletions(-) diff --git a/data/json/bionics.json b/data/json/bionics.json index 61b482e3da0b6..eab22fbb55b7d 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -602,7 +602,7 @@ "react_cost": "100 J", "time": "1 s", "flags": [ "BIONIC_TOGGLED" ], - "active_flags": [ "CLIMATE_CONTROL" ] + "enchantments": [ { "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] }, { "id": "bio_cloak", diff --git a/data/json/enchantments.json b/data/json/enchantments.json index ea41fb08e922d..abc721c87b76d 100644 --- a/data/json/enchantments.json +++ b/data/json/enchantments.json @@ -25,7 +25,7 @@ "type": "enchantment", "id": "RM13", "condition": "ACTIVE", - "values": [ { "value": "FOOTSTEP_NOISE", "multiply": -0.67 } ] + "values": [ { "value": "FOOTSTEP_NOISE", "multiply": -0.67 }, { "value": "CLIMATE_CONTROL", "add": 50 } ] }, { "type": "enchantment", diff --git a/data/json/items/armor/bespoke_armor/custom_bodysuits.json b/data/json/items/armor/bespoke_armor/custom_bodysuits.json index 63952c4929683..9994b8199623d 100644 --- a/data/json/items/armor/bespoke_armor/custom_bodysuits.json +++ b/data/json/items/armor/bespoke_armor/custom_bodysuits.json @@ -105,7 +105,12 @@ "warmth": 10, "material_thickness": 4, "valid_mods": [ "steel_padded" ], - "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "mutations": [ "well_distributed" ] } ] }, + "relic_data": { + "passive_effects": [ + { "has": "WORN", "condition": "ALWAYS", "mutations": [ "well_distributed" ] }, + { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } + ] + }, "environmental_protection": 1, "flags": [ "VARSIZE", "POCKETS", "STURDY", "USES_BIONIC_POWER", "MUNDANE" ] }, @@ -117,7 +122,7 @@ "name": { "str": "advanced nomad jumpsuit (on)", "str_pl": "advanced nomad jumpsuits (on)" }, "description": "A reinforced but airy jumpsuit designed to survive the long-term wear and tear of exploring the apocalyptic wasteland. Its clever construction adds additional core support, helping you to carry more equipment. The internal cooling tubes are active and humming.", "revert_to": "armor_nomad_advanced", - "flags": [ "VARSIZE", "POCKETS", "STURDY", "USES_BIONIC_POWER", "CLIMATE_CONTROL", "MUNDANE" ], + "flags": [ "VARSIZE", "POCKETS", "STURDY", "USES_BIONIC_POWER", "MUNDANE" ], "power_draw": "100 J", "use_action": { "ammo_scale": 0, diff --git a/data/json/items/armor/power_armor.json b/data/json/items/armor/power_armor.json index a41711cae633c..de42b666b29db 100644 --- a/data/json/items/armor/power_armor.json +++ b/data/json/items/armor/power_armor.json @@ -139,6 +139,9 @@ "symbol": "[", "looks_like": "depowered_armor", "color": "light_gray", + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -234,7 +237,7 @@ "type": "TOOL_ARMOR", "name": { "str": "combat exoskeleton (on)", "str_pl": "combat exoskeletons (on)" }, "description": "These were the second wave of military combat exoskeleton, and got a lot of media attention, with popular Navy commercials featuring them heavily. It consists of a muscle-boosting exoskeleton frame with overlaid segmented alloy plating. Despite advancements over the original bulky 'tank suits', the wearer still cannot easily fit through narrow spaces, or sit down comfortably (and it ruins upholstery). There is an integrated chemical-resistant bodyglove that precludes wearing other clothing. It is turned on and continually drawing power. Use it to turn it off.", - "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "CLIMATE_CONTROL", "COMBAT_TOGGLEABLE" ], + "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "COMBAT_TOGGLEABLE" ], "power_draw": "4 kJ", "revert_to": "power_armor_basic", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_basic" }, @@ -327,6 +330,9 @@ "symbol": "[", "looks_like": "power_armor_basic", "color": "dark_gray", + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -422,7 +428,7 @@ "type": "TOOL_ARMOR", "name": { "str": "heavy combat exoskeleton (on)", "str_pl": "heavy combat exoskeletons (on)" }, "description": "Colloquially known as a 'tank suit' in the media, these bulky exoskeletons, covered in thick segmented armor plates, were tested in military service a few years back and determined to be too heavy and expensive for regular use. Now that it's in your hands, though, you have a massive suit of power armor capable of resisting almost any small arms fire and most other forms of attack. On the other hand, it doubles your effective weight, and it's almost impossible not to bump into things. There is an integrated chemical-resistant bodyglove that precludes wearing other clothing. It is turned on and continually drawing power. Use it to turn it off.", - "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "CLIMATE_CONTROL", "COMBAT_TOGGLEABLE" ], + "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "COMBAT_TOGGLEABLE" ], "power_draw": "4 kJ", "revert_to": "power_armor_heavy", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_heavy" }, @@ -587,6 +593,9 @@ "symbol": "[", "looks_like": "depowered_armor", "color": "dark_gray", + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -682,7 +691,7 @@ "type": "TOOL_ARMOR", "name": { "str": "field combat exoskeleton (on)", "str_pl": "field combat exoskeletons (on)" }, "description": "The final iteration of military power armor before the fall of civilization, this type - a powered exoskeleton with high-tech segmented plating - was designed for actual widespread combat use and was seen on the front lines during the last days of the Cataclysm. Like the heavier suits, it is resistant to most modern weaponry, but it is light and maneuverable, and can fit into normal vehicles and doorways without fuss, a huge advantage over predecessors. Unfortunately, the world ended before it could roll out in significant numbers. There is an integrated chemical-resistant bodyglove that precludes wearing other clothing. It is turned on and continually drawing power. Use it to turn it off.", - "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "CLIMATE_CONTROL", "COMBAT_TOGGLEABLE" ], + "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "COMBAT_TOGGLEABLE" ], "power_draw": "4 kJ", "revert_to": "power_armor_light", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "power_armor_light" }, diff --git a/data/json/items/armor/suits_protection.json b/data/json/items/armor/suits_protection.json index cfdf28f2ee89f..6cd7455375333 100644 --- a/data/json/items/armor/suits_protection.json +++ b/data/json/items/armor/suits_protection.json @@ -3042,7 +3042,12 @@ } ], "extend": { "flags": [ "NORMAL", "MUNDANE", "USES_BIONIC_POWER" ] }, - "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "mutations": [ "well_distributed" ] } ] }, + "relic_data": { + "passive_effects": [ + { "has": "WORN", "condition": "ALWAYS", "mutations": [ "well_distributed" ] }, + { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } + ] + }, "use_action": { "type": "transform", "msg": "You turn the climate control on.", @@ -3059,7 +3064,6 @@ "type": "TOOL_ARMOR", "name": { "str": "nomad plate armor (on)", "str_pl": "nomad plate armors (on)" }, "revert_to": "armor_nomad_plate", - "extend": { "flags": [ "CLIMATE_CONTROL" ] }, "power_draw": "100 J", "use_action": { "ammo_scale": 0, @@ -3110,7 +3114,12 @@ } ], "extend": { "flags": [ "NORMAL", "MUNDANE", "USES_BIONIC_POWER" ] }, - "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "mutations": [ "well_distributed" ] } ] }, + "relic_data": { + "passive_effects": [ + { "has": "WORN", "condition": "ALWAYS", "mutations": [ "well_distributed" ] }, + { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } + ] + }, "use_action": { "type": "transform", "msg": "You turn the climate control on.", @@ -3127,7 +3136,6 @@ "type": "TOOL_ARMOR", "name": { "str": "nomad light plate armor (on)", "str_pl": "nomad light plate armors (on)" }, "revert_to": "armor_nomad_lightplate", - "extend": { "flags": [ "CLIMATE_CONTROL" ] }, "power_draw": "100 J", "use_action": { "ammo_scale": 0, @@ -3178,7 +3186,12 @@ } ], "extend": { "flags": [ "NORMAL", "MUNDANE", "USES_BIONIC_POWER" ] }, - "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "mutations": [ "well_distributed" ] } ] }, + "relic_data": { + "passive_effects": [ + { "has": "WORN", "condition": "ALWAYS", "mutations": [ "well_distributed" ] }, + { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } + ] + }, "use_action": { "type": "transform", "msg": "You turn the climate control on.", @@ -3195,7 +3208,6 @@ "type": "TOOL_ARMOR", "name": { "str": "nomad heavy plate armor (on)", "str_pl": "nomad heavy plate armors (on)" }, "revert_to": "armor_nomad_heavyplate", - "extend": { "flags": [ "CLIMATE_CONTROL" ] }, "power_draw": "100 J", "use_action": { "ammo_scale": 0, diff --git a/data/json/items/tool_armor.json b/data/json/items/tool_armor.json index 61d7e8862a986..755b8959256fb 100644 --- a/data/json/items/tool_armor.json +++ b/data/json/items/tool_armor.json @@ -1265,7 +1265,6 @@ "ELECTRIC_IMMUNE", "THERMOMETER", "TRADER_AVOID", - "CLIMATE_CONTROL", "NO_REPAIR", "NANOFAB_REPAIR", "PADDED", @@ -1437,6 +1436,9 @@ "NANOFAB_REPAIR", "PADDED" ], + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "armor": [ { "material": [ { "type": "lvl4ballisticglass", "covered_by_mat": 100, "thickness": 1.0 } ], @@ -1533,7 +1535,6 @@ "TRADER_AVOID", "PSYSHIELD_PARTIAL", "GNV_EFFECT", - "CLIMATE_CONTROL", "NO_REPAIR", "NANOFAB_REPAIR", "PADDED" diff --git a/data/mods/Aftershock/items/armor/exosuit/exosuit_frame.json b/data/mods/Aftershock/items/armor/exosuit/exosuit_frame.json index 44e4f0e3f4905..4462650bad2c1 100644 --- a/data/mods/Aftershock/items/armor/exosuit/exosuit_frame.json +++ b/data/mods/Aftershock/items/armor/exosuit/exosuit_frame.json @@ -305,7 +305,15 @@ ], "ammo": "battery", "flags": [ "USE_UPS", "STURDY", "WATERPROOF", "ELECTRIC_IMMUNE", "COMBAT_TOGGLEABLE", "OUTER", "MUNDANE", "DEAF" ], - "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "STRENGTH", "add": 10 } ] } ] }, + "relic_data": { + "passive_effects": [ + { + "has": "WORN", + "condition": "ACTIVE", + "values": [ { "value": "STRENGTH", "add": 10 }, { "value": "CLIMATE_CONTROL", "add": 50 } ] + } + ] + }, "use_action": [ { "target": "modular_exosuit_on", @@ -333,7 +341,6 @@ "ELECTRIC_IMMUNE", "COMBAT_TOGGLEABLE", "OUTER", - "CLIMATE_CONTROL", "PARTIAL_DEAF", "SUN_GLASSES", "FLASH_PROTECTION" diff --git a/data/mods/Aftershock/items/armor/exosuit/exosuit_underlayers.json b/data/mods/Aftershock/items/armor/exosuit/exosuit_underlayers.json index 2740000cf0580..82a8c35c8bc08 100644 --- a/data/mods/Aftershock/items/armor/exosuit/exosuit_underlayers.json +++ b/data/mods/Aftershock/items/armor/exosuit/exosuit_underlayers.json @@ -28,13 +28,17 @@ } ], "warmth": 10, - "flags": [ "EXO_UNDERLAYER", "CANT_WEAR", "SKINTIGHT", "WATERPROOF", "POWERARMOR_COMPATIBLE", "SOFT", "CLIMATE_CONTROL" ], + "flags": [ "EXO_UNDERLAYER", "CANT_WEAR", "SKINTIGHT", "WATERPROOF", "POWERARMOR_COMPATIBLE", "SOFT" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", - "values": [ { "value": "ITEM_ENCUMBRANCE", "add": -10 }, { "value": "ARMOR_COLD", "multiply": -0.25 } ] + "values": [ + { "value": "ITEM_ENCUMBRANCE", "add": -10 }, + { "value": "ARMOR_COLD", "multiply": -0.25 }, + { "value": "CLIMATE_CONTROL", "add": 50 } + ] } ] } @@ -76,13 +80,17 @@ } ], "warmth": 10, - "flags": [ "EXO_UNDERLAYER", "CANT_WEAR", "SKINTIGHT", "WATERPROOF", "POWERARMOR_COMPATIBLE", "SOFT", "CLIMATE_CONTROL" ], + "flags": [ "EXO_UNDERLAYER", "CANT_WEAR", "SKINTIGHT", "WATERPROOF", "POWERARMOR_COMPATIBLE", "SOFT" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", - "values": [ { "value": "ITEM_ENCUMBRANCE", "add": -10 }, { "value": "ARMOR_COLD", "multiply": -0.25 } ] + "values": [ + { "value": "ITEM_ENCUMBRANCE", "add": -10 }, + { "value": "ARMOR_COLD", "multiply": -0.25 }, + { "value": "CLIMATE_CONTROL", "add": 50 } + ] } ] } @@ -125,15 +133,18 @@ "SOFT", "GAS_PROOF", "RAD_RESIST", - "RAINPROOF", - "CLIMATE_CONTROL" + "RAINPROOF" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", - "values": [ { "value": "ITEM_ENCUMBRANCE", "add": -10 }, { "value": "ARMOR_COLD", "multiply": -0.25 } ] + "values": [ + { "value": "ITEM_ENCUMBRANCE", "add": -10 }, + { "value": "ARMOR_COLD", "multiply": -0.25 }, + { "value": "CLIMATE_CONTROL", "add": 50 } + ] } ] } @@ -184,15 +195,18 @@ "SOFT", "GAS_PROOF", "RAD_RESIST", - "RAINPROOF", - "CLIMATE_CONTROL" + "RAINPROOF" ], "relic_data": { "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", - "values": [ { "value": "ITEM_ENCUMBRANCE", "add": -10 }, { "value": "ARMOR_COLD", "multiply": -0.25 } ] + "values": [ + { "value": "ITEM_ENCUMBRANCE", "add": -10 }, + { "value": "ARMOR_COLD", "multiply": -0.25 }, + { "value": "CLIMATE_CONTROL", "add": 50 } + ] } ] } diff --git a/data/mods/Aftershock/items/armor/winter_masks.json b/data/mods/Aftershock/items/armor/winter_masks.json index 994d2ffcbaf30..4c364bcd01c2d 100644 --- a/data/mods/Aftershock/items/armor/winter_masks.json +++ b/data/mods/Aftershock/items/armor/winter_masks.json @@ -30,6 +30,9 @@ { "covers": [ "eyes" ], "rigid_layer_only": true, "coverage": 100, "encumbrance": 5 }, { "covers": [ "mouth" ], "rigid_layer_only": true, "coverage": 100, "encumbrance": 15 } ], + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "battery": 1000 } } ], "warmth": 10, "material_thickness": 6, @@ -60,9 +63,7 @@ "warmth": 150, "revert_to": "afs_magellan_suit_helmet", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "afs_magellan_suit_helmet" }, - "extend": { - "flags": [ "CLIMATE_CONTROL", "GAS_PROOF", "WATCH", "ALARMCLOCK", "THERMOMETER", "HYGROMETER", "PARTIAL_DEAF", "TRADER_AVOID" ] - }, + "extend": { "flags": [ "GAS_PROOF", "WATCH", "ALARMCLOCK", "THERMOMETER", "HYGROMETER", "PARTIAL_DEAF", "TRADER_AVOID" ] }, "environmental_protection": 15 }, { @@ -95,6 +96,9 @@ { "covers": [ "eyes" ], "rigid_layer_only": true, "coverage": 100, "encumbrance": 15 }, { "covers": [ "mouth" ], "rigid_layer_only": true, "coverage": 100, "encumbrance": 20 } ], + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "pocket_data": [ { "pocket_type": "MAGAZINE_WELL", @@ -119,7 +123,6 @@ "power_draw": "6944 mJ", "warmth": 150, "revert_to": "afs_frontier_cryomask", - "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "afs_frontier_cryomask" }, - "extend": { "flags": [ "CLIMATE_CONTROL" ] } + "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "afs_frontier_cryomask" } } ] diff --git a/data/mods/Aftershock/items/armor/winter_suits.json b/data/mods/Aftershock/items/armor/winter_suits.json index c08a724d42bf7..7bb543a8c0684 100644 --- a/data/mods/Aftershock/items/armor/winter_suits.json +++ b/data/mods/Aftershock/items/armor/winter_suits.json @@ -29,6 +29,9 @@ { "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 10 }, { "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 15 } ], + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "pocket_data": [ { "pocket_type": "MAGAZINE", "rigid": true, "ammo_restriction": { "battery": 1000 } } ], "warmth": 20, "material_thickness": 2, @@ -59,8 +62,7 @@ "power_draw": "8170 mJ", "warmth": 150, "revert_to": "afs_magellan_suit", - "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "afs_magellan_suit" }, - "extend": { "flags": [ "CLIMATE_CONTROL" ] } + "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "afs_magellan_suit" } }, { "id": "afs_frontier_cryo", @@ -93,6 +95,9 @@ { "covers": [ "hand_l", "hand_r" ], "coverage": 100, "encumbrance": 25 }, { "covers": [ "foot_l", "foot_r" ], "coverage": 100, "encumbrance": 15 } ], + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "pocket_data": [ { "pocket_type": "MAGAZINE_WELL", @@ -118,7 +123,6 @@ "power_draw": "6944 mJ", "warmth": 150, "revert_to": "afs_frontier_cryo", - "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "afs_frontier_cryo" }, - "extend": { "flags": [ "CLIMATE_CONTROL" ] } + "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "Your %s deactivates.", "target": "afs_frontier_cryo" } } ] diff --git a/data/mods/Aftershock/items/ethereal.json b/data/mods/Aftershock/items/ethereal.json index 5a8ee739546e6..fb3ba18cb3010 100644 --- a/data/mods/Aftershock/items/ethereal.json +++ b/data/mods/Aftershock/items/ethereal.json @@ -11,17 +11,10 @@ "warmth": 150, "color": "green", "material": [ "oil" ], - "flags": [ - "AURA", - "SEMITANGIBLE", - "OVERSIZE", - "ONLY_ONE", - "WATER_FRIENDLY", - "TRADER_AVOID", - "NO_TAKEOFF", - "CLIMATE_CONTROL", - "NONCONDUCTIVE" - ], + "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "WATER_FRIENDLY", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ], + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "armor": [ { "covers": [ "leg_l", "leg_r", "torso", "arm_l", "arm_r", "hand_l", "hand_r", "head", "foot_l", "foot_r", "mouth", "eyes" ] @@ -40,19 +33,15 @@ "warmth": 150, "color": "green", "material": [ "oil" ], - "flags": [ - "AURA", - "SEMITANGIBLE", - "OVERSIZE", - "ONLY_ONE", - "WATER_FRIENDLY", - "TRADER_AVOID", - "NO_TAKEOFF", - "CLIMATE_CONTROL", - "NONCONDUCTIVE" - ], + "flags": [ "AURA", "SEMITANGIBLE", "OVERSIZE", "ONLY_ONE", "WATER_FRIENDLY", "TRADER_AVOID", "NO_TAKEOFF", "NONCONDUCTIVE" ], "relic_data": { - "passive_effects": [ { "has": "WORN", "condition": "ALWAYS", "values": [ { "value": "ARMOR_COLD", "multiply": -0.25 } ] } ] + "passive_effects": [ + { + "has": "WORN", + "condition": "ALWAYS", + "values": [ { "value": "ARMOR_COLD", "multiply": -0.25 }, { "value": "CLIMATE_CONTROL", "add": 50 } ] + } + ] }, "armor": [ { diff --git a/data/mods/Aftershock/items/obsolete.json b/data/mods/Aftershock/items/obsolete.json index 5e27cc23b6b16..f3847e2932fee 100644 --- a/data/mods/Aftershock/items/obsolete.json +++ b/data/mods/Aftershock/items/obsolete.json @@ -252,23 +252,16 @@ "price_postapoc": 50000, "material": [ "superalloy", "kevlar" ], "material_thickness": 2, + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "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 } ], "warmth": 20, "environmental_protection": 5, - "flags": [ - "CLIMATE_CONTROL", - "ELECTRIC_IMMUNE", - "RAD_PROOF", - "WATERPROOF", - "COLLAR", - "THERMOMETER", - "ONLY_ONE", - "OUTER", - "STURDY" - ], + "flags": [ "ELECTRIC_IMMUNE", "RAD_PROOF", "WATERPROOF", "COLLAR", "THERMOMETER", "ONLY_ONE", "OUTER", "STURDY" ], "looks_like": "depowered_armor", "armor": [ { diff --git a/data/mods/Aftershock/items/tool_armor.json b/data/mods/Aftershock/items/tool_armor.json index efcf07eb7aee4..6cfe5eeb6adbc 100644 --- a/data/mods/Aftershock/items/tool_armor.json +++ b/data/mods/Aftershock/items/tool_armor.json @@ -15,6 +15,9 @@ "volume": "4500 ml", "charges_per_use": 5, "ammo": "battery", + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "pocket_data": [ { "pocket_type": "MAGAZINE_WELL", @@ -54,6 +57,6 @@ "power_draw": "90 J", "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" ] + "flags": [ "STURDY", "WATERPROOF", "THERMOMETER", "RAINPROOF" ] } ] diff --git a/data/mods/CRT_EXPANSION/crt_gear/advanced_gear.json b/data/mods/CRT_EXPANSION/crt_gear/advanced_gear.json index ad74e6cdd3352..e7ff272a6ade3 100644 --- a/data/mods/CRT_EXPANSION/crt_gear/advanced_gear.json +++ b/data/mods/CRT_EXPANSION/crt_gear/advanced_gear.json @@ -47,6 +47,9 @@ "symbol": "[", "color": "light_gray", "warmth": 15, + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -60,7 +63,7 @@ "material_thickness": 3, "environmental_protection": 18, "use_action": [ "WEATHER_TOOL" ], - "flags": [ "ELECTRIC_IMMUNE", "GAS_PROOF", "VARSIZE", "OVERSIZE", "STURDY", "ONLY_ONE", "WATERPROOF", "CLIMATE_CONTROL" ], + "flags": [ "ELECTRIC_IMMUNE", "GAS_PROOF", "VARSIZE", "OVERSIZE", "STURDY", "ONLY_ONE", "WATERPROOF" ], "armor": [ { "encumbrance": 25, diff --git a/data/mods/TEST_DATA/items.json b/data/mods/TEST_DATA/items.json index fa87bbfb2b72b..0e3b65c9eb7b4 100644 --- a/data/mods/TEST_DATA/items.json +++ b/data/mods/TEST_DATA/items.json @@ -2429,6 +2429,9 @@ "symbol": "[", "looks_like": "depowered_armor", "color": "light_gray", + "relic_data": { + "passive_effects": [ { "has": "WORN", "condition": "ACTIVE", "values": [ { "value": "CLIMATE_CONTROL", "add": 50 } ] } ] + }, "pocket_data": [ { "pocket_type": "CONTAINER", @@ -2460,7 +2463,7 @@ "type": "TOOL_ARMOR", "name": { "str": "test power armor (on)" }, "description": "This is a prototype power armor just for testing.", - "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID", "CLIMATE_CONTROL" ], + "flags": [ "USE_UPS", "WATERPROOF", "STURDY", "ELECTRIC_IMMUNE", "TRADER_AVOID" ], "power_draw": "4 kJ", "revert_to": "test_power_armor", "use_action": { "type": "transform", "menu_text": "Turn off", "msg": "The %s armor disengages.", "target": "test_power_armor" } diff --git a/doc/MAGIC.md b/doc/MAGIC.md index 6e9ad9b2e6d02..18790eb8ec8fb 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -684,7 +684,8 @@ The following is a list of possible `values`: | `BONUS_BLOCK` | | `BONUS_DODGE` | | `BONUS_DAMAGE` | -| `CARRY_WEIGHT` | +| `CARRY_WEIGHT` | +| `CLIMATE_CONTROL` | Moves body temperature towards comfortable by number of warmth units up to value. | `DEXTERITY` | | `INTELLIGENCE` | | `PERCEPTION` | diff --git a/src/character.cpp b/src/character.cpp index 2f0e81026dddf..0678115d06074 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -289,7 +289,6 @@ static const json_character_flag json_flag_BLIND( "BLIND" ); static const json_character_flag json_flag_BULLET_IMMUNE( "BULLET_IMMUNE" ); static const json_character_flag json_flag_CLAIRVOYANCE( "CLAIRVOYANCE" ); static const json_character_flag json_flag_CLAIRVOYANCE_PLUS( "CLAIRVOYANCE_PLUS" ); -static const json_character_flag json_flag_CLIMATE_CONTROL( "CLIMATE_CONTROL" ); static const json_character_flag json_flag_COLD_IMMUNE( "COLD_IMMUNE" ); static const json_character_flag json_flag_CUT_IMMUNE( "CUT_IMMUNE" ); static const json_character_flag json_flag_DEAF( "DEAF" ); @@ -3501,21 +3500,23 @@ units::mass Character::get_weight() const return ret; } -bool Character::in_climate_control() +int Character::climate_control_strength() { - bool regulated_area = false; - // Check - if( has_flag( json_flag_CLIMATE_CONTROL ) ) { - return true; + // In warmth points + const int DEFAULT_STRENGTH = 50; + + int ench_power = enchantment_cache->get_value_add( enchant_vals::mod::CLIMATE_CONTROL ); + if( ench_power > 0 ) { + return ench_power; } + map &here = get_map(); if( has_trait( trait_M_SKIN3 ) && here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_FUNGUS, pos() ) && in_sleep_state() ) { - return true; - } - if( worn.in_climate_control() ) { - return true; + return DEFAULT_STRENGTH; } + + bool regulated_area = false; if( calendar::turn >= next_climate_control_check ) { // save CPU and simulate acclimation. next_climate_control_check = calendar::turn + 20_turns; @@ -3542,9 +3543,10 @@ bool Character::in_climate_control() next_climate_control_check += 40_turns; } } else { - return last_climate_control_ret; + return last_climate_control_ret ? DEFAULT_STRENGTH : 0; } - return regulated_area; + + return regulated_area ? DEFAULT_STRENGTH : 0; } std::map Character::get_wind_resistance( const std::map ( BODYTEMP_NORM * 0.5 ); + const int variation = static_cast( BODYTEMP_NORM * ( climate_control_strength / 100.0f ) ); if( temperature > BODYTEMP_NORM ) { return std::max( BODYTEMP_NORM, temperature - variation ); diff --git a/src/character.h b/src/character.h index b3867ed7b022f..6f83f2a307a58 100644 --- a/src/character.h +++ b/src/character.h @@ -808,8 +808,8 @@ class Character : public Creature, public visitable /** Returns true if the player is wearing an active optical cloak */ bool is_wearing_active_optcloak() const; - /** Returns true if the player is in a climate controlled area or armor */ - bool in_climate_control(); + /** Returns strength of any climate control affecting character */ + int climate_control_strength(); /** Returns wind resistance provided by armor, etc **/ std::map get_wind_resistance( const @@ -2866,7 +2866,7 @@ class Character : public Creature, public visitable /** Correction factor of the body temperature due to traits and mutations for player lying on the floor **/ int bodytemp_modifier_traits_floor() const; /** Value of the body temperature corrected by climate control **/ - int temp_corrected_by_climate_control( int temperature ) const; + int temp_corrected_by_climate_control( int temperature, int climate_control_strength ) const; bool in_sleep_state() const override; /** Set vitamin deficiency/excess disease states dependent upon current vitamin levels */ diff --git a/src/character_attire.cpp b/src/character_attire.cpp index d627ff0469852..3b61bdbfc1748 100644 --- a/src/character_attire.cpp +++ b/src/character_attire.cpp @@ -1660,19 +1660,6 @@ void outfit::get_overlay_ids( std::vector> & } } -bool outfit::in_climate_control() const -{ - for( const item &w : worn ) { - if( w.active && w.is_power_armor() ) { - return true; - } - if( w.has_flag( flag_CLIMATE_CONTROL ) ) { - return true; - } - } - return false; -} - std::list::iterator outfit::position_to_wear_new_item( const item &new_item ) { // By default we put this item on after the last item on the same or any diff --git a/src/character_attire.h b/src/character_attire.h index 1dd2905ab4a88..de1147d58ee29 100644 --- a/src/character_attire.h +++ b/src/character_attire.h @@ -75,7 +75,6 @@ class outfit const body_part_set &worn_item_body_parts ) const; // will someone get shocked by zapback bool hands_conductive() const; - bool in_climate_control() const; bool can_pickVolume( const item &it, bool ignore_pkt_settings = true ) const; side is_wearing_shoes( const bodypart_id &bp ) const; bool is_wearing_helmet() const; diff --git a/src/character_body.cpp b/src/character_body.cpp index e559645057d3b..638c9efed682a 100644 --- a/src/character_body.cpp +++ b/src/character_body.cpp @@ -423,7 +423,7 @@ void Character::update_bodytemp() const bool has_heatsink = has_flag( json_flag_HEATSINK ) || is_wearing( itype_rm13_armor_on ) || heat_immune; const bool has_common_cold = has_effect( effect_common_cold ); - const bool has_climate_control = in_climate_control(); + const int climate_control = climate_control_strength(); const bool use_floor_warmth = can_use_floor_warmth(); const furn_id furn_at_pos = here.furn( pos() ); const cata::optional boardable = vp.part_with_feature( "BOARDABLE", true ); @@ -579,8 +579,9 @@ void Character::update_bodytemp() temp_equalizer( bp, bp->main_part ); // Climate Control eases the effects of high and low ambient temps - if( has_climate_control ) { - set_part_temp_conv( bp, temp_corrected_by_climate_control( get_part_temp_conv( bp ) ) ); + if( climate_control ) { + set_part_temp_conv( bp, temp_corrected_by_climate_control( get_part_temp_conv( bp ), + climate_control ) ); } // FINAL CALCULATION : Increments current body temperature towards convergent. diff --git a/src/flag.cpp b/src/flag.cpp index 66d5dcf9938cc..468ef53d4d236 100644 --- a/src/flag.cpp +++ b/src/flag.cpp @@ -59,7 +59,6 @@ const flag_id flag_CHALLENGE( "CHALLENGE" ); const flag_id flag_CHARGEDIM( "CHARGEDIM" ); const flag_id flag_CHOKE( "CHOKE" ); const flag_id flag_CITY_START( "CITY_START" ); -const flag_id flag_CLIMATE_CONTROL( "CLIMATE_CONTROL" ); const flag_id flag_COLD( "COLD" ); const flag_id flag_COLD_IMMUNE( "COLD_IMMUNE" ); const flag_id flag_COLLAPSED_STOCK( "COLLAPSED_STOCK" ); diff --git a/src/flag.h b/src/flag.h index 3d2482d5e4db7..53285318bbd7a 100644 --- a/src/flag.h +++ b/src/flag.h @@ -69,7 +69,6 @@ extern const flag_id flag_CHALLENGE; extern const flag_id flag_CHARGEDIM; extern const flag_id flag_CHOKE; extern const flag_id flag_CITY_START; -extern const flag_id flag_CLIMATE_CONTROL; extern const flag_id flag_COLD; extern const flag_id flag_COLD_IMMUNE; extern const flag_id flag_COLLAPSED_STOCK; diff --git a/src/magic_enchantment.cpp b/src/magic_enchantment.cpp index 1b0e3c8b399d4..a51243c0cbef8 100644 --- a/src/magic_enchantment.cpp +++ b/src/magic_enchantment.cpp @@ -142,6 +142,7 @@ namespace io case enchant_vals::mod::ITEM_COVERAGE: return "ITEM_COVERAGE"; case enchant_vals::mod::ITEM_ATTACK_SPEED: return "ITEM_ATTACK_SPEED"; case enchant_vals::mod::ITEM_WET_PROTECTION: return "ITEM_WET_PROTECTION"; + case enchant_vals::mod::CLIMATE_CONTROL: return "CLIMATE_CONTROL"; case enchant_vals::mod::NUM_MOD: break; } cata_fatal( "Invalid enchant_vals::mod" ); diff --git a/src/magic_enchantment.h b/src/magic_enchantment.h index 44d4d6f085aa5..fb6daa891cc70 100644 --- a/src/magic_enchantment.h +++ b/src/magic_enchantment.h @@ -120,6 +120,7 @@ enum class mod : int { ITEM_COVERAGE, ITEM_ATTACK_SPEED, ITEM_WET_PROTECTION, + CLIMATE_CONTROL, NUM_MOD }; } // namespace enchant_vals