Skip to content

Commit

Permalink
Misc fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kevingranade committed Mar 16, 2022
1 parent d8ab217 commit eb62c42
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 29 deletions.
57 changes: 40 additions & 17 deletions src/mapgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6680,6 +6680,9 @@ std::unique_ptr<vehicle> map::add_vehicle_to_map(
part != frame_indices.end(); part++ ) {
const tripoint p = veh_to_add->global_part_pos3( *part );

if( veh_to_add->part( *part ).is_fake ) {
continue;
}
//Don't spawn anything in water
if( has_flag_ter( ter_furn_flag::TFLAG_DEEP_WATER, p ) && !can_float ) {
return nullptr;
Expand Down Expand Up @@ -6715,45 +6718,65 @@ std::unique_ptr<vehicle> map::add_vehicle_to_map(
*
* the overlap span is still a mess, though.
*/

std::unique_ptr<RemovePartHandler> handler_ptr;
bool did_merge = false;
for( const tripoint &map_pos : first_veh->get_points( true ) ) {
std::vector<vehicle_part *> parts_to_move = veh_to_add->get_parts_at( map_pos, "",
part_status_flag::any );
if( !parts_to_move.empty() ) {
// Store target_point by value because first_veh->parts may reallocate
// to a different address after install_part()
const point target_point = first_veh->get_parts_at( map_pos, "",
part_status_flag:: any ).front()->mount;
std::vector<vehicle_part *> first_veh_parts = first_veh->get_parts_at( map_pos, "",
part_status_flag:: any );
// this happens of this location is occupied by a fake part.
if( first_veh_parts.empty() || first_veh_parts.front()->is_fake ) {
continue;
}
did_merge = true;
const point target_point = first_veh_parts.front()->mount;
const point source_point = parts_to_move.front()->mount;
for( const vehicle_part *vp : parts_to_move ) {
// TODO: change mount points to be tripoint
first_veh->install_part( target_point, *vp );
}

if( !handler_ptr ) {
// This is a heuristic: we just assume the default handler is good enough when called
// on the main game map. And assume that we run from some mapgen code if called on
// another instance.
if( !g || &get_map() != this ) {
handler_ptr = std::make_unique<MapgenRemovePartHandler>( *this );
}
}
// Triggers fake part removal that causes problems otherwise.
veh_to_add->refresh( true );
// this couuld probably be done in a single loop with installing parts above
std::vector<int> parts_in_square = veh_to_add->parts_at_relative( source_point, true );
std::vector<int> parts_in_square = veh_to_add->parts_at_relative( source_point, false );
std::set<int> parts_to_check;
for( int index = parts_in_square.size() - 1; index >= 0; index-- ) {
veh_to_add->remove_part( parts_in_square[index] );
if( handler_ptr ) {
veh_to_add->remove_part( parts_in_square[index], *handler_ptr );
} else {
veh_to_add->remove_part( parts_in_square[index] );
}
parts_to_check.insert( parts_in_square[index] );
}
veh_to_add->find_and_split_vehicles( parts_to_check );
}
}

// TODO: more targeted damage around the impact site
first_veh->smash( *this );
first_veh->enable_refresh();

// TODO: entangle the old vehicle and the new vehicle somehow, perhaps with tow cables
// or something like them, to make them harder to separate
std::unique_ptr<vehicle> new_veh = add_vehicle_to_map( std::move( veh_to_add ), true );
if( new_veh != nullptr ) {
new_veh->smash( *this );
return new_veh;
if( did_merge ) {
// TODO: more targeted damage around the impact site
first_veh->smash( *this );
// TODO: entangle the old vehicle and the new vehicle somehow, perhaps with tow cables
// or something like them, to make them harder to separate
std::unique_ptr<vehicle> new_veh = add_vehicle_to_map( std::move( veh_to_add ), true );
if( new_veh != nullptr ) {
new_veh->smash( *this );
return new_veh;
}
return nullptr;
}
return nullptr;

} else if( impassable( p ) ) {
if( !merge_wrecks ) {
return nullptr;
Expand Down
24 changes: 12 additions & 12 deletions src/vehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1843,6 +1843,9 @@ bool vehicle::remove_part( const int p, RemovePartHandler &handler )
zones_dirty = true;
}
parts[p].removed = true;
if( parts[p].has_fake ) {
parts[parts[p].fake_part_at].removed = true;
}
removed_part_count++;

handler.removed( *this, p );
Expand Down Expand Up @@ -2788,7 +2791,7 @@ vehicle_part_with_feature_range<vpart_bitflags> vehicle::get_enabled_parts(
std::vector<int> vehicle::all_parts_at_location( const std::string &location ) const
{
std::vector<int> parts_found;
auto all_parts = get_all_parts();
vehicle_part_range all_parts = get_all_parts();
for( const vpart_reference &vpr : all_parts ) {
if( vpr.info().location == location && !parts[vpr.part_index()].removed ) {
parts_found.push_back( vpr.part_index() );
Expand Down Expand Up @@ -3311,7 +3314,7 @@ int vehicle::fuel_capacity( const itype_id &ftype ) const
vehicle_part_range vpr = get_all_parts();
return std::accumulate( vpr.begin(), vpr.end(), 0, [&ftype]( const int &lhs,
const vpart_reference & rhs ) {
cata::value_ptr<islot_ammo> a_val = item::find_type( ftype )->ammo;
cata::value_ptr<islot_ammo> a_val = item::find_type( ftype )->ammo;
return lhs + ( rhs.part().ammo_current() == ftype ?
rhs.part().ammo_capacity( !!a_val ? a_val->type : ammotype::NULL_ID() ) :
0 );
Expand All @@ -3325,9 +3328,8 @@ float vehicle::fuel_specific_energy( const itype_id &ftype ) const
for( const vpart_reference &vpr : get_all_parts() ) {
if( vpr.part().is_tank() && vpr.part().ammo_current() == ftype &&
vpr.part().base.only_item().made_of( phase_id::LIQUID ) ) {
float mass = to_gram( vpr.part().base.only_item().weight() );
total_energy += vpr.part().base.only_item().specific_energy * mass;
total_mass += mass;
total_energy += vpr.part().base.only_item().get_item_thermal_energy();
total_mass += to_gram( vpr.part().base.only_item().weight() );
}
}
return total_energy / total_mass;
Expand Down Expand Up @@ -5885,11 +5887,6 @@ void vehicle::refresh( const bool remove_fakes )
std::set<int> smzs = precalc_mounts( 0, pivot_rotation[0], pivot_anchor[0] );
// update the fakes, and then repopulate the cache
update_active_fakes();
map &here = get_map();
here.add_vehicle_to_cache( this );
for( const int dirty_z : smzs ) {
here.on_vehicle_moved( dirty_z );
}
check_environmental_effects = true;
insides_dirty = true;
zones_dirty = true;
Expand Down Expand Up @@ -6516,6 +6513,10 @@ int vehicle::damage( int p, int dmg, damage_type type, bool aimed )
}

p = get_non_fake_part( p );
// If we're trying to hit a fake part with no associated real part, just cancel out.
if( p == -1 ) {
return dmg;
}
std::vector<int> pl = parts_at_relative( parts[p].mount, true );
if( pl.empty() ) {
// We ran out of non removed parts at this location already.
Expand Down Expand Up @@ -6599,7 +6600,6 @@ void vehicle::damage_all( int dmg1, int dmg2, damage_type type, const point &imp
return;
}

std::cout << "veh " << name << " has " << parts.size() << " parts.";
for( const vpart_reference &vp : get_all_parts() ) {
const size_t p = vp.part_index();
int distance = 1 + square_dist( vp.mount(), impact );
Expand Down Expand Up @@ -7387,7 +7387,7 @@ int vehicle::get_non_fake_part( const int part_num )
return part_num;
}
}
std::cout << "Returning -1 for get_non_fake_part.";
debugmsg( "Returning -1 for get_non_fake_part on part_num %d.", part_num );
return -1;
}

Expand Down

0 comments on commit eb62c42

Please sign in to comment.