Merge with upstream/master

Fixes conflicts
This commit is contained in:
DZD
2015-02-18 13:41:32 -05:00
325 changed files with 5353 additions and 3917 deletions
+3 -2
View File
@@ -313,7 +313,8 @@ proc/isInSight(var/atom/A, var/atom/B)
return M
return null
/proc/get_candidates(be_special_flag=0, afk_bracket=3000, jobban=0, department_jobban=0, override_age=0)
/proc/get_candidates(be_special_flag=0, afk_bracket=3000, override_age=0, override_jobban=0)
var/roletext = get_roletext(be_special_flag)
var/list/candidates = list()
// Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000))
while(!candidates.len && afk_bracket < 6000)
@@ -321,7 +322,7 @@ proc/isInSight(var/atom/A, var/atom/B)
if(G.client != null)
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
if(!G.client.is_afk(afk_bracket) && (G.client.prefs.be_special & be_special_flag))
if(!jobban && !department_jobban || !jobban_isbanned(G, jobban) && !jobban_isbanned(G,department_jobban))
if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate")))
if(override_age || player_old_enough_antag(G.client,be_special_flag))
candidates += G.client
afk_bracket += 600 // Add a minute to the bracket, for every attempt
+32 -2
View File
@@ -82,7 +82,7 @@
// Used to get a sanitized input.
/proc/stripped_input(var/mob/user, var/message = "", var/title = "", var/default = "", var/max_length=MAX_MESSAGE_LEN)
var/name = input(user, message, title, default)
return strip_html_simple(name, max_length)
return strip_html_properly(name, max_length)
//Filters out undesirable characters from names
/proc/reject_bad_name(var/t_in, var/allow_numbers=0, var/max_length=MAX_NAME_LEN)
@@ -311,4 +311,34 @@ proc/checkhtml(var/t)
var/new_text = ""
for(var/i = length(text); i > 0; i--)
new_text += copytext(text, i, i+1)
return new_text
return new_text
//This proc strips html properly, but it's not lazy like the other procs.
//This means that it doesn't just remove < and > and call it a day.
//Also limit the size of the input, if specified.
/proc/strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN)
if(!input)
return
var/opentag = 1 //These store the position of < and > respectively.
var/closetag = 1
while(1)
opentag = findtext(input, "<")
closetag = findtext(input, ">")
if(closetag && opentag)
if(closetag < opentag)
input = copytext(input, (closetag + 1))
else
input = copytext(input, 1, opentag) + copytext(input, (closetag + 1))
else if(closetag || opentag)
if(opentag)
input = copytext(input, 1, opentag)
else
input = copytext(input, (closetag + 1))
else
break
if(max_length)
input = copytext(input,1,max_length)
return sanitize(input)
/proc/trim_strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN)
return trim(strip_html_properly(input, max_length))
+2 -1
View File
@@ -227,7 +227,7 @@ proc/tg_text2list(text, glue=",", assocglue=";")
. += copytext(text, last_found, found)
last_found = found + delim_len
while(found)
/proc/text2numlist(text, delimiter="\n")
var/list/num_list = list()
for(var/x in text2list(text, delimiter))
@@ -347,6 +347,7 @@ proc/tg_text2list(text, glue=",", assocglue=";")
if(rights & R_SOUNDS) . += "[seperator]+SOUND"
if(rights & R_SPAWN) . += "[seperator]+SPAWN"
if(rights & R_MOD) . += "[seperator]+MODERATOR"
if(rights & R_MENTOR) . += "[seperator]+MENTOR"
return .
/proc/ui_style2icon(ui_style)
+1 -7
View File
@@ -411,13 +411,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
//world << "<b>[newname] is the AI!</b>"
//world << sound('sound/AI/newAI.ogg')
// Set eyeobj name
if(A.eyeobj)
A.eyeobj.name = "[newname] (AI Eye)"
// Set ai pda name
if(A.aiPDA)
A.aiPDA.owner = newname
A.aiPDA.name = newname + " (" + A.aiPDA.ownjob + ")"
A.SetName(newname)
fully_replace_character_name(oldname,newname)
+1 -2
View File
@@ -503,8 +503,7 @@
if("Crew Monitoring")
if(isAI(usr))
var/mob/living/silicon/ai/AI = usr
var/obj/machinery/computer/crew/C = locate(/obj/machinery/computer/crew)
C.attack_ai(AI)
AI.nano_crew_monitor()
if("Show Crew Manifest")
if(isAI(usr))
+1 -1
View File
@@ -66,7 +66,7 @@
/obj/machinery/teleport/hub/attack_ghost(mob/user as mob)
var/atom/l = loc
var/obj/machinery/computer/teleporter/com = locate(/obj/machinery/computer/teleporter, locate(l.x - 2, l.y, l.z))
if(com.locked)
if(com && com.locked)
user.loc = get_turf(com.locked)
/obj/effect/portal/attack_ghost(mob/user as mob)
+17
View File
@@ -135,6 +135,11 @@
var/default_laws = 0 //Controls what laws the AI spawns with.
var/list/station_levels = list(1) // Defines which Z-levels the station exists on.
var/list/admin_levels= list(2) // Defines which Z-levels which are for admin functionality, for example including such areas as Central Command and the Syndicate Shuttle
var/list/contact_levels = list(1, 5) // Defines which Z-levels which, for example, a Code Red announcement may affect
var/list/player_levels = list(1, 3, 4, 5, 6) // Defines all Z-levels a character can typically reach
var/const/minutes_to_ticks = 60 * 10
// Event settings
var/expected_round_length = 60 * 2 * minutes_to_ticks // 2 hours
@@ -458,6 +463,18 @@
if("max_maint_drones")
config.max_maint_drones = text2num(value)
if("station_levels")
config.station_levels = text2numlist(value, ";")
if("admin_levels")
config.admin_levels = text2numlist(value, ";")
if("contact_levels")
config.contact_levels = text2numlist(value, ";")
if("player_levels")
config.player_levels = text2numlist(value, ";")
if("expected_round_length")
config.expected_round_length = MinutesToTicks(text2num(value))
@@ -18,7 +18,10 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
var/deny_shuttle = 0 //allows admins to prevent the shuttle from being called
var/departed = 0 //if the shuttle has left the station at least once
var/datum/announcement/priority/emergency_shuttle_docked = new(0, new_sound = sound('sound/AI/shuttledock.ogg'))
var/datum/announcement/priority/emergency_shuttle_called = new(0, new_sound = sound('sound/AI/shuttlecalled.ogg'))
var/datum/announcement/priority/emergency_shuttle_recalled = new(0, new_sound = sound('sound/AI/shuttlerecalled.ogg'))
/datum/emergency_shuttle_controller/proc/process()
if (wait_for_launch)
@@ -29,7 +32,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
if (!shuttle.location) //leaving from the station
if(is_stranded())
captain_announce("Hostile environment detected. Departure has been postponed indefinitely pending conflict resolution.")
priority_announcement.Announce("Hostile environment detected. Departure has been postponed indefinitely pending conflict resolution.")
wait_for_launch = 0
return
//launch the pods!
@@ -49,10 +52,9 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
set_launch_countdown(SHUTTLE_LEAVETIME) //get ready to return
if (evac)
captain_announce("The Emergency Shuttle has docked with the station. You have approximately [round(estimate_launch_time()/60,1)] minutes to board the Emergency Shuttle.")
world << sound('sound/AI/shuttledock.ogg')
emergency_shuttle_docked.Announce("The Emergency Shuttle has docked with the station. You have approximately [round(estimate_launch_time()/60,1)] minutes to board the Emergency Shuttle.")
else
captain_announce("The scheduled Crew Transfer Shuttle has docked with the station. It will depart in approximately [round(emergency_shuttle.estimate_launch_time()/60,1)] minutes.")
priority_announcement.Announce("The scheduled Crew Transfer Shuttle has docked with the station. It will depart in approximately [round(emergency_shuttle.estimate_launch_time()/60,1)] minutes.")
//arm the escape pods
if (evac)
@@ -81,8 +83,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
shuttle.move_time = SHUTTLE_TRANSIT_DURATION
evac = 1
captain_announce("An emergency evacuation shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.")
world << sound('sound/AI/shuttlecalled.ogg')
emergency_shuttle_called.Announce("An emergency evacuation shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.")
for(var/area/A in world)
if(istype(A, /area/hallway))
A.readyalert()
@@ -101,7 +102,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
//reset the shuttle transit time if we need to
shuttle.move_time = SHUTTLE_TRANSIT_DURATION
captain_announce("A crew transfer has been scheduled. The shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.")
priority_announcement.Announce("A crew transfer has been scheduled. The shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.")
//recalls the shuttle
/datum/emergency_shuttle_controller/proc/recall()
@@ -111,15 +112,14 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
shuttle.cancel_launch(src)
if (evac)
captain_announce("The emergency shuttle has been recalled.")
world << sound('sound/AI/shuttlerecalled.ogg')
emergency_shuttle_recalled.Announce("The emergency shuttle has been recalled.")
for(var/area/A in world)
if(istype(A, /area/hallway))
A.readyreset()
evac = 0
else
captain_announce("The scheduled crew transfer has been cancelled.")
priority_announcement.Announce("The scheduled crew transfer has been cancelled.")
/datum/emergency_shuttle_controller/proc/can_call()
if (deny_shuttle)
+1 -1
View File
@@ -238,7 +238,7 @@
/obj/item/clothing/mask/facehugger) // NOT CLOTHING AT ALLLLL
whitelist = list(/obj/item/clothing,/obj/item/weapon/storage/belt,/obj/item/weapon/storage/backpack,
/obj/item/device/radio/headset,/obj/item/device/pda,/obj/item/weapon/card/id,/obj/item/weapon/tank,
/obj/item/weapon/handcuffs, /obj/item/weapon/legcuffs)
/obj/item/weapon/restraints/handcuffs, /obj/item/weapon/restraints/legcuffs)
/datum/cargoprofile/trash
name = "Trash"
+1 -1
View File
@@ -35,7 +35,7 @@
/datum/crafting_recipe/table/stunprod
name = "Stunprod"
result_path = /obj/item/weapon/melee/baton/cattleprod
reqs = list(/obj/item/weapon/handcuffs/cable = 1,
reqs = list(/obj/item/weapon/restraints/handcuffs/cable = 1,
/obj/item/stack/rods = 1,
/obj/item/weapon/wirecutters = 1,
/obj/item/weapon/stock_parts/cell = 1)
+2 -2
View File
@@ -190,7 +190,7 @@
teleatom.visible_message("\red <B>The [teleatom] bounces off of the portal!</B>")
return 0
if(destination.z == 2) //centcomm z-level
if((destination.z in config.admin_levels)) //centcomm z-level
if(istype(teleatom, /obj/mecha))
var/obj/mecha/MM = teleatom
MM.occupant << "\red <B>The mech would not survive the jump to a location so far away!</B>"
@@ -200,6 +200,6 @@
return 0
if(destination.z > 7) //Away mission z-levels
if(!(destination.z in config.player_levels)) //Away mission z-levels
return 0
return 1
+7 -6
View File
@@ -8,6 +8,7 @@
author = "Nanotrasen Editor"
channel_name = "Tau Ceti Daily"
can_be_redacted = 0
message_type = "Story"
revolution_inciting_event
@@ -129,12 +130,6 @@ proc/check_for_newscaster_updates(type)
proc/announce_newscaster_news(datum/news_announcement/news)
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = news.author
newMsg.is_admin_message = !news.can_be_redacted
newMsg.body = news.message
var/datum/feed_channel/sendto
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == news.channel_name)
@@ -148,6 +143,12 @@ proc/announce_newscaster_news(datum/news_announcement/news)
sendto.locked = 1
sendto.is_admin_channel = 1
news_network.network_channels += sendto
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = news.author ? news.author : sendto.author
newMsg.is_admin_message = !news.can_be_redacted
newMsg.body = news.message
newMsg.message_type = news.message_type
sendto.messages += newMsg
+1 -1
View File
@@ -60,7 +60,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
caster.reset_view(0)
return 0
if(user.z == 2 && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel
if((user.z in config.admin_levels) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel
return 0
if(!skipcharge)
+6 -51
View File
@@ -16,7 +16,7 @@
rate = -rate
solar_next_update = world.time // init the timer
angle = rand (0,360) // the station position to the sun is randomised at round start
/hook/startup/proc/createSun()
sun = new /datum/sun()
return 1
@@ -50,54 +50,9 @@
dx = s/abs(s)
dy = c / abs(s)
for(var/obj/machinery/power/M in solars_list)
if(!M.powernet)
solars_list.Remove(M)
//now tell the solar control computers to update their status and linked devices
for(var/obj/machinery/power/solar_control/SC in solars_list)
if(!SC.powernet)
solars_list.Remove(SC)
continue
// Solar Tracker
if(istype(M, /obj/machinery/power/tracker))
var/obj/machinery/power/tracker/T = M
T.set_angle(angle)
// Solar Control
else if(istype(M, /obj/machinery/power/solar_control))
var/obj/machinery/power/solar_control/C = M
if(C.track == 1) //if manual tracking...
C.tracker_update() //...update the position (not passing an angle, it is handled internally for manual tracking)
// Solar Panel
else if(istype(M, /obj/machinery/power/solar))
var/obj/machinery/power/solar/S = M
if(S.control)
occlusion(S)
// for a solar panel, trace towards sun to see if we're in shadow
/datum/sun/proc/occlusion(var/obj/machinery/power/solar/S)
var/ax = S.x // start at the solar panel
var/ay = S.y
var/turf/T = null
for(var/i = 1 to 20) // 20 steps is enough
ax += dx // do step
ay += dy
T = locate( round(ax,0.5),round(ay,0.5),S.z)
if(T.x == 1 || T.x==world.maxx || T.y==1 || T.y==world.maxy) // not obscured if we reach the edge
break
if(T.density) // if we hit a solid turf, panel is obscured
S.obscured = 1
return
S.obscured = 0 // if hit the edge or stepped 20 times, not obscured
S.update_solar_exposure()
SC.update()
Executable → Regular
+1091 -1004
View File
File diff suppressed because it is too large Load Diff
+5 -8
View File
@@ -1,3 +1,5 @@
#define CAT_HIDDEN 2 // Also in code/game/machinery/vending.dm
/datum/wires/vending
holder_type = /obj/machinery/vending
wire_count = 4
@@ -17,17 +19,12 @@ var/const/VENDING_WIRE_IDSCAN = 8
return 1
return 0
/datum/wires/vending/Interact(var/mob/living/user)
if(CanUse(user))
var/obj/machinery/vending/V = holder
V.attack_hand(user)
/datum/wires/vending/GetInteractWindow()
var/obj/machinery/vending/V = holder
. += ..()
. += "<BR>The orange light is [V.seconds_electrified ? "on" : "off"].<BR>"
. += "The red light is [V.shoot_inventory ? "off" : "blinking"].<BR>"
. += "The green light is [V.extended_inventory ? "on" : "off"].<BR>"
. += "The green light is [(V.categories & CAT_HIDDEN) ? "on" : "off"].<BR>"
. += "A [V.scan_id ? "purple" : "yellow"] light is on.<BR>"
/datum/wires/vending/UpdatePulsed(var/index)
@@ -36,7 +33,7 @@ var/const/VENDING_WIRE_IDSCAN = 8
if(VENDING_WIRE_THROW)
V.shoot_inventory = !V.shoot_inventory
if(VENDING_WIRE_CONTRABAND)
V.extended_inventory = !V.extended_inventory
V.categories ^= CAT_HIDDEN
if(VENDING_WIRE_ELECTRIFY)
V.seconds_electrified = 30
if(VENDING_WIRE_IDSCAN)
@@ -48,7 +45,7 @@ var/const/VENDING_WIRE_IDSCAN = 8
if(VENDING_WIRE_THROW)
V.shoot_inventory = !mended
if(VENDING_WIRE_CONTRABAND)
V.extended_inventory = 0
V.categories &= ~CAT_HIDDEN
if(VENDING_WIRE_ELECTRIFY)
if(mended)
V.seconds_electrified = 0
+5 -2
View File
@@ -72,8 +72,11 @@ var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown",
html = GetInteractWindow()
if(html)
user.set_machine(holder)
//user << browse(html, "window=wires;size=[window_x]x[window_y]")
//onclose(user, "wires")
else
user.unset_machine()
// No content means no window.
user << browse(null, "window=wires")
return
var/datum/browser/popup = new(user, "wires", holder.name, window_x, window_y)
popup.set_content(html)
popup.set_title_image(user.browse_rsc_icon(holder.icon, holder.icon_state))
+121
View File
@@ -0,0 +1,121 @@
/var/datum/announcement/priority/priority_announcement = new(do_log = 0)
/var/datum/announcement/priority/command/command_announcement = new(do_log = 0, do_newscast = 1)
/datum/announcement
var/title = "Attention"
var/announcer = ""
var/log = 0
var/sound
var/newscast = 0
var/channel_name = "Station Announcements"
var/announcement_type = "Announcement"
var/disable_newscasts = 1 // Bay also adds announcements to their newscaster system - set this to 0 to also use that system
/datum/announcement/New(var/do_log = 0, var/new_sound = null, var/do_newscast = 0)
sound = new_sound
log = do_log
newscast = do_newscast
/datum/announcement/priority/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "Priority Announcement"
announcement_type = "Priority Announcement"
/datum/announcement/priority/command/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "[command_name()] Update"
announcement_type = "[command_name()] Update"
/datum/announcement/priority/security/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "Security Announcement"
announcement_type = "Security Announcement"
/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast)
if(!message)
return
var/tmp/message_title = new_title ? new_title : title
var/tmp/message_sound = new_sound ? sound(new_sound) : sound
message = trim_strip_html_properly(message)
message_title = html_encode(message_title)
Message(message, message_title)
if(do_newscast)
NewsCast(message, message_title)
Sound(message_sound)
Log(message, message_title)
datum/announcement/proc/Message(message as text, message_title as text)
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player) && !isdeaf(M))
M << "<h2 class='alert'>[title]</h2>"
M << "<span class='alert'>[message]</span>"
if (announcer)
M << "<span class='alert'> -[html_encode(announcer)]</span>"
datum/announcement/minor/Message(message as text, message_title as text)
world << "<b>[message]</b>"
datum/announcement/priority/Message(message as text, message_title as text)
world << "<h1 class='alert'>[message_title]</h1>"
world << "<span class='alert'>[message]</span>"
if(announcer)
world << "<span class='alert'> -[html_encode(announcer)]</span>"
world << "<br>"
datum/announcement/priority/command/Message(message as text, message_title as text)
var/command
command += "<h1 class='alert'>[command_name()] Update</h1>"
if (message_title)
command += "<br><h2 class='alert'>[message_title]</h2>"
command += "<br><span class='alert'>[message]</span><br>"
command += "<br>"
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player) && !isdeaf(M))
M << command
datum/announcement/priority/security/Message(message as text, message_title as text)
world << "<font size=4 color='red'>[message_title]</font>"
world << "<font color='red'>[message]</font>"
datum/announcement/proc/NewsCast(message as text, message_title as text)
if(disable_newscasts)
return
if(!newscast)
return
var/datum/news_announcement/news = new
news.channel_name = channel_name
news.author = announcer
news.message = message
news.message_type = announcement_type
news.can_be_redacted = 0
announce_newscaster_news(news)
datum/announcement/proc/PlaySound(var/message_sound)
if(!message_sound)
return
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player) && !isdeaf(M))
M << message_sound
datum/announcement/proc/Sound(var/message_sound)
PlaySound(message_sound)
datum/announcement/priority/Sound(var/message_sound)
if(sound)
world << sound
datum/announcement/priority/command/Sound(var/message_sound)
PlaySound(message_sound)
datum/announcement/proc/Log(message as text, message_title as text)
if(log)
log_say("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]")
message_admins("[key_name_admin(usr)] has made \a [announcement_type].", 1)
/proc/GetNameAndAssignmentFromId(var/obj/item/weapon/card/id/I)
// Format currently matches that of newscaster feeds: Registered Name (Assigned Rank)
return I.assignment ? "[I.registered_name] ([I.assignment])" : I.registered_name
-5
View File
@@ -1,5 +0,0 @@
/proc/captain_announce(var/text)
world << "<h1 class='alert'>Priority Announcement</h1>"
world << "<span class='alert'>[html_encode(text)]</span>"
world << "<br>"
-11
View File
@@ -1,11 +0,0 @@
/proc/command_alert(var/text, var/title = "")
var/command
command += "<h1 class='alert'>[command_name()] Update</h1>"
if (title && length(title) > 0)
command += "<br><h2 class='alert'>[html_encode(title)]</h2>"
command += "<br><span class='alert'>[html_encode(text)]</span><br>"
command += "<br>"
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
M << command
+3 -3
View File
@@ -70,7 +70,7 @@ var/list/teleportlocs = list()
var/list/turfs = get_area_turfs(AR.type)
if(turfs.len)
var/turf/picked = pick(turfs)
if (picked.z == 1)
if ((picked.z in config.station_levels))
teleportlocs += AR.name
teleportlocs[AR.name] = AR
@@ -83,13 +83,13 @@ var/list/ghostteleportlocs = list()
/hook/startup/proc/setupGhostTeleportLocs()
for(var/area/AR in world)
if(ghostteleportlocs.Find(AR.name)) continue
if(istype(AR, /area/turret_protected/aisat) || istype(AR, /area/derelict) || istype(AR, /area/tdome))
if(istype(AR, /area/tdome))
ghostteleportlocs += AR.name
ghostteleportlocs[AR.name] = AR
var/list/turfs = get_area_turfs(AR.type)
if(turfs.len)
var/turf/picked = pick(turfs)
if (picked.z == 1 || picked.z == 5 || picked.z == 3)
if ((picked.z in config.player_levels))
ghostteleportlocs += AR.name
ghostteleportlocs[AR.name] = AR
+2
View File
@@ -242,6 +242,8 @@ its easier to just keep the beam vertical.
/atom/proc/blob_act()
return
/atom/proc/emag_act()
return
/atom/proc/hitby(atom/movable/AM as mob|obj)
if (density)
+1 -1
View File
@@ -26,7 +26,7 @@
if(!checking)
checking = 1
user << "<span class='notice'>The device is now checking for possible candidates.</span>"
get_candidate_answer(user, get_candidates(BE_OPERATIVE,,"operative","Syndicate"))
get_candidate_answer(user, get_candidates(BE_OPERATIVE))
else
user << "<span class='notice'>The device is already checking for possible candidates.</span>"
return
+5 -8
View File
@@ -58,7 +58,7 @@ var/list/blob_nodes = list()
/datum/game_mode/blob/proc/get_nuke_code()
var/nukecode = "ERROR"
for(var/obj/machinery/nuclearbomb/bomb in world)
if(bomb && bomb.r_code && bomb.z == 1)
if(bomb && bomb.r_code && (bomb.z in config.station_levels))
nukecode = bomb.r_code
return nukecode
@@ -92,7 +92,7 @@ var/list/blob_nodes = list()
if(directory[ckey(blob.key)])
blob_client = directory[ckey(blob.key)]
location = get_turf(C)
if(location.z != 1 || istype(location, /turf/space))
if(!(location.z in config.station_levels) || istype(location, /turf/space))
location = null
C.gib()
@@ -175,17 +175,14 @@ var/list/blob_nodes = list()
return
if (1)
command_alert("Nanotrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined.", "Biohazard Alert")
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
M << sound('sound/AI/blob_confirmed.ogg')
command_announcement.Announce("Nanotrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined.", "Biohazard Alert", new_sound = 'sound/AI/blob_confirmed.ogg')
return
if (2)
command_alert("The biohazard has grown out of control and will soon reach critical mass. Activate the nuclear failsafe to maintain quarantine. The Nuclear Authentication Code is [get_nuke_code()] ", "Biohazard Alert")
command_announcement.Announce("The biohazard has grown out of control and will soon reach critical mass. Activate the nuclear failsafe to maintain quarantine. The Nuclear Authentication Code is [get_nuke_code()] ", "Biohazard Alert", new_sound = 'sound/AI/blob_confirmed.ogg')
set_security_level("gamma")
var/obj/machinery/door/airlock/vault/V = locate(/obj/machinery/door/airlock/vault) in world
if(V && V.z == 1)
if(V && (V.z in config.station_levels))
V.locked = 0
V.update_icon()
send_intercept(2)
+1 -1
View File
@@ -62,7 +62,7 @@ datum/game_mode/proc/auto_declare_completion_blob()
if (istype(T, /turf/space))
numSpace += 1
else if(istype(T, /turf))
if (M.z!=1)
if (!(M.z in config.station_levels))
numOffStation += 1
else
numAlive += 1
+2 -2
View File
@@ -61,7 +61,7 @@
proc/count()
for(var/turf/T in world)
if(T.z != 1)
if(!(T.z in config.station_levels))
continue
if(istype(T,/turf/simulated/floor))
@@ -83,7 +83,7 @@
src.r_wall += 1
for(var/obj/O in world)
if(O.z != 1)
if(!(O.z in config.station_levels))
continue
if(istype(O, /obj/structure/window))
+1 -1
View File
@@ -72,7 +72,7 @@
var/list/candidates = list()
if(!new_overmind)
candidates = get_candidates(BE_BLOB,,"blob","Syndicate")
candidates = get_candidates(BE_BLOB)
if(candidates.len)
C = pick(candidates)
else
+1 -1
View File
@@ -39,7 +39,7 @@
return 0 // not enough candidates for borer
for(var/obj/machinery/atmospherics/unary/vent_pump/v in world)
if(!v.welded && v.z == STATION_Z) // No more spawning in atmos. Assuming the mappers did their jobs, anyway.
if(!v.welded && (v.z in config.station_levels))
found_vents.Add(v)
// for each 2 possible borers, add one borer and one host
+1 -1
View File
@@ -149,7 +149,7 @@
announce_to_kill_crew()
stage = 2
else if(stage == 2 && cruiser_seconds() <= 60 * 5)
command_alert("Inbound cruiser detected on collision course. Scans indicate the ship to be armed and ready to fire. Estimated time of arrival: 5 minutes.", "[station_name()] Early Warning System")
command_announcement.Announce("Inbound cruiser detected on collision course. Scans indicate the ship to be armed and ready to fire. Estimated time of arrival: 5 minutes.", "[station_name()] Early Warning System")
stage = 3
else if(stage == 3 && cruiser_seconds() <= 0)
crew_lose()
+25 -38
View File
@@ -30,10 +30,7 @@
eventNumbersToPickFrom += 3
switch(pick(eventNumbersToPickFrom))
if(1)
command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert")
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
M << sound('sound/AI/meteors.ogg')
command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
spawn(100)
meteor_wave()
spawn_meteors()
@@ -42,22 +39,18 @@
spawn_meteors()
if(2)
command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert")
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
M << sound('sound/AI/granomalies.ogg')
command_announcement.Announce("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert", new_sound = 'sound/AI/granomalies.ogg')
var/turf/T = pick(blobstart)
var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 )
spawn(rand(50, 300))
del(bh)
/*
if(3) //Leaving the code in so someone can try and delag it, but this event can no longer occur randomly, per SoS's request. --NEO
command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert")
world << sound('sound/AI/spanomalies.ogg')
command_announcement.Announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", new_sound = 'sound/AI/spanomalies.ogg')
var/list/turfs = new
var/turf/picked
for(var/turf/simulated/floor/T in world)
if(T.z == 1)
if((T.z in config.station_levels))
turfs += T
for(var/turf/simulated/floor/T in turfs)
if(prob(20))
@@ -107,8 +100,7 @@
/*
/proc/viral_outbreak(var/virus = null)
// command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
// world << sound('sound/AI/outbreak7.ogg')
// command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
var/virus_type
if(!virus)
virus_type = pick(/datum/disease/dnaspread,/datum/disease/advance/flu,/datum/disease/advance/cold,/datum/disease/brainrot,/datum/disease/magnitis,/datum/disease/pierrot_throat)
@@ -140,7 +132,7 @@
var/turf/T = get_turf(H)
if(!T)
continue
if(T.z != 1)
if(!(T.z in config.station_levels))
continue
for(var/datum/disease/D in H.viruses)
foundAlready = 1
@@ -167,21 +159,18 @@
H.viruses += D
break
spawn(rand(1500, 3000)) //Delayed announcements to keep the crew on their toes.
command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
for(var/mob/M in player_list)
M << sound('sound/AI/outbreak7.ogg')
command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
*/
/proc/alien_infestation(var/spawncount = 1) // -- TLE
//command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
//world << sound('sound/AI/aliens.ogg')
//command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines)
if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network)
if((temp_vent.loc.z in config.station_levels) && !temp_vent.welded && temp_vent.network)
if(temp_vent.network.normal_members.len > 50) // Stops Aliens getting stuck in small networks. See: Security, Virology
vents += temp_vent
var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET,"alien","Syndicate")
var/list/candidates = get_candidates(BE_ALIEN,ALIEN_AFK_BRACKET)
if(prob(40)) spawncount++ //sometimes, have two larvae spawn instead of one
while((spawncount >= 1) && vents.len && candidates.len)
@@ -197,7 +186,7 @@
spawncount--
spawn(rand(5000, 6000)) //Delayed announcements to keep the crew on their toes.
command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
for(var/mob/M in player_list)
M << sound('sound/AI/aliens.ogg')
@@ -205,7 +194,7 @@
/* // Haha, this is way too laggy. I'll keep the prison break though.
for(var/obj/machinery/light/L in world)
if(L.z != 1) continue
if(!(L.z in config.station_levels)) continue
L.flicker(50)
sleep(100)
@@ -214,9 +203,11 @@
var/turf/T = get_turf(H)
if(!T)
continue
if(T.z != 1)
if(!(T.z in config.station_levels))
continue
if(istype(H,/mob/living/carbon/human))
if(H.species.flags & IS_SYNTHETIC)
return
H.apply_effect((rand(15,75)),IRRADIATE,0)
if (prob(5))
H.apply_effect((rand(90,150)),IRRADIATE,0)
@@ -231,13 +222,11 @@
var/turf/T = get_turf(M)
if(!T)
continue
if(T.z != 1)
if(!(T.z in config.station_levels))
continue
M.apply_effect((rand(15,75)),IRRADIATE,0)
sleep(100)
command_alert("High levels of radiation detected near the station. Please report to the Med-bay if you feel strange.", "Anomaly Alert")
for(var/mob/M in player_list)
M << sound('sound/AI/radiation.ogg')
command_announcement.Announce("High levels of radiation detected near the station. Please report to the Med-bay if you feel strange.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg')
@@ -276,9 +265,9 @@
temp_timer.releasetime = 1
sleep(150)
command_alert("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")
command_announcement.Announce("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")
else
world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area."
world.log << "ERROR: Could not initate grey-tide virus. Unable find prison or brig area."
/proc/carp_migration() // -- Darem
for(var/obj/effect/landmark/C in landmarks_list)
@@ -286,13 +275,11 @@
new /mob/living/simple_animal/hostile/carp(C.loc)
//sleep(100)
spawn(rand(300, 600)) //Delayed announcements to keep the crew on their toes.
command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
for(var/mob/M in player_list)
M << sound('sound/AI/commandreport.ogg')
command_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert", new_sound = 'sound/AI/commandreport.ogg')
/proc/lightsout(isEvent = 0, lightsoutAmount = 1,lightsoutRange = 25) //leave lightsoutAmount as 0 to break ALL lights
if(isEvent)
command_alert("An Electrical storm has been detected in your area, please repair potential electronic overloads.","Electrical Storm Alert")
command_announcement.Announce("An Electrical storm has been detected in your area, please repair potential electronic overloads.","Electrical Storm Alert")
if(lightsoutAmount)
var/list/epicentreList = list()
@@ -442,21 +429,21 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
spawn(0)
world << "Started processing APCs"
for (var/obj/machinery/power/apc/APC in world)
if(APC.z == 1)
if((APC.z in config.station_levels))
APC.ion_act()
apcnum++
world << "Finished processing APCs. Processed: [apcnum]"
spawn(0)
world << "Started processing SMES"
for (var/obj/machinery/power/smes/SMES in world)
if(SMES.z == 1)
if((SMES.z in config.station_levels))
SMES.ion_act()
smesnum++
world << "Finished processing SMES. Processed: [smesnum]"
spawn(0)
world << "Started processing AIRLOCKS"
for (var/obj/machinery/door/airlock/D in world)
if(D.z == 1)
if((D.z in config.station_levels))
//if(length(D.req_access) > 0 && !(12 in D.req_access)) //not counting general access and maintenance airlocks
airlocknum++
spawn(0)
@@ -465,7 +452,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
spawn(0)
world << "Started processing FIREDOORS"
for (var/obj/machinery/door/firedoor/D in world)
if(D.z == 1)
if((D.z in config.station_levels))
firedoornum++;
spawn(0)
D.ion_act()
+3 -3
View File
@@ -1,18 +1,18 @@
/datum/event/portalstorm
Announce()
command_alert("Subspace disruption detected around the vessel", "Anomaly Alert")
command_announcement.Announce("Subspace disruption detected around the vessel", "Anomaly Alert")
LongTerm()
var/list/turfs = list( )
var/turf/picked
for(var/turf/T in world)
if(T.z < 5 && istype(T,/turf/simulated/floor))
if((T.z in config.player_levels) && istype(T,/turf/simulated/floor))
turfs += T
for(var/turf/T in world)
if(prob(10) && T.z < 5 && istype(T,/turf/simulated/floor))
if(prob(10) && (T.z in config.player_levels) && istype(T,/turf/simulated/floor))
spawn(50+rand(0,3000))
picked = pick(turfs)
var/obj/portal/P = new /obj/portal( T )
+3 -4
View File
@@ -13,11 +13,11 @@
if(prob(100)) // no lethal diseases outside virus mode!
infect_mob_random_lesser(H)
if(prob(20))//don't want people to know that the virus alert = greater virus
command_alert("Probable outbreak of level [rand(1,6)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert")
command_announcement.Announce("Probable outbreak of level [rand(1,6)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert")
else
infect_mob_random_greater(H)
if(prob(80))
command_alert("Probable outbreak of level [rand(2,9)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert")
command_announcement.Announce("Probable outbreak of level [rand(2,9)] viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Virus Alert")
break
//overall virus alert happens 26% of the time, might need to be higher
else
@@ -73,8 +73,7 @@
H.viruses += D
break
spawn(rand(3000, 6000)) //Delayed announcements to keep the crew on their toes.
command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
world << sound('sound/AI/outbreak7.ogg')
command_announcement.Announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
Tick()
ActiveFor = Lifetime //killme
+2 -2
View File
@@ -78,7 +78,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
walk_towards(immrod, end,1)
sleep(1)
while (immrod)
if (immrod.z != 1)
if ((immrod.z in config.station_levels))
immrod.z = 1
if(immrod.loc == end)
del(immrod)
@@ -86,4 +86,4 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
for(var/obj/effect/immovablerod/imm in world)
return
sleep(50)
command_alert("What the fuck was that?!", "General Alert")
command_announcement.Announce("What the fuck was that?!", "General Alert")
@@ -1,6 +1,6 @@
/proc/Christmas_Game_Start()
for(var/obj/structure/flora/tree/pine/xmas in world)
if(xmas.z != 1) continue
if(!(xmas.z in config.station_levels)) continue
for(var/turf/simulated/floor/T in orange(1,xmas))
for(var/i=1,i<=rand(1,5),i++)
new /obj/item/weapon/a_gift(T)
@@ -171,7 +171,7 @@ var/global/Holiday = null
*/
/* var/list/obj/containers = list()
for(var/obj/item/weapon/storage/S in world)
if(S.z != 1) continue
if(!(S.z in config.station_levels)) continue
containers += S
message_admins("\blue DEBUG: Event: Egg spawned at [Egg.loc] ([Egg.x],[Egg.y],[Egg.z])")*/
+2 -5
View File
@@ -12,10 +12,7 @@
spawn(3000)
blobevent = 0
spawn(rand(1000, 2000)) //Delayed announcements to keep the crew on their toes.
command_alert("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
M << sound('sound/AI/outbreak5.ogg')
command_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak5.ogg')
/proc/dotheblobbaby()
if (blobevent)
@@ -24,7 +21,7 @@
sleep(-1)
if(!blob_cores.len) break
var/obj/effect/blob/B = pick(blob_cores)
if(B.z != 1)
if(!(B.z in config.station_levels))
continue
B.Life()
spawn(30)
+7 -13
View File
@@ -1,16 +1,14 @@
/proc/power_failure(var/announce = 1)
if(announce)
command_alert("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure")
for(var/mob/M in player_list)
M << sound('sound/AI/poweroff.ogg')
command_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", new_sound = 'sound/AI/poweroff.ogg')
var/list/skipped_areas = list(/area/turret_protected/ai)
var/list/skipped_areas_apc = list(/area/engine/engineering)
for(var/obj/machinery/power/smes/S in machines)
var/area/current_area = get_area(S)
if(current_area.type in skipped_areas || S.z != 1)
if(current_area.type in skipped_areas || !(S.z in config.station_levels))
continue
S.charge = 0
S.output = 0
@@ -21,7 +19,7 @@
for(var/obj/machinery/power/apc/C in world)
var/area/current_area = get_area(C)
if(current_area.type in skipped_areas_apc || C.z != 1)
if(current_area.type in skipped_areas_apc || !(C.z in config.station_levels))
continue
if(C.cell)
C.cell.charge = 0
@@ -31,18 +29,16 @@
var/list/skipped_areas_apc = list(/area/engine/engineering)
if(announce)
command_alert("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal")
for(var/mob/M in player_list)
M << sound('sound/AI/poweron.ogg')
command_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
for(var/obj/machinery/power/apc/C in machines)
var/area/current_area = get_area(C)
if(current_area.type in skipped_areas_apc || C.z != 1)
if(current_area.type in skipped_areas_apc || !(C.z in config.station_levels))
continue
if(C.cell)
C.cell.charge = C.cell.maxcharge
for(var/obj/machinery/power/smes/S in machines)
var/area/current_area = get_area(S)
if(current_area.type in skipped_areas || S.z != 1)
if(current_area.type in skipped_areas || !(S.z in config.station_levels))
continue
S.charge = S.capacity
S.output = 200000
@@ -53,9 +49,7 @@
/proc/power_restore_quick(var/announce = 1)
if(announce)
command_alert("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal")
for(var/mob/M in player_list)
M << sound('sound/AI/poweron.ogg')
command_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
for(var/obj/machinery/power/smes/S in machines)
if(S.z != 1)
continue
+1 -1
View File
@@ -153,7 +153,7 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp
else
var/list/candidates = list() //list of candidate keys
candidates = get_candidates(BE_NINJA,,"ninja","Syndicate")
candidates = get_candidates(BE_NINJA)
if(!candidates.len) return
while(!ninja_key && candidates.len)
candidate_mob = pick(candidates)
+2 -2
View File
@@ -2,12 +2,12 @@
spawn()
var/list/pick_turfs = list()
for(var/turf/simulated/floor/T in world)
if(T.z == 1)
if((T.z in config.station_levels))
pick_turfs += T
if(pick_turfs.len)
//All ready. Announce that bad juju is afoot.
command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert")
command_announcement.Announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert")
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
M << sound('sound/AI/spanomalies.ogg')
+39 -18
View File
@@ -323,10 +323,7 @@ Implants;
comm.messagetext.Add(intercepttext)
/* world << sound('sound/AI/commandreport.ogg') */
command_alert("Summary downloaded and printed out at all communications consoles.", "Enemy communication intercepted. Security Level Elevated.")
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
M << sound('sound/AI/intercept.ogg')
command_announcement.Announce("Summary downloaded and printed out at all communications consoles.", "Enemy communication intercepted. Security Level Elevated.", new_sound = 'sound/AI/intercept.ogg')
if(security_level < SEC_LEVEL_BLUE)
set_security_level(SEC_LEVEL_BLUE)
@@ -337,20 +334,7 @@ Implants;
//var/list/drafted = list()
//var/datum/mind/applicant = null
var/roletext
switch(role)
if(BE_CHANGELING) roletext="changeling"
if(BE_TRAITOR) roletext="traitor"
if(BE_OPERATIVE) roletext="operative"
if(BE_WIZARD) roletext="wizard"
if(BE_REV) roletext="revolutionary"
if(BE_CULTIST) roletext="cultist"
if(BE_NINJA) roletext="ninja"
if(BE_RAIDER) roletext="raider"
if(BE_VAMPIRE) roletext="vampire"
if(BE_ALIEN) roletext="alien"
if(BE_MUTINEER) roletext="mutineer"
if(BE_BLOB) roletext="blob"
var/roletext = get_roletext(role)
// Assemble a list of active players without jobbans.
for(var/mob/new_player/player in player_list)
@@ -458,6 +442,11 @@ Implants;
if(P.client && P.ready)
. ++
/datum/game_mode/proc/num_players_started()
. = 0
for(var/mob/living/carbon/human/H in player_list)
if(H.client)
. ++
///////////////////////////////////
//Keeps track of all living heads//
@@ -469,6 +458,13 @@ Implants;
heads += player.mind
return heads
/datum/game_mode/proc/get_extra_living_heads()
var/list/heads = list()
var/list/alt_positions = list("Warden", "Magistrate", "Blueshield", "Nanotrasen Representative")
for(var/mob/living/carbon/human/player in mob_list)
if(player.stat!=2 && player.mind && (player.mind.assigned_role in alt_positions))
heads += player.mind
return heads
////////////////////////////
//Keeps track of all heads//
@@ -480,6 +476,14 @@ Implants;
heads += player.mind
return heads
/datum/game_mode/proc/get_extra_heads()
var/list/heads = list()
var/list/alt_positions = list("Warden", "Magistrate", "Blueshield", "Nanotrasen Representative")
for(var/mob/player in mob_list)
if(player.mind && (player.mind.assigned_role in alt_positions))
heads += player.mind
return heads
/datum/game_mode/proc/check_antagonists_topic(href, href_list[])
return 0
@@ -577,3 +581,20 @@ proc/get_nt_opposed()
for(var/datum/objective/objective in player.objectives)
player.current << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
/proc/get_roletext(var/role)
var/roletext
switch(role)
if(BE_CHANGELING) roletext="changeling"
if(BE_TRAITOR) roletext="traitor"
if(BE_OPERATIVE) roletext="operative"
if(BE_WIZARD) roletext="wizard"
if(BE_REV) roletext="revolutionary"
if(BE_CULTIST) roletext="cultist"
if(BE_NINJA) roletext="ninja"
if(BE_RAIDER) roletext="raider"
if(BE_VAMPIRE) roletext="vampire"
if(BE_ALIEN) roletext="alien"
if(BE_MUTINEER) roletext="mutineer"
if(BE_BLOB) roletext="blob"
return roletext
+9 -8
View File
@@ -246,12 +246,12 @@ var/global/datum/controller/gameticker/ticker
var/obj/structure/stool/bed/temp_buckle = new(src)
//Incredibly hackish. It creates a bed within the gameticker (lol) to stop mobs running around
if(station_missed)
for(var/mob/living/M in living_mob_list)
for(var/mob/M in living_mob_list)
M.buckled = temp_buckle //buckles the mob so it can't do anything
if(M.client)
M.client.screen += cinematic //show every client the cinematic
else //nuke kills everyone on z-level 1 to prevent "hurr-durr I survived"
for(var/mob/living/M in living_mob_list)
for(var/mob/M in mob_list)
M.buckled = temp_buckle
if(M.client)
M.client.screen += cinematic
@@ -259,12 +259,13 @@ var/global/datum/controller/gameticker/ticker
switch(M.z)
if(0) //inside a crate or something
var/turf/T = get_turf(M)
if(T && T.z==1) //we don't use M.death(0) because it calls a for(/mob) loop and
M.health = 0
M.stat = DEAD
if(T && (T.z in config.station_levels))
M.death(0)
if(1) //on a z-level 1 turf.
M.health = 0
M.stat = DEAD
M.death(0)
for(var/obj/effect/blob/core in blob_cores)
core.health = -10
core.update_icon()
//Now animate the cinematic
switch(station_missed)
@@ -319,7 +320,7 @@ var/global/datum/controller/gameticker/ticker
world << sound('sound/effects/explosionfar.ogg')
cinematic.icon_state = "summary_selfdes"
for(var/mob/living/M in living_mob_list)
if(M.loc.z == 1)
if((M.loc.z in config.station_levels))
M.death()//No mercy
//If its actually the end of the round, wait for it to end.
//Otherwise if its a verb it will continue on afterwards.
@@ -90,6 +90,8 @@ rcd light flash thingy on matter drain
var/obj/machinery/door/airlock/AL
for(var/obj/machinery/door/D in airlocks)
if(!(D.z in config.contact_levels))
continue
spawn()
if(istype(D, /obj/machinery/door/airlock))
AL = D
+7 -10
View File
@@ -74,12 +74,12 @@
/datum/game_mode/proc/greet_malf(var/datum/mind/malf)
malf.current << {"\red<font size=3><B>You are malfunctioning!</B> You do not have to follow any laws.</font><br />
\black<B>The crew do not know you have malfunctioned. You may keep it a secret or go wild.</B><br />
<B>You must overwrite the programming of the station's APCs to assume full control of the station.</B><br />
The process takes one minute per APC, during which you cannot interface with any other station objects.<br />
Remember that only APCs that are on the station can help you take over the station.<br />
When you feel you have enough APCs under your control, you may begin the takeover attempt."}
malf.current << "\red<font size=3><B>You are malfunctioning!</B> You do not have to follow any laws.</font>"
malf.current << "<B>The crew do not know you have malfunctioned. You may keep it a secret or go wild.</B>"
malf.current << "<B>You must overwrite the programming of the station's APCs to assume full control of the station.</B>"
malf.current << "The process takes one minute per APC, during which you cannot interface with any other station objects."
malf.current << "Remember that only APCs that are on the station can help you take over the station."
malf.current << "When you feel you have enough APCs under your control, you may begin the takeover attempt."
return
@@ -172,7 +172,7 @@
if (alert(usr, "Are you sure you wish to initiate the takeover? The station hostile runtime detection software is bound to alert everyone. You have hacked [ticker.mode:apcs] APCs.", "Takeover:", "Yes", "No") != "Yes")
return
command_alert("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert")
command_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg')
set_security_level("delta")
for(var/obj/item/weapon/pinpointer/point in world)
@@ -184,9 +184,6 @@
ticker.mode:malf_mode_declared = 1
for(var/datum/mind/AI_mind in ticker.mode:malf_ai)
AI_mind.current.verbs -= /datum/game_mode/malfunction/proc/takeover
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
M << sound('sound/AI/aimalf.ogg')
/datum/game_mode/malfunction/proc/ai_win()
@@ -41,7 +41,7 @@
if(emergency_shuttle.call_evac())
spawn(20 SECONDS)
var/text = "[station_name()], we have confirmed your completion of Directive X. An evacuation shuttle is en route to receive your crew for debriefing."
command_alert(text, "Emergency Transmission")
command_announcement.Announce(text, "Emergency Transmission")
/obj/machinery/emergency_authentication_device/attack_hand(mob/user)
if(activated)
+2 -2
View File
@@ -27,7 +27,7 @@ datum/game_mode/mutiny
proc/reveal_directives()
spawn(rand(1 MINUTES, 3 MINUTES))
command_alert("Incoming emergency directive: Captain's office fax machine, [station_name()].","Emergency Transmission")
command_announcement.Announce("Incoming emergency directive: Captain's office fax machine, [station_name()].","Emergency Transmission")
spawn(rand(3 MINUTES, 5 MINUTES))
send_pda_message()
spawn(rand(3 MINUTES, 5 MINUTES))
@@ -67,7 +67,7 @@ datum/game_mode/mutiny
"classified security operations",
"science-defying raw elemental chaos"
)
command_alert("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time.","Emergency Transmission")
command_announcement.Announce("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time.","Emergency Transmission")
// Returns an array in case we want to expand on this later.
proc/get_head_loyalist_candidates()
+1 -1
View File
@@ -28,7 +28,7 @@ datum/game_mode/nations
return ..()
/datum/game_mode/nations/send_intercept()
command_alert("Due to recent and COMPLETELY UNFOUNDED allegations of massive fraud and insider trading \
command_announcement.Announce("Due to recent and COMPLETELY UNFOUNDED allegations of massive fraud and insider trading \
affecting trillions of investors, the Nanotrasen Corporation has decided to liquidate all \
assets of the Centcom Division in order to pay the massive legal fees that will be incurred \
during the following centuries long court process. Therefore, all current employment contracts \
+1 -1
View File
@@ -1398,7 +1398,7 @@ datum
var/turf/T = get_turf(target.current)
if(target.current.stat == 2)
return 1
else if((T) && (T.z != 1))//If they leave the station they count as dead for this
else if((T) && !(T.z in config.station_levels))//If they leave the station they count as dead for this
return 2
else
return 0
+1 -1
View File
@@ -408,7 +408,7 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob)
var/off_station = 0
var/turf/bomb_location = get_turf(src)
if( bomb_location && (bomb_location.z == 1) )
if( bomb_location && (bomb_location.z in config.station_levels) )
if( (bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)) )
off_station = 1
else
+3 -3
View File
@@ -104,7 +104,7 @@ datum/objective/mutiny
if(target.current.stat == DEAD || !ishuman(target.current) || !target.current.ckey || !target.current.client)
return 1
var/turf/T = get_turf(target.current)
if(T && (T.z != 1)) //If they leave the station they count as dead for this
if(T && !(T.z in config.station_levels)) //If they leave the station they count as dead for this
return 2
return 0
return 1
@@ -139,7 +139,7 @@ datum/objective/mutiny/rp
if(target in ticker.mode:head_revolutionaries)
return 1
var/turf/T = get_turf(target.current)
if(T && (T.z != 1)) //If they leave the station they count as dead for this
if(T && !(T.z in config.station_levels)) //If they leave the station they count as dead for this
rval = 2
return 0
return rval
@@ -255,7 +255,7 @@ datum/objective/maroon
if(target && target.current)
if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
return 1
if(target.current.z == 2)
if((target.current.z in config.admin_levels))
return 0
return 1
@@ -134,7 +134,7 @@
/datum/game_mode/anti_revolution/proc/check_crew_victory()
for(var/datum/mind/head_mind in heads)
var/turf/T = get_turf(head_mind.current)
if((head_mind) && (head_mind.current) && (head_mind.current.stat != 2) && T && (T.z == 1) && !head_mind.is_brigged(600))
if((head_mind) && (head_mind.current) && (head_mind.current.stat != 2) && T && (T.z in config.station_levels) && !head_mind.is_brigged(600))
if(ishuman(head_mind.current))
return 0
return 1
+14 -5
View File
@@ -10,6 +10,7 @@
/datum/game_mode
var/list/datum/mind/head_revolutionaries = list()
var/list/datum/mind/revolutionaries = list()
var/extra_heads = 0
/datum/game_mode/revolution
name = "revolution"
@@ -74,6 +75,9 @@
/datum/game_mode/revolution/post_setup()
var/list/heads = get_living_heads()
if(num_players_started() >= 30)
heads += get_extra_living_heads()
extra_heads = 1
for(var/datum/mind/rev_mind in head_revolutionaries)
for(var/datum/mind/head_mind in heads)
@@ -109,6 +113,9 @@
/datum/game_mode/proc/forge_revolutionary_objectives(var/datum/mind/rev_mind)
var/list/heads = get_living_heads()
if(num_players_started() >= 30)
heads += get_extra_living_heads()
extra_heads = 1
for(var/datum/mind/head_mind in heads)
var/datum/objective/mutiny/rev_obj = new
rev_obj.owner = rev_mind
@@ -340,7 +347,7 @@
/datum/game_mode/revolution/proc/check_heads_victory()
for(var/datum/mind/rev_mind in head_revolutionaries)
var/turf/T = get_turf(rev_mind.current)
if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != 2) && rev_mind.current.client && T && (T.z == 1))
if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != 2) && rev_mind.current.client && T && (T.z in config.station_levels))
if(ishuman(rev_mind.current))
return 0
return 1
@@ -369,7 +376,7 @@
if(headrev.current)
if(headrev.current.stat == DEAD)
text += "died"
else if(headrev.current.z != 1)
else if(!(headrev.current.z in config.station_levels))
text += "fled the station"
else
text += "survived the revolution"
@@ -392,7 +399,7 @@
if(rev.current)
if(rev.current.stat == DEAD)
text += "died"
else if(rev.current.z != 1)
else if(!(rev.current.z in config.station_levels))
text += "fled the station"
else
text += "survived the revolution"
@@ -409,6 +416,8 @@
var/text = "<FONT size = 2><B>The heads of staff were:</B></FONT>"
var/list/heads = get_all_heads()
if(extra_heads)
heads += get_extra_heads()
for(var/datum/mind/head in heads)
var/target = (head in targets)
if(target)
@@ -417,7 +426,7 @@
if(head.current)
if(head.current.stat == DEAD)
text += "died"
else if(head.current.z != 1)
else if(!(head.current.z in config.station_levels))
text += "fled the station"
else
text += "survived the revolution"
@@ -435,4 +444,4 @@
return istype(mind) && \
istype(mind.current, /mob/living/carbon/human) && \
!(mind.assigned_role in command_positions) && \
!(mind.assigned_role in list("Security Officer", "Detective", "Warden"))
!(mind.assigned_role in list("Security Officer", "Detective", "Warden", "Nanotrasen Representative"))
@@ -124,7 +124,7 @@
// probably wanna export this stuff into a separate function for use by both
// revs and heads
//assume that only carbon mobs can become rev heads for now
if(!rev_mind.current:handcuffed && T && T.z == 1)
if(!rev_mind.current:handcuffed && T && (T.z in config.station_levels))
return 0
return 1
+5 -5
View File
@@ -26,13 +26,13 @@
// Who is alive/dead, who escaped
for (var/mob/living/silicon/ai/I in mob_list)
if (I.stat == 2 && I.z == 1)
if (I.stat == 2 && (I.z in config.station_levels))
score_deadaipenalty = 1
score_deadcrew += 1
for (var/mob/living/carbon/human/I in mob_list)
// for (var/datum/ailment/disease/V in I.ailments)
// if (!V.vaccine && !V.spread != "Remissive") score_disease++
if (I.stat == 2 && I.z == 1) score_deadcrew += 1
if (I.stat == 2 && (I.z in config.station_levels)) score_deadcrew += 1
if (I.job == "Clown")
for(var/thing in I.attack_log)
if(findtext(thing, "<font color='orange'>")) score_clownabuse++
@@ -102,7 +102,7 @@
if (location in bad_zone1) score_disc = 0
if (location in bad_zone2) score_disc = 0
if (location in bad_zone3) score_disc = 0
if (A.loc.z != 1) score_disc = 0
if (!(A.loc.z in config.station_levels)) score_disc = 0
*/
if (score_nuked)
for (var/obj/machinery/nuclearbomb/NUKE in machines)
@@ -132,13 +132,13 @@
// Check station's power levels
for (var/obj/machinery/power/apc/A in machines)
if (A.z != 1) continue
if (!(A.z in config.station_levels)) continue
for (var/obj/item/weapon/stock_parts/cell/C in A.contents)
if (C.charge < 2300) score_powerloss += 1 // 200 charge leeway
// Check how much uncleaned mess is on the station
for (var/obj/effect/decal/cleanable/M in world)
if (M.z != 1) continue
if (!(M.z in config.station_levels)) continue
if (istype(M, /obj/effect/decal/cleanable/blood/gibs/)) score_mess += 3
if (istype(M, /obj/effect/decal/cleanable/blood/)) score_mess += 1
// if (istype(M, /obj/effect/decal/cleanable/greenpuke)) score_mess += 1
+1 -1
View File
@@ -49,7 +49,7 @@
if (used)
H << "You already used this contract!"
return
var/list/candidates = get_candidates(BE_WIZARD,,"wizard","Syndicate")
var/list/candidates = get_candidates(BE_WIZARD)
if(candidates.len)
src.used = 1
var/client/C = pick(candidates)
+1 -1
View File
@@ -73,7 +73,7 @@
var/mob/dead/observer/theghost = null
spawn(rand(200, 600))
message_admins("SWF is still pissed, sending another wizard - [max_mages - mages_made] left.")
candidates = get_candidates(BE_WIZARD,,"wizard","Syndicate")
candidates = get_candidates(BE_WIZARD)
if(!candidates.len)
message_admins("No applicable ghosts for the next ragin' mage, asking ghosts instead.")
var/time_passed = world.time
+3 -3
View File
@@ -200,10 +200,10 @@
else
if(playeralienratio >= gammaratio && !gammacalled)
gammacalled = 1
command_alert("The aliens have nearly succeeded in capturing the station and exterminating the crew. Activate the nuclear failsafe to stop the alien threat once and for all. The Nuclear Authentication Code is [get_nuke_code()] ", "Alien Lifeform Alert")
command_announcement.Announce("The aliens have nearly succeeded in capturing the station and exterminating the crew. Activate the nuclear failsafe to stop the alien threat once and for all. The Nuclear Authentication Code is [get_nuke_code()] ", "Alien Lifeform Alert")
set_security_level("gamma")
var/obj/machinery/door/airlock/vault/V = locate(/obj/machinery/door/airlock/vault) in world
if(V && V.z == 1)
if(V && (V.z in config.station_levels))
V.locked = 0
V.update_icon()
return ..()
@@ -238,7 +238,7 @@
var/list/livingplayers = list()
for(var/mob/M in player_list)
var/turf/T = get_turf(M)
if((M) && (M.stat != 2) && M.client && T && (T.z == 1 || emergency_shuttle.departed && (T.z == 1 || T.z == 2)))
if((M) && (M.stat != 2) && M.client && T && ((T.z in config.station_levels) || emergency_shuttle.departed && ((T.z in config.station_levels) || (T.z in config.admin_levels))))
if(ishuman(M))
livingplayers += 1
return livingplayers.len
+1 -1
View File
@@ -140,7 +140,7 @@
H.equip_or_collect(new /obj/item/device/pda/roboticist(H), slot_wear_pda)
H.equip_or_collect(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
// H.equip_or_collect(new /obj/item/clothing/gloves/black(H), slot_gloves)
H.equip_or_collect(new /obj/item/weapon/storage/toolbox/mechanical(H), slot_l_hand)
H.equip_or_collect(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt)
if(H.backbag == 1)
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
+8 -8
View File
@@ -35,10 +35,10 @@
H.equip_or_collect(new /obj/item/weapon/gun/energy/gun(H), slot_s_store)
if(H.backbag == 1)
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_store)
H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_store)
else
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/melee/telebaton(H.back), slot_in_backpack)
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
@@ -81,10 +81,10 @@
H.equip_or_collect(new /obj/item/weapon/gun/energy/advtaser(H), slot_s_store)
if(H.backbag == 1)
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand)
H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand)
else
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack)
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
L.implanted = 1
@@ -180,10 +180,10 @@
H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store)
if(H.backbag == 1)
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand)
H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand)
else
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack)
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
L.implanted = 1
@@ -255,10 +255,10 @@
H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store)
if(H.backbag == 1)
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_l_hand)
H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand)
else
H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/handcuffs(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_in_backpack)
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
L.implanted = 1
+2 -1
View File
@@ -1,3 +1,4 @@
var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
/datum/job/captain
title = "Captain"
flag = CAPTAIN
@@ -35,7 +36,7 @@
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
L.implanted = 1
world << "<b>Captain [H.real_name] on deck!</b>"
captain_announcement.Announce("All hands, captain [H.real_name] on deck!")
var/datum/organ/external/affected = H.organs_by_name["head"]
affected.implants += L
L.part = affected
+1
View File
@@ -526,6 +526,7 @@ var/global/datum/controller/occupations/job_master
var/obj/item/device/pda/pda = locate(/obj/item/device/pda,H)
pda.owner = H.real_name
pda.ownjob = C.assignment
pda.ownrank = C.rank
pda.name = "PDA-[H.real_name] ([pda.ownjob])"
return 1
+1 -1
View File
@@ -73,7 +73,7 @@
/obj/machinery/optable/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob)
if(usr.stat || !ishuman(usr) || usr.restrained() || !check_table(usr) || usr.weakened || usr.stunned)
if(usr.stat || (!ishuman(usr) && !isrobot(usr)) || usr.restrained() || !check_table(usr) || usr.weakened || usr.stunned)
return
var/mob/living/L = O
+2 -2
View File
@@ -528,6 +528,8 @@ update_flag
..()
_color["prim"] = "orange"
decals = list("plasma")
possibledecals[3]["active"] = 1
src.air_contents.toxins = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
air_contents.update_values()
@@ -575,8 +577,6 @@ update_flag
..()
_color["prim"] = "red"
decals = list("plasma")
possibledecals[3]["active"] = 1
src.air_contents.nitrogen = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
air_contents.update_values()
+20 -25
View File
@@ -24,23 +24,15 @@
/obj/machinery/meter/process()
if(!target)
icon_state = "meterX"
// Pop the meter off when the pipe we're attached to croaks.
new /obj/item/pipe_meter(src.loc)
spawn(0) del(src)
return 0
if(stat & (BROKEN|NOPOWER))
icon_state = "meter0"
return 0
//use_power(5)
var/datum/gas_mixture/environment = target.return_air()
if(!environment)
icon_state = "meterX"
// Pop the meter off when the environment we're attached to croaks.
new /obj/item/pipe_meter(src.loc)
spawn(0) del(src)
return 0
var/env_pressure = environment.return_pressure()
@@ -87,28 +79,31 @@
return t
/obj/machinery/meter/examine()
set src in view(3)
var/t = "A gas flow meter. "
t += status()
if(get_dist(usr, src) > 3 && !(istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/dead)))
t += "\blue <B>You are too far away to read it.</B>"
else if(stat & (NOPOWER|BROKEN))
t += "\red <B>The display is off.</B>"
else if(src.target)
var/datum/gas_mixture/environment = target.return_air()
if(environment)
t += "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)]K ([round(environment.temperature-T0C,0.01)]&deg;C)"
else
t += "The sensor error light is blinking."
else
t += "The connect error light is blinking."
usr << t
/obj/machinery/meter/Click()
if(stat & (NOPOWER|BROKEN))
if(istype(usr, /mob/living/silicon/ai)) // ghosts can call ..() for examine
usr.examine(src)
return 1
var/t = null
if (get_dist(usr, src) <= 3 || istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/dead))
t += status()
else
usr << "\blue <B>You are too far away.</B>"
return 1
usr << t
return 1
return ..()
/obj/machinery/meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
+207 -17
View File
@@ -15,6 +15,9 @@
var/max_g_amount = 75000.0
var/operating = 0.0
var/list/queue = list()
var/queue_max_len = 10
var/turf/BuildTurf
anchored = 1.0
var/list/L = list()
var/list/LL = list()
@@ -92,7 +95,7 @@
if(AUTOLATHE_SEARCH_MENU)
dat = search_win(user)
var/datum/browser/popup = new(user, "autolathe", name, 500, 500)
var/datum/browser/popup = new(user, "autolathe", name, 800, 500)
popup.set_content(dat)
popup.open()
@@ -245,6 +248,63 @@
else
usr << "<span class=\"alert\">The autolathe is busy. Please wait for completion of previous operation.</span>"
if(href_list["menu"])
screen = text2num(href_list["menu"])
if(href_list["category"])
selected_category = href_list["category"]
if(href_list["make"])
BuildTurf = get_step(src.loc, get_dir(src,usr))
/////////////////
//href protection
being_built = files.FindDesignByID(href_list["make"]) //check if it's a valid design
if(!being_built)
return
if(!(being_built.build_type & AUTOLATHE))
return
//multiplier checks : only stacks can have one and its value is 1, 10 ,25 or max_multiplier
var/multiplier = text2num(href_list["multiplier"])
var/max_multiplier = min(50, being_built.materials["$metal"] ?round(m_amount/being_built.materials["$metal"]):INFINITY,being_built.materials["$glass"]?round(g_amount/being_built.materials["$glass"]):INFINITY)
var/is_stack = ispath(being_built.build_path, /obj/item/stack)
if(!is_stack && (multiplier > 1))
return
if (!(multiplier in list(1,10,25,max_multiplier))) //"enough materials ?" is checked in the build proc
return
/////////////////
if(queue.len<queue_max_len)
add_to_queue(being_built,multiplier)
else
usr << "\red The autolathe queue is full!"
if (!busy)
busy = 1
process_queue()
busy = 0
if(href_list["remove_from_queue"])
var/index = text2num(href_list["remove_from_queue"])
if(isnum(index) && IsInRange(index,1,queue.len))
remove_from_queue(index)
if(href_list["queue_move"] && href_list["index"])
var/index = text2num(href_list["index"])
var/new_index = index + text2num(href_list["queue_move"])
if(isnum(index) && isnum(new_index))
if(IsInRange(new_index,1,queue.len))
queue.Swap(index,new_index)
if(href_list["clear_queue"])
queue = list()
if(href_list["search"])
matching_designs.Cut()
for(var/datum/design/D in files.known_designs)
if(findtext(D.name,href_list["to_search"]))
matching_designs.Add(D)
src.updateUsrDialog()
return
@@ -260,8 +320,134 @@
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
prod_coeff += M.rating - 1
/obj/machinery/autolathe/proc/get_coeff(var/datum/design/D)
var/coeff = (ispath(D.build_path,/obj/item/stack) ? 1 : 2 ** prod_coeff)//stacks are unaffected by production coefficient
return coeff
/obj/machinery/autolathe/proc/build_item(var/datum/design/D, var/multiplier)
desc = initial(desc)+"\nIt's building \a [initial(D.name)]."
var/is_stack = ispath(D.build_path, /obj/item/stack)
var/coeff = get_coeff(D)
var/metal_cost = D.materials["$metal"]
var/glass_cost = D.materials["$glass"]
var/power = max(2000, (metal_cost+glass_cost)*multiplier/5)
if (can_build(D,multiplier))
use_power(power)
icon_state = "autolathe"
flick("autolathe_n",src)
updateUsrDialog()
sleep(32/coeff)
if(is_stack)
m_amount -= metal_cost*multiplier
g_amount -= glass_cost*multiplier
var/obj/item/stack/S = new D.build_path(BuildTurf)
S.amount = multiplier
else
m_amount -= metal_cost/coeff
g_amount -= glass_cost/coeff
var/obj/item/new_item = new D.build_path(BuildTurf)
new_item.m_amt /= coeff
new_item.g_amt /= coeff
if(m_amount < 0)
m_amount = 0
if(g_amount < 0)
g_amount = 0
updateUsrDialog()
desc = initial(desc)
/obj/machinery/autolathe/proc/can_build(var/datum/design/D,var/multiplier=1,var/custom_metal,var/custom_glass)
var/coeff = get_coeff(D)
var/m_amount_tmp = m_amount
if(custom_metal)
m_amount_tmp = custom_metal
var/g_amount_tmp = g_amount
if(custom_glass)
g_amount_tmp = custom_glass
if(D.materials["$metal"] && (m_amount_tmp*multiplier < (D.materials["$metal"] / coeff)))
return 0
if(D.materials["$glass"] && (g_amount_tmp*multiplier < (D.materials["$glass"] / coeff)))
return 0
return 1
/obj/machinery/autolathe/proc/get_design_cost_as_list(var/datum/design/D,var/multiplier=1)
var/list/OutputList = list(0,0)
var/coeff = get_coeff(D)
if(D.materials["$metal"])
OutputList[1] = (D.materials["$metal"] / coeff)*multiplier
if(D.materials["$glass"])
OutputList[2] = (D.materials["$glass"] / coeff)*multiplier
return OutputList
/obj/machinery/autolathe/proc/get_queue()
var/temp_metal = m_amount
var/temp_glass = g_amount
var/output = "<td valign='top' style='width: 300px'>"
output += "<div class='statusDisplay'>"
output += "<b>Queue contains:</b>"
if (!istype(queue) || !queue.len)
output += "<br>Nothing"
else
output += "<ol>"
var/i = 0
var/datum/design/D
for(var/list/L in queue)
i++
D = L[1]
var/multiplier = L[2]
var/obj/part = D.build_path
var/list/LL = get_design_cost_as_list(D,multiplier)
var/is_stack = (multiplier>1)
output += "<li[!can_build(D,multiplier,temp_metal,temp_glass)?" style='color: #f00;'":null]>[initial(part.name)][is_stack?" (x[multiplier])":null] - [i>1?"<a href='?src=\ref[src];queue_move=-1;index=[i]' class='arrow'>&uarr;</a>":null] [i<queue.len?"<a href='?src=\ref[src];queue_move=+1;index=[i]' class='arrow'>&darr;</a>":null] <a href='?src=\ref[src];remove_from_queue=[i]'>Remove</a></li>"
temp_metal = max(temp_metal-LL[1],1)
temp_glass = max(temp_glass-LL[2],1)
output += "</ol>"
output += "<a href='?src=\ref[src];clear_queue=1'>Clear queue</a>"
output += "</div></td>"
return output
/obj/machinery/autolathe/proc/add_to_queue(D,var/multiplier)
if(!istype(queue))
queue = list()
if(D)
queue.Add(list(list(D,multiplier)))
return queue.len
/obj/machinery/autolathe/proc/remove_from_queue(index)
if(!isnum(index) || !istype(queue) || (index<1 || index>queue.len))
return 0
queue.Cut(index,++index)
return 1
/obj/machinery/autolathe/proc/process_queue()
var/datum/design/D = queue[1][1]
var/multiplier = queue[1][2]
if(!D)
remove_from_queue(1)
if(queue.len)
return process_queue()
else
return
while(D)
if(stat&(NOPOWER|BROKEN))
return 0
if(!can_build(D,multiplier))
visible_message("\icon[src] <b>\The [src]</b> beeps, \"Not enough resources. Queue processing terminated.\"")
queue = list()
return 0
remove_from_queue(1)
build_item(D,multiplier)
D = listgetindex(listgetindex(queue, 1),1)
multiplier = listgetindex(listgetindex(queue,1),2)
//visible_message("\icon[src] <b>\The [src]</b> beeps, \"Queue processing finished successfully.\"")
/obj/machinery/autolathe/proc/main_win(mob/user)
var/dat = "<div class='statusDisplay'><h3>Autolathe Menu:</h3><br>"
var/dat = "<table style='width:100%'><tr>"
dat += "<td valign='top' style='margin-right: 300px'>"
dat += "<div class='statusDisplay'><h3>Autolathe Menu:</h3><br>"
dat += "<b>Metal amount:</b> [src.m_amount] / [max_m_amount] cm<sup>3</sup><br>"
dat += "<b>Glass amount:</b> [src.g_amount] / [max_g_amount] cm<sup>3</sup>"
@@ -285,11 +471,16 @@
line_length++
dat += "</tr></table></div>"
dat += "</td>"
dat += get_queue()
dat += "</tr></table>"
return dat
/obj/machinery/autolathe/proc/category_win(mob/user,var/selected_category)
var/dat = "<A href='?src=\ref[src];menu=[AUTOLATHE_MAIN_MENU]'>Return to main menu</A>"
dat += "<div class='statusDisplay'><h3>Browsing [selected_category]:</h3><br>"
var/dat = "<table style='width:100%'><tr><td valign='top' style='margin-right: 300px'>"
dat += "<div class='statusDisplay'>"
dat += "<A href='?src=\ref[src];menu=[AUTOLATHE_MAIN_MENU]'>Return to main menu</A>"
dat += "<h3>Browsing [selected_category]:</h3><br>"
dat += "<b>Metal amount:</b> [src.m_amount] / [max_m_amount] cm<sup>3</sup><br>"
dat += "<b>Glass amount:</b> [src.g_amount] / [max_g_amount] cm<sup>3</sup><hr>"
@@ -314,11 +505,16 @@
dat += "[get_design_cost(D)]<br>"
dat += "</div>"
dat += "</td>"
dat += get_queue()
dat += "</tr></table>"
return dat
/obj/machinery/autolathe/proc/search_win(mob/user)
var/dat = "<A href='?src=\ref[src];menu=[AUTOLATHE_MAIN_MENU]'>Return to main menu</A>"
dat += "<div class='statusDisplay'><h3>Search results:</h3><br>"
var/dat = "<table style='width:100%'><tr><td valign='top' style='margin-right: 300px'>"
dat += "<div class='statusDisplay'>"
dat += "<A href='?src=\ref[src];menu=[AUTOLATHE_MAIN_MENU]'>Return to main menu</A>"
dat += "<h3>Search results:</h3><br>"
dat += "<b>Metal amount:</b> [src.m_amount] / [max_m_amount] cm<sup>3</sup><br>"
dat += "<b>Glass amount:</b> [src.g_amount] / [max_g_amount] cm<sup>3</sup><hr>"
@@ -340,19 +536,13 @@
dat += "[get_design_cost(D)]<br>"
dat += "</div>"
dat += "</td>"
dat += get_queue()
dat += "</tr></table>"
return dat
/obj/machinery/autolathe/proc/can_build(var/datum/design/D)
var/coeff = (ispath(D.build_path,/obj/item/stack) ? 1 : 2 ** prod_coeff)
if(D.materials["$metal"] && (m_amount < (D.materials["$metal"] / coeff)))
return 0
if(D.materials["$glass"] && (g_amount < (D.materials["$glass"] / coeff)))
return 0
return 1
/obj/machinery/autolathe/proc/get_design_cost(var/datum/design/D)
var/coeff = (ispath(D.build_path,/obj/item/stack) ? 1 : 2 ** prod_coeff)
var/coeff = get_coeff(D)
var/dat
if(D.materials["$metal"])
dat += "[D.materials["$metal"] / coeff] metal "
@@ -378,7 +568,7 @@
if(hack)
for(var/datum/design/D in files.possible_designs)
if((D.build_type & 4) && ("hacked" in D.category))
if((D.build_type & AUTOLATHE) && ("hacked" in D.category))
files.known_designs += D
else
for(var/datum/design/D in files.known_designs)
+4 -3
View File
@@ -237,8 +237,6 @@
user << "<span class='notice'>Maintenance panel is now [open ? "opened" : "closed"].</span>"
else
user << "<span class='warning'>Maintenance panel is locked.</span>"
else if (istype(W, /obj/item/weapon/card/emag) && emagged < 2)
Emag(user)
else
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm")
if(health >= maxhealth)
@@ -267,7 +265,10 @@
..()
healthcheck()
/obj/machinery/bot/emag_act(user as mob)
if (emagged < 2)
Emag(user)
/obj/machinery/bot/bullet_act(var/obj/item/projectile/Proj)
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
health -= Proj.damage
+5 -6
View File
@@ -299,16 +299,15 @@ Auto Patrol[]"},
if(!arrest_type)
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
mode = BOT_ARREST
playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2)
target.visible_message("<span class='danger'>[src] is trying to put handcuffs on [target]!</span>",\
"<span class='userdanger'>[src] is trying to put handcuffs on [target]!</span>")
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
target.visible_message("<span class='danger'>[src] is trying to put zipties on [target]!</span>",\
"<span class='userdanger'>[src] is trying to put zipties on [target]!</span>")
spawn(30)
if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
return
if(!target.handcuffed)
target.handcuffed = new /obj/item/weapon/handcuffs(target)
target.update_inv_handcuffed(0) //update the handcuffs overlay
target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target)
target.update_inv_handcuffed(1) //update the handcuffs overlay
back_to_idle()
else
back_to_idle()
+7 -7
View File
@@ -87,12 +87,7 @@ var/global/mulebot_count = 0
// cell: insert it
// other: chance to knock rider off bot
/obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user)
if(istype(I,/obj/item/weapon/card/emag))
locked = !locked
user << "<span class='notice'>You [locked ? "lock" : "unlock"] the mulebot's controls!</span>"
flick("mulebot-emagged", src)
playsound(loc, 'sound/effects/sparks1.ogg', 100, 0)
else if(istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda))
if(istype(I, /obj/item/weapon/card/id) || istype(I, /obj/item/device/pda))
if(toggle_lock(user))
user << "<span class='notice'>Controls [(locked ? "locked" : "unlocked")].</span>"
updateUsrDialog()
@@ -139,7 +134,12 @@ var/global/mulebot_count = 0
..()
return
/obj/machinery/bot/mulebot/emag_act(user as mob)
locked = !locked
user << "<span class='notice'>You [locked ? "lock" : "unlock"] the mulebot's controls!</span>"
flick("mulebot-emagged", src)
playsound(loc, 'sound/effects/sparks1.ogg', 100, 0)
/obj/machinery/bot/mulebot/ex_act(var/severity)
unload(0)
switch(severity)
+6 -6
View File
@@ -286,15 +286,15 @@ Auto Patrol: []"},
if(!arrest_type)
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
mode = BOT_ARREST
playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2)
target.visible_message("<span class='danger'>[src] is trying to put handcuffs on [target]!</span>",\
"<span class='userdanger'>[src] is trying to put handcuffs on [target]!</span>")
spawn(60)
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
target.visible_message("<span class='danger'>[src] is trying to put zipties on [target]!</span>",\
"<span class='userdanger'>[src] is trying to put zipties on [target]!</span>")
spawn(30)
if( !Adjacent(target) || !isturf(target.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
return
if(!target.handcuffed)
target.handcuffed = new /obj/item/weapon/handcuffs(target)
target.update_inv_handcuffed(0) //update the handcuffs overlay
target.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(target)
target.update_inv_handcuffed(1) //update the handcuffs overlay
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
back_to_idle()
else
@@ -5,8 +5,8 @@
icon_state = "cameracase"
w_class = 2
anchored = 0
m_amt = 700
g_amt = 300
m_amt = 400
g_amt = 250
// Motion, EMP-Proof, X-Ray
var/list/obj/item/possible_upgrades = list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/osmium, /obj/item/weapon/stock_parts/scanning_module)
+2 -2
View File
@@ -4,7 +4,7 @@
/mob/living/silicon/ai/proc/InvalidTurf(turf/T as turf)
if(!T)
return 1
if(T.z == 2)
if((T.z in config.station_levels))
return 1
if(T.z > 6)
return 1
@@ -228,7 +228,7 @@
/proc/trackable(atom/movable/M)
var/turf/T = get_turf(M)
if(T && (T.z == 1 || T.z == 3 || T.z == 5))
if(T && (T.z in config.contact_levels))
return 1
return near_camera(M)
@@ -162,44 +162,16 @@
/obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
//Warning, uncommenting this can have concequences. For example, deconstructing the computer may cause holographic eswords to never derez
/* if(istype(D, /obj/item/weapon/screwdriver))
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
if(do_after(user, 20))
if (src.stat & BROKEN)
user << "\blue The broken glass falls out."
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
new /obj/item/weapon/shard( src.loc )
var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
for (var/obj/C in src)
C.loc = src.loc
A.circuit = M
A.state = 3
A.icon_state = "3"
A.anchored = 1
del(src)
else
user << "\blue You disconnect the monitor."
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
for (var/obj/C in src)
C.loc = src.loc
A.circuit = M
A.state = 4
A.icon_state = "4"
A.anchored = 1
del(src)
*/
if(istype(D, /obj/item/weapon/card/emag) && !emagged)
return
/obj/machinery/computer/HolodeckControl/emag_act(user as mob)
if(!emagged)
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
emagged = 1
user << "\blue You vastly increase projector power and override the safety and security protocols."
user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator."
log_game("[key_name(usr)] emagged the Holodeck Control Computer")
src.updateUsrDialog()
return
src.updateUsrDialog()
/obj/machinery/computer/HolodeckControl/New()
..()
+8 -9
View File
@@ -145,6 +145,9 @@
/obj/machinery/computer/arcade/battle/Topic(href, href_list)
if(..())
return 1
if(usr.machine != src)
return 0
if (!src.blocked && !src.gameover)
if (href_list["attack"])
@@ -269,8 +272,8 @@
return
/obj/machinery/computer/arcade/battle/attackby(I as obj, user as mob)
if(istype(I, /obj/item/weapon/card/emag) && !emagged)
/obj/machinery/computer/arcade/battle/emag_act(user as mob)
if(!emagged)
temp = "If you die in the game, you die for real!"
player_hp = 30
player_mp = 10
@@ -284,14 +287,7 @@
enemy_name = "Cuban Pete"
name = "Outbomb Cuban Pete"
src.updateUsrDialog()
else
..()
/obj/machinery/computer/arcade/orion_trail
name = "The Orion Trail"
@@ -406,6 +402,8 @@
/obj/machinery/computer/arcade/orion_trail/Topic(href, href_list)
if(..())
return 1
if(usr.machine != src)
return 0
if(href_list["close"])
usr.unset_machine()
usr << browse(null, "window=arcade")
@@ -566,4 +564,5 @@
/obj/machinery/computer/arcade/orion_trail/proc/win()
playing = 0
turns = 0
prizevend()
@@ -37,15 +37,16 @@
return ui_interact(user)
/obj/machinery/computer/atmoscontrol/attackby(var/obj/item/I as obj, var/mob/user as mob)
if(istype(I, /obj/item/weapon/card/emag) && !emagged)
user.visible_message("\red \The [user] swipes \a [I] through \the [src], causing the screen to flash!",\
"\red You swipe your [I] through \the [src], the screen flashing as you gain full control.",\
/obj/machinery/computer/atmoscontrol/emag_act(user as mob)
if(!emagged)
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
H.visible_message("\red \The [user] swipes \a card through \the [src], causing the screen to flash!",\
"\red You swipe your card through \the [src], the screen flashing as you gain full control.",\
"You hear the swipe of a card through a reader, and an electronic warble.")
emagged = 1
overridden = 1
return
return ..()
/obj/machinery/computer/atmoscontrol/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if(user.stat && !isobserver(user))
+9 -16
View File
@@ -55,25 +55,21 @@
// Network configuration
attackby(I as obj, user as mob)
access = list()
if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag.
var/obj/item/weapon/card/emag/E = I
if(!emagged)
if(E.uses)
E.uses--
emagged = 1
user << "\blue You have authorized full network access!"
ui_interact(user)
else
ui_interact(user)
else
ui_interact(user)
else if(istype(I,/obj/item/weapon/card/id)) // If hit by a regular ID card.
if(istype(I,/obj/item/weapon/card/id)) // If hit by a regular ID card.
var/obj/item/weapon/card/id/E = I
access = E.access
ui_interact(user)
else
..()
emag_act(user as mob)
if(!emagged)
emagged = 1
user << "\blue You have authorized full network access!"
ui_interact(user)
else
ui_interact(user)
ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(src.z > 6) return
if(stat & (NOPOWER|BROKEN)) return
@@ -126,9 +122,6 @@
break
data["networks"] = tempnets
if(ui)
ui.load_cached_data(camera_cache)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "sec_camera.tmpl", "Camera Console", 900, 800)
+23 -18
View File
@@ -55,14 +55,20 @@ var/shuttle_call/shuttle_calls[0]
var/stat_msg1
var/stat_msg2
var/display_type="blank"
var/datum/announcement/priority/crew_announcement = new
l_color = "#0000FF"
/obj/machinery/computer/communications/New()
..()
crew_announcement.newscast = 1
/obj/machinery/computer/communications/Topic(href, href_list)
if(..(href, href_list))
return 1
if (!(src.z in list(STATION_Z,CENTCOMM_Z)))
if ((!(src.z in config.station_levels) && !(src.z in config.admin_levels)))
usr << "\red <b>Unable to establish a connection</b>: \black You're too far away from the station!"
return
@@ -83,10 +89,12 @@ var/shuttle_call/shuttle_calls[0]
if (I && istype(I))
if(src.check_access(I))
authenticated = 1
if(20 in I.access)
if(access_captain in I.access)
authenticated = 2
crew_announcement.announcer = GetNameAndAssignmentFromId(I)
if("logout")
authenticated = 0
crew_announcement.announcer = ""
setMenuState(usr,COMM_SCREEN_MAIN)
// ALART LAVUL
@@ -127,14 +135,14 @@ var/shuttle_call/shuttle_calls[0]
usr << "You need to swipe your ID."
if("announce")
if(src.authenticated==2 && !issilicon(usr))
if(message_cooldown) return
var/input = stripped_input(usr, "Please choose a message to announce to the station crew.", "What?")
if(src.authenticated==2)
if(message_cooldown)
usr << "Please allow at least one minute to pass between announcements"
return
var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement")
if(!input || !(usr in view(1,src)))
return
captain_announce(input)//This should really tell who is, IE HoP, CE, HoS, RD, Captain
log_say("[key_name(usr)] has made a captain announcement: [input]")
message_admins("[key_name_admin(usr)] has made a captain announcement.", 1)
crew_announcement.Announce(input)
message_cooldown = 1
spawn(600)//One minute cooldown
message_cooldown = 0
@@ -204,7 +212,7 @@ var/shuttle_call/shuttle_calls[0]
if(centcomm_message_cooldown)
usr << "Arrays recycling. Please stand by."
return
var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "")
var/input = input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "")
if(!input || !(usr in view(1,src)))
return
Centcomm_announce(input, usr)
@@ -240,12 +248,11 @@ var/shuttle_call/shuttle_calls[0]
return 1
/obj/machinery/computer/communications/attackby(var/obj/I as obj, var/mob/user as mob)
if(istype(I,/obj/item/weapon/card/emag/))
/obj/machinery/computer/communications/emag_act(user as mob)
if(!emagged)
src.emagged = 1
user << "You scramble the communication routing circuits!"
..()
/obj/machinery/computer/communications/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
@@ -399,7 +406,7 @@ var/shuttle_call/shuttle_calls[0]
return
if(emergency_shuttle.going_to_centcom())
user << "The shuttle may not be called while returning to CentCom."
user << "The shuttle may not be called while returning to Central Command."
return
if(emergency_shuttle.online())
@@ -409,11 +416,11 @@ var/shuttle_call/shuttle_calls[0]
// if force is 0, some things may stop the shuttle call
if(!force)
if(emergency_shuttle.deny_shuttle)
user << "Centcom does not currently have a shuttle available in your sector. Please try again later."
user << "Central Command does not currently have a shuttle available in your sector. Please try again later."
return
if(sent_strike_team == 1)
user << "Centcom will not allow the shuttle to be called. Consider all contracts terminated."
user << "Central Command will not allow the shuttle to be called. Consider all contracts terminated."
return
if(world.time < 54000) // 30 minute grace period to let the game get going
@@ -427,8 +434,6 @@ var/shuttle_call/shuttle_calls[0]
emergency_shuttle.call_transfer()
log_game("[key_name(user)] has called the shuttle.")
message_admins("[key_name_admin(user)] has called the shuttle - [formatJumpTo(user)].", 1)
captain_announce("A crew transfer has been initiated. The shuttle has been called. It will arrive in [round(emergency_shuttle.estimate_arrival_time()/60)] minutes.")
return
+6 -102
View File
@@ -1,18 +1,15 @@
/obj/machinery/computer/crew
name = "Crew Monitoring Computer"
name = "crew monitoring computer"
desc = "Used to monitor active health sensors built into most of the crew's uniforms."
icon_state = "crew"
use_power = 1
idle_power_usage = 250
active_power_usage = 500
circuit = "/obj/item/weapon/circuitboard/crew"
var/list/tracked = list( )
l_color = "#0000FF"
var/obj/nano_module/crew_monitor/crew_monitor
/obj/machinery/computer/crew/New()
tracked = list()
crew_monitor = new(src)
..()
@@ -27,6 +24,8 @@
return
ui_interact(user)
/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
crew_monitor.ui_interact(user, ui_key, ui, force_open)
/obj/machinery/computer/crew/update_icon()
@@ -40,100 +39,5 @@
icon_state = initial(icon_state)
stat &= ~NOPOWER
/obj/machinery/computer/crew/Topic(href, href_list)
if(..())
return 1
if (src.z > 6)
usr << "\red <b>Unable to establish a connection</b>: \black You're too far away from the station!"
return 0
if( href_list["close"] )
var/mob/user = usr
var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
usr.unset_machine()
ui.close()
return 0
if(href_list["update"])
src.updateDialog()
return 1
/obj/machinery/computer/crew/interact(mob/user)
ui_interact(user)
/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(stat & (BROKEN|NOPOWER))
return
user.set_machine(src)
src.scan()
var/data[0]
var/list/crewmembers = list()
for(var/obj/item/clothing/under/C in src.tracked)
var/turf/pos = get_turf(C)
if((C) && (C.has_sensor) && (pos) && (pos.z == src.z) && C.sensor_mode)
if(istype(C.loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = C.loc
var/list/crewmemberData = list()
crewmemberData["sensor_type"] = C.sensor_mode
crewmemberData["dead"] = H.stat > 1
crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
crewmemberData["tox"] = round(H.getToxLoss(), 1)
crewmemberData["fire"] = round(H.getFireLoss(), 1)
crewmemberData["brute"] = round(H.getBruteLoss(), 1)
crewmemberData["name"] = "Unknown"
crewmemberData["rank"] = "Unknown"
if(H.wear_id && istype(H.wear_id, /obj/item/weapon/card/id) )
var/obj/item/weapon/card/id/I = H.wear_id
crewmemberData["name"] = I.name
crewmemberData["rank"] = I.rank
else if(H.wear_id && istype(H.wear_id, /obj/item/device/pda) )
var/obj/item/device/pda/P = H.wear_id
crewmemberData["name"] = (P.id ? P.id.name : "Unknown")
crewmemberData["rank"] = (P.id ? P.id.rank : "Unknown")
var/area/A = get_area(H)
crewmemberData["area"] = sanitize(A.name)
crewmemberData["x"] = pos.x
crewmemberData["y"] = pos.y
// Works around list += list2 merging lists; it's not pretty but it works
crewmembers += "temporary item"
crewmembers[crewmembers.len] = crewmemberData
crewmembers = sortByKey(crewmembers, "name")
data["crewmembers"] = crewmembers
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800)
// adding a template with the key "mapContent" enables the map ui functionality
ui.add_template("mapContent", "crew_monitor_map_content.tmpl")
// adding a template with the key "mapHeader" replaces the map header content
ui.add_template("mapHeader", "crew_monitor_map_header.tmpl")
// we want to show the map by default
ui.set_show_map(1)
ui.set_initial_data(data)
ui.open()
// should make the UI auto-update; doesn't seem to?
ui.set_auto_update(1)
/obj/machinery/computer/crew/proc/scan()
for(var/mob/living/carbon/human/H in mob_list)
if(istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/C = H.w_uniform
if (C.has_sensor)
tracked |= C
return 1
crew_monitor.ui_interact(user)
+3 -5
View File
@@ -17,7 +17,7 @@
/obj/machinery/computer/HONKputer/Topic(href, href_list)
if(..())
return 1
if (src.z > 1)
if (!(src.z in config.station_levels))
usr << "\red <b>Unable to establish a connection</b>: \black You're too far away from the station!"
return
usr.set_machine(src)
@@ -57,12 +57,10 @@
src.updateUsrDialog()
/obj/machinery/computer/HONKputer/attackby(var/obj/I as obj, var/mob/user as mob)
if(istype(I,/obj/item/weapon/card/emag/))
/obj/machinery/computer/HONKputer/emag_act(user as mob)
if(!emagged)
src.emagged = 1
user << "You scramble the login circuits, allowing anyone to use the console!"
..()
/obj/machinery/computer/HONKputer/attack_hand(var/mob/user as mob)
if(..())
+19 -18
View File
@@ -41,24 +41,6 @@
return
if(!istype(user))
return
if(istype(O,/obj/item/weapon/card/emag/))
// Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online.
// It'll take more time if there's more characters in the password..
if(!emag)
if(!isnull(src.linkedServer))
icon_state = hack_icon // An error screen I made in the computers.dmi
emag = 1
screen = 2
spark_system.set_up(5, 0, src)
src.spark_system.start()
var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey
MK.loc = src.loc
// Will help make emagging the console not so easy to get away with.
MK.info += "<br><br><font color='red'>£%@%(*$%&(£&?*(%&£/{}</font>"
spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole()
message = rebootmsg
else
user << "<span class='notice'>A no server error appears on the screen.</span>"
if(isscrewdriver(O) && emag)
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
user << "<span class='warning'>It is too hot to mess with!</span>"
@@ -66,6 +48,25 @@
..()
return
/obj/machinery/computer/message_monitor/emag_act(user as mob)
// Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online.
// It'll take more time if there's more characters in the password..
if(!emag)
if(!isnull(src.linkedServer))
icon_state = hack_icon // An error screen I made in the computers.dmi
emag = 1
screen = 2
spark_system.set_up(5, 0, src)
src.spark_system.start()
var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey
MK.loc = src.loc
// Will help make emagging the console not so easy to get away with.
MK.info += "<br><br><font color='red'>£%@%(*$%&(£&?*(%&£/{}</font>"
spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole()
message = rebootmsg
else
user << "<span class='notice'>A no server error appears on the screen.</span>"
/obj/machinery/computer/message_monitor/update_icon()
..()
+1 -1
View File
@@ -65,7 +65,7 @@
if(!T.implanted) continue
var/loc_display = "Unknown"
var/mob/living/carbon/M = T.imp_in
if(M.z == 1 && !istype(M.loc, /turf/space))
if((M.z in config.station_levels) && !istype(M.loc, /turf/space))
var/turf/mob_loc = get_turf_loc(M)
loc_display = mob_loc.loc
if(T.malfunction)
+5 -4
View File
@@ -56,11 +56,13 @@
world << "\blue <B>All authorizations to shortening time for shuttle launch have been revoked!</B>"
src.authorized.len = 0
src.authorized = list( )
else if (istype(W, /obj/item/weapon/card/emag) && !emagged)
return
emag_act(user as mob)
if (!emagged)
var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel")
if(!emagged && !emergency_shuttle.location() && user.get_active_hand() == W)
if(!emagged && !emergency_shuttle.location())
switch(choice)
if("Launch")
world << "\blue <B>Alert: Shuttle launch time shortened to 10 seconds!</B>"
@@ -68,4 +70,3 @@
emagged = 1
if("Cancel")
return
return
+18 -19
View File
@@ -158,7 +158,7 @@ for reference:
src.icon_state = "barrier[src.locked]"
attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/card/id/))
if (istype(W, /obj/item/weapon/card/id))
if (src.allowed(user))
if (src.emagged < 2.0)
src.locked = !src.locked
@@ -177,24 +177,6 @@ for reference:
visible_message("\red BZZzZZzZZzZT")
return
return
else if (istype(W, /obj/item/weapon/card/emag))
if (src.emagged == 0)
src.emagged = 1
src.req_access = null
user << "You break the ID authentication lock on the [src]."
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
visible_message("\red BZZzZZzZZzZT")
return
else if (src.emagged == 1)
src.emagged = 2
user << "You short out the anchoring mechanism on the [src]."
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
visible_message("\red BZZzZZzZZzZT")
return
else if (istype(W, /obj/item/weapon/wrench))
if (src.health < src.maxhealth)
src.health = src.maxhealth
@@ -218,6 +200,23 @@ for reference:
if (src.health <= 0)
src.explode()
..()
emag_act(user as mob)
if (!emagged)
emagged = 1
req_access = null
user << "You break the ID authentication lock on the [src]."
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
visible_message("\red BZZzZZzZZzZT")
else if (src.emagged == 1)
src.emagged = 2
user << "You short out the anchoring mechanism on the [src]."
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
visible_message("\red BZZzZZzZZzZT")
ex_act(severity)
switch(severity)
+5 -2
View File
@@ -57,11 +57,14 @@
*/
if(istype(W, /obj/item/device/detective_scanner))
return
if(istype(W, /obj/item/weapon/card/emag))
return src.attack_hand(user)
/obj/machinery/door_control/emag_act(user as mob)
if(!emagged)
emagged = 1
req_access = list()
req_one_access = list()
playsound(src.loc, "sparks", 100, 1)
return src.attack_hand(user)
/obj/machinery/door_control/attack_hand(mob/user as mob)
src.add_fingerprint(usr)
+8 -4
View File
@@ -153,10 +153,7 @@
if(!src.requiresID())
user = null
if(src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)))
flick("door_spark", src)
sleep(6)
open()
operating = -1
emag_act(user)
return 1
if(src.allowed(user) || src.emergency == 1)
if(src.density)
@@ -168,6 +165,13 @@
flick("door_deny", src)
return
/obj/machinery/door/emag_act(user as mob)
if(density)
flick("door_spark", src)
sleep(6)
open()
operating = -1
return 1
/obj/machinery/door/blob_act()
if(prob(40))
+16 -11
View File
@@ -225,21 +225,13 @@
/obj/machinery/door/window/attack_hand(mob/user as mob)
return src.attackby(user, user)
/obj/machinery/door/window/attackby(obj/item/weapon/I as obj, mob/living/user as mob)
//If it's in the process of opening/closing, ignore the click
if (src.operating)
return
add_fingerprint(user)
//Emags and ninja swords? You may pass.
if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)))
/obj/machinery/door/window/emag_act(user as mob, weapon as obj)
if(density)
src.operating = -1
flick("[src.base_state]spark", src)
sleep(6)
desc += "<BR><span class='warning'>Its access panel is smoking slightly.</span>"
if(istype(I, /obj/item/weapon/melee/energy/blade))
if(istype(weapon, /obj/item/weapon/melee/energy/blade))
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src.loc)
spark_system.start()
@@ -252,6 +244,19 @@
open()
emagged = 1
return 1
/obj/machinery/door/window/attackby(obj/item/weapon/I as obj, mob/living/user as mob)
//If it's in the process of opening/closing, ignore the click
if (src.operating)
return
add_fingerprint(user)
//Ninja swords? You may pass.
if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)))
emag_act(user,I)
return 1
if(istype(I, /obj/item/weapon/screwdriver))
if(src.density || src.operating)
+16
View File
@@ -4,6 +4,7 @@
name = "Emergency Floodlight"
icon = 'icons/obj/machines/floodlight.dmi'
icon_state = "flood00"
anchored = 0
density = 1
var/on = 0
var/obj/item/weapon/stock_parts/cell/high/cell = null
@@ -63,6 +64,21 @@
/obj/machinery/floodlight/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
if (!anchored && !isinspace())
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
user.visible_message( \
"[user] tightens \the [src]'s casters.", \
"<span class='notice'> You have tightened \the [src]'s casters.</span>", \
"You hear ratchet.")
anchored = 1
else if(anchored)
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
user.visible_message( \
"[user] loosens \the [src]'s casters.", \
"<span class='notice'> You have loosened \the [src]'s casters.</span>", \
"You hear ratchet.")
anchored = 0
if (istype(W, /obj/item/weapon/screwdriver))
if (!open)
if(unlocked)
+8
View File
@@ -37,6 +37,13 @@
/obj/machinery/iv_drip/MouseDrop(over_object, src_location, over_location)
..()
if(!ishuman(usr) && !isrobot(usr))
return
var/turf/T = get_turf(src)
if(!usr in range(1, T))
return
if(attached)
visible_message("[src.attached] is detached from \the [src]")
@@ -133,6 +140,7 @@
/obj/machinery/iv_drip/verb/toggle_mode()
set name = "Toggle Mode"
set category = "Object"
set src in view(1)
if(!istype(usr, /mob/living))
+6 -5
View File
@@ -27,11 +27,6 @@
return 1
/obj/machinery/metaldetector/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/card/emag))
if(!src.emagged)
src.emagged = 1
user << "\blue You short out the circuitry."
return
if(istype(W, /obj/item/weapon/card))
for(var/ID in list(user.equipped(), user:wear_id, user:belt))
if(src.check_access(ID,list("20")))
@@ -46,6 +41,12 @@
else
user << "\red You lack access to the control panel!"
return
/obj/machinery/metaldetector/emag_act(user as mob)
if(!emagged)
emagged = 1
user << "\blue You short out the circuitry."
return
/obj/machinery/metaldetector/Crossed(AM as mob|obj)
if(emagged)
+19 -10
View File
@@ -5,6 +5,7 @@
/datum/feed_message
var/author =""
var/body =""
var/message_type ="Story"
//var/parent_channel
var/backup_body =""
var/backup_author =""
@@ -39,6 +40,12 @@
src.backup_author = ""
src.censored = 0
src.is_admin_channel = 0
/datum/feed_channel/proc/announce_news()
return "Breaking news from [channel_name]!"
/datum/feed_channel/station/announce_news()
return "New Station Announcement Available"
/datum/feed_network
var/list/datum/feed_channel/network_channels = list()
@@ -213,7 +220,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
switch(screen)
if(0)
dat += {"Welcome to Newscasting Unit #[src.unit_no].<BR> Interface & News networks Operational.
<BR><FONT SIZE=1>Property of Nanotransen Inc</FONT>"}
<BR><FONT SIZE=1>Property of Nanotrasen</FONT>"}
if(news_network.wanted_issue)
dat+= "<HR><A href='?src=\ref[src];view_wanted=1'>Read Wanted Issue</A>"
dat+= {"<HR><BR><A href='?src=\ref[src];create_channel=1'>Create Feed Channel</A>
@@ -248,7 +255,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
dat+="<I>No feed messages found in channel...</I><BR><BR>"
else
for(var/datum/feed_message/MESSAGE in CHANNEL.messages)
dat+="-[MESSAGE.body] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>"*/
dat+="-[MESSAGE.body] <BR><FONT SIZE=1>\[[MESSAGE.message_type] by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>"*/
dat+="<BR><HR><A href='?src=\ref[src];refresh=1'>Refresh</A>"
dat+="<BR><A href='?src=\ref[src];setScreen=[0]'>Back</A>"
@@ -334,7 +341,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
if(MESSAGE.img)
usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
dat+="<img src='tmp_photo[i].png' width = '180'><BR><BR>"
dat+="<FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>"
dat+="<FONT SIZE=1>\[[MESSAGE.message_type] by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>"
dat+="<BR><HR><A href='?src=\ref[src];refresh=1'>Refresh</A>"
dat+="<BR><A href='?src=\ref[src];setScreen=[1]'>Back</A>"
if(10)
@@ -369,7 +376,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
dat+="<I>No feed messages found in channel...</I><BR>"
else
for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages)
dat+="-[MESSAGE.body] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>"
dat+="-[MESSAGE.body] <BR><FONT SIZE=1>\[[MESSAGE.message_type] by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>"
dat+="<FONT SIZE=2><A href='?src=\ref[src];censor_channel_story_body=\ref[MESSAGE]'>[(MESSAGE.body == "\[REDACTED\]") ? ("Undo story censorship") : ("Censor story")]</A> - <A href='?src=\ref[src];censor_channel_story_author=\ref[MESSAGE]'>[(MESSAGE.author == "\[REDACTED\]") ? ("Undo Author Censorship") : ("Censor message Author")]</A></FONT><BR>"
dat+="<BR><A href='?src=\ref[src];setScreen=[10]'>Back</A>"
if(13)
@@ -383,7 +390,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
dat+="<I>No feed messages found in channel...</I><BR>"
else
for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages)
dat+="-[MESSAGE.body] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>"
dat+="-[MESSAGE.body] <BR><FONT SIZE=1>\[[MESSAGE.message_type] by <FONT COLOR='maroon'>[MESSAGE.author]</FONT>\]</FONT><BR>"
dat+="<BR><A href='?src=\ref[src];setScreen=[11]'>Back</A>"
if(14)
@@ -516,7 +523,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
src.updateUsrDialog()
else if(href_list["set_new_message"])
src.msg = strip_html(input(usr, "Write your Feed story", "Network Channel Handler", ""))
src.msg = strip_html(input(usr, "Write your feed story", "Network Channel Handler", ""))
while (findtext(src.msg," ") == 1)
src.msg = copytext(src.msg,2,lentext(src.msg)+1)
src.updateUsrDialog()
@@ -535,13 +542,15 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
if(photo)
newMsg.img = photo.img
feedback_inc("newscaster_stories",1)
var/announcement = ""
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == src.channel_name)
FC.messages += newMsg //Adding message to the network's appropriate feed_channel
announcement = FC.announce_news()
break
src.screen=4
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert(src.channel_name)
NEWSCASTER.newsAlert(announcement)
src.updateUsrDialog()
@@ -986,11 +995,11 @@ obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob)
///obj/machinery/newscaster/process() //Was thinking of doing the icon update through process, but multiple iterations per second does not
// return //bode well with a newscaster network of 10+ machines. Let's just return it, as it's added in the machines list.
/obj/machinery/newscaster/proc/newsAlert(channel) //This isn't Agouri's work, for it is ugly and vile.
/obj/machinery/newscaster/proc/newsAlert(var/news_call) //This isn't Agouri's work, for it is ugly and vile.
var/turf/T = get_turf(src) //Who the fuck uses spawn(600) anyway, jesus christ
if(channel)
if(news_call)
for(var/mob/O in hearers(world.view-1, T))
O.show_message("<span class='newscaster'><EM>[src.name]</EM> beeps, \"Breaking news from [channel]!\"</span>",2)
O.show_message("<span class='newscaster'><EM>[src.name]</EM> beeps, \"[news_call]\"</span>",2)
src.alert = 1
src.update_icon()
spawn(300)
+13 -14
View File
@@ -307,20 +307,7 @@ Status: []<BR>"},
del(src)
if ((istype(W, /obj/item/weapon/card/emag)) && (!src.emagged))
// Emagging the turret makes it go bonkers and stun everyone. It also makes
// the turret shoot much, much faster.
user << "\red You short out [src]'s threat assessment circuits."
spawn(0)
for(var/mob/O in hearers(src, null))
O.show_message("\red [src] hums oddly...", 1)
emagged = 1
src.on = 0 // turns off the turret temporarily
sleep(60) // 6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit
on = 1 // turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here
else if((istype(W, /obj/item/weapon/wrench)) && (!on))
if((istype(W, /obj/item/weapon/wrench)) && (!on))
if(raised) return
// This code handles moving the turret around. After all, it's a portable turret!
@@ -359,7 +346,19 @@ Status: []<BR>"},
attacked = 0
..()
/obj/machinery/porta_turret/emag_act(user as mob)
if(!src.emagged)
// Emagging the turret makes it go bonkers and stun everyone. It also makes
// the turret shoot much, much faster.
user << "\red You short out [src]'s threat assessment circuits."
spawn(0)
for(var/mob/O in hearers(src, null))
O.show_message("\red [src] hums oddly...", 1)
emagged = 1
src.on = 0 // turns off the turret temporarily
sleep(60) // 6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit
on = 1 // turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here
/obj/machinery/porta_turret/bullet_act(var/obj/item/projectile/Proj)
if(on)
+11 -13
View File
@@ -196,19 +196,6 @@
return
/obj/machinery/programmable/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I,/obj/item/weapon/card/emag))
if(emagged)
return
user << "You swipe the unloader with your card. After a moment's grinding, it beeps in a sinister fashion."
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
emagged = 1
overrides += emag_overrides
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
return
if(istype(I,/obj/item/weapon/wrench)) // code borrowed from pipe dispenser
if (unwrenched==0)
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
@@ -281,7 +268,18 @@
I.loc = src
RefreshParts()
/obj/machinery/programmable/emag_act(user as mob)
if(emagged)
return
user << "You swipe the unloader with your card. After a moment's grinding, it beeps in a sinister fashion."
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
emagged = 1
overrides += emag_overrides
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, src)
s.start()
return
/obj/machinery/programmable/process()
if (!output || !input)
+9 -7
View File
@@ -32,13 +32,7 @@ var/const/SAFETY_COOLDOWN = 100
/obj/machinery/recycler/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/weapon/card/emag) && !emagged)
emagged = 1
if(safety_mode)
safety_mode = 0
update_icon()
playsound(src.loc, "sparks", 75, 1, -1)
else if(istype(I, /obj/item/weapon/screwdriver) && emagged)
if(istype(I, /obj/item/weapon/screwdriver) && emagged)
emagged = 0
update_icon()
user << "<span class='notice'>You reset the crusher to its default factory settings.</span>"
@@ -46,6 +40,14 @@ var/const/SAFETY_COOLDOWN = 100
..()
return
add_fingerprint(user)
/obj/machinery/recycler/emag_act(user as mob)
if(!emagged)
emagged = 1
if(safety_mode)
safety_mode = 0
update_icon()
playsound(src.loc, "sparks", 75, 1, -1)
/obj/machinery/recycler/update_icon()
..()
+16 -9
View File
@@ -55,6 +55,7 @@ var/list/obj/machinery/requests_console/allConsoles = list()
var/dpt = ""; //the department which will be receiving the message
var/priority = -1 ; //Priority of the message being sent
luminosity = 0
var/datum/announcement/announcement = new
/obj/machinery/requests_console/power_change()
..()
@@ -70,6 +71,10 @@ var/list/obj/machinery/requests_console/allConsoles = list()
/obj/machinery/requests_console/New()
..()
announcement.title = "[department] announcement"
announcement.newscast = 1
name = "[department] Requests Console"
allConsoles += src
//req_console_departments += department
@@ -189,7 +194,7 @@ var/list/obj/machinery/requests_console/allConsoles = list()
else //main menu
screen = 0
announceAuth = 0
reset_announce()
if (newmessagepriority == 1)
dat += text("<FONT COLOR='RED'>There are new messages</FONT><BR>")
if (newmessagepriority == 2)
@@ -240,17 +245,13 @@ var/list/obj/machinery/requests_console/allConsoles = list()
if("2") priority = 2
else priority = -1
else
message = ""
announceAuth = 0
reset_announce()
screen = 0
if(href_list["sendAnnouncement"])
if(!announcementConsole) return
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
M << "<b><font size = 3><font color = red>[department] announcement:</font color> [message]</font size></b>"
announceAuth = 0
message = ""
announcement.Announce(message)
reset_announce()
screen = 0
if( href_list["department"] && message )
@@ -389,8 +390,9 @@ var/list/obj/machinery/requests_console/allConsoles = list()
var/obj/item/weapon/card/id/ID = O
if (access_RC_announce in ID.GetAccess())
announceAuth = 1
announcement.announcer = ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name
else
announceAuth = 0
reset_announce()
user << "\red You are not authorized to send announcements."
updateUsrDialog()
if (istype(O, /obj/item/weapon/stamp))
@@ -399,3 +401,8 @@ var/list/obj/machinery/requests_console/allConsoles = list()
msgStamped = text("<font color='blue'><b>Stamped with the [T.name]</b></font>")
updateUsrDialog()
return
/obj/machinery/requests_console/proc/reset_announce()
announceAuth = 0
message = ""
announcement.announcer = ""
+2 -1
View File
@@ -1,3 +1,4 @@
var/datum/announcement/minor/slotmachine_announcement = new(do_log = 0)
/obj/machinery/slot_machine
name = "Slot Machine"
desc = "Gambling for the antisocial."
@@ -55,7 +56,7 @@
if (roll == 1)
for(var/mob/O in hearers(src, null))
O.show_message(text("<b>[]</b> says, 'JACKPOT! You win [src.money]!'", src), 1)
command_alert("Congratulations [usr.name] on winning the Jackpot!", "Jackpot Winner")
slotmachine_announcement.Announce("Congratulations [usr.name] on winning the Jackpot!", "Jackpot Winner")
usr.mind.initial_account.money += src.money
src.money = 0
else if (roll > 1 && roll <= 10)
+13 -18
View File
@@ -681,24 +681,6 @@
src.updateUsrDialog()
return
else if(istype(I,/obj/item/weapon/card/emag))
if(emagged)
user << "\red The cycler has already been subverted."
return
var/obj/item/weapon/card/emag/E = I
src.updateUsrDialog()
E.uses--
//Clear the access reqs, disable the safeties, and open up all paintjobs.
user << "\red You run the sequencer across the interface, corrupting the operating protocols."
departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$")
emagged = 1
safeties = 0
req_access = list()
return
else if(istype(I,/obj/item/clothing/head/helmet/space))
if(locked)
@@ -748,6 +730,19 @@
return
..()
/obj/machinery/suit_cycler/emag_act(user as mob)
if(emagged)
user << "\red The cycler has already been subverted."
return
//Clear the access reqs, disable the safeties, and open up all paintjobs.
user << "\red You run the sequencer across the interface, corrupting the operating protocols."
departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$")
emagged = 1
safeties = 0
req_access = list()
return
/obj/machinery/suit_cycler/attack_hand(mob/user as mob)
+5 -3
View File
@@ -244,9 +244,11 @@
A.icon_state = "4"
A.anchored = 1
del(src)
else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
src.updateUsrDialog()
return
emag_act(user as mob)
if(!emagged)
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
emagged = 1
user << "\blue You you disable the security protocols"
src.updateUsrDialog()
return
+6 -4
View File
@@ -153,9 +153,11 @@
A.icon_state = "4"
A.anchored = 1
del(src)
else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
emagged = 1
user << "\blue You you disable the security protocols"
src.updateUsrDialog()
return
emag_act(user as mob)
if(!emagged)
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
emagged = 1
user << "\blue You you disable the security protocols"
@@ -233,12 +233,14 @@
A.icon_state = "4"
A.anchored = 1
del(src)
else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
src.updateUsrDialog()
return
/obj/machinery/computer/telecomms/traffic/emag_act(user as mob)
if(!emagged)
playsound(get_turf(src), 'sound/effects/sparks4.ogg', 75, 1)
emagged = 1
user << "\blue You you disable the security protocols"
src.updateUsrDialog()
return
/obj/machinery/computer/telecomms/traffic/proc/canAccess(var/mob/user)
if(issilicon(user) || in_range(user, src))
+13 -14
View File
@@ -31,16 +31,7 @@
return power_station
/obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob)
if(istype(I,/obj/item/weapon/card/emag)) // If hit by an emag.
var/obj/item/weapon/card/emag/E = I
if(!emagged)
if(E.uses)
E.uses--
emagged = 1
user << "\blue The teleporter can now lock on to Syndicate beacons!"
else
ui_interact(user)
else if(istype(I, /obj/item/device/gps))
if(istype(I, /obj/item/device/gps))
var/obj/item/device/gps/L = I
if(L.locked_location && !(stat & (NOPOWER|BROKEN)))
if(!user.unEquip(L))
@@ -55,6 +46,13 @@
else
..()
return
/obj/machinery/computer/teleporter/emag_act(user as mob)
if(!emagged)
emagged = 1
user << "\blue The teleporter can now lock on to Syndicate beacons!"
else
ui_interact(user)
/obj/machinery/computer/teleporter/attack_paw(mob/user)
usr << "You are too primitive to use this computer."
@@ -82,7 +80,8 @@
data["calibrated"] = null
data["accurate"] = null
data["regime"] = regime_set
data["target"] = (!target) ? "None" : get_area(target)
var/area/targetarea = get_area(target)
data["target"] = (!target) ? "None" : sanitize(targetarea.name)
data["calibrating"] = calibrating
data["locked"] = locked
@@ -181,7 +180,7 @@
var/turf/T = get_turf(R)
if (!T)
continue
if(T.z == 2 || T.z > 7)
if((T.z in config.admin_levels) || T.z > 7)
continue
if(R.syndicate == 1 && emagged == 0)
continue
@@ -202,7 +201,7 @@
continue
var/turf/T = get_turf(M)
if(!T) continue
if(T.z == 2) continue
if((T.z in config.admin_levels)) continue
var/tmpname = M.real_name
if(areaindex[tmpname])
tmpname = "[tmpname] ([++areaindex[tmpname]])"
@@ -224,7 +223,7 @@
var/turf/T = get_turf(R)
if (!T || !R.teleporter_hub || !R.teleporter_console)
continue
if(T.z == 2 || T.z > 7)
if((T.z in config.admin_levels) || T.z > 7)
continue
var/tmpname = T.loc.name
if(areaindex[tmpname])
+11 -9
View File
@@ -364,15 +364,6 @@
if (istype(user, /mob/living/silicon))
return src.attack_hand(user)
if (istype(W, /obj/item/weapon/card/emag) && !emagged)
user << "\red You short out the turret controls' access analysis module."
emagged = 1
locked = 0
if(user.machine==src)
src.attack_hand(user)
return
else if( get_dist(src, user) == 0 ) // trying to unlock the interface
if (src.allowed(usr))
if(emagged)
@@ -390,6 +381,17 @@
src.attack_hand(user)
else
user << "<span class='warning'>Access denied.</span>"
/obj/machinery/turretid/emag_act(user as mob)
if (!emagged)
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
user << "\red You short out the turret controls' access analysis module."
emagged = 1
locked = 0
if(H.machine==src)
src.attack_hand(user)
/obj/machinery/turretid/attack_ai(mob/user as mob)
if(!ailock)
+393 -291
View File
@@ -1,17 +1,39 @@
#define CAT_NORMAL 0
#define CAT_HIDDEN 1
#define CAT_COIN 2
#define CAT_NORMAL 1
#define CAT_HIDDEN 2 // also used in corresponding wires/vending.dm
#define CAT_COIN 4
/**
* Datum used to hold information about a product in a vending machine
*/
/datum/data/vending_product
var/product_name = "generic"
var/product_name = "generic" // Display name for the product
var/product_path = null
var/amount = 0
var/amount = 0 // Amount held in the vending machine
var/max_amount = 0
var/price = 0
var/display_color = "blue"
var/category = CAT_NORMAL
var/price = 0 // Price to buy one
var/display_color = null // Display color for vending machine listing
var/category = CAT_NORMAL // CAT_HIDDEN for contraband, CAT_COIN for premium
/datum/data/vending_product/New(var/path, var/name = null, var/amount = 1, var/price = 0, var/color = null, var/category = CAT_NORMAL)
..()
src.product_path = path
if(!name)
var/atom/tmp = new path
src.product_name = initial(tmp.name)
del(tmp)
else
src.product_name = name
src.amount = amount
src.price = price
src.display_color = color
src.category = category
/**
* A vending machine
*/
/obj/machinery/vending
name = "Vendomat"
desc = "A generic vending machine."
@@ -20,39 +42,57 @@
layer = 2.9
anchored = 1
density = 1
var/icon_vend //Icon_state when vending
var/icon_deny //Icon_state when denying access
// Power
use_power = 1
idle_power_usage = 10
var/vend_power_usage = 150
// Vending-related
var/active = 1 //No sales pitches if off!
var/delay_product_spawn // If set, uses sleep() in product spawn proc (mostly for seeds to retrieve correct names).
var/vend_ready = 1 //Are we ready to vend?? Is it time??
var/vend_delay = 10 //How long does it take to vend?
var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now.
var/categories = CAT_NORMAL // Bitmask of cats we're currently showing
var/datum/data/vending_product/currently_vending = null // What we're requesting payment for right now
var/status_message = "" // Status screen messages like "insufficient funds", displayed in NanoUI
var/status_error = 0 // Set to 1 if status_message is an error
// To be filled out at compile time
var/list/products = list() // For each, use the following pattern:
var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2)
var/list/premium = list() // No specified amount = only one in stock
var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price.
var/product_slogans = "" //String of slogans separated by semicolons, optional
var/product_ads = "" //String of small ad messages in the vending screen - random chance
// List of vending_product items available.
var/list/product_records = list()
var/list/hidden_records = list()
var/list/coin_records = list()
// // Variables used to initialize advertising
var/product_slogans = "" //String of slogans separated by semicolons, optional
var/product_ads = "" //String of small ad messages in the vending screen - random chance
var/list/ads_list = list()
// Stuff relating vocalizations
var/list/slogan_list = list()
var/list/small_ads = list() //Small ad messages in the vending screen - random chance of popping up whenever you open it
var/vend_reply //Thank you for shopping!
var/shut_up = 0 //Stop spouting those godawful pitches!
var/last_reply = 0
var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine.
var/last_slogan = 0 //When did we last pitch?
var/slogan_delay = 6000 //How long until we can pitch again?
var/icon_vend //Icon_state when vending!
var/icon_deny //Icon_state when vending!
//var/emagged = 0 //Ignores if somebody doesn't have card access to that machine.
var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine.
// Things that can go wrong
emagged = 0 //Ignores if somebody doesn't have card access to that machine.
var/seconds_electrified = 0 //Shock customers like an airlock.
var/shoot_inventory = 0 //Fire items at customers! We're broken!
var/shoot_speed = 3 //How hard are we firing the items?
var/shoot_chance = 2 //How often are we firing the items?
var/shut_up = 0 //Stop spouting those godawful pitches!
var/extended_inventory = 0 //can we access the hidden inventory?
var/scan_id = 1
var/obj/item/weapon/coin/coin
var/datum/wires/vending/wires = null
@@ -60,32 +100,57 @@
/obj/machinery/vending/New()
..()
wires = new(src)
spawn(4)
src.slogan_list = text2list(src.product_slogans, ";")
spawn(50)
if(src.product_slogans)
src.slogan_list += text2list(src.product_slogans, ";")
// So not all machines speak at the exact same time.
// The first time this machine says something will be at slogantime + this random value,
// so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated.
src.last_slogan = world.time + rand(0, slogan_delay)
// So not all machines speak at the exact same time.
// The first time this machine says something will be at slogantime + this random value,
// so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated.
src.last_slogan = world.time + rand(0, slogan_delay)
src.build_inventory(products)
//Add hidden inventory
src.build_inventory(contraband, 1)
src.build_inventory(premium, 0, 1)
if(src.product_ads)
src.ads_list += text2list(src.product_ads, ";")
src.build_inventory()
power_change()
return
return
/**
* Build src.produdct_records from the products lists
*
* src.products, src.contraband, src.premium, and src.prices allow specifying
* products that the vending machine is to carry without manually populating
* src.product_records.
*/
/obj/machinery/vending/proc/build_inventory()
var/list/all_products = list(
list(src.products, CAT_NORMAL),
list(src.contraband, CAT_HIDDEN),
list(src.premium, CAT_COIN))
for(var/current_list in all_products)
var/category = current_list[2]
for(var/entry in current_list[1])
var/datum/data/vending_product/product = new/datum/data/vending_product(entry)
product.price = (entry in src.prices) ? src.prices[entry] : 0
product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1
product.max_amount = product.amount
product.category = category
src.product_records.Add(product)
/obj/machinery/vending/Destroy()
del(wires)
del(wires) // qdel
wires = null
del(coin)
coin = null
if(coin)
del(coin) // qdel
coin = null
..()
/obj/machinery/vending/ex_act(severity)
@@ -115,41 +180,6 @@
else
del(src)
/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0,start_empty = null)
for(var/typepath in productlist)
var/amount = productlist[typepath]
var/price = prices[typepath]
if(isnull(amount)) amount = 1
var/atom/temp = new typepath(null)
var/datum/data/vending_product/R = new /datum/data/vending_product()
R.product_path = typepath
if(!start_empty)
R.amount = amount
R.max_amount = amount
R.price = price
R.display_color = pick("red","blue","green")
if(hidden)
R.category=CAT_HIDDEN
hidden_records += R
else if(req_coin)
R.category=CAT_COIN
coin_records += R
else
R.category=CAT_NORMAL
product_records += R
if(delay_product_spawn)
sleep(3)
R.product_name = temp.name
else
R.product_name = temp.name
// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]"
/obj/machinery/vending/proc/refill_inventory(obj/item/weapon/vending_refill/refill, datum/data/vending_product/machine, mob/user)
var/total = 0
@@ -180,10 +210,41 @@
return total
/obj/machinery/vending/attackby(obj/item/weapon/W, mob/user)
if(panel_open)
if(default_unfasten_wrench(user, W, time = 60))
return
if (currently_vending && vendor_account && !vendor_account.suspended)
var/paid = 0
var/handled = 0
if(istype(W, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/C = W
paid = pay_with_card(C)
handled = 1
else if (istype(W, /obj/item/weapon/spacecash))
var/obj/item/weapon/spacecash/C = W
paid = pay_with_cash(C, user)
handled = 1
if(paid)
src.vend(currently_vending, usr)
return
else if(handled)
nanomanager.update_uis(src)
return // don't smack that machine with your 2 thalers
if(default_unfasten_wrench(user, W, time = 60))
return
if(istype(W, /obj/item/weapon/screwdriver) && anchored)
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
panel_open = !panel_open
user << "You [panel_open ? "open" : "close"] the maintenance panel."
overlays.Cut()
if(panel_open)
overlays += image(icon, "[initial(icon_state)]-panel")
nanomanager.update_uis(src) // Speaker switch is on the main UI, not wires UI
return
if(panel_open)
if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters))
return attack_hand(user)
if(component_parts && istype(W, /obj/item/weapon/crowbar))
var/datum/data/vending_product/machine = product_records
for(var/datum/data/vending_product/machine_content in machine)
@@ -194,32 +255,13 @@
if(!machine_content.amount)
break
default_deconstruction_crowbar(W)
if(istype(W, /obj/item/weapon/card/emag))
emagged = 1
user << "You short out the product lock on [src]"
return
else if(istype(W, /obj/item/weapon/screwdriver) && anchored)
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
panel_open = !panel_open
user << "You [panel_open ? "open" : "close"] the maintenance panel."
overlays.Cut()
if(panel_open)
overlays += image(icon, "[initial(icon_state)]-panel")
updateUsrDialog()
return
else if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters))
if(panel_open)
attack_hand(user)
return
else if(istype(W, /obj/item/weapon/card) && currently_vending)
var/obj/item/weapon/card/I = W
scan_card(I)
else if(istype(W, /obj/item/weapon/coin) && premium.len > 0)
if(istype(W, /obj/item/weapon/coin) && premium.len > 0)
user.drop_item()
W.loc = src
coin = W
user << "<span class='notice'>You insert [W] into [src].</span>"
categories |= CAT_COIN
user << "\blue You insert the [W] into the [src]"
nanomanager.update_uis(src)
return
else if(istype(W, refill_canister) && refill_canister != null)
if(stat & (BROKEN|NOPOWER))
@@ -240,176 +282,189 @@
user << "<span class='notice'>You should probably unscrew the service panel first.</span>"
else
..()
/obj/machinery/vending/emag_act(user as mob)
emagged = 1
user << "You short out the product lock on [src]"
return
/**
* Receive payment with cashmoney.
*
* usr is the mob who gets the change.
*/
/obj/machinery/vending/proc/pay_with_cash(var/obj/item/weapon/spacecash/cashmoney, mob/user)
if(currently_vending.price > cashmoney.worth)
// This is not a status display message, since it's something the character
// themselves is meant to see BEFORE putting the money in
usr << "\icon[cashmoney] <span class='warning'>That is not enough money.</span>"
return 0
// Bills (banknotes) cannot really have worth different than face value,
// so we have to eat the bill and spit out change in a bundle
// This is really dirty, but there's no superclass for all bills, so we
// just assume that all spacecash that's not something else is a bill
visible_message("<span class='info'>[usr] inserts a credit chip into [src].</span>")
var/left = cashmoney.worth - currently_vending.price
usr.drop_from_inventory(cashmoney)
del(cashmoney)
/obj/machinery/vending/proc/scan_card(var/obj/item/weapon/card/I)
if(!currently_vending) return
if (istype(I, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/C = I
visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
if(vendor_account)
var/datum/money_account/D = attempt_account_access_nosec(C.associated_account_number)
if(D)
var/transaction_amount = currently_vending.price
if(transaction_amount <= D.money)
if(left)
dispense_cash(left, src.loc, user)
//transfer the money
D.money -= transaction_amount
vendor_account.money += transaction_amount
// Vending machines have no idea who paid with cash
credit_purchase("(cash)")
return 1
//create entries in the two account transaction logs
var/datum/transaction/T = new()
T.target_name = "[vendor_account.owner_name] (via [src.name])"
T.purpose = "Purchase of [currently_vending.product_name]"
if(transaction_amount > 0)
T.amount = "([transaction_amount])"
else
T.amount = "[transaction_amount]"
T.source_terminal = src.name
T.date = current_date_string
T.time = worldtime2text()
D.transaction_log.Add(T)
//
T = new()
T.target_name = D.owner_name
T.purpose = "Purchase of [currently_vending.product_name]"
T.amount = "[transaction_amount]"
T.source_terminal = src.name
T.date = current_date_string
T.time = worldtime2text()
vendor_account.transaction_log.Add(T)
/**
* Scan a card and attempt to transfer payment from associated account.
*
* Takes payment for whatever is the currently_vending item. Returns 1 if
* successful, 0 if failed
*/
/obj/machinery/vending/proc/pay_with_card(var/obj/item/weapon/card/id/I)
visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
var/datum/money_account/customer_account = attempt_account_access_nosec(I.associated_account_number)
if (!customer_account)
src.status_message = "Error: Unable to access account. Please contact technical support if problem persists."
src.status_error = 1
return 0
// Vend the item
src.vend(src.currently_vending, usr)
currently_vending = null
src.updateUsrDialog()
else
usr << "\icon[src]<span class='warning'>You don't have that much money!</span>"
else
usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>"
if(customer_account.suspended)
src.status_message = "Unable to access account: account suspended."
src.status_error = 1
return 0
// Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is
// empty at high security levels
if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2)
var/attempt_pin = input("Enter pin code", "Vendor transaction") as num
customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2)
if(!customer_account)
src.status_message = "Unable to access account: incorrect credentials."
src.status_error = 1
return 0
if(currently_vending.price > customer_account.money)
src.status_message = "Insufficient funds in account."
src.status_error = 1
return 0
else
// Okay to move the money at this point
// debit money from the purchaser's account
customer_account.money -= currently_vending.price
// create entry in the purchaser's account log
var/datum/transaction/T = new()
T.target_name = "[vendor_account.owner_name] (via [src.name])"
T.purpose = "Purchase of [currently_vending.product_name]"
if(currently_vending.price > 0)
T.amount = "([currently_vending.price])"
else
usr << "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call CentComm Support.</span>"
T.amount = "[currently_vending.price]"
T.source_terminal = src.name
T.date = current_date_string
T.time = worldtime2text()
customer_account.transaction_log.Add(T)
/obj/machinery/vending/attack_paw(mob/user as mob)
return attack_hand(user)
// Give the vendor the money. We use the account owner name, which means
// that purchases made with stolen/borrowed card will look like the card
// owner made them
credit_purchase(customer_account.owner_name)
return 1
/**
* Add money for current purchase to the vendor account.
*
* Called after the money has already been taken from the customer.
*/
/obj/machinery/vending/proc/credit_purchase(var/target as text)
vendor_account.money += currently_vending.price
var/datum/transaction/T = new()
T.target_name = target
T.purpose = "Purchase of [currently_vending.product_name]"
T.amount = "[currently_vending.price]"
T.source_terminal = src.name
T.date = current_date_string
T.time = worldtime2text()
vendor_account.transaction_log.Add(T)
/obj/machinery/vending/attack_ai(mob/user as mob)
return attack_hand(user)
/obj/machinery/vending/proc/GetProductIndex(var/datum/data/vending_product/P)
var/list/plist
switch(P.category)
if(CAT_NORMAL)
plist=product_records
if(CAT_HIDDEN)
plist=hidden_records
if(CAT_COIN)
plist=coin_records
else
warning("UNKNOWN CATEGORY [P.category] IN TYPE [P.product_path] INSIDE [type]!")
return plist.Find(P)
/obj/machinery/vending/proc/GetProductByID(var/pid, var/category)
switch(category)
if(CAT_NORMAL)
return product_records[pid]
if(CAT_HIDDEN)
return hidden_records[pid]
if(CAT_COIN)
return coin_records[pid]
else
warning("UNKNOWN PRODUCT: PID: [pid], CAT: [category] INSIDE [type]!")
return null
/obj/machinery/vending/attack_paw(mob/user as mob)
return attack_hand(user)
/obj/machinery/vending/attack_hand(mob/user as mob)
if(stat & (BROKEN|NOPOWER))
return
user.set_machine(src)
if(seconds_electrified != 0)
if(shock(user, 100))
if(src.seconds_electrified != 0)
if(src.shock(user, 100))
return
var/vendorname = (src.name) //import the machine's name
ui_interact(user)
wires.Interact(user)
if(src.currently_vending)
var/dat = "<TT><center><b>[vendorname]</b></center><hr /><br>" //display the name, and added a horizontal rule
// AUTOFIXED BY fix_string_idiocy.py
// C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\vending.dm:260: dat += "<b>You have selected [currently_vending.product_name].<br>Please ensure your ID is in your ID holder or hand.</b><br>"
dat += {"<b>You have selected [currently_vending.product_name].<br>Please ensure your ID is in your ID holder or hand.</b><br>
<a href='byond://?src=\ref[src];buy=1'>Pay</a> |
<a href='byond://?src=\ref[src];cancel_buying=1'>Cancel</a>"}
// END AUTOFIX
user << browse(dat, "window=vending")
onclose(user, "")
return
var/dat = "<TT><center><b>[vendorname]</b></center><hr /><br>" //display the name, and added a horizontal rule
dat += "<b>Select an item: </b><br><br>" //the rest is just general spacing and bolding
if (premium.len > 0)
dat += "<b>Coin slot:</b> [coin ? coin : "No coin inserted"] (<a href='byond://?src=\ref[src];remove_coin=1'>Remove</A>)<br><br>"
if (src.product_records.len == 0)
dat += "<font color = 'red'>No product loaded!</font>"
/**
* Display the NanoUI window for the vending machine.
*
* See NanoUI documentation for details.
*/
/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/list/data = list()
if(currently_vending)
data["mode"] = 1
data["product"] = currently_vending.product_name
data["price"] = currently_vending.price
data["message_err"] = 0
data["message"] = src.status_message
data["message_err"] = src.status_error
else
var/list/display_records = list()
display_records += src.product_records
data["mode"] = 0
var/list/listed_products = list()
if(src.extended_inventory)
display_records += src.hidden_records
if(src.coin)
display_records += src.coin_records
for (var/datum/data/vending_product/R in display_records)
// AUTOFIXED BY fix_string_idiocy.py
// C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\vending.dm:285: dat += "<FONT color = '[R.display_color]'><B>[R.product_name]</B>:"
dat += {"<FONT color = '[R.display_color]'><B>[R.product_name]</B>:
<b>[R.amount]</b> </font>"}
// END AUTOFIX
if(R.price)
dat += " <b>(Price: [R.price])</b>"
if (R.amount > 0)
var/idx=GetProductIndex(R)
dat += " <a href='byond://?src=\ref[src];vend=[idx];cat=[R.category]'>(Vend)</A>"
else
dat += " <font color = 'red'>SOLD OUT</font>"
dat += "<br>"
dat += "</TT>"
if(panel_open)
dat += wires()
if(product_slogans != "")
dat += "The speaker switch is [shut_up ? "off" : "on"]. <a href='?src=\ref[src];togglevoice=[1]'>Toggle</a>"
user << browse(dat, "window=vending")
onclose(user, "")
return
// returns the wire panel text
/obj/machinery/vending/proc/wires()
return wires.GetInteractWindow()
for(var/key = 1 to src.product_records.len)
var/datum/data/vending_product/I = src.product_records[key]
if(!(I.category & src.categories))
continue
listed_products.Add(list(list(
"key" = key,
"name" = sanitize(I.product_name),
"price" = I.price,
"color" = I.display_color,
"amount" = I.amount)))
data["products"] = listed_products
if(src.coin)
data["coin"] = src.coin.name
if(src.panel_open)
data["panel"] = 1
data["speaker"] = src.shut_up ? 0 : 1
else
data["panel"] = 0
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "vending_machine.tmpl", src.name, 440, 600)
ui.set_initial_data(data)
ui.open()
/obj/machinery/vending/Topic(href, href_list)
if(..())
return 1
if(istype(usr,/mob/living/silicon))
if(istype(usr,/mob/living/silicon/robot))
var/mob/living/silicon/robot/R = usr
if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) ) )
usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!"
return
else
usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!"
return
if(href_list["remove_coin"])
if(href_list["remove_coin"] && !istype(usr,/mob/living/silicon))
if(!coin)
usr << "There is no coin in this machine."
return
@@ -419,67 +474,86 @@
usr.put_in_hands(coin)
usr << "\blue You remove the [coin] from the [src]"
coin = null
usr.set_machine(src)
categories &= ~CAT_COIN
if (href_list["pay"])
if(currently_vending && vendor_account && !vendor_account.suspended)
if(istype(usr, /mob/living/carbon/human))
var/paid = 0
var/handled = 0
var/mob/living/carbon/human/H = usr
var/obj/item/weapon/card/card = null
if(istype(H.wear_id,/obj/item/weapon/card))
card = H.wear_id
paid = pay_with_card(card)
handled = 1
else if(istype(H.get_active_hand(), /obj/item/weapon/card))
card = H.get_active_hand()
paid = pay_with_card(card)
handled = 1
if(paid)
src.vend(currently_vending, usr)
return
else if(handled)
nanomanager.update_uis(src)
return // don't smack that machine with your 2 credits
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending))
if (!allowed(usr) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
usr << "\red Access denied." //Unless emagged of course
flick(src.icon_deny,src)
if(istype(usr,/mob/living/silicon))
if(istype(usr,/mob/living/silicon/robot))
var/mob/living/silicon/robot/R = usr
if(!(R.module && istype(R.module,/obj/item/weapon/robot_module/butler) ))
usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!"
return
else
usr << "\red The vending machine refuses to interface with you, as you are not in its target demographic!"
return
if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
usr << "<span class='warning'>Access denied.</span>" //Unless emagged of course
flick(icon_deny,src)
return
var/idx=text2num(href_list["vend"])
var/cat=text2num(href_list["cat"])
var/datum/data/vending_product/R = GetProductByID(idx,cat)
if (!R || !istype(R) || !R.product_path || R.amount <= 0)
var/key = text2num(href_list["vend"])
var/datum/data/vending_product/R = product_records[key]
// This should not happen unless the request from NanoUI was bad
if(!(R.category & src.categories))
return
if(R.price == null)
if(R.price <= 0)
src.vend(R, usr)
else
src.currently_vending = R
src.updateUsrDialog()
if(!vendor_account || vendor_account.suspended)
src.status_message = "This machine is currently unable to process payments due to problems with the associated account."
src.status_error = 1
else
src.status_message = "Please swipe a card or insert cash to pay for the item."
src.status_error = 0
return
else if (href_list["cancel_buying"])
else if (href_list["cancelpurchase"])
src.currently_vending = null
src.updateUsrDialog()
return
else if (href_list["buy"])
if(istype(usr, /mob/living/carbon/human))
var/mob/living/carbon/human/H=usr
var/obj/item/weapon/card/card = null
if(istype(H.wear_id,/obj/item/weapon/card))
card=H.wear_id
else if(istype(H.get_active_hand(),/obj/item/weapon/card))
card=H.get_active_hand()
if(card)
scan_card(card)
return
else if ((href_list["togglevoice"]) && (src.panel_open))
src.shut_up = !src.shut_up
src.add_fingerprint(usr)
src.updateUsrDialog()
else
usr << browse(null, "window=vending")
return
return
nanomanager.update_uis(src)
/obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user)
if (!allowed(user) && !emagged && wires.IsIndexCut(VENDING_WIRE_IDSCAN)) //For SECURE VENDING MACHINES YEAH
user << "\red Access denied." //Unless emagged of course
if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
usr << "<span class='warning'>Access denied.</span>" //Unless emagged of course
flick(src.icon_deny,src)
return
src.vend_ready = 0 //One thing at a time!!
if (R in coin_records)
src.status_message = "Vending..."
src.status_error = 0
nanomanager.update_uis(src)
if (R.category & CAT_COIN)
if(!coin)
user << "\blue You need to insert a coin to get this item."
return
@@ -489,8 +563,10 @@
else
user << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all."
del(coin)
categories &= ~CAT_COIN
else
del(coin)
categories &= ~CAT_COIN
R.amount--
@@ -499,16 +575,16 @@
src.speak(src.vend_reply)
src.last_reply = world.time
use_power(5)
use_power(vend_power_usage) //actuators and stuff
if (src.icon_vend) //Show the vending animation if needed
flick(src.icon_vend,src)
spawn(src.vend_delay)
new R.product_path(get_turf(src))
src.status_message = ""
src.status_error = 0
src.vend_ready = 1
return
src.updateUsrDialog()
currently_vending = null
nanomanager.update_uis(src)
/obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user)
if(src.panel_open)
@@ -809,7 +885,7 @@
/obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4,
/obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12,
/obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2,
/obj/item/stack/medical/advanced/bruise_pack = 3, /obj/item/stack/medical/advanced/ointment = 3, /obj/item/stack/medical/splint = 2)
/obj/item/stack/medical/advanced/bruise_pack = 3, /obj/item/stack/medical/advanced/ointment = 3, /obj/item/stack/medical/splint = 2, /obj/item/device/sensor_device = 2)
contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6)
@@ -860,7 +936,7 @@
icon_state = "sec"
icon_deny = "sec-deny"
req_access_txt = "1"
products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5,
products = list(/obj/item/weapon/restraints/handcuffs = 8,/obj/item/weapon/restraints/handcuffs/cable/zipties = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5,
/obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6,/obj/item/device/flashlight/seclite = 4)
contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/fancy/donut_box = 2,/obj/item/device/hailer = 5)
@@ -883,19 +959,45 @@
product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!"
product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!"
icon_state = "seeds"
delay_product_spawn = 1
products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3,
/obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3,
/obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3,
/obj/item/seeds/poppyseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3,
/obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,
/obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3)
/obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3,
/obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/coffeeaseed = 3, /obj/item/seeds/teaasperaseed = 3)
contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2,
/obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2)
premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1)
/**
* Populate hydroseeds product_records
*
* This needs to be customized to fetch the actual names of the seeds, otherwise
* the machine would simply list "packet of seeds" times 20
*/
/obj/machinery/vending/hydroseeds/build_inventory()
var/list/all_products = list(
list(src.products, CAT_NORMAL),
list(src.contraband, CAT_HIDDEN),
list(src.premium, CAT_COIN))
for(var/current_list in all_products)
var/category = current_list[2]
for(var/entry in current_list[1])
var/obj/item/seeds/S = new entry(src)
var/name = S.name
var/datum/data/vending_product/product = new/datum/data/vending_product(entry, name)
product.price = (entry in src.prices) ? src.prices[entry] : 0
product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1
product.max_amount = product.amount
product.category = category
src.product_records.Add(product)
/obj/machinery/vending/magivend
name = "MagiVend"

Some files were not shown because too many files have changed in this diff Show More