// This system is used to grab a ghost from observers with the required preferences and // lack of bans set. See posibrain.dm for an example of how they are called/used. ~Z var/list/ghost_traps /proc/get_ghost_trap(var/trap_key) if(!ghost_traps) populate_ghost_traps() return ghost_traps[trap_key] /proc/get_ghost_traps() if(!ghost_traps) populate_ghost_traps() return ghost_traps /proc/populate_ghost_traps() ghost_traps = list() for(var/traptype in typesof(/datum/ghosttrap)) var/datum/ghosttrap/G = new traptype ghost_traps[G.object] = G /datum/ghosttrap var/object = "positronic brain" var/respawn_check = 0//Which respawning test we check against var/list/ban_checks = list("AI","Cyborg") var/pref_check = BE_SYNTH var/ghost_trap_message = "They are occupying a positronic brain now." var/ghost_trap_role = "Positronic Brain" var/can_set_own_name = TRUE var/list_as_special_role = TRUE // If true, this entry will be listed as a special role in the character setup var/list/request_timeouts /datum/ghosttrap/New() request_timeouts = list() ..() // Check for bans, proper atom types, etc. /datum/ghosttrap/proc/assess_candidate(var/mob/abstract/observer/candidate, var/mob/target) if(!candidate.MayRespawn(1, respawn_check)) return 0 if(islist(ban_checks)) for(var/bantype in ban_checks) if(jobban_isbanned(candidate, "[bantype]")) to_chat(candidate, "You are banned from one or more required roles and hence cannot enter play as \a [object].") return 0 return 1 // Print a message to all ghosts with the right prefs/lack of bans. /datum/ghosttrap/proc/request_player(var/mob/target, var/request_string, var/request_timeout) if(request_timeout) request_timeouts[target] = world.time + request_timeout destroyed_event.register(target, src, /datum/ghosttrap/proc/target_destroyed) else request_timeouts -= target for(var/mob/abstract/observer/O in player_list) if(!O.MayRespawn()) continue if(islist(ban_checks)) for(var/bantype in ban_checks) if(jobban_isbanned(O, "[bantype]")) continue if(pref_check && !(pref_check in O.client.prefs.be_special_role)) continue if(O.client) to_chat(O, "[ghost_follow_link(target, O)] [request_string] (Occupy)") /datum/ghosttrap/proc/target_destroyed(var/destroyed_target) request_timeouts -= destroyed_target // Handles a response to request_player(). /datum/ghosttrap/Topic(href, href_list) if(..()) return 1 if(href_list["candidate"] && href_list["target"]) var/mob/abstract/observer/candidate = locate(href_list["candidate"]) // BYOND magic. var/mob/target = locate(href_list["target"]) // So much BYOND magic. if(!target || !candidate) return if(candidate != usr) return if(request_timeouts[target] && world.time > request_timeouts[target]) to_chat(candidate, "This occupation request is no longer valid.") return if(target.key) to_chat(candidate, "The target is already occupied.") return if(assess_candidate(candidate, target)) transfer_personality(candidate,target) return 1 // Shunts the ckey/mind into the target mob. /datum/ghosttrap/proc/transfer_personality(var/mob/candidate, var/mob/target) if(!assess_candidate(candidate)) return 0 target.ckey = candidate.ckey if(target.mind) target.mind.assigned_role = "[ghost_trap_role]" announce_ghost_joinleave(candidate, 0, "[ghost_trap_message]") welcome_candidate(target) set_new_name(target) return 1 // Fluff! /datum/ghosttrap/proc/welcome_candidate(var/mob/target) to_chat(target, "You are a positronic brain, brought into existence on [station_name()].") to_chat(target, "As a synthetic intelligence, you answer to all crewmembers, as well as the AI.") to_chat(target, "Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.") to_chat(target, "Use say [target.get_language_prefix()]b to speak to other artificial intelligences.") var/turf/T = get_turf(target) T.visible_message("\The [target] chimes quietly.") var/obj/item/device/mmi/digital/posibrain/P = target.loc if(!istype(P)) //wat return P.searching = 0 P.name = "positronic brain ([P.brainmob.name])" P.icon_state = "posibrain-occupied" // Allows people to set their own name. May or may not need to be removed for posibrains if people are dumbasses. /datum/ghosttrap/proc/set_new_name(var/mob/target) if(!can_set_own_name) return var/newname = sanitizeSafe(input(target,"Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN) if (newname != "") target.real_name = newname target.name = target.real_name /*********************************** * Diona pods and walking mushrooms * ***********************************/ /datum/ghosttrap/plant object = "living plant" ban_checks = list("Dionaea") pref_check = BE_PLANT ghost_trap_message = "They are occupying a living plant now." ghost_trap_role = "Plant" /datum/ghosttrap/plant/welcome_candidate(var/mob/target) to_chat(target, "You awaken slowly, stirring into sluggish motion as the air caresses you.") // This is a hack, replace with some kind of species blurb proc. if(istype(target,/mob/living/carbon/alien/diona)) to_chat(target, "You are \a [target], one of a race of drifting interstellar plantlike creatures that sometimes share their seeds with human traders.") to_chat(target, "Too much darkness will send you into shock and starve you, but light will help you heal.") /***************** * Cortical Borer * *****************/ /datum/ghosttrap/borer object = "cortical borer" ban_checks = list("Borer") pref_check = MODE_BORER ghost_trap_message = "They are occupying a borer now." ghost_trap_role = "Cortical Borer" can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/borer/welcome_candidate(var/mob/target) to_chat(target, "You are a cortical borer! You are a brain slug that worms its way into the head of its victim. Use stealth, persuasion and your powers of mind control to keep you, your host and your eventual spawn safe and warm.") to_chat(target, "You can speak to your victim with say, to other borers with say [target.get_language_prefix()]x, and use your Abilities tab to access powers.") /******************** * Maintenance Drone * *********************/ /datum/ghosttrap/drone object = "maintenance drone" pref_check = BE_PAI ghost_trap_message = "They are occupying a maintenance drone now." ghost_trap_role = "Maintenance Drone" can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/drone/New() respawn_check = MINISYNTH ..() datum/ghosttrap/drone/assess_candidate(var/mob/abstract/observer/candidate, var/mob/target) . = ..() if(. && !target.can_be_possessed_by(candidate)) return 0 datum/ghosttrap/drone/transfer_personality(var/mob/candidate, var/mob/living/silicon/robot/drone/drone) if(!assess_candidate(candidate)) return 0 drone.transfer_personality(candidate.client) /******************** * Mining Drone * *********************/ /datum/ghosttrap/mdrone object = "mining drone" pref_check = BE_PAI ghost_trap_message = "They are occupying a mining drone now." ghost_trap_role = "Mining Drone" can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/mdrone/New() respawn_check = MINISYNTH ..() /datum/ghosttrap/mdrone/assess_candidate(var/mob/abstract/observer/candidate, var/mob/target) . = ..() if(. && !target.can_be_possessed_by(candidate)) return 0 datum/ghosttrap/drone/transfer_personality(var/mob/candidate, var/mob/living/silicon/robot/drone/drone) if(!assess_candidate(candidate)) return 0 drone.transfer_personality(candidate.client) var/tmp_health = drone.health drone.revive() drone.health = tmp_health drone.updatehealth() /*********************************** * Syndicate Cyborg * ***********************************/ /datum/ghosttrap/syndicateborg object = "syndicate cyborg" ban_checks = list("Antagonist","AI","Cyborg") pref_check = BE_SYNTH ghost_trap_message = "They are occupying a syndicate cyborg now." ghost_trap_role = "Syndicate Cyborg" can_set_own_name = TRUE list_as_special_role = FALSE /datum/ghosttrap/syndicateborg/welcome_candidate(var/mob/target) to_chat(target, "You are a syndicate cyborg, bound to help and follow the orders of the mercenaries that are deploying you. Remember to speak to the other mercenaries to know more about their plans") mercs.add_antagonist_mind(target.mind,1) /************** * pAI * **************/ /datum/ghosttrap/pai object = "pAI" pref_check = BE_PAI ghost_trap_message = "They are occupying a pAI now." ghost_trap_role = "pAI" datum/ghosttrap/pai/assess_candidate(var/mob/candidate, var/mob/target) return 0 datum/ghosttrap/pai/transfer_personality(var/mob/candidate, var/mob/living/silicon/robot/drone/drone) return 0 /************** * Wizard Familiar * **************/ /datum/ghosttrap/familiar object = "wizard familiar" pref_check = MODE_WIZARD ghost_trap_message = "They are occupying a familiar now." ghost_trap_role = "Wizard Familiar" ban_checks = list(MODE_WIZARD) list_as_special_role = FALSE /datum/ghosttrap/familiar/welcome_candidate(var/mob/target) return 0 /************** * Skeleton minion * **************/ /datum/ghosttrap/skeleton object = "skeleton minion" pref_check = MODE_WIZARD ghost_trap_message = "They are occupying a skeleton minion." ghost_trap_role = "Skeleton Minion" ban_checks = list(MODE_WIZARD) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/skeleton/welcome_candidate(var/mob/target) return 0 //Gamemodes /datum/ghosttrap/merc object = "Mercenary" pref_check = MODE_MERCENARY ghost_trap_message = "They are occupying a mercenary." ghost_trap_role = "Mercenary" ban_checks = list(MODE_MERCENARY) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/merc/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/raider object = "Raider" pref_check = MODE_RAIDER ghost_trap_message = "They are occupying a raider." ghost_trap_role = "Raider" ban_checks = list(MODE_RAIDER) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/raider/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/ninja object = "Ninja" pref_check = MODE_NINJA ghost_trap_message = "They are occupying a ninja." ghost_trap_role = "Ninja" ban_checks = list(MODE_NINJA) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/ninja/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/wizard object = "Wizard" pref_check = MODE_WIZARD ghost_trap_message = "They are occupying a wizard." ghost_trap_role = "Wizard" ban_checks = list(MODE_WIZARD) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/wizard/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/malf object = "AI Malfunction" pref_check = MODE_MALFUNCTION ghost_trap_message = "They are occupying a malfunctioning AI." ghost_trap_role = "Malfuntioning AI" ban_checks = list(MODE_MALFUNCTION) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/malf/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/ert object = "Emergency Responder" pref_check = MODE_ERT ghost_trap_message = "They are occupying an ERT member." ghost_trap_role = "ERT member" ban_checks = list(MODE_ERT) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/ert/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/changeling object = "Changeling" pref_check = MODE_CHANGELING ghost_trap_message = "They are occupying a changeling." ghost_trap_role = "Changeling" ban_checks = list(MODE_CHANGELING) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/changeling/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/cultist object = "Cult" pref_check = MODE_CULTIST ghost_trap_message = "They are occupying a cultist." ghost_trap_role = "Cultist" ban_checks = list(MODE_CULTIST) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/cultist/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/traitor object = "Traitor" pref_check = MODE_TRAITOR ghost_trap_message = "They are occupying a traitor." ghost_trap_role = "Traitor" ban_checks = list(MODE_TRAITOR) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/traitor/welcome_candidate(var/mob/target) to_chat(target, " Check your notes for your PDA code!") return 1 /datum/ghosttrap/vampire object = "Vampire" pref_check = MODE_VAMPIRE ghost_trap_message = "They are occupying a vampire." ghost_trap_role = "Vampire" ban_checks = list(MODE_VAMPIRE) can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/vampire/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/special object = "Special" pref_check = null ghost_trap_message = "They are occupying a person." ghost_trap_role = "person" ban_checks = list() can_set_own_name = FALSE list_as_special_role = FALSE /datum/ghosttrap/special/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/brainwashed object = "split personality" ghost_trap_message = "They are a split personality now." ghost_trap_role = "Split personality" can_set_own_name = TRUE list_as_special_role = TRUE /datum/ghosttrap/brainwashed/welcome_candidate(var/mob/target) return 0 /datum/ghosttrap/friend object = "friend" ghost_trap_message = "They are an imaginary friend now." ghost_trap_role = "Imaginary friend" can_set_own_name = TRUE list_as_special_role = TRUE /datum/ghosttrap/friend/welcome_candidate(var/mob/target) return 0