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

[Magiclysm] Teleport_To spell type #50130

Merged
merged 18 commits into from
Jul 22, 2021
2 changes: 1 addition & 1 deletion data/json/artifact/legacy_artifact_active.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
"id": "AEA_TELEPORT",
"name": { "str": "Artifact Teleport" },
"description": "Randomly teleports you a short distance.",
"effect": "teleport_random",
"effect": "short_range_teleport",
"shape": "blast",
"valid_targets": [ "self" ],
"flags": [ "NO_HANDS", "SILENT", "NO_LEGS", "UNSAFE_TELEPORT" ],
Expand Down
2 changes: 1 addition & 1 deletion data/json/monster_special_attacks/spells.json
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@
"id": "phase_skulker_teleport",
"name": { "str": "Phase Skulker Teleport" },
"description": "Teleports the monster.",
"effect": "teleport_random",
"effect": "short_range_teleport",
"shape": "blast",
"valid_targets": [ "none" ],
"flags": [ "SOMATIC", "SILENT", "NO_LEGS" ],
Expand Down
2 changes: 1 addition & 1 deletion data/mods/Magiclysm/Spells/attunements/Wither_Mage.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"id": "assassin_teleport",
"name": "Assassin Teleport",
"description": "This is a sub-spell for Assassin Strike. It teleports you.",
"effect": "teleport_random",
"effect": "short_range_teleport",
"shape": "blast",
"valid_targets": [ "none" ],
"flags": [ "SILENT" ],
Expand Down
20 changes: 20 additions & 0 deletions data/mods/Magiclysm/Spells/debug.json
Original file line number Diff line number Diff line change
Expand Up @@ -279,5 +279,25 @@
"energy_source": "MANA",
"min_duration": 400,
"max_duration": 400
},
{
"id": "debug_teleport_to",
"type": "SPELL",
"name": "Debug Teleport To",
"description": "Teleports you to target location.",
"effect": "short_range_teleport",
"shape": "blast",
"valid_targets": [ "ground" ],
"flags": [ "SOMATIC", "SILENT", "NO_LEGS", "TARGET_TELEPORT" ],
"min_range": 100,
"max_range": 100,
"min_aoe": 0,
"max_aoe": 0,
"max_level": 1,
"difficulty": 4,
"spell_class": "NONE",
"base_casting_time": 100,
"energy_source": "MANA",
"base_energy_cost": 100
}
]
31 changes: 28 additions & 3 deletions data/mods/Magiclysm/Spells/magus.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"type": "SPELL",
"name": "Phase Door",
"description": "Teleports you in a random direction a short distance.",
"effect": "teleport_random",
"effect": "short_range_teleport",
"shape": "blast",
"valid_targets": [ "none" ],
"flags": [ "SOMATIC", "SILENT", "NO_LEGS" ],
Expand All @@ -69,7 +69,32 @@
"spell_class": "MAGUS",
"base_casting_time": 100,
"energy_source": "MANA",
"base_energy_cost": 100
"base_energy_cost": 100,
"learn_spells": { "dimension_door": 10 }
},
{
"id": "dimension_door",
"type": "SPELL",
"name": "Dimension Door",
"description": "Teleports you randomly near a target location.",
"effect": "short_range_teleport",
"shape": "blast",
"valid_targets": [ "ground" ],
"flags": [ "SOMATIC", "SILENT", "NO_LEGS", "TARGET_TELEPORT" ],
"min_range": 10,
"max_range": 20,
"range_increment": 1,
"min_aoe": 6,
"max_aoe": 3,
"aoe_increment": -0.3,
"max_level": 30,
"difficulty": 5,
"spell_class": "MAGUS",
"base_casting_time": 600,
"energy_source": "MANA",
"base_energy_cost": 600,
"energy_increment": -10,
"final_energy_cost": 350
},
{
"id": "gravity_well",
Expand Down Expand Up @@ -220,7 +245,7 @@
"type": "SPELL",
"name": "Escape",
"description": "Teleports you in a random direction a medium distance, to help escape your foes in dangerous situations.",
"effect": "teleport_random",
"effect": "short_range_teleport",
"shape": "blast",
"valid_targets": [ "none" ],
"flags": [ "SOMATIC", "SILENT", "NO_LEGS", "VERBAL" ],
Expand Down
2 changes: 1 addition & 1 deletion data/mods/Magiclysm/Spells/technomancer.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@
"description": "This spell manipulates some quantum something or other to tunnel you through a short distance of space, and even matter, unfortunately there's that whole uncertainty thing as to where you come out. It leaves you a little dazed on the other side as you reorient yourself.",
"valid_targets": [ "none" ],
"flags": [ "NO_LEGS", "NO_HANDS", "SILENT" ],
"effect": "teleport_random",
"effect": "short_range_teleport",
"effect_str": "dazed",
"shape": "blast",
"spell_class": "TECHNOMANCER",
Expand Down
1 change: 1 addition & 0 deletions data/mods/Magiclysm/items/spellbooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"spells": [
"debug_hp",
"debug_stamina",
"debug_teleport_to",
"example_template",
"debug_bionic",
"pain_split",
Expand Down
3 changes: 2 additions & 1 deletion doc/MAGIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Below is a table of currently implemented effects, along with special rules for
| `translocate` | Opens up a window that allows the caster to choose a translocation gate to teleport to.
| `area_pull` | Pulls `valid_targets` in aoe toward the target location
| `area_push` | Pushes `valid_targets` in aoe away from the target location
| `teleport_random` | teleports the player randomly range spaces with aoe variation
| `short_range_teleport` | teleports the player randomly range spaces with aoe variation
| `targeted_polymorph` | A targeted monster is permanently transformed into the monster ID specified by `effect_str` if it has less HP than the spell's damage. If `effect_str` is left empty, the target will transform into a random monster with a similar difficulty rating, alternatively the flag `"POLYMORPH_GROUP"` can be used to pick a weighted monster ID from a monster group. The player and NPCs are immune to this spell effect.
| `recover_energy` | recovers an energy source equal to damage of the spell. The energy source recovered is defined in "effect_str" and may be one of "MANA", "STAMINA", "FATIGUE", "PAIN", "BIONIC"
| `ter_transform` | transform the terrain and furniture in an area centered at the target. The chance of any one of the points in the area of effect changing is one_in( damage ). The effect_str is the id of a ter_furn_transform.
Expand Down Expand Up @@ -174,6 +174,7 @@ Spells may have any number of flags, for example:
| `PAIN_NORESIST` | pain altering spells can't be resisted (like with the deadened trait)
| `WITH_CONTAINER` | items spawned with container
| `UNSAFE_TELEPORT` | teleport spell risks killing the caster or others
| `TARGET_TELEPORT` | teleport spell changes to maximum range target with aoe as variation around target
| `SPAWN_GROUP` | spawn or summon from an item or monster group, instead of individual item/monster ID
| `NO_PROJECTILE` | the "projectile" portion of the spell phases through walls. the epicenter of the spell effect is exactly where you target it with no regards to obstacles

Expand Down
5 changes: 3 additions & 2 deletions src/magic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ std::string enum_to_string<spell_flag>( spell_flag data )
case spell_flag::NO_HANDS: return "NO_HANDS";
case spell_flag::NO_LEGS: return "NO_LEGS";
case spell_flag::UNSAFE_TELEPORT: return "UNSAFE_TELEPORT";
case spell_flag::TARGET_TELEPORT: return "TARGET_TELEPORT";
case spell_flag::SWAP_POS: return "SWAP_POS";
case spell_flag::CONCENTRATE: return "CONCENTRATE";
case spell_flag::RANDOM_AOE: return "RANDOM_AOE";
Expand Down Expand Up @@ -2019,7 +2020,7 @@ void spellcasting_callback::draw_spell_info( const spell &sp, const uilist *menu
}
aoe_string = string_format( "%s: %d %s", aoe_string_temp, sp.aoe(), degree_string );
}
} else if( fx == "teleport_random" ) {
} else if( fx == "short_range_teleport" ) {
if( sp.aoe() > 0 ) {
aoe_string = string_format( "%s: %d", _( "Variance" ), sp.aoe() );
}
Expand Down Expand Up @@ -2278,7 +2279,7 @@ static void draw_spellbook_info( const spell_type &sp, uilist *menu )
damage_string = _( "Threshold" );
} else if( fx == "recover_energy" ) {
damage_string = _( "Recover" );
} else if( fx == "teleport_random" ) {
} else if( fx == "short_range_teleport" ) {
aoe_string = _( "Variance" );
} else if( fx == "area_pull" || fx == "area_push" || fx == "ter_transform" ) {
aoe_string = _( "AoE" );
Expand Down
5 changes: 3 additions & 2 deletions src/magic.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ enum class spell_flag : int {
SOMATIC, // arm encumbrance affects fail % and casting time (slightly)
NO_HANDS, // hands do not affect spell energy cost
UNSAFE_TELEPORT, // teleport spell risks killing the caster or others
TARGET_TELEPORT, // aoe is teleport variance from target
NO_LEGS, // legs do not affect casting time
CONCENTRATE, // focus affects spell fail %
RANDOM_AOE, // picks random number between min+increment*level and max instead of normal behavior
Expand Down Expand Up @@ -661,7 +662,7 @@ struct override_parameters {
}
};

void teleport_random( const spell &sp, Creature &caster, const tripoint & );
void short_range_teleport( const spell &sp, Creature &caster, const tripoint &target );
void pain_split( const spell &, Creature &, const tripoint & );
void attack( const spell &sp, Creature &caster,
const tripoint &epicenter );
Expand Down Expand Up @@ -721,7 +722,7 @@ effect_map{
{ "pain_split", spell_effect::pain_split },
{ "attack", spell_effect::attack },
{ "targeted_polymorph", spell_effect::targeted_polymorph },
{ "teleport_random", spell_effect::teleport_random },
{ "short_range_teleport", spell_effect::short_range_teleport },
{ "spawn_item", spell_effect::spawn_ethereal_item },
{ "recover_energy", spell_effect::recover_energy },
{ "summon", spell_effect::spawn_summoned_monster },
Expand Down
16 changes: 14 additions & 2 deletions src/magic_spell_effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,21 @@ static void build_line( spell_detail::line_iterable line, const tripoint &source
}
} // namespace spell_detail

void spell_effect::teleport_random( const spell &sp, Creature &caster, const tripoint & )
void spell_effect::short_range_teleport( const spell &sp, Creature &caster, const tripoint &target )
{
bool safe = !sp.has_flag( spell_flag::UNSAFE_TELEPORT );
const bool safe = !sp.has_flag( spell_flag::UNSAFE_TELEPORT );
const bool target_teleport = sp.has_flag( spell_flag::TARGET_TELEPORT );
if( target_teleport ) {
if( sp.aoe() == 0 ) {
teleport::teleport_to_point( caster, target, safe, false );
return;
}

std::set<tripoint> potential_targets = calculate_spell_effect_area( sp, target, caster );
tripoint where = random_entry( potential_targets );
teleport::teleport_to_point( caster, where, safe, false );
return;
}
const int min_distance = sp.range();
const int max_distance = sp.range() + sp.aoe();
if( min_distance > max_distance || min_distance < 0 || max_distance < 0 ) {
Expand Down
35 changes: 23 additions & 12 deletions src/teleport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,38 @@ bool teleport::teleport( Creature &critter, int min_distance, int max_distance,
debugmsg( "ERROR: Function teleport::teleport called with invalid arguments." );
return false;
}
Character *const p = critter.as_character();
const bool c_is_u = p != nullptr && p->is_avatar();
int tries = 0;
tripoint origin = critter.pos();
tripoint new_pos = origin;
map &here = get_map();
//The teleportee is dimensionally anchored so nothing happens
if( p && ( p->worn_with_flag( json_flag_DIMENSIONAL_ANCHOR ) ||
p->has_flag( json_flag_DIMENSIONAL_ANCHOR ) ) ) {
p->add_msg_if_player( m_warning, _( "You feel a strange, inwards force." ) );
return false;
}
do {
int rangle = rng( 0, 360 );
int rdistance = rng( min_distance, max_distance );
new_pos.x = origin.x + rdistance * std::cos( rangle );
new_pos.y = origin.y + rdistance * std::sin( rangle );
tries++;
} while( here.impassable( new_pos ) && tries < 20 );
return teleport_to_point( critter, new_pos, safe, add_teleglow );
}

bool teleport::teleport_to_point( Creature &critter, const tripoint &target, bool safe,
bool add_teleglow )
{

if( critter.pos() == target ) {
return false;
}
Character *const p = critter.as_character();
const bool c_is_u = p != nullptr && p->is_avatar();
map &here = get_map();
//The teleportee is dimensionally anchored so nothing happens
if( p && ( p->worn_with_flag( json_flag_DIMENSIONAL_ANCHOR ) ||
p->has_effect_with_flag( json_flag_DIMENSIONAL_ANCHOR ) ) ) {
p->add_msg_if_player( m_warning, _( "You feel a strange, inwards force." ) );
return false;
}
//handles teleporting into solids.
if( here.impassable( new_pos ) ) {
if( here.impassable( target ) ) {
if( safe ) {
if( c_is_u ) {
add_msg( m_bad, _( "You cannot teleport safely." ) );
Expand All @@ -61,14 +72,14 @@ bool teleport::teleport( Creature &critter, int min_distance, int max_distance,
}
critter.apply_damage( nullptr, bodypart_id( "torso" ), 9999 );
if( c_is_u ) {
get_event_bus().send<event_type::teleports_into_wall>( p->getID(), here.obstacle_name( new_pos ) );
get_event_bus().send<event_type::teleports_into_wall>( p->getID(), here.obstacle_name( target ) );
add_msg( m_bad, _( "You die after teleporting into a solid." ) );
}
critter.check_dead_state();

}
//handles telefragging other creatures
if( Creature *const poor_soul = g->critter_at<Creature>( new_pos ) ) {
if( Creature *const poor_soul = g->critter_at<Creature>( target ) ) {
Character *const poor_player = dynamic_cast<Character *>( poor_soul );
if( safe ) {
if( c_is_u ) {
Expand Down Expand Up @@ -103,7 +114,7 @@ bool teleport::teleport( Creature &critter, int min_distance, int max_distance,
}
}

critter.setpos( new_pos );
critter.setpos( target );
//player and npc exclusive teleporting effects
if( p ) {
if( add_teleglow ) {
Expand Down
2 changes: 2 additions & 0 deletions src/teleport.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#ifndef CATA_SRC_TELEPORT_H
#define CATA_SRC_TELEPORT_H
struct tripoint;

class Creature;

Expand All @@ -12,6 +13,7 @@ namespace teleport
bool teleport( Creature &critter, int min_distance = 2, int max_distance = 12,
bool safe = false,
bool add_teleglow = true );
bool teleport_to_point( Creature &critter, const tripoint &target, bool safe, bool add_teleglow );
} // namespace teleport

#endif // CATA_SRC_TELEPORT_H