diff --git a/data/json/legacy_artifact_active.json b/data/json/legacy_artifact_active.json index 0689a8e1a06f4..c822e0c3c7629 100644 --- a/data/json/legacy_artifact_active.json +++ b/data/json/legacy_artifact_active.json @@ -507,6 +507,22 @@ "min_duration": 180000, "max_duration": 180000 }, + { + "type": "SPELL", + "id": "AEA_ENTRANCE", + "name": "Artifact Entrance", + "description": "Entrances surrounding monsters", + "effect": "charm_monster", + "message": "", + "min_damage": 0, + "max_damage": 600, + "min_duration": 500, + "max_duration": 5000, + "min_aoe": 8, + "max_aoe": 8, + "valid_targets": [ "self", "hostile" ], + "flags": [ "RANDOM_DAMAGE", "RANDOM_DURATION" ] + }, { "type": "SPELL", "id": "AEA_SCREAM", diff --git a/doc/MAGIC.md b/doc/MAGIC.md index 42344b20dca01..5a8f5c74ee26e 100644 --- a/doc/MAGIC.md +++ b/doc/MAGIC.md @@ -109,6 +109,8 @@ Any aoe will manifest as a circular area centered on the target, and will only d * "morale" - gives a morale effect to all npcs or avatar within aoe, with value damage(). decay_start is duration() / 10. +* "charm_monster" - charms a monster that has less hp than damage() for approximately duration() + * "mutate" - mutates the target(s). if effect_str is defined, mutates toward that category instead of picking at random. the "MUTATE_TRAIT" flag allows effect_str to be a specific trait instead of a category. damage() / 100 is the percent chance the mutation will be successful (a value of 10000 represents 100.00%) * "bash" - bashes the terrain at the target. uses damage() as the strength of the bash. diff --git a/src/magic.cpp b/src/magic.cpp index 14f98ed5c929d..7ff91a393038e 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -218,6 +218,7 @@ void spell_type::load( JsonObject &jo, const std::string & ) { "mod_moves", spell_effect::mod_moves }, { "map", spell_effect::map }, { "morale", spell_effect::morale }, + { "charm_monster", spell_effect::charm_monster }, { "mutate", spell_effect::mutate }, { "bash", spell_effect::bash }, { "none", spell_effect::none } diff --git a/src/magic.h b/src/magic.h index 6d557c8aa8bce..b8edcd690d0ff 100644 --- a/src/magic.h +++ b/src/magic.h @@ -506,6 +506,7 @@ void flashbang( const spell &sp, Creature &caster, const tripoint &target ); void mod_moves( const spell &sp, Creature &caster, const tripoint &target ); void map( const spell &sp, Creature &caster, const tripoint & ); void morale( const spell &sp, Creature &caster, const tripoint &target ); +void charm_monster( const spell &sp, Creature &caster, const tripoint &target ); void mutate( const spell &sp, Creature &caster, const tripoint &target ); void bash( const spell &sp, Creature &caster, const tripoint &target ); void none( const spell &sp, Creature &, const tripoint &target ); diff --git a/src/magic_spell_effect.cpp b/src/magic_spell_effect.cpp index 651d07c867120..ca1e2371c25c4 100644 --- a/src/magic_spell_effect.cpp +++ b/src/magic_spell_effect.cpp @@ -782,6 +782,25 @@ void spell_effect::morale( const spell &sp, Creature &caster, const tripoint &ta } } +void spell_effect::charm_monster( const spell &sp, Creature &caster, const tripoint &target ) +{ + const std::set area = spell_effect_blast( sp, caster.pos(), target, sp.aoe(), false ); + for( const tripoint &potential_target : area ) { + if( !sp.is_valid_target( caster, potential_target ) ) { + continue; + } + monster *mon = g->critter_at( potential_target ); + if( !mon ) { + continue; + } + sp.make_sound( potential_target ); + if( mon->friendly == 0 && mon->get_hp() <= sp.damage() ) { + mon->unset_dest(); + mon->friendly += sp.duration() / 100; + } + } +} + void spell_effect::mutate( const spell &sp, Creature &caster, const tripoint &target ) { const std::set area = spell_effect_blast( sp, caster.pos(), target, sp.aoe(), false );