Skip to content

Commit

Permalink
Migrate more monster fields to absolute coords
Browse files Browse the repository at this point in the history
Change to tripoint_abs_ms:
- goal [was map-relative]
- wander_pos [was map-relative]
- patrol_route [was absolute but not typed]
Remove serialization for path.
Invalidate path on map shift.
Made goal optional, unset when reached.
Rename goal-related functions for consistency/readability.
  • Loading branch information
eltank authored and Venera3 committed Sep 21, 2021
1 parent 7098d16 commit e59ff40
Show file tree
Hide file tree
Showing 15 changed files with 210 additions and 198 deletions.
6 changes: 3 additions & 3 deletions src/editmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,9 +485,9 @@ void editmap::uber_draw_ter( const catacurses::window &w, map *m )
}
if( refresh_mplans ) {
monster *mon = dynamic_cast<monster *>( critter );
if( mon != nullptr && mon->pos() != mon->move_target() ) {
for( auto &location : line_to( mon->pos(), mon->move_target() ) ) {
hilights["mplan"].points[location] = 1;
if( mon != nullptr && mon->has_dest() ) {
for( auto &location : line_to( mon->get_location(), mon->get_dest() ) ) {
hilights["mplan"].points[m->getlocal( location )] = 1;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10635,7 +10635,7 @@ void game::vertical_move( int movez, bool force, bool peeking )
// TODO: Remove stair teleport bullshit
if( rl_dist( u.pos(), old_pos ) <= 1 ) {
for( monster *m : monsters_following ) {
m->set_dest( u.pos() );
m->set_dest( u.get_location() );
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/gamemode_defense.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1361,7 +1361,7 @@ std::vector<mtype_id> defense_game::pick_monster_wave()

void defense_game::spawn_wave_monster( const mtype_id &type )
{
tripoint player_pos = get_player_character().pos();
const tripoint_abs_ms player_pos = get_player_character().get_location();
map &here = get_map();
for( int tries = 0; tries < 1000; tries++ ) {
point pnt;
Expand Down
14 changes: 6 additions & 8 deletions src/iuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9179,27 +9179,25 @@ cata::optional<int> iuse::lux_meter( Character *p, item *, bool, const tripoint
return 0;
}

cata::optional<int> iuse::directional_hologram( Character *p, item *it, bool, const tripoint &pos )
cata::optional<int> iuse::directional_hologram( Character *p, item *it, bool, const tripoint & )
{
if( it->is_armor() && !( p->is_worn( *it ) ) ) {
p->add_msg_if_player( m_neutral, _( "You need to wear the %1$s before activating it." ),
it->tname() );
return cata::nullopt;
}
const cata::optional<tripoint> posp_ = choose_adjacent( _( "Choose hologram direction." ) );
if( !posp_ ) {
const cata::optional<tripoint> posp = choose_adjacent( _( "Choose hologram direction." ) );
if( !posp ) {
return cata::nullopt;
}
const tripoint posp = *posp_;
const tripoint delta = *posp - get_player_character().pos();

monster *const hologram = g->place_critter_at( mon_hologram, posp );
monster *const hologram = g->place_critter_at( mon_hologram, *posp );
if( !hologram ) {
p->add_msg_if_player( m_info, _( "Can't create a hologram there." ) );
return cata::nullopt;
}
tripoint target = pos;
target.x = p->posx() + 4 * SEEX * ( posp.x - p->posx() );
target.y = p->posy() + 4 * SEEY * ( posp.y - p->posy() );
tripoint_abs_ms target = p->get_location() + delta * ( 4 * SEEX );
hologram->friendly = -1;
hologram->add_effect( effect_docile, 1_hours );
hologram->wandf = -30;
Expand Down
35 changes: 17 additions & 18 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7341,7 +7341,8 @@ void map::copy_grid( const tripoint &to, const tripoint &from )
}
}

void map::spawn_monsters_submap_group( const tripoint &gp, mongroup &group, bool ignore_sight )
void map::spawn_monsters_submap_group( const tripoint &gp, mongroup &group,
const tripoint_abs_sm &submap_pos, bool ignore_sight )
{
Character &player_character = get_player_character();
const int s_range = std::min( HALF_MAPSIZE_X,
Expand Down Expand Up @@ -7453,26 +7454,25 @@ void map::spawn_monsters_submap_group( const tripoint &gp, mongroup &group, bool
}

// Find horde's target submap
// TODO: fix point types
tripoint horde_target( tripoint( -abs_sub.xy(), abs_sub.z ) + group.target.xy().raw() );
sm_to_ms( horde_target );
tripoint_abs_sm horde_target = submap_pos + ( group.target - group.pos );
for( auto &tmp : group.monsters ) {
for( int tries = 0; tries < 10 && !locations.empty(); tries++ ) {
const tripoint p = random_entry_removed( locations );
if( !tmp.can_move_to( p ) ) {
const tripoint local_pos = random_entry_removed( locations );
const tripoint_abs_ms abs_pos = get_map().getglobal( local_pos );
if( !tmp.can_move_to( local_pos ) ) {
continue; // target can not contain the monster
}
if( group.horde ) {
// Give monster a random point near horde's expected destination
const tripoint rand_dest = horde_target +
point( rng( 0, SEEX ), rng( 0, SEEY ) );
const int turns = rl_dist( p, rand_dest ) + group.interest;
const point_rel_ms pos_in_sm( rng( 0, SEEX ), rng( 0, SEEY ) );
const tripoint_abs_ms rand_dest = project_to<coords::ms>( horde_target ) + pos_in_sm;
const int turns = rl_dist( abs_pos, rand_dest ) + group.interest;
tmp.wander_to( rand_dest, turns );
add_msg_debug( debugmode::DF_MAP, "%s targeting %d,%d,%d", tmp.disp_name(),
tmp.wander_pos.x, tmp.wander_pos.y, tmp.wander_pos.z );
add_msg_debug( debugmode::DF_MAP, "%s targeting %s", tmp.disp_name(),
tmp.wander_pos.to_string_writable() );
}

monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), local_pos );
if( placed ) {
placed->on_load();
}
Expand All @@ -7485,15 +7485,14 @@ void map::spawn_monsters_submap_group( const tripoint &gp, mongroup &group, bool

void map::spawn_monsters_submap( const tripoint &gp, bool ignore_sight )
{
// Load unloaded monsters
// TODO: fix point types
overmap_buffer.spawn_monster( tripoint_abs_sm( gp + abs_sub.xy() ) );

const tripoint_abs_sm submap_pos( gp + abs_sub.xy() );
// Load unloaded monsters
overmap_buffer.spawn_monster( submap_pos );
// Only spawn new monsters after existing monsters are loaded.
// TODO: fix point types
auto groups = overmap_buffer.groups_at( tripoint_abs_sm( gp + abs_sub.xy() ) );
auto groups = overmap_buffer.groups_at( submap_pos );
for( auto &mgp : groups ) {
spawn_monsters_submap_group( gp, *mgp, ignore_sight );
spawn_monsters_submap_group( gp, *mgp, submap_pos, ignore_sight );
}

submap *const current_submap = get_submap_at_grid( gp );
Expand Down
3 changes: 2 additions & 1 deletion src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -1700,7 +1700,8 @@ class map
// Helper #1 - spawns monsters on one submap
void spawn_monsters_submap( const tripoint &gp, bool ignore_sight );
// Helper #2 - spawns monsters on one submap and from one group on this submap
void spawn_monsters_submap_group( const tripoint &gp, mongroup &group, bool ignore_sight );
void spawn_monsters_submap_group( const tripoint &gp, mongroup &group,
const tripoint_abs_sm &submap_pos, bool ignore_sight );

protected:
void saven( const tripoint &grid );
Expand Down
7 changes: 4 additions & 3 deletions src/mattack_actors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ std::unique_ptr<mattack_actor> leap_actor::clone() const

bool leap_actor::call( monster &z ) const
{
if( !z.can_act() || !z.move_effects( false ) ) {
if( !z.has_dest() || !z.can_act() || !z.move_effects( false ) ) {
return false;
}

std::vector<tripoint> options;
tripoint target = z.move_target();
float best_float = trigdist ? trig_dist( z.pos(), target ) : square_dist( z.pos(), target );
const tripoint_abs_ms target_abs = z.get_dest();
const float best_float = rl_dist( z.get_location(), target_abs );
if( best_float < min_consider_range || best_float > max_consider_range ) {
return false;
}
Expand All @@ -84,6 +84,7 @@ bool leap_actor::call( monster &z ) const
return false;
}
map &here = get_map();
const tripoint target = here.getlocal( target_abs );
std::multimap<int, tripoint> candidates;
for( const tripoint &candidate : here.points_in_radius( z.pos(), max_range ) ) {
if( candidate == z.pos() ) {
Expand Down
40 changes: 24 additions & 16 deletions src/monattack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,7 @@ void mattack::smash_specific( monster *z, Creature *target )
if( z->has_flag( MF_RIDEABLE_MECH ) ) {
z->use_mech_power( -5 );
}
z->set_goal( target->pos() );
z->set_dest( target->get_location() );
smash( z );
}

Expand Down Expand Up @@ -1499,24 +1499,32 @@ bool mattack::grow_vine( monster *z )
if( monster *const vine = g->place_critter_around( mon_creeper_vine, z->pos(), 1 ) ) {
vine->make_ally( *z );
// Store position of parent hub in vine goal point.
vine->set_goal( z->pos() );
vine->set_dest( z->get_location() );
}
}

return true;
}

// Return true if the creeper hub that spawned the vine is still there
static bool has_vine_parent( monster *z )
{
if( !z->has_dest() || !get_map().inbounds( z->get_dest() ) ) {
return false;
}
const monster *parent = get_creature_tracker().creature_at<monster>( z->get_dest() );
return parent != nullptr && parent->type->id == mon_creeper_hub;
}

bool mattack::vine( monster *z )
{
int vine_neighbors = 0;
map &here = get_map();
bool parent_out_of_range = !here.inbounds( z->move_target() );
creature_tracker &creatures = get_creature_tracker();
monster *parent = creatures.creature_at<monster>( z->move_target() );
if( !parent_out_of_range && ( parent == nullptr || parent->type->id != mon_creeper_hub ) ) {
if( !has_vine_parent( z ) ) {
// TODO: Should probably die instead.
return true;
}
int vine_neighbors = 0;
map &here = get_map();
creature_tracker &creatures = get_creature_tracker();
z->moves -= 100;
for( const tripoint &dest : here.points_in_radius( z->pos(), 1 ) ) {
Creature *critter = creatures.creature_at( dest );
Expand Down Expand Up @@ -1548,7 +1556,7 @@ bool mattack::vine( monster *z )
}
}
// Calculate distance from nearest hub
int dist_from_hub = rl_dist( z->pos(), z->move_target() );
int dist_from_hub = rl_dist( z->get_location(), z->get_dest() );
if( dist_from_hub > 20 || vine_neighbors > 5 || one_in( 7 - vine_neighbors ) ||
!one_in( dist_from_hub ) ) {
return true;
Expand All @@ -1557,7 +1565,7 @@ bool mattack::vine( monster *z )
vine->make_ally( *z );
vine->reset_special( "VINE" );
// Store position of parent hub in vine goal point.
vine->set_goal( z->move_target() );
vine->set_dest( z->get_dest() );
}

return true;
Expand Down Expand Up @@ -2390,9 +2398,9 @@ bool mattack::callblobs( monster *z )
// if we want to deal with NPCS and friendly monsters as well.
// The strategy is to send about 1/3 of the available blobs after the player,
// and keep the rest near the brain blob for protection.
const tripoint enemy = get_player_character().pos();
const tripoint_abs_ms enemy = get_player_character().get_location();
const std::vector<tripoint_abs_ms> nearby_points = closest_points_first( z->get_location(), 3 );
std::list<monster *> allies;
std::vector<tripoint> nearby_points = closest_points_first( z->pos(), 3 );
for( monster &candidate : g->all_monsters() ) {
if( candidate.type->in_species( species_SLIME ) && candidate.type->id != mon_blob_brain ) {
// Just give the allies consistent assignments.
Expand All @@ -2405,7 +2413,7 @@ bool mattack::callblobs( monster *z )
int guards = 0;
for( std::list<monster *>::iterator ally = allies.begin();
ally != allies.end(); ++ally, ++guards ) {
tripoint post = enemy;
tripoint_abs_ms post = enemy;
if( guards < num_guards ) {
// Each guard is assigned a spot in the nearby_points vector based on their order.
int assigned_spot = ( nearby_points.size() * guards ) / num_guards;
Expand All @@ -2424,8 +2432,8 @@ bool mattack::callblobs( monster *z )
bool mattack::jackson( monster *z )
{
// Jackson draws nearby zombies into the dance.
const std::vector<tripoint_abs_ms> nearby_points = closest_points_first( z->get_location(), 3 );
std::list<monster *> allies;
std::vector<tripoint> nearby_points = closest_points_first( z->pos(), 3 );
for( monster &candidate : g->all_monsters() ) {
if( candidate.type->in_species( species_ZOMBIE ) && candidate.type->id != mon_zombie_jackson ) {
// Just give the allies consistent assignments.
Expand All @@ -2437,7 +2445,7 @@ bool mattack::jackson( monster *z )
int dancers = 0;
bool converted = false;
for( auto ally = allies.begin(); ally != allies.end(); ++ally, ++dancers ) {
tripoint post = z->pos();
tripoint_abs_ms post = z->get_location();
if( dancers < num_dancers ) {
// Each dancer is assigned a spot in the nearby_points vector based on their order.
int assigned_spot = ( nearby_points.size() * dancers ) / num_dancers;
Expand Down Expand Up @@ -3062,7 +3070,7 @@ bool mattack::nurse_operate( monster *z )
return false;
}
// Should designate target as the attack_target
z->set_dest( target->pos() );
z->set_dest( target->get_location() );

// Check if target is already grabbed by something else
if( target->has_effect( effect_grabbed ) ) {
Expand Down
Loading

0 comments on commit e59ff40

Please sign in to comment.