Skip to content

Commit 6de2de5

Browse files
authored
Merge pull request #82318 from GuardianDll/consume_vitamin_for_magic
2 parents 9b06573 + 1fcb4c3 commit 6de2de5

File tree

4 files changed

+65
-15
lines changed

4 files changed

+65
-15
lines changed

doc/JSON/MAGIC.md

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ In `data/mods/Magiclysm` there is a template spell, copied here for your perusal
7171
"base_energy_cost": 30, // the amount of energy (of the requisite type) to cast the spell
7272
"final_energy_cost": 100,
7373
"energy_increment": -6,
74-
"energy_source": "MANA", // the type of energy used to cast the spell. types are: MANA, BIONIC, HP, STAMINA, NONE (none will not use mana)
74+
"energy_source": "MANA", // the type of energy used to cast the spell. types are: MANA, BIONIC, HP, STAMINA, NONE. Alternative notation can be used for spell consuming vitamins, see example below
7575
"components": [ /* requirement_id */], // an id from a requirement, like the ones you use for crafting. spell components require to cast.
7676
"difficulty": 12, // the difficulty to learn/cast the spell
7777
"max_level": 10, // maximum level you can achieve in the spell
@@ -197,7 +197,7 @@ Effect | Description
197197
`pain_split` | Evens out all of your limbs' damage.
198198
`pull_target` | Attempts to pull the target towards the caster in a straight line. If the path is blocked by impassable furniture or terrain, the effect fails.
199199
`recharge_vehicle` | Increases or decreases the battery charge of a vehicle or battery-connected power grid. Damage is equal to the charge (negative decreases).
200-
`recover_energy` | Recovers an energy source equal to damage of the spell. The energy source is defined in `effect_str` and may be one of `BIONIC`, `SLEEPINESS`, `PAIN`, `MANA` or `STAMINA`.
200+
`recover_energy` | Recovers an energy source equal to damage of the spell and may be one of `BIONIC`, `SLEEPINESS`, `PAIN`, `MANA` or `STAMINA`. Alternative notation can be used for spell consuming vitamins, see example below
201201
`remove_effect` | Removes `effect_str` effects from all creatures in the aoe.
202202
`remove_field` | Removes a `effect_str` field in the aoe. Causes teleglow of varying intensity and potentially teleportation depending on field density, if the field removed is `fd_reality_tear`. (see `ter_transform` for more versatility)
203203
`revive` | Revives a monster like a zombie necromancer. The monster must have the `REVIVES` flag.
@@ -322,20 +322,22 @@ Flag | Description
322322

323323
### Damage Types
324324

325-
The following are the available damage types, for those spells that have a damaging component:
325+
Any damage type can be used, see [JSON_INFO.md#damage-types](JSON_INFO.md#damage-types) for how they are defined and their specific property
326326

327-
Damage type | Description
328-
--- |---
329-
`acid` |
330-
`bash` |
331-
`biological` | Internal damage such as poison.
332-
`cold` |
333-
`cut` |
334-
`electric` |
335-
`heat` |
336-
`pure` | This damage type goes through armor altogether. Set by default.
337-
`stab` |
327+
### Energy Type
338328

329+
`energy_source` responds for the type of energy consumed, and as of now, can look like:
330+
331+
`BIONIC`, `SLEEPINESS`, `PAIN`, `MANA` or `STAMINA`
332+
333+
```jsonc
334+
"energy_source": "MANA",
335+
"energy_source": "STAMINA",
336+
"energy_source": "BIONIC", // consumes MJ from your CBM batteries
337+
"energy_source": "NONE",
338+
"energy_source": "HP", // Require a tool with CUT 1, and allow to pick the limb to be damaged
339+
"energy_source": { "type": "VITAMIN", "vitamin": "vitamin_id" },
340+
```
339341

340342
### Spell level
341343

src/magic.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include "translations.h"
6666
#include "uilist.h"
6767
#include "units.h"
68+
#include "vitamin.h"
6869
#include "vpart_position.h"
6970

7071
struct species_type;
@@ -204,6 +205,7 @@ std::string enum_to_string<magic_energy_type>( magic_energy_type data )
204205
case magic_energy_type::mana: return "MANA";
205206
case magic_energy_type::none: return "NONE";
206207
case magic_energy_type::stamina: return "STAMINA";
208+
case magic_energy_type::vitamin: return "VITAMIN";
207209
case magic_energy_type::last: break;
208210
}
209211
cata_fatal( "Invalid magic_energy_type" );
@@ -508,7 +510,13 @@ void spell_type::load( const JsonObject &jo, std::string_view src )
508510
}
509511

510512
optional( jo, was_loaded, "spell_class", spell_class, spell_class_default );
511-
optional( jo, was_loaded, "energy_source", energy_source );
513+
if( jo.has_string( "energy_source" ) ) {
514+
optional( jo, was_loaded, "energy_source", energy_source );
515+
} else if( jo.has_object( "energy_source" ) ) {
516+
const JsonObject jo_energy = jo.get_object( "energy_source" );
517+
mandatory( jo_energy, was_loaded, "type", energy_source );
518+
optional( jo_energy, was_loaded, "vitamin", vitamin_energy_source_ );
519+
}
512520
optional( jo, was_loaded, "damage_type", dmg_type, dmg_type_default );
513521
optional( jo, was_loaded, "get_level_formula_id", get_level_formula_id );
514522
optional( jo, was_loaded, "exp_for_level_formula_id", exp_for_level_formula_id );
@@ -713,6 +721,17 @@ void spell_type::check_consistency()
713721
if( sp_t.spell_tags[spell_flag::WONDER] && sp_t.additional_spells.empty() ) {
714722
debugmsg( "ERROR: %s has WONDER flag but no spells to choose from!", sp_t.id.c_str() );
715723
}
724+
if( sp_t.get_energy_source() == magic_energy_type::vitamin &&
725+
!sp_t.vitamin_energy_source().has_value() ) {
726+
debugmsg( R"(spell %s uses energy_source "vitamin", but doesn't specify the "vitamin")",
727+
sp_t.id.c_str() );
728+
}
729+
if( sp_t.get_energy_source() != magic_energy_type::vitamin &&
730+
sp_t.vitamin_energy_source().has_value() ) {
731+
debugmsg( R"(spell %s specifies "vitamin", but doesn't use the vitamin energy source)",
732+
sp_t.id.c_str() );
733+
}
734+
716735
if( sp_t.exp_for_level_formula_id.has_value() &&
717736
sp_t.exp_for_level_formula_id.value()->num_params != 1 ) {
718737
debugmsg( "ERROR: %s exp_for_level_formula_id has params that != 1!", sp_t.id.c_str() );
@@ -1533,6 +1552,8 @@ std::string spell::energy_string() const
15331552
return _( "stamina" );
15341553
case magic_energy_type::bionic:
15351554
return _( "kJ" );
1555+
case magic_energy_type::vitamin:
1556+
return vitamin_energy_source().value().obj().name();
15361557
default:
15371558
return "";
15381559
}
@@ -1554,6 +1575,9 @@ std::string spell::energy_cost_string( const Character &guy ) const
15541575
auto pair = get_hp_bar( energy_cost( guy ), guy.get_stamina_max() );
15551576
return colorize( pair.first, pair.second );
15561577
}
1578+
if( energy_source() == magic_energy_type::vitamin ) {
1579+
return colorize( std::to_string( energy_cost( guy ) ), c_cyan );
1580+
}
15571581
debugmsg( "ERROR: Spell %s has invalid energy source.", id().c_str() );
15581582
return _( "error: energy_type" );
15591583
}
@@ -1573,6 +1597,9 @@ std::string spell::energy_cur_string( const Character &guy ) const
15731597
auto pair = get_hp_bar( guy.get_stamina(), guy.get_stamina_max() );
15741598
return colorize( pair.first, pair.second );
15751599
}
1600+
if( energy_source() == magic_energy_type::vitamin ) {
1601+
return colorize( std::to_string( guy.vitamin_get( vitamin_energy_source().value() ) ), c_cyan );
1602+
}
15761603
if( energy_source() == magic_energy_type::hp ) {
15771604
return "";
15781605
}
@@ -1654,6 +1681,11 @@ magic_energy_type spell::energy_source() const
16541681
return type->get_energy_source();
16551682
}
16561683

1684+
std::optional<vitamin_id> spell::vitamin_energy_source() const
1685+
{
1686+
return type->vitamin_energy_source();
1687+
}
1688+
16571689
bool spell::is_target_in_range( const Creature &caster, const tripoint_bub_ms &p ) const
16581690
{
16591691
return rl_dist( caster.pos_bub(), p ) <= range( caster );
@@ -1810,6 +1842,11 @@ magic_energy_type spell_type::get_energy_source() const
18101842
}
18111843
}
18121844

1845+
std::optional<vitamin_id> spell_type::vitamin_energy_source() const
1846+
{
1847+
return vitamin_energy_source_;
1848+
}
1849+
18131850
std::optional<jmath_func_id> spell_type::overall_get_level_formula_id() const
18141851
{
18151852
if( get_level_formula_id.has_value() ) {
@@ -1890,6 +1927,9 @@ void spell::consume_spell_cost( Character &caster, bool cast_success ) const
18901927
case magic_energy_type::stamina:
18911928
caster.mod_stamina( -cost );
18921929
break;
1930+
case magic_energy_type::vitamin:
1931+
caster.vitamin_mod( vitamin_energy_source().value(), -cost );
1932+
break;
18931933
case magic_energy_type::bionic:
18941934
caster.mod_power_level( -units::from_kilojoule( static_cast<std::int64_t>( cost ) ) );
18951935
break;
@@ -2637,6 +2677,8 @@ bool known_magic::has_enough_energy( const Character &guy, const spell &sp ) con
26372677
return guy.get_power_level() >= units::from_kilojoule( static_cast<std::int64_t>( cost ) );
26382678
case magic_energy_type::stamina:
26392679
return guy.get_stamina() >= cost;
2680+
case magic_energy_type::vitamin:
2681+
return guy.vitamin_get( sp.vitamin_energy_source().value() ) >= cost;
26402682
case magic_energy_type::hp:
26412683
for( const std::pair<const bodypart_str_id, bodypart> &elem : guy.get_body() ) {
26422684
if( elem.second.get_hp_cur() > cost ) {

src/magic.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ class spell_type
342342
// what energy do you use to cast this spell
343343
magic_energy_type get_energy_source() const;
344344

345+
// what energy do you use to cast this spell
346+
std::optional<vitamin_id> vitamin_energy_source() const;
347+
345348
damage_type_id dmg_type = damage_type_id::NULL_ID();
346349

347350
// list of valid targets enum
@@ -441,6 +444,7 @@ class spell_type
441444
static const float casting_time_increment_default;
442445

443446
std::optional<magic_energy_type> energy_source;
447+
std::optional<vitamin_id> vitamin_energy_source_; // NOLINT(cata-serialize)
444448
std::optional<jmath_func_id> get_level_formula_id;
445449
std::optional<jmath_func_id> exp_for_level_formula_id;
446450
std::optional<int> max_book_level;
@@ -632,6 +636,7 @@ class spell
632636

633637
// magic energy source enum
634638
magic_energy_type energy_source() const;
639+
std::optional<vitamin_id> vitamin_energy_source() const;
635640
// the color that's representative of the damage type
636641
nc_color damage_type_color() const;
637642
std::string damage_type_string() const;

src/magic_type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ enum class magic_energy_type : int {
2121
mana,
2222
stamina,
2323
bionic,
24+
vitamin,
2425
none,
2526
last
2627
};

0 commit comments

Comments
 (0)