Ghost Roles (#6706)

This commit is contained in:
Werner
2019-08-10 23:57:49 +02:00
committed by GitHub
parent 15fcefb923
commit a8e4e7f88c
36 changed files with 1865 additions and 683 deletions
+146
View File
@@ -0,0 +1,146 @@
/datum/ghostspawner
var/short_name = null
var/name = null
var/desc = null
var/welcome_message = null
var/list/tags = list() //Tags associated with that spawner
//Vars regarding the spawnpoints and conditions of the spawner
var/list/spawnpoints = null //List of the applicable spawnpoints (by name)
var/landmark_name = null //Alternatively you can specify a landmark name
var/max_count = 0 //How often can this spawner be used
var/count = 0 //How ofen has this spawner been used
var/req_perms = null //What permission flags are required to use this spawner
var/req_perms_edit = R_ADMIN
var/req_head_whitelist = FALSE //If a head of staff whitelist is required
var/req_species_whitelist = null //Name/Datum of the species whitelist that is required, or null
var/enabled = TRUE //If the spawnpoint is enabled
var/enable_chance = null //If set to a value other than null, has the set chance to become enabled
var/enable_dmessage = TRUE //The message to send to deadchat if the ghostspawner is enabled or TRUE for a default message
var/respawn_flag = null //Flag to check for when trying to spawn someone of that type (CREW, ANIMAL, MINISYNTH)
var/jobban_job = null //If this is set, then it will check if the user is jobbanned from a specific job. Otherwise it will check for the name of the spawner
//Vars regarding the mob to use
var/mob/spawn_mob = null //The mob that should be spawned
var/list/variables = list() //Variables of that mob
var/mob_name = FALSE //The name of that mob; If null prompts for it
var/mob_name_prefix = null //The prefix that should be applied to the mob (i.e. CCIAA, Tpr., Cmdr.)
var/mob_name_suffix = null //The suffix that should be applied to the mob name
/datum/ghostspawner/New()
. = ..()
if(!jobban_job)
jobban_job = name
if(!isnull(enable_chance))
enabled = prob(enable_chance)
//Return a error message if the user CANT see the ghost spawner. Otherwise FALSE
/datum/ghostspawner/proc/cant_see(mob/user) //If the user can see the spawner in the menu
if(req_perms) //Only those with the correct flags can see restricted roles
if(check_rights(req_perms, show_msg=FALSE, user=user))
return FALSE //Return early and dont perform whitelist checks if staff flags are met
else
return "Missing Permissions"
if(req_head_whitelist && !check_whitelist(user))
return "Missing Head of Staff Whitelist"
if(req_species_whitelist && !is_alien_whitelisted(user, req_species_whitelist))
return "Missing Species Whitelist"
if(jobban_job && jobban_isbanned(user,jobban_job))
return "Job Banned"
if(!enabled && !can_edit(user)) //If its not enabled and the user cant edit it, dont show it
return "Currently Disabled"
return FALSE
//Return a error message if the user CANT spawn. Otherwise FALSE
/datum/ghostspawner/proc/cant_spawn(mob/user) //If the user can spawn using the spawner
if(!ROUND_IS_STARTED)
return "The round is not started yet."
var/cant_see = cant_see()
if(cant_see) //If we cant see it, we cant spawn it
return cant_see
if(!istype(user, /mob/abstract/observer))
return "You are not a ghost."
if(!enabled) //If the spawner id disabled, we cant spawn in
return "This spawner is not enabled."
if(respawn_flag && !user.MayRespawn(0,respawn_flag))
return "You can not respawn at this time."
if(!config.enter_allowed)
return "There is an administrative lock on entering the game."
if(SSticker.mode?.explosion_in_progress)
return "The station is currently exploding."
if(max_count && count > max_count)
return "No more slots are available."
//Check if a spawnpoint is available
var/T = select_spawnpoint(FALSE)
if(!T)
return "No spawnpoint available."
return FALSE
//Proc executed before someone is spawned in
/datum/ghostspawner/proc/pre_spawn(mob/user)
count++ //Increment the spawned in mob count
if(count >= max_count)
disable()
return TRUE
//This proc selects the spawnpoint to use.
/datum/ghostspawner/proc/select_spawnpoint(var/use=TRUE)
if(!isnull(spawnpoints))
for(var/spawnpoint in spawnpoints) //Loop through the applicable spawnpoints
var/turf/T = SSghostroles.get_spawnpoint(spawnpoint, use) //Gets the first matching spawnpoint or null if none are available
if(T) //If we have a spawnpoint, return it
return T
if(!isnull(landmark_name))
var/obj/effect/landmark/L
for(var/obj/effect/landmark/landmark in landmarks_list)
if(landmark.name == landmark_name)
L = landmark
return get_turf(L)
log_debug("Ghostspawner: Spawner [short_name] has neither spawnpoints nor landmarks or a matching spawnpoint/landmark could not be found")
return null //If we dont have anything return null
//The proc to actually spawn in the user
/datum/ghostspawner/proc/spawn_mob(mob/user)
//OVERWRITE THIS IN THE CHILD IMPLEMENTATIONS to return the spawned in mob !!!
return null
//Proc executed after someone is spawned in
/datum/ghostspawner/proc/post_spawn(mob/user)
if(welcome_message)
to_chat(user, welcome_message)
return TRUE
//Proc to check if a specific user can edit this spawner (open/close/...)
/datum/ghostspawner/proc/can_edit(mob/user)
if(check_rights(req_perms_edit, show_msg=FALSE, user=user))
return TRUE
return FALSE
/datum/ghostspawner/proc/is_enabled()
if(max_count)
return enabled && count < max_count
return enabled
//Proc to enable the ghostspawner
/datum/ghostspawner/proc/enable()
enabled = TRUE
if(enable_dmessage)
for(var/mob/abstract/observer/O in player_list)
if(O.client && !cant_see(O))
if(enable_dmessage == TRUE)
to_chat(O, "<span class='deadsay'><b>A ghostspawner for a \"[src.name]\" has been enabled.</b></span>")
else
to_chat(O, "<span class='deadsay'><b>[enable_dmessage]</b></span>")
return TRUE
//Proc to disable the ghostspawner
/datum/ghostspawner/proc/disable()
enabled = FALSE
return TRUE
@@ -0,0 +1,115 @@
/datum/ghostspawner/human/admin
tags = list("Admin")
/datum/ghostspawner/human/admin/ert_commander
short_name = "ertcommander"
name = "ERT Commander"
desc = "Command the response team from Central Command"
landmark_name = "ERTCommander"
req_perms = R_CCIAA
//Vars related to human mobs
outfit = /datum/outfit/admin/nt/ert_commander
possible_species = list("Human")
possible_genders = list(MALE,FEMALE)
allow_appearance_change = TRUE
assigned_role = "Emergency Response Team Commander"
special_role = "ERT Commander"
respawn_flag = null
mob_name = null
mob_name_prefix = "Cmdr. "
/datum/ghostspawner/human/admin/legion_commander
short_name = "legioncommander"
name = "TCFL Commander"
desc = "Command the TCFL, a walking and talking joke, whos members regularly die before they even arrive at their target."
landmark_name = "TCFLCommander"
req_perms = R_CCIAA
//Vars related to human mobs
outfit = /datum/outfit/admin/nt/tcfl_commander
possible_species = list("Human")
possible_genders = list(MALE,FEMALE)
allow_appearance_change = TRUE
assigned_role = "Tau Ceti Foreign Legion Commander"
special_role = "TCFL Commander"
respawn_flag = null
mob_name = null
mob_name_prefix = "Cmdr. "
/datum/ghostspawner/human/admin/cciaagent
short_name = "cciaagent"
name = "CCIA Agent"
desc = "Board the Aurora, annoy crew with your interviews and get squashed by your own shuttle."
landmark_name = "CCIAAgent"
req_perms = R_CCIAA
//Vars related to human mobs
outfit = /datum/outfit/admin/nt/cciaa
possible_species = list("Human")
possible_genders = list(MALE,FEMALE)
allow_appearance_change = TRUE
assigned_role = "Emergency Response Team Commander"
special_role = "ERT Commander"
respawn_flag = null
mob_name = null
mob_name_prefix = "CCIAA "
/datum/ghostspawner/human/admin/cciaescort
short_name = "cciaescort"
name = "CCIA Escort"
desc = "Escort a CCIA Agent to the station, watch them annoy the crew and prevent them from throwing themselvs under their own shuttle."
enabled = FALSE
landmark_name = "CCIAEscort"
req_perms = null
req_perms_edit = R_CCIAA
max_count = 1
//Vars related to human mobs
outfit = /datum/outfit/admin/nt/protection_detail
possible_species = list("Human")
possible_genders = list(MALE,FEMALE)
allow_appearance_change = TRUE
assigned_role = "Civil Protection Officer"
special_role = "Civil Protection Officer"
respawn_flag = null
mob_name = null
mob_name_prefix = "Ofc. "
/datum/ghostspawner/human/admin/checkpointsec
short_name = "checkpointsec"
name = "Odin Checkpoint Security"
desc = "Secure the Odin checkpoint. Verify the identity of everyone passing through, perform random searches on \"suspicious\" crew."
enabled = FALSE
spawnpoints = list("OdinCheckpoint")
req_perms = null
req_perms_edit = R_CCIAA
max_count = 4
//Vars related to human mobs
outfit = /datum/outfit/admin/nt/protection_detail
possible_species = list("Human","Skrell","Tajara","Unathi")
possible_genders = list(MALE,FEMALE)
allow_appearance_change = TRUE
assigned_role = "Odin Security Officer"
special_role = "Odin Security Officer"
respawn_flag = null
mob_name = null
mob_name_prefix = "Spec. "
@@ -0,0 +1,166 @@
/datum/ghostspawner/human/rescuepodsurv
short_name = "rescuepodsurv"
name = "Rescue Pod Survivor"
desc = "You managed to get into a rescue pod and landed somewhere on a asteroid."
tags = list("External")
enabled = FALSE
req_perms = null
max_count = 1
//Vars related to human mobs
outfit = /datum/outfit/admin/random/visitor
possible_species = list("Human","Skrell","Tajara","Unathi")
possible_genders = list(MALE,FEMALE)
allow_appearance_change = TRUE
assigned_role = "Pod Survivor"
special_role = "Pod Survivor"
respawn_flag = CREW
mob_name = FALSE
enable_chance = 10
/datum/ghostspawner/human/rescuepodsurv/New()
. = ..()
var/t = pick(list("star","priest","rep","smuggler"))
if(t == "star")
welcome_message = "You are a stranded starlet!<br>You were relaxing comfortably in your cryo pod as tragedy struck - the pilot of your luxury yacht fell asleep under some mysterious circumstances. You were unceremoniously stuffed into an escape pod, and left to wander in space. What a despicable, low-quality plot to get rid of you. Should've chosen murder instead - you certainly know you'll convince someone nice to lend you a shuttle."
outfit = /datum/outfit/admin/pod/star
possible_genders = list(FEMALE)
possible_species = list("Human","Skrell","Tajara")
else if(t == "priest")
welcome_message = "You are a stranded Trinary Perfection priest!<br>You were traveling around space on your small shuttle, preaching peacefully of the future divinity of the synthetics, and the grand purpose of mankind as the ones to help them achieve that goal. Unfortunately, Dominians don't seem to be as peaceful in disagreeing with your views - and had to evacuate your shot-down ship. Have your prayers to the Divines helped you now?"
outfit = /datum/outfit/admin/pod/priest
possible_species = list("Human")
else if(t == "rep")
welcome_message = "You are a stranded Idris Incorporated representative!<br>You were traveling back from your business in Sol to the Mendell City HQ. Unfortunately, after a very unusual set of circumstances, the engine broke down just almost as you got back. You're stranded somewhere nearby - perhaps your excellent customer service and negotiation skills might get you a ride back to Mendell?"
outfit = /datum/outfit/admin/pod/rep
possible_species = list("Human")
else
welcome_message = "You are a stranded drugs smuggler!<br>You shouldn't have had the fucking Tajara pilot your ship. <i>Of course</i> we crashed into a rock. Good thing you've got some of the stuff with you while evacuating - maybe you'll crash somewhere you could sell it for a ticket back?"
outfit = /datum/outfit/admin/pod/smuggler
possible_species = list("Human","Skrell","Unathi")
/datum/ghostspawner/human/rescuepodsurv/select_spawnpoint(var/use=TRUE)
//Randomly select a Turf on the asteroid.
var/turf/T = pick_area_turf(/area/mine/unexplored)
if(!use) //If we are just checking if we can get one, return the turf we found
return T
if(!T) //If we didnt find a turn, return now
return null
//Otherwise spawn a droppod at that location
var/x = T.x
var/y = T.y
var/z = T.z
new /datum/random_map/droppod(null,x,y,z,supplied_drop="custom",do_not_announce=TRUE,automated=FALSE)
return get_turf(locate(x+1,y+1,z)) //Get the turf again, so we end up inside of the pod - There is probs a better way to do this
//Base equipment for the pod (softsuit + emergency oxygen)
/datum/outfit/admin/pod
head = /obj/item/clothing/head/helmet/space/emergency
mask = /obj/item/clothing/mask/breath
suit = /obj/item/clothing/suit/space/emergency
suit_store = /obj/item/weapon/tank/emergency_oxygen/double
l_ear = /obj/item/device/radio/headset
back = /obj/item/weapon/storage/backpack
/datum/outfit/admin/pod/post_equip(mob/living/carbon/human/H, visualsOnly)
. = ..()
//Turn on the oxygen tank
H.internal = H.s_store
if(istype(H.internal,/obj/item/weapon/tank) && H.internals)
H.internals.icon_state = "internal1"
/datum/outfit/admin/pod/star
name = "RescuePod - Star"
uniform = "dress selection"
shoes = "flats selection"
id = /obj/item/weapon/card/id
backpack_contents = list(
/obj/item/weapon/lipstick/random = 2,
/obj/item/weapon/haircomb/random = 1,
/obj/item/weapon/spacecash/c1000 = 2,
/obj/item/device/oxycandle = 1,
/obj/item/airbubble = 1
)
/datum/outfit/admin/pod/star/get_id_assignment()
return "Visitor"
/datum/outfit/admin/pod/star/get_id_rank()
return "Visitor"
/datum/outfit/admin/pod/priest
name = "RescuePod - Priest"
uniform = /obj/item/clothing/under/rank/chaplain
shoes = /obj/item/clothing/shoes/black
id = /obj/item/weapon/card/id
pda = /obj/item/device/pda/chaplain
backpack_contents = list(
/obj/item/weapon/storage/bible/fluff/oscar_bible = 1,
/obj/item/device/oxycandle = 1,
/obj/item/airbubble = 1
)
/datum/outfit/admin/pod/priest/get_id_assignment()
return "Priest"
/datum/outfit/admin/pod/priest/get_id_rank()
return "Priest"
/datum/outfit/admin/pod/rep
name = "RescuePod - IdrisRep"
uniform = /obj/item/clothing/under/rank/idris
id = /obj/item/weapon/card/id/idris
pda = /obj/item/device/pda/lawyer
shoes = /obj/item/clothing/shoes/laceup
glasses = /obj/item/clothing/glasses/sunglasses/big
l_hand = /obj/item/weapon/storage/briefcase
backpack_contents = list(
/obj/item/clothing/head/beret/liaison = 1,
/obj/item/device/camera = 1,
/obj/item/weapon/gun/energy/pistol = 1,
/obj/item/device/oxycandle = 1,
/obj/item/airbubble = 1
)
/datum/outfit/admin/pod/rep/get_id_assignment()
return "Corporate Liaison (Idris)"
/datum/outfit/admin/pod/rep/get_id_rank()
return "Corporate Liaison"
/datum/outfit/admin/pod/smuggler
name = "RescuePod - Smuggler"
shoes = "shoe selection"
uniform = "pants selection"
backpack_contents = list(
/obj/item/weapon/reagent_containers/inhaler/space_drugs = 3,
/obj/item/weapon/reagent_containers/inhaler/hyperzine = 2,
/obj/item/weapon/reagent_containers/inhaler/soporific = 1,
/obj/item/weapon/gun/projectile/leyon = 1,
/obj/item/device/oxycandle = 1,
/obj/item/airbubble = 1
)
/datum/outfit/admin/pod/smuggler/get_id_assignment()
return "Merchant"
/datum/outfit/admin/pod/smuggler/get_id_rank()
return "Merchant"
@@ -0,0 +1,113 @@
/datum/ghostspawner/human
short_name = null
name = null
desc = null
respawn_flag = CREW //Flag to check for when trying to spawn someone of that type (CREW, ANIMAL, MINISYNTH)
//Vars regarding the mob to use
spawn_mob = /mob/living/carbon/human //The mob that should be spawned
variables = list() //Variables of that mob
//Vars related to human mobs
var/datum/outfit/outfit = null //Outfit to equip
var/possible_species = list("Human")
var/possible_genders = list(MALE,FEMALE)
var/allow_appearance_change = FALSE
var/assigned_role = null
var/special_role = null
var/faction = null
mob_name = null
//Proc executed before someone is spawned in
/datum/ghostspawner/human/pre_spawn(mob/user)
. = ..()
/datum/ghostspawner/human/proc/get_mob_name(mob/user)
var/mname = mob_name
if(isnull(mname))
var/pick_message = "Pick a name."
if(mob_name_prefix)
pick_message = "[pick_message] Automatic Prefix: \"[mob_name_prefix]\" "
if(mob_name_suffix)
pick_message = "[pick_message] Automatic Suffix: \"[mob_name_suffix]\" "
mname = sanitizeSafe(input(user, pick_message, "Name (without prefix/suffix"))
if(mob_name_prefix)
mname = "[mob_name_prefix][mname]"
if(mob_name_suffix)
mname = "[mname][mob_name_suffix]"
return mname
//The proc to actually spawn in the user
/datum/ghostspawner/human/spawn_mob(mob/user)
//Select a spawnpoint (if available)
var/turf/T = select_spawnpoint()
if(!T)
log_debug("GhostSpawner: Unable to select spawnpoint for [short_name]")
return FALSE
//Get the name / age from them first
var/mname = get_mob_name(user)
var/age = input(user, "Enter your characters age:","Num") as num
//Spawn in the mob
var/mob/living/carbon/human/M = new spawn_mob(null)
M.change_gender(pick(possible_genders))
M.set_species(pick(possible_species))
//Prepare the mob
M.check_dna(M)
M.dna.ready_dna(M)
//Move the mob inside and initialize the mind
M.key = user.ckey //!! After that USER is invalid, so we have to use M
M.mind_initialize()
if(assigned_role)
M.mind.assigned_role = assigned_role
if(special_role)
M.mind.special_role = special_role
if(faction)
M.faction = faction
//Move the mob
M.forceMove(T)
M.lastarea = get_area(M.loc) //So gravity doesnt fuck them.
M.megavend = TRUE //So the autodrobe ignores them
//Setup the appearance
if(allow_appearance_change)
M.change_appearance(APPEARANCE_ALL, M.loc, check_species_whitelist = 1)
else //otherwise randomize
M.client.prefs.randomize_appearance_for(M, FALSE)
//Setup the mob age and name
if(!mname)
mname = random_name(M.gender, M.species.name)
M.fully_replace_character_name(M.real_name, mname)
if(!age)
age = rand(35, 50)
M.age = Clamp(age, 21, 65)
//Setup the outfit
if(outfit)
M.preEquipOutfit(outfit, FALSE)
M.equipOutfit(outfit, FALSE)
M.force_update_limbs()
M.update_eyes()
M.regenerate_icons()
return M
//Proc executed after someone is spawned in
/datum/ghostspawner/human/post_spawn(mob/user)
. = ..()
@@ -0,0 +1,32 @@
/datum/ghostspawner/human/merchantass
short_name = "merchantass"
name = "Merchants Assistant"
desc = "Assist the Merchant with their duties."
tags = list("External")
enabled = FALSE
spawnpoints = list("MerchantAss")
req_perms = null
max_count = 1
//Vars related to human mobs
outfit = /datum/outfit/job/merchant/assistant
possible_species = list("Human","Skrell","Tajara","Unathi")
possible_genders = list(MALE,FEMALE)
allow_appearance_change = TRUE
assigned_role = "Merchants Assistant"
special_role = "Merchants Assistant"
respawn_flag = null
mob_name = null
/datum/ghostspawner/human/merchantass/can_edit(mob/user)
. = ..()
var/is_merchant = FALSE
if(ishuman(user))
var/mob/living/carbon/human/H = user
is_merchant = (H.job == "Merchant")
return . || is_merchant
@@ -0,0 +1,27 @@
/datum/ghostspawner/human/visitorerror
short_name = "visitorerror"
name = "Visitor"
desc = "You are a Visitor, but noone told them."
tags = list("External")
enabled = FALSE
landmark_name = "JoinLate"
req_perms = null
max_count = 1
//Vars related to human mobs
outfit = /datum/outfit/admin/random/visitor
possible_species = list("Human","Skrell","Tajara","Unathi")
possible_genders = list(MALE,FEMALE)
allow_appearance_change = TRUE
assigned_role = "Visitor"
special_role = "Visitor"
respawn_flag = CREW
mob_name = null
enable_chance = 10
/datum/ghostspawner/human/visitorerror/select_spawnpoint(var/use=TRUE)
return pick(latejoin)
@@ -0,0 +1,41 @@
/datum/ghostspawner/simplemob/maintdrone
short_name = "maintdrone"
name = "Maintenence Drone"
desc = "Maintain and Improve the Systems on the Aurora"
tags = list("Simple Mobs")
respawn_flag = MINISYNTH //Flag to check for when trying to spawn someone of that type (CREW, ANIMAL, MINISYNTH)
jobban_job = "Cyborg"
//Vars regarding the mob to use
spawn_mob = /mob/living/simple_animal/rat //The mob that should be spawned
/datum/ghostspawner/simplemob/maintdrone/cant_see()
if(!config.allow_drone_spawn)
return "Spawning as drone is disabled"
return ..()
/datum/ghostspawner/simplemob/maintdrone/select_spawnpoint(var/use)
return TRUE //We just fake it here, since the spawnpoint is selected if someone is spawned in.
//The proc to actually spawn in the user
/datum/ghostspawner/simplemob/maintdrone/spawn_mob(mob/user)
var/obj/machinery/drone_fabricator/fabricator
var/list/all_fabricators = list()
for(var/obj/machinery/drone_fabricator/DF in SSmachinery.all_machines)
if((DF.stat & NOPOWER) || !DF.produce_drones || DF.drone_progress < 100)
continue
all_fabricators[DF.fabricator_tag] = DF
if(!all_fabricators.len)
to_chat(user, "<span class='danger'>There are no available drone spawn points, sorry.</span>")
return FALSE
var/choice = input(user, "Which fabricator do you wish to use?") as null|anything in all_fabricators
if(!choice || !all_fabricators[choice])
return FALSE
fabricator = all_fabricators[choice]
if(user && fabricator && !((fabricator.stat & NOPOWER) || !fabricator.produce_drones || fabricator.drone_progress < 100))
return fabricator.create_drone(user.client)
return FALSE
@@ -0,0 +1,41 @@
/datum/ghostspawner/simplemob/rat
short_name = "rat"
name = "Rat"
desc = "Join as a Rat on the aurora, a common nuciance to the crew."
welcome_message = "You are now a rat. Though you may interact with players, do not give any hints away that you are more than a simple rodent. Find food, avoid cats, and try to survive!"
tags = list("Simple Mobs")
respawn_flag = ANIMAL //Flag to check for when trying to spawn someone of that type (CREW, ANIMAL, MINISYNTH)
//Vars regarding the mob to use
spawn_mob = /mob/living/simple_animal/rat //The mob that should be spawned
//This proc selects the spawnpoint to use.
/datum/ghostspawner/simplemob/rat/select_spawnpoint()
//find a viable mouse candidate
var/obj/machinery/atmospherics/unary/vent_pump/spawnpoint = find_mouse_spawnpoint(pick(current_map.station_levels))
return get_turf(spawnpoint)
/datum/ghostspawner/simplemob/rat/cant_see()
if(config.disable_player_rats)
return "Spawning as Rat is disabled"
return ..()
//The proc to actually spawn in the user
/datum/ghostspawner/simplemob/rat/spawn_mob(mob/user)
//Select a spawnpoint (if available)
var/turf/T = select_spawnpoint()
var/mob/living/simple_animal/S
if (T)
S = new spawn_mob(T)
else
to_chat(user, "<span class='warning'>Unable to find any safe, unwelded vents to spawn rats at. The station must be quite a mess! Trying again might work, if you think there's still a safe place. </span>")
if(S)
if(config.uneducated_rats)
S.universal_understand = 0
announce_ghost_joinleave(user, 0, "They are now a [name].")
S.ckey = user.ckey
return S