Makes special role preferences a list, instead of flag entry.

Allows us to define more than 16 special roles.
Updates some role usages to use the new ghost trap system.
This commit is contained in:
PsiOmegaDelta
2016-01-15 11:12:50 +01:00
parent 228454c7d0
commit b74f2baf6d
15 changed files with 176 additions and 210 deletions
-19
View File
@@ -26,25 +26,6 @@
#define BE_PAI 0x4000
#define BE_LOYALIST 0x8000
var/list/be_special_flags = list(
"Traitor" = BE_TRAITOR,
"Operative" = BE_OPERATIVE,
"Changeling" = BE_CHANGELING,
"Wizard" = BE_WIZARD,
"Malf AI" = BE_MALF,
"Revolutionary" = BE_REV,
"Loyalist" = BE_LOYALIST,
"Xenomorph" = BE_ALIEN,
"Positronic Brain" = BE_AI,
"Cultist" = BE_CULTIST,
"Monkey" = BE_MONKEY,
"Ninja" = BE_NINJA,
"Raider" = BE_RAIDER,
"Diona" = BE_PLANT,
"Mutineer" = BE_MUTINEER,
"pAI" = BE_PAI
)
#define IS_MODE_COMPILED(MODE) (ispath(text2path("/datum/game_mode/"+(MODE))))
+1 -2
View File
@@ -330,12 +330,11 @@ proc/isInSight(var/atom/A, var/atom/B)
// Same as above but for alien candidates.
/proc/get_alien_candidates()
var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn
var/i = 0
while(candidates.len <= 0 && i < 5)
for(var/mob/dead/observer/G in player_list)
if(G.client.prefs.be_special & BE_ALIEN)
if(BE_ALIEN in G.client.prefs.be_special_role)
if(((G.client.inactivity/10)/60) <= ALIEN_SELECT_AFK_BUFFER + i) // the most active players are more likely to become an alien
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
candidates += G.key
+2 -2
View File
@@ -435,7 +435,7 @@ var/global/list/additional_antag_types = list()
continue
if(istype(player, /mob/new_player))
continue
if(!role || (player.client.prefs.be_special & role))
if(!role || (role in player.client.prefs.be_special_role))
log_debug("[player.key] had [antag_id] enabled, so we are drafting them.")
candidates |= player.mind
else
@@ -446,7 +446,7 @@ var/global/list/additional_antag_types = list()
// Get a list of all the people who want to be the antagonist for this round
for(var/mob/new_player/player in players)
if(!role || (player.client.prefs.be_special & role))
if(!role || (role in player.client.prefs.be_special_role))
log_debug("[player.key] had [antag_id] enabled, so we are drafting them.")
candidates += player.mind
players -= player
+1 -1
View File
@@ -91,7 +91,7 @@ var/global/datum/controller/occupations/job_master
if(job.minimum_character_age && (player.client.prefs.age < job.minimum_character_age))
Debug("FOC character not old enough, Player: [player]")
continue
if(flag && (!player.client.prefs.be_special & flag))
if(flag && !(flag in player.client.prefs.be_special_role))
Debug("FOC flag failed, Player: [player], Flag: [flag], ")
continue
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
+1 -1
View File
@@ -30,7 +30,7 @@
progress++
if(progress >= MAX_PROGRESS)
for(var/mob/M in dead_mob_list)
if(istype(M,/mob/dead) && M.client && M.client.prefs && (M.client.prefs.be_special & BE_ALIEN))
if(istype(M,/mob/dead) && M.client && M.client.prefs && (BE_ALIEN in M.client.prefs.be_special_role))
M << "<span class='notice'>An alien is ready to hatch! ([ghost_follow_link(src, M)]) (<a href='byond://?src=\ref[src];spawn=1'>spawn</a>)</span>"
processing_objects -= src
update_icon()
@@ -1,54 +1,72 @@
var/global/list/special_roles = list( //keep synced with the defines BE_* in setup.dm --rastaf
//some autodetection here.
// TODO: Update to new antagonist system.
"traitor" = IS_MODE_COMPILED("traitor"), // 0
"operative" = IS_MODE_COMPILED("nuclear"), // 1
"changeling" = IS_MODE_COMPILED("changeling"), // 2
"wizard" = IS_MODE_COMPILED("wizard"), // 3
"malf AI" = IS_MODE_COMPILED("malfunction"), // 4
"revolutionary" = IS_MODE_COMPILED("revolution"), // 5
"alien candidate" = 1, //always show // 6
"positronic brain" = 1, // 7
"cultist" = IS_MODE_COMPILED("cult"), // 8
"infested monkey" = IS_MODE_COMPILED("monkey"), // 9
"ninja" = "true", // 10
"raider" = IS_MODE_COMPILED("heist"), // 11
"diona" = 1, // 12
"loyalist" = IS_MODE_COMPILED("revolution"), // 13
"pAI candidate" = 1, // -- TLE // 14
)
/datum/category_item/player_setup_item/antagonism/candidacy
name = "Candidacy"
sort_order = 2
var/list/private_valid_special_roles
/datum/category_item/player_setup_item/antagonism/candidacy/load_character(var/savefile/S)
S["be_special"] >> pref.be_special
S["be_special"] >> pref.be_special_role
/datum/category_item/player_setup_item/antagonism/candidacy/save_character(var/savefile/S)
S["be_special"] << pref.be_special
S["be_special"] << pref.be_special_role
/datum/category_item/player_setup_item/antagonism/candidacy/sanitize_character()
pref.be_special = sanitize_integer(pref.be_special, 0, 65535, initial(pref.be_special))
if(!istype(pref.be_special_role))
pref.be_special_role = list()
for(var/role in pref.be_special_role)
if(!(role in valid_special_roles()))
pref.be_special_role -= role
/datum/category_item/player_setup_item/antagonism/candidacy/content(var/mob/user)
if(jobban_isbanned(user, "Syndicate"))
. += "<b>You are banned from antagonist roles.</b>"
pref.be_special = 0
else
var/n = 0
for (var/i in special_roles)
if(special_roles[i]) //if mode is available on the server
if(jobban_isbanned(user, i) || (i == "positronic brain" && jobban_isbanned(user, "AI") && jobban_isbanned(user, "Cyborg")) || (i == "pAI candidate" && jobban_isbanned(user, "pAI")))
. += "<b>Be [i]:</b> <font color=red><b> \[BANNED]</b></font><br>"
else
. += "<b>Be [i]:</b> <a href='?src=\ref[src];be_special=[n]'><b>[pref.be_special&(1<<n) ? "Yes" : "No"]</b></a><br>"
n++
. += "<b>Special Role Availability:</b><br>"
for(var/datum/antagonist/antag in all_antag_types)
. += "[antag.role_text]: "
if(jobban_isbanned(preference_mob(), antag.bantype))
. += "<span class='danger'>\[BANNED\]</span><br>"
else if(antag.role_type in pref.be_special_role)
. += "<b>Yes</b> / <a href='?src=\ref[src];del_special=[antag.role_type]'>No</a></br>"
else
. += "<a href='?src=\ref[src];add_special=[antag.role_type]'>Yes</a> / <b>No</b></br>"
var/list/ghost_traps = get_ghost_traps()
for(var/ghost_trap_key in ghost_traps)
var/datum/ghosttrap/ghost_trap = ghost_traps[ghost_trap_key]
if(!ghost_trap.list_as_special_role)
continue
. += "[(ghost_trap.ghost_trap_role)]: "
for(var/ban_type in ghost_trap.ban_checks)
if(jobban_isbanned(preference_mob(), ban_type))
. += "<span class='danger'>\[BANNED\]</span><br>"
continue
if(ghost_trap.pref_check in pref.be_special_role)
. += "<b>Yes</b> / <a href='?src=\ref[src];del_special=[ghost_trap.pref_check]'>No</a></br>"
else
. += "<a href='?src=\ref[src];add_special=[ghost_trap.pref_check]'>Yes</a> / <b>No</b></br>"
/datum/category_item/player_setup_item/antagonism/candidacy/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["be_special"])
var/num = text2num(href_list["be_special"])
pref.be_special ^= (1<<num)
if(href_list["add_special"])
if(!(href_list["add_special"] in valid_special_roles()))
return TOPIC_HANDLED
pref.be_special_role |= href_list["add_special"]
return TOPIC_REFRESH
if(href_list["del_special"])
pref.be_special_role -= href_list["del_special"]
return TOPIC_REFRESH
return ..()
/datum/category_item/player_setup_item/antagonism/candidacy/proc/valid_special_roles()
if(!private_valid_special_roles)
private_valid_special_roles = list()
for(var/datum/antagonist/antag in all_antag_types)
private_valid_special_roles += antag.role_type
for(var/ghost_trap_key in ghost_traps)
var/datum/ghosttrap/ghost_trap = ghost_traps[ghost_trap_key]
if(!ghost_trap.list_as_special_role)
continue
private_valid_special_roles += ghost_trap.pref_check
return private_valid_special_roles
+1 -1
View File
@@ -17,7 +17,7 @@ datum/preferences
//game-preferences
var/lastchangelog = "" //Saved changlog filesize to detect if there was a change
var/ooccolor = "#010000" //Whatever this is set to acts as 'reset' color and is thus unusable as an actual custom color
var/be_special = 0 //Special role selection
var/list/be_special_role = list() //Special role selection
var/UI_style = "Midnight"
var/toggles = TOGGLES_DEFAULT
var/UI_style_color = "#ffffff"
@@ -145,15 +145,3 @@
src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1)
src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2)
feedback_add_details("admin_verb","TAmbi") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//be special
/client/verb/toggle_be_special(role in be_special_flags)
set name = "Toggle SpecialRole Candidacy"
set category = "Preferences"
set desc = "Toggles which special roles you would like to be a candidate for, during events."
var/role_flag = be_special_flags[role]
if(!role_flag) return
prefs.be_special ^= role_flag
prefs.save_preferences()
src << "You will [(prefs.be_special & role_flag) ? "now" : "no longer"] be considered for [role] events (where possible)."
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+73 -13
View File
@@ -3,12 +3,17 @@
var/list/ghost_traps
proc/get_ghost_trap(var/trap_key)
/proc/get_ghost_trap(var/trap_key)
if(!ghost_traps)
populate_ghost_traps()
return ghost_traps[trap_key]
proc/populate_ghost_traps()
/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
@@ -21,11 +26,11 @@ proc/populate_ghost_traps()
var/pref_check = BE_AI
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
// Check for bans, proper atom types, etc.
/datum/ghosttrap/proc/assess_candidate(var/mob/dead/observer/candidate)
if(!istype(candidate) || !candidate.client || !candidate.ckey)
return 0
/datum/ghosttrap/proc/assess_candidate(var/mob/dead/observer/candidate, var/mob/target)
if(!candidate.MayRespawn(1, minutes_since_death))
return 0
if(islist(ban_checks))
@@ -36,9 +41,7 @@ proc/populate_ghost_traps()
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)
if(!target)
return
/datum/ghosttrap/proc/request_player(var/mob/target, var/request_string, var/valid_time)
for(var/mob/dead/observer/O in player_list)
if(!O.MayRespawn())
continue
@@ -46,10 +49,10 @@ proc/populate_ghost_traps()
for(var/bantype in ban_checks)
if(jobban_isbanned(O, "[bantype]"))
continue
if(pref_check && !(O.client.prefs.be_special & pref_check))
if(pref_check && !(pref_check in O.client.prefs.be_special_role))
continue
if(O.client)
O << "[request_string]<a href='?src=\ref[src];candidate=\ref[O];target=\ref[target]'>Click here</a> if you wish to play as this option."
O << "[request_string] <a href='?src=\ref[src];candidate=\ref[O];target=\ref[target]';valid_until=[world.time + valid_time]>(Occupy)</a> ([ghost_follow_link(target, O)])"
// Handles a response to request_player().
/datum/ghosttrap/Topic(href, href_list)
@@ -58,9 +61,18 @@ proc/populate_ghost_traps()
if(href_list["candidate"] && href_list["target"])
var/mob/dead/observer/candidate = locate(href_list["candidate"]) // BYOND magic.
var/mob/target = locate(href_list["target"]) // So much BYOND magic.
var/valid_until = text2num(href_list["valid_until"])
if(!target || !candidate)
return
if(candidate == usr && assess_candidate(candidate) && !target.ckey)
if(candidate != usr)
return
if(valid_until && world.time > valid_until)
candidate << "This occupation request is no longer valid."
return
if(target.key)
candidate << "The target is already occupied."
return
if(assess_candidate(candidate, target))
transfer_personality(candidate,target)
return 1
@@ -93,12 +105,17 @@ proc/populate_ghost_traps()
// 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
// Doona pods and walking mushrooms.
/***********************************
* Diona pods and walking mushrooms *
***********************************/
/datum/ghosttrap/plant
object = "living plant"
ban_checks = list("Dionaea")
@@ -111,4 +128,47 @@ proc/populate_ghost_traps()
// This is a hack, replace with some kind of species blurb proc.
if(istype(target,/mob/living/carbon/alien/diona))
target << "<B>You are \a [target], one of a race of drifting interstellar plantlike creatures that sometimes share their seeds with human traders.</B>"
target << "<B>Too much darkness will send you into shock and starve you, but light will help you heal.</B>"
target << "<B>Too much darkness will send you into shock and starve you, but light will help you heal.</B>"
/*****************
* Cortical Borer *
*****************/
/datum/ghosttrap/borer
object = "cortical borer"
ban_checks = list("Borer")
pref_check = BE_ALIEN
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)
target << "<span class='notice'>You are a cortical borer!</span> 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."
target << "You can speak to your victim with <b>say</b>, to other borers with <b>say [target.get_language_prefix()]x</b>, 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()
minutes_since_death = DRONE_SPAWN_DELAY
..()
datum/ghosttrap/drone/assess_candidate(var/mob/dead/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)
+1 -1
View File
@@ -4,7 +4,7 @@
if(!host || !istype(host)) return
var/datum/ghosttrap/plant/P = get_ghost_trap("living plant")
P.request_player(host, "Someone is harvesting [display_name]. ")
P.request_player(host, "Someone is harvesting [display_name].")
spawn(75)
if(!host.ckey && !host.client)
@@ -16,63 +16,14 @@
/obj/item/device/mmi/digital/posibrain/attack_self(mob/user as mob)
if(brainmob && !brainmob.key && searching == 0)
//Start the process of searching for a new user.
user << "\blue You carefully locate the manual activation switch and start the positronic brain's boot process."
user << "<span class='notice'>You carefully locate the manual activation switch and start the positronic brain's boot process.</span>"
icon_state = "posibrain-searching"
src.searching = 1
src.request_player()
var/datum/ghosttrap/G = get_ghost_trap("positronic brain")
G.request_player(brainmob, "Someone is requesting a personality for a positronic brain.", 60 SECONDS)
spawn(600) reset_search()
/obj/item/device/mmi/digital/posibrain/proc/request_player()
for(var/mob/dead/observer/O in player_list)
if(!O.MayRespawn())
continue
if(jobban_isbanned(O, "AI") && jobban_isbanned(O, "Cyborg"))
continue
if(O.client)
if(O.client.prefs.be_special & BE_AI)
question(O.client)
/obj/item/device/mmi/digital/posibrain/proc/question(var/client/C)
spawn(0)
if(!C) return
var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round")
if(response == "Yes")
response = alert(C, "Are you sure you want to play as a positronic brain?", "Positronic brain request", "Yes", "No")
if(!C || brainmob.key || 0 == searching) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
if(response == "Yes")
transfer_personality(C.mob)
else if (response == "Never for this round")
C.prefs.be_special ^= BE_AI
/obj/item/device/mmi/digital/posibrain/transfer_identity(var/mob/living/carbon/H)
..()
if(brainmob.mind)
brainmob.mind.assigned_role = "Positronic Brain"
brainmob << "<span class='notify'>You feel slightly disoriented. That's normal when you're just a metal cube.</span>"
icon_state = "posibrain-occupied"
return
/obj/item/device/mmi/digital/posibrain/proc/transfer_personality(var/mob/candidate)
announce_ghost_joinleave(candidate, 0, "They are occupying a positronic brain now.")
src.searching = 0
src.brainmob.mind = candidate.mind
src.brainmob.ckey = candidate.ckey
src.brainmob.mind.reset()
src.name = "positronic brain ([src.brainmob.name])"
src.brainmob << "<b>You are a positronic brain, brought into existence on [station_name()].</b>"
src.brainmob << "<b>As a synthetic intelligence, you answer to all crewmembers, as well as the AI.</b>"
src.brainmob << "<b>Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.</b>"
src.brainmob << "<b>Use say [candidate.get_language_prefix()]b to speak to other artificial intelligences.</b>"
src.brainmob.mind.assigned_role = "Positronic Brain"
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\blue The positronic brain chimes quietly.")
icon_state = "posibrain-occupied"
/obj/item/device/mmi/digital/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
if(src.brainmob && src.brainmob.key) return
src.searching = 0
@@ -80,7 +31,19 @@
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\blue The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
M.show_message("<span class='notice'>The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?</span>")
/obj/item/device/mmi/digital/posibrain/attack_ghost(var/mob/dead/observer/user)
if(!searching || (src.brainmob && src.brainmob.key))
return
var/datum/ghosttrap/G = get_ghost_trap("positronic brain")
if(!G.assess_candidate(user))
return
var/response = alert(user, "Are you sure you wish to possess this [src]?", "Possess [src]", "Yes", "No")
if(response == "Yes")
G.transfer_personality(user, brainmob)
return
/obj/item/device/mmi/digital/posibrain/examine(mob/user)
if(!..(user))
+5 -2
View File
@@ -814,8 +814,11 @@ default behaviour is:
if(deaf >= 0)
ear_deaf = deaf
/mob/living/proc/can_be_possessed_by(var/mob/dead/observer/possessor)
if(!istype(possessor))
/mob/proc/can_be_possessed_by(var/mob/dead/observer/possessor)
return istype(possessor) && possessor.client && possessor.ckey
/mob/living/can_be_possessed_by(var/mob/dead/observer/possessor)
if(!..())
return 0
if(!possession_candidate)
possessor << "<span class='warning'>That animal cannot be possessed.</span>"
@@ -357,7 +357,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
else
asked.Remove(O.key)
if(O.client)
if(O.client.prefs.be_special & BE_PAI)
if(BE_PAI in O.client.prefs.be_special_role)
question(O.client)
/datum/paiController/proc/question(var/client/C)
@@ -370,4 +370,4 @@ var/datum/paiController/paiController // Global handler for pAI candidates
if(response == "Yes")
recruitWindow(C.mob)
else if (response == "Never for this round")
C.prefs.be_special ^= BE_PAI
C.prefs.be_special_role -= BE_PAI
@@ -60,7 +60,7 @@ var/list/mob_hat_cache = list()
holder_type = /obj/item/weapon/holder/drone
/mob/living/silicon/robot/drone/can_be_possessed_by(var/mob/dead/observer/possessor)
if(!istype(possessor))
if(!istype(possessor) || !possessor.client || !possessor.ckey)
return 0
if(!config.allow_drone_spawn)
src << "<span class='danger'>Playing as drones is not currently permitted.</span>"
@@ -161,7 +161,7 @@ var/list/mob_hat_cache = list()
if(hat)
return
hat = new_hat
new_hat.loc = src
new_hat.forceMove(src)
updateicon()
//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..().
@@ -196,12 +196,7 @@ var/list/mob_hat_cache = list()
return
user.visible_message("<span class='danger'>\The [user] swipes \his ID card through \the [src], attempting to reboot it.</span>", "<span class='danger'>>You swipe your ID card through \the [src], attempting to reboot it.</span>")
var/drones = 0
for(var/mob/living/silicon/robot/drone/D in world)
if(D.key && D.client)
drones++
if(drones < config.max_maint_drones)
request_player()
request_player()
return
else
@@ -304,28 +299,13 @@ var/list/mob_hat_cache = list()
//Reboot procs.
/mob/living/silicon/robot/drone/proc/request_player()
for(var/mob/dead/observer/O in player_list)
if(jobban_isbanned(O, "Cyborg"))
continue
if(O.client)
if(O.client.prefs.be_special & BE_PAI)
question(O.client)
/mob/living/silicon/robot/drone/proc/question(var/client/C)
spawn(0)
if(!C || jobban_isbanned(C,"Cyborg")) return
var/response = alert(C, "Someone is attempting to reboot a maintenance drone. Would you like to play as one?", "Maintenance drone reboot", "Yes", "No", "Never for this round")
if(!C || ckey)
return
if(response == "Yes")
transfer_personality(C)
else if (response == "Never for this round")
C.prefs.be_special ^= BE_PAI
if(active_drones() >= config.max_maint_drones)
return
var/datum/ghosttrap/G = get_ghost_trap("maintenance drone")
G.request_player(src, "Someone is attempting to reboot a maintenance drone.", 30 SECONDS)
/mob/living/silicon/robot/drone/proc/transfer_personality(var/client/player)
if(!player) return
src.ckey = player.ckey
if(player.mob && player.mob.mind)
@@ -361,3 +341,10 @@ var/list/mob_hat_cache = list()
/mob/living/silicon/robot/drone/construction/updatename()
real_name = "construction drone ([rand(100,999)])"
name = real_name
/proc/active_drones()
var/drones = 0
for(var/mob/living/silicon/robot/drone/D in mob_list)
if(D.key && D.client)
drones++
return drones
@@ -173,41 +173,8 @@
//Procs for grabbing players.
/mob/living/simple_animal/borer/proc/request_player()
for(var/mob/dead/observer/O in player_list)
if(jobban_isbanned(O, "Borer"))
continue
if(O.client)
if(O.client.prefs.be_special & BE_ALIEN)
question(O.client)
/mob/living/simple_animal/borer/proc/question(var/client/C)
spawn(0)
if(!C) return
var/response = alert(C, "A cortical borer needs a player. Are you interested?", "Cortical borer request", "Yes", "No", "Never for this round")
if(!C || ckey)
return
if(response == "Yes")
transfer_personality(C)
else if (response == "Never for this round")
C.prefs.be_special ^= BE_ALIEN
/mob/living/simple_animal/borer/proc/transfer_personality(var/client/candidate)
if(!candidate || !candidate.mob || !candidate.mob.mind)
return
src.mind = candidate.mob.mind
candidate.mob.mind.current = src
src.ckey = candidate.ckey
if(src.mind)
src.mind.assigned_role = "Cortical Borer"
src.mind.special_role = "Cortical Borer"
src << "<span class='notice'>You are a cortical borer!</span> 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."
src << "You can speak to your victim with <b>say</b>, to other borers with <b>say :x</b>, and use your Abilities tab to access powers."
var/datum/ghosttrap/G = get_ghost_trap("cortical borer")
G.request_player(src, "A cortical borer needs a player.")
/mob/living/simple_animal/borer/cannot_use_vents()
return
return