From ed24ac47de08a88a717bda059aea5bd5f9dde0c2 Mon Sep 17 00:00:00 2001 From: DZD Date: Fri, 31 Jul 2015 18:15:45 -0400 Subject: [PATCH] Up to date with -tg- - Ports /tgstation/-tg-station#10871. - Fixes some errors currently present in the above. - Ports /tgstation/-tg-station#9927. --- code/datums/mind.dm | 19 +- .../shadowling/ascendant_shadowling.dm | 12 +- code/game/gamemodes/shadowling/shadowling.dm | 49 ++- .../shadowling/shadowling_abilities.dm | 170 +++++++--- .../gamemodes/shadowling/shadowling_items.dm | 3 +- .../special_shadowling_abilities.dm | 302 +++++++++--------- code/game/gamemodes/wizard/wizard.dm | 7 + code/game/turfs/turf.dm | 5 + .../mob/living/carbon/human/examine.dm | 2 + code/modules/mob/living/carbon/human/life.dm | 12 +- .../modules/mob/living/silicon/robot/login.dm | 1 + 11 files changed, 356 insertions(+), 226 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 853191a4d7d..1b0503faad6 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -971,14 +971,11 @@ datum/mind current.mind.spell_list.Cut() message_admins("[key_name_admin(usr)] has de-shadowling'ed [current].") log_admin("[key_name(usr)] has de-shadowling'ed [current].") - current.verbs -= /mob/living/carbon/human/proc/shadowling_hatch - current.verbs -= /mob/living/carbon/human/proc/shadowling_ascendance + remove_spell(/obj/effect/proc_holder/spell/wizard/targeted/shadowling_hatch) + remove_spell(/obj/effect/proc_holder/spell/wizard/targeted/shadowling_ascend) current.remove_language("Shadowling Hivemind") else if(src in ticker.mode.shadowling_thralls) - ticker.mode.shadowling_thralls -= src - special_role = null - current.remove_language("Shadowling Hivemind") - current << "You have been brainwashed! You are no longer a thrall!" + ticker.mode.remove_thrall(src,0) message_admins("[key_name_admin(usr)] has de-thrall'ed [current].") log_admin("[key_name(usr)] has de-thrall'ed [current].") if("shadowling") @@ -987,9 +984,9 @@ datum/mind return ticker.mode.shadows += src special_role = "Shadowling" - current << "You notice a brightening around you. No, it isn't that. The shadows grow, darken, swirl. The darkness has a new welcome for you, and you realize with a \ - start that you can't be human. No, you are a shadowling, a harbringer of the shadows! Your alien abilities have been unlocked from within, and you may both commune with your allies and use \ - a chrysalis to reveal your true form. You are to ascend at all costs." + current << "Something stirs deep in your mind. A red light floods your vision, and slowly you remember. Though your human disguise has served you well, the \ + time is nigh to cast it off and enter your true form. You have disguised yourself amongst the humans, but you are not one of them. You are a shadowling, and you are to ascend at all costs.\ + " ticker.mode.finalize_shadowling(src) ticker.mode.update_shadow_icons_added(src) if("thrall") @@ -997,10 +994,6 @@ datum/mind usr << "This only works on humans!" return ticker.mode.add_thrall(src) - special_role = "Shadowling Thrall" - current << "All at once it becomes clear to you. Where others see darkness, you see an ally. You realize that the shadows are not dead and dark as one would think, but \ - living, and breathing, and eating. Their children, the Shadowlings, are to be obeyed and protected at all costs." - current << "You may use the Hivemind Commune ability to communicate with your fellow enlightened ones." message_admins("[key_name_admin(usr)] has thrall'ed [current].") log_admin("[key_name(usr)] has thrall'ed [current].") diff --git a/code/game/gamemodes/shadowling/ascendant_shadowling.dm b/code/game/gamemodes/shadowling/ascendant_shadowling.dm index a7c87ca7aa3..0c18d927e53 100644 --- a/code/game/gamemodes/shadowling/ascendant_shadowling.dm +++ b/code/game/gamemodes/shadowling/ascendant_shadowling.dm @@ -18,9 +18,9 @@ response_harm = "flails at" harm_intent_damage = 0 - melee_damage_lower = 35 - melee_damage_upper = 35 - attacktext = "claws at" + melee_damage_lower = 60 //Was 35, buffed + melee_damage_upper = 60 + attacktext = "rends" attack_sound = 'sound/weapons/slash.ogg' minbodytemp = 0 @@ -31,3 +31,9 @@ /mob/living/simple_animal/ascendant_shadowling/Process_Spacemove(var/movement_dir = 0) return 1 //copypasta from carp code + +/mob/living/simple_animal/ascendant_shadowling/ex_act(severity) + return //You think an ascendant can be hurt by bombs? HA + +/mob/living/simple_animal/ascendant_shadowling/singularity_act() + return 0 //Well hi, fellow god! How are you today? \ No newline at end of file diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 0fbb94aaa2e..80c70788fc6 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -86,7 +86,7 @@ Made by Xhuis if(!possible_shadowlings.len) return 0 - var/shadowlings = 2 //How many shadowlings there are; hardcoded to 2 + var/shadowlings = max(2, round(num_players()/10)) //How many shadowlings there are; hardcoded to 2 while(shadowlings) var/datum/mind/shadow = pick(possible_shadowlings) @@ -133,8 +133,8 @@ Made by Xhuis /datum/game_mode/proc/finalize_shadowling(var/datum/mind/shadow_mind) var/mob/living/carbon/human/S = shadow_mind.current - shadow_mind.current.verbs += /mob/living/carbon/human/proc/shadowling_hatch - S.mind.AddSpell(new /obj/effect/proc_holder/spell/wizard/targeted/enthrall) + shadow_mind.current.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/shadowling_hatch) + shadow_mind.current.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/enthrall) spawn(0) shadow_mind.current.add_language("Shadowling Hivemind") update_shadow_icons_added(shadow_mind) @@ -144,18 +144,53 @@ Made by Xhuis shadow_mind.current.hud_updateflag |= (1 << SPECIALROLE_HUD) /datum/game_mode/proc/add_thrall(datum/mind/new_thrall_mind) - if (!istype(new_thrall_mind)) + if(!istype(new_thrall_mind)) return 0 if(!(new_thrall_mind in shadowling_thralls)) shadowling_thralls += new_thrall_mind + new_thrall_mind.special_role = "shadowling thrall" update_shadow_icons_added(new_thrall_mind) new_thrall_mind.current.attack_log += "\[[time_stamp()]\] Became a thrall" - new_thrall_mind.memory += "The Shadowlings' Objectives: [objective_explanation]" - new_thrall_mind.current << "The objectives of the shadowlings: [objective_explanation]" new_thrall_mind.current.add_language("Shadowling Hivemind") + new_thrall_mind.current.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/lesser_glare) + new_thrall_mind.current.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/lesser_shadow_walk) + //new_thrall_mind.current.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/thrall_vision) //Uncomment when vision code is unfucked. + new_thrall_mind.current << "You see the truth. Reality has been torn away and you realize what a fool you've been." + new_thrall_mind.current << "The shadowlings are your masters. Serve them above all else and ensure they complete their goals." + new_thrall_mind.current << "You may not harm other thralls or the shadowlings. However, you do not need to obey other thralls." + new_thrall_mind.current << "Your body has been irreversibly altered. The attentive can see this - you may conceal it by wearing a mask." + new_thrall_mind.current << "Though not nearly as powerful as your masters, you possess some weak powers. These can be found in the Thrall Abilities tab." + new_thrall_mind.current << "You may communicate with your allies by speaking in the Shadowling Hivemind (:8)." + new_thrall_mind.current.hud_updateflag |= (1 << SPECIALROLE_HUD) return 1 +/datum/game_mode/proc/remove_thrall(datum/mind/thrall_mind, var/kill = 0) + if(!istype(thrall_mind) || !(thrall_mind in thralls) || !isliving(thrall_mind.current)) + return 0 //If there is no mind, the mind isn't a thrall, or the mind's mob isn't alive, return + update_shadow_icons_removed(thrall_mind) + thralls.Remove(thrall_mind) + thrall_mind.current.attack_log += "\[[time_stamp()]\] Dethralled" + thrall_mind.special_role = null + thrall_mind.remove_spell(/obj/effect/proc_holder/spell/wizard/targeted/lesser_glare) + thrall_mind.remove_spell(/obj/effect/proc_holder/spell/wizard/targeted/lesser_shadow_walk) + //thrall_mind.remove_spell(/obj/effect/proc_holder/spell/targeted/thrall_vision) //uncomment when vision code is unfucked. + thrall_mind.current.remove_language("Shadowling Hivemind") + if(kill && ishuman(thrall_mind.current)) //If dethrallization surgery fails, kill the mob as well as dethralling them + var/mob/living/carbon/human/H = thrall_mind.current + H.visible_message("[H] jerks violently and falls still.", \ + "A piercing white light floods your mind, banishing your memories as a thrall and--") + H.death() + return 1 + var/mob/living/M = thrall_mind.current + if(issilicon(M)) + M.audible_message("[M] lets out a short blip.", \ + "You have been turned into a robot! You are no longer a thrall! Though you try, you cannot remember anything about your servitude...") + else + M.visible_message("[M] looks like their mind is their own again!", \ + "A piercing white light floods your eyes. Your mind is your own again! Though you try, you cannot remember anything about the shadowlings or your time \ + under their command...") + return 1 /* @@ -191,7 +226,7 @@ Made by Xhuis else if(shadowling_dead && !check_shadow_victory()) //If the shadowlings have ascended, they can not lose the round world << "The shadowlings have been killed by the crew!" else if(!check_shadow_victory() && emergency_shuttle.returned()) - world << "The crew has escaped the station before the shadowlings could ascend!" + world << "The crew escaped the station before the shadowlings could ascend!" ..() return 1 diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 1935f3159d7..5aaa3030529 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -28,7 +28,34 @@ target.Stun(10) M.silent += 10 +/obj/effect/proc_holder/spell/wizard/targeted/lesser_glare + name = "Lesser Glare" + desc = "Stuns and mutes a target for a short duration." + panel = "Thrall Abilities" + charge_max = 450 + clothes_req = 0 +/obj/effect/proc_holder/spell/wizard/targeted/lesser_glare/cast(list/targets) + for(var/mob/living/carbon/human/target in targets) + if(!ishuman(target) || !target) + charge_counter = charge_max + return + if(target.stat) + charge_counter = charge_max + return + if(is_shadow_or_thrall(target)) + usr << "You don't see why you would want to paralyze an ally." + charge_counter = charge_max + return + var/mob/living/carbon/human/M = target + usr.visible_message("[usr]'s eyes flash a blinding red!") + target.visible_message("[target] freezes in place, their eyes glazing over...") + if(in_range(target, usr)) + target << "Your gaze is forcibly drawn into [usr]'s eyes, and you are mesmerized by the heavenly lights..." + else + target << "Red lights suddenly dance in your vision, and you are mesmerized by their heavenly beauty..." + target.Stun(3) //Roughly 30% as long as the normal one + M.silent += 3 /obj/effect/proc_holder/spell/wizard/aoe_turf/veil name = "Veil" @@ -68,6 +95,9 @@ /obj/effect/proc_holder/spell/wizard/aoe_turf/veil/cast(list/targets) usr << "You silently disable all nearby lights." + for(var/obj/effect/glowshroom/G in orange(2, usr)) //Why the fuck was this in the loop below? + G.visible_message("\The [G] withers away!") + qdel(G) for(var/turf/T in targets) for(var/obj/item/F in T.contents) extinguishItem(F) @@ -78,9 +108,6 @@ L.on = 0 L.visible_message("[L] flickers and falls dark.") L.update(0) - for(var/obj/effect/glowshroom/G in orange(2, usr)) //Very small radius - G.visible_message("\The [G] withers away!") - qdel(G) for(var/obj/machinery/computer/C in T.contents) C.set_light(0) C.visible_message("[C] grows dim, its screen barely readable.") @@ -111,10 +138,59 @@ user.incorporeal_move = 0 user.alpha = 255 +/obj/effect/proc_holder/spell/wizard/targeted/lesser_shadow_walk + name = "Guise" + desc = "Wraps your form in shadows, making you harder to see." + panel = "Thrall Abilities" + charge_max = 1200 + clothes_req = 0 + range = -1 + include_user = 1 +/obj/effect/proc_holder/spell/wizard/targeted/lesser_shadow_walk/cast(list/targets) + for(var/mob/living/user in targets) + var/lumcount = 0 + var/turf/T = get_turf(user) + lumcount = T.get_lumcount()*10 + if(lumcount > 5) + user << "It's too bright to do that!" + charge_counter = charge_max + return + user.visible_message("[user] suddenly fades away!", "You veil yourself in darkness, making you harder to see.") + user.alpha = 20 + sleep(40) + user.visible_message("[user] appears from nowhere!", "Your shadowy guise slips away.") + user.alpha = initial(user.alpha) + +/* +/obj/effect/proc_holder/spell/wizard/targeted/thrall_vision //Uncomment this if we ever update our vision code to not be absolute garbage. + name = "Darksight" + desc = "Gives you night vision." + panel = "Thrall Abilities" + charge_max = 0 + range = -1 + include_user = 1 + clothes_req = 0 + var/active = 0 + +/obj/effect/proc_holder/spell/wizard/targeted/thrall_vision/cast(list/targets) + for(var/mob/living/user in targets) + if(!istype(user) || !ishuman(user)) + return + var/mob/living/carbon/human/H = user + active = !active + if(active) + user << "You shift the nerves in your eyes, allowing you to see in the dark." + H.see_in_dark = 8 + H.dna.species.invis_sight = SEE_INVISIBLE_MINIMUM + else + user << "You return your vision to normal." + H.see_in_dark = 0 + H.dna.species.invis_sight = initial(H.dna.species.invis_sight) +*/ /obj/effect/proc_holder/spell/wizard/aoe_turf/flashfreeze - name = "Flash Freeze" + name = "Icy Veins" desc = "Instantly freezes the blood of nearby people, stunning them and causing burn damage." panel = "Shadowling Abilities" range = 5 @@ -126,19 +202,19 @@ playsound(usr.loc, 'sound/effects/ghost2.ogg', 50, 1) for(var/turf/T in targets) - for(var/mob/living/carbon/human/target in T.contents) - if(is_shadow_or_thrall(target)) - if(target == usr) //No message for the user, of course + for(var/mob/living/carbon/M in T.contents) + if(is_shadow_or_thrall(M)) + if(M == usr) //No message for the user, of course continue else - target << "You feel a blast of paralyzingly cold air wrap around you and flow past, but you are unaffected!" + M << "You feel a blast of paralyzingly cold air wrap around you and flow past, but you are unaffected!" continue - target << "You are hit by a blast of paralyzingly cold air and feel goosebumps break out across your body!" - target.Stun(2) - if(target.bodytemperature) - target.bodytemperature -= 200 //Extreme amount of initial cold - if(target.reagents) - target.reagents.add_reagent("frostoil", 15) //Half of a cryosting + M << "You are hit by a blast of paralyzingly cold air and feel goosebumps break out across your body!" + M.Stun(2) + if(M.bodytemperature) + M.bodytemperature -= 200 //Extreme amount of initial cold + if(M.reagents) + M.reagents.add_reagent("frostoil", 15) //Half of a cryosting @@ -147,7 +223,7 @@ name = "Enthrall" desc = "Allows you to enslave a conscious, non-braindead, non-catatonic human to your will. This takes some time to cast." panel = "Shadowling Abilities" - charge_max = 450 + charge_max = 0 clothes_req = 0 range = 1 //Adjacent to user var/enthralling = 0 @@ -164,7 +240,7 @@ usr << "You need to be closer to enthrall [target]." charge_counter = charge_max return - if(!target.key) + if(!target.key || !target.mind) usr << "The target has no mind." charge_counter = charge_max return @@ -212,24 +288,21 @@ target << "Your unwavering loyalty to Nanotrasen falters, dims, dies." if(3) usr << "You begin rearranging [target]'s memories." - usr.visible_message("[usr]'s eyes flare brightly, their unflinching gaze staring constantly at [target].") + usr.visible_message("[usr]'s eyes flare brightly.") target << "Your head cries out. The veil of reality begins to crumple and something evil bleeds through." //Ow the edge if(!do_mob(usr, target, 100)) //around 30 seconds total for enthralling, 45 for someone with a loyalty implant usr << "The enthralling has been interrupted - your target's mind returns to its previous state." - target << "Your thoughts become coherent once more. Already you can barely remember what's happened to you." + target << "A spike of pain drives into your head, wiping your memory. You aren't sure what's happened, but you feel a faint sense of revulsion." enthralling = 0 return enthralling = 0 usr << "You have enthralled [target]!" - target.visible_message("[target]'s expression appears as if they have experienced a revelation!", \ - "You see the Truth. Reality has been torn away and you realize what a fool you've been.") - target << "The shadowlings are your masters. Serve them above all else and ensure they complete their goals." - target << "You may not harm other thralls or the shadowlings. However, you do not need to obey other thralls." - target << "You can communicate with the other enlightened ones by speaking in the shadowling hivemind (:8)." + target.visible_message("[target] looks to have experienced a revelation!", \ + "False faces all dark not real not real not--") target.setOxyLoss(0) //In case the shadowling was choking them out ticker.mode.add_thrall(target.mind) - target.mind.special_role = "Shadowling Thrall" + target.mind.special_role = "shadowling thrall" /obj/effect/proc_holder/spell/wizard/targeted/collective_mind name = "Collective Hivemind" @@ -291,9 +364,12 @@ usr << "You may find Ascendance in the Shadowling Evolution tab." for(M in living_mob_list) if(is_shadow(M)) - M.mind.current.spell_list -= /obj/effect/proc_holder/spell/wizard/targeted/collective_mind - M.mind.current.verbs -= /mob/living/carbon/human/proc/shadowling_hatch //In case a shadowling hasn't hatched - M.mind.current.verbs += /mob/living/carbon/human/proc/shadowling_ascendance + var/obj/effect/proc_holder/spell/wizard/targeted/collective_mind/CM + if(CM in M.mind.spell_list) + M.mind.spell_list -= CM + qdel(CM) + M.mind.remove_spell(/obj/effect/proc_holder/spell/wizard/targeted/shadowling_hatch) + M.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/shadowling_ascend) if(M == usr) M << "You project this power to the rest of the shadowlings." else @@ -472,7 +548,7 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob) /obj/effect/proc_holder/spell/wizard/targeted/annihilate name = "Annihilate" - desc = "Gibs a human after a short time." + desc = "Gibs someone instantly." panel = "Ascendant" range = 7 charge_max = 0 @@ -485,18 +561,15 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob) charge_counter = charge_max return - for(var/mob/living/carbon/human/boom in targets) + for(var/mob/living/boom in targets) if(is_shadow_or_thrall(boom)) usr << "Making an ally explode seems unwise." charge_counter = charge_max return - usr.visible_message("[usr]'s eyes flare as they gesture at [boom]!", \ + usr.visible_message("[usr]'s markings flare as they gesture at [boom]!", \ "You direct a lance of telekinetic energy at [boom].") - boom << "You feel an immense pressure building all across your body!" - boom.Stun(10) - boom.audible_message("[boom] screams!") - sleep(20) - playsound(boom, 'sound/effects/splat.ogg', 100, 1) + playsound(usr, 'sound/effects/supermatter.ogg', 100, 1) + sleep(4) boom.visible_message("[boom] explodes!") boom.gib() @@ -522,7 +595,7 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob) usr << "You cannot enthrall an ally." charge_counter = charge_max return - if(!target.ckey) + if(!target.ckey || !target.mind) usr << "The target has no mind." charge_counter = charge_max return @@ -537,12 +610,8 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob) usr << "You instantly rearrange [target]'s memories, hyptonitizing them into a thrall." target << "An agonizing spike of pain drives into your mind, and--" - target << "And you see the Truth. Reality has been torn away and you realize what a fool you've been." - target << "The shadowlings are your masters. Serve them above all else and ensure they complete their goals." - target << "You may not harm other thralls or the shadowlings. However, you do not need to obey other thralls." - target << "You can communicate with the other enlightened ones by using the Shadowling Hivemind (:8)." ticker.mode.add_thrall(target.mind) - target.mind.special_role = "Thrall" + target.mind.special_role = "shadowling thrall" target.add_language("Shadowling Hivemind") @@ -575,7 +644,7 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob) /obj/effect/proc_holder/spell/wizard/aoe_turf/glacial_blast name = "Glacial Blast" - desc = "Extremely empowered version of Flash Freeze." + desc = "Extremely empowered version of Icy Veins." panel = "Ascendant" range = 5 charge_max = 100 @@ -585,6 +654,7 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob) var/mob/living/simple_animal/ascendant_shadowling/SHA = usr if(SHA.phasing) usr << "You are not in the same plane of existence. Unphase first." + charge_counter = charge_max return usr << "You freeze the nearby air." @@ -598,10 +668,24 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob) else target << "You feel a blast of paralyzingly cold air wrap around you and flow past, but you are unaffected!" continue - target << "You are hit by a blast of cold unlike anything you have ever felt. Your limbs instantly lock in place and you feel ice burns across your body!" + target << "You are hit by a blast of cold unlike anything you have ever felt. Your limbs instantly lock in place and you feel frost burns across your body!" target.Weaken(15) if(target.bodytemperature) target.bodytemperature -= INFINITY //:^) target.take_organ_damage(0,80) +/obj/effect/proc_holder/spell/wizard/targeted/shadowlingAscendantTransmit + name = "Ascendant Broadcast" + desc = "Sends a message to the whole wide world." + panel = "Ascendant" + charge_max = 200 + clothes_req = 0 + range = -1 + include_user = 1 +/obj/effect/proc_holder/spell/wizard/targeted/shadowlingAscendantTransmit/cast(list/targets) + for(var/mob/living/user in targets) + var/text = stripped_input(user, "What do you want to say to everything on and near [world.name]?.", "Transmit to World", "") + if(!text) + return + world << "\"[text]\"" diff --git a/code/game/gamemodes/shadowling/shadowling_items.dm b/code/game/gamemodes/shadowling/shadowling_items.dm index f3da8bda1bf..e494c7507f0 100644 --- a/code/game/gamemodes/shadowling/shadowling_items.dm +++ b/code/game/gamemodes/shadowling/shadowling_items.dm @@ -98,7 +98,6 @@ /obj/structure/shadow_vortex/Crossed(var/td) ..() if(ismob(td)) - td << "You enter the rift. Sickening chimes begin to jangle in your ears. \ - All around you is endless blackness. After you see something moving, you realize it isn't entirely lifeless." //A bit of spooking before they die + td << "You enter the rift. Deafening chimes jingle in your ears. You are swallowed in darkness." playsound(loc, 'sound/effects/EMPulse.ogg', 25, 1) qdel(td) diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 05af76eb2a9..8f4cdca3f73 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -1,170 +1,176 @@ //In here: Hatch and Ascendance -var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "Noaey'gief", "Mii`mahza", "Amerziox", "Gyrg-mylin", "Kanet'pruunance", "Vigistaezian") -/mob/living/carbon/human/proc/shadowling_hatch() - set category = "Shadowling Evolution" - set name = "Hatch" +var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "Noaey'gief", "Mii`mahza", "Amerziox", "Gyrg-mylin", "Kanet'pruunance") +/obj/effect/proc_holder/spell/wizard/targeted/shadowling_hatch + name = "Hatch" + desc = "Casts off your disguise." + panel = "Shadowling Evolution" + charge_max = 3000 + clothes_req = 0 + range = -1 + include_user = 1 - if(usr.stat) +/obj/effect/proc_holder/spell/wizard/targeted/shadowling_hatch/cast(list/targets) + if(usr.stat || !ishuman(usr) || !usr) return - usr.verbs -= /mob/living/carbon/human/proc/shadowling_hatch - switch(alert("Are you sure you want to hatch? You cannot undo this!",,"Yes","No")) - if("No") - usr << "You decide against hatching for now." - usr.verbs += /mob/living/carbon/human/proc/shadowling_hatch - return - if("Yes") - usr.Stun(INFINITY) //This is bad but notransform won't work. - usr.visible_message("[usr]'s things suddenly slip off. They hunch over and vomit up a copious amount of purple goo which begins to shape around them!", \ - "You remove any equipment which would hinder your hatching and begin regurgitating the resin which will protect you.") + for(var/mob/living/carbon/human/H in targets) + var/hatch_or_no = alert(H,"Are you sure you want to hatch? You cannot undo this!",,"Yes","No") + switch(hatch_or_no) + if("No") + H << "You decide against hatching for now." + charge_counter = charge_max + return + if("Yes") + H.Stun(INFINITY) //This is bad but notransform won't work. + H.visible_message("[H]'s things suddenly slip off. They hunch over and vomit up a copious amount of purple goo which begins to shape around them!", \ + "You remove any equipment which would hinder your hatching and begin regurgitating the resin which will protect you.") - for(var/obj/item/I in usr) //drops all items - var/obj/item/organ/O = I - if(!istype(O) || O.owner != src) - usr.unEquip(I) + for(var/obj/item/I in H) //drops all items + var/obj/item/organ/O = I + if(!istype(O) || O.owner != src) + H.unEquip(I) - sleep(50) - var/turf/simulated/floor/F - var/turf/shadowturf = get_turf(usr) - for(F in orange(1, usr)) - new /obj/structure/alien/resin/wall/shadowling(F) - for(var/obj/structure/alien/resin/wall/shadowling/R in shadowturf) //extremely hacky - qdel(R) - new /obj/structure/alien/weeds/node(shadowturf) //Dim lighting in the chrysalis -- removes itself with the chrysalis + sleep(50) + var/turf/simulated/floor/F + var/turf/shadowturf = get_turf(usr) + for(F in orange(1, usr)) + new /obj/structure/alien/resin/wall/shadowling(F) + for(var/obj/structure/alien/resin/wall/shadowling/R in shadowturf) //extremely hacky + qdel(R) + new /obj/structure/alien/weeds/node(shadowturf) //Dim lighting in the chrysalis -- removes itself afterwards - usr.visible_message("A chrysalis forms around [usr], sealing them inside.", \ - "You create your chrysalis and begin to contort within.") - usr.Weaken(30) - sleep(100) - usr.visible_message("The skin on [usr]'s back begins to split apart. Black spines slowly emerge from the divide.", \ - "Spines pierce your back. Your claws break apart your fingers. You feel excruciating pain as your true form begins its exit.") + H.visible_message("A chrysalis forms around [H], sealing them inside.", \ + "You create your chrysalis and begin to contort within.") + usr.Weaken(30) - sleep(90) - usr.visible_message("[usr], skin shifting, begins tearing at the walls around them.", \ + sleep(100) + H.visible_message("The skin on [H]'s back begins to split apart. Black spines slowly emerge from the divide.", \ + "Spines pierce your back. Your claws break apart your fingers. You feel excruciating pain as your true form begins its exit.") + + sleep(90) + H.visible_message("[H], skin shifting, begins tearing at the walls around them.", \ "Your false skin slips away. You begin tearing at the fragile membrane protecting you.") - sleep(80) - playsound(usr.loc, 'sound/weapons/slash.ogg', 25, 1) - usr << "You rip and slice." - sleep(10) - playsound(usr.loc, 'sound/weapons/slashmiss.ogg', 25, 1) - usr << "The chrysalis falls like water before you." - sleep(10) - playsound(usr.loc, 'sound/weapons/slice.ogg', 25, 1) - usr << "You are free!" + sleep(80) + playsound(H.loc, 'sound/weapons/slash.ogg', 25, 1) + H << "You rip and slice." + sleep(10) + playsound(H.loc, 'sound/weapons/slashmiss.ogg', 25, 1) + H << "The chrysalis falls like water before you." + sleep(10) + playsound(H.loc, 'sound/weapons/slice.ogg', 25, 1) + H << "You are free!" - sleep(10) - playsound(usr.loc, 'sound/effects/ghost.ogg', 100, 1) - var/newNameId = pick(possibleShadowlingNames) - possibleShadowlingNames.Remove(newNameId) - usr.real_name = newNameId - usr.name = usr.real_name - usr.SetStunned(0) - usr << "YOU LIVE!!!" + sleep(10) + playsound(H.loc, 'sound/effects/ghost.ogg', 100, 1) + var/newNameId = pick(possibleShadowlingNames) + possibleShadowlingNames.Remove(newNameId) + H.real_name = newNameId + H.name = usr.real_name + H.SetStunned(0) + H << "YOU LIVE!!!" - for(var/obj/structure/alien/resin/wall/shadowling/W in orange(usr, 1)) - playsound(W, 'sound/effects/splat.ogg', 50, 1) - qdel(W) - for(var/obj/structure/alien/weeds/node/N in shadowturf) - qdel(N) - usr.visible_message("The chrysalis explodes in a shower of purple flesh and fluid!") - var/mob/living/carbon/human/M = usr - M.underwear = "None" - M.undershirt = "None" - M.faction |= "faithless" + for(var/obj/structure/alien/resin/wall/shadowling/W in orange(H, 1)) + playsound(W, 'sound/effects/splat.ogg', 50, 1) + qdel(W) + for(var/obj/structure/alien/weeds/node/N in shadowturf) + qdel(N) + H.visible_message("The chrysalis explodes in a shower of purple flesh and fluid!") - usr.equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(usr), slot_w_uniform) - usr.equip_to_slot_or_del(new /obj/item/clothing/shoes/shadowling(usr), slot_shoes) - usr.equip_to_slot_or_del(new /obj/item/clothing/suit/space/shadowling(usr), slot_wear_suit) - usr.equip_to_slot_or_del(new /obj/item/clothing/head/shadowling(usr), slot_head) - usr.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(usr), slot_gloves) - usr.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(usr), slot_wear_mask) - usr.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/shadowling(usr), slot_glasses) - set_species("Shadowling") + H.underwear = "None" + H.undershirt = "None" + H.faction |= "faithless" - sleep(10) - usr << "Your powers are awoken. You may now live to your fullest extent. Remember your goal. Cooperate with your thralls and allies." - usr.mind.AddSpell(new /obj/effect/proc_holder/spell/wizard/targeted/glare) - usr.mind.AddSpell(new /obj/effect/proc_holder/spell/wizard/aoe_turf/veil) - usr.mind.AddSpell(new /obj/effect/proc_holder/spell/wizard/targeted/shadow_walk) - usr.mind.AddSpell(new /obj/effect/proc_holder/spell/wizard/aoe_turf/flashfreeze) - usr.mind.AddSpell(new /obj/effect/proc_holder/spell/wizard/targeted/collective_mind) + H.equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(usr), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/shadowling(usr), slot_shoes) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/space/shadowling(usr), slot_wear_suit) + H.equip_to_slot_or_del(new /obj/item/clothing/head/shadowling(usr), slot_head) + H.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(usr), slot_gloves) + H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(usr), slot_wear_mask) + H.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/shadowling(usr), slot_glasses) + H.set_species("Shadowling") + sleep(10) + H << "Your powers are awoken. You may now live to your fullest extent. Remember your goal. Cooperate with your thralls and allies." + H.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/shadowling_hatch) + H.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/glare) + H.AddSpell(/obj/effect/proc_holder/spell/wizard/aoe_turf/veil) + H.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/shadow_walk) + H.AddSpell(/obj/effect/proc_holder/spell/wizard/aoe_turf/flashfreeze) + H.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/collective_mind) +/obj/effect/proc_holder/spell/wizard/targeted/shadowling_ascend + name = "Ascend" + desc = "Enters your true form." + panel = "Shadowling Evolution" + charge_max = 3000 + clothes_req = 0 + range = -1 + include_user = 1 -/mob/living/carbon/human/proc/shadowling_ascendance() - set category = "Shadowling Evolution" - set name = "Ascendance" - - if(usr.stat) +/obj/effect/proc_holder/spell/wizard/targeted/shadowling_ascend/cast(list/targets) + if(usr.stat || !ishuman(usr) || !usr) return - usr.verbs -= /mob/living/carbon/human/proc/shadowling_ascendance - switch(alert("It is time to ascend. Are you completely sure about this? You cannot undo this!",,"Yes","No")) - if("No") - usr << "You decide against ascending for now." - usr.verbs += /mob/living/carbon/human/proc/shadowling_ascendance - return - if("Yes") - usr.Stun(INFINITY) - usr.visible_message("[usr] rapidly bends and contorts, their eyes flaring a deep crimson!", \ - "You begin unlocking the genetic vault within you and prepare yourself for the power to come.") + for(var/mob/living/carbon/human/H in targets) + var/hatch_or_no = alert(H,"It is time to ascend. Are you sure about this?",,"Yes","No") + switch(hatch_or_no) + if("No") + H << "You decide against ascending for now." + charge_counter = charge_max + return + if("Yes") + H.notransform = 1 + H.visible_message("[H] gently rises into the air, red light glowing in its eyes.", \ + "You rise into the air and get ready for your transformation.") - sleep(30) - usr.visible_message("[usr] suddenly shoots up a few inches in the air and begins hovering there, still twisting.", \ - "You hover into the air to make room for your new form.") + sleep(50) - sleep(60) - usr.visible_message("[usr]'s skin begins to pulse red in sync with their eyes. Their form slowly expands outward.", \ - "You feel yourself beginning to mutate.") + H.visible_message("[H]'s skin begins to crack and harden.", \ + "Your flesh begins creating a shield around yourself.") - sleep(20) - if(!ticker.mode.shadowling_ascended) - usr << "It isn't enough. Time to draw upon your thralls." - else - usr << "After some telepathic searching, you find the reservoir of life energy from the thralls and tap into it." + sleep(100) + H.visible_message("The small horns on [H]'s head slowly grow and elongate.", \ + "Your body continues to mutate. Your telepathic abilities grow.") //y-your horns are so big, senpai...!~ - sleep(50) - for(var/mob/M in mob_list) - if(is_thrall(M) && !ticker.mode.shadowling_ascended) - M.visible_message("[M] trembles minutely as they collapse, black smoke pouring from their disintegrating face.", \ - "It's time! Your masters are ascending! Your last thoughts are happy as your body is drained of life.") + sleep(90) + H.visible_message("[H]'s body begins to violently stretch and contort.", \ + "You begin to rend apart the final barries to godhood.") - ticker.mode.thralls -= M.mind //To prevent message spam - M.death(0) - - usr << "Drawing upon your thralls, you find the strength needed to finish and rend apart the final barriers to godhood." - - sleep(20) - usr << "Yes!" - sleep(10) - usr << "YES!" - sleep(10) - usr << "YE--" - sleep(1) - for(var/mob/living/M in orange(7, src)) - M.Weaken(10) - M << "An immense pressure slams you onto the ground!" - world << "\"VYSHA NERADA YEKHEZET U'RUU!!\"" - world << 'sound/hallucinations/veryfar_noise.ogg' - for(var/obj/machinery/power/apc/A in world) - A.overload_lighting() - var/mob/A = new /mob/living/simple_animal/ascendant_shadowling(usr.loc) - usr.spell_list = list() - usr.mind.AddSpell(new /obj/effect/proc_holder/spell/wizard/targeted/annihilate) - usr.mind.AddSpell(new /obj/effect/proc_holder/spell/wizard/targeted/hypnosis) - usr.mind.AddSpell(new /obj/effect/proc_holder/spell/wizard/targeted/shadowling_phase_shift) - usr.mind.AddSpell(new /obj/effect/proc_holder/spell/wizard/aoe_turf/glacial_blast) - usr.mind.transfer_to(A) - A.spell_list = usr.spell_list - A.name = usr.real_name - A.languages = usr.languages - if(A.real_name) - A.real_name = usr.real_name - usr.invisibility = 60 //This is pretty bad, but is also necessary for the shuttle call to function properly - usr.flags |= GODMODE - sleep(50) - if(!ticker.mode.shadowling_ascended) - if(emergency_shuttle && emergency_shuttle.can_call()) - emergency_shuttle.call_evac() - emergency_shuttle.launch_time = 0 // Cannot recall - ticker.mode.shadowling_ascended = 1 - qdel(usr) + sleep(40) + H << "Yes!" + sleep(10) + H << "YES!!" + sleep(10) + H << "YE--" + sleep(1) + for(var/mob/living/M in orange(7, H)) + M.Weaken(10) + M << "An immense pressure slams you onto the ground!" + world << "\"VYSHA NERADA YEKHEZET U'RUU!!\"" + world << 'sound/hallucinations/veryfar_noise.ogg' + for(var/obj/machinery/power/apc/A in range(200, H)) + A.overload_lighting() + var/mob/A = new /mob/living/simple_animal/ascendant_shadowling(H.loc) + for(var/obj/effect/proc_holder/spell/S in H.mind.spell_list) + if(S == src) continue + H.mind.remove_spell(S) + H.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/annihilate) + H.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/hypnosis) + H.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/shadowling_phase_shift) + H.AddSpell(/obj/effect/proc_holder/spell/wizard/aoe_turf/glacial_blast) + H.AddSpell(/obj/effect/proc_holder/spell/wizard/targeted/shadowlingAscendantTransmit) + H.mind.transfer_to(A) + A.name = H.real_name + A.languages = H.languages + if(A.real_name) + A.real_name = H.real_name + H.invisibility = 60 //This is pretty bad, but is also necessary for the shuttle call to function properly + H.flags |= GODMODE + H.loc = A + sleep(50) + if(!ticker.mode.shadowling_ascended) + if(emergency_shuttle && emergency_shuttle.can_call()) + emergency_shuttle.call_evac() + emergency_shuttle.launch_time = 0 // Cannot recall + ticker.mode.shadowling_ascended = 1 + A.mind.remove_spell(src) + qdel(H) diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 2455637e61b..785fbb38f59 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -278,6 +278,13 @@ if (spell_to_remove.name == "Artificer" && !removeallspells) continue qdel(spell_to_remove) +/datum/mind/proc/remove_spell(var/obj/effect/proc_holder/spell/spell) //To remove a specific spell from a mind + if(!spell) return + for(var/obj/effect/proc_holder/spell/S in spell_list) + if(istype(S, spell)) + qdel(S) + spell_list -= S + /*Checks if the wizard can cast spells. Made a proc so this is not repeated 14 (or more) times.*/ /mob/proc/casting() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index ca526459f37..8191421e8c8 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -396,3 +396,8 @@ O.singularity_act() ChangeTurf(/turf/space) return(2) + +/turf/proc/get_lumcount() //Gets the lighting level of a given turf. + if(lighting_overlay) + return lighting_overlay.get_clamped_lum() + return 1 diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 96d9f6ddc0e..c0c11aa1aa7 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -419,6 +419,8 @@ msg += "[src] has \a [implant] sticking out of [t_his] flesh!\n" if(digitalcamo) msg += "[t_He] [t_is] repulsively uncanny!\n" + if(!wear_mask && is_thrall(src) && in_range(usr,src)) + msg += "Their features seem unnaturally tight and drawn.\n" if(decaylevel == 1) msg += "[t_He] [t_is] starting to smell.\n" if(decaylevel == 2) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 613f0ad99b3..73053496473 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -748,11 +748,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing if(isturf(loc)) //else, there's considered to be no light var/turf/T = loc - var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T - if(L) - light_amount = (L.get_clamped_lum()*10) - 5 //hardcapped so it's not abused by having a ton of flashlights - else - light_amount = 5 + light_amount = min(T.get_lumcount()*10, 5) //hardcapped so it's not abused by having a ton of flashlights nutrition += light_amount traumatic_shock -= light_amount @@ -770,11 +766,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc var/light_amount = 0 if(isturf(loc)) var/turf/T = loc - var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T - if(L) - light_amount = L.get_clamped_lum()*10 - else - light_amount = 10 + light_amount = T.get_lumcount()*10 if(light_amount > species.light_dam) //if there's enough light, start dying if(species.light_effect_amp) adjustFireLoss(5) //This gets doubled by Shadowling's innate fire weakness, so it ends up being 10. diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm index 3aef61fb3d5..df9f6e050e5 100644 --- a/code/modules/mob/living/silicon/robot/login.dm +++ b/code/modules/mob/living/silicon/robot/login.dm @@ -3,4 +3,5 @@ regenerate_icons() show_laws(0) if(mind) ticker.mode.remove_revolutionary(mind) + if(mind) ticker.mode.remove_thrall(mind,0) return \ No newline at end of file