diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 3407b3342b..ffcb5ac231 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -125,7 +125,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list( #define isbot(A) (istype(A, /mob/living/simple_animal/bot)) -#define isshade(A) (istype(A, /mob/living/simple_animal/shade)) +#define isshade(A) (istype(A, /mob/living/simple_animal/hostile/construct/shade)) #define ismouse(A) (istype(A, /mob/living/simple_animal/mouse)) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 82302a2e06..8e14c7a58e 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -323,3 +323,4 @@ /// This trait is added by the parry system. #define ACTIVE_PARRY_TRAIT "active_parry" #define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a bad soundcloud rapper's name +#define TRAIT_SACRIFICED "sacrificed" //Makes sure that people cant be cult sacrificed twice. diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 605b20a4f3..e30f0e260d 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -13,6 +13,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NEARSIGHT" = TRAIT_NEARSIGHT, "TRAIT_FAT" = TRAIT_FAT, "TRAIT_HUSK" = TRAIT_HUSK, + "TRAIT_SACRIFICED" = TRAIT_SACRIFICED, "TRAIT_NOCLONE" = TRAIT_NOCLONE, "TRAIT_CLUMSY" = TRAIT_CLUMSY, "TRAIT_CHUNKYFINGERS" = TRAIT_CHUNKYFINGERS, diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm index 47b93928d4..9a0665e91f 100644 --- a/code/controllers/subsystem/traumas.dm +++ b/code/controllers/subsystem/traumas.dm @@ -52,7 +52,7 @@ SUBSYSTEM_DEF(traumas) "doctors" = typecacheof(list(/mob/living/simple_animal/bot/medbot)), "the supernatural" = typecacheof(list(/mob/living/simple_animal/hostile/construct, /mob/living/simple_animal/hostile/clockwork, /mob/living/simple_animal/drone/cogscarab, - /mob/living/simple_animal/revenant, /mob/living/simple_animal/shade)), + /mob/living/simple_animal/revenant, /mob/living/simple_animal/hostile/construct/shade)), "aliens" = typecacheof(list(/mob/living/carbon/alien, /mob/living/simple_animal/slime)), "conspiracies" = typecacheof(list(/mob/living/simple_animal/bot/secbot, /mob/living/simple_animal/bot/ed209, /mob/living/simple_animal/drone, /mob/living/simple_animal/pet/penguin)), diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index fe2bdf90b1..8941c540ae 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -508,7 +508,7 @@ /obj/machinery/door/airlock/cult/allowed(mob/living/L) if(!density) return 1 - if(friendly || iscultist(L) || istype(L, /mob/living/simple_animal/shade) || isconstruct(L)) + if(friendly || iscultist(L) || isshade(L) || isconstruct(L)) if(!stealthy) new openingoverlaytype(loc) return 1 diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 58146be20f..a15e1368d8 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -492,7 +492,7 @@ var/possessed = FALSE /obj/item/nullrod/scythe/talking/process() - for(var/mob/living/simple_animal/shade/S in contents) + for(var/mob/living/simple_animal/hostile/construct/shade/S in contents) if(S.mind) return else @@ -516,7 +516,7 @@ if(LAZYLEN(candidates)) var/mob/C = pick(candidates) - var/mob/living/simple_animal/shade/S = new(src) + var/mob/living/simple_animal/hostile/construct/shade/S = new(src) S.real_name = name S.name = name S.ckey = C.ckey @@ -537,7 +537,7 @@ possessed = FALSE /obj/item/nullrod/scythe/talking/Destroy() - for(var/mob/living/simple_animal/shade/S in contents) + for(var/mob/living/simple_animal/hostile/construct/shade/S in contents) to_chat(S, "You were destroyed!") qdel(S) return ..() diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index 244b8c804b..476f35fe4c 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -198,7 +198,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", if(istype(A, /obj/item/cult_bastard)) for(var/obj/item/soulstone/SS in A.contents) SS.usability = TRUE - for(var/mob/living/simple_animal/shade/EX in SS) + for(var/mob/living/simple_animal/hostile/construct/shade/EX in SS) SSticker.mode.remove_cultist(EX.mind, 1, 0) EX.icon_state = "ghost1" EX.name = "Purified [EX.name]" @@ -217,7 +217,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", if(do_after(user, 40, target = SS)) playsound(src,'sound/effects/pray_chaplain.ogg',60,1) SS.usability = TRUE - for(var/mob/living/simple_animal/shade/EX in SS) + for(var/mob/living/simple_animal/hostile/construct/shade/EX in SS) SSticker.mode.remove_cultist(EX.mind, 1, 0) EX.icon_state = "ghost1" EX.name = "Purified [EX.name]" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 03376df905..ad8dd168eb 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -508,7 +508,7 @@ if("constructwraith") M.change_mob_type( /mob/living/simple_animal/hostile/construct/wraith , null, null, delmob ) if("shade") - M.change_mob_type( /mob/living/simple_animal/shade , null, null, delmob ) + M.change_mob_type( /mob/living/simple_animal/hostile/construct/shade , null, null, delmob ) /////////////////////////////////////new ban stuff diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index 6e3fcfae2a..a2ec4a47a4 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -295,6 +295,8 @@ ++cultplayers else ++alive + if(!alive) + return var/ratio = cultplayers/alive if(ratio > CULT_RISEN && !cult_risen) for(var/datum/mind/B in members) diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 6cc2fb94b8..276729b359 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -82,7 +82,7 @@ Runes can either be invoked by one's self or with many different cultists. Each fail_invoke() /obj/effect/rune/attack_animal(mob/living/simple_animal/M) - if(istype(M, /mob/living/simple_animal/shade) || istype(M, /mob/living/simple_animal/hostile/construct)) + if(isshade(M) || istype(M, /mob/living/simple_animal/hostile/construct)) if(construct_invoke || !iscultist(M)) //if you're not a cult construct we want the normal fail message attack_hand(M) else @@ -191,7 +191,7 @@ structure_check() searches for nearby cultist structures required for the invoca /obj/effect/rune/convert/do_invoke_glow() return -/obj/effect/rune/convert/invoke(var/list/invokers) +/obj/effect/rune/convert/invoke(list/invokers) if(rune_in_use) return var/list/myriad_targets = list() @@ -203,11 +203,16 @@ structure_check() searches for nearby cultist structures required for the invoca fail_invoke() log_game("Offer rune failed - no eligible targets") return + var/mob/living/L = pick(myriad_targets) + if(HAS_TRAIT(L, TRAIT_SACRIFICED)) + fail_invoke() + log_game("Offer rune failed - target has already been sacrificed") + to_chat(invokers, "[L] has already been sacrificed!") + return rune_in_use = TRUE visible_message("[src] pulses blood red!") var/oldcolor = color color = RUNE_COLOR_DARKRED - var/mob/living/L = pick(myriad_targets) var/is_clock = is_servant_of_ratvar(L) var/mob/living/F = invokers[1] @@ -264,7 +269,7 @@ structure_check() searches for nearby cultist structures required for the invoca H.uncuff() H.stuttering = 0 H.cultslurring = 0 - return 1 + return TRUE /obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers) var/mob/living/first_invoker = invokers[1] @@ -308,12 +313,16 @@ structure_check() searches for nearby cultist structures required for the invoca stone.invisibility = 0 if(sacrificial) + ADD_TRAIT(sacrificial, TRAIT_SACRIFICED, "sacrificed") if(iscyborg(sacrificial)) - playsound(sacrificial, 'sound/magic/disable_tech.ogg', 100, 1) - sacrificial.dust() //To prevent the MMI from remaining - else - playsound(sacrificial, 'sound/magic/disintegrate.ogg', 100, 1) - sacrificial.gib() + var/mob/living/silicon/robot/bot = sacrificial + playsound(sacrificial, 'sound/magic/disable_tech.ogg', 100, TRUE) + bot.deconstruct() + + else if(ishuman(sacrificial)) + playsound(sacrificial, 'sound/magic/disintegrate.ogg', 100, TRUE) + var/mob/living/carbon/human/H = sacrificial + H.spew_organ(2, 6) return TRUE /obj/effect/rune/empower diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm index 46961c0caf..abef18ade0 100644 --- a/code/modules/antagonists/wizard/equipment/soulstone.dm +++ b/code/modules/antagonists/wizard/equipment/soulstone.dm @@ -36,7 +36,7 @@ /obj/item/soulstone/examine(mob/user) . = ..() - if(usability || iscultist(user, TRUE) || iswizard(user) || isobserver(user)) + if(usability || iscultist(user) || iswizard(user) || isobserver(user)) if (old_shard) . += "A soulstone, used to capture a soul, either from dead humans or from freed shades." else @@ -46,7 +46,7 @@ . += "This shard is spent; it is now just a creepy rock." /obj/item/soulstone/Destroy() //Stops the shade from being qdel'd immediately and their ghost being sent back to the arrival shuttle. - for(var/mob/living/simple_animal/shade/A in src) + for(var/mob/living/simple_animal/hostile/construct/shade/A in src) A.death() return ..() @@ -58,7 +58,7 @@ to_chat(user, "Your body is wracked with debilitating pain!") return if(spent) - to_chat(user, "There is no power left in the shard.") + to_chat(user, "There is no power left in [src].") return if(!ishuman(M))//If target is not a human. return ..() @@ -81,7 +81,7 @@ release_shades(user) /obj/item/soulstone/proc/release_shades(mob/user) - for(var/mob/living/simple_animal/shade/A in src) + for(var/mob/living/simple_animal/hostile/construct/shade/A in src) A.status_flags &= ~GODMODE A.forceMove(get_turf(user)) A.mobility_flags = MOBILITY_FLAGS_DEFAULT @@ -103,12 +103,12 @@ /obj/structure/constructshell/examine(mob/user) . = ..() - if(iscultist(user, TRUE) || iswizard(user) || user.stat == DEAD) - . += "A construct shell, used to house bound souls from a soulstone." - . += "Placing a soulstone with a soul into this shell allows you to produce your choice of the following:" - . += "An Artificer, which can produce more shells and soulstones, as well as fortifications." - . += "A Wraith, which does high damage and can jaunt through walls, though it is quite fragile." - . += "A Juggernaut, which is very hard to kill and can produce temporary walls, but is slow." + if(iscultist(user) || iswizard(user) || user.stat == DEAD) + . += {"A construct shell, used to house bound souls from a soulstone.\n + Placing a soulstone with a soul into this shell allows you to produce your choice of the following:\n + An Artificer, which can produce more shells and soulstones, as well as fortifications.\n + A Wraith, which does high damage and can jaunt through walls, though it is quite fragile.\n + A Juggernaut, which is very hard to kill and can produce temporary walls, but is slow."} /obj/structure/constructshell/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/soulstone)) @@ -145,14 +145,14 @@ if("VICTIM") var/mob/living/carbon/human/T = target var/datum/antagonist/cult/C = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - if(C && C.cult_team?.is_sacrifice_target(T.mind)) + if(C?.cult_team.is_sacrifice_target(T.mind)) if(iscultist(user)) to_chat(user, "\"This soul is mine. SACRIFICE THEM!\"") else - to_chat(user, "The soulstone seems to reject this soul.") + to_chat(user, "[src] seems to reject this soul.") return FALSE if(contents.len) - to_chat(user, "Capture failed!: The soulstone is full! Free an existing soul to make room.") + to_chat(user, "Capture failed!: [src] is full! Free an existing soul to make room.") else if((!old_shard && T.stat != CONSCIOUS) || (old_shard && T.stat == DEAD)) if(T.client == null) @@ -167,7 +167,7 @@ to_chat(user, "Capture failed!: Kill or maim the victim first!") if("SHADE") - var/mob/living/simple_animal/shade/T = target + var/mob/living/simple_animal/hostile/construct/shade/T = target if(contents.len) to_chat(user, "Capture failed!: The soulstone is full! Free an existing soul to make room.") else @@ -177,13 +177,13 @@ T.health = T.maxHealth icon_state = "soulstone2" name = "soulstone: Shade of [T.real_name]" - to_chat(T, "Your soul has been captured by the soulstone. Its arcane energies are reknitting your ethereal form.") + to_chat(T, "Your soul has been captured by [src]. Its arcane energies are reknitting your ethereal form.") if(user != T) - to_chat(user, "Capture successful!: [T.real_name]'s soul has been captured and stored within the soulstone.") + to_chat(user, "Capture successful!: [T.real_name]'s soul has been captured and stored within [src].") if("CONSTRUCT") var/obj/structure/constructshell/T = target - var/mob/living/simple_animal/shade/A = locate() in src + var/mob/living/simple_animal/hostile/construct/shade/A = locate() in src if(A) var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer") if(!T || !T.loc) @@ -199,8 +199,8 @@ if(iscultist(user) || iswizard(user)) makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, A, user, 0, T.loc) - else - makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder/noncult, A, user, 0, T.loc) + else + return for(var/datum/mind/B in SSticker.mode.cult) if(B == A.mind) SSticker.mode.cult -= A.mind @@ -208,19 +208,24 @@ qdel(T) qdel(src) else - to_chat(user, "Creation failed!: The soul stone is empty! Go kill someone!") + to_chat(user, "Creation failed!: [src] is empty! Go kill someone!") /proc/makeNewConstruct(mob/living/simple_animal/hostile/construct/ctype, mob/target, mob/stoner = null, cultoverride = 0, loc_override = null) + if(QDELETED(target)) + return var/mob/living/simple_animal/hostile/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target))) if(stoner) newstruct.faction |= "[REF(stoner)]" newstruct.master = stoner var/datum/action/innate/seek_master/SM = new() SM.Grant(newstruct) - target.transfer_ckey(newstruct) + newstruct.key = target.key + if(target.type == /mob/living/simple_animal/hostile/construct/shade) //Make sure we remember which body belonged to the shade + var/mob/living/simple_animal/hostile/construct/shade/shade = target + newstruct.original_mind = shade.original_mind var/obj/screen/alert/bloodsense/BS - if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode) + if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker?.mode) SSticker.mode.add_cultist(newstruct.mind, 0) if(iscultist(stoner) || cultoverride) to_chat(newstruct, "You are still bound to serve the cult[stoner ? " and [stoner]":""], follow [stoner ? stoner.p_their() : "their"] orders and help [stoner ? stoner.p_them() : "them"] complete [stoner ? stoner.p_their() : "their"] goals at all costs.") @@ -234,19 +239,18 @@ /obj/item/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/user, vic = 0) - new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton + if(HAS_TRAIT_FROM(T, TRAIT_SACRIFICED, "sacrificed")) + if(user) + to_chat(user, "This body has already been harvested!") + return + ADD_TRAIT(T, TRAIT_SACRIFICED, "sacrificed") T.stop_sound_channel(CHANNEL_HEARTBEAT) - T.invisibility = INVISIBILITY_ABSTRACT - T.dust_animation() - QDEL_IN(T, 5) - var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade(src) - S.status_flags |= GODMODE //So they won't die inside the stone somehow - S.mobility_flags = NONE //Can't move out of the soul stone + var/mob/living/simple_animal/hostile/construct/shade/S = new /mob/living/simple_animal/hostile/construct/shade(src) S.name = "Shade of [T.real_name]" S.real_name = "Shade of [T.real_name]" T.transfer_ckey(S) + S.original_mind = T.mind.current S.copy_languages(T, LANGUAGE_MIND)//Copies the old mobs languages into the new mob holder. - S.copy_languages(user, LANGUAGE_MASTER) S.update_atom_languages() grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue if(user) @@ -264,7 +268,7 @@ to_chat(user, "Capture successful!: [T.real_name]'s soul has been ripped from [T.p_their()] body and stored within the soul stone.") -/obj/item/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/U) +/obj/item/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/user) var/mob/dead/observer/chosen_ghost for(var/mob/dead/observer/ghost in GLOB.player_list) //We put them back in their body @@ -279,13 +283,12 @@ if(!T) return FALSE if(!chosen_ghost) - to_chat(U, "There were no spirits willing to become a shade.") + to_chat(user, "There were no spirits willing to become a shade.") return FALSE if(contents.len) //If they used the soulstone on someone else in the meantime return FALSE T.ckey = chosen_ghost.ckey for(var/obj/item/W in T) T.dropItemToGround(W) - init_shade(T, U) - qdel(T) + init_shade(T, user) return TRUE diff --git a/code/modules/holiday/halloween/halloween.dm b/code/modules/holiday/halloween/halloween.dm index d3b9b92b4f..d44b94aaf3 100644 --- a/code/modules/holiday/halloween/halloween.dm +++ b/code/modules/holiday/halloween/halloween.dm @@ -86,7 +86,7 @@ else if(trapped == HOWLING_GHOST) visible_message("[pick("OooOOooooOOOoOoOOooooOOOOO", "BooOOooOooooOOOO", "BOO!", "WoOOoOoooOooo")]") playsound(loc, 'sound/spookoween/ghosty_wind.ogg', 300, 1) - new /mob/living/simple_animal/shade/howling_ghost(loc) + new /mob/living/simple_animal/hostile/construct/shade/howling_ghost(loc) trapped = 0 else if(trapped == SCARY_BATS) @@ -123,7 +123,7 @@ //Spookoween Ghost// //////////////////// -/mob/living/simple_animal/shade/howling_ghost +/mob/living/simple_animal/hostile/construct/shade/howling_ghost name = "ghost" real_name = "ghost" icon = 'icons/mob/mob.dmi' @@ -137,13 +137,13 @@ layer = 4 var/timer = 0 -/mob/living/simple_animal/shade/howling_ghost/Initialize() +/mob/living/simple_animal/hostile/construct/shade/howling_ghost/Initialize() . = ..() icon_state = pick("ghost","ghostian","ghostian2","ghostking","ghost1","ghost2") icon_living = icon_state timer = rand(1,15) -/mob/living/simple_animal/shade/howling_ghost/Life() +/mob/living/simple_animal/hostile/construct/shade/howling_ghost/Life() ..() timer-- if(prob(20)) @@ -152,16 +152,16 @@ spooky_ghosty() timer = rand(1,15) -/mob/living/simple_animal/shade/howling_ghost/proc/EtherealMove(direction) +/mob/living/simple_animal/hostile/construct/shade/howling_ghost/proc/EtherealMove(direction) forceMove(get_step(src, direction)) setDir(direction) -/mob/living/simple_animal/shade/howling_ghost/proc/roam() +/mob/living/simple_animal/hostile/construct/shade/howling_ghost/proc/roam() if(prob(80)) var/direction = pick(NORTH,SOUTH,EAST,WEST,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST) EtherealMove(direction) -/mob/living/simple_animal/shade/howling_ghost/proc/spooky_ghosty() +/mob/living/simple_animal/hostile/construct/shade/howling_ghost/proc/spooky_ghosty() if(prob(20)) //haunt playsound(loc, pick('sound/spookoween/ghosty_wind.ogg','sound/spookoween/ghost_whisper.ogg','sound/spookoween/chain_rattling.ogg'), 300, 1) if(prob(10)) //flickers @@ -175,7 +175,7 @@ step(I,direction) return -/mob/living/simple_animal/shade/howling_ghost/CanPass(atom/movable/mover, turf/target) +/mob/living/simple_animal/hostile/construct/shade/howling_ghost/CanPass(atom/movable/mover, turf/target) return 1 /////////////////////////// diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 26486f255a..ebe5372e63 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -611,7 +611,7 @@ update_mobility() UpdateStaminaBuffer() update_health_hud() - + /mob/living/carbon/update_sight() if(!client) return diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 95bd8d8991..af8382a82b 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -44,6 +44,7 @@ var/can_repair_constructs = FALSE var/can_repair_self = FALSE var/runetype + var/original_mind /mob/living/simple_animal/hostile/construct/Initialize() . = ..() @@ -66,6 +67,11 @@ CR.button.screen_loc = "6:[pos],4:-2" CR.button.moved = "6:[pos],4:-2" +/mob/living/simple_animal/hostile/construct/death() + if(original_mind) + transfer_ckey(original_mind) + ..() + /mob/living/simple_animal/hostile/construct/Login() ..() to_chat(src, playstyle_string) @@ -107,7 +113,7 @@ return /mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE) - return 0 + return FALSE /mob/living/simple_animal/hostile/construct/adjustHealth(amount, updating_health = TRUE, forced = FALSE) . = ..() diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index 75182b85e5..b46b56f472 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -1,53 +1,33 @@ -/mob/living/simple_animal/shade +/mob/living/simple_animal/hostile/construct/shade name = "Shade" real_name = "Shade" desc = "A bound spirit." - gender = PLURAL - icon = 'icons/mob/mob.dmi' icon_state = "shade" icon_living = "shade" mob_biotypes = MOB_SPIRIT maxHealth = 40 health = 40 - spacewalk = TRUE - healable = 0 - speak_emote = list("hisses") emote_hear = list("wails.","screeches.") response_help_continuous = "puts their hand through" response_help_simple = "put your hand through" - response_disarm_continuous = "flails at" - response_disarm_simple = "flail at" - response_harm_continuous = "punches" - response_harm_simple = "punch" - speak_chance = 1 melee_damage_lower = 5 melee_damage_upper = 12 attack_verb_continuous = "metaphysically strikes" attack_verb_simple = "metaphysically strike" - minbodytemp = 0 - maxbodytemp = INFINITY - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - stop_automated_movement = 1 - status_flags = 0 - faction = list("cult") - status_flags = CANPUSH - movement_type = FLYING + speed = -1 //they don't have to lug a body made of runed metal around loot = list(/obj/item/ectoplasm) - del_on_death = TRUE - initial_language_holder = /datum/language_holder/construct - blood_volume = 0 - has_field_of_vision = FALSE //we are a spoopy ghost + playstyle_string = "You are a shade! Your job is to survive until you are granted a shell, and help out cultists with casting runes!" -/mob/living/simple_animal/shade/death() +/mob/living/simple_animal/hostile/construct/shade/death() deathmessage = "lets out a contented sigh as [p_their()] form unwinds." ..() -/mob/living/simple_animal/shade/canSuicide() +/mob/living/simple_animal/hostile/construct/shade/canSuicide() if(istype(loc, /obj/item/soulstone)) //do not suicide inside the soulstone - return 0 + return FALSE return ..() -/mob/living/simple_animal/shade/attack_animal(mob/living/simple_animal/M) +/mob/living/simple_animal/hostile/construct/shade/attack_animal(mob/living/simple_animal/M) if(isconstruct(M)) var/mob/living/simple_animal/hostile/construct/C = M if(!C.can_repair_constructs) @@ -62,7 +42,7 @@ else if(src != M) return ..() -/mob/living/simple_animal/shade/attackby(obj/item/O, mob/user, params) //Marker -Agouri +/mob/living/simple_animal/hostile/construct/shade/attackby(obj/item/O, mob/user, params) //Marker -Agouri if(istype(O, /obj/item/soulstone)) var/obj/item/soulstone/SS = O SS.transfer_soul("SHADE", src, user) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 7de30a7095..3a7e270567 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -617,7 +617,7 @@ return 1 if(ispath(MP, /mob/living/simple_animal/hostile/mushroom)) return 1 - if(ispath(MP, /mob/living/simple_animal/shade)) + if(ispath(MP, /mob/living/simple_animal/hostile/construct/shade)) return 1 if(ispath(MP, /mob/living/simple_animal/hostile/killertomato)) return 1