Skip to content

Commit

Permalink
Added vehicle holes to a wide range of areas
Browse files Browse the repository at this point in the history
  • Loading branch information
joveeater committed Aug 1, 2022
1 parent 4022583 commit 9773f38
Show file tree
Hide file tree
Showing 18 changed files with 371 additions and 123 deletions.
2 changes: 1 addition & 1 deletion src/activity_item_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ std::vector<tripoint> route_adjacent( const player &p, const tripoint &dest )
map &here = get_map();

for( const tripoint &tp : here.points_in_radius( dest, 1 ) ) {
if( tp != p.pos() && here.passable( tp ) ) {
if( tp != p.pos() && here.passable( tp ) && !here.obstructed_by_vehicle_rotation( dest, tp ) ) {
passable_tiles.emplace( tp );
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7872,7 +7872,7 @@ tripoint Character::adjacent_tile() const
}
}

if( dangerous_fields == 0 ) {
if( dangerous_fields == 0 && ! get_map().obstructed_by_vehicle_rotation( pos(), p ) ) {
ret.push_back( p );
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/explosion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ static std::map<const Creature *, int> do_blast_new( const tripoint &blast_cente
for( const dist_point_pair &pair : blast_map ) {
float distance;
tripoint position;
tripoint last_position = position;
tripoint last_position = blast_center;
std::tie( distance, position ) = pair;

const std::vector<tripoint> line_of_movement = line_to( blast_center, position );
Expand Down
50 changes: 40 additions & 10 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4602,6 +4602,8 @@ void game::knockback( std::vector<tripoint> &traj, int stun, int dam_mult )
// TODO: make the force parameter actually do something.
// the header file says higher force causes more damage.
// perhaps that is what it should do?

// TODO: refactor this so it's not copy/pasted 3 times
tripoint tp = traj.front();
if( !critter_at( tp ) ) {
debugmsg( _( "Nothing at (%d,%d,%d) to knockback!" ), tp.x, tp.y, tp.z );
Expand All @@ -4614,7 +4616,7 @@ void game::knockback( std::vector<tripoint> &traj, int stun, int dam_mult )
add_msg( _( "%s was stunned!" ), targ->name() );
}
for( size_t i = 1; i < traj.size(); i++ ) {
if( m.impassable( traj[i].xy() ) ) {
if( m.impassable( traj[i].xy() ) || m.obstructed_by_vehicle_rotation( tp, traj[i] ) ) {
targ->setpos( traj[i - 1] );
force_remaining = traj.size() - i;
if( stun != 0 ) {
Expand Down Expand Up @@ -4665,14 +4667,16 @@ void game::knockback( std::vector<tripoint> &traj, int stun, int dam_mult )
add_msg( _( "The %s flops around and dies!" ), targ->name() );
}
}
tp = traj[i];
}
} else if( npc *const targ = critter_at<npc>( tp ) ) {
if( stun > 0 ) {
targ->add_effect( effect_stunned, 1_turns * stun );
add_msg( _( "%s was stunned!" ), targ->name );
}
for( size_t i = 1; i < traj.size(); i++ ) {
if( m.impassable( traj[i].xy() ) ) { // oops, we hit a wall!
if( m.impassable( traj[i].xy() ) ||
m.obstructed_by_vehicle_rotation( tp, traj[i] ) ) { // oops, we hit a wall!
targ->setpos( traj[i - 1] );
force_remaining = traj.size() - i;
if( stun != 0 ) {
Expand Down Expand Up @@ -4729,6 +4733,7 @@ void game::knockback( std::vector<tripoint> &traj, int stun, int dam_mult )
break;
}
targ->setpos( traj[i] );
tp = traj[i];
}
} else if( u.pos() == tp ) {
if( stun > 0 ) {
Expand All @@ -4739,7 +4744,8 @@ void game::knockback( std::vector<tripoint> &traj, int stun, int dam_mult )
stun );
}
for( size_t i = 1; i < traj.size(); i++ ) {
if( m.impassable( traj[i] ) ) { // oops, we hit a wall!
if( m.impassable( traj[i] ) ||
m.obstructed_by_vehicle_rotation( tp, traj[i] ) ) { // oops, we hit a wall!
u.setpos( traj[i - 1] );
force_remaining = traj.size() - i;
if( stun != 0 ) {
Expand Down Expand Up @@ -4807,6 +4813,8 @@ void game::knockback( std::vector<tripoint> &traj, int stun, int dam_mult )
} else {
u.setpos( traj[i] );
}

tp = traj[i];
}
}
}
Expand Down Expand Up @@ -5929,7 +5937,7 @@ void game::peek()
return;
}

if( m.impassable( u.pos() + *p ) ) {
if( m.impassable( u.pos() + *p ) || m.obstructed_by_vehicle_rotation( u.pos(), u.pos() + *p ) ) {
return;
}

Expand Down Expand Up @@ -10329,7 +10337,6 @@ void game::fling_creature( Creature *c, const units::angle &dir, float flvel, bo
return;
}

int steps = 0;
bool thru = true;
const bool is_u = ( c == &u );
// Don't animate critters getting bashed if animations are off
Expand All @@ -10340,16 +10347,36 @@ void game::fling_creature( Creature *c, const units::angle &dir, float flvel, bo
tileray tdir( dir );
int range = flvel / 10;
tripoint pt = c->pos();
tripoint prev_point = pt;
bool force_next = false;
tripoint next_forced = tripoint_zero;
while( range > 0 ) {
c->underwater = false;
// TODO: Check whenever it is actually in the viewport
// or maybe even just redraw the changed tiles
bool seen = is_u || u.sees( *c ); // To avoid redrawing when not seen
tdir.advance();
pt.x = c->posx() + tdir.dx();
pt.y = c->posy() + tdir.dy();
if( force_next ) {
pt = next_forced;
force_next = false;
} else {
tdir.advance();
pt.x = c->posx() + tdir.dx();
pt.y = c->posy() + tdir.dy();
}
float force = 0;

if( m.obstructed_by_vehicle_rotation( prev_point, pt ) ) {
//We process the intervening tile on this iteration and then the current tile on the next
next_forced = pt;
force_next = true;
if( one_in( 2 ) ) {
pt.x = prev_point.x;
} else {
pt.y = prev_point.y;
}
}


if( monster *const mon_ptr = critter_at<monster>( pt ) ) {
monster &critter = *mon_ptr;
// Approximate critter's "stopping power" with its max hp
Expand Down Expand Up @@ -10413,8 +10440,11 @@ void game::fling_creature( Creature *c, const units::angle &dir, float flvel, bo
// although at lower velocity
break;
}
range--;
steps++;
//Vehicle wall tiles don't count for range
if( !force_next ) {
range--;
}
prev_point = pt;
if( animate && ( seen || u.sees( *c ) ) ) {
invalidate_main_ui_adaptor();
ui_manager::redraw_invalidated();
Expand Down
3 changes: 2 additions & 1 deletion src/iuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,8 @@ int iuse::fungicide( player *p, item *it, bool, const tripoint & )
if( dest == p->pos() ) {
continue;
}
if( g->m.passable( dest ) && x_in_y( spore_count, 8 ) ) {
if( g->m.passable( dest ) && !get_map().obstructed_by_vehicle_rotation( p->pos(), dest ) &&
x_in_y( spore_count, 8 ) ) {
if( monster *const mon_ptr = g->critter_at<monster>( dest ) ) {
monster &critter = *mon_ptr;
if( g->u.sees( dest ) &&
Expand Down
60 changes: 44 additions & 16 deletions src/magic_spell_effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,16 @@ static bool between_or_on( const point &a0, const point &a1, const point &d, con
}
// Builds line until obstructed or outside of region bound by near and far lines. Stores result in set
static void build_line( spell_detail::line_iterable line, const tripoint &source,
const point &delta, const point &delta_perp, bool ( *test )( const tripoint & ),
const point &delta, const point &delta_perp, bool ( *test )( const tripoint &, const tripoint & ),
std::set<tripoint> &result )
{
tripoint last_point = source;
while( between_or_on( point_zero, delta, delta_perp, line.get() ) ) {
if( !test( source + line.get() ) ) {
if( !test( source + line.get(), last_point ) ) {
break;
}
result.emplace( source + line.get() );
last_point = source + line.get();
line.next();
}
}
Expand Down Expand Up @@ -163,10 +165,13 @@ static bool in_spell_aoe( const tripoint &start, const tripoint &end, const int
return true;
}
const std::vector<tripoint> trajectory = line_to( start, end );
tripoint last_point = start;
for( const tripoint &pt : trajectory ) {
if( g->m.impassable( pt ) && !g->m.has_flag( "THIN_OBSTACLE", pt ) ) {
if( ( g->m.impassable( pt ) && !g->m.has_flag( "THIN_OBSTACLE", pt ) ) ||
g->m.obstructed_by_vehicle_rotation( pt, last_point ) ) {
return false;
}
last_point = pt;
}
return true;
}
Expand Down Expand Up @@ -202,26 +207,30 @@ std::set<tripoint> spell_effect::spell_effect_cone( const spell &sp, const tripo
}
for( const tripoint &ep : end_points ) {
std::vector<tripoint> trajectory = line_to( source, ep );
tripoint last_point = source;
for( const tripoint &tp : trajectory ) {
if( ignore_walls || g->m.passable( tp ) || g->m.has_flag( "THIN_OBSTACLE", tp ) ) {
if( ignore_walls || ( !g->m.obstructed_by_vehicle_rotation( tp, last_point ) &&
( g->m.passable( tp ) || g->m.has_flag( "THIN_OBSTACLE", tp ) ) ) ) {
targets.emplace( tp );
} else {
break;
}
last_point = tp;
}
}
// we don't want to hit ourselves in the blast!
targets.erase( source );
return targets;
}

static bool test_always_true( const tripoint & )
static bool test_always_true( const tripoint &, const tripoint & )
{
return true;
}
static bool test_passable( const tripoint &p )
static bool test_passable( const tripoint &p, const tripoint &prev )
{
return ( g->m.passable( p ) || g->m.has_flag( "THIN_OBSTACLE", p ) );
return ( !g->m.obstructed_by_vehicle_rotation( prev, p ) && ( g->m.passable( p ) ||
g->m.has_flag( "THIN_OBSTACLE", p ) ) );
}

std::set<tripoint> spell_effect::spell_effect_line( const spell &, const tripoint &source,
Expand Down Expand Up @@ -254,7 +263,8 @@ std::set<tripoint> spell_effect::spell_effect_line( const spell &, const tripoin
// is delta aligned with, cw, or ccw of primary axis
int delta_side = spell_detail::side_of( point_zero, axis_delta, delta );

bool ( *test )( const tripoint & ) = ignore_walls ? test_always_true : test_passable;
bool ( *test )( const tripoint &,
const tripoint & ) = ignore_walls ? test_always_true : test_passable;

// Canonical path from source to target, offset to local space
std::vector<point> path_to_target = line_to( point_zero, delta );
Expand All @@ -273,37 +283,44 @@ std::set<tripoint> spell_effect::spell_effect_line( const spell &, const tripoin
// Add cw and ccw legs
if( delta_side == 0 ) { // delta is already axis aligned, only need straight lines
// cw leg
point prev_point = point_zero;
for( const point &p : line_to( point_zero, unit_cw_perp_axis * cw_len ) ) {
base_line.reset( p );
if( !test( source + p ) ) {
if( !test( source + p, source + prev_point ) ) {
break;
}

spell_detail::build_line( base_line, source, delta, delta_perp, test, result );
prev_point = p;
}
// ccw leg
prev_point = point_zero;
for( const point &p : line_to( point_zero, unit_cw_perp_axis * -ccw_len ) ) {
base_line.reset( p );
if( !test( source + p ) ) {
if( !test( source + p, source + prev_point ) ) {
break;
}

spell_detail::build_line( base_line, source, delta, delta_perp, test, result );
prev_point = p;
}
} else if( delta_side == 1 ) { // delta is cw of primary axis
// ccw leg is behind perp axis
point prev_point = point_zero;
for( const point &p : line_to( point_zero, unit_cw_perp_axis * -ccw_len ) ) {
base_line.reset( p );

// forward until in
while( spell_detail::side_of( point_zero, delta_perp, base_line.get() ) == 1 ) {
base_line.next();
}
if( !test( source + p ) ) {
if( !test( source + p, source + prev_point ) ) {
break;
}
spell_detail::build_line( base_line, source, delta, delta_perp, test, result );
prev_point = p;
}
prev_point = point_zero;
// cw leg is before perp axis
for( const point &p : line_to( point_zero, unit_cw_perp_axis * cw_len ) ) {
base_line.reset( p );
Expand All @@ -313,13 +330,15 @@ std::set<tripoint> spell_effect::spell_effect_line( const spell &, const tripoin
base_line.prev();
}
base_line.next();
if( !test( source + p ) ) {
if( !test( source + p, source + prev_point ) ) {
break;
}
spell_detail::build_line( base_line, source, delta, delta_perp, test, result );
prev_point = p;
}
} else if( delta_side == -1 ) { // delta is ccw of primary axis
// ccw leg is before perp axis
point prev_point = point_zero;
for( const point &p : line_to( point_zero, unit_cw_perp_axis * -ccw_len ) ) {
base_line.reset( p );

Expand All @@ -328,11 +347,13 @@ std::set<tripoint> spell_effect::spell_effect_line( const spell &, const tripoin
base_line.prev();
}
base_line.next();
if( !test( source + p ) ) {
if( !test( source + p, source + prev_point ) ) {
break;
}
spell_detail::build_line( base_line, source, delta, delta_perp, test, result );
prev_point = p;
}
prev_point = point_zero;
// cw leg is behind perp axis
for( const point &p : line_to( point_zero, unit_cw_perp_axis * cw_len ) ) {
base_line.reset( p );
Expand All @@ -341,10 +362,11 @@ std::set<tripoint> spell_effect::spell_effect_line( const spell &, const tripoin
while( spell_detail::side_of( point_zero, delta_perp, base_line.get() ) == 1 ) {
base_line.next();
}
if( !test( source + p ) ) {
if( !test( source + p, source + prev_point ) ) {
break;
}
spell_detail::build_line( base_line, source, delta, delta_perp, test, result );
prev_point = p;
}
}

Expand Down Expand Up @@ -471,15 +493,18 @@ void spell_effect::projectile_attack( const spell &sp, Creature &caster,
const tripoint &target )
{
std::vector<tripoint> trajectory = line_to( caster.pos(), target );
tripoint prev_point = caster.pos();
for( std::vector<tripoint>::iterator iter = trajectory.begin(); iter != trajectory.end(); iter++ ) {
if( g->m.impassable( *iter ) && !g->m.has_flag( "THIN_OBSTACLE", *iter ) ) {
if( ( g->m.impassable( *iter ) && !g->m.has_flag( "THIN_OBSTACLE", *iter ) ) ||
g->m.obstructed_by_vehicle_rotation( prev_point, *iter ) ) {
if( iter != trajectory.begin() ) {
target_attack( sp, caster, *( iter - 1 ) );
} else {
target_attack( sp, caster, *iter );
}
return;
}
prev_point = *iter;
}
target_attack( sp, caster, trajectory.back() );
}
Expand Down Expand Up @@ -549,6 +574,8 @@ int area_expander::run( const tripoint &center )
// Number of nodes expanded.
int expanded = 0;

map &here = get_map();

while( !frontier.empty() ) {
int best_index = frontier.top();
frontier.pop();
Expand All @@ -557,7 +584,8 @@ int area_expander::run( const tripoint &center )
for( size_t i = 0; i < 8; i++ ) {
tripoint pt = best.position + point( x_offset[ i ], y_offset[ i ] );

if( g->m.impassable( pt ) && !g->m.has_flag( "THIN_OBSTACLE", pt ) ) {
if( ( here.impassable( pt ) && !here.has_flag( "THIN_OBSTACLE", pt ) ) ||
here.obstructed_by_vehicle_rotation( best.position, pt ) ) {
continue;
}

Expand Down
Loading

0 comments on commit 9773f38

Please sign in to comment.