From c49d69431a15c540589d75b096dbb20a5fa0bc27 Mon Sep 17 00:00:00 2001 From: kane-f <57303506+kane-f@users.noreply.github.com> Date: Thu, 24 Jun 2021 16:11:27 +0100 Subject: [PATCH] New mime uplink spell: Invisible Un-wall (#29706) * Basis of spell * Spellbook and uplink entry * Only mimes can read it * Spell rework * Indent fix * Table hotfix * Checks to prevent players breaking some maps and whatnot * Reimplementation as requested * Movables... * Further reimplementation * Typo * Duration handle fix * Documenting spell * Duration has to be defined itself * Description fix * Allowing turfs to be targeted * Trying this to include turfs * Annoying workaround but it'll do * Removing from bundle * New recoil * Fix * Fix * Works better in uncross * Here too * Oh wow * Performance tweak * This is redundant * Requested fixes Co-authored-by: kanef --- code/datums/uplink_item.dm | 7 ++ .../game/gamemodes/wizard/spellbook_oneuse.dm | 41 +++++++++--- code/game/machinery/doors/airlock.dm | 2 + code/game/machinery/doors/firedoor.dm | 4 ++ code/game/machinery/doors/windowdoor.dm | 4 ++ code/game/objects/structures/fullwindow.dm | 1 - code/game/objects/structures/tables_racks.dm | 4 ++ code/game/objects/structures/window.dm | 4 ++ code/modules/power/treadmill.dm | 4 ++ .../spells/aoe_turf/conjure/forcewall.dm | 65 +++++++++++++++++++ 10 files changed, 126 insertions(+), 10 deletions(-) diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 37b08b4ee72..565a1077e5b 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -998,6 +998,13 @@ var/list/uplink_items = list() cost = 12 jobs_exclusive = list("Mime") +/datum/uplink_item/jobspecific/clown_mime/unwall_spell + name = "Invisible Un-Wall Spellbook" + desc = "Grants the user the ability to conjure a strange wall allowing the passage of anything through a space regardless of the objects in place. Only real Mimes are capable of learning from this forbidden tome." + item = /obj/item/weapon/spellbook/oneuse/unwall + cost = 12 + jobs_exclusive = list("Mime") + /datum/uplink_item/jobspecific/clown_mime/punchline name = "Punchline" desc = "A high risk high reward abomination combining experimental phazon and bananium technologies. Wind-up Punchline to charge it. Enough charge and your targets will slip through reality. Warning: Forcing wind-ups beyond the limiter may reverse the prototype phazite honkpacitors and disrupt reality around the user." diff --git a/code/game/gamemodes/wizard/spellbook_oneuse.dm b/code/game/gamemodes/wizard/spellbook_oneuse.dm index ebc5caa08bd..729f3425397 100644 --- a/code/game/gamemodes/wizard/spellbook_oneuse.dm +++ b/code/game/gamemodes/wizard/spellbook_oneuse.dm @@ -17,7 +17,7 @@ ..() name += spellname -/obj/item/weapon/spellbook/oneuse/attack_self(mob/user as mob) +/obj/item/weapon/spellbook/oneuse/attack_self(mob/user) var/spell/S = new spell(user) for(var/spell/knownspell in user.spell_list) if(knownspell.type == S.type) @@ -36,10 +36,10 @@ user.attack_log += text("\[[time_stamp()]\] [user.real_name] ([user.ckey]) learned the spell [spellname] ([S]).") onlearned(user) -/obj/item/weapon/spellbook/oneuse/proc/recoil(mob/user as mob) +/obj/item/weapon/spellbook/oneuse/proc/recoil(mob/user) user.visible_message("[src] glows in a black light!") -/obj/item/weapon/spellbook/oneuse/proc/onlearned(mob/user as mob) +/obj/item/weapon/spellbook/oneuse/proc/onlearned(mob/user) used = 1 user.visible_message("[src] glows dark for a second!") @@ -52,7 +52,7 @@ icon_state ="bookfireball" desc = "This book feels warm to the touch." -/obj/item/weapon/spellbook/oneuse/fireball/recoil(mob/user as mob) +/obj/item/weapon/spellbook/oneuse/fireball/recoil(mob/user) ..() explosion(user.loc, -1, 0, 2, 3, 0) qdel(src) @@ -75,7 +75,7 @@ icon_state ="bookblind" desc = "This book looks blurry, no matter how you look at it." -/obj/item/weapon/spellbook/oneuse/blind/recoil(mob/user as mob) +/obj/item/weapon/spellbook/oneuse/blind/recoil(mob/user) ..() to_chat(user, "You go blind!") user.eye_blind = 10 @@ -103,13 +103,36 @@ icon_state ="bookforcewall" desc = "This book has a dedication to mimes everywhere inside the front cover." -/obj/item/weapon/spellbook/oneuse/forcewall/recoil(mob/user as mob) +/obj/item/weapon/spellbook/oneuse/forcewall/recoil(mob/user) ..() to_chat(user, "You suddenly feel very solid!") var/obj/structure/closet/statue/S = new /obj/structure/closet/statue(user.loc, user) S.timer = 30 user.drop_item() +/obj/item/weapon/spellbook/oneuse/unwall + spell = /spell/targeted/mime_unwall + spellname = "unwall" + icon_state ="bookforcewall" + desc = "This book has a dedication to finger gun-toting mimes everywhere inside the front cover." + disabled_from_bundle = 1 + +/obj/item/weapon/spellbook/oneuse/unwall/attack_self(mob/user) + if(ishuman(user)) + var/mob/living/carbon/human/M = user + if(!issilent(M)) + recoil(user) + else + recoil(user) + ..() + +/obj/item/weapon/spellbook/oneuse/unwall/recoil(mob/user) + ..() + to_chat(user, "You suddenly feel very silent!") + if(ishuman(user)) + var/mob/living/carbon/human/M = user + M.flash_eyes(visual = 1) + user.mind.miming = MIMING_OUT_OF_CURSE /obj/item/weapon/spellbook/oneuse/knock spell = /spell/aoe_turf/knock @@ -117,7 +140,7 @@ icon_state ="bookknock" desc = "This book is hard to hold closed properly." -/obj/item/weapon/spellbook/oneuse/knock/recoil(mob/user as mob) +/obj/item/weapon/spellbook/oneuse/knock/recoil(mob/user) ..() to_chat(user, "You're knocked down!") user.Knockdown(20) @@ -128,7 +151,7 @@ icon_state ="bookhangman" desc = "This book has some letters blanked out in the words." -/obj/item/weapon/spellbook/oneuse/hangman/recoil(mob/user as mob) +/obj/item/weapon/spellbook/oneuse/hangman/recoil(mob/user) ..() if(ishuman(user)) var/mob/living/carbon/human/H = user @@ -160,7 +183,7 @@ desc = "This book is made of 100% post-consumer wizard." disabled_from_bundle = 1 -/obj/item/weapon/spellbook/oneuse/charge/recoil(mob/user as mob) +/obj/item/weapon/spellbook/oneuse/charge/recoil(mob/user) ..() to_chat(user, "[src] suddenly feels very warm!") empulse(src, 1, 1) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 9a1a3068342..134e3d5e5b5 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1368,6 +1368,8 @@ About the new airlock wires panel: wires.SignalIndex(AIRLOCK_WIRE_ONOPEN) /obj/machinery/door/airlock/Uncross(atom/movable/mover) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this, especially because of that thing below -kanef + return 1 if(density && ismob(mover) && !(mover.checkpass(PASSGLASS) && !opacity) && !(mover.checkpass(PASSDOOR)) && !(istype(mover,/mob/living/simple_animal/shade)))//REEEEEEE to_chat(mover, "You are pinned inside the closed airlock; you can't move!") return 0 diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index a7c1b958841..336eef616eb 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -603,6 +603,8 @@ var/global/list/alert_overlays_global = list() flow_flags = ON_BORDER /obj/machinery/door/firedoor/border_only/Cross(atom/movable/mover, turf/target, height=1.5, air_group = 0) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this -kanef + return 1 if(istype(mover) && (mover.checkpass(PASSDOOR|PASSGLASS))) return 1 if(get_dir(loc, target) == dir || get_dir(loc, mover) == dir) @@ -620,6 +622,8 @@ var/global/list/alert_overlays_global = list() close() /obj/machinery/door/firedoor/border_only/Uncross(atom/movable/mover as mob|obj, turf/target as turf) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this -kanef + return 1 if(istype(mover) && (mover.checkpass(PASSDOOR|PASSGLASS))) return 1 if(flow_flags & ON_BORDER) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 8b50a944809..250fc211965 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -105,6 +105,8 @@ close() /obj/machinery/door/window/Cross(atom/movable/mover, turf/target, height=1.5, air_group = 0) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this -kanef + return 1 if(istype(mover) && (mover.checkpass(PASSDOOR|PASSGLASS))) return TRUE if(get_dir(loc, target) == dir || get_dir(loc, mover) == dir) @@ -119,6 +121,8 @@ return !density || (dir != to_dir) || check_access(ID) /obj/machinery/door/window/Uncross(atom/movable/mover, turf/target) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this -kanef + return 1 if(istype(mover) && (mover.checkpass(PASSDOOR|PASSGLASS))) return TRUE if(flow_flags & ON_BORDER) //but it will always be on border tho diff --git a/code/game/objects/structures/fullwindow.dm b/code/game/objects/structures/fullwindow.dm index 2f5f0f10566..1d23449c024 100644 --- a/code/game/objects/structures/fullwindow.dm +++ b/code/game/objects/structures/fullwindow.dm @@ -26,7 +26,6 @@ return 1 /obj/structure/window/full/Cross(atom/movable/mover, turf/target, height = 1.5, air_group = 0) - if(istype(mover) && mover.checkpass(PASSGLASS)) dim_beam(mover) return 1 diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 1d51833e21f..2587915918b 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -301,6 +301,8 @@ return /obj/structure/table/Cross(atom/movable/mover, turf/target, height=1.5, air_group = 0) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this -kanef + return 1 if(air_group || (height==0)) return 1 if(istype(mover,/obj/item/projectile)) @@ -346,6 +348,8 @@ return 1 /obj/structure/table/Uncross(atom/movable/mover as mob|obj, target as turf) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this -kanef + return 1 if(istype(mover) && mover.checkpass(PASSTABLE)) return 1 if(flow_flags & ON_BORDER) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index caebb8c6bb1..97f6967e80c 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -173,6 +173,8 @@ var/list/one_way_windows healthcheck() /obj/structure/window/Uncross(var/atom/movable/mover, var/turf/target) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this -kanef + return 1 if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 if(flow_flags & ON_BORDER) @@ -186,6 +188,8 @@ var/list/one_way_windows return 1 /obj/structure/window/Cross(atom/movable/mover, turf/target, height = 0) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this -kanef + return 1 if(istype(mover) && mover.checkpass(PASSGLASS))//checking for beam dispersion both in and out, since beams do not trigger Uncross. if((get_dir(loc, target) & dir) || (get_dir(loc, mover) & dir) || (get_dir(loc, target) & reverse_direction(dir)) || (get_dir(loc, mover) & reverse_direction(dir))) dim_beam(mover) diff --git a/code/modules/power/treadmill.dm b/code/modules/power/treadmill.dm index 8b0a04ef988..a20f9cf4928 100644 --- a/code/modules/power/treadmill.dm +++ b/code/modules/power/treadmill.dm @@ -83,6 +83,8 @@ to_chat(runner,"You're exhausted! You can't run anymore!") /obj/machinery/power/treadmill/Uncross(var/atom/movable/mover, var/turf/target) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this -kanef + return 1 if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 if((flow_flags & ON_BORDER) && (mover.dir == dir)) @@ -91,6 +93,8 @@ return 1 /obj/machinery/power/treadmill/Cross(atom/movable/mover, turf/target, height=1.5, air_group = 0) + if(locate(/obj/effect/unwall_field) in loc) //Annoying workaround for this -kanef + return 1 if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 if(get_dir(loc, target) == dir || get_dir(loc, mover) == dir) diff --git a/code/modules/spells/aoe_turf/conjure/forcewall.dm b/code/modules/spells/aoe_turf/conjure/forcewall.dm index 60e2d313c6d..4236b83375e 100644 --- a/code/modules/spells/aoe_turf/conjure/forcewall.dm +++ b/code/modules/spells/aoe_turf/conjure/forcewall.dm @@ -32,6 +32,40 @@ override_base = "grey" hud_state = "mime_wall" +/* +Unwall spell, sadly has to be targeted to be any fun to use +-kanef +*/ +/spell/targeted/mime_unwall + name = "Invisible un-wall" + desc = "Create an invisible un-wall on a targeted location, an anomaly allowing the passage of all objects through anything on it." + school = "mime" + abbreviation = "FW" + user_type = USER_TYPE_OTHER + panel = "Mime" + specialization = SSOFFENSIVE + + school = "mime" + charge_max = 300 + cast_sound = null + cooldown_min = 2 SECONDS + spell_flags = WAIT_FOR_CLICK + range = 1 + max_targets = 1 + invocation_type = SpI_EMOTE + invocation = "mimes placing their hands on a flat surface, and pushing against it." + + override_base = "grey" + hud_state = "mime_wall" + +/spell/targeted/mime_unwall/cast(var/list/targets, mob/user) + ..() + for(var/atom/target in targets) + if(isturf(target)) + new /obj/effect/unwall_field(target) + else + new /obj/effect/unwall_field(target.loc) + /obj/effect/forcefield desc = "A space wizard's magic wall." name = "FORCEWALL" @@ -69,3 +103,34 @@ new /obj/effect/forcefield/cult(get_turf(src)) qdel(src) return + +/* +Unwall fields +-kanef +*/ +/obj/effect/unwall_field + icon = 'icons/effects/effects.dmi' + icon_state = "fuel" + name = "invisible un-wall" + desc = "You have a REALLY bad feeling about this." + anchored = 1.0 + opacity = 0 + var/duration = 300 // How long the wall lasts, in ticks + var/static/list/forbidden_passes = list(/turf/unsimulated/wall,/turf/simulated/wall/invulnerable,/obj/structure/grille/invulnerable) // To stop people breaking maps like centcomm or lamprey stuff + +/obj/effect/unwall_field/permanent // For future mapping or bus shenanigans + duration = 0 // Forever + +/obj/effect/unwall_field/New() + ..() + if(duration) // Wait the duration if any and delete it, if zero, don't + spawn(duration) + qdel(src) + +/obj/effect/unwall_field/to_bump(atom/movable/A) + if(is_type_in_list(src.loc,forbidden_passes)) + return + for(var/atom/B in src.loc) // Go through everything, discount passing through forbidden stuff + if(is_type_in_list(B,forbidden_passes)) + return + A.forceMove(src.loc) \ No newline at end of file