diff --git a/code/__defines/math_physics.dm b/code/__defines/math_physics.dm index 987cb1ba9d..198f87eccc 100644 --- a/code/__defines/math_physics.dm +++ b/code/__defines/math_physics.dm @@ -15,9 +15,10 @@ #define RADIATOR_EXPOSED_SURFACE_AREA_RATIO 0.04 // (3 cm + 100 cm * sin(3deg))/(2*(3+100 cm)). Unitless ratio. #define HUMAN_EXPOSED_SURFACE_AREA 5.2 //m^2, surface area of 1.7m (H) x 0.46m (D) cylinder -#define T0C 273.15 // 0.0 degrees celcius -#define T20C 293.15 // 20.0 degrees celcius -#define TCMB 2.7 // -270.3 degrees celcius +#define T0C 273.15 // 0.0 degrees celcius +#define T20C 293.15 // 20.0 degrees celcius +#define TCMB 2.7 // -270.3 degrees celcius +#define TN60C 213.15 // -60 degrees celcius #define CLAMP01(x) max(0, min(1, x)) #define QUANTIZE(variable) (round(variable,0.0001)) diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index 69f837d8f9..0551df6c3c 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -30,13 +30,13 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/captain(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/cap(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) - H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/captain(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/captain(H), slot_w_uniform) if(H.age>49) - // Since we can have something other than the default uniform at this + // Since we can have something other than the default uniform at this // point, check if we can actually attach the medal var/obj/item/clothing/uniform = H.w_uniform var/obj/item/clothing/accessory/medal/gold/captain/medal = new() - + if(uniform && uniform.can_attach_accessory(medal)) uniform.attach_accessory(null, medal) else @@ -107,4 +107,5 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/ids(H), slot_l_hand) else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/ids(H.back), slot_in_backpack) - return 1 + H.implant_loyalty() + return 1 \ No newline at end of file diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 4a48dbb4ae..aa5fc79613 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -9,13 +9,23 @@ icon_state = "body_scanner_0" density = 1 anchored = 1 + circuit = /obj/item/weapon/circuitboard/body_scanner use_power = 1 idle_power_usage = 60 active_power_usage = 10000 //10 kW. It's a big all-body scanner. + light_color = "#00FF00" + /obj/machinery/bodyscanner/New() + ..() + spawn( 5 ) + var/obj/machinery/body_scanconsole/C = locate(/obj/machinery/body_scanconsole) in range(2,src) + if(C) + C.connected = src + +/obj/machinery/bodyscanner/map/New() ..() circuit = new circuit(src) component_parts = list() @@ -23,81 +33,14 @@ component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) component_parts += new /obj/item/stack/material/glass/reinforced(src, 2) - - spawn( 5 ) - var/obj/machinery/body_scanconsole/C = locate(/obj/machinery/body_scanconsole) in range(2,src) - if(C) - C.connected = src - return - RefreshParts() -/obj/machinery/bodyscanner/relaymove(mob/user as mob) - if (user.stat) - return - src.go_out() - return - -/obj/machinery/bodyscanner/verb/eject() - set src in oview(1) - set category = "Object" - set name = "Eject Body Scanner" - - if (usr.stat != 0) - return - src.go_out() - add_fingerprint(usr) - return - -/obj/machinery/bodyscanner/verb/move_inside() - set src in oview(1) - set category = "Object" - set name = "Enter Body Scanner" - - if (usr.stat != 0) - return - if (src.occupant) - usr << "The scanner is already occupied!" - return - if (usr.abiotic()) - usr << "The subject cannot have abiotic items on." - return - usr.pulling = null - usr.client.perspective = EYE_PERSPECTIVE - usr.client.eye = src - usr.loc = src - src.occupant = usr - update_use_power(2) - src.icon_state = "body_scanner_1" - for(var/obj/O in src) - //O = null - if(O in component_parts) - continue - if(O == circuit) - continue - qdel(O) - //Foreach goto(124) - src.add_fingerprint(usr) - return - -/obj/machinery/bodyscanner/proc/go_out() - if ((!( src.occupant ) || src.locked)) - return - for(var/obj/O in src) - if(O in component_parts) - continue - if(O == circuit) - continue - O.loc = src.loc - //Foreach goto(30) - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.loc = src.loc - src.occupant = null - update_use_power(1) - src.icon_state = "body_scanner_0" - return +/obj/machinery/bodyscanner/power_change() + ..() + if(!(stat & (BROKEN|NOPOWER))) + set_light(2) + else + set_light(0) /obj/machinery/bodyscanner/attackby(var/obj/item/G, user as mob) if(default_deconstruction_screwdriver(user, G)) @@ -107,42 +50,96 @@ if(istype(G, /obj/item/weapon/grab)) var/obj/item/weapon/grab/H = G - if(!(ismob(H.affecting))) + if(panel_open) + user << "Close the maintenance panel first." return - if (src.occupant) - user << "The scanner is already occupied!" + if(!ismob(H.affecting)) return - if (H.affecting.abiotic()) - user << "Subject cannot have abiotic items on." + if(occupant) + user << "The scanner is already occupied!" return + for(var/mob/living/carbon/slime/M in range(1, H.affecting)) + if(M.Victim == H.affecting) + user << "[H.affecting.name] has a fucking slime attached to them, deal with that first." + return var/mob/M = H.affecting - if (M.client) - M.client.perspective = EYE_PERSPECTIVE - M.client.eye = src - M.loc = src - src.occupant = M - update_use_power(2) - src.icon_state = "body_scanner_1" - for(var/obj/O in src) - if(O in component_parts) - continue - if(O == circuit) - continue - O.loc = src.loc - //Foreach goto(154) - src.add_fingerprint(user) - //G = null + if(M.abiotic()) + user << "Subject cannot have abiotic items on." + return + M.forceMove(src) + occupant = M + icon_state = "body_scanner_1" + add_fingerprint(user) qdel(G) + +/obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/O, mob/user as mob) + if(!istype(O)) + return 0 //not a mob + if(user.incapacitated()) + return 0 //user shouldn't be doing things + if(O.anchored) + return 0 //mob is anchored??? + if(get_dist(user, src) > 1 || get_dist(user, O) > 1) + return 0 //doesn't use adjacent() to allow for non-cardinal (fuck my life) + if(!ishuman(user) && !isrobot(user)) + return 0 //not a borg or human + if(panel_open) + user << "Close the maintenance panel first." + return 0 //panel open + if(occupant) + user << "\The [src] is already occupied." + return 0 //occupied + + if(O.buckled) + return 0 + if(O.abiotic()) + user << "Subject cannot have abiotic items on." + return 0 + for(var/mob/living/carbon/slime/M in range(1, O)) + if(M.Victim == O) + user << "[O] has a fucking slime attached to them, deal with that first." + return 0 + + if(O == user) + visible_message("[user] climbs into \the [src].") + else + visible_message("[user] puts [O] into the body scanner.") + + O.forceMove(src) + occupant = O + icon_state = "body_scanner_1" + add_fingerprint(user) + +/obj/machinery/bodyscanner/relaymove(mob/user as mob) + if(user.incapacitated()) + return 0 //maybe they should be able to get out with cuffs, but whatever + go_out() + +/obj/machinery/bodyscanner/verb/eject() + set src in oview(1) + set category = "Object" + set name = "Eject Body Scanner" + + if(usr.incapacitated()) + return + go_out() + add_fingerprint(usr) + +/obj/machinery/bodyscanner/proc/go_out() + if ((!( src.occupant ) || src.locked)) + return + if (src.occupant.client) + src.occupant.client.eye = src.occupant.client.mob + src.occupant.client.perspective = MOB_PERSPECTIVE + src.occupant.loc = src.loc + src.occupant = null + src.icon_state = "body_scanner_0" return /obj/machinery/bodyscanner/ex_act(severity) switch(severity) if(1.0) for(var/atom/movable/A as mob|obj in src) - if(A in component_parts) - continue - if(A == circuit) - continue A.loc = src.loc ex_act(severity) //Foreach goto(35) @@ -152,10 +149,6 @@ if(2.0) if (prob(50)) for(var/atom/movable/A as mob|obj in src) - if(A in component_parts) - continue - if(A == circuit) - continue A.loc = src.loc ex_act(severity) //Foreach goto(108) @@ -165,10 +158,6 @@ if(3.0) if (prob(25)) for(var/atom/movable/A as mob|obj in src) - if(A in component_parts) - continue - if(A == circuit) - continue A.loc = src.loc ex_act(severity) //Foreach goto(181) @@ -178,32 +167,7 @@ else return -/obj/machinery/body_scanconsole/ex_act(severity) - - switch(severity) - if(1.0) - //SN src = null - qdel(src) - return - if(2.0) - if (prob(50)) - //SN src = null - qdel(src) - return - else - return - -/obj/machinery/body_scanconsole/power_change() - ..() - if(stat & BROKEN) - icon_state = "body_scannerconsole-p" - else - if (stat & NOPOWER) - spawn(rand(0, 15)) - src.icon_state = "body_scannerconsole-p" - else - icon_state = initial(icon_state) - +//Body Scan Console /obj/machinery/body_scanconsole var/obj/machinery/bodyscanner/connected var/known_implants = list(/obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking) @@ -216,67 +180,12 @@ density = 0 anchored = 1 circuit = /obj/item/weapon/circuitboard/scanner_console + var/printing = null + var/printing_text = null /obj/machinery/body_scanconsole/New() ..() - spawn( 5 ) - src.connected = locate(/obj/machinery/bodyscanner) in range(2,src) - return - return - -/* - -/obj/machinery/body_scanconsole/process() //not really used right now - if(stat & (NOPOWER|BROKEN)) - return - //use_power(250) // power stuff - -// var/mob/M //occupant -// if (!( src.status )) //remove this -// return -// if ((src.connected && src.connected.occupant)) //connected & occupant ok -// M = src.connected.occupant -// else -// if (istype(M, /mob)) -// //do stuff -// else -/// src.temphtml = "Process terminated due to lack of occupant in scanning chamber." -// src.status = null -// src.updateDialog() -// return - -*/ - -/obj/machinery/body_scanconsole/attack_ai(user as mob) - return src.attack_hand(user) - -/obj/machinery/body_scanconsole/attack_hand(user as mob) - if(..()) - return - if(stat & (NOPOWER|BROKEN)) - return - if(!connected || (connected.stat & (NOPOWER|BROKEN))) - user << "This console is not connected to a functioning body scanner." - return - if(!ishuman(connected.occupant)) - user << "This device can only scan compatible lifeforms." - return - - var/dat - if (src.delete && src.temphtml) //Window in buffer but its just simple message, so nothing - src.delete = src.delete - else if (!src.delete && src.temphtml) //Window in buffer - its a menu, dont add clear message - dat = text("[]

Main Menu", src.temphtml, src) - else - if (src.connected) //Is something connected? - dat = format_occupant_data(src.connected.get_occupant_data()) - dat += "
Print
" - else - dat = "Error: No Body Scanner connected." - - dat += text("
Close", user) - user << browse(dat, "window=scanconsole;size=430x600") - return + findscanner() /obj/machinery/body_scanconsole/attackby(var/obj/item/I, var/mob/user) if(istype(I, /obj/item/weapon/screwdriver) && circuit) @@ -309,206 +218,374 @@ src.attack_hand(user) return -/obj/machinery/body_scanconsole/Topic(href, href_list) - if (..()) - return +/obj/machinery/body_scanconsole/power_change() + if(stat & BROKEN) + icon_state = "body_scannerconsole-p" + else if(powered() && !panel_open) + icon_state = initial(icon_state) + stat &= ~NOPOWER + else + spawn(rand(0, 15)) + src.icon_state = "body_scannerconsole-p" + stat |= NOPOWER - if (href_list["print"]) - if (!src.connected) - usr << "\icon[src]Error: No body scanner connected." +/obj/machinery/body_scanconsole/ex_act(severity) + switch(severity) + if(1.0) + //SN src = null + qdel(src) return - var/mob/living/carbon/human/occupant = src.connected.occupant - if (!src.connected.occupant) - usr << "\icon[src]The body scanner is empty." - return - if (!istype(occupant,/mob/living/carbon/human)) - usr << "\icon[src]The body scanner cannot scan that lifeform." - return - var/obj/item/weapon/paper/R = new(src.loc) - R.name = "Body scan report" - R.info = format_occupant_data(src.connected.get_occupant_data()) - - -/obj/machinery/bodyscanner/proc/get_occupant_data() - if (!occupant || !istype(occupant, /mob/living/carbon/human)) - return - var/mob/living/carbon/human/H = occupant - var/list/occupant_data = list( - "stationtime" = worldtime2text(), - "stat" = H.stat, - "health" = round(H.health/H.maxHealth)*100, - "virus_present" = H.virus2.len, - "bruteloss" = H.getBruteLoss(), - "fireloss" = H.getFireLoss(), - "oxyloss" = H.getOxyLoss(), - "toxloss" = H.getToxLoss(), - "rads" = H.radiation, - "cloneloss" = H.getCloneLoss(), - "brainloss" = H.getBrainLoss(), - "paralysis" = H.paralysis, - "bodytemp" = H.bodytemperature, - "borer_present" = H.has_brain_worms(), - "inaprovaline_amount" = H.reagents.get_reagent_amount("inaprovaline"), - "dexalin_amount" = H.reagents.get_reagent_amount("dexalin"), - "stoxin_amount" = H.reagents.get_reagent_amount("stoxin"), - "bicaridine_amount" = H.reagents.get_reagent_amount("bicaridine"), - "dermaline_amount" = H.reagents.get_reagent_amount("dermaline"), - "blood_amount" = round((H.vessel.get_reagent_amount("blood") / H.species.blood_volume)*100), - "disabilities" = H.sdisabilities, - "lung_ruptured" = H.is_lung_ruptured(), - "external_organs" = H.organs.Copy(), - "internal_organs" = H.internal_organs.Copy(), - "species_organs" = H.species.has_organ //Just pass a reference for this, it shouldn't ever be modified outside of the datum. - ) - return occupant_data - - -/obj/machinery/body_scanconsole/proc/format_occupant_data(var/list/occ) - var/dat = "Scan performed at [occ["stationtime"]]
" - dat += "Occupant Statistics:
" - var/aux - switch (occ["stat"]) - if(0) - aux = "Conscious" - if(1) - aux = "Unconscious" + if(2.0) + if (prob(50)) + //SN src = null + qdel(src) + return else - aux = "Dead" - dat += text("[]\tHealth %: [] ([])
", ("Viral pathogen detected in blood stream.
" - dat += text("[]\t-Brute Damage %: []
", (""), occ["bruteloss"]) - dat += text("[]\t-Respiratory Damage %: []
", (""), occ["oxyloss"]) - dat += text("[]\t-Toxin Content %: []
", (""), occ["toxloss"]) - dat += text("[]\t-Burn Severity %: []

", (""), occ["fireloss"]) + return - dat += text("[]\tRadiation Level %: []
", (""), occ["rads"]) - dat += text("[]\tGenetic Tissue Damage %: []
", (""), occ["cloneloss"]) - dat += text("[]\tApprox. Brain Damage %: []
", (""), occ["brainloss"]) - dat += text("Paralysis Summary %: [] ([] seconds left!)
", occ["paralysis"], round(occ["paralysis"] / 4)) - dat += text("Body Temperature: [occ["bodytemp"]-T0C]°C ([occ["bodytemp"]*1.8-459.67]°F)

") +/obj/machinery/body_scanconsole/proc/findscanner() + spawn( 5 ) + var/obj/machinery/bodyscanner/bodyscannernew = null + // Loop through every direction + for(dir in list(NORTH,EAST,SOUTH,WEST)) + // Try to find a scanner in that direction + bodyscannernew = locate(/obj/machinery/bodyscanner, get_step(src, dir)) + src.connected = bodyscannernew + return - if(occ["borer_present"]) - dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
" +/obj/machinery/body_scanconsole/attack_ai(user as mob) + return attack_hand(user) - dat += text("[]\tBlood Level %: [] ([] units)

", (""), occ["blood_amount"], occ["blood_amount"]) +/obj/machinery/body_scanconsole/attack_ghost(user as mob) + return attack_hand(user) - dat += text("Inaprovaline: [] units
", occ["inaprovaline_amount"]) - dat += text("Soporific: [] units
", occ["stoxin_amount"]) - dat += text("[]\tDermaline: [] units

", (""), occ["dermaline_amount"]) - dat += text("[]\tBicaridine: [] units
", (""), occ["bicaridine_amount"]) - dat += text("[]\tDexalin: [] units
", (""), occ["dexalin_amount"]) +/obj/machinery/body_scanconsole/attack_hand(user as mob) + if(stat & (NOPOWER|BROKEN)) + return - dat += "
" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" + if (panel_open) + user << "Close the maintenance panel first." + return - for(var/obj/item/organ/external/e in occ["external_organs"]) - var/AN = "" - var/open = "" - var/infected = "" - var/imp = "" - var/bled = "" - var/robot = "" - var/splint = "" - var/internal_bleeding = "" - var/lung_ruptured = "" + if(!src.connected) + findscanner() - dat += "" + ui_interact(user) - for(var/datum/wound/W in e.wounds) if(W.internal) - internal_bleeding = "
Internal bleeding" - break - if(istype(e, /obj/item/organ/external/chest) && occ["lung_ruptured"]) - lung_ruptured = "Lung ruptured:" - if(e.status & ORGAN_SPLINTED) - splint = "Splinted:" - if(e.status & ORGAN_BLEEDING) - bled = "Bleeding:" - if(e.status & ORGAN_BROKEN) - AN = "[e.broken_description]:" - switch(e.robotic) - if(ORGAN_ROBOT) robot = "Prosthetic:" - if(ORGAN_ASSISTED) robot = "Augmented:" - if(e.open) - open = "Open:" +/obj/machinery/body_scanconsole/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] - switch (e.germ_level) - if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200) - infected = "Mild Infection:" - 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:" - if(e.rejecting) - infected += "(being rejected)" - if (e.implants.len) - var/unknown_body = 0 - for(var/I in e.implants) - if(is_type_in_list(I,known_implants)) - imp += "[I] implanted:" + data["connected"] = connected ? 1 : 0 + + if(connected) + data["occupied"] = connected.occupant ? 1 : 0 + + var/occupantData[0] + if(connected.occupant && ishuman(connected.occupant)) + var/mob/living/carbon/human/H = connected.occupant + occupantData["name"] = H.name + occupantData["stat"] = H.stat + occupantData["health"] = H.health + occupantData["maxHealth"] = H.maxHealth + + occupantData["hasVirus"] = H.virus2.len + + occupantData["bruteLoss"] = H.getBruteLoss() + occupantData["oxyLoss"] = H.getOxyLoss() + occupantData["toxLoss"] = H.getToxLoss() + occupantData["fireLoss"] = H.getFireLoss() + + occupantData["radLoss"] = H.radiation + occupantData["cloneLoss"] = H.getCloneLoss() + occupantData["brainLoss"] = H.getBrainLoss() + occupantData["paralysis"] = H.paralysis + occupantData["paralysisSeconds"] = round(H.paralysis / 4) + occupantData["bodyTempC"] = H.bodytemperature-T0C + occupantData["bodyTempF"] = (((H.bodytemperature-T0C) * 1.8) + 32) + + occupantData["hasBorer"] = H.has_brain_worms() + + var/bloodData[0] + if(H.vessel) + var/blood_volume = round(H.vessel.get_reagent_amount("blood")) + bloodData["volume"] = blood_volume + bloodData["percent"] = round(((blood_volume / 560)*100)) + bloodData["bloodLevel"] = round(H.vessel.get_reagent_amount("blood")) + bloodData["bloodMax"] = H.max_blood + + occupantData["blood"] = bloodData + + var/reagentData[0] + if(H.reagents.reagent_list.len >= 1) + for(var/datum/reagent/R in H.reagents.reagent_list) + reagentData[++reagentData.len] = list("name" = R.name, "amount" = R.volume) + else + reagentData = null + + occupantData["reagents"] = reagentData + + var/extOrganData[0] + for(var/obj/item/organ/external/E in H.organs) + var/organData[0] + organData["name"] = E.name + organData["open"] = E.open + organData["germ_level"] = E.germ_level + organData["bruteLoss"] = E.brute_dam + organData["fireLoss"] = E.burn_dam + organData["totalLoss"] = E.brute_dam + E.burn_dam + organData["maxHealth"] = E.max_damage + + var/implantData[0] + for(var/obj/I in E.implants) + var/implantSubData[0] + implantSubData["name"] = I.name + if(is_type_in_list(I, known_implants)) + implantSubData["known"] = 1 + + implantData.Add(list(implantSubData)) + + organData["implants"] = implantData + organData["implants_len"] = implantData.len + + var/organStatus[0] + if(E.status & ORGAN_DESTROYED) + organStatus["destroyed"] = 1 + if(E.status & ORGAN_BROKEN) + organStatus["broken"] = E.broken_description + if(E.status & ORGAN_ROBOT) + organStatus["robotic"] = 1 + if(E.status & ORGAN_SPLINTED) + organStatus["splinted"] = 1 + if(E.status & ORGAN_BLEEDING) + organStatus["bleeding"] = 1 + + organData["status"] = organStatus + + if(istype(E, /obj/item/organ/external/chest) && H.is_lung_ruptured()) + organData["lungRuptured"] = 1 + + for(var/datum/wound/W in E.wounds) + if(W.internal) + organData["internalBleeding"] = 1 + break + + extOrganData.Add(list(organData)) + + occupantData["extOrgan"] = extOrganData + + var/intOrganData[0] + for(var/obj/item/organ/I in H.internal_organs) + var/organData[0] + organData["name"] = I.name + if(I.status & ORGAN_ASSISTED) + organData["desc"] = "Assisted" + else if(I.robotic >= ORGAN_ROBOT) + organData["desc"] = "Mechanical" else - unknown_body++ - if(unknown_body) - imp += "Unknown body present:" + organData["desc"] = null + organData["germ_level"] = I.germ_level + organData["damage"] = I.damage + organData["maxHealth"] = I.max_damage - if(!AN && !open && !infected & !imp) - AN = "None:" - if(!e.is_stump()) - dat += "" + intOrganData.Add(list(organData)) + + occupantData["intOrgan"] = intOrganData + + occupantData["blind"] = (H.sdisabilities & BLIND) + occupantData["nearsighted"] = (H.disabilities & NEARSIGHTED) + + data["occupant"] = occupantData + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "adv_med.tmpl", "Body Scanner", 690, 800) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + +/obj/machinery/body_scanconsole/Topic(href, href_list) + if(..()) + return 1 + + if (href_list["print_p"]) + generate_printing_text() + + if (!(printing) && printing_text) + printing = 1 + visible_message("\The [src] rattles and prints out a sheet of paper.") + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc) + P.info = "
Body Scan - [href_list["name"]]

" + P.info += "Time of scan: [worldtime2text(world.time)]

" + P.info += "[printing_text]" + P.info += "

Notes:
" + P.name = "Body Scan - [href_list["name"]]" + printing = null + printing_text = null + + if (href_list["ejectify"]) + src.connected.eject() + +/obj/machinery/body_scanconsole/proc/generate_printing_text() + var/dat = "" + + if(connected) + var/mob/living/carbon/human/occupant = connected.occupant + dat = "Occupant Statistics:
" //Blah obvious + if(istype(occupant)) //is there REALLY someone in there? + var/t1 + switch(occupant.stat) // obvious, see what their status is + if(0) + t1 = "Conscious" + if(1) + t1 = "Unconscious" + else + t1 = "*dead*" + dat += " 50 ? "blue" : "red"]>\tHealth %: [occupant.health], ([t1])
" + + if(occupant.virus2.len) + dat += "Viral pathogen detected in blood stream.
" + + var/extra_font = null + extra_font = "" + dat += "[extra_font]\t-Brute Damage %: [occupant.getBruteLoss()]
" + + extra_font = "" + dat += "[extra_font]\t-Respiratory Damage %: [occupant.getOxyLoss()]
" + + extra_font = "" + dat += "[extra_font]\t-Toxin Content %: [occupant.getToxLoss()]
" + + extra_font = "" + dat += "[extra_font]\t-Burn Severity %: [occupant.getFireLoss()]
" + + extra_font = "" + dat += "[extra_font]\tRadiation Level %: [occupant.radiation]
" + + extra_font = "" + dat += "[extra_font]\tGenetic Tissue Damage %: [occupant.getCloneLoss()]
" + + extra_font = "" + dat += "[extra_font]\tApprox. Brain Damage %: [occupant.getBrainLoss()]
" + + dat += "Paralysis Summary %: [occupant.paralysis] ([round(occupant.paralysis / 4)] seconds left!)
" + dat += "Body Temperature: [occupant.bodytemperature-T0C]°C ([occupant.bodytemperature*1.8-459.67]°F)
" + + dat += "
" + + if(occupant.has_brain_worms()) + dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
" + + if(occupant.vessel) + var/blood_volume = round(occupant.vessel.get_reagent_amount("blood")) + var/blood_percent = blood_volume / 560 + blood_percent *= 100 + + extra_font = " 448 ? "blue" : "red"]>" + dat += "[extra_font]\tBlood Level %: [blood_percent] ([blood_volume] units)
" + + if(occupant.reagents) + for(var/datum/reagent/R in occupant.reagents) + dat += "Reagent: [R.name], Amount: [R.volume]
" + + dat += "
OrganBurn DamageBrute DamageOther Wounds
[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured]
" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + + for(var/obj/item/organ/external/e in occupant.organs) + dat += "" + var/AN = "" + var/open = "" + var/infected = "" + var/robot = "" + var/imp = "" + var/bled = "" + var/splint = "" + var/internal_bleeding = "" + var/lung_ruptured = "" + for(var/datum/wound/W in e.wounds) if(W.internal) + internal_bleeding = "
Internal bleeding" + break + if(istype(e, /obj/item/organ/external/chest) && occupant.is_lung_ruptured()) + lung_ruptured = "Lung ruptured:" + if(e.status & ORGAN_SPLINTED) + splint = "Splinted:" + if(e.status & ORGAN_BLEEDING) + bled = "Bleeding:" + if(e.status & ORGAN_BROKEN) + AN = "[e.broken_description]:" + if(e.status & ORGAN_ROBOT) + robot = "Prosthetic:" + if(e.open) + open = "Open:" + switch (e.germ_level) + if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200) + infected = "Mild Infection:" + 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:" + + var/unknown_body = 0 + for(var/I in e.implants) + if(is_type_in_list(I,known_implants)) + imp += "[I] implanted:" + else + unknown_body++ + + if(unknown_body) + imp += "Unknown body present:" + if(!AN && !open && !infected & !imp) + AN = "None:" + if(!(e.status & ORGAN_DESTROYED)) + dat += "" + else + dat += "" + dat += "" + for(var/obj/item/organ/i in occupant.internal_organs) + var/mech = "" + if(i.status & ORGAN_ASSISTED) + mech = "Assisted:" + if(i.robotic >= ORGAN_ROBOT) + mech = "Mechanical:" + var/infection = "None" + switch (i.germ_level) + if (1 to INFECTION_LEVEL_ONE + 200) + infection = "Mild Infection:" + 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 += "" + dat += "" + dat += "" + dat += "
OrganBurn DamageBrute DamageOther Wounds
[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured][e.name]--Not Found
[i.name]N/A[i.damage][infection]:[mech]
" + if(occupant.sdisabilities & BLIND) + dat += "Cataracts detected.
" + if(occupant.disabilities & NEARSIGHTED) + dat += "Retinal misalignment detected.
" else - dat += "[e.name]--Not [e.is_stump() ? "Found" : "Attached Completely"]" - dat += "" + dat += "\The [src] is empty." + else + dat = " Error: No Body Scanner connected." - for(var/obj/item/organ/i in occ["internal_organs"]) - - var/mech = "" - if(i.status & ORGAN_ASSISTED) - mech = "Assisted:" - if(i.robotic >= ORGAN_ROBOT) - mech = "Mechanical:" - - var/infection = "None" - switch (i.germ_level) - if (1 to INFECTION_LEVEL_ONE + 200) - infection = "Mild Infection:" - 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++:" - if(i.rejecting) - infection += "(being rejected)" - - dat += "" - dat += "[i.name]N/A[i.damage][infection]:[mech]" - dat += "" - dat += "" - - var/list/species_organs = occ["species_organs"] - for(var/organ_name in species_organs) - if(!locate(species_organs[organ_name]) in occ["internal_organs"]) - dat += text("No [organ_name] detected.
") - - if(occ["sdisabilities"] & BLIND) - dat += text("Cataracts detected.
") - if(occ["sdisabilities"] & NEARSIGHTED) - dat += text("Retinal misalignment detected.
") - return dat + printing_text = dat \ No newline at end of file diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index c7b5f3c73a..19d1ee1253 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -94,13 +94,8 @@ obj/machinery/computer/general_air_control/Destroy() /obj/machinery/computer/general_air_control/attack_hand(mob/user) if(..(user)) return - user << browse(return_text(),"window=computer") - user.set_machine(src) - onclose(user, "computer") -/obj/machinery/computer/general_air_control/process() - ..() - src.updateUsrDialog() + ui_interact(user) /obj/machinery/computer/general_air_control/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -110,43 +105,27 @@ obj/machinery/computer/general_air_control/Destroy() sensor_information[id_tag] = signal.data -/obj/machinery/computer/general_air_control/proc/return_text() - var/sensor_data +/obj/machinery/computer/general_air_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + + var/list/data = list() + var/sensors_ui[0] if(sensors.len) for(var/id_tag in sensors) var/long_name = sensors[id_tag] - var/list/data = sensor_information[id_tag] - var/sensor_part = "[long_name]:
" - - if(data) - if(data["pressure"]) - sensor_part += " Pressure: [data["pressure"]] kPa
" - if(data["temperature"]) - sensor_part += " Temperature: [data["temperature"]] K
" - if(data["oxygen"]||data["phoron"]||data["nitrogen"]||data["carbon_dioxide"]) - sensor_part += " Gas Composition :" - if(data["oxygen"]) - sensor_part += "[data["oxygen"]]% O2; " - if(data["nitrogen"]) - sensor_part += "[data["nitrogen"]]% N; " - if(data["carbon_dioxide"]) - sensor_part += "[data["carbon_dioxide"]]% CO2; " - if(data["phoron"]) - sensor_part += "[data["phoron"]]% TX; " - sensor_part += "
" - - else - sensor_part = "[long_name] can not be found!
" - - sensor_data += sensor_part - + var/list/sensor_data = sensor_information[id_tag] + sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data) else - sensor_data = "No sensors connected." + sensors_ui = null - var/output = {"[name]
-Sensor Data:

[sensor_data]"} + data["sensors"] = sensors_ui - return output + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 525, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/general_air_control/proc/set_frequency(new_frequency) radio_controller.remove_object(src, frequency) @@ -156,7 +135,6 @@ obj/machinery/computer/general_air_control/Destroy() /obj/machinery/computer/general_air_control/initialize() set_frequency(frequency) - /obj/machinery/computer/general_air_control/large_tank_control icon = 'icons/obj/computer.dmi' @@ -171,39 +149,41 @@ obj/machinery/computer/general_air_control/Destroy() var/pressure_setting = ONE_ATMOSPHERE * 45 circuit = /obj/item/weapon/circuitboard/air_management/tank_control +/obj/machinery/computer/general_air_control/large_tank_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) -/obj/machinery/computer/general_air_control/large_tank_control/return_text() - var/output = ..() - //if(signal.data) - // input_info = signal.data // Attempting to fix intake control -- TLE - - output += "Tank Control System

" - if(input_info) - var/power = (input_info["power"]) - var/volume_rate = round(input_info["volume_rate"], 0.1) - output += "Input: [power?("Injecting"):("On Hold")] Refresh
Flow Rate Limit: [volume_rate] L/s
" - output += "Command: Toggle Power Set Flow Rate
" - + var/list/data = list() + var/sensors_ui[0] + if(sensors.len) + for(var/id_tag in sensors) + var/long_name = sensors[id_tag] + var/list/sensor_data = sensor_information[id_tag] + sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data) else - output += "ERROR: Can not find input port Search
" + sensors_ui = null - output += "Flow Rate Limit: - - - - [round(input_flow_setting, 0.1)] L/s + + + +
" + data["sensors"] = sensors_ui + data["tanks"] = 1 - output += "
" + if(input_info) + data["input_info"] = list("power" = input_info["power"], "volume_rate" = round(input_info["volume_rate"], 0.1)) + else + data["input_info"] = null if(output_info) - var/power = (output_info["power"]) - var/output_pressure = output_info["internal"] - output += {"Output: [power?("Open"):("On Hold")] Refresh
-Max Output Pressure: [output_pressure] kPa
"} - output += "Command: Toggle Power Set Pressure
" - + data["output_info"] = list("power" = output_info["power"], "output_pressure" = output_info["internal"]) else - output += "ERROR: Can not find output port Search
" + data["output_info"] = null - output += "Max Output Pressure Set: - - - - [pressure_setting] kPa + + + +
" + data["input_flow_setting"] = round(input_flow_setting, 0.1) + data["pressure_setting"] = pressure_setting - return output + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 660, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/general_air_control/large_tank_control/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -224,15 +204,11 @@ Max Output Pressure: [output_pressure] kPa
"} if(href_list["adj_pressure"]) var/change = text2num(href_list["adj_pressure"]) pressure_setting = between(0, pressure_setting + change, 50*ONE_ATMOSPHERE) - spawn(1) - src.updateUsrDialog() return 1 if(href_list["adj_input_flow_rate"]) var/change = text2num(href_list["adj_input_flow_rate"]) input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors - spawn(1) - src.updateUsrDialog() return 1 if(!radio_connection) @@ -273,9 +249,6 @@ Max Output Pressure: [output_pressure] kPa
"} signal.data["sigtype"]="command" radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - spawn(5) - src.updateUsrDialog() - /obj/machinery/computer/general_air_control/supermatter_core icon = 'icons/obj/computer.dmi' @@ -290,39 +263,40 @@ Max Output Pressure: [output_pressure] kPa
"} var/pressure_setting = 100 circuit = /obj/item/weapon/circuitboard/air_management/supermatter_core +/obj/machinery/computer/general_air_control/supermatter_core/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) -/obj/machinery/computer/general_air_control/supermatter_core/return_text() - var/output = ..() - //if(signal.data) - // input_info = signal.data // Attempting to fix intake control -- TLE + var/list/data = list() + var/sensors_ui[0] + if(sensors.len) + for(var/id_tag in sensors) + var/long_name = sensors[id_tag] + var/list/sensor_data = sensor_information[id_tag] + sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data) + else + sensors_ui = null + + data["sensors"] = sensors_ui + data["core"] = 1 - output += "Core Cooling Control System

" if(input_info) - var/power = (input_info["power"]) - var/volume_rate = round(input_info["volume_rate"], 0.1) - output += "Coolant Input: [power?("Injecting"):("On Hold")] Refresh
Flow Rate Limit: [volume_rate] L/s
" - output += "Command: Toggle Power Set Flow Rate
" - + data["input_info"] = list("power" = input_info["power"], "volume_rate" = round(input_info["volume_rate"], 0.1)) else - output += "ERROR: Can not find input port Search
" - - output += "Flow Rate Limit: - - - - [round(input_flow_setting, 0.1)] L/s + + + +
" - - output += "
" - + data["input_info"] = null if(output_info) - var/power = (output_info["power"]) - var/pressure_limit = output_info["external"] - output += {"Core Outpump: [power?("Open"):("On Hold")] Refresh
-Min Core Pressure: [pressure_limit] kPa
"} - output += "Command: Toggle Power Set Pressure
" - + data["output_info"] = list("power" = output_info["power"], "pressure_limit" = output_info["external"]) else - output += "ERROR: Can not find output port Search
" + data["output_info"] = null - output += "Min Core Pressure Set: - - - - [pressure_setting] kPa + + + +
" + data["input_flow_setting"] = round(input_flow_setting, 0.1) + data["pressure_setting"] = pressure_setting - return output + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 650, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/general_air_control/supermatter_core/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -343,15 +317,11 @@ Min Core Pressure: [pressure_limit] kPa
"} if(href_list["adj_pressure"]) var/change = text2num(href_list["adj_pressure"]) pressure_setting = between(0, pressure_setting + change, 10*ONE_ATMOSPHERE) - spawn(1) - src.updateUsrDialog() return 1 if(href_list["adj_input_flow_rate"]) var/change = text2num(href_list["adj_input_flow_rate"]) input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors - spawn(1) - src.updateUsrDialog() return 1 if(!radio_connection) @@ -392,9 +362,6 @@ Min Core Pressure: [pressure_limit] kPa
"} signal.data["sigtype"]="command" radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - spawn(5) - src.updateUsrDialog() - /obj/machinery/computer/general_air_control/fuel_injection icon = 'icons/obj/computer.dmi' icon_screen = "alert:0" @@ -437,27 +404,34 @@ Min Core Pressure: [pressure_limit] kPa
"} ..() -/obj/machinery/computer/general_air_control/fuel_injection/return_text() - var/output = ..() - - output += "Fuel Injection System
" - if(device_info) - var/power = device_info["power"] - var/volume_rate = device_info["volume_rate"] - output += {"Status: [power?("Injecting"):("On Hold")] Refresh
-Rate: [volume_rate] L/sec
"} - - if(automation) - output += "Automated Fuel Injection: Engaged
" - output += "Injector Controls Locked Out
" - else - output += "Automated Fuel Injection: Disengaged
" - output += "Injector: Toggle Power Inject (1 Cycle)
" +/obj/machinery/computer/general_air_control/fuel_injection/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + var/list/data = list() + var/sensors_ui[0] + if(sensors.len) + for(var/id_tag in sensors) + var/long_name = sensors[id_tag] + var/list/sensor_data = sensor_information[id_tag] + sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data) else - output += "ERROR: Can not find device Search
" + sensors_ui = null - return output + data["sensors"] = sensors_ui + data["fuel"] = 1 + data["automation"] = automation + + if(device_info) + data["device_info"] = list("power" = device_info["power"], "volume_rate" = device_info["volume_rate"]) + else + data["device_info"] = null + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 650, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/general_air_control/fuel_injection/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 8427a08418..5cc9801d0f 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -22,62 +22,51 @@ add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - interact(user) + ui_interact(user) /obj/machinery/computer/operating/attack_hand(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - interact(user) - - -/obj/machinery/computer/operating/interact(mob/user) - if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) ) - if (!istype(user, /mob/living/silicon)) - user.unset_machine() - user << browse(null, "window=op") - return + ui_interact(user) +/** + * Display the NanoUI window for the operating computer. + * + * See NanoUI documentation for details. + */ +/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) user.set_machine(src) - var/dat = "Operating Computer\n" - dat += "Close

" //| Update" - if(src.table && (src.table.check_victim())) - src.victim = src.table.victim - dat += {" -Patient Information:
-
-Name: [src.victim.real_name]
-Age: [src.victim.age]
-Blood Type: [src.victim.b_type]
-
-Health: [src.victim.health]
-Brute Damage: [src.victim.getBruteLoss()]
-Toxins Damage: [src.victim.getToxLoss()]
-Fire Damage: [src.victim.getFireLoss()]
-Suffocation Damage: [src.victim.getOxyLoss()]
-Patient Status: [src.victim.stat ? "Non-Responsive" : "Stable"]
-Heartbeat rate: [victim.get_pulse(GETPULSE_TOOL)]
-"} - else - src.victim = null - dat += {" -Patient Information:
-
-No Patient Detected -"} - user << browse(dat, "window=op") - onclose(user, "op") + var/list/data = list() + var/list/victim_ui = list() + + if(table && (table.check_victim())) + victim = table.victim + + victim_ui = list("real_name" = victim.real_name, "age" = victim.age, "b_type" = victim.b_type, "health" = victim.health, + "brute" = victim.getBruteLoss(), "tox" = src.victim.getToxLoss(), "burn" = victim.getFireLoss(), "oxy" = victim.getOxyLoss(), + "stat" = (victim.stat ? "Non-Responsive" : "Stable"), "pulse" = victim.get_pulse(GETPULSE_TOOL)) + else + victim = null + victim_ui = null + + data["table"] = table + data["victim"] = victim_ui + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "operating.tmpl", src.name, 380, 400) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/operating/Topic(href, href_list) if(..()) return 1 if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) - return - -/obj/machinery/computer/operating/process() - if(..()) - src.updateDialog() + src.add_fingerprint(usr) + nanomanager.update_uis(src) \ No newline at end of file diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 189fe5b40a..d338edacc1 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -53,7 +53,7 @@ prize.loc = src.loc /obj/machinery/computer/arcade/attack_ai(mob/user as mob) - return src.attack_hand(user) + return attack_hand(user) /obj/machinery/computer/arcade/emp_act(severity) @@ -84,6 +84,7 @@ circuit = /obj/item/weapon/circuitboard/arcade/battle var/enemy_name = "Space Villian" var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc + var/enemy_action = "" var/player_hp = 30 //Player health/attack points var/player_mp = 10 var/enemy_hp = 45 //Enemy health/attack points @@ -103,81 +104,80 @@ name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers") - src.enemy_name = replacetext((name_part1 + name_part2), "the ", "") - src.name = (name_action + name_part1 + name_part2) + enemy_name = replacetext((name_part1 + name_part2), "the ", "") + name = (name_action + name_part1 + name_part2) /obj/machinery/computer/arcade/battle/attack_hand(mob/user as mob) if(..()) return user.set_machine(src) - var/dat = "Close" - dat += "

[src.enemy_name]

" + ui_interact(user) - dat += "

[src.temp]

" - dat += "
Health: [src.player_hp] | Magic: [src.player_mp] | Enemy Health: [src.enemy_hp]
" +/** + * Display the NanoUI window for the arcade machine. + * + * See NanoUI documentation for details. + */ +/obj/machinery/computer/arcade/battle/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) - dat += "
" - if (src.gameover) - dat += "New Game" - else - dat += "Attack | " - dat += "Heal | " - dat += "Recharge Power" + var/list/data = list() + data["temp"] = temp + data["enemyAction"] = enemy_action + data["enemyName"] = enemy_name + data["playerHP"] = player_hp + data["playerMP"] = player_mp + data["enemyHP"] = enemy_hp + data["gameOver"] = gameover - dat += "
" - - user << browse(dat, "window=arcade") - onclose(user, "arcade") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "arcade_battle.tmpl", src.name, 400, 300) + ui.set_initial_data(data) + ui.open() + //ui.set_auto_update(2) /obj/machinery/computer/arcade/battle/Topic(href, href_list) if(..()) return 1 - if (!src.blocked && !src.gameover) + if (!blocked && !gameover) if (href_list["attack"]) - src.blocked = 1 + blocked = 1 var/attackamt = rand(2,6) - src.temp = "You attack for [attackamt] damage!" - src.updateUsrDialog() + temp = "You attack for [attackamt] damage!" if(turtle > 0) turtle-- sleep(10) - src.enemy_hp -= attackamt - src.arcade_action() + enemy_hp -= attackamt + arcade_action() else if (href_list["heal"]) - src.blocked = 1 + blocked = 1 var/pointamt = rand(1,3) var/healamt = rand(6,8) - src.temp = "You use [pointamt] magic to heal for [healamt] damage!" - src.updateUsrDialog() + temp = "You use [pointamt] magic to heal for [healamt] damage!" turtle++ sleep(10) - src.player_mp -= pointamt - src.player_hp += healamt - src.blocked = 1 - src.updateUsrDialog() - src.arcade_action() + player_mp -= pointamt + player_hp += healamt + blocked = 1 + arcade_action() else if (href_list["charge"]) - src.blocked = 1 + blocked = 1 var/chargeamt = rand(4,7) - src.temp = "You regain [chargeamt] points" - src.player_mp += chargeamt + temp = "You regain [chargeamt] points" + player_mp += chargeamt if(turtle > 0) turtle-- - src.updateUsrDialog() sleep(10) - src.arcade_action() + arcade_action() - if (href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=arcade") else if (href_list["newgame"]) //Reset everything temp = "New Round" @@ -193,14 +193,14 @@ emagged = 0 src.add_fingerprint(usr) - src.updateUsrDialog() + nanomanager.update_uis(src) return /obj/machinery/computer/arcade/battle/proc/arcade_action() - if ((src.enemy_mp <= 0) || (src.enemy_hp <= 0)) + if ((enemy_mp <= 0) || (enemy_hp <= 0)) if(!gameover) - src.gameover = 1 - src.temp = "[src.enemy_name] has fallen! Rejoice!" + gameover = 1 + temp = "[enemy_name] has fallen! Rejoice!" if(emagged) feedback_inc("arcade_win_emagged") @@ -212,53 +212,52 @@ emagged = 0 else if(!contents.len) feedback_inc("arcade_win_normal") - src.prizevend() + prizevend() else feedback_inc("arcade_win_normal") - src.prizevend() + prizevend() else if (emagged && (turtle >= 4)) var/boomamt = rand(5,10) - src.temp = "[src.enemy_name] throws a bomb, exploding you for [boomamt] damage!" - src.player_hp -= boomamt + enemy_action = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!" + player_hp -= boomamt - else if ((src.enemy_mp <= 5) && (prob(70))) + else if ((enemy_mp <= 5) && (prob(70))) var/stealamt = rand(2,3) - src.temp = "[src.enemy_name] steals [stealamt] of your power!" - src.player_mp -= stealamt - src.updateUsrDialog() + enemy_action = "[enemy_name] steals [stealamt] of your power!" + player_mp -= stealamt - if (src.player_mp <= 0) - src.gameover = 1 + if (player_mp <= 0) + gameover = 1 sleep(10) - src.temp = "You have been drained! GAME OVER" + temp = "You have been drained! GAME OVER" if(emagged) feedback_inc("arcade_loss_mana_emagged") usr.gib() else feedback_inc("arcade_loss_mana_normal") - else if ((src.enemy_hp <= 10) && (src.enemy_mp > 4)) - src.temp = "[src.enemy_name] heals for 4 health!" - src.enemy_hp += 4 - src.enemy_mp -= 4 + else if ((enemy_hp <= 10) && (enemy_mp > 4)) + enemy_action = "[enemy_name] heals for 4 health!" + enemy_hp += 4 + enemy_mp -= 4 else var/attackamt = rand(3,6) - src.temp = "[src.enemy_name] attacks for [attackamt] damage!" - src.player_hp -= attackamt + enemy_action = "[enemy_name] attacks for [attackamt] damage!" + player_hp -= attackamt - if ((src.player_mp <= 0) || (src.player_hp <= 0)) - src.gameover = 1 - src.temp = "You have been crushed! GAME OVER" + if ((player_mp <= 0) || (player_hp <= 0)) + gameover = 1 + temp = "You have been crushed! GAME OVER" if(emagged) feedback_inc("arcade_loss_hp_emagged") usr.gib() else feedback_inc("arcade_loss_hp_normal") - src.blocked = 0 + blocked = 0 return @@ -276,7 +275,6 @@ enemy_name = "Cuban Pete" name = "Outbomb Cuban Pete" - src.updateUsrDialog() return 1 diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index bdab3bbbb1..da165448da 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -16,6 +16,7 @@ var/obj/item/weapon/disk/data/diskette = null //Mostly so the geneticist can steal everything. var/loading = 0 // Nice loading text + /obj/machinery/computer/cloning/initialize() ..() updatemodules() @@ -25,7 +26,7 @@ ..() /obj/machinery/computer/cloning/proc/updatemodules() - src.scanner = findscanner() + scanner = findscanner() releasecloner() findcloner() @@ -63,12 +64,12 @@ /obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES - if (!src.diskette) + if (!diskette) user.drop_item() W.loc = src - src.diskette = W + diskette = W user << "You insert [W]." - src.updateUsrDialog() + updateUsrDialog() return else if(istype(W, /obj/item/device/multitool)) var/obj/item/device/multitool/M = W @@ -78,6 +79,15 @@ P.connected = src P.name = "[initial(P.name)] #[pods.len]" user << "You connect [P] to [src]." + + else if (menu == 4 && (istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))) + if(check_access(W)) + records.Remove(active_record) + qdel(active_record) + temp = "Record deleted." + menu = 2 + else + temp = "Access Denied." else ..() return @@ -94,109 +104,55 @@ updatemodules() - var/dat = "

Cloning System Control

" - dat += "Refresh" + ui_interact(user) - dat += "
[temp]
" +/obj/machinery/computer/cloning/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) - switch(src.menu) - if(1) - // Modules - dat += "

Modules

" - //dat += "Reload Modules" - if (isnull(src.scanner)) - dat += " DNA scanner not found.
" - else - dat += " DNA scanner found.
" - if (pods.len) - dat += " [pods.len] cloning vat\s found.
" - else - dat += " No cloning vats found.
" + var/data[0] - // Scanner - dat += "

Scanner Functions

" + var/records_list_ui[0] + for(var/datum/dna2/record/R in records) + records_list_ui[++records_list_ui.len] = list("ckey" = R.ckey, "name" = R.dna.real_name) - if(loading) - dat += "Scanning...
" - else - dat += "[scantemp]
" + var/pods_list_ui[0] + for(var/obj/machinery/clonepod/pod in pods) + pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.biomass) - if (isnull(src.scanner)) - dat += "No scanner connected!
" - else - if (src.scanner.occupant) - if(scantemp == "Scanner unoccupied") scantemp = "" // Stupid check to remove the text + if(pods) + data["pods"] = pods_list_ui + else + data["pods"] = null - dat += "Scan - [src.scanner.occupant]
" - else - scantemp = "Scanner unoccupied" + if(records) + data["records"] = records_list_ui + else + data["records"] = null - dat += "Lock status: [src.scanner.locked ? "Locked" : "Unlocked"]
" + if(active_record) + data["activeRecord"] = list("ckey" = active_record.ckey, "real_name" = active_record.dna.real_name, \ + "ui" = active_record.dna.uni_identity, "se" = active_record.dna.struc_enzymes) + else + data["activeRecord"] = null - if (pods.len) - for (var/obj/machinery/clonepod/pod in pods) - dat += "[pod] biomass: [pod.biomass]
" + data["menu"] = menu + data["connected"] = scanner + data["podsLen"] = pods.len + data["loading"] = loading + if(!scanner.occupant) + scantemp = "" + data["scantemp"] = scantemp + data["occupant"] = scanner.occupant + data["locked"] = scanner.locked + data["diskette"] = diskette + data["temp"] = temp - // Database - dat += "

Database Functions

" - dat += "View Records
" - if (src.diskette) - dat += "Eject Disk" - - - if(2) - dat += "

Current records

" - dat += "Back

" - for(var/datum/dna2/record/R in src.records) - dat += "
  • [R.dna.real_name]
  • " - - if(3) - dat += "

    Selected Record

    " - dat += "Back
    " - - if (!src.active_record) - dat += "ERROR: Record not found." - else - dat += {"
    Delete Record
    - Name: [src.active_record.dna.real_name]
    "} - var/obj/item/weapon/implant/health/H = null - if(src.active_record.implant) - H=locate(src.active_record.implant) - - if ((H) && (istype(H))) - dat += "Health: [H.sensehealth()] | OXY-BURN-TOX-BRUTE
    " - else - dat += "Unable to locate implant.
    " - - if (!isnull(src.diskette)) - dat += "Load from disk." - - dat += " | Save: UI + UE" - dat += " | Save: UI" - dat += " | Save: SE" - dat += "
    " - else - dat += "
    " //Keeping a line empty for appearances I guess. - - dat += {"UI: [src.active_record.dna.uni_identity]
    - SE: [src.active_record.dna.struc_enzymes]

    "} - - if(pods.len) - dat += {"Clone
    "} - - if(4) - if (!src.active_record) - src.menu = 2 - dat = "[src.temp]
    " - dat += "

    Confirm Record Deletion

    " - - dat += "Scan card to confirm.
    " - dat += "No" - - - user << browse(dat, "window=cloning") - onclose(user, "cloning") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "cloning.tmpl", src.name, 400, 450) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) /obj/machinery/computer/cloning/Topic(href, href_list) if(..()) @@ -205,101 +161,87 @@ if(loading) return - if ((href_list["scan"]) && (!isnull(src.scanner))) + if ((href_list["scan"]) && (!isnull(scanner))) scantemp = "" loading = 1 - src.updateUsrDialog() spawn(20) - src.scan_mob(src.scanner.occupant) + scan_mob(scanner.occupant) loading = 0 - src.updateUsrDialog() - //No locking an open scanner. - else if ((href_list["lock"]) && (!isnull(src.scanner))) - if ((!src.scanner.locked) && (src.scanner.occupant)) - src.scanner.locked = 1 + else if ((href_list["lock"]) && (!isnull(scanner))) + if ((!scanner.locked) && (scanner.occupant)) + scanner.locked = 1 else - src.scanner.locked = 0 + scanner.locked = 0 + + else if ((href_list["eject"]) && (!isnull(scanner))) + if ((!scanner.locked) && (scanner.occupant)) + scanner.eject_occupant() else if (href_list["view_rec"]) - src.active_record = locate(href_list["view_rec"]) - if(istype(src.active_record,/datum/dna2/record)) - if ((isnull(src.active_record.ckey))) - qdel(src.active_record) - src.temp = "ERROR: Record Corrupt" + active_record = find_record(href_list["view_rec"]) + if(istype(active_record,/datum/dna2/record)) + if ((isnull(active_record.ckey))) + qdel(active_record) + temp = "ERROR: Record Corrupt" else - src.menu = 3 + menu = 3 else - src.active_record = null - src.temp = "Record missing." + active_record = null + temp = "Record missing." else if (href_list["del_rec"]) - if ((!src.active_record) || (src.menu < 3)) + if ((!active_record) || (menu < 3)) return - if (src.menu == 3) //If we are viewing a record, confirm deletion - src.temp = "Delete record?" - src.menu = 4 - - else if (src.menu == 4) - var/obj/item/weapon/card/id/C = usr.get_active_hand() - if (istype(C)||istype(C, /obj/item/device/pda)) - if(src.check_access(C)) - src.records.Remove(src.active_record) - qdel(src.active_record) - src.temp = "Record deleted." - src.menu = 2 - else - src.temp = "Access Denied." + if (menu == 3) //If we are viewing a record, confirm deletion + temp = "Delete record?" + menu = 4 else if (href_list["disk"]) //Load or eject. switch(href_list["disk"]) if("load") - if ((isnull(src.diskette)) || isnull(src.diskette.buf)) - src.temp = "Load error." - src.updateUsrDialog() + if ((isnull(diskette)) || isnull(diskette.buf)) + temp = "Load error." return - if (isnull(src.active_record)) - src.temp = "Record error." - src.menu = 1 - src.updateUsrDialog() + if (isnull(active_record)) + temp = "Record error." + menu = 1 return - src.active_record = src.diskette.buf + active_record = diskette.buf - src.temp = "Load successful." + temp = "Load successful." if("eject") - if (!isnull(src.diskette)) - src.diskette.loc = src.loc - src.diskette = null + if (!isnull(diskette)) + diskette.loc = loc + diskette = null else if (href_list["save_disk"]) //Save to disk! - if ((isnull(src.diskette)) || (src.diskette.read_only) || (isnull(src.active_record))) - src.temp = "Save error." - src.updateUsrDialog() - return + if ((isnull(diskette)) || (diskette.read_only) || (isnull(active_record))) + temp = "Save error." // DNA2 makes things a little simpler. - src.diskette.buf=src.active_record - src.diskette.buf.types=0 + diskette.buf = active_record + diskette.buf.types = 0 switch(href_list["save_disk"]) //Save as Ui/Ui+Ue/Se if("ui") - src.diskette.buf.types=DNA2_BUF_UI + diskette.buf.types = DNA2_BUF_UI if("ue") - src.diskette.buf.types=DNA2_BUF_UI|DNA2_BUF_UE + diskette.buf.types = DNA2_BUF_UI | DNA2_BUF_UE if("se") - src.diskette.buf.types=DNA2_BUF_SE - src.diskette.name = "data disk - '[src.active_record.dna.real_name]'" - src.temp = "Save \[[href_list["save_disk"]]\] successful." + diskette.buf.types = DNA2_BUF_SE + diskette.name = "data disk - '[active_record.dna.real_name]'" + temp = "Save \[[href_list["save_disk"]]\] successful." else if (href_list["refresh"]) - src.updateUsrDialog() + updateUsrDialog() else if (href_list["clone"]) - var/datum/dna2/record/C = locate(href_list["clone"]) + var/datum/dna2/record/C = find_record(href_list["clone"]) //Look for that player! They better be dead! if(istype(C)) //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. @@ -340,11 +282,12 @@ temp = "Error: Data corruption." else if (href_list["menu"]) - src.menu = text2num(href_list["menu"]) + menu = href_list["menu"] + temp = "" + scantemp = "" - src.add_fingerprint(usr) - src.updateUsrDialog() - return + nanomanager.update_uis(src) + add_fingerprint(usr) /obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob) if ((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna)) @@ -381,13 +324,13 @@ subject.dna.check_integrity() var/datum/dna2/record/R = new /datum/dna2/record() - R.dna=subject.dna + R.dna = subject.dna R.ckey = subject.ckey - R.id= copytext(md5(subject.real_name), 2, 6) - R.name=R.dna.real_name - R.types=DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE - R.languages=subject.languages - R.flavor=subject.flavor_texts.Copy() + R.id = copytext(md5(subject.real_name), 2, 6) + R.name = R.dna.real_name + R.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE + R.languages = subject.languages + R.flavor = subject.flavor_texts.Copy() //Add an implant if needed var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject) @@ -402,13 +345,13 @@ if (!isnull(subject.mind)) //Save that mind so traitors can continue traitoring after cloning. R.mind = "\ref[subject.mind]" - src.records += R + records += R scantemp = "Subject successfully scanned." //Find a specific record by key. /obj/machinery/computer/cloning/proc/find_record(var/find_key) var/selected_record = null - for(var/datum/dna2/record/R in src.records) + for(var/datum/dna2/record/R in records) if (R.ckey == find_key) selected_record = R break diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index a4553403bc..b3f9765746 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -88,7 +88,7 @@ if(!giver && user.unEquip(I)) I.forceMove(src) giver = I - updateUsrDialog() + nanomanager.update_uis(src) else if(giver) user << "There is already ID card inside." return @@ -102,40 +102,51 @@ return user.set_machine(src) - var/dat - if (mode == 1) //Logs - dat += "

    Activity log


    " - for (var/entry in internal_log) - dat += "[entry]

    " - dat += "Print
    " - dat += "Back
    " - else - dat += "

    Guest pass terminal #[uid]


    " - dat += "View activity log

    " - dat += "Issuing ID: [giver]
    " - dat += "Issued to: [giv_name]
    " - dat += "Reason: [reason]
    " - dat += "Duration (minutes): [duration] m
    " - dat += "Access to areas:
    " - if (giver && giver.access) - for (var/A in giver.access) - var/area = get_access_desc(A) - if (A in accesses) - area = "[area]" - dat += "[area]
    " - dat += "
    Issue pass
    " + ui_interact(user) - user << browse(dat, "window=guestpass;size=400x520") - onclose(user, "guestpass") +/** + * Display the NanoUI window for the guest pass console. + * + * See NanoUI documentation for details. + */ +/obj/machinery/computer/guestpass/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + var/list/data = list() + + var/area_list[0] + + if (giver && giver.access) + data["access"] = giver.access + for (var/A in giver.access) + if(A in accesses) + area_list[++area_list.len] = list("area" = A, "area_name" = get_access_desc(A), "on" = 1) + else + area_list[++area_list.len] = list("area" = A, "area_name" = get_access_desc(A), "on" = null) + + data["giver"] = giver + data["giveName"] = giv_name + data["reason"] = reason + data["duration"] = duration + data["area"] = area_list + data["mode"] = mode + data["log"] = internal_log + data["uid"] = uid + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "guest_pass.tmpl", src.name, 400, 520) + ui.set_initial_data(data) + ui.open() + //ui.set_auto_update(5) /obj/machinery/computer/guestpass/Topic(href, href_list) if(..()) return 1 usr.set_machine(src) if (href_list["mode"]) - mode = text2num(href_list["mode"]) + mode = href_list["mode"] if (href_list["choice"]) switch(href_list["choice"]) @@ -182,7 +193,6 @@ if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) I.loc = src giver = I - updateUsrDialog() if ("print") var/dat = "

    Activity log of guest pass terminal #[uid]


    " @@ -214,5 +224,6 @@ pass.name = "guest pass #[number]" else usr << "Cannot issue pass without issuing ID." - updateUsrDialog() - return + + src.add_fingerprint(usr) + nanomanager.update_uis(src) \ No newline at end of file diff --git a/code/game/machinery/computer3/lapvend.dm b/code/game/machinery/computer3/lapvend.dm index efd0747b35..6acb530acc 100644 --- a/code/game/machinery/computer3/lapvend.dm +++ b/code/game/machinery/computer3/lapvend.dm @@ -6,12 +6,10 @@ layer = 2.9 anchored = 1 density = 1 - var/datum/browser/popup = null var/obj/machinery/computer3/laptop/vended/newlap = null var/obj/item/device/laptop/relap = null var/vendmode = 0 - var/cardreader = 0 var/floppy = 0 var/radionet = 0 @@ -34,9 +32,11 @@ if(vendmode == 1 && I) scan_id(I, W) vendmode = 0 - if(vendmode == 3 && I) + nanomanager.update_uis(src) + if(vendmode == 2 && I) if(reimburse_id(I, W)) vendmode = 0 + nanomanager.update_uis(src) if(vendmode == 0) if(istype(W, /obj/item/device/laptop)) var/obj/item/device/laptop/L = W @@ -44,84 +44,49 @@ calc_reimburse(L) usr.drop_item() L.loc = src - vendmode = 3 + vendmode = 2 usr << "You slot your [L.name] into \The [src.name]" + nanomanager.update_uis(src) else ..() /obj/machinery/lapvend/attack_hand(mob/user as mob) + if(stat & (BROKEN|NOPOWER)) + return + + ui_interact(user) + +/** + * Display the NanoUI window for the vending machine. + * + * See NanoUI documentation for details. + */ +/obj/machinery/lapvend/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) user.set_machine(src) - var/vendorname = (src.name) //import the machine's name - var/dat = "
    [vendorname]


    " //display the name, and added a horizontal rule - if(vendmode == 0) - dat += "
    Please choose your laptop customization options

    " - dat += "
    Your comptuer will automatically be loaded with any programs you can use after the transaction is complete.
    " - dat += "
    Some programs will require additional components to be installed!


    " - dat += "
    HDD (Required) : Added

    " - dat += "
    Card Reader : Single (50) | Dual (125)

    " - dat += "
    Floppy Drive: Add (50)

    " - dat += "
    Radio Network card Add (50)

    " - dat += "
    Camera Card Add (100)

    " - dat += "
    Network card Area (75) Adjacent (50)Powernet (25)

    " - dat += "
    Power source upgrade
    Extended (175) Unreal (250)" - if(vendmode == 0 || vendmode == 1) - dat += "

    Cart

    " - dat += "Total: [total()]
    " - if(cardreader == 1) - dat += "Card Reader: (single) (50)
    " - else if (cardreader == 2) - dat += "Card Reader: (double) (125)
    " - else - dat += "Card Reader: None
    " - if(floppy == 0) - dat += "Floppy Drive: None
    " - else - dat += "Floppy Drive: Added (50)
    " - if(radionet == 1) - dat += "Radio Card: Added (50)
    " - else - dat += "Radio Card: None
    " - if(camera == 1) - dat += "Camera Card: Added (100)
    " - else - dat += "Camera Card: None
    " - if(network == 1) - dat += "Network card: Area (75)
    " - else if(network == 2) - dat += "Network card: Adjacent (50)
    " - else if(network == 3) - dat += "Network card: Powernet (25)
    " - else - dat += "Network card: None" - if (power == 0) - dat += "Power source: Regular" - else if (power == 1) - dat += "Power source: Extended (175)
    " - else - dat += "Power source: Unreal (250)
    " - - if(vendmode == 0) - dat += "
    Vend Laptop" - - if(vendmode == 1) - dat += "Please swipe your card and enter your PIN to complete the transaction" - - if(vendmode == 3) - dat += "Please swipe your card and enter your PIN to be finish returning your computer
    " - dat += "Cancel" - - - - - popup = new(user, "lapvend", name, 450, 500) - popup.set_content(dat) - popup.open() - return + var/list/data = list() + data["mode"] = vendmode + data["cardreader"] = cardreader + data["floppy"] = floppy + data["radionet"] = radionet + data["camera"] = camera + data["network"] = network + data["power"] = power + data["total"] = total() + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "laptop_vendor.tmpl", src.name, 480, 425) + ui.set_initial_data(data) + ui.open() + //ui.set_auto_update(5) /obj/machinery/lapvend/Topic(href, href_list) + if(stat & (BROKEN|NOPOWER)) + return + if(usr.stat || usr.restrained()) + return if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) usr.set_machine(src) switch(href_list["choice"]) @@ -146,7 +111,7 @@ if ("super_add") power = 2 - if ("single_rem" || "dual_rem") + if ("cardreader_rem") cardreader = 0 if ("floppy_rem") floppy = 0 @@ -154,9 +119,9 @@ radionet = 0 if ("camnet_rem") camera = 0 - if ("area_rem" || "prox_rem" || "cable_rem") + if ("network_rem") network = 0 - if ("high_rem" || "super_rem") + if ("power_rem") power = 0 if("vend") @@ -168,9 +133,8 @@ relap = null vendmode = 0 - src.updateUsrDialog() - return - + src.add_fingerprint(usr) + nanomanager.update_uis(src) /obj/machinery/lapvend/proc/vend() if(cardreader > 0) @@ -253,7 +217,6 @@ choose_progs(C) vend() - popup.close() newlap.close_laptop() newlap = null cardreader = 0 diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index 927facec8d..779f76fc93 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -57,6 +57,12 @@ var/list/flooring_types build_type = null /decl/flooring/snow + name = "snow" + desc = "A layer of many tiny bits of frozen water. It's hard to tell how deep it is." + icon = 'icons/turf/snow_new.dmi' + icon_base = "snow" + +/decl/flooring/snow/snow2 name = "snow" desc = "A layer of many tiny bits of frozen water. It's hard to tell how deep it is." icon = 'icons/turf/snow.dmi' diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm index 86ec1b2891..55795bc5b3 100644 --- a/code/game/turfs/flooring/flooring_premade.dm +++ b/code/game/turfs/flooring/flooring_premade.dm @@ -45,27 +45,6 @@ icon_state = "reinforced" initial_flooring = /decl/flooring/reinforced -/turf/simulated/floor/snow - name = "snow" - icon = 'icons/turf/snow.dmi' - icon_state = "snow" - initial_flooring = /decl/flooring/snow - -/turf/simulated/floor/snow/gravsnow - name = "snow" - icon_state = "gravsnow" - initial_flooring = /decl/flooring/snow/gravsnow - -/turf/simulated/floor/snow/plating - name = "snowy playing" - icon_state = "snowyplating" - initial_flooring = /decl/flooring/snow/plating - -/turf/simulated/floor/snow/plating/drift - name = "snowy plating" - icon_state = "snowyplayingdrift" - initial_flooring = /decl/flooring/snow/plating/drift - /turf/simulated/floor/reinforced/airless oxygen = 0 nitrogen = 0 @@ -225,4 +204,57 @@ /turf/simulated/floor/beach/water/ocean */ /turf/simulated/floor/airless/ceiling -/turf/simulated/floor/plating \ No newline at end of file +/turf/simulated/floor/plating + + +//**** Here lives snow **** +/turf/simulated/floor/snow + name = "snow" + icon = 'icons/turf/snow_new.dmi' + icon_state = "snow" + var/list/crossed_dirs = list() + +/turf/simulated/floor/snow/snow2 + name = "snow" + icon = 'icons/turf/snow.dmi' + icon_state = "snow" + initial_flooring = /decl/flooring/snow + +/turf/simulated/floor/snow/gravsnow + name = "snow" + icon_state = "gravsnow" + initial_flooring = /decl/flooring/snow/gravsnow + +/turf/simulated/floor/snow/plating + name = "snowy playing" + icon_state = "snowyplating" + initial_flooring = /decl/flooring/snow/plating + +/turf/simulated/floor/snow/plating/drift + name = "snowy plating" + icon_state = "snowyplayingdrift" + initial_flooring = /decl/flooring/snow/plating/drift + +#define FOOTSTEP_SPRITE_AMT 2 + +/turf/snow/Entered(atom/A) + if(ismob(A)) + var/mdir = "[A.dir]" + if(crossed_dirs[mdir]) + crossed_dirs[mdir] = min(crossed_dirs[mdir] + 1, FOOTSTEP_SPRITE_AMT) + else + crossed_dirs[mdir] = 1 + + update_icon() + + . = ..() + +/turf/snow/update_icon() + overlays.Cut() + for(var/d in crossed_dirs) + var/amt = crossed_dirs[d] + + for(var/i in 1 to amt) + overlays += icon(icon, "footprint[i]", text2num(d)) + +//**** Here ends snow **** \ No newline at end of file diff --git a/code/game/turfs/snow/snow.dm b/code/game/turfs/snow/snow.dm new file mode 100644 index 0000000000..b09275ca41 --- /dev/null +++ b/code/game/turfs/snow/snow.dm @@ -0,0 +1,51 @@ +/turf/snow + name = "snow" + + dynamic_lighting = 0 + icon = 'icons/turf/snow_new.dmi' + icon_state = "snow" + + oxygen = MOLES_O2STANDARD * 1.15 + nitrogen = MOLES_N2STANDARD * 1.15 + + temperature = TN60C + var/list/crossed_dirs = list() + +#define FOOTSTEP_SPRITE_AMT 2 + +/turf/snow/Entered(atom/A) + if(ismob(A)) + var/mdir = "[A.dir]" + if(crossed_dirs[mdir]) + crossed_dirs[mdir] = min(crossed_dirs[mdir] + 1, FOOTSTEP_SPRITE_AMT) + else + crossed_dirs[mdir] = 1 + + update_icon() + + . = ..() + +/turf/snow/update_icon() + overlays.Cut() + for(var/d in crossed_dirs) + var/amt = crossed_dirs[d] + + for(var/i in 1 to amt) + overlays += icon(icon, "footprint[i]", text2num(d)) + +/turf/snow/snow2 + name = "snow" + icon = 'icons/turf/snow.dmi' + icon_state = "snow" + +/turf/snow/gravsnow + name = "snow" + icon_state = "gravsnow" + +/turf/snow/plating + name = "snowy playing" + icon_state = "snowyplating" + +/turf/snow/drift + name = "snowy plating" + icon_state = "snowyplayingdrift" diff --git a/code/hub.dm b/code/hub.dm index 6c38b00143..767ff8510f 100644 --- a/code/hub.dm +++ b/code/hub.dm @@ -1,8 +1,10 @@ /world hub = "Exadv1.spacestation13" - hub_password = "SORRYNOPASSWORD" + hub_password = "kMZy3U5jJHSiBQjr" + //hub_password = "SORRYNOPASSWORD" name = "Space Station 13" + /* This is for any host that would like their server to appear on the main SS13 hub. To use it, simply replace the password above, with the password found below, and it should work. If not, let us know on the main tgstation IRC channel of irc.rizon.net #tgstation13 we can help you there. diff --git a/code/modules/admin/verbs/buildmode.dm b/code/modules/admin/verbs/buildmode.dm index 0ecc220ae2..5a211d960b 100644 --- a/code/modules/admin/verbs/buildmode.dm +++ b/code/modules/admin/verbs/buildmode.dm @@ -71,38 +71,61 @@ screen_loc = "NORTH,WEST+1" Click() switch(master.cl.buildmode) - if(1) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button = Construct / Upgrade" - usr << "\blue Right Mouse Button = Deconstruct / Delete / Downgrade" - usr << "\blue Left Mouse Button + ctrl = R-Window" - usr << "\blue Left Mouse Button + alt = Airlock" + if(1) // Basic Build + usr << "***********************************************************" + usr << "Left Mouse Button = Construct / Upgrade" + usr << "Right Mouse Button = Deconstruct / Delete / Downgrade" + usr << "Left Mouse Button + ctrl = R-Window" + usr << "Left Mouse Button + alt = Airlock" usr << "" - usr << "\blue Use the button in the upper left corner to" - usr << "\blue change the direction of built objects." - usr << "\blue ***********************************************************" - if(2) - usr << "\blue ***********************************************************" - usr << "\blue Right Mouse Button on buildmode button = Set object type" - usr << "\blue Middle Mouse Button on buildmode button= On/Off object type saying" - usr << "\blue Middle Mouse Button on turf/obj = Capture object type" - usr << "\blue Left Mouse Button on turf/obj = Place objects" - usr << "\blue Right Mouse Button = Delete objects" + usr << "Use the button in the upper left corner to" + usr << "change the direction of built objects." + usr << "***********************************************************" + if(2) // Adv. Build + usr << "***********************************************************" + usr << "Right Mouse Button on buildmode button = Set object type" + usr << "Middle Mouse Button on buildmode button= On/Off object type saying" + usr << "Middle Mouse Button on turf/obj = Capture object type" + usr << "Left Mouse Button on turf/obj = Place objects" + usr << "Right Mouse Button = Delete objects" + usr << "Mouse Button + ctrl = Copy object type" usr << "" - usr << "\blue Use the button in the upper left corner to" - usr << "\blue change the direction of built objects." - usr << "\blue ***********************************************************" - if(3) - usr << "\blue ***********************************************************" - usr << "\blue Right Mouse Button on buildmode button = Select var(type) & value" - usr << "\blue Left Mouse Button on turf/obj/mob = Set var(type) & value" - usr << "\blue Right Mouse Button on turf/obj/mob = Reset var's value" - usr << "\blue ***********************************************************" - if(4) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button on turf/obj/mob = Select" - usr << "\blue Right Mouse Button on turf/obj/mob = Throw" - usr << "\blue ***********************************************************" + usr << "Use the button in the upper left corner to" + usr << "change the direction of built objects." + usr << "***********************************************************" + if(3) // Edit + usr << "***********************************************************" + usr << "Right Mouse Button on buildmode button = Select var(type) & value" + usr << "Left Mouse Button on turf/obj/mob = Set var(type) & value" + usr << "Right Mouse Button on turf/obj/mob = Reset var's value" + usr << "***********************************************************" + if(4) // Throw + usr << "***********************************************************" + usr << "Left Mouse Button on turf/obj/mob = Select" + usr << "Right Mouse Button on turf/obj/mob = Throw" + usr << "***********************************************************" + if(5) // Room Build + usr << "***********************************************************" + usr << "Left Mouse Button on turf = Select as point A" + usr << "Right Mouse Button on turf = Select as point B" + usr << "Right Mouse Button on buildmode button = Change floor/wall type" + usr << "***********************************************************" + if(6) // Make Ladders + usr << "***********************************************************" + usr << "Left Mouse Button on turf = Set as upper ladder loc" + usr << "Right Mouse Button on turf = Set as lower ladder loc" + usr << "***********************************************************" + if(7) // Move Into Contents + usr << "***********************************************************" + usr << "Left Mouse Button on turf/obj/mob = Select" + usr << "Right Mouse Button on turf/obj/mob = Move into selection" + usr << "***********************************************************" + if(8) // Make Lights + usr << "***********************************************************" + usr << "Left Mouse Button on turf/obj/mob = Make it glow" + usr << "Right Mouse Button on turf/obj/mob = Reset glowing" + usr << "Right Mouse Button on buildmode button = Change glow properties" + usr << "***********************************************************" return 1 /obj/effect/bmode/buildquit @@ -144,62 +167,100 @@ var/objholder = /obj/structure/closet var/objsay = 1 - Click(location, control, params) - var/list/pa = params2list(params) + var/wall_holder = /turf/simulated/wall + var/floor_holder = /turf/simulated/floor/plating + var/turf/coordA = null + var/turf/coordB = null - if(pa.Find("middle")) - switch(master.cl.buildmode) - if(2) - objsay=!objsay + var/new_light_color = "#FFFFFF" + var/new_light_range = 3 + var/new_light_intensity = 3 + +/obj/effect/bmode/buildmode/Click(location, control, params) + var/list/pa = params2list(params) + + if(pa.Find("middle")) + switch(master.cl.buildmode) + if(2) + objsay=!objsay - if(pa.Find("left")) - switch(master.cl.buildmode) - if(1) - master.cl.buildmode = 2 - src.icon_state = "buildmode2" - if(2) - master.cl.buildmode = 3 - src.icon_state = "buildmode3" - if(3) - master.cl.buildmode = 4 - src.icon_state = "buildmode4" - if(4) - master.cl.buildmode = 1 - src.icon_state = "buildmode1" + if(pa.Find("left")) + switch(master.cl.buildmode) + if(1) + master.cl.buildmode = 2 + src.icon_state = "buildmode2" + if(2) + master.cl.buildmode = 3 + src.icon_state = "buildmode3" + if(3) + master.cl.buildmode = 4 + src.icon_state = "buildmode4" + if(4) + master.cl.buildmode = 5 + src.icon_state = "buildmode5" + if(5) + master.cl.buildmode = 6 + src.icon_state = "buildmode6" + if(6) + master.cl.buildmode = 7 + src.icon_state = "buildmode7" + if(7) + master.cl.buildmode = 8 + src.icon_state = "buildmode8" + if(8) + master.cl.buildmode = 1 + src.icon_state = "buildmode1" - else if(pa.Find("right")) - switch(master.cl.buildmode) - if(1) + else if(pa.Find("right")) + switch(master.cl.buildmode) + if(1) // Basic Build + return 1 + if(2) // Adv. Build + objholder = get_path_from_partial_text(/obj/structure/closet) + + if(3) // Edit + var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine") + + master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name") + if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0)) return 1 - if(2) - objholder = text2path(input(usr,"Enter typepath:" ,"Typepath","/obj/structure/closet")) - if(!ispath(objholder)) - objholder = /obj/structure/closet - alert("That path is not allowed.") - else - if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0)) - objholder = /obj/structure/closet - if(3) - var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine") - - master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name") - if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0)) - return 1 - var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference") - if(!thetype) return 1 - switch(thetype) - if("text") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", "value") as text - if("number") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", 123) as num - if("mob-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as mob in mob_list - if("obj-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world - if("turf-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world - return 1 + var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference") + if(!thetype) return 1 + switch(thetype) + if("text") + master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", "value") as text + if("number") + master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", 123) as num + if("mob-reference") + master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as mob in mob_list + if("obj-reference") + master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world + if("turf-reference") + master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world + if(5) // Room build + var/choice = alert("Would you like to change the floor or wall holders?","Room Builder", "Floor", "Wall") + switch(choice) + if("Floor") + floor_holder = get_path_from_partial_text(/turf/simulated/floor/plating) + if("Wall") + wall_holder = get_path_from_partial_text(/turf/simulated/wall) + if(8) // Lights + var/choice = alert("Change the new light range, power, or color?", "Light Maker", "Range", "Power", "Color") + switch(choice) + if("Range") + var/input = input("New light range.","Light Maker",3) as null|num + if(input) + new_light_range = input + if("Power") + var/input = input("New light power.","Light Maker",3) as null|num + if(input) + new_light_intensity = input + if("Color") + var/input = input("New light color.","Light Maker",3) as null|color + if(input) + new_light_color = input + return 1 /proc/build_click(var/mob/user, buildmode, params, var/obj/object) var/obj/effect/bmode/buildholder/holder = null @@ -211,7 +272,7 @@ var/list/pa = params2list(params) switch(buildmode) - if(1) + if(1) // Basic Build if(istype(object,/turf) && pa.Find("left") && !pa.Find("alt") && !pa.Find("ctrl") ) if(istype(object,/turf/space)) var/turf/T = object @@ -260,8 +321,8 @@ if(NORTHWEST) var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) WIN.set_dir(NORTHWEST) - if(2) - if(pa.Find("left")) + if(2) // Adv. Build + if(pa.Find("left") && !pa.Find("ctrl")) if(ispath(holder.buildmode.objholder,/turf)) var/turf/T = get_turf(object) T.ChangeTurf(holder.buildmode.objholder) @@ -269,27 +330,31 @@ var/obj/A = new holder.buildmode.objholder (get_turf(object)) A.set_dir(holder.builddir.dir) else if(pa.Find("right")) - if(isobj(object)) qdel(object) + if(isobj(object)) + qdel(object) + else if(pa.Find("ctrl")) + holder.buildmode.objholder = object.type + user << "[object]([object.type]) copied to buildmode." if(pa.Find("middle")) holder.buildmode.objholder = text2path("[object.type]") if(holder.buildmode.objsay) usr << "[object.type]" - if(3) + if(3) // Edit if(pa.Find("left")) //I cant believe this shit actually compiles. if(object.vars.Find(holder.buildmode.varholder)) log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]") object.vars[holder.buildmode.varholder] = holder.buildmode.valueholder else - usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'" + user << "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'" if(pa.Find("right")) if(object.vars.Find(holder.buildmode.varholder)) log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]") object.vars[holder.buildmode.varholder] = initial(object.vars[holder.buildmode.varholder]) else - usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'" + user << "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'" - if(4) + if(4) // Throw if(pa.Find("left")) if(istype(object, /atom/movable)) holder.throw_atom = object @@ -297,3 +362,127 @@ if(holder.throw_atom) holder.throw_atom.throw_at(object, 10, 1) log_admin("[key_name(usr)] threw [holder.throw_atom] at [object]") + if(5) // Room build + if(pa.Find("left")) + holder.buildmode.coordA = get_turf(object) + user << "Defined [object] ([object.type]) as point A." + + if(pa.Find("right")) + holder.buildmode.coordB = get_turf(object) + user << "Defined [object] ([object.type]) as point B." + + if(holder.buildmode.coordA && holder.buildmode.coordB) + user << "A and B set, creating rectangle." + holder.buildmode.make_rectangle( + holder.buildmode.coordA, + holder.buildmode.coordB, + holder.buildmode.wall_holder, + holder.buildmode.floor_holder + ) + holder.buildmode.coordA = null + holder.buildmode.coordB = null + if(6) // Ladders + if(pa.Find("left")) + holder.buildmode.coordA = get_turf(object) + user << "Defined [object] ([object.type]) as upper ladder location." + + if(pa.Find("right")) + holder.buildmode.coordB = get_turf(object) + user << "Defined [object] ([object.type]) as lower ladder location." + + if(holder.buildmode.coordA && holder.buildmode.coordB) + user << "Ladder locations set, building ladders." + var/obj/structure/ladder/A = new /obj/structure/ladder(holder.buildmode.coordA) + var/obj/structure/ladder/B = new /obj/structure/ladder(holder.buildmode.coordB) + A.target = B + B.target = A + B.icon_state = "ladderup" + holder.buildmode.coordA = null + holder.buildmode.coordB = null + if(7) // Move into contents + if(pa.Find("left")) + if(istype(object, /atom)) + holder.throw_atom = object + if(pa.Find("right")) + if(holder.throw_atom && istype(object, /atom/movable)) + object.forceMove(holder.throw_atom) + log_admin("[key_name(usr)] moved [object] into [holder.throw_atom].") + if(8) // Lights + if(pa.Find("left")) + if(object) + object.set_light(holder.buildmode.new_light_range, holder.buildmode.new_light_intensity, holder.buildmode.new_light_color) + if(pa.Find("right")) + if(object) + object.set_light(0, 0, "#FFFFFF") + +/obj/effect/bmode/buildmode/proc/get_path_from_partial_text(default_path) + var/desired_path = input("Enter full or partial typepath.","Typepath","[default_path]") + + var/list/types = typesof(/atom) + var/list/matches = list() + + for(var/path in types) + if(findtext("[path]", desired_path)) + matches += path + + if(matches.len==0) + alert("No results found. Sorry.") + return + + var/result = null + + if(matches.len==1) + result = matches[1] + else + result = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches + if(!objholder) + result = default_path + return result + +/obj/effect/bmode/buildmode/proc/make_rectangle(var/turf/A, var/turf/B, var/turf/wall_type, var/turf/floor_type) + if(!A || !B) // No coords + return + if(A.z != B.z) // Not same z-level + return + + var/height = A.y - B.y + var/width = A.x - B.x + var/z_level = A.z + + var/turf/lower_left_corner = null + // First, try to find the lowest part + var/desired_y = 0 + if(A.y <= B.y) + desired_y = A.y + else + desired_y = B.y + + //Now for the left-most part. + var/desired_x = 0 + if(A.x <= B.x) + desired_x = A.x + else + desired_x = B.x + + lower_left_corner = locate(desired_x, desired_y, z_level) + + // Now we can begin building the actual room. This defines the boundries for the room. + var/low_bound_x = lower_left_corner.x + var/low_bound_y = lower_left_corner.y + + var/high_bound_x = lower_left_corner.x + abs(width) + var/high_bound_y = lower_left_corner.y + abs(height) + + for(var/i = low_bound_x, i <= high_bound_x, i++) + for(var/j = low_bound_y, j <= high_bound_y, j++) + var/turf/T = locate(i, j, z_level) + if(i == low_bound_x || i == high_bound_x || j == low_bound_y || j == high_bound_y) + if(isturf(wall_type)) + T.ChangeTurf(wall_type) + else + new wall_type(T) + else + if(isturf(floor_type)) + T.ChangeTurf(floor_type) + else + new floor_type(T) \ No newline at end of file diff --git a/code/modules/holodeck/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm index 4c0d0a755e..1bc0c721c7 100644 --- a/code/modules/holodeck/HolodeckControl.dm +++ b/code/modules/holodeck/HolodeckControl.dm @@ -30,62 +30,60 @@ "Snow Field" = "snowfield", \ "Theatre" = "theatre", \ "Meeting Hall" = "meetinghall", \ - "Courtroom" = "courtroom" \ + "Courtroom" = "courtroom", \ + "Turn Off" = "turnoff" \ ) var/list/restricted_programs = list("Atmospheric Burn Simulation" = "burntest", "Wildlife Simulation" = "wildlifecarp") + var/current_program = "turnoff" /obj/machinery/computer/HolodeckControl/attack_ai(var/mob/user as mob) return src.attack_hand(user) /obj/machinery/computer/HolodeckControl/attack_hand(var/mob/user as mob) - if(..()) return user.set_machine(src) - var/dat - dat += "Holodeck Control System
    " - dat += "
    Current Loaded Programs:
    " - for(var/prog in supported_programs) - dat += "([prog])
    " + ui_interact(user) - dat += "
    " - dat += "(Turn Off)
    " +/** + * Display the NanoUI window for the Holodeck Computer. + * + * See NanoUI documentation for details. + */ +/obj/machinery/computer/HolodeckControl/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) - dat += "
    " - dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
    " + var/list/data = list() + var/program_list[0] + var/restricted_program_list[0] + for(var/P in supported_programs) + program_list[++program_list.len] = list("name" = P, "program" = supported_programs[P]) + + for(var/P in restricted_programs) + restricted_program_list[++restricted_program_list.len] = list("name" = P, "program" = restricted_programs[P]) + + data["supportedPrograms"] = program_list + data["restrictedPrograms"] = restricted_program_list + data["currentProgram"] = current_program if(issilicon(user)) - dat += "
    " - if(safety_disabled) - if (emagged) - dat += "ERROR: Cannot re-enable Safety Protocols.
    " - else - dat += "(Re-Enable Safety Protocols?)
    " - else - dat += "(Override Safety Protocols?)
    " - - dat += "
    " - - if(safety_disabled) - for(var/prog in restricted_programs) - dat += "(Begin [prog])
    " - dat += "Ensure the holodeck is empty before testing.
    " - dat += "
    " - dat += "Safety Protocols are DISABLED
    " + data["isSilicon"] = 1 else - dat += "Safety Protocols are ENABLED
    " - + data["isSilicon"] = null + data["safetyDisabled"] = safety_disabled + data["emagged"] = emagged if(linkedholodeck.has_gravity) - dat += "Gravity is (ON)
    " + data["gravity"] = 1 else - dat += "Gravity is (OFF)
    " - - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") - - return + data["gravity"] = null + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "holodeck.tmpl", src.name, 400, 550) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(20) /obj/machinery/computer/HolodeckControl/Topic(href, href_list) if(..()) @@ -97,6 +95,7 @@ var/prog = href_list["program"] if(prog in holodeck_programs) loadProgram(holodeck_programs[prog]) + current_program = href_list["program"] else if(href_list["AIoverride"]) if(!issilicon(usr)) @@ -118,8 +117,8 @@ toggleGravity(linkedholodeck) src.add_fingerprint(usr) - src.updateUsrDialog() - return + + nanomanager.update_uis(src) /obj/machinery/computer/HolodeckControl/emag_act(var/remaining_charges, var/mob/user as mob) playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1) @@ -132,7 +131,6 @@ user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call [company_name] maintenance and do not use the simulator." log_game("[key_name(usr)] emagged the Holodeck Control Computer") return 1 - src.updateUsrDialog() return /obj/machinery/computer/HolodeckControl/proc/update_projections() diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8e892436e0..697ae06cf3 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -619,11 +619,11 @@ if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) var/burn_dam = 0 switch(bodytemperature) - if(-INFINITY to species.cold_level_3) + if(species.cold_level_1 to species.cold_level_2) burn_dam = COLD_DAMAGE_LEVEL_1 - if(species.cold_level_3 to species.cold_level_2) + if(species.cold_level_2 to species.cold_level_3) burn_dam = COLD_DAMAGE_LEVEL_2 - if(species.cold_level_2 to species.cold_level_1) + if(species.cold_level_3 to -INFINITY) burn_dam = COLD_DAMAGE_LEVEL_3 take_overall_damage(burn=burn_dam, used_weapon = "Low Body Temperature") fire_alert = max(fire_alert, 1) @@ -847,9 +847,9 @@ if(!isSynthetic() && (species.flags & IS_PLANT) && (!light_organ || light_organ.is_broken())) if(nutrition < 200) take_overall_damage(2,0) - - //traumatic_shock is updated every tick, incrementing that is pointless - shock_stage is the counter. - //Not that it matters much for diona, who have NO_PAIN. + + //traumatic_shock is updated every tick, incrementing that is pointless - shock_stage is the counter. + //Not that it matters much for diona, who have NO_PAIN. shock_stage++ // TODO: stomach and bloodstream organ. diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 724ccbdd27..8c30f1d486 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -32,54 +32,37 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins /obj/machinery/photocopier/faxmachine/attack_hand(mob/user as mob) user.set_machine(src) - var/dat = "Fax Machine
    " + ui_interact(user) - var/scan_name +/** + * Display the NanoUI window for the fax machine. + * + * See NanoUI documentation for details. + */ +/obj/machinery/photocopier/faxmachine/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + + var/list/data = list() if(scan) - scan_name = scan.name + data["scanName"] = scan.name else - scan_name = "--------" - - dat += "Confirm Identity: [scan_name]
    " - - if(authenticated) - dat += "{Log Out}" + data["scanName"] = null + data["bossName"] = boss_name + data["authenticated"] = authenticated + data["copyItem"] = copyitem + if(copyitem) + data["copyItemName"] = copyitem.name else - dat += "{Log In}" + data["copyItemName"] = null + data["cooldown"] = sendcooldown + data["destination"] = destination - dat += "
    " - - if(authenticated) - dat += "Logged in to: [boss_name] Quantum Entanglement Network

    " - - if(copyitem) - dat += "Remove Item

    " - - if(sendcooldown) - dat += "Transmitter arrays realigning. Please stand by.
    " - - else - - dat += "Send
    " - dat += "Currently sending: [copyitem.name]
    " - dat += "Sending to: [destination]
    " - - else - if(sendcooldown) - dat += "Please insert paper to send via secure connection.

    " - dat += "Transmitter arrays realigning. Please stand by.
    " - else - dat += "Please insert paper to send via secure connection.

    " - - else - dat += "Proper authentication is required to use this device.

    " - - if(copyitem) - dat += "Remove Item
    " - - user << browse(dat, "window=copier") - onclose(user, "copier") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "fax.tmpl", src.name, 500, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(10) //this machine is so unimportant let's not have it update that often. /obj/machinery/photocopier/faxmachine/Topic(href, href_list) if(href_list["send"]) @@ -99,7 +82,6 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins usr.put_in_hands(copyitem) usr << "You take \the [copyitem] out of \the [src]." copyitem = null - updateUsrDialog() if(href_list["scan"]) if (scan) @@ -131,7 +113,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins if(href_list["logout"]) authenticated = 0 - updateUsrDialog() + nanomanager.update_uis(src) /obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination) if(stat & (BROKEN|NOPOWER)) @@ -216,4 +198,4 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins for(var/client/C in admins) if(R_ADMIN & C.holder.rights) C << msg - C << 'sound/effects/printer.ogg' \ No newline at end of file + C << 'sound/effects/printer.ogg' diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index d122d42c2b..ec0d7acf19 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -30,24 +30,32 @@ /obj/machinery/photocopier/attack_hand(mob/user as mob) user.set_machine(src) - var/dat = "Photocopier

    " - if(copyitem) - dat += "Remove Item
    " - if(toner) - dat += "Copy
    " - dat += "Printing: [copies] copies." - dat += "- " - dat += "+

    " - else if(toner) - dat += "Please insert something to copy.

    " + ui_interact(user) + +/** + * Display the NanoUI window for the photocopier. + * + * See NanoUI documentation for details. + */ +/obj/machinery/photocopier/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + + var/list/data = list() + data["copyItem"] = copyitem + data["toner"] = toner + data["copies"] = copies + data["maxCopies"] = maxcopies if(istype(user,/mob/living/silicon)) - dat += "Print photo from database

    " - dat += "Current toner level: [toner]" - if(!toner) - dat +="
    Please insert a new toner cartridge!" - user << browse(dat, "window=copier") - onclose(user, "copier") - return + data["isSilicon"] = 1 + else + data["isSilicon"] = null + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "photocopier.tmpl", src.name, 300, 250) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(10) /obj/machinery/photocopier/Topic(href, href_list) if(href_list["copy"]) @@ -72,22 +80,18 @@ break use_power(active_power_usage) - updateUsrDialog() else if(href_list["remove"]) if(copyitem) copyitem.loc = usr.loc usr.put_in_hands(copyitem) usr << "You take \the [copyitem] out of \the [src]." copyitem = null - updateUsrDialog() else if(href_list["min"]) if(copies > 1) copies-- - updateUsrDialog() else if(href_list["add"]) if(copies < maxcopies) copies++ - updateUsrDialog() else if(href_list["aipic"]) if(!istype(usr,/mob/living/silicon)) return if(stat & (BROKEN|NOPOWER)) return @@ -109,7 +113,8 @@ p.desc += " - Copied by [tempAI.name]" toner -= 5 sleep(15) - updateUsrDialog() + + nanomanager.update_uis(src) /obj/machinery/photocopier/attackby(obj/item/O as obj, mob/user as mob) if(istype(O, /obj/item/weapon/paper) || istype(O, /obj/item/weapon/photo) || istype(O, /obj/item/weapon/paper_bundle)) @@ -119,7 +124,6 @@ O.loc = src user << "You insert \the [O] into \the [src]." flick(insert_anim, src) - updateUsrDialog() else user << "There is already something in \the [src]." else if(istype(O, /obj/item/device/toner)) @@ -129,7 +133,6 @@ var/obj/item/device/toner/T = O toner += T.toner_amount qdel(O) - updateUsrDialog() else user << "This cartridge is not yet ready for replacement! Use up the rest of the toner." else if(istype(O, /obj/item/weapon/wrench)) diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 5c4dc8c169..741ba588e4 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -2,7 +2,6 @@ #define LIQUID 2 #define GAS 3 -#define BOTTLE_SPRITES list("bottle-1", "bottle-2", "bottle-3", "bottle-4") //list of available bottle sprites #define REAGENTS_PER_SHEET 20 @@ -23,10 +22,11 @@ var/condi = 0 var/useramount = 15 // Last used amount var/pillamount = 10 - var/bottlesprite = "bottle-1" //yes, strings - var/pillsprite = "1" - var/client/has_sprites = list() + var/bottlesprite = 1 + var/pillsprite = 1 var/max_pill_count = 20 + var/tab = "home" + var/analyze_data[0] flags = OPENCONTAINER /obj/machinery/chem_master/New() @@ -56,7 +56,6 @@ user.drop_item() B.loc = src user << "You add the beaker to the machine!" - src.updateUsrDialog() icon_state = "mixer1" else if(istype(B, /obj/item/weapon/storage/pill_bottle)) @@ -69,9 +68,74 @@ user.drop_item() B.loc = src user << "You add the pill bottle into the dispenser slot!" - src.updateUsrDialog() return +/obj/machinery/chem_master/attack_hand(mob/user as mob) + if(stat & BROKEN) + return + user.set_machine(src) + ui_interact(user) + +/** + * Display the NanoUI window for the chem master. + * + * See NanoUI documentation for details. + */ +/obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + + var/list/data = list() + data["tab"] = tab + data["condi"] = condi + + if(loaded_pill_bottle) + data["pillBottle"] = list("total" = loaded_pill_bottle.contents.len, "max" = loaded_pill_bottle.max_storage_space) + else + data["pillBottle"] = null + + if(beaker) + var/datum/reagents/R = beaker:reagents + var/ui_reagent_beaker_list[0] + for(var/datum/reagent/G in R.reagent_list) + ui_reagent_beaker_list[++ui_reagent_beaker_list.len] = list("name" = G.name, "volume" = G.volume, "description" = G.description, "id" = G.id) + + data["beaker"] = list("total_volume" = R.total_volume, "reagent_list" = ui_reagent_beaker_list) + else + data["beaker"] = null + + if(reagents.total_volume) + var/ui_reagent_list[0] + for(var/datum/reagent/N in reagents.reagent_list) + ui_reagent_list[++ui_reagent_list.len] = list("name" = N.name, "volume" = N.volume, "description" = N.description, "id" = N.id) + + data["reagents"] = list("total_volume" = reagents.total_volume, "reagent_list" = ui_reagent_list) + else + data["reagents"] = null + + data["mode"] = mode + + if(analyze_data) + data["analyzeData"] = list("name" = analyze_data["name"], "desc" = analyze_data["desc"], "blood_type" = analyze_data["blood_type"], "blood_DNA" = analyze_data["blood_DNA"]) + else + data["analyzeData"] = null + + data["pillSprite"] = pillsprite + data["bottleSprite"] = bottlesprite + + var/P[20] //how many pill sprites there are. Sprites are taken from chemical.dmi and can be found in nano/images/pill.png + for(var/i = 1 to P.len) + P[i] = i + data["pillSpritesAmount"] = P + + data["bottleSpritesAmount"] = list(1, 2, 3, 4) //how many bottle sprites there are. Sprites are taken from chemical.dmi and can be found in nano/images/pill.png + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "chem_master.tmpl", src.name, 575, 400) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(5) + /obj/machinery/chem_master/Topic(href, href_list) if(stat & (BROKEN|NOPOWER)) return if(usr.stat || usr.restrained()) return @@ -80,20 +144,19 @@ src.add_fingerprint(usr) usr.set_machine(src) + if(href_list["tab_select"]) + tab = href_list["tab_select"] if (href_list["ejectp"]) if(loaded_pill_bottle) loaded_pill_bottle.loc = src.loc loaded_pill_bottle = null - else if(href_list["close"]) - usr << browse(null, "window=chemmaster") - usr.unset_machine() - return if(beaker) var/datum/reagents/R = beaker:reagents - if (href_list["analyze"]) - var/dat = "" + if (tab == "analyze") + analyze_data["name"] = href_list["name"] + analyze_data["desc"] = href_list["desc"] if(!condi) if(href_list["name"] == "Blood") var/datum/reagent/blood/G @@ -101,16 +164,9 @@ if(F.name == href_list["name"]) G = F break - var/A = G.name - var/B = G.data["blood_type"] - var/C = G.data["blood_DNA"] - dat += "Chemmaster 3000Chemical infos:

    Name:
    [A]

    Description:
    Blood Type: [B]
    DNA: [C]


    (Back)" - else - dat += "Chemmaster 3000Chemical infos:

    Name:
    [href_list["name"]]

    Description:
    [href_list["desc"]]


    (Back)" - else - dat += "Condimaster 3000Condiment infos:

    Name:
    [href_list["name"]]

    Description:
    [href_list["desc"]]


    (Back)" - usr << browse(dat, "window=chem_master;size=575x400") - return + analyze_data["name"] = G.name + analyze_data["blood_type"] = G.data["blood_type"] + analyze_data["blood_DNA"] = G.data["blood_DNA"] else if (href_list["add"]) @@ -147,9 +203,6 @@ else if (href_list["toggle"]) mode = !mode - else if (href_list["main"]) - attack_hand(usr) - return else if (href_list["eject"]) if(beaker) beaker:loc = src.loc @@ -185,9 +238,8 @@ P.icon_state = "pill"+pillsprite reagents.trans_to_obj(P,amount_per_pill) if(src.loaded_pill_bottle) - if(loaded_pill_bottle.contents.len < loaded_pill_bottle.storage_slots) + if(loaded_pill_bottle.contents.len < loaded_pill_bottle.max_storage_space) P.loc = loaded_pill_bottle - src.updateUsrDialog() else if (href_list["createbottle"]) if(!condi) @@ -197,106 +249,23 @@ P.name = "[name] bottle" P.pixel_x = rand(-7, 7) //random position P.pixel_y = rand(-7, 7) - P.icon_state = bottlesprite + P.icon_state = "bottle"+bottlesprite reagents.trans_to_obj(P,60) P.update_icon() else var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(src.loc) reagents.trans_to_obj(P,50) - else if(href_list["change_pill"]) - #define MAX_PILL_SPRITE 20 //max icon state of the pill sprites - var/dat = "" - for(var/i = 1 to MAX_PILL_SPRITE) - dat += "" - dat += "
    " - usr << browse(dat, "window=chem_master") - return - else if(href_list["change_bottle"]) - var/dat = "" - for(var/sprite in BOTTLE_SPRITES) - dat += "" - dat += "
    " - usr << browse(dat, "window=chem_master") - return + else if(href_list["pill_sprite"]) pillsprite = href_list["pill_sprite"] else if(href_list["bottle_sprite"]) bottlesprite = href_list["bottle_sprite"] - src.updateUsrDialog() - return + nanomanager.update_uis(src) /obj/machinery/chem_master/attack_ai(mob/user as mob) return src.attack_hand(user) -/obj/machinery/chem_master/attack_hand(mob/user as mob) - if(stat & BROKEN) - return - user.set_machine(src) - if(!(user.client in has_sprites)) - spawn() - has_sprites += user.client - for(var/i = 1 to MAX_PILL_SPRITE) - usr << browse_rsc(icon('icons/obj/chemical.dmi', "pill" + num2text(i)), "pill[i].png") - for(var/sprite in BOTTLE_SPRITES) - usr << browse_rsc(icon('icons/obj/chemical.dmi', sprite), "[sprite].png") - var/dat = "" - if(!beaker) - dat = "Please insert beaker.
    " - if(src.loaded_pill_bottle) - dat += "Eject Pill Bottle \[[loaded_pill_bottle.contents.len]/[loaded_pill_bottle.storage_slots]\]

    " - else - dat += "No pill bottle inserted.

    " - dat += "Close" - else - var/datum/reagents/R = beaker:reagents - dat += "Eject beaker and Clear Buffer
    " - if(src.loaded_pill_bottle) - dat += "Eject Pill Bottle \[[loaded_pill_bottle.contents.len]/[loaded_pill_bottle.storage_slots]\]

    " - else - dat += "No pill bottle inserted.

    " - if(!R.total_volume) - dat += "Beaker is empty." - else - dat += "Add to buffer:
    " - for(var/datum/reagent/G in R.reagent_list) - dat += "[G.name] , [G.volume] Units - " - dat += "(Analyze) " - dat += "(1) " - dat += "(5) " - dat += "(10) " - dat += "(30) " - dat += "(60) " - dat += "(All) " - dat += "(Custom)
    " - - dat += "
    Transfer to [(!mode ? "disposal" : "beaker")]:
    " - if(reagents.total_volume) - for(var/datum/reagent/N in reagents.reagent_list) - dat += "[N.name] , [N.volume] Units - " - dat += "(Analyze) " - dat += "(1) " - dat += "(5) " - dat += "(10) " - dat += "(30) " - dat += "(60) " - dat += "(All) " - dat += "(Custom)
    " - else - dat += "Empty
    " - if(!condi) - dat += "

    Create pill (60 units max)
    " - dat += "Create multiple pills
    " - dat += "Create bottle (60 units max)" - else - dat += "Create bottle (50 units max)" - if(!condi) - user << browse("Chemmaster 3000Chemmaster menu:

    [dat]", "window=chem_master;size=575x400") - else - user << browse("Condimaster 3000Condimaster menu:

    [dat]", "window=chem_master;size=575x400") - onclose(user, "chem_master") - return - /obj/machinery/chem_master/condimaster name = "CondiMaster 3000" condi = 1 diff --git a/html/changelogs/JerTheAce_HoPLoyalty.yml b/html/changelogs/JerTheAce_HoPLoyalty.yml new file mode 100644 index 0000000000..e9daa351da --- /dev/null +++ b/html/changelogs/JerTheAce_HoPLoyalty.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: JerTheAce + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Head of Personnel now has a loyalty implant." diff --git a/html/changelogs/Sin4_UIs.yml b/html/changelogs/Sin4_UIs.yml new file mode 100644 index 0000000000..87c1907c43 --- /dev/null +++ b/html/changelogs/Sin4_UIs.yml @@ -0,0 +1,37 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Sin4 + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added NanoUI for Advanced Body Scanners, Arcade, Atmospherics Control Computer, Chemmaster, Cloning Console, Fax Machines, Guestpass Console, Holodeck Computer, Laptop Vendors, Operating Computer, and Photocopiers." + - bugfix: "Fixes chemmaster not putting pills in pill bottles." \ No newline at end of file diff --git a/icons/misc/buildmode.dmi b/icons/misc/buildmode.dmi index a9374db340..c294178f91 100644 Binary files a/icons/misc/buildmode.dmi and b/icons/misc/buildmode.dmi differ diff --git a/icons/turf/snow.dmi b/icons/turf/snow.dmi index 5871cbdfc6..8f13ef9107 100644 Binary files a/icons/turf/snow.dmi and b/icons/turf/snow.dmi differ diff --git a/icons/turf/snow_new.dmi b/icons/turf/snow_new.dmi new file mode 100644 index 0000000000..8a95c14bed Binary files /dev/null and b/icons/turf/snow_new.dmi differ diff --git a/nano/README.md b/nano/README.md index 30da5745bd..b83661fbac 100644 --- a/nano/README.md +++ b/nano/README.md @@ -8,6 +8,35 @@ template engine. This README is not yet complete, but gives a basic rundown of how the folder structure works. I'll get around to finishing it one day. +## Contributors + +This section is for listing the contributors to NanoUI. + + - -tg-station/Neersighted + - Special thanks goes to Neersighted for creating most of the newest and best features + of NanoUI. Everything between using the Gulp build system to switching to LESS styles + has been directly adapated and/or copied from his original work for -tg-station and + their UI system, tgui. + + Systems ported/adapted from -tg-station and Neersighted include, but are not limited + to: + + - NanoUI's JavaScript controlling the "fancy" borderless window mode. + - The NanoTrasen.svg logo (Licensed under CC 3.0 BY-SA). + - The Gulp buildscript concept, as well as a large amount of the actual + Gulpfile.coffee. + - The packages in bower.json and packages.json files were hand-picked by Neersighted + for usage in compiling NanoUI. + - A considerable amount of this README is adapated from Neersighted's documentation. + - The concepts following: Using FontAwesome instead of icon16, Using LESS to expand + NanoUI's CSS style. + +NanoUI is licensed under AGPLv3. This applies to it's serverside `DM` code as well as it's +clientside `JavaScript` and `LESS` code. The file `nano/images/nanotrasen.svg` is licensed +under CC 3.0 BY-SA, and was created by Neersighted. All other image files in the +`nano/images/` directory are subject to the standard image license applied to the Paradise +repository icons. + ## Folder Rundown ### /assets @@ -75,4 +104,4 @@ of the `Gulpfile.js` and `Gulpfile.coffee` files to perform compilation tasks. In order to build an un-minified version of NanoUI, you may simply run `gulp` in the `nanoui` directory. However, this should only be used while testing, and you should run the command `gulp --min` before commiting changes, in order to produce minified -JavaScript. \ No newline at end of file +JavaScript. diff --git a/nano/images/pills32.png b/nano/images/pills32.png new file mode 100644 index 0000000000..61459093c1 Binary files /dev/null and b/nano/images/pills32.png differ diff --git a/nano/scripts/nano/nano_transition.js b/nano/scripts/nano/nano_transition.js index d40d9575bf..ab124cc75f 100644 --- a/nano/scripts/nano/nano_transition.js +++ b/nano/scripts/nano/nano_transition.js @@ -26,7 +26,7 @@ NanoTransition = function() { if(merge === undefined) merge = false; - var element = document.getElementsByClassName(id); + var element = $("." + id); if(element.length == 0) return newState; diff --git a/nano/templates/adv_med.tmpl b/nano/templates/adv_med.tmpl new file mode 100644 index 0000000000..b2b3685690 --- /dev/null +++ b/nano/templates/adv_med.tmpl @@ -0,0 +1,244 @@ + +{{if !data.occupied}} +

    No occupant detected.

    +{{else}} +

    Occupant Data:

    +
    +
    + Name: +
    +
    + {{:data.occupant.name}} +
    +
    +
    +
    + Health: +
    + {{:helper.displayBar(data.occupant.health, 0, 100, (data.occupant.health >= 50) ? 'good' : (data.occupant.health >= 25) ? 'average' : 'bad')}} +
    + {{:helper.smoothRound(data.occupant.health*10)/10}}% +
    +
    +
    + Status: +
    +
    + {{if data.occupant.stat==0}} + Stable + {{else data.occupant.stat==1}} + Non-Responsive + {{else}} + Dead + {{/if}} +
    +
    + {{:helper.link('Print', 'file', {'print_p' : 1, 'name' : data.occupant.name})}} +

    Damage:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Brute:{{:data.occupant.bruteLoss}}Brain:{{:data.occupant.brainLoss}}
    Burn:{{:data.occupant.fireLoss}}Radiation:{{:data.occupant.radLoss}}
    Oxygen:{{:data.occupant.oxyLoss}}Genetic:{{:data.occupant.cloneLoss}}
    Toxins:{{:data.occupant.toxLoss}}Paralysis:{{:data.occupant.paralysis}}% ({{:helper.smoothRound(data.occupant.paralysisSeconds)}} seconds left!)
    Body Temperature:{{:helper.smoothRound(data.occupant.bodyTempC*10)/10}}°C, {{:helper.smoothRound(data.occupant.bodyTempF*10)/10}}°F
    +
    + {{if data.occupant.hasVirus}} +
    + Viral pathogen detected in blood stream. +
    + {{/if}} + {{if data.occupant.hasBorer}} +
    + Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended. +
    + {{/if}} + {{if data.occupant.blind}} +
    Pupils unresponsive.
    + {{/if}} + {{if data.occupant.nearsighted}} +
    Retinal Misalignment Detected
    + {{/if}} +

    Blood

    + + + + + + + +
    Volume:{{:helper.smoothRound(data.occupant.blood.volume)}}Percent:{{:helper.smoothRound(data.occupant.blood.percent)}}%
    +

    Reagents

    + {{if data.occupant.reagents}} + + {{for data.occupant.reagents}} + + + + + {{/for}} +
    {{:value.name}}:{{:value.amount}}
    + {{else}} +
    No reagents detected.
    + {{/if}} +

    External Organs

    +
    + {{for data.occupant.extOrgan}} +
    + {{if value.status.destroyed}} +
    + {{:value.name}} - DESTROYED +
    + {{else}} +
    +
    + {{:value.name}} +
    +
    +
    + {{if value.status.broken}} + {{:value.status.broken}} + {{else value.status.splinted}} + Splinted + {{else value.status.robotic}} + Robotic + {{/if}} +
    +
    +  Brute/Burn +
    +
    + {{:value.bruteLoss}}/{{:value.fireLoss}} +
    +
    +  Injuries +
    +
    + {{if !value.status.bleeding}} + {{if !value.status.internalBleeding}} + No Injuries Detected + {{else}} + Internal Bleeding Detected + {{/if}} + {{else}} + {{if value.status.internalBleeding}} +
    Internal Bleeding Detected. External Bleeding Detected.
    + {{else}} + External Bleeding Detected + {{/if}} + {{/if}} +
    + {{if value.germ_level > 100}} +
    +  Infection +
    +
    + {{if value.germ_level < 300}} + Mild Infection + {{else value.germ_level < 400}} + Mild Infection+ + {{else value.germ_level < 500}} + Mild Infection++ + {{else value.germ_level < 700}} + Acute Infection + {{else value.germ_level < 800}} + Acute Infection+ + {{else value.germ_level < 900}} + Acute Infection++ + {{else value.germ_level >= 900}} + Septic + {{/if}} +
    + {{/if}} + {{if value.open}} +
    +  Operation Status +
    +
    + Open Incision +
    + {{/if}} + {{if value.implants_len}} +
    +  Implants +
    + {{for value.implants :impValue:impindex}} +
    +   {{:impValue.known ? impValue.name : "Unknown"}} +
    + {{/for}} + {{/if}} + {{/if}} +
    + {{/for}} +
    +

    Internal Organs

    +
    + {{for data.occupant.intOrgan}} +
    +
    + {{:value.name}} +
    +
    + {{:value.desc != null ? value.desc : ""}} +
    +
    +
    + {{if value.germ_level > 100}} +
    +  Infection +
    +
    + {{if value.germ_level < 300}} + Mild Infection + {{else value.germ_level < 400}} + Mild Infection+ + {{else value.germ_level < 500}} + Mild Infection++ + {{else value.germ_level < 700}} + Acute Infection + {{else value.germ_level < 800}} + Acute Infection+ + {{else value.germ_level < 900}} + Acute Infection++ + {{else value.germ_level >= 900}} + Septic + {{/if}} +
    + {{/if}} +
    +  Damage +
    +
    + {{:value.damage}} +
    +
    + {{/for}} +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/arcade_battle.tmpl b/nano/templates/arcade_battle.tmpl new file mode 100644 index 0000000000..7725698634 --- /dev/null +++ b/nano/templates/arcade_battle.tmpl @@ -0,0 +1,30 @@ + + +

    {{:data.enemyName}}

    +{{if data.gameOver}} +
    {{:data.temp}}
    +{{else}} +
    {{:data.temp}}
    +
    {{:data.enemyAction}}
    +{{/if}} +
    +
    Health:
    +
    {{:data.playerHP}}
    +
    Magic:
    +
    {{:data.playerMP}}
    +
    Enemy Health:
    +
    {{:data.enemyHP}}
    +
    + +{{if data.gameOver}} +
    {{:helper.link('New Game', null, {'newgame' : 1})}}
    +{{else}} +
    + {{:helper.link('Attack', null, {'attack' : 1})}} + {{:helper.link('Heal', null, {'heal' : 1})}} + {{:helper.link('Recharge Power', null, {'charge' : 1})}} +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/atmo_control.tmpl b/nano/templates/atmo_control.tmpl new file mode 100644 index 0000000000..be2f30d482 --- /dev/null +++ b/nano/templates/atmo_control.tmpl @@ -0,0 +1,224 @@ + +{{if data.sensors}} + {{for data.sensors}} + {{if value.sensor_data}} +
    +
    {{:value.long_name}}
    + {{if value.sensor_data.pressure}} +
    +
    Pressure:
    +
    {{:value.sensor_data.pressure}} kPa
    +
    + {{/if}} + {{if value.sensor_data.temperature}} +
    +
    Temperature:
    +
    {{:value.sensor_data.temperature}} kPa
    +
    + {{/if}} + {{if value.sensor_data.oxygen || value.sensor_data.nitrogen || value.sensor_data.carbon_dioxide || value.sensor_data.phoron}} +
    +
    Gas Composition:
    + {{if value.sensor_data.oxygen}} +
    {{:value.sensor_data.pressure}}% O2
    + {{/if}} + {{if value.sensor_data.nitrogen}} +
    {{:value.sensor_data.pressure}}% N
    + {{/if}} + {{if value.sensor_data.carbon_dioxide}} +
    {{:value.sensor_data.pressure}}% CO2
    + {{/if}} + {{if value.sensor_data.phoron}} +
    {{:value.sensor_data.pressure}}% TX
    + {{/if}} +
    + {{/if}} +
    + {{else}} +
    +
    {{:value.long_name}} can not be found!
    +
    + {{/if}} + {{/for}} +{{else}} +
    + No sensors connected. +
    +{{/if}} + +{{if data.tanks || data.core}} +

    + {{if data.tanks}} + Tank Control System + {{else data.core}} + Core Cooling Control System + {{/if}} +

    + + {{if data.input_info}} +
    +
    + {{if data.tanks}} + Input: + {{else data.core}} + Coolant Input: + {{/if}} +
    +
    + {{if data.input_info.power}} + Injecting + {{else}} + On Hold + {{/if}} +
    +
    +
    +
    Flow Rate Limit:
    +
    {{:data.input_info.volume_rate}} L/s
    +
    +
    +
    Command:
    + {{:helper.link('Toggle Power', 'power', {'in_toggle_injector' : 1})}} + {{:helper.link('Set Flow Rate', 'pencil', {'in_set_flowrate' : 1})}} + {{:helper.link('Refresh', 'refresh', {'in_refresh_status' : 1})}} +
    + {{else}} +
    +
    ERROR: Can not find input port
    + {{:helper.link('Search', 'search', {'in_refresh_status' : 1})}} +
    + {{/if}} +
    +
    + Flow Rate Limit: +
    +
    + {{:helper.link('100', 'minus', {'adj_input_flow_rate' : -100})}} + {{:helper.link('10', 'minus', {'adj_input_flow_rate' : -10})}} + {{:helper.link('1', 'minus', {'adj_input_flow_rate' : -1})}} + {{:helper.link('0.1', 'minus', {'adj_input_flow_rate' : -0.1})}} +
     {{:data.input_flow_setting}} L/s 
    + {{:helper.link('0.1', 'plus', {'adj_input_flow_rate' : 0.1})}} + {{:helper.link('1', 'plus', {'adj_input_flow_rate' : 1})}} + {{:helper.link('10', 'plus', {'adj_input_flow_rate' : 10})}} + {{:helper.link('100', 'plus', {'adj_input_flow_rate' : 100})}} +
    +
    + + {{if data.output_info}} +
    +
    + {{if data.tanks}} + Output: + {{else data.core}} + Core Outpump: + {{/if}} +
    +
    + {{if data.output_info.power}} + Open + {{else}} + On Hold + {{/if}} +
    +
    +
    + {{if data.tanks}} +
    Max Output Pressure:
    +
    {{:data.output_info.output_pressure}} kPa
    + {{else data.core}} +
    Min Core Pressure:
    +
    {{:data.output_info.pressure_limit}} kPa
    + {{/if}} +
    +
    +
    Command:
    + {{:helper.link('Toggle Power', 'power', {'out_toggle_power' : 1})}} + {{:helper.link('Set Pressure', 'pencil', {'out_set_pressure' : 1})}} + {{:helper.link('Refresh', 'refresh', {'out_refresh_status' : 1})}} +
    + {{else}} +
    +
    ERROR: Can not find output port
    + {{:helper.link('Search', 'search', {'out_refresh_status' : 1})}} +
    + {{/if}} + +
    + {{if data.tanks}} +
    + Max Output Pressure Set: +
    +
    + {{:helper.link('1000', 'minus', {'adj_pressure' : -1000})}} + {{:helper.link('100', 'minus', {'adj_pressure' : -100})}} + {{:helper.link('10', 'minus', {'adj_pressure' : -10})}} + {{:helper.link('1', 'minus', {'adj_pressure' : -1})}} +
     {{:data.pressure_setting}} kPa 
    + {{:helper.link('1', 'plus', {'adj_pressure' : 1})}} + {{:helper.link('10', 'plus', {'adj_pressure' : 10})}} + {{:helper.link('100', 'plus', {'adj_pressure' : 100})}} + {{:helper.link('1000', 'plus', {'adj_pressure' : 1000})}} +
    + {{else data.core}} +
    + Min Core Pressure Set: +
    +
    + {{:helper.link('100', 'minus', {'adj_pressure' : -100})}} + {{:helper.link('50', 'minus', {'adj_pressure' : -50})}} + {{:helper.link('10', 'minus', {'adj_pressure' : -10})}} + {{:helper.link('1', 'minus', {'adj_pressure' : -1})}} +
     {{:data.pressure_setting}} kPa 
    + {{:helper.link('1', 'plus', {'adj_pressure' : 1})}} + {{:helper.link('10', 'plus', {'adj_pressure' : 10})}} + {{:helper.link('50', 'plus', {'adj_pressure' : 50})}} + {{:helper.link('100', 'plus', {'adj_pressure' : 100})}} +
    + {{/if}} +
    +{{/if}} + +{{if data.fuel}} +

    Fuel Injection System

    + + {{if data.device_info}} +
    +
    + Status: +
    +
    + {{if data.device_info.power}} + Injecting + {{else}} + On Hold + {{/if}} +
    {{:helper.link('Refresh', 'refresh', {'refresh_status' : 1})}}
    +
    +
    +
    +
    Rate:
    +
    {{:data.device_info.volume_rate}} L/s
    +
    +
    +
    Automated Fuel Injection:
    + {{if data.automation}} + {{:helper.link('Engaged', 'check', {'toggle_automation' : 1})}} +
    Injector Controls Locked Out
    + {{else}} + {{:helper.link('Disengaged', 'close', {'toggle_automation' : 1})}} +
    Injector:
    + {{:helper.link('Toggle Power', 'power', {'toggle_injector' : 1})}} + {{:helper.link('Inject (1 Cycle)', 'syringe', {'injection' : 1})}} + {{/if}} +
    + {{else}} +
    +
    ERROR: Can not find device
    + {{:helper.link('Search', 'search', {'refresh_status' : 1})}} +
    + {{/if}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/chem_disp.tmpl b/nano/templates/chem_disp.tmpl index 1b57881074..f5fe8f7451 100644 --- a/nano/templates/chem_disp.tmpl +++ b/nano/templates/chem_disp.tmpl @@ -49,7 +49,7 @@ Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm
    {{if data.isBeakerLoaded}} - Volume: {{:helper.smoothRound(data.beakerCurrentVolume)}} / {{:data.beakerMaxVolume}}
    + Volume: {{:data.beakerCurrentVolume}} / {{:data.beakerMaxVolume}}
    {{for data.beakerContents}} {{:value.volume}} units of {{:value.name}}
    {{empty}} diff --git a/nano/templates/chem_master.tmpl b/nano/templates/chem_master.tmpl new file mode 100644 index 0000000000..1b8315154a --- /dev/null +++ b/nano/templates/chem_master.tmpl @@ -0,0 +1,116 @@ + +{{if data.tab == 'home'}} +
    +
    {{:helper.link(data.pillBottle ? 'Eject Pill Bottle' : 'No pill bottle inserted', 'eject', {'ejectp' : 1}, data.pillBottle ? null : 'linkOff')}}
    + + {{if data.pillBottle}} +
    {{:data.pillBottle.total}} / {{:data.pillBottle.max}}
    + {{/if}} +
    +
    {{:helper.link(data.beaker ? 'Eject Beaker and Clear Buffer' : 'Please insert beaker', 'eject', {'eject' : 1}, data.beaker ? null : 'linkOff')}}
    + + {{if data.beaker}} + {{if data.beaker.total_volume}} + Add to buffer: + {{for data.beaker.reagent_list}} +
    +
    {{:value.name}}
    +
    {{:value.volume}} Units
    +
    +
    + {{:helper.link('Analyze', 'signal-diag', {'tab_select' : 'analyze', 'desc' : value.description, 'name' : value.name})}} + {{:helper.link('1', 'plus', {'add' : value.id, 'amount' : 1})}} + {{:helper.link('5', 'plus', {'add' : value.id, 'amount' : 5})}} + {{:helper.link('10', 'plus', {'add' : value.id, 'amount' : 10})}} + {{:helper.link('30', 'plus', {'add' : value.id, 'amount' : 30})}} + {{:helper.link('60', 'plus', {'add' : value.id, 'amount' : 60})}} + {{:helper.link('All', 'plus', {'add' : value.id, 'amount' : value.volume})}} + {{:helper.link('Custom', 'plus', {'addcustom' : value.id})}} +
    + {{/for}} + {{else}} + Beaker is empty. + {{/if}} +
    +
    +
    Transfer to
    + {{:helper.link(!data.mode ? 'disposal' : 'beaker', null, {'toggle' : 1})}} +
    + {{if data.reagents}} + {{if data.reagents.total_volume}} + {{for data.reagents.reagent_list}} +
    +
    {{:value.name}}
    +
    {{:value.volume}} Units
    +
    +
    + {{:helper.link('Analyze', 'signal-diag', {'tab_select' : 'analyze', 'desc' : value.description, 'name' : value.name})}} + {{:helper.link('1', 'minus', {'remove' : value.id, 'amount' : 1})}} + {{:helper.link('5', 'minus', {'remove' : value.id, 'amount' : 5})}} + {{:helper.link('10', 'minus', {'remove' : value.id, 'amount' : 10})}} + {{:helper.link('30', 'minus', {'remove' : value.id, 'amount' : 30})}} + {{:helper.link('60', 'minus', {'remove' : value.id, 'amount' : 60})}} + {{:helper.link('All', 'minus', {'remove' : value.id, 'amount' : value.volume})}} + {{:helper.link('Custom', 'minus', {'removecustom' : value.id})}} +
    + {{/for}} + {{/if}} + {{else}} + Empty + {{/if}} + {{if !data.condi}} +
    +
    + {{:helper.link('Create pill (60 units max)', null, {'createpill' : 1})}} + {{:helper.link('Create multiple pills', null, {'createpill_multiple' : 1})}} + {{:helper.link('Create bottle (60 units max)', null, {'createbottle' : 1})}} +
    +
    + {{:helper.link('', 'pill pill' + data.pillSprite, {'tab_select' : 'pill'}, null, 'link32')}} + {{:helper.link('', 'pill bottle' + data.bottleSprite, {'tab_select' : 'bottle'}, null, 'link32')}} +
    + {{/if}} + {{/if}} + +{{else data.tab == 'analyze'}} + {{if !data.condi}} +

    Chemical Info:

    + {{else}} +

    Condiment Info:

    + {{/if}} +
    +
    Name:
    +
    {{:data.analyzeData.name}}
    +
    + {{if data.analyzeData.name == 'Blood'}} +
    +
    Blood Type:
    +
    {{:data.analyzeData.blood_type}}
    +
    +
    +
    DNA:
    +
    {{:data.analyzeData.blood_DNA}}
    +
    + {{else}} +
    +
    Description:
    +
    {{:data.analyzeData.desc}}
    +
    + {{/if}} + {{:helper.link('Back', 'arrowreturn-1-w', {'tab_select' : 'home'})}} + +{{else data.tab == 'pill'}} + {{for data.pillSpritesAmount}} + {{:helper.link('', 'pill pill' + value, {'pill_sprite' : value}, null, data.pillSprite == value ? 'linkOn link32' : 'link32')}} + {{/for}} +

    {{:helper.link('Return', 'arrowreturn-1-w', {'tab_select' : 'home'})}}
    + +{{else data.tab == 'bottle'}} + {{for data.bottleSpritesAmount}} + {{:helper.link('', 'pill bottle' + value, {'bottle_sprite' : value}, null, data.bottleSprite == value ? 'linkOn link32' : 'link32')}} + {{/for}} +

    {{:helper.link('Return', 'arrowreturn-1-w', {'tab_select' : 'home'})}}
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/cloning.tmpl b/nano/templates/cloning.tmpl new file mode 100644 index 0000000000..a927fcc4d9 --- /dev/null +++ b/nano/templates/cloning.tmpl @@ -0,0 +1,104 @@ + + +{{:data.temp}} + +{{if data.menu == 1}} + +

    Modules

    +
    + {{if data.connected}} + DNA scanner found. + {{else}} + DNA scanner not found. + {{/if}} +
    +
    + {{if data.podsLen > 0}} + {{:data.podsLen}} cloning vat\s found. + {{else}} + No cloning vats found. + {{/if}} +
    + + +

    Scanner Functions

    +
    + {{if data.loading}} + Scanning... + {{else}} + {{:data.scantemp}} + {{/if}} +
    +
    + {{if data.connected}} +
    + {{:helper.link(data.occupant ? 'Scan - ' + data.occupant : 'Scanner unoccupied', 'play', {'scan' : 1}, data.occupant ? null : 'linkOff')}} +
    +
    + {{:helper.link(data.locked ? 'Unlock' : 'Lock', data.locked ? 'locked' : 'unlocked', {'lock' : 1}, null, data.locked ? 'redButton' : null)}} +
    +
    + {{:helper.link('Eject', 'eject', {'eject' : 1}, data.occupant ? null : 'linkOff')}} +
    + {{else}} + No scanner connected! + {{/if}} +
    + + {{if data.podsLen}} + {{for data.pods}} +
    {{:value.pod}}, biomass: {{:value.biomass}}
    + {{/for}} + {{/if}} + + +

    Database Functions

    +
    + {{:helper.link('View Records', 'list', {'menu' : 2})}} + {{:helper.link('Eject Disk', 'eject', {'disk' : 'eject'}, data.diskette ? null : 'linkOff')}} +
    + +{{else data.menu == 2}} +

    Current records

    + {{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 1})}} +
    + {{for data.records}} + {{:helper.link(value.name, 'document', {'view_rec' : value.ckey})}} + {{/for}} +
    + +{{else data.menu == 3}} +

    Selected Record

    +
    {{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 2})}}
    + + {{if data.activeRecord}} + {{:helper.link('Delete Record', 'trash', {'del_rec' : 1}, null, 'redButton')}} +
    +
    Name:
    +
    {{:data.activeRecord.real_name}}
    +
    + + {{:helper.link('Load from disk', 'transfer-e-w', {'disk' : 'load'}, data.disk ? null : 'linkOff')}} + +
    +
    Save:
    + {{:helper.link('UI + UE', 'disk', {'save_disk' : 'ue'}, data.disk ? null : 'linkOff')}} + {{:helper.link('UI', 'disk', {'save_disk' : 'ui'}, data.disk ? null : 'linkOff')}} + {{:helper.link('SE', 'disk', {'save_disk' : 'se'}, data.disk ? null : 'linkOff')}} +
    + + {{:helper.link('Clone', 'play', {'clone' : data.activeRecord.ckey}, data.podsLen ? null : 'linkOff')}} + + {{else}} +
    ERROR: Record not found.
    + {{/if}} + +{{else data.menu == 4}} + {{:data.temp}} +

    Confirm Record Deletion

    +
    Scan card to confirm.
    + {{:helper.link('Cancel', 'cancel', {'menu' : 3})}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/fax.tmpl b/nano/templates/fax.tmpl new file mode 100644 index 0000000000..4745a7aeb3 --- /dev/null +++ b/nano/templates/fax.tmpl @@ -0,0 +1,55 @@ + + +
    +
    + Confirm Identity: +
    + {{:helper.link(data.scanName ? data.scanName : 'Insert Card', 'check', {'scan' : 1})}} + {{if data.authenticated}} + {{:helper.link('Log Out', 'eject', {'logout' : 1}, null, 'redButton')}} + {{else}} + {{:helper.link('Log In', 'person', {'auth' : 1}, data.scanName ? null : 'linkOff')}} + {{/if}} +
    +{{if data.authenticated}} + +
    + +
    +
    + Logged in to: +
    +
    + {{:data.bossName}} Quantum Entanglement Network +
    +
    + {{if data.copyItem}} + {{if data.cooldown}} +
    Transmitter arrays realigning. Please stand by.
    + {{else}} +
    +
    Currently sending:
    +
    {{:data.copyItemName}}
    +
    +
    +
    Sending to:
    + {{:helper.link(data.destination, 'tag', {'dept' : 1})}} +
    +
    {{:helper.link('Send', 'signal-diag', {'send' : 1})}}
    + {{/if}} + {{else}} +
    Please insert paper to send via secure connection.
    + {{if data.cooldown}} +
    Transmitter arrays realigning. Please stand by.
    + {{/if}} + {{/if}} +{{else}} +
    Proper authentication is required to use this device.
    +{{/if}} +{{if data.copyItem}} +
    {{:helper.link('Remove Item', 'eject', {'remove' : 1})}}
    +{{/if}} + diff --git a/nano/templates/guest_pass.tmpl b/nano/templates/guest_pass.tmpl new file mode 100644 index 0000000000..80525f5331 --- /dev/null +++ b/nano/templates/guest_pass.tmpl @@ -0,0 +1,59 @@ + + +{{if data.mode == 1}} +
    +
    + Activity Log +
    + {{:helper.link('Print', 'print', {'print' : 1})}} {{:helper.link('Back', 'arrowreturn-1-w', {'mode' : 0})}} +
    +
    + {{for data.log}} +
    + {{:value}} +
    + {{/for}} +{{else}} +

    Guest pass terminal #{{:data.uid}}

    +
    + {{:helper.link('View activity log', 'list', {'mode' : 1})}} {{:helper.link('Issure Pass', 'eject', {'action' : 'issue'})}} +
    +
    +
    +
    + Issuing ID: +
    + {{:helper.link(data.giver ? data.giver : 'Insert ID', 'person', {'action' : 'id'})}} +
    +
    +
    + Issued to: +
    + {{:helper.link(data.giveName, 'pencil', {'choice' : 'giv_name'})}} +
    +
    +
    + Reason: +
    + {{:helper.link(data.reason, 'pencil', {'choice' : 'reason'})}} +
    +
    +
    + Duration (minutes): +
    + {{:helper.link(data.duration, 'clock', {'choice' : 'duration'})}} +
    +
    +
    + Access to areas: +
    +
    + {{for data.area}} +
    + {{:helper.link(value.area_name, value.on ? 'check' : 'close', {'choice' : 'access', 'access' : value.area}, null, value.on ? 'linkOn' : null)}} +
    + {{/for}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/holodeck.tmpl b/nano/templates/holodeck.tmpl new file mode 100644 index 0000000000..71d4ad5605 --- /dev/null +++ b/nano/templates/holodeck.tmpl @@ -0,0 +1,36 @@ + + +

    Current Loaded Programs:

    +{{for data.supportedPrograms}} +
    {{:helper.link(value.name, data.currentProgram == value.program ? 'check' : 'close', {'program' : value.program}, null, data.currentProgram == value.program ? 'linkOn' : null)}}
    +{{/for}} +
    Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
    +{{if data.isSilicon}} + {{if data.safetyDisabled}} + {{if data.emagged}} +
    ERROR: Cannot re-enable Safety Protocols.
    + {{else}} +
    {{:helper.link('Re-Enable Safety Protocols?', 'help', {'AIoverride' : 1}, null, 'linkOn')}}
    + {{/if}} + {{else}} +
    {{:helper.link('Re-Enable Safety Protocols?', 'help', {'AIoverride' : 1}, null, 'redButton')}}
    + {{/if}} +{{/if}} + +{{if data.safetyDisabled}} + {{for data.restrictedPrograms}} +
    {{:helper.link('Begin ' + value.name, data.currentProgram == value.program ? 'check' : 'close', {'program' : value.program}, null, data.currentProgram == value.program ? 'linkOn' : null)}}
    + {{/for}} +
    Ensure the holodeck is empty before testing.
    +
    Safety Protocols are DISABLED
    +{{else}} +
    Safety Protocols are ENABLED
    +{{/if}} + +
    +
    Gravity:
    + {{:helper.link(data.gravity ? 'On ' : 'Off', data.gravity ? 'check' : 'close', {'gravity' : 1}, null, data.gravity ? 'linkOn' : 'redButton')}} +
    \ No newline at end of file diff --git a/nano/templates/laptop_vendor.tmpl b/nano/templates/laptop_vendor.tmpl new file mode 100644 index 0000000000..e0de4f7272 --- /dev/null +++ b/nano/templates/laptop_vendor.tmpl @@ -0,0 +1,173 @@ + + +{{if data.mode == 0}} +
    + Please choose your laptop customization options.
    + Your comptuer will automatically be loaded with any programs you can use after the transaction is complete.
    + Some programs will require additional components to be installed! +
    + +
    + +
    +
    HDD (Required):
    +
    Added
    +
    + +
    +
    + Card Reader: +
    + {{:helper.link('Single (50)', data.cardreader == 1 ? 'check' : 'plus', {'choice' : 'single_add'}, data.cardreader == 1 ? 'selected' : null)}} + {{:helper.link('Dual (125)', data.cardreader == 2 ? 'check' : 'plus', {'choice' : 'dual_add'}, data.cardreader == 2 ? 'selected' : null)}} + {{:helper.link('None', 'close', {'choice' : 'cardreader_rem'}, data.cardreader == 0 ? 'redButton' : null)}} +
    + +
    +
    + Floppy Drive: +
    + {{:helper.link('Add (50)', data.floppy == 1 ? 'check' : 'plus', {'choice' : 'floppy_add'}, data.floppy == 1 ? 'selected' : null)}} + {{:helper.link('None', 'close', {'choice' : 'floppy_rem'}, data.floppy == 0 ? 'redButton' : null)}} +
    + +
    +
    + Radio card: +
    + {{:helper.link('Add (50)', data.radionet == 1 ? 'check' : 'plus', {'choice' : 'radio_add'}, data.radionet == 1 ? 'selected' : null)}} + {{:helper.link('None', 'close', {'choice' : 'radio_rem'}, data.radionet == 0 ? 'redButton' : null)}} +
    + +
    +
    + Camera Card: +
    + {{:helper.link('Add (100)', data.camera == 1 ? 'check' : 'plus', {'choice' : 'camnet_add'}, data.camera == 1 ? 'selected' : null)}} + {{:helper.link('None', 'close', {'choice' : 'camnet_rem'}, data.camera == 0 ? 'redButton' : null)}} +
    + +
    +
    + Network card: +
    +
    + {{:helper.link('Area (75)', data.network == 1 ? 'check' : 'plus', {'choice' : 'area_add'}, data.network == 1 ? 'selected' : null)}} + {{:helper.link('Adjacent (50)', data.network == 2 ? 'check' : 'plus', {'choice' : 'prox_add'}, data.network == 2 ? 'selected' : null)}} + {{:helper.link('Powernet (25)', data.network == 3 ? 'check' : 'plus', {'choice' : 'cable_add'}, data.network == 3 ? 'selected' : null)}} + {{:helper.link('None', 'close', {'choice' : 'network_rem'}, data.network == 0 ? 'redButton' : null)}} +
    +
    + +
    + +
    +
    + Power Source: +
    + {{:helper.link('Extended (175)', data.power == 1 ? 'check' : 'plus', {'choice' : 'high_add'}, data.power == 1 ? 'selected' : null)}} + {{:helper.link('Unreal (250)', data.power == 2 ? 'check' : 'plus', {'choice' : 'super_add'}, data.power == 2 ? 'selected' : null)}} + {{:helper.link('Default', data.power == 0 ? 'check' : 'plus', {'choice' : 'power_rem'}, data.power == 0 ? 'selected' : null)}} +
    + +
    +
    +
    Total:
    +
    {{:data.total}}
    + {{:helper.link('Vend Laptop', 'cart', {'choice' : 'vend'})}} +
    + +{{else data.mode == 1}} +

    Cart

    + +
    + +
    +
    Total:
    +
    {{:data.total}}
    +
    + +
    +
    Card Reader:
    + {{if data.cardreader == 1}} + {{:helper.link('(single) (50)', 'close', {'choice' : 'cardreader_rem'})}} + {{else data.cardreader == 2}} + {{:helper.link('(double) (125)', 'close', {'choice' : 'cardreader_rem'})}} + {{else}} +
    None
    + {{/if}} +
    + +
    +
    Floppy Drive:
    + {{if data.floppy == 1}} + {{:helper.link('Added (50)', 'close', {'choice' : 'floppy_rem'})}} + {{else}} +
    None
    + {{/if}} +
    + +
    +
    Radio Card:
    + {{if data.radionet == 1}} + {{:helper.link('Added (50)', 'close', {'choice' : 'radio_rem'})}} + {{else}} +
    None
    + {{/if}} +
    + +
    +
    Camera Card:
    + {{if data.camera == 1}} + {{:helper.link('Added (100)', 'close', {'choice' : 'camnet_rem'})}} + {{else}} +
    None
    + {{/if}} +
    + +
    +
    Network Card:
    + {{if data.network == 1}} + {{:helper.link('Area (75)', 'close', {'choice' : 'network_rem'})}} + {{else data.network == 2}} + {{:helper.link('Adjacent (50)', 'close', {'choice' : 'network_rem'})}} + {{else data.network == 3}} + {{:helper.link('Powernet (25)', 'close', {'choice' : 'network_rem'})}} + {{else}} +
    None
    + {{/if}} +
    + +
    +
    Power Source:
    + {{if data.power == 1}} + {{:helper.link('Unreal (250)', 'close', {'choice' : 'power_rem'})}} + {{else data.power == 2}} + {{:helper.link('Extended (175)', 'close', {'choice' : 'power_rem'})}} + {{else}} +
    Regular
    + {{/if}} +
    + +
    + +
    +
    Please swipe your card and enter your PIN to complete the transaction
    +
    + +
    + + {{:helper.link('Cancel', 'close', {'choice' : 'cancel'}, null, 'redButton')}} + +{{else data.mode == 2}} +
    + Please swipe your card and enter your PIN to finish returning your computer. + +
    + + {{:helper.link('Cancel', 'close', {'choice' : 'cancel'}, null, 'redButton')}} +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/operating.tmpl b/nano/templates/operating.tmpl new file mode 100644 index 0000000000..c53bd94c65 --- /dev/null +++ b/nano/templates/operating.tmpl @@ -0,0 +1,47 @@ + + +{{if data.table}} +

    Patient Information:

    + {{if data.victim}} +
    +
    Name:
    +
    {{:data.victim.real_name}}
    + +
    Age:
    +
    {{:data.victim.age}}
    + +
    Blood Type:
    +
    {{:data.victim.b_type}}
    +
    +
    +
    +
    Health:
    +
    {{:data.victim.health}}
    + +
    Brute Damage:
    +
    {{:data.victim.brute}}
    + +
    Toxins Damage:
    +
    {{:data.victim.tox}}
    + +
    Fire Damage:
    +
    {{:data.victim.burn}}
    + +
    Suffocation Damage:
    +
    {{:data.victim.oxy}}
    + +
    Patient Status:
    +
    {{:data.victim.stat}}
    + +
    Heartbeat Rate:
    +
    {{:data.victim.pulse}}
    +
    + {{else}} + No Patient Detected + {{/if}} +{{else}} + No Table Detected +{{/if}} diff --git a/nano/templates/photocopier.tmpl b/nano/templates/photocopier.tmpl new file mode 100644 index 0000000000..9c9910e969 --- /dev/null +++ b/nano/templates/photocopier.tmpl @@ -0,0 +1,47 @@ + + +{{if data.copyItem}} +
    + {{:helper.link('Remove Item', 'eject', {'remove' : 1})}} + {{if data.toner}} + {{:helper.link('Copy', 'copy', {'copy' : 1})}}
    +
    +
    +
    + Printing: +
    +
    +
    + {{:helper.link('-', null, {'min' : 1}, data.copies == 1 ? 'linkOff' : null)}} +
    {{:data.copies}}
    + {{:helper.link('+', null, {'add' : 1}, data.copies == data.maxCopies ? 'linkOff' : null)}} +
    +
    +
    +
    +
    +
    Current toner level:
    +
    {{:data.toner}}u
    +
    + {{else}} +
    + Please insert a new toner cartridge! +
    + {{/if}} +{{else data.toner}} +

    Please insert something to copy.

    + {{if data.isSilicon}} + {{:helper.link('Print photo from database', 'image', {'aipic' : 1})}} + {{/if}} +
    +
    Current toner level:
    +
    {{:data.toner}}u
    +
    +{{else}} +
    + Please insert a new toner cartridge! +
    +{{/if}} \ No newline at end of file diff --git a/polaris.dme b/polaris.dme index 27a1f3a715..f8b2503635 100644 --- a/polaris.dme +++ b/polaris.dme @@ -900,6 +900,7 @@ #include "code\game\turfs\simulated\wall_icon.dm" #include "code\game\turfs\simulated\wall_types.dm" #include "code\game\turfs\simulated\walls.dm" +#include "code\game\turfs\snow\snow.dm" #include "code\game\turfs\space\space.dm" #include "code\game\turfs\space\transit.dm" #include "code\game\turfs\unsimulated\beach.dm"