Merge pull request #254 from Markolie/master

Bug fixes, latejoining additions
This commit is contained in:
Fox-McCloud
2015-02-05 20:26:20 -05:00
29 changed files with 656 additions and 261 deletions
+2
View File
@@ -82,6 +82,8 @@ datum/controller/game_controller/proc/setup()
for(var/i=0, i<max_secret_rooms, i++)
make_mining_asteroid_secret()
populate_spawn_points()
spawn(0)
if(ticker)
+13 -3
View File
@@ -85,12 +85,21 @@
playercount += 1
if (player.client && player.mind && player.mind.special_role && player.stat != 2)
traitorcount += 1
if (player.client && player.mind && !player.mind.special_role && player.stat != 2 && ishuman(player) && (player.client && player.client.prefs.be_special & BE_TRAITOR) && !jobban_isbanned(player, "traitor") && !jobban_isbanned(player, "Syndicate"))
possible_traitors += player
if (player.client && player.mind && !player.mind.special_role && player.stat != 2)
if (ishuman(player) || isrobot(player) || isAI(player))
if (player.client && player.client.prefs.be_special & BE_TRAITOR && !jobban_isbanned(player, "traitor") && !jobban_isbanned(player, "Syndicate"))
possible_traitors += player.mind
for(var/datum/mind/player in possible_traitors)
for(var/job in restricted_jobs)
if(player.assigned_role == job)
possible_traitors -= player
if(player.current) // Remove loyalty implanted mobs from the list
if(ishuman(player.current))
var/mob/living/carbon/human/H = player.current
for(var/obj/item/weapon/implant/loyalty/I in H.contents)
for(var/datum/organ/external/organs in H.organs)
if(I in organs.implants)
possible_traitors -= player
//message_admins("Live Players: [playercount]")
//message_admins("Live Traitors: [traitorcount]")
@@ -118,7 +127,8 @@
message_admins("No potential traitors. Cancelling new traitor.")
traitorcheckloop()
return
var/mob/living/newtraitor = pick(possible_traitors)
var/datum/mind/newtraitormind = pick(possible_traitors)
var/mob/living/newtraitor = newtraitormind.current
//message_admins("[newtraitor.real_name] is the new Traitor.")
forge_traitor_objectives(newtraitor.mind)
+4 -1
View File
@@ -115,4 +115,7 @@
H.l_store.add_fingerprint(H,1)
if(H.r_store)
H.r_store.add_fingerprint(H,1)
return 1
return 1
/datum/job/proc/is_position_available()
return (current_positions < total_positions) || (total_positions == -1)
+5 -3
View File
@@ -2,7 +2,7 @@
title = "AI"
flag = AI
department_flag = ENGSEC
total_positions = 0
total_positions = 0 // Not used for AI, see is_position_available below and modules/mob/living/silicon/ai/latejoin.dm
spawn_positions = 1
selection_color = "#ccffcc"
supervisors = "your laws"
@@ -13,13 +13,15 @@
if(!H) return 0
return 1
/datum/job/ai/is_position_available()
return (empty_playable_ai_cores.len != 0)
/datum/job/cyborg
title = "Cyborg"
flag = CYBORG
department_flag = ENGSEC
total_positions = 0
total_positions = 1
spawn_positions = 1
supervisors = "your laws and the AI" //Nodrak
selection_color = "#ddffdd"
+6 -5
View File
@@ -379,7 +379,7 @@ var/global/datum/controller/occupations/job_master
proc/EquipRank(var/mob/living/carbon/human/H, var/rank, var/joined_late = 0)
if(!H) return 0
if(!H) return null
var/datum/job/job = GetJob(rank)
if(job)
job.equip(H)
@@ -442,9 +442,10 @@ var/global/datum/controller/occupations/job_master
switch(rank)
if("Cyborg")
H.Robotize()
return 1
if("AI","Clown") //don't need bag preference stuff!
return H.Robotize()
if("AI")
return H
if("Clown") //don't need bag preference stuff!
if(rank=="Clown") // Clowns DO need to breathe, though - N3X
H.species.equip(H)
else
@@ -484,7 +485,7 @@ var/global/datum/controller/occupations/job_master
H.hud_updateflag |= (1 << ID_HUD)
H.hud_updateflag |= (1 << IMPLOYAL_HUD)
H.hud_updateflag |= (1 << SPECIALROLE_HUD)
return 1
return H
proc/spawnId(var/mob/living/carbon/human/H, rank, title)
+1
View File
@@ -135,6 +135,7 @@ var/list/civilian_positions = list(
var/list/nonhuman_positions = list(
"AI",
"Cyborg",
"Drone",
"pAI"
)
+2 -2
View File
@@ -565,7 +565,7 @@ obj/machinery/bot/proc/start_patrol()
send_status()
if(awaiting_beacon) // awaiting beacon response
awaiting_beacon++
if(awaiting_beacon > 20) // wait 20 secs for beacon response
if(awaiting_beacon > 40) // wait 40 secs for beacon response
find_nearest_beacon() // then go to nearest instead
return
if(next_destination)
@@ -583,7 +583,7 @@ obj/machinery/bot/proc/start_patrol()
new_destination = "__nearest__"
post_signal(beacon_freq, "findbeacon", "patrol")
awaiting_beacon = 1
spawn(100)
spawn(150)
awaiting_beacon = 0
if(nearest_beacon)
set_destination(nearest_beacon)
+1 -1
View File
@@ -67,7 +67,7 @@
icon_state = "[lasercolor]ed209[on]"
set_weapon() //giving it the right projectile and firing sound.
spawn(3)
var/datum/job/detective/J = new/datum/job/detective
var/datum/job/officer/J = new/datum/job/officer
botcard.access = J.get_access()
prev_access = botcard.access
+1 -1
View File
@@ -86,7 +86,7 @@
icon_state = "[base_icon][on]"
spawn(3)
var/datum/job/detective/J = new/datum/job/detective
var/datum/job/officer/J = new/datum/job/officer
botcard.access = J.get_access()
prev_access = botcard.access
add_to_beacons(bot_filter)
+56 -9
View File
@@ -156,11 +156,15 @@
if(istype(P, /obj/item/weapon/screwdriver))
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
user << "<span class='notice'>You connect the monitor.</span>"
if(!laws.inherent.len) //If laws isn't set to null but nobody supplied a board, the AI would normally be created lawless. We don't want that.
laws = null
var/mob/living/silicon/ai/A = new /mob/living/silicon/ai (loc, laws, brain)
if(A) //if there's no brain, the mob is deleted and a structure/AIcore is created
A.rename_self("ai", 1)
if(!brain)
var/open_for_latejoin = alert(user, "Would you like this core to be open for latejoining AIs?", "Latejoin", "Yes", "Yes", "No") == "Yes"
var/obj/structure/AIcore/deactivated/D = new(loc)
if(open_for_latejoin)
empty_playable_ai_cores += D
else
var/mob/living/silicon/ai/A = new /mob/living/silicon/ai ( loc, laws, brain )
if(A) //if there's no brain, the mob is deleted and a structure/AIcore is created
A.rename_self("ai", 1)
feedback_inc("cyborg_ais_created",1)
del(src)
@@ -171,10 +175,53 @@
anchored = 1
state = 20//So it doesn't interact based on the above. Not really necessary.
attackby(var/obj/item/device/aicard/A as obj, var/mob/user as mob)
if(istype(A, /obj/item/device/aicard))//Is it?
A.transfer_ai("INACTIVE","AICARD",src,user)
return
/obj/structure/AIcore/deactivated/attackby(var/obj/item/W, var/mob/user)
if(istype(W, /obj/item/device/aicard))//Is it?
var/obj/item/device/aicard/card = W
card.transfer_ai("INACTIVE","AICARD",src,user)
else if(istype(W, /obj/item/weapon/wrench))
if(anchored)
user.visible_message("\blue \The [user] starts to unbolt \the [src] from the plating...")
if(!do_after(user,40))
user.visible_message("\blue \The [user] decides not to unbolt \the [src].")
return
user.visible_message("\blue \The [user] finishes unfastening \the [src]!")
anchored = 0
return
else
user.visible_message("\blue \The [user] starts to bolt \the [src] to the plating...")
if(!do_after(user,40))
user.visible_message("\blue \The [user] decides not to bolt \the [src].")
return
user.visible_message("\blue \The [user] finishes fastening down \the [src]!")
anchored = 1
return
else
return ..()
/client/proc/empty_ai_core_toggle_latejoin()
set name = "Toggle AI Core Latejoin"
set category = "Admin"
var/list/cores = list()
for(var/obj/structure/AIcore/deactivated/D in world)
cores["[D] ([D.loc.loc])"] = D
if(!cores.len)
src << "No deactivated AI cores were found."
var/id = input("Which core?", "Toggle AI Core Latejoin", null) as null|anything in cores
if(!id) return
var/obj/structure/AIcore/deactivated/D = cores[id]
if(!D) return
if(D in empty_playable_ai_cores)
empty_playable_ai_cores -= D
src << "\The [id] is now <font color=\"#ff0000\">not available</font> for latejoining AIs."
else
empty_playable_ai_cores += D
src << "\The [id] is now <font color=\"#008000\">available</font> for latejoining AIs."
/*
+282 -145
View File
@@ -6,9 +6,6 @@
* ~ Zuhayr
*/
//Used for logging people entering cryosleep and important items they are carrying.
var/global/list/frozen_crew = list()
var/global/list/frozen_items = list()
//Main cryopod console.
@@ -18,15 +15,33 @@ var/global/list/frozen_items = list()
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "cellconsole"
circuit = "/obj/item/weapon/circuitboard/cryopodcontrol"
density = 0
interact_offline = 1
var/mode = null
/obj/machinery/computer/cryopod/attack_paw()
src.attack_hand()
//Used for logging people entering cryosleep and important items they are carrying.
var/list/frozen_crew = list()
var/list/frozen_items = list()
var/storage_type = "crewmembers"
var/storage_name = "Cryogenic Oversight Control"
var/allow_items = 1
/obj/machinery/computer/cryopod/robot
name = "robotic storage console"
desc = "An interface between crew and the robotic storage systems"
icon = 'icons/obj/robot_storage.dmi'
icon_state = "console"
circuit = "/obj/item/weapon/circuitboard/robotstoragecontrol"
storage_type = "cyborgs"
storage_name = "Robotic Storage Control"
allow_items = 0
/obj/machinery/computer/cryopod/attack_ai()
src.attack_hand()
obj/machinery/computer/cryopod/attack_hand(mob/user = usr)
/obj/machinery/computer/cryopod/attack_hand(mob/user = usr)
if(stat & (NOPOWER|BROKEN))
return
@@ -38,17 +53,18 @@ obj/machinery/computer/cryopod/attack_hand(mob/user = usr)
if (!( ticker ))
return
dat += "<hr/><br/><b>Cryogenic Oversight Control</b><br/>"
dat += "<hr/><br/><b>[storage_name]</b><br/>"
dat += "<i>Welcome, [user.real_name].</i><br/><br/><hr/>"
dat += "<a href='?src=\ref[src];log=1'>View storage log</a>.<br>"
dat += "<a href='?src=\ref[src];item=1'>Recover object</a>.<br>"
dat += "<a href='?src=\ref[src];allitems=1'>Recover all objects</a>.<br>"
dat += "<a href='?src=\ref[src];crew=1'>Revive crew</a>.<br/><hr/>"
if(allow_items)
dat += "<a href='?src=\ref[src];view=1'>View objects</a>.<br>"
dat += "<a href='?src=\ref[src];item=1'>Recover object</a>.<br>"
dat += "<a href='?src=\ref[src];allitems=1'>Recover all objects</a>.<br>"
user << browse(dat, "window=cryopod_console")
onclose(user, "cryopod_console")
obj/machinery/computer/cryopod/Topic(href, href_list)
/obj/machinery/computer/cryopod/Topic(href, href_list)
if(..())
return
@@ -59,45 +75,56 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
if(href_list["log"])
var/dat = "<b>Recently stored crewmembers</b><br/><hr/><br/>"
var/dat = "<b>Recently stored [storage_type]</b><br/><hr/><br/>"
for(var/person in frozen_crew)
dat += "[person]<br/>"
dat += "<hr/>"
user << browse(dat, "window=cryolog")
if(href_list["view"])
if(!allow_items) return
var/dat = "<b>Recently stored objects</b><br/><hr/><br/>"
for(var/obj/item/I in frozen_items)
dat += "[I.name]<br/>"
dat += "<hr/>"
user << browse(dat, "window=cryoitems")
else if(href_list["item"])
if(!allow_items) return
if(frozen_items.len == 0)
user << "\blue There is nothing to recover from storage."
user << "<span class='notice'>There is nothing to recover from storage.</span>"
return
var/obj/item/I = input(usr, "Please choose which object to retrieve.","Object recovery",null) as obj in frozen_items
if(!I || frozen_items.len == 0)
user << "\blue There is nothing to recover from storage."
var/obj/item/I = input(usr, "Please choose which object to retrieve.","Object recovery",null) as null|anything in frozen_items
if(!I)
return
visible_message("\blue The console beeps happily as it disgorges \the [I].", 3)
if(!(I in frozen_items))
user << "<span class='notice'>\The [I] is no longer in storage.</span>"
return
visible_message("<span class='notice'>The console beeps happily as it disgorges \the [I].</span>", 3)
I.loc = get_turf(src)
frozen_items -= I
else if(href_list["allitems"])
if(!allow_items) return
if(frozen_items.len == 0)
user << "\blue There is nothing to recover from storage."
user << "<span class='notice'>There is nothing to recover from storage.</span>"
return
visible_message("\blue The console beeps happily as it disgorges the desired objects.", 3)
visible_message("<span class='notice'>The console beeps happily as it disgorges the desired objects.</span>", 3)
for(var/obj/item/I in frozen_items)
I.loc = get_turf(src)
frozen_items -= I
else if(href_list["crew"])
user << "\red Functionality unavailable at this time."
src.updateUsrDialog()
return
@@ -106,10 +133,15 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
build_path = "/obj/machinery/computer/cryopod"
origin_tech = "programming=3"
/obj/item/weapon/circuitboard/robotstoragecontrol
name = "Circuit board (Robotic Storage Console)"
build_path = "/obj/machinery/computer/cryopod/robot"
origin_tech = "programming=3"
//Decorative structures to go alongside cryopods.
/obj/structure/cryofeed
name = "\improper cryogenic feed"
name = "cryogenic feed"
desc = "A bewildering tangle of machinery and pipes."
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "cryo_rear"
@@ -131,19 +163,30 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
//Cryopods themselves.
/obj/machinery/cryopod
name = "\improper cryogenic freezer"
name = "cryogenic freezer"
desc = "A man-sized pod for entering suspended animation."
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "body_scanner_0"
density = 1
anchored = 1
var/mob/occupant = null // Person waiting to be despawned.
var/orient_right = null // Flips the sprite.
var/time_till_despawn = 9000 // 15 minutes-ish safe period before being despawned.
var/time_entered = 0 // Used to keep track of the safe period.
var/base_icon_state = "body_scanner_0"
var/occupied_icon_state = "body_scanner_1"
var/on_store_message = "has entered long-term storage."
var/on_store_name = "Cryogenic Oversight"
var/on_enter_occupant_message = "You feel cool air surround you. You go numb as your senses turn inward."
var/allow_occupant_types = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
var/disallow_occupant_types = list()
var/mob/occupant = null // Person waiting to be despawned.
var/orient_right = null // Flips the sprite.
var/time_till_despawn = 18000 // 30 minutes-ish safe period before being despawned.
var/time_entered = 0 // Used to keep track of the safe period.
var/obj/item/device/radio/intercom/announce //
var/obj/machinery/computer/cryopod/control_computer
var/last_no_computer_message = 0
// These items are preserved when the process() despawn proc occurs.
var/list/preserve_items = list(
/obj/item/weapon/hand_tele,
@@ -156,133 +199,212 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
/obj/item/clothing/suit,
/obj/item/clothing/shoes/magboots,
/obj/item/blueprints,
/obj/item/clothing/head/helmet/space/
/obj/item/clothing/head/helmet/space,
/obj/item/weapon/tank
)
/obj/machinery/cryopod/right
orient_right = 1
icon_state = "body_scanner_0-r"
/obj/machinery/cryopod/New()
/obj/machinery/cryopod/robot
name = "robotic storage unit"
desc = "A storage unit for robots."
icon = 'icons/obj/robot_storage.dmi'
icon_state = "pod_0"
base_icon_state = "pod_0"
occupied_icon_state = "pod_1"
on_store_message = "has entered robotic storage."
on_store_name = "Robotic Storage Oversight"
on_enter_occupant_message = "The storage unit broadcasts a sleep signal to you. Your systems start to shut down, and you enter low-power mode."
allow_occupant_types = list(/mob/living/silicon/robot)
disallow_occupant_types = list(/mob/living/silicon/robot/drone)
/obj/machinery/cryopod/robot/right
orient_right = 1
icon_state = "pod_0-r"
/obj/machinery/cryopod/New()
announce = new /obj/item/device/radio/intercom(src)
if(orient_right)
icon_state = "body_scanner_0-r"
icon_state = "[base_icon_state]-r"
else
icon_state = "body_scanner_0"
icon_state = base_icon_state
..()
/obj/machinery/cryopod/initialize()
..()
find_control_computer()
/obj/machinery/cryopod/proc/find_control_computer(urgent=0)
control_computer = locate(/obj/machinery/computer/cryopod) in src.loc.loc
// Don't send messages unless we *need* the computer, and less than five minutes have passed since last time we messaged
if(!control_computer && urgent && last_no_computer_message + 5*60*10 < world.time)
log_admin("Cryopod in [src.loc.loc] could not find control computer!")
message_admins("Cryopod in [src.loc.loc] could not find control computer!")
last_no_computer_message = world.time
return control_computer != null
/obj/machinery/cryopod/proc/check_occupant_allowed(mob/M)
var/correct_type = 0
for(var/type in allow_occupant_types)
if(istype(M, type))
correct_type = 1
break
if(!correct_type) return 0
for(var/type in disallow_occupant_types)
if(istype(M, type))
return 0
return 1
//Lifted from Unity stasis.dm and refactored. ~Zuhayr
/obj/machinery/cryopod/process()
if(occupant)
//Allow a ten minute gap between entering the pod and actually despawning.
if(world.time - time_entered < time_till_despawn)
return
if(!occupant.client && occupant.stat<2) //Occupant is living and has no client.
if(!control_computer)
if(!find_control_computer(urgent=1))
return
//Drop all items into the pod.
for(var/obj/item/W in occupant)
occupant.drop_from_inventory(W)
W.loc = src
despawn_occupant()
if(W.contents.len) //Make sure we catch anything not handled by del() on the items.
for(var/obj/item/O in W.contents)
O.loc = src
// This function can not be undone; do not call this unless you are sure
// Also make sure there is a valid control computer
/obj/machinery/cryopod/robot/despawn_occupant()
var/mob/living/silicon/robot/R = occupant
if(!istype(R)) return ..()
R.contents -= R.mmi
del(R.mmi)
for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc
for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags
O.loc = R
del(I)
del(R.module)
//Delete all items not on the preservation list.
var/list/items = src.contents
items -= occupant // Don't delete the occupant
items -= announce // or the autosay radio.
return ..()
for(var/obj/item/W in items)
var/preserve = null
for(var/T in preserve_items)
if(istype(W,T))
preserve = 1
break
// This function can not be undone; do not call this unless you are sure
// Also make sure there is a valid control computer
/obj/machinery/cryopod/proc/despawn_occupant()
//Drop all items into the pod.
for(var/obj/item/W in occupant)
occupant.drop_from_inventory(W)
W.loc = src
if(!preserve)
del(W)
else
frozen_items += W
if(W.contents.len) //Make sure we catch anything not handled by del() on the items.
for(var/obj/item/O in W.contents)
if(istype(O,/obj/item/weapon/tank)) //Stop eating pockets, you fuck!
continue
O.loc = src
//Update any existing objectives involving this mob.
for(var/datum/objective/O in all_objectives)
if(istype(O,/datum/objective/mutiny) && O.target == occupant.mind) //We don't want revs to get objectives that aren't for heads of staff. Letting them win or lose based on cryo is silly so we remove the objective.
del(O) //TODO: Update rev objectives on login by head (may happen already?) ~ Z
else if(O.target && istype(O.target,/datum/mind))
if(O.target == occupant.mind)
if(O.owner && O.owner.current)
O.owner.current << "\red You get the feeling your target is no longer within your reach. Time for Plan [pick(list("A","B","C","D","X","Y","Z"))]..."
O.target = null
spawn(1) //This should ideally fire after the occupant is deleted.
if(!O) return
O.find_target()
if(!(O.target))
all_objectives -= O
O.owner.objectives -= O
del(O)
//Delete all items not on the preservation list.
var/list/items = src.contents
items -= occupant // Don't delete the occupant
items -= announce // or the autosay radio.
//Handle job slot/tater cleanup.
var/job = occupant.mind.assigned_role
for(var/obj/item/W in items)
job_master.FreeRole(job)
var/preserve = null
for(var/T in preserve_items)
if(istype(W,T))
preserve = 1
break
if(occupant.mind.objectives.len)
del(occupant.mind.objectives)
occupant.mind.special_role = null
if(!preserve)
del(W)
else
if(control_computer && control_computer.allow_items)
control_computer.frozen_items += W
W.loc = null
else
if(ticker.mode.name == "AutoTraitor")
var/datum/game_mode/traitor/autotraitor/current_mode = ticker.mode
current_mode.possible_traitors.Remove(occupant)
W.loc = src.loc
// Delete them from datacore.
//Update any existing objectives involving this mob.
for(var/datum/objective/O in all_objectives)
// We don't want revs to get objectives that aren't for heads of staff. Letting
// them win or lose based on cryo is silly so we remove the objective.
if(istype(O,/datum/objective/mutiny) && O.target == occupant.mind)
del(O)
else if(O.target && istype(O.target,/datum/mind))
if(O.target == occupant.mind)
if(O.owner && O.owner.current)
O.owner.current << "<span class='warning'>You get the feeling your target is no longer within your reach. Time for Plan [pick(list("A","B","C","D","X","Y","Z"))]...</span>"
O.target = null
spawn(1) //This should ideally fire after the occupant is deleted.
if(!O) return
O.find_target()
if(!(O.target))
all_objectives -= O
O.owner.objectives -= O
del(O)
if(PDA_Manifest.len)
PDA_Manifest.Cut()
for(var/datum/data/record/R in data_core.medical)
if ((R.fields["name"] == occupant.real_name))
del(R)
for(var/datum/data/record/T in data_core.security)
if ((T.fields["name"] == occupant.real_name))
del(T)
for(var/datum/data/record/G in data_core.general)
if ((G.fields["name"] == occupant.real_name))
del(G)
//Handle job slot/tater cleanup.
var/job = occupant.mind.assigned_role
if(orient_right)
icon_state = "body_scanner_0-r"
else
icon_state = "body_scanner_0"
job_master.FreeRole(job)
//TODO: Check objectives/mode, update new targets if this mob is the target, spawn new antags?
if(occupant.mind.objectives.len)
del(occupant.mind.objectives)
occupant.mind.special_role = null
else
if(ticker.mode.name == "AutoTraitor")
var/datum/game_mode/traitor/autotraitor/current_mode = ticker.mode
current_mode.possible_traitors.Remove(occupant)
//This should guarantee that ghosts don't spawn.
occupant.ckey = null
// Delete them from datacore.
//Make an announcement and log the person entering storage.
frozen_crew += "[occupant.real_name]"
if(PDA_Manifest.len)
PDA_Manifest.Cut()
for(var/datum/data/record/R in data_core.medical)
if ((R.fields["name"] == occupant.real_name))
del(R)
for(var/datum/data/record/T in data_core.security)
if ((T.fields["name"] == occupant.real_name))
del(T)
for(var/datum/data/record/G in data_core.general)
if ((G.fields["name"] == occupant.real_name))
del(G)
var/ailist[] = list()
for (var/mob/living/silicon/ai/A in living_mob_list)
ailist += A
if (ailist.len)
var/mob/living/silicon/ai/announcer = pick(ailist)
announcer.say(";[occupant.real_name] has entered long-term storage.")
else
announce.autosay("[occupant.real_name] has entered long-term storage.", "Cryogenic Oversight")
if(orient_right)
icon_state = "[base_icon_state]-r"
else
icon_state = base_icon_state
//TODO: Check objectives/mode, update new targets if this mob is the target, spawn new antags?
//This should guarantee that ghosts don't spawn.
occupant.ckey = null
//Make an announcement and log the person entering storage.
control_computer.frozen_crew += "[occupant.real_name]"
var/ailist[] = list()
for (var/mob/living/silicon/ai/A in living_mob_list)
ailist += A
if (ailist.len)
var/mob/living/silicon/ai/announcer = pick(ailist)
announcer.say(";[occupant.real_name] [on_store_message]")
else
announce.autosay("[occupant.real_name] [on_store_message]", "[on_store_name]")
visible_message("\blue The crypod hums and hisses as it moves [occupant.real_name] into storage.", 3)
visible_message("<span class='notice'>\The [src] hums and hisses as it moves [occupant.real_name] into storage.</span>", 3)
// Delete the mob.
del(occupant)
occupant = null
return
// Delete the mob.
del(occupant)
occupant = null
name = initial(name)
/obj/machinery/cryopod/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob)
@@ -290,17 +412,20 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
if(istype(G, /obj/item/weapon/grab))
if(occupant)
user << "\blue The cryo pod is in use."
user << "<span class='notice'>\The [src] is in use.</span>"
return
if(!ismob(G:affecting))
return
if(!check_occupant_allowed(G:affecting))
return
var/willing = null //We don't want to allow people to be forced into despawning.
var/mob/M = G:affecting
if(M.client)
if(alert(M,"Would you like to enter cryosleep?",,"Yes","No") == "Yes")
if(alert(M,"Would you like to enter long-term storage?",,"Yes","No") == "Yes")
if(!M || !G || !G:affecting) return
willing = 1
else
@@ -308,7 +433,7 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
if(willing)
visible_message("[user] starts putting [G:affecting:name] into the cryo pod.", 3)
visible_message("[user] starts putting [G:affecting:name] into \the [src].", 3)
if(do_after(user, 20))
if(!M || !G || !G:affecting) return
@@ -320,21 +445,23 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
M.client.eye = src
if(orient_right)
icon_state = "body_scanner_1-r"
icon_state = "[occupied_icon_state]-r"
else
icon_state = "body_scanner_1"
icon_state = occupied_icon_state
M << "\blue You feel cool air surround you. You go numb as your senses turn inward."
M << "\blue <b>If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.</b>"
M << "<span class='notice'>[on_enter_occupant_message]</span>"
M << "<span class='notice'><b>If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.</b></span>"
occupant = M
time_entered = world.time
// Book keeping!
log_admin("[key_name_admin(M)] has entered a stasis pod.")
message_admins("\blue [key_name_admin(M)] has entered a stasis pod.")
var/turf/location = get_turf(src)
log_admin("[key_name_admin(M)] has entered a stasis pod. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[location.x];Y=[location.y];Z=[location.z]'>JMP</a>)")
message_admins("<span class='notice'>[key_name_admin(M)] has entered a stasis pod.</span>")
//Despawning occurs when process() is called with an occupant without a client.
src.add_fingerprint(M)
/obj/machinery/cryopod/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob)
@@ -346,7 +473,7 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
return
if(!ismob(O)) //humans only
return
if(istype(O, /mob/living/simple_animal) || istype(O, /mob/living/silicon)) //animals and robutts dont fit
if(!check_occupant_allowed(O))
return
if(!ishuman(user) && !isrobot(user)) //No ghosts or mice putting people into the sleeper
return
@@ -393,25 +520,24 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
L.client.eye = src
if(orient_right)
icon_state = "body_scanner_1-r"
icon_state = "[occupied_icon_state]-r"
else
icon_state = "body_scanner_1"
icon_state = occupied_icon_state
L << "\blue You feel cool air surround you. You go numb as your senses turn inward."
L << "\blue <b>If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.</b>"
L << "<span class='notice'>[on_enter_occupant_message]</span>"
L << "<span class='notice'><b>If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.</b></span>"
occupant = L
time_entered = world.time
// Book keeping!
log_admin("[key_name_admin(L)] has entered a stasis pod.")
message_admins("\blue [key_name_admin(L)] has entered a stasis pod.")
log_admin("[key_name_admin(L)] has entered a stasis pod. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
message_admins("<span class='notice'>[key_name_admin(L)] has entered a stasis pod.</span>")
//Despawning occurs when process() is called with an occupant without a client.
src.add_fingerprint(L)
return
/obj/machinery/cryopod/verb/eject()
set name = "Eject Pod"
set category = "Object"
@@ -420,12 +546,22 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
return
if(orient_right)
icon_state = "body_scanner_0-r"
icon_state = "[base_icon_state]-r"
else
icon_state = "body_scanner_0"
icon_state = base_icon_state
//Eject any items that aren't meant to be in the pod.
var/list/items = src.contents
if(occupant) items -= occupant
if(announce) items -= announce
for(var/obj/item/W in items)
W.loc = get_turf(src)
src.go_out()
add_fingerprint(usr)
name = initial(name)
return
/obj/machinery/cryopod/verb/move_inside()
@@ -433,11 +569,11 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
set category = "Object"
set src in oview(1)
if(usr.stat != 0 || !(ishuman(usr) || ismonkey(usr)))
if(usr.stat != 0 || !check_occupant_allowed(usr))
return
if(src.occupant)
usr << "\blue <B>The cryo pod is in use.</B>"
usr << "<span class='notice'><B>\The [src] is in use.</B></span>"
return
for(var/mob/living/carbon/slime/M in range(1,usr))
@@ -445,7 +581,7 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
usr << "You're too busy getting your life sucked out of you."
return
visible_message("[usr] starts climbing into the cryo pod.", 3)
visible_message("[usr] starts climbing into \the [src].", 3)
if(do_after(usr, 20))
@@ -453,7 +589,7 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
return
if(src.occupant)
usr << "\blue <B>The cryo pod is in use.</B>"
usr << "<span class='notice'><B>\The [src] is in use.</B></span>"
return
usr.stop_pulling()
@@ -463,16 +599,17 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
src.occupant = usr
if(orient_right)
icon_state = "body_scanner_1-r"
icon_state = "[occupied_icon_state]-r"
else
icon_state = "body_scanner_1"
icon_state = occupied_icon_state
usr << "\blue You feel cool air surround you. You go numb as your senses turn inward."
usr << "\blue <b>If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.</b>"
usr << "<span class='notice'>[on_enter_occupant_message]</span>"
usr << "<span class='notice'><b>If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.</b></span>"
occupant = usr
time_entered = world.time
src.add_fingerprint(usr)
name = "[name] ([usr.name])"
return
@@ -489,9 +626,9 @@ obj/machinery/computer/cryopod/Topic(href, href_list)
occupant = null
if(orient_right)
icon_state = "body_scanner_0-r"
icon_state = "[base_icon_state]-r"
else
icon_state = "body_scanner_0"
icon_state = base_icon_state
return
+12
View File
@@ -39,6 +39,18 @@
if("JoinLate")
latejoin += loc
del(src)
if("JoinLateGateway")
latejoin_gateway += loc
del(src)
if("JoinLateCryo")
latejoin_cryo += loc
del(src)
if("JoinLateCyborg")
latejoin_cyborg += loc
del(src)
//prisoners
if("prisonwarp")
+4
View File
@@ -75,6 +75,10 @@
if(P.damage && !P.nodamage)
deal_damage(P.damage)
/obj/spacepod/blob_act()
deal_damage(30)
return
/obj/spacepod/attack_animal(mob/living/simple_animal/user as mob)
if(user.melee_damage_upper == 0)
user.emote("[user.friendly] [src]")
+7 -1
View File
@@ -167,6 +167,9 @@ var/list/monkeystart = list()
var/list/wizardstart = list()
var/list/newplayer_start = list()
var/list/latejoin = list()
var/list/latejoin_gateway = list()
var/list/latejoin_cryo = list()
var/list/latejoin_cyborg = list()
var/list/prisonwarp = list() //prisoners go to these
var/list/holdingfacility = list() //captured people go here
var/list/xeno_spawn = list()//Aliens spawn at these.
@@ -329,4 +332,7 @@ var/recall_time_limit=72000
var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
// AI controlled bots
var/global/list/aibots = list()
var/global/list/aibots = list()
// Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it.
var/global/obj/item/device/radio/intercom/global_announcer = new(null)
+2 -1
View File
@@ -64,7 +64,8 @@ var/list/admin_verbs_admin = list(
/client/proc/man_up,
/client/proc/global_man_up,
/client/proc/delbook,
/client/proc/event_manager_panel
/client/proc/event_manager_panel,
/client/proc/empty_ai_core_toggle_latejoin
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
+13
View File
@@ -91,6 +91,7 @@ datum/preferences
var/be_random_name = 0 //whether we are a random name every round
var/gender = MALE //gender of character (well duh)
var/age = 30 //age of character
var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2).
var/b_type = "A+" //blood type (not-chooseable)
var/underwear = 1 //underwear type
var/undershirt = 1 //undershirt type
@@ -214,6 +215,7 @@ datum/preferences
dat += "<br>"
dat += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender'><b>[gender == MALE ? "Male" : "Female"]</b></a><br>"
dat += "<b>Age:</b> <a href='?_src_=prefs;preference=age;task=input'>[age]</a>"
//dat += "<b>Spawn Point</b>: <a href='byond://?src=\ref[user];preference=spawnpoint;task=input'>[spawnpoint]</a>"
dat += "<br><table><tr><td><b>Body</b> "
dat += "(<a href='?_src_=prefs;preference=all;task=random'>&reg;</A>)"
dat += "<br>"
@@ -1293,6 +1295,17 @@ datum/preferences
var/skin_style_name = input(user, "Select a new skin style") as null|anything in list("default1", "default2", "default3")
if(!skin_style_name) return
*/
/* if("spawnpoint")
var/list/spawnkeys = list()
for(var/S in spawntypes)
spawnkeys += S
var/choice = input(user, "Where would you like to spawn when latejoining?") as null|anything in spawnkeys
if(!choice || !spawntypes[choice])
spawnpoint = "Arrivals Shuttle"
return
spawnpoint = choice */
else
switch(href_list["preference"])
if("gender")
@@ -121,6 +121,7 @@
S["age"] >> age
S["species"] >> species
S["language"] >> language
S["spawnpoint"] >> spawnpoint
//colors to be consolidated into hex strings (requires some work with dna code)
S["hair_red"] >> r_hair
@@ -323,6 +324,7 @@
real_name = reject_bad_name(real_name)
if(isnull(species)) species = "Human"
if(isnull(language)) language = "None"
if(isnull(spawnpoint)) spawnpoint = "Arrivals Shuttle"
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
if(!real_name) real_name = random_name(gender)
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
@@ -0,0 +1,57 @@
var/list/spawntypes = list()
/proc/populate_spawn_points()
spawntypes = list()
for(var/type in typesof(/datum/spawnpoint)-/datum/spawnpoint)
var/datum/spawnpoint/S = new type()
spawntypes[S.display_name] = S
/datum/spawnpoint
var/msg //Message to display on the arrivals computer.
var/list/turfs //List of turfs to spawn on.
var/display_name //Name used in preference setup.
var/list/restrict_job = null
var/list/disallow_job = null
proc/check_job_spawning(job)
if(restrict_job && !(job in restrict_job))
return 0
if(disallow_job && (job in disallow_job))
return 0
return 1
/datum/spawnpoint/arrivals
display_name = "Arrivals Shuttle"
msg = "has arrived on the station"
/datum/spawnpoint/arrivals/New()
..()
turfs = latejoin
/datum/spawnpoint/gateway
display_name = "Gateway"
msg = "has completed translation from offsite gateway"
/datum/spawnpoint/gateway/New()
..()
turfs = latejoin_gateway
/datum/spawnpoint/cryo
display_name = "Cryogenic Storage"
msg = "has completed cryogenic revival"
disallow_job = list("Cyborg")
/datum/spawnpoint/cryo/New()
..()
turfs = latejoin_cryo
/datum/spawnpoint/cyborg
display_name = "Cyborg Storage"
msg = "has been activated from storage"
restrict_job = list("Cyborg")
/datum/spawnpoint/cyborg/New()
..()
turfs = latejoin_cyborg
+2 -2
View File
@@ -501,7 +501,7 @@
icon_state = "rig0-singuloth"
item_state = "singuloth_helm"
_color = "singuloth"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 80)
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 100)
/obj/item/clothing/suit/space/rig/singuloth
icon_state = "rig-singuloth"
@@ -509,4 +509,4 @@
desc = "This is a ceremonial armor from the chapter of the Singuloth Knights. It's made of pure forged adamantium."
item_state = "singuloth_hardsuit"
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 80)
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 100)
+13 -25
View File
@@ -101,85 +101,73 @@
flags = FPRINT | TABLEPASS | ONESIZEFITSALL
/obj/item/clothing/under/psyche
name = "psychedelic"
name = "psychedelic jumpsuit"
desc = "Groovy!"
icon_state = "psyche"
_color = "psyche"
/obj/item/clothing/under/color/lightblue
name = "lightblue"
desc = "lightblue"
name = "light blue jumpsuit"
icon_state = "lightblue"
_color = "lightblue"
/obj/item/clothing/under/color/aqua
name = "aqua"
desc = "aqua"
name = "aqua jumpsuit"
icon_state = "aqua"
_color = "aqua"
flags = FPRINT | TABLEPASS | ONESIZEFITSALL
/obj/item/clothing/under/color/purple
name = "purple"
desc = "purple"
name = "purple jumpsuit"
icon_state = "purple"
item_state = "p_suit"
_color = "purple"
/obj/item/clothing/under/color/lightpurple
name = "lightpurple"
desc = "lightpurple"
name = "light purple jumpsuit"
icon_state = "lightpurple"
_color = "lightpurple"
/obj/item/clothing/under/color/lightgreen
name = "lightgreen"
desc = "lightgreen"
name = "light green jumpsuit"
icon_state = "lightgreen"
_color = "lightgreen"
/obj/item/clothing/under/color/lightblue
name = "lightblue"
desc = "lightblue"
name = "light blue jumpsuit"
icon_state = "lightblue"
_color = "lightblue"
/obj/item/clothing/under/color/lightbrown
name = "lightbrown"
desc = "lightbrown"
name = "light brown jumpsuit"
icon_state = "lightbrown"
_color = "lightbrown"
flags = FPRINT | TABLEPASS | ONESIZEFITSALL
/obj/item/clothing/under/color/brown
name = "brown"
desc = "brown"
name = "brown jumpsuit"
icon_state = "brown"
_color = "brown"
flags = FPRINT | TABLEPASS
/obj/item/clothing/under/color/yellowgreen
name = "yellowgreen"
desc = "yellowgreen"
name = "yellow green jumpsuit"
icon_state = "yellowgreen"
_color = "yellowgreen"
/obj/item/clothing/under/color/darkblue
name = "darkblue"
desc = "darkblue"
name = "dark blue jumpsuit"
icon_state = "darkblue"
_color = "darkblue"
flags = FPRINT | TABLEPASS | ONESIZEFITSALL
/obj/item/clothing/under/color/lightred
name = "lightred"
desc = "lightred"
name = "light red jumpsuit"
icon_state = "lightred"
_color = "lightred"
/obj/item/clothing/under/color/darkred
name = "darkred"
desc = "darkred"
name = "dark red jumpsuit"
icon_state = "darkred"
_color = "darkred"
flags = FPRINT | TABLEPASS | ONESIZEFITSALL
+1 -1
View File
@@ -115,7 +115,7 @@ var/list/ai_list = list()
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.
new/obj/structure/AIcore/deactivated(loc)//New empty terminal.
empty_playable_ai_cores += new/obj/structure/AIcore/deactivated(loc)//New empty terminal.
del(src)//Delete AI.
return
else
@@ -0,0 +1,44 @@
var/global/list/empty_playable_ai_cores = list()
/hook/roundstart/proc/spawn_empty_ai()
for(var/obj/effect/landmark/start/S in landmarks_list)
if(S.name != "AI")
continue
if(locate(/mob/living) in S.loc)
continue
empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(get_turf(S))
return 1
/mob/living/silicon/ai/verb/wipe_core()
set name = "Wipe Core"
set category = "OOC"
set desc = "Wipe your core. This is functionally equivalent to cryo or robotic storage, freeing up your job slot."
if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
usr << "<span class='danger'>You cannot use this verb in malfunction. If you need to leave, please adminhelp.</span>"
return
// Guard against misclicks, this isn't the sort of thing we want happening accidentally
if(alert("WARNING: This will immediately wipe your core and ghost you, removing your character from the round permanently (similar to cryo and robotic storage). Are you entirely sure you want to do this?",
"Wipe Core", "No", "No", "Yes") != "Yes")
return
// We warned you.
empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(loc)
global_announcer.autosay("[src] has been moved to intelligence storage.", "Artificial Intelligence Oversight")
//Handle job slot/tater cleanup.
var/job = mind.assigned_role
job_master.FreeRole(job)
if(mind.objectives.len)
del(mind.objectives)
mind.special_role = null
else
if(ticker.mode.name == "AutoTraitor")
var/datum/game_mode/traitor/autotraitor/current_mode = ticker.mode
current_mode.possible_traitors.Remove(src)
del(src)
@@ -349,12 +349,15 @@ var/datum/paiController/paiController // Global handler for pAI candidates
proc/requestRecruits()
for(var/mob/dead/observer/O in player_list)
if(O.client && O.client.prefs.be_special & BE_PAI)
if(check_recruit(O))
O << "\blue <b>A pAI card is looking for personalities. (<a href='?src=\ref[src];signup=\ref[O]'>Sign Up</a>)</b>"
//question(O.client)
if(player_old_enough_antag(O.client,BE_PAI))
if(check_recruit(O))
O << "\blue <b>A pAI card is looking for personalities. (<a href='?src=\ref[src];signup=\ref[O]'>Sign Up</a>)</b>"
//question(O.client)
proc/check_recruit(var/mob/dead/observer/O)
if(jobban_isbanned(O, "pAI") || jobban_isbanned(O,"nonhumandept"))
return 0
if(!player_old_enough_antag(O.client,BE_PAI))
return 0
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
return 0
if(O.client)
+71 -14
View File
@@ -167,7 +167,7 @@
src << alert("You are currently not whitelisted to play [client.prefs.species].")
return 0
AttemptLateSpawn(href_list["SelectedJob"])
AttemptLateSpawn(href_list["SelectedJob"],client.prefs.spawnpoint)
return
if(href_list["privacy_poll"])
@@ -272,7 +272,7 @@
proc/IsJobAvailable(rank)
var/datum/job/job = job_master.GetJob(rank)
if(!job) return 0
if((job.current_positions >= job.total_positions) && job.total_positions != -1) return 0
if(!job.is_position_available()) return 0
if(jobban_isbanned(src,rank)) return 0
if(!is_job_whitelisted(src, rank)) return 0
if(!job.player_old_enough(src.client)) return 0
@@ -290,7 +290,7 @@
return 1
proc/AttemptLateSpawn(rank)
proc/AttemptLateSpawn(rank,var/spawning_at)
if (src != usr)
return 0
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
@@ -305,11 +305,48 @@
job_master.AssignRole(src, rank, 1)
var/mob/living/carbon/human/character = create_character() //creates the human and transfers vars and mind
var/mob/living/character = create_character() //creates the human and transfers vars and mind
EquipRacialItems(character)
job_master.EquipRank(character, rank, 1) //equips the human
character = job_master.EquipRank(character, rank, 1) //equips the human
EquipCustomItems(character)
character.loc = pick(latejoin)
// AIs don't need a spawnpoint, they must spawn at an empty core
if(character.mind.assigned_role == "AI")
character = character.AIize(move=0) // AIize the character, but don't move them yet
// IsJobAvailable for AI checks that there is an empty core available in this list
var/obj/structure/AIcore/deactivated/C = empty_playable_ai_cores[1]
empty_playable_ai_cores -= C
character.loc = C.loc
AnnounceCyborg(character, rank, "has been downloaded to the empty core in \the [character.loc.loc]")
ticker.mode.latespawn(character)
del(C)
del(src)
return
//Find our spawning point.
var/join_message
var/datum/spawnpoint/S
if(spawning_at)
S = spawntypes[spawning_at]
if(S && istype(S))
if(S.check_job_spawning(rank))
character.loc = pick(S.turfs)
join_message = S.msg
else
character << "Your chosen spawnpoint ([S.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead."
character.loc = pick(latejoin)
join_message = "has arrived on the station"
else
character.loc = pick(latejoin)
join_message = "has arrived on the station"
character.lastarea = get_area(loc)
// Moving wheelchair if they have one
if(character.buckled && istype(character.buckled, /obj/structure/stool/bed/chair/wheelchair))
@@ -321,14 +358,15 @@
if(character.mind.assigned_role != "Cyborg")
data_core.manifest_inject(character)
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
AnnounceArrival(character, rank)
AnnounceArrival(character, rank, join_message)
callHook("latespawn", list(character))
else
character.Robotize()
AnnounceCyborg(character, rank, join_message)
callHook("latespawn", list(character))
del(src)
proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank)
proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message)
if (ticker.current_state == GAME_STATE_PLAYING)
var/ailist[] = list()
for (var/mob/living/silicon/ai/A in living_mob_list)
@@ -337,16 +375,35 @@
var/mob/living/silicon/ai/announcer = pick(ailist)
if(character.mind)
if((character.mind.assigned_role != "Cyborg") && (character.mind.special_role != "MODE"))
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
var/arrivalmessage = announcer.arrivalmsg
arrivalmessage = replacetext(arrivalmessage,"$name",character.real_name)
arrivalmessage = replacetext(arrivalmessage,"$rank",rank ? "[rank]" : "visitor")
announcer.say(";[arrivalmessage]")
else
var/obj/item/device/radio/intercom/a = new /obj/item/device/radio/intercom(null)// BS12 EDIT Arrivals Announcement Computer, rather than the AI.
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
a.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] has arrived on the station.", "Arrivals Announcement Computer")
del(a)
if(character.mind)
if((character.mind.assigned_role != "Cyborg") && (character.mind.special_role != "MODE"))
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
global_announcer.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message)
if (ticker.current_state == GAME_STATE_PLAYING)
var/ailist[] = list()
for (var/mob/living/silicon/ai/A in living_mob_list)
ailist += A
if (ailist.len)
var/mob/living/silicon/ai/announcer = pick(ailist)
if(character.mind)
if((character.mind.special_role != "MODE"))
var/arrivalmessage = "A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"]."
announcer.say(";[arrivalmessage]")
else
if(character.mind)
if((character.mind.special_role != "MODE"))
// can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc.
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
proc/LateChoices()
var/mills = world.time // 1/10 of a second, not real milliseconds but whatever
+27 -26
View File
@@ -61,13 +61,13 @@
spawning = 1
return ..()
/mob/living/carbon/human/AIize()
/mob/living/carbon/human/AIize(move=1) // 'move' argument needs defining here too because BYOND is dumb
if (monkeyizing)
return
for(var/t in organs)
del(t)
return ..()
return ..(move)
/mob/living/carbon/AIize()
if (monkeyizing)
@@ -80,7 +80,7 @@
invisibility = 101
return ..()
/mob/proc/AIize()
/mob/proc/AIize(move=1)
if(client)
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jams for AIs
var/mob/living/silicon/ai/O = new (loc,,,1)//No MMI but safety is in effect.
@@ -93,28 +93,29 @@
else
O.key = key
var/obj/loc_landmark
for(var/obj/effect/landmark/start/sloc in landmarks_list)
if (sloc.name != "AI")
continue
if (locate(/mob/living) in sloc.loc)
continue
loc_landmark = sloc
if (!loc_landmark)
for(var/obj/effect/landmark/tripai in landmarks_list)
if (tripai.name == "tripai")
if(locate(/mob/living) in tripai.loc)
continue
loc_landmark = tripai
if (!loc_landmark)
O << "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone."
if(move)
var/obj/loc_landmark
for(var/obj/effect/landmark/start/sloc in landmarks_list)
if (sloc.name == "AI")
loc_landmark = sloc
if (sloc.name != "AI")
continue
if ((locate(/mob/living) in sloc.loc) || (locate(/obj/structure/AIcore) in sloc.loc))
continue
loc_landmark = sloc
if (!loc_landmark)
for(var/obj/effect/landmark/tripai in landmarks_list)
if (tripai.name == "tripai")
if((locate(/mob/living) in tripai.loc) || (locate(/obj/structure/AIcore) in tripai.loc))
continue
loc_landmark = tripai
if (!loc_landmark)
O << "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone."
for(var/obj/effect/landmark/start/sloc in landmarks_list)
if (sloc.name == "AI")
loc_landmark = sloc
O.loc = loc_landmark.loc
for (var/obj/item/device/radio/intercom/comm in O.loc)
comm.ai += O
O.loc = loc_landmark.loc
for (var/obj/item/device/radio/intercom/comm in O.loc)
comm.ai += O
O << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
O << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
@@ -131,9 +132,9 @@
O.job = "AI"
O.rename_self("ai",1)
. = O
del(src)
spawn(0)
del(src)
return O
/mob/living/carbon/human/make_into_mask(var/should_gib = 0)
for(var/t in organs)