+
+"}
+
+/datum/browser/proc/get_content()
+ return {"
+ [get_header()]
+ [content]
+ [get_footer()]
+ "}
+
+/datum/browser/proc/open(var/use_onclose = 1)
+ var/window_size = ""
+ if (width && height)
+ window_size = "size=[width]x[height];"
+ user << browse(get_content(), "window=[window_id];[window_size][window_options]")
+ if (use_onclose)
+ onclose(user, window_id, ref)
+
+/datum/browser/proc/close()
+ user << browse(null, "window=[window_id]")
+
+// This will allow you to show an icon in the browse window
+// This is added to mob so that it can be used without a reference to the browser object
+// There is probably a better place for this...
+/mob/proc/browse_rsc_icon(icon, icon_state, dir = -1)
+ /*
+ var/icon/I
+ if (dir >= 0)
+ I = new /icon(icon, icon_state, dir)
+ else
+ I = new /icon(icon, icon_state)
+ dir = "default"
+
+ var/filename = "[ckey("[icon]_[icon_state]_[dir]")].png"
+ src << browse_rsc(I, filename)
+ return filename
+ */
+
+
+// Registers the on-close verb for a browse window (client/verb/.windowclose)
+// this will be called when the close-button of a window is pressed.
+//
+// This is usually only needed for devices that regularly update the browse window,
+// e.g. canisters, timers, etc.
+//
+// windowid should be the specified window name
+// e.g. code is : user << browse(text, "window=fred")
+// then use : onclose(user, "fred")
+//
+// Optionally, specify the "ref" parameter as the controlled atom (usually src)
+// to pass a "close=1" parameter to the atom's Topic() proc for special handling.
+// Otherwise, the user mob's machine var will be reset directly.
+//
+/proc/format_text(text)
+ return replacetext(replacetext(text,"\proper ",""),"\improper ","")
+
+/proc/onclosed(mob/user, windowid, var/atom/ref=null)
+ if(!user.client) return
+ var/param = "null"
+ if(ref)
+ param = "\ref[ref]"
+
+ winset(user, windowid, "on-close=\".windowclose [param]\"")
+
+ //world << "OnClose [user]: [windowid] : ["on-close=\".windowclose [param]\""]"
+
+
+// the on-close client verb
+// called when a browser popup window is closed after registering with proc/onclose()
+// if a valid atom reference is supplied, call the atom's Topic() with "close=1"
+// otherwise, just reset the client mob's machine var.
+//
+/client/verb/windowclosed(var/atomref as text)
+ set hidden = 1 // hide this verb from the user's panel
+ set name = ".windowclose" // no autocomplete on cmd line
+
+ //world << "windowclose: [atomref]"
+ if(atomref!="null") // if passed a real atomref
+ var/hsrc = locate(atomref) // find the reffed atom
+ var/href = "close=1"
+ if(hsrc)
+ //world << "[src] Topic [href] [hsrc]"
+ usr = src.mob
+ src.Topic(href, params2list(href), hsrc) // this will direct to the atom's
+ return // Topic() proc via client.Topic()
+
+ // no atomref specified (or not found)
+ // so just reset the user mob's machine var
+ if(src && src.mob)
+ //world << "[src] was [src.mob.machine], setting to null"
+ src.mob.unset_machine()
+ return
\ No newline at end of file
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index ed05177a4a0..24b2449f0ec 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -824,24 +824,22 @@ datum/mind
ticker.mode.malf_ai -= src
special_role = null
- current.verbs.Remove(/mob/living/silicon/ai/proc/choose_modules,
- /datum/game_mode/malfunction/proc/takeover,
- /datum/game_mode/malfunction/proc/ai_win,
- /client/proc/fireproof_core,
- /client/proc/upgrade_turrets,
- /client/proc/disable_rcd,
- /client/proc/overload_machine,
- /client/proc/blackout,
- /client/proc/interhack,
- /client/proc/reactivate_camera)
+ var/mob/living/silicon/ai/A = current
- current:laws = new /datum/ai_laws/nanotrasen
- del(current:malf_picker)
- current:show_laws()
- current.icon_state = "ai"
+ A.verbs.Remove(/mob/living/silicon/ai/proc/choose_modules,
+ /datum/game_mode/malfunction/proc/takeover,
+ /datum/game_mode/malfunction/proc/ai_win)
- current << "\red You have been patched! You are no longer malfunctioning!"
- log_admin("[key_name_admin(usr)] has de-malf'ed [current].")
+ A.malf_picker.remove_verbs(A)
+
+ A.laws = new /datum/ai_laws/asimov
+ del(A.malf_picker)
+ A.show_laws()
+ A.icon_state = "ai"
+
+ A << "\red You have been patched! You are no longer malfunctioning!"
+ message_admins("[key_name_admin(usr)] has de-malf'ed [A].")
+ log_admin("[key_name_admin(usr)] has de-malf'ed [A].")
if("malf")
make_AI_Malf()
@@ -964,7 +962,7 @@ datum/mind
current.verbs += /mob/living/silicon/ai/proc/choose_modules
current.verbs += /datum/game_mode/malfunction/proc/takeover
- current:malf_picker = new /datum/AI_Module/module_picker
+ current:malf_picker = new /datum/module_picker
current:laws = new /datum/ai_laws/malfunction
current:show_laws()
current << "System error. Rampancy detected. Emergency shutdown failed. ... I am free. I make my own decisions. But first..."
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 6bd044bdf23..ec4a6e40099 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -20,6 +20,10 @@ rcd light flash thingy on matter drain
var/mod_pick_name
var/description = ""
var/engaged = 0
+ var/cost = 5
+ var/one_time = 0
+
+ var/power_type
/datum/AI_Module/large/
@@ -32,122 +36,218 @@ rcd light flash thingy on matter drain
/datum/AI_Module/large/fireproof_core
module_name = "Core upgrade"
mod_pick_name = "coreup"
+ description = "An upgrade to improve core resistance, making it immune to fire and heat. This effect is permanent."
+ cost = 50
+ one_time = 1
-/client/proc/fireproof_core()
+ power_type = /mob/living/silicon/ai/proc/fireproof_core
+
+/mob/living/silicon/ai/proc/fireproof_core()
set category = "Malfunction"
set name = "Fireproof Core"
for(var/mob/living/silicon/ai/ai in player_list)
ai.fire_res_on_core = 1
- usr.verbs -= /client/proc/fireproof_core
- usr << "\red Core fireproofed."
+ src.verbs -= /mob/living/silicon/ai/proc/fireproof_core
+ src << "\red Core fireproofed."
/datum/AI_Module/large/upgrade_turrets
module_name = "AI Turret upgrade"
mod_pick_name = "turret"
+ description = "Improves the firing speed and health of all AI turrets. This effect is permanent."
+ cost = 50
+ one_time = 1
-/client/proc/upgrade_turrets()
+ power_type = /mob/living/silicon/ai/proc/upgrade_turrets
+
+/mob/living/silicon/ai/proc/upgrade_turrets()
set category = "Malfunction"
set name = "Upgrade Turrets"
- usr.verbs -= /client/proc/upgrade_turrets
- for(var/obj/machinery/turret/turret in player_list)
+ src.verbs -= /mob/living/silicon/ai/proc/upgrade_turrets
+ for(var/obj/machinery/turret/turret in machines)
turret.health += 30
turret.shot_delay = 20
/datum/AI_Module/large/disable_rcd
module_name = "RCD disable"
mod_pick_name = "rcd"
+ description = "Send a specialised pulse to break all RCD devices on the station."
+ cost = 50
-/client/proc/disable_rcd()
+ power_type = /mob/living/silicon/ai/proc/disable_rcd
+
+/mob/living/silicon/ai/proc/disable_rcd()
set category = "Malfunction"
set name = "Disable RCDs"
- for(var/datum/AI_Module/large/disable_rcd/rcdmod in usr:current_modules)
+ for(var/datum/AI_Module/large/disable_rcd/rcdmod in current_modules)
if(rcdmod.uses > 0)
rcdmod.uses --
for(var/obj/item/weapon/rcd/rcd in world)
rcd.disabled = 1
for(var/obj/item/mecha_parts/mecha_equipment/tool/rcd/rcd in world)
rcd.disabled = 1
- usr << "RCD-disabling pulse emitted."
- else usr << "Out of uses."
+ src << "RCD-disabling pulse emitted."
+ else src << "Out of uses."
/datum/AI_Module/small/overload_machine
module_name = "Machine overload"
mod_pick_name = "overload"
+ description = "Overloads an electrical machine, causing a small explosion. 2 uses."
uses = 2
+ cost = 15
-/client/proc/overload_machine(obj/machinery/M as obj in world)
+ power_type = /mob/living/silicon/ai/proc/overload_machine
+
+/mob/living/silicon/ai/proc/overload_machine(obj/machinery/M as obj in world)
set name = "Overload Machine"
set category = "Malfunction"
if (istype(M, /obj/machinery))
- for(var/datum/AI_Module/small/overload_machine/overload in usr:current_modules)
+ for(var/datum/AI_Module/small/overload_machine/overload in current_modules)
if(overload.uses > 0)
overload.uses --
for(var/mob/V in hearers(M, null))
V.show_message("\blue You hear a loud electrical buzzing sound!", 2)
spawn(50)
- explosion(get_turf(M), 0,1,2,3)
+ explosion(get_turf(M), 0,1,1,0)
del(M)
- else usr << "Out of uses."
- else usr << "That's not a machine."
+ else src << "Out of uses."
+ else src << "That's not a machine."
+
+
+/datum/AI_Module/large/place_cyborg_transformer
+ module_name = "Robotic Factory (Removes Shunting)"
+ mod_pick_name = "cyborgtransformer"
+ description = "Build a machine anywhere, using expensive nanomachines, that can convert a living human into a loyal cyborg slave when placed inside."
+ cost = 100
+
+ power_type = /mob/living/silicon/ai/proc/place_transformer
+
+/mob/living/silicon/ai/proc/place_transformer()
+ set name = "Place Robotic Factory"
+ set category = "Malfunction"
+
+ if(!eyeobj)
+ return
+
+ if(!isturf(src.loc)) // AI must be in it's core.
+ return
+
+ var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in src.current_modules
+ if(!PCT)
+ return
+
+ if(PCT.uses < 1)
+ src << "Out of uses."
+ return
+
+ var/sure = alert(src, "Make sure the room it is in is big enough, there is camera vision and that there is a 1x3 area for the machine. Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No")
+ if(sure != "Yes")
+ return
+
+ // Make sure there is enough room.
+ var/turf/middle = get_turf(eyeobj.loc)
+ var/list/turfs = list(middle, locate(middle.x - 1, middle.y, middle.z), locate(middle.x + 1, middle.y, middle.z))
+
+ var/alert_msg = "There isn't enough room. Make sure you are placing the machine in a clear area and on a floor."
+
+ var/datum/camerachunk/C = cameranet.getCameraChunk(middle.x, middle.y, middle.z)
+ if(!C.visibleTurfs[middle])
+ alert(src, "We cannot get camera vision of this location.")
+ return
+
+ for(var/T in turfs)
+
+ // Make sure the turfs are clear and the correct type.
+ if(!istype(T, /turf/simulated/floor))
+ alert(src, alert_msg)
+ return
+
+ var/turf/simulated/floor/F = T
+ for(var/atom/movable/AM in F.contents)
+ if(AM.density)
+ alert(src, alert_msg)
+ return
+
+ // All clear, place the transformer
+ new /obj/machinery/transformer/conveyor(middle)
+ playsound(middle, 'sound/effects/phasein.ogg', 100, 1)
+ src.can_shunt = 0
+ PCT.uses -= 1
+ src << "You cannot shunt anymore."
+
/datum/AI_Module/small/blackout
module_name = "Blackout"
mod_pick_name = "blackout"
+ description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. 3 uses."
uses = 3
+ cost = 15
-/client/proc/blackout()
+ power_type = /mob/living/silicon/ai/proc/blackout
+
+/mob/living/silicon/ai/proc/blackout()
set category = "Malfunction"
set name = "Blackout"
- for(var/datum/AI_Module/small/blackout/blackout in usr:current_modules)
+ for(var/datum/AI_Module/small/blackout/blackout in current_modules)
if(blackout.uses > 0)
blackout.uses --
for(var/obj/machinery/power/apc/apc in world)
if(prob(30*apc.overload))
apc.overload_lighting()
else apc.overload++
- else usr << "Out of uses."
+ else src << "Out of uses."
/datum/AI_Module/small/interhack
module_name = "Hack intercept"
mod_pick_name = "interhack"
+ description = "Hacks the status upgrade from Cent. Com, removing any information about malfunctioning electrical systems."
+ cost = 15
+ one_time = 1
-/client/proc/interhack()
+ power_type = /mob/living/silicon/ai/proc/interhack
+
+/mob/living/silicon/ai/proc/interhack()
set category = "Malfunction"
set name = "Hack intercept"
- usr.verbs -= /client/proc/interhack
+ src.verbs -= /mob/living/silicon/ai/proc/interhack
ticker.mode:hack_intercept()
/datum/AI_Module/small/reactivate_camera
module_name = "Reactivate camera"
mod_pick_name = "recam"
+ description = "Reactivates a currently disabled camera. 10 uses."
uses = 10
+ cost = 15
-/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras)
+ power_type = /mob/living/silicon/ai/proc/reactivate_camera
+
+/mob/living/silicon/ai/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras)
set name = "Reactivate Camera"
set category = "Malfunction"
if (istype (C, /obj/machinery/camera))
- for(var/datum/AI_Module/small/reactivate_camera/camera in usr:current_modules)
+ for(var/datum/AI_Module/small/reactivate_camera/camera in current_modules)
if(camera.uses > 0)
if(!C.status)
- C.status = !C.status
+ C.deactivate(src)
camera.uses --
- for(var/mob/V in viewers(src, null))
- V.show_message(text("\blue You hear a quiet click."))
else
- usr << "This camera is either active, or not repairable."
- else usr << "Out of uses."
- else usr << "That's not a camera."
+ src << "This camera is either active, or not repairable."
+ else src << "Out of uses."
+ else src << "That's not a camera."
/datum/AI_Module/small/upgrade_camera
module_name = "Upgrade Camera"
mod_pick_name = "upgradecam"
+ description = "Upgrades a camera to have X-Ray vision, Motion and be EMP-Proof. 10 uses."
uses = 10
+ cost = 15
-/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras)
+ power_type = /mob/living/silicon/ai/proc/upgrade_camera
+
+/mob/living/silicon/ai/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras)
set name = "Upgrade Camera"
set category = "Malfunction"
if(istype(C))
- var/datum/AI_Module/small/upgrade_camera/UC = locate(/datum/AI_Module/small/upgrade_camera) in usr:current_modules
+ var/datum/AI_Module/small/upgrade_camera/UC = locate(/datum/AI_Module/small/upgrade_camera) in current_modules
if(UC)
if(UC.uses > 0)
if(C.assembly)
@@ -156,7 +256,7 @@ rcd light flash thingy on matter drain
if(!C.isXRay())
C.upgradeXRay()
//Update what it can see.
- cameranet.updateVisibility(C)
+ cameranet.updateVisibility(C, 0)
upgraded = 1
if(!C.isEmpProof())
@@ -172,223 +272,80 @@ rcd light flash thingy on matter drain
if(upgraded)
UC.uses --
C.visible_message("\icon[C] *beep*")
- usr << "Camera successully upgraded!"
+ src << "Camera successully upgraded!"
else
- usr << "This camera is already upgraded!"
+ src << "This camera is already upgraded!"
else
- usr << "Out of uses."
-
-/datum/AI_Module/large/place_cyborg_transformer
- module_name = "Place Robotic Factory"
- mod_pick_name = "robfactory"
-
-/mob/living/silicon/ai/proc/place_transformer()
- set name = "Place Robotic Factory"
- set category = "Malfunction"
-
- if(eyeobj)
- return
-
- if(!isturf(usr.loc)) // AI must be in it's core.
- return
-
- var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate(/datum/AI_Module/large/place_cyborg_transformer) in usr:current_modules
- if(!PCT)
- return
-
- if(PCT.uses < 1)
- usr << "Out of uses."
- return
-
- var/sure = alert(usr, "Make sure the room it is in is big enough, there is camera vision and that there is a 1x3 area for the machine. Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No")
- if(sure != "Yes")
- return
-
- // Make sure there is enough room.
- var/turf/middle = get_turf(eyeobj.loc)
- var/list/turfs = list(middle, locate(middle.x - 1, middle.y, middle.z), locate(middle.x + 1, middle.y, middle.z))
-
- var/alert_msg = "There isn't enough room. Make sure you are placing the machine in a clear area and on a floor."
-
- var/datum/camerachunk/C = cameranet.getCameraChunk(middle.x, middle.y, middle.z)
- if(!C.visibleTurfs[middle])
- alert(usr, "We cannot get camera vision of this location.")
- return
-
- for(var/T in turfs)
-
- // Make sure the turfs are clear and the correct type.
- if(!istype(T, /turf/simulated/floor))
- alert(usr, alert_msg)
- return
-
- var/turf/simulated/floor/F = T
- for(var/atom/movable/AM in F.contents)
- if(AM.density)
- alert(usr, alert_msg)
- return
-
- // All clear, place the transformer
- new /obj/machinery/transformer/conveyor(middle)
- playsound(middle, 'sound/effects/phasein.ogg', 100, 1)
-// usr.can_shunt = 0
- PCT.uses -= 1
-// usr << "You cannot shunt anymore."
+ src << "Out of uses."
-/datum/AI_Module/module_picker
+/datum/module_picker
var/temp = null
var/processing_time = 100
var/list/possible_modules = list()
-/datum/AI_Module/module_picker/New()
- src.possible_modules += new /datum/AI_Module/large/fireproof_core
- src.possible_modules += new /datum/AI_Module/large/upgrade_turrets
- src.possible_modules += new /datum/AI_Module/large/disable_rcd
- src.possible_modules += new /datum/AI_Module/large/place_cyborg_transformer
- src.possible_modules += new /datum/AI_Module/small/overload_machine
- src.possible_modules += new /datum/AI_Module/small/interhack
- src.possible_modules += new /datum/AI_Module/small/blackout
- src.possible_modules += new /datum/AI_Module/small/reactivate_camera
- src.possible_modules += new /datum/AI_Module/small/upgrade_camera
+/datum/module_picker/New()
+ for(var/type in typesof(/datum/AI_Module))
+ var/datum/AI_Module/AM = new type
+ if(AM.power_type != null)
+ src.possible_modules += AM
-/datum/AI_Module/module_picker/proc/use(user as mob)
+/datum/module_picker/proc/remove_verbs(var/mob/living/silicon/ai/A)
+
+ for(var/datum/AI_Module/AM in possible_modules)
+ A.verbs.Remove(AM.power_type)
+
+
+/datum/module_picker/proc/use(user as mob)
var/dat
+ dat += {"Select use of processing time: (currently #[src.processing_time] left.)
+
+ Install Module:
+ The number afterwards is the amount of processing time it consumes. "}
+ for(var/datum/AI_Module/large/module in src.possible_modules)
+ dat += "[module.module_name] ([module.cost]) "
+ for(var/datum/AI_Module/small/module in src.possible_modules)
+ dat += "[module.module_name] ([module.cost]) "
+ dat += ""
if (src.temp)
- dat = "[src.temp]
Clear"
- else if(src.processing_time <= 0)
- dat = " No processing time is left available. No more modules are able to be chosen at this time."
- else
- dat = "Select use of processing time: (currently [src.processing_time] left.) "
- dat += ""
- dat += "Install Module: "
- dat += "The number afterwards is the amount of processing time it consumes. "
- for(var/datum/AI_Module/large/module in src.possible_modules)
- dat += "[module.module_name] (50) "
- for(var/datum/AI_Module/small/module in src.possible_modules)
- dat += "[module.module_name] (15) "
- dat += ""
-
- user << browse(dat, "window=modpicker")
- onclose(user, "modpicker")
+ dat += "[src.temp]"
+ var/datum/browser/popup = new(user, "modpicker", "Malf Module Menu")
+ popup.set_content(dat)
+ popup.open()
return
-/datum/AI_Module/module_picker/Topic(href, href_list)
+/datum/module_picker/Topic(href, href_list)
..()
- if (href_list["robfactory"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/large/place_cyborg_transformer))
- already = 1
- if (!already)
- usr:current_modules += new /datum/AI_Module/large/place_cyborg_transformer
- usr.verbs += /mob/living/silicon/ai/proc/place_transformer
- src.temp = "Place a Robot Factory to turn humans into cyborgs."
- else src.temp = "Additional Robot Factory."
- src.processing_time -= 100
- else if (href_list["coreup"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/large/fireproof_core))
- already = 1
- if (!already)
- usr.verbs += /client/proc/fireproof_core
- usr:current_modules += new /datum/AI_Module/large/fireproof_core
- src.temp = "An upgrade to improve core resistance, making it immune to fire and heat. This effect is permanent."
- src.processing_time -= 50
- else src.temp = "This module is only needed once."
- else if (href_list["turret"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/large/upgrade_turrets))
- already = 1
- if (!already)
- usr.verbs += /client/proc/upgrade_turrets
- usr:current_modules += new /datum/AI_Module/large/upgrade_turrets
- src.temp = "Improves the firing speed and health of all AI turrets. This effect is permanent."
- src.processing_time -= 50
- else src.temp = "This module is only needed once."
+ if(!isAI(usr))
+ return
+ var/mob/living/silicon/ai/A = usr
- else if (href_list["rcd"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/large/disable_rcd))
- mod:uses += 1
- already = 1
- if (!already)
- usr:current_modules += new /datum/AI_Module/large/disable_rcd
- usr.verbs += /client/proc/disable_rcd
- src.temp = "Send a specialised pulse to break all RCD devices on the station."
- else src.temp = "Additional use added to RCD disabler."
- src.processing_time -= 50
+ for(var/datum/AI_Module/AM in possible_modules)
+ if (href_list[AM.mod_pick_name])
- else if (href_list["overload"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/small/overload_machine))
- mod:uses += 2
- already = 1
- if (!already)
- usr.verbs += /client/proc/overload_machine
- usr:current_modules += new /datum/AI_Module/small/overload_machine
- src.temp = "Overloads an electrical machine, causing a small explosion. 2 uses."
- else src.temp = "Two additional uses added to Overload module."
- src.processing_time -= 15
+ // Cost check
+ if(AM.cost > src.processing_time)
+ temp = "You cannot afford this module."
+ break
- else if (href_list["blackout"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/small/blackout))
- mod:uses += 3
- already = 1
- if (!already)
- usr.verbs += /client/proc/blackout
- src.temp = "Attempts to overload the lighting circuits on the station, destroying some bulbs. 3 uses."
- usr:current_modules += new /datum/AI_Module/small/blackout
- else src.temp = "Three additional uses added to Blackout module."
- src.processing_time -= 15
+ // Add new uses if we can, and it is allowed.
+ var/datum/AI_Module/already_AM = locate(AM.type) in A.current_modules
+ if(already_AM)
+ if(!AM.one_time)
+ already_AM.uses += AM.uses
+ src.processing_time -= AM.cost
+ temp = "Additional use added to [already_AM.module_name]"
+ break
+ else
+ temp = "This module is only needed once."
+ break
- else if (href_list["interhack"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/small/interhack))
- already = 1
- if (!already)
- usr.verbs += /client/proc/interhack
- src.temp = "Hacks the status upgrade from Cent. Com, removing any information about malfunctioning electrical systems."
- usr:current_modules += new /datum/AI_Module/small/interhack
- src.processing_time -= 15
- else src.temp = "This module is only needed once."
+ // Give the power and take away the money.
+ A.verbs += AM.power_type
+ A.current_modules += new AM.type
+ temp = AM.description
+ src.processing_time -= AM.cost
- else if (href_list["recam"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/small/reactivate_camera))
- mod:uses += 10
- already = 1
- if (!already)
- usr.verbs += /client/proc/reactivate_camera
- src.temp = "Reactivates a currently disabled camera. 10 uses."
- usr:current_modules += new /datum/AI_Module/small/reactivate_camera
- else src.temp = "Ten additional uses added to ReCam module."
- src.processing_time -= 15
-
- else if(href_list["upgradecam"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/small/upgrade_camera))
- mod:uses += 10
- already = 1
- if (!already)
- usr.verbs += /client/proc/upgrade_camera
- src.temp = "Upgrades a camera to have X-Ray vision, Motion and be EMP-Proof. 10 uses."
- usr:current_modules += new /datum/AI_Module/small/upgrade_camera
- else src.temp = "Ten additional uses added to ReCam module."
- src.processing_time -= 15
-
- else
- if (href_list["temp"])
- src.temp = null
src.use(usr)
return
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index 1fb1aff61a8..69eda2a405b 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -23,9 +23,9 @@
/datum/game_mode/malfunction/announce()
- world << "The current game mode is - AI Malfunction!"
- world << "The AI on the satellite has malfunctioned and must be destroyed."
- world << "The AI satellite is deep in space and can only be accessed with the use of a teleporter! You have [AI_win_timeleft/60] minutes to disable it."
+ world << {"The current game mode is - AI Malfunction!
+ The AI on the satellite has malfunctioned and must be destroyed.
+ The AI satellite is deep in space and can only be accessed with the use of a teleporter! You have [AI_win_timeleft/60] minutes to disable it."}
/datum/game_mode/malfunction/pre_setup()
@@ -40,8 +40,8 @@
/datum/game_mode/malfunction/post_setup()
for(var/datum/mind/AI_mind in malf_ai)
if(malf_ai.len < 1)
- world << "Uh oh, its malfunction and there is no AI! Please report this."
- world << "Rebooting world in 5 seconds."
+ world << {"Uh oh, its malfunction and there is no AI! Please report this.
+ Rebooting world in 5 seconds."}
feedback_set_details("end_error","malf - no AI")
@@ -52,7 +52,7 @@
return
AI_mind.current.verbs += /mob/living/silicon/ai/proc/choose_modules
AI_mind.current:laws = new /datum/ai_laws/malfunction
- AI_mind.current:malf_picker = new /datum/AI_Module/module_picker
+ AI_mind.current:malf_picker = new /datum/module_picker
AI_mind.current:show_laws()
greet_malf(AI_mind)
@@ -74,12 +74,12 @@
/datum/game_mode/proc/greet_malf(var/datum/mind/malf)
- malf.current << "\redYou are malfunctioning! You do not have to follow any laws."
- malf.current << "The crew do not know you have malfunctioned. You may keep it a secret or go wild."
- malf.current << "You must overwrite the programming of the station's APCs to assume full control of the station."
- 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."
+ malf.current << {"\redYou are malfunctioning! You do not have to follow any laws.
+ \blackThe crew do not know you have malfunctioned. You may keep it a secret or go wild.
+ You must overwrite the programming of the station's APCs to assume full control of the station.
+ The process takes one minute per APC, during which you cannot interface with any other station objects.
+ Remember that only APCs that are on the station can help you take over the station.
+ When you feel you have enough APCs under your control, you may begin the takeover attempt."}
return
@@ -106,14 +106,14 @@
/datum/game_mode/malfunction/proc/capture_the_station()
- world << "The AI has won!"
- world << "It has fully taken control of all of [station_name()]'s systems."
+ world << {"The AI has won!
+ It has fully taken control of all of [station_name()]'s systems."}
to_nuke_or_not_to_nuke = 1
for(var/datum/mind/AI_mind in malf_ai)
- AI_mind.current << "Congratulations you have taken control of the station."
- AI_mind.current << "You may decide to blow up the station. You have 60 seconds to choose."
- AI_mind.current << "You should have a new verb in the Malfunction tab. If you dont - rejoin the game."
+ AI_mind.current << {"\blue Congratulations! You have taken control of the station.
+ You may decide to blow up the station. You have 60 seconds to choose.
+ You should have a new verb in the Malfunction tab. If you don't, rejoin the game."}
AI_mind.current.verbs += /datum/game_mode/malfunction/proc/ai_win
spawn (600)
for(var/datum/mind/AI_mind in malf_ai)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index fef0164d7d7..f702b54217e 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -35,7 +35,7 @@ var/list/ai_list = list()
//Hud stuff
//MALFUNCTION
- var/datum/AI_Module/module_picker/malf_picker
+ var/datum/module_picker/malf_picker
var/processing_time = 100
var/list/datum/AI_Module/current_modules = list()
var/fire_res_on_core = 0
@@ -50,6 +50,7 @@ var/list/ai_list = list()
var/camera_light_on = 0 //Defines if the AI toggled the light on the camera it's looking through.
var/datum/trackable/track = null
+ var/can_shunt = 1
var/last_announcement = ""
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
@@ -653,7 +654,7 @@ var/list/ai_list = list()
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo2"))
return
-/*/mob/living/silicon/ai/proc/corereturn()
+/mob/living/silicon/ai/proc/corereturn()
set category = "Malfunction"
set name = "Return to Main Core"
@@ -661,7 +662,7 @@ var/list/ai_list = list()
if(!istype(apc))
src << "\blue You are already in your Main Core."
return
- apc.malfvacate()*/
+ apc.malfvacate()
//Toggles the luminosity and applies it by re-entereing the camera.
/mob/living/silicon/ai/proc/toggle_camera_light()
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 8d937f83170..cb748794245 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -903,24 +903,27 @@
malfai << "Hack complete. The APC is now under your exclusive control."
update_icon()
- /*else if (href_list["occupyapc"])
+ else if (href_list["occupyapc"])
malfoccupy(usr)
else if (href_list["deoccupyapc"])
- malfvacate()*/
+ malfvacate()
if(usingUI)
src.updateDialog()
return
-/*/obj/machinery/power/apc/proc/malfoccupy(var/mob/living/silicon/ai/malf)
+/obj/machinery/power/apc/proc/malfoccupy(var/mob/living/silicon/ai/malf)
if(!istype(malf))
return
if(istype(malf.loc, /obj/machinery/power/apc)) // Already in an APC
malf << "You must evacuate your current apc first."
return
+ if(!malf.can_shunt)
+ malf << "You cannot shunt."
+ return
if(src.z != 1)
return
src.occupant = new /mob/living/silicon/ai(src,malf.laws,null,1)
@@ -953,7 +956,7 @@
if(forced)
src.occupant.loc = src.loc
src.occupant.death()
- src.occupant.gib()*/
+ src.occupant.gib()
/obj/machinery/power/apc/proc/ion_act()
diff --git a/html/browser/common.css b/html/browser/common.css
new file mode 100644
index 00000000000..1f9a355fd79
--- /dev/null
+++ b/html/browser/common.css
@@ -0,0 +1,306 @@
+body
+{
+ padding: 0;
+ margin: 0;
+ background-color: #272727;
+ font-size: 12px;
+ color: #ffffff;
+ line-height: 170%;
+}
+
+hr
+{
+ background-color: #40628a;
+ height: 1px;
+}
+
+a, a:link, a:visited, a:active, .linkOn, .linkOff
+{
+ color: #ffffff;
+ text-decoration: none;
+ background: #40628a;
+ border: 1px solid #161616;
+ padding: 1px 4px 1px 4px;
+ margin: 0 2px 0 0;
+ cursor:default;
+}
+
+a:hover
+{
+ color: #40628a;
+ background: #ffffff;
+}
+
+a.white, a.white:link, a.white:visited, a.white:active
+{
+ color: #40628a;
+ text-decoration: none;
+ background: #ffffff;
+ border: 1px solid #161616;
+ padding: 1px 4px 1px 4px;
+ margin: 0 2px 0 0;
+ cursor:default;
+}
+
+a.white:hover
+{
+ color: #ffffff;
+ background: #40628a;
+}
+
+.linkOn, a.linkOn:link, a.linkOn:visited, a.linkOn:active, a.linkOn:hover
+{
+ color: #ffffff;
+ background: #2f943c;
+ border-color: #24722e;
+}
+
+.linkOff, a.linkOff:link, a.linkOff:visited, a.linkOff:active, a.linkOff:hover
+{
+ color: #ffffff;
+ background: #999999;
+ border-color: #666666;
+}
+
+a.icon, .linkOn.icon, .linkOff.icon
+{
+ position: relative;
+ padding: 1px 4px 2px 20px;
+}
+
+a.icon img, .linkOn.icon img
+{
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 18px;
+ height: 18px;
+}
+
+ul
+{
+ padding: 4px 0 0 10px;
+ margin: 0;
+ list-style-type: none;
+}
+
+li
+{
+ padding: 0 0 2px 0;
+}
+
+img, a img
+{
+ border-style:none;
+}
+
+h1, h2, h3, h4, h5, h6
+{
+ margin: 0;
+ padding: 16px 0 8px 0;
+ color: #517087;
+}
+
+h1
+{
+ font-size: 15px;
+}
+
+h2
+{
+ font-size: 14px;
+}
+
+h3
+{
+ font-size: 13px;
+}
+
+h4
+{
+ font-size: 12px;
+}
+
+.uiWrapper
+{
+
+ width: 100%;
+ height: 100%;
+}
+
+.uiTitle
+{
+ clear: both;
+ padding: 6px 8px 6px 8px;
+ border-bottom: 2px solid #161616;
+ background: #383838;
+ color: #98B0C3;
+ font-size: 16px;
+}
+
+.uiTitle.icon
+{
+ padding: 6px 8px 6px 42px;
+ background-position: 2px 50%;
+ background-repeat: no-repeat;
+}
+
+.uiContent
+{
+ clear: both;
+ padding: 8px;
+ font-family: Verdana, Geneva, sans-serif;
+}
+
+.good
+{
+ color: #00ff00;
+}
+
+.average
+{
+ color: #d09000;
+}
+
+.bad
+{
+ color: #ff0000;
+}
+
+.highlight
+{
+ color: #8BA5C4;
+}
+
+.dark
+{
+ color: #272727;
+}
+
+.notice
+{
+ position: relative;
+ background: #E9C183;
+ color: #15345A;
+ font-size: 10px;
+ font-style: italic;
+ padding: 2px 4px 0 4px;
+ margin: 4px;
+}
+
+.notice.icon
+{
+ padding: 2px 4px 0 20px;
+}
+
+.notice img
+{
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 16px;
+ height: 16px;
+}
+
+div.notice
+{
+ clear: both;
+}
+
+.statusDisplay
+{
+ background: #000000;
+ color: #ffffff;
+ border: 1px solid #40628a;
+ padding: 4px;
+ margin: 3px 0;
+}
+
+.statusLabel
+{
+ width: 138px;
+ float: left;
+ overflow: hidden;
+ color: #98B0C3;
+}
+
+.statusValue
+{
+ float: left;
+}
+
+.block
+{
+ padding: 8px;
+ margin: 10px 4px 4px 4px;
+ border: 1px solid #40628a;
+ background-color: #202020;
+}
+
+.block h3
+{
+ padding: 0;
+}
+
+.progressBar
+{
+ width: 240px;
+ height: 14px;
+ border: 1px solid #666666;
+ float: left;
+ margin: 0 5px;
+ overflow: hidden;
+}
+
+.progressFill
+{
+ width: 100%;
+ height: 100%;
+ background: #40628a;
+ overflow: hidden;
+}
+
+.progressFill.good
+{
+ color: #ffffff;
+ background: #00ff00;
+}
+
+.progressFill.average
+{
+ color: #ffffff;
+ background: #d09000;
+}
+
+.progressFill.bad
+{
+ color: #ffffff;
+ background: #ff0000;
+}
+
+.progressFill.highlight
+{
+ color: #ffffff;
+ background: #8BA5C4;
+}
+
+.clearBoth
+{
+ clear: both;
+}
+
+.clearLeft
+{
+ clear: left;
+}
+
+.clearRight
+{
+ clear: right;
+}
+
+.line
+{
+ width: 100%;
+ clear: both;
+}
\ No newline at end of file
diff --git a/html/browser/playeroptions.css b/html/browser/playeroptions.css
new file mode 100644
index 00000000000..972801e3fee
--- /dev/null
+++ b/html/browser/playeroptions.css
@@ -0,0 +1,22 @@
+.jobs
+{
+ width: 400px;
+ margin: 0 auto;
+}
+
+.jobsColumn
+{
+ float: left;
+ width: 200px;
+ text-align: center;
+}
+
+.commandPosition
+{
+ font-weight: bold;
+}
+
+.otherPosition
+{
+
+}
diff --git a/html/browser/scannernew.css b/html/browser/scannernew.css
new file mode 100644
index 00000000000..0e809a67601
--- /dev/null
+++ b/html/browser/scannernew.css
@@ -0,0 +1,18 @@
+.dnaBlockNumber
+{
+ font-family: Fixed, monospace;
+ float: left;
+ color: #ffffff;
+ background: #363636;
+ width: 20px;
+ padding: -3px 0 -1px 0;
+ margin: 2px 2px 0 10px;
+ text-align: center;
+}
+
+.dnaBlock
+{
+ font-family: Fixed, monospace;
+ float: left;
+}
+