mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-15 10:04:30 +01:00
Merge remote-tracking branch 'tgstation/master' into upstream-2025-11-29
# Conflicts: # _maps/RandomRuins/SpaceRuins/derelict_sulaco.dmm # _maps/RandomRuins/SpaceRuins/garbagetruck2.dmm # _maps/map_files/CatwalkStation/CatwalkStation_2023.dmm # _maps/map_files/tramstation/tramstation.dmm # code/_onclick/hud/new_player.dm # code/datums/components/squashable.dm # code/datums/diseases/advance/symptoms/heal.dm # code/datums/diseases/chronic_illness.dm # code/datums/status_effects/buffs.dm # code/datums/status_effects/debuffs/drunk.dm # code/datums/status_effects/debuffs/stamcrit.dm # code/game/machinery/computer/crew.dm # code/game/objects/items/devices/scanners/health_analyzer.dm # code/game/objects/items/wall_mounted.dm # code/game/turfs/closed/indestructible.dm # code/modules/admin/view_variables/filterrific.dm # code/modules/antagonists/heretic/influences.dm # code/modules/cargo/orderconsole.dm # code/modules/client/preferences.dm # code/modules/events/space_vines/vine_mutations.dm # code/modules/mob/dead/new_player/new_player.dm # code/modules/mob/living/carbon/human/death.dm # code/modules/mob/living/carbon/human/species_types/jellypeople.dm # code/modules/mob/living/damage_procs.dm # code/modules/mob/living/living.dm # code/modules/mob_spawn/ghost_roles/mining_roles.dm # code/modules/mob_spawn/mob_spawn.dm # code/modules/projectiles/ammunition/energy/laser.dm # code/modules/projectiles/guns/ballistic/launchers.dm # code/modules/projectiles/guns/energy/laser.dm # code/modules/reagents/chemistry/machinery/chem_dispenser.dm # code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm # code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm # code/modules/reagents/chemistry/reagents/medicine_reagents.dm # code/modules/surgery/healing.dm # code/modules/unit_tests/designs.dm # icons/mob/inhands/items_lefthand.dmi # icons/mob/inhands/items_righthand.dmi # tgui/packages/tgui/interfaces/ChemDispenser.tsx
This commit is contained in:
@@ -59,15 +59,15 @@
|
||||
outfit = /datum/outfit/job/assistant
|
||||
icon_state = "corpsegreytider"
|
||||
|
||||
/obj/effect/mob_spawn/corpse/human/assistant/beesease_infection/special(mob/living/spawned_mob, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/human/assistant/beesease_infection/special(mob/living/spawned_mob, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_mob.ForceContractDisease(new /datum/disease/beesease)
|
||||
|
||||
/obj/effect/mob_spawn/corpse/human/assistant/brainrot_infection/special(mob/living/spawned_mob, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/human/assistant/brainrot_infection/special(mob/living/spawned_mob, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_mob.ForceContractDisease(new /datum/disease/brainrot)
|
||||
|
||||
/obj/effect/mob_spawn/corpse/human/assistant/spanishflu_infection/special(mob/living/spawned_mob, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/human/assistant/spanishflu_infection/special(mob/living/spawned_mob, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_mob.ForceContractDisease(new /datum/disease/fluspanish)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
burn_damage = 1000
|
||||
mob_species = /datum/species/skeleton
|
||||
|
||||
/obj/effect/mob_spawn/corpse/human/charredskeleton/special(mob/living/carbon/human/spawned_human, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/human/charredskeleton/special(mob/living/carbon/human/spawned_human, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_human.color = "#454545"
|
||||
spawned_human.gender = NEUTER
|
||||
@@ -34,7 +34,7 @@
|
||||
outfit = select_outfit()
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/corpse/human/legioninfested/special(mob/living/carbon/human/spawned_human, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/human/legioninfested/special(mob/living/carbon/human/spawned_human, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
var/obj/item/organ/legion_tumour/cancer = new()
|
||||
cancer.Insert(spawned_human, special = TRUE, movement_flags = DELETE_IF_REPLACED)
|
||||
@@ -75,7 +75,7 @@
|
||||
/// Corpse spawner used by dwarf legions to make small corpses
|
||||
/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf
|
||||
|
||||
/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf/special(mob/living/carbon/human/spawned_human, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/human/legioninfested/dwarf/special(mob/living/carbon/human/spawned_human, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_human.dna.add_mutation(/datum/mutation/dwarfism, MUTATION_SOURCE_MUTATOR)
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/select_outfit()
|
||||
return null
|
||||
|
||||
/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/special(mob/living/carbon/human/spawned_human, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/special(mob/living/carbon/human/spawned_human, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_human.gender = NEUTER
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
brute_damage = 0
|
||||
burn_damage = 1000
|
||||
|
||||
/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/charred/special(mob/living/carbon/human/spawned_human, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/human/legioninfested/skeleton/charred/special(mob/living/carbon/human/spawned_human, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_human.color = "#454545"
|
||||
spawned_human.AddComponent(/datum/component/storm_hating)
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
outfit = /datum/outfit/centcom/centcom_intern/unarmed
|
||||
mob_name = "Nameless Intern"
|
||||
|
||||
/obj/effect/mob_spawn/corpse/human/intern/special(mob/living/carbon/human/spawned_human, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/human/intern/special(mob/living/carbon/human/spawned_human, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_human.gender = MALE //we're making it canon babies
|
||||
spawned_human.update_body()
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
/obj/effect/mob_spawn/corpse/ai
|
||||
mob_type = /mob/living/silicon/ai/spawned
|
||||
|
||||
/obj/effect/mob_spawn/corpse/ai/create(mob/user, newname)
|
||||
/obj/effect/mob_spawn/corpse/ai/create(mob/user, newname, apply_prefs)
|
||||
var/ai_already_present = locate(/mob/living/silicon/ai) in loc
|
||||
if(ai_already_present)
|
||||
return
|
||||
. = ..()
|
||||
return CANCEL_SPAWN
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/corpse/ai/special(mob/living/silicon/ai/spawned/dead_ai, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/ai/special(mob/living/silicon/ai/spawned/dead_ai, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
dead_ai.name = src.name
|
||||
dead_ai.real_name = src.name
|
||||
@@ -24,7 +24,7 @@
|
||||
///the color of the slime you're spawning.
|
||||
var/slime_species = /datum/slime_type/grey
|
||||
|
||||
/obj/effect/mob_spawn/corpse/slime/special(mob/living/basic/slime/spawned_slime, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/slime/special(mob/living/basic/slime/spawned_slime, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_slime.set_slime_type(slime_species)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
//mostly for unit tests to not get alarmed (which by all means it should because this is a mess)
|
||||
mob_type = /obj/item/clothing/mask/facehugger
|
||||
|
||||
/obj/effect/mob_spawn/corpse/facehugger/create(mob/user)
|
||||
/obj/effect/mob_spawn/corpse/facehugger/create(mob/user, newname, apply_prefs)
|
||||
var/obj/item/clothing/mask/facehugger/spawned_facehugger = new mob_type(loc)
|
||||
spawned_facehugger.Die()
|
||||
qdel(src)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
flavour_text = "Walk this mortal plane and terrorize all living adventurers who dare cross your path."
|
||||
spawner_job_path = /datum/job/skeleton
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/skeleton/special(mob/living/new_spawn, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/skeleton/special(mob/living/new_spawn, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
to_chat(new_spawn, "<b>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?</b>")
|
||||
new_spawn.AddComponent(/datum/component/stationstuck, PUNISHMENT_MURDER, "You experience a feeling like a stressed twine being pulled until it snaps. Then, merciful nothing.")
|
||||
@@ -30,7 +30,7 @@
|
||||
you_are_text = "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/ghost_role/human/zombie/special(mob/living/new_spawn, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/zombie/special(mob/living/new_spawn, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
to_chat(new_spawn, "<b>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?</b>")
|
||||
new_spawn.AddComponent(/datum/component/stationstuck, PUNISHMENT_MURDER, "You experience a feeling like a stressed twine being pulled until it snaps. Then, merciful nothing.")
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
flavour_text = "Write me some god damn flavor text!" //the flavor text will be the backstory argument called on the antagonist's greet, see hunter.dm for details
|
||||
show_flavor = FALSE
|
||||
var/back_story = "error"
|
||||
allow_custom_character = GHOSTROLE_TAKE_PREFS_APPEARANCE
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/fugitive/special(mob/living/carbon/human/spawned_human, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/fugitive/special(mob/living/carbon/human/spawned_human, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
var/datum/antagonist/fugitive_hunter/fughunter = new
|
||||
fughunter.backstory = back_story
|
||||
|
||||
@@ -32,14 +32,7 @@
|
||||
notify_flags = NOTIFY_CATEGORY_NOFLASH,
|
||||
)
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/golem/name_mob(mob/living/spawned_mob, forced_name)
|
||||
if(forced_name || !iscarbon(spawned_mob))
|
||||
return ..()
|
||||
|
||||
forced_name = generate_random_name_species_based(spawned_mob.gender, TRUE, species_type = /datum/species/golem)
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/golem/special(mob/living/new_spawn, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/golem/special(mob/living/new_spawn, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
if(is_path_in_list(initial_type, GLOB.golem_stack_food_directory))
|
||||
var/datum/golem_food_buff/initial_buff = GLOB.golem_stack_food_directory[initial_type]
|
||||
@@ -73,7 +66,7 @@
|
||||
desc = "A humanoid shape, empty, lifeless, and full of potential."
|
||||
prompt_name = "a free golem"
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/golem/adamantine/special(mob/living/new_spawn, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/golem/adamantine/special(mob/living/new_spawn, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
if(!ishuman(new_spawn))
|
||||
return
|
||||
@@ -110,8 +103,6 @@
|
||||
to_chat(new_spawn, span_userdanger("Serve [real_owner.real_name], and assist [real_owner.p_them()] in completing [real_owner.p_their()] goals at any cost."))
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/golem/servant/name_mob(mob/living/spawned_mob, forced_name)
|
||||
if(forced_name || !iscarbon(spawned_mob))
|
||||
return ..()
|
||||
if(owner_ref?.resolve())
|
||||
forced_name = "Golem ([rand(1,999)])"
|
||||
return ..()
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \
|
||||
the fresh air of Earth. These thoughts are dispelled by yet another recollection of how you got here... "
|
||||
spawner_job_path = /datum/job/hermit
|
||||
allow_custom_character = ALL
|
||||
quirks_enabled = TRUE // SKYRAT EDIT ADDITION - ghost role loadouts
|
||||
random_appearance = FALSE // SKYRAT EDIT ADDITION
|
||||
|
||||
@@ -81,6 +82,7 @@
|
||||
flavour_text = "Ch'yea. You came here, like, on spring break, hopin' to pick up some bangin' hot chicks, y'knaw?"
|
||||
spawner_job_path = /datum/job/beach_bum
|
||||
outfit = /datum/outfit/beachbum
|
||||
allow_custom_character = GHOSTROLE_TAKE_PREFS_APPEARANCE
|
||||
quirks_enabled = TRUE // SKYRAT EDIT ADDITION - ghost role loadouts
|
||||
random_appearance = FALSE // SKYRAT EDIT ADDITION
|
||||
|
||||
@@ -89,8 +91,9 @@
|
||||
flavour_text = "It's up to you to make sure nobody drowns or gets eaten by sharks and stuff."
|
||||
name = "lifeguard sleeper"
|
||||
outfit = /datum/outfit/beachbum/lifeguard
|
||||
allow_custom_character = NONE
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/beach/lifeguard/special(mob/living/carbon/human/lifeguard, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/beach/lifeguard/special(mob/living/carbon/human/lifeguard, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
lifeguard.gender = FEMALE
|
||||
lifeguard.update_body()
|
||||
@@ -123,6 +126,7 @@
|
||||
flavour_text = "Time to mix drinks and change lives. Smoking space drugs makes it easier to understand your patrons' odd dialect."
|
||||
spawner_job_path = /datum/job/space_bartender
|
||||
outfit = /datum/outfit/spacebartender
|
||||
allow_custom_character = ALL
|
||||
random_appearance = FALSE // SKYRAT EDIT ADDITION
|
||||
|
||||
/datum/outfit/spacebartender
|
||||
@@ -242,7 +246,7 @@
|
||||
to_chat(user, span_warning("You have exhausted your usefulness to the Necropolis."))
|
||||
return FALSE
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/ash_walker/special(mob/living/carbon/human/spawned_human, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/ash_walker/special(mob/living/carbon/human/spawned_human, mob/mob_possessor, apply_prefs)
|
||||
// SKYRAT EDIT ADDITION BEGIN
|
||||
spawned_human.fully_replace_character_name(null, spawned_human.generate_random_mob_name(TRUE)) // SKYRAT EDIT MOVE - Moving before parent call prevents char name randomization
|
||||
quirks_enabled = TRUE // ghost role quirks
|
||||
@@ -300,8 +304,9 @@
|
||||
quirks_enabled = TRUE // SKYRAT EDIT ADDITION - ghost role loadouts
|
||||
random_appearance = FALSE // SKYRAT EDIT ADDITION
|
||||
deletes_on_zero_uses_left = FALSE
|
||||
allow_custom_character = ALL
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/lavaland_syndicate/special(mob/living/new_spawn, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/lavaland_syndicate/special(mob/living/new_spawn, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
new_spawn.grant_language(/datum/language/codespeak, source = LANGUAGE_SPAWNER) // SKYRAT EDIT CHANGE - ORIGINAL: new_spawn.grant_language(/datum/language/codespeak, source = LANGUAGE_MIND)
|
||||
|
||||
|
||||
@@ -14,9 +14,12 @@
|
||||
important_text = "Work as a team with your fellow survivors and do not abandon them."
|
||||
outfit = /datum/outfit/oldeng
|
||||
spawner_job_path = /datum/job/ancient_crew
|
||||
allow_custom_character = GHOSTROLE_TAKE_PREFS_APPEARANCE
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/oldstation/create_from_ghost(mob/dead/user)
|
||||
/obj/effect/mob_spawn/ghost_role/human/oldstation/create(mob/mob_possessor, newname, apply_prefs)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
notify_ghosts(
|
||||
"Someone just woke up on Charlie Station! Why not join them and help out?",
|
||||
source = ., //the spawned mob
|
||||
@@ -102,6 +105,7 @@
|
||||
outfit = /datum/outfit/syndicate_empty/battlecruiser
|
||||
spawner_job_path = /datum/job/battlecruiser_crew
|
||||
uses = 4
|
||||
allow_custom_character = ALL
|
||||
|
||||
/// The antag team to apply the player to
|
||||
var/datum/team/antag_team
|
||||
@@ -191,6 +195,7 @@
|
||||
important_text = "Work as a team with your fellow actors and the director to make entertainment for the masses."
|
||||
outfit = /datum/outfit/actor
|
||||
spawner_job_path = /datum/job/ghost_role
|
||||
allow_custom_character = ALL
|
||||
|
||||
/datum/outfit/actor
|
||||
name = "Actor"
|
||||
@@ -215,6 +220,7 @@
|
||||
important_text = "Work as a team with your fellow actors and the director to make entertainment for the masses."
|
||||
outfit = /datum/outfit/actor/director
|
||||
spawner_job_path = /datum/job/ghost_role
|
||||
allow_custom_character = ALL
|
||||
|
||||
/datum/outfit/actor/director
|
||||
name = "Director"
|
||||
|
||||
@@ -139,8 +139,9 @@
|
||||
if(!silent)
|
||||
to_chat(user, span_warning("\The [src] is not ready to hatch yet!"))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/spider/special(mob/living/basic/spider/spawned_mob, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/spider/special(mob/living/basic/spider/spawned_mob, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
if (isspider(spawned_mob))
|
||||
spawned_mob.directive = directive
|
||||
@@ -197,21 +198,12 @@
|
||||
)
|
||||
flash_window = TRUE
|
||||
|
||||
/**
|
||||
* Makes a ghost into a spider based on the type of egg cluster.
|
||||
*
|
||||
* Allows a ghost to get a prompt to use the egg cluster to become a spider.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - The ghost attempting to become a spider
|
||||
* * newname - If set, renames the mob to this name
|
||||
*/
|
||||
/obj/effect/mob_spawn/ghost_role/spider/create(mob/user, newname)
|
||||
/obj/effect/mob_spawn/ghost_role/spider/pre_ghost_take(mob/dead/observer/user)
|
||||
var/chosen_spider = length(potentialspawns) > 1 ? get_radial_choice(user) : potentialspawns[1]
|
||||
if(QDELETED(src) || QDELETED(user) || isnull(chosen_spider))
|
||||
if(isnull(chosen_spider))
|
||||
return FALSE
|
||||
mob_type = chosen_spider
|
||||
return ..()
|
||||
return TRUE
|
||||
|
||||
/// Pick a spider type from a radial menu
|
||||
/obj/effect/mob_spawn/ghost_role/spider/proc/get_radial_choice(mob/user)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
though fate has other plans for you."
|
||||
flavour_text = "Good. It seems as though your ship crashed. You remember that you were convicted of "
|
||||
spawner_job_path = /datum/job/escaped_prisoner
|
||||
allow_custom_character = GHOSTROLE_TAKE_PREFS_APPEARANCE
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/prisoner_transport/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -24,7 +25,7 @@
|
||||
new /obj/structure/fluff/empty_sleeper/syndicate(get_turf(src))
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/prisoner_transport/special(mob/living/carbon/human/spawned_human, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/prisoner_transport/special(mob/living/carbon/human/spawned_human, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_human.fully_replace_character_name(null, "NTP #LL-0[rand(111,999)]") //Nanotrasen Prisoner #Lavaland-(numbers)
|
||||
|
||||
@@ -50,6 +51,7 @@
|
||||
flavour_text = "Cater to visiting guests with your fellow staff, advertise the hotel, and make sure the manager doesn't fire you. Remember, the customer is always right!"
|
||||
important_text = "Do NOT leave the hotel, as that is grounds for contract termination."
|
||||
spawner_job_path = /datum/job/hotel_staff
|
||||
allow_custom_character = ALL
|
||||
|
||||
/datum/outfit/hotelstaff
|
||||
name = "Hotel Staff"
|
||||
@@ -94,6 +96,7 @@
|
||||
flavour_text = "You have awoken, without instruction. Death to Nanotrasen! If there are some clues around as to what you're supposed to be doing, you best follow those."
|
||||
outfit = /datum/outfit/syndicate_empty
|
||||
spawner_job_path = /datum/job/space_syndicate
|
||||
allow_custom_character = ALL
|
||||
|
||||
/datum/outfit/syndicate_empty
|
||||
name = "Syndicate Operative Empty"
|
||||
@@ -119,6 +122,7 @@
|
||||
flavour_text = "Hang out at the bar and chat with your buddies. Feel free to hop back in the cryogenics when you're done chatting."
|
||||
outfit = /datum/outfit/cryobartender
|
||||
spawner_job_path = /datum/job/space_bar_patron
|
||||
allow_custom_character = ALL
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/space_bar_patron/attack_hand(mob/user, list/modifiers)
|
||||
var/despawn = tgui_alert(usr, "Return to cryosleep? (Warning, Your mob will be deleted!)", null, list("Yes", "No"))
|
||||
@@ -153,7 +157,7 @@
|
||||
new/obj/structure/fluff/empty_sleeper(get_turf(src))
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/exile/special(mob/living/new_spawn, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/exile/special(mob/living/new_spawn, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
new_spawn.fully_replace_character_name(null,"Wish Granter's Victim ([rand(1,999)])")
|
||||
var/wish = rand(1,4)
|
||||
@@ -178,6 +182,7 @@
|
||||
you_are_text = "You are a Nanotrasen Private Security Officer!"
|
||||
flavour_text = "If higher command has an assignment for you, it's best you follow that. Otherwise, death to The Syndicate."
|
||||
outfit = /datum/outfit/nanotrasensoldier
|
||||
allow_custom_character = ALL
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/commander
|
||||
name = "sleeper"
|
||||
@@ -187,6 +192,7 @@
|
||||
you_are_text = "You are a Nanotrasen Commander!"
|
||||
flavour_text = "Upper-crusty of Nanotrasen. You should be given the respect you're owed."
|
||||
outfit = /datum/outfit/nanotrasencommander
|
||||
allow_custom_character = GHOSTROLE_TAKE_PREFS_APPEARANCE
|
||||
|
||||
//space doctor, a rat with cancer, and bessie from an old removed lavaland ruin.
|
||||
|
||||
@@ -199,6 +205,7 @@
|
||||
flavour_text = "It's your job- no, your duty as a doctor, to care and heal those in need."
|
||||
outfit = /datum/outfit/job/doctor
|
||||
spawner_job_path = /datum/job/space_doctor
|
||||
allow_custom_character = ALL
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/doctor/alive/equip(mob/living/carbon/human/doctor)
|
||||
. = ..()
|
||||
@@ -227,7 +234,7 @@
|
||||
icon = 'icons/obj/machines/sleeper.dmi'
|
||||
icon_state = "sleeper"
|
||||
|
||||
/obj/effect/mob_spawn/cow/special(mob/living/spawned_mob, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/cow/special(mob/living/spawned_mob, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
gender = FEMALE
|
||||
|
||||
@@ -244,6 +251,7 @@
|
||||
flavour_text = "Monitor Nanotrasen communications and record information. All intruders should be disposed of \
|
||||
swiftly to assure no gathered information is stolen or lost. Try not to wander too far from the outpost as the \
|
||||
caves can be a deadly place even for a trained operative such as yourself."
|
||||
allow_custom_character = ALL
|
||||
|
||||
/datum/outfit/snowsyndie
|
||||
name = "Syndicate Snow Operative"
|
||||
@@ -269,8 +277,9 @@
|
||||
important_text = "Obey orders given by your captain. DO NOT let the ship fall into enemy hands."
|
||||
outfit = /datum/outfit/syndicatespace/syndicrew
|
||||
spawner_job_path = /datum/job/syndicate_cybersun
|
||||
allow_custom_character = ALL
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/syndicatespace/special(mob/living/new_spawn, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/human/syndicatespace/special(mob/living/new_spawn, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
new_spawn.grant_language(/datum/language/codespeak, source = LANGUAGE_SPAWNER) // SKYRAT EDIT CHANGE - ORIGINAL: new_spawn.grant_language(/datum/language/codespeak, source = LANGUAGE_MIND)
|
||||
var/datum/job/spawn_job = SSjob.get_job_type(spawner_job_path)
|
||||
@@ -286,6 +295,7 @@
|
||||
important_text = "Protect the ship and secret documents in your backpack with your own life."
|
||||
outfit = /datum/outfit/syndicatespace/syndicaptain
|
||||
spawner_job_path = /datum/job/syndicate_cybersun_captain
|
||||
allow_custom_character = ALL
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/human/syndicatespace/captain/Destroy()
|
||||
new /obj/structure/fluff/empty_sleeper/syndicate/captain(get_turf(src))
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
if(flower_bud.trait_flags & SPACEVINE_COLD_RESISTANT)
|
||||
spawned_human_trap.unsuitable_cold_damage = 0
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/venus_human_trap/special(mob/living/spawned_mob, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/venus_human_trap/special(mob/living/spawned_mob, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_mob.mind.add_antag_datum(/datum/antagonist/venus_human_trap)
|
||||
|
||||
@@ -54,3 +54,4 @@
|
||||
if(!silent)
|
||||
to_chat(user, span_warning("\The [src] has not borne fruit yet!"))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -44,16 +44,36 @@
|
||||
QDEL_NULL(outfit)
|
||||
return ..()
|
||||
|
||||
/// Creates whatever mob the spawner makes. Return FALSE if we want to exit from here without doing that, returning NULL will be logged to admins.
|
||||
/obj/effect/mob_spawn/proc/create(mob/mob_possessor, newname)
|
||||
/**
|
||||
* Creates whatever mob the spawner makes.
|
||||
*
|
||||
* * mob_possessor - The ghost/mob that is possessing this mob, if applicable
|
||||
* * newname - A forced name for the mob, if applicable
|
||||
* * apply_prefs - Whether we should apply the possessor's preferences to the mob, if applicable
|
||||
*
|
||||
* Returns
|
||||
* - the created mob
|
||||
* - CANCEL_SPAWN if the spawn process should be stopped
|
||||
* - null if the spawn failed (and something went wrong)
|
||||
*/
|
||||
/obj/effect/mob_spawn/proc/create(mob/mob_possessor, newname, apply_prefs)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
var/mob/living/spawned_mob = new mob_type(get_turf(src)) //living mobs only
|
||||
special(spawned_mob, mob_possessor, apply_prefs)
|
||||
name_mob(spawned_mob, newname)
|
||||
special(spawned_mob, mob_possessor)
|
||||
equip(spawned_mob)
|
||||
spawned_mob_ref = WEAKREF(spawned_mob)
|
||||
return spawned_mob
|
||||
|
||||
/obj/effect/mob_spawn/proc/special(mob/living/spawned_mob, mob/mob_possessor)
|
||||
/**
|
||||
* Any special behavior that needs to be done to the mob after it's created but before it's equipped.
|
||||
*
|
||||
* * spawned_mob - The mob that was created
|
||||
* * mob_possessor - The ghost/mob that is possessing this mob, if applicable
|
||||
* * apply_prefs - Whether we should apply the possessor's preferences to the mob, if applicable
|
||||
*/
|
||||
/obj/effect/mob_spawn/proc/special(mob/living/spawned_mob, mob/mob_possessor, apply_prefs)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(faction)
|
||||
spawned_mob.faction = faction
|
||||
@@ -112,9 +132,8 @@
|
||||
var/uses = 1
|
||||
/// Does the spawner delete itself when it runs out of uses?
|
||||
var/deletes_on_zero_uses_left = TRUE
|
||||
/// A list of the ckeys that currently are trying to access this spawner, so that they can't try to spawn more than once (in case there's sleeps).
|
||||
/// Static because you only really want to be able to spawn in one spawner at a time, obviously.
|
||||
var/static/list/ckeys_trying_to_spawn
|
||||
///bitflag that determines if players can spawn in as their statics
|
||||
var/allow_custom_character = NONE
|
||||
|
||||
////descriptions
|
||||
|
||||
@@ -152,16 +171,25 @@
|
||||
|
||||
//ATTACK GHOST IGNORING PARENT RETURN VALUE
|
||||
/obj/effect/mob_spawn/ghost_role/attack_ghost(mob/dead/observer/user)
|
||||
if(!SSticker.HasRoundStarted() || !loc)
|
||||
if(!SSticker.HasRoundStarted() || isnull(loc) || QDELETED(src))
|
||||
return
|
||||
|
||||
// We don't open the prompt more than once at a time.
|
||||
// Lazylist of the ckeys that currently are trying to access any spawner, so that they can't try to spawn more than once (in case there's sleeps).
|
||||
var/static/list/ckeys_trying_to_spawn
|
||||
if(LAZYFIND(ckeys_trying_to_spawn, user.ckey))
|
||||
return
|
||||
if(uses <= 0 && !infinite_use)
|
||||
to_chat(user, span_warning("This spawner is out of charges!"))
|
||||
return FALSE
|
||||
if(!can_ghost_take(user))
|
||||
return FALSE
|
||||
|
||||
uses -= 1 // Remove a use EARLY to account for sleep / inputs
|
||||
var/user_ckey = user.ckey // Just in case shenanigans happen, we always want to remove it from the list.
|
||||
LAZYADD(ckeys_trying_to_spawn, user_ckey)
|
||||
|
||||
var/prompt_fail = FALSE
|
||||
var/apply_prefs = FALSE
|
||||
// SKYRAT EDIT ADDITION START
|
||||
if(restricted_species && !(user.client?.prefs?.read_preference(/datum/preference/choiced/species) in restricted_species))
|
||||
var/incorrect_species = tgui_alert(user, "Current species preference incompatible, proceed with random appearance?", "Incompatible Species", list("Yes", "No"))
|
||||
@@ -174,43 +202,46 @@
|
||||
var/prompt = "Become [prompt_name]?"
|
||||
if(!temp_body && user.can_reenter_corpse && user.mind)
|
||||
prompt += " (Warning, You can no longer be revived!)"
|
||||
var/ghost_role = tgui_alert(usr, prompt, buttons = list("Yes", "No"), timeout = 10 SECONDS)
|
||||
if(ghost_role != "Yes" || !loc || QDELETED(user))
|
||||
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
|
||||
return
|
||||
prompt_fail = tgui_alert(user, prompt, buttons = list("Yes", "No"), timeout = 10 SECONDS) != "Yes"
|
||||
|
||||
if(!(GLOB.ghost_role_flags & GHOSTROLE_SPAWNER) && !(flags_1 & ADMIN_SPAWNED_1))
|
||||
to_chat(user, span_warning("An admin has temporarily disabled non-admin ghost roles!"))
|
||||
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
|
||||
return
|
||||
if(uses <= 0 && !infinite_use) //just in case
|
||||
to_chat(user, span_warning("This spawner is out of charges!"))
|
||||
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
|
||||
return
|
||||
var/species_pref = user.client.prefs.read_preference(/datum/preference/choiced/species) || /datum/species/human
|
||||
if(!prompt_fail && user.started_as_observer && allow_custom_character && (GLOB.species_prototypes[species_pref].inherent_respiration_type & RESPIRATION_OXYGEN))
|
||||
var/static_prompt = "Because you haven't taken a role so far, you may spawn in as \
|
||||
[((allow_custom_character & GHOSTROLE_TAKE_PREFS_SPECIES) || species_pref == /datum/species/human) ? "" : "a human version of"] \
|
||||
your customized character with a random name. Would you like to?"
|
||||
apply_prefs = tgui_alert(user, static_prompt, "Custom Character", list("Yes", "No"), 10 SECONDS) == "Yes"
|
||||
|
||||
if(!prompt_fail && !pre_ghost_take(user))
|
||||
prompt_fail = TRUE
|
||||
|
||||
if(prompt_fail || !can_ghost_take(user) || !create_from_ghost(user, apply_prefs, subtract_uses = FALSE))
|
||||
uses += 1
|
||||
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
|
||||
|
||||
/// Allows for modifications before the ghost is turned into a mob.
|
||||
/// You can put sleeps or inputs in here, sanity checking is done for you after this proc returns.
|
||||
/// Returning FALSE will cancel the spawn process.
|
||||
/obj/effect/mob_spawn/ghost_role/proc/pre_ghost_take(mob/dead/observer/user)
|
||||
return TRUE
|
||||
|
||||
/// Checks if a ghost can take this ghost role.
|
||||
/obj/effect/mob_spawn/ghost_role/proc/can_ghost_take(mob/dead/observer/user)
|
||||
if(is_banned_from(user.ckey, role_ban))
|
||||
to_chat(user, span_warning("You are banned from this role!"))
|
||||
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
|
||||
return
|
||||
return FALL_STOP_INTERCEPTING
|
||||
if(!(GLOB.ghost_role_flags & GHOSTROLE_SPAWNER) && !(flags_1 & ADMIN_SPAWNED_1))
|
||||
to_chat(user, span_warning("An admin has temporarily disabled non-admin ghost roles!"))
|
||||
return FALSE
|
||||
// SKYRAT EDIT ADDITION START
|
||||
if(is_banned_from(user.ckey, BAN_GHOST_ROLE_SPAWNER)) // Ghost role bans
|
||||
to_chat(user, span_warning("Error, you are banned from playing ghost roles!"))
|
||||
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
|
||||
return
|
||||
return FALSE
|
||||
// SKYRAT EDIT ADDITION END
|
||||
if(!allow_spawn(user, silent = FALSE))
|
||||
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
|
||||
return
|
||||
if(QDELETED(src) || QDELETED(user))
|
||||
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
|
||||
return
|
||||
|
||||
if(uses <= 0 && !infinite_use) // Just in case something took longer than it should've and we got here after the uses went below zero.
|
||||
to_chat(user, span_warning("This spawner is out of charges!"))
|
||||
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey)
|
||||
return
|
||||
|
||||
create_from_ghost(user)
|
||||
return FALSE
|
||||
if(!allow_spawn(user, silent = FALSE))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Uses a use and creates a mob from a passed ghost
|
||||
@@ -219,49 +250,57 @@
|
||||
*
|
||||
* If you are manually forcing a player into this mob spawn,
|
||||
* you should be using this and not directly calling [proc/create].
|
||||
*
|
||||
* * * user - The ghost/mob that is possessing this mob
|
||||
* * * apply_prefs - Whether we should apply the possessor's preferences to the mob
|
||||
* * * subtract_uses - Whether to subtract a use from the spawner.
|
||||
* Set to FALSE if you want to handle uses manually elsewhere.
|
||||
*/
|
||||
/obj/effect/mob_spawn/ghost_role/proc/create_from_ghost(mob/dead/user)
|
||||
/obj/effect/mob_spawn/ghost_role/proc/create_from_ghost(mob/dead/observer/user, apply_prefs, subtract_uses = TRUE)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
ASSERT(istype(user))
|
||||
var/user_ckey = user.ckey // We need to do it before everything else, because after the create() the ckey will already have been transferred.
|
||||
|
||||
user.log_message("became a [prompt_name].", LOG_GAME)
|
||||
uses -= 1 // Remove a use before trying to spawn to prevent strangeness like the spawner trying to spawn more mobs than it should be able to
|
||||
if(!temp_body)
|
||||
user.mind = null // dissassociate mind, don't let it follow us to the next life
|
||||
|
||||
var/created = create(user)
|
||||
LAZYREMOVE(ckeys_trying_to_spawn, user_ckey) // We do this AFTER the create() so that we're basically sure that the user won't be in their ghost body anymore, so they can't click on the spawner again.
|
||||
|
||||
if(!created)
|
||||
uses += 1 // Refund use because we didn't actually spawn anything
|
||||
|
||||
if(isnull(created)) // If we explicitly return FALSE instead of just not returning a mob, we don't want to spam the admins
|
||||
CRASH("An instance of [type] didn't return anything when creating a mob, this might be broken!")
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_GHOSTROLE_SPAWNED, created)
|
||||
check_uses() // Now we check if the spawner should delete itself or not
|
||||
var/mob/created = create(user, apply_prefs = apply_prefs)
|
||||
if(ismob(created))
|
||||
SEND_SIGNAL(src, COMSIG_GHOSTROLE_SPAWNED, created)
|
||||
if(subtract_uses)
|
||||
uses -= 1
|
||||
check_uses()
|
||||
else if(isnull(created)) // null instead of explicit CANCEL_SPAWN means something went wrong
|
||||
CRASH("An instance of [type] didn't return anything when creating a mob, this might be broken!")
|
||||
|
||||
return created
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/create(mob/mob_possessor, newname)
|
||||
/obj/effect/mob_spawn/ghost_role/create(mob/mob_possessor, newname, apply_prefs)
|
||||
if(!mob_possessor.key) // This is in the scenario that the server is somehow lagging, or someone fucked up their code, and we try to spawn the same person in twice. We'll simply not spawn anything and CRASH(), so that we report what happened.
|
||||
CRASH("Attempted to create an instance of [type] with a mob that had no ckey attached to it, which isn't supported by ghost role spawners!")
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/ghost_role/special(mob/living/spawned_mob, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/ghost_role/special(mob/living/spawned_mob, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
if(mob_possessor)
|
||||
if(mob_possessor.client && apply_prefs && allow_custom_character && ishuman(spawned_mob))
|
||||
var/mob/living/carbon/human/spawned_human = spawned_mob
|
||||
if(allow_custom_character & GHOSTROLE_TAKE_PREFS_APPEARANCE)
|
||||
mob_possessor.client.prefs.apply_prefs_to(spawned_human, icon_updates = TRUE, do_not_apply = typesof(/datum/preference/name, /datum/preference/choiced/species))
|
||||
if(allow_custom_character & GHOSTROLE_TAKE_PREFS_SPECIES)
|
||||
spawned_human.set_species(mob_possessor.client.prefs.read_preference(/datum/preference/choiced/species))
|
||||
spawned_human.fully_replace_character_name(spawned_human.real_name, spawned_human.generate_random_mob_name())
|
||||
if(mob_possessor.mind)
|
||||
mob_possessor.mind.transfer_to(spawned_mob, force_key_move = TRUE)
|
||||
else
|
||||
spawned_mob.PossessByPlayer(mob_possessor.key)
|
||||
|
||||
var/datum/mind/spawned_mind = spawned_mob.mind
|
||||
if(spawned_mind)
|
||||
spawned_mob.mind.set_assigned_role_with_greeting(SSjob.get_job_type(spawner_job_path))
|
||||
spawned_mind.name = spawned_mob.real_name
|
||||
|
||||
if(show_flavor)
|
||||
var/output_message = span_infoplain("<span class='big bold'>[you_are_text]</span>")
|
||||
if(flavour_text != "")
|
||||
@@ -310,16 +349,16 @@
|
||||
if(mapload || (SSticker && SSticker.current_state > GAME_STATE_SETTING_UP))
|
||||
INVOKE_ASYNC(src, PROC_REF(create))
|
||||
|
||||
/obj/effect/mob_spawn/corpse/special(mob/living/spawned_mob, mob/mob_possessor)
|
||||
/obj/effect/mob_spawn/corpse/special(mob/living/spawned_mob, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
spawned_mob.death(TRUE)
|
||||
spawned_mob.adjustOxyLoss(oxy_damage)
|
||||
spawned_mob.adjustBruteLoss(brute_damage)
|
||||
spawned_mob.adjustFireLoss(burn_damage)
|
||||
spawned_mob.adjust_oxy_loss(oxy_damage)
|
||||
spawned_mob.adjust_brute_loss(brute_damage)
|
||||
spawned_mob.adjust_fire_loss(burn_damage)
|
||||
if (corpse_description)
|
||||
spawned_mob.AddComponent(/datum/component/temporary_description, corpse_description, naive_corpse_description)
|
||||
|
||||
/obj/effect/mob_spawn/corpse/create(mob/mob_possessor, newname)
|
||||
/obj/effect/mob_spawn/corpse/create(mob/mob_possessor, newname, apply_prefs)
|
||||
. = ..()
|
||||
qdel(src)
|
||||
|
||||
@@ -339,7 +378,7 @@
|
||||
///husks the corpse if true.
|
||||
var/husk = FALSE
|
||||
|
||||
/obj/effect/mob_spawn/corpse/human/special(mob/living/carbon/human/spawned_human)
|
||||
/obj/effect/mob_spawn/corpse/human/special(mob/living/carbon/human/spawned_human, mob/mob_possessor, apply_prefs)
|
||||
. = ..()
|
||||
if(husk)
|
||||
spawned_human.Drain()
|
||||
|
||||
Reference in New Issue
Block a user