diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 9e3bfd70e568a..0f72756fd6dc8 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -1196,7 +1196,11 @@ std::optional deploy_appliance_actor::use( Character *p, item &it, const tr } it.spill_contents( suitable.value() ); - place_appliance( tripoint_bub_ms( suitable.value() ), vpart_appliance_from_item( appliance_base ) ); + if( !place_appliance( tripoint_bub_ms( suitable.value() ), + vpart_appliance_from_item( appliance_base ), it ) ) { + // failed to place somehow, cancel!! + return 0; + } p->mod_moves( -to_moves( 2_seconds ) ); return 1; } diff --git a/src/veh_appliance.cpp b/src/veh_appliance.cpp index ca0d59cc07ddc..8c463d4dd0d36 100644 --- a/src/veh_appliance.cpp +++ b/src/veh_appliance.cpp @@ -54,7 +54,7 @@ vpart_id vpart_appliance_from_item( const itype_id &item_id ) return vpart_ap_standing_lamp; } -void place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, +bool place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, const std::optional &base ) { @@ -64,7 +64,7 @@ void place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, if( !veh ) { debugmsg( "error constructing vehicle" ); - return; + return false; } veh->add_tag( flag_APPLIANCE ); @@ -72,10 +72,19 @@ void place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, int partnum = -1; if( base ) { item copied = *base; + if( vpinfo.base_item != copied.typeId() ) { + // transform the deploying item into what it *should* be before storing it + copied.convert( vpinfo.base_item ); + } partnum = veh->install_part( point_zero, vpart, std::move( copied ) ); } else { partnum = veh->install_part( point_zero, vpart ); } + if( partnum == -1 ) { + // unrecoverable, failed to be installed somehow + here.destroy_vehicle( veh ); + return false; + } veh->name = vpart->name(); veh->last_update = calendar::turn; @@ -114,6 +123,7 @@ void place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, if( vpinfo.has_flag( flag_HALF_CIRCLE_LIGHT ) && partnum != -1 ) { orient_part( veh, vpinfo, partnum ); } + return true; } player_activity veh_app_interact::run( vehicle &veh, const point &p ) diff --git a/src/veh_appliance.h b/src/veh_appliance.h index d7c69b3bd41fb..b63ea1ee95e71 100644 --- a/src/veh_appliance.h +++ b/src/veh_appliance.h @@ -9,7 +9,7 @@ class vehicle; class ui_adaptor; vpart_id vpart_appliance_from_item( const itype_id &item_id ); -void place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, +bool place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, const std::optional &base = std::nullopt ); /** diff --git a/src/vehicle.cpp b/src/vehicle.cpp index fc5035e84b6e1..353693547dacd 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1489,6 +1489,10 @@ int vehicle::install_part( const point &dp, const vpart_id &type, item &&base, int vehicle::install_part( const point &dp, vehicle_part &&vp ) { + if( vp.base.is_null() ) { + debugmsg( "Part to be installed is missing base item, did the constructor fail to set_base?" ); + return -1; + } const vpart_info &vpi = vp.info(); const ret_val valid_mount = can_mount( dp, vpi ); if( !valid_mount.success() ) { diff --git a/src/vehicle_part.cpp b/src/vehicle_part.cpp index 625d6f8d0f152..a8b0ba4dab327 100644 --- a/src/vehicle_part.cpp +++ b/src/vehicle_part.cpp @@ -104,6 +104,7 @@ void vehicle_part::set_base( item &&new_base ) if( new_base.typeId() != info().base_item ) { debugmsg( "new base '%s' doesn't match part type '%s', this is a bug", new_base.typeId().str(), info().id.str() ); + base = null_item_reference(); return; } base = std::move( new_base );