Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport #70945 and #71001 #73960

Merged
merged 2 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 60 additions & 19 deletions src/activity_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 = 0;
if( type.has_value() ) {
item veh_tool = item( type.value(), calendar::turn );
for( const std::pair<const quality_id, int> &quality : type.value()->qualities ) {
if( quality.first == qual_SAW_M ) {
qual = quality.second;
}
}
for( const std::pair<const quality_id, int> &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.",
Expand All @@ -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<std::string, int>::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<std::string, int>::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();
}
}

Expand Down Expand Up @@ -1369,7 +1409,8 @@ bool hacksaw_activity_actor::can_resume_with_internal( const activity_actor &oth
{
const hacksaw_activity_actor &actor = static_cast<const hacksaw_activity_actor &>
( 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
Expand Down
6 changes: 4 additions & 2 deletions src/activity_actor_definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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" );
}
Expand All @@ -197,7 +198,8 @@ class hacksaw_activity_actor : public activity_actor
private:
tripoint target;
item_location tool;

std::optional<itype_id> type;
std::optional<tripoint> veh_pos;
bool can_resume_with_internal( const activity_actor &other,
const Character &/*who*/ ) const override;
};
Expand Down
9 changes: 6 additions & 3 deletions src/iuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4913,7 +4913,7 @@ std::optional<int> iuse::oxytorch( Character *p, item *it, const tripoint & )
return std::nullopt;
}

std::optional<int> iuse::hacksaw( Character *p, item *it, const tripoint & )
std::optional<int> 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",
Expand Down Expand Up @@ -4952,8 +4952,11 @@ std::optional<int> 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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/iuse.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ std::optional<int> granade_act( Character *, item *, const tripoint & );
std::optional<int> grenade_inc_act( Character *, item *, const tripoint & );
std::optional<int> gun_repair( Character *, item *, const tripoint & );
std::optional<int> gunmod_attach( Character *, item *, const tripoint & );
std::optional<int> hacksaw( Character *, item *, const tripoint & );
std::optional<int> hacksaw( Character *, item *, const tripoint &it_pnt );
std::optional<int> hairkit( Character *, item *, const tripoint & );
std::optional<int> hammer( Character *, item *, const tripoint & );
std::optional<int> hand_crank( Character *, item *, const tripoint & );
Expand Down
2 changes: 2 additions & 0 deletions src/vehicle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 6 additions & 3 deletions src/vehicle_use.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand All @@ -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;
Expand Down Expand Up @@ -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() );
}
}
Loading