Skip to content

Commit

Permalink
Fix spells crashing when they can't find a target. (#36507)
Browse files Browse the repository at this point in the history
* Enable translation

* Change spell::random_valid_target to return an optional value.

This handles the case when no target point can be found.

Changed all callers accordingly to ignore the action when no target has been found.

* Fix wrong word used to describe what's wrong. Remember: spell != skill. They sound similar, but they are not exactly the same. Thanks for the reminder.

Co-Authored-By: Anton Burmistrov <Night_Pryanik@mail.ru>
  • Loading branch information
2 people authored and ZhilkinSerg committed Dec 28, 2019
1 parent c886711 commit 311b795
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 19 deletions.
9 changes: 7 additions & 2 deletions src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4440,14 +4440,19 @@ void activity_handlers::spellcasting_finish( player_activity *act, player *p )
}
} while( !target_is_valid );
} else if( casting.has_flag( RANDOM_TARGET ) ) {
target = casting.random_valid_target( *p, p->pos() );
const cata::optional<tripoint> target_ = casting.random_valid_target( *p, p->pos() );
if( !target_ ) {
p->add_msg_if_player( m_bad, _( "Your spell can't find a suitable target." ) );
return;
}
target = *target_;
}

// no turning back now. it's all said and done.
bool success = no_fail || rng_float( 0.0f, 1.0f ) >= casting.spell_fail( *p );
int exp_gained = casting.casting_exp( *p );
if( !success ) {
p->add_msg_if_player( m_bad, "You lose your concentration!" );
p->add_msg_if_player( m_bad, _( "You lose your concentration!" ) );
if( !casting.is_max_level() && level_override == -1 ) {
// still get some experience for trying
casting.gain_exp( exp_gained / 5 );
Expand Down
30 changes: 14 additions & 16 deletions src/magic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1092,10 +1092,9 @@ void spell::cast_all_effects( Creature &source, const tripoint &target ) const
source.add_msg_if_player( sp.message() );

if( sp.has_flag( RANDOM_TARGET ) ) {
if( _self ) {
sp.cast_all_effects( source, sp.random_valid_target( source, source.pos() ) );
} else {
sp.cast_all_effects( source, sp.random_valid_target( source, target ) );
if( const cata::optional<tripoint> new_target = sp.random_valid_target( source,
_self ? source.pos() : target ) ) {
sp.cast_all_effects( source, *new_target );
}
} else {
if( _self ) {
Expand All @@ -1111,10 +1110,9 @@ void spell::cast_all_effects( Creature &source, const tripoint &target ) const
for( const fake_spell &extra_spell : type->additional_spells ) {
spell sp = extra_spell.get_spell( get_level() );
if( sp.has_flag( RANDOM_TARGET ) ) {
if( extra_spell.self ) {
sp.cast_all_effects( source, sp.random_valid_target( source, source.pos() ) );
} else {
sp.cast_all_effects( source, sp.random_valid_target( source, target ) );
if( const cata::optional<tripoint> new_target = sp.random_valid_target( source,
extra_spell.self ? source.pos() : target ) ) {
sp.cast_all_effects( source, *new_target );
}
} else {
if( extra_spell.self ) {
Expand All @@ -1127,20 +1125,20 @@ void spell::cast_all_effects( Creature &source, const tripoint &target ) const
}
}

tripoint spell::random_valid_target( const Creature &caster, const tripoint &caster_pos ) const
cata::optional<tripoint> spell::random_valid_target( const Creature &caster,
const tripoint &caster_pos ) const
{
const std::set<tripoint> area = spell_effect::spell_effect_blast( *this, caster_pos, caster_pos,
range(), false );
std::set<tripoint> valid_area;
for( const tripoint &target : area ) {
for( const tripoint &target : spell_effect::spell_effect_blast( *this, caster_pos, caster_pos,
range(), false ) ) {
if( is_valid_target( caster, target ) ) {
valid_area.emplace( target );
}
}
size_t rand_i = rng( 0, valid_area.size() - 1 );
auto iter = valid_area.begin();
std::advance( iter, rand_i );
return *iter;
if( valid_area.empty() ) {
return cata::nullopt;
}
return random_entry( valid_area );
}

// player
Expand Down
3 changes: 2 additions & 1 deletion src/magic.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,8 @@ class spell
bool is_valid_effect_target( valid_target t ) const;

// picks a random valid tripoint from @area
tripoint random_valid_target( const Creature &caster, const tripoint &caster_pos ) const;
cata::optional<tripoint> random_valid_target( const Creature &caster,
const tripoint &caster_pos ) const;
};

class known_magic
Expand Down

0 comments on commit 311b795

Please sign in to comment.