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

Don't do map processing of critters off the map #79336

Merged
merged 10 commits into from
Jan 27, 2025
2 changes: 1 addition & 1 deletion src/avatar_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ bool avatar_action::move( avatar &you, map &m, const tripoint_rel_ms &d )
}
you.melee_attack( critter, true );
if( critter.is_hallucination() ) {
critter.die( &you );
critter.die( &m, &you );
}
g->draw_hit_mon( dest_loc, critter, critter.is_dead() );
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/ballistics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ void projectile_attack( dealt_projectile_attack &attack, const projectile &proj_
origin->check_avoid_friendly_fire() ) {
continue;
}
critter->deal_projectile_attack( null_source ? nullptr : origin, attack, cur_missed_by,
critter->deal_projectile_attack( &here, null_source ? nullptr : origin, attack, cur_missed_by,
print_messages, wp_attack );

if( critter->is_npc() ) {
Expand Down
46 changes: 28 additions & 18 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1802,6 +1802,8 @@ bool Character::is_mounted() const

void Character::forced_dismount()
{
map &here = get_map();

remove_effect( effect_riding );
remove_effect( effect_mech_recon_vision );
bool mech = false;
Expand Down Expand Up @@ -1879,7 +1881,7 @@ void Character::forced_dismount()
pgettext( "memorial_male", "Fell off a mount." ),
pgettext( "memorial_female", "Fell off a mount." ) );
}
check_dead_state();
check_dead_state( &here );
}
add_effect( effect_downed, 5_turns, true );
} else {
Expand Down Expand Up @@ -2378,6 +2380,7 @@ void Character::expose_to_disease( const diseasetype_id &dis_type )

void Character::process_turn()
{
map &here = get_map();
// Has to happen before reset_stats
clear_miss_reasons();
migrate_items_to_storage( false );
Expand Down Expand Up @@ -2405,7 +2408,7 @@ void Character::process_turn()
if( leak_level_dirty ) {
calculate_leak_level();
}
process_items();
process_items( &here );
leak_items();
// Didn't just pick something up
last_item = itype_id::NULL_ID();
Expand Down Expand Up @@ -3666,7 +3669,7 @@ void Character::normalize()
}

// Actual player death is mostly handled in game::is_game_over
void Character::die( Creature *nkiller )
void Character::die( map *, Creature *nkiller )
{
g->set_critter_died();
set_all_parts_hp_cur( 0 );
Expand Down Expand Up @@ -8091,10 +8094,10 @@ std::string Character::weapname_ammo() const
}
}

void Character::on_hit( Creature *source, bodypart_id bp_hit,
void Character::on_hit( map *here, Creature *source, bodypart_id bp_hit,
float /*difficulty*/, dealt_projectile_attack const *const proj )
{
check_dead_state();
check_dead_state( here );
if( source == nullptr || proj != nullptr ) {
return;
}
Expand Down Expand Up @@ -8179,8 +8182,7 @@ void Character::on_hit( Creature *source, bodypart_id bp_hit,
}
}

map &here = get_map();
const optional_vpart_position veh_part = here.veh_at( pos_bub() );
const optional_vpart_position veh_part = here->veh_at( pos_abs() );
bool in_skater_vehicle = in_vehicle && veh_part.part_with_feature( "SEAT_REQUIRES_BALANCE", false );

if( ( worn_with_flag( flag_REQUIRES_BALANCE ) || in_skater_vehicle ) && !is_on_ground() ) {
Expand Down Expand Up @@ -10438,7 +10440,7 @@ std::vector<run_cost_effect> Character::run_cost_effects( float &movecost ) cons
return effects;
}

void Character::place_corpse()
void Character::place_corpse( map *here )
{
//If the character/NPC is on a distant mission, don't drop their their gear when they die since they still have a local pos
if( !death_drops ) {
Expand All @@ -10447,7 +10449,6 @@ void Character::place_corpse()
std::vector<item *> tmp = inv_dump();
item body = item::make_corpse( mtype_id::NULL_ID(), calendar::turn, get_name() );
body.set_item_temperature( units::from_celsius( 37 ) );
map &here = get_map();
for( item *itm : tmp ) {
body.force_insert_item( *itm, pocket_type::CONTAINER );
}
Expand All @@ -10465,7 +10466,7 @@ void Character::place_corpse()
}
}

here.add_item_or_charges( pos_bub(), body );
here->add_item_or_charges( here->get_bub( pos_abs() ), body );
}

void Character::place_corpse( const tripoint_abs_omt &om_target )
Expand Down Expand Up @@ -11160,6 +11161,15 @@ void Character::gravity_check()
}
}

void Character::gravity_check( map *here )
{
const tripoint_bub_ms pos = here->get_bub( pos_abs() );
if( here->is_open_air( pos ) && !in_vehicle && !has_effect_with_flag( json_flag_GLIDING ) &&
here->try_fall( pos, this ) ) {
here->update_visibility_cache( pos.z() );
}
}

void Character::stagger()
{
map &here = get_map();
Expand Down Expand Up @@ -12739,6 +12749,7 @@ bool Character::can_fly()
// FIXME: Relies on hardcoded bash damage type
void Character::knock_back_to( const tripoint_bub_ms &to )
{
map &here = get_map();
if( to == pos_bub() ) {
return;
}
Expand All @@ -12758,7 +12769,7 @@ void Character::knock_back_to( const tripoint_bub_ms &to )
critter->apply_damage( this, bodypart_id( "torso" ), ( str_max - 6 ) / 4 );
critter->add_effect( effect_stunned, 1_turns );
}
critter->check_dead_state();
critter->check_dead_state( &here );

add_msg_player_or_npc( _( "You bounce off a %s!" ), _( "<npcname> bounces off a %s!" ),
critter->name() );
Expand All @@ -12772,11 +12783,10 @@ void Character::knock_back_to( const tripoint_bub_ms &to )
np->deal_damage( this, bodypart_id( "torso" ), damage_instance( damage_bash, 3 ) );
add_msg_player_or_npc( _( "You bounce off %s!" ), _( "<npcname> bounces off %s!" ),
np->get_name() );
np->check_dead_state();
np->check_dead_state( &here );
return;
}

map &here = get_map();
// If we're still in the function at this point, we're actually moving a tile!
if( here.has_flag( ter_furn_flag::TFLAG_LIQUID, to ) &&
here.has_flag( ter_furn_flag::TFLAG_DEEP_WATER, to ) ) {
Expand Down Expand Up @@ -12849,10 +12859,10 @@ void Character::leak_items()
}
}

void Character::process_items()
void Character::process_items( map *here )
{
if( weapon.process( get_map(), this, pos_bub() ) ) {
weapon.spill_contents( pos_bub() );
if( weapon.process( *here, this, here->get_bub( pos_abs() ) ) ) {
weapon.spill_contents( here, here->get_bub( pos_abs() ) );
remove_weapon();
}

Expand All @@ -12861,8 +12871,8 @@ void Character::process_items()
if( !it ) {
continue;
}
if( it->process( get_map(), this, pos_bub() ) ) {
it->spill_contents( pos_bub() );
if( it->process( *here, this, here->get_bub( pos_abs() ) ) ) {
it->spill_contents( here, here->get_bub( pos_abs() ) );
removed_items.push_back( it );
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,7 @@ class Character : public Creature, public visitable
public:

void gravity_check() override;
void gravity_check( map *here ) override;
void stagger();

void mod_stat( const std::string &stat, float modifier ) override;
Expand Down Expand Up @@ -1271,7 +1272,7 @@ class Character : public Creature, public visitable

// any side effects that might happen when the Character is hit
/** Handles special defenses from melee attack that hit us (source can be null) */
void on_hit( Creature *source, bodypart_id bp_hit,
void on_hit( map *here, Creature *source, bodypart_id bp_hit,
float difficulty = INT_MIN, dealt_projectile_attack const *proj = nullptr ) override;
// any side effects that might happen when the Character hits a Creature
void did_hit( Creature &target );
Expand Down Expand Up @@ -1891,7 +1892,7 @@ class Character : public Creature, public visitable
virtual item::reload_option select_ammo( const item_location &base, bool prompt = false,
bool empty = true ) = 0;

void process_items();
void process_items( map *here );
void leak_items();
/** Search surrounding squares for traps (and maybe other things in the future). */
void search_surroundings();
Expand Down Expand Up @@ -2569,7 +2570,7 @@ class Character : public Creature, public visitable
* Should only be called through player::normalize(), not on it's own!
*/
void normalize() override;
void die( Creature *nkiller ) override;
void die( map *here, Creature *nkiller ) override;
virtual void prevent_death();

std::string get_name() const override;
Expand Down Expand Up @@ -3279,7 +3280,7 @@ class Character : public Creature, public visitable
float speed_rating() const override;

// Put corpse+inventory on map at the place where this is.
void place_corpse();
void place_corpse( map *here );
// Put corpse+inventory on defined om tile
void place_corpse( const tripoint_abs_omt &om_target );

Expand Down
2 changes: 1 addition & 1 deletion src/computer_session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ void computer_session::action_terminate()
t_south == ter_t_concrete_wall ) ||
( t_south == ter_t_reinforced_glass &&
t_north == ter_t_concrete_wall ) ) {
mon->die( &player_character );
mon->die( &here, &player_character );
}
}
query_any( _( "Subjects terminated. Press any key…" ) );
Expand Down
38 changes: 29 additions & 9 deletions src/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,16 @@ void Creature::setpos( const tripoint_bub_ms &p, bool check_gravity/* = true*/ )
}
}

void Creature::setpos( map *here, const tripoint_bub_ms &p, bool check_gravity/* = true*/ )
{
const tripoint_abs_ms old_loc = pos_abs();
set_pos_abs_only( here->get_abs( p ) );
on_move( old_loc );
if( check_gravity ) {
gravity_check( here );
}
}

bool Creature::will_be_cramped_in_vehicle_tile( const tripoint_abs_ms &loc ) const
{
map &here = get_map();
Expand Down Expand Up @@ -313,6 +323,10 @@ void Creature::gravity_check()
{
}

void Creature::gravity_check( map * )
{
}

void Creature::normalize()
{
}
Expand Down Expand Up @@ -914,6 +928,8 @@ void Creature::deal_melee_hit( Creature *source, int hit_spread, bool critical_h
damage_instance dam, dealt_damage_instance &dealt_dam,
const weakpoint_attack &attack, const bodypart_id *bp )
{
map &here = get_map();

if( source == nullptr || source->is_hallucination() ) {
dealt_dam.bp_hit = anatomy_human_anatomy->random_body_part();
return;
Expand Down Expand Up @@ -942,7 +958,7 @@ void Creature::deal_melee_hit( Creature *source, int hit_spread, bool critical_h
attack_copy.is_crit = critical_hit;
attack_copy.type = weakpoint_attack::type_of_melee_attack( d );

on_hit( source, bp_hit ); // trigger on-gethit events
on_hit( &here, source, bp_hit ); // trigger on-gethit events
dam.onhit_effects( source, this ); // on-hit effects for inflicted damage types
dealt_dam = deal_damage( source, bp_hit, d, attack_copy );
dealt_dam.bp_hit = bp_hit;
Expand Down Expand Up @@ -1270,7 +1286,7 @@ void Creature::print_proj_avoid_msg( Creature *source, viewer &player_view ) con
* @param attack A structure describing the attack and its results.
* @param print_messages enables message printing by default.
*/
void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack &attack,
void Creature::deal_projectile_attack( map *here, Creature *source, dealt_projectile_attack &attack,
const double &missed_by, bool print_messages,
const weakpoint_attack &wp_attack )
{
Expand All @@ -1285,7 +1301,7 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack
if( mons && mons->mounted_player ) {
if( !mons->has_flag( mon_flag_MECH_DEFENSIVE ) &&
one_in( std::max( 2, mons->get_size() - mons->mounted_player->get_size() ) ) ) {
mons->mounted_player->deal_projectile_attack( source, attack, missed_by, print_messages,
mons->mounted_player->deal_projectile_attack( here, source, attack, missed_by, print_messages,
wp_attack );
return;
}
Expand Down Expand Up @@ -1367,7 +1383,7 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack
messaging_projectile_attack( source, hit_selection, total_dam );
}

check_dead_state();
check_dead_state( here );
attack.last_hit_critter = this;
attack.missed_by = goodhit;
attack.headshot = hit_selection.is_headshot;
Expand Down Expand Up @@ -2040,6 +2056,8 @@ int Creature::get_effect_int( const efftype_id &eff_id, const bodypart_id &bp )
}
void Creature::process_effects()
{
map &here = get_map();

// id's and body_part's of all effects to be removed. If we ever get player or
// monster specific removals these will need to be moved down to that level and then
// passed in to this function.
Expand Down Expand Up @@ -2079,7 +2097,7 @@ void Creature::process_effects()
cata::event sent( e.death_event(), calendar::turn, std::move( event_data ) );
get_event_bus().send( sent );
}
die( e.get_source().resolve_creature() );
die( &here, e.get_source().resolve_creature() );
}
}
}
Expand Down Expand Up @@ -2228,7 +2246,7 @@ void Creature::decrement_summon_timer()
return;
}
if( lifespan_end.value() <= calendar::turn ) {
die( nullptr );
die( &get_map(), nullptr );
}
}

Expand Down Expand Up @@ -3296,10 +3314,10 @@ void Creature::process_damage_over_time()
}
}

void Creature::check_dead_state()
void Creature::check_dead_state( map *here )
{
if( is_dead_state() ) {
die( killer );
die( here, killer );
}
}

Expand Down Expand Up @@ -3345,11 +3363,13 @@ std::string Creature::replace_with_npc_name( std::string input ) const

void Creature::knock_back_from( const tripoint_bub_ms &p )
{
map &here = get_map();

if( p == pos_bub() ) {
return; // No effect
}
if( is_hallucination() ) {
die( nullptr );
die( &here, nullptr );
return;
}
tripoint_bub_ms to = pos_bub();
Expand Down
Loading
Loading