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

Magic bionics #39940

Merged
merged 3 commits into from
May 3, 2020
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
2 changes: 1 addition & 1 deletion data/mods/Magiclysm/itemgroups/spellbooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
[ "spell_scroll_obfuscated_body", 10 ],
[ "spell_scroll_lava_bomb", 5 ],
[ "spell_scroll_druidic_healing", 20 ],
[ "spell_scroll_overcharge_eyes", 50 ]
[ "bio_sneeze_beam", 50 ]
]
},
{
Expand Down
28 changes: 28 additions & 0 deletions data/mods/Magiclysm/items/bionics.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,33 @@
"price": 450000,
"weight": "500 g",
"difficulty": 8
},
{
"type": "enchantment",
"id": "ench_bio_sneeze_beam",
"values": [ { "value": "MAX_MANA", "add": 500 } ]
},
{
"id": "bio_sneeze_beam",
"copy-from": "bionic_general",
"type": "BIONIC_ITEM",
"name": { "str": "Crystallized Mana Nose Replacement" },
"description": "A large gem made with crystallized mana and some other stabilizing metals. Comes with a specially designed power pack (installed into the skull) that does not interfere with your mana ley lines. WARNING: for Technomancer use only. By using this spell you are waiving all liability of Frikken Laser Beams Inc. and its subsidiaries.",
"price": 450000,
"weight": "750 g",
"volume": "177 ml",
"difficulty": 8
},
{
"id": "bio_sneeze_beam",
"type": "bionic",
"name": { "str": "Crystallized Mana Nose Replacement" },
"description": "A large gem made with crystallized mana and some other stabilizing metals. Comes with a specially designed power pack (installed into the skull) that does not interfere with your mana ley lines. WARNING: for Technomancer use only. By using this spell you are waiving all liability of Frikken Laser Beams Inc. and its subsidiaries.",
"occupied_bodyparts": [ [ "HEAD", 10 ], [ "MOUTH", 1 ] ],
"capacity": "500 kJ",
"learned_spells": { "overcharge_eyes": 4 },
"canceled_mutations": [ "EARTHSHAPER" ],
"enchantments": [ "ench_bio_sneeze_beam" ],
"flags": [ "BIONIC_SHOCKPROOF" ]
}
]
2 changes: 1 addition & 1 deletion data/mods/Magiclysm/items/spell_scrolls.json
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@
"copy-from": "spell_scroll",
"id": "spell_scroll_overcharge_eyes",
"//": "Technomancer spell",
"name": { "str": "Scroll of Overcharge", "str_pl": "Scrolls of Overcharge" },
"name": { "str": "Scroll of Optical Sneeze Beam", "str_pl": "Scrolls of Optical Sneeze Beam" },
"description": "You overcharge your internal batteries to send a semi-directed beam from your face.",
"use_action": { "type": "learn_spell", "spells": [ "overcharge_eyes" ] }
},
Expand Down
1 change: 1 addition & 0 deletions doc/JSON_INFO.md
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ This section describes each json file and their contents. Each json has their ow
| power_gen_emission | (_optional_) `emit_id` of the field emitted by this bionic when it produces energy. Emit_ids are defined in `emit.json`.
| stat_bonus | (_optional_) List of passive stat bonus. Stat are designated as follow: "DEX", "INT", "STR", "PER".
| enchantments | (_optional_) List of enchantments applied by this CBM (see MAGIC.md for instructions on enchantment. NB: enchantments are not necessarily magic.)
| learned_spells | (_optional_) Map of {spell:level} you gain when installing this CBM, and lose when you uninstall this CBM. Spell classes are automatically gained.

```C++
{
Expand Down
37 changes: 37 additions & 0 deletions src/bionics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2425,6 +2425,28 @@ void Character::add_bionic( const bionic_id &b )
add_bionic( inc_bid );
}

for( const std::pair<spell_id, int> spell_pair : b->learned_spells ) {
const spell_id learned_spell = spell_pair.first;
if( learned_spell->spell_class != trait_id( "NONE" ) ) {
const trait_id spell_class = learned_spell->spell_class;
// spells you learn from a bionic overwrite the opposite spell class.
// for best UX, include those spell classes in "canceled_mutations"
if( !has_trait( spell_class ) ) {
set_mutation( spell_class );
on_mutation_gain( spell_class );
add_msg_if_player( spell_class->desc() );
}
}
if( !magic.knows_spell( learned_spell ) ) {
magic.learn_spell( learned_spell, *this, true );
}
spell &known_spell = magic.get_spell( learned_spell );
// spells you learn from installing a bionic upgrade spells you know if they are the same
if( known_spell.get_level() < spell_pair.second ) {
known_spell.set_level( spell_pair.second );
}
}

reset_encumbrance();
recalc_sight_limits();
if( !b->enchantments.empty() ) {
Expand All @@ -2435,6 +2457,8 @@ void Character::add_bionic( const bionic_id &b )
void Character::remove_bionic( const bionic_id &b )
{
bionic_collection new_my_bionics;
// any spells you should not forget due to still having a bionic installed that has it.
std::set<spell_id> cbm_spells;
for( bionic &i : *my_bionics ) {
if( b == i.id ) {
continue;
Expand All @@ -2445,8 +2469,20 @@ void Character::remove_bionic( const bionic_id &b )
continue;
}

for( const std::pair<spell_id, int> &spell_pair : i.id->learned_spells ) {
cbm_spells.emplace( spell_pair.first );
}

new_my_bionics.push_back( bionic( i.id, i.invlet ) );
}

// any spells you learn from installing a bionic you forget.
for( const std::pair<spell_id, int> &spell_pair : b->learned_spells ) {
if( cbm_spells.count( spell_pair.first ) == 0 ) {
magic.forget_spell( spell_pair.first );
}
}

*my_bionics = new_my_bionics;
reset_encumbrance();
recalc_sight_limits();
Expand Down Expand Up @@ -2576,6 +2612,7 @@ void load_bionic( const JsonObject &jsobj )
assign( jsobj, "coverage_power_gen_penalty", new_bionic.coverage_power_gen_penalty );
assign( jsobj, "is_remote_fueled", new_bionic.is_remote_fueled );

assign( jsobj, "learned_spells", new_bionic.learned_spells );
jsobj.read( "canceled_mutations", new_bionic.canceled_mutations );
jsobj.read( "included_bionics", new_bionic.included_bionics );
jsobj.read( "included", new_bionic.included );
Expand Down
6 changes: 6 additions & 0 deletions src/bionics.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ struct bionic_data {
* E.g. enhanced optic bionic may cancel HYPEROPIC trait.
*/
std::vector<trait_id> canceled_mutations;

/**
* The spells you learn when you install this bionic, and what level you learn them at.
*/
std::map<spell_id, int> learned_spells;

/**
* Additional bionics that are installed automatically when this
* bionic is installed. This can be used to install several bionics
Expand Down
16 changes: 16 additions & 0 deletions src/magic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,22 @@ void spell::gain_level()
gain_exp( exp_to_next_level() );
}

void spell::gain_levels( int gains )
{
if( gains < 1 ) {
return;
}
for( int gained = 0; gained < gains || is_max_level(); gained++ ) {
gain_level();
}
}

void spell::set_level( int nlevel )
{
experience = 0;
gain_levels( nlevel );
}

bool spell::is_max_level() const
{
return get_level() >= type->max_level;
Expand Down
3 changes: 3 additions & 0 deletions src/magic.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ class spell
float exp_modifier( const Character &guy ) const;
// level up!
void gain_level();
// gains a number of levels, or until max. 0 or less just returns early.
void gain_levels( int gains );
void set_level( int nlevel );
// is the spell at max level?
bool is_max_level() const;
// what is the max level of the spell
Expand Down