Skip to content

Commit

Permalink
Merge pull request #56143 from kevingranade/fake-parts
Browse files Browse the repository at this point in the history
Fake parts for filling vehicle gaps
  • Loading branch information
kevingranade authored Jun 8, 2022
2 parents 2ec0e5e + 62fd404 commit befb7ab
Show file tree
Hide file tree
Showing 22 changed files with 1,465 additions and 426 deletions.
74 changes: 70 additions & 4 deletions data/mods/TEST_DATA/vehicle.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@
{ "x": 0, "y": -2, "parts": [ "frame_vertical", "seat" ] },
{ "x": 1, "y": -2, "parts": [ "frame_vertical", "seat", "wheel_mount_medium_steerable", "wheel" ] },
{ "x": -1, "y": -2, "parts": [ "frame_vertical", "seat", "wheel_mount_medium_steerable", "wheel" ] },
{ "x": 1, "y": 0, "parts": [ "frame_vertical", "door" ] },
{ "x": 1, "y": 0, "parts": [ "frame_vertical", "solar_panel" ] },
{ "x": -1, "y": 0, "parts": [ "frame_vertical", "engine_electric", "storage_battery" ] }
]
},
Expand All @@ -231,9 +231,9 @@
{ "x": -2, "y": -2, "parts": [ "frame_vertical", "seat" ] },
{ "x": -1, "y": -1, "parts": [ "frame_vertical", "seat" ] },
{ "x": 2, "y": -2, "parts": [ "frame_vertical", "seat" ] },
{ "x": 1, "y": 0, "parts": [ "frame_vertical", "door" ] },
{ "x": 2, "y": 0, "parts": [ "frame_vertical", "door" ] },
{ "x": 2, "y": -1, "parts": [ "frame_vertical", "door" ] },
{ "x": 1, "y": 0, "parts": [ "frame_vertical", "solar_panel" ] },
{ "x": 2, "y": 0, "parts": [ "frame_vertical", "solar_panel" ] },
{ "x": 2, "y": -1, "parts": [ "frame_vertical", "solar_panel" ] },
{ "x": -1, "y": 0, "parts": [ "frame_vertical", "engine_v6" ] },
{ "x": -2, "y": 0, "parts": [ "frame_vertical", "engine_v6" ] }
]
Expand Down Expand Up @@ -362,5 +362,71 @@
{ "item": "motor_tiny", "prob": 25 }
],
"damage_reduction": { "all": 32 }
},
{
"id": "test_van",
"type": "vehicle",
"name": "Test Van",
"blueprint": [
[ "o o " ],
[ "-O---+-O" ],
[ "+===|#'|" ],
[ "+===|o'>" ],
[ "+===|#'|" ],
[ "-O---+-O" ],
[ "o o " ]
],
"parts": [
{ "x": 0, "y": 0, "parts": [ "frame_vertical", "seat", "controls", "dashboard", "roof" ] },
{ "x": 0, "y": 1, "parts": [ "frame_vertical", "box", "roof" ] },
{ "x": 0, "y": 2, "parts": [ "frame_vertical", "seat", "roof" ] },
{ "x": 0, "y": -1, "parts": [ "frame_vertical", "door" ] },
{ "x": 0, "y": 3, "parts": [ "frame_vertical", "door" ] },
{ "x": 1, "y": -1, "parts": [ "frame_horizontal", "windshield" ] },
{ "x": 1, "y": 0, "parts": [ "frame_horizontal", "windshield" ] },
{ "x": 1, "y": 1, "parts": [ "frame_horizontal", "windshield" ] },
{ "x": 1, "y": 2, "parts": [ "frame_horizontal", "windshield" ] },
{ "x": 1, "y": 3, "parts": [ "frame_horizontal" ] },
{ "x": 1, "y": -2, "part": "wing_mirror" },
{ "x": 1, "y": 4, "part": "wing_mirror" },
{ "x": 2, "y": -1, "parts": [ "frame_nw", "halfboard_nw", "headlight" ] },
{ "x": 2, "y": -1, "parts": [ "wheel_mount_medium_steerable", "wheel_wide" ] },
{ "x": 2, "y": 0, "parts": [ "frame_horizontal", "halfboard_horizontal" ] },
{ "x": 2, "y": 1, "parts": [ "frame_horizontal", "halfboard_horizontal" ] },
{ "x": 2, "y": 1, "parts": [ "engine_v6", "alternator_car", "battery_car" ] },
{ "x": 2, "y": 2, "parts": [ "frame_horizontal", "halfboard_horizontal" ] },
{ "x": 2, "y": 3, "parts": [ "frame_ne", "halfboard_ne", "headlight" ] },
{ "x": 2, "y": 3, "parts": [ "wheel_mount_medium_steerable", "wheel_wide" ] },
{ "x": -1, "y": -1, "parts": [ "frame_horizontal", "board_horizontal" ] },
{ "x": -1, "y": 0, "parts": [ "frame_horizontal", "board_horizontal" ] },
{ "x": -1, "y": 1, "parts": [ "frame_horizontal", "board_horizontal" ] },
{ "x": -1, "y": 2, "parts": [ "frame_horizontal", "board_horizontal" ] },
{ "x": -1, "y": 3, "parts": [ "frame_horizontal", "board_horizontal" ] },
{ "x": -1, "y": -1, "part": "tank", "fuel": "gasoline" },
{ "x": -2, "y": -1, "parts": [ "frame_vertical", "door" ] },
{ "x": -2, "y": 0, "parts": [ "frame_vertical", "cargo_space", "roof" ] },
{ "x": -2, "y": 1, "parts": [ "frame_vertical", "cargo_space", "roof" ] },
{ "x": -2, "y": 2, "parts": [ "frame_vertical", "cargo_space", "roof" ] },
{ "x": -2, "y": 3, "parts": [ "frame_vertical", "door" ] },
{ "x": -3, "y": -1, "parts": [ "frame_vertical", "board_vertical", "roof" ] },
{ "x": -3, "y": 0, "parts": [ "frame_vertical", "cargo_space", "roof" ] },
{ "x": -3, "y": 1, "parts": [ "frame_vertical", "cargo_space", "roof" ] },
{ "x": -3, "y": 2, "parts": [ "frame_vertical", "cargo_space", "roof" ] },
{ "x": -3, "y": 3, "parts": [ "frame_vertical", "board_vertical", "roof" ] },
{ "x": -4, "y": -1, "parts": [ "frame_vertical", "board_vertical", "roof" ] },
{ "x": -4, "y": 0, "parts": [ "frame_vertical", "cargo_space", "roof" ] },
{ "x": -4, "y": 1, "parts": [ "frame_vertical", "cargo_space", "roof" ] },
{ "x": -4, "y": 2, "parts": [ "frame_vertical", "cargo_space", "roof" ] },
{ "x": -4, "y": 3, "parts": [ "frame_vertical", "board_vertical", "roof" ] },
{ "x": -4, "y": -1, "parts": [ "wheel_mount_medium", "wheel_wide" ] },
{ "x": -4, "y": 3, "parts": [ "wheel_mount_medium", "wheel_wide" ] },
{ "x": -5, "y": -1, "parts": [ "frame_sw", "board_sw", "roof" ] },
{ "x": -5, "y": 0, "parts": [ "frame_horizontal", "door_shutter", "roof" ] },
{ "x": -5, "y": 1, "parts": [ "frame_horizontal", "door_shutter", "roof" ] },
{ "x": -5, "y": 2, "parts": [ "frame_horizontal", "door_shutter", "roof" ] },
{ "x": -5, "y": 3, "parts": [ "frame_se", "board_se", "roof" ] },
{ "x": -5, "y": -2, "part": "wing_mirror" },
{ "x": -5, "y": 4, "part": "external_tank_small" }
]
}
]
6 changes: 3 additions & 3 deletions src/explosion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ static void do_blast( const tripoint &p, const float power,

if( const optional_vpart_position vp = here.veh_at( pt ) ) {
// TODO: Make this weird unit used by vehicle::damage more sensible
vp->vehicle().damage( vp->part_index(), force, fire ? damage_type::HEAT : damage_type::BASH,
false );
vp->vehicle().damage( here, vp->part_index(), force,
fire ? damage_type::HEAT : damage_type::BASH, false );
}

Creature *critter = creatures.creature_at( pt, true );
Expand Down Expand Up @@ -457,7 +457,7 @@ static std::vector<tripoint> shrapnel( const tripoint &src, int power,
}
if( here.impassable( target ) ) {
if( optional_vpart_position vp = here.veh_at( target ) ) {
vp->vehicle().damage( vp->part_index(), damage / 10 );
vp->vehicle().damage( here, vp->part_index(), damage / 10 );
} else {
here.bash( target, damage / 100, true );
}
Expand Down
2 changes: 1 addition & 1 deletion src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5040,7 +5040,7 @@ bool game::forced_door_closing( const tripoint &p, const ter_id &door_type, int
if( bash_dmg <= 0 ) {
return false;
}
vp->vehicle().damage( vp->part_index(), bash_dmg );
vp->vehicle().damage( m, vp->part_index(), bash_dmg );
if( m.veh_at( p ) ) {
// Check again in case all parts at the door tile
// have been destroyed, if there is still a vehicle
Expand Down
5 changes: 3 additions & 2 deletions src/grab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "units_utility.h"
#include "vehicle.h"
#include "vpart_position.h"
#include "vpart_range.h"

static const efftype_id effect_harnessed( "harnessed" );

Expand All @@ -31,8 +32,8 @@ bool game::grabbed_veh_move( const tripoint &dp )
return false;
}
const int grabbed_part = grabbed_vehicle_vp->part_index();
for( int part_index = 0; part_index < grabbed_vehicle->part_count(); ++part_index ) {
monster *mon = grabbed_vehicle->get_monster( part_index );
for( const vpart_reference &vpr : grabbed_vehicle->get_all_parts() ) {
monster *mon = grabbed_vehicle->get_monster( vpr.part_index() );
if( mon != nullptr && mon->has_effect( effect_harnessed ) ) {
add_msg( m_info, _( "You cannot move this vehicle whilst your %s is harnessed!" ),
mon->get_name() );
Expand Down
3 changes: 2 additions & 1 deletion src/iuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5247,6 +5247,7 @@ cata::optional<int> iuse::unfold_generic( Character *p, item *it, bool, const tr
}
map &here = get_map();
vehicle *veh = here.add_vehicle( vehicle_prototype_none, p->pos(), 0_degrees, 0, 0, false );
veh->suspend_refresh();
if( veh == nullptr ) {
p->add_msg_if_player( m_info, _( "There's no room to unfold the %s." ), it->tname() );
return cata::nullopt;
Expand All @@ -5273,7 +5274,7 @@ cata::optional<int> iuse::unfold_generic( Character *p, item *it, bool, const tr
return 0;
}
}

veh->enable_refresh();
here.add_vehicle_to_cache( veh );

std::string unfold_msg = it->get_var( "unfold_msg" );
Expand Down
71 changes: 34 additions & 37 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ void map::add_vehicle_to_cache( vehicle *veh )
}

// Get parts
for( const vpart_reference &vpr : veh->get_all_parts() ) {
for( const vpart_reference &vpr : veh->get_all_parts_with_fakes() ) {
if( vpr.part().removed ) {
continue;
}
Expand Down Expand Up @@ -575,20 +575,21 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &fac
if( coll.type == veh_coll_veh ) {
continue;
}
if( coll.part > veh.part_count() ||
veh.part( coll.part ).removed ) {
continue;
}
int part_num = veh.get_non_fake_part( coll.part );

const point &collision_point = veh.part( coll.part ).mount;
const int coll_dmg = coll.imp;

// Shock damage, if the target part is a rotor treat as an aimed hit.
if( veh.part_info( coll.part ).rotor_diameter() > 0 ) {
veh.damage( coll.part, coll_dmg, damage_type::BASH, true );
} else {
impulse += coll_dmg;
veh.damage( coll.part, coll_dmg, damage_type::BASH );
veh.damage_all( coll_dmg / 2, coll_dmg, damage_type::BASH, collision_point );
// don't try to deal damage to invalid part (probably removed or destroyed)
if( part_num != -1 ) {
if( veh.part_info( part_num ).rotor_diameter() > 0 ) {
veh.damage( *this, part_num, coll_dmg, damage_type::BASH, true );
} else {
impulse += coll_dmg;
veh.damage( *this, part_num, coll_dmg, damage_type::BASH );
veh.damage_all( coll_dmg / 2, coll_dmg, damage_type::BASH, collision_point );
}
}
}

Expand Down Expand Up @@ -877,21 +878,23 @@ float map::vehicle_vehicle_collision( vehicle &veh, vehicle &veh2,
if( &veh2 != static_cast<vehicle *>( veh_veh_coll.target ) ) {
continue;
}
int coll_part = veh.get_non_fake_part( veh_veh_coll.part );
int target_part = veh2.get_non_fake_part( veh_veh_coll.target_part );

int parm1 = veh.part_with_feature( veh_veh_coll.part, VPFLAG_ARMOR, true );
if( parm1 < 0 ) {
parm1 = veh_veh_coll.part;
int coll_parm = veh.part_with_feature( coll_part, VPFLAG_ARMOR, true );
if( coll_parm < 0 ) {
coll_parm = coll_part;
}
int parm2 = veh2.part_with_feature( veh_veh_coll.target_part, VPFLAG_ARMOR, true );
if( parm2 < 0 ) {
parm2 = veh_veh_coll.target_part;
int target_parm = veh2.part_with_feature( target_part, VPFLAG_ARMOR, true );
if( target_parm < 0 ) {
target_parm = target_part;
}

epicenter1 += veh.part( parm1 ).mount;
veh.damage( parm1, dmg1_part, damage_type::BASH );
epicenter1 += veh.part( coll_parm ).mount;
veh.damage( *this, coll_parm, dmg1_part, damage_type::BASH );

epicenter2 += veh2.part( parm2 ).mount;
veh2.damage( parm2, dmg2_part, damage_type::BASH );
epicenter2 += veh2.part( target_parm ).mount;
veh2.damage( *this, target_parm, dmg2_part, damage_type::BASH );
}

epicenter2.x /= coll_parts_cnt;
Expand Down Expand Up @@ -1260,6 +1263,8 @@ bool map::displace_vehicle( vehicle &veh, const tripoint &dp, const bool adjust_

veh.shed_loose_parts();
smzs = veh.advance_precalc_mounts( dst_offset, src, dp, ramp_offset, adjust_pos, parts_to_move );
veh.update_active_fakes();

if( src_submap != dst_submap ) {
veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
Expand Down Expand Up @@ -3707,7 +3712,7 @@ void map::bash_vehicle( const tripoint &p, bash_params &params )
{
// Smash vehicle if present
if( const optional_vpart_position vp = veh_at( p ) ) {
vp->vehicle().damage( vp->part_index(), params.strength, damage_type::BASH );
vp->vehicle().damage( *this, vp->part_index(), params.strength, damage_type::BASH );
if( !params.silent ) {
sounds::sound( p, 18, sounds::sound_t::combat, _( "crash!" ), false,
"smash_success", "hit_vehicle" );
Expand Down Expand Up @@ -3813,7 +3818,7 @@ void map::crush( const tripoint &p )

if( const optional_vpart_position vp = veh_at( p ) ) {
// Arbitrary number is better than collapsing house roof crushing APCs
vp->vehicle().damage( vp->part_index(), rng( 100, 1000 ), damage_type::BASH, false );
vp->vehicle().damage( *this, vp->part_index(), rng( 100, 1000 ), damage_type::BASH, false );
}
}

Expand Down Expand Up @@ -3842,7 +3847,7 @@ void map::shoot( const tripoint &p, projectile &proj, const bool hit_items )
const bool laser = ammo_effects.count( "LASER" );

if( const optional_vpart_position vp = veh_at( p ) ) {
dam = vp->vehicle().damage( vp->part_index(), dam, main_damage_type, hit_items );
dam = vp->vehicle().damage( *this, vp->part_index(), dam, main_damage_type, hit_items );
}

const auto shoot_furn_ter = [&]( const map_data_common_t &data ) {
Expand Down Expand Up @@ -5754,7 +5759,7 @@ void map::add_splatter( const field_type_id &type, const tripoint &where, int in
if( const optional_vpart_position vp = veh_at( where ) ) {
vehicle *const veh = &vp->vehicle();
// Might be -1 if all the vehicle's parts at where are marked for removal
const int part = veh->part_displayed_at( vp->mount() );
const int part = veh->part_displayed_at( vp->mount(), true );
if( part != -1 ) {
veh->part( part ).blood += 200 * std::min( intensity, 3 ) / 3;
return;
Expand Down Expand Up @@ -8348,7 +8353,7 @@ void map::do_vehicle_caching( int z )
return;
}
for( vehicle *v : ch->vehicle_list ) {
for( const vpart_reference &vp : v->get_all_parts() ) {
for( const vpart_reference &vp : v->get_all_parts_with_fakes() ) {
const tripoint part_pos = v->global_part_pos3( vp.part() );
if( !inbounds( part_pos.xy() ) ) {
continue;
Expand Down Expand Up @@ -8758,19 +8763,11 @@ void map::scent_blockers( std::array<std::array<bool, MAPSIZE_X>, MAPSIZE_Y> &bl
auto vehs = get_vehicles();
for( auto &wrapped_veh : vehs ) {
vehicle &veh = *( wrapped_veh.v );
for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OBSTACLE ) ) {
const tripoint part_pos = vp.pos();
if( local_bounds.contains( part_pos.xy() ) ) {
reduces_scent[part_pos.x][part_pos.y] = true;
}
}

// Doors, but only the closed ones
for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OPENABLE ) ) {
if( vp.part().open ) {
for( const vpart_reference &vp : veh.get_all_parts_with_fakes() ) {
if( !vp.has_feature( VPFLAG_OBSTACLE ) &&
( !vp.has_feature( VPFLAG_OPENABLE ) || !vp.part().open ) ) {
continue;
}

const tripoint part_pos = vp.pos();
if( local_bounds.contains( part_pos.xy() ) ) {
reduces_scent[part_pos.x][part_pos.y] = true;
Expand Down
2 changes: 1 addition & 1 deletion src/map_field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ void field_processor_fd_fire( const tripoint &p, field_entry &cur, field_proc_da
// Get the part of the vehicle in the fire (_internal skips the boundary check)
vehicle *veh = here.veh_at_internal( p, part );
if( veh != nullptr ) {
veh->damage( part, cur.get_field_intensity() * 10, damage_type::HEAT, true );
veh->damage( here, part, cur.get_field_intensity() * 10, damage_type::HEAT, true );
// Damage the vehicle in the fire.
}
if( can_burn ) {
Expand Down
Loading

0 comments on commit befb7ab

Please sign in to comment.