Skip to content

Commit

Permalink
Make vehicle::{explode_fuel,break_off,damage_direct} use references
Browse files Browse the repository at this point in the history
  • Loading branch information
irwiss committed Jul 11, 2023
1 parent d406114 commit 9191106
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 44 deletions.
63 changes: 30 additions & 33 deletions src/vehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5271,7 +5271,7 @@ void vehicle::do_engine_damage( vehicle_part &vp, int strain )
if( is_engine_on( vp ) && !is_perpetual_type( vp ) && engine_fuel_left( vp ) &&
rng( 1, 100 ) < strain ) {
const int dmg = rng( 0, strain * 4 );
damage_direct( get_map(), index_of_part( &vp ), dmg );
damage_direct( get_map(), vp, dmg );
if( one_in( 2 ) ) {
add_msg( _( "Your engine emits a high pitched whine." ) );
} else {
Expand Down Expand Up @@ -6805,27 +6805,30 @@ int vehicle::damage( map &here, int p, int dmg, const damage_type_id &type, bool
}
}

vehicle_part &vp_target = part( target_part );
const vpart_info &vpi_target = vp_target.info();

const int armor_part = part_with_feature( vp_initial.mount, "ARMOR", true );
if( armor_part < 0 ) { // Not covered by armor -- damage part
return damage_direct( here, target_part, dmg, type );
return damage_direct( here, vp_target, dmg, type );
}
const vehicle_part &vp_target = part( target_part );
const vpart_info &vpi_target = vp_target.info();
const vehicle_part &vp_armor = part( armor_part );

vehicle_part &vp_armor = part( armor_part );
const vpart_info &vpi_armor = vp_armor.info();
// Covered by armor -- hit both armor and part, but reduce damage by armor's reduction
const int protection = type->no_resist ? 0 : vp_armor.info().damage_reduction.at( type );
const int protection = type->no_resist ? 0 : vpi_armor.damage_reduction.at( type );
// Parts on roof aren't protected
const bool overhead = vpi_target.has_flag( "ROOF" ) || vpi_target.location == "on_roof";
// Calling damage_direct may remove the damaged part completely, therefore the
// other index (target_part) becomes wrong if target_part > armor_part.
// Damaging the part with the higher index first is safe, as removing a part
// only changes indices after the removed part.
if( armor_part < target_part ) {
damage_direct( here, target_part, overhead ? dmg : dmg - protection, type );
return damage_direct( here, armor_part, dmg, type );
damage_direct( here, vp_target, overhead ? dmg : dmg - protection, type );
return damage_direct( here, vp_armor, dmg, type );
} else {
const int damage_dealt = damage_direct( here, armor_part, dmg, type );
damage_direct( here, target_part, overhead ? dmg : dmg - protection, type );
const int damage_dealt = damage_direct( here, vp_armor, dmg, type );
damage_direct( here, vp_target, overhead ? dmg : dmg - protection, type );
return damage_dealt;
}
}
Expand All @@ -6841,7 +6844,7 @@ void vehicle::damage_all( int dmg1, int dmg2, const damage_type_id &type, const
}

for( const vpart_reference &vpr : get_all_parts() ) {
const vehicle_part &vp = vpr.part();
vehicle_part &vp = vpr.part();
const vpart_info &vpi = vp.info();
const int distance = 1 + square_dist( vp.mount, impact );
if( distance > 1 ) {
Expand All @@ -6853,7 +6856,7 @@ void vehicle::damage_all( int dmg1, int dmg2, const damage_type_id &type, const
net_dmg = std::max( 0, net_dmg - vp_shock_absorber.info().bonus );
}
}
damage_direct( get_map(), vpr.part_index(), net_dmg, type );
damage_direct( get_map(), vp, net_dmg, type );
}
}
}
Expand Down Expand Up @@ -6924,9 +6927,8 @@ bool vehicle::shift_if_needed( map &here )
return false;
}

int vehicle::break_off( map &here, int p, int dmg )
int vehicle::break_off( map &here, vehicle_part &vp, int dmg )
{
vehicle_part &vp = parts[p];
const vpart_info &vpi = vp.info();
/* Already-destroyed part - chance it could be torn off into pieces.
* Chance increases with damage, and decreases with part max durability
Expand Down Expand Up @@ -6958,14 +6960,11 @@ int vehicle::break_off( map &here, int p, int dmg )
// For structural parts, remove other parts first
std::vector<int> parts_in_square = parts_at_relative( vp.mount, true );
for( int index = parts_in_square.size() - 1; index >= 0; index-- ) {
// Ignore the frame being destroyed
if( parts_in_square[index] == p ) {
continue;
}
vehicle_part &vp_here = parts[parts_in_square[index]];
const vpart_info &vpi_here = vp_here.info();

if( vpi_here.has_flag( "TOW_CABLE" ) ) {
if( &vp_here == &vp ) {
continue; // Ignore the frame being destroyed
} else if( vpi_here.has_flag( "TOW_CABLE" ) ) {
// Tow cables - remove it in one piece, remove remote part, and remove towing data
add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is disconnected!" ), name, vp_here.name() );
invalidate_towing( true );
Expand All @@ -6991,7 +6990,7 @@ int vehicle::break_off( map &here, int p, int dmg )
add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is destroyed!" ), name, vp.name() );
scatter_parts( vp );
remove_part( vp, *handler_ptr );
find_and_split_vehicles( here, { p } );
find_and_split_vehicles( here, { index_of_part( &vp, /* include_removed = */ true ) } );
} else {
if( vpi.has_flag( "TOW_CABLE" ) ) {
// Tow cables - remove it in one piece, remove remote part, and remove towing data
Expand Down Expand Up @@ -7033,7 +7032,7 @@ int vehicle::break_off( map &here, int p, int dmg )
if( vpi_here.has_flag( "TOW_CABLE" ) ) {
invalidate_towing( true );
} else {
if( vpi.has_flag( "POWER_TRANSFER" ) ) {
if( vpi_here.has_flag( "POWER_TRANSFER" ) ) {
remove_remote_part( vp_here );
}
here.add_item_or_charges( pos, vp_here.properties_to_item() );
Expand All @@ -7047,9 +7046,8 @@ int vehicle::break_off( map &here, int p, int dmg )
return dmg;
}

bool vehicle::explode_fuel( int p, const damage_type_id &type )
bool vehicle::explode_fuel( vehicle_part &vp, const damage_type_id &type )
{
vehicle_part &vp = part( p );
const itype_id &ft = vp.info().fuel_type;
item fuel = item( ft );
if( !fuel.has_explosion_data() ) {
Expand All @@ -7075,13 +7073,11 @@ bool vehicle::explode_fuel( int p, const damage_type_id &type )
return true;
}

int vehicle::damage_direct( map &here, int p, int dmg, const damage_type_id &type )
int vehicle::damage_direct( map &here, vehicle_part &vp, int dmg, const damage_type_id &type )
{
// Make sure p is within range and hasn't been removed already
if( ( static_cast<size_t>( p ) >= parts.size() ) || parts[p].removed ) {
return dmg;
if( vp.removed ) {
return dmg; // part is already dead
}
vehicle_part &vp = parts[p];
const vpart_info &vpi = vp.info();
const tripoint vppos = global_part_pos3( vp );
// If auto-driving and damage happens, bail out
Expand All @@ -7090,13 +7086,13 @@ int vehicle::damage_direct( map &here, int p, int dmg, const damage_type_id &typ
}
here.set_memory_seen_cache_dirty( vppos );
if( vp.is_broken() ) {
return break_off( here, p, dmg );
return break_off( here, vp, dmg );
}

int tsh = std::min( 20, vpi.durability / 10 );
if( dmg < tsh && type != damage_pure ) {
if( type == damage_heat && vp.is_fuel_store() ) {
explode_fuel( p, type );
explode_fuel( vp, type );
}

return dmg;
Expand Down Expand Up @@ -7131,9 +7127,10 @@ int vehicle::damage_direct( map &here, int p, int dmg, const damage_type_id &typ
}

if( vp.is_fuel_store() ) {
explode_fuel( p, type );
explode_fuel( vp, type );
} else if( vp.is_broken() && vpi.has_flag( "UNMOUNT_ON_DAMAGE" ) ) {
monster *mon = get_monster( p );
const int vp_idx = index_of_part( &vp, /* include_removed = */ true );
monster *mon = get_monster( vp_idx );
if( mon != nullptr && mon->has_effect( effect_harnessed ) ) {
mon->remove_effect( effect_harnessed );
}
Expand Down
8 changes: 4 additions & 4 deletions src/vehicle.h
Original file line number Diff line number Diff line change
Expand Up @@ -805,13 +805,13 @@ class vehicle
const vehicle_part &excluded ) const;

// direct damage to part (armor protection and internals are not counted)
// returns damage bypassed
int damage_direct( map &here, int p, int dmg,
// @returns damage still left to apply
int damage_direct( map &here, vehicle_part &vp, int dmg,
const damage_type_id &type = damage_type_id( "pure" ) );
// Removes the part, breaks it into pieces and possibly removes parts attached to it
int break_off( map &here, int p, int dmg );
int break_off( map &here, vehicle_part &vp, int dmg );
// Returns if it did actually explode
bool explode_fuel( int p, const damage_type_id &type );
bool explode_fuel( vehicle_part &vp, const damage_type_id &type );
//damages vehicle controls and security system
void smash_security_system();
// get vpart powerinfo for part number, accounting for variable-sized parts and hps.
Expand Down
7 changes: 4 additions & 3 deletions src/vehicle_move.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,14 +597,14 @@ void vehicle::thrust( int thd, int z )
// If you are going faster than the animal can handle, harness is damaged
// Animal may come free ( and possibly hit by vehicle )
for( size_t e = 0; e < parts.size(); e++ ) {
const vehicle_part &vp = parts[ e ];
vehicle_part &vp = parts[e];
if( vp.info().fuel_type == fuel_type_animal && engines.size() != 1 ) {
monster *mon = get_monster( e );
if( mon != nullptr && mon->has_effect( effect_harnessed ) ) {
if( velocity > mon->get_speed() * 12 ) {
add_msg( m_bad, _( "Your %s is not fast enough to keep up with the %s" ), mon->get_name(), name );
int dmg = rng( 0, 10 );
damage_direct( get_map(), e, dmg );
damage_direct( get_map(), vp, dmg );
}
}
}
Expand Down Expand Up @@ -1242,7 +1242,8 @@ void vehicle::handle_trap( const tripoint &p, int part )
explosion_handler::explosion( source, p, veh_data.damage, 0.5f, false, veh_data.shrapnel );
} else {
// Hit the wheel directly since it ran right over the trap.
damage_direct( here, pwh, veh_data.damage );
vehicle_part &vp_wheel = parts[part];
damage_direct( here, vp_wheel, veh_data.damage );
}
bool still_has_trap = true;
if( veh_data.remove_trap || veh_data.do_explosion ) {
Expand Down
8 changes: 4 additions & 4 deletions src/vehicle_use.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,16 +454,16 @@ void vehicle::smash_security_system()
debugmsg( "No security system found on vehicle." );
return; // both must be valid parts
}
const vehicle_part &vp_controls = part( idx_controls );
const vehicle_part &vp_security = part( idx_security );
vehicle_part &vp_controls = part( idx_controls );
vehicle_part &vp_security = part( idx_security );
///\EFFECT_MECHANICS reduces chance of damaging controls when smashing security system
const float skill = player_character.get_skill_level( skill_mechanics );
const int percent_controls = 70 / ( 1 + skill );
const int percent_alarm = ( skill + 3 ) * 10;
const int rand = rng( 1, 100 );

if( percent_controls > rand ) {
damage_direct( here, idx_controls, vp_controls.info().durability / 4 );
damage_direct( here, vp_controls, vp_controls.info().durability / 4 );

if( vp_controls.removed || vp_controls.is_broken() ) {
player_character.controlling_vehicle = false;
Expand All @@ -474,7 +474,7 @@ void vehicle::smash_security_system()
}
}
if( percent_alarm > rand ) {
damage_direct( here, idx_security, vp_security.info().durability / 5 );
damage_direct( here, vp_security, vp_security.info().durability / 5 );
// chance to disable alarm immediately, or disable on destruction
if( percent_alarm / 4 > rand || vp_security.is_broken() ) {
is_alarm_on = false;
Expand Down

0 comments on commit 9191106

Please sign in to comment.