mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 18:02:57 +00:00
Does the thing
This commit is contained in:
@@ -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))
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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]"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,6 +203,12 @@ 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, "<span class='warning'>[L] has already been sacrificed!</span>")
|
||||
return
|
||||
rune_in_use = TRUE
|
||||
visible_message("<span class='warning'>[src] pulses blood red!</span>")
|
||||
var/oldcolor = color
|
||||
@@ -264,7 +270,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 +314,19 @@ 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
|
||||
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)
|
||||
else
|
||||
playsound(sacrificial, 'sound/magic/disintegrate.ogg', 100, 1)
|
||||
sacrificial.gib()
|
||||
playsound(sacrificial, 'sound/magic/disintegrate.ogg', 100, TRUE)
|
||||
sacrifical.gib()
|
||||
return TRUE
|
||||
|
||||
/obj/effect/rune/empower
|
||||
|
||||
@@ -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)
|
||||
. += "<span class='cult'>A soulstone, used to capture a soul, either from dead humans or from freed shades.</span>"
|
||||
else
|
||||
@@ -46,7 +46,7 @@
|
||||
. += "<span class='cult'>This shard is spent; it is now just a creepy rock.</span>"
|
||||
|
||||
/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, "<span class='userdanger'>Your body is wracked with debilitating pain!</span>")
|
||||
return
|
||||
if(spent)
|
||||
to_chat(user, "<span class='warning'>There is no power left in the shard.</span>")
|
||||
to_chat(user, "<span class='warning'>There is no power left in [src].</span>")
|
||||
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)
|
||||
. += "<span class='cult'>A construct shell, used to house bound souls from a soulstone.</span>"
|
||||
. += "<span class='cult'>Placing a soulstone with a soul into this shell allows you to produce your choice of the following:</span>"
|
||||
. += "<span class='cult'>An <b>Artificer</b>, which can produce <b>more shells and soulstones</b>, as well as fortifications.</span>"
|
||||
. += "<span class='cult'>A <b>Wraith</b>, which does high damage and can jaunt through walls, though it is quite fragile.</span>"
|
||||
. += "<span class='cult'>A <b>Juggernaut</b>, which is very hard to kill and can produce temporary walls, but is slow.</span>"
|
||||
if(iscultist(user) || iswizard(user) || user.stat == DEAD)
|
||||
. += {"<span class='cult'>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 <b>Artificer</b>, which can produce <b>more shells and soulstones</b>, as well as fortifications.\n
|
||||
A <b>Wraith</b>, which does high damage and can jaunt through walls, though it is quite fragile.\n
|
||||
A <b>Juggernaut</b>, which is very hard to kill and can produce temporary walls, but is slow.</span>"}
|
||||
|
||||
/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, "<span class='cult'><b>\"This soul is mine.</b></span> <span class='cultlarge'>SACRIFICE THEM!\"</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>The soulstone seems to reject this soul.</span>")
|
||||
to_chat(user, "<span class='danger'>[src] seems to reject this soul.</span>")
|
||||
return FALSE
|
||||
if(contents.len)
|
||||
to_chat(user, "<span class='userdanger'>Capture failed!</span>: The soulstone is full! Free an existing soul to make room.")
|
||||
to_chat(user, "<span class='userdanger'>Capture failed!</span>: [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, "<span class='userdanger'>Capture failed!</span>: 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, "<span class='userdanger'>Capture failed!</span>: The soulstone is full! Free an existing soul to make room.")
|
||||
else
|
||||
@@ -177,15 +177,20 @@
|
||||
T.health = T.maxHealth
|
||||
icon_state = "soulstone2"
|
||||
name = "soulstone: Shade of [T.real_name]"
|
||||
to_chat(T, "<span class='notice'>Your soul has been captured by the soulstone. Its arcane energies are reknitting your ethereal form.</span>")
|
||||
to_chat(T, "<span class='notice'>Your soul has been captured by [src]. Its arcane energies are reknitting your ethereal form.</span>")
|
||||
if(user != T)
|
||||
to_chat(user, "<span class='info'><b>Capture successful!</b>:</span> [T.real_name]'s soul has been captured and stored within the soulstone.")
|
||||
to_chat(user, "<span class='info'><b>Capture successful!</b>:</span> [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")
|
||||
var/list/constructs = list(
|
||||
"Juggernaut" = image(icon = 'icons/mob/cult.dmi', icon_state = "juggernaut"),
|
||||
"Wraith" = image(icon = 'icons/mob/cult.dmi', icon_state = "wraith"),
|
||||
"Artificer" = image(icon = 'icons/mob/cult.dmi', icon_state = "artificer")
|
||||
)
|
||||
var/construct_class = show_radial_menu(user, src, constructs, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
|
||||
if(!T || !T.loc)
|
||||
return
|
||||
switch(construct_class)
|
||||
@@ -200,7 +205,7 @@
|
||||
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)
|
||||
return
|
||||
for(var/datum/mind/B in SSticker.mode.cult)
|
||||
if(B == A.mind)
|
||||
SSticker.mode.cult -= A.mind
|
||||
@@ -208,19 +213,28 @@
|
||||
qdel(T)
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='userdanger'>Creation failed!</span>: The soul stone is empty! Go kill someone!")
|
||||
to_chat(user, "<span class='userdanger'>Creation failed!</span>: [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)))
|
||||
var/makeicon = newstruct.icon_state
|
||||
var/holyness = newstruct.holy
|
||||
flick("make_[makeicon][holyness]", newstruct)
|
||||
playsound(newstruct, 'sound/effects/constructform.ogg', 50)
|
||||
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, "<b>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.</b>")
|
||||
@@ -233,20 +247,21 @@
|
||||
newstruct.cancel_camera()
|
||||
|
||||
|
||||
/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
|
||||
/obj/item/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/user)
|
||||
if(!shade_controller)
|
||||
shade_controller = T
|
||||
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.key = shade_controller.key
|
||||
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 +279,7 @@
|
||||
to_chat(user, "<span class='info'><b>Capture successful!</b>:</span> [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
|
||||
@@ -283,9 +298,7 @@
|
||||
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)
|
||||
return TRUE
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
else if(trapped == HOWLING_GHOST)
|
||||
visible_message("<span class='userdanger'><font size='5'>[pick("OooOOooooOOOoOoOOooooOOOOO", "BooOOooOooooOOOO", "BOO!", "WoOOoOoooOooo")]</font></span>")
|
||||
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
|
||||
|
||||
///////////////////////////
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
var/can_repair_constructs = FALSE
|
||||
var/can_repair_self = FALSE
|
||||
var/runetype
|
||||
var/original_body
|
||||
|
||||
/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_body)
|
||||
transfer_ckey(original_body)
|
||||
..()
|
||||
|
||||
/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)
|
||||
. = ..()
|
||||
|
||||
@@ -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 = "<span class='big bold'>You are a shade!</span><b> Your job is to survive until you are granted a shell, and help out cultists with casting runes!</b>"
|
||||
|
||||
/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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user