From c54d746cdfbf5a006e3818a4e09fa57c75b8a143 Mon Sep 17 00:00:00 2001 From: DGamerL <108773801+DGamerL@users.noreply.github.com> Date: Tue, 14 Jan 2025 21:46:36 +0100 Subject: [PATCH 1/4] Adds conical spells from TG --- code/datums/spell_targeting/cone.dm | 75 +++++++++++++++++++ code/datums/spells/cones/TESTING_cone.dm | 1 + code/datums/spells/cones/cone_spell.dm | 43 +++++++++++ .../datums/{spell.dm => spells/spell_base.dm} | 0 .../{spells.dm => observer_spells.dm} | 0 paradise.dme | 7 +- 6 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 code/datums/spell_targeting/cone.dm create mode 100644 code/datums/spells/cones/TESTING_cone.dm create mode 100644 code/datums/spells/cones/cone_spell.dm rename code/datums/{spell.dm => spells/spell_base.dm} (100%) rename code/modules/mob/dead/observer/{spells.dm => observer_spells.dm} (100%) diff --git a/code/datums/spell_targeting/cone.dm b/code/datums/spell_targeting/cone.dm new file mode 100644 index 0000000000000..7bd690add87ed --- /dev/null +++ b/code/datums/spell_targeting/cone.dm @@ -0,0 +1,75 @@ + +/datum/spell_targeting/cone + max_targets = INFINITY + use_intercept_click = TRUE + /// This controls how many levels the cone has. Increase this value to make a bigger cone. + var/cone_levels = 3 + /// This value determines if the cone penetrates walls. + var/respect_density = FALSE + +/datum/spell_targeting/cone/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) + var/list/turfs_to_return = list() + var/turf/turf_to_use = get_turf(user) + var/turf/left_turf + var/turf/right_turf + var/dir_to_use = get_dir(user, clicked_atom) + var/right_dir + var/left_dir + switch(dir_to_use) + if(NORTH) + left_dir = WEST + right_dir = EAST + if(SOUTH) + left_dir = EAST + right_dir = WEST + if(EAST) + left_dir = NORTH + right_dir = SOUTH + if(WEST) + left_dir = SOUTH + right_dir = NORTH + + // Go though every level of the cone levels and generate the cone. + for(var/level in 1 to cone_levels) + var/list/level_turfs = list() + // Our center turf always exists, it's straight ahead of the caster. + turf_to_use = get_step(turf_to_use, dir_to_use) + level_turfs += turf_to_use + // Level 1 only ever has 1 turf, it's a cone. + if(level != 1) + var/level_width_in_each_direction = round((calculate_cone_shape(level) - 1) / 2) + left_turf = turf_to_use + right_turf = turf_to_use + // Check turfs to the left... + for(var/left_of_center in 1 to level_width_in_each_direction) + if(respect_density && left_turf.density) + break + left_turf = get_step(left_turf, left_dir) + level_turfs += left_turf + // And turfs to the right. + for(var/right_of_enter in 1 to level_width_in_each_direction) + if(respect_density && right_turf.density) + break + right_turf = get_step(right_turf, right_dir) + level_turfs += right_turf + // Add the list of all turfs on this level to the turfs to return + turfs_to_return += list(level_turfs) + + // If we're at the last level, we're done + if(level == cone_levels) + break + // But if we're not at the last level, we should check that we can keep going + if(respect_density && turf_to_use.density) + break + + return turfs_to_return + +/** + * Adjusts the width of the cone at the passed level. + * This is never called on the first level of the cone (level 1 is always 1 width) + * + * Return a number - the TOTAL width of the cone at the passed level. + */ +/datum/spell_targeting/cone/proc/calculate_cone_shape(current_level) + // Default formula: (1 (innate) -> 3 -> 5 -> 5 -> 7 -> 7 -> 9 -> 9 -> ...) + return current_level + (current_level % 2) + 1 diff --git a/code/datums/spells/cones/TESTING_cone.dm b/code/datums/spells/cones/TESTING_cone.dm new file mode 100644 index 0000000000000..f869c946ac331 --- /dev/null +++ b/code/datums/spells/cones/TESTING_cone.dm @@ -0,0 +1 @@ +/datum/spell/cone/cold diff --git a/code/datums/spells/cones/cone_spell.dm b/code/datums/spells/cones/cone_spell.dm new file mode 100644 index 0000000000000..0968522ebd0f4 --- /dev/null +++ b/code/datums/spells/cones/cone_spell.dm @@ -0,0 +1,43 @@ +/datum/spell/cone + + +/datum/spell/cone/create_new_targeting() + return new /datum/spell_targeting/cone + +/datum/spell/cone/cast(list/targets, mob/user) + for(var/list/turf_list in targets) + do_cone_effects(turf_list, user) + +/datum/spell/cone/proc/do_cone_effects(list/targets, mob/user) + for(var/turf/target_turf as anything in targets) + if(QDELETED(target_turf)) //if turf is no longer there + continue + + do_turf_cone_effect(target_turf, user, spell_level) + if(iswallturf(target_turf)) + continue + + for(var/atom/movable/movable_content as anything in target_turf) + if(isobj(movable_content)) + do_obj_cone_effect(movable_content, user, spell_level) + else if(isliving(movable_content)) + do_mob_cone_effect(movable_content, user, spell_level) + +/datum/spell/cone/proc/do_turf_cone_effect(turf/target_turf, mob/caster, level) + target_turf.color = COLOR_RED + +/datum/spell/cone/proc/do_obj_cone_effect(obj/target_obj, mob/caster, level) + return + +/datum/spell/cone/proc/do_mob_cone_effect(mob/target_mob, mob/caster, level) + target_mob.color = COLOR_GREEN + +/datum/spell/cone/staggered + /// The delay between each cone level triggering. + var/delay_between_level = 0.2 SECONDS + +/datum/spell/cone/staggered/cast(list/targets, mob/user) + var/level_counter = 0 + for(var/list/turf_list in targets) + level_counter++ + addtimer(CALLBACK(src, PROC_REF(do_cone_effects), turf_list, user, level_counter), delay_between_level * level_counter) diff --git a/code/datums/spell.dm b/code/datums/spells/spell_base.dm similarity index 100% rename from code/datums/spell.dm rename to code/datums/spells/spell_base.dm diff --git a/code/modules/mob/dead/observer/spells.dm b/code/modules/mob/dead/observer/observer_spells.dm similarity index 100% rename from code/modules/mob/dead/observer/spells.dm rename to code/modules/mob/dead/observer/observer_spells.dm diff --git a/paradise.dme b/paradise.dme index 90e5468b42641..44e48e058c960 100644 --- a/paradise.dme +++ b/paradise.dme @@ -418,7 +418,6 @@ #include "code\datums\ruins.dm" #include "code\datums\shuttles.dm" #include "code\datums\spawners_menu.dm" -#include "code\datums\spell.dm" #include "code\datums\station_state.dm" #include "code\datums\tgs_event_handler.dm" #include "code\datums\verb_callbacks.dm" @@ -593,6 +592,7 @@ #include "code\datums\spell_targeting\aoe.dm" #include "code\datums\spell_targeting\click_spell_targeting.dm" #include "code\datums\spell_targeting\clicked_atom.dm" +#include "code\datums\spell_targeting\cone.dm" #include "code\datums\spell_targeting\matter_eater_targeting.dm" #include "code\datums\spell_targeting\reachable_turfs.dm" #include "code\datums\spell_targeting\remoteview_targeting.dm" @@ -635,6 +635,7 @@ #include "code\datums\spells\sentient_sword_lunge.dm" #include "code\datums\spells\shapeshift.dm" #include "code\datums\spells\spacetime_dist.dm" +#include "code\datums\spells\spell_base.dm" #include "code\datums\spells\summon_supermatter.dm" #include "code\datums\spells\summonitem.dm" #include "code\datums\spells\touch_attacks.dm" @@ -653,6 +654,8 @@ #include "code\datums\spells\alien_spells\tail_lash.dm" #include "code\datums\spells\alien_spells\transfer_plasma.dm" #include "code\datums\spells\alien_spells\whisper.dm" +#include "code\datums\spells\cones\cone_spell.dm" +#include "code\datums\spells\cones\TESTING_cone.dm" #include "code\datums\station_traits\_station_trait.dm" #include "code\datums\station_traits\admin_panel.dm" #include "code\datums\station_traits\negative_traits.dm" @@ -2217,8 +2220,8 @@ #include "code\modules\mob\dead\observer\observer_login.dm" #include "code\modules\mob\dead\observer\observer_logout.dm" #include "code\modules\mob\dead\observer\observer_say.dm" +#include "code\modules\mob\dead\observer\observer_spells.dm" #include "code\modules\mob\dead\observer\orbit.dm" -#include "code\modules\mob\dead\observer\spells.dm" #include "code\modules\mob\living\autohiss.dm" #include "code\modules\mob\living\damage_procs.dm" #include "code\modules\mob\living\death.dm" From c84850e603002c79d7a23ea4993a7873a7729a9c Mon Sep 17 00:00:00 2001 From: DGamerL <108773801+DGamerL@users.noreply.github.com> Date: Tue, 14 Jan 2025 21:48:22 +0100 Subject: [PATCH 2/4] Remove testing stuff --- code/datums/spells/cones/TESTING_cone.dm | 1 - code/datums/spells/cones/cone_spell.dm | 4 ++-- paradise.dme | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 code/datums/spells/cones/TESTING_cone.dm diff --git a/code/datums/spells/cones/TESTING_cone.dm b/code/datums/spells/cones/TESTING_cone.dm deleted file mode 100644 index f869c946ac331..0000000000000 --- a/code/datums/spells/cones/TESTING_cone.dm +++ /dev/null @@ -1 +0,0 @@ -/datum/spell/cone/cold diff --git a/code/datums/spells/cones/cone_spell.dm b/code/datums/spells/cones/cone_spell.dm index 0968522ebd0f4..7d9194b233a51 100644 --- a/code/datums/spells/cones/cone_spell.dm +++ b/code/datums/spells/cones/cone_spell.dm @@ -24,13 +24,13 @@ do_mob_cone_effect(movable_content, user, spell_level) /datum/spell/cone/proc/do_turf_cone_effect(turf/target_turf, mob/caster, level) - target_turf.color = COLOR_RED + return /datum/spell/cone/proc/do_obj_cone_effect(obj/target_obj, mob/caster, level) return /datum/spell/cone/proc/do_mob_cone_effect(mob/target_mob, mob/caster, level) - target_mob.color = COLOR_GREEN + return /datum/spell/cone/staggered /// The delay between each cone level triggering. diff --git a/paradise.dme b/paradise.dme index 44e48e058c960..faabc0767d376 100644 --- a/paradise.dme +++ b/paradise.dme @@ -655,7 +655,6 @@ #include "code\datums\spells\alien_spells\transfer_plasma.dm" #include "code\datums\spells\alien_spells\whisper.dm" #include "code\datums\spells\cones\cone_spell.dm" -#include "code\datums\spells\cones\TESTING_cone.dm" #include "code\datums\station_traits\_station_trait.dm" #include "code\datums\station_traits\admin_panel.dm" #include "code\datums\station_traits\negative_traits.dm" From 795274ce9cd9cfa67c6e2282a6cef9fa939f897e Mon Sep 17 00:00:00 2001 From: DGamerL <108773801+DGamerL@users.noreply.github.com> Date: Tue, 14 Jan 2025 21:52:50 +0100 Subject: [PATCH 3/4] Errant whitespace --- code/datums/spell_targeting/cone.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/datums/spell_targeting/cone.dm b/code/datums/spell_targeting/cone.dm index 7bd690add87ed..7cc9b7a956100 100644 --- a/code/datums/spell_targeting/cone.dm +++ b/code/datums/spell_targeting/cone.dm @@ -1,4 +1,3 @@ - /datum/spell_targeting/cone max_targets = INFINITY use_intercept_click = TRUE From 9b2f9e6e018a546b8d6b211b7ab6af2b9869f4ed Mon Sep 17 00:00:00 2001 From: DGamerL <108773801+DGamerL@users.noreply.github.com> Date: Tue, 14 Jan 2025 21:55:03 +0100 Subject: [PATCH 4/4] Fix levels --- code/datums/spells/cones/cone_spell.dm | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/code/datums/spells/cones/cone_spell.dm b/code/datums/spells/cones/cone_spell.dm index 7d9194b233a51..11b249c9f0d3d 100644 --- a/code/datums/spells/cones/cone_spell.dm +++ b/code/datums/spells/cones/cone_spell.dm @@ -5,23 +5,25 @@ return new /datum/spell_targeting/cone /datum/spell/cone/cast(list/targets, mob/user) + var/level_counter = 1 for(var/list/turf_list in targets) - do_cone_effects(turf_list, user) + do_cone_effects(turf_list, user, level_counter) + level_counter++ -/datum/spell/cone/proc/do_cone_effects(list/targets, mob/user) +/datum/spell/cone/proc/do_cone_effects(list/targets, mob/user, level) for(var/turf/target_turf as anything in targets) if(QDELETED(target_turf)) //if turf is no longer there continue - do_turf_cone_effect(target_turf, user, spell_level) + do_turf_cone_effect(target_turf, user, level) if(iswallturf(target_turf)) continue for(var/atom/movable/movable_content as anything in target_turf) if(isobj(movable_content)) - do_obj_cone_effect(movable_content, user, spell_level) + do_obj_cone_effect(movable_content, user, level) else if(isliving(movable_content)) - do_mob_cone_effect(movable_content, user, spell_level) + do_mob_cone_effect(movable_content, user, level) /datum/spell/cone/proc/do_turf_cone_effect(turf/target_turf, mob/caster, level) return