From b8ae27143aec1e35a0c193fc273448995dfaa0e9 Mon Sep 17 00:00:00 2001 From: Repede Date: Sat, 6 Apr 2024 22:56:03 -0400 Subject: [PATCH] Shadekin nerfs (again) (#7705) # Conflicts: # code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm # vorestation.dme --- code/__defines/misc.dm | 1 + code/__defines/misc_vr.dm | 2 + .../carbon/human/species/shadekin/shadekin.dm | 15 +- .../species/shadekin/shadekin_abilities.dm | 8 + code/modules/telesci/bscyrstal.dm | 1 + maps/yw/yw_vrstuff/vrmaps_turfs.dm | 9 + .../species/shadekin/shadekin_abilities.dm | 307 ++++++++++++++++++ .../code/modules/telesci/bscrystal.dm | 24 ++ vorestation.dme | 2 + 9 files changed, 363 insertions(+), 6 deletions(-) create mode 100644 modular_chomp/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm create mode 100644 modular_chomp/code/modules/telesci/bscrystal.dm diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 85df59ef56b..3c303d18ad0 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -8,6 +8,7 @@ #define INVISIBILITY_LIGHTING 20 #define INVISIBILITY_LEVEL_ONE 35 #define INVISIBILITY_LEVEL_TWO 45 +#define INVISIBILITY_SHADEKIN 55 //CHOMPStation change #define INVISIBILITY_OBSERVER 60 #define INVISIBILITY_EYE 61 diff --git a/code/__defines/misc_vr.dm b/code/__defines/misc_vr.dm index b7eb768f6ee..888a2d4aac0 100644 --- a/code/__defines/misc_vr.dm +++ b/code/__defines/misc_vr.dm @@ -42,6 +42,8 @@ #define BLUE_SHIELDED 2 // Shield from bluespace teleportation (telescience) #define TEMPERATURE_SHIELDED 4 // YW Addition: Temperature change shielding +// 8 used for persistence block somewhere else +#define PHASE_SHIELDED 16 // Prevents shadekin phasing in/out in this area //Assistant/Visitor/Whatever #define USELESS_JOB "Visitor" diff --git a/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm b/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm index 032a76628d8..4cee0f6b3f7 100644 --- a/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm +++ b/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm @@ -113,6 +113,9 @@ var/energy_light = 0.25 var/energy_dark = 0.75 + var/phase_gentle = TRUE //CHOMPEdit - Add gentle phasing, defaults to on. + var/doing_phase = FALSE //CHOMPEdit - Prevent bugs when spamming phase button + /datum/species/shadekin/New() ..() for(var/power in shadekin_abilities) @@ -303,27 +306,27 @@ switch(eyecolor_type) if(BLUE_EYES) - total_health = 100 + total_health = 75 //ChompEDIT - balance tweaks energy_light = 0.5 energy_dark = 0.5 if(RED_EYES) - total_health = 200 + total_health = 150 //ChompEDIT - balance tweaks energy_light = -1 energy_dark = 0.1 if(PURPLE_EYES) - total_health = 150 + total_health = 100 //ChompEDIT - balance tweaks energy_light = -0.5 energy_dark = 1 if(YELLOW_EYES) - total_health = 100 + total_health = 50 //ChompEDIT - balance tweaks energy_light = -2 energy_dark = 3 if(GREEN_EYES) - total_health = 100 + total_health = 100 //ChompEDIT - balance tweaks energy_light = 0.125 energy_dark = 2 if(ORANGE_EYES) - total_health = 175 + total_health = 125 //ChompEDIT - balance tweaks energy_light = -0.5 energy_dark = 0.25 diff --git a/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm b/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm index eed09b56c52..6184762866f 100644 --- a/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm +++ b/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm @@ -26,6 +26,7 @@ verbpath = /mob/living/carbon/human/proc/phase_shift ability_icon_state = "tech_passwall" +/* //ChompEDIT - Moved to modular_chomp /mob/living/carbon/human/proc/phase_shift() set name = "Phase Shift (100)" set desc = "Shift yourself out of alignment with realspace to travel quickly to different areas." @@ -164,6 +165,13 @@ density = FALSE force_max_speed = TRUE ability_flags &= ~AB_PHASE_SHIFTING +*/ //ChompEDIT END - moved to modular_chomp + +//CHOMPEdit Start - Shadekin probably shouldn't be hit while phasing +/datum/modifier/shadekin_phase + name = "Shadekin Phasing" + evasion = 100 +//CHOMPEdit End /datum/modifier/shadekin_phase_vision name = "Shadekin Phase Vision" diff --git a/code/modules/telesci/bscyrstal.dm b/code/modules/telesci/bscyrstal.dm index 2349755a7b2..f60a40ce63c 100644 --- a/code/modules/telesci/bscyrstal.dm +++ b/code/modules/telesci/bscyrstal.dm @@ -35,6 +35,7 @@ s.start() if(isliving(hit_atom)) blink_mob(hit_atom) + dephase_shadekin() //ChompEDIT - mess with shadekins qdel(src) // Artifical bluespace crystal, doesn't give you much research. diff --git a/maps/yw/yw_vrstuff/vrmaps_turfs.dm b/maps/yw/yw_vrstuff/vrmaps_turfs.dm index 5f42ff5933d..d4e0671c653 100644 --- a/maps/yw/yw_vrstuff/vrmaps_turfs.dm +++ b/maps/yw/yw_vrstuff/vrmaps_turfs.dm @@ -15,3 +15,12 @@ /turf/unsimulated/floor/irongrass icon ='icons/obj/clockwork_objects.dmi' icon_state = "grass" + + +//YW Addition - no VR for shadekins +/mob/living/carbon/human/shadekin_ability_check() + . = ..() + if(. && istype(get_area(src), /area/vrworld)) + to_chat(src, "The VR systems cannot comprehend this power! This is useless to you!") + . = FALSE +//YW add End diff --git a/modular_chomp/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm b/modular_chomp/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm new file mode 100644 index 00000000000..d763b15c7b2 --- /dev/null +++ b/modular_chomp/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm @@ -0,0 +1,307 @@ +//CHOMPEdit Start - General ability check +/mob/living/carbon/human/proc/shadekin_ability_check() + var/datum/species/shadekin/SK = species + if(!istype(SK)) + to_chat(src, "Only a shadekin can use that!") + return FALSE + else if(stat) + to_chat(src, "Can't use that ability in your state!") + return FALSE + /*else if((ability_flags & AB_DARK_RESPITE || has_modifier_of_type(/datum/modifier/dark_respite)) && !(ability_flags & AB_PHASE_SHIFTED)) + to_chat(src, "You can't use that so soon after an emergency warp!") + return FALSE*/ + return TRUE +//CHOMPEdit End + +/mob/living/carbon/human/proc/phase_shift() + set name = "Phase Shift (100)" + set desc = "Shift yourself out of alignment with realspace to travel quickly to different areas." + set category = "Shadekin" + + var/ability_cost = 100 + + var/darkness = 1 + var/turf/T = get_turf(src) + if(!T) + to_chat(src,"You can't use that here!") + return FALSE + if((get_area(src).flags & PHASE_SHIELDED)) //CHOMPAdd - Mapping tools to control phasing + to_chat(src,"This area is preventing you from phasing!") + return FALSE + + if(ability_flags & AB_PHASE_SHIFTING) + return FALSE + + var/brightness = T.get_lumcount() //Brightness in 0.0 to 1.0 + darkness = 1-brightness //Invert + + var/watcher = 0 + //Chompedit start - Nerf to phasing + for(var/thing in orange(7, src)) + if(istype(thing, /mob/living/carbon/human)) + var/mob/living/carbon/human/watchers = thing + if(watchers in oviewers(7,src) && watchers.species != SPECIES_SHADEKIN) // And they can see us... //CHOMPEDIT - (And aren't themselves a shadekin) + if(!(watchers.stat) && !isbelly(watchers.loc) && !istype(watchers.loc, /obj/item/weapon/holder)) // And they are alive and not being held by someone... + watcher++ // They are watching us! + else if(istype(thing, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/watchers = thing + if(watchers in oviewers(7,src)) + if(!watchers.stat && !isbelly(watchers.loc)) + watcher++ //The robot is watching us! + else if(istype(thing, /obj/machinery/camera)) + var/obj/machinery/camera/watchers = thing + if(watchers.can_use()) + if(src in watchers.can_see()) + watcher++ //The camera is watching us! + //CHOMPedit end + + + ability_cost = CLAMP(ability_cost/(0.01+darkness*2),50, 80)//This allows for 1 watcher in full light + if(watcher>0) + ability_cost = ability_cost + ( 15 * watcher ) + if(!(ability_flags & AB_PHASE_SHIFTED)) + log_debug("[src] attempted to shift with [watcher] observers with a cost of [ability_cost] in a darkness level of [darkness]") + //CHOMPEdit start - inform about the observers affecting phasing + if(darkness<=0.4 && watcher>=2) + to_chat(src, "You have a few observers in a well-lit area! This may prevent phasing. (Working cameras count towards observers)") + else if(watcher>=3) + to_chat(src, "You have a large number of observers! This may prevent phasing. (Working cameras count towards observers)") + //CHOMPEdit end + + + var/datum/species/shadekin/SK = species + /* CHOMPEdit start - general shadekin ability check + if(!istype(SK)) + to_chat(src, "Only a shadekin can use that!") + return FALSE + else if(stat) + to_chat(src, "Can't use that ability in your state!") + return FALSE + //CHOMPEdit Start - Dark Respite + else if((ability_flags & AB_DARK_RESPITE || has_modifier_of_type(/datum/modifier/dark_respite)) && !(ability_flags & AB_PHASE_SHIFTED)) + to_chat(src, "You can't use that so soon after an emergency warp!") + return FALSE + */ + if(!shadekin_ability_check()) + return FALSE + //CHOMPEdit End + //CHOMPEdit Start - Prevent bugs when spamming phase button + else if(SK.doing_phase) + to_chat(src, "You are already trying to phase!") + return FALSE + //CHOMPEdit End + + else if(shadekin_get_energy() < ability_cost && !(ability_flags & AB_PHASE_SHIFTED)) + to_chat(src, "Not enough energy for that ability!") + return FALSE + + if(!(ability_flags & AB_PHASE_SHIFTED)) + shadekin_adjust_energy(-ability_cost) + playsound(src, 'sound/effects/stealthoff.ogg', 75, 1) + + if(!T.CanPass(src,T) || loc != T) + to_chat(src,"You can't use that here!") + return FALSE + + + SK.doing_phase = TRUE //CHOMPEdit - Prevent bugs when spamming phase button + //Shifting in + if(ability_flags & AB_PHASE_SHIFTED) + phase_in(T) + //Shifting out + else + phase_out(T) + SK.doing_phase = FALSE //CHOMPEdit - Prevent bugs when spamming phase button + + + +/mob/living/carbon/human/proc/phase_in(var/turf/T) + if(ability_flags & AB_PHASE_SHIFTED) + var/datum/species/shadekin/SK = species + + // pre-change + forceMove(T) + var/original_canmove = canmove + SetStunned(0) + SetWeakened(0) + if(buckled) + buckled.unbuckle_mob() + if(pulledby) + pulledby.stop_pulling() + stop_pulling() + canmove = FALSE + + // change + ability_flags &= ~AB_PHASE_SHIFTED + ability_flags |= AB_PHASE_SHIFTING + mouse_opacity = 1 + name = get_visible_name() + for(var/obj/belly/B as anything in vore_organs) + B.escapable = initial(B.escapable) + + //cut_overlays() + invisibility = initial(invisibility) + see_invisible = initial(see_invisible) + see_invisible_default = initial(see_invisible_default) // CHOMPEdit - Allow seeing phased entities while phased. + incorporeal_move = initial(incorporeal_move) + density = initial(density) + force_max_speed = initial(force_max_speed) + //CHOMPEdit begin - resetting pull ability after phasing back in + can_pull_size = initial(can_pull_size) + can_pull_mobs = initial(can_pull_mobs) + hovering = initial(hovering) + //CHOMPEdit end + update_icon() + + //Cosmetics mostly + var/obj/effect/temp_visual/shadekin/phase_in/phaseanim = new /obj/effect/temp_visual/shadekin/phase_in(src.loc) + phaseanim.dir = dir + alpha = 0 + custom_emote(1,"phases in!") + sleep(5) //The duration of the TP animation + canmove = original_canmove + alpha = initial(alpha) + remove_modifiers_of_type(/datum/modifier/shadekin_phase_vision) + remove_modifiers_of_type(/datum/modifier/shadekin_phase) //CHOMPEdit - Shadekin probably shouldn't be hit while phasing + + //Potential phase-in vore + if(can_be_drop_pred || can_be_drop_prey) //Toggleable in vore panel + var/list/potentials = living_mobs(0) + if(potentials.len) + var/mob/living/target = pick(potentials) + if(can_be_drop_pred && istype(target) && target.devourable && target.can_be_drop_prey && vore_selected) + target.forceMove(vore_selected) + to_chat(target, "\The [src] phases in around you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!") + to_chat(src, "You phase around [target], [vore_selected.vore_verb]ing them into your [vore_selected.name]!") + else if(can_be_drop_prey && istype(target) && devourable && target.can_be_drop_pred && target.vore_selected) + forceMove(target.vore_selected) + to_chat(target, "\The [src] phases into you, [target.vore_selected.vore_verb]ing them into your [target.vore_selected.name]!") + to_chat(src, "You phase into [target], having them [target.vore_selected.vore_verb] you into their [target.vore_selected.name]!") + + ability_flags &= ~AB_PHASE_SHIFTING + + //Affect nearby lights + var/destroy_lights = 0 + + //CHOMPEdit start - Add back light destruction + if(SK.get_shadekin_eyecolor(src) == RED_EYES) + destroy_lights = 80 + else if(SK.get_shadekin_eyecolor(src) == PURPLE_EYES) + destroy_lights = 25 + //CHOMPEdit end + + //CHOMPEdit start - Add gentle phasing + if(SK.phase_gentle) // gentle case: No light destruction. Flicker in 4 tile radius once. + for(var/obj/machinery/light/L in machines) + if(L.z != z || get_dist(src,L) > 4) + continue + L.flicker(1) + src.Stun(1) + else + //CHOMPEdit end + for(var/obj/machinery/light/L in machines) + if(L.z != z || get_dist(src,L) > 10) + continue + + if(prob(destroy_lights)) + spawn(rand(5,25)) + L.broken() + else + L.flicker(10) + +/mob/living/carbon/human/proc/phase_out(var/turf/T) + if(!(ability_flags & AB_PHASE_SHIFTED)) + // pre-change + forceMove(T) + var/original_canmove = canmove + SetStunned(0) + SetWeakened(0) + if(buckled) + buckled.unbuckle_mob() + if(pulledby) + pulledby.stop_pulling() + stop_pulling() + canmove = FALSE + + // change + ability_flags |= AB_PHASE_SHIFTED + ability_flags |= AB_PHASE_SHIFTING + mouse_opacity = 0 + custom_emote(1,"phases out!") + name = get_visible_name() + + //CHOMPEdit begin - Unequipping slots when phasing in, and preventing pulling stuff while phased. + if(l_hand) + unEquip(l_hand) + if(r_hand) + unEquip(r_hand) + if(back) + unEquip(back) + + can_pull_size = 0 + can_pull_mobs = MOB_PULL_NONE + hovering = TRUE + //CHOMPEdit end + + for(var/obj/belly/B as anything in vore_organs) + B.escapable = FALSE + + var/obj/effect/temp_visual/shadekin/phase_out/phaseanim = new /obj/effect/temp_visual/shadekin/phase_out(src.loc) + phaseanim.dir = dir + alpha = 0 + add_modifier(/datum/modifier/shadekin_phase_vision) + add_modifier(/datum/modifier/shadekin_phase) //CHOMPEdit - Shadekin probably shouldn't be hit while phasing + sleep(5) + invisibility = INVISIBILITY_SHADEKIN + see_invisible = INVISIBILITY_SHADEKIN + see_invisible_default = INVISIBILITY_SHADEKIN // CHOMPEdit - Allow seeing phased entities while phased. + //cut_overlays() + update_icon() + alpha = 127 + + canmove = original_canmove + incorporeal_move = TRUE + density = FALSE + force_max_speed = TRUE + ability_flags &= ~AB_PHASE_SHIFTING + +//CHOMPEdit start - force dephase proc, to be called by other procs to dephase the shadekin. T is the target to force dephase them to. +/mob/living/carbon/human/proc/attack_dephase(var/turf/T = null, atom/dephaser) + var/datum/species/shadekin/SK = species + + // no assigned dephase-target, just use our own + if(!T) + T = get_turf(src) + + // make sure it's possible to be dephased (and we're in phase) + if(!istype(SK) || SK.doing_phase || !T.CanPass(src,T) || loc != T || !(ability_flags & AB_PHASE_SHIFTED) ) + return FALSE + + + log_admin("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.fingerprintslast].") + message_admins("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.fingerprintslast]. (JMP)", 1) + // start the dephase + phase_in(T) + shadekin_adjust_energy(-20) // loss of energy for the interception + // apply a little extra stun for good measure + src.Weaken(3) + +//CHOMPEdit start - gentle phasing for carbonkin +//toggle proc for toggling gentle/normal phasing +/mob/living/carbon/human/proc/phase_strength_toggle() + set name = "Toggle Phase Strength" + set desc = "Toggle strength of phase. Gentle but slower, or faster but destructive to lights." + set category = "Shadekin" + + var/datum/species/shadekin/SK = species + if(!istype(SK)) + to_chat(src, "Only a shadekin can use that!") + return FALSE + + if(SK.phase_gentle) + to_chat(src, "Phasing toggled to Normal. You may damage lights.") + SK.phase_gentle = 0 + else + to_chat(src, "Phasing toggled to Gentle. You won't damage lights, but concentrating on that incurs a short stun.") + SK.phase_gentle = 1 +//CHOMPEdit End diff --git a/modular_chomp/code/modules/telesci/bscrystal.dm b/modular_chomp/code/modules/telesci/bscrystal.dm new file mode 100644 index 00000000000..1d3d443a21b --- /dev/null +++ b/modular_chomp/code/modules/telesci/bscrystal.dm @@ -0,0 +1,24 @@ +// This proc turns the BSC or arti-BSC into a phased-creature mine. +/obj/item/weapon/bluespace_crystal/Crossed(atom/movable/M) + . = ..() + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(H.get_species() == SPECIES_SHADEKIN && (H.ability_flags & AB_PHASE_SHIFTED)) + var/turf/T = get_turf(src) + visible_message("[src] fizzles and disappears as something interacts with it!") + playsound(src, pick('sound/effects/Glassbr1.ogg', 'sound/effects/Glassbr2.ogg', 'sound/effects/Glassbr3.ogg'), 50, 1) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread() + s.set_up(5, 1, T) + s.start() + H.attack_dephase(T, src) + qdel(src) + + +// This proc is the 'Dephase grenade' check. range is changeable. 0=self, 1=3x3, 2=5x5, 3=7x7... +/obj/item/weapon/bluespace_crystal/proc/dephase_shadekin() + var/turf/T = get_turf(src) + for(var/thing in range(3, T)) + if(istype(thing, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = thing + if(H.get_species() == SPECIES_SHADEKIN && (H.ability_flags & AB_PHASE_SHIFTED)) + H.attack_dephase(null, src) diff --git a/vorestation.dme b/vorestation.dme index 15fc430f394..ee0552d0e45 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -4473,4 +4473,6 @@ #include "maps\yw\structures\closets\research.dm" #include "maps\yw\structures\closets\security.dm" #include "maps\~map_system\maps.dm" +#include "modular_chomp\code\modules\mob\living\carbon\human\species\shadekin\shadekin_abilities.dm" +#include "modular_chomp\code\modules\telesci\bscrystal.dm" // END_INCLUDE