From fa508a48d5c1dcc8bf83ea6e48724611f2b549fe Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 2 May 2020 21:52:48 +0200 Subject: [PATCH 1/8] Damage over time initial implementation --- src/character.cpp | 5 +++++ src/character.h | 1 + src/creature.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/creature.h | 9 +++++++++ src/iuse_actor.cpp | 27 +++++++++++++++++++++++++++ src/iuse_actor.h | 15 +++++++++++++++ src/monster.cpp | 5 +++++ src/monster.h | 2 ++ 8 files changed, 108 insertions(+) diff --git a/src/character.cpp b/src/character.cpp index 1d1b1a9172319..4e650b50f388b 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -8584,6 +8584,11 @@ int Character::reduce_healing_effect( const efftype_id &eff_id, int remove_med, return intensity; } +void Character::heal_bp( bodypart_id bp, int dam ) +{ + heal( bp->token, dam ); +} + void Character::heal( body_part healed, int dam ) { hp_part healpart; diff --git a/src/character.h b/src/character.h index 6a72dc603cd0e..2a5fee27125cb 100644 --- a/src/character.h +++ b/src/character.h @@ -794,6 +794,7 @@ class Character : public Creature, public visitable /** Handles effects that happen when the player is damaged and aware of the fact. */ void on_hurt( Creature *source, bool disturb = true ); /** Heals a body_part for dam */ + void heal_bp( bodypart_id bp, int dam ) override; void heal( body_part healed, int dam ); /** Heals an hp_part for dam */ void heal( hp_part healed, int dam ); diff --git a/src/creature.cpp b/src/creature.cpp index 4e1ae88311d5f..07c80b3b6c63d 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -152,6 +152,8 @@ void Creature::process_turn() process_effects(); + process_damage_over_time(); + // Call this in case any effects have changed our stats reset_stats(); @@ -897,6 +899,10 @@ void Creature::deal_damage_handle_type( const damage_unit &du, bodypart_id bp, i pain += roll_remainder( adjusted_damage / div ); } +void Creature::heal_bp( bodypart_id bp, int dam ) +{ +} + /* * State check functions */ @@ -1666,6 +1672,44 @@ body_part Creature::select_body_part( Creature *source, int hit_roll ) const return human_anatomy->select_body_part( szdif, hit_roll )->token; } +void Creature::add_damage_over_time( const bodypart_id &bp, const damage_type &type, + const int amount, const time_duration &time ) +{ + const std::pair dmg_spec( time, amount ); + std::map> DoT_instance; + DoT_instance.emplace( type, dmg_spec ); + if( damage_over_time_map.find( bp ) != damage_over_time_map.end() ) { + + damage_over_time_map[bp].try_emplace( type, dmg_spec ); + } else { + damage_over_time_map.emplace( bp, DoT_instance ); + } +} + +void Creature::process_damage_over_time() +{ + for( const bodypart_id &bp : get_all_body_parts() ) { + if( damage_over_time_map.find( bp ) != damage_over_time_map.end() ) { + for( const std::pair> &DoT_instance : + damage_over_time_map[bp] ) { + const std::pair &dmg_spec = DoT_instance.second; + if( dmg_spec.first > 0_turns ) { + const int dmg_amount = dmg_spec.second; + if( dmg_amount < 0 ) { + heal_bp( bp, -dmg_amount ); + } else { + deal_damage( nullptr, bp, damage_instance( DoT_instance.first, dmg_amount ) ); + } + + damage_over_time_map[bp][DoT_instance.first].first -= 1_turns; + } else { + damage_over_time_map[bp].erase( DoT_instance.first ); + } + } + } + } +} + void Creature::check_dead_state() { if( is_dead_state() ) { diff --git a/src/creature.h b/src/creature.h index 5394393946fd2..52eba38fe1cc3 100644 --- a/src/creature.h +++ b/src/creature.h @@ -265,6 +265,8 @@ class Creature virtual void apply_damage( Creature *source, bodypart_id bp, int amount, bool bypass_med = false ) = 0; + virtual void heal_bp( bodypart_id bp, int dam ); + /** * This creature just dodged an attack - possibly special/ranged attack - from source. * Players should train dodge, monsters may use some special defenses. @@ -750,6 +752,9 @@ class Creature virtual void process_one_effect( effect &e, bool is_new ) = 0; pimpl effects; + + std::map< bodypart_id, std::map > >damage_over_time_map; + // Miscellaneous key/value pairs. std::unordered_map values; @@ -795,6 +800,10 @@ class Creature public: body_part select_body_part( Creature *source, int hit_roll ) const; + void add_damage_over_time( const bodypart_id &bp, const damage_type &type, const int amount, + const time_duration &time ); + void process_damage_over_time(); + static void load_hit_range( const JsonObject & ); // Empirically determined by "synthetic_range_test" in tests/ranged_balance.cpp. static std::vector dispersion_for_even_chance_of_good_hit; diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 14ea87d28e584..34de611bb8239 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -690,6 +690,21 @@ static effect_data load_effect_data( const JsonObject &e ) get_body_part_token( e.get_string( "bp", "NUM_BP" ) ), e.get_bool( "permanent", false ) ); } +static DoT_data load_DoT_data( const JsonObject &e ) +{ + time_duration time; + std::vector bps; + if( e.has_string( "duration" ) ) { + time = read_from_json_string( *e.get_raw( "duration" ), time_duration::units ); + } else { + time = time_duration::from_turns( e.get_int( "duration", 0 ) ); + } + for( const std::string &bp_id : e.get_array( "bodyparts" ) ) { + bps.emplace_back( bodypart_str_id( bp_id ) ); + } + return DoT_data( dt_by_name( e.get_string( "damage_type" ) ), time, bps, e.get_int( "amount" ) ); +} + void consume_drug_iuse::load( const JsonObject &obj ) { obj.read( "activation_message", activation_message ); @@ -701,6 +716,11 @@ void consume_drug_iuse::load( const JsonObject &obj ) effects.push_back( load_effect_data( e ) ); } } + if( obj.has_array( "damage_over_time" ) ) { + for( const JsonObject e : obj.get_array( "damage_over_time" ) ) { + damage_over_time.push_back( load_DoT_data( e ) ); + } + } obj.read( "stat_adjustments", stat_adjustments ); obj.read( "fields_produced", fields_produced ); obj.read( "moves", moves ); @@ -777,6 +797,13 @@ int consume_drug_iuse::use( player &p, item &it, bool, const tripoint & ) const } p.add_effect( eff.id, dur, eff.bp, eff.permanent ); } + //Apply the various damage_over_time + for( const DoT_data Dot : damage_over_time ) { + for( const bodypart_str_id &bp : Dot.bps ) { + p.add_damage_over_time( bp.id(), Dot.type, Dot.amount, Dot.duration ); + } + + } for( const auto &stat_adjustment : stat_adjustments ) { p.mod_stat( stat_adjustment.first, stat_adjustment.second ); } diff --git a/src/iuse_actor.h b/src/iuse_actor.h index 2aaf591fa434c..439ca0f8de29b 100644 --- a/src/iuse_actor.h +++ b/src/iuse_actor.h @@ -12,6 +12,7 @@ #include "calendar.h" #include "color.h" +#include "damage.h" #include "enums.h" #include "explosion.h" #include "game_constants.h" @@ -239,6 +240,18 @@ struct effect_data { id( nid ), duration( dur ), bp( nbp ), permanent( perm ) {} }; +/** Used in consume_drug_iuse for storing damage over time data. */ +struct DoT_data { + damage_type type; + time_duration duration; + std::vector bps; + int amount; + + DoT_data( const damage_type &type, const time_duration &dur, const std::vector &nbp, + const int dmg ) : + type( type ), duration( dur ), bps( nbp ), amount( dmg ) {} +}; + /** * This iuse encapsulates the effects of taking a drug. */ @@ -261,6 +274,8 @@ class consume_drug_iuse : public iuse_actor /** Modify player vitamin_levels by random amount between min (first) and max (second) */ std::map> vitamins; + std::vector damage_over_time; + /** How many move points this action takes. */ int moves = 100; diff --git a/src/monster.cpp b/src/monster.cpp index 68fb6488c8470..d0b3f1743f867 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -1624,6 +1624,11 @@ void monster::die_in_explosion( Creature *source ) die( source ); } +void monster::heal_bp( bodypart_id, int dam ) +{ + heal( dam ); +} + bool monster::movement_impaired() { return effect_cache[MOVEMENT_IMPAIRED]; diff --git a/src/monster.h b/src/monster.h index 61a258014c1dc..1d2abe257155f 100644 --- a/src/monster.h +++ b/src/monster.h @@ -320,6 +320,8 @@ class monster : public Creature void explode(); // Let the monster die and let its body explode into gibs void die_in_explosion( Creature *source ); + + void heal_bp( bodypart_id bp, int dam ) override; /** * Flat addition to the monsters @ref hp. If `overheal` is true, this is not capped by max hp. * Returns actually healed hp. From 395ddc7f99c0963d68531c800a762b371ee7f8dc Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sat, 2 May 2020 22:04:30 +0200 Subject: [PATCH 2/8] Unhardcode healing from panacea and move it to Aftershock --- data/mods/Aftershock/items/comestibles.json | 23 +++++++++++++++++++++ src/player_hardcoded_effects.cpp | 6 ------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/data/mods/Aftershock/items/comestibles.json b/data/mods/Aftershock/items/comestibles.json index a73f11e34e478..127bf14320281 100644 --- a/data/mods/Aftershock/items/comestibles.json +++ b/data/mods/Aftershock/items/comestibles.json @@ -90,5 +90,28 @@ { "id": "downed", "duration": 1 } ] } + }, + { + "id": "panacea", + "type": "COMESTIBLE", + "comestible_type": "MED", + "name": { "str": "Panaceus", "str_pl": "Panaceii" }, + "symbol": "!", + "color": "red", + "copy-from": "panacea", + "use_action": { + "type": "consume_drug", + "activation_message": "You feel AMAZING!", + "effects": [ { "id": "panacea", "duration": "1 m" }, { "id": "cureall" } ], + "damage_over_time": [ + { + "damage_type": "true", + "duration": "1 m", + "amount": -10, + "bodyparts": [ "torso", "head", "arm_l", "leg_l", "arm_r", "leg_r" ] + } + ] + }, + "flags": [ "NPC_SAFE", "IRREPLACEABLE_CONSUMABLE" ] } ] diff --git a/src/player_hardcoded_effects.cpp b/src/player_hardcoded_effects.cpp index 90e745e920536..849e21169ac3a 100644 --- a/src/player_hardcoded_effects.cpp +++ b/src/player_hardcoded_effects.cpp @@ -1307,12 +1307,6 @@ void player::hardcoded_effects( effect &it ) // Just unpause, in case someone added it as a temporary effect (numbing poison etc.) it.unpause_effect(); } - } else if( id == effect_panacea ) { - // restore health all body parts, dramatically reduce pain - for( int i = 0; i < num_hp_parts; i++ ) { - hp_cur[i] += 10; - } - mod_pain( -10 ); } else if( id == effect_toxin_buildup ) { // Loosely based on toxic man-made compounds (mostly pesticides) which don't degrade // easily, leading to build-up in muscle and fat tissue through bioaccumulation. From c36a39c8ae274294f5b747df8d0e37d1ec680821 Mon Sep 17 00:00:00 2001 From: Fris0uman <41293484+Fris0uman@users.noreply.github.com> Date: Sun, 3 May 2020 09:55:52 +0200 Subject: [PATCH 3/8] Update src/creature.cpp Co-authored-by: Curtis Merrill --- src/creature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/creature.cpp b/src/creature.cpp index 07c80b3b6c63d..3d59d09a7181b 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -899,7 +899,7 @@ void Creature::deal_damage_handle_type( const damage_unit &du, bodypart_id bp, i pain += roll_remainder( adjusted_damage / div ); } -void Creature::heal_bp( bodypart_id bp, int dam ) +void Creature::heal_bp( bodypart_id /* bp */, int /* dam */ ) { } From bdc89cfe47d843ccd080e066b0f50591cdbe56c3 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sun, 3 May 2020 11:07:52 +0200 Subject: [PATCH 4/8] DoT class --- src/creature.cpp | 39 +++++++++++++-------------------------- src/creature.h | 6 +++--- src/damage.cpp | 17 +++++++++++++++++ src/damage.h | 12 ++++++++++++ src/iuse_actor.cpp | 27 ++++++--------------------- src/iuse_actor.h | 16 ++-------------- 6 files changed, 53 insertions(+), 64 deletions(-) diff --git a/src/creature.cpp b/src/creature.cpp index 3d59d09a7181b..37ce60e768da7 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -1672,40 +1672,27 @@ body_part Creature::select_body_part( Creature *source, int hit_roll ) const return human_anatomy->select_body_part( szdif, hit_roll )->token; } -void Creature::add_damage_over_time( const bodypart_id &bp, const damage_type &type, - const int amount, const time_duration &time ) +void Creature::add_damage_over_time( const damage_over_time_data &DoT ) { - const std::pair dmg_spec( time, amount ); - std::map> DoT_instance; - DoT_instance.emplace( type, dmg_spec ); - if( damage_over_time_map.find( bp ) != damage_over_time_map.end() ) { - - damage_over_time_map[bp].try_emplace( type, dmg_spec ); - } else { - damage_over_time_map.emplace( bp, DoT_instance ); - } + damage_over_time_map.emplace_back( DoT ); } void Creature::process_damage_over_time() { - for( const bodypart_id &bp : get_all_body_parts() ) { - if( damage_over_time_map.find( bp ) != damage_over_time_map.end() ) { - for( const std::pair> &DoT_instance : - damage_over_time_map[bp] ) { - const std::pair &dmg_spec = DoT_instance.second; - if( dmg_spec.first > 0_turns ) { - const int dmg_amount = dmg_spec.second; - if( dmg_amount < 0 ) { - heal_bp( bp, -dmg_amount ); - } else { - deal_damage( nullptr, bp, damage_instance( DoT_instance.first, dmg_amount ) ); - } - - damage_over_time_map[bp][DoT_instance.first].first -= 1_turns; + for( auto DoT = damage_over_time_map.begin(); DoT != damage_over_time_map.end(); ) { + if( DoT->duration > 0_turns ) { + for( const bodypart_str_id &bp : DoT->bps ) { + const int dmg_amount = DoT->amount; + if( dmg_amount < 0 ) { + heal_bp( bp.id(), -dmg_amount ); } else { - damage_over_time_map[bp].erase( DoT_instance.first ); + deal_damage( nullptr, bp.id(), damage_instance( DoT->type, dmg_amount ) ); } } + DoT->duration -= 1_turns; + ++DoT; + } else { + damage_over_time_map.erase( DoT ); } } } diff --git a/src/creature.h b/src/creature.h index 52eba38fe1cc3..82e3cef395e9c 100644 --- a/src/creature.h +++ b/src/creature.h @@ -12,6 +12,7 @@ #include "anatomy.h" #include "bodypart.h" +#include "damage.h" #include "pimpl.h" #include "string_formatter.h" #include "translations.h" @@ -753,7 +754,7 @@ class Creature pimpl effects; - std::map< bodypart_id, std::map > >damage_over_time_map; + std::vector damage_over_time_map; // Miscellaneous key/value pairs. std::unordered_map values; @@ -800,8 +801,7 @@ class Creature public: body_part select_body_part( Creature *source, int hit_roll ) const; - void add_damage_over_time( const bodypart_id &bp, const damage_type &type, const int amount, - const time_duration &time ); + void add_damage_over_time( const damage_over_time_data &DoT ); void process_damage_over_time(); static void load_hit_range( const JsonObject & ); diff --git a/src/damage.cpp b/src/damage.cpp index 38ffe715ecd21..5c2bbb7fc6c39 100644 --- a/src/damage.cpp +++ b/src/damage.cpp @@ -423,3 +423,20 @@ resistances load_resistances_instance( const JsonObject &jo ) ret.resist_vals = load_damage_array( jo ); return ret; } + +void damage_over_time_data::load_DoT_data( const JsonObject &obj ) +{ + type = dt_by_name( obj.get_string( "damage_type" ) ); + + amount = obj.get_int( "amount" ); + + if( obj.has_string( "duration" ) ) { + duration = read_from_json_string( *obj.get_raw( "duration" ), time_duration::units ); + } else { + duration = time_duration::from_turns( obj.get_int( "duration", 0 ) ); + } + + for( const std::string &bp_id : obj.get_array( "bodyparts" ) ) { + bps.emplace_back( bodypart_str_id( bp_id ) ); + } +} diff --git a/src/damage.h b/src/damage.h index 6302bd3eed6ca..4e84726aa46ea 100644 --- a/src/damage.h +++ b/src/damage.h @@ -8,6 +8,7 @@ #include #include "type_id.h" +#include "calendar.h" class item; class monster; @@ -85,6 +86,17 @@ struct damage_instance { void deserialize( JsonIn & ); }; +class damage_over_time_data +{ + public: + damage_type type; + time_duration duration; + std::vector bps; + int amount; + + void load_DoT_data( const JsonObject &obj ); +}; + struct dealt_damage_instance { std::array dealt_dams; body_part bp_hit; diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 34de611bb8239..1e31f5d6f3bff 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -25,6 +25,7 @@ #include "clothing_mod.h" #include "crafting.h" #include "creature.h" +#include "damage.h" #include "debug.h" #include "effect.h" #include "enum_conversions.h" @@ -690,21 +691,6 @@ static effect_data load_effect_data( const JsonObject &e ) get_body_part_token( e.get_string( "bp", "NUM_BP" ) ), e.get_bool( "permanent", false ) ); } -static DoT_data load_DoT_data( const JsonObject &e ) -{ - time_duration time; - std::vector bps; - if( e.has_string( "duration" ) ) { - time = read_from_json_string( *e.get_raw( "duration" ), time_duration::units ); - } else { - time = time_duration::from_turns( e.get_int( "duration", 0 ) ); - } - for( const std::string &bp_id : e.get_array( "bodyparts" ) ) { - bps.emplace_back( bodypart_str_id( bp_id ) ); - } - return DoT_data( dt_by_name( e.get_string( "damage_type" ) ), time, bps, e.get_int( "amount" ) ); -} - void consume_drug_iuse::load( const JsonObject &obj ) { obj.read( "activation_message", activation_message ); @@ -718,7 +704,9 @@ void consume_drug_iuse::load( const JsonObject &obj ) } if( obj.has_array( "damage_over_time" ) ) { for( const JsonObject e : obj.get_array( "damage_over_time" ) ) { - damage_over_time.push_back( load_DoT_data( e ) ); + damage_over_time_data tmp_DoT_data; + tmp_DoT_data.load_DoT_data( e ); + damage_over_time.emplace_back( tmp_DoT_data ); } } obj.read( "stat_adjustments", stat_adjustments ); @@ -798,11 +786,8 @@ int consume_drug_iuse::use( player &p, item &it, bool, const tripoint & ) const p.add_effect( eff.id, dur, eff.bp, eff.permanent ); } //Apply the various damage_over_time - for( const DoT_data Dot : damage_over_time ) { - for( const bodypart_str_id &bp : Dot.bps ) { - p.add_damage_over_time( bp.id(), Dot.type, Dot.amount, Dot.duration ); - } - + for( const damage_over_time_data &Dot : damage_over_time ) { + p.add_damage_over_time( Dot ); } for( const auto &stat_adjustment : stat_adjustments ) { p.mod_stat( stat_adjustment.first, stat_adjustment.second ); diff --git a/src/iuse_actor.h b/src/iuse_actor.h index 439ca0f8de29b..7f450397ed483 100644 --- a/src/iuse_actor.h +++ b/src/iuse_actor.h @@ -10,7 +10,6 @@ #include #include -#include "calendar.h" #include "color.h" #include "damage.h" #include "enums.h" @@ -240,18 +239,6 @@ struct effect_data { id( nid ), duration( dur ), bp( nbp ), permanent( perm ) {} }; -/** Used in consume_drug_iuse for storing damage over time data. */ -struct DoT_data { - damage_type type; - time_duration duration; - std::vector bps; - int amount; - - DoT_data( const damage_type &type, const time_duration &dur, const std::vector &nbp, - const int dmg ) : - type( type ), duration( dur ), bps( nbp ), amount( dmg ) {} -}; - /** * This iuse encapsulates the effects of taking a drug. */ @@ -274,7 +261,8 @@ class consume_drug_iuse : public iuse_actor /** Modify player vitamin_levels by random amount between min (first) and max (second) */ std::map> vitamins; - std::vector damage_over_time; + /**List of damage over time applyed by this drug, negative damage heals*/ + std::vector damage_over_time; /** How many move points this action takes. */ int moves = 100; From 7ed98c6069b957ed6e38d34041f68d6e5ccafbe5 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sun, 3 May 2020 12:41:31 +0200 Subject: [PATCH 5/8] Save and load DoT --- src/damage.cpp | 10 ++++++++++ src/damage.h | 2 ++ src/savegame_json.cpp | 16 ++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/src/damage.cpp b/src/damage.cpp index 5c2bbb7fc6c39..4209cdf5130aa 100644 --- a/src/damage.cpp +++ b/src/damage.cpp @@ -440,3 +440,13 @@ void damage_over_time_data::load_DoT_data( const JsonObject &obj ) bps.emplace_back( bodypart_str_id( bp_id ) ); } } + +void damage_over_time_data::store( JsonOut &jsout ) const +{ + jsout.start_object(); + jsout.member( "damage_type", name_by_dt( type ) ); + jsout.member( "duration", duration ); + jsout.member( "amount", amount ); + jsout.member( "bodyparts", bps ); + jsout.end_object(); +} diff --git a/src/damage.h b/src/damage.h index 4e84726aa46ea..042b9508c1b9c 100644 --- a/src/damage.h +++ b/src/damage.h @@ -95,6 +95,8 @@ class damage_over_time_data int amount; void load_DoT_data( const JsonObject &obj ); + + void store( JsonOut &jsout ) const; }; struct dealt_damage_instance { diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 6b6ec6ca635ac..b6dd27c25c914 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -48,6 +48,7 @@ #include "craft_command.h" #include "creature.h" #include "creature_tracker.h" +#include "damage.h" #include "debug.h" #include "effect.h" #include "enum_conversions.h" @@ -2981,6 +2982,13 @@ void Creature::store( JsonOut &jsout ) const } jsout.member( "effects", tmp_map ); + jsout.member( "damage_over_time_map" ); + jsout.start_array(); + for( const damage_over_time_data &DoT : damage_over_time_map ) { + DoT.store( jsout ); + } + jsout.end_array(); + jsout.member( "values", values ); jsout.member( "blocks_left", num_blocks ); @@ -3046,6 +3054,14 @@ void Creature::load( const JsonObject &jsin ) } jsin.read( "values", values ); + if( jsin.has_array( "damage_over_time_map" ) ) { + for( const JsonObject &obj : jsin.get_array( "damage_over_time_map" ) ) { + damage_over_time_data tmp_DoT; + tmp_DoT.load_DoT_data( obj ); + add_damage_over_time( tmp_DoT ); + } + } + jsin.read( "blocks_left", num_blocks ); jsin.read( "dodges_left", num_dodges ); jsin.read( "num_blocks_bonus", num_blocks_bonus ); From 1fc89a34b8e62720e5cd979c4a35f3bef75ad355 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sun, 3 May 2020 12:46:19 +0200 Subject: [PATCH 6/8] doc --- doc/JSON_INFO.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index 55fadb0dd8148..fb136425b0add 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -2270,6 +2270,14 @@ The contents of use_action fields can either be a string indicating a built-in f "type" : "consume_drug", // A drug the player can consume. "activation_message" : "You smoke your crack rocks. Mother would be proud.", // Message, ayup. "effects" : { "high": 15 }, // Effects and their duration. + "damage_over_time": [ + { + "damage_type": "true", // Type of damage + "duration": "1 m", // For how long this damage will be applied + "amount": -10, // Amount of damage applied every turn, negative damage heals + "bodyparts": [ "torso", "head", "arm_l", "leg_l", "arm_r", "leg_r" ] // Body parts hit by the damage + } + ] "stat_adjustments": {"hunger" : -10}, // Adjustment to make to player stats. "fields_produced" : {"cracksmoke" : 2}, // Fields to produce, mostly used for smoke. "charges_needed" : { "fire" : 1 }, // Charges to use in the process of consuming the drug. From 9be7d8010fddad043b5b7a5dbf62985c2556c5f1 Mon Sep 17 00:00:00 2001 From: Fris0uman <41293484+Fris0uman@users.noreply.github.com> Date: Sun, 3 May 2020 18:31:25 +0200 Subject: [PATCH 7/8] Apply suggestions from code review Co-authored-by: Curtis Merrill --- src/damage.cpp | 4 ++-- src/damage.h | 2 +- src/iuse_actor.cpp | 8 +------- src/savegame_json.cpp | 16 ++-------------- 4 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/damage.cpp b/src/damage.cpp index 4209cdf5130aa..da8b36310f0ab 100644 --- a/src/damage.cpp +++ b/src/damage.cpp @@ -424,7 +424,7 @@ resistances load_resistances_instance( const JsonObject &jo ) return ret; } -void damage_over_time_data::load_DoT_data( const JsonObject &obj ) +void damage_over_time_data::load( const JsonObject &obj ) { type = dt_by_name( obj.get_string( "damage_type" ) ); @@ -441,7 +441,7 @@ void damage_over_time_data::load_DoT_data( const JsonObject &obj ) } } -void damage_over_time_data::store( JsonOut &jsout ) const +void damage_over_time_data::serialize( JsonOut &jsout ) const { jsout.start_object(); jsout.member( "damage_type", name_by_dt( type ) ); diff --git a/src/damage.h b/src/damage.h index 042b9508c1b9c..cdaa8ce9e91c1 100644 --- a/src/damage.h +++ b/src/damage.h @@ -94,7 +94,7 @@ class damage_over_time_data std::vector bps; int amount; - void load_DoT_data( const JsonObject &obj ); + void load( const JsonObject &obj ); void store( JsonOut &jsout ) const; }; diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 1e31f5d6f3bff..2b8c243f02c59 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -702,13 +702,7 @@ void consume_drug_iuse::load( const JsonObject &obj ) effects.push_back( load_effect_data( e ) ); } } - if( obj.has_array( "damage_over_time" ) ) { - for( const JsonObject e : obj.get_array( "damage_over_time" ) ) { - damage_over_time_data tmp_DoT_data; - tmp_DoT_data.load_DoT_data( e ); - damage_over_time.emplace_back( tmp_DoT_data ); - } - } + optional( obj, false, "damage_over_time", damage_over_time_data ); obj.read( "stat_adjustments", stat_adjustments ); obj.read( "fields_produced", fields_produced ); obj.read( "moves", moves ); diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index b6dd27c25c914..9d2bb8b3d254a 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -2982,13 +2982,7 @@ void Creature::store( JsonOut &jsout ) const } jsout.member( "effects", tmp_map ); - jsout.member( "damage_over_time_map" ); - jsout.start_array(); - for( const damage_over_time_data &DoT : damage_over_time_map ) { - DoT.store( jsout ); - } - jsout.end_array(); - +jsout.member( "damage_over_time_map", damage_over_time_map ); jsout.member( "values", values ); jsout.member( "blocks_left", num_blocks ); @@ -3054,13 +3048,7 @@ void Creature::load( const JsonObject &jsin ) } jsin.read( "values", values ); - if( jsin.has_array( "damage_over_time_map" ) ) { - for( const JsonObject &obj : jsin.get_array( "damage_over_time_map" ) ) { - damage_over_time_data tmp_DoT; - tmp_DoT.load_DoT_data( obj ); - add_damage_over_time( tmp_DoT ); - } - } +jsin.read( "damage_over_time_map", damage_over_time_data ); jsin.read( "blocks_left", num_blocks ); jsin.read( "dodges_left", num_dodges ); From 6efc8b6b739c2206cae673dbd8e5d016a7b02ef6 Mon Sep 17 00:00:00 2001 From: Fris0uman Date: Sun, 3 May 2020 19:28:58 +0200 Subject: [PATCH 8/8] serialize, deserialize and load in proper cdda fashion --- src/damage.cpp | 22 +++++++++++++++------- src/damage.h | 5 ++++- src/iuse_actor.cpp | 3 ++- src/savegame_json.cpp | 4 ++-- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/damage.cpp b/src/damage.cpp index da8b36310f0ab..7fa9a2deffd27 100644 --- a/src/damage.cpp +++ b/src/damage.cpp @@ -7,6 +7,7 @@ #include #include "debug.h" +#include "generic_factory.h" #include "item.h" #include "json.h" #include "monster.h" @@ -426,19 +427,17 @@ resistances load_resistances_instance( const JsonObject &jo ) void damage_over_time_data::load( const JsonObject &obj ) { - type = dt_by_name( obj.get_string( "damage_type" ) ); - - amount = obj.get_int( "amount" ); + std::string tmp_string; + mandatory( obj, was_loaded, "damage_type", tmp_string ); + type = dt_by_name( tmp_string ); + mandatory( obj, was_loaded, "amount", amount ); + mandatory( obj, was_loaded, "bodyparts", bps ); if( obj.has_string( "duration" ) ) { duration = read_from_json_string( *obj.get_raw( "duration" ), time_duration::units ); } else { duration = time_duration::from_turns( obj.get_int( "duration", 0 ) ); } - - for( const std::string &bp_id : obj.get_array( "bodyparts" ) ) { - bps.emplace_back( bodypart_str_id( bp_id ) ); - } } void damage_over_time_data::serialize( JsonOut &jsout ) const @@ -450,3 +449,12 @@ void damage_over_time_data::serialize( JsonOut &jsout ) const jsout.member( "bodyparts", bps ); jsout.end_object(); } + +void damage_over_time_data::deserialize( JsonIn &jsin ) +{ + const JsonObject &jo = jsin.get_object(); + type = dt_by_name( jo.get_string( "damage_type" ) ); + jo.read( "amount", amount ); + jo.read( "duration", duration ); + jo.read( "bodyparts", bps ); +} diff --git a/src/damage.h b/src/damage.h index cdaa8ce9e91c1..dc795dd4bb772 100644 --- a/src/damage.h +++ b/src/damage.h @@ -94,9 +94,12 @@ class damage_over_time_data std::vector bps; int amount; + bool was_loaded; + void load( const JsonObject &obj ); - void store( JsonOut &jsout ) const; + void serialize( JsonOut &jsout ) const; + void deserialize( JsonIn &jsin ); }; struct dealt_damage_instance { diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 2b8c243f02c59..1a3ce5571d7c7 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -35,6 +35,7 @@ #include "flat_set.h" #include "game.h" #include "game_inventory.h" +#include "generic_factory.h" #include "int_id.h" #include "inventory.h" #include "item.h" @@ -702,7 +703,7 @@ void consume_drug_iuse::load( const JsonObject &obj ) effects.push_back( load_effect_data( e ) ); } } - optional( obj, false, "damage_over_time", damage_over_time_data ); + optional( obj, false, "damage_over_time", damage_over_time ); obj.read( "stat_adjustments", stat_adjustments ); obj.read( "fields_produced", fields_produced ); obj.read( "moves", moves ); diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 9d2bb8b3d254a..cd71758d4e8fd 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -2982,7 +2982,7 @@ void Creature::store( JsonOut &jsout ) const } jsout.member( "effects", tmp_map ); -jsout.member( "damage_over_time_map", damage_over_time_map ); + jsout.member( "damage_over_time_map", damage_over_time_map ); jsout.member( "values", values ); jsout.member( "blocks_left", num_blocks ); @@ -3048,7 +3048,7 @@ void Creature::load( const JsonObject &jsin ) } jsin.read( "values", values ); -jsin.read( "damage_over_time_map", damage_over_time_data ); + jsin.read( "damage_over_time_map", damage_over_time_map ); jsin.read( "blocks_left", num_blocks ); jsin.read( "dodges_left", num_dodges );