Skip to content

Commit

Permalink
fix: Rework spell studying and notify (#5524)
Browse files Browse the repository at this point in the history
* Rework spell studying and notify

Studying a spell now tracks level gained and sends appropriate level up event on level up.

Updates notify event such that it will grant new spell if dependent spell level is equal to or greater than target level.

* Add documentation

* style(autofix.ci): automated formatting

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
KheirFerrum and autofix-ci[bot] authored Oct 6, 2024
1 parent daa6242 commit 5b1f340
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 17 deletions.
24 changes: 20 additions & 4 deletions doc/src/content/docs/en/mod/json/reference/creatures/magic.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ In `data/mods/Magiclysm` there is a template spell, copied here for your perusal
"sound_ambient": true, // whether or not this is treated as an ambient sound or not
"sound_id": "misc", // the sound id
"sound_variant": "shockwave" // the sound variant
"learn_spells": { "acid_resistance_greater": 15 } // You learn the specified spell once your level in this spell is greater than or equal to the number shown.
}
```

Expand Down Expand Up @@ -265,10 +266,11 @@ that use a negative 'recover' effect to cause pain or stamina damage. For exampl

### Learning Spells

There are two ways of granting spells that is implemented: Mutating can grant a spell with the
"spells_learned" field which also lets you specify the level granted. Otherwise you can learn a
spell from an item through a use_action, which is also the only way to train a spell other than
using it. Examples of both are shown below:
There are three ways of granting spells that are implemented: Mutating can grant a spell with the
"spells_learned" field which also lets you specify the level granted. Certain spells can also teach
you spells once they reach an appropriate level via the "learn_spells" variable. Finally, You can
learn a spell from an item through a use_action, which is also the only way to train a spell other
than using it. Examples of all three are shown below:

```json
{
Expand All @@ -287,6 +289,20 @@ using it. Examples of both are shown below:
},
```

For the below example you will learn the spell Greater Acid Resistance once Acid Resistance reaches
level 15

```json
{
"id": "acid_resistance",
"type": "SPELL",
"name": { "str": "Acid Resistance" },
"description": "Protects the user from acid.",
...
"learn_spells": { "acid_resistance_greater": 15 }
}
```

You can study this spellbook for a rate of ~1 experience per turn depending on intelligence,
spellcraft, and focus.

Expand Down
31 changes: 22 additions & 9 deletions src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4672,27 +4672,40 @@ void activity_handlers::study_spell_do_turn( player_activity *act, player *p )
}
if( act->get_str_value( 1 ) == "study" ) {
spell &studying = p->magic->get_spell( spell_id( act->name ) );
if( act->get_str_value( 0 ) == "gain_level" ) {
if( studying.get_level() < act->get_value( 1 ) ) {
act->moves_left = 1000000;
} else {
act->moves_left = 0;
}
}
const int old_level = studying.get_level();
const int xp = roll_remainder( studying.exp_modifier( *p ) / to_turns<float>( 6_seconds ) );

act->values[0] += xp;
studying.gain_exp( xp );
// Every time we use get_level the level is recalculated, this is suboptimal, so we remember it here.
const int new_level = studying.get_level();

if( new_level > old_level ) {
act->values[1] += new_level - old_level;
g->events().send<event_type::player_levels_spell>( studying.id(), new_level );
if( act->get_str_value( 0 ) == "gain_level" ) {
act->moves_left = 0;
}
} else if( act->get_str_value( 0 ) == "gain_level" ) {
act->moves_left = 1000000;
}
}
}

void activity_handlers::study_spell_finish( player_activity *act, player *p )
{
act->set_to_null();
const int total_exp_gained = act->get_value( 0 );
const int total_levels_gained = act->get_value( 1 );

if( act->get_str_value( 1 ) == "study" ) {
p->add_msg_if_player( m_good, _( "You gained %i experience from your study session." ),
total_exp_gained );
std::string level_string;
if( total_levels_gained > 0 ) {
level_string = string_format( vgettext( " and %d level", " and %d levels", total_levels_gained ),
total_levels_gained );
}
p->add_msg_if_player( m_good, _( "You gained %i experience%s from your study session." ),
total_exp_gained, level_string );
const spell &sp = p->magic->get_spell( spell_id( act->name ) );
p->practice( sp.skill(), total_exp_gained, sp.get_difficulty() );
} else if( act->get_str_value( 1 ) == "learn" && act->values[2] == 0 ) {
Expand Down
2 changes: 1 addition & 1 deletion src/iuse_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2576,7 +2576,7 @@ int learn_spell_actor::use( player &p, item &, bool, const tripoint & ) const
if( study_spell->moves_total == 10100 ) {
study_spell->str_values[0] = "gain_level";
study_spell->values[0] = 0; // reserved for xp
study_spell->values[1] = p.magic->get_spell( spell_id( spells[action] ) ).get_level() + 1;
study_spell->values[1] = 0; // reserved for levels
}
study_spell->name = spells[action];
p.assign_activity( std::move( study_spell ), false );
Expand Down
5 changes: 2 additions & 3 deletions src/magic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2159,13 +2159,12 @@ void spell_events::notify( const cata::event &e )
it != spell_cast.learn_spells.end(); ++it ) {
std::string learn_spell_id = it->first;
int learn_at_level = it->second;
if( learn_at_level == slvl ) {
if( slvl >= learn_at_level && !g->u.magic->knows_spell( learn_spell_id ) ) {
g->u.magic->learn_spell( learn_spell_id, g->u );
spell_type spell_learned = spell_factory.obj( spell_id( learn_spell_id ) );
add_msg(
_( "Your experience and knowledge in creating and manipulating magical energies to cast %s have opened your eyes to new possibilities, you can now cast %s." ),
spell_cast.name,
spell_learned.name );
spell_cast.name, spell_learned.name );
}
}
break;
Expand Down

0 comments on commit 5b1f340

Please sign in to comment.