diff --git a/code/datums/components/stationstuck.dm b/code/datums/components/stationstuck.dm index b9027ef8115..615d6ff79a6 100644 --- a/code/datums/components/stationstuck.dm +++ b/code/datums/components/stationstuck.dm @@ -1,38 +1,60 @@ + +#define PUNISHMENT_MURDER "murder" +#define PUNISHMENT_GIB "gib" +#define PUNISHMENT_TELEPORT "teleport" + //very similar to stationloving, but more made for mobs and not objects. used on derelict drones currently + + +/* +This component is similar to stationloving in that it is meant to keep something on the z-level +The difference is that stationloving is for objects and stationstuck is for mobs. +It has a punishment variable that is what happens to the parent when they leave the z-level. See punish() documentation +*/ /datum/component/stationstuck dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - var/murder = TRUE //teleports if not + var/punishment = PUNISHMENT_GIB //see defines above var/stuck_zlevel var/message = "" -/datum/component/stationstuck/Initialize(_murder = TRUE, _message = "") +/datum/component/stationstuck/Initialize(_punishment = PUNISHMENT_GIB, _message = "") if(!isliving(parent)) return COMPONENT_INCOMPATIBLE var/mob/living/L = parent RegisterSignal(L, list(COMSIG_MOVABLE_Z_CHANGED), .proc/punish) - murder = _murder + punishment = _punishment message = _message - stuck_zlevel = L.z -/datum/component/stationstuck/InheritComponent(datum/component/stationstuck/newc, original, _murder, _message) +/datum/component/stationstuck/InheritComponent(datum/component/stationstuck/newc, original, _punishment, _message) if(newc) - murder = newc.murder + punishment = newc.punishment message = newc.message else - murder = _murder + punishment = _punishment message = _message +/** + * Called when parent leaves the zlevel this is set to (aka whichever zlevel it was on when it was added) + * Sends a message, then does an effect depending on what the punishment was. + * + * Punishments: + * * PUNISHMENT_MURDER: kills parent + * * PUNISHMENT_GIB: gibs parent + * * PUNISHMENT_TELEPORT: finds a safe turf if possible, or a completely random one if not. + */ /datum/component/stationstuck/proc/punish() var/mob/living/L = parent if(message) - var/span = murder ? "userdanger" : "danger" + var/span = punishment == PUNISHMENT_TELEPORT ? "danger" : "userdanger" to_chat(L, "[message]") - if(murder) - L.gib() - return - var/targetturf = find_safe_turf(stuck_zlevel) - if(!targetturf) - targetturf = locate(world.maxx/2,world.maxy/2,stuck_zlevel) - L.forceMove(targetturf) - return targetturf + switch(punishment) + if(PUNISHMENT_MURDER) + L.death() + if(PUNISHMENT_GIB) + L.gib() + if(PUNISHMENT_TELEPORT) + var/targetturf = find_safe_turf(stuck_zlevel) + if(!targetturf) + targetturf = locate(world.maxx/2,world.maxy/2,stuck_zlevel) + L.forceMove(targetturf) diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 62f9efaae8c..17085337550 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -724,3 +724,174 @@ belt = /obj/item/storage/belt/military/assault id = /obj/item/card/id/syndicate_command/captain_id backpack_contents = list(/obj/item/documents/syndicate/red, /obj/item/paper/fluff/ruins/forgottenship/password, /obj/item/gun/ballistic/automatic/pistol/aps) + +/obj/effect/mob_spawn/human/beach/alive + death = FALSE + roundstart = FALSE + random = TRUE + mob_name = "Beach Bum" + name = "beach bum sleeper" + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "sleeper" + short_desc = "You're, like, totally a dudebro, bruh." + flavour_text = "Ch'yea. You came here, like, on spring break, hopin' to pick up some bangin' hot chicks, y'knaw?" + assignedrole = "Beach Bum" + +/obj/effect/mob_spawn/human/beach/alive/lifeguard + short_desc = "You're a spunky lifeguard!" + flavour_text = "It's up to you to make sure nobody drowns or gets eaten by sharks and stuff." + mob_gender = "female" + name = "lifeguard sleeper" + id_job = "Lifeguard" + uniform = /obj/item/clothing/under/shorts/red + +/datum/outfit/beachbum + name = "Beach Bum" + glasses = /obj/item/clothing/glasses/sunglasses + r_pocket = /obj/item/storage/wallet/random + l_pocket = /obj/item/reagent_containers/food/snacks/pizzaslice/dank; + uniform = /obj/item/clothing/under/pants/youngfolksjeans + id = /obj/item/card/id + +/datum/outfit/beachbum/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + . = ..() + if(visualsOnly) + return + H.dna.add_mutation(STONER) + +/obj/effect/mob_spawn/human/bartender/alive + death = FALSE + roundstart = FALSE + random = TRUE + name = "bartender sleeper" + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "sleeper" + short_desc = "You are a space bartender!" + flavour_text = "Time to mix drinks and change lives. Smoking space drugs makes it easier to understand your patrons' odd dialect." + assignedrole = "Space Bartender" + id_job = "Bartender" + +/datum/outfit/spacebartender + name = "Space Bartender" + uniform = /obj/item/clothing/under/rank/civilian/bartender + back = /obj/item/storage/backpack + shoes = /obj/item/clothing/shoes/sneakers/black + suit = /obj/item/clothing/suit/armor/vest + glasses = /obj/item/clothing/glasses/sunglasses/reagent + id = /obj/item/card/id + +/datum/outfit/spacebartender/post_equip(mob/living/carbon/human/H, visualsOnly) + . = ..() + var/obj/item/card/id/id_card = H.wear_id + if(H.age < AGE_MINOR) + id_card.registered_age = AGE_MINOR + to_chat(H, "You're not technically old enough to access or serve alcohol, but your ID has been discreetly modified to display your age as [AGE_MINOR]. Try to keep that a secret!") + +/obj/effect/mob_spawn/human/skeleton/alive + death = FALSE + roundstart = FALSE + icon = 'icons/effects/blood.dmi' + icon_state = "remains" + short_desc = "By unknown powers, your skeletal remains have been reanimated!" + flavour_text = "Walk this mortal plane and terrorize all living adventurers who dare cross your path." + assignedrole = "Skeleton" + +/obj/effect/mob_spawn/human/skeleton/alive/special(mob/living/new_spawn) + to_chat(new_spawn, "You have this horrible lurching feeling deep down that your binding to this world will fail if you abandon this zone... Were you reanimated to protect something?") + new_spawn.AddComponent(/datum/component/stationstuck, PUNISHMENT_MURDER, "You experience a feeling like a stressed twine being pulled until it snaps. Then, merciful nothing.") + +/obj/effect/mob_spawn/human/zombie/alive + death = FALSE + roundstart = FALSE + icon = 'icons/effects/blood.dmi' + icon_state = "remains" + short_desc = "By unknown powers, your rotting remains have been resurrected!" + flavour_text = "Walk this mortal plane and terrorize all living adventurers who dare cross your path." + +/obj/effect/mob_spawn/human/zombie/alive/special(mob/living/new_spawn) + to_chat(new_spawn, "You have this horrible lurching feeling deep down that your binding to this world will fail if you abandon this zone... Were you reanimated to protect something?") + new_spawn.AddComponent(/datum/component/stationstuck, PUNISHMENT_MURDER, "You experience a feeling like a stressed twine being pulled until it snaps. Then, merciful nothing.") + +//terribly basic spawns below, please read the disclaimer. unless you're an admin. these are perfect for events as they have no intro text. + +//if you're going to use these in a map of some kind, add GUIDANCE or stationstuck component to them on spawn. see ash walkers and skeletons for an example of each. they're simply not very fleshed out. +//if this is in your map, the player will have no idea what to do so will just go to the station and kill people until a policy headache arises + +//For ghost bar. +/obj/effect/mob_spawn/human/alive/space_bar_patron + name = "Bar cryogenics" + mob_name = "Bar patron" + random = TRUE + permanent = TRUE + uses = -1 + outfit = /datum/outfit/spacebartender + assignedrole = "Space Bar Patron" + +/obj/effect/mob_spawn/human/alive/space_bar_patron/attack_hand(mob/user) + var/despawn = alert("Return to cryosleep? (Warning, Your mob will be deleted!)", null, "Yes", "No") + if(despawn == "No" || !loc || !Adjacent(user)) + return + user.visible_message("[user.name] climbs back into cryosleep...") + qdel(user) + +/datum/outfit/cryobartender + name = "Cryogenic Bartender" + uniform = /obj/item/clothing/under/rank/civilian/bartender + back = /obj/item/storage/backpack + shoes = /obj/item/clothing/shoes/sneakers/black + suit = /obj/item/clothing/suit/armor/vest + glasses = /obj/item/clothing/glasses/sunglasses/reagent + +/obj/effect/mob_spawn/human/nanotrasensoldier/alive + death = FALSE + roundstart = FALSE + mob_name = "Private Security Officer" + name = "sleeper" + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "sleeper" + faction = "nanotrasenprivate" + short_desc = "You are a Nanotrasen Private Security Officer!" + +/obj/effect/mob_spawn/human/commander/alive + death = FALSE + roundstart = FALSE + mob_name = "\improper Nanotrasen Commander" + name = "sleeper" + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "sleeper" + short_desc = "You are a Nanotrasen Commander!" + +/obj/effect/mob_spawn/human/doctor/alive + death = FALSE + roundstart = FALSE + random = TRUE + name = "sleeper" + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "sleeper" + short_desc = "You are a space doctor!" + assignedrole = "Space Doctor" + +/obj/effect/mob_spawn/human/doctor/alive/equip(mob/living/carbon/human/doctor) + . = ..() + // Remove radio and PDA so they wouldn't annoy station crew. + var/list/del_types = list(/obj/item/pda, /obj/item/radio/headset) + for(var/del_type in del_types) + var/obj/item/unwanted_item = locate(del_type) in doctor + qdel(unwanted_item) + +/obj/effect/mob_spawn/mouse + name = "sleeper" + mob_type = /mob/living/simple_animal/mouse + death = FALSE + roundstart = FALSE + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "sleeper" + +/obj/effect/mob_spawn/cow + name = "sleeper" + mob_type = /mob/living/simple_animal/cow + death = FALSE + roundstart = FALSE + mob_gender = FEMALE + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "sleeper" diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index b9a1c4e571b..d4480c422b7 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -2,6 +2,9 @@ //To do: Allow corpses to appear mangled, bloody, etc. Allow customizing the bodies appearance (they're all bald and white right now). + +//HEY! LISTEN! anything that is ALIVE and thus GHOSTS CAN TAKE is in ghost_role_spawners.dm! + /obj/effect/mob_spawn name = "Mob Spawner" density = TRUE @@ -252,6 +255,7 @@ /obj/effect/mob_spawn/human/corpse/damaged brute_damage = 1000 +//i left this here despite being a mob spawner because this is a base type /obj/effect/mob_spawn/human/alive icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" @@ -291,23 +295,6 @@ O.Die() //call the facehugger's death proc qdel(src) -/obj/effect/mob_spawn/mouse - name = "sleeper" - mob_type = /mob/living/simple_animal/mouse - death = FALSE - roundstart = FALSE - icon = 'icons/obj/machines/sleeper.dmi' - icon_state = "sleeper" - -/obj/effect/mob_spawn/cow - name = "sleeper" - mob_type = /mob/living/simple_animal/cow - death = FALSE - roundstart = FALSE - mob_gender = FEMALE - icon = 'icons/obj/machines/sleeper.dmi' - icon_state = "sleeper" - // I'll work on making a list of corpses people request for maps, or that I think will be commonly used. Syndicate operatives for example. ///////////Civilians////////////////////// @@ -336,31 +323,11 @@ outfit = /datum/outfit/job/cook icon_state = "corpsecook" - /obj/effect/mob_spawn/human/doctor name = "Doctor" outfit = /datum/outfit/job/doctor icon_state = "corpsedoctor" - -/obj/effect/mob_spawn/human/doctor/alive - death = FALSE - roundstart = FALSE - random = TRUE - name = "sleeper" - icon = 'icons/obj/machines/sleeper.dmi' - icon_state = "sleeper" - short_desc = "You are a space doctor!" - assignedrole = "Space Doctor" - -/obj/effect/mob_spawn/human/doctor/alive/equip(mob/living/carbon/human/H) - ..() - // Remove radio and PDA so they wouldn't annoy station crew. - var/list/del_types = list(/obj/item/pda, /obj/item/radio/headset) - for(var/del_type in del_types) - var/obj/item/I = locate(del_type) in H - qdel(I) - /obj/effect/mob_spawn/human/engineer name = "Engineer" outfit = /datum/outfit/job/engineer/gloved @@ -390,84 +357,19 @@ /obj/effect/mob_spawn/human/miner/explorer outfit = /datum/outfit/job/miner/equipped - /obj/effect/mob_spawn/human/plasmaman mob_species = /datum/species/plasmaman outfit = /datum/outfit/plasmaman - /obj/effect/mob_spawn/human/bartender name = "Space Bartender" id_job = "Bartender" id_access_list = list(ACCESS_BAR) outfit = /datum/outfit/spacebartender -/obj/effect/mob_spawn/human/bartender/alive - death = FALSE - roundstart = FALSE - random = TRUE - name = "bartender sleeper" - icon = 'icons/obj/machines/sleeper.dmi' - icon_state = "sleeper" - short_desc = "You are a space bartender!" - flavour_text = "Time to mix drinks and change lives. Smoking space drugs makes it easier to understand your patrons' odd dialect." - assignedrole = "Space Bartender" - id_job = "Bartender" - -/datum/outfit/spacebartender - name = "Space Bartender" - uniform = /obj/item/clothing/under/rank/civilian/bartender - back = /obj/item/storage/backpack - shoes = /obj/item/clothing/shoes/sneakers/black - suit = /obj/item/clothing/suit/armor/vest - glasses = /obj/item/clothing/glasses/sunglasses/reagent - id = /obj/item/card/id - -/datum/outfit/spacebartender/post_equip(mob/living/carbon/human/H, visualsOnly) - . = ..() - - var/obj/item/card/id/W = H.wear_id - if(H.age < AGE_MINOR) - W.registered_age = AGE_MINOR - to_chat(H, "You're not technically old enough to access or serve alcohol, but your ID has been discreetly modified to display your age as [AGE_MINOR]. Try to keep that a secret!") - /obj/effect/mob_spawn/human/beach outfit = /datum/outfit/beachbum -/obj/effect/mob_spawn/human/beach/alive - death = FALSE - roundstart = FALSE - random = TRUE - mob_name = "Beach Bum" - name = "beach bum sleeper" - icon = 'icons/obj/machines/sleeper.dmi' - icon_state = "sleeper" - short_desc = "You're, like, totally a dudebro, bruh." - flavour_text = "Ch'yea. You came here, like, on spring break, hopin' to pick up some bangin' hot chicks, y'knaw?" - assignedrole = "Beach Bum" - -/obj/effect/mob_spawn/human/beach/alive/lifeguard - short_desc = "You're a spunky lifeguard!" - flavour_text = "It's up to you to make sure nobody drowns or gets eaten by sharks and stuff." - mob_gender = "female" - name = "lifeguard sleeper" - id_job = "Lifeguard" - uniform = /obj/item/clothing/under/shorts/red - -/datum/outfit/beachbum - name = "Beach Bum" - glasses = /obj/item/clothing/glasses/sunglasses - r_pocket = /obj/item/storage/wallet/random - l_pocket = /obj/item/reagent_containers/food/snacks/pizzaslice/dank; - uniform = /obj/item/clothing/under/pants/youngfolksjeans - id = /obj/item/card/id - -/datum/outfit/beachbum/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - ..() - if(visualsOnly) - return - H.dna.add_mutation(STONER) - /////////////////Officers+Nanotrasen Security////////////////////// /obj/effect/mob_spawn/human/bridgeofficer @@ -485,7 +387,6 @@ glasses = /obj/item/clothing/glasses/sunglasses id = /obj/item/card/id - /obj/effect/mob_spawn/human/commander name = "Commander" id_job = "Commander" @@ -505,7 +406,6 @@ r_pocket = /obj/item/lighter id = /obj/item/card/id - /obj/effect/mob_spawn/human/nanotrasensoldier name = "\improper Nanotrasen Private Security Officer" id_job = "Private Security Force" @@ -523,28 +423,8 @@ back = /obj/item/storage/backpack/security id = /obj/item/card/id - -/obj/effect/mob_spawn/human/commander/alive - death = FALSE - roundstart = FALSE - mob_name = "\improper Nanotrasen Commander" - name = "sleeper" - icon = 'icons/obj/machines/sleeper.dmi' - icon_state = "sleeper" - short_desc = "You are a Nanotrasen Commander!" - -/obj/effect/mob_spawn/human/nanotrasensoldier/alive - death = FALSE - roundstart = FALSE - mob_name = "Private Security Officer" - name = "sleeper" - icon = 'icons/obj/machines/sleeper.dmi' - icon_state = "sleeper" - faction = "nanotrasenprivate" - short_desc = "You are a Nanotrasen Private Security Officer!" - - /////////////////Spooky Undead////////////////////// +//there are living variants of many of these, they're now in ghost_role_spawners.dm /obj/effect/mob_spawn/human/skeleton name = "skeletal remains" @@ -552,30 +432,12 @@ mob_species = /datum/species/skeleton mob_gender = NEUTER -/obj/effect/mob_spawn/human/skeleton/alive - death = FALSE - roundstart = FALSE - icon = 'icons/effects/blood.dmi' - icon_state = "remains" - short_desc = "By unknown powers, your skeletal remains have been reanimated!" - flavour_text = "Walk this mortal plain and terrorize all living adventurers who dare cross your path." - assignedrole = "Skeleton" - /obj/effect/mob_spawn/human/zombie name = "rotting corpse" mob_name = "zombie" mob_species = /datum/species/zombie assignedrole = "Zombie" -/obj/effect/mob_spawn/human/zombie/alive - death = FALSE - roundstart = FALSE - icon = 'icons/effects/blood.dmi' - icon_state = "remains" - short_desc = "By unknown powers, your rotting remains have been resurrected!" - flavour_text = "Walk this mortal plain and terrorize all living adventurers who dare cross your path." - - /obj/effect/mob_spawn/human/abductor name = "abductor" mob_name = "alien" @@ -586,30 +448,3 @@ name = "Abductor Corpse" uniform = /obj/item/clothing/under/color/grey shoes = /obj/item/clothing/shoes/combat - - -//For ghost bar. -/obj/effect/mob_spawn/human/alive/space_bar_patron - name = "Bar cryogenics" - mob_name = "Bar patron" - random = TRUE - permanent = TRUE - uses = -1 - outfit = /datum/outfit/spacebartender - assignedrole = "Space Bar Patron" - -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/mob_spawn/human/alive/space_bar_patron/attack_hand(mob/user) - var/despawn = alert("Return to cryosleep? (Warning, Your mob will be deleted!)",,"Yes","No") - if(despawn == "No" || !loc || !Adjacent(user)) - return - user.visible_message("[user.name] climbs back into cryosleep...") - qdel(user) - -/datum/outfit/cryobartender - name = "Cryogenic Bartender" - uniform = /obj/item/clothing/under/rank/civilian/bartender - back = /obj/item/storage/backpack - shoes = /obj/item/clothing/shoes/sneakers/black - suit = /obj/item/clothing/suit/armor/vest - glasses = /obj/item/clothing/glasses/sunglasses/reagent diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm index d77cc98cae4..0b3eee0384f 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm @@ -129,7 +129,7 @@ /mob/living/simple_animal/drone/derelict/Initialize() . = ..() - AddComponent(/datum/component/stationstuck, TRUE, "Your emergency station return device activates, sending you back to KS13!", "01000110 01010101 01000011 01001011 00100000 01011001 01001111 01010101
WARNING: Dereliction of KS13 detected. Self-destruct activated.") + AddComponent(/datum/component/stationstuck, PUNISHMENT_GIB, "01000110 01010101 01000011 01001011 00100000 01011001 01001111 01010101
WARNING: Dereliction of KS13 detected. Self-destruct activated.")