diff --git a/src/mapgen.cpp b/src/mapgen.cpp index a7c84a6844f4..c829db17667e 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -5579,7 +5579,7 @@ std::unique_ptr map::add_vehicle_to_map( for( const vpart_reference &vpr : old_veh->get_all_parts() ) { const tripoint part_pos = old_veh->global_part_pos3( vpr.part() ) - global_pos; - wreckage->install_part( part_pos.xy(), vehicle_part{vpr.part()} ); + wreckage->install_part( part_pos.xy(), vehicle_part{vpr.part(), &*wreckage} ); } wreckage->name = _( "Wreckage" ); diff --git a/src/monster.cpp b/src/monster.cpp index 759f1464ac81..31706022fa88 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -272,63 +272,8 @@ monster::monster( const monster &source ) : Creature( source ), corpse_components.push_back( item::spawn( *it ) ); } - hp = source.hp; - special_attacks = source.special_attacks; - goal = source.goal; - position = source.position; - dead = source.dead; - upgrades = source.upgrades; - upgrade_time = source.upgrade_time; - reproduces = source.reproduces; - baby_timer = source.baby_timer; - udder_timer = source.udder_timer; - horde_attraction = source.horde_attraction; - path = source.path; - effect_cache = source.effect_cache; - summon_time_limit = source.summon_time_limit; - - set_tied_item( item::spawn( *source.tied_item ) ); - set_tack_item( item::spawn( *source.tack_item ) ); - set_armor_item( item::spawn( *source.armor_item ) ); - set_storage_item( item::spawn( *source.storage_item ) ); - set_battery_item( item::spawn( *source.battery_item ) ); - set_anatomy( anatomy_id( "default_anatomy" ) ); -}; - -monster::monster( monster &&source ) noexcept : Creature( std::move( source ) ), - corpse_components( new monster_component_item_location( - this ) ), tied_item( new monster_tied_item_location( this ) ), - tack_item( new monster_tack_item_location( this ) ), - armor_item( new monster_armor_item_location( this ) ), - storage_item( new monster_storage_item_location( this ) ), - battery_item( new monster_battery_item_location( this ) ), - inv( new monster_item_location( this ) ) -{ - wander_pos = source.wander_pos; - wandf = source.wandf; - mounted_player = source.mounted_player; - mounted_player_id = source.mounted_player_id; - dragged_foe_id = source.dragged_foe_id; - friendly = source.friendly; - anger = source.anger; - morale = source.morale; - faction = source.faction; - mission_id = source.mission_id; - type = source.type; - no_extra_death_drops = source.no_extra_death_drops; - no_corpse_quiet = source.no_corpse_quiet; - death_drops = source.death_drops; - made_footstep = source.made_footstep; - unique_name = source.unique_name; - hallucination = source.hallucination; - fish_population = source.fish_population; - ignoring = source.ignoring; - lastseen_turn = source.lastseen_turn; - staircount = source.staircount; - ammo = source.ammo; - - for( const item * const &it : source.corpse_components ) { - corpse_components.push_back( item::spawn( *it ) ); + for( const item * const &it : source.inv ) { + inv.push_back( item::spawn( *it ) ); } hp = source.hp; diff --git a/src/monster.h b/src/monster.h index 3249ead7cacd..383c8d89b8b1 100644 --- a/src/monster.h +++ b/src/monster.h @@ -97,7 +97,6 @@ class monster : public Creature, public location_visitable monster( const mtype_id &id ); monster( const mtype_id &id, const tripoint &pos ); monster( const monster & ); - monster( monster && ) noexcept ; ~monster() override; monster &operator=( const monster & ) = delete; monster &operator=( monster && ) = delete; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 45d53215aa68..411692de3612 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -256,6 +256,112 @@ units::volume vehicle_stack::max_volume() const // Vehicle class methods. +void vehicle::copy_static_from( const vehicle &source ) +{ + //next_hack_id isn't copied + //parts isn't copied; + collision_check_points = source.collision_check_points; + owner = source.owner; + old_owner = source.old_owner; + coefficient_air_resistance = source.coefficient_air_resistance; + coefficient_rolling_resistance = source.coefficient_rolling_resistance; + coefficient_water_resistance = source.coefficient_water_resistance; + draft_m = source.draft_m; + hull_height = source.hull_height; + hull_area = source.hull_area; + occupied_points = source.occupied_points; + alternators = source.alternators; + engines = source.engines; + reactors = source.reactors; + solar_panels = source.solar_panels; + wind_turbines = source.wind_turbines; + water_wheels = source.water_wheels; + sails = source.sails; + funnels = source.funnels; + emitters = source.emitters; + loose_parts = source.loose_parts; + wheelcache = source.wheelcache; + rotors = source.rotors; + rail_wheelcache = source.rail_wheelcache; + steering = source.steering; + speciality = source.speciality; + floating = source.floating; + rail_profile = source.rail_profile; + name = source.name; + type = source.type; + relative_parts = source.relative_parts; + labels = source.labels; + tags = source.tags; + fuel_remainder = source.fuel_remainder; + fuel_used_last_turn = source.fuel_used_last_turn; + loot_zones = source.loot_zones; + active_items = source.active_items; + magic = source.magic; + summon_time_limit = source.summon_time_limit; + mass_cache = source.mass_cache; + pivot_cache = source.pivot_cache; + mount_max = source.mount_max; + mount_min = source.mount_min; + mass_center_precalc = source.mass_center_precalc; + mass_center_no_precalc = source.mass_center_no_precalc; + autodrive_local_target = source.autodrive_local_target; + active_autodrive_controller = source.active_autodrive_controller; + removed_part_count = source.removed_part_count; + sm_pos = source.sm_pos; + alternator_load = source.alternator_load; + occupied_cache_time = source.occupied_cache_time; + last_update = source.last_update; + pos = source.pos; + velocity = source.velocity; + cruise_velocity = source.cruise_velocity; + vertical_velocity = source.vertical_velocity; + om_id = source.om_id; + turn_dir = source.turn_dir; + last_turn = source.last_turn; + of_turn = source.of_turn; + of_turn_carry = source.of_turn_carry; + extra_drag = source.extra_drag; + last_fluid_check = source.last_fluid_check; + theft_time = source.theft_time; + pivot_rotation = source.pivot_rotation; + front_left = source.front_left; + front_right = source.front_right; + tow_data = source.tow_data; + pivot_anchor = source.pivot_anchor; + face = source.face; + move = source.move; + no_refresh = source.no_refresh; + pivot_dirty = source.pivot_dirty; + mass_dirty = source.mass_dirty; + mass_center_precalc_dirty = source.mass_center_precalc_dirty; + mass_center_no_precalc_dirty = source.mass_center_no_precalc_dirty; + coeff_rolling_dirty = source.coeff_rolling_dirty; + coeff_air_dirty = source.coeff_air_dirty; + coeff_water_dirty = source.coeff_water_dirty; + coeff_air_changed = source.coeff_air_changed; + is_floating = source.is_floating; + in_water = source.in_water; + is_flying = source.is_flying; + requested_z_change = source.requested_z_change; + attached = source.attached; + is_autodriving = source.is_autodriving; + is_following = source.is_following; + is_patrolling = source.is_patrolling; + cruise_on = source.cruise_on; + engine_on = source.engine_on; + tracking_on = source.tracking_on; + is_locked = source.is_locked; + is_alarm_on = source.is_alarm_on; + camera_on = source.camera_on; + autopilot_on = source.autopilot_on; + skidding = source.skidding; + check_environmental_effects = source.check_environmental_effects; + insides_dirty = source.insides_dirty; + is_falling = source.is_falling; + zones_dirty = source.zones_dirty; + vehicle_noise = source.vehicle_noise; +} + vehicle::vehicle( const vproto_id &type_id, int init_veh_fuel, int init_veh_status ): type( type_id ) { @@ -268,10 +374,11 @@ vehicle::vehicle( const vproto_id &type_id, int init_veh_fuel, const vehicle_prototype &proto = type.obj(); // Copy the already made vehicle. The blueprint is created when the json data is loaded // and is guaranteed to be valid (has valid parts etc.). - *this = *proto.blueprint; - for( vehicle_part &part : parts ) { - part.set_vehicle_hack( this ); + copy_static_from( *proto.blueprint ); + for( vehicle_part &part : proto.blueprint->parts ) { + parts.emplace_back( part, this ); } + refresh_locations_hack(); init_state( init_veh_fuel, init_veh_status ); } precalc_mounts( 0, pivot_rotation[0], pivot_anchor[0] ); @@ -1109,7 +1216,7 @@ bool vehicle::is_part_on( const int p ) const bool vehicle::is_alternator_on( const int a ) const { - auto alt = parts[ alternators [ a ] ]; + auto &alt = parts[ alternators [ a ] ]; if( alt.is_unavailable() ) { return false; } @@ -1545,7 +1652,7 @@ bool vehicle::is_connected( const vehicle_part &to, const vehicle_part &from, } } if( !found ) { - vehicle_part next_part = parts[parts_there[0]]; + const vehicle_part &next_part = parts[parts_there[0]]; discovered.push_back( &next_part ); } } @@ -1781,11 +1888,9 @@ bool vehicle::merge_rackable_vehicle( vehicle *carry_veh, const std::vector static_cast( to_degrees( relative_dir ) ), carry_veh->name ); for( int carry_part : carry_map.carry_parts_here ) { - //TODO!: check that the carry veh is really destroyed after this parts.push_back( std::move( carry_veh->parts[ carry_part ] ) ); - refresh_locations_hack(); vehicle_part &carried_part = parts.back(); - + carried_part.set_vehicle_hack( this ); carried_part.mount = carry_map.carry_mount; carried_part.carry_names.push( unique_id ); carried_part.enabled = false; @@ -1796,6 +1901,7 @@ bool vehicle::merge_rackable_vehicle( vehicle *carry_veh, const std::vector } parts[ carry_map.rack_part ].set_flag( vehicle_part::carrying_flag ); } + refresh_locations_hack(); const std::pair::iterator, std::unordered_multimap::iterator> zones_on_point = carry_veh->loot_zones.equal_range( carry_map.old_mount ); @@ -1977,6 +2083,7 @@ void vehicle::part_removal_cleanup() ++it; } } + refresh_locations_hack(); removed_part_count = 0; if( changed || parts.empty() ) { refresh(); @@ -2327,8 +2434,7 @@ bool vehicle::split_vehicles( const std::vector> &new_vehs, } } // transfer the vehicle_part to the new vehicle - new_vehicle->parts.emplace_back( std::move( parts[ mov_part ] ) ); - new_vehicle->refresh_locations_hack(); + new_vehicle->parts.emplace_back( parts[ mov_part ], new_vehicle ); vehicle_part &np = new_vehicle->parts.back(); np.mount = new_mount; np.set_vehicle_hack( new_vehicle ); @@ -2364,6 +2470,7 @@ bool vehicle::split_vehicles( const std::vector> &new_vehs, removed_part_count++; } + new_vehicle->refresh_locations_hack(); // We want to create the vehicle zones after we've setup the parts // because we need only to move the zone once per mount, not per part. If we move per // part, we will end up with duplicates of the zone per part on the same mount @@ -2401,6 +2508,9 @@ bool vehicle::split_vehicles( const std::vector> &new_vehs, new_vehicle->relocate_passengers( passengers ); } } + if( did_split ) { + part_removal_cleanup(); + } return did_split; } @@ -2612,7 +2722,7 @@ int vehicle::obstacle_at_position( point pos ) const return -1; } - auto ref = parts[i]; + auto &ref = parts[i]; if( ref.info().has_flag( VPFLAG_OPENABLE ) && ref.open ) { return -1; @@ -2629,7 +2739,7 @@ int vehicle::opaque_at_position( point pos ) const return -1; } - auto ref = parts[i]; + auto &ref = parts[i]; if( ref.info().has_flag( VPFLAG_OPENABLE ) && ref.open ) { return -1; diff --git a/src/vehicle.h b/src/vehicle.h index 6169ae6490a4..acfc587a76bd 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -471,9 +471,11 @@ class vehicle ~vehicle(); private: + void copy_static_from( const vehicle & ); vehicle( const vehicle & ) = delete; - vehicle &operator=( vehicle && ) = default; - vehicle &operator=( const vehicle & ) = default; + vehicle( vehicle && ) = delete; + vehicle &operator=( vehicle && ) = delete; + vehicle &operator=( const vehicle & ) = delete; public: /** Disable or enable refresh() ; used to speed up performance when creating a vehicle */ diff --git a/src/vehicle_part.cpp b/src/vehicle_part.cpp index 7af64638e470..a3485a918063 100644 --- a/src/vehicle_part.cpp +++ b/src/vehicle_part.cpp @@ -97,21 +97,31 @@ void vehicle_part::copy_static_from( const vehicle_part &source ) } //TODO!: This is a bit scuffed and will be until vehicles are game objects. -vehicle_part::vehicle_part( const vehicle_part &source ) : vehicle_part() +vehicle_part::vehicle_part( const vehicle_part &source, vehicle *veh ) : vehicle_part( veh ) { copy_static_from( source ); base = item::spawn( *source.base ); - for( item * const &it : source.items ) { + for( const item * const &it : source.items ) { items.push_back( item::spawn( *it ) ); } } -vehicle_part &vehicle_part::operator=( const vehicle_part &source ) +vehicle_part::vehicle_part( vehicle_part &&source ) : vehicle_part() { copy_static_from( source ); - base = item::spawn( *source.base ); - for( item * const &it : source.items ) { - items.push_back( item::spawn( *it ) ); + base = source.base.release(); + for( detached_ptr &it : source.items.clear() ) { + items.push_back( std::move( it ) ); + } +} + +vehicle_part &vehicle_part::operator=( vehicle_part &&source ) +{ + copy_static_from( source ); + base = source.base.release(); + items.clear(); + for( detached_ptr &it : source.items.clear() ) { + items.push_back( std::move( it ) ); } return *this; } diff --git a/src/vehicle_part.h b/src/vehicle_part.h index 01f986eb976b..d8f7c6694219 100644 --- a/src/vehicle_part.h +++ b/src/vehicle_part.h @@ -42,9 +42,10 @@ struct vehicle_part { vehicle_part( vehicle * ); vehicle_part( const vpart_id &vp, point dp, detached_ptr &&obj, vehicle * ); + vehicle_part( const vehicle_part &, vehicle * ); - vehicle_part( const vehicle_part & ); - vehicle_part &operator=( const vehicle_part & ); + vehicle_part( vehicle_part && ); + vehicle_part &operator=( vehicle_part && ); /** Check this instance is non-null (not default constructed) */ explicit operator bool() const;