Merge remote-tracking branch 'upstream/dev' into power-net

Conflicts:
	code/ATMOSPHERICS/components/binary_devices/pump.dm
	code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
	code/ATMOSPHERICS/components/unary/vent_pump.dm
	code/ATMOSPHERICS/pipes.dm
This commit is contained in:
mwerezak
2014-07-18 15:02:07 -04:00
77 changed files with 1578 additions and 1038 deletions

View File

@@ -17,4 +17,5 @@ install:
- cd ..
script:
- (! grep -q 'step_[xy]' maps/tgstation2.dmm)
- DreamMaker baystation12.dme

View File

@@ -1,6 +1,9 @@
// BEGIN_INTERNALS
/*
MAP_ICON_TYPE: 0
LAST_COMPILE_VERSION: 506.1247
DIR: maps
LAST_COMPILE_TIME: 1405542427
AUTO_FILE_DIR: OFF
*/
// END_INTERNALS

View File

@@ -42,7 +42,6 @@ Thus, the two variables affect pump operation are set in New():
on = 1
/obj/machinery/atmospherics/binary/pump/update_icon()
if(!powered())
icon_state = "off"

View File

@@ -85,6 +85,11 @@
/obj/machinery/atmospherics/unary/vent_pump/update_icon(var/safety = 0)
if(!check_icon_cache())
return
if (!node)
on = 0
//broadcast_status() // from now air alarm/control computer should request update purposely --rastaf0
if(!on)
return 0
overlays.Cut()

View File

@@ -134,7 +134,7 @@
/obj/machinery/atmospherics/pipe/simple
icon = 'icons/atmos/pipes.dmi'
icon_state = "intact"
icon_state = ""
name = "pipe"
desc = "A one meter section of regular pipe"
@@ -306,6 +306,7 @@
return null
/obj/machinery/atmospherics/pipe/simple/visible
icon_state = "intact"
level = 2
/obj/machinery/atmospherics/pipe/simple/visible/scrubbers
@@ -329,6 +330,7 @@
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/simple/hidden
icon_state = "intact"
level = 1
alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game
@@ -367,7 +369,7 @@
/obj/machinery/atmospherics/pipe/manifold
icon = 'icons/atmos/manifold.dmi'
icon_state = "map"
icon_state = ""
name = "pipe manifold"
desc = "A manifold composed of regular pipes"
@@ -527,6 +529,7 @@
update_icon()
/obj/machinery/atmospherics/pipe/manifold/visible
icon_state = "map"
level = 2
/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers
@@ -550,6 +553,7 @@
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/manifold/hidden
icon_state = "map"
level = 1
alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game
@@ -575,7 +579,7 @@
/obj/machinery/atmospherics/pipe/manifold4w
icon = 'icons/atmos/manifold.dmi'
icon_state = "map_4way"
icon_state = ""
name = "4-way pipe manifold"
desc = "A manifold composed of regular pipes"
@@ -722,6 +726,7 @@
update_icon()
/obj/machinery/atmospherics/pipe/manifold4w/visible
icon_state = "map_4way"
level = 2
/obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers
@@ -745,6 +750,7 @@
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/manifold4w/hidden
icon_state = "map_4way"
level = 1
alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game

View File

@@ -52,9 +52,11 @@
icon_state = "soapnt"
/obj/item/weapon/soap/deluxe
desc = "A deluxe Waffle Co. brand bar of soap. Smells of condoms."
icon_state = "soapdeluxe"
/obj/item/weapon/soap/deluxe/New()
desc = "A deluxe Waffle Co. brand bar of soap. Smells of [pick("lavender", "vanilla", "strawberry", "chocolate" ,"space")]."
/obj/item/weapon/soap/syndie
desc = "An untrustworthy bar of soap. Smells of fear."
icon_state = "soapsyndie"

View File

@@ -35,6 +35,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/debug = 0
var/powerupdate = 10 //We give everything 10 ticks to settle out it's power usage.
var/requires_power = 1
var/unlimited_power = 0
var/always_unpowered = 0 //this gets overriden to 1 for space in area/New()
var/power_equip = 1
@@ -364,6 +365,7 @@ var/list/ghostteleportlocs = list()
name = "\improper Syndicate Mothership"
icon_state = "syndie-ship"
requires_power = 0
unlimited_power = 1
/area/syndicate_mothership/control
name = "\improper Syndicate Control Room"
@@ -436,6 +438,7 @@ var/list/ghostteleportlocs = list()
name = "\improper Syndicate Station"
icon_state = "yellow"
requires_power = 0
unlimited_power = 1
/area/syndicate_station/start
name = "\improper Syndicate Forward Operating Base"

View File

@@ -124,7 +124,7 @@
del(A)
continue
var/obj/effect/landmark/uplinklocker = locate("landmark*Syndicate-Uplink") //i will be rewriting this shortly
var/obj/effect/landmark/uplinkdevice = locate("landmark*Syndicate-Uplink") //i will be rewriting this shortly
var/obj/effect/landmark/nuke_spawn = locate("landmark*Nuclear-Bomb")
var/nuke_code = "[rand(10000, 99999)]"
@@ -153,8 +153,9 @@
update_all_synd_icons()
if(uplinklocker)
new /obj/structure/closet/syndicate/nuclear(uplinklocker.loc)
if(uplinkdevice)
var/obj/item/device/radio/uplink/U = new(uplinkdevice.loc)
U.hidden_uplink.uses = 40
if(nuke_spawn && synd_spawn.len > 0)
var/obj/machinery/nuclearbomb/the_bomb = new /obj/machinery/nuclearbomb(nuke_spawn.loc)
the_bomb.r_code = nuke_code
@@ -166,6 +167,7 @@
/datum/game_mode/proc/prepare_syndicate_leader(var/datum/mind/synd_mind, var/nuke_code)
var/obj/effect/landmark/code_spawn = locate("landmark*Nuclear-Code")
if (nuke_code)
synd_mind.store_memory("<B>Syndicate Nuclear Bomb Code</B>: [nuke_code]", 0, 0)
synd_mind.current << "The nuclear authorization code is: <B>[nuke_code]</B>"
@@ -173,7 +175,7 @@
P.info = "The nuclear authorization code is: <b>[nuke_code]</b>"
P.name = "nuclear bomb code"
if (ticker.mode.config_tag=="nuclear")
P.loc = synd_mind.current.loc
P.loc = code_spawn.loc
else
var/mob/living/carbon/human/H = synd_mind.current
P.loc = H.loc
@@ -230,6 +232,7 @@
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/c20r(synd_mob), slot_belt)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(synd_mob.back), slot_in_backpack)
/* Commented; nukes now have a suit cycler for changing rig-suits, they don't need to spawn with them
var/obj/item/clothing/suit/space/rig/syndi/new_suit = new(synd_mob)
var/obj/item/clothing/head/helmet/space/rig/syndi/new_helmet = new(synd_mob)
@@ -245,8 +248,8 @@
if("Skrell")
new_suit.species_restricted = list("Skrell")
synd_mob.equip_to_slot_or_del(new_suit, slot_wear_suit)
synd_mob.equip_to_slot_or_del(new_helmet, slot_head)
synd_mob.equip_to_slot_or_del(new_suit, slot_in_backpack)
synd_mob.equip_to_slot_or_del(new_helmet, slot_in_backpack)*/
// var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(synd_mob)
// E.imp_in = synd_mob

View File

@@ -309,10 +309,18 @@
if(e.open)
open = "Open:"
switch (e.germ_level)
if (INFECTION_LEVEL_ONE + 50 to INFECTION_LEVEL_TWO)
if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200)
infected = "Mild Infection:"
if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_THREE)
if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300)
infected = "Mild Infection+:"
if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400)
infected = "Mild Infection++:"
if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200)
infected = "Acute Infection:"
if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300)
infected = "Acute Infection+:"
if (INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_TWO + 400)
infected = "Acute Infection++:"
if (INFECTION_LEVEL_THREE to INFINITY)
infected = "Septic:"
@@ -341,10 +349,18 @@
var/infection = "None"
switch (i.germ_level)
if (1 to INFECTION_LEVEL_TWO)
if (1 to INFECTION_LEVEL_ONE + 200)
infection = "Mild Infection:"
if (INFECTION_LEVEL_TWO to INFINITY)
if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300)
infection = "Mild Infection+:"
if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400)
infection = "Mild Infection++:"
if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200)
infection = "Acute Infection:"
if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300)
infection = "Acute Infection+:"
if (INFECTION_LEVEL_TWO + 300 to INFINITY)
infection = "Acute Infection++:"
dat += "<tr>"
dat += "<td>[i.name]</td><td>N/A</td><td>[i.damage]</td><td>[infection]:[mech]</td><td></td>"

View File

@@ -1,3 +1,7 @@
#define CONTROL_POD_DOORS 0
#define CONTROL_NORMAL_DOORS 1
#define CONTROL_EMITTERS 2
/obj/machinery/door_control
name = "remote door-control"
desc = "It controls doors, remotely."
@@ -7,7 +11,7 @@
power_channel = ENVIRON
var/id = null
var/range = 10
var/normaldoorcontrol = 0
var/normaldoorcontrol = CONTROL_POD_DOORS
var/desiredstate = 0 // Zero is closed, 1 is open.
var/specialfunctions = 1
/*
@@ -63,8 +67,59 @@
playsound(src.loc, "sparks", 100, 1)
return src.attack_hand(user)
/obj/machinery/door_control/proc/handle_door()
for(var/obj/machinery/door/airlock/D in range(range))
if(D.id_tag == src.id)
if(specialfunctions & OPEN)
if (D.density)
spawn(0)
D.open()
return
else
spawn(0)
D.close()
return
if(desiredstate == 1)
if(specialfunctions & IDSCAN)
D.aiDisabledIdScanner = 1
if(specialfunctions & BOLTS)
D.lock()
if(specialfunctions & SHOCK)
D.secondsElectrified = -1
if(specialfunctions & SAFE)
D.safe = 0
else
if(specialfunctions & IDSCAN)
D.aiDisabledIdScanner = 0
if(specialfunctions & BOLTS)
if(!D.isWireCut(4) && D.arePowerSystemsOn())
D.unlock()
if(specialfunctions & SHOCK)
D.secondsElectrified = 0
if(specialfunctions & SAFE)
D.safe = 1
/obj/machinery/door_control/proc/handle_pod()
for(var/obj/machinery/door/poddoor/M in world)
if(M.id == src.id)
if(M.density)
spawn(0)
M.open()
return
else
spawn(0)
M.close()
return
/obj/machinery/door_control/proc/handle_emitters(mob/user as mob)
for(var/obj/machinery/power/emitter/E in range(range))
if(E.id == src.id)
spawn(0)
E.activate(user)
return
/obj/machinery/door_control/attack_hand(mob/user as mob)
src.add_fingerprint(usr)
src.add_fingerprint(user)
if(stat & (NOPOWER|BROKEN))
return
@@ -77,49 +132,13 @@
icon_state = "doorctrl1"
add_fingerprint(user)
if(normaldoorcontrol)
for(var/obj/machinery/door/airlock/D in range(range))
if(D.id_tag == src.id)
if(specialfunctions & OPEN)
if (D.density)
spawn(0)
D.open()
return
else
spawn(0)
D.close()
return
if(desiredstate == 1)
if(specialfunctions & IDSCAN)
D.aiDisabledIdScanner = 1
if(specialfunctions & BOLTS)
D.lock()
if(specialfunctions & SHOCK)
D.secondsElectrified = -1
if(specialfunctions & SAFE)
D.safe = 0
else
if(specialfunctions & IDSCAN)
D.aiDisabledIdScanner = 0
if(specialfunctions & BOLTS)
if(!D.isWireCut(4) && D.arePowerSystemsOn())
D.unlock()
if(specialfunctions & SHOCK)
D.secondsElectrified = 0
if(specialfunctions & SAFE)
D.safe = 1
else
for(var/obj/machinery/door/poddoor/M in world)
if (M.id == src.id)
if (M.density)
spawn( 0 )
M.open()
return
else
spawn( 0 )
M.close()
return
switch(normaldoorcontrol)
if(CONTROL_NORMAL_DOORS)
handle_door()
if(CONTROL_POD_DOORS)
handle_pod()
if(CONTROL_EMITTERS)
handle_emitters(user)
desiredstate = !desiredstate
spawn(15)

View File

@@ -108,7 +108,9 @@
//are we ready for undocking?
/datum/computer/file/embedded_program/docking/airlock/ready_for_undocking()
return airlock_program.check_doors_secured()
var/ext_closed = airlock_program.check_exterior_door_secured()
var/int_closed = airlock_program.check_interior_door_secured()
return (ext_closed || int_closed)
//An airlock controller to be used by the airlock-based docking port controller.
//Same as a regular airlock controller but allows disabling of the regular airlock functions when docking

View File

@@ -35,10 +35,10 @@
if (istype(M, /obj/machinery/embedded_controller/radio/airlock)) //if our controller is an airlock controller than we can auto-init our tags
var/obj/machinery/embedded_controller/radio/airlock/controller = M
tag_exterior_door = controller.tag_exterior_door
tag_interior_door = controller.tag_interior_door
tag_airpump = controller.tag_airpump
tag_chamber_sensor = controller.tag_chamber_sensor
tag_exterior_door = controller.tag_exterior_door? controller.tag_exterior_door : "[id_tag]_outer"
tag_interior_door = controller.tag_interior_door? controller.tag_interior_door : "[id_tag]_inner"
tag_airpump = controller.tag_airpump? controller.tag_airpump : "[id_tag]_pump"
tag_chamber_sensor = controller.tag_chamber_sensor? controller.tag_chamber_sensor : "[id_tag]_sensor"
tag_exterior_sensor = controller.tag_exterior_sensor
tag_interior_sensor = controller.tag_interior_sensor
memory["secure"] = controller.tag_secure
@@ -248,9 +248,15 @@
return (state == STATE_WAIT && target_state == TARGET_NONE)
//are the doors closed and locked?
/datum/computer/file/embedded_program/airlock/proc/check_exterior_door_secured()
return (memory["exterior_status"]["state"] == "closed" && memory["exterior_status"]["lock"] == "locked")
/datum/computer/file/embedded_program/airlock/proc/check_interior_door_secured()
return (memory["interior_status"]["state"] == "closed" && memory["interior_status"]["lock"] == "locked")
/datum/computer/file/embedded_program/airlock/proc/check_doors_secured()
var/ext_closed = (memory["exterior_status"]["state"] == "closed" && memory["exterior_status"]["lock"] == "locked")
var/int_closed = (memory["interior_status"]["state"] == "closed" && memory["interior_status"]["lock"] == "locked")
var/ext_closed = check_exterior_door_secured()
var/int_closed = check_interior_door_secured()
return (ext_closed && int_closed)
/datum/computer/file/embedded_program/airlock/proc/signalDoor(var/tag, var/command)

View File

@@ -1,5 +1,6 @@
//This controller goes on the escape pod itself
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod
name = "escape pod controller"
var/datum/shuttle/ferry/escape_pod/pod
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)

View File

@@ -58,7 +58,7 @@
if (istype(M, /obj/machinery/embedded_controller/radio/simple_docking_controller))
var/obj/machinery/embedded_controller/radio/simple_docking_controller/controller = M
tag_door = controller.tag_door
tag_door = controller.tag_door? controller.tag_door : "[id_tag]_hatch"
spawn(10)
signal_door("update") //signals connected doors to update their status

View File

@@ -28,7 +28,7 @@ obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob)
if(!isarea(a))
user << "\red The [name] blinks red as you try to insert the item!"
return
if(a.power_equip == 0)
if(a.power_equip == 0 && !a.unlimited_power)
user << "\red The [name] blinks red as you try to insert the item!"
return
@@ -59,7 +59,7 @@ obj/machinery/recharger/attack_hand(mob/user as mob)
if(charging)
charging.update_icon()
charging.loc = loc
user.put_in_hands(charging)
charging = null
update_icon()

View File

@@ -21,6 +21,19 @@
if(istype(P, /obj/item/device/multitool))
attack_hand(user)
// REPAIRING: Use Nanopaste to repair 10-20 integrity points.
if(istype(P, /obj/item/stack/nanopaste))
var/obj/item/stack/nanopaste/T = P
if (integrity < 100) //Damaged, let's repair!
integrity = between(0, integrity + rand(10,20), 100)
T.use(1)
usr << "You apply the Nanopaste to [src], repairing some of the damage."
else
usr << "This machine is already in perfect condition."
return
switch(construct_op)
if(0)
if(istype(P, /obj/item/weapon/screwdriver))

View File

@@ -213,11 +213,20 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/proc/checkheat()
// Checks heat from the environment and applies any integrity damage
var/datum/gas_mixture/environment = loc.return_air()
var/damage_chance = 0 // Percent based chance of applying 1 integrity damage this tick
switch(environment.temperature)
if(T0C to (T20C + 20))
integrity = between(0, integrity, 100)
if((T20C + 20) to (T0C + 70))
integrity = max(0, integrity - 1)
if((T0C + 40) to (T0C + 70)) // 40C-70C, minor overheat, 10% chance of taking damage
damage_chance = 10
if((T0C + 70) to (T0C + 130)) // 70C-130C, major overheat, 25% chance of taking damage
damage_chance = 25
if((T0C + 130) to (T0C + 200)) // 130C-200C, dangerous overheat, 50% chance of taking damage
damage_chance = 50
if((T0C + 200) to INFINITY) // More than 200C, INFERNO. Takes damage every tick.
damage_chance = 100
if (damage_chance && prob(damage_chance))
integrity = between(0, integrity - 1, 100)
if(delay)
delay--
else

View File

@@ -303,4 +303,3 @@
for(var/mob/M in src)
M.emp_act(severity)
..()

View File

@@ -32,9 +32,9 @@
/obj/item/weapon/kitchen/utensil/New()
if (prob(60))
src.pixel_y = rand(0, 4)
return
create_reagents(5)
return
/obj/item/weapon/kitchen/utensil/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M))

View File

@@ -25,6 +25,19 @@
new /obj/item/clothing/shoes/magboots(src)
/obj/structure/closet/syndicate/suit
desc = "It's a storage unit for rig suits."
/obj/structure/closet/syndicate/suit/New()
..()
sleep(2)
new /obj/item/weapon/tank/jetpack/oxygen(src)
new /obj/item/clothing/shoes/magboots(src)
new /obj/item/clothing/suit/space/rig/syndi(src)
new /obj/item/clothing/mask/gas/syndicate(src)
new /obj/item/clothing/head/helmet/space/rig/syndi(src)
/obj/structure/closet/syndicate/nuclear
desc = "It's a storage unit for nuclear-operative gear."

View File

@@ -752,7 +752,7 @@
name = "Robotics labcoat"
desc = "A labcoat with a few markings denoting it as the labcoat of roboticist."
icon = 'icons/obj/custom_items.dmi'
icon_state = "aeneasrinil_open"
icon_state = "aeneasrinil"
/obj/item/clothing/suit/storage/labcoat/fluff/pink //spaceman96: Trenna Seber
name = "pink labcoat"

View File

@@ -54,7 +54,7 @@
speech_verb = "shrieks"
colour = "vox"
key = "v"
flags = RESTRICTED
flags = RESTRICTED | UNTRANSLATABLE
/datum/language/diona
name = "Rootspeak"
@@ -62,7 +62,7 @@
speech_verb = "creaks and rustles"
colour = "soghun"
key = "q"
flags = RESTRICTED
flags = RESTRICTED | UNTRANSLATABLE
/datum/language/human
name = "Sol Common"
@@ -106,7 +106,7 @@
// Can we speak this language, as opposed to just understanding it?
/mob/proc/can_speak(datum/language/speaking)
return (universal_speak || speaking in src.languages)
return ((universal_speak && !(speaking.flags & UNTRANSLATABLE)) || speaking in src.languages)
//TBD
/mob/verb/check_languages()

View File

@@ -92,7 +92,7 @@ var/list/department_radio_keys = list(
if (speaking.flags & SIGNLANG)
say_signlang(message, pick(speaking.signlang_verb), speaking)
return
return 1
//speaking into radios
if(used_radios.len)
@@ -166,6 +166,7 @@ var/list/department_radio_keys = list(
O.hear_talk(src, message, verb, speaking)
log_say("[name]/[key] : [message]")
return 1
/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language)
for (var/mob/O in viewers(src, null))

View File

@@ -27,6 +27,7 @@ var/list/ai_list = list()
var/viewalerts = 0
var/lawcheck[1]
var/ioncheck[1]
var/lawchannel = "Common" // Default channel on which to state laws
var/icon/holo_icon//Default is assigned when AI is created.
var/obj/item/device/pda/ai/aiPDA = null
var/obj/item/device/multitool/aiMulti = null
@@ -103,7 +104,6 @@ var/list/ai_list = list()
add_language("Siik'maas", 0)
add_language("Siik'tajr", 0)
add_language("Skrellian", 0)
add_language("Rootspeak", 0)
add_language("Tradeband", 1)
add_language("Gutter", 0)
@@ -390,6 +390,13 @@ var/list/ai_list = list()
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
checklaws()
if (href_list["lawr"]) // Selects on which channel to state laws
var/setchannel = input(usr, "Specify channel.", "Channel selection") in list("State","Common","Science","Command","Medical","Engineering","Security","Supply","Binary","Holopad", "Cancel")
if(setchannel == "Cancel")
return
lawchannel = setchannel
checklaws()
//Uncomment this line of code if you are enabling the AI Vocal (VOX) announcements.
/*
if(href_list["say_word"])

View File

@@ -51,24 +51,33 @@
src.laws_sanity_check()
src.laws.clear_supplied_laws()
/mob/living/silicon/ai/proc/statelaws() // -- TLE
// set category = "AI Commands"
// set name = "State Laws"
src.say("Current Active Laws:")
/var/prefix = ""
switch(lawchannel)
if("Common") prefix = ";"
if("Science") prefix = ":n "
if("Command") prefix = ":c "
if("Medical") prefix = ":m "
if("Engineering") prefix = ":e "
if("Security") prefix = ":s "
if("Supply") prefix = ":u "
if("Binary") prefix = ":b "
if("Holopad") prefix = ":h "
else prefix = ""
if(src.say("[prefix]Current Active Laws:") != 1)
return
//src.laws_sanity_check()
//src.laws.show_laws(world)
var/number = 1
sleep(10)
if (src.laws.zeroth)
if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite
src.say("0. [src.laws.zeroth]")
src.say("[prefix]0. [src.laws.zeroth]")
sleep(10)
for (var/index = 1, index <= src.laws.ion.len, index++)
@@ -76,7 +85,7 @@
var/num = ionnum()
if (length(law) > 0)
if (src.ioncheck[index] == "Yes")
src.say("[num]. [law]")
src.say("[prefix][num]. [law]")
sleep(10)
for (var/index = 1, index <= src.laws.inherent.len, index++)
@@ -84,22 +93,20 @@
if (length(law) > 0)
if (src.lawcheck[index+1] == "Yes")
src.say("[number]. [law]")
src.say("[prefix][number]. [law]")
sleep(10)
number++
for (var/index = 1, index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index]
if (length(law) > 0)
if(src.lawcheck.len >= number+1)
if (src.lawcheck[number+1] == "Yes")
src.say("[number]. [law]")
src.say("[prefix][number]. [law]")
sleep(10)
number++
/mob/living/silicon/ai/verb/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
set category = "AI Commands"
set name = "State Laws"
@@ -144,6 +151,8 @@
src.lawcheck[number+1] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
number++
list += {"<br><br><A href='byond://?src=\ref[src];laws=1'>State Laws</A>"}
list += {"<br><A href='byond://?src=\ref[src];lawr=1'>Channel: [src.lawchannel]</A><br>"}
list += {"<A href='byond://?src=\ref[src];laws=1'>State Laws</A>"}
usr << browse(list, "window=laws")

View File

@@ -1,9 +1,8 @@
/mob/living/silicon/ai/say(var/message)
if(parent && istype(parent) && parent.stat != 2)
parent.say(message)
return
return parent.say(message)
//If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
..(message)
return ..(message)
// These Verbs are commented out since we've disabled the AI vocal (VOX) announcements.
// If you re-enable them there is 3 lines in ai.dm Topic() that you need to uncomment as well.

View File

@@ -1,10 +1,12 @@
/mob/living/silicon/pai
name = "pAI"
icon = 'icons/mob/mob.dmi'//
icon_state = "shadow"
icon = 'icons/mob/pai.dmi'
icon_state = "repairbot"
robot_talk_understand = 0
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
small = 1
pass_flags = 1
var/network = "SS13"
var/obj/machinery/camera/current = null
@@ -15,10 +17,21 @@
var/obj/item/device/paicard/card // The card we inhabit
var/obj/item/device/radio/radio // Our primary radio
var/speakStatement = "states"
var/speakExclamation = "declares"
var/speakQuery = "queries"
var/chassis = "repairbot" // A record of your chosen chassis.
var/global/list/possible_chassis = list(
"Drone" = "repairbot",
"Cat" = "cat",
"Mouse" = "mouse",
"Monkey" = "monkey"
)
var/global/list/possible_say_verbs = list(
"Robotic" = list("states","declares","queries"),
"Natural" = list("says","yells","asks"),
"Beep" = list("beeps","beeps loudly","boops"),
"Chirp" = list("chirps","chirrups","cheeps"),
"Feline" = list("purrs","yowls","meows")
)
var/obj/item/weapon/pai_cable/cable // The cable we produce and use when door or camera jacking
@@ -54,6 +67,7 @@
/mob/living/silicon/pai/New(var/obj/item/device/paicard)
canmove = 0
src.loc = paicard
card = paicard
@@ -68,6 +82,10 @@
add_language("Tradeband", 1)
add_language("Gutter", 1)
verbs += /mob/living/silicon/pai/proc/fold_out
verbs += /mob/living/silicon/pai/proc/choose_chassis
verbs += /mob/living/silicon/pai/proc/choose_verbs
//PDA
pda = new(src)
spawn(5)
@@ -113,7 +131,9 @@
return 0
/mob/living/silicon/pai/restrained()
return 0
if(istype(src.loc,/obj/item/device/paicard))
return 0
..()
/mob/living/silicon/pai/emp_act(severity)
// Silence for 2 minutes
@@ -231,7 +251,6 @@
src.reset_view(C)
return 1
/mob/living/silicon/pai/cancel_camera()
set category = "pAI Commands"
set name = "Cancel Camera View"
@@ -275,3 +294,144 @@
card.setPersonality(pai)
*/
// Procs/code after this point is used to convert the stationary pai item into a
// mobile pai mob. This also includes handling some of the general shit that can occur
// to it. Really this deserves its own file, but for the moment it can sit here. ~ Z
/mob/living/silicon/pai/proc/fold_out()
set category = "pAI Commands"
set name = "Unfold Chassis"
if(stat || sleeping || paralysis || weakened)
return
if(src.loc != card)
return
if(world.time <= last_special)
return
last_special = world.time + 100
verbs -= /mob/living/silicon/pai/proc/fold_out
verbs += /mob/living/silicon/pai/proc/fold_up
var/turf/T = get_turf(src)
if(istype(T)) T.visible_message("<b>[src]</b> folds outwards, expanding into a mobile form.")
canmove = 1
//I'm not sure how much of this is necessary, but I would rather avoid issues.
if(istype(card.loc,/mob))
var/mob/M = card.loc
M.drop_item(card)
src.client.perspective = EYE_PERSPECTIVE
src.client.eye = src
src.forceMove(get_turf(card))
card.forceMove(src)
/mob/living/silicon/pai/proc/fold_up()
set category = "pAI Commands"
set name = "Collapse Chassis"
if(stat || sleeping || paralysis || weakened)
return
if(src.loc == card)
return
if(world.time <= last_special)
return
close_up()
/mob/living/silicon/pai/proc/choose_chassis()
set category = "pAI Commands"
set name = "Choose Chassis"
var/choice
var/finalized = "No"
while(finalized == "No" && src.client)
choice = input(usr,"What would you like to use for your mobile chassis icon? This decision can only be made once.") as null|anything in possible_chassis
if(!choice) return
icon_state = possible_chassis[choice]
finalized = alert("Look at your sprite. Is this what you wish to use?",,"No","Yes")
chassis = possible_chassis[choice]
verbs -= /mob/living/silicon/pai/proc/choose_chassis
/mob/living/silicon/pai/proc/choose_verbs()
set category = "pAI Commands"
set name = "Choose Speech Verbs"
var/choice = input(usr,"What theme would you like to use for your speech verbs? This decision can only be made once.") as null|anything in possible_say_verbs
if(!choice) return
var/list/sayverbs = possible_say_verbs[choice]
speak_statement = sayverbs[1]
speak_exclamation = sayverbs[(sayverbs.len>1 ? 2 : sayverbs.len)]
speak_query = sayverbs[(sayverbs.len>2 ? 3 : sayverbs.len)]
verbs -= /mob/living/silicon/pai/proc/choose_verbs
/mob/living/silicon/pai/lay_down()
set name = "Rest"
set category = "IC"
if(istype(src.loc,/obj/item/device/paicard))
resting = 0
else
resting = !resting
icon_state = resting ? "[chassis]_rest" : "[chassis]"
src << "\blue You are now [resting ? "resting" : "getting up"]"
canmove = !resting
//Overriding this will stop a number of headaches down the track.
/mob/living/silicon/pai/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(W.force)
visible_message("<span class='danger'>[user.name] attacks [src] with [W]!</span>")
src.adjustBruteLoss(W.force)
src.updatehealth()
else
visible_message("<span class='warning'>[user.name] bonks [src] harmlessly with [W].</span>")
if(stat != 2) close_up()
return
/mob/living/silicon/pai/attack_hand(mob/user as mob)
visible_message("<span class='danger'>[user.name] boops [src] on the head.</span>")
close_up()
//I'm not sure how much of this is necessary, but I would rather avoid issues.
/mob/living/silicon/pai/proc/close_up()
last_special = world.time + 100
verbs -= /mob/living/silicon/pai/proc/fold_up
verbs += /mob/living/silicon/pai/proc/fold_out
var/turf/T = get_turf(src)
if(istype(T)) T.visible_message("<b>[src]</b> neatly folds inwards, compacting down to a rectangular card.")
src.stop_pulling()
src.client.perspective = EYE_PERSPECTIVE
src.client.eye = card
//This seems redundant but not including the forced loc setting messes the behavior up.
src.loc = card
card.loc = get_turf(card)
src.forceMove(card)
card.forceMove(card.loc)
canmove = 0
/mob/living/silicon/pai/start_pulling(var/atom/movable/AM)
if(istype(AM,/obj/item))
var/obj/item/O = AM
if(O.w_class == 1)
..()
else
src << "<span class='warning'>You are too small to pull that.</span>"

View File

@@ -528,14 +528,22 @@
dat += {"<h2>Medical Analysis Suite</h2><hr>
<h4>Host Bioscan</h4>
"}
var/mob/living/M = src.loc
if(!istype(M, /mob/living))
while (!istype(M, /mob/living))
M = M.loc
if(istype(M, /turf))
src.temp = "Error: No biological host found. <br>"
src.subscreen = 0
return dat
var/mob/living/M
//If we are not deployed, check the holder of the card.
if(src.loc == card)
M = card.loc
//If we are deployed or the card is not held, check the first living mob in our turf.
if(!M || !istype(M))
var/turf/T = get_turf(src)
M = locate(/mob/living/) in T.contents
if(!M || !istype(M))
src.temp = "Error: No biological host found. <br>"
src.subscreen = 0
return dat
dat += {"<b>Bioscan Results for [M]</b>: <br>
Overall Status: [M.stat > 1 ? "dead" : "[M.health]% healthy"] <br><br>

View File

@@ -317,10 +317,10 @@
if (!yes || ( \
!istype(AM,/obj/machinery/door) && \
!istype(AM,/obj/machinery/recharge_station) && \
!istype(AM,/obj/machinery/disposal/deliveryChute && \
!istype(AM,/obj/machinery/disposal/deliveryChute) && \
!istype(AM,/obj/machinery/teleport/hub) && \
!istype(AM,/obj/effect/portal)
))) return
)) return
..()
return

View File

@@ -56,8 +56,13 @@
modules += O
/obj/item/weapon/robot_module/proc/add_languages(var/mob/living/silicon/robot/R)
R.add_language("Tradeband", 1)
//full set of languages
R.add_language("Sol Common", 1)
R.add_language("Tradeband", 1)
R.add_language("Sinta'unathi", 0)
R.add_language("Siik'maas", 0)
R.add_language("Siik'tajr", 0)
R.add_language("Skrellian", 0)
R.add_language("Gutter", 0)

View File

@@ -2,11 +2,11 @@
var/ending = copytext(text, length(text))
if (ending == "?")
return "queries"
return speak_query
else if (ending == "!")
return "declares"
return speak_exclamation
return "states"
return speak_statement
#define IS_AI 1
#define IS_ROBOT 2
@@ -15,7 +15,7 @@
/mob/living/silicon/say_understands(var/other,var/datum/language/speaking = null)
//These only pertain to common. Languages are handled by mob/say_understands()
if (!speaking)
if (istype(other, /mob/living/carbon/human))
if (istype(other, /mob/living/carbon))
return 1
if (istype(other, /mob/living/silicon))
return 1
@@ -85,14 +85,14 @@
if("department")
switch(bot_type)
if(IS_AI)
AI.holopad_talk(message)
return AI.holopad_talk(message)
if(IS_ROBOT)
log_say("[key_name(src)] : [message]")
R.radio.talk_into(src,message,message_mode,verb,speaking)
if(IS_PAI)
log_say("[key_name(src)] : [message]")
P.radio.talk_into(src,message,message_mode,verb,speaking)
return
return 1
if("binary")
switch(bot_type)
@@ -105,12 +105,13 @@
return
robot_talk(message)
return
return 1
if("general")
switch(bot_type)
if(IS_AI)
if (AI.aiRadio.disabledAi)
src << "\red System Error - Transceiver Disabled"
return
else
log_say("[key_name(src)] : [message]")
AI.aiRadio.talk_into(src,message,null,verb,speaking)
@@ -120,7 +121,7 @@
if(IS_PAI)
log_say("[key_name(src)] : [message]")
P.radio.talk_into(src,message,null,verb,speaking)
return
return 1
else
if(message_mode && message_mode in radiochannels)
@@ -128,6 +129,7 @@
if(IS_AI)
if (AI.aiRadio.disabledAi)
src << "\red System Error - Transceiver Disabled"
return
else
log_say("[key_name(src)] : [message]")
AI.aiRadio.talk_into(src,message,message_mode,verb,speaking)
@@ -137,7 +139,7 @@
if(IS_PAI)
log_say("[key_name(src)] : [message]")
P.radio.talk_into(src,message,message_mode,verb,speaking)
return
return 1
return ..(message,speaking,verb)
@@ -172,7 +174,8 @@
This is another way of saying that we won't bother dealing with them.*/
else
src << "No holopad connected."
return
return
return 1
/mob/living/proc/robot_talk(var/message)

View File

@@ -8,6 +8,11 @@
var/list/hud_list[9]
var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer
//Used in say.dm.
var/speak_statement = "states"
var/speak_exclamation = "declares"
var/speak_query = "queries"
/mob/living/silicon/proc/show_laws()
return

View File

@@ -74,7 +74,7 @@
return 1
//Universal speak makes everything understandable, for obvious reasons.
else if(src.universal_speak || src.universal_understand)
else if((src.universal_speak || src.universal_understand) && !(speaking.flags & UNTRANSLATABLE))
return 1
//Languages are handled after.

View File

@@ -36,12 +36,11 @@ nanoui is used to open and update nano browser uis
var/list/stylesheets = list()
// the list of javascript scripts to use for this ui
var/list/scripts = list()
// the list of templates to use with this ui (usually just one)
// a list of templates which can be used with this ui
var/templates[0]
// the body content for this ui, do not change unless you know what you're doing
// the #mainTemplate div will contain the compiled "main" template html
var/content = "<div id='mainTemplate'></div>"
// the title of this ui
// the layout key for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing)
var/layout_key = "default"
// the default state to use for this ui (this is used on the frontend, leave it as "default" unless you know what you're doing)
var/state_key = "default"
// initial data, containing the full data structure, must be sent to the ui (the data structure cannot be extended later on)
var/list/initial_data[0]
@@ -59,7 +58,7 @@ nanoui is used to open and update nano browser uis
* @param nuser /mob The mob who has opened/owns this ui
* @param nsrc_object /obj|/mob The obj or mob which this ui belongs to
* @param nui_key string A string key to use for this ui. Allows for multiple unique uis on one src_oject
* @param ntemplate string The name of the template file from /nano/templates (e.g. "my_template.tmpl")
* @param ntemplate string The filename of the template file from /nano/templates (e.g. "my_template.tmpl")
* @param ntitle string The title of this ui
* @param nwidth int the width of the ui window
* @param nheight int the height of the ui window
@@ -67,14 +66,14 @@ nanoui is used to open and update nano browser uis
*
* @return /nanoui new nanoui object
*/
/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null)
/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null)
user = nuser
src_object = nsrc_object
ui_key = nui_key
window_id = "[ui_key]\ref[src_object]"
// Add the passed template as the 'main' template, this is required
add_template("main", ntemplate)
// add the passed template filename as the "main" template, this is required
add_template("main", ntemplate_filename)
if (ntitle)
title = ntitle
@@ -99,8 +98,8 @@ nanoui is used to open and update nano browser uis
add_script("nano_state_manager.js") // The NanoStateManager JS, it handles updates from the server and passes data to the current state
add_script("nano_state.js") // The NanoState JS, this is the base state which all states must inherit from
add_script("nano_state_default.js") // The NanoStateDefault JS, this is the "default" state (used by all UIs by default), which inherits from NanoState
add_script("nano_base_callbacks.js") // The NanoBaseCallbacks JS, this is used to set up (before and after update) callbacks which are common to all templates
add_script("nano_base_helpers.js") // The NanoBaseHelpers JS, this is used to set up template helpers which are common to all templates
add_script("nano_base_callbacks.js") // The NanoBaseCallbacks JS, this is used to set up (before and after update) callbacks which are common to all UIs
add_script("nano_base_helpers.js") // The NanoBaseHelpers JS, this is used to set up template helpers which are common to all UIs
add_stylesheet("shared.css") // this CSS sheet is common to all UIs
add_stylesheet("icons.css") // this CSS sheet is common to all UIs
@@ -224,6 +223,7 @@ nanoui is used to open and update nano browser uis
/**
* Add a CSS stylesheet to this UI
* These must be added before the UI has been opened, adding after that will have no effect
*
* @param file string The name of the CSS file from /nano/css (e.g. "my_style.css")
*
@@ -234,6 +234,7 @@ nanoui is used to open and update nano browser uis
/**
* Add a JavsScript script to this UI
* These must be added before the UI has been opened, adding after that will have no effect
*
* @param file string The name of the JavaScript file from /nano/js (e.g. "my_script.js")
*
@@ -243,35 +244,36 @@ nanoui is used to open and update nano browser uis
scripts.Add(file)
/**
* Add a template to this UI
* Add a template for this UI
* Templates are combined with the data sent to the UI to create the rendered view
* Each template needs a div in ui.content to contain the rendered content.
* The div format is '<div id='<templateKey>Template'></div>' where <templateKey> is replaced with the templater's key.
* All UIs are set up by default to use a 'main' template, so only use this proc if you want to add advanced functionality.
* These must be added before the UI has been opened, adding after that will have no effect
*
* @param key string The key name for this template, used to identify the div to render this template into ('<div id='<templateKey>Template'></div>')
* @param file string The name of the template file from /nano/templates (e.g. "my_template.tmpl")
* @param key string The key which is used to reference this template in the frontend
* @param filename string The name of the template file from /nano/templates (e.g. "my_template.tmpl")
*
* @return nothing
*/
/datum/nanoui/proc/add_template(key, file)
templates[key] = file
/datum/nanoui/proc/add_template(key, filename)
templates[key] = filename
/**
* Set the HTML content of the UI
* This should only really be used to add more template divs (see the add_template() proc)
* Set the layout key for use in the frontend Javascript
* The layout key is the basic layout key for the page
* Two files are loaded on the client based on the layout key varable:
* -> a template in /nano/templates with the filename "layout_<layout_key>.tmpl
* -> a CSS stylesheet in /nano/css with the filename "layout_<layout_key>.css
*
* @param ncontent string The new HTML content for this UI
* @param nlayout string The layout key to use
*
* @return nothing
*/
/datum/nanoui/proc/set_content(ncontent)
content = ncontent
/datum/nanoui/proc/set_layout_key(nlayout_key)
layout_key = lowertext(nlayout_key)
/**
* Set the state key for use in the frontend Javascript
*
* @param nstate_key string The new HTML content for this UI
* @param nstate_key string The key of the state to use
*
* @return nothing
*/
@@ -289,11 +291,16 @@ nanoui is used to open and update nano browser uis
on_close_logic = state
/**
* Return the HTML header content for this UI
* Return the HTML for this UI
*
* @return string HTML header content
* @return string HTML for the UI
*/
/datum/nanoui/proc/get_header()
/datum/nanoui/proc/get_html()
// before the UI opens, add the layout files based on the layout key
add_stylesheet("layout_[layout_key].css")
add_template("layout", "layout_[layout_key].tmpl")
var/head_content = ""
for (var/filename in scripts)
@@ -302,20 +309,17 @@ nanoui is used to open and update nano browser uis
for (var/filename in stylesheets)
head_content += "<link rel='stylesheet' type='text/css' href='[filename]'> "
var/templatel_data[0]
for (var/key in templates)
templatel_data[key] = templates[key];
var/template_data_json = "{}" // An empty JSON object
if (templatel_data.len > 0)
template_data_json = list2json(templatel_data)
if (templates.len > 0)
template_data_json = list2json(templates)
var/list/send_data = get_send_data(initial_data)
var/initial_data_json = list2json(send_data)
var/url_parameters_json = list2json(list("src" = "\ref[src]"))
return {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
return {"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<head>
@@ -332,43 +336,18 @@ nanoui is used to open and update nano browser uis
</script>
[head_content]
</head>
<body scroll=auto data-url-parameters='[url_parameters_json]' data-template-data='[template_data_json]' data-initial-data='[initial_data_json]'>
<div id='uiWrapper'>
[title ? "<div id='uiTitleWrapper'><div id='uiStatusIcon' class='icon24 uiStatusGood'></div><div id='uiTitle'>[title]</div><div id='uiTitleFluff'></div></div>" : ""]
<div id='uiContent'>
<div id='uiLoadingNotice'>Initiating...</div>
<noscript>
<div id='uiNoScript'>
<h2>JAVASCRIPT REQUIRED</h2>
<p>Your Internet Explorer's Javascript is disabled (or broken).<br/>
Enable Javascript and then open this UI again.</p>
</div>
</noscript>
"}
/**
* Return the HTML footer content for this UI
*
* @return string HTML footer content
*/
/datum/nanoui/proc/get_footer()
return {"
</div>
<body scroll=auto data-template-data='[template_data_json]' data-url-parameters='[url_parameters_json]' data-initial-data='[initial_data_json]'>
<div id='uiLayout'>
</div>
<noscript>
<div id='uiNoScript'>
<h2>JAVASCRIPT REQUIRED</h2>
<p>Your Internet Explorer's Javascript is disabled (or broken).<br/>
Enable Javascript and then open this UI again.</p>
</div>
</noscript>
</body>
</html>"}
/**
* Return the HTML for this UI
*
* @return string HTML for the UI
*/
/datum/nanoui/proc/get_html()
return {"
[get_header()]
[content]
[get_footer()]
</html>
"}
/**
@@ -377,6 +356,7 @@ nanoui is used to open and update nano browser uis
* @return nothing
*/
/datum/nanoui/proc/open()
var/window_size = ""
if (width && height)
window_size = "size=[width]x[height];"

View File

@@ -394,7 +394,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(germ_level >= INFECTION_LEVEL_ONE)
//having an infection raises your body temperature
var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_THREE, 1) + owner.species.body_temperature
var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/(INFECTION_LEVEL_ONE+300), 1) + owner.species.body_temperature
if (owner.bodytemperature < fever_temperature)
//world << "fever: [owner.bodytemperature] < [fever_temperature], raising temperature."
owner.bodytemperature++

View File

@@ -308,7 +308,7 @@
return
else
user << "<span class='notice'>You transfer [MAXCOIL - src.amount ] length\s of cable from one coil to the other.</span>"
user << "<span class='notice'>You transfer [MAXCOIL - C.amount ] length\s of cable from one coil to the other.</span>"
src.amount -= (MAXCOIL-C.amount)
src.updateicon()
src.update_wclass()

View File

@@ -8,6 +8,7 @@
anchored = 0
density = 1
req_access = list(access_engine_equip)
var/id = null
use_power = 0
idle_power_usage = 10
@@ -51,9 +52,11 @@
else
icon_state = "emitter"
/obj/machinery/power/emitter/attack_hand(mob/user as mob)
src.add_fingerprint(user)
activate(user)
/obj/machinery/power/emitter/proc/activate(mob/user as mob)
if(state == 2)
if(!powernet)
user << "The emitter isn't connected to a wire."

View File

@@ -424,6 +424,17 @@
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/syringe/drugs
name = "Syringe (drugs)"
desc = "Contains aggressive drugs meant for torture."
New()
..()
reagents.add_reagent("space_drugs", 5)
reagents.add_reagent("mindbreaker", 5)
reagents.add_reagent("cryptobiolin", 5)
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/ld50_syringe/choral
New()
..()

View File

@@ -85,6 +85,7 @@
harvesting = 0
cur_artifact.anchored = 0
cur_artifact.being_used = 0
cur_artifact = null
src.visible_message("<b>[name]</b> states, \"Battery is full.\"")
icon_state = "incubator"
@@ -140,27 +141,13 @@
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Source already being harvested.\"")
else
var/mundane = 0
for(var/obj/O in get_turf(owned_scanner))
if(O.invisibility)
continue
if(!istype(O, /obj/machinery/artifact) && !istype(O, /obj/machinery/artifact_scanpad))
mundane++
break
for(var/mob/O in get_turf(owned_scanner))
if(O.invisibility)
continue
mundane++
break
if(articount > 1 || mundane)
var/message = "<b>[src]</b> states, \"Cannot harvest. Too many artifacts on the pad.\""
src.visible_message(message)
else
if(articount > 1)
state("Cannot harvest. Too many artifacts on the pad.")
else if(analysed)
cur_artifact = analysed
//if both effects are active, we can't harvest either
if(cur_artifact.my_effect.activated && cur_artifact.secondary_effect.activated)
if(cur_artifact.my_effect && cur_artifact.my_effect.activated && cur_artifact.secondary_effect.activated)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Source is emitting conflicting energy signatures.\"")
else if(!cur_artifact.my_effect.activated && !cur_artifact.secondary_effect.activated)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. No energy emitting from source.\"")
@@ -233,6 +220,7 @@
harvesting = 0
cur_artifact.anchored = 0
cur_artifact.being_used = 0
cur_artifact = null
src.visible_message("<b>[name]</b> states, \"Energy harvesting interrupted.\"")
icon_state = "incubator"

View File

@@ -16,6 +16,9 @@
p = min(p, 100)
icon_state = "anobattery[round(p,25)]"
/obj/item/weapon/anobattery/proc/use_power(var/amount)
stored_charge = max(0, stored_charge - amount)
/obj/item/weapon/anodevice
name = "Anomaly power utilizer"
icon = 'icons/obj/xenoarchaeology.dmi'
@@ -78,7 +81,7 @@
/obj/item/weapon/anodevice/process()
if(activated)
if(inserted_battery && inserted_battery.battery_effect)
if(inserted_battery && inserted_battery.battery_effect && (inserted_battery.stored_charge > 0) )
//make sure the effect is active
if(!inserted_battery.battery_effect.activated)
inserted_battery.battery_effect.ToggleActivate(1)
@@ -106,20 +109,20 @@
inserted_battery.battery_effect.DoEffectTouch(holder)
//consume power
inserted_battery.stored_charge -= energy_consumed_on_touch
inserted_battery.use_power(energy_consumed_on_touch)
else
//consume power equal to time passed
inserted_battery.stored_charge -= world.time - last_process
inserted_battery.use_power(world.time - last_process)
else if(inserted_battery.battery_effect.effect == EFFECT_PULSE)
inserted_battery.battery_effect.chargelevel = inserted_battery.battery_effect.chargelevelmax
//consume power relative to the time the artifact takes to charge and the effect range
inserted_battery.stored_charge -= inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.chargelevelmax
inserted_battery.use_power(inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.chargelevelmax)
else
//consume power equal to time passed
inserted_battery.stored_charge -= world.time - last_process
inserted_battery.use_power(world.time - last_process)
last_activation = world.time
@@ -159,11 +162,12 @@
//max 10 sec interval
interval = min(max(interval, 0), 100)
if(href_list["startup"])
activated = 1
src.visible_message("\blue \icon[src] [src] whirrs.", "\icon[src]\blue You hear something whirr.")
if(!inserted_battery.battery_effect.activated)
inserted_battery.battery_effect.ToggleActivate(1)
time_end = world.time + duration
if(inserted_battery && inserted_battery.battery_effect && (inserted_battery.stored_charge > 0) )
activated = 1
src.visible_message("\blue \icon[src] [src] whirrs.", "\icon[src]\blue You hear something whirr.")
if(!inserted_battery.battery_effect.activated)
inserted_battery.battery_effect.ToggleActivate(1)
time_end = world.time + duration
if(href_list["shutdown"])
activated = 0
if(href_list["ejectbattery"])
@@ -196,7 +200,7 @@
if(activated && inserted_battery.battery_effect.effect == EFFECT_TOUCH && !isnull(inserted_battery))
inserted_battery.battery_effect.DoEffectTouch(M)
inserted_battery.stored_charge -= energy_consumed_on_touch
inserted_battery.use_power(energy_consumed_on_touch)
user.visible_message("\blue [user] taps [M] with [src], and it shudders on contact.")
else
user.visible_message("\blue [user] taps [M] with [src], but nothing happens.")

View File

@@ -13,22 +13,23 @@
var/last_scan_time = 0
var/scan_delay = 25
/obj/item/device/ano_scanner/New()
..()
spawn(0)
scan()
/obj/item/device/ano_scanner/initialize()
scan()
/obj/item/device/ano_scanner/attack_self(var/mob/user as mob)
return src.interact(user)
/obj/item/device/ano_scanner/interact(var/mob/user as mob)
var/message = "Background radiation levels detected."
if(nearest_artifact_distance >= 0)
message = "Exotic energy detected on wavelength '[nearest_artifact_id]' in a radius of [nearest_artifact_distance]m"
user << "<span class='info'>[message]</span>"
if(world.time - last_scan_time >= scan_delay)
spawn(0)
scan()
if(nearest_artifact_distance >= 0)
message = "Exotic energy detected on wavelength '[nearest_artifact_id]' in a radius of [nearest_artifact_distance]m"
else
message = "Scanning array is recharging."
user << "<span class='info'>[message]</span>"
/obj/item/device/ano_scanner/proc/scan()
set background = 1

View File

@@ -749,10 +749,11 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
#define IS_SYNTHETIC 16384
//Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
#define RESTRICTED 2 // Language can only be accquired by spawning or an admin.
#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight
#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
#define RESTRICTED 2 // Language can only be accquired by spawning or an admin.
#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight
#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand.
#define UNTRANSLATABLE 16 // Language is not translated by universal_speak or universal_understand.
//Flags for zone sleeping
#define ZONE_ACTIVE 1

BIN
icons/mob/pai.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 52 KiB

File diff suppressed because it is too large Load Diff

21
nano/css/layout_basic.css Normal file
View File

@@ -0,0 +1,21 @@
body {
background: #272727 url(uiBasicBackground.png) 50% 0 repeat-x;
}
#uiContent {
clear: both;
padding: 8px;
}
#uiLoadingNotice {
position: relative;
background: url(uiNoticeBackground.jpg) 50% 50%;
color: #000000;
font-size: 14px;
font-style: italic;
font-weight: bold;
padding: 3px 4px 3px 4px;
margin: 4px 0 4px 0;
}

View File

@@ -0,0 +1,64 @@
body {
background: #272727 url(uiBackground.png) 50% 0 repeat-x;
}
#uiWrapper {
width: 100%;
height: 100%;
}
#uiTitleWrapper {
position: relative;
height: 30px;
}
#uiTitle {
position: absolute;
top: 6px;
left: 44px;
width: 66%;
overflow: hidden;
color: #E9C183;
font-size: 16px;
}
#uiTitle.icon {
padding: 6px 8px 6px 42px;
background-position: 2px 50%;
background-repeat: no-repeat;
}
#uiTitleFluff {
position: absolute;
top: 4px;
right: 12px;
width: 42px;
height: 24px;
background: url(uiTitleFluff.png) 50% 50% no-repeat;
}
#uiStatusIcon {
position: absolute;
top: 4px;
left: 12px;
width: 24px;
height: 24px;
}
#uiContent {
clear: both;
padding: 8px;
}
#uiLoadingNotice {
position: relative;
background: url(uiNoticeBackground.jpg) 50% 50%;
color: #000000;
font-size: 14px;
font-style: italic;
font-weight: bold;
padding: 3px 4px 3px 4px;
margin: 4px 0 4px 0;
}

View File

@@ -5,24 +5,43 @@ body {
color: #ffffff;
line-height: 170%;
font-family: Verdana, Geneva, sans-serif;
background: #272727 url(uiBackground.png) 50% 0 repeat-x;
background: #272727;
}
#uiNoScript {
position: fixed;
top: 50%;
left: 50%;
margin: -60px 0 0 -150px;
width: 280px;
height: 120px;
background: #ffffff;
border: 2px solid #ff0000;
color: #000000;
font-size: 10px;
font-weight: bold;
z-index: 9999;
padding: 0px 10px;
text-align: center;
}
hr {
background-color: #40628a;
height: 1px;
}
.link, .linkOn, .linkOff, .selected, .disabled {
float: left;
float: left;
min-width: 15px;
height: 16px;
text-align: center;
text-align: center;
color: #ffffff;
text-decoration: none;
background: #40628a;
border: 1px solid #161616;
padding: 0px 4px 4px 4px;
margin: 0 2px 2px 0;
cursor:default;
cursor: default;
white-space: nowrap;
}
@@ -33,10 +52,12 @@ hr {
a:hover, .linkActive:hover {
background: #507aac;
}
.linkPending, .linkPending:hover {
color: #ffffff;
background: #507aac;
}
a.white, a.white:link, a.white:visited, a.white:active {
color: #40628a;
text-decoration: none;
@@ -44,25 +65,30 @@ a.white, a.white:link, a.white:visited, a.white:active {
border: 1px solid #161616;
padding: 1px 4px 1px 4px;
margin: 0 2px 0 0;
cursor:default;
cursor: default;
}
a.white:hover {
color: #ffffff;
background: #40628a;
}
.linkOn, a.linkOn:link, a.linkOn:visited, a.linkOn:active, a.linkOn:hover, .selected, a.selected:link, a.selected:visited, a.selected:active, a.selected:hover {
color: #ffffff;
background: #2f943c;
}
.linkOff, a.linkOff:link, a.linkOff:visited, a.linkOff:active, a.linkOff:hover, .disabled, a.disabled:link, a.disabled:visited, a.disabled:active, a.disabled:hover {
color: #ffffff;
background: #999999;
border-color: #666666;
}
a.icon, .linkOn.icon, .linkOff.icon, .selected.icon, .disabled.icon {
position: relative;
padding: 1px 4px 2px 20px;
}
a.icon img, .linkOn.icon img, .linkOff.icon img, .selected.icon img, .disabled.icon img {
position: absolute;
top: 0;
@@ -70,11 +96,13 @@ a.icon img, .linkOn.icon img, .linkOff.icon img, .selected.icon img, .disabled.i
width: 18px;
height: 18px;
}
.linkDanger, a.linkDanger:link, a.linkDanger:visited, a.linkDanger:active {
color: #ffffff;
background-color: #ff0000;
border-color: #aa0000;
}
.linkDanger:hover {
background-color: #ff6666;
}
@@ -84,97 +112,37 @@ ul {
margin: 0;
list-style-type: none;
}
li {
padding: 0 0 2px 0;
}
img, a img {
border-style:none;
border-style: none;
}
h1, h2, h3, h4, h5, h6 {
margin: 0;
padding: 12px 0 6px 0;
color: #517087;
clear: both;
}
h1 {
font-size: 18px;
}
h2 {
font-size: 16px;
}
h3 {
font-size: 14px;
}
h4 {
font-size: 12px;
}
#uiWrapper {
width: 100%;
height: 100%;
}
#uiTitleWrapper {
position: relative;
height: 30px;
}
#uiTitle {
position: absolute;
top: 6px;
left: 44px;
width: 66%;
overflow: hidden;
color: #E9C183;
font-size: 16px;
}
#uiTitle.icon {
padding: 6px 8px 6px 42px;
background-position: 2px 50%;
background-repeat: no-repeat;
}
#uiTitleFluff {
position: absolute;
top: 4px;
right: 12px;
width: 42px;
height: 24px;
background: url(uiTitleFluff.png) 50% 50% no-repeat;
}
#uiStatusIcon {
position: absolute;
top: 4px;
left: 12px;
width: 24px;
height: 24px;
}
#uiContent {
clear: both;
padding: 8px;
}
#uiLoadingNotice {
position: relative;
background: url(uiNoticeBackground.jpg) 50% 50%;
color: #000000;
font-size: 14px;
font-style: italic;
font-weight: bold;
padding: 3px 4px 3px 4px;
margin: 4px 0 4px 0;
}
#uiNoScript {
position: fixed;
top: 50%;
left: 50%;
margin: -60px 0 0 -150px;
width: 280px;
height: 120px;
background: #ffffff;
border: 2px solid #ff0000;
color: #000000;
font-size: 10px;
font-weight: bold;
z-index: 9999;
padding: 0px 10px;
text-align: center;
}
.white {
color: white;
@@ -185,10 +153,12 @@ h4 {
color: #4f7529;
font-weight: bold;
}
.average {
color: #cd6500;
font-weight: bold;
}
.bad {
color: #ee0000;
font-weight: bold;
@@ -200,17 +170,21 @@ h4 {
}
.redBackground {
background: #ea0000;
background: #ea0000;
}
.yellowBackground {
background: #cacc00;
background: #cacc00;
}
.highlight {
color: #8BA5C4;
}
.dark {
color: #272727;
}
.noticePlaceholder {
position: relative;
font-size: 12px;
@@ -219,6 +193,7 @@ h4 {
padding: 3px 4px 3px 4px;
margin: 4px 0 4px 0;
}
.notice {
position: relative;
background: url(uiNoticeBackground.jpg) 50% 50%;
@@ -229,9 +204,11 @@ h4 {
padding: 3px 4px 3px 4px;
margin: 4px 0 4px 0;
}
.notice.icon {
padding: 2px 4px 0 20px;
}
.notice img {
position: absolute;
top: 0;
@@ -240,37 +217,40 @@ h4 {
height: 16px;
}
div.notice {
clear: both;
}
.itemGroup {
border: 1px solid #e9c183;
background: #2c2c2c;
padding: 4px;
clear: both;
}
.item {
width: 100%;
margin: 4px 0 0 0;
background: #2c2c2c;
padding: 4px;
clear: both;
}
.item {
width: 100%;
margin: 4px 0 0 0;
clear: both;
}
.itemLabel {
float: left;
width: 30%;
color: #e9c183;
}
.itemContent {
float: left;
width: 69%;
}
.itemLabelNarrow {
float: left;
width: 20%;
color: #e9c183;
}
.itemLabelWide {
float: left;
width: 45%;
@@ -281,10 +261,12 @@ div.notice {
float: left;
width: 79%;
}
.itemContentSmall {
float: left;
width: 33%;
}
.itemContentMedium {
float: left;
width: 55%;
@@ -297,6 +279,7 @@ div.notice {
padding: 4px;
margin: 3px 0;
}
.statusDisplayRecords {
background: #000000;
color: #ffffff;
@@ -307,25 +290,28 @@ div.notice {
overflow-y: auto;
}
.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;
}
.displayBar {
position: relative;
width: 236px;
@@ -336,6 +322,7 @@ div.notice {
overflow: hidden;
background: #000000;
}
.displayBarText {
position: absolute;
top: -2px;
@@ -345,6 +332,7 @@ div.notice {
color: #ffffff;
font-weight: normal;
}
.displayBarFill {
width: 0%;
height: 100%;
@@ -352,58 +340,70 @@ div.notice {
overflow: hidden;
float: left;
}
.displayBarFill.alignRight {
float: right;
}
.displayBarFill.good {
color: #ffffff;
background: #4f7529;
}
.displayBarFill.average {
color: #ffffff;
background: #cd6500;
}
.displayBarFill.bad {
color: #ffffff;
background: #ee0000;
}
.displayBarFill.highlight {
color: #ffffff;
background: #8BA5C4;
}
.clearBoth {
clear: both;
}
.clearLeft {
clear: left;
}
.clearRight {
clear: right;
}
.line {
width: 100%;
clear: both;
}
.inactive, , a.inactive:link, a.inactive:visited, a.inactive:active, a.inactive:hover {
.inactive, a.inactive:link, a.inactive:visited, a.inactive:active, a.inactive:hover {
color: #ffffff;
background: #999999;
border-color: #666666;
}
.fixedLeft {
width: 110px;
float: left;
}
.fixedLeftWide {
width: 165px;
float: left;
}
.fixedLeftWider{
.fixedLeftWider {
width: 220px;
float: left;
}
.fixedLeftWidest{
.fixedLeftWidest {
width: 250px;
float: left;
}
@@ -414,150 +414,131 @@ div.notice {
/* Used in PDA */
.wholeScreen
{
position: absolute
color: #517087;
font-size: 16px;
font-weight: bold;
text-align:center;
.wholeScreen {
position: absolute;
color: #517087;
font-size: 16px;
font-weight: bold;
text-align: center;
}
.pdalink
{
.pdalink {
float: left;
white-space:nowrap;
white-space: nowrap;
}
/* DNA Modifier UI (dna_modifier.tmpl) */
.dnaBlock
{
.dnaBlock {
float: left;
width: 90px;
padding: 0 0 5px 0;
padding: 0 0 5px 0;
}
.dnaBlockNumber
{
font-family: Fixed, monospace;
float: left;
color: #ffffff;
background: #363636;
min-width: 20px;
.dnaBlockNumber {
font-family: Fixed, monospace;
float: left;
color: #ffffff;
background: #363636;
min-width: 20px;
height: 20px;
padding: 0;
text-align: center;
padding: 0;
text-align: center;
}
.dnaSubBlock
{
font-family: Fixed, monospace;
float: left;
.dnaSubBlock {
font-family: Fixed, monospace;
float: left;
padding: 0;
min-width: 16px;
height: 20px;
text-align: center;
}
.mask
{
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url(uiMaskBackground.png);
.mask {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url(uiMaskBackground.png);
}
.maskContent
{
width: 100%;
height: 200px;
margin: 200px 0;
text-align: center;
.maskContent {
width: 100%;
height: 200px;
margin: 200px 0;
text-align: center;
}
/* Table stuffs for power monitor */
table.pmon
{
border:2px solid RoyalBlue;
table.pmon {
border: 2px solid RoyalBlue;
}
table.pmon td, table.pmon th
{
border-bottom:1px dotted black;
padding:0px 5px 0px 5px;
table.pmon td, table.pmon th {
border-bottom: 1px dotted black;
padding: 0px 5px 0px 5px;
}
/* Table Stuffs for manifest*/
th.command
{
background: #3333FF;
font-weight: bold;
color: #ffffff;
th.command {
background: #3333FF;
font-weight: bold;
color: #ffffff;
}
th.sec
{
background: #8e0000;
font-weight: bold;
color: #ffffff;
}
th.med
{
background: #006600;
font-weight: bold;
color: #ffffff;
}
th.eng
{
background: #b27300;
font-weight: bold;
color: #ffffff;
}
th.sci
{
background: #a65ba6;
font-weight: bold;
color: #ffffff;
}
th.civ
{
background: #a32800;
font-weight: bold;
color: #ffffff;
}
th.misc
{
background: #666666;
font-weight: bold;
color: #ffffff;
th.sec {
background: #8e0000;
font-weight: bold;
color: #ffffff;
}
th.med {
background: #006600;
font-weight: bold;
color: #ffffff;
}
th.eng {
background: #b27300;
font-weight: bold;
color: #ffffff;
}
th.sci {
background: #a65ba6;
font-weight: bold;
color: #ffffff;
}
th.civ {
background: #a32800;
font-weight: bold;
color: #ffffff;
}
th.misc {
background: #666666;
font-weight: bold;
color: #ffffff;
}
/* Damage colors for crew monitoring computer */
.burn
{
color: orange;
.burn {
color: orange;
}
.brute
{
color: red;
.brute {
color: red;
}
.toxin
{
color: green;
.toxin {
color: green;
}
.oxyloss
{
color: blue;
.oxyloss {
color: blue;
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -45,7 +45,8 @@ NanoStateClass.prototype.onUpdate = function (data) {
try
{
$("#mainTemplate").html(NanoTemplate.parse('main', data)); // render the 'mail' template to the #mainTemplate div
$("#uiLayout").html(NanoTemplate.parse('layout', data)); // render the 'mail' template to the #mainTemplate div
$("#uiContent").html(NanoTemplate.parse('main', data)); // render the 'mail' template to the #mainTemplate div
}
catch(error)
{

View File

@@ -25,8 +25,6 @@ NanoStateManager = function ()
// this function sets up the templates and base functionality
var init = function ()
{
$('#uiLoadingNotice').html('Loading...');
// We store initialData and templateData in the body tag, it's as good a place as any
_data = $('body').data('initialData');
@@ -47,7 +45,6 @@ NanoStateManager = function ()
doUpdate(_data);
_isInitialised = true;
$('#uiLoadingNotice').hide();
});
};

View File

@@ -1,77 +1,74 @@
var NanoTemplate = function () {
var _templateData = {};
var _templates = {};
var _compiledTemplates = {};
var _helpers = {};
var init = function () {
// We store initialData and templateData in the body tag, it's as good a place as any
var templateData = $('body').data('templateData');
// We store templateData in the body tag, it's as good a place as any
_templateData = $('body').data('templateData');
if (templateData == null)
if (_templateData == null)
{
alert('Error: Template data did not load correctly.');
}
// we count the number of templates for this ui so that we know when they've all been rendered
var templateCount = 0;
for (var key in templateData)
{
if (templateData.hasOwnProperty(key))
{
templateCount++;
}
}
if (!templateCount)
{
alert('ERROR: No templates listed!');
}
// load markup for each template and register it
for (var key in templateData)
{
if (!templateData.hasOwnProperty(key))
{
continue;
}
$.when($.ajax({
url: templateData[key],
cache: false,
dataType: 'text'
}))
.done(function(templateMarkup) {
//templateMarkup = templateMarkup.replace(/ +\) *\}\}/g, ')}}');
templateMarkup += '<div class="clearBoth"></div>';
try
{
NanoTemplate.addTemplate(key, templateMarkup)
templateCount--;
if (templateCount <= 0)
{
$(document).trigger('templatesLoaded');
}
}
catch(error)
{
alert('ERROR: An error occurred while loading the UI: ' + error.message);
return;
}
})
.fail(function () {
alert('ERROR: Loading template ' + key + '(' + templateData[key] + ') failed!');
});;
}
loadNextTemplate();
};
var loadNextTemplate = function () {
// we count the number of templates for this ui so that we know when they've all been rendered
var templateCount = Object.size(_templateData);
if (!templateCount)
{
$(document).trigger('templatesLoaded');
return;
}
// load markup for each template and register it
for (var key in _templateData)
{
if (!_templateData.hasOwnProperty(key))
{
continue;
}
$.when($.ajax({
url: _templateData[key],
cache: false,
dataType: 'text'
}))
.done(function(templateMarkup) {
templateMarkup += '<div class="clearBoth"></div>';
try
{
NanoTemplate.addTemplate(key, templateMarkup);
}
catch(error)
{
alert('ERROR: An error occurred while loading the UI: ' + error.message);
return;
}
delete _templateData[key];
loadNextTemplate();
})
.fail(function () {
alert('ERROR: Loading template ' + key + '(' + _templateData[key] + ') failed!');
});
return;
}
}
var compileTemplates = function () {
for (var key in _templates) {
@@ -79,7 +76,7 @@ var NanoTemplate = function () {
_compiledTemplates[key] = doT.template(_templates[key], null, _templates)
}
catch (error) {
alert(error);
alert(error.message);
}
}
};
@@ -92,13 +89,18 @@ var NanoTemplate = function () {
_templates[key] = templateString;
},
parse: function (templateKey, data) {
if (!_compiledTemplates.hasOwnProperty(templateKey)) {
if (!_compiledTemplates.hasOwnProperty(templateKey) || !_compiledTemplates[templateKey]) {
if (!_templates.hasOwnProperty(templateKey)) {
alert('ERROR: Template "' + templateKey + '" does not exist in _compiledTemplates!');
return;
return '<h2>Template error (does not exist)</h2>';
}
compileTemplates();
}
if (typeof _compiledTemplates[templateKey] != 'function') {
alert(_compiledTemplates[templateKey]);
alert('ERROR: Template "' + templateKey + '" failed to compile!');
return '<h2>Template error (failed to compile)</h2>';
}
return _compiledTemplates[templateKey].call(this, data['data'], data['config'], _helpers);
},
addHelper: function (helperName, helperFunction) {

View File

@@ -4,7 +4,7 @@
Tank Label:
</div>
<div class="itemContent">
<div style="float: left; width: 180px;">{{:data.name}}</div> {{:helper.link('Relabel', 'pencil', {'relabel' : 1}, (data.canLabel) ? null : 'disabled')}}
<div style="float: left; width: 180px;">{{:data.name}}</div> {{:helper.link('Relabel', 'pencil', {'relabel' : 1}, data.canLabel ? null : 'disabled')}}
</div>
</div>

View File

@@ -91,6 +91,6 @@
</div>
</div>
<div class="item" style="padding-top: 10px; width: 100%">
{{:helper.link('Abort', 'cancel', {'command' : 'abort'}, (data.processing && !airlock_disabled) ? null : 'disabled', (data.processing && !data.airlock_disabled) ? 'redBackground' : null)}}
{{:helper.link('Abort', 'cancel', {'command' : 'abort'}, (data.processing && !data.airlock_disabled) ? null : 'disabled', (data.processing && !data.airlock_disabled) ? 'redBackground' : null)}}
</div>
</div>

View File

@@ -30,7 +30,7 @@
{{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', null)}}
{{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : null)}}
{{else}}
{{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled? 'redBackground' : null)}}
{{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redBackground' : null)}}
{{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : 'yellowBackground')}}
{{/if}}
{{else}}

View File

@@ -79,7 +79,7 @@
{{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', null)}}
{{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : null)}}
{{else}}
{{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled? 'redBackground' : null)}}
{{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redBackground' : null)}}
{{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : 'yellowBackground')}}
{{/if}}
</div>

View File

@@ -72,9 +72,9 @@
<div class="item" style="padding-top: 10px">
<div class="item">
<div class="itemContent" style="padding-top: 2px; width: 100%">
{{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch? null : 'disabled' , null)}}
{{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel? null : 'disabled' , null)}}
{{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force? null : 'disabled' , data.can_force? 'redBackground' : null)}}
{{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}}
{{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}}
{{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redBackground' : null)}}
</div>
</div>
</div>

View File

@@ -87,14 +87,14 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
{{:data.maser_wavelength}} MHz
</div>
<div class="itemContent" style="text-align:left; width: 22%;">
{{:helper.link('-2 KHz', null, {'maserWavelength' : -2}, null)}}
{{:helper.link('-1 KHz', null, {'maserWavelength' : -1}, null)}}
{{:helper.link('-0.5 KHz', null, {'maserWavelength' : -0.5}, null)}}
{{:helper.link('-2 GHz', null, {'maserWavelength' : -2}, null)}}
{{:helper.link('-1 GHz', null, {'maserWavelength' : -1}, null)}}
{{:helper.link('-0.5 GHz', null, {'maserWavelength' : -0.5}, null)}}
</div>
<div class="itemContent" style="text-align:right; width: 22%;">
{{:helper.link('+0.5 KHz', null, {'maserWavelength' : 0.5}, null)}}
{{:helper.link('+1 KHz', null, {'maserWavelength' : 1}, null)}}
{{:helper.link('+2 KHz', null, {'maserWavelength' : 2}, null)}}
{{:helper.link('+0.5 GHz', null, {'maserWavelength' : 0.5}, null)}}
{{:helper.link('+1 GHz', null, {'maserWavelength' : 1}, null)}}
{{:helper.link('+2 GHz', null, {'maserWavelength' : 2}, null)}}
</div>
</div>

View File

@@ -0,0 +1,3 @@
<div id='uiContent'>
<div id='uiLoadingNotice'>Initiating...</div>
</div>

View File

@@ -0,0 +1,4 @@
<div id='uiTitleWrapper'><div id='uiStatusIcon' class='icon24 uiStatusGood'></div><div id='uiTitle'>{{:config.title}}</div><div id='uiTitleFluff'></div></div>
<div id='uiContent'>
<div id='uiLoadingNotice'>Initiating...</div>
</div>

View File

@@ -233,16 +233,16 @@ Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm
<H3>Current Conversations</H3>
{{for data.convopdas}}
<div class="item">
{{:helper.link(Name, 'circle-arrow-s', {'choice' : "Select Conversation", 'convo' : data.Reference } , null, fixedLeftWider)}}
{{if data.cartridge}}
{{if data.cartridge.type == "/obj/item/weapon/cartridge/syndicate" && data.Detonate == 1}}
{{:helper.link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : data.Reference}, null, 'fixedLeft')}}
{{:helper.link(value.Name, 'circle-arrow-s', {'choice' : "Select Conversation", 'convo' : value.Reference } , null, value.fixedLeftWider)}}
{{if value.cartridge}}
{{if value.cartridge.type == "/obj/item/weapon/cartridge/syndicate" && value.Detonate == 1}}
{{:helper.link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : value.Reference}, null, 'fixedLeft')}}
{{/if}}
{{if data.cartridge.type == "/obj/item/weapon/cartridge/clown"}}
{{:helper.link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : data.Reference}, null, 'fixedLeft')}}
{{if value.cartridge.type == "/obj/item/weapon/cartridge/clown"}}
{{:helper.link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : value.Reference}, null, 'fixedLeft')}}
{{/if}}
{{if data.cartridge.type == "/obj/item/weapon/cartridge/mime"}}
{{:helper.link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : data.Reference}, null, 'fixedLeft')}}
{{if value.cartridge.type == "/obj/item/weapon/cartridge/mime"}}
{{:helper.link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : value.Reference}, null, 'fixedLeft')}}
{{/if}}
{{/if}}
</div>
@@ -250,7 +250,7 @@ Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm
<H3>Other PDAs</H3>
{{for data.pdas}}
<div class="item">
{{:helper.link(Name, 'circle-arrow-s', {'choice' : "Message", 'target' : value.Reference}, null, fixedLeftWider)}}
{{:helper.link(value.Name, 'circle-arrow-s', {'choice' : "Message", 'target' : value.Reference}, null, value.fixedLeftWider)}}
{{if value.cartridge}}
{{if value.cartridge.type == "/obj/item/weapon/cartridge/syndicate" && value.Detonate == 1}} {{:helper.link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : value.Reference}, null, 'fixedLeft')}} {{/if}}
{{if value.cartridge.type == "/obj/item/weapon/cartridge/clown"}} {{:helper.link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : value.Reference}, null, 'fixedLeft')}} {{/if}}

View File

@@ -60,7 +60,7 @@
<div class="itemContent" style="padding-top: 2px; width: 100%">
{{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch? null : 'disabled' , null)}}
{{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}}
{{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force? null : 'disabled' , can_force? 'redBackground' : null)}}
{{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force? null : 'disabled' , data.can_force ? 'redBackground' : null)}}
</div>
</div>
</div>

View File

@@ -67,7 +67,7 @@
<div class="itemContent" style="padding-top: 2px; width: 100%">
{{:data.~link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}}
{{:data.~link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}}
{{:data.~link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , can_force? 'redBackground' : null)}}
{{:data.~link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redBackground' : null)}}
</div>
</div>
</div>

View File

@@ -4,7 +4,7 @@
Chamber Pressure:
</div>
<div class="itemContent">
{{:helper.displayBar(chamber_pressure, 0, 200, (chamber_pressure < 80) || (chamber_pressure > 120) ? 'bad' : (chamber_pressure < 95) || (chamber_pressure > 110) ? 'average' : 'good')}}
{{:helper.displayBar(data.chamber_pressure, 0, 200, (data.chamber_pressure < 80) || (data.chamber_pressure > 120) ? 'bad' : (data.chamber_pressure < 95) || (data.chamber_pressure > 110) ? 'average' : 'good')}}
<div class="statusValue">
{{:data.chamber_pressure}} kPa
</div>

View File

@@ -94,7 +94,7 @@
{{else}}
{{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redBackground' : null)}}
{{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : 'yellowBackground')}}
{{:helper.link('MANUAL EJECT', 'alert', {'command' : 'toggle_override'}, can_force ? null : 'disabled', can_force ? 'redBackground' : null)}}
{{:helper.link('MANUAL EJECT', 'alert', {'command' : 'toggle_override'}, data.can_force ? null : 'disabled', data.can_force ? 'redBackground' : null)}}
{{/if}}
</div>
</div>

View File

@@ -9,7 +9,7 @@
Tank Pressure:
</div>
<div class="itemContent">
{{:helper.displayBar(data.tankPressure, 0, 1013, (data.tankPressure > 200) ? 'good' : (data.tankPressure > 100) ? 'average' : 'bad'))}}
{{:helper.displayBar(data.tankPressure, 0, 1013, (data.tankPressure > 200) ? 'good' : ((data.tankPressure > 100) ? 'average' : 'bad'))}}
<div class="statusValue">
{{:data.tankPressure}} kPa
</div>

0
tools/mapmerge/mapmerge.sh Normal file → Executable file
View File