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

[DDA Port] Autodrive v2 and improved overmap pathfinding #1169

Merged
merged 17 commits into from
Dec 12, 2021
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
19 changes: 10 additions & 9 deletions src/action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,31 +578,32 @@ bool can_move_vertical_at( const tripoint &p, int movez )

bool can_examine_at( const tripoint &p )
{
if( g->m.veh_at( p ) ) {
map &here = get_map();
Character &u = get_player_character();
if( here.veh_at( p ) ) {
return true;
}
if( g->m.has_flag( flag_CONSOLE, p ) ) {
if( here.has_flag( flag_CONSOLE, p ) ) {
return true;
}
if( g->m.has_items( p ) ) {
if( here.has_items( p ) ) {
return true;
}
const furn_t &xfurn_t = g->m.furn( p ).obj();
const ter_t &xter_t = g->m.ter( p ).obj();
const furn_t &xfurn_t = here.furn( p ).obj();
const ter_t &xter_t = here.ter( p ).obj();

if( g->m.has_furn( p ) && xfurn_t.examine != &iexamine::none ) {
if( here.has_furn( p ) && xfurn_t.examine != &iexamine::none ) {
return true;
} else if( xter_t.examine != &iexamine::none ) {
return true;
}

Creature *c = g->critter_at( p );
if( c != nullptr && p != g->u.pos() ) {
if( c != nullptr && p != u.pos() ) {
return true;
}

const trap &tr = g->m.tr_at( p );
return tr.can_see( p, g->u );
return here.can_see_trap_at( p, u );
}

static bool can_pickup_at( const tripoint &p )
Expand Down
74 changes: 74 additions & 0 deletions src/activity_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
#include "translations.h"
#include "uistate.h"
#include "units.h"
#include "vehicle.h"
#include "vpart_position.h"

static const itype_id itype_bone_human( "bone_human" );
static const itype_id itype_electrohack( "electrohack" );
Expand Down Expand Up @@ -313,6 +315,77 @@ void aim_activity_actor::unload_RAS_weapon()
}
}

void autodrive_activity_actor::start( player_activity &act, Character &who )
{
const bool in_vehicle = who.in_vehicle && who.controlling_vehicle;
const optional_vpart_position vp = get_map().veh_at( who.pos() );
if( !( vp && in_vehicle ) ) {
who.cancel_activity();
return;
}

player_vehicle = &vp->vehicle();
player_vehicle->is_autodriving = true;
act.moves_left = calendar::INDEFINITELY_LONG;
}

void autodrive_activity_actor::do_turn( player_activity &act, Character &who )
{
if( who.in_vehicle && who.controlling_vehicle && player_vehicle ) {
if( who.moves <= 0 ) {
// out of moves? the driver's not doing anything this turn
// (but the vehicle will continue moving)
return;
}
switch( player_vehicle->do_autodrive( who ) ) {
case autodrive_result::ok:
if( who.moves > 0 ) {
// if do_autodrive() didn't eat up all our moves, end the turn
// equivalent to player pressing the "pause" button
who.moves = 0;
}
sounds::reset_markers();
break;
case autodrive_result::abort:
who.cancel_activity();
break;
case autodrive_result::finished:
act.moves_left = 0;
break;
}
} else {
who.cancel_activity();
}
}

void autodrive_activity_actor::canceled( player_activity &act, Character &who )
{
who.add_msg_if_player( m_info, _( "Auto-drive canceled." ) );
who.omt_path.clear();
if( player_vehicle ) {
player_vehicle->stop_autodriving( false );
}
act.set_to_null();
}

void autodrive_activity_actor::finish( player_activity &act, Character &who )
{
who.add_msg_if_player( m_info, _( "You have reached your destination." ) );
player_vehicle->stop_autodriving( false );
act.set_to_null();
}

void autodrive_activity_actor::serialize( JsonOut &jsout ) const
{
// Activity is not being saved but still provide some valid json if called.
jsout.write_null();
}

std::unique_ptr<activity_actor> autodrive_activity_actor::deserialize( JsonIn & )
{
return autodrive_activity_actor().clone();
}

void dig_activity_actor::start( player_activity &act, Character & )
{
act.moves_total = moves_total;
Expand Down Expand Up @@ -963,6 +1036,7 @@ namespace activity_actors
const std::unordered_map<activity_id, std::unique_ptr<activity_actor>( * )( JsonIn & )>
deserialize_functions = {
{ activity_id( "ACT_AIM" ), &aim_activity_actor::deserialize },
{ activity_id( "ACT_AUTODRIVE" ), &autodrive_activity_actor::deserialize },
{ activity_id( "ACT_DIG" ), &dig_activity_actor::deserialize },
{ activity_id( "ACT_DIG_CHANNEL" ), &dig_channel_activity_actor::deserialize },
{ activity_id( "ACT_DROP" ), &drop_activity_actor::deserialize },
Expand Down
26 changes: 26 additions & 0 deletions src/activity_actor_definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "units_energy.h"

class Creature;
class vehicle;

class aim_activity_actor : public activity_actor
{
Expand Down Expand Up @@ -79,6 +80,31 @@ class aim_activity_actor : public activity_actor
void unload_RAS_weapon();
};

class autodrive_activity_actor : public activity_actor
{
private:
vehicle *player_vehicle = nullptr;

public:
autodrive_activity_actor() = default;

activity_id get_type() const override {
return activity_id( "ACT_AUTODRIVE" );
}

void start( player_activity &act, Character & ) override;
void do_turn( player_activity &, Character & ) override;
void canceled( player_activity &, Character & ) override;
void finish( player_activity &act, Character & ) override;

std::unique_ptr<activity_actor> clone() const override {
return std::make_unique<autodrive_activity_actor>( *this );
}

void serialize( JsonOut &jsout ) const override;
static std::unique_ptr<activity_actor> deserialize( JsonIn &jsin );
};

class dig_activity_actor : public activity_actor
{
private:
Expand Down
54 changes: 14 additions & 40 deletions src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@
static const activity_id ACT_ADV_INVENTORY( "ACT_ADV_INVENTORY" );
static const activity_id ACT_ARMOR_LAYERS( "ACT_ARMOR_LAYERS" );
static const activity_id ACT_ATM( "ACT_ATM" );
static const activity_id ACT_AUTODRIVE( "ACT_AUTODRIVE" );
static const activity_id ACT_BUILD( "ACT_BUILD" );
static const activity_id ACT_BURROW( "ACT_BURROW" );
static const activity_id ACT_BUTCHER( "ACT_BUTCHER" );
Expand Down Expand Up @@ -319,7 +318,6 @@ activity_handlers::do_turn_functions = {
{ ACT_BUTCHER, butcher_do_turn },
{ ACT_BUTCHER_FULL, butcher_do_turn },
{ ACT_TRAVELLING, travel_do_turn },
{ ACT_AUTODRIVE, drive_do_turn },
{ ACT_FIELD_DRESS, butcher_do_turn },
{ ACT_SKIN, butcher_do_turn },
{ ACT_QUARTER, butcher_do_turn },
Expand Down Expand Up @@ -2978,39 +2976,6 @@ void activity_handlers::adv_inventory_do_turn( player_activity *, player *p )
create_advanced_inv();
}

void activity_handlers::drive_do_turn( player_activity *act, player *p )
{
vehicle *player_veh = veh_pointer_or_null( g->m.veh_at( p->pos() ) );
if( !player_veh ) {
act->set_to_null();
p->cancel_activity();
return;
}
if( p->in_vehicle && p->controlling_vehicle && player_veh->is_autodriving &&
!g->u.omt_path.empty() && !player_veh->omt_path.empty() ) {
player_veh->do_autodrive();
if( g->u.global_omt_location() == g->u.omt_path.back() ) {
g->u.omt_path.pop_back();
}
p->moves = 0;
} else {
p->add_msg_if_player( m_info, _( "Auto-drive canceled." ) );
if( !player_veh->omt_path.empty() ) {
player_veh->omt_path.clear();
}
player_veh->is_autodriving = false;
act->set_to_null();
p->cancel_activity();
return;
}
if( player_veh->omt_path.empty() ) {
act->set_to_null();
player_veh->is_autodriving = false;
p->add_msg_if_player( m_info, _( "You have reached your destination." ) );
p->cancel_activity();
}
}

void activity_handlers::travel_do_turn( player_activity *act, player *p )
{
if( !p->omt_path.empty() ) {
Expand All @@ -3020,13 +2985,22 @@ void activity_handlers::travel_do_turn( player_activity *act, player *p )
act->set_to_null();
return;
}
const tripoint_abs_omt next_omt = p->omt_path.back();
tripoint_abs_ms waypoint;
if( p->omt_path.size() == 1 ) {
// if next omt is the final one, target its midpoint
waypoint = midpoint( project_bounds<coords::ms>( next_omt ) );
} else {
// otherwise target the middle of the edge nearest to our current location
const tripoint_abs_ms cur_omt_mid = midpoint( project_bounds<coords::ms>
( p->global_omt_location() ) );
waypoint = clamp( cur_omt_mid, project_bounds<coords::ms>( next_omt ) );
}
map &here = get_map();
// TODO: fix point types
tripoint sm_tri = here.getlocal(
project_to<coords::ms>( p->omt_path.back() ).raw() );
tripoint centre_sub = sm_tri + point( SEEX, SEEY );
if( !g->m.passable( centre_sub ) ) {
tripoint_range<tripoint> candidates = g->m.points_in_radius( centre_sub, 2 );
tripoint centre_sub = here.getlocal( waypoint.raw() );
if( !here.passable( centre_sub ) ) {
tripoint_range<tripoint> candidates = here.points_in_radius( centre_sub, 2 );
for( const tripoint &elem : candidates ) {
if( g->m.passable( elem ) ) {
centre_sub = elem;
Expand Down
1 change: 0 additions & 1 deletion src/activity_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ void chop_trees_do_turn( player_activity *act, player *p );
void fetch_do_turn( player_activity *act, player *p );
void move_loot_do_turn( player_activity *act, player *p );
void travel_do_turn( player_activity *act, player *p );
void drive_do_turn( player_activity *act, player *p );
void adv_inventory_do_turn( player_activity *act, player *p );
void armor_layers_do_turn( player_activity *act, player *p );
void atm_do_turn( player_activity *act, player *p );
Expand Down
6 changes: 3 additions & 3 deletions src/activity_item_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -892,9 +892,9 @@ static int move_cost( const item &it, const tripoint &src, const tripoint &dest

if( const cata::optional<vpart_reference> vp = g->m.veh_at(
cart_position ).part_with_feature( "CARGO", false ) ) {
auto veh = vp->vehicle();
auto vstor = vp->part_index();
auto capacity = veh.free_volume( vstor );
const vehicle &veh = vp->vehicle();
size_t vstor = vp->part_index();
units::volume capacity = veh.free_volume( vstor );

return move_cost_cart( it, src, dest, capacity );
}
Expand Down
35 changes: 12 additions & 23 deletions src/cata_tiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1193,31 +1193,20 @@ void cata_tiles::draw( const point &dest, const tripoint &center, int width, int
g->displaying_visibility_creature = nullptr;
}
}
std::unordered_set<point> collision_checkpoints;
std::unordered_set<point> target_points;
for( const wrapped_vehicle &elem : g->m.get_vehicles() ) {
if( elem.v->get_autodrive_target() != tripoint_zero ) {
target_points.insert( g->m.getlocal( elem.v->get_autodrive_target().xy() ) );
}
if( elem.v->collision_check_points.empty() ) {
continue;
} else {
for( const point &pt_elem : elem.v->collision_check_points ) {
collision_checkpoints.insert( g->m.getlocal( pt_elem ) );
}
}
}
const point half_tile( tile_width / 2, 0 );
const point quarter_tile( tile_width / 4, tile_height / 4 );
if( g->display_overlay_state( ACTION_DISPLAY_VEHICLE_AI ) ) {
for( const point &pt_elem : collision_checkpoints ) {
overlay_strings.emplace( player_to_screen( pt_elem ) + point( tile_width / 2, 0 ),
formatted_text( "CHECK", catacurses::yellow,
direction::NORTH ) );
}
for( const point &pt_elem : target_points ) {
overlay_strings.emplace( player_to_screen( pt_elem ) + point( tile_width / 2, 0 ),
formatted_text( "TARGET", catacurses::red,
direction::NORTH ) );
for( const wrapped_vehicle &elem : here.get_vehicles() ) {
const vehicle &veh = *elem.v;
const point veh_pos = veh.global_pos3().xy();
for( const auto &overlay_data : veh.get_debug_overlay_data() ) {
const point pt = veh_pos + std::get<0>( overlay_data );
const int color = std::get<1>( overlay_data );
const std::string &text = std::get<2>( overlay_data );
overlay_strings.emplace( player_to_screen( pt ),
formatted_text( text, color,
text_alignment::left ) );
}
}
}
for( int row = min_row; row < max_row; row ++ ) {
Expand Down
Loading