Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into screensaver

Conflicts:
	icons/obj/modular_console.dmi
	icons/obj/modular_laptop.dmi
This commit is contained in:
Chinsky
2016-01-09 10:25:21 +03:00
74 changed files with 730 additions and 226 deletions
+5
View File
@@ -50,6 +50,11 @@
/datum/alarm_handler/proc/major_alarms()
return alarms
/datum/alarm_handler/proc/has_major_alarms()
if(alarms && alarms.len)
return 1
return 0
/datum/alarm_handler/proc/minor_alarms()
return alarms
@@ -180,7 +180,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
return mob_species && (mob_species.appearance_flags & flag)
/datum/category_item/player_setup_item/general/body/OnTopic(var/href,var/list/href_list, var/mob/user)
var/mob_species = all_species[pref.species]
var/datum/species/mob_species = all_species[pref.species]
if(href_list["random"])
pref.randomize_appearance_for()
@@ -217,7 +217,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
continue
if(pref.gender == FEMALE && S.gender == MALE)
continue
if(!(pref.species in S.species_allowed))
if(!(mob_species.get_bodytype() in S.species_allowed))
continue
valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
@@ -235,7 +235,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
continue
if(pref.gender == FEMALE && S.gender == MALE)
continue
if(!(pref.species in S.species_allowed))
if(!(mob_species.get_bodytype() in S.species_allowed))
continue
valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
@@ -268,7 +268,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/list/valid_hairstyles = list()
for(var/hairstyle in hair_styles_list)
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
if(!(pref.species in S.species_allowed))
if(!(mob_species.get_bodytype() in S.species_allowed))
continue
valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
@@ -324,7 +324,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
continue
if(pref.gender == FEMALE && S.gender == MALE)
continue
if(!(pref.species in S.species_allowed))
if(!(mob_species.get_bodytype() in S.species_allowed))
continue
valid_facialhairstyles[facialhairstyle] = facial_hair_styles_list[facialhairstyle]
+6
View File
@@ -1233,6 +1233,12 @@ var/global/list/gear_datums = list()
sort_category = "misc"
cost = 1
/datum/gear/mirror
display_name = "handheld mirror"
path = /obj/item/weapon/mirror
sort_category = "misc"
cost = 1
/datum/gear/zippo
display_name = "zippo"
path = /obj/item/weapon/flame/lighter/zippo
+90 -42
View File
@@ -1,8 +1,3 @@
/*TODO:
implement icon loading that is efficient using browse_rsc
implement being able to move pieces
*/
/obj/item/weapon/board
name = "board"
desc = "A standard 12' checkerboard. Well used."
@@ -14,6 +9,13 @@
var/board = list()
var/selected = -1
/obj/item/weapon/board/New()
..()
var i
for(i = 0; i < 12; i++)
new /obj/item/weapon/checker(src.loc)
new /obj/item/weapon/checker/red(src.loc)
/obj/item/weapon/board/examine(mob/user, var/distance = -1)
if(in_range(user,src))
user.set_machine(src)
@@ -21,29 +23,56 @@
return
..()
/obj/item/weapon/board/attack_hand(mob/living/carbon/human/M as mob)
if(M.machine == src)
..()
else
src.examine(M)
obj/item/weapon/board/attackby(obj/item/I as obj, mob/user as mob)
if(!addPiece(I,user))
..()
/obj/item/weapon/board/proc/addPiece(obj/item/I as obj, mob/user as mob, var/tile = 0)
if(I.w_class != 1) //only small stuff
user.show_message("<span class='warning'>\The [I] is too big to be used as a board piece.</span>")
return
return 0
if(num == 64)
user.show_message("<span class='warning'>\The [src] is already full!</span>")
return
return 0
if(tile > 0 && board["[tile]"])
user.show_message("<span class='warning'>That space is already filled!</span>")
return 0
if(!user.Adjacent(src))
return 0
user.drop_from_inventory(I)
I.forceMove(src)
num++
if(!board_icons["[I.icon] [I.icon_state]"])
board_icons["[I.icon] [I.icon_state]"] = new /icon(I.icon,I.icon_state)
var i;
for(i=0;i<64;i++)
if(!board["[i]"])
board["[i]"] = I
break
if(tile == 0)
var i;
for(i=0;i<64;i++)
if(!board["[i]"])
board["[i]"] = I
break
else
board["[tile]"] = I
src.updateDialog()
return 1
/obj/item/weapon/board/interact(mob/user as mob)
if(user.incapacitated(INCAPACITATION_DISABLED) || (!isAI(user) && !user.Adjacent(src))) //can't see if you arent conscious. If you are not an AI you can't see it unless you are next to it, either.
user << browse(null, "window=boardgame")
user.unset_machine()
return
var/dat = "<HTML>"
dat += "<table border='0'>"
@@ -81,42 +110,61 @@ obj/item/weapon/board/attackby(obj/item/I as obj, mob/user as mob)
onclose(usr, "boardgame")
/obj/item/weapon/board/Topic(href, href_list)
if(href_list["select"])
var/s = href_list["select"]
var/obj/item/I = board["[s]"]
if(selected >= 0)
if(I) //cant put items on other items.
return
if(!usr.Adjacent(src))
usr.unset_machine()
usr << browse(null, "window=boardgame")
return
if(!usr.incapacitated()) //you can't move pieces if you can't move
if(href_list["select"])
var/s = href_list["select"]
var/obj/item/I = board["[s]"]
if(selected >= 0)
//check to see if clicked on tile is currently selected one
if(text2num(s) == selected)
selected = 0 //deselect it
return
if(I) //cant put items on other items.
return
//put item in new spot.
I = board["[selected]"]
I = board["[selected]"]
board["[selected]"] = null
board -= "[selected]"
board -= null
board["[s]"] = I
selected = -1
else
if(I)
selected = text2num(s)
else
var/mob/living/carbon/human/H = locate(href_list["person"])
if(!istype(H))
return
var/obj/item/O = H.get_active_hand()
if(!O)
return
addPiece(O,H,text2num(s))
if(href_list["remove"])
var/obj/item/I = board["[selected]"]
board["[selected]"] = null
board -= "[selected]"
board -= null
board["[s]"] = I
I.forceMove(src.loc)
num--
selected = -1
else
if(I)
selected = text2num(s)
if(href_list["remove"])
var/obj/item/I = board["[selected]"]
board["[selected]"] = null
board -= "[selected]"
board -= null
I.forceMove(src.loc)
num--
selected = -1
var j
for(j=0;j<64;j++)
if(board["[j]"])
var/obj/item/K = board["[j]"]
if(K.icon == I.icon && cmptext(K.icon_state,I.icon_state))
src.updateDialog()
return
//Didn't find it in use, remove it and allow GC to delete it.
board_icons["[I.icon] [I.icon_state]"] = null
board_icons -= "[I.icon] [I.icon_state]"
board_icons -= null
var j
for(j=0;j<64;j++)
if(board["[j]"])
var/obj/item/K = board["[j]"]
if(K.icon == I.icon && cmptext(K.icon_state,I.icon_state))
src.updateDialog()
return
//Didn't find it in use, remove it and allow GC to delete it.
board_icons["[I.icon] [I.icon_state]"] = null
board_icons -= "[I.icon] [I.icon_state]"
board_icons -= null
src.updateDialog()
/obj/item/weapon/checker/
+10 -4
View File
@@ -1,7 +1,13 @@
//This proc is called whenever someone clicks an inventory ui slot.
/mob/proc/attack_ui(slot)
var/obj/item/W = get_active_hand()
if(istype(W))
var/obj/item/E = get_equipped_item(slot)
if (istype(E))
if(istype(W))
E.attackby(W,src)
else
E.attack_hand(src)
else
equip_to_slot_if_possible(W, slot)
/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1)
@@ -77,13 +83,13 @@ var/list/slot_equipment_priority = list( \
// Try put it in their backpack
if(istype(src.back,/obj/item/weapon/storage))
var/obj/item/weapon/storage/backpack = src.back
if(backpack.contents.len < backpack.storage_slots)
if(backpack.can_be_inserted(newitem, 1))
newitem.forceMove(src.back)
return 1
// Try to place it in any item that can store stuff, on the mob.
for(var/obj/item/weapon/storage/S in src.contents)
if (S.contents.len < S.storage_slots)
if(S.can_be_inserted(newitem, 1))
newitem.forceMove(S)
return 1
return 0
@@ -186,7 +192,7 @@ var/list/slot_equipment_priority = list( \
wear_mask = null
update_inv_wear_mask(0)
return
/mob/proc/isEquipped(obj/item/I)
if(!I)
return 0
+78 -56
View File
@@ -26,6 +26,8 @@
var/blood = 1
var/list/target_types = list()
var/maximum_search_range = 7
/mob/living/bot/cleanbot/New()
..()
get_targets()
@@ -36,6 +38,25 @@
if(radio_controller)
radio_controller.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
/mob/living/bot/cleanbot/proc/handle_target()
if(loc == target.loc)
if(!cleaning)
UnarmedAttack(target)
return 1
if(!path.len)
// spawn(0)
path = AStar(loc, target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
if(!path)
custom_emote(2, "[src] can't reach the target and is giving up.")
target = null
path = list()
return
if(path.len)
step_to(src, path[1])
path -= path[1]
return 1
return
/mob/living/bot/cleanbot/Life()
..()
@@ -46,7 +67,7 @@
return
if(cleaning)
return
if(!screwloose && !oddbutton && prob(5))
custom_emote(2, "makes an excited beeping booping sound!")
@@ -74,65 +95,64 @@
spawn(600)
ignorelist -= gib
if(!target) // Find a target
for(var/obj/effect/decal/cleanable/D in view(7, src))
if(D in ignorelist)
continue
for(var/T in target_types)
if(istype(D, T))
target = D
patrol_path = list()
// Find a target
if(pulledby) // Don't wiggle if someone pulls you
patrol_path = list()
return
if(!target) // No targets in range
if(!should_patrol)
return
var/found_spot
search_loop:
for(var/i=0, i <= maximum_search_range, i++)
for(var/obj/effect/decal/cleanable/D in view(i, src))
if(D in ignorelist)
continue
for(var/T in target_types)
if(istype(D, T))
patrol_path = list()
target = D
found_spot = handle_target()
if (found_spot)
break search_loop
else
target = null
continue // no need to check the other types
if(!patrol_path || !patrol_path.len)
if(!signal_sent || signal_sent > world.time + 200) // Waited enough or didn't send yet
var/datum/radio_frequency/frequency = radio_controller.return_frequency(beacon_freq)
if(!frequency)
return
closest_dist = 9999
next_dest = null
next_dest_loc = null
var/datum/signal/signal = new()
signal.source = src
signal.transmission_method = 1
signal.data = list("findbeakon" = "patrol")
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
signal_sent = world.time
else
if(next_dest)
next_dest_loc = listener.memorized[next_dest]
if(next_dest_loc)
patrol_path = AStar(loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id = botcard, exclude = null)
signal_sent = 0
else
if(pulledby) // Don't wiggle if someone pulls you
patrol_path = list()
if(!found_spot && !target) // No targets in range
if(!patrol_path || !patrol_path.len)
if(!signal_sent || signal_sent > world.time + 200) // Waited enough or didn't send yet
var/datum/radio_frequency/frequency = radio_controller.return_frequency(beacon_freq)
if(!frequency)
return
if(patrol_path[1] == loc)
patrol_path -= patrol_path[1]
var/moved = step_towards(src, patrol_path[1])
if(moved)
patrol_path -= patrol_path[1]
if(target)
if(loc == target.loc)
if(!cleaning)
UnarmedAttack(target)
closest_dist = 9999
next_dest = null
next_dest_loc = null
var/datum/signal/signal = new()
signal.source = src
signal.transmission_method = 1
signal.data = list("findbeakon" = "patrol")
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
signal_sent = world.time
else
if(next_dest)
next_dest_loc = listener.memorized[next_dest]
if(next_dest_loc)
patrol_path = AStar(loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id = botcard, exclude = null)
signal_sent = 0
else
if(pulledby) // Don't wiggle if someone pulls you
patrol_path = list()
return
if(!path.len)
spawn(0)
path = AStar(loc, target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
if(!path)
path = list()
return
if(path.len)
step_to(src, path[1])
path -= path[1]
return
if(patrol_path[1] == loc)
patrol_path -= patrol_path[1]
var/moved = step_towards(src, patrol_path[1])
if(moved)
patrol_path -= patrol_path[1]
/mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/D, var/proximity)
if(!..())
@@ -145,7 +165,7 @@
return
cleaning = 1
custom_emote(2, "begins to clean up the [D]")
custom_emote(2, "begins to clean up \the [D]")
update_icons()
var/cleantime = istype(D, /obj/effect/decal/cleanable/dirt) ? 10 : 50
if(do_after(src, cleantime))
@@ -155,6 +175,8 @@
if(!D)
return
qdel(D)
if(D == target)
target = null
cleaning = 0
update_icons()
@@ -1385,7 +1385,7 @@
/mob/living/carbon/human/MouseDrop(var/atom/over_object)
var/mob/living/carbon/human/H = over_object
if(holder_type && istype(H) && !H.lying && !issmall(H) && Adjacent(H))
if(H.a_intent == I_HELP && holder_type && istype(H) && !H.lying && !issmall(H) && Adjacent(H))
get_scooped(H, (usr == src))
return
return ..()
@@ -39,7 +39,7 @@
push_flags = MONKEY|SLIME|SIMPLE_ANIMAL|ALIEN
pass_flags = PASSTABLE
holder_type = /obj/item/weapon/holder
/datum/species/monkey/handle_npc(var/mob/living/carbon/human/H)
if(H.stat != CONSCIOUS)
return
@@ -1,4 +1,7 @@
var/global/ntnrc_uid = 0
/datum/ntnet_conversation/
var/id = null
var/title = "Untitled Conversation"
var/datum/computer_file/program/chatclient/operator // "Administrator" of this channel. Creator starts as channel's operator,
var/list/messages = list()
@@ -6,6 +9,8 @@
var/password
/datum/ntnet_conversation/New()
id = ntnrc_uid
ntnrc_uid++
if(ntnet_global)
ntnet_global.chat_channels.Add(src)
..()
@@ -28,6 +28,7 @@
// Important hardware (must be installed for computer to work)
var/obj/item/weapon/computer_hardware/processor_unit/processor_unit // CPU. Without it the computer won't run. Better CPUs can run more programs at once.
var/obj/item/weapon/computer_hardware/network_card/network_card // Network Card component of this computer. Allows connection to NTNet
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive // Hard Drive component of this computer. Stores programs and files.
var/obj/item/weapon/computer_hardware/battery_module/battery_module // An internal power source for this computer. Can be recharged.
@@ -36,6 +37,8 @@
var/obj/item/weapon/computer_hardware/nano_printer/nano_printer // Nano Printer component of this computer, for your everyday paperwork needs.
var/obj/item/weapon/computer_hardware/hard_drive/portable/portable_drive // Portable data storage
var/list/idle_threads = list() // Idle programs on background. They still receive process calls but can't be interacted with.
// Eject ID card from computer, if it has ID slot with card inside.
/obj/item/modular_computer/verb/eject_id()
@@ -164,7 +167,7 @@
/obj/item/modular_computer/proc/turn_on(var/mob/user)
var/issynth = issilicon(user) // Robots and AIs get different activation messages.
if((battery_module && battery_module.battery.charge) || check_power_override()) // Battery-run and charged or non-battery but powered by APC.
if(processor_unit && ((battery_module && battery_module.battery.charge) || check_power_override())) // Battery-run and charged or non-battery but powered by APC.
if(issynth)
user << "You send an activation signal to \the [src], turning it on"
else
@@ -188,11 +191,22 @@
kill_program(1)
visible_message("<span class='danger'>\The [src]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.</span>")
for(var/datum/computer_file/program/P in idle_threads)
if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature))
P.kill_program(1)
idle_threads.Remove(P)
visible_message("<span class='danger'>\The [src] screen displays an \"Process [P.filename].[P.filetype] (PID [rand(100,999)]) terminated - Network Error\" error</span>")
if(active_program)
active_program.process_tick()
active_program.ntnet_status = get_ntnet_status()
active_program.computer_emagged = computer_emagged
for(var/datum/computer_file/program/P in idle_threads)
P.process_tick()
P.ntnet_status = get_ntnet_status()
P.computer_emagged = computer_emagged
handle_power() // Handles all computer power interaction
// Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_"
@@ -230,6 +244,17 @@
if(3)
data["PC_ntneticon"] = "sig_lan.gif"
if(idle_threads.len)
var/list/program_headers = list()
for(var/datum/computer_file/program/P in idle_threads)
if(!P.ui_header)
continue
program_headers.Add(list(list(
"icon" = P.ui_header
)))
data["PC_programheaders"] = program_headers
data["PC_stationtime"] = worldtime2text()
data["PC_hasheader"] = 1
data["PC_showexitprogram"] = active_program ? 1 : 0 // Hides "Exit Program" button on mainscreen
@@ -257,9 +282,13 @@
return 0
return ntnet_global.add_log(text, network_card)
/obj/item/modular_computer/proc/shutdown_computer()
/obj/item/modular_computer/proc/shutdown_computer(var/loud = 1)
kill_program(1)
visible_message("\The [src] shuts down.")
for(var/datum/computer_file/program/P in idle_threads)
P.kill_program(1)
idle_threads.Remove(P)
if(loud)
visible_message("\The [src] shuts down.")
enabled = 0
update_icon()
return
@@ -284,6 +313,23 @@
if( href_list["PC_shutdown"] )
shutdown_computer()
return
if( href_list["PC_minimize"] )
var/mob/user = usr
if(!active_program || !processor_unit)
return
if(idle_threads.len >= processor_unit.max_idle_programs)
user << "<span class='notice'>\The [src] displays a \"Maximal CPU load reached. Unable to minimize another program.\" error</span>"
return
idle_threads.Add(active_program)
active_program.running = 0 // Should close any existing UIs
nanomanager.close_uis(active_program.NM ? active_program.NM : active_program)
active_program = null
update_icon()
if(user && istype(user))
ui_interact(user) // Re-open the UI on this computer. It should show the main screen now.
if( href_list["PC_runprogram"] )
var/prog = href_list["PC_runprogram"]
var/datum/computer_file/program/P = null
@@ -299,6 +345,14 @@
if(!P.is_supported_by_hardware(hardware_flag, 1, user))
return
// The program is already running. Resume it.
if(P in idle_threads)
P.running = 1
active_program = P
idle_threads.Remove(P)
update_icon()
return
if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) // The program requires NTNet connection, but we are not connected to NTNet.
user << "<span class='danger'>\The [src]'s screen shows \"NETWORK ERROR - Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\" warning.</span>"
return
@@ -311,9 +365,7 @@
/obj/item/modular_computer/proc/power_failure()
if(enabled) // Shut down the computer
visible_message("<span class='danger'>\The [src]'s screen flickers \"BATTERY CRITICAL\" warning as it shuts down unexpectedly.</span>")
kill_program(1)
enabled = 0
update_icon()
shutdown_computer(0)
// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged
/obj/item/modular_computer/proc/handle_power()
@@ -322,11 +374,10 @@
return 0
var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage
if(network_card && network_card.enabled)
power_usage += network_card.power_usage
if(hard_drive && hard_drive.enabled)
power_usage += hard_drive.power_usage
for(var/obj/item/weapon/computer_hardware/H in get_all_components())
if(H.enabled)
power_usage += H.power_usage
if(battery_module)
battery_module.battery.use(power_usage * CELLRATE)
@@ -440,6 +491,12 @@
return
found = 1
battery_module = H
else if(istype(H, /obj/item/weapon/computer_hardware/processor_unit))
if(processor_unit)
user << "This computer's processor slot is already occupied by \the [processor_unit]."
return
found = 1
processor_unit = H
if(found)
user << "You install \the [H] into \the [src]"
H.holder2 = src
@@ -467,11 +524,15 @@
if(battery_module == H)
battery_module = null
found = 1
if(processor_unit == H)
processor_unit = null
found = 1
critical = 1
if(found)
user << "You remove \the [H] from \the [src]."
H.forceMove(get_turf(src))
H.holder2 = null
if(critical)
if(critical && enabled)
user << "<span class='danger'>\The [src]'s screen freezes for few seconds and then displays an \"HARDWARE ERROR: Critical component disconnected. Please verify component connection and reboot the device. If the problem persists contact technical support for assistance.\" warning.</span>"
kill_program(1)
enabled = 0
@@ -492,6 +553,8 @@
return card_slot
if(battery_module && (battery_module.name == name))
return battery_module
if(processor_unit && (processor_unit.name == name))
return processor_unit
return null
// Returns list of all components
@@ -509,4 +572,6 @@
all_components.Add(card_slot)
if(battery_module)
all_components.Add(battery_module)
if(processor_unit)
all_components.Add(processor_unit)
return all_components
@@ -78,9 +78,7 @@
/obj/item/modular_computer/processor/shutdown_computer()
if(!machinery_computer)
return
kill_program(1)
visible_message("\The [machinery_computer] shuts down.")
enabled = 0
..()
machinery_computer.update_icon()
return
@@ -8,6 +8,7 @@
. = ..()
if(!cpu)
return
cpu.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit(cpu)
if(_has_id_slot)
cpu.card_slot = new/obj/item/weapon/computer_hardware/card_slot(cpu)
if(_has_printer)
@@ -84,8 +84,7 @@
if(cpu && cpu.enabled) // Shut down the computer
visible_message("<span class='danger'>\The [src]'s screen flickers [cpu.battery_module ? "\"BATTERY CRITICAL\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly.</span>")
if(cpu)
cpu.kill_program(1)
cpu.enabled = 0
cpu.shutdown_computer(0)
battery_powered = 0
update_icon()
stat |= NOPOWER
@@ -18,6 +18,8 @@
var/available_on_ntnet = 1 // Whether the program can be downloaded from NTNet. Set to 0 to disable.
var/available_on_syndinet = 0 // Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable.
var/computer_emagged = 0 // Set to 1 if computer that's running us was emagged. Computer updates this every Process() tick
var/ui_header = null // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /nano/images/status_icons. Be careful not to use too large images!
/datum/computer_file/program/New(var/obj/item/modular_computer/comp = null)
..()
@@ -35,6 +37,11 @@
temp.usage_flags = usage_flags
return temp
// Relays icon update to the computer.
/datum/computer_file/program/proc/update_computer_icon()
if(computer)
computer.update_icon()
// Attempts to create a log in global ntnet datum. Returns 1 on success, 0 on fail.
/datum/computer_file/program/proc/generate_network_log(var/text)
if(computer)
@@ -15,18 +15,37 @@
filename = "alarmmonitor"
filedesc = "Alarm Monitoring"
nanomodule_path = /datum/nano_module/alarm_monitor/engineering
program_icon_state = "alarm_monitor"
ui_header = "alarm_green.gif"
program_icon_state = "alert-green"
extended_desc = "This program provides visual interface for station's alarm system."
requires_ntnet = 1
network_destination = "alarm monitoring network"
size = 5
var/has_alert = 0
/datum/computer_file/program/alarm_monitor/process_tick()
..()
var/datum/nano_module/alarm_monitor/NMA = NM
if(istype(NMA) && NMA.has_major_alarms())
if(!has_alert)
program_icon_state = "alert-red"
ui_header = "alarm_red.gif"
update_computer_icon()
has_alert = 1
else
if(has_alert)
program_icon_state = "alert-green"
ui_header = "alarm_green.gif"
update_computer_icon()
has_alert = 0
return 1
/datum/computer_file/program/atmos_control
filename = "atmoscontrol"
filedesc = "Atmosphere Control"
nanomodule_path = /datum/nano_module/atmos_control
program_icon_state = "atmos_control"
extended_desc = "This program allows remote control of air alarms around the station"
extended_desc = "This program allows remote control of air alarms around the station. This program can not be run on tablet computers."
required_access = access_atmospherics
requires_ntnet = 1
network_destination = "atmospheric control system"
@@ -39,7 +58,7 @@
filedesc = "RCON Remote Control"
nanomodule_path = /datum/nano_module/rcon
program_icon_state = "generic"
extended_desc = "This program allows remote control of power distribution systems around the station."
extended_desc = "This program allows remote control of power distribution systems around the station. This program can not be run on tablet computers."
required_access = access_engine
requires_ntnet = 1
network_destination = "RCON remote control system"
@@ -10,6 +10,7 @@
requires_ntnet_feature = NTNET_SOFTWAREDOWNLOAD
available_on_ntnet = 0
nanomodule_path = /datum/nano_module/computer_ntnetdownload/
ui_header = "downloader_finished.gif"
var/datum/computer_file/program/downloaded_file = null
var/hacked_download = 0
var/download_completion = 0 //GQ of downloaded data.
@@ -32,6 +33,8 @@
if(!computer || !computer.hard_drive || !computer.hard_drive.try_store_file(PRG))
return 0
ui_header = "downloader_running.gif"
if(PRG in ntnet_global.available_station_software)
generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from NTNet Software Repository.")
hacked_download = 0
@@ -50,6 +53,7 @@
generate_network_log("Aborted download of file [hacked_download ? "**ENCRYPTED**" : downloaded_file.filename].[downloaded_file.filetype].")
downloaded_file = null
download_completion = 0
ui_header = "downloader_finished.gif"
/datum/computer_file/program/ntnetdownload/proc/complete_file_download()
if(!downloaded_file)
@@ -60,6 +64,7 @@
downloaderror = "I/O ERROR - Unable to save file. Check whether you have enough free space on your hard drive and whether your hard drive is properly connected. If the issue persists contact your system administrator for assistance."
downloaded_file = null
download_completion = 0
ui_header = "downloader_finished.gif"
/datum/computer_file/program/ntnetdownload/process_tick()
if(!downloaded_file)
@@ -7,8 +7,10 @@
requires_ntnet = 1
requires_ntnet_feature = NTNET_COMMUNICATION
network_destination = "NTNRC server"
ui_header = "ntnrc_idle.gif"
available_on_ntnet = 1
nanomodule_path = /datum/nano_module/computer_chatclient/
var/last_message = null // Used to generate the toolbar icon
var/username
var/datum/ntnet_conversation/channel = null
var/operator_mode = 0 // Channel operator mode
@@ -30,7 +32,7 @@
if(href_list["PRG_joinchannel"])
var/datum/ntnet_conversation/C
for(var/datum/ntnet_conversation/chan in ntnet_global.chat_channels)
if(chan.title == href_list["PRG_joinchannel"])
if(chan.id == text2num(href_list["PRG_joinchannel"]))
C = chan
break
@@ -143,6 +145,20 @@
..(href, href_list)
/datum/computer_file/program/chatclient/process_tick()
..()
if(running)
ui_header = "ntnrc_idle.gif"
if(channel)
// Remember the last message. If there is no message in the channel remember null.
last_message = channel.messages.len ? channel.messages[channel.messages.len - 1] : null
else
last_message = null
return 1
if(channel && channel.messages && channel.messages.len)
ui_header = last_message == channel.messages[channel.messages.len - 1] ? "ntnrc_idle.gif" : "ntnrc_new.gif"
else
ui_header = "ntnrc_idle.gif"
/datum/computer_file/program/chatclient/kill_program(var/forced = 0)
if(channel)
@@ -188,7 +204,8 @@
for(var/datum/ntnet_conversation/conv in ntnet_global.chat_channels)
if(conv && conv.title)
all_channels.Add(list(list(
"chan" = conv.title
"chan" = conv.title,
"id" = conv.id
)))
data["all_channels"] = all_channels
@@ -0,0 +1,36 @@
// CPU that allows the computer to run programs.
// Better CPUs are obtainable via research and can run more programs on background.
/obj/item/weapon/computer_hardware/processor_unit
name = "standard processor"
desc = "A standard CPU used in most computers. It can run up to three programs simultaneously."
icon_state = "cpu_normal"
hardware_size = 2
power_usage = 50
critical = 1
var/max_idle_programs = 2 // 2 idle, + 1 active = 3 as said in description.
/obj/item/weapon/computer_hardware/processor_unit/small
name = "standard microprocessor"
desc = "A standard miniaturised CPU used in portable devices. It can run up to two programs simultaneously."
icon_state = "cpu_small"
hardware_size = 1
power_usage = 25
max_idle_programs = 1
/obj/item/weapon/computer_hardware/processor_unit/photonic
name = "photonic processor"
desc = "An advanced experimental CPU that uses photonic core instead of regular circuitry. It can run up to five programs simultaneously, but uses a lot of power."
icon_state = "cpu_normal_photonic"
hardware_size = 2
power_usage = 250
max_idle_programs = 4
/obj/item/weapon/computer_hardware/processor_unit/photonic/small
name = "photonic microprocessor"
desc = "An advanced miniaturised CPU for use in portable devices. It uses photonic core instead of regular circuitry. It can run up to three programs simultaneously."
icon_state = "cpu_small_photonic"
hardware_size = 1
power_usage = 75
max_idle_programs = 2
@@ -19,6 +19,7 @@
var/total_price = 0 // Price of currently vended device.
// Device loadout
var/dev_cpu = 1 // 1: Default, 2: Upgraded
var/dev_battery = 1 // 1: Default, 2: Upgraded, 3: Advanced
var/dev_disk = 1 // 1: Default, 2: Upgraded, 3: Advanced
var/dev_netcard = 0 // 0: None, 1: Basic, 2: Long-Range
@@ -36,6 +37,7 @@
if(fabricated_tablet)
qdel(fabricated_tablet)
fabricated_tablet = null
dev_cpu = 1
dev_battery = 1
dev_disk = 1
dev_netcard = 0
@@ -50,17 +52,25 @@
if(fabricate)
fabricated_laptop = new(src)
total_price = 99
switch(dev_cpu)
if(1)
if(fabricate)
fabricated_laptop.cpu.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(fabricated_laptop.cpu)
if(2)
if(fabricate)
fabricated_laptop.cpu.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit(fabricated_laptop.cpu)
total_price += 299
switch(dev_battery)
if(1) // Basic(750C)
if(fabricate)
fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module(fabricated_tablet)
fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module(fabricated_laptop.cpu)
if(2) // Upgraded(1100C)
if(fabricate)
fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module/advanced(fabricated_tablet)
fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module/advanced(fabricated_laptop.cpu)
total_price += 199
if(3) // Advanced(1500C)
if(fabricate)
fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module/super(fabricated_tablet)
fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module/super(fabricated_laptop.cpu)
total_price += 499
switch(dev_disk)
if(1) // Basic(128GQ)
@@ -100,6 +110,7 @@
else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this.
if(fabricate)
fabricated_tablet = new(src)
fabricated_tablet.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(fabricated_tablet)
total_price = 199
switch(dev_battery)
if(1) // Basic(300C)
@@ -169,6 +180,10 @@
state = 2 // Wait for ID swipe for payment processing
fabricate_and_recalc_price(0)
return 1
if(href_list["hw_cpu"])
dev_cpu = text2num(href_list["hw_cpu"])
fabricate_and_recalc_price(0)
return 1
if(href_list["hw_battery"])
dev_battery = text2num(href_list["hw_battery"])
fabricate_and_recalc_price(0)
@@ -213,6 +228,7 @@
data["hw_tesla"] = dev_tesla
data["hw_nanoprint"] = dev_nanoprint
data["hw_card"] = dev_card
data["hw_cpu"] = dev_cpu
data["totalprice"] = "[total_price]$"
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
@@ -41,6 +41,14 @@
return all_alarms
// Modified version of above proc that uses slightly less resources, returns 1 if there is a major alarm, 0 otherwise.
/datum/nano_module/alarm_monitor/proc/has_major_alarms()
for(var/datum/alarm_handler/AH in alarm_handlers)
if(AH.has_major_alarms())
return 1
return 0
/datum/nano_module/alarm_monitor/proc/minor_alarms()
var/list/all_alarms = new()
for(var/datum/alarm_handler/AH in alarm_handlers)
+10
View File
@@ -43,6 +43,16 @@
/obj/machinery/power/apc/high
cell_type = /obj/item/weapon/cell/high
// Construction site APC, starts turned off
/obj/machinery/power/apc/high/inactive
cell_type = /obj/item/weapon/cell/high
lighting = 0
equipment = 0
environ = 0
locked = 0
coverlocked = 0
start_charge = 100
/obj/machinery/power/apc/super
cell_type = /obj/item/weapon/cell/super
+1 -1
View File
@@ -595,7 +595,7 @@
icon = 'icons/obj/lighting.dmi'
force = 2
throwforce = 5
w_class = 2
w_class = 1
var/status = 0 // LIGHT_OK, LIGHT_BURNED or LIGHT_BROKEN
var/base_state
var/switchcount = 0 // number of times switched
+39
View File
@@ -916,6 +916,45 @@ other types of metals and chemistry for reagents).
build_path = /obj/item/weapon/computer_hardware/battery_module/micro
sort_string = "VBAAU"
/datum/design/item/modularcomponent/cpu/
name = "computer processor unit"
id = "cpu_normal"
req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2)
build_type = IMPRINTER
materials = list(DEFAULT_WALL_MATERIAL = 8000)
chemicals = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/processor_unit
sort_string = "VBAAV"
/datum/design/item/modularcomponent/cpu/small
name = "computer microprocessor unit"
id = "cpu_small"
req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
build_type = IMPRINTER
materials = list(DEFAULT_WALL_MATERIAL = 4000)
chemicals = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/processor_unit/small
sort_string = "VBAAW"
/datum/design/item/modularcomponent/cpu/photonic
name = "computer photonic processor unit"
id = "pcpu_normal"
req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 4)
build_type = IMPRINTER
materials = list(DEFAULT_WALL_MATERIAL = 32000, glass = 8000)
chemicals = list("sacid" = 40)
build_path = /obj/item/weapon/computer_hardware/processor_unit/photonic
sort_string = "VBAAX"
/datum/design/item/modularcomponent/cpu/photonic/small
name = "computer photonic microprocessor unit"
id = "pcpu_small"
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3)
build_type = IMPRINTER
materials = list(DEFAULT_WALL_MATERIAL = 16000, glass = 4000)
chemicals = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/processor_unit/photonic/small
sort_string = "VBAAY"
/*
CIRCUITS BELOW
*/
@@ -30,7 +30,6 @@
icon_state = "satchel"
slot_flags = SLOT_BELT | SLOT_POCKET
w_class = 3
storage_slots = 50
max_storage_space = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class
max_storage_space = 100
max_w_class = 3
can_hold = list(/obj/item/weapon/fossil)
+1 -1
View File
@@ -28,7 +28,7 @@
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/E = tool
user.visible_message("<span class='notice'>[user] has attached [target]'s [E.name] to the [E.amputation_point].</span>>", \
user.visible_message("<span class='notice'>[user] has attached [target]'s [E.name] to the [E.amputation_point].</span>", \
"<span class='notice'>You have attached [target]'s [E.name] to the [E.amputation_point].</span>")
user.drop_from_inventory(E)
E.replaced(target)
+1 -1
View File
@@ -88,7 +88,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\blue [user] has cut away necrotic tissue in [target]'s [affected.name] with \the [tool].", \
"\blue You have cut away necrotic tissue in [target]'s [affected.name] with \the [tool].")
affected.open = 3
affected.status &= ~ORGAN_DEAD
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)