mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 18:44:48 +01:00
Merge pull request #254 from Markolie/master
Bug fixes, latejoining additions
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -135,6 +135,7 @@ var/list/civilian_positions = list(
|
||||
var/list/nonhuman_positions = list(
|
||||
"AI",
|
||||
"Cyborg",
|
||||
"Drone",
|
||||
"pAI"
|
||||
)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
@@ -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)
|
||||
@@ -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,
|
||||
|
||||
@@ -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'>®</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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user