diff --git a/src/character.cpp b/src/character.cpp index 1858a1f3c37b5..a778f03102c41 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -611,7 +611,7 @@ void Character::mount_creature( monster &z ) z.remove_effect( effect_tied ); if( z.tied_item ) { i_add( *z.tied_item ); - z.tied_item = cata::nullopt; + z.tied_item.reset(); } } z.mounted_player_id = getID(); diff --git a/src/creature.cpp b/src/creature.cpp index c3f49a6c13aad..f268e9578653b 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -685,7 +685,8 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack if( z ) { if( !proj.get_drop().is_null() ) { z->add_effect( effect_tied, 1_turns, num_bp, true ); - z->tied_item = proj.get_drop(); + item drop_item = proj.get_drop(); + z->tied_item = cata::make_value( proj.get_drop() ); } else { add_msg( m_debug, "projectile with TANGLE effect, but no drop item specified" ); } diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 9c650fc83182b..66758d9ccdaf9 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -276,7 +276,7 @@ static item_location tack_loc() void monexamine::remove_battery( monster &z ) { g->m.add_item_or_charges( g->u.pos(), *z.battery_item ); - z.battery_item = cata::nullopt; + z.battery_item.reset(); } void monexamine::insert_battery( monster &z ) @@ -306,10 +306,10 @@ void monexamine::insert_battery( monster &z ) index > static_cast( bat_inv.size() ) ) { return; } - auto bat_item = bat_inv[index - 1]; + item *bat_item = bat_inv[index - 1]; int item_pos = g->u.get_item_position( bat_item ); if( item_pos != INT_MIN ) { - z.battery_item = *bat_item; + z.battery_item = cata::make_value( *bat_item ); g->u.i_rem( item_pos ); } } @@ -391,7 +391,7 @@ void monexamine::attach_or_remove_saddle( monster &z ) if( z.has_effect( effect_saddled ) ) { z.remove_effect( effect_saddled ); g->u.i_add( *z.tack_item ); - z.tack_item = cata::nullopt; + z.tack_item.reset(); } else { item_location loc = tack_loc(); @@ -400,7 +400,7 @@ void monexamine::attach_or_remove_saddle( monster &z ) return; } z.add_effect( effect_saddled, 1_turns, num_bp, true ); - z.tack_item = *loc; + z.tack_item = cata::make_value( *loc.get_item() ); loc.remove_item(); } } @@ -493,7 +493,7 @@ void monexamine::attach_bag_to( monster &z ) } item &it = *loc; - z.storage_item = it; + z.storage_item = cata::make_value( it ); add_msg( _( "You mount the %1$s on your %2$s." ), it.display_name(), pet_name ); g->u.i_rem( &it ); z.add_effect( effect_has_bag, 1_turns, num_bp, true ); @@ -511,7 +511,7 @@ void monexamine::remove_bag_from( monster &z ) } g->m.add_item_or_charges( g->u.pos(), *z.storage_item ); add_msg( _( "You remove the %1$s from %2$s." ), z.storage_item->display_name(), pet_name ); - z.storage_item = cata::nullopt; + z.storage_item.reset(); g->u.moves -= 200; } else { add_msg( m_bad, _( "Your %1$s doesn't have a bag!" ), pet_name ); @@ -585,7 +585,7 @@ bool monexamine::add_armor( monster &z ) } armor.set_var( "pet_armor", "true" ); - z.armor_item = armor; + z.armor_item = cata::make_value( armor ); add_msg( pgettext( "pet armor", "You put the %1$s on your %2$s." ), armor.display_name(), pet_name ); loc.remove_item(); @@ -609,7 +609,7 @@ void monexamine::remove_armor( monster &z ) g->m.add_item_or_charges( z.pos(), *z.armor_item ); add_msg( pgettext( "pet armor", "You remove the %1$s from %2$s." ), z.armor_item->display_name(), pet_name ); - z.armor_item = cata::nullopt; + z.armor_item.reset(); // TODO: removing armor from a horse takes a lot longer than 2 seconds. This should be a long action. g->u.moves -= 200; } else { @@ -646,7 +646,7 @@ void monexamine::tie_or_untie( monster &z ) z.remove_effect( effect_tied ); if( z.tied_item ) { g->u.i_add( *z.tied_item ); - z.tied_item = cata::nullopt; + z.tied_item.reset(); } } else { std::vector rope_inv = g->u.items_with( []( const item & itm ) { @@ -669,10 +669,10 @@ void monexamine::tie_or_untie( monster &z ) index > static_cast( rope_inv.size() ) ) { return; } - auto rope_item = rope_inv[index - 1]; + item *rope_item = rope_inv[index - 1]; int item_pos = g->u.get_item_position( rope_item ); if( item_pos != INT_MIN ) { - z.tied_item = *rope_item; + z.tied_item = cata::make_value( *rope_item ); g->u.i_rem( item_pos ); z.add_effect( effect_tied, 1_turns, num_bp, true ); } diff --git a/src/monster.cpp b/src/monster.cpp index 31515e038846f..90ab9aed4c6ae 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -234,7 +234,7 @@ monster::monster( const mtype_id &id ) : monster() int max_charge = type.magazine->capacity; item mech_bat_item = item( mech_bat, 0 ); mech_bat_item.ammo_consume( rng( 0, max_charge ), tripoint_zero ); - battery_item = mech_bat_item; + battery_item = cata::make_value( mech_bat_item ); } } @@ -1620,7 +1620,7 @@ bool monster::move_effects( bool ) add_msg( _( "The %s easily slips out of its bonds." ), name() ); } g->m.add_item_or_charges( pos(), *tied_item ); - tied_item = cata::nullopt; + tied_item.reset(); } } else { if( tied_item ) { @@ -1629,7 +1629,7 @@ bool monster::move_effects( bool ) if( !broken ) { g->m.add_item_or_charges( pos(), *tied_item ); } - tied_item = cata::nullopt; + tied_item.reset(); if( u_see_me ) { if( broken ) { add_msg( _( "The %s snaps the bindings holding it down." ), name() ); @@ -2656,11 +2656,11 @@ units::volume monster::get_carried_volume() return total_volume; } -void monster::move_special_item_to_inv( cata::optional &it ) +void monster::move_special_item_to_inv( cata::value_ptr &it ) { if( it ) { add_item( *it ); - it = cata::nullopt; + it.reset(); } } diff --git a/src/monster.h b/src/monster.h index add5e33786176..015db45b55a8d 100644 --- a/src/monster.h +++ b/src/monster.h @@ -27,6 +27,7 @@ #include "type_id.h" #include "units.h" #include "point.h" +#include "value_ptr.h" class JsonObject; class JsonIn; @@ -436,14 +437,14 @@ class monster : public Creature Character *mounted_player = nullptr; // player that is mounting this creature character_id mounted_player_id; // id of player that is mounting this creature ( for save/load ) character_id dragged_foe_id; // id of character being dragged by the monster - cata::optional tied_item; // item used to tie the monster - cata::optional tack_item; // item representing saddle and reins and such - cata::optional armor_item; // item of armor the monster may be wearing - cata::optional storage_item; // storage item for monster carrying items - cata::optional battery_item; // item to power mechs + cata::value_ptr tied_item; // item used to tie the monster + cata::value_ptr tack_item; // item representing saddle and reins and such + cata::value_ptr armor_item; // item of armor the monster may be wearing + cata::value_ptr storage_item; // storage item for monster carrying items + cata::value_ptr battery_item; // item to power mechs units::mass get_carried_weight(); units::volume get_carried_volume(); - void move_special_item_to_inv( cata::optional &it ); + void move_special_item_to_inv( cata::value_ptr &it ); // DEFINING VALUES int friendly; diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 0a7fe9b88b57f..32b243b4e46b4 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -1819,12 +1819,37 @@ void monster::load( const JsonObject &data ) if( data.read( "wandz", wander_pos.z ) ) { wander_pos.z = position.z; } - data.read( "tied_item", tied_item ); - data.read( "tack_item", tack_item ); - data.read( "armor_item", armor_item ); - data.read( "storage_item", storage_item ); + if( data.has_object( "tied_item" ) ) { + JsonIn *tied_item_json = data.get_raw( "tied_item" ); + item newitem; + newitem.deserialize( *tied_item_json ); + tied_item = cata::make_value( newitem ); + } + if( data.has_object( "tack_item" ) ) { + JsonIn *tack_item_json = data.get_raw( "tack_item" ); + item newitem; + newitem.deserialize( *tack_item_json ); + tack_item = cata::make_value( newitem ); + } + if( data.has_object( "armor_item" ) ) { + JsonIn *armor_item_json = data.get_raw( "armor_item" ); + item newitem; + newitem.deserialize( *armor_item_json ); + armor_item = cata::make_value( newitem ); + } + if( data.has_object( "storage_item" ) ) { + JsonIn *storage_item_json = data.get_raw( "storage_item" ); + item newitem; + newitem.deserialize( *storage_item_json ); + storage_item = cata::make_value( newitem ); + } + if( data.has_object( "battery_item" ) ) { + JsonIn *battery_item_json = data.get_raw( "battery_item" ); + item newitem; + newitem.deserialize( *battery_item_json ); + battery_item = cata::make_value( newitem ); + } data.read( "hp", hp ); - data.read( "battery_item", battery_item ); // sp_timeout indicates an old save, prior to the special_attacks refactor if( data.has_array( "sp_timeout" ) ) { @@ -1957,11 +1982,21 @@ void monster::store( JsonOut &json ) const json.member( "morale", morale ); json.member( "hallucination", hallucination ); json.member( "stairscount", staircount ); - json.member( "tied_item", tied_item ); - json.member( "tack_item", tack_item ); - json.member( "armor_item", armor_item ); - json.member( "storage_item", storage_item ); - json.member( "battery_item", battery_item ); + if( tied_item ) { + json.member( "tied_item", *tied_item ); + } + if( tack_item ) { + json.member( "tack_item", *tack_item ); + } + if( armor_item ) { + json.member( "armor_item", *armor_item ); + } + if( storage_item ) { + json.member( "storage_item", *storage_item ); + } + if( battery_item ) { + json.member( "battery_item", *battery_item ); + } // Store the relative position of the goal so it loads correctly after a map shift. json.member( "destination", goal - pos() ); json.member( "ammo", ammo ); diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index 5fa06a8184dd1..49b7008dbdf69 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -1739,7 +1739,7 @@ void vehicle::use_harness( int part, const tripoint &pos ) m.remove_effect( effect_tied ); if( m.tied_item ) { g->u.i_add( *m.tied_item ); - m.tied_item = cata::nullopt; + m.tied_item.reset(); } } }