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
+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]")