From 461a43f1085f2e4b61f0d9acdd96cfc8f5ec60ac Mon Sep 17 00:00:00 2001 From: Eric <52087122+Ramza13@users.noreply.github.com> Date: Mon, 20 May 2024 14:52:17 +0100 Subject: [PATCH 1/2] Fix segfault when using vehicle tool to hacksaw (#70945) * Fix * fix * Update activity_actor_definitions.h --- src/activity_actor.cpp | 79 ++++++++++++++++++++++++-------- src/activity_actor_definitions.h | 6 ++- src/iuse.cpp | 9 ++-- src/iuse.h | 2 +- src/vehicle.h | 2 + src/vehicle_use.cpp | 9 ++-- 6 files changed, 79 insertions(+), 28 deletions(-) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index f8de3c6eaeee9..4c72f0ec4d172 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -1239,7 +1239,22 @@ void hacksaw_activity_actor::start( player_activity &act, Character &/*who*/ ) return; } - const int qual = tool->get_quality( qual_SAW_M ); + int qual; + if( type.has_value() ) { + item veh_tool = item( type.value(), calendar::turn ); + for( const std::pair &quality : type.value()->qualities ) { + if( quality.first == qual_SAW_M ) { + qual = quality.second; + } + } + for( const std::pair &quality : type.value()->charged_qualities ) { + if( quality.first == qual_SAW_M ) { + qual = std::max( qual, quality.second ); + } + } + } else { + qual = tool->get_quality( qual_SAW_M ); + } if( qual < 2 ) { if( !testing ) { debugmsg( "Item %s with 'HACKSAW' use action requires SAW_M quality of at least 2.", @@ -1261,27 +1276,52 @@ void hacksaw_activity_actor::do_turn( player_activity &/*act*/, Character &who ) { std::string method = "HACKSAW"; - if( tool->ammo_sufficient( &who, method ) ) { - int ammo_consumed = tool->ammo_required(); - std::map::const_iterator iter = tool->type->ammo_scale.find( method ); - if( iter != tool->type->ammo_scale.end() ) { - ammo_consumed *= iter->second; - } + if( !veh_pos.has_value() ) { + if( tool->ammo_sufficient( &who, method ) ) { + int ammo_consumed = tool->ammo_required(); + std::map::const_iterator iter = tool->type->ammo_scale.find( method ); + if( iter != tool->type->ammo_scale.end() ) { + ammo_consumed *= iter->second; + } - tool->ammo_consume( ammo_consumed, tool.position(), &who ); - sfx::play_activity_sound( "tool", "hacksaw", sfx::get_heard_volume( target ) ); - if( calendar::once_every( 1_minutes ) ) { - //~ Sound of a metal sawing tool at work! - sounds::sound( target, 15, sounds::sound_t::destructive_activity, _( "grnd grnd grnd" ) ); + tool->ammo_consume( ammo_consumed, tool.position(), &who ); + sfx::play_activity_sound( "tool", "hacksaw", sfx::get_heard_volume( target ) ); + if( calendar::once_every( 1_minutes ) ) { + //~ Sound of a metal sawing tool at work! + sounds::sound( target, 15, sounds::sound_t::destructive_activity, _( "grnd grnd grnd" ) ); + } + } else { + if( who.is_avatar() ) { + who.add_msg_if_player( m_bad, _( "Your %1$s ran out of charges." ), tool->tname() ); + } else { // who.is_npc() + add_msg_if_player_sees( who.pos(), _( "%1$s %2$s ran out of charges." ), who.disp_name( false, + true ), tool->tname() ); + } + who.cancel_activity(); } } else { - if( who.is_avatar() ) { - who.add_msg_if_player( m_bad, _( "Your %1$s ran out of charges." ), tool->tname() ); - } else { // who.is_npc() - add_msg_if_player_sees( who.pos(), _( "%1$s %2$s ran out of charges." ), who.disp_name( false, - true ), tool->tname() ); + map &here = get_map(); + const optional_vpart_position vp = here.veh_at( veh_pos.value() ); + if( !vp ) { + debugmsg( "Lost ACT_HACKSAW vehicle tool" ); + return; + } + vehicle &veh = vp->vehicle(); + if( vehicle::use_vehicle_tool( veh, veh_pos.value(), type.value(), true ) ) { + sfx::play_activity_sound( "tool", "hacksaw", sfx::get_heard_volume( target ) ); + if( calendar::once_every( 1_minutes ) ) { + //~ Sound of a metal sawing tool at work! + sounds::sound( target, 15, sounds::sound_t::destructive_activity, _( "grnd grnd grnd" ) ); + } + } else { + if( who.is_avatar() ) { + who.add_msg_if_player( m_bad, _( "Your %1$s ran out of charges." ), type.value()->nname( 1 ) ); + } else { // who.is_npc() + add_msg_if_player_sees( who.pos(), _( "%1$s %2$s ran out of charges." ), who.disp_name( false, + true ), type.value()->nname( 1 ) ); + } + who.cancel_activity(); } - who.cancel_activity(); } } @@ -1369,7 +1409,8 @@ bool hacksaw_activity_actor::can_resume_with_internal( const activity_actor &oth { const hacksaw_activity_actor &actor = static_cast ( other ); - return actor.target == target && actor.tool.operator == ( tool ); + return actor.target == target && ( ( veh_pos.has_value() && + veh_pos.value() == actor.veh_pos.value_or( tripoint_max ) ) || actor.tool.operator == ( tool ) ); } void hacksaw_activity_actor::serialize( JsonOut &jsout ) const diff --git a/src/activity_actor_definitions.h b/src/activity_actor_definitions.h index 3a2a2dd86355b..81b938e952f0f 100644 --- a/src/activity_actor_definitions.h +++ b/src/activity_actor_definitions.h @@ -176,7 +176,8 @@ class hacksaw_activity_actor : public activity_actor public: explicit hacksaw_activity_actor( const tripoint &target, const item_location &tool ) : target( target ), tool( tool ) {}; - + explicit hacksaw_activity_actor( const tripoint &target, const itype_id &type, + const tripoint &veh_pos ) : target( target ), type( type ), veh_pos( veh_pos ) {}; activity_id get_type() const override { return activity_id( "ACT_HACKSAW" ); } @@ -197,7 +198,8 @@ class hacksaw_activity_actor : public activity_actor private: tripoint target; item_location tool; - + std::optional type; + std::optional veh_pos; bool can_resume_with_internal( const activity_actor &other, const Character &/*who*/ ) const override; }; diff --git a/src/iuse.cpp b/src/iuse.cpp index 86d2adbb58e2a..f6e3a0a02905f 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -4913,7 +4913,7 @@ std::optional iuse::oxytorch( Character *p, item *it, const tripoint & ) return std::nullopt; } -std::optional iuse::hacksaw( Character *p, item *it, const tripoint & ) +std::optional iuse::hacksaw( Character *p, item *it, const tripoint &it_pnt ) { if( !p ) { debugmsg( "%s called action hacksaw that requires character but no character is present", @@ -4952,8 +4952,11 @@ std::optional iuse::hacksaw( Character *p, item *it, const tripoint & ) } return std::nullopt; } - - p->assign_activity( hacksaw_activity_actor( pnt, item_location{*p, it} ) ); + if( p->pos() == it_pnt ) { + p->assign_activity( hacksaw_activity_actor( pnt, item_location{ *p, it } ) ); + } else { + p->assign_activity( hacksaw_activity_actor( pnt, it->typeId(), it_pnt ) ); + } return std::nullopt; } diff --git a/src/iuse.h b/src/iuse.h index ad3a6beb02952..fb1ce7088bf14 100644 --- a/src/iuse.h +++ b/src/iuse.h @@ -134,7 +134,7 @@ std::optional granade_act( Character *, item *, const tripoint & ); std::optional grenade_inc_act( Character *, item *, const tripoint & ); std::optional gun_repair( Character *, item *, const tripoint & ); std::optional gunmod_attach( Character *, item *, const tripoint & ); -std::optional hacksaw( Character *, item *, const tripoint & ); +std::optional hacksaw( Character *, item *, const tripoint &it_pnt ); std::optional hairkit( Character *, item *, const tripoint & ); std::optional hammer( Character *, item *, const tripoint & ); std::optional hand_crank( Character *, item *, const tripoint & ); diff --git a/src/vehicle.h b/src/vehicle.h index 5575cd38584d6..3e42c148cc5f1 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -1767,6 +1767,8 @@ class vehicle * @return amount of ammo in the `pseudo_magazine` or 0 */ int prepare_tool( item &tool ) const; + static bool use_vehicle_tool( vehicle &veh, const tripoint &vp_pos, const itype_id &tool_type, + bool no_invoke = false ); /** * if \p tool is not an itype with tool != nullptr this returns { itype::NULL_ID(), 0 } pair * @param tool the item to examine diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index 163f35d11e942..3f48b353f2f19 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -1820,7 +1820,8 @@ int vehicle::prepare_tool( item &tool ) const return ammo_count; } -static bool use_vehicle_tool( vehicle &veh, const tripoint &vp_pos, const itype_id &tool_type ) +bool vehicle::use_vehicle_tool( vehicle &veh, const tripoint &vp_pos, const itype_id &tool_type, + bool no_invoke ) { item tool( tool_type, calendar::turn ); const auto &[ammo_type_id, avail_ammo_amount] = veh.tool_ammo_available( tool_type ); @@ -1829,7 +1830,9 @@ static bool use_vehicle_tool( vehicle &veh, const tripoint &vp_pos, const itype_ if( tool.ammo_required() > avail_ammo_amount ) { return false; } - get_player_character().invoke_item( &tool ); + if( !no_invoke ) { + get_player_character().invoke_item( &tool, vp_pos ); + } // HACK: Evil hack incoming player_activity &act = get_player_character().activity; @@ -2432,4 +2435,4 @@ void vehicle::interact_with( const tripoint &p, bool with_pickup ) menu.reset(); build_interact_menu( menu, p, with_pickup ); } while( menu.query() ); -} \ No newline at end of file +} From 97a82de805962380aa28ba817356a6ab23dcf8a0 Mon Sep 17 00:00:00 2001 From: inogenous <123803852+inogenous@users.noreply.github.com> Date: Fri, 24 May 2024 12:07:58 +0100 Subject: [PATCH 2/2] Merge pull request #71001 from inogenous/fix-uninitialized-qual-gcc13 Fix: Prevent uninitialized int --- src/activity_actor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index 4c72f0ec4d172..ea97bd6145046 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -1239,7 +1239,7 @@ void hacksaw_activity_actor::start( player_activity &act, Character &/*who*/ ) return; } - int qual; + int qual = 0; if( type.has_value() ) { item veh_tool = item( type.value(), calendar::turn ); for( const std::pair &quality : type.value()->qualities ) {