Skip to content

Commit

Permalink
refactor spell_effect::spawn_ethereal_item (CleverRaven#64600)
Browse files Browse the repository at this point in the history
  • Loading branch information
mqrause authored Apr 5, 2023
1 parent ad4e5c9 commit de40ba8
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 37 deletions.
5 changes: 0 additions & 5 deletions data/json/flags.json
Original file line number Diff line number Diff line change
Expand Up @@ -1065,11 +1065,6 @@
"type": "json_flag",
"//": "pain altering spells can't be resisted (like with the deadened trait)"
},
{
"id": "WITH_CONTAINER",
"type": "json_flag",
"//": "items spawned by spells are put in their containers."
},
{
"id": "SPAWN_WITH_DEATH_DROPS",
"type": "json_flag",
Expand Down
1 change: 0 additions & 1 deletion doc/MAGIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ Flag | Description
`TARGET_TELEPORT` | Teleport spell changes to maximum range target with aoe as variation around target.
`UNSAFE_TELEPORT` | Teleport spell risks killing the caster or others.
`VERBAL` | Spell makes noise at caster location, mouth encumbrance affects fail %.
`WITH_CONTAINER` | Items spawned with container.
`WONDER` | This drastically alters the behavior of the parent spell: The spell itself doesn't cast, but the damage and range information are used to cast the `extra_effects`. A n number of `extra_effects` will be chosen to be cast at random, where n is the current damage of the spell (stacks with the `RANDOM_DAMAGE` flag), the message of the casted spell will also be displayed. If this spell's message is not wanted, make sure `message` is an empty string.


Expand Down
11 changes: 8 additions & 3 deletions src/debug_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -750,9 +750,14 @@ static void spell_description(
}

} else if( spl_eff == "spawn_item" ) {
damage_string = string_format( _( "Spawn %1$d %2$s" ), spl.damage( chrc ),
item::nname( itype_id( spl.effect_data() ), spl.damage( chrc ) ) );

if( spl.has_flag( spell_flag::SPAWN_GROUP ) ) {
// todo: more user-friendly presentation
damage_string = string_format( _( "Spawn item group %1$s %2$d times" ), spl.effect_data(),
spl.damage( chrc ) );
} else {
damage_string = string_format( _( "Spawn %1$d %2$s" ), spl.damage( chrc ),
item::nname( itype_id( spl.effect_data() ), spl.damage( chrc ) ) );
}
} else if( spl_eff == "summon" ) {
std::string monster_name = "FIXME";
if( spl.has_flag( spell_flag::SPAWN_GROUP ) ) {
Expand Down
11 changes: 8 additions & 3 deletions src/magic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ std::string enum_to_string<spell_flag>( spell_flag data )
case spell_flag::RANDOM_CRITTER: return "RANDOM_CRITTER";
case spell_flag::MUTATE_TRAIT: return "MUTATE_TRAIT";
case spell_flag::PAIN_NORESIST: return "PAIN_NORESIST";
case spell_flag::WITH_CONTAINER: return "WITH_CONTAINER";
case spell_flag::SPAWN_GROUP: return "SPAWN_GROUP";
case spell_flag::IGNITE_FLAMMABLE: return "IGNITE_FLAMMABLE";
case spell_flag::NO_FAIL: return "NO_FAIL";
Expand Down Expand Up @@ -2254,8 +2253,14 @@ void spellcasting_callback::spell_info_text( const spell &sp, int width )
aoe_string = string_format( "%s: %d", _( "Variance" ), sp.aoe( pc ) );
}
} else if( sp.effect() == "spawn_item" ) {
damage_string = string_format( "%s %d %s", _( "Spawn" ), sp.damage( pc ),
item::nname( itype_id( sp.effect_data() ), sp.damage( pc ) ) );
if( sp.has_flag( spell_flag::SPAWN_GROUP ) ) {
// todo: more user-friendly presentation
damage_string = string_format( _( "Spawn item group %1$s %2$d times" ), sp.effect_data(),
sp.damage( pc ) );
} else {
damage_string = string_format( "%s %d %s", _( "Spawn" ), sp.damage( pc ),
item::nname( itype_id( sp.effect_data() ), sp.damage( pc ) ) );
}
} else if( sp.effect() == "summon" ) {
std::string monster_name = "FIXME";
if( sp.has_flag( spell_flag::SPAWN_GROUP ) ) {
Expand Down
1 change: 0 additions & 1 deletion src/magic.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ enum class spell_flag : int {
EXTRA_EFFECTS_FIRST, // the extra effects are cast before the main spell.
PAIN_NORESIST, // pain altering spells can't be resisted (like with the deadened trait)
NO_FAIL, // this spell cannot fail when you cast it
WITH_CONTAINER, // items spawned with container
SPAWN_GROUP, // spawn or summon from an item or monster group, instead of individual item/monster ID
IGNITE_FLAMMABLE, // if spell effect area has any thing flammable, a fire will be produced
MUST_HAVE_CLASS_TO_LEARN, // you can't learn the spell unless you already have the class.
Expand Down
56 changes: 32 additions & 24 deletions src/magic_spell_effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1060,33 +1060,41 @@ void spell_effect::directed_push( const spell &sp, Creature &caster, const tripo

void spell_effect::spawn_ethereal_item( const spell &sp, Creature &caster, const tripoint & )
{
item granted( sp.effect_data(), calendar::turn );
// Comestibles are never ethereal. Other spawned items are ethereal unless permanent and max level.
if( !granted.is_comestible() && !( sp.has_flag( spell_flag::PERMANENT ) &&
sp.is_max_level( caster ) ) &&
!sp.has_flag( spell_flag::PERMANENT_ALL_LEVELS ) ) {
granted.set_var( "ethereal", to_turns<int>( sp.duration_turns( caster ) ) );
granted.ethereal = true;
}
if( granted.count_by_charges() && sp.damage( caster ) > 0 ) {
granted.charges = sp.damage( caster );
if( !caster.is_avatar() ) {
debugmsg( "Spells that spawn items are only supported for the avatar, not for %s.",
caster.disp_name() );
return;
}
if( sp.has_flag( spell_flag::WITH_CONTAINER ) ) {
granted = granted.in_its_container();

std::vector<item> granted;

for( int i = 0; i < sp.damage( caster ); i++ ) {
if( sp.has_flag( spell_flag::SPAWN_GROUP ) ) {
std::vector<item> group_items = item_group::items_from( item_group_id( sp.effect_data() ),
calendar::turn );
granted.insert( granted.end(), group_items.begin(), group_items.end() );
} else {
granted.emplace_back( sp.effect_data(), calendar::turn );
}
}

avatar &player_character = get_avatar();
if( player_character.can_wear( granted ).success() ) {
granted.set_flag( json_flag_FIT );
player_character.wear_item( granted, false );
} else if( !player_character.has_wield_conflicts( granted ) &&
player_character.wield( granted, 0 ) ) {
// nothing to do
} else {
player_character.i_add( granted );
}
if( !granted.count_by_charges() ) {
for( int i = 1; i < sp.damage( caster ); i++ ) {
player_character.i_add( granted );
for( item &it : granted ) {
// Spawned items are ethereal unless permanent and max level. Comestibles are never ethereal.
if( !it.is_comestible() && !sp.has_flag( spell_flag::PERMANENT_ALL_LEVELS ) &&
!( sp.has_flag( spell_flag::PERMANENT ) && sp.is_max_level( caster ) ) ) {
it.set_var( "ethereal", to_turns<int>( sp.duration_turns( caster ) ) );
it.ethereal = true;
}

if( player_character.can_wear( it ).success() ) {
it.set_flag( json_flag_FIT );
player_character.wear_item( it, false );
} else if( !player_character.has_wield_conflicts( it ) &&
player_character.wield( it, 0 ) ) {
// nothing to do
} else {
player_character.i_add( it );
}
}
sp.make_sound( caster.pos(), caster );
Expand Down

0 comments on commit de40ba8

Please sign in to comment.