diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 6e95048bd7f..2c56d1201b5 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -21,7 +21,8 @@ /obj/effect/overlay/temp anchored = 1 - layer = 3.3 + layer = 4.1 + mouse_opacity = 0 var/duration = 10 var/randomdir = 1 @@ -37,7 +38,7 @@ icon_state = "purplesparkles" /obj/effect/overlay/temp/revenant/cracks - name = "spooky lights" + name = "glowing cracks" icon_state = "purplecrack" duration = 6 diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index 1981e552192..bab0a4e07e4 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -54,8 +54,8 @@ locked = 0 desc += "It appears to be broken." icon_state = src.icon_broken - for(var/mob/O in viewers(user, 3)) - O.show_message(text("\The [src] has been broken by [] with an electromagnetic card!", user), 1, text("You hear a faint electrical spark."), 2) + if(user) + visible_message("\The [src] has been broken by [user] with an electromagnetic card!") return /obj/item/weapon/storage/lockbox/show_to(mob/user) if(locked) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 0975f933063..fc34408821c 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -402,8 +402,8 @@ locked = 0 desc += " It appears to be broken." update_icon() - for(var/mob/O in viewers(user, 3)) - O.show_message("The locker has been broken by [user] with an electromagnetic card!", 1, "You hear a faint electrical spark.", 2) + if(user) + visible_message("The [name] has been broken by [user] with an electromagnetic card!", "You hear a faint electrical spark.") overlays += "sparking" spawn(4) //overlays don't support flick so we have to cheat update_icon() diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm index 5ecd4d5e558..fa176aea591 100644 --- a/code/modules/assembly/flash.dm +++ b/code/modules/assembly/flash.dm @@ -44,10 +44,11 @@ /obj/item/device/assembly/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something. - crit_fail = 1 - update_icon() - var/turf/T = get_turf(src) - T.visible_message("The [src.name] burns out!") + if(!crit_fail) + crit_fail = 1 + update_icon() + var/turf/T = get_turf(src) + T.visible_message("The [src.name] burns out!") /obj/item/device/assembly/flash/proc/flash_recharge(interval=10) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index a2820d63dee..5e91b7a4eb0 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -3,7 +3,7 @@ //Don't hear deadchat and are NOT normal ghosts //Admin-spawn or random event -#define INVISIBILITY_REVENANT 30 +#define INVISIBILITY_REVENANT 50 /mob/living/simple_animal/revenant name = "revenant" @@ -14,6 +14,8 @@ invisibility = INVISIBILITY_REVENANT health = INFINITY //Revenants don't use health, they use essence instead maxHealth = INFINITY + alpha = 160 + layer = 5 healable = 0 see_invisible = SEE_INVISIBLE_MINIMUM see_in_dark = 8 @@ -51,7 +53,6 @@ /mob/living/simple_animal/revenant/Life() - ..() ear_damage = 0 ear_deaf = 0 //YOU CAN'T DEAFEN A REVENANT if(revealed && essence <= 0) @@ -60,6 +61,7 @@ unreveal_time = 0 revealed = 0 invisibility = INVISIBILITY_REVENANT + alpha = 160 src << "You are once more concealed." if(unstun_time && world.time >= unstun_time) unstun_time = 0 @@ -67,6 +69,7 @@ src << "You can move again!" if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate essence = min(essence_regen_cap, essence+essence_regen_amount) + ..() /mob/living/simple_animal/revenant/proc/reveal(time) @@ -76,6 +79,7 @@ return revealed = 1 invisibility = 0 + alpha = 255 if(!unreveal_time) src << "You have been revealed!" else @@ -112,8 +116,7 @@ /mob/living/simple_animal/revenant/ClickOn(atom/A, params) //Copypaste from ghost code - revenants can't interact with the world directly. - if(client.inquisitive_ghost) - A.examine(src) + A.examine(src) if(ishuman(A) && in_range(src, A)) Harvest(A) @@ -163,15 +166,17 @@ src << "You begin siphoning essence from [target]'s soul." if(target.stat != DEAD) target << "You feel a horribly unpleasant draining sensation as your grip on life weakens..." - icon_state = "revenant_draining" - reveal(27) - stun(27) + reveal(46) + stun(46) target.visible_message("[target] suddenly rises slightly into the air, their skin turning an ashy gray.") - target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=24) - if(do_after(src, 30, 9, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. + target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=44) + if(do_after(src, 50, 15, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. change_essence_amount(essence_drained, 0, target) + if(essence_drained <= 90 && target.stat != DEAD) + essence_regen_cap += 5 + src << "The absorption of [target]'s living soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap]." if(essence_drained > 90) - essence_regen_cap += 25 + essence_regen_cap += 15 perfectsouls += 1 src << "The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap]." src << "[target]'s soul has been considerably weakened and will yield no more essence for the time being." @@ -236,9 +241,9 @@ src << "Objective #2: [objective2.explanation_text]" ticker.mode.traitors |= src.mind //Necessary for announcing AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null)) - AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_light(null)) - AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile(null)) - AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf(null)) + AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null)) + AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/overload(null)) + AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction(null)) /mob/living/simple_animal/revenant/death() diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm index cbdfcf5f94f..097e135c21d 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm @@ -1,4 +1,4 @@ -//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E. +//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob /obj/effect/proc_holder/spell/targeted/revenant_transmit name = "Transmit" desc = "Telepathically transmits a message to the target." @@ -21,170 +21,171 @@ M << "An alien voice resonates from all around... [msg]" -//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people. -/obj/effect/proc_holder/spell/aoe_turf/revenant_light - name = "Overload Lights (100E)" - desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby." - panel = "Revenant Abilities (Locked)" - charge_max = 200 +/obj/effect/proc_holder/spell/aoe_turf/revenant clothes_req = 0 - range = 5 - var/shock_range = 2 - var/shock_damage = 20 - var/reveal = 80 - var/stun = 40 - var/locked = 1 - action_icon_state = "overload_lights" action_background_icon_state = "bg_revenant" + panel = "Revenant Abilities (Locked)" + name = "Report this to a coder" + var/reveal = 80 //How long it reveals the revenant in deciseconds + var/stun = 20 //How long it stuns the revenant in deciseconds + var/locked = 1 //If it's locked and needs to be unlocked before use + var/unlock_amount = 100 //How much essence it costs to unlock + var/cast_amount = 50 //How much essence it costs to use -/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, mob/living/simple_animal/revenant/user = usr) +/obj/effect/proc_holder/spell/aoe_turf/revenant/New() + ..() if(locked) - if(!user.castcheck(-100)) + name = "[initial(name)] ([unlock_amount]E)" + else + name = "[initial(name)] ([cast_amount]E)" + +/obj/effect/proc_holder/spell/aoe_turf/revenant/can_cast(mob/living/simple_animal/revenant/user = usr) + if(user.inhibited) + return 0 + if(charge_counter < charge_max) + return 0 + if(locked) + if(user.essence <= unlock_amount) + return 0 + if(user.essence <= cast_amount) + return 0 + return 1 + +/obj/effect/proc_holder/spell/aoe_turf/revenant/proc/attempt_cast(mob/living/simple_animal/revenant/user = usr) + if(locked) + if(!user.castcheck(-unlock_amount)) charge_counter = charge_max - return - user << "You have unlocked Overload Lights!" - name = "Overload Lights (40E)" + return 0 + name = "[initial(name)] ([cast_amount]E)" + user << "You have unlocked [initial(name)]!" panel = "Revenant Abilities" locked = 0 charge_counter = charge_max - return - if(!user.castcheck(-40)) + return 0 + if(!user.castcheck(-cast_amount)) charge_counter = charge_max - return - for(var/turf/T in targets) - spawn(0) - for(var/obj/machinery/light/L in T.contents) - spawn(0) - if(!L.on) - return - L.visible_message("\The [L] suddenly flares brightly and begins to spark!") - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(4, 0, L) - s.start() - new/obj/effect/overlay/temp/revenant(L.loc) - sleep(20) - flick("[L.base_state]2", L) - for(var/mob/living/carbon/human/M in range(shock_range, L)) - if(M == user) - return - M.Beam(L,icon_state="purple_lightning",icon='icons/effects/effects.dmi',time=5) - M.electrocute_act(shock_damage, "[L.name]", safety=1) - var/datum/effect_system/spark_spread/z = new /datum/effect_system/spark_spread - z.set_up(4, 0, M) - z.start() - playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1) + return 0 + name = "[initial(name)] ([cast_amount]E)" user.reveal(reveal) user.stun(stun) + user.update_action_buttons() + return 1 +//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people. +/obj/effect/proc_holder/spell/aoe_turf/revenant/overload + name = "Overload Lights" + desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby." + charge_max = 200 + range = 5 + stun = 40 + cast_amount = 45 + var/shock_range = 2 + var/shock_damage = 18 + action_icon_state = "overload_lights" + +/obj/effect/proc_holder/spell/aoe_turf/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr) + if(attempt_cast(user)) + for(var/turf/T in targets) + spawn(0) + for(var/obj/machinery/light/L in T.contents) + spawn(0) + if(!L.on) + return + L.visible_message("\The [L] suddenly flares brightly and begins to spark!") + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(4, 0, L) + s.start() + new/obj/effect/overlay/temp/revenant(L.loc) + sleep(20) + if(!L.on) //wait, wait, don't shock me + return + flick("[L.base_state]2", L) + for(var/mob/living/carbon/human/M in range(shock_range, L)) + if(M == user) + return + M.Beam(L,icon_state="purple_lightning",icon='icons/effects/effects.dmi',time=5) + M.electrocute_act(shock_damage, "[L.name]", safety=1) + var/datum/effect_system/spark_spread/z = new /datum/effect_system/spark_spread + z.set_up(4, 0, M) + z.start() + playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1) //Defile: Corrupts nearby stuff, unblesses floor tiles. -/obj/effect/proc_holder/spell/aoe_turf/revenant_defile - name = "Defile (75E)" - desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors." - panel = "Revenant Abilities (Locked)" +/obj/effect/proc_holder/spell/aoe_turf/revenant/defile + name = "Defile" + desc = "Twists and corrupts the nearby area as well as dispelling holy auras on floors." charge_max = 150 - clothes_req = 0 range = 3 - var/reveal = 80 - var/stun = 20 - var/locked = 1 + stun = 30 + unlock_amount = 75 + cast_amount = 40 action_icon_state = "defile" - action_background_icon_state = "bg_revenant" - -/obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - if(locked) - if(!user.castcheck(-75)) - charge_counter = charge_max - return - user << "You have unlocked Defile!" - name = "Defile (30E)" - panel = "Revenant Abilities" - locked = 0 - charge_counter = charge_max - return - if(!user.castcheck(-30)) - charge_counter = charge_max - return - for(var/turf/T in targets) - spawn(0) - if(T.flags & NOJAUNT) - T.flags -= NOJAUNT - new/obj/effect/overlay/temp/revenant(T) - for(var/mob/living/carbon/human/human in T.contents) - human << "You suddenly feel tired." - human.adjustStaminaLoss(40) - new/obj/effect/overlay/temp/revenant(human.loc) - if(!istype(T, /turf/simulated/wall/rust) && !istype(T, /turf/simulated/wall/r_wall) && istype(T, /turf/simulated/wall) && prob(15)) - new/obj/effect/overlay/temp/revenant(T) - T.ChangeTurf(/turf/simulated/wall/rust) - if(!istype(T, /turf/simulated/wall/r_wall/rust) && istype(T, /turf/simulated/wall/r_wall) && prob(15)) - new/obj/effect/overlay/temp/revenant(T) - T.ChangeTurf(/turf/simulated/wall/r_wall/rust) - for(var/obj/structure/window/window in T.contents) - window.hit(rand(50,100)) - if(window && window.fulltile) - new/obj/effect/overlay/temp/revenant/cracks(window.loc) - for(var/obj/machinery/light/light in T.contents) - light.flicker(30) //spooky - user.reveal(reveal) - user.stun(stun) + var/stamdamage= 25 + var/toxdamage = 3 + var/confusion = 50 +/obj/effect/proc_holder/spell/aoe_turf/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr) + if(attempt_cast(user)) + for(var/turf/T in targets) + spawn(0) + if(T.flags & NOJAUNT) + T.flags -= NOJAUNT + new/obj/effect/overlay/temp/revenant(T) + for(var/mob/living/carbon/human/human in T.contents) + human << "You suddenly feel [pick("sick and tired", "tired and confused", "nauseated", "dizzy")]." + human.adjustStaminaLoss(stamdamage) + human.adjustToxLoss(toxdamage) + human.confused += confusion + new/obj/effect/overlay/temp/revenant(human.loc) + if(!istype(T, /turf/simulated/wall/shuttle) && !istype(T, /turf/simulated/wall/rust) && !istype(T, /turf/simulated/wall/r_wall) && istype(T, /turf/simulated/wall) && prob(15)) + new/obj/effect/overlay/temp/revenant(T) + T.ChangeTurf(/turf/simulated/wall/rust) + if(!istype(T, /turf/simulated/wall/r_wall/rust) && istype(T, /turf/simulated/wall/r_wall) && prob(15)) + new/obj/effect/overlay/temp/revenant(T) + T.ChangeTurf(/turf/simulated/wall/r_wall/rust) + for(var/obj/structure/window/window in T.contents) + window.hit(rand(50,90)) + if(window && window.fulltile) + new/obj/effect/overlay/temp/revenant/cracks(window.loc) + for(var/obj/machinery/light/light in T.contents) + light.flicker(30) //spooky //Malfunction: Makes bad stuff happen to robots and machines. -/obj/effect/proc_holder/spell/aoe_turf/revenant_malf - name = "Malfunction (150E)" +/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction + name = "Malfunction" desc = "Corrupts and damages nearby machines and mechanical objects." - panel = "Revenant Abilities (Locked)" charge_max = 200 - clothes_req = 0 range = 4 - var/reveal = 80 - var/stun = 20 - var/locked = 1 + unlock_amount = 150 action_icon_state = "malfunction" - action_background_icon_state = "bg_revenant" -/obj/effect/proc_holder/spell/aoe_turf/revenant_malf/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - if(locked) - if(!user.castcheck(-150)) - charge_counter = charge_max - return - user << "You have unlocked Malfunction!" - name = "Malfunction (45E)" - panel = "Revenant Abilities" - locked = 0 - charge_counter = charge_max - return - if(!user.castcheck(-45)) - charge_counter = charge_max - return - for(var/turf/T in targets) - spawn(0) - for(var/obj/machinery/bot/bot in T.contents) - if(!bot.emagged) - new/obj/effect/overlay/temp/revenant(bot.loc) - bot.locked = 0 - bot.open = 1 - bot.Emag(null) - for(var/mob/living/carbon/human/human in T.contents) - human << "You feel disoriented." - new/obj/effect/overlay/temp/revenant(human.loc) - human.emp_act(1) - for(var/obj/machinery/mach in T.contents) - if(istype(mach, /obj/machinery/dominator) || istype(mach, /obj/machinery/power/apc) || istype(mach, /obj/machinery/power/smes) || istype(mach, /obj/machinery/bot)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery //Also doesn't work on bots so they can go do stuff faster(god this is so ugly) - continue - if(prob(30)) - new/obj/effect/overlay/temp/revenant(mach.loc) - mach.emag_act(null) - else - if(!istype(mach, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all - mach.emp_act(1) - for(var/mob/living/silicon/robot/S in T.contents) //Only works on cyborgs, not AI - S << "ERROR $!(@ ERROR )#^! SENSORY OVERLOAD \[$(!@#" - S << 'sound/misc/interference.ogg' - playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1) - new/obj/effect/overlay/temp/revenant(S.loc) - S.spark_system.start() - S.Weaken(6) - user.reveal(reveal) - user.stun(stun) \ No newline at end of file +//A note to future coders: do not replace this with an EMP because it will wreck malf AIs and gang dominators and everyone will hate you. +/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction/cast(list/targets, mob/living/simple_animal/revenant/user = usr) + if(attempt_cast(user)) + for(var/turf/T in targets) + spawn(0) + for(var/obj/machinery/bot/bot in T.contents) + if(!bot.emagged) + new/obj/effect/overlay/temp/revenant(bot.loc) + bot.locked = 0 + bot.open = 1 + bot.Emag(null) + for(var/mob/living/carbon/human/human in T.contents) + human << "You feel [pick("your sense of direction flicker out", "a stabbing pain in your head", "your mind fill with static")]." + new/obj/effect/overlay/temp/revenant(human.loc) + human.emp_act(1) + for(var/obj/thing in T.contents) + if(istype(thing, /obj/machinery/dominator) || istype(thing, /obj/machinery/power/apc) || istype(thing, /obj/machinery/power/smes) || istype(thing, /obj/machinery/bot)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery + continue + if(prob(20)) + if(prob(50)) + new/obj/effect/overlay/temp/revenant(thing.loc) + thing.emag_act(null) + else + if(!istype(thing, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all + thing.emp_act(1) + for(var/mob/living/silicon/robot/S in T.contents) //Only works on cyborgs, not AI + playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1) + new/obj/effect/overlay/temp/revenant(S.loc) + S.spark_system.start() + S.emp_act(1) \ No newline at end of file diff --git a/html/changelogs/Joan - REVENANTS REEE.yml b/html/changelogs/Joan - REVENANTS REEE.yml new file mode 100644 index 00000000000..42854ba8bf2 --- /dev/null +++ b/html/changelogs/Joan - REVENANTS REEE.yml @@ -0,0 +1,42 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +# tgs (TG-ported fixes?) +################################# + +# Your name. +author: Joan + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Revenant draining now takes about 5 seconds to complete and can be interrupted by dragging the target away." + - tweak: "Revenants can now tell if they are currently visible." + - tweak: "Revenant ability costs tweaked; Defile now costs 40 essence to cast, Overload Lights now costs 45 essence to cast, and Malfunction now costs 50 essence to cast." + - tweak: "Malfunction now affects non-machine objects, even if they're not being held by a human." + - tweak: "Defile does an extremely low amount of toxin damage to humans and confuses, but does much less stamina damage and stuns the revenant for slightly longer." + - tweak: "Overload Lights will no longer shock if the light is broken after a light is chosen to shock an area." + diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 26b2c2415a1..b2cb80edcfb 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ