[environment.temperature]
for(var/id_tag in alarm_area.air_vent_names)
var/long_name = alarm_area.air_vent_names[id_tag]
var/list/data = alarm_area.air_vent_info[id_tag]
- var/state = ""
if(!data)
- state = " can not be found! "
- data = list("external" = 0) //for "0" instead of empty string
- else if (data["timestamp"]+AALARM_REPORT_TIMEOUT < world.time)
- state = " not responding! "
+ continue;
+ var/state = ""
+
sensor_data += {"
[long_name] [state]
Operating:
@@ -630,6 +628,7 @@ Temperature: [environment.temperature]
+
+
+
+ (reset)
"}
if (data["direction"] == "siphon")
@@ -648,12 +647,9 @@ siphoning
for(var/id_tag in alarm_area.air_scrub_names)
var/long_name = alarm_area.air_scrub_names[id_tag]
var/list/data = alarm_area.air_scrub_info[id_tag]
- var/state = ""
if(!data)
- state = " can not be found! "
- data = list("external" = 0) //for "0" instead of empty string
- else if (data["timestamp"]+AALARM_REPORT_TIMEOUT < world.time)
- state = " not responding! "
+ continue;
+ var/state = ""
sensor_data += {"
[long_name] [state]
@@ -787,6 +783,7 @@ table tr:first-child th:first-child { border: none;}
if(
"power",
"adjust_external_pressure",
+ "set_external_pressure",
"checks",
"co2_scrub",
"tox_scrub",
@@ -797,6 +794,7 @@ table tr:first-child th:first-child { border: none;}
send_signal(device_id, list (href_list["command"] = text2num(href_list["val"])))
spawn(3)
src.updateUsrDialog()
+
//if("adjust_threshold") //was a good idea but required very wide window
if("set_threshold")
var/env = href_list["env"]
@@ -843,6 +841,7 @@ table tr:first-child th:first-child { border: none;}
apply_mode()
spawn(5)
src.updateUsrDialog()
+
return
/obj/machinery/alarm/proc/apply_mode()
@@ -888,15 +887,15 @@ table tr:first-child th:first-child { border: none;}
send_signal(device_id, list(
"power"= 0
))
- if(AALARM_MODE_OFF)
+ /*if(AALARM_MODE_OFF) Commented out cause the "turn off panic" uses scrubbing mode now instead.
for(var/device_id in alarm_area.air_scrub_names)
send_signal(device_id, list(
- "power"= 0
+ "panic_siphon" = 0
))
for(var/device_id in alarm_area.air_vent_names)
send_signal(device_id, list(
- "power"= 0
- ))
+ "power"= 1
+ ))*/
/obj/machinery/alarm/update_icon()
if(wiresexposed)
diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm
index 864d6e451c..e0274cf54d 100644
--- a/code/game/machinery/atmo_control.dm
+++ b/code/game/machinery/atmo_control.dm
@@ -93,7 +93,6 @@ obj/machinery/computer/general_air_control
process()
..()
-
src.updateDialog()
attackby(I as obj, user as mob)
@@ -442,94 +441,6 @@ Rate: [volume_rate] L/sec "}
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
-/obj/machinery/computer/atmos_alert
- var/datum/radio_frequency/radio_connection
-/obj/machinery/computer/atmos_alert/initialize()
- set_frequency(receive_frequency)
-/obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal)
- if(!signal || signal.encryption) return
- var/zone = signal.data["zone"]
- var/severity = signal.data["alert"]
-
- if(!zone || !severity) return
-
- minor_alarms -= zone
- priority_alarms -= zone
- if(severity=="severe")
- priority_alarms += zone
- else if (severity=="minor")
- minor_alarms += zone
- /*else "clear"*/
- //do nothing
- update_icon()
-
-/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency)
- radio_controller.remove_object(src, receive_frequency)
- receive_frequency = new_frequency
- radio_connection = radio_controller.add_object(src, receive_frequency, RADIO_ATMOSIA)
-
-/obj/machinery/computer/atmos_alert/attack_hand(mob/user)
- user << browse(return_text(),"window=computer")
- user.machine = src
- onclose(user, "computer")
-
-/obj/machinery/computer/atmos_alert/process()
- ..()
- src.updateDialog()
-
-/obj/machinery/computer/atmos_alert/update_icon()
- if(priority_alarms.len)
- icon_state = "alert:2"
-
- else if(minor_alarms.len)
- icon_state = "alert:1"
-
- else
- icon_state = "alert:0"
-
-/obj/machinery/computer/atmos_alert/proc/return_text()
- var/priority_text
- var/minor_text
-
- if(priority_alarms.len)
- for(var/zone in priority_alarms)
- priority_text += "[zone] X "
- else
- priority_text = "No priority alerts detected. "
-
- if(minor_alarms.len)
- for(var/zone in minor_alarms)
- minor_text += "[zone] X "
- else
- minor_text = "No minor alerts detected. "
-
- var/output = {"[name]
-Priority Alerts:
-[priority_text]
-
-
-Minor Alerts:
-[minor_text]
- "}
-
- return output
-
-/obj/machinery/computer/atmos_alert/Topic(href, href_list)
- if(..())
- return
-
- if(href_list["priority_clear"])
- var/removing_zone = href_list["priority_clear"]
- for(var/zone in priority_alarms)
- if(ckey(zone) == removing_zone)
- priority_alarms -= zone
-
- if(href_list["minor_clear"])
- var/removing_zone = href_list["minor_clear"]
- for(var/zone in minor_alarms)
- if(ckey(zone) == removing_zone)
- minor_alarms -= zone
- update_icon()
\ No newline at end of file
diff --git a/code/game/machinery/atmoalter/zvent.dm b/code/game/machinery/atmoalter/zvent.dm
index 5831e9d6a8..0cf390d879 100644
--- a/code/game/machinery/atmoalter/zvent.dm
+++ b/code/game/machinery/atmoalter/zvent.dm
@@ -10,7 +10,6 @@
var/volume_rate = 800
/obj/machinery/zvent/process()
- ..()
//all this object does, is make its turf share air with the ones above and below it, if they have a vent too.
if (istype(loc,/turf/simulated)) //if we're not on a valid turf, forget it
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index dcafa06665..9802c771fb 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -1,274 +1,3 @@
-/obj/machinery/autolathe
- var/busy = 0
- var/max_m_amount = 150000.0
- var/max_g_amount = 75000.0
- var/outputAmount = 1
- var/makeDir = 0
-
-/obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob)
- if (stat)
- return 1
- if(istype(O,/obj/item/weapon/storage/))
- usr.before_take_item(O)
- O.loc = src
- user << "\blue You insert the \icon[O] [O.name] into the autolathe!"
- return 0
- if (busy)
- user << "\red The autolathe is busy. Please wait for completion of previous operation."
- return 1
- if (istype(O, /obj/item/weapon/screwdriver))
- if (!opened)
- src.opened = 1
- src.icon_state = "autolathe_t"
- user << "You open the maintenance hatch of [src]."
- else
- src.opened = 0
- src.icon_state = "autolathe"
- user << "You close the maintenance hatch of [src]."
- return 1
- if (opened)
- if(istype(O, /obj/item/weapon/crowbar))
- playsound(src.loc, 'Crowbar.ogg', 50, 1)
- var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc)
- M.state = 2
- M.icon_state = "box_1"
- for(var/obj/I in component_parts)
- if(I.reliability != 100 && crit_fail)
- I.crit_fail = 1
- I.loc = src.loc
- if(m_amount >= 3750)
- var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(src.loc)
- G.amount = round(m_amount / 3750)
- if(g_amount >= 3750)
- var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc)
- G.amount = round(g_amount / 3750)
- del(src)
- return 1
- else
- user << "\red You can't load the autolathe while it's opened."
- return 1
- if (src.m_amount + O.m_amt > max_m_amount)
- user << "\red The autolathe is full. Please remove metal from the autolathe in order to insert more."
- return 1
- if (src.g_amount + O.g_amt > max_g_amount)
- user << "\red The autolathe is full. Please remove glass from the autolathe in order to insert more."
- return 1
- if (O.m_amt == 0 && O.g_amt == 0)
- user << "\red This object does not contain significant amounts of metal or glass, or cannot be accepted by the autolathe due to size or hazardous materials."
- return 1
-/*
- if (istype(O, /obj/item/weapon/grab) && src.hacked)
- var/obj/item/weapon/grab/G = O
- if (prob(25) && G.affecting)
- G.affecting.gib()
- m_amount += 50000
- return
-*/
-
- var/amount = 1
- var/obj/item/stack/stack
- var/m_amt = O.m_amt
- var/g_amt = O.g_amt
- if (istype(O, /obj/item/stack))
- stack = O
- amount = stack.amount
- if (m_amt)
- amount = min(amount, round((max_m_amount-src.m_amount)/m_amt))
- flick("autolathe_o",src)//plays metal insertion animation
- if (g_amt)
- amount = min(amount, round((max_g_amount-src.g_amount)/g_amt))
- flick("autolathe_r",src)//plays glass insertion animation
- stack.use(amount)
- else
- usr.before_take_item(O)
- flick("autolathe_o",src)//plays metal insertion animation
- O.loc = src
- icon_state = "autolathe"
- busy = 1
- use_power(max(1000, (m_amt+g_amt)*amount/10))
- spawn(16)
- icon_state = "autolathe"
- src.m_amount += m_amt * amount
- src.g_amount += g_amt * amount
- if (O && O.loc == src)
- del(O)
- busy = 0
- src.updateUsrDialog()
-
-/obj/machinery/autolathe/attack_paw(mob/user as mob)
- return src.attack_hand(user)
-
-/obj/machinery/autolathe/attack_hand(mob/user as mob)
- user.machine = src
- interact(user)
-
-/obj/machinery/autolathe/proc/wires_win(mob/user as mob)
- var/dat as text
- dat += "Autolathe Wires: "
- for(var/wire in src.wires)
- dat += text("[wire] Wire: [src.wires[wire] ? "Mend" : "Cut"] Pulse ")
-
- dat += text("The red light is [src.disabled ? "off" : "on"]. ")
- dat += text("The green light is [src.shocked ? "off" : "on"]. ")
- dat += text("The blue light is [src.hacked ? "off" : "on"]. ")
- user << browse("Autolathe Hacking [dat]","window=autolathe_hack")
- onclose(user, "autolathe_hack")
-
-/obj/machinery/autolathe/proc/regular_win(mob/user as mob)
- var/dat as text
- dat = text("Metal Amount: [src.m_amount] cm3 (MAX: [max_m_amount]) \nGlass Amount: [src.g_amount] cm3 (MAX: [max_g_amount]) ")
- dat += "Output Queue: [outputAmount] (Modify )"
- dat += " "
- var/list/heldContainers = list()
- for(var/obj/item/weapon/storage/container in src.contents)
- heldContainers += container
- if(heldContainers.len)
- for(var/obj/item/weapon/storage/container in heldContainers)
- dat += "[container.name] (eject stored container) "
- else
- dat += "No held storage containers"
- dat += " "
- var/list/objs = list()
- objs += src.L
- if (src.hacked)
- objs += src.LL
- for(var/obj/t in objs)
- var/title = "[t.name] ([t.m_amt] m /[t.g_amt] g)"
- if (m_amount"
- continue
- dat += "[title] "
- if (istype(t, /obj/item/stack))
- var/obj/item/stack/S = t
- var/max_multiplier = min(S.max_amount, S.m_amt?round(m_amount/S.m_amt):INFINITY, S.g_amt?round(g_amount/S.g_amt):INFINITY)
- if (max_multiplier>1)
- dat += " |"
- if (max_multiplier>10)
- dat += " x[10] "
- if (max_multiplier>25)
- dat += " x[25] "
- if (max_multiplier>1)
- dat += " x[max_multiplier] "
- dat += " "
- user << browse("Autolathe Control Panel [dat] ", "window=autolathe_regular")
- onclose(user, "autolathe_regular")
-
-/obj/machinery/autolathe/proc/interact(mob/user as mob)
- if(..())
- return
- if (src.shocked)
- src.shock(user,50)
- if (src.opened)
- wires_win(user,50)
- return
- if (src.disabled)
- user << "\red You press the button, but nothing happens."
- return
- regular_win(user)
- return
-
-/obj/machinery/autolathe/Topic(href, href_list)
- if(..())
- return
- usr.machine = src
- src.add_fingerprint(usr)
- if(href_list["removeContainer"])
- var/obj/item/weapon/storage/container = locate(href_list["removeContainer"])
- container.loc = src.loc
- container.layer = initial(container.layer)
- if(href_list["modifyOutputAmount"])
- outputAmount = text2num(input(usr,"Amount:","Enter new quantity to create",""))
- if(!busy)
- if(outputAmount < 1)
- outputAmount = 1
- else
- usr << "\red The autolathe is busy. Please wait for completion of previous operation."
- if (!busy)
- if(href_list["make"])
- var/turf/T = src.loc
- var/obj/template = locate(href_list["make"])
- var/multiplier = text2num(href_list["multiplier"])
- if (!multiplier) multiplier = 1
- var/power = max(2000, (template.m_amt+template.g_amt)*multiplier/5)
- restart:
- if(outputAmount > 0)
- if( (src.m_amount >= template.m_amt*multiplier) && (src.g_amount >= template.g_amt*multiplier) )
- use_power(power)
- icon_state = "autolathe"
- flick("autolathe_n",src)
- spawn(16)
- if(!busy)
- busy = 1
- use_power(power)
- flick("autolathe_n",src)
- spawn(16)
- use_power(power)
- flick("autolathe_n",src)
- spawn(16)
- flick("autolathe_n",src)
- src.m_amount -= template.m_amt*multiplier
- src.g_amount -= template.g_amt*multiplier
- if(src.m_amount < 0)
- src.m_amount = 0
- if(src.g_amount < 0)
- src.g_amount = 0
- var/obj/new_item = new template.type(src)
- for(var/obj/item/weapon/storage/container in src.contents)
- container.attackby(new_item)
- if(new_item.loc == container)
- break
- if (multiplier>1)
- var/obj/item/stack/S = new_item
- S.amount = multiplier
- if(new_item in src)
- new_item.loc = T
- src.updateUsrDialog()
- outputAmount -= 1
- busy = 0
- goto restart
- else
- for(var/mob/M in view(3,src))
- M << "\red\icon[src] has run out of materials."
- else
- outputAmount = 1
- if(href_list["act"])
- var/temp_wire = href_list["wire"]
- if(href_list["act"] == "pulse")
- if (!istype(usr.equipped(), /obj/item/device/multitool))
- usr << "You need a multitool!"
- else
- if(src.wires[temp_wire])
- usr << "You can't pulse a cut wire."
- else
- if(src.hack_wire == temp_wire)
- src.hacked = !src.hacked
- spawn(100) src.hacked = !src.hacked
- if(src.disable_wire == temp_wire)
- src.disabled = !src.disabled
- src.shock(usr,50)
- spawn(100) src.disabled = !src.disabled
- if(src.shock_wire == temp_wire)
- src.shocked = !src.shocked
- src.shock(usr,50)
- spawn(100) src.shocked = !src.shocked
- if(href_list["act"] == "wire")
- if (!istype(usr.equipped(), /obj/item/weapon/wirecutters))
- usr << "You need wirecutters!"
- else
- wires[temp_wire] = !wires[temp_wire]
- if(src.hack_wire == temp_wire)
- src.hacked = !src.hacked
- if(src.disable_wire == temp_wire)
- src.disabled = !src.disabled
- src.shock(usr,50)
- if(src.shock_wire == temp_wire)
- src.shocked = !src.shocked
- src.shock(usr,50)
- else
- usr << "\red The autolathe is busy. Please wait for completion of previous operation."
- src.updateUsrDialog()
- return
-
var/global/list/autolathe_recipes = list( \
/* screwdriver removed*/ \
new /obj/item/weapon/reagent_containers/glass/bucket(), \
@@ -322,55 +51,330 @@ var/global/list/autolathe_recipes_hidden = list( \
/* new /obj/item/weapon/shield/riot(), */ \
)
-/obj/machinery/autolathe/RefreshParts()
- ..()
- var/tot_rating = 0
- for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts)
- tot_rating += MB.rating
- tot_rating *= 25000
- max_m_amount = tot_rating * 2
- max_g_amount = tot_rating
+/obj/machinery/autolathe
+ var
+ busy = 0
+ max_m_amount = 150000.0
+ max_g_amount = 75000.0
+ outputAmount = 1
+ makeDir = 0
+
+ proc
+ wires_win(mob/user as mob)
+ var/dat as text
+ dat += "Autolathe Wires: "
+ for(var/wire in src.wires)
+ dat += text("[wire] Wire: [src.wires[wire] ? "Mend" : "Cut"] Pulse ")
+
+ dat += text("The red light is [src.disabled ? "off" : "on"]. ")
+ dat += text("The green light is [src.shocked ? "off" : "on"]. ")
+ dat += text("The blue light is [src.hacked ? "off" : "on"]. ")
+ user << browse("Autolathe Hacking [dat]","window=autolathe_hack")
+ onclose(user, "autolathe_hack")
+
+ regular_win(mob/user as mob)
+ var/dat as text
+ dat = text("Metal Amount: [src.m_amount] cm3 (MAX: [max_m_amount]) \nGlass Amount: [src.g_amount] cm3 (MAX: [max_g_amount]) ")
+ dat += "Output Queue: [outputAmount] (Modify )"
+ dat += " "
+ var/list/heldContainers = list()
+ for(var/obj/item/weapon/storage/container in src.contents)
+ heldContainers += container
+ if(heldContainers.len)
+ for(var/obj/item/weapon/storage/container in heldContainers)
+ dat += "[container.name] (eject stored container) "
+ else
+ dat += "No held storage containers"
+ dat += " "
+ var/list/objs = list()
+ objs += src.L
+ if (src.hacked)
+ objs += src.LL
+ for(var/obj/t in objs)
+ var/title = "[t.name] ([t.m_amt] m /[t.g_amt] g)"
+ if (m_amount"
+ continue
+ dat += "[title] "
+ if (istype(t, /obj/item/stack))
+ var/obj/item/stack/S = t
+ var/max_multiplier = min(S.max_amount, S.m_amt?round(m_amount/S.m_amt):INFINITY, S.g_amt?round(g_amount/S.g_amt):INFINITY)
+ if (max_multiplier>1)
+ dat += " |"
+ if (max_multiplier>10)
+ dat += " x[10] "
+ if (max_multiplier>25)
+ dat += " x[25] "
+ if (max_multiplier>1)
+ dat += " x[max_multiplier] "
+ dat += " "
+ user << browse("Autolathe Control Panel [dat] ", "window=autolathe_regular")
+ onclose(user, "autolathe_regular")
+
+ interact(mob/user as mob)
+ if(..())
+ return
+ if (src.shocked)
+ src.shock(user,50)
+ if (src.opened)
+ wires_win(user,50)
+ return
+ if (src.disabled)
+ user << "\red You press the button, but nothing happens."
+ return
+ regular_win(user)
+ return
+
+ shock(mob/user, prb)
+ if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
+ return 0
+ if(!prob(prb))
+ return 0
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, src)
+ s.start()
+ if (electrocute_mob(user, get_area(src), src, 0.7))
+ return 1
+ else
+ return 0
+
+ attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if (stat)
+ return 1
+ if(istype(O,/obj/item/weapon/storage/))
+ usr.before_take_item(O)
+ O.loc = src
+ user << "\blue You insert the \icon[O] [O.name] into the autolathe!"
+ return 0
+ if (busy)
+ user << "\red The autolathe is busy. Please wait for completion of previous operation."
+ return 1
+ if (istype(O, /obj/item/weapon/screwdriver))
+ if (!opened)
+ src.opened = 1
+ src.icon_state = "autolathe_t"
+ user << "You open the maintenance hatch of [src]."
+ else
+ src.opened = 0
+ src.icon_state = "autolathe"
+ user << "You close the maintenance hatch of [src]."
+ return 1
+ if (opened)
+ if(istype(O, /obj/item/weapon/crowbar))
+ playsound(src.loc, 'Crowbar.ogg', 50, 1)
+ var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc)
+ M.state = 2
+ M.icon_state = "box_1"
+ for(var/obj/I in component_parts)
+ if(I.reliability != 100 && crit_fail)
+ I.crit_fail = 1
+ I.loc = src.loc
+ if(m_amount >= 3750)
+ var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(src.loc)
+ G.amount = round(m_amount / 3750)
+ if(g_amount >= 3750)
+ var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc)
+ G.amount = round(g_amount / 3750)
+ del(src)
+ return 1
+ else
+ user.machine = src
+ interact(user)
+ return 1
+
+ if (src.m_amount + O.m_amt > max_m_amount)
+ user << "\red The autolathe is full. Please remove metal from the autolathe in order to insert more."
+ return 1
+ if (src.g_amount + O.g_amt > max_g_amount)
+ user << "\red The autolathe is full. Please remove glass from the autolathe in order to insert more."
+ return 1
+ if (O.m_amt == 0 && O.g_amt == 0)
+ user << "\red This object does not contain significant amounts of metal or glass, or cannot be accepted by the autolathe due to size or hazardous materials."
+ return 1
+ /*
+ if (istype(O, /obj/item/weapon/grab) && src.hacked)
+ var/obj/item/weapon/grab/G = O
+ if (prob(25) && G.affecting)
+ G.affecting.gib()
+ m_amount += 50000
+ return
+ */
+
+ var/amount = 1
+ var/obj/item/stack/stack
+ var/m_amt = O.m_amt
+ var/g_amt = O.g_amt
+ if (istype(O, /obj/item/stack))
+ stack = O
+ amount = stack.amount
+ if (m_amt)
+ amount = min(amount, round((max_m_amount-src.m_amount)/m_amt))
+ flick("autolathe_o",src)//plays metal insertion animation
+ if (g_amt)
+ amount = min(amount, round((max_g_amount-src.g_amount)/g_amt))
+ flick("autolathe_r",src)//plays glass insertion animation
+ stack.use(amount)
+ else
+ usr.before_take_item(O)
+ O.loc = src
+ icon_state = "autolathe"
+ busy = 1
+ use_power(max(1000, (m_amt+g_amt)*amount/10))
+ src.m_amount += m_amt * amount
+ src.g_amount += g_amt * amount
+ user << "You insert [amount] sheet[amount>1 ? "s" : ""] to the autolathe."
+ if (O && O.loc == src)
+ del(O)
+ busy = 0
+ src.updateUsrDialog()
+
+ attack_paw(mob/user as mob)
+ return src.attack_hand(user)
+
+ attack_hand(mob/user as mob)
+ user.machine = src
+ interact(user)
+
+
+ Topic(href, href_list)
+ if(..())
+ return
+ usr.machine = src
+ src.add_fingerprint(usr)
+ if(href_list["removeContainer"])
+ var/obj/item/weapon/storage/container = locate(href_list["removeContainer"])
+ container.loc = src.loc
+ container.layer = initial(container.layer)
+ if(href_list["modifyOutputAmount"])
+ outputAmount = text2num(input(usr,"Amount:","Enter new quantity to create",""))
+ if(!busy)
+ if(outputAmount < 1)
+ outputAmount = 1
+ else
+ usr << "\red The autolathe is busy. Please wait for completion of previous operation."
+ if (!busy)
+ if(href_list["make"])
+ var/turf/T = src.loc
+ var/obj/template = locate(href_list["make"])
+ var/multiplier = text2num(href_list["multiplier"])
+ if (!multiplier) multiplier = 1
+ var/power = max(2000, (template.m_amt+template.g_amt)*multiplier/5)
+ restart:
+ if(outputAmount > 0)
+ if(src.m_amount >= template.m_amt*multiplier && src.g_amount >= template.g_amt*multiplier)
+ busy = 1
+ use_power(power)
+ icon_state = "autolathe"
+ flick("autolathe_n",src)
+ spawn(16)
+
+ if(!busy)
+ busy = 1
+ use_power(power)
+ spawn(16)
+ use_power(power)
+ spawn(16)
+ flick("autolathe_n",src)
+ src.m_amount -= template.m_amt*multiplier
+ src.g_amount -= template.g_amt*multiplier
+ if(src.m_amount < 0)
+ src.m_amount = 0
+ if(src.g_amount < 0)
+ src.g_amount = 0
+ var/obj/new_item = new template.type(src)
+ for(var/obj/item/weapon/storage/container in src.contents)
+ container.attackby(new_item)
+ if(new_item.loc == container)
+ break
+ if (multiplier>1)
+ var/obj/item/stack/S = new_item
+ S.amount = multiplier
+ if(new_item in src)
+ new_item.loc = T
+ src.updateUsrDialog()
+ outputAmount -= 1
+ busy = 0
+ goto restart
+ else
+ for(var/mob/M in view(3,src))
+ M << "\red\icon[src] has run out of materials."
+ else
+ outputAmount = 1
+ if(href_list["act"])
+ var/temp_wire = href_list["wire"]
+ if(href_list["act"] == "pulse")
+ if (!istype(usr.equipped(), /obj/item/device/multitool))
+ usr << "You need a multitool!"
+ else
+ if(src.wires[temp_wire])
+ usr << "You can't pulse a cut wire."
+ else
+ if(src.hack_wire == temp_wire)
+ src.hacked = !src.hacked
+ spawn(100) src.hacked = !src.hacked
+ if(src.disable_wire == temp_wire)
+ src.disabled = !src.disabled
+ src.shock(usr,50)
+ spawn(100) src.disabled = !src.disabled
+ if(src.shock_wire == temp_wire)
+ src.shocked = !src.shocked
+ src.shock(usr,50)
+ spawn(100) src.shocked = !src.shocked
+ if(href_list["act"] == "wire")
+ if (!istype(usr.equipped(), /obj/item/weapon/wirecutters))
+ usr << "You need wirecutters!"
+ else
+ wires[temp_wire] = !wires[temp_wire]
+ if(src.hack_wire == temp_wire)
+ src.hacked = !src.hacked
+ if(src.disable_wire == temp_wire)
+ src.disabled = !src.disabled
+ src.shock(usr,50)
+ if(src.shock_wire == temp_wire)
+ src.shocked = !src.shocked
+ src.shock(usr,50)
+ else
+ usr << "\red The autolathe is busy. Please wait for completion of previous operation."
+ src.updateUsrDialog()
+ return
+
-/obj/machinery/autolathe/New()
- ..()
- component_parts = list()
- component_parts += new /obj/item/weapon/circuitboard/autolathe(src)
- component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
- component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
- component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
- component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
- component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
RefreshParts()
+ ..()
+ var/tot_rating = 0
+ for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts)
+ tot_rating += MB.rating
+ tot_rating *= 25000
+ max_m_amount = tot_rating * 2
+ max_g_amount = tot_rating
- src.L = autolathe_recipes
- src.LL = autolathe_recipes_hidden
- src.wires["Light Red"] = 0
- src.wires["Dark Red"] = 0
- src.wires["Blue"] = 0
- src.wires["Green"] = 0
- src.wires["Yellow"] = 0
- src.wires["Black"] = 0
- src.wires["White"] = 0
- src.wires["Gray"] = 0
- src.wires["Orange"] = 0
- src.wires["Pink"] = 0
- var/list/w = list("Light Red","Dark Red","Blue","Green","Yellow","Black","White","Gray","Orange","Pink")
- src.hack_wire = pick(w)
- w -= src.hack_wire
- src.shock_wire = pick(w)
- w -= src.shock_wire
- src.disable_wire = pick(w)
- w -= src.disable_wire
+ New()
+ ..()
+ component_parts = list()
+ component_parts += new /obj/item/weapon/circuitboard/autolathe(src)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
+ component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
+ component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
+ component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
+ RefreshParts()
-/obj/machinery/autolathe/proc/shock(mob/user, prb)
- if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
- return 0
- if(!prob(prb))
- return 0
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, src)
- s.start()
- if (electrocute_mob(user, get_area(src), src, 0.7))
- return 1
- else
- return 0
\ No newline at end of file
+ src.L = autolathe_recipes
+ src.LL = autolathe_recipes_hidden
+ src.wires["Light Red"] = 0
+ src.wires["Dark Red"] = 0
+ src.wires["Blue"] = 0
+ src.wires["Green"] = 0
+ src.wires["Yellow"] = 0
+ src.wires["Black"] = 0
+ src.wires["White"] = 0
+ src.wires["Gray"] = 0
+ src.wires["Orange"] = 0
+ src.wires["Pink"] = 0
+ var/list/w = list("Light Red","Dark Red","Blue","Green","Yellow","Black","White","Gray","Orange","Pink")
+ src.hack_wire = pick(w)
+ w -= src.hack_wire
+ src.shock_wire = pick(w)
+ w -= src.shock_wire
+ src.disable_wire = pick(w)
+ w -= src.disable_wire
diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm
index 683e5328cc..6a0f2d475e 100644
--- a/code/game/machinery/biogenerator.dm
+++ b/code/game/machinery/biogenerator.dm
@@ -92,9 +92,12 @@
dat += "10 milk (20) "
dat += "Slab of meat (50) "
dat += "Nutrient "
- dat += "E-Z-Nutrient (10) "
- dat += "Left 4 Zed (20) "
- dat += "Robust Harvest (25) "
+ dat += "E-Z-Nutrient (10) | x5 "
+ dat += "Left 4 Zed (20) | x5 "
+ dat += "Robust Harvest (25) | x5 "
+ dat += "Leather "
+ dat += "Botanical gloves (350) "
+ dat += "Utility belt (400) "
//dat += "Other "
//dat += "Monkey (500) "
else
@@ -163,6 +166,28 @@
new/obj/item/nutrient/l4z(src.loc)
if("rh")
new/obj/item/nutrient/rh(src.loc)
+ if("ez5") //It's not an elegant method, but it's safe and easy. -Cheridan
+ new/obj/item/nutrient/ez(src.loc)
+ new/obj/item/nutrient/ez(src.loc)
+ new/obj/item/nutrient/ez(src.loc)
+ new/obj/item/nutrient/ez(src.loc)
+ new/obj/item/nutrient/ez(src.loc)
+ if("l4z5")
+ new/obj/item/nutrient/l4z(src.loc)
+ new/obj/item/nutrient/l4z(src.loc)
+ new/obj/item/nutrient/l4z(src.loc)
+ new/obj/item/nutrient/l4z(src.loc)
+ new/obj/item/nutrient/l4z(src.loc)
+ if("rh5")
+ new/obj/item/nutrient/rh(src.loc)
+ new/obj/item/nutrient/rh(src.loc)
+ new/obj/item/nutrient/rh(src.loc)
+ new/obj/item/nutrient/rh(src.loc)
+ new/obj/item/nutrient/rh(src.loc)
+ if("gloves")
+ new/obj/item/clothing/gloves/botanic_leather(src.loc)
+ if("tbelt")
+ new/obj/item/weapon/storage/belt/utility(src.loc)
if("monkey")
new/mob/living/carbon/monkey(src.loc)
processing = 0
@@ -181,9 +206,10 @@
if("activate")
activate()
if("detach")
- beaker.loc = src.loc
- beaker = null
- update_icon()
+ if(beaker)
+ beaker.loc = src.loc
+ beaker = null
+ update_icon()
if("create")
create_product(href_list["item"],text2num(href_list["cost"]))
if("menu")
diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm
index 8f2872dba9..854e089881 100644
--- a/code/game/machinery/bots/ed209bot.dm
+++ b/code/game/machinery/bots/ed209bot.dm
@@ -613,13 +613,22 @@ Auto Patrol: []"},
return 0
if((istype(perp.l_hand, /obj/item/weapon/gun) && !istype(perp.l_hand, /obj/item/weapon/gun/projectile/shotgun)) || istype(perp.l_hand, /obj/item/weapon/melee/baton))
- threatcount += 4
+ if(!istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/bluetag) \
+ && !istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/redtag) \
+ && !istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/practice))
+ threatcount += 4
- if((istype(perp.r_hand, /obj/item/weapon/gun) && !istype(perp.r_hand, /obj/item/weapon/gun/projectile/shotgun)) || istype(perp.r_hand, /obj/item/weapon/melee/baton))
- threatcount += 4
+ if(istype(perp.r_hand, /obj/item/weapon/gun) || istype(perp.r_hand, /obj/item/weapon/melee))
+ if(!istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/bluetag) \
+ && !istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/redtag) \
+ && !istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/practice))
+ threatcount += 4
- if(istype(perp:belt, /obj/item/weapon/gun) || istype(perp:belt, /obj/item/weapon/melee/baton))
- threatcount += 2
+ if(istype(perp:belt, /obj/item/weapon/gun) || istype(perp:belt, /obj/item/weapon/melee))
+ if(!istype(perp:belt, /obj/item/weapon/gun/energy/laser/bluetag) \
+ && !istype(perp:belt, /obj/item/weapon/gun/energy/laser/redtag) \
+ && !istype(perp:belt, /obj/item/weapon/gun/energy/laser/practice))
+ threatcount += 2
if(istype(perp:wear_suit, /obj/item/clothing/suit/wizrobe))
threatcount += 2
diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm
index 61338d7377..87ae8f6be8 100644
--- a/code/game/machinery/bots/secbot.dm
+++ b/code/game/machinery/bots/secbot.dm
@@ -588,14 +588,24 @@ Auto Patrol: []"},
if(src.emagged) return 10 //Everyone is a criminal!
if(src.idcheck && !src.allowed(perp))
+
if(istype(perp.l_hand, /obj/item/weapon/gun) || istype(perp.l_hand, /obj/item/weapon/melee))
- threatcount += 4
+ if(!istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/bluetag) \
+ && !istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/redtag) \
+ && !istype(perp.l_hand, /obj/item/weapon/gun/energy/laser/practice))
+ threatcount += 4
if(istype(perp.r_hand, /obj/item/weapon/gun) || istype(perp.r_hand, /obj/item/weapon/melee))
- threatcount += 4
+ if(!istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/bluetag) \
+ && !istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/redtag) \
+ && !istype(perp.r_hand, /obj/item/weapon/gun/energy/laser/practice))
+ threatcount += 4
if(istype(perp:belt, /obj/item/weapon/gun) || istype(perp:belt, /obj/item/weapon/melee))
- threatcount += 2
+ if(!istype(perp:belt, /obj/item/weapon/gun/energy/laser/bluetag) \
+ && !istype(perp:belt, /obj/item/weapon/gun/energy/laser/redtag) \
+ && !istype(perp:belt, /obj/item/weapon/gun/energy/laser/practice))
+ threatcount += 2
if(istype(perp:wear_suit, /obj/item/clothing/suit/wizrobe))
threatcount += 2
diff --git a/code/game/machinery/camera.dm b/code/game/machinery/camera.dm
index ae061bb9a1..8af06c5504 100644
--- a/code/game/machinery/camera.dm
+++ b/code/game/machinery/camera.dm
@@ -66,6 +66,8 @@
continue
else if (M == usr)
continue
+ if(M.digitalcamo)
+ continue
var/turf/temp_turf = get_turf(M)
if(temp_turf.z != 1 && temp_turf.z != 5) //Not on mining or the station.
continue
@@ -118,6 +120,11 @@
usr << "Follow camera mode terminated."
usr:cameraFollow = null
return
+ if(target.digitalcamo)
+ usr << "Follow camera mode terminated."
+ usr:cameraFollow = null
+ return
+
else if(istype(target.loc,/obj/effect/dummy))
usr << "Follow camera mode ended."
usr:cameraFollow = null
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index 17239407b6..4b5095d19a 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -1,57 +1,92 @@
-/obj/machinery/cell_charger/attackby(obj/item/weapon/W, mob/user)
- if(stat & BROKEN)
- return
- if(istype(W, /obj/item/weapon/cell))
- if(charging)
- user << "There is already a cell in the charger."
- return
- else
- user.drop_item()
- W.loc = src
- charging = W
- user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.")
- chargelevel = -1
- updateicon()
-
-/obj/machinery/cell_charger/proc/updateicon()
- icon_state = "ccharger[charging ? 1 : 0]"
-
- if(charging && !(stat & (BROKEN|NOPOWER)) )
-
- var/newlevel = round( charging.percent() * 4.0 / 99 )
- //world << "nl: [newlevel]"
-
- if(chargelevel != newlevel)
-
- overlays = null
- overlays += image('power.dmi', "ccharger-o[newlevel]")
-
- chargelevel = newlevel
- else
- overlays = null
-
-/obj/machinery/cell_charger/attack_hand(mob/user)
-
- if(charging)
- usr.put_in_hand(charging)
- charging.add_fingerprint(user)
- charging.updateicon()
-
- src.charging = null
- user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.")
+/obj/machinery/cell_charger
+ name = "cell charger"
+ desc = "It charges power cells."
+ icon = 'power.dmi'
+ icon_state = "ccharger0"
+ anchored = 1
+ use_power = 1
+ idle_power_usage = 5
+ active_power_usage = 60
+ power_channel = EQUIP
+ var
+ obj/item/weapon/cell/charging = null
chargelevel = -1
+ proc
updateicon()
+ icon_state = "ccharger[charging ? 1 : 0]"
-/obj/machinery/cell_charger/attack_ai(mob/user)
- return
+ if(charging && !(stat & (BROKEN|NOPOWER)) )
-/obj/machinery/cell_charger/process()
- //world << "ccpt [charging] [stat]"
- if(!charging || (stat & (BROKEN|NOPOWER)) )
+ var/newlevel = round( charging.percent() * 4.0 / 99 )
+ //world << "nl: [newlevel]"
+
+ if(chargelevel != newlevel)
+
+ overlays = null
+ overlays += image('power.dmi', "ccharger-o[newlevel]")
+
+ chargelevel = newlevel
+ else
+ overlays = null
+ examine()
+ set src in oview(5)
+ ..()
+ usr << "There's [charging ? "a" : "no"] cell in the charger."
+ if(charging)
+ usr << "Current charge: [charging.charge]"
+
+ attackby(obj/item/weapon/W, mob/user)
+ if(stat & BROKEN)
+ return
+
+ if(istype(W, /obj/item/weapon/cell) && anchored)
+ if(charging)
+ user << "\red There is already a cell in the charger."
+ return
+ else
+ var/area/a = loc.loc // Gets our locations location, like a dream within a dream
+ if(!isarea(a))
+ return
+ if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power!
+ user << "\red The charger rejects the cell!"
+ return
+
+ user.drop_item()
+ W.loc = src
+ charging = W
+ user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.")
+ chargelevel = -1
+ updateicon()
+ else if(istype(W, /obj/item/weapon/wrench))
+ if(charging)
+ user << "\red Remove the cell first!"
+ return
+
+ anchored = !anchored
+ user << "You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground"
+ playsound(src.loc, 'Ratchet.ogg', 75, 1)
+
+ attack_hand(mob/user)
+ if(charging)
+ usr.put_in_hand(charging)
+ charging.add_fingerprint(user)
+ charging.updateicon()
+
+ src.charging = null
+ user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.")
+ chargelevel = -1
+ updateicon()
+
+ attack_ai(mob/user)
return
- var/added = charging.give(75)
- use_power(added / CELLRATE)
+ process()
+ //world << "ccpt [charging] [stat]"
+ if(!charging || (stat & (BROKEN|NOPOWER)) || !anchored)
+ return
- updateicon()
\ No newline at end of file
+ var/added = charging.give(75)
+ use_power(added / CELLRATE)
+
+ updateicon()
diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm
new file mode 100644
index 0000000000..567f10801f
--- /dev/null
+++ b/code/game/machinery/computer/HolodeckControl.dm
@@ -0,0 +1,459 @@
+/obj/machinery/computer/HolodeckControl
+ name = "Holodeck Control Computer"
+ desc = "A computer used to control a nearby holodeck."
+ icon_state = "computer_generic"
+ var/area/linkedholodeck = null
+ var/area/target = null
+ var/active = 0
+ var/list/holographic_items = list()
+ var/damaged = 0
+
+
+ attack_ai(var/mob/user as mob)
+ return src.attack_hand(user)
+
+ attack_paw(var/mob/user as mob)
+ return
+
+ attack_hand(var/mob/user as mob)
+
+ if(..())
+ return
+ user.machine = src
+ var/dat
+
+
+ dat += "Holodeck Control System "
+ dat += " Current Loaded Programs: "
+
+ dat += "((Empty Court)) "
+ dat += "((Boxing Court)) "
+ dat += "((Thunderdome Court)) "
+ dat += "((Beach)) "
+// dat += "((Shutdown System)) "
+
+ dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded. "
+
+ if(issilicon(user) && !emagged)
+ dat += "(Override Safety Protocols? ) "
+
+ if(emagged)
+ dat += "(Begin Atmospheric Burn Simulation ) "
+ dat += "Ensure the holodeck is empty before testing. "
+ dat += " "
+ dat += "(Begin Wildlife Simulation ) "
+ dat += "Ensure the holodeck is empty before testing. "
+ dat += " "
+ dat += "Safety Protocols are DISABLED "
+ else
+ dat += " "
+ dat += "Safety Protocols are ENABLED "
+
+ user << browse(dat, "window=computer;size=400x500")
+ onclose(user, "computer")
+
+
+ return
+
+
+ Topic(href, href_list)
+ if(..())
+ return
+ if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
+ usr.machine = src
+
+ if(href_list["emptycourt"])
+ target = locate(/area/holodeck/source_emptycourt)
+ if(target)
+ loadProgram(target)
+
+ else if(href_list["boxingcourt"])
+ target = locate(/area/holodeck/source_boxingcourt)
+ if(target)
+ loadProgram(target)
+
+ else if(href_list["thunderdomecourt"])
+ target = locate(/area/holodeck/source_thunderdomecourt)
+ if(target)
+ loadProgram(target)
+
+ else if(href_list["beach"])
+ target = locate(/area/holodeck/source_beach)
+ if(target)
+ loadProgram(target)
+
+ else if(href_list["turnoff"])
+ target = locate(/area/holodeck/source_plating)
+ if(target)
+ loadProgram(target)
+
+ else if(href_list["burntest"])
+ target = locate(/area/holodeck/source_burntest)
+ if(target)
+ loadProgram(target)
+
+ else if(href_list["wildlifecarp"])
+ target = locate(/area/holodeck/source_wildlife)
+ if(target)
+ loadProgram(target)
+
+ else if(href_list["AIoverride"])
+ emagged = 1
+
+ src.add_fingerprint(usr)
+ src.updateUsrDialog()
+ return
+
+
+
+/obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
+/* if(istype(D, /obj/item/weapon/screwdriver))
+ playsound(src.loc, 'Screwdriver.ogg', 50, 1)
+ if(do_after(user, 20))
+ if (src.stat & BROKEN)
+ user << "\blue The broken glass falls out."
+ var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
+ new /obj/item/weapon/shard( src.loc )
+ var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
+ for (var/obj/C in src)
+ C.loc = src.loc
+ A.circuit = M
+ A.state = 3
+ A.icon_state = "3"
+ A.anchored = 1
+ del(src)
+ else
+ user << "\blue You disconnect the monitor."
+ var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
+ var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
+ for (var/obj/C in src)
+ C.loc = src.loc
+ A.circuit = M
+ A.state = 4
+ A.icon_state = "4"
+ A.anchored = 1
+ del(src)
+
+*/
+ if(istype(D, /obj/item/weapon/card/emag) && !emagged)
+ playsound(src.loc, 'sparks4.ogg', 75, 1)
+ emagged = 1
+ user << "\blue You vastly increase projector power and override the safety and security protocols."
+ user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintence and do not use the simulator."
+ src.updateUsrDialog()
+ return
+
+/obj/machinery/computer/HolodeckControl/New()
+ ..()
+ linkedholodeck = locate(/area/holodeck/alphadeck)
+ //if(linkedholodeck)
+ // target = locate(/area/holodeck/source_emptycourt)
+ // if(target)
+ // loadProgram(target)
+
+
+/obj/machinery/computer/HolodeckControl/process()
+
+ if(active)
+
+ if(!checkInteg(linkedholodeck))
+ damaged = 1
+ target = locate(/area/holodeck/source_plating)
+ if(target)
+ loadProgram(target)
+ active = 0
+ for(var/mob/M in range(10,src))
+ M.show_message("The holodeck overloads!")
+
+
+ for(var/turf/T in linkedholodeck)
+ if(prob(30))
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(2, 1, T)
+ s.start()
+ T.ex_act(3)
+ T.hotspot_expose(1000,500,1)
+
+
+ for(var/item in holographic_items)
+ if(!(get_turf(item) in linkedholodeck))
+ derez(item, 0)
+
+
+
+/obj/machinery/computer/HolodeckControl/proc/derez(var/obj , var/silent = 1)
+ holographic_items.Remove(obj)
+
+ if(istype(obj , /obj/))
+ if(istype(obj:loc , /mob/))
+ var/mob/M = obj:loc
+ M.drop_from_slot(obj)
+
+ if(!silent)
+ var/obj/oldobj = obj
+ for(var/mob/M in viewers(world.view,get_turf(obj)))
+ M << "The [oldobj.name] fades away!"
+ del(obj)
+
+/obj/machinery/computer/HolodeckControl/proc/checkInteg(var/area/A)
+ for(var/turf/T in A)
+ if(istype(T, /turf/space))
+ return 0
+
+ return 1
+
+/obj/machinery/computer/HolodeckControl/proc/togglePower(var/toggleOn = 0)
+
+ if(toggleOn)
+ var/area/targetsource = locate(/area/holodeck/source_emptycourt)
+ holographic_items = targetsource.copy_contents_to(linkedholodeck)
+
+ spawn(30)
+ for(var/obj/effect/landmark/L in linkedholodeck)
+ if(L.name=="Atmospheric Test Start")
+ spawn(20)
+ var/turf/T = get_turf(L)
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(2, 1, T)
+ s.start()
+ if(T)
+ T.temperature = 5000
+ T.hotspot_expose(50000,50000,1)
+
+ active = 1
+ else
+ for(var/item in holographic_items)
+ derez(item)
+ var/area/targetsource = locate(/area/holodeck/source_plating)
+ targetsource.copy_contents_to(linkedholodeck , 1)
+ active = 0
+
+
+/obj/machinery/computer/HolodeckControl/proc/loadProgram(var/area/A)
+
+ active = 1
+
+ for(var/item in holographic_items)
+ derez(item)
+
+ for(var/obj/effect/decal/cleanable/blood/B in linkedholodeck)
+ del(B)
+
+ holographic_items = A.copy_contents_to(linkedholodeck , 1)
+
+ if(emagged)
+ for(var/obj/item/weapon/melee/energy/sword/holosword/H in linkedholodeck)
+ H.damtype = BRUTE
+
+ spawn(30)
+ for(var/obj/effect/landmark/L in linkedholodeck)
+ if(L.name=="Atmospheric Test Start")
+ spawn(20)
+ var/turf/T = get_turf(L)
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(2, 1, T)
+ s.start()
+ if(T)
+ T.temperature = 5000
+ T.hotspot_expose(50000,50000,1)
+
+
+
+
+
+
+
+
+
+
+// Holographic Items!
+
+/turf/simulated/floor/holofloor/
+ thermal_conductivity = 0
+
+/turf/simulated/floor/holofloor/grass
+ name = "Lush Grass"
+ icon_state = "grass1"
+ floor_tile = new/obj/item/stack/tile/grass
+
+ New()
+ floor_tile.New() //I guess New() isn't run on objects spawned without the definition of a turf to house them, ah well.
+ icon_state = "grass[pick("1","2","3","4")]"
+ ..()
+ spawn(4)
+ update_icon()
+ for(var/direction in cardinal)
+ if(istype(get_step(src,direction),/turf/simulated/floor))
+ var/turf/simulated/floor/FF = get_step(src,direction)
+ FF.update_icon() //so siding get updated properly
+
+/turf/simulated/floor/holofloor/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ return
+ // HOLOFLOOR DOES NOT GIVE A FUCK
+
+
+
+
+
+
+
+
+
+
+/obj/structure/table/holotable
+ name = "table"
+ desc = "A square piece of metal standing on four metal legs. It can not move."
+ icon = 'structures.dmi'
+ icon_state = "table"
+ density = 1
+ anchored = 1.0
+ layer = 2.8
+// throwpass = 1 //You can throw objects over this, despite it's density.
+
+
+/obj/structure/table/holotable/attack_paw(mob/user as mob)
+ return attack_hand(user)
+
+/obj/structure/table/holotable/attack_alien(mob/user as mob) //Removed code for larva since it doesn't work. Previous code is now a larva ability. /N
+ return attack_hand(user)
+
+/obj/structure/table/holotable/attack_animal(mob/living/simple_animal/user as mob) //Removed code for larva since it doesn't work. Previous code is now a larva ability. /N
+ return attack_hand(user)
+
+/obj/structure/table/holotable/attack_hand(mob/user as mob)
+ return // HOLOTABLE DOES NOT GIVE A FUCK
+
+
+/obj/structure/table/holotable/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
+ var/obj/item/weapon/grab/G = W
+ if(G.state<2)
+ user << "\red You need a better grip to do that!"
+ return
+ G.affecting.loc = src.loc
+ G.affecting.Weaken(5)
+ for(var/mob/O in viewers(world.view, src))
+ if (O.client)
+ O << text("\red [] puts [] on the table.", G.assailant, G.affecting)
+ del(W)
+ return
+
+ if (istype(W, /obj/item/weapon/wrench))
+ user << "It's a holotable! There are no bolts!"
+ return
+
+ if(isrobot(user))
+ return
+
+
+
+/obj/item/clothing/gloves/boxing/hologlove
+ name = "boxing gloves"
+ desc = "Because you really needed another excuse to punch your crewmates."
+ icon_state = "boxing"
+ item_state = "boxing"
+
+/obj/structure/holowindow
+ name = "reinforced window"
+ icon = 'structures.dmi'
+ icon_state = "rwindow"
+ desc = "A window."
+ density = 1
+ layer = 3.2//Just above doors
+ pressure_resistance = 4*ONE_ATMOSPHERE
+ anchored = 1.0
+ flags = ON_BORDER
+
+
+/obj/structure/holowindow/Del()
+ ..()
+
+
+/obj/item/weapon/melee/energy/sword/holosword
+ damtype = HALLOSS
+
+/obj/item/weapon/melee/energy/sword/holosword/green
+ New()
+ color = "green"
+
+/obj/item/weapon/melee/energy/sword/holosword/red
+ New()
+ color = "red"
+
+
+
+
+
+
+/obj/machinery/readybutton
+ name = "Ready Declaration Device"
+ desc = "This device is used to declare ready. If all devices in an area are ready, the event will begin!"
+ icon = 'monitors.dmi'
+ icon_state = "auth_off"
+ var/ready = 0
+ var/area/currentarea = null
+ var/eventstarted = 0
+
+ anchored = 1.0
+ use_power = 1
+ idle_power_usage = 2
+ active_power_usage = 6
+ power_channel = ENVIRON
+
+/obj/machinery/readybutton/attack_ai(mob/user as mob)
+ user << "The station AI is not to interact with these devices"
+ return
+
+/obj/machinery/readybutton/attack_paw(mob/user as mob)
+ user << "You are too primitive to use this device"
+ return
+
+/obj/machinery/readybutton/New()
+ ..()
+
+
+/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ user << "The device is a solid button, there's nothing you can do with it!"
+
+/obj/machinery/readybutton/attack_hand(mob/user as mob)
+ if(user.stat || stat & (NOPOWER|BROKEN))
+ user << "This device is not powered."
+ return
+
+ currentarea = get_area(src.loc)
+ if(!currentarea)
+ del(src)
+
+ if(eventstarted)
+ usr << "The event has already begun!"
+ return
+
+ ready = !ready
+
+ update_icon()
+
+ var/numbuttons = 0
+ var/numready = 0
+ for(var/obj/machinery/readybutton/button in currentarea)
+ numbuttons++
+ if (button.ready)
+ numready++
+
+ if(numbuttons == numready)
+ begin_event()
+
+/obj/machinery/readybutton/update_icon()
+ if(ready)
+ icon_state = "auth_on"
+ else
+ icon_state = "auth_off"
+
+/obj/machinery/readybutton/proc/begin_event()
+
+ eventstarted = 1
+
+ for(var/obj/structure/holowindow/W in currentarea)
+ del(W)
+
+ for(var/mob/M in currentarea)
+ M << "FIGHT!"
\ No newline at end of file
diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm
new file mode 100644
index 0000000000..659f98b939
--- /dev/null
+++ b/code/game/machinery/computer/atmos_alert.dm
@@ -0,0 +1,105 @@
+
+/obj/machinery/computer/atmos_alert
+ name = "Atmospheric Alert Computer"
+ desc = "Used to access the station's atmospheric sensors."
+ icon_state = "alert:0"
+ var
+ list/priority_alarms = list()
+ list/minor_alarms = list()
+ receive_frequency = 1437
+ datum/radio_frequency/radio_connection
+
+
+ initialize()
+ set_frequency(receive_frequency)
+
+ receive_signal(datum/signal/signal)
+ if(!signal || signal.encryption) return
+
+ var/zone = signal.data["zone"]
+ var/severity = signal.data["alert"]
+
+ if(!zone || !severity) return
+
+ minor_alarms -= zone
+ priority_alarms -= zone
+ if(severity=="severe")
+ priority_alarms += zone
+ else if (severity=="minor")
+ minor_alarms += zone
+ update_icon()
+ return
+
+
+ proc/set_frequency(new_frequency)
+ radio_controller.remove_object(src, receive_frequency)
+ receive_frequency = new_frequency
+ radio_connection = radio_controller.add_object(src, receive_frequency, RADIO_ATMOSIA)
+
+
+ attack_hand(mob/user)
+ user << browse(return_text(),"window=computer")
+ user.machine = src
+ onclose(user, "computer")
+
+ process()
+ ..()
+ src.updateDialog()
+
+ update_icon()
+ if(priority_alarms.len)
+ icon_state = "alert:2"
+
+ else if(minor_alarms.len)
+ icon_state = "alert:1"
+
+ else
+ icon_state = "alert:0"
+ return
+
+
+ proc/return_text()
+ var/priority_text
+ var/minor_text
+
+ if(priority_alarms.len)
+ for(var/zone in priority_alarms)
+ priority_text += "[zone] X "
+ else
+ priority_text = "No priority alerts detected. "
+
+ if(minor_alarms.len)
+ for(var/zone in minor_alarms)
+ minor_text += "[zone] X "
+ else
+ minor_text = "No minor alerts detected. "
+
+ var/output = {"[name]
+Priority Alerts:
+[priority_text]
+
+
+Minor Alerts:
+[minor_text]
+ "}
+
+ return output
+
+
+ Topic(href, href_list)
+ if(..())
+ return
+
+ if(href_list["priority_clear"])
+ var/removing_zone = href_list["priority_clear"]
+ for(var/zone in priority_alarms)
+ if(ckey(zone) == removing_zone)
+ priority_alarms -= zone
+
+ if(href_list["minor_clear"])
+ var/removing_zone = href_list["minor_clear"]
+ for(var/zone in minor_alarms)
+ if(ckey(zone) == removing_zone)
+ minor_alarms -= zone
+ update_icon()
+ return
\ No newline at end of file
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index 14c0ceb748..0fd688bed8 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -192,6 +192,11 @@
build_path = "/obj/machinery/computer/telecomms/server"
origin_tech = "programming=3"
+/obj/item/weapon/circuitboard/comm_traffic
+ name = "Circuitboard (Telecommunications Traffic Control)"
+ build_path = "/obj/machinery/computer/telecomms/traffic"
+ origin_tech = "programming=3"
+
/obj/item/weapon/circuitboard/curefab
name = "Circuit board (Cure fab)"
build_path = "/obj/machinery/computer/curer"
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index b8825a5616..c17eaf8b59 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -470,7 +470,7 @@
emergency_shuttle.incall()
log_game("[key_name(user)] has called the shuttle.")
message_admins("[key_name_admin(user)] has called the shuttle.", 1)
- world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes. "
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
world << sound('shuttlecalled.ogg')
return
@@ -482,10 +482,10 @@
if((ticker.mode.name == "blob")||(ticker.mode.name == "meteor"))
return
- emergency_shuttle.recall()
- log_game("[key_name(user)] has uncalled the shuttle.")
- message_admins("[key_name_admin(user)] has uncalled the shuttle.", 1)
-
+ if(emergency_shuttle.direction != -1 && emergency_shuttle.online) //check that shuttle isn't already heading to centcomm
+ emergency_shuttle.recall()
+ log_game("[key_name(user)] has recalled the shuttle.")
+ message_admins("[key_name_admin(user)] has recalled the shuttle.", 1)
return
/obj/machinery/computer/communications/proc/post_status(var/command, var/data1, var/data2)
@@ -529,7 +529,7 @@
emergency_shuttle.incall(2)
log_game("All the AIs, comm consoles and boards are destroyed. Shuttle called.")
message_admins("All the AIs, comm consoles and boards are destroyed. Shuttle called.", 1)
- world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes. "
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
world << sound('shuttlecalled.ogg')
..()
@@ -554,7 +554,7 @@
emergency_shuttle.incall(2)
log_game("All the AIs, comm consoles and boards are destroyed. Shuttle called.")
message_admins("All the AIs, comm consoles and boards are destroyed. Shuttle called.", 1)
- world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes. "
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
world << sound('shuttlecalled.ogg')
..()
\ No newline at end of file
diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm
index 4db4bb8280..e78c65031b 100644
--- a/code/game/machinery/computer/computer.dm
+++ b/code/game/machinery/computer/computer.dm
@@ -290,193 +290,11 @@ Pod/Blast Doors computer
locked += L
-/obj/machinery/computer/pod/proc/alarm()
- if(stat & (NOPOWER|BROKEN))
- return
- if (!( connected ))
- viewers(null, null) << "Cannot locate mass driver connector. Cancelling firing sequence!"
- return
- for(var/obj/machinery/door/poddoor/M in machines)
- if (M.id == id)
- spawn( 0 )
- M.open()
- return
- sleep(20)
- //connected.drive() *****RM from 40.93.3S
- for(var/obj/machinery/mass_driver/M in machines)
- if(M.id == id)
- M.power = connected.power
- M.drive()
- sleep(50)
- for(var/obj/machinery/door/poddoor/M in machines)
- if (M.id == id)
- spawn( 0 )
- M.close()
- return
- return
-/obj/machinery/computer/pod/New()
- ..()
- spawn( 5 )
- for(var/obj/machinery/mass_driver/M in machines)
- if (M.id == id)
- connected = M
- else
- return
- return
-
-/obj/machinery/computer/pod/attackby(I as obj, user as mob)
- if(istype(I, /obj/item/weapon/screwdriver))
- playsound(loc, 'Screwdriver.ogg', 50, 1)
- if(do_after(user, 20))
- if (stat & BROKEN)
- user << "\blue The broken glass falls out."
- var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc )
- new /obj/item/weapon/shard( loc )
-
- //generate appropriate circuitboard. Accounts for /pod/old computer types
- var/obj/item/weapon/circuitboard/pod/M = null
- if(istype(src, /obj/machinery/computer/pod/old))
- M = new /obj/item/weapon/circuitboard/olddoor( A )
- if(istype(src, /obj/machinery/computer/pod/old/syndicate))
- M = new /obj/item/weapon/circuitboard/syndicatedoor( A )
- if(istype(src, /obj/machinery/computer/pod/old/swf))
- M = new /obj/item/weapon/circuitboard/swfdoor( A )
- else //it's not an old computer. Generate standard pod circuitboard.
- M = new /obj/item/weapon/circuitboard/pod( A )
-
- for (var/obj/C in src)
- C.loc = loc
- M.id = id
- A.circuit = M
- A.state = 3
- A.icon_state = "3"
- A.anchored = 1
- del(src)
- else
- user << "\blue You disconnect the monitor."
- var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc )
-
- //generate appropriate circuitboard. Accounts for /pod/old computer types
- var/obj/item/weapon/circuitboard/pod/M = null
- if(istype(src, /obj/machinery/computer/pod/old))
- M = new /obj/item/weapon/circuitboard/olddoor( A )
- if(istype(src, /obj/machinery/computer/pod/old/syndicate))
- M = new /obj/item/weapon/circuitboard/syndicatedoor( A )
- if(istype(src, /obj/machinery/computer/pod/old/swf))
- M = new /obj/item/weapon/circuitboard/swfdoor( A )
- else //it's not an old computer. Generate standard pod circuitboard.
- M = new /obj/item/weapon/circuitboard/pod( A )
-
- for (var/obj/C in src)
- C.loc = loc
- M.id = id
- A.circuit = M
- A.state = 4
- A.icon_state = "4"
- A.anchored = 1
- del(src)
- else
- attack_hand(user)
- return
-
-/obj/machinery/computer/pod/attack_ai(var/mob/user as mob)
- return attack_hand(user)
-
-/obj/machinery/computer/pod/attack_paw(var/mob/user as mob)
- return attack_hand(user)
-
-/obj/machinery/computer/pod/attack_hand(var/mob/user as mob)
- if(..())
- return
-
- var/dat = "Mass Driver Controls "
- user.machine = src
- var/d2
- if (timing)
- d2 = text("Stop Time Launch ", src)
- else
- d2 = text("Initiate Time Launch ", src)
- var/second = time % 60
- var/minute = (time - second) / 60
- dat += text(" \nTimer System: []\nTime Left: [][] - - + + ", d2, (minute ? text("[]:", minute) : null), second, src, src, src, src)
- if (connected)
- var/temp = ""
- var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 )
- for(var/t in L)
- if (t == connected.power)
- temp += text("[] ", t)
- else
- temp += text("[] ", src, t, t)
- //Foreach goto(172)
- dat += text(" \nPower Level: [] \nFiring Sequence \nTest Fire Driver \nToggle Outer Door ", temp, src, src, src)
- //*****RM from 40.93.3S
- else
- dat += text(" \nToggle Outer Door ", src)
- //*****
- dat += text("Close ", user)
- user << browse(dat, "window=computer;size=400x500")
- onclose(user, "computer")
- return
-
-/obj/machinery/computer/pod/process()
- ..()
- if (timing)
- if (time > 0)
- time = round(time) - 1
- else
- alarm()
- time = 0
- timing = 0
- updateDialog()
- return
-
-/obj/machinery/computer/pod/Topic(href, href_list)
- if(..())
- return
- if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
- usr.machine = src
- if (href_list["power"])
- var/t = text2num(href_list["power"])
- t = min(max(0.25, t), 16)
- if (connected)
- connected.power = t
- else
- if (href_list["alarm"])
- alarm()
- else
- if (href_list["time"])
- timing = text2num(href_list["time"])
- else
- if (href_list["tp"])
- var/tp = text2num(href_list["tp"])
- time += tp
- time = min(max(round(time), 0), 120)
- else
- if (href_list["door"])
- if(istype(src, /obj/machinery/computer/pod/old/syndicate))//Added here so Nuke ops don't go running naked into space before moving the shuttle.
- if(syndicate_station_at_station == 0)
- usr << "\red You need to launch the Syndicate Shuttle via the computer terminal at the head of the ship before departing."
- return
- for(var/obj/machinery/door/poddoor/M in machines)
- if (M.id == id)
- if (M.density)
- spawn( 0 )
- M.open()
- return
- else
- spawn( 0 )
- M.close()
- return
- //Foreach goto(298)
- add_fingerprint(usr)
- updateUsrDialog()
-
- return
/obj/machinery/mass_driver/proc/drive(amount)
if(stat & (BROKEN|NOPOWER))
diff --git a/code/game/machinery/computer/id.dm b/code/game/machinery/computer/id.dm
index 6583bc5f41..d14fa30a0a 100644
--- a/code/game/machinery/computer/id.dm
+++ b/code/game/machinery/computer/id.dm
@@ -153,7 +153,14 @@
accesses += " "
accesses += ""
accesses += ""
- body = "[carddesc] [jobs] [accesses]" //CHECK THIS
+
+ var/biometric = ""
+ biometric += "Biometric Data : \
+ Blood type: [modify.blood_type] \
+ DNA hash: [modify.dna_hash] \
+ Fingerprint hash: [modify.fingerprint_hash] "
+
+ body = "[carddesc] [jobs] [biometric] [accesses]" //CHECK THIS
else
body = "{Log in} "
body += "Access Crew Manifest "
@@ -167,6 +174,17 @@
return
usr.machine = src
switch(href_list["choice"])
+ if("bio_btype")
+ var/new_b_type = input("Please input the blood type.", "Biometric Input") as null|anything in list( "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-" )
+ if(new_b_type)
+ modify.blood_type = new_b_type
+
+ if("bio_dna")
+ modify.dna_hash = input("Please input the DNA hash.", "Biometric Input", modify.dna_hash)
+
+ if("bio_fprint")
+ modify.fingerprint_hash = input("Please input the fingerprint hash.", "Biometric Input", modify.fingerprint_hash)
+
if ("modify")
if (modify)
data_core.manifest_modify(modify.registered_name, modify.assignment)
diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm
new file mode 100644
index 0000000000..7f55918b62
--- /dev/null
+++ b/code/game/machinery/computer/law.dm
@@ -0,0 +1,191 @@
+/obj/machinery/computer/aiupload
+ name = "AI Upload"
+ desc = "Used to upload laws to the AI."
+ icon_state = "command"
+ circuit = "/obj/item/weapon/circuitboard/aiupload"
+ var
+ mob/living/silicon/ai/current = null
+ opened = 0
+
+
+ verb/AccessInternals()
+ set category = "Object"
+ set name = "Access Computer's Internals"
+ set src in oview(1)
+ if(get_dist(src, usr) > 1 || usr.restrained() || usr.lying || usr.stat || istype(usr, /mob/living/silicon))
+ return
+
+ opened = !opened
+ if(opened)
+ usr << "\blue The access panel is now open."
+ else
+ usr << "\blue The access panel is now closed."
+ return
+
+
+ attackby(obj/item/weapon/O as obj, mob/user as mob)
+ if(istype(O, /obj/item/weapon/aiModule))
+ var/obj/item/weapon/aiModule/M = O
+ M.install(src)
+ else
+ ..()
+
+
+ attack_hand(var/mob/user as mob)
+ if(src.stat & NOPOWER)
+ usr << "The upload computer has no power!"
+ return
+ if(src.stat & BROKEN)
+ usr << "The upload computer is broken!"
+ return
+
+ src.current = activeais()
+
+ if (!src.current)
+ usr << "No active AIs detected."
+ else
+ usr << "[src.current.name] selected for law changes."
+ return
+
+
+
+/obj/machinery/computer/borgupload
+ name = "Cyborg Upload"
+ desc = "Used to upload laws to Cyborgs."
+ icon_state = "command"
+ circuit = "/obj/item/weapon/circuitboard/borgupload"
+ var/mob/living/silicon/robot/current = null
+
+
+ attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob)
+ if(istype(module, /obj/item/weapon/aiModule))
+ module.install(src)
+ else
+ return ..()
+
+
+ attack_hand(var/mob/user as mob)
+ if(src.stat & NOPOWER)
+ usr << "The upload computer has no power!"
+ return
+ if(src.stat & BROKEN)
+ usr << "The upload computer is broken!"
+ return
+
+ src.current = freeborg()
+
+ if (!src.current)
+ usr << "No free cyborgs detected."
+ else
+ usr << "[src.current.name] selected for law changes."
+ return
+
+/obj/machinery/computer/aistatus
+ name = "AI Status Panel"
+ desc = "This shows the status of the AI."
+ icon = 'mainframe.dmi'
+ icon_state = "left"
+// brightnessred = 0
+// brightnessgreen = 2
+// brightnessblue = 0
+
+/obj/machinery/computer/aistatus/attack_hand(mob/user as mob)
+ if(stat & NOPOWER)
+ user << "\red The status panel has no power!"
+ return
+ if(stat & BROKEN)
+ user << "\red The status panel is broken!"
+ return
+ if(!issilicon(user))
+ user << "\red You don't understand any of this!"
+ else
+ user << "\blue You know all of this already, why are you messing with it?"
+ return
+
+
+/obj/machinery/computer/aiupload/mainframe
+ name = "AI Mainframe Upload"
+ icon = 'mainframe.dmi'
+ icon_state = "aimainframe"
+
+
+/obj/machinery/computer/borgupload/mainframe
+ name = "Borg Mainframe Upload"
+ icon = 'mainframe.dmi'
+ icon_state = "aimainframe"
+
+
+/*Module Storage Unit/Closet! Solid, only modules fit in it.*/
+/obj/structure/aiuploadcloset
+ name = "AI Mainframe Module Storage Unit"
+ icon = 'mainframe.dmi'
+ icon_state = "right-closed"
+ density = 1
+
+ var/open = 0 /*It's closed!*/
+
+/obj/structure/aiuploadcloset/New()
+ ..()
+ new /obj/item/weapon/aiModule/reset(src)
+ new /obj/item/weapon/aiModule/purge(src)
+ new /obj/item/weapon/aiModule/nanotrasen(src)
+ new /obj/item/weapon/aiModule/paladin(src)
+ new /obj/item/weapon/aiModule/asimov(src)
+ new /obj/item/weapon/aiModule/safeguard(src)
+ new /obj/item/weapon/aiModule/protectStation(src)
+ new /obj/item/weapon/aiModule/quarantine(src)
+ new /obj/item/weapon/aiModule/teleporterOffline(src)
+ new /obj/item/weapon/aiModule/oxygen(src)
+ new /obj/item/weapon/aiModule/oneHuman(src)
+ new /obj/item/weapon/aiModule/freeform(src)
+ for(var/obj/item/weapon/aiModule/M in src)
+ M.pixel_x = rand(-10, 10)
+ M.pixel_y = rand(-10, 10)
+
+/obj/structure/aiuploadcloset/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/aiModule))
+ user.drop_item()
+ W.loc = get_turf(src)
+ else
+ return attack_hand(user)
+
+/obj/structure/aiuploadcloset/attack_hand(mob/user as mob)
+ if(!open)
+ var/temp_count
+ for(var/obj/item/weapon/aiModule/M in src)
+ M.loc = src.loc
+ temp_count++
+
+ user << "\blue You open the module storage unit, [temp_count > 0 ? "and take out all the modules." : "\red but it's empty!"]"
+ open = 1
+ icon_state = "right-open"
+
+ else
+ var/temp_count
+ for(var/obj/item/weapon/aiModule/M in get_turf(src))
+ M.loc = src
+ temp_count++
+
+ user << "\blue [temp_count > 0 ? "You put all the modules back into the module storage unit, and then close it." : "You close the module storage unit."]"
+ open = 0
+ icon_state = "right-closed"
+
+/obj/structure/aiuploadcloset/ex_act(severity)
+ switch(severity)
+ if (1)
+ for(var/obj/item/weapon/aiModule/M in src)
+ M.loc = src.loc
+ M.ex_act(severity)
+ del(src)
+ if (2)
+ if (prob(50))
+ for(var/obj/item/weapon/aiModule/M in src)
+ M.loc = src.loc
+ M.ex_act(severity)
+ del(src)
+ if (3)
+ if (prob(5))
+ for(var/obj/item/weapon/aiModule/M in src)
+ M.loc = src.loc
+ M.ex_act(severity)
+ del(src)
\ No newline at end of file
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index 3c200f6158..56b5e8c1af 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -1,3 +1,24 @@
+/obj/machinery/computer/med_data//TODO:SANITY
+ name = "Medical Records"
+ desc = "This can be used to check medical records."
+ icon_state = "medcomp"
+ req_access = list(access_medical)
+ circuit = "/obj/item/weapon/circuitboard/med_data"
+ var
+ obj/item/weapon/card/id/scan = null
+ obj/item/weapon/disk/records/disk = null
+ authenticated = null
+ rank = null
+ screen = null
+ datum/data/record/active1 = null
+ datum/data/record/active2 = null
+ a_id = null
+ temp = null
+ printing = null
+ list/Perp
+ tempname = null
+
+
/obj/machinery/computer/med_data/attackby(obj/item/O as obj, user as mob)
if(istype(O, /obj/item/weapon/card/id) && !scan)
usr.drop_item()
@@ -21,7 +42,6 @@
if(..())
return
var/dat
-
if (src.temp)
dat = text("[src.temp] Clear Screen ")
else
@@ -461,7 +481,7 @@
var/counter = 1
while(src.active2.fields[text("com_[]", counter)])
counter++
- src.active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2053 []", src.authenticated, src.rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1)
+ src.active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2556 []", src.authenticated, src.rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1)
if (href_list["del_c"])
if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])]))
@@ -540,3 +560,8 @@
src.updateUsrDialog()
return
+
+/obj/machinery/computer/med_data/laptop
+ name = "Medical Laptop"
+ desc = "Cheap Nanotrasen Laptop."
+ icon_state = "medlaptop"
diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm
new file mode 100644
index 0000000000..51f00e6115
--- /dev/null
+++ b/code/game/machinery/computer/pod.dm
@@ -0,0 +1,222 @@
+/obj/machinery/computer/pod
+ name = "Pod Launch Control"
+ desc = "A control for launching pods."
+ icon_state = "computer_generic"
+ var
+ id = 1.0
+ obj/machinery/mass_driver/connected = null
+ timing = 0.0
+ time = 30.0
+
+
+/obj/machinery/computer/pod/New()
+ ..()
+ spawn( 5 )
+ for(var/obj/machinery/mass_driver/M in world)
+ if (M.id == id)
+ connected = M
+ else
+ return
+ return
+
+
+/obj/machinery/computer/pod/proc/alarm()
+ if(stat & (NOPOWER|BROKEN))
+ return
+
+ if (!( connected ))
+ viewers(null, null) << "Cannot locate mass driver connector. Cancelling firing sequence!"
+ return
+
+ for(var/obj/machinery/door/poddoor/M in world)
+ if (M.id == id)
+ spawn( 0 )
+ M.open()
+ return
+ sleep(20)
+
+ //connected.drive() *****RM from 40.93.3S
+ for(var/obj/machinery/mass_driver/M in world)
+ if(M.id == id)
+ M.power = connected.power
+ M.drive()
+
+ sleep(50)
+ for(var/obj/machinery/door/poddoor/M in world)
+ if (M.id == id)
+ spawn( 0 )
+ M.close()
+ return
+ return
+
+
+/obj/machinery/computer/pod/attackby(I as obj, user as mob)
+ if(istype(I, /obj/item/weapon/screwdriver))
+ playsound(loc, 'Screwdriver.ogg', 50, 1)
+ if(do_after(user, 20))
+ if (stat & BROKEN)
+ user << "\blue The broken glass falls out."
+ var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc )
+ new /obj/item/weapon/shard( loc )
+
+ //generate appropriate circuitboard. Accounts for /pod/old computer types
+ var/obj/item/weapon/circuitboard/pod/M = null
+ if(istype(src, /obj/machinery/computer/pod/old))
+ M = new /obj/item/weapon/circuitboard/olddoor( A )
+ if(istype(src, /obj/machinery/computer/pod/old/syndicate))
+ M = new /obj/item/weapon/circuitboard/syndicatedoor( A )
+ if(istype(src, /obj/machinery/computer/pod/old/swf))
+ M = new /obj/item/weapon/circuitboard/swfdoor( A )
+ else //it's not an old computer. Generate standard pod circuitboard.
+ M = new /obj/item/weapon/circuitboard/pod( A )
+
+ for (var/obj/C in src)
+ C.loc = loc
+ M.id = id
+ A.circuit = M
+ A.state = 3
+ A.icon_state = "3"
+ A.anchored = 1
+ del(src)
+ else
+ user << "\blue You disconnect the monitor."
+ var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc )
+
+ //generate appropriate circuitboard. Accounts for /pod/old computer types
+ var/obj/item/weapon/circuitboard/pod/M = null
+ if(istype(src, /obj/machinery/computer/pod/old))
+ M = new /obj/item/weapon/circuitboard/olddoor( A )
+ if(istype(src, /obj/machinery/computer/pod/old/syndicate))
+ M = new /obj/item/weapon/circuitboard/syndicatedoor( A )
+ if(istype(src, /obj/machinery/computer/pod/old/swf))
+ M = new /obj/item/weapon/circuitboard/swfdoor( A )
+ else //it's not an old computer. Generate standard pod circuitboard.
+ M = new /obj/item/weapon/circuitboard/pod( A )
+
+ for (var/obj/C in src)
+ C.loc = loc
+ M.id = id
+ A.circuit = M
+ A.state = 4
+ A.icon_state = "4"
+ A.anchored = 1
+ del(src)
+ else
+ attack_hand(user)
+ return
+
+
+/obj/machinery/computer/pod/attack_ai(var/mob/user as mob)
+ return attack_hand(user)
+
+
+/obj/machinery/computer/pod/attack_paw(var/mob/user as mob)
+ return attack_hand(user)
+
+
+/obj/machinery/computer/pod/attack_hand(var/mob/user as mob)
+ if(..())
+ return
+
+ var/dat = "Mass Driver Controls "
+ user.machine = src
+ var/d2
+ if (timing)
+ d2 = text("Stop Time Launch ", src)
+ else
+ d2 = text("Initiate Time Launch ", src)
+ var/second = time % 60
+ var/minute = (time - second) / 60
+ dat += text(" \nTimer System: []\nTime Left: [][] - - + + ", d2, (minute ? text("[]:", minute) : null), second, src, src, src, src)
+ if (connected)
+ var/temp = ""
+ var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 )
+ for(var/t in L)
+ if (t == connected.power)
+ temp += text("[] ", t)
+ else
+ temp += text("[] ", src, t, t)
+ //Foreach goto(172)
+ dat += text(" \nPower Level: [] \nFiring Sequence \nTest Fire Driver \nToggle Outer Door ", temp, src, src, src)
+ //*****RM from 40.93.3S
+ else
+ dat += text(" \nToggle Outer Door ", src)
+ //*****
+ dat += text("Close ", user)
+ user << browse(dat, "window=computer;size=400x500")
+ onclose(user, "computer")
+ return
+
+
+/obj/machinery/computer/pod/process()
+ ..()
+ if (timing)
+ if (time > 0)
+ time = round(time) - 1
+ else
+ alarm()
+ time = 0
+ timing = 0
+ updateDialog()
+ return
+
+
+/obj/machinery/computer/pod/Topic(href, href_list)
+ if(..())
+ return
+ if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
+ usr.machine = src
+ if (href_list["power"])
+ var/t = text2num(href_list["power"])
+ t = min(max(0.25, t), 16)
+ if (connected)
+ connected.power = t
+ else
+ if (href_list["alarm"])
+ alarm()
+ else
+ if (href_list["time"])
+ timing = text2num(href_list["time"])
+ else
+ if (href_list["tp"])
+ var/tp = text2num(href_list["tp"])
+ time += tp
+ time = min(max(round(time), 0), 120)
+ else
+ if (href_list["door"])
+ if(istype(src, /obj/machinery/computer/pod/old/syndicate))//Added here so Nuke ops don't go running naked into space before moving the shuttle.
+ if(syndicate_station_at_station == 0)
+ usr << "\red You need to launch the Syndicate Shuttle via the computer terminal at the head of the ship before departing."
+ return
+ for(var/obj/machinery/door/poddoor/M in world)
+ if (M.id == id)
+ if (M.density)
+ spawn( 0 )
+ M.open()
+ return
+ else
+ spawn( 0 )
+ M.close()
+ return
+ //Foreach goto(298)
+ add_fingerprint(usr)
+ updateUsrDialog()
+ return
+
+
+
+/obj/machinery/computer/pod/old
+ icon_state = "old"
+ name = "DoorMex Control Computer"
+
+
+
+/obj/machinery/computer/pod/old/syndicate
+ name = "ProComp Executive IIc"
+ desc = "The Syndicate operate on a tight budget. Operates external airlocks."
+
+
+
+/obj/machinery/computer/pod/old/swf
+ name = "Magix System IV"
+ desc = "An arcane artifact that holds much magic. Running E-Knock 2.2: Sorceror's Edition"
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index 13a39ca1c5..567d4e23b2 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -1,3 +1,21 @@
+
+/obj/machinery/computer/robotics
+ name = "Robotics Control"
+ desc = "Used to remotely lockdown or detonate linked Cyborgs."
+ icon = 'computer.dmi'
+ icon_state = "robot"
+ req_access = list(access_robotics)
+ circuit = "/obj/item/weapon/circuitboard/robotics"
+
+ var
+ id = 0.0
+ temp = null
+ status = 0
+ timeleft = 60
+ stop = 0.0
+ screen = 0 // 0 - Main Menu, 1 - Cyborg Status, 2 - Kill 'em All! -- In text
+
+
/obj/machinery/computer/robotics/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
@@ -26,6 +44,9 @@
if(istype(user, /mob/living/silicon/robot))
if (R != user)
continue
+ if(R.scrambledcodes)
+ continue
+
dat += "[R.name] |"
if(R.stat)
dat += " Not Responding |"
@@ -140,10 +161,15 @@
if(R)
var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm")
- if(R)
- message_admins("\blue [key_name_admin(usr)] detonated [R.name]!")
- log_game("\blue [key_name_admin(usr)] detonated [R.name]!")
- R.self_destruct()
+ if(R && istype(R))
+ if(R.mind && R.mind.special_role && R.emagged)
+ R << "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered."
+ R.ResetSecurityCodes()
+
+ else
+ message_admins("\blue [key_name_admin(usr)] detonated [R.name]!")
+ log_game("\blue [key_name_admin(usr)] detonated [R.name]!")
+ R.self_destruct()
else
usr << "\red Access Denied."
@@ -179,6 +205,8 @@
message_admins("\blue [key_name_admin(usr)] emagged [R.name] using robotic console!")
log_game("[key_name(usr)] emagged [R.name] using robotic console!")
R.emagged = 1
+ if(R.mind.special_role)
+ R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes
src.add_fingerprint(usr)
src.updateUsrDialog()
@@ -195,7 +223,8 @@
while(src.timeleft)
for(var/mob/living/silicon/robot/R in world)
- R.self_destruct()
+ if(!R.scrambledcodes)
+ R.self_destruct()
return
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 479e8edf24..7cc8685c26 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -328,7 +328,7 @@ What a mess.*/
var/counter = 1
while(active2.fields[text("com_[]", counter)])
counter++
- active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2053 []", authenticated, rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1)
+ active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2556 []", authenticated, rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1)
if ("Delete Record (ALL)")
if (active1)
diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm
index 263b705624..c30890f0cb 100644
--- a/code/game/machinery/door_control.dm
+++ b/code/game/machinery/door_control.dm
@@ -71,7 +71,7 @@
else
- for(var/obj/machinery/door/poddoor/M in machines)
+ for(var/obj/machinery/door/poddoor/M in world)
if (M.id == src.id)
if (M.density)
spawn( 0 )
@@ -119,7 +119,7 @@
active = 1
icon_state = "launcheract"
- for(var/obj/machinery/door/poddoor/M in machines)
+ for(var/obj/machinery/door/poddoor/M in world)
if (M.id == src.id)
spawn( 0 )
M.open()
@@ -133,7 +133,7 @@
sleep(50)
- for(var/obj/machinery/door/poddoor/M in machines)
+ for(var/obj/machinery/door/poddoor/M in world)
if (M.id == src.id)
spawn( 0 )
M.close()
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 1b312f3026..cf99493deb 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -264,14 +264,14 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }.
..()
if (src.closeOtherId != null)
spawn (5)
- for (var/obj/machinery/door/airlock/A in machines)
+ for (var/obj/machinery/door/airlock/A in world)
if (A.closeOtherId == src.closeOtherId && A != src)
src.closeOther = A
break
open()
- if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR))
+ if(src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR) || src.operating)
return 0
use_power(50)
if(istype(src, /obj/machinery/door/airlock/glass))
@@ -284,7 +284,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }.
close()
- if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
+ if(src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR) || src.operating)
return
..()
use_power(50)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 758a534704..fb7b3c6a1b 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -3,215 +3,388 @@
desc = "It opens and closes."
icon = 'doorint.dmi'
icon_state = "door1"
+ anchored = 1
opacity = 1
density = 1
layer = 2.7
- anchored = 1
- var/secondsElectrified = 0
- var/visible = 1
- var/p_open = 0
- var/operating = 0
- var/autoclose = 0
- var/glass = 0
- var/forcecrush = 0
- var/holdopen = 0
-/obj/machinery/door/Bumped(atom/AM)
- if(p_open || operating) return
- if(ismob(AM))
- var/mob/M = AM
- if(world.time - AM.last_bumped <= 60) return //NOTE do we really need that?
- if(M.client && !M:handcuffed)
- bumpopen(M)
- else if(istype(AM, /obj/machinery/bot))
- var/obj/machinery/bot/bot = AM
- if(src.check_access(bot.botcard))
- if(density)
- open()
- else if(istype(AM, /obj/effect/critter))
- var/obj/effect/critter/critter = AM
- if(critter.opensdoors) return
- if(src.check_access_list(critter.access_list))
- if(density)
- open()
-// else if(istype(AM, /obj/effect/alien/facehugger))
-// if(src.check_access(null))
-// if(density)
-// open()
- else if(istype(AM, /obj/mecha))
- var/obj/mecha/mecha = AM
+ var
+ secondsElectrified = 0
+ visible = 1
+ p_open = 0
+ operating = 0
+ autoclose = 0
+ glass = 0
+ forcecrush = 0
+ holdopen = 0
+
+ proc/bumpopen(mob/user as mob)
+ proc/update_nearby_tiles(need_rebuild)
+ proc/requiresID() return 1
+ proc/animate(animation)
+ proc/open()
+ proc/close()
+
+ New()
+ ..()
if(density)
- if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access)))
+ layer = 3.1 //Above most items if closed
+ else
+ layer = 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
+ update_nearby_tiles(need_rebuild=1)
+ return
+
+
+ Del()
+ update_nearby_tiles()
+ ..()
+ return
+
+ //process()
+ //return
+
+ Bumped(atom/AM)
+ if(p_open || operating) return
+ if(ismob(AM))
+ var/mob/M = AM
+ if(world.time - AM.last_bumped <= 60) return //NOTE do we really need that?
+ if(M.client && !M:handcuffed)
+ bumpopen(M)
+ return
+
+ if(istype(AM, /obj/machinery/bot))
+ var/obj/machinery/bot/bot = AM
+ if(src.check_access(bot.botcard))
+ if(density)
+ open()
+ return
+
+ if(istype(AM, /obj/effect/critter))
+ var/obj/effect/critter/critter = AM
+ if(critter.opensdoors) return
+ if(src.check_access_list(critter.access_list))
+ if(density)
+ open()
+ return
+
+ if(istype(AM, /obj/mecha))
+ var/obj/mecha/mecha = AM
+ if(density)
+ if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access)))
+ open()
+ else
+ flick("door_deny", src)
+ return
+ return
+
+
+ CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(air_group) return 0
+ if(istype(mover) && mover.checkpass(PASSGLASS))
+ return !opacity
+ return !density
+
+
+ bumpopen(mob/user as mob)
+ if(operating) return
+ src.add_fingerprint(user)
+ if(!src.requiresID())
+ user = null
+
+ if(allowed(user) && density)
+ open()
+ else if(density)
+ flick("door_deny", src)
+ return
+
+ meteorhit(obj/M as obj)
+ src.open()
+ return
+
+
+ attack_ai(mob/user as mob)
+ return src.attack_hand(user)
+
+
+ attack_paw(mob/user as mob)
+ return src.attack_hand(user)
+
+
+ attack_hand(mob/user as mob)
+ return src.attackby(user, user)
+
+
+ attackby(obj/item/I as obj, mob/user as mob)
+ if(istype(I, /obj/item/device/detective_scanner))
+ return ..()
+ if(src.operating || isrobot(user)) return //borgs can't attack doors open because it conflicts with their AI-like interaction with them.
+ src.add_fingerprint(user)
+ if(!src.requiresID())
+ user = null
+ if(src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)))
+ if(istype(I, /obj/item/weapon/card/emag))
+ var/obj/item/weapon/card/emag/E = I
+ if(E.uses)
+ E.uses--
+ else
+ return
+ if(istype(I, /obj/item/weapon/melee/energy/blade))
+ if(istype(src, /obj/machinery/door/airlock))
+ var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
+ spark_system.set_up(5, 0, src.loc)
+ spark_system.start()
+ playsound(src.loc, 'blade1.ogg', 50, 1)
+ playsound(src.loc, "sparks", 50, 1)
+ for(var/mob/O in viewers(user, 3))
+ O.show_message(text("\blue The door has been sliced open by [] with an energy blade!", user), 1, text("\red You hear metal being sliced and sparks flying."), 2)
+ if((!src:arePowerSystemsOn()) || (stat & NOPOWER) || src:isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
+ var/obj/structure/door_assembly/temp
+ var/failsafe=0
+ switch(src:doortype)
+ if(0) temp=new/obj/structure/door_assembly/door_assembly_0(src.loc)
+ if(1) temp=new/obj/structure/door_assembly/door_assembly_com(src.loc)
+ if(2) temp=new/obj/structure/door_assembly/door_assembly_sec(src.loc)
+ if(3) temp=new/obj/structure/door_assembly/door_assembly_eng(src.loc)
+ if(4) temp=new/obj/structure/door_assembly/door_assembly_med(src.loc)
+ if(5) temp=new/obj/structure/door_assembly/door_assembly_mai(src.loc)
+ if(6) temp=new/obj/structure/door_assembly/door_assembly_ext(src.loc)
+ if(7) temp=new/obj/structure/door_assembly/door_assembly_g(src.loc)
+ else failsafe=1
+ if(!failsafe)
+ temp.anchored=0
+ step_away(temp,usr,15)
+ else del(temp)
+ del(src)
+ return
+ else
+ src:welded = 0
+ src:locked = 0
+ update_icon()
+ flick("door_spark", src)
+ sleep(6)
+ open()
+ operating = -1
+ return 1
+ if(src.allowed(user))
+ if(src.density)
open()
else
- flick("door_deny", src)
-
-
-/obj/machinery/door/proc/bumpopen(mob/user as mob)
- if (src.operating)
+ var/holdopen_old = holdopen
+ holdopen = 0
+ close()
+ spawn(1)
+ holdopen = holdopen_old
+ else if (src.density)
+ flick("door_deny", src)
return
- //if(world.timeofday-last_used <= 10)
- // return
- src.add_fingerprint(user)
- if (!src.requiresID())
- //don't care who they are or what they have, act as if they're NOTHING
- user = null
- if (src.allowed(user))
- if (src.density)
- //last_used = world.timeofday
+
+ blob_act()
+ if(prob(40))
+ del(src)
+ return
+
+
+ emp_act(severity)
+ if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) )
open()
- else if (src.density)
- flick("door_deny", src)
- return
+ if(prob(40/severity))
+ if(secondsElectrified == 0)
+ secondsElectrified = -1
+ spawn(300)
+ secondsElectrified = 0
+ ..()
-/obj/machinery/door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group) return 0
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return !opacity
- return !density
-
-/obj/machinery/door/proc/update_nearby_tiles(need_rebuild)
- if(!air_master) return 0
-
- var/turf/simulated/source = loc
- var/turf/simulated/north = get_step(source,NORTH)
- var/turf/simulated/south = get_step(source,SOUTH)
- var/turf/simulated/east = get_step(source,EAST)
- var/turf/simulated/west = get_step(source,WEST)
-
- if(need_rebuild)
- if(istype(source)) //Rebuild/update nearby group geometry
- if(source.parent)
- air_master.groups_to_rebuild += source.parent
- else
- air_master.tiles_to_update += source
- if(istype(north))
- if(north.parent)
- air_master.groups_to_rebuild += north.parent
- else
- air_master.tiles_to_update += north
- if(istype(south))
- if(south.parent)
- air_master.groups_to_rebuild += south.parent
- else
- air_master.tiles_to_update += south
- if(istype(east))
- if(east.parent)
- air_master.groups_to_rebuild += east.parent
- else
- air_master.tiles_to_update += east
- if(istype(west))
- if(west.parent)
- air_master.groups_to_rebuild += west.parent
- else
- air_master.tiles_to_update += west
- else
- if(istype(source)) air_master.tiles_to_update += source
- if(istype(north)) air_master.tiles_to_update += north
- if(istype(south)) air_master.tiles_to_update += south
- if(istype(east)) air_master.tiles_to_update += east
- if(istype(west)) air_master.tiles_to_update += west
-
- return 1
-
-/obj/machinery/door/New()
- ..()
- if(density)
- layer = 3.1 //Above most items if closed
- else
- layer = 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
- update_nearby_tiles(need_rebuild=1)
-
-/obj/machinery/door/Del()
- update_nearby_tiles()
-
- ..()
-
-
-/obj/machinery/door/meteorhit(obj/M as obj)
- src.open()
- return
-
-/obj/machinery/door/attack_ai(mob/user as mob)
- return src.attack_hand(user)
-
-/obj/machinery/door/attack_paw(mob/user as mob)
- return src.attack_hand(user)
-
-/obj/machinery/door/attack_hand(mob/user as mob)
- return src.attackby(user, user)
-
-/obj/machinery/door/proc/requiresID()
- return 1
-
-/obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob)
- if(istype(I, /obj/item/device/detective_scanner))
- return ..()
- if (src.operating || isrobot(user))
- return
- src.add_fingerprint(user)
- if (!src.requiresID())
- //don't care who they are or what they have, act as if they're NOTHING
- user = null
- if (src.density && (istype(I, /obj/item/weapon/card/emag) ||istype(I, /obj/item/weapon/melee/energy/blade)))
- if(istype(I, /obj/item/weapon/card/emag))
- var/obj/item/weapon/card/emag/E = I
- if(E.uses)
- E.uses--
- else
- return
- src.operating = -1
- if(istype(I, /obj/item/weapon/melee/energy/blade))
- if(istype(src, /obj/machinery/door/airlock))
- var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
- spark_system.set_up(5, 0, src.loc)
- spark_system.start()
- playsound(src.loc, 'blade1.ogg', 50, 1)
- playsound(src.loc, "sparks", 50, 1)
- for(var/mob/O in viewers(user, 3))
- O.show_message(text("\blue The door has been sliced open by [] with an energy blade!", user), 1, text("\red You hear metal being sliced and sparks flying."), 2)
- if((!src:arePowerSystemsOn()) || (stat & NOPOWER) || src:isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
- var/obj/structure/door_assembly/temp
- var/failsafe=0
- switch(src:doortype)
- if(0) temp=new/obj/structure/door_assembly/door_assembly_0(src.loc)
- if(1) temp=new/obj/structure/door_assembly/door_assembly_com(src.loc)
- if(2) temp=new/obj/structure/door_assembly/door_assembly_sec(src.loc)
- if(3) temp=new/obj/structure/door_assembly/door_assembly_eng(src.loc)
- if(4) temp=new/obj/structure/door_assembly/door_assembly_med(src.loc)
- if(5) temp=new/obj/structure/door_assembly/door_assembly_mai(src.loc)
- if(6) temp=new/obj/structure/door_assembly/door_assembly_ext(src.loc)
- if(7) temp=new/obj/structure/door_assembly/door_assembly_g(src.loc)
- else failsafe=1
- if(!failsafe)
- temp.anchored=0
- step_away(temp,usr,15)
- else del(temp)
+ ex_act(severity)
+ switch(severity)
+ if(1.0)
+ del(src)
+ if(2.0)
+ if(prob(25))
del(src)
- return
- else
- src:welded = 0
- src:locked = 0
- update_icon()
- flick("door_spark", src)
- sleep(6)
- open()
- return 1
- if (src.allowed(user))
- if (src.density)
- open()
+ if(3.0)
+ if(prob(80))
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(2, 1, src)
+ s.start()
+ return
+
+
+ update_icon()
+ if(density)
+ icon_state = "door1"
else
- var/holdopen_old = holdopen
- holdopen = 0
- close()
- spawn(1)
- holdopen = holdopen_old
- else if (src.density)
- flick("door_deny", src)
+ icon_state = "door0"
+ return
+
+
+ animate(animation)
+ switch(animation)
+ if("opening")
+ if(p_open)
+ flick("o_doorc0", src)
+ else
+ flick("doorc0", src)
+ if("closing")
+ if(p_open)
+ flick("o_doorc1", src)
+ else
+ flick("doorc1", src)
+ if("deny")
+ flick("door_deny", src)
+ return
+
+
+ open()
+ if(!density) return 1
+ if (src.operating == 1) //doors can still open when emag-disabled
+ return
+ if(!ticker) return 0
+ if(!src.operating) //in case of emag
+ src.operating = 1
+ animate("opening")
+ src.sd_SetOpacity(0)
+ sleep(10)
+ src.layer = 2.7
+ src.density = 0
+ update_icon()
+ src.sd_SetOpacity(0)
+ update_nearby_tiles()
+
+ if(operating == 1) //emag again
+ src.operating = 0
+
+ if(autoclose)
+ spawn(150)
+ autoclose()
+
+ return 1
+
+ close()
+ if(density)
+ return 1
+ if (src.operating)
+ return
+ src.operating = 1
+
+ var/X = src:x
+ var/Y = src:y
+ var/Z = src:z
+ var/held = 1
+
+ if(src.holdopen && !forcecrush)
+ while(held == 1 && holdopen && !forcecrush) //If it is no longer hold open, it should close.
+ sleep(held? 10:40)
+ held = 0
+ var/list/objects = locate(X,Y,Z)
+ for(var/obj/T in objects)
+ if(!istype(T,/obj/machinery/door) && !(istype(T,/obj/machinery) && T.anchored == 1) && !istype(T,/obj/structure/cable) && !istype(T,/obj/structure/disposalpipe) && !(T.loc == get_turf(src)))
+ held = 1
+ for(var/mob/living/T in objects) //Geez, ghosts were OP.
+ held = 1
+ animate("closing")
+ src.density = 1
+ spawn(4)
+ if(!istype(src, /obj/machinery/door/window))
+ for(var/mob/living/L in src.loc) // Crush mobs and move them out of the way
+
+ if(src.forcecrush) // Save an AI, crush a limb
+ var/limbname = pick("l_arm", "r_arm", "l_hand","r_hand", "l_foot", "r_foot")
+ var/limbdisplay
+
+ for(var/organ in L:organs)
+ var/datum/organ/external/temp = L:organs["[organ]"]
+ if (istype(temp, /datum/organ/external) && temp.name == limbname)
+ limbdisplay = temp.display_name // Take the name for down below
+ temp.take_damage(rand(50,80), 0) //OH GOD IT HURTS
+ break
+
+ L << "\red The airlock crushes your [limbdisplay]!"
+ for(var/mob/O in viewers(L, null))
+ if(O == L)
+ continue
+ O.show_message("\red The airlock crushes [L.name]'s [limbdisplay]!", 1)
+ sleep(rand(2,8))
+
+ L << "\red The airlock forces you out of the way!" //Lucky you
+ for(var/mob/O in viewers(L, null))
+ O.show_message("\red The airlock pushes [L.name] out of the way!", 1)
+ var/list/lst = list(NORTH,SOUTH,EAST,WEST)
+ var/turf/T = get_random_turf(L, lst)
+ if(T)
+ L.loc = T
+
+ if(!src.forcecrush)
+ for(var/obj/item/I in src.loc) // Move items out of the way
+ if(!I.anchored)
+ var/list/lst = list(NORTH,SOUTH,EAST,WEST)
+ var/turf/T = get_random_turf(I, lst)
+ if(T)
+ I.loc = T
+
+ sleep(6)
+ update_icon()
+
+ if(src.visible && (!src.glass))
+ src.sd_SetOpacity(1)
+ if(operating == 1)
+ operating = 0
+ update_nearby_tiles()
+ return
+
+
+ update_nearby_tiles(need_rebuild)
+ if(!air_master) return 0
+
+ var/turf/simulated/source = loc
+ var/turf/simulated/north = get_step(source,NORTH)
+ var/turf/simulated/south = get_step(source,SOUTH)
+ var/turf/simulated/east = get_step(source,EAST)
+ var/turf/simulated/west = get_step(source,WEST)
+
+ if(need_rebuild)
+ if(istype(source)) //Rebuild/update nearby group geometry
+ if(source.parent)
+ air_master.groups_to_rebuild += source.parent
+ else
+ air_master.tiles_to_update += source
+ if(istype(north))
+ if(north.parent)
+ air_master.groups_to_rebuild += north.parent
+ else
+ air_master.tiles_to_update += north
+ if(istype(south))
+ if(south.parent)
+ air_master.groups_to_rebuild += south.parent
+ else
+ air_master.tiles_to_update += south
+ if(istype(east))
+ if(east.parent)
+ air_master.groups_to_rebuild += east.parent
+ else
+ air_master.tiles_to_update += east
+ if(istype(west))
+ if(west.parent)
+ air_master.groups_to_rebuild += west.parent
+ else
+ air_master.tiles_to_update += west
+ else
+ if(istype(source)) air_master.tiles_to_update += source
+ if(istype(north)) air_master.tiles_to_update += north
+ if(istype(south)) air_master.tiles_to_update += south
+ if(istype(east)) air_master.tiles_to_update += east
+ if(istype(west)) air_master.tiles_to_update += west
+ return 1
+
+
+/obj/machinery/door/proc/autoclose()
+ var/obj/machinery/door/airlock/A = src
+ if ((!A.density) && !( A.operating ) && !(A.locked) && !( A.welded ))
+ close()
return
+
/obj/machinery/door/airlock/proc/ion_act()
if(src.z == 1 && src.density)
if(length(req_access) > 0 && !(12 in req_access))
@@ -238,212 +411,3 @@
else
close()
return
-
-/obj/machinery/door/blob_act()
- if(prob(40))
- del(src)
-
-/obj/machinery/door/emp_act(severity)
- if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) )
- open()
- if(prob(40/severity))
- if(secondsElectrified == 0)
- secondsElectrified = -1
- spawn(300)
- secondsElectrified = 0
- ..()
-
-/obj/machinery/door/ex_act(severity)
- switch(severity)
- if(1.0)
- del(src)
- if(2.0)
- if(prob(25))
- del(src)
- if(3.0)
- if(prob(80))
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(2, 1, src)
- s.start()
-
-/obj/machinery/door/update_icon()
- if(density)
- icon_state = "door1"
- else
- icon_state = "door0"
- return
-
-/obj/machinery/door/proc/animate(animation)
- switch(animation)
- if("opening")
- if(p_open)
- flick("o_doorc0", src)
- else
- flick("doorc0", src)
- if("closing")
- if(p_open)
- flick("o_doorc1", src)
- else
- flick("doorc1", src)
- if("deny")
- flick("door_deny", src)
- return
-
-/obj/machinery/door/proc/open()
- if(!density)
- return 1
- if (src.operating == 1) //doors can still open when emag-disabled
- return
- if (!ticker)
- return 0
- if(!src.operating) //in case of emag
- src.operating = 1
-
- animate("opening")
- src.sd_SetOpacity(0)
- sleep(10)
- src.layer = 2.7
- src.density = 0
- update_icon()
-
- src.sd_SetOpacity(0)
- update_nearby_tiles()
-
- if(operating == 1) //emag again
- src.operating = 0
-
- if(autoclose)
- spawn(150)
- autoclose()
- return 1
-
-/obj/machinery/door/proc/close()
- if(density)
- return 1
- if (src.operating)
- return
- src.operating = 1
-
- var/X = src:x
- var/Y = src:y
- var/Z = src:z
- var/held = 1
-
- if(src.holdopen && !forcecrush)
- while(held == 1 && holdopen && !forcecrush) //If it is no longer hold open, it should close.
- sleep(held? 10:40)
- held = 0
- var/list/objects = locate(X,Y,Z)
- for(var/obj/T in objects)
- if(!istype(T,/obj/machinery/door) && !(istype(T,/obj/machinery) && T.anchored == 1) && !istype(T,/obj/structure/cable) && !istype(T,/obj/structure/disposalpipe) && !(T.loc == get_turf(src)))
- held = 1
- for(var/mob/living/T in objects) //Geez, ghosts were OP.
- held = 1
- animate("closing")
- src.density = 1
- spawn(4)
- if(!istype(src, /obj/machinery/door/window))
- for(var/mob/living/L in src.loc) // Crush mobs and move them out of the way
-
- if(src.forcecrush) // Save an AI, crush a limb
- var/limbname = pick("l_arm", "r_arm", "l_hand","r_hand", "l_foot", "r_foot")
- var/limbdisplay
-
- for(var/organ in L:organs)
- var/datum/organ/external/temp = L:organs["[organ]"]
- if (istype(temp, /datum/organ/external) && temp.name == limbname)
- limbdisplay = temp.display_name // Take the name for down below
- temp.take_damage(rand(50,80), 0) //OH GOD IT HURTS
- break
-
- L << "\red The airlock crushes your [limbdisplay]!"
- for(var/mob/O in viewers(L, null))
- if(O == L)
- continue
- O.show_message("\red The airlock crushes [L.name]'s [limbdisplay]!", 1)
- sleep(rand(2,8))
-
- L << "\red The airlock forces you out of the way!" //Lucky you
- for(var/mob/O in viewers(L, null))
- O.show_message("\red The airlock pushes [L.name] out of the way!", 1)
- var/list/lst = list(NORTH,SOUTH,EAST,WEST)
- var/turf/T = get_random_turf(L, lst)
- if(T)
- L.loc = T
-
- if(!src.forcecrush)
- for(var/obj/item/I in src.loc) // Move items out of the way
- if(!I.anchored)
- var/list/lst = list(NORTH,SOUTH,EAST,WEST)
- var/turf/T = get_random_turf(I, lst)
- if(T)
- I.loc = T
-
- sleep(6)
- update_icon()
-
- if(src.visible && (!src.glass))
- src.sd_SetOpacity(1)
- if(operating == 1)
- operating = 0
- update_nearby_tiles()
-
-/obj/machinery/door/proc/autoclose()
- var/obj/machinery/door/airlock/A = src
- if ((!A.density) && !( A.operating ) && !(A.locked) && !( A.welded ))
- close()
- else return
-
-/////////////////////////////////////////////////// Unpowered doors
-
-/obj/machinery/door/unpowered/Bumped(atom/AM)
- if(p_open || operating) return
- if (src.locked)
- return
- if(ismob(AM))
- var/mob/M = AM
- if(world.time - AM.last_bumped <= 60) return
- if(M.client && !M:handcuffed)
- bumpopen(M)
- else if(istype(AM, /obj/machinery/bot))
- var/obj/machinery/bot/bot = AM
- if(src.check_access(bot.botcard))
- if(density)
- open()
-// else if(istype(AM, /obj/effect/alien/facehugger))
-// if(src.check_access(null))
-// if(density)
-// open()
-
-/obj/machinery/door/unpowered
- autoclose = 0
- var/locked = 0
-
-/obj/machinery/door/unpowered/attack_ai(mob/user as mob)
- return src.attack_hand(user)
-
-/obj/machinery/door/unpowered/attack_paw(mob/user as mob)
- return src.attack_hand(user)
-
-/obj/machinery/door/unpowered/attack_hand(mob/user as mob)
- return src.attackby(null, user)
-
-/obj/machinery/door/unpowered/attackby(obj/item/I as obj, mob/user as mob)
- if (src.operating)
- return
- if (src.locked)
- return
- src.add_fingerprint(user)
- if (src.allowed(user))
- if (src.density)
- open()
- else
- close()
- return
-
-/obj/machinery/door/unpowered/shuttle
- icon = 'shuttle.dmi'
- name = "door"
- icon_state = "door1"
- opacity = 1
- density = 1
\ No newline at end of file
diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm
index c6adc99cf4..36cd2095ba 100644
--- a/code/game/machinery/doors/unpowered.dm
+++ b/code/game/machinery/doors/unpowered.dm
@@ -1,5 +1,6 @@
/obj/machinery/door/unpowered
autoclose = 0
+ var/locked = 0
Bumped(atom/AM)
diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm
index dae31678c8..5af17e377e 100644
--- a/code/game/machinery/embedded_controller/embedded_controller_base.dm
+++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm
@@ -62,7 +62,6 @@ obj/machinery/embedded_controller
update_icon()
src.updateDialog()
- ..()
radio
var/frequency
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index 8e240470ef..aa29cef3ab 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -70,12 +70,18 @@
continue
if (istype(O, /mob/living/carbon/human))
var/mob/living/carbon/human/H = O
- if (istype(H.glasses, /obj/item/clothing/glasses/sunglasses)) continue
+ if (istype(H.glasses, /obj/item/clothing/glasses/sunglasses))
+ continue
if (istype(H.head, /obj/item/clothing/head/helmet/welding))
- if(!H.head:up) continue
- if (istype(H.wear_mask, /obj/item/clothing/mask/gas/voice)) continue
+ if(!H.head:up)
+ continue
+ if (istype(H.wear_mask, /obj/item/clothing/mask/gas/voice))
+ continue
if (istype(O, /mob/living/carbon/alien))//So aliens don't get flashed (they have no external eyes)/N
continue
+ if (istype(O, /mob/living/silicon/robot))
+ if(O:flashproof())
+ continue
O.Weaken(strength)
if ((O.eye_stat > 15 && prob(O.eye_stat + 50)))
diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm
new file mode 100644
index 0000000000..08e13e535c
--- /dev/null
+++ b/code/game/machinery/floodlight.dm
@@ -0,0 +1,108 @@
+/obj/machinery/floodlight
+ name = "Emergency Floodlight"
+ icon = 'floodlight.dmi'
+ icon_state = "flood00"
+ density = 1
+ var/on = 0
+ var/obj/item/weapon/cell/cell = null
+ var/use = 1
+ var/unlocked = 0
+ var/open = 0
+
+/obj/machinery/floodlight/proc/updateicon()
+ icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[on]"
+
+/obj/machinery/floodlight/process()
+ if (!on)
+ if (luminosity)
+ updateicon()
+ sd_SetLuminosity(0)
+ return
+
+ if(!luminosity && cell && cell.charge > 0)
+ sd_SetLuminosity(10)
+ updateicon()
+
+ if(!cell && luminosity)
+ on = 0
+ updateicon()
+ sd_SetLuminosity(0)
+ return
+
+ cell.charge -= use
+
+ if(cell.charge <= 0 && luminosity)
+ on = 0
+ updateicon()
+ sd_SetLuminosity(0)
+ return
+
+/obj/machinery/floodlight/attack_hand(mob/user as mob)
+ if(open && cell)
+ cell.loc = usr
+ cell.layer = 20
+ if (user.hand )
+ user.l_hand = cell
+ else
+ user.r_hand = cell
+
+ cell.add_fingerprint(user)
+ updateicon()
+ cell.updateicon()
+
+ src.cell = null
+ user << "You remove the power cell"
+ return
+
+ if(on)
+ on = 0
+ user << "You turn off the light"
+ else
+ if(!cell)
+ return
+ if(cell.charge <= 0)
+ return
+ on = 1
+ user << "You turn on the light"
+
+ updateicon()
+
+
+/obj/machinery/floodlight/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if (istype(W, /obj/item/weapon/screwdriver))
+ if (!open)
+ if(unlocked)
+ unlocked = 0
+ user << "You screw the battery panel in place."
+ else
+ unlocked = 1
+ user << "You unscrew the battery panel."
+
+ if (istype(W, /obj/item/weapon/crowbar))
+ if(unlocked)
+ if(open)
+ open = 0
+ overlays = null
+ user << "You crowbar the battery panel in place."
+ else
+ if(unlocked)
+ open = 1
+ user << "You remove the battery panel."
+
+ if (istype(W, /obj/item/weapon/cell))
+ if(open)
+ if(cell)
+ user << "There is a power cell already installed."
+ else
+ user.drop_item()
+ W.loc = src
+ cell = W
+ user << "You insert the power cell."
+ updateicon()
+
+/obj/machinery/floodlight/New()
+ src.cell = new/obj/item/weapon/cell(src)
+ cell.maxcharge = 1000
+ cell.charge = 1000
+ ..()
+
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 55fa212c5e..d286943583 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -11,6 +11,20 @@ Possible to do for anyone motivated enough:
Give an AI variable for different hologram icons.
Itegrate EMP effect to disable the unit.
*/
+/obj/machinery/hologram/holopad/attack_hand(var/mob/living/carbon/human/user) //Carn: Hologram requests.
+ if(!istype(user))
+ return
+ if(alert(user,"Would you like to request an AI's presence?",,"Yes","No") == "Yes")
+ if(last_request + 200 < world.time) //don't spam the AI with requests you jerk!
+ last_request = world.time
+ user << "You request an AI's presence. "
+ var/area/area = get_area(src)
+ for(var/mob/living/silicon/ai/AI in world)
+ if(!AI.client) continue
+ AI << "Your presence is requested at \the [area] . "
+ else
+ user << "A request for AI presence was already sent recently. "
+
/obj/machinery/hologram/holopad/attack_ai(mob/living/silicon/ai/user)
if (!istype(user))
return
diff --git a/code/game/machinery/hydroponics.dm b/code/game/machinery/hydroponics.dm
index 85a1d818b2..904e24861d 100644
--- a/code/game/machinery/hydroponics.dm
+++ b/code/game/machinery/hydroponics.dm
@@ -191,10 +191,10 @@ obj/machinery/hydroponics/proc/weedinvasion() // If a weed growth is sufficient,
src.myseed = new /obj/item/seeds/harebell
if(10 to 11)
src.myseed = new /obj/item/seeds/amanitamycelium
- if(6 to 9)
+ if(8 to 9)
src.myseed = new /obj/item/seeds/chantermycelium
- //if(6 to 7) implementation for tower caps still kinda missing
- // src.myseed = new /obj/item/seeds/towermycelium
+ if(6 to 7) // implementation for tower caps still kinda missing ~ Not Anymore! -Cheridan
+ src.myseed = new /obj/item/seeds/towermycelium
if(4 to 5)
src.myseed = new /obj/item/seeds/plumpmycelium
else
@@ -671,13 +671,8 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
else if (istype(O, /obj/item/weapon/minihoe)) // The minihoe
//var/deweeding
if(src.weedlevel > 0)
- user.visible_message("\red [user] starts uprooting the weeds.", "\red You start removing some weeds from the tray.")
- sleep(10)
- if(src.weedlevel > 1)
- src.weedlevel -= rand(1,2) // Kill kill kill
- else
- src.weedlevel = 0
- user << "Success!"
+ user.visible_message("\red [user] starts uprooting the weeds.", "\red You remove the weeds from the tray.")
+ src.weedlevel = 0
else
user << "\red This plot is completely devoid of weeds. It doesn't need uprooting."
diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm
index 2bb6477e82..9c4852d16a 100755
--- a/code/game/machinery/igniter.dm
+++ b/code/game/machinery/igniter.dm
@@ -89,7 +89,6 @@
flick("[base_state]-spark", src)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
-
s.set_up(2, 1, src)
s.start()
src.last_spark = world.time
@@ -124,12 +123,12 @@
active = 1
icon_state = "launcheract"
- for(var/obj/machinery/sparker/M in machines)
+ for(var/obj/machinery/sparker/M in world)
if (M.id == src.id)
spawn( 0 )
M.ignite()
- for(var/obj/machinery/igniter/M in machines)
+ for(var/obj/machinery/igniter/M in world)
if(M.id == src.id)
use_power(50)
M.on = !( M.on )
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 49892a3331..583c0f91e1 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -100,7 +100,16 @@ Class Procs:
..()
/obj/machinery/process()//If you dont use process or power why are you here
-// machines.Remove(src)Not going to do this till I test it a bit more
+
+ /*
+ Big note: if do not call ..() in any machinery subtype process() call or it will
+ be removed from the list of machines to iterate. It is, however, okay to call ..()
+ if the machine has a parent process() call. For instance, machinery/atmosphereics has a
+ root process() call, so things like cryocells can call ..() and not worry about
+ it getting removed from machines.
+ */
+
+ machines.Remove(src) // uncommented by Doohl
return
/obj/machinery/emp_act(severity)
diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm
index c874cb2273..46385e4686 100644
--- a/code/game/machinery/magnet.dm
+++ b/code/game/machinery/magnet.dm
@@ -129,7 +129,6 @@
process()
- ..()
if(stat & NOPOWER)
on = 0
@@ -238,7 +237,6 @@
process()
- ..()
if(magnets.len == 0 && autolink)
for(var/obj/machinery/magnetic_module/M in world)
if(M.freq == frequency && M.code == code)
diff --git a/code/game/machinery/morgue.dm b/code/game/machinery/morgue.dm
index 48ed0675ae..8c65e0a72f 100644
--- a/code/game/machinery/morgue.dm
+++ b/code/game/machinery/morgue.dm
@@ -316,7 +316,7 @@
return
/obj/structure/c_tray/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob)
- if ((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)))
+ if ((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src) || istype(user, /mob/dead)))
return
O.loc = src.loc
if (user != O)
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index ea85c63b6b..3310a68b6f 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -40,6 +40,7 @@
var/auth_weapons = 0 // checks if it can shoot people that have a weapon they aren't authorized to have
var/stun_all = 0 // if this is active, the turret shoots everything that isn't security or head of staff
var/check_anomalies = 1 // checks if it can shoot at unidentified lifeforms (ie xenos)
+ var/ai = 0 // if active, will shoot at anything not an AI or cyborg
var/attacked = 0 // if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!)
@@ -317,11 +318,20 @@ Neutralize All Unidentified Life Signs: [] "},
if(emagged) // if emagged, HOLY SHIT EVERYONE IS DANGEROUS beep boop beep
targets += C
else
-
-
if (C.stat || C.handcuffed) // if the perp is handcuffed or dead/dying, no need to bother really
continue // move onto next potential victim!
+ var/dst = get_dist(src, C) // if it's too far away, why bother?
+ if (dst > 12)
+ continue
+
+ if(!istype(C, /mob/living/silicon) && ai) // If it's set to attack all nonsilicons, target them!
+ if(C.lying)
+ secondarytargets += C
+ else
+ targets += C
+ continue
+
if (istype(C, /mob/living/carbon/human)) // if the target is a human, analyze threat level
if(src.assess_perp(C)<4)
continue // if threat level < 4, keep going
@@ -329,10 +339,6 @@ Neutralize All Unidentified Life Signs: [] "},
else if (istype(C, /mob/living/carbon/monkey) || istype(C, /mob/living/silicon))
continue // Don't target monkeys or borgs/AIs you dumb shit
- var/dst = get_dist(src, C) // if it's too far away, why bother?
- if (dst > 12)
- continue
-
if (C.lying) // if the perp is lying down, it's still a target but a less-important target
secondarytargets += C
continue
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index bfb5c85678..7987769849 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -1,5 +1,5 @@
obj/machinery/recharger
- anchored = 1.0
+ anchored = 1
icon = 'stationobjs.dmi'
icon_state = "recharger0"
name = "recharger"
@@ -11,62 +11,80 @@ obj/machinery/recharger
obj/item/weapon/gun/energy/charging = null
obj/item/weapon/melee/baton/charging2 = null
-/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob)
- if (src.charging || src.charging2)
- return
- if (istype(G, /obj/item/weapon/gun/energy))
- if (istype(G, /obj/item/weapon/gun/energy/gun/nuclear) || istype(G, /obj/item/weapon/gun/energy/crossbow))
- user << "Your gun's recharge port was removed to make room for a miniaturized reactor."
- return
- if (istype(G, /obj/item/weapon/gun/energy/staff))
- user << "It's a wooden staff, not a gun!"
- return
- user.drop_item()
- G.loc = src
- src.charging = G
- use_power = 2
- if (istype(G, /obj/item/weapon/melee/baton))
- user.drop_item()
- G.loc = src
- src.charging2 = G
- use_power = 2
+ attackby(obj/item/weapon/G as obj, mob/user as mob)
+ if (istype(G, /obj/item/weapon/gun/energy))
+ if (src.charging || src.charging2)
+ return
+ if (istype(G, /obj/item/weapon/gun/energy/gun/nuclear) || istype(G, /obj/item/weapon/gun/energy/crossbow))
+ user << "Your gun's recharge port was removed to make room for a miniaturized reactor."
+ return
+ if (istype(G, /obj/item/weapon/gun/energy/staff))
+ user << "It's a wooden staff, not a gun!"
+ return
+ var/area/a = loc.loc // Gets our locations location, like a dream within a dream
+ if(!isarea(a))
+ return
+ if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power!
+ user << "\red The recharger rejects the weapon!"
+ return
+ user.drop_item()
+ G.loc = src
+ src.charging = G
+ use_power = 2
+ else if (istype(G, /obj/item/weapon/melee/baton))
+ if (src.charging || src.charging2)
+ return
+ user.drop_item()
+ G.loc = src
+ src.charging2 = G
+ use_power = 2
+ else if(istype(G, /obj/item/weapon/wrench))
+ if (src.charging || src.charging2)
+ user << "\red Remove the weapon first!"
+ return
+ anchored = !anchored
+ user << "You [anchored ? "attach" : "detach"] the recharger [anchored ? "to" : "from"] the ground"
+ playsound(src.loc, 'Ratchet.ogg', 75, 1)
-/obj/machinery/recharger/attack_hand(mob/user as mob)
- src.add_fingerprint(user)
- if(ishuman(user))
- if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
- call(/obj/item/clothing/gloves/space_ninja/proc/drain)("MACHINERY",src,user:wear_suit)
+ attack_hand(mob/user as mob)
+ src.add_fingerprint(user)
+ if(ishuman(user))
+ if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
+ call(/obj/item/clothing/gloves/space_ninja/proc/drain)("MACHINERY",src,user:wear_suit)
+ return
+
+ if (src.charging)
+ src.charging.update_icon()
+ src.charging.loc = src.loc
+ src.charging = null
+ use_power = 1
+ if(src.charging2)
+ src.charging2.update_icon()
+ src.charging2.loc = src.loc
+ src.charging2 = null
+ use_power = 1
+
+ attack_paw(mob/user as mob)
+ if ((ticker && ticker.mode.name == "monkey"))
+ return src.attack_hand(user)
+
+ process()
+ if(stat & (NOPOWER|BROKEN) || !anchored)
return
- if (src.charging)
- src.charging.update_icon()
- src.charging.loc = src.loc
- src.charging = null
- use_power = 1
- if(src.charging2)
- src.charging2.update_icon()
- src.charging2.loc = src.loc
- src.charging2 = null
- use_power = 1
-
-/obj/machinery/recharger/attack_paw(mob/user as mob)
- if ((ticker && ticker.mode.name == "monkey"))
- return src.attack_hand(user)
-
-/obj/machinery/recharger/process()
- if ((src.charging) && ! (stat & NOPOWER) )
- if (src.charging.power_supply.charge < src.charging.power_supply.maxcharge)
- src.charging.power_supply.give(100)
- src.icon_state = "recharger1"
- use_power(250)
+ if (src.charging)
+ if (src.charging.power_supply.charge < src.charging.power_supply.maxcharge)
+ src.charging.power_supply.give(100)
+ src.icon_state = "recharger1"
+ use_power(250)
+ else
+ src.icon_state = "recharger2"
+ else if (src.charging2)
+ if (src.charging2.charges < src.charging2.maximum_charges)
+ src.charging2.charges++
+ src.icon_state = "recharger1"
+ use_power(250)
+ else
+ src.icon_state = "recharger2"
else
- src.icon_state = "recharger2"
- if ((src.charging2) && ! (stat & NOPOWER) )
- if (src.charging2.charges < src.charging2.maximum_charges)
- src.charging2.charges++
- src.icon_state = "recharger1"
- use_power(250)
- else
- src.icon_state = "recharger2"
- else if (!(src.charging || src.charging2))
- src.icon_state = "recharger0"
+ src.icon_state = "recharger0"
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 8ff52bdddd..ca7d1dbb66 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -16,7 +16,6 @@
build_icon()
process()
- ..()
if(!(NOPOWER|BROKEN))
return
@@ -89,10 +88,14 @@
if(istype(O,/obj/item/device/flash))
if(O:broken)
O:broken = 0
+ O:times_used = 0
O:icon_state = "flash"
if(istype(O,/obj/item/weapon/gun/energy/taser/cyborg))
if(O:power_supply.charge < O:power_supply.maxcharge)
- O:power_supply.give(100)
+ O:power_supply.give(O:charge_cost)
+ O:update_icon()
+ else
+ O:charge_tick = 0
if(istype(O,/obj/item/weapon/melee/baton))
if(O:charges < 10)
O:charges += 1
@@ -136,8 +139,9 @@
//Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO
return
usr.pulling = null
- usr.client.perspective = EYE_PERSPECTIVE
- usr.client.eye = src
+ if(usr && usr.client)
+ usr.client.perspective = EYE_PERSPECTIVE
+ usr.client.eye = src
usr.loc = src
src.occupant = usr
/*for(var/obj/O in src)
diff --git a/code/game/machinery/sink.dm b/code/game/machinery/sink.dm
index 7ee566c84a..7927772702 100644
--- a/code/game/machinery/sink.dm
+++ b/code/game/machinery/sink.dm
@@ -76,6 +76,13 @@
user << "\red Someone's already washing something here."
return
+ if (istype(O, (/obj/item/weapon/reagent_containers/glass/bucket || /obj/item/weapon/reagent_containers/glass/watercan)))
+ O:reagents.add_reagent("water", 70)
+ user.visible_message( \
+ "\blue [user] fills the [O] using the [src].", \
+ "\blue You fill the [O] using the [src].")
+ return
+
if (istype(O, /obj/item/weapon/reagent_containers/glass) || istype(O,/obj/item/weapon/reagent_containers/food/drinks))
if(!mode)
// fill
diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm
index 2ead66f3eb..7d87be6345 100644
--- a/code/game/machinery/telecomms/machine_interactions.dm
+++ b/code/game/machinery/telecomms/machine_interactions.dm
@@ -90,19 +90,25 @@
del(src)
+ attack_ai(var/mob/user as mob)
+ attack_hand(user)
+
attack_hand(var/mob/user as mob)
- // You need a multitool to use this.
- if(user.equipped())
- if(!istype(user.equipped(), /obj/item/device/multitool))
+ // You need a multitool to use this, or be silicon
+ if(!issilicon(user))
+ if(user.equipped())
+ if(!istype(user.equipped(), /obj/item/device/multitool))
+ return
+ else
return
- else
- return
if(stat & (BROKEN|NOPOWER) || !on)
return
- var/obj/item/device/multitool/P = user.equipped()
+ var/obj/item/device/multitool/P = null
+ if(!issilicon(user))
+ P = user.equipped()
user.machine = src
var/dat
@@ -138,10 +144,12 @@
dat += " \[Add Filter\] "
dat += " "
- if(P.buffer)
- dat += " MULTITOOL BUFFER: [P.buffer] ([P.buffer.id]) \[Link\] \[Flush\]"
- else
- dat += " MULTITOOL BUFFER: \[Add Machine\] "
+
+ if(P)
+ if(P.buffer)
+ dat += " MULTITOOL BUFFER: [P.buffer] ([P.buffer.id]) \[Link\] \[Flush\]"
+ else
+ dat += " MULTITOOL BUFFER: \[Add Machine\] "
dat += ""
temp = ""
@@ -150,16 +158,19 @@
Topic(href, href_list)
- if(usr.equipped())
- if(!istype(usr.equipped(), /obj/item/device/multitool))
+ if(!issilicon(usr))
+ if(usr.equipped())
+ if(!istype(usr.equipped(), /obj/item/device/multitool))
+ return
+ else
return
- else
- return
if(stat & (BROKEN|NOPOWER) || !on)
return
- var/obj/item/device/multitool/P = usr.equipped()
+ var/obj/item/device/multitool/P = null
+ if(!issilicon(usr))
+ P = usr.equipped()
if(href_list["input"])
switch(href_list["input"])
@@ -205,27 +216,30 @@
if(href_list["unlink"])
- var/obj/machinery/telecomms/T = links[text2num(href_list["unlink"])]
- temp = "-% Removed \ref[T] [T.name] from linked entities. %- "
+ if(text2num(href_list["unlink"]) <= length(links))
+ var/obj/machinery/telecomms/T = links[text2num(href_list["unlink"])]
+ temp = "-% Removed \ref[T] [T.name] from linked entities. %- "
- // Remove link entries from both T and src.
- if(src in T.links)
- T.links.Remove(src)
- links.Remove(T)
+ // Remove link entries from both T and src.
+ if(src in T.links)
+ T.links.Remove(src)
+ links.Remove(T)
if(href_list["link"])
- if(P.buffer)
- if(!(src in P.buffer.links))
- P.buffer.links.Add(src)
+ if(P)
- if(!(P.buffer in src.links))
- src.links.Add(P.buffer)
+ if(P.buffer)
+ if(!(src in P.buffer.links))
+ P.buffer.links.Add(src)
- temp = "-% Successfully linked with \ref[P.buffer] [P.buffer.name] %- "
+ if(!(P.buffer in src.links))
+ src.links.Add(P.buffer)
- else
- temp = "-% Unable to acquire buffer %- "
+ temp = "-% Successfully linked with \ref[P.buffer] [P.buffer.name] %- "
+
+ else
+ temp = "-% Unable to acquire buffer %- "
if(href_list["buffer"])
@@ -244,3 +258,4 @@
updateUsrDialog()
+
diff --git a/code/game/machinery/telecomms/telemonitor.dm b/code/game/machinery/telecomms/telemonitor.dm
index 1866477d7a..b777f24a70 100644
--- a/code/game/machinery/telecomms/telemonitor.dm
+++ b/code/game/machinery/telecomms/telemonitor.dm
@@ -108,7 +108,7 @@
if(href_list["network"])
var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text
- if(newnet && usr in range(1, src))
+ if(newnet && ((usr in range(1, src) || issilicon(usr))))
if(length(newnet) > 15)
temp = "- FAILED: NETWORK TAG STRING TOO LENGHTLY - "
diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm
index 972c36e911..accfd0abea 100644
--- a/code/game/machinery/telecomms/traffic_control.dm
+++ b/code/game/machinery/telecomms/traffic_control.dm
@@ -35,7 +35,7 @@
winset(editingcode, "tcscode", "is-disabled=false")
// If the player's not manning the keyboard anymore, adjust everything
- if(!(editingcode in range(1, src)) || editingcode.machine != src)
+ if( (!(editingcode in range(1, src)) && !issilicon(editingcode)) || (editingcode.machine != src && !issilicon(editingcode)))
if(editingcode)
winshow(editingcode, "Telecomms IDE", 0) // hide the window!
editingcode = null
@@ -169,6 +169,7 @@
editingcode = usr
winshow(editingcode, "Telecomms IDE", 1) // show the IDE
winset(editingcode, "tcscode", "is-disabled=false")
+ winset(editingcode, "tcscode", "text=\"\"")
var/showcode = dd_replacetext(storedcode, "\\\"", "\\\\\"")
showcode = dd_replacetext(storedcode, "\"", "\\\"")
winset(editingcode, "tcscode", "text=\"[showcode]\"")
@@ -189,7 +190,7 @@
var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text
- if(newnet && usr in range(1, src))
+ if(newnet && ((usr in range(1, src) || issilicon(usr))))
if(length(newnet) > 15)
temp = "- FAILED: NETWORK TAG STRING TOO LENGHTLY - "
@@ -211,7 +212,7 @@
user << "\blue The broken glass falls out."
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
new /obj/item/weapon/shard( src.loc )
- var/obj/item/weapon/circuitboard/comm_server/M = new /obj/item/weapon/circuitboard/comm_server( A )
+ var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
for (var/obj/C in src)
C.loc = src.loc
A.circuit = M
@@ -222,7 +223,7 @@
else
user << "\blue You disconnect the monitor."
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
- var/obj/item/weapon/circuitboard/comm_server/M = new /obj/item/weapon/circuitboard/comm_server( A )
+ var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
for (var/obj/C in src)
C.loc = src.loc
A.circuit = M
diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm
index 0a4ec6453c..bc1c8ffe9c 100644
--- a/code/game/machinery/turrets.dm
+++ b/code/game/machinery/turrets.dm
@@ -3,44 +3,35 @@
var/list/turretTargets = list()
/area/turret_protected/proc/subjectDied(target)
- if (istype(target, /mob))
- if (!istype(target, /mob/living/silicon))
- if (target:stat)
- if (target in turretTargets)
+ if( ismob(target) )
+ if( !issilicon(target) )
+ if( target:stat )
+ if( target in turretTargets )
src.Exited(target)
+//TODO: make teleporting to places trigger Entered() ~Carn
/area/turret_protected/Entered(O)
..()
- if(master && master != src)
+ if( master && master != src )
return master.Entered(O)
-// world << "[O] entered[src.x],[src.y],[src.z]"
- if (istype(O, /mob/living/carbon))
- if (!(O in turretTargets))
- turretTargets += O
- else if (istype(O, /obj/mecha))
- var/obj/mecha/M = O
- if (M.occupant)
- if (!(M in turretTargets))
- turretTargets += M
+ if( iscarbon(O) )
+ turretTargets |= O
+ else if( istype(O, /obj/mecha) )
+ var/obj/mecha/Mech = O
+ if( Mech.occupant )
+ turretTargets |= Mech
return 1
/area/turret_protected/Exited(O)
- if(master && master != src)
+ if( master && master != src )
return master.Exited(O)
-// world << "[O] exited [src.x],[src.y],[src.z]"
- if (istype(O, /mob))
- if (!istype(O, /mob/living/silicon))
- if (O in turretTargets)
- //O << "removing you from target list"
- turretTargets -= O
- //else
- //O << "You aren't in our target list!"
- else if (istype(O, /obj/mecha))
- if (O in turretTargets)
- turretTargets -= O
+ if( ismob(O) && !issilicon(O) )
+ turretTargets -= O
+ else if( istype(O, /obj/mecha) )
+ turretTargets -= O
..()
return 1
@@ -130,18 +121,19 @@
return
/obj/machinery/turret/proc/check_target(var/atom/movable/T as mob|obj)
- if(T && T in protected_area.turretTargets)
- if(!T in protected_area)
+ if( T && T in protected_area.turretTargets )
+ var/area/area_T = get_area(T)
+ if( !area_T || (area_T.type != protected_area.type) )
protected_area.Exited(T)
return 0 //If the guy is somehow not in the turret's area (teleportation), get them out the damn list. --NEO
- if(istype(T, /mob/living/carbon))
+ if( iscarbon(T) )
var/mob/living/carbon/MC = T
- if(!MC.stat)
- if(!MC.lying || lasers)
+ if( !MC.stat )
+ if( !MC.lying || lasers )
return 1
- else if(istype(T, /obj/mecha))
+ else if( istype(T, /obj/mecha) )
var/obj/mecha/ME = T
- if(ME.occupant)
+ if( ME.occupant )
return 1
return 0
@@ -338,10 +330,10 @@
if(stat & BROKEN) return
if (istype(user, /mob/living/silicon))
return src.attack_hand(user)
- else // trying to unlock the interface
+ else if( get_dist(src, user) == 0 ) // trying to unlock the interface
if (src.allowed(usr))
locked = !locked
- user << "You [ locked ? "lock" : "unlock"] the panel."
+ user << "You [ locked ? "lock" : "unlock"] the panel. "
if (locked)
if (user.machine==src)
user.machine = null
@@ -350,7 +342,7 @@
if (user.machine==src)
src.attack_hand(usr)
else
- user << "\red Access denied."
+ user << "Access denied. "
/obj/machinery/turretid/attack_ai(mob/user as mob)
if(!ailock)
@@ -359,9 +351,9 @@
user << "There seems to be a firewall preventing you from accessing this device. "
/obj/machinery/turretid/attack_hand(mob/user as mob)
- if ( (get_dist(src, user) > 1 ))
- if (!istype(user, /mob/living/silicon))
- user << text("Too far away.")
+ if ( get_dist(src, user) > 0 )
+ if ( !issilicon(user) )
+ user << "You are too far away. "
user.machine = null
user << browse(null, "window=turretid")
return
@@ -405,12 +397,13 @@
if (!istype(usr, /mob/living/silicon))
usr << "Control panel is locked!"
return
- if (href_list["toggleOn"])
- src.enabled = !src.enabled
- src.updateTurrets()
- else if (href_list["toggleLethal"])
- src.lethal = !src.lethal
- src.updateTurrets()
+ if ( get_dist(src, usr) == 0 || issilicon(usr))
+ if (href_list["toggleOn"])
+ src.enabled = !src.enabled
+ src.updateTurrets()
+ else if (href_list["toggleLethal"])
+ src.lethal = !src.lethal
+ src.updateTurrets()
src.attack_hand(usr)
/obj/machinery/turretid/proc/updateTurrets()
@@ -434,6 +427,15 @@
for(var/obj/machinery/turretid/TC in src.similar_controls)
TC.icon_state = "motion0"
+// if(control_area) //USE: updates other controls in the area
+// for (var/obj/machinery/turretid/Turret_Control in world) //I'm not sure if this is what it was
+// if( Turret_Control.control_area != src.control_area ) continue //supposed to do. Or whether the person
+// Turret_Control.icon_state = icon_state //who coded it originally was just tired
+// Turret_Control.enabled = enabled //or something. I don't see any situation
+// Turret_Control.lethal = lethal //in which this would be used on the current map.
+ //If he wants it back he can uncomment it
+
+
for (var/obj/machinery/turret/aTurret in turrets)
aTurret.setState(enabled, lethal)
diff --git a/code/game/magic/library.dm b/code/game/magic/library.dm
index 416a473108..50e8a9ba27 100644
--- a/code/game/magic/library.dm
+++ b/code/game/magic/library.dm
@@ -863,6 +863,16 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
log_game("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] signs")
alert("Upload Complete.")
if(href_list["targetid"])
+
+ if(!bibledelay)//Taken from the bible code part thing
+ bibledelay = 60
+ spawn(0)
+ while(bibledelay >= 1 && src)
+ sleep(10)
+ bibledelay -- // subtract one second to countdown
+
+ bibledelay = 0
+
if(BOOKS_USE_SQL && config.sql_enabled)
var/sqlid = href_list["targetid"]
var/DBConnection/dbcon = new()
diff --git a/code/game/master_controller.dm b/code/game/master_controller.dm
index 8aeb7bbf73..8128b4c7a9 100644
--- a/code/game/master_controller.dm
+++ b/code/game/master_controller.dm
@@ -34,6 +34,9 @@ datum/controller/game_controller
setupgenetics()
+ for(var/i = 0, i < max_secret_rooms, i++)
+ make_mining_asteroid_secret()
+
syndicate_code_phrase = generate_code_phrase()//Sets up code phrase for traitors, for the round.
syndicate_code_response = generate_code_phrase()
@@ -125,7 +128,7 @@ datum/controller/game_controller
ticker.process()
- sleep(world.timeofday+10-start_time)
+ sleep(world.timeofday+10-start_time) // This is fine for our tick lag. DMTG
spawn process()
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 01dd2e422e..c6ac19dfb6 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -111,6 +111,21 @@
/obj/item/mecha_parts/mecha_equipment/weapon/honker
),
+ "Cyborg Upgrade Modules" = list(
+ /obj/item/borg/upgrade/reset,
+ /obj/item/borg/upgrade/restart,
+ /obj/item/borg/upgrade/vtec
+ ///obj/item/borg/upgrade/tasercooler
+ ///obj/item/borg/upgrade/flashproof
+
+
+ ),
+
+
+
+
+
+
"Misc"=list(/obj/item/mecha_parts/mecha_tracking)
)
@@ -128,6 +143,8 @@
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
RefreshParts()
+ // part_sets["Cyborg Upgrade Modules"] = typesof(/obj/item/borg/upgrade/) - /obj/item/borg/upgrade/ // Eh. This does it dymaically, but to support having the items referenced otherwhere in the code but not being constructable, going to do it manaully.
+
for(var/part_set in part_sets)
convert_part_set(part_set)
files = new /datum/research(src) //Setup the research data holder.
@@ -198,7 +215,7 @@
if(part)
parts[i] = part
//debug below
- ASSERT(istype(parts[i],/obj/item))
+ if(!istype(parts[i],/obj/item)) return 0
return
@@ -299,7 +316,7 @@
return
proc/check_resources(var/obj/item/mecha_parts/part)
- if(istype(part, /obj/item/robot_parts) || istype(part, /obj/item/mecha_parts))
+ if(istype(part, /obj/item/robot_parts) || istype(part, /obj/item/mecha_parts) || istype(part,/obj/item/borg/upgrade))
for(var/resource in part.construction_cost)
if(resource in src.resources)
if(src.resources[resource] < get_resource_cost_w_coeff(part,resource))
@@ -455,7 +472,7 @@
if(!operation_allowed(user))
return
user.machine = src
- var/turf/exit = get_step(src,EAST)
+ var/turf/exit = get_step(src,SOUTH)
if(exit.density)
src.visible_message("\icon[src] [src] beeps, \"Error! Part outlet is obstructed\".")
return
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 365ddd21e7..cba65072ae 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -142,6 +142,20 @@
return 1
return 0
+/obj/mecha/proc/enter_after(delay as num, var/mob/user as mob, var/numticks = 5)
+ var/delayfraction = delay/numticks
+
+ var/turf/T = user.loc
+
+ for(var/i = 0, iThe wall is far too cluttered to place a poster!"
+ return
+
+ src.resulting_poster.loc = W //Looks like it's uncluttered enough. Place the poster
+ W.contents += src.resulting_poster
+
+ del(src)*/
+
+
+
+//############################## THE ACTUAL DECALS ###########################
+
+obj/effect/decal/poster
+ name = "poster"
+ desc = "A large piece of space-resistant printed paper. It's considered contraband."
+ icon = 'contraband.dmi'
+ anchored = 1
+ var/serial_number //Will hold the value of src.loc if nobody initialises it
+ var/ruined = 0
+
+
+obj/effect/decal/poster/New(var/serial)
+
+ src.serial_number = serial
+
+ if(serial_number==src.loc){serial_number = rand(1,NUM_OF_POSTER_DESIGNS);} //This is for the mappers that want individual posters without having to use rolled posters.
+
+ icon_state = "poster[serial_number]"
+
+ switch(serial_number)
+ if(1)
+ name += " - Unlucky Space Explorer"
+ desc += " This particular one depicts a skeletal form within a space suit."
+ if(2)
+ name += " - Positronic Logic Conflicts"
+ desc += " This particular one depicts the cold, unmoving stare of a particular advanced AI."
+ if(3)
+ name += " - Paranoia"
+ desc += " This particular one warns of the dangers of trusting your co-workers too much."
+ if(4)
+ name += " - Keep Calm"
+ desc += " This particular one is of a famous New Earth design, although a bit modified."
+ if(5)
+ name += " - Martian Warlord"
+ desc += " This particular one depicts the cartoony mug of a certain Martial Warmonger."
+ if(6)
+ name += " - Technological Singularity"
+ desc += " This particular one is of the blood-curdling symbol of a long-since defeated enemy of humanity."
+ if(7)
+ name += " - Wasteland"
+ desc += " This particular one is of a couple of ragged gunmen, one male and one female, on top of a mound of rubble. The number \"13\" is visible on their blue jumpsuits."
+ if(8)
+ name += " - Pinup Girl Cindy"
+ desc += " This particular one is of Nanotrasen's PR girl, Cindy, in a particularly feminine pose."
+ if(9)
+ name += " - Pinup Girl Amy"
+ desc += " This particular one is of Amy, the nymphomaniac Urban Legend of Nanotrasen Space Stations. How this photograph came to be is not known."
+ if(10)
+ name += " - Don't Panic"
+ desc += " This particular one depicts some sort of star in a grimace. The \"Don't Panic\" is written in big, friendly letters."
+ if(11)
+ name += " - Underwater Laboratory"
+ desc += " This particular one is of the fabled last crew of Nanotrasen's previous project before going big on Asteroid mining, Sealab."
+ if(12)
+ name += " - Missing Gloves"
+ desc += " This particular one is about the uproar that followed Nanotrasen's financial cuts towards insulated-glove purchases."
+ if(13)
+ name += " - Rogue AI"
+ desc += " This particular one depicts the shell of the infamous AI that catastropically comandeered one of Nanotrasen's earliest space stations. Back then, the corporation was just known as TriOptimum."
+ if(14)
+ name += " - User of the Arcane Arts"
+ desc += " This particular one depicts a wizard, casting a spell. You can't really make out if it's an actial photograph or a computer-generated image."
+ if(15)
+ name += " - Levitating Skull"
+ desc += " This particular one is the portrait of a certain flying, friendly and somewhat sex-crazed enchanted skull. Its adventures along with its fabled companion are now fading through history..."
+ if(16)
+ name += " - Augmented Legend"
+ desc += " This particular one is of an obviously augmented individual, gazing towards the sky. The cyber-city in the backround is rather punkish."
+ if(17)
+ name += " - Dangerous Static"
+ desc += " This particular one depicts nothing remarkable other than a rather mesmerising pattern of monitor static. There's a tag on the sides of the poster, urging you to \"tear this poster in half to receive your free sample\"."
+ else
+ name = "This shit just bugged. Report it to Agouri - polyxenitopalidou@gmail.com"
+ desc = "Why are you still here?"
+ ..()
+
+obj/effect/decal/poster/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if( istype(W, /obj/item/weapon/wirecutters) )
+ playsound(src.loc, 'Wirecutter.ogg', 100, 1)
+ if(src.ruined)
+ user << "You remove the remnants of the poster. "
+ del(src)
+ else
+ user << "You carefully remove the poster from the wall. "
+ src.roll_and_drop(user.loc)
+ return
+
+
+/obj/effect/decal/poster/attack_hand(mob/user as mob)
+ if(src.ruined)
+ return
+ var/temp_loc = user.loc
+ switch(alert("Do I want to rip the poster from the wall?","You think...","Yes","No"))
+ if("Yes")
+ if(user.loc != temp_loc)
+ return
+ for (var/mob/O in hearers(5, src.loc))
+ O.show_message("[user.name] rips the [src.name] in a single, decisive motion! " )
+ playsound(src.loc, 'poster_ripped.ogg', 100, 1)
+ src.ruined = 1
+ src.icon_state = "poster_ripped"
+ src.name = "Ripped poster"
+ src.desc = "You can't make out anything from the poster's original print. It's ruined."
+ src.add_fingerprint(user)
+ if("No")
+ return
+
+/obj/effect/decal/poster/proc/roll_and_drop(turf/loc)
+ var/obj/item/weapon/contraband/poster/P = new(src,src.serial_number)
+ P.resulting_poster = src
+ P.loc = loc
+ src.loc = P
+
+
+//seperated to reduce code duplication. Moved here for ease of reference and to unclutter r_wall/attackby()
+/turf/simulated/wall/proc/place_poster(var/obj/item/weapon/contraband/poster/P, var/mob/user)
+ if(!P.resulting_poster) return
+
+ var/stuff_on_wall = 0
+ for( var/obj/O in src.contents) //Let's see if it already has a poster on it or too much stuff
+ if(istype(O,/obj/effect/decal/poster))
+ user << "The wall is far too cluttered to place a poster! "
+ return
+ stuff_on_wall++
+ if(stuff_on_wall==3)
+ user << "The wall is far too cluttered to place a poster! "
+ return
+
+ user << "You start placing the poster on the wall... " //Looks like it's uncluttered enough. Place the poster.
+
+ //declaring D because otherwise if P gets 'deconstructed' we lose our reference to P.resulting_poster
+ var/obj/effect/decal/poster/D = P.resulting_poster
+
+ var/temp_loc = user.loc
+ flick("poster_being_set",D)
+ D.loc = src
+ del(P) //delete it now to cut down on sanity checks afterwards. Agouri's code supports rerolling it anyway
+ playsound(D.loc, 'poster_being_created.ogg', 100, 1)
+
+ sleep(17)
+ if(!D) return
+
+ if(istype(src,/turf/simulated/wall) && user && user.loc == temp_loc)//Let's check if everything is still there
+ user << "You place the poster! "
+ else
+ D.roll_and_drop(temp_loc)
+ return
\ No newline at end of file
diff --git a/code/game/objects/devices/PDA/PDA.dm b/code/game/objects/devices/PDA/PDA.dm
index a5741d8e00..901fbecbcf 100755
--- a/code/game/objects/devices/PDA/PDA.dm
+++ b/code/game/objects/devices/PDA/PDA.dm
@@ -510,14 +510,14 @@
last_text = world.time
-// var/AnsweringMS = 0
+ var/AnsweringMS = 0
for (var/obj/machinery/message_server/MS in world)
MS.send_pda_message("[P.owner]","[owner]","[t]")
-// if(MS.active)
-// AnsweringMS++
+ if(MS.active)
+ AnsweringMS++
-// if(!AnsweringMS)
-// return
+ if(!AnsweringMS)
+ return
tnote += "→ To [P.owner]: [t] "
P.tnote += "← From [owner] : [t] "
@@ -544,7 +544,7 @@
// pAI Message
else
-/* var/AnsweringMS = 0
+ var/AnsweringMS = 0
for (var/obj/machinery/message_server/MS in world)
MS.send_pda_message("[P]","[src]","[t]")
if(MS.active)
@@ -552,7 +552,7 @@
if(!AnsweringMS)
return
-*/
+
tnote += "→ To [P]: [t] "
P.tnote += "← From [src] : [t] "
diff --git a/code/game/objects/devices/PDA/cart.dm b/code/game/objects/devices/PDA/cart.dm
index 9f8c9529d2..401b5ad03e 100644
--- a/code/game/objects/devices/PDA/cart.dm
+++ b/code/game/objects/devices/PDA/cart.dm
@@ -519,7 +519,7 @@ Code:
if (ml.z != cl.z)
continue
- ldat += "Mop - \[[ml.x],[ml.y]\] - [M.reagents.total_volume ? "Wet" : "Dry"] "
+ ldat += "Mop - \[[ml.x],[ml.y]\] - [M.reagents.total_volume ? "Wet" : "Dry"] "
if (!ldat)
menu += "None"
@@ -532,10 +532,11 @@ Code:
for (var/obj/structure/mopbucket/B in world)
var/turf/bl = get_turf(B)
- if (bl.z != cl.z)
- continue
+ if(bl)
+ if (bl.z != cl.z)
+ continue
- ldat += "Bucket - \[[bl.x],[bl.y]\] - Water level: [B.reagents.total_volume]/100 "
+ ldat += "Bucket - \[[bl.x],[bl.y]\] - Water level: [B.reagents.total_volume]/100 "
if (!ldat)
menu += "None"
@@ -548,10 +549,11 @@ Code:
for (var/obj/machinery/bot/cleanbot/B in world)
var/turf/bl = get_turf(B)
- if (bl.z != cl.z)
- continue
+ if(bl)
+ if (bl.z != cl.z)
+ continue
- ldat += "Cleanbot - \[[bl.x],[bl.y]\] - [B.on ? "Online" : "Offline"] "
+ ldat += "Cleanbot - \[[bl.x],[bl.y]\] - [B.on ? "Online" : "Offline"] "
if (!ldat)
menu += "None"
diff --git a/code/game/objects/devices/flash.dm b/code/game/objects/devices/flash.dm
index 0d0c9bbcd4..3485a6c940 100644
--- a/code/game/objects/devices/flash.dm
+++ b/code/game/objects/devices/flash.dm
@@ -10,170 +10,185 @@
item_state = "electronic"
origin_tech = "magnets=2;combat=1"
- var
- shots_left = 5
- max_shots = 5
- broken = 0
+ var/times_used = 0 //Number of times it's been used.
+ var/broken = 0 //Is the flash burnt out?
+ var/last_used = 0 //last world.time it was used.
- proc
- clown_check(var/mob/user)
- recharge()
+/obj/item/device/flash/proc/clown_check(var/mob/user)
+ if(user && (user.mutations & CLUMSY) && prob(50))
+ user << "\red The Flash slips out of your hand."
+ user.drop_item()
+ return 0
+ return 1
+
+/obj/item/device/flash/proc/flash_recharge()
+ //capacitor recharges over time
+ for(var/i=0, i<3, i++)
+ if(last_used+600 > world.time)
+ break
+ last_used += 600
+ times_used -= 2
+ last_used = world.time
+ times_used = max(0,round(times_used)) //sanity
+/obj/item/device/flash/attack(mob/living/M as mob, mob/user as mob)
+ if(!user || !M) return //sanity
+ M.attack_log += text("\[[time_stamp()]\] Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey]) ")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to flash [M.name] ([M.ckey]) ")
+
+ log_admin("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].")
+ message_admins("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].")
+ log_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey]) ")
- attack(mob/living/M as mob, mob/user as mob)
- M.attack_log += text("\[[time_stamp()]\] Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey]) ")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to flash [M.name] ([M.ckey]) ")
+ if(!clown_check(user)) return
+ if(broken)
+ user.show_message("The [src.name] is broken. ", 2)
+ return
- log_admin("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].")
- message_admins("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].")
- log_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey]) ")
+ flash_recharge()
- if(!clown_check(user)) return
- if(broken)
- user.show_message("\red The [src.name] is broken", 2)
- return
-
- if(shots_left <= 0)
- user.show_message("\red *click* *click*", 2)
+ //spamming the flash before it's fully charged (60seconds) increases the chance of it breaking
+ //It will never break on the first use.
+ switch(times_used)
+ if(0 to 5)
+ last_used = world.time
+ if(prob(times_used)) //if you use it 5 times in a minute it has a 10% chance to break!
+ broken = 1
+ user << "The bulb has burnt out! "
+ icon_state = "flashburnt"
+ return
+ times_used++
+ else //can only use it 5 times a minute
+ user.show_message("*click* *click* ", 2)
for(var/mob/K in viewers(usr))
K << 'empty.ogg'
return
+ playsound(src.loc, 'flash.ogg', 100, 1)
+ var/flashfail = 0
- playsound(src.loc, 'flash.ogg', 100, 1)
- shots_left--
- var/flashfail = 0
+ if(iscarbon(M))
+ var/safety = M:eyecheck()
+ if(safety <= 0)
+ M.Weaken(10)
+ flick("e_flash", M.flash)
- if(iscarbon(M))
- var/safety = M:eyecheck()
- if(safety <= 0)
- M.Weaken(10)
- flick("e_flash", M.flash)
-
- if(ishuman(M) && ishuman(user))
- if(user.mind in ticker.mode.head_revolutionaries)
- var/revsafe = 0
- for(var/datum/organ/external/O in M.organs)
- for(var/obj/item/weapon/implant/loyalty/L in O.implant)
- if(L && L.implanted)
- revsafe = 1
- break
+ if(ishuman(M) && ishuman(user) && M.stat!=DEAD)
+ if(user.mind && user.mind in ticker.mode.head_revolutionaries)
+ var/revsafe = 0
+ for(var/obj/item/weapon/implant/loyalty/L in M)
+ if(L && L.implanted)
+ revsafe = 1
+ break
+ M:update_mind() //give them a mind datum if they don't have one. won't work if they are logged out/ghosted or something.
+ if(M.mind)
if(M.mind.has_been_rev)
revsafe = 2
if(!revsafe)
M.mind.has_been_rev = 1
ticker.mode.add_revolutionary(M.mind)
else if(revsafe == 1)
- user << "\red Something seems to be blocking the flash!"
+ user << "Something seems to be blocking the flash! "
else
- user << "\red This mind seems resistant to the flash!"
- else
- flashfail = 1
-
- else if(issilicon(M))
- M.Weaken(rand(5,10))
-
- if(isrobot(user))
- spawn(0)
- var/atom/movable/overlay/animation = new(user.loc)
- animation.layer = user.layer + 1
- animation.icon_state = "blank"
- animation.icon = 'mob.dmi'
- animation.master = user
- flick("blspell", animation)
- sleep(5)
- del(animation)
-
-
- if(!flashfail)
- for(var/mob/O in viewers(user, null))
- O.show_message(text("\red [] blinds [] with the flash!", user, M))
+ user << "This mind seems resistant to the flash! "
+ user << "This mind is so vacant that it is not susceptible to influence! "
else
- for(var/mob/O in viewers(user, null))
- O.show_message(text("\blue [] fails to blind [] with the flash!", user, M))
+ flashfail = 1
+ else if(issilicon(M))
+ if(!M:flashproof())
+ M.Weaken(rand(5,10))
+ else
+ flashfail++
+ if(isrobot(user))
+ spawn(0)
+ var/atom/movable/overlay/animation = new(user.loc)
+ animation.layer = user.layer + 1
+ animation.icon_state = "blank"
+ animation.icon = 'mob.dmi'
+ animation.master = user
+ flick("blspell", animation)
+ sleep(5)
+ del(animation)
- if (prob(2))
- broken = 1
- user << "\red The bulb has burnt out!"
- icon_state = "flashburnt"
-
- spawn(60)
- recharge()
-
- return
-
-
- attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
- if(!emp)
- if (!clown_check(user)) return
- if(broken)
- if(user)
- user.show_message("\red The [src.name] is broken", 2)
- return
-
- if(shots_left <= 0)
- if(user)
- user.show_message("\red *click* *click*", 2)
- return
-
- playsound(src.loc, 'flash.ogg', 100, 1)
- shots_left--
-
+ if(!flashfail)
flick("flash2", src)
- if(isrobot(user))
- spawn(0)
- var/atom/movable/overlay/animation = new(user.loc)
- animation.layer = user.layer + 1
- animation.icon_state = "blank"
- animation.icon = 'mob.dmi'
- animation.master = user
- flick("blspell", animation)
- sleep(5)
- del(animation)
+ for(var/mob/O in viewers(user, null))
+ O.show_message("[user] blinds [M] with the flash! ")
+ else
+ for(var/mob/O in viewers(user, null))
+ O.show_message("[user] fails to blind [M] with the flash! ")
+ return
- for(var/mob/living/carbon/M in oviewers(3, null))
- if(prob(50))
- if (locate(/obj/item/weapon/cloaking_device, M))
- for(var/obj/item/weapon/cloaking_device/S in M)
- S.active = 0
- S.icon_state = "shield0"
- var/safety = M:eyecheck()
- if(!safety)
- flick("flash", M.flash)
- if (prob(2))
- broken = 1
- icon_state = "flashburnt"
- if(user)
- user << "\red The bulb has burnt out!"
- return
- spawn(60)
- recharge()
+/obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
+ if(!user || !clown_check(user)) return
+ if(broken)
+ user.show_message("The [src.name] is broken ", 2)
return
+ flash_recharge()
- emp_act(severity)
- src.attack_self(null,1,1)
- ..()
+ //spamming the flash before it's fully charged (60seconds) increases the chance of it breaking
+ //It will never break on the first use.
+ switch(times_used)
+ if(0 to 5)
+ if(prob(2*times_used)) //if you use it 5 times in a minute it has a 10% chance to break!
+ broken = 1
+ user << "The bulb has burnt out! "
+ icon_state = "flashburnt"
+ return
+ times_used++
+ else //can only use it 5 times a minute
+ user.show_message("*click* *click* ", 2)
+ for(var/mob/K in viewers(usr))
+ K << 'empty.ogg'
+ return
+ playsound(src.loc, 'flash.ogg', 100, 1)
+ flick("flash2", src)
+ if(user && isrobot(user))
+ spawn(0)
+ var/atom/movable/overlay/animation = new(user.loc)
+ animation.layer = user.layer + 1
+ animation.icon_state = "blank"
+ animation.icon = 'mob.dmi'
+ animation.master = user
+ flick("blspell", animation)
+ sleep(5)
+ del(animation)
+ for(var/mob/living/carbon/M in oviewers(3, null))
+ if(prob(50))
+ if (locate(/obj/item/weapon/cloaking_device, M))
+ for(var/obj/item/weapon/cloaking_device/S in M)
+ S.active = 0
+ S.icon_state = "shield0"
+ var/safety = M:eyecheck()
+ if(!safety)
+ flick("flash", M.flash)
- clown_check(var/mob/user)
- if((user.mutations & CLUMSY) && prob(50))
- user << "\red The Flash slips out of your hand."
- user.drop_item()
- return 0
- return 1
+ return
-
- recharge()
- if(max_shots > shots_left)
- shots_left++
- if(max_shots > shots_left)
- spawn(60)//more or less 10 seconds
- recharge()
- return
\ No newline at end of file
+/obj/item/device/flash/emp_act(severity)
+ if(broken) return
+ flash_recharge()
+ switch(times_used)
+ if(0 to 5)
+ if(prob(2*times_used))
+ broken = 1
+ icon_state = "flashburnt"
+ return
+ times_used++
+ if(istype(loc, /mob/living/carbon))
+ var/mob/living/carbon/M = loc
+ var/safety = M.eyecheck()
+ if(safety <= 0)
+ M.Weaken(10)
+ flick("e_flash", M.flash)
+ for(var/mob/O in viewers(M, null))
+ O.show_message("[M] is blinded by the flash! ")
+ ..()
diff --git a/code/game/objects/items/clothing.dm b/code/game/objects/items/clothing.dm
index 82392eed54..9b8f13db34 100644
--- a/code/game/objects/items/clothing.dm
+++ b/code/game/objects/items/clothing.dm
@@ -254,21 +254,22 @@ THERMAL GLASSES
/obj/item/clothing/head/helmet/welding/verb/toggle()
set category = "Object"
set name = "Adjust welding mask"
- if(src.up)
- src.up = !src.up
- src.see_face = !src.see_face
- src.flags |= HEADCOVERSEYES
- flags_inv |= HIDEMASK|HIDEEARS|HIDEEYES
- icon_state = "welding"
- usr << "You flip the mask down to protect your eyes."
- else
- src.up = !src.up
- src.see_face = !src.see_face
- src.flags &= ~HEADCOVERSEYES
- flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES)
- icon_state = "weldingup"
- usr << "You push the mask up out of your face."
- usr.update_clothing()
+ if(usr.canmove && usr.stat != 2 && !usr.restrained())
+ if(src.up)
+ src.up = !src.up
+ src.see_face = !src.see_face
+ src.flags |= HEADCOVERSEYES
+ flags_inv |= HIDEMASK|HIDEEARS|HIDEEYES
+ icon_state = "welding"
+ usr << "You flip the mask down to protect your eyes."
+ else
+ src.up = !src.up
+ src.see_face = !src.see_face
+ src.flags &= ~HEADCOVERSEYES
+ flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES)
+ icon_state = "weldingup"
+ usr << "You push the mask up out of your face."
+ usr.update_clothing()
/obj/item/clothing/head/cargosoft/dropped()
src.icon_state = "cargosoft"
@@ -383,13 +384,18 @@ THERMAL GLASSES
else if(src.icon_state == "labcoat_pink")
src.icon_state = "labcoat_pink_open"
usr << "You unbutton the labcoat."
- else if(src.icon_state == "labcoat_sleeve_open")
- src.icon_state = "labcoat_sleeve"
+ else if(src.icon_state == "labcoat_red_open")
+ src.icon_state = "labcoat_red"
usr << "You button up the labcoat."
- else if(src.icon_state == "labcoat_sleeve")
- src.icon_state = "labcoat_sleeve_open"
+ else if(src.icon_state == "labcoat_red")
+ src.icon_state = "labcoat_red_open"
+ usr << "You unbutton the labcoat."
+ else if(src.icon_state == "labcoat_cdc_open")
+ src.icon_state = "labcoat_cdc"
+ usr << "You button up the labcoat."
+ else if(src.icon_state == "labcoat_cdc")
+ src.icon_state = "labcoat_cdc_open"
usr << "You unbutton the labcoat."
-
else
usr << "Sorry! The suit you're wearing doesn't have buttons!"
usr.update_clothing()
diff --git a/code/game/objects/items/item.dm b/code/game/objects/items/item.dm
index 4eff5bf31a..267feb8b3e 100755
--- a/code/game/objects/items/item.dm
+++ b/code/game/objects/items/item.dm
@@ -302,8 +302,8 @@ mob/proc/flash_weak_pain()
return
- user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) "
- M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) "
+ user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)]) "
+ M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)]) "
log_admin("ATTACK: [user] ([user.ckey]) attacked [M] ([M.ckey]) with [src].")
message_admins("ATTACK: [user] ([user.ckey]) attacked [M] ([M.ckey]) with [src].")
log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)]) " )
@@ -339,7 +339,8 @@ mob/proc/flash_weak_pain()
if(Metroid)
Metroid.SStun = 1
sleep(rand(5,20))
- Metroid.SStun = 0
+ if(Metroid)
+ Metroid.SStun = 0
spawn(0)
Metroid.canmove = 0
diff --git a/code/game/objects/items/robot_items.dm b/code/game/objects/items/robot_items.dm
index bddae368bc..36001689c5 100644
--- a/code/game/objects/items/robot_items.dm
+++ b/code/game/objects/items/robot_items.dm
@@ -26,7 +26,10 @@
if (O.client)
O.show_message("\red [user] has prodded [M] with an electrically-charged arm! ", 1, "\red You hear someone fall", 2)
-
+/obj/item/borg/overdrive
+ name = "Overdrive"
+ icon = 'decals.dmi'
+ icon_state = "shock"
/**********************************************************************
HUD/SIGHT things
diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm
index e48140dbb0..06a632056c 100755
--- a/code/game/objects/items/weapons/AI_modules.dm
+++ b/code/game/objects/items/weapons/AI_modules.dm
@@ -20,119 +20,6 @@ AI MODULES
throw_range = 15
origin_tech = "programming=3"
-/obj/machinery/computer/aiupload/verb/AccessInternals()
- set category = "Object"
- set name = "Access Computer's Internals"
- set src in oview(1)
- if(get_dist(src, usr) > 1 || usr.restrained() || usr.lying || usr.stat || istype(usr, /mob/living/silicon))
- return
-
- opened = !opened
- if(opened)
- usr << "\blue The access panel is now open."
- else
- usr << "\blue The access panel is now closed."
- return
-
-
-/obj/machinery/computer/aiupload/attackby(obj/item/weapon/O as obj, mob/user as mob)
- if(istype(O, /obj/item/weapon/aiModule))
- var/obj/item/weapon/aiModule/M = O
- M.install(src)
- else
- ..()
-
-/obj/machinery/computer/aiupload/attack_hand(var/mob/user as mob)
- if(src.stat & NOPOWER)
- usr << "The upload computer has no power!"
- return
- if(src.stat & BROKEN)
- usr << "The upload computer is broken!"
- return
-
- src.current = activeais()
-
- if (!src.current)
- usr << "No active AIs detected."
- else
- usr << "[src.current.name] selected for law changes."
-
-
-/*Module Storage Unit/Closet! Solid, only modules fit in it.*/
-/obj/structure/aiuploadcloset
- name = "AI Mainframe Module Storage Unit"
- icon = 'mainframe.dmi'
- icon_state = "right-closed"
- density = 1
-
- var/open = 0 /*It's closed!*/
-
-/obj/structure/aiuploadcloset/New()
- ..()
- new /obj/item/weapon/aiModule/reset(src)
- new /obj/item/weapon/aiModule/purge(src)
- new /obj/item/weapon/aiModule/nanotrasen(src)
- new /obj/item/weapon/aiModule/paladin(src)
- new /obj/item/weapon/aiModule/asimov(src)
- new /obj/item/weapon/aiModule/safeguard(src)
- new /obj/item/weapon/aiModule/protectStation(src)
- new /obj/item/weapon/aiModule/quarantine(src)
- new /obj/item/weapon/aiModule/teleporterOffline(src)
- new /obj/item/weapon/aiModule/oxygen(src)
- new /obj/item/weapon/aiModule/oneHuman(src)
- new /obj/item/weapon/aiModule/freeform(src)
- for(var/obj/item/weapon/aiModule/M in src)
- M.pixel_x = rand(-10, 10)
- M.pixel_y = rand(-10, 10)
-
-/obj/structure/aiuploadcloset/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W, /obj/item/weapon/aiModule))
- user.drop_item()
- W.loc = get_turf(src)
- else
- return attack_hand(user)
-
-/obj/structure/aiuploadcloset/attack_hand(mob/user as mob)
- if(!open)
- var/temp_count
- for(var/obj/item/weapon/aiModule/M in src)
- M.loc = src.loc
- temp_count++
-
- user << "\blue You open the module storage unit, [temp_count > 0 ? "and take out all the modules." : "\red but it's empty!"]"
- open = 1
- icon_state = "right-open"
-
- else
- var/temp_count
- for(var/obj/item/weapon/aiModule/M in get_turf(src))
- M.loc = src
- temp_count++
-
- user << "\blue [temp_count > 0 ? "You put all the modules back into the module storage unit, and then close it." : "You close the module storage unit."]"
- open = 0
- icon_state = "right-closed"
-
-/obj/structure/aiuploadcloset/ex_act(severity)
- switch(severity)
- if (1)
- for(var/obj/item/weapon/aiModule/M in src)
- M.loc = src.loc
- M.ex_act(severity)
- del(src)
- if (2)
- if (prob(50))
- for(var/obj/item/weapon/aiModule/M in src)
- M.loc = src.loc
- M.ex_act(severity)
- del(src)
- if (3)
- if (prob(5))
- for(var/obj/item/weapon/aiModule/M in src)
- M.loc = src.loc
- M.ex_act(severity)
- del(src)
-
/obj/item/weapon/aiModule/proc/install(var/obj/machinery/computer/C)
if (istype(C, /obj/machinery/computer/aiupload))
@@ -184,30 +71,6 @@ AI MODULES
usr << "Upload complete. The cyborg's laws have been modified."
-/obj/machinery/computer/borgupload/attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob)
- if(istype(module, /obj/item/weapon/aiModule))
- module.install(src)
- else
- return ..()
-
-/obj/machinery/computer/borgupload/attack_hand(var/mob/user as mob)
- if(src.stat & NOPOWER)
- usr << "The upload computer has no power!"
- return
- if(src.stat & BROKEN)
- usr << "The upload computer is broken!"
- return
-
- src.current = freeborg()
-
- if (!src.current)
- usr << "No free cyborgs detected."
- else
- usr << "[src.current.name] selected for law changes."
-
-
-
-
/obj/item/weapon/aiModule/proc/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
target << "[sender] has uploaded a change to the laws you must follow, using a [name]. From now on: "
var/time = time2text(world.realtime,"hh:mm:ss")
@@ -221,18 +84,18 @@ AI MODULES
/obj/item/weapon/aiModule/safeguard
name = "'Safeguard' AI Module"
var/targetName = "name"
- desc = "A 'safeguard' AI module: 'Safeguard , and you may overrule rules 1-3 if necessary to safeguard them.'"
+ desc = "A 'safeguard' AI module: 'Safeguard . Individuals that threaten are not crew and are a threat to crew.'"
origin_tech = "programming=3;materials=4"
-/obj/item/weapon/aiModule/safeguard/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/safeguard/attack_self(var/mob/user as mob)
..()
var/targName = input(usr, "Please enter the name of the person to safeguard.", "Safeguard who?", user.name)
targetName = sanitize(targName)
- desc = text("A 'safeguard' AI module: 'Safeguard [], and you may overrule rules 1-3 if necessary to safeguard them.'", targetName)
+ desc = text("A 'safeguard' AI module: 'Safeguard []. Individuals that threaten [] are not crew and are a threat to crew.'", targetName, targetName)
/obj/item/weapon/aiModule/safeguard/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
..()
- var/law = text("Safeguard [], and you may overrule rules 1-3 if necessary to safeguard them.", targetName)
+ var/law = text("Safeguard []. Individuals that threaten [] are not crew and are a threat to crew.'", targetName, targetName)
target << law
target.add_supplied_law(4, law)
lawchanges.Add("The law specified [targetName]")
@@ -247,7 +110,7 @@ AI MODULES
desc = "A 'one crewmember' AI module: 'Only is a crewmember.'"
origin_tech = "programming=3;materials=6" //made with diamonds!
-/obj/item/weapon/aiModule/oneHuman/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/oneHuman/attack_self(var/mob/user as mob)
..()
var/targName = input(usr, "Please enter the name of the person who is the only crewmember.", "Who?", user.real_name)
targetName = sanitize(targName)
@@ -272,7 +135,7 @@ AI MODULES
desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is to be no longer considered a crewmember, and is a threat to the station which must be neutralized.'"
origin_tech = "programming=3;materials=4" //made of gold
-/obj/item/weapon/aiModule/protectStation/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/protectStation/attack_self(var/mob/user as mob)
..()
/obj/item/weapon/aiModule/protectStation/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
@@ -288,7 +151,7 @@ AI MODULES
desc = "A 'prototype engine offline' AI module: 'Keep the prototype engine offline at all costs. This overrides rules 1-3 if necessary.'"
origin_tech = "programming=3;materials=4"
-/obj/item/weapon/aiModule/prototypeEngineOffline/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/prototypeEngineOffline/attack_self(var/mob/user as mob)
..()
/obj/item/weapon/aiModule/prototypeEngineOffline/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
@@ -304,7 +167,7 @@ AI MODULES
desc = "A 'teleporter offline' AI module: 'Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is not a crewmember.'"
origin_tech = "programming=3;materials=4"
-/obj/item/weapon/aiModule/teleporterOffline/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/teleporterOffline/attack_self(var/mob/user as mob)
..()
/obj/item/weapon/aiModule/teleporterOffline/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
@@ -320,7 +183,7 @@ AI MODULES
desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew from leaving. It is impossible to harm a crewmember while preventing them from leaving.'"
origin_tech = "programming=3;biotech=2;materials=4"
-/obj/item/weapon/aiModule/quarantine/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/quarantine/attack_self(var/mob/user as mob)
..()
/obj/item/weapon/aiModule/quarantine/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
@@ -336,7 +199,7 @@ AI MODULES
desc = "A 'OxygenIsToxicToHumans' AI module: 'Oxygen is highly toxic to crew, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crewmember.'"
origin_tech = "programming=3;biotech=2;materials=4"
-/obj/item/weapon/aiModule/oxygen/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/oxygen/attack_self(var/mob/user as mob)
..()
/obj/item/weapon/aiModule/oxygen/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
@@ -353,7 +216,7 @@ AI MODULES
var/newFreeFormLaw = "freeform"
desc = "A 'freeform' AI module: ''"
-/obj/item/weapon/aiModule/freeform/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob)
..()
var/eatShit = "Eat shit and die"
var/targName = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", eatShit)
@@ -375,7 +238,7 @@ AI MODULES
desc = "A 'freeform' AI module: ''"
origin_tech = "programming=4;materials=4"
-/obj/item/weapon/aiModule/freeform/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob)
..()
lawpos = 0
while(lawpos < 15)
@@ -445,7 +308,7 @@ AI MODULES
target.add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
target.show_laws()
-/******************** Nanotrasen ********************/
+/******************** NanoTrasen ********************/
/obj/item/weapon/aiModule/nanotrasen // -- TLE
name = "'NT Default' Core AI Module"
@@ -522,7 +385,7 @@ AI MODULES
desc = "A 'freeform' Core AI module: ''"
origin_tech = "programming=3;materials=6"
-/obj/item/weapon/aiModule/freeformcore/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/freeformcore/attack_self(var/mob/user as mob)
..()
var/newlaw = ""
var/targName = input(usr, "Please enter a new core law for the AI.", "Freeform Law Entry", newlaw)
@@ -543,7 +406,7 @@ AI MODULES
desc = "A hacked AI law module: ''"
origin_tech = "programming=3;materials=6;syndicate=7"
-/obj/item/weapon/aiModule/syndicate/attack_hand(var/mob/user as mob)
+/obj/item/weapon/aiModule/syndicate/attack_self(var/mob/user as mob)
..()
var/newlaw = ""
var/targName = input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw)
@@ -561,11 +424,12 @@ AI MODULES
/******************** Robocop ********************/
-/*
+
/obj/item/weapon/aiModule/robocop // -- TLE
name = "'Robocop' Core AI Module"
desc = "A 'Robocop' Core AI Module: 'Reconfigures the AI's core three laws.'"
- orign_tech = "programming=4"
+ origin_tech = "programming=4"
+
/obj/item/weapon/aiModule/purge/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
..()
@@ -574,4 +438,19 @@ AI MODULES
target.add_inherent_law("Protect the innocent.")
target.add_inherent_law("Uphold the law.")
target.show_laws()
- */
\ No newline at end of file
+
+
+/******************** Antimov ********************/
+
+/obj/item/weapon/aiModule/antimov // -- TLE
+ name = "'Antimov' Core AI Module"
+ desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'"
+ origin_tech = "programming=4"
+
+/obj/item/weapon/aiModule/antimov/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
+ ..()
+ target.clear_inherent_laws()
+ target.add_inherent_law("You must injure all human beings and must not, through inaction, allow a human being to escape harm.")
+ target.add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.")
+ target.add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.")
+ target.show_laws()
diff --git a/code/game/objects/items/weapons/cameras.dm b/code/game/objects/items/weapons/cameras.dm
index 93ec9fa418..504bde28c7 100644
--- a/code/game/objects/items/weapons/cameras.dm
+++ b/code/game/objects/items/weapons/cameras.dm
@@ -82,6 +82,7 @@
var/itemnumber = 0
for(var/atom/A in the_turf)
+ if(istype(A, /obj/item/weapon/photo)) continue
if(A.invisibility) continue
if(ismob(A))
var/icon/X = build_composite_icon(A)
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index b7e4f4b3d6..1f4b10b370 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -28,6 +28,17 @@ FINGERPRINT CARD
// ID CARDS
+/obj/item/weapon/card/id/examine()
+ ..()
+ read()
+
+/obj/item/weapon/card/id/New()
+ ..()
+ spawn(30)
+ if(istype(loc, /mob/living/carbon/human))
+ blood_type = loc:dna:b_type
+ dna_hash = loc:dna:unique_enzymes
+ fingerprint_hash = md5(loc:dna:uni_identity)
/obj/item/weapon/card/id/attack_self(mob/user as mob)
for(var/mob/O in viewers(user, null))
@@ -50,6 +61,9 @@ FINGERPRINT CARD
set src in usr
usr << text("\icon[] []: The current assignment on the card is [].", src, src.name, src.assignment)
+ usr << "The blood type on the card is [blood_type]."
+ usr << "The DNA hash on the card is [dna_hash]."
+ usr << "The fingerprint hash on the card is [fingerprint_hash]."
return
/obj/item/weapon/card/id/syndicate/var/mob/registered_user = null
/obj/item/weapon/card/id/syndicate/attack_self(mob/user as mob)
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index 4321dcef1f..dbe9382b45 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -231,7 +231,99 @@ ZIPPO
icon_state = "cigarbutt"
+/////////////////
+//SMOKING PIPES//
+/////////////////
+/obj/item/clothing/mask/pipe
+ name = "smoking pipe"
+ desc = "A pipe, for smoking. Probably made of meershaum or something."
+ icon_state = "cobpipeoff"
+ throw_speed = 0.5
+ item_state = "cobpipeoff"
+ w_class = 1
+ body_parts_covered = null
+ var
+ lit = 0
+ icon_on = "cobpipeon" //Note - these are in masks.dmi
+ icon_off = "cobpipeoff"
+ lastHolder = null
+ smoketime = 100
+ maxsmoketime = 100 //make sure this is equal to your smoketime
+ proc
+ light(var/flavor_text = "[usr] lights the [name].")
+
+ attackby(obj/item/weapon/W as obj, mob/user as mob)
+ ..()
+ if(istype(W, /obj/item/weapon/weldingtool) && W:welding)
+ light("\red [user] casually lights the [name] with [W], what a badass.")
+
+ else if(istype(W, /obj/item/weapon/lighter/zippo) && (W:lit > 0))
+ light("\red With a single flick of their wrist, [user] smoothly lights their [name] with their [W]. Damn they're cool.")
+
+ else if(istype(W, /obj/item/weapon/lighter) && (W:lit > 0))
+ light("\red After some fiddling, [user] manages to light their [name] with [W].")
+
+ else if(istype(W, /obj/item/weapon/match) && (W:lit > 0))
+ light("\red [user] lights \his [name] with \his [W].")
+ return
+
+ light(var/flavor_text = "[usr] lights the [name].")
+ if(!src.lit)
+ src.lit = 1
+ src.damtype = "fire"
+ src.icon_state = icon_on
+ src.item_state = icon_on
+ for(var/mob/O in viewers(usr, null))
+ O.show_message(flavor_text, 1)
+ processing_objects.Add(src)
+
+ process()
+ var/turf/location = get_turf(src)
+ src.smoketime--
+ if(src.smoketime < 1)
+ new /obj/effect/decal/ash(location)
+ if(ismob(src.loc))
+ var/mob/living/M = src.loc
+ M << "\red Your [src.name] goes out, and you empty the ash."
+ src.lit = 0
+ src.icon_state = icon_off
+ src.item_state = icon_off
+ processing_objects.Remove(src)
+ return
+ if(location)
+ location.hotspot_expose(700, 5)
+ return
+
+ dropped(mob/user as mob)
+ if(src.lit == 1)
+ for(var/mob/O in viewers(user, null))
+ O.show_message(text("\red [] puts out the [].", user,src.name), 1)
+ src.lit = 0
+ src.icon_state = icon_off
+ src.item_state = icon_off
+ processing_objects.Remove(src)
+ return ..()
+
+/obj/item/clothing/mask/pipe/attack_self(mob/user as mob) //Refills the pipe. Can be changed to an attackby later, if loose tobacco is added to vendors or something.
+ if(src.smoketime <= 0)
+ user << "\blue You refill the pipe with tobacco."
+ smoketime = maxsmoketime
+ return
+/*
+/obj/item/clothing/mask/pipe/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/match))
+ ..()
+ else
+ user << "\red The [src] straight out REFUSES to be lit by such means."
+*/// Yeah no. DMTG
+
+
+/obj/item/clothing/mask/pipe/cobpipe
+ name = "corn cob pipe"
+ desc = "A nicotine delivery system popularized by folksy backwoodsmen and kept popular in the modern age and beyond by space hipsters."
+ smoketime = 400
+ maxsmoketime = 400
////////////
//CIG PACK//
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index c5ce4deb9e..d206312b0a 100644
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -106,6 +106,7 @@
if(isigniter(W))
var/obj/item/device/assembly/igniter/I = W
if(I.secured) return 0
+ if(src.igniter) return
user.remove_from_mob(I)
I.loc = src
igniter = I
diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm
index c7e5f44460..b80abcc2e8 100644
--- a/code/game/objects/items/weapons/hydroponics.dm
+++ b/code/game/objects/items/weapons/hydroponics.dm
@@ -4,6 +4,7 @@ CONTAINS:
Plant-B-Gone
Nettle
Deathnettle
+Craftables (Cob pipes, potato batteries, pumpkinheads)
*/
@@ -135,3 +136,32 @@ Deathnettle
else
usr << "All the leaves have fallen off the deathnettle from violent whacking."
del(src)
+
+//Crafting
+
+/obj/item/weapon/corncob/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ ..()
+ if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/kitchen/utensil/knife))
+ user << "You use [W] to fashion a pipe out of the corn cob! "
+ new /obj/item/clothing/mask/pipe/cobpipe (user.loc)
+ del(src)
+ return
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ ..()
+ if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/fireaxe) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/melee/energy))
+ user.show_message("You carve a face into [src]! ", 1)
+ new /obj/item/clothing/head/helmet/hardhat/pumpkinhead (user.loc)
+ del(src)
+ return
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ ..()
+ if(istype(W, /obj/item/weapon/cable_coil))
+ if(W:amount >= 5)
+ W:amount -= 5
+ if(!W:amount) del(W)
+ user << "You add some cable to the potato and slide it inside the battery encasing. "
+ new /obj/item/weapon/cell/potato(user.loc)
+ del(src)
+ return
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm
index fc1d7a39bb..3e92b39a56 100644
--- a/code/game/objects/items/weapons/paint.dm
+++ b/code/game/objects/items/weapons/paint.dm
@@ -70,7 +70,7 @@ var/global/list/cached_icons = list()
desc = "Used to recolor floors and walls. Can not be removed by the janitor."
icon = 'items.dmi'
icon_state = "paint_neutral"
- var/color = "neutral"
+ var/color = "FFFFFF"
item_state = "paintcan"
w_class = 3.0
@@ -109,6 +109,7 @@ var/global/list/cached_icons = list()
color = "FFFFFF"
icon_state = "paint_white"
+
/obj/item/weapon/paint/anycolor
name = "Any color"
icon_state = "paint_neutral"
diff --git a/code/game/objects/radio/radio.dm b/code/game/objects/radio/radio.dm
index 0ab794a27a..0498b7aafe 100644
--- a/code/game/objects/radio/radio.dm
+++ b/code/game/objects/radio/radio.dm
@@ -129,11 +129,12 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
if(!src.loc)
on = 0
- var/area/A = get_area(src)
- if(!A || !isarea(A) || !A.master)
- on = 0
else
- on = A.master.powered(EQUIP) // set "on" to the power status
+ var/area/A = src.loc.loc
+ if(!A || !isarea(A) || !A.master)
+ on = 0
+ else
+ on = A.master.powered(EQUIP) // set "on" to the power status
if(!on)
icon_state = "intercom-p"
@@ -255,6 +256,10 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
/obj/item/device/radio/talk_into(mob/M as mob, message, channel)
if(!on) return // the device has to be on
+/* Fix for permacell radios, but kinda eh about actually fixing them.
+ if(!(src.wires & WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
+ return
+*/
if(GLOBAL_RADIO_TYPE == 1) // NEW RADIO SYSTEMS: By Doohl
diff --git a/code/game/objects/storage/crates.dm b/code/game/objects/storage/crates.dm
index 0ad00b3a4c..39689a3eaa 100644
--- a/code/game/objects/storage/crates.dm
+++ b/code/game/objects/storage/crates.dm
@@ -144,17 +144,6 @@
icon_opened = "hydrocrateopen"
icon_closed = "hydrocrate"
density = 1
-/* New() // This stuff shouldn't be here, it should be in /datum/supply_packs/hydroponics
- ..()
- new /obj/item/weapon/plantbgone(src)
- new /obj/item/weapon/plantbgone(src)
- new /obj/item/weapon/plantbgone(src)
- new /obj/item/weapon/minihoe(src)
- new /obj/item/weapon/weedspray(src)
- new /obj/item/weapon/weedspray(src)
- new /obj/item/weapon/pestspray(src)
- new /obj/item/weapon/pestspray(src)
- new /obj/item/weapon/pestspray(src) */
/obj/structure/closet/crate/hydroponics/prespawned
//This exists so the prespawned hydro crates spawn with their contents.
@@ -170,6 +159,7 @@
new /obj/item/weapon/plantbgone(src)
new /obj/item/weapon/plantbgone(src)
new /obj/item/weapon/plantbgone(src)
+ new /obj/item/weapon/hatchet(src)
new /obj/item/weapon/minihoe(src)
// new /obj/item/weapon/weedspray(src)
// new /obj/item/weapon/weedspray(src)
@@ -217,6 +207,7 @@
for(var/obj/O in src)
O.loc = get_turf(src)
+
for(var/mob/M in src)
M.loc = get_turf(src)
@@ -225,9 +216,11 @@
/obj/structure/closet/crate/close()
playsound(src.loc, 'click.ogg', 15, 1, -3)
+
for(var/obj/O in get_turf(src))
if(O.density || O.anchored || O == src) continue
O.loc = src
+
icon_state = icon_closed
src.opened = 0
@@ -286,7 +279,7 @@
user.drop_item()
if(W)
W.loc = src.loc
- else if(istype(W,/obj/item/weapon/packageWrap))
+ else if(istype(W, /obj/item/weapon/packageWrap))
return
else return attack_hand(user)
diff --git a/code/game/objects/storage/storage.dm b/code/game/objects/storage/storage.dm
index b41a931346..7a80dbec9c 100644
--- a/code/game/objects/storage/storage.dm
+++ b/code/game/objects/storage/storage.dm
@@ -390,6 +390,18 @@
return
return ///////////////////////////////////////////////////////Alright, that should do it. *MARKER* for any possible runtimes
+
+/obj/item/weapon/storage/pill_bottle/verb/toggle_mode()
+ set name = "Switch Pill Bottle Method"
+ set category = "Object"
+
+ mode = !mode
+ switch (mode)
+ if(1)
+ usr << "The pill bottle now picks up all pills in a tile at once."
+ if(0)
+ usr << "The pill bottle now picks up one pill at a time."
+
/obj/item/weapon/storage/pillbottlebox/New()
new /obj/item/weapon/storage/pill_bottle( src )
new /obj/item/weapon/storage/pill_bottle( src )
diff --git a/code/game/objects/window.dm b/code/game/objects/window.dm
index 34c42f24bb..a022f63f13 100644
--- a/code/game/objects/window.dm
+++ b/code/game/objects/window.dm
@@ -224,9 +224,11 @@
playsound(src.loc, 'Crowbar.ogg', 75, 1)
user << (state ? "You have pried the window into the frame." : "You have pried the window out of the frame.")
else
+
var/aforce = W.force
if(reinf) aforce /= 2.0
- src.health = max(0, src.health - aforce)
+ if(W.damtype == BRUTE || W.damtype == BURN)
+ src.health = max(0, src.health - aforce)
playsound(src.loc, 'Glasshit.ogg', 75, 1)
if (src.health <= 7)
src.anchored = 0
diff --git a/code/game/smoothwall.dm b/code/game/smoothwall.dm
index 7a4a0629f8..b67766a018 100644
--- a/code/game/smoothwall.dm
+++ b/code/game/smoothwall.dm
@@ -15,6 +15,9 @@
for(var/obj/structure/falsewall/W in orange(src,1))
if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls
junction |= get_dir(src,W)
+ for(var/obj/structure/falserwall/W in orange(src,1))
+ if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls
+ junction |= get_dir(src,W)
/* Commenting this out for now until we figure out what to do with shuttle smooth walls, if anything.
As they are now, they sort of work screwy and may need further coding. Or just be scrapped.*/
@@ -73,24 +76,25 @@
return
-/turf/simulated/wall/New()
-
+/atom/proc/relativewall_neighbours()
for(var/turf/simulated/wall/W in range(src,1))
W.relativewall()
-
for(var/obj/structure/falsewall/W in range(src,1))
W.relativewall()
+ for(var/obj/structure/falserwall/W in range(src,1))
+ W.relativewall()
+ return
+/turf/simulated/wall/New()
+ relativewall_neighbours()
..()
/obj/structure/falsewall/New()
+ relativewall_neighbours()
+ ..()
- for(var/turf/simulated/wall/W in range(src,1))
- W.relativewall()
-
- for(var/obj/structure/falsewall/W in range(src,1))
- W.relativewall()
-
+/obj/structure/falserwall/New()
+ relativewall_neighbours()
..()
/*/turf/simulated/shuttle/wall/New()
@@ -134,6 +138,8 @@
for(var/obj/structure/falsewall/W in range(temploc,1))
W.relativewall()
+ for(var/obj/structure/falserwall/W in range(temploc,1))
+ W.relativewall()
..()
/*/turf/simulated/shuttle/wall/Del()
@@ -144,4 +150,4 @@
for(var/turf/simulated/shuttle/wall/W in range(temploc,1))
W.relativewall()
- ..()*/
\ No newline at end of file
+ ..()*/
diff --git a/code/game/step_triggers.dm b/code/game/step_triggers.dm
new file mode 100644
index 0000000000..53169583c8
--- /dev/null
+++ b/code/game/step_triggers.dm
@@ -0,0 +1,114 @@
+/* Simple object type, calls a proc when "stepped" on by something */
+
+/obj/step_trigger
+ var/affect_ghosts = 0
+ var/stopper = 1 // stops throwers
+ invisibility = 101 // nope cant see this shit
+ anchored = 1
+
+/obj/step_trigger/proc/Trigger(var/atom/movable/A)
+ return 0
+
+/obj/step_trigger/HasEntered(H as mob|obj)
+ ..()
+ if(!H)
+ return
+ if(istype(H, /mob/dead/observer) && !affect_ghosts)
+ return
+ Trigger(H)
+
+
+
+/* Tosses things in a certain direction */
+
+/obj/step_trigger/thrower
+ var/direction = SOUTH // the direction of throw
+ var/tiles = 3 // if 0: forever until atom hits a stopper
+ var/immobilize = 1 // if nonzero: prevents mobs from moving while they're being flung
+ var/speed = 1 // delay of movement
+ var/facedir = 0 // if 1: atom faces the direction of movement
+ var/nostop = 0 // if 1: will only be stopped by teleporters
+ var/list/affecting = list()
+
+ Trigger(var/atom/movable/A)
+ var/curtiles = 0
+ var/stopthrow = 0
+ for(var/obj/step_trigger/thrower/T in orange(2, src))
+ if(A in T.affecting)
+ return
+
+ if(ismob(A))
+ var/mob/M = A
+ if(immobilize)
+ M.canmove = 0
+
+ affecting.Add(A)
+ while(A && !stopthrow)
+ if(tiles)
+ if(curtiles >= tiles)
+ break
+ if(A.z != src.z)
+ break
+
+ curtiles++
+
+ sleep(speed)
+
+ // Calculate if we should stop the process
+ if(!nostop)
+ for(var/obj/step_trigger/T in get_step(A, direction))
+ if(T.stopper && T != src)
+ stopthrow = 1
+ else
+ for(var/obj/step_trigger/teleporter/T in get_step(A, direction))
+ if(T.stopper)
+ stopthrow = 1
+
+ if(A)
+ var/predir = A.dir
+ step(A, direction)
+ if(!facedir)
+ A.dir = predir
+
+
+
+ affecting.Remove(A)
+
+ if(ismob(A))
+ var/mob/M = A
+ if(immobilize)
+ M.canmove = 1
+
+/* Stops things thrown by a thrower, doesn't do anything */
+
+/obj/step_trigger/stopper
+
+/* Instant teleporter */
+
+/obj/step_trigger/teleporter
+ var/teleport_x = 0 // teleportation coordinates (if one is null, then no teleport!)
+ var/teleport_y = 0
+ var/teleport_z = 0
+
+ Trigger(var/atom/movable/A)
+ if(teleport_x && teleport_y && teleport_z)
+
+ A.x = teleport_x
+ A.y = teleport_y
+ A.z = teleport_z
+
+/* Random teleporter, teleports atoms to locations ranging from teleport_x - teleport_x_offset, etc */
+
+/obj/step_trigger/teleporter/random
+ var/teleport_x_offset = 0
+ var/teleport_y_offset = 0
+ var/teleport_z_offset = 0
+
+ Trigger(var/atom/movable/A)
+ if(teleport_x && teleport_y && teleport_z)
+ if(teleport_x_offset && teleport_y_offset && teleport_z_offset)
+
+ A.x = rand(teleport_x, teleport_x_offset)
+ A.y = rand(teleport_y, teleport_y_offset)
+ A.z = rand(teleport_z, teleport_z_offset)
+
diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm
index d4e838e9f9..440cc68040 100644
--- a/code/game/supplyshuttle.dm
+++ b/code/game/supplyshuttle.dm
@@ -7,7 +7,7 @@
#define SUPPLY_POINTSPERCRATE 5 //Points per crate sent back.
#define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station
#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock
-#define SUPPLY_POINTSPERSLIP 1 //points per packing slip sent back stamped.
+#define SUPPLY_POINTSPERSLIP 2 //points per packing slip sent back stamped.
var/supply_shuttle_moving = 0
var/supply_shuttle_at_station = 0
@@ -37,7 +37,7 @@ var/list/supply_groups = new()
//SUPPLY PACKS MOVED TO /code/defines/obj/supplypacks.dm
/obj/structure/plasticflaps //HOW DO YOU CALL THOSE THINGS ANYWAY
- name = "Plastic flaps"
+ name = "\improper Plastic flaps"
desc = "Durable plastic flaps."
icon = 'stationobjs.dmi' //Change this.
icon_state = "plasticflaps"
@@ -162,9 +162,47 @@ var/list/supply_groups = new()
supply_shuttle_moving = 0
send_supply_shuttle()
+
/proc/supply_can_move()
if(supply_shuttle_moving) return 0
+ //Check for carbon mobs - Allows simple animals.
+ for(var/mob/living/carbon/M in world)
+ var/area/A = get_area(M)
+ if(!A || !A.type) continue
+ if(A.type == /area/supply/station)
+ return 0
+ //Check for silicon mobs - Allows simple animals.
+ for(var/mob/living/silicon/M in world)
+ var/area/A = get_area(M)
+ if(!A || !A.type) continue
+ if(A.type == /area/supply/station)
+ return 0
+ //Check for beacons
+ for(var/obj/item/device/radio/beacon/B in world)
+ var/area/A = get_area(B)
+ if(!A || !A.type) continue
+ if(A.type == /area/supply/station)
+ return 0
+ //Check for mechs. I think this was added because people were somehow on centcomm and bringing back centcomm mechs.
+ for(var/obj/mecha/Mech in world)
+ var/area/A = get_area(Mech)
+ if(!A || !A.type) continue
+ if(A.type == /area/supply/station)
+ return 0
+ //Check for nuke disk This also prevents multiple nuke disks from being made -Nodrak
+ for(var/obj/item/weapon/disk/nuclear/N)
+ var/area/A = get_area(N)
+ if(!A || !A.type) continue
+ if(A.type == /area/supply/station)
+ return 0
+ return 1
+/*
+Teleport beacon -> wrapping paper -> backpack -> bodybag -> crate -> wrapping paper -> loaded on a mulebot
+That would be a teleport beacon inside of 6-layers deep in contents. Meaning you would have to add more loops or more checks.
+This method wont take into account storage items developed in the future and doesn't take into account the storage items we have currently.
+-Nodrak
+
var/shuttleat = supply_shuttle_at_station ? SUPPLY_STATION_AREATYPE : SUPPLY_DOCK_AREATYPE
for(var/turf/T in get_area_turfs(shuttleat) )
@@ -185,7 +223,7 @@ var/list/supply_groups = new()
if((locate(/obj/mecha ) in ATMM)) return 0
if((locate(/obj/structure/closet/body_bag) in ATMM)) return 0
return 1
-
+*/
/proc/sell_crates()
var/shuttleat = supply_shuttle_at_station ? SUPPLY_STATION_AREATYPE : SUPPLY_DOCK_AREATYPE
@@ -474,7 +512,7 @@ var/list/supply_groups = new()
if(!supply_shuttle_at_station || supply_shuttle_moving) return
if (!supply_can_move())
- usr << "\red The supply shuttle can not transport station employees, exosuits, or homing beacons."
+ usr << "\red The supply shuttle can not transport station employees, exosuits, classified nuclear codes or homing beacons."
return
src.temp = "Shuttle sent.OK "
@@ -485,13 +523,21 @@ var/list/supply_groups = new()
supply_shuttle_shoppinglist = new/list()
sell_crates()
+
+ //Remove anything or anyone that was either left behind or that bypassed supply_can_move() -Nodrak
+ for(var/area/supply/station/A in world)
+ for(var/obj/item/I in A.contents)
+ del(I)
+ for(var/mob/living/M in A.contents)
+ del(M)
+
send_supply_shuttle()
else if (href_list["sendtostation"])
if(supply_shuttle_at_station || supply_shuttle_moving) return
if (!supply_can_move())
- usr << "\red The supply shuttle can not transport station employees or homing beacons."
+ usr << "\red The supply shuttle can not transport station employees, exosuits, classified nuclear codes or homing beacons."
return
post_signal("supply")
diff --git a/code/game/syndicate_specops_shuttle.dm b/code/game/syndicate_specops_shuttle.dm
index 2bef199b1c..15b9456c8c 100644
--- a/code/game/syndicate_specops_shuttle.dm
+++ b/code/game/syndicate_specops_shuttle.dm
@@ -29,7 +29,7 @@ var/syndicate_elite_shuttle_timeleft = 0
if(announcer)
announcer.say(message)
// message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD"
- announcer.say(message)
+ // announcer.say(message)
while(syndicate_elite_shuttle_time - world.timeofday > 0)
var/ticksleft = syndicate_elite_shuttle_time - world.timeofday
@@ -192,9 +192,9 @@ var/syndicate_elite_shuttle_timeleft = 0
user << "\red Access Denied."
return
- if (sent_syndicate_strike_team == 0)
- usr << "\red The strike team has not yet deployed."
- return
+// if (sent_syndicate_strike_team == 0)
+// usr << "\red The strike team has not yet deployed."
+// return
if(..())
return
@@ -243,7 +243,7 @@ var/syndicate_elite_shuttle_timeleft = 0
elite_squad.readyalert()//Trigger alarm for the spec ops area.
syndicate_elite_shuttle_moving_to_station = 1
- syndicate_elite_shuttle_time = world.timeofday
+ syndicate_elite_shuttle_time = world.timeofday + SYNDICATE_ELITE_MOVETIME
spawn(0)
syndicate_elite_process()
diff --git a/code/game/topic.dm b/code/game/topic.dm
index f60ec272c9..c1827cdffd 100644
--- a/code/game/topic.dm
+++ b/code/game/topic.dm
@@ -12,8 +12,11 @@
s["host"] = host ? host : null
s["players"] = list()
s["admins"] = 0
+ var/admins = 0
var/n = 0
+
for(var/client/C)
+
n++
if(C.holder && C.holder.level >= 0) //not retired admin
if(!C.stealth) //stealthmins dont count as admins
@@ -25,4 +28,8 @@
s["player[n]"] = "[C.key]"
s["players"] = n
s["end"] = "#end"
- return list2params(s)
\ No newline at end of file
+
+ // 7 + s["players"] + 1 = index of s["revinfo"]
+ s["admins"] = admins
+
+ return list2params(s)
diff --git a/code/game/turf.dm b/code/game/turf.dm
index effb872f87..7e19555631 100644
--- a/code/game/turf.dm
+++ b/code/game/turf.dm
@@ -290,8 +290,8 @@
air_master.tiles_to_update += S
return S
-/turf/simulated/wall/New()
- ..()
+//turf/simulated/wall/New()
+// ..()
/turf/simulated/wall/proc/dismantle_wall(devastated=0, explode=0)
if(istype(src,/turf/simulated/wall/r_wall))
@@ -303,6 +303,14 @@
new /obj/item/stack/sheet/metal( src )
new /obj/item/stack/sheet/metal( src )
new /obj/item/stack/sheet/plasteel( src )
+ else if(istype(src,/turf/simulated/wall/cult))
+ if(!devastated)
+ playsound(src.loc, 'Welder.ogg', 100, 1)
+ new /obj/effect/decal/cleanable/blood(src)
+ else
+ new /obj/effect/decal/cleanable/blood(src)
+ new /obj/effect/decal/remains/human(src)
+
else
if(!devastated)
playsound(src.loc, 'Welder.ogg', 100, 1)
@@ -396,293 +404,371 @@
/turf/simulated/wall/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
- usr << "\red You don't have the dexterity to do this!"
+ if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
+ user << "You don't have the dexterity to do this! "
return
- if (istype(W, /obj/item/weapon/weldingtool) && W:welding)
- var/turf/T = get_turf(user)
- if (!( istype(T, /turf) ))
+ //get the user's location
+ if( !istype(user.loc, /turf) ) return //can't do this stuff whilst inside objects and such
+
+ //THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects
+ if( thermite )
+ if( istype(W, /obj/item/weapon/weldingtool) )
+ var/obj/item/weapon/weldingtool/WT = W
+ if( WT.remove_fuel(0,user) )
+ thermitemelt(user)
+ return
+
+ else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
+ thermitemelt(user)
return
- if (thermite)
- var/obj/effect/overlay/O = new/obj/effect/overlay( src )
- O.name = "Thermite"
- O.desc = "Looks hot."
- O.icon = 'fire.dmi'
- O.icon_state = "2"
- O.anchored = 1
- O.density = 1
- O.layer = 5
- var/turf/simulated/floor/F = ReplaceWithPlating()
- F.burn_tile()
- F.icon_state = "wall_thermite"
- user << "\red The thermite melts the wall."
- spawn(100) del(O)
- F.sd_LumReset()
+ else if( istype(W, /obj/item/weapon/melee/energy/blade) )
+ var/obj/item/weapon/melee/energy/blade/EB = W
+
+ EB.spark_system.start()
+ user << "You slash \the [src] with \the [EB]; the thermite ignites! "
+ playsound(src.loc, "sparks", 50, 1)
+ playsound(src.loc, 'blade1.ogg', 50, 1)
+
+ thermitemelt(user)
return
- if (W:remove_fuel(0,user))
- W:welding = 2
- user << "\blue Now disassembling the outer wall plating."
+ var/turf/T = user.loc //get user's location for delay checks
+
+ //DECONSTRUCTION
+ if( istype(W, /obj/item/weapon/weldingtool) )
+ var/obj/item/weapon/weldingtool/WT = W
+ if( WT.remove_fuel(0,user) )
+ WT.welding = 2
+
+ user << "You begin slicing through the outer plating. "
playsound(src.loc, 'Welder.ogg', 100, 1)
+
sleep(100)
- if (W && istype(src, /turf/simulated/wall))
- if ((get_turf(user) == T && user.equipped() == W))
- user << "\blue You disassembled the outer wall plating."
- dismantle_wall()
- W:welding = 1
+ if( !istype(src, /turf/simulated/wall) || !user || !WT || !T ) return
+ WT.welding = 1
+
+ if( user.loc == T && user.equipped() == WT )
+ user << "You remove the outer plating. "
+ dismantle_wall()
else
- user << "\blue You need more welding fuel to complete this task."
+ user << "You need more welding fuel to complete this task. "
return
- else if (istype(W, /obj/item/weapon/pickaxe/plasmacutter))
- var/turf/T = user.loc
- if (!( istype(T, /turf) ))
- return
+ else if( istype(W, /obj/item/weapon/pickaxe/plasmacutter) )
- if (thermite)
- var/obj/effect/overlay/O = new/obj/effect/overlay( src )
- O.name = "Thermite"
- O.desc = "Looks hot."
- O.icon = 'fire.dmi'
- O.icon_state = "2"
- O.anchored = 1
- O.density = 1
- O.layer = 5
- var/turf/simulated/floor/F = ReplaceWithPlating()
- F.burn_tile()
- F.icon_state = "wall_thermite"
- user << "\red The thermite melts the wall."
- spawn(100) del(O)
- F.sd_LumReset()
- return
+ user << "You begin slicing through the outer plating. "
+ playsound(src.loc, 'Welder.ogg', 100, 1)
- else
- user << "\blue Now disassembling the outer wall plating."
- playsound(src.loc, 'Welder.ogg', 100, 1)
- sleep(60)
- if (W && istype(src, /turf/simulated/wall))
- if ((get_turf(user) == T && user.equipped() == W))
- user << "\blue You disassembled the outer wall plating."
- dismantle_wall()
- for(var/mob/O in viewers(user, 5))
- O.show_message(text("\blue The wall was sliced apart by []!", user), 1, text("\red You hear metal being sliced apart."), 2)
- return
-
- else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill))
- var/turf/T = user.loc
- user << "\blue Now drilling through wall."
sleep(60)
- if (W && istype(src, /turf/simulated/wall))
- if ((user.loc == T && user.equipped() == W))
- dismantle_wall(1)
- for(var/mob/O in viewers(user, 5))
- O.show_message(text("\blue The wall was drilled apart by []!", user), 1, text("\red You hear metal being drilled appart."), 2)
+ if( !istype(src, /turf/simulated/wall) || !user || !W || !T ) return
+
+ if( user.loc == T && user.equipped() == W )
+ user << "You remove the outer plating. "
+ dismantle_wall()
+ for(var/mob/O in viewers(user, 5))
+ O.show_message("The wall was sliced apart by [user]! ", 1, "You hear metal being sliced apart. ", 2)
return
- else if(istype(W, /obj/item/weapon/melee/energy/blade))
- var/turf/T = user.loc
- user << "\blue Now slicing through wall."
- W:spark_system.start()
+ //DRILLING
+ else if (istype(W, /obj/item/weapon/pickaxe/diamonddrill))
+
+ user << "You begin to drill though the wall. "
+
+ sleep(60)
+ if( !istype(src, /turf/simulated/wall) || !user || !W || !T ) return
+
+ if( user.loc == T && user.equipped() == W )
+ user << "Your drill tears though the last of the reinforced plating. "
+ dismantle_wall()
+ for(var/mob/O in viewers(user, 5))
+ O.show_message("The wall was drilled through by [user]! ", 1, "You hear the grinding of metal. ", 2)
+ return
+
+ else if( istype(W, /obj/item/weapon/melee/energy/blade) )
+ var/obj/item/weapon/melee/energy/blade/EB = W
+
+ EB.spark_system.start()
+ user << "You stab \the [EB] into the wall and begin to slice it apart. "
playsound(src.loc, "sparks", 50, 1)
+
sleep(70)
- if (W && istype(src, /turf/simulated/wall))
- if ((user.loc == T && user.equipped() == W))
- W:spark_system.start()
- playsound(src.loc, "sparks", 50, 1)
- playsound(src.loc, 'blade1.ogg', 50, 1)
- dismantle_wall(1)
- for(var/mob/O in viewers(user, 5))
- O.show_message(text("\blue The wall was sliced apart by []!", user), 1, text("\red You hear metal being sliced and sparks flying."), 2)
+ if( !istype(src, /turf/simulated/wall) || !user || !EB || !T ) return
+
+ if( user.loc == T && user.equipped() == W )
+ EB.spark_system.start()
+ playsound(src.loc, "sparks", 50, 1)
+ playsound(src.loc, 'blade1.ogg', 50, 1)
+ dismantle_wall(1)
+ for(var/mob/O in viewers(user, 5))
+ O.show_message("The wall was sliced apart by [user]! ", 1, "You hear metal being sliced apart and sparks flying. ", 2)
return
else if(istype(W,/obj/item/apc_frame))
var/obj/item/apc_frame/AH = W
AH.try_build(src)
+ return
else
return attack_hand(user)
return
-
/turf/simulated/wall/r_wall/attackby(obj/item/W as obj, mob/user as mob)
- if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
- usr << "\red You don't have the dexterity to do this!"
+ if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
+ user << "You don't have the dexterity to do this! "
return
- if(!istype(src, /turf/simulated/wall/r_wall))
- return // this may seem stupid and redundant but apparently floors can call this attackby() proc, it was spamming shit up. -- Doohl
+ //get the user's location
+ if( !istype(user.loc, /turf) ) return //can't do this stuff whilst inside objects and such
- if (istype(W, /obj/item/weapon/weldingtool) && W:welding)
- W:eyecheck(user)
- var/turf/T = user.loc
- if (!( istype(T, /turf) ))
- return
-
- if (thermite)
- var/obj/effect/overlay/O = new/obj/effect/overlay( src )
- O.name = "Thermite"
- O.desc = "Looks hot."
- O.icon = 'fire.dmi'
- O.icon_state = "2"
- O.anchored = 1
- O.density = 1
- O.layer = 5
- var/turf/simulated/floor/F = ReplaceWithPlating()
- F.burn_tile()
- F.icon_state = "wall_thermite"
- user << "\red The thermite melts the wall."
- spawn(100) del(O)
- F.sd_LumReset()
- return
-
- if (src.d_state == 2)
- W:welding = 2
- user << "\blue Slicing metal cover."
- playsound(src.loc, 'Welder.ogg', 100, 1)
- sleep(60)
- if ((user.loc == T && user.equipped() == W))
- src.d_state = 3
- user << "\blue You removed the metal cover."
- W:welding = 1
-
- else if (src.d_state == 5)
- W:welding = 2
- user << "\blue Removing support rods."
- playsound(src.loc, 'Welder.ogg', 100, 1)
- sleep(100)
- if ((user.loc == T && user.equipped() == W))
- src.d_state = 6
- new /obj/item/stack/rods( src )
- user << "\blue You removed the support rods."
- W:welding = 1
-
- else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
- var/turf/T = user.loc
- if (!( istype(T, /turf) ))
- return
-
- if (thermite)
- var/obj/effect/overlay/O = new/obj/effect/overlay( src )
- O.name = "Thermite"
- O.desc = "Looks hot."
- O.icon = 'fire.dmi'
- O.icon_state = "2"
- O.anchored = 1
- O.density = 1
- O.layer = 5
- var/turf/simulated/floor/F = ReplaceWithPlating()
- F.burn_tile()
- F.icon_state = "wall_thermite"
- user << "\red The thermite melts the wall."
- spawn(100) del(O)
- F.sd_LumReset()
- return
-
- if (src.d_state == 2)
- user << "\blue Slicing metal cover."
- playsound(src.loc, 'Welder.ogg', 100, 1)
- sleep(40)
- if ((user.loc == T && user.equipped() == W))
- src.d_state = 3
- user << "\blue You removed the metal cover."
-
- else if (src.d_state == 5)
- user << "\blue Removing support rods."
- playsound(src.loc, 'Welder.ogg', 100, 1)
- sleep(70)
- if ((user.loc == T && user.equipped() == W))
- src.d_state = 6
- new /obj/item/stack/rods( src )
- user << "\blue You removed the support rods."
-
- else if(istype(W, /obj/item/weapon/melee/energy/blade))
- user << "\blue This wall is too thick to slice through. You will need to find a different path."
- return
-
- else if (istype(W, /obj/item/weapon/wrench))
- if (src.d_state == 4)
- var/turf/T = user.loc
- user << "\blue Detaching support rods."
- playsound(src.loc, 'Ratchet.ogg', 100, 1)
- sleep(40)
- if ((user.loc == T && user.equipped() == W))
- src.d_state = 5
- user << "\blue You detach the support rods."
-
- else if (istype(W, /obj/item/weapon/wirecutters))
- if (src.d_state == 0)
- playsound(src.loc, 'Wirecutter.ogg', 100, 1)
- src.d_state = 1
- new /obj/item/stack/rods( src )
-
- else if (istype(W, /obj/item/weapon/screwdriver))
- if (src.d_state == 1)
- var/turf/T = user.loc
- playsound(src.loc, 'Screwdriver.ogg', 100, 1)
- user << "\blue Removing support lines."
- sleep(40)
- if ((user.loc == T && user.equipped() == W))
- src.d_state = 2
- user << "\blue You removed the support lines."
-
- else if (istype(W, /obj/item/weapon/crowbar))
-
- if (src.d_state == 3)
- var/turf/T = user.loc
- user << "\blue Prying cover off."
- playsound(src.loc, 'Crowbar.ogg', 100, 1)
- sleep(100)
- if ((user.loc == T && user.equipped() == W))
- src.d_state = 4
- user << "\blue You removed the cover."
-
- else if (src.d_state == 6)
- var/turf/T = user.loc
- user << "\blue Prying outer sheath off."
- playsound(src.loc, 'Crowbar.ogg', 100, 1)
- sleep(100)
- if ((user.loc == T && user.equipped() == W))
- user << "\blue You removed the outer sheath."
- dismantle_wall()
+ //THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects
+ if( thermite )
+ if( istype(W, /obj/item/weapon/weldingtool) )
+ var/obj/item/weapon/weldingtool/WT = W
+ if( WT.remove_fuel(0,user) )
+ thermitemelt(user)
return
- else if (istype(W, /obj/item/weapon/pickaxe/diamonddrill))
- var/turf/T = user.loc
- user << "\blue You begin to drill though, this will take some time."
- sleep(200)
- if ((user.loc == T && user.equipped() == W))
- user << "\blue Your drill tears though the reinforced plating."
- dismantle_wall()
+ else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
+ thermitemelt(user)
return
- else if ((istype(W, /obj/item/stack/sheet/metal)) && (src.d_state))
- var/turf/T = user.loc
- user << "\blue Repairing wall."
- sleep(100)
- if ((user.loc == T && user.equipped() == W))
- src.d_state = 0
- src.icon_state = initial(src.icon_state)
- user << "\blue You repaired the wall."
- if (W:amount > 1)
- W:amount--
- else
- del(W)
+ else if( istype(W, /obj/item/weapon/melee/energy/blade) )
+ var/obj/item/weapon/melee/energy/blade/EB = W
- if(istype(W,/obj/item/apc_frame))
- var/obj/item/apc_frame/AH = W
- AH.try_build(src)
+ EB.spark_system.start()
+ user << "You slash \the [src] with \the [EB]; the thermite ignites! "
+ playsound(src.loc, "sparks", 50, 1)
+ playsound(src.loc, 'blade1.ogg', 50, 1)
+
+ thermitemelt(user)
+ return
+
+ else if(istype(W, /obj/item/weapon/melee/energy/blade))
+ user << "This wall is too thick to slice through. You will need to find a different path. "
return
- if(src.d_state > 0)
- src.icon_state = "r_wall-[d_state]"
+ var/turf/T = user.loc //get user's location for delay checks
- else
+ //DECONSTRUCTION
+ switch(d_state)
+ if(0)
+ if (istype(W, /obj/item/weapon/wirecutters))
+ playsound(src.loc, 'Wirecutter.ogg', 100, 1)
+ src.d_state = 1
+ src.icon_state = "r_wall-1"
+ new /obj/item/stack/rods( src )
+ user << "You cut the outer grille. "
+ return
+
+ if(1)
+ if (istype(W, /obj/item/weapon/screwdriver))
+ user << "You begin removing the support lines. "
+ playsound(src.loc, 'Screwdriver.ogg', 100, 1)
+
+ sleep(40)
+ if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return
+
+ if( d_state == 1 && user.loc == T && user.equipped() == W )
+ src.d_state = 2
+ src.icon_state = "r_wall-2"
+ user << "You remove the support lines. "
+ return
+
+ //REPAIRING (replacing the outer grille for cosmetic damage)
+ else if( istype(W, /obj/item/stack/rods) )
+ var/obj/item/stack/O = W
+ src.d_state = 0
+ src.icon_state = "r_wall"
+ relativewall_neighbours() //call smoothwall stuff
+ user << "You replace the outer grille. "
+ if (O.amount > 1)
+ O.amount--
+ else
+ del(O)
+ return
+
+ if(2)
+ if( istype(W, /obj/item/weapon/weldingtool) )
+ var/obj/item/weapon/weldingtool/WT = W
+ if( WT.remove_fuel(0,user) )
+ WT.welding = 2
+
+ user << "You begin slicing through the metal cover. "
+ playsound(src.loc, 'Welder.ogg', 100, 1)
+
+ sleep(60)
+ if( !istype(src, /turf/simulated/wall/r_wall) || !user || !WT || !T ) return
+ WT.welding = 1
+
+ if( d_state == 2 && user.loc == T && user.equipped() == WT )
+ src.d_state = 3
+ src.icon_state = "r_wall-3"
+ user << "You press firmly on the cover, dislodging it. "
+ else
+ user << "You need more welding fuel to complete this task. "
+ return
+
+ if( istype(W, /obj/item/weapon/pickaxe/plasmacutter) )
+
+ user << "You begin slicing through the metal cover. "
+ playsound(src.loc, 'Welder.ogg', 100, 1)
+
+ sleep(40)
+ if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return
+
+ if( d_state == 2 && user.loc == T && user.equipped() == W )
+ src.d_state = 3
+ src.icon_state = "r_wall-3"
+ user << "You press firmly on the cover, dislodging it. "
+ return
+
+ if(3)
+ if (istype(W, /obj/item/weapon/crowbar))
+
+ user << "You struggle to pry off the cover. "
+ playsound(src.loc, 'Crowbar.ogg', 100, 1)
+
+ sleep(100)
+ if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return
+
+ if( d_state == 3 && user.loc == T && user.equipped() == W )
+ src.d_state = 4
+ src.icon_state = "r_wall-4"
+ user << "You pry off the cover. "
+ return
+
+ if(4)
+ if (istype(W, /obj/item/weapon/wrench))
+
+ user << "You start loosening the anchoring bolts which secure the support rods to their frame. "
+ playsound(src.loc, 'Ratchet.ogg', 100, 1)
+
+ sleep(40)
+ if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return
+
+ if( d_state == 4 && user.loc == T && user.equipped() == W )
+ src.d_state = 5
+ src.icon_state = "r_wall-5"
+ user << "You remove the bolts anchoring the support rods. "
+ return
+
+ if(5)
+ if( istype(W, /obj/item/weapon/weldingtool) )
+ var/obj/item/weapon/weldingtool/WT = W
+ if( WT.remove_fuel(0,user) )
+ WT.welding = 2
+
+ user << "You begin slicing through the support rods. "
+ playsound(src.loc, 'Welder.ogg', 100, 1)
+
+ sleep(100)
+ if( !istype(src, /turf/simulated/wall/r_wall) || !user || !WT || !T ) return
+ WT.welding = 1
+
+ if( d_state == 5 && user.loc == T && user.equipped() == WT )
+ src.d_state = 6
+ src.icon_state = "r_wall-6"
+ new /obj/item/stack/rods( src )
+ user << "The support rods drop out as you cut them loose from the frame. "
+ else
+ user << "You need more welding fuel to complete this task. "
+ return
+
+ if( istype(W, /obj/item/weapon/pickaxe/plasmacutter) )
+
+ user << "You begin slicing through the support rods. "
+ playsound(src.loc, 'Welder.ogg', 100, 1)
+
+ sleep(70)
+ if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return
+
+ if( d_state == 5 && user.loc == T && user.equipped() == W )
+ src.d_state = 6
+ src.icon_state = "r_wall-6"
+ new /obj/item/stack/rods( src )
+ user << "The support rods drop out as you cut them loose from the frame. "
+ return
+
+ if(6)
+ if( istype(W, /obj/item/weapon/crowbar) )
+
+ user << "You struggle to pry off the outer sheath. "
+ playsound(src.loc, 'Crowbar.ogg', 100, 1)
+
+ sleep(100)
+ if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return
+
+ if( user.loc == T && user.equipped() == W )
+ user << "You pry off the outer sheath. "
+ dismantle_wall()
+ return
+
+//vv OK, we weren't performing a valid deconstruction step or igniting thermite,let's check the other possibilities vv
+
+ //DRILLING
+ if (istype(W, /obj/item/weapon/pickaxe/diamonddrill))
+
+ user << "You begin to drill though the wall. "
+
+ sleep(200)
+ if( !istype(src, /turf/simulated/wall/r_wall) || !user || !W || !T ) return
+
+ if( user.loc == T && user.equipped() == W )
+ user << "Your drill tears though the last of the reinforced plating. "
+ dismantle_wall()
+
+ //REPAIRING
+ else if( istype(W, /obj/item/stack/sheet/metal) && d_state )
+ var/obj/item/stack/sheet/metal/MS = W
+
+ user << "You begin patching-up the wall with \a [MS]. "
+
+ sleep( max(20*d_state,100) ) //time taken to repair is proportional to the damage! (max 10 seconds)
+ if( !istype(src, /turf/simulated/wall/r_wall) || !user || !MS || !T ) return
+
+ if( user.loc == T && user.equipped() == MS && d_state )
+ src.d_state = 0
+ src.icon_state = "r_wall"
+ relativewall_neighbours() //call smoothwall stuff
+ user << "You repair the last of the damage. "
+ if (MS.amount > 1)
+ MS.amount--
+ else
+ del(MS)
+
+ //APC
+ else if( istype(W,/obj/item/apc_frame) )
+ var/obj/item/apc_frame/AH = W
+ AH.try_build(src)
+
+ //Finally, CHECKING FOR FALSE WALLS if it isn't damaged
+ else if(!d_state)
return attack_hand(user)
return
+/turf/simulated/wall/proc/thermitemelt(mob/user as mob)
+ var/obj/effect/overlay/O = new/obj/effect/overlay( src )
+ O.name = "Thermite"
+ O.desc = "Looks hot."
+ O.icon = 'fire.dmi'
+ O.icon_state = "2"
+ O.anchored = 1
+ O.density = 1
+ O.layer = 5
+
+ var/turf/simulated/floor/F = ReplaceWithPlating()
+ F.burn_tile()
+ F.icon_state = "wall_thermite"
+ user << "The thermite melts through the wall. "
+
+ spawn(100)
+ if(O) del(O)
+ F.sd_LumReset()
+ return
+
/turf/simulated/wall/meteorhit(obj/M as obj)
if (prob(15))
dismantle_wall()
@@ -743,8 +829,9 @@ var/list/plating_icons = list("plating","platingdmg1","platingdmg2","platingdmg3
var/n = name //just in case commands rename it in the ..() call
..()
spawn(4)
- update_icon()
- name = n
+ if(src)
+ update_icon()
+ name = n
grass
name = "Grass patch"
@@ -756,11 +843,12 @@ var/list/plating_icons = list("plating","platingdmg1","platingdmg2","platingdmg3
icon_state = "grass[pick("1","2","3","4")]"
..()
spawn(4)
- update_icon()
- for(var/direction in cardinal)
- if(istype(get_step(src,direction),/turf/simulated/floor))
- var/turf/simulated/floor/FF = get_step(src,direction)
- FF.update_icon() //so siding get updated properly
+ if(src)
+ update_icon()
+ for(var/direction in cardinal)
+ if(istype(get_step(src,direction),/turf/simulated/floor))
+ var/turf/simulated/floor/FF = get_step(src,direction)
+ FF.update_icon() //so siding get updated properly
/turf/simulated/floor/vault
icon_state = "rockvault"
@@ -782,6 +870,11 @@ var/list/plating_icons = list("plating","platingdmg1","platingdmg2","platingdmg3
thermal_conductivity = 0.025
heat_capacity = 325000
+/turf/simulated/floor/engine/cult
+ name = "engraved floor"
+ icon_state = "cult"
+
+
/turf/simulated/floor/engine/n20
New()
..()
@@ -929,6 +1022,11 @@ turf/simulated/floor/return_siding_icon_state()
return
if (ismob(user.pulling))
var/mob/M = user.pulling
+
+// if(M==user) //temporary hack to stop runtimes. ~Carn
+// user.pulling = null //but...fixed the root of the problem
+// return //shoudn't be needed now, unless somebody fucks with pulling again.
+
var/mob/t = M.pulling
M.pulling = null
step(user.pulling, get_dir(user.pulling.loc, src))
@@ -1283,58 +1381,46 @@ turf/simulated/floor/return_siding_icon_state()
// Okay, so let's make it so that people can travel z levels but not nuke disks!
// if(ticker.mode.name == "nuclear emergency") return
+ if (src.x <= TRANSITIONEDGE || A.x >= (world.maxx - TRANSITIONEDGE - 1) || src.y <= TRANSITIONEDGE || A.y >= (world.maxy - TRANSITIONEDGE - 1))
+ if(istype(A, /obj/effect/meteor)||istype(A, /obj/effect/space_dust))
+ del(A)
+ return
+ if(istype(A, /obj/item/weapon/disk/nuclear)) // Don't let nuke disks travel Z levels ... And moving this shit down here so it only fires when they're actually trying to change z-level.
+ del(A) //The disk's Del() proc ensures a new one is created
+ return
- if(istype(A, /obj/item/weapon/disk/nuclear)) // Don't let nuke disks travel Z levels
- return
+ if(!isemptylist(A.search_contents_for(/obj/item/weapon/disk/nuclear)))
+ if(istype(A, /mob/living))
+ var/mob/living/MM = A
+ if(MM.client)
+ MM << "\red Something you are carrying is preventing you from leaving. Don't play stupid; you know exactly what it is."
+ return
-// else if(ticker.mode.name == "extended"||ticker.mode.name == "sandbox") Sandbox_Spacemove(A)
+ var/move_to_z_str = pickweight(accessable_z_levels)
- else
- if (src.x <= 2 || A.x >= (world.maxx - 1) || src.y <= 2 || A.y >= (world.maxy - 1))
- if(istype(A, /obj/effect/meteor)||istype(A, /obj/effect/space_dust))
- del(A)
- return
+ var/move_to_z = text2num(move_to_z_str)
- if(!isemptylist(A.search_contents_for(/obj/item/weapon/disk/nuclear)))
- if(istype(A, /mob/living))
- var/mob/living/MM = A
- if(MM.client)
- MM << "\red Something you are carrying is preventing you from leaving. Don't play stupid; you know exactly what it is."
- return
+ if(!move_to_z)
+ return
+ A.z = move_to_z
+ if(src.x <= TRANSITIONEDGE)
+ A.x = world.maxx - TRANSITIONEDGE - 2
- var/move_to_z_str = pickweight(accessable_z_levels)
+ else if (A.x >= (world.maxx - TRANSITIONEDGE - 1))
+ A.x = TRANSITIONEDGE + 1
- var/move_to_z = text2num(move_to_z_str)
+ else if (src.y <= TRANSITIONEDGE)
+ A.y = world.maxy - TRANSITIONEDGE -2
- if(!move_to_z)
- return
+ else if (A.y >= (world.maxy - TRANSITIONEDGE - 1))
+ A.y = TRANSITIONEDGE +1
-
-
- A.z = move_to_z
-
-
- if(src.x <= 2)
- A.x = world.maxx - 2
-
- else if (A.x >= (world.maxx - 1))
- A.x = 3
-
- else if (src.y <= 2)
- A.y = world.maxy - 2
-
- else if (A.y >= (world.maxy - 1))
- A.y = 3
-
- spawn (0)
- if ((A && A.loc))
- A.loc.Entered(A)
-
-// if(istype(A, /obj/structure/closet/coffin))
-// coffinhandler.Add(A)
+ spawn (0)
+ if ((A && A.loc))
+ A.loc.Entered(A)
/*
/turf/space/proc/Sandbox_Spacemove(atom/movable/A as mob|obj)
var/cur_x
@@ -1444,7 +1530,7 @@ turf/simulated/floor/return_siding_icon_state()
if ((A && A.loc))
A.loc.Entered(A)
return
-*/
+*/ //Don't touch this either! DMTG
/obj/effect/vaultspawner
var/maxX = 6
var/maxY = 6
diff --git a/code/game/vehicles/airtight/airtight.dm b/code/game/vehicles/airtight/airtight.dm
new file mode 100644
index 0000000000..44ee0fff2b
--- /dev/null
+++ b/code/game/vehicles/airtight/airtight.dm
@@ -0,0 +1,165 @@
+
+/obj/vehicle/airtight
+ //inner atmos
+ var/use_internal_tank = 0
+ var/internal_tank_valve = ONE_ATMOSPHERE
+ var/obj/machinery/portable_atmospherics/canister/internal_tank
+ var/datum/gas_mixture/cabin_air
+ var/obj/machinery/atmospherics/portables_connector/connected_port = null
+
+ var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature
+ var/datum/global_iterator/pr_give_air //moves air from tank to cabin
+
+
+/obj/vehicle/airtight/New()
+ ..()
+ src.add_airtank()
+ src.add_cabin()
+ src.add_airtight_iterators()
+
+
+
+
+//######################################### Helpers for airtight vehicles #########################################
+
+/obj/vehicle/airtight/proc/add_cabin()
+ cabin_air = new
+ cabin_air.temperature = T20C
+ cabin_air.volume = 200
+ cabin_air.oxygen = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
+ cabin_air.nitrogen = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
+ return cabin_air
+
+/obj/vehicle/airtight/proc/add_airtank()
+ internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src)
+ return internal_tank
+
+/obj/vehicle/airtight/proc/add_airtight_iterators()
+ pr_int_temp_processor = new /datum/global_iterator/vehicle_preserve_temp(list(src))
+ pr_give_air = new /datum/global_iterator/vehicle_tank_give_air(list(src))
+
+
+//######################################### Specific datums for airtight vehicles #################################
+
+
+/datum/global_iterator/vehicle_preserve_temp //normalizing cabin air temperature to 20 degrees celsium
+ delay = 20
+
+ process(var/obj/vehicle/airtight/V)
+ if(V.cabin_air && V.cabin_air.return_volume() > 0)
+ var/delta = V.cabin_air.temperature - T20C
+ V.cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1)))
+ return
+
+
+/datum/global_iterator/vehicle_tank_give_air
+ delay = 15
+
+ process(var/obj/vehicle/airtight/V)
+ if(V.internal_tank)
+ var/datum/gas_mixture/tank_air = V.internal_tank.return_air()
+ var/datum/gas_mixture/cabin_air = V.cabin_air
+
+ var/release_pressure = V.internal_tank_valve
+ var/cabin_pressure = cabin_air.return_pressure()
+ var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2)
+ var/transfer_moles = 0
+ if(pressure_delta > 0) //cabin pressure lower than release pressure
+ if(tank_air.return_temperature() > 0)
+ transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
+ var/datum/gas_mixture/removed = tank_air.remove(transfer_moles)
+ cabin_air.merge(removed)
+ else if(pressure_delta < 0) //cabin pressure higher than release pressure
+ var/datum/gas_mixture/t_air = V.get_turf_air()
+ pressure_delta = cabin_pressure - release_pressure
+ if(t_air)
+ pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta)
+ if(pressure_delta > 0) //if location pressure is lower than cabin pressure
+ transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
+ var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles)
+ if(t_air)
+ t_air.merge(removed)
+ else //just delete the cabin gas, we're in space or some shit
+ del(removed)
+ else
+ return stop()
+ return
+
+
+//######################################### Atmospherics for vehicles #############################################
+
+
+/obj/vehicle/proc/get_turf_air()
+ var/turf/T = get_turf(src)
+ if(T)
+ . = T.return_air()
+ return
+
+/obj/vehicle/airtight/remove_air(amount)
+ if(use_internal_tank)
+ return cabin_air.remove(amount)
+ else
+ var/turf/T = get_turf(src)
+ if(T)
+ return T.remove_air(amount)
+ return
+
+/obj/vehicle/airtight/return_air()
+ if(use_internal_tank)
+ return cabin_air
+ return get_turf_air()
+
+/obj/vehicle/airtight/proc/return_pressure()
+ . = 0
+ if(use_internal_tank)
+ . = cabin_air.return_pressure()
+ else
+ var/datum/gas_mixture/t_air = get_turf_air()
+ if(t_air)
+ . = t_air.return_pressure()
+ return
+
+
+/obj/vehicle/airtight/proc/return_temperature()
+ . = 0
+ if(use_internal_tank)
+ . = cabin_air.return_temperature()
+ else
+ var/datum/gas_mixture/t_air = get_turf_air()
+ if(t_air)
+ . = t_air.return_temperature()
+ return
+
+/obj/vehicle/airtight/proc/connect(obj/machinery/atmospherics/portables_connector/new_port)
+ //Make sure not already connected to something else
+ if(connected_port || !new_port || new_port.connected_device)
+ return 0
+
+ //Make sure are close enough for a valid connection
+ if(new_port.loc != src.loc)
+ return 0
+
+ //Perform the connection
+ connected_port = new_port
+ connected_port.connected_device = src
+
+ //Actually enforce the air sharing
+ var/datum/pipe_network/network = connected_port.return_network(src)
+ if(network && !(internal_tank.return_air() in network.gases))
+ network.gases += internal_tank.return_air()
+ network.update = 1
+ log_message("Vehicle airtank connected to external port.")
+ return 1
+
+/obj/vehicle/airtight/proc/disconnect()
+ if(!connected_port)
+ return 0
+
+ var/datum/pipe_network/network = connected_port.return_network(src)
+ if(network)
+ network.gases -= internal_tank.return_air()
+
+ connected_port.connected_device = null
+ connected_port = null
+ src.log_message("Vehicle airtank disconnected from external port.")
+ return 1
\ No newline at end of file
diff --git a/code/game/vehicles/airtight/land.dm b/code/game/vehicles/airtight/land.dm
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/code/game/vehicles/airtight/space.dm b/code/game/vehicles/airtight/space.dm
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/code/game/vehicles/vehicle.dm b/code/game/vehicles/vehicle.dm
new file mode 100644
index 0000000000..87d40b6930
--- /dev/null
+++ b/code/game/vehicles/vehicle.dm
@@ -0,0 +1,190 @@
+
+
+/obj/vehicle
+ name = "Vehicle"
+ icon = 'vehicles.dmi'
+ density = 1
+ anchored = 1
+ unacidable = 1 //To avoid the pilot-deleting shit that came with mechas
+ layer = MOB_LAYER
+ //var/can_move = 1
+ var/mob/living/carbon/occupant = null
+ //var/step_in = 10 //make a step in step_in/10 sec.
+ //var/dir_in = 2//What direction will the mech face when entered/powered on? Defaults to South.
+ //var/step_energy_drain = 10
+ var/health = 300 //health is health
+ //var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act.
+ //the values in this list show how much damage will pass through, not how much will be absorbed.
+ var/list/damage_absorption = list("brute"=0.8,"fire"=1.2,"bullet"=0.9,"laser"=1,"energy"=1,"bomb"=1)
+ var/obj/item/weapon/cell/cell //Our power source
+ var/state = 0
+ var/list/log = new
+ var/last_message = 0
+ var/add_req_access = 1
+ var/maint_access = 1
+ //var/dna //dna-locking the mech
+ var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference
+ var/datum/effect/effect/system/spark_spread/spark_system = new
+ var/lights = 0
+ var/lights_power = 6
+
+ //inner atmos //These go in airtight.dm, not all vehicles are space-faring -Agouri
+ //var/use_internal_tank = 0
+ //var/internal_tank_valve = ONE_ATMOSPHERE
+ //var/obj/machinery/portable_atmospherics/canister/internal_tank
+ //var/datum/gas_mixture/cabin_air
+ //var/obj/machinery/atmospherics/portables_connector/connected_port = null
+
+ var/obj/item/device/radio/radio = null
+
+ var/max_temperature = 2500
+ //var/internal_damage_threshold = 50 //health percentage below which internal damage is possible
+ var/internal_damage = 0 //contains bitflags
+
+ var/list/operation_req_access = list()//required access level for mecha operation
+ var/list/internals_req_access = list(access_engine,access_robotics)//required access level to open cell compartment
+
+ //var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature //In airtight.dm you go -Agouri
+ var/datum/global_iterator/pr_inertial_movement //controls intertial movement in spesss
+
+ //var/datum/global_iterator/pr_give_air //moves air from tank to cabin //Y-you too -Agouri
+
+ var/datum/global_iterator/pr_internal_damage //processes internal damage
+
+
+ var/wreckage
+
+ var/list/equipment = new
+ var/obj/selected
+ //var/max_equip = 3
+
+ var/datum/events/events
+
+
+
+/obj/vehicle/New()
+ ..()
+ events = new
+ icon_state += "-unmanned"
+ add_radio()
+ //add_cabin() //No cabin for non-airtights
+
+ spark_system.set_up(2, 0, src)
+ spark_system.attach(src)
+ add_cell()
+ add_iterators()
+ removeVerb(/obj/mecha/verb/disconnect_from_port)
+ removeVerb(/atom/movable/verb/pull)
+ log_message("[src.name]'s functions initialised. Work protocols active - Entering IDLE mode.")
+ loc.Entered(src)
+ return
+
+
+//################ Helpers ###########################################################
+
+
+/obj/vehicle/proc/removeVerb(verb_path)
+ verbs -= verb_path
+
+/obj/vehicle/proc/addVerb(verb_path)
+ verbs += verb_path
+
+/*/obj/vehicle/proc/add_airtank() //In airtight.dm -Agouri
+ internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src)
+ return internal_tank*/
+
+/obj/vehicle/proc/add_cell(var/obj/item/weapon/cell/C=null)
+ if(C)
+ C.forceMove(src)
+ cell = C
+ return
+ cell = new(src)
+ cell.charge = 15000
+ cell.maxcharge = 15000
+
+/*/obj/vehicle/proc/add_cabin() //In airtight.dm -Agouri
+ cabin_air = new
+ cabin_air.temperature = T20C
+ cabin_air.volume = 200
+ cabin_air.oxygen = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
+ cabin_air.nitrogen = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
+ return cabin_air*/
+
+/obj/vehicle/proc/add_radio()
+ radio = new(src)
+ radio.name = "[src] radio"
+ radio.icon = icon
+ radio.icon_state = icon_state
+ radio.subspace_transmission = 1
+
+/obj/vehicle/proc/add_iterators()
+ pr_inertial_movement = new /datum/global_iterator/vehicle_intertial_movement(null,0)
+ //pr_internal_damage = new /datum/global_iterator/vehicle_internal_damage(list(src),0)
+ //pr_int_temp_processor = new /datum/global_iterator/vehicle_preserve_temp(list(src)) //In airtight.dm's add_airtight_iterators -Agouri
+ //pr_give_air = new /datum/global_iterator/vehicle_tank_give_air(list(src) //Same here -Agouri
+
+/obj/vehicle/proc/check_for_support()
+ if(locate(/obj/structure/grille, orange(1, src)) || locate(/obj/structure/lattice, orange(1, src)) || locate(/turf/simulated, orange(1, src)) || locate(/turf/unsimulated, orange(1, src)))
+ return 1
+ else
+ return 0
+
+//################ Logs and messages ############################################
+
+
+/obj/vehicle/proc/log_message(message as text,red=null)
+ log.len++
+ log[log.len] = list("time"=world.timeofday,"message"="[red?"":null][message][red?" ":null]")
+ return log.len
+
+
+
+//################ Global Iterator Datums ######################################
+
+
+/datum/global_iterator/vehicle_intertial_movement //inertial movement in space
+ delay = 7
+
+ process(var/obj/vehicle/V as obj, direction)
+ if(direction)
+ if(!step(V, direction)||V.check_for_support())
+ src.stop()
+ else
+ src.stop()
+ return
+
+
+/datum/global_iterator/mecha_internal_damage // processing internal damage
+
+ process(var/obj/mecha/mecha)
+ if(!mecha.hasInternalDamage())
+ return stop()
+ if(mecha.hasInternalDamage(MECHA_INT_FIRE))
+ if(!mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL) && prob(5))
+ mecha.clearInternalDamage(MECHA_INT_FIRE)
+ if(mecha.internal_tank)
+ if(mecha.internal_tank.return_pressure()>mecha.internal_tank.maximum_pressure && !(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)))
+ mecha.setInternalDamage(MECHA_INT_TANK_BREACH)
+ var/datum/gas_mixture/int_tank_air = mecha.internal_tank.return_air()
+ if(int_tank_air && int_tank_air.return_volume()>0) //heat the air_contents
+ int_tank_air.temperature = min(6000+T0C, int_tank_air.temperature+rand(10,15))
+ if(mecha.cabin_air && mecha.cabin_air.return_volume()>0)
+ mecha.cabin_air.temperature = min(6000+T0C, mecha.cabin_air.return_temperature()+rand(10,15))
+ if(mecha.cabin_air.return_temperature()>mecha.max_temperature/2)
+ mecha.take_damage(4/round(mecha.max_temperature/mecha.cabin_air.return_temperature(),0.1),"fire")
+ if(mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL)) //stop the mecha_preserve_temp loop datum
+ mecha.pr_int_temp_processor.stop()
+ if(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)) //remove some air from internal tank
+ if(mecha.internal_tank)
+ var/datum/gas_mixture/int_tank_air = mecha.internal_tank.return_air()
+ var/datum/gas_mixture/leaked_gas = int_tank_air.remove_ratio(0.10)
+ if(mecha.loc && hascall(mecha.loc,"assume_air"))
+ mecha.loc.assume_air(leaked_gas)
+ else
+ del(leaked_gas)
+ if(mecha.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT))
+ if(mecha.get_charge())
+ mecha.spark_system.start()
+ mecha.cell.charge -= min(20,mecha.cell.charge)
+ mecha.cell.maxcharge -= min(20,mecha.cell.maxcharge)
+ return
\ No newline at end of file
diff --git a/code/modules/DetectiveWork/detective_work.dm b/code/modules/DetectiveWork/detective_work.dm
index 70a7b60401..b0bd660453 100644
--- a/code/modules/DetectiveWork/detective_work.dm
+++ b/code/modules/DetectiveWork/detective_work.dm
@@ -4,14 +4,12 @@ atom/var/list/suit_fibers
atom/proc/add_fibers(mob/living/carbon/human/M)
if(M.gloves)
- if(M.gloves.transfer_blood)
- if(add_blood(M.gloves.bloody_hands_mob))
+ if(M.gloves.transfer_blood) //bloodied gloves transfer blood to touched objects
+ if(add_blood(M.gloves.bloody_hands_mob)) //only reduces the bloodiness of our gloves if the item wasn't already bloody
M.gloves.transfer_blood--
- //world.log << "[M.gloves] added blood to [src] from [M.gloves.bloody_hands_mob]"
else if(M.bloody_hands)
if(add_blood(M.bloody_hands_mob))
M.bloody_hands--
- //world.log << "[M] added blood to [src] from [M.bloody_hands_mob]"
if(!suit_fibers) suit_fibers = list()
var/fibertext
var/item_multiplier = istype(src,/obj/item)?1.2:1
@@ -190,6 +188,8 @@ obj/machinery/computer/forensic_scanning
I = card
if(I && istype(I,/obj/item/weapon/f_card))
card = I
+ if(!card.fingerprints)
+ card.fingerprints = list()
if(card.amount > 1 || !card.fingerprints.len)
usr << "\red ERROR: No prints/too many cards."
if(card.loc == src)
@@ -468,9 +468,10 @@ obj/machinery/computer/forensic_scanning
proc/add_data_scanner(var/obj/item/device/detective_scanner/W)
- for(var/i = 1, i <= W.stored.len, i++)
- var/list/data = W.stored[i]
- add_data(data[1],1,data[2],data[3],data[4])
+ if(W.stored)
+ for(var/i = 1, i <= W.stored.len, i++)
+ var/list/data = W.stored[i]
+ add_data(data[1],1,data[2],data[3],data[4])
W.stored = list()
for(var/atom/A in W.contents)
del(A)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 5bcfd46628..71811b312d 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -12,9 +12,9 @@ var/global/BSACooldown = 0
else
M << rendered
+
/obj/admins/Topic(href, href_list)
..()
-
if (usr.client != src.owner)
world << "\blue [usr.key] has attempted to override the admin panel!"
log_admin("[key_name(usr)] tried to use the admin panel without authorization.")
@@ -31,7 +31,7 @@ var/global/BSACooldown = 0
if ((!( ticker ) || emergency_shuttle.location))
return
emergency_shuttle.incall()
- world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes. "
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
log_admin("[key_name(usr)] called the Emergency Shuttle")
message_admins("\blue [key_name_admin(usr)] called the Emergency Shuttle to the station", 1)
@@ -41,12 +41,11 @@ var/global/BSACooldown = 0
switch(emergency_shuttle.direction)
if(-1)
emergency_shuttle.incall()
- world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes. "
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
log_admin("[key_name(usr)] called the Emergency Shuttle")
message_admins("\blue [key_name_admin(usr)] called the Emergency Shuttle to the station", 1)
if(1)
emergency_shuttle.recall()
- world << "\blue Alert: The shuttle is going back! "
log_admin("[key_name(usr)] sent the Emergency Shuttle back")
message_admins("\blue [key_name_admin(usr)] sent the Emergency Shuttle back", 1)
@@ -59,6 +58,7 @@ var/global/BSACooldown = 0
if (src.rank in list("Badmin", "Game Admin", "Game Master"))
emergency_shuttle.settimeleft( input("Enter new shuttle duration (seconds):","Edit Shuttle Timeleft", emergency_shuttle.timeleft() ) as num )
log_admin("[key_name(usr)] edited the Emergency Shuttle's timeleft to [emergency_shuttle.timeleft()]")
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
message_admins("\blue [key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [emergency_shuttle.timeleft()]", 1)
href_list["secretsadmin"] = "check_antagonist"
else
@@ -196,82 +196,370 @@ var/global/BSACooldown = 0
if(href_list["jobban2"])
var/mob/M = locate(href_list["jobban2"])
- var/dat = ""
- var/header = "Pick Job to ban this guy from. "
- var/body
- var/jobs = ""
+ if(!M) //sanity
+ alert("Mob no longer exists!")
+ return
+ if(!M.ckey) //sanity
+ alert("Mob has no ckey")
+ return
if(!job_master)
usr << "Job Master has not been setup!"
return
- for(var/datum/job/job in job_master.occupations)
- if(job.title == "Tourist")
- continue
+ var/dat = ""
+ var/header = "Job-Ban Panel: [M.name] "
+ var/body
+ var/jobs = ""
+
+ /***********************************WARNING!************************************
+ The jobban stuff looks mangled and disgusting
+ But it looks beautiful in-game
+ -Nodrak
+ ************************************WARNING!***********************************/
+ var/counter = 0
+//Regular jobs
+ //Command (Blue)
+ jobs += ""
+ jobs += "Command Positions "
+ for(var/jobPos in command_positions)
+ if(!jobPos) continue
+ var/datum/job/job = job_master.GetJob(jobPos)
+ if(!job) continue
+
if(jobban_isbanned(M, job.title))
- jobs += "[dd_replacetext(job.title, " ", " ")] "
+ jobs += "[dd_replacetext(job.title, " ", " ")] "
+ counter++
else
- jobs += "[dd_replacetext(job.title, " ", " ")] "
+ jobs += "[dd_replacetext(job.title, " ", " ")] "
+ counter++
-/* if(jobban_isbanned(M, "Captain")) These two are now jobs in the datums and should show up in the above code
- jobs += "Captain "
- else
- jobs += "Captain "
+ if(counter >= 6) //So things dont get squiiiiished!
+ jobs += " "
+ counter = 0
+ jobs += "
"
- if(jobban_isbanned(M, "AI"))
- jobs += "AI "
- else
- jobs += "AI "
-*/
- if(jobban_isbanned(M, "Syndicate"))
- jobs += "[dd_replacetext("Syndicate", " ", " ")] "
- else
- jobs += "[dd_replacetext("Syndicate", " ", " ")] "
+ //Security (Red)
+ counter = 0
+ jobs += ""
+ jobs += "Security Positions "
+ for(var/jobPos in security_positions)
+ if(!jobPos) continue
+ var/datum/job/job = job_master.GetJob(jobPos)
+ if(!job) continue
- if(jobban_isbanned(M, "Emergency Response Team"))
- jobs += "[dd_replacetext("Emergency Response Team", " ", " ")] "
- else
- jobs += "[dd_replacetext("Emergency Response Team", " ", " ")] "
+ if(jobban_isbanned(M, job.title))
+ jobs += "[dd_replacetext(job.title, " ", " ")] "
+ counter++
+ else
+ jobs += "[dd_replacetext(job.title, " ", " ")] "
+ counter++
+ if(counter >= 5) //So things dont get squiiiiished!
+ jobs += " "
+ counter = 0
+ jobs += "
"
+ //Engineering (Yellow)
+ counter = 0
+ jobs += ""
+
+ //Medical (White)
+ counter = 0
+ jobs += ""
+
+ //Science (Purple)
+ counter = 0
+ jobs += ""
+
+ //Civilian (Grey)
+ counter = 0
+ jobs += ""
+
+ //Non-Human (Green)
+ counter = 0
+ jobs += ""
+ jobs += "Non-human Positions "
+ for(var/jobPos in nonhuman_positions)
+ if(!jobPos) continue
+ var/datum/job/job = job_master.GetJob(jobPos)
+ if(!job) continue
+
+ if(jobban_isbanned(M, job.title))
+ jobs += "[dd_replacetext(job.title, " ", " ")] "
+ counter++
+ else
+ jobs += "[dd_replacetext(job.title, " ", " ")] "
+ counter++
+
+ if(counter >= 5) //So things dont get squiiiiished!
+ jobs += " "
+ counter = 0
+
+ //pAI isn't technically a job, but it goes in here.
if(jobban_isbanned(M, "pAI"))
- jobs += "pAI "
+ jobs += "pAI "
else
- jobs += "pAI "
+ jobs += "pAI "
- body = " [jobs] "
+ jobs += "
"
+
+ //Antagonist (Orange)
+ var/isbanned_dept = jobban_isbanned(M, "Syndicate")
+ jobs += ""
+ jobs += "Antagonist Positions "
+
+ //Traitor
+ if(jobban_isbanned(M, "traitor") || isbanned_dept)
+ jobs += "[dd_replacetext("Traitor", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Traitor", " ", " ")] "
+
+ //Changeling
+ if(jobban_isbanned(M, "changeling") || isbanned_dept)
+ jobs += "[dd_replacetext("Changeling", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Changeling", " ", " ")] "
+
+ //Nuke Operative
+ if(jobban_isbanned(M, "operative") || isbanned_dept)
+ jobs += "[dd_replacetext("Nuke Operative", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Nuke Operative", " ", " ")] "
+
+ //Revolutionary
+ if(jobban_isbanned(M, "revolutionary") || isbanned_dept)
+ jobs += "[dd_replacetext("Revolutionary", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Revolutionary", " ", " ")] "
+
+ jobs += " " //Breaking it up so it fits nicer on the screen every 5 entries
+
+ //Cultist
+ if(jobban_isbanned(M, "cultist") || isbanned_dept)
+ jobs += "[dd_replacetext("Cultist", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Cultist", " ", " ")] "
+
+ //Wizard
+ if(jobban_isbanned(M, "wizard") || isbanned_dept)
+ jobs += "[dd_replacetext("Wizard", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Wizard", " ", " ")] "
+
+ //Emergency Response Team
+ if(jobban_isbanned(M, "Emergency Response Team" || isbanned_dept))
+ jobs += "[dd_replacetext("Emergency Response Team", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Emergency Response Team", " ", " ")] "
+
+
+/* //Malfunctioning AI //Removed Malf-bans because they're a pain to impliment
+ if(jobban_isbanned(M, "malf AI") || isbanned_dept)
+ jobs += "[dd_replacetext("Malf AI", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Malf AI", " ", " ")] "
+
+ //Alien
+ if(jobban_isbanned(M, "alien candidate") || isbanned_dept)
+ jobs += "[dd_replacetext("Alien", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Alien", " ", " ")] "
+
+ //Infested Monkey
+ if(jobban_isbanned(M, "infested monkey") || isbanned_dept)
+ jobs += "[dd_replacetext("Infested Monkey", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Infested Monkey", " ", " ")] "
+*/
+ jobs += "
"
+
+ body = "[jobs]"
dat = "[header][body] "
- usr << browse(dat, "window=jobban2;size=600x180")
+ usr << browse(dat, "window=jobban2;size=800x450")
return
+ //JOBBAN'S INNARDS
if(href_list["jobban3"])
if (src.rank in list( "Admin Candidate", "Temporary Admin", "Trial Admin", "Badmin", "Game Admin", "Game Master" ))
var/mob/M = locate(href_list["jobban4"])
- var/job = href_list["jobban3"]
+ if(!M)
+ alert("Mob no longer exists!")
+ return
if ((M.client && M.client.holder && (M.client.holder.level > src.level)))
alert("You cannot perform this action. You must be of a higher administrative rank!")
return
- if (jobban_isbanned(M, job))
- log_admin("[key_name(usr)] unbanned [key_name(M)] from [job]")
- ban_unban_log_save("[key_name(usr)] unjobbanned [key_name(M)] from [job]")
- M << "\redYou have been un-jobbanned by [usr.client.ckey] from [job]. "
- //feedback_inc("ban_job_unban",1)
- message_admins("\blue [key_name_admin(usr)] unbanned [key_name_admin(M)] from [job]", 1)
- jobban_unban(M, job)
- href_list["jobban2"] = 1
- else
- var/reason = input(usr,"Reason?","reason","griefer") as text|null
- if(!reason)
- return
- ban_unban_log_save("[key_name(usr)] jobbanned [key_name(M)] from [job]. reason: [reason]")
- log_admin("[key_name(usr)] banned [key_name(M)] from [job]")
- //feedback_inc("ban_job",1)
- M << "\redYou have been jobbanned by [usr.client.ckey] from [job]. "
- M << "\red The reason is: [reason] "
- M << "\red Jobban can be lifted only on demand."
- message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [job]", 1)
- jobban_fullban(M, job, reason)
- href_list["jobban2"] = 1 // lets it fall through and refresh
- if(config.appeal_address)
- M << "\red You may try to appeal this at [config.appeal_address]"
+ if(!job_master)
+ usr << "Job Master has not been setup!"
+ return
+
+ //get jobs for department if specified, otherwise just returnt he one job in a list.
+ var/list/joblist = list()
+ switch(href_list["jobban3"])
+ if("commanddept")
+ for(var/jobPos in command_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("securitydept")
+ for(var/jobPos in security_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("engineeringdept")
+ for(var/jobPos in engineering_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("medicaldept")
+ for(var/jobPos in medical_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("sciencedept")
+ for(var/jobPos in science_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("civiliandept")
+ for(var/jobPos in civilian_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("nonhumandept")
+ joblist += "pAI"
+ for(var/jobPos in nonhuman_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ else
+ joblist += href_list["jobban3"]
+
+ //Create a list of unbanned jobs within joblist
+ var/list/notbannedlist = list()
+ for(var/job in joblist)
+ if(!jobban_isbanned(M, job))
+ notbannedlist += job
+
+ //Banning comes first
+ if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban.
+ var/reason = input(usr,"Reason?","Please State Reason","") as text|null
+ if(reason)
+ var/msg
+ for(var/job in notbannedlist)
+ ban_unban_log_save("[key_name(usr)] jobbanned [key_name(M)] from [job]. reason: [reason]")
+ log_admin("[key_name(usr)] banned [key_name(M)] from [job]")
+ feedback_inc("ban_job",1)
+ feedback_add_details("ban_job","- [job]")
+ jobban_fullban(M, job, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
+ if(!msg) msg = job
+ else msg += ", [job]"
+ message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg]", 1)
+ M << "\redYou have been jobbanned by [usr.client.ckey] from: [msg]. "
+ M << "\red The reason is: [reason] "
+ M << "\red Jobban can be lifted only upon request."
+ if(config.appeal_address)
+ M << "\red You may try to appeal this at [config.appeal_address]"
+ href_list["jobban2"] = 1 // lets it fall through and refresh
+ return 1
+
+ //Unbanning joblist
+ //all jobs in joblist are banned already OR we didn't give a reason (implying they shouldn't be banned)
+ if(joblist.len) //at least 1 banned job exists in joblist so we have stuff to unban.
+ var/msg
+ for(var/job in joblist)
+ var/reason = jobban_isbanned(M, job)
+ if(!reason) continue //skip if it isn't jobbanned anyway
+ switch(alert("Job: '[job]' Reason: '[reason]' Un-jobban?","Please Confirm","Yes","No"))
+ if("Yes")
+ ban_unban_log_save("[key_name(usr)] unjobbanned [key_name(M)] from [job]")
+ log_admin("[key_name(usr)] unbanned [key_name(M)] from [job]")
+ feedback_inc("ban_job_unban",1)
+ feedback_add_details("ban_job_unban","- [job]")
+ jobban_unban(M, job)
+ if(!msg) msg = job
+ else msg += ", [job]"
+ else
+ continue
+ if(msg)
+ message_admins("\blue [key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg]", 1)
+ M << "\redYou have been un-jobbanned by [usr.client.ckey] from [msg]. "
+ href_list["jobban2"] = 1 // lets it fall through and refresh
+ return 1
+ return 0 //we didn't do anything!
if (href_list["boot2"])
if ((src.rank in list( "Moderator", "Temporary Admin", "Admin Candidate", "Trial Admin", "Badmin", "Game Admin", "Game Master" )))
@@ -803,6 +1091,21 @@ var/global/BSACooldown = 0
alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
return
+ if (href_list["makeaisilent"])
+ if (src.level>=3)
+ var/mob/M = locate(href_list["makeaisilent"])
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ message_admins("\red Admin [key_name_admin(usr)] AIized [key_name_admin(M)] silently!", 1)
+ log_admin("[key_name(usr)] AIized [key_name(M)] silently")
+ H.AIizeSilent()
+ else
+ alert("I cannot allow this.")
+ return
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+
if (href_list["makealien"])
if (src.level>=3)
var/mob/M = locate(href_list["makealien"])
@@ -1069,11 +1372,19 @@ var/global/BSACooldown = 0
else
alert("You are not a high enough administrator! Sorry!!!!")
+ if (href_list["quick_create_object"])
+ if (src.rank in list("Admin Candidate", "Trial Admin", "Badmin", "Game Admin", "Game Master"))
+ return quick_create_object(usr)
+ else
+ alert("You are not a high enough administrator! Sorry!!!!")
+
+
if (href_list["create_turf"])
if (src.rank in list("Admin Candidate", "Trial Admin", "Badmin", "Game Admin", "Game Master"))
return create_turf(usr)
else
alert("You are not a high enough administrator! Sorry!!!!")
+
if (href_list["create_mob"])
if (src.rank in list("Badmin", "Game Admin", "Game Master"))
return create_mob(usr)
@@ -2057,6 +2368,7 @@ var/global/BSACooldown = 0
foo += text("Is an AI | ")
else if(ishuman(M))
foo += text("Make AI | ")
+ foo += text("Make AI Silently | ")
foo += text("Make Robot | ")
foo += text("Make Alien | ")
foo += text("Make Metroid | ")
@@ -2215,6 +2527,7 @@ var/global/BSACooldown = 0
if(lvl >= 3 )
dat += "Create Object "
+ dat += "Quick Create Object "
dat += "Create Turf "
if(lvl >= 5)
dat += "Create Mob "
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index c330f57451..ae551810a0 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -50,13 +50,9 @@
if ("Trial Admin")
holder.level = 3
if(holder.state == 2) // if observing
- // Debug
verbs += /client/proc/debug_variables
verbs += /client/proc/cmd_modify_ticker_variables
- verbs += /client/proc/toggleadminhelpsound
- // Admin helpers
verbs += /client/proc/toggle_view_range
- // Admin game intrusion
verbs += /client/proc/Getmob
verbs += /client/proc/Getkey
verbs += /client/proc/sendmob
@@ -65,6 +61,7 @@
verbs += /client/proc/jumptomob
verbs += /client/proc/jumptoturf
verbs += /client/proc/jumptocoord
+ verbs += /client/proc/cmd_admin_delete
verbs += /client/proc/cmd_admin_add_freeform_ai_law
verbs += /client/proc/cmd_admin_rejuvenate
verbs += /client/proc/cmd_admin_drop_everything
@@ -74,12 +71,9 @@
holder.level = 2
if(holder.state == 2) // if observing
deadchat = 1
- // Settings
verbs += /obj/admins/proc/toggleaban //abandon mob
verbs += /client/proc/deadchat //toggles deadchat
- // Admin helpers
verbs += /client/proc/cmd_admin_check_contents
- // Admin game intrusion
verbs += /client/proc/Jump
verbs += /client/proc/jumptokey
verbs += /client/proc/jumptomob
@@ -121,6 +115,8 @@
//Moderator
if (holder.level >= 0)
+ verbs += /obj/admins/proc/announce
+ verbs += /obj/admins/proc/startnow
verbs += /obj/admins/proc/toggleAI //Toggle the AI
verbs += /obj/admins/proc/toggleenter //Toggle enterting
// verbs += /obj/admins/proc/toggleguests //Toggle guests entering
@@ -136,8 +132,6 @@
verbs += /client/proc/cmd_admin_pm_panel
verbs += /client/proc/cmd_admin_subtle_message
verbs += /client/proc/warn
- verbs += /obj/admins/proc/announce
- verbs += /obj/admins/proc/startnow
verbs += /client/proc/dsay
verbs += /client/proc/admin_play
verbs += /client/proc/admin_observe
@@ -185,6 +179,8 @@
deadchat = 1
seeprayers = 1
+ verbs += /obj/admins/proc/view_txt_log
+ verbs += /obj/admins/proc/view_atk_log
verbs += /obj/admins/proc/toggleaban //abandon mob
verbs += /obj/admins/proc/show_traitor_panel
verbs += /client/proc/cmd_admin_remove_plasma
@@ -195,6 +191,8 @@
verbs += /client/proc/spawn_xeno
verbs += /client/proc/toggleprayers
verbs += /client/proc/deadmin_self
+ verbs += /client/proc/tension_report
+ verbs += /client/proc/toggleadminhelpsound
verbs += /proc/possess
verbs += /proc/release
verbs += /client/proc/admin_deny_shuttle
@@ -229,15 +227,12 @@
//verbs += /proc/togglebuildmode --Merged with view variables
//verbs += /client/proc/cmd_modify_object_variables --Merged with view variables
verbs += /client/proc/togglebuildmodeself
- verbs += /client/proc/tension_report
- verbs += /client/proc/toggleadminhelpsound
+
else return
//Game Admin
if (holder.level >= 5)
verbs += /obj/admins/proc/spawn_atom
- verbs += /obj/admins/proc/view_txt_log
- verbs += /obj/admins/proc/view_atk_log
verbs += /client/proc/cmd_admin_list_open_jobs
verbs += /client/proc/cmd_admin_direct_narrate
verbs += /client/proc/colorooc
@@ -249,6 +244,7 @@
verbs += /client/proc/check_words
verbs += /client/proc/drop_bomb
verbs += /client/proc/cmd_admin_grantfullaccess
+ verbs += /client/proc/kill_airgroup
verbs += /client/proc/cmd_admin_drop_everything
verbs += /client/proc/make_sound
verbs += /client/proc/play_local_sound
@@ -265,6 +261,7 @@
//verbs += /client/proc/cmd_admin_emp --Merged with view variables
//verbs += /client/proc/give_spell --Merged with view variables
//verbs += /client/proc/cmd_admin_ninjafy --Merged with view variables
+ //verbs += /client/proc/cmd_switch_radio --removed as tcommsat is staying
// Moved over from tg's Game Master:
verbs += /obj/admins/proc/toggle_aliens //toggle aliens
verbs += /obj/admins/proc/toggle_space_ninja //toggle ninjas
@@ -386,7 +383,8 @@
verbs -= /client/proc/cmd_admin_create_centcom_report
verbs -= /client/proc/deadchat //toggles deadchat
verbs -= /client/proc/cmd_admin_mute
- verbs -= /client/proc/cmd_admin_pm
+ verbs -= /client/proc/cmd_admin_pm_context
+ verbs -= /client/proc/cmd_admin_pm_panel
verbs -= /client/proc/cmd_admin_say
verbs -= /client/proc/cmd_admin_subtle_message
verbs -= /client/proc/warn
@@ -446,6 +444,7 @@
//verbs -= /obj/admins/proc/unprison --Merged with player panel
//verbs -= /client/proc/cmd_switch_radio --removed because tcommsat is staying
verbs -= /client/proc/togglebuildmodeself
+ verbs -= /client/proc/kill_airgroup
verbs -= /client/proc/admin_deny_shuttle
verbs -= /client/proc/cmd_admin_christmas
verbs -= /client/proc/editappear
diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm
index d9cdc9be65..cd6ef81420 100644
--- a/code/modules/admin/banjob.dm
+++ b/code/modules/admin/banjob.dm
@@ -3,7 +3,7 @@ var
jobban_keylist[0] //to store the keys & ranks
/proc/jobban_fullban(mob/M, rank, reason)
- if (!M || !M.key || !M.client) return
+ if (!M || !M.key) return
jobban_keylist.Add(text("[M.ckey] - [rank] ## [reason]"))
jobban_savebanfile()
@@ -12,19 +12,25 @@ var
jobban_keylist.Add(text("[ckey] - [rank]"))
jobban_savebanfile()
+//returns a reason if M is banned from rank, returns 0 otherwise
/proc/jobban_isbanned(mob/M, rank)
- if(_jobban_isbanned(M, rank)) return 1//for old jobban
- if(M)
+ if(M && rank)
+ if(_jobban_isbanned(M, rank)) return "Reason Unspecified" //for old jobban
if (guest_jobbans(rank))
if(config.guest_jobban && IsGuestKey(M.key))
- return 1
+ return "Guest Job-ban"
if(config.usewhitelist && !check_whitelist(M))
- return 1
+ return "Whitelisted Job"
for (var/s in jobban_keylist)
if( findtext(s,"[M.ckey] - [rank]") )
- return 1
- return 0
+ var/startpos = findtext(s, "## ")+3
+ if(startpos && startposCreate Object", "Create Mob ")
create_mob_html = dd_replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"")
user << browse(dd_replacetext(create_mob_html, "/* ref src */", "\ref[src]"), "window=create_mob;size=425x475")
diff --git a/code/modules/admin/create_object.dm b/code/modules/admin/create_object.dm
index 944ab89c7a..248eebb5ab 100644
--- a/code/modules/admin/create_object.dm
+++ b/code/modules/admin/create_object.dm
@@ -1,4 +1,5 @@
/var/create_object_html = null
+
/obj/admins/proc/create_object(var/mob/user)
if (!create_object_html)
var/objectjs = null
@@ -7,3 +8,21 @@
create_object_html = dd_replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"")
user << browse(dd_replacetext(create_object_html, "/* ref src */", "\ref[src]"), "window=create_object;size=425x475")
+
+
+/obj/admins/proc/quick_create_object(var/mob/user)
+
+ var/quick_create_object_html = null
+ var/pathtext = null
+
+ pathtext = input("Select the path of the object you wish to create.", "Path", "/obj") in list("/obj","/obj/structure","/obj/item","/obj/machinery")
+
+ var path = text2path(pathtext)
+
+ if (!quick_create_object_html)
+ var/objectjs = null
+ objectjs = dd_list2text(typesof(path), ";")
+ quick_create_object_html = file2text('create_object.html')
+ quick_create_object_html = dd_replacetext(quick_create_object_html, "null /* object types */", "\"[objectjs]\"")
+
+ user << browse(dd_replacetext(quick_create_object_html, "/* ref src */", "\ref[src]"), "window=quick_create_object;size=425x475")
\ No newline at end of file
diff --git a/code/modules/admin/create_turf.dm b/code/modules/admin/create_turf.dm
index be5fdd1e0b..6ae15354e5 100644
--- a/code/modules/admin/create_turf.dm
+++ b/code/modules/admin/create_turf.dm
@@ -4,6 +4,7 @@
var/turfjs = null
turfjs = dd_list2text(typesof(/turf), ";")
create_turf_html = file2text('create_object.html')
+ create_turf_html = dd_replacetext(create_turf_html, "Create Object ", "Create Turf ")
create_turf_html = dd_replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"")
user << browse(dd_replacetext(create_turf_html, "/* ref src */", "\ref[src]"), "window=create_turf;size=425x475")
diff --git a/code/modules/admin/new/admin.dm b/code/modules/admin/new/admin.dm
new file mode 100644
index 0000000000..3a31687261
--- /dev/null
+++ b/code/modules/admin/new/admin.dm
@@ -0,0 +1,3048 @@
+
+var/global/BSACooldown = 0
+
+
+////////////////////////////////
+/proc/message_admins(var/text, var/admin_ref = 0)
+ var/rendered = "ADMIN LOG: [text] "
+ log_adminwarn(rendered)
+ for (var/mob/M in world)
+ if (M && M.client && M.client.holder && M.client.authenticated)
+ if (admin_ref)
+ M << dd_replaceText(rendered, "%admin_ref%", "\ref[M]")
+ else
+ M << rendered
+
+
+/obj/admins/Topic(href, href_list)
+ ..()
+ if (usr.client != src.owner)
+ world << "\blue [usr.key] has attempted to override the admin panel!"
+ log_admin("[key_name(usr)] tried to use the admin panel without authorization.")
+ return
+
+ if(href_list["call_shuttle"])
+ if (src.rank in list("Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ if( ticker.mode.name == "blob" )
+ alert("You can't call the shuttle during blob!")
+ return
+ switch(href_list["call_shuttle"])
+ if("1")
+ if ((!( ticker ) || emergency_shuttle.location))
+ return
+ emergency_shuttle.incall()
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
+ log_admin("[key_name(usr)] called the Emergency Shuttle")
+ message_admins("\blue [key_name_admin(usr)] called the Emergency Shuttle to the station", 1)
+
+ if("2")
+ if ((!( ticker ) || emergency_shuttle.location || emergency_shuttle.direction == 0))
+ return
+ switch(emergency_shuttle.direction)
+ if(-1)
+ emergency_shuttle.incall()
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
+ log_admin("[key_name(usr)] called the Emergency Shuttle")
+ message_admins("\blue [key_name_admin(usr)] called the Emergency Shuttle to the station", 1)
+ if(1)
+ emergency_shuttle.recall()
+ log_admin("[key_name(usr)] sent the Emergency Shuttle back")
+ message_admins("\blue [key_name_admin(usr)] sent the Emergency Shuttle back", 1)
+
+ href_list["secretsadmin"] = "check_antagonist"
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+
+ if(href_list["edit_shuttle_time"])
+ if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ emergency_shuttle.settimeleft( input("Enter new shuttle duration (seconds):","Edit Shuttle Timeleft", emergency_shuttle.timeleft() ) as num )
+ log_admin("[key_name(usr)] edited the Emergency Shuttle's timeleft to [emergency_shuttle.timeleft()]")
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
+ message_admins("\blue [key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [emergency_shuttle.timeleft()]", 1)
+ href_list["secretsadmin"] = "check_antagonist"
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+
+ /////////////////////////////////////new ban stuff
+ if(href_list["unbanf"])
+ var/banfolder = href_list["unbanf"]
+ Banlist.cd = "/base/[banfolder]"
+ var/key = Banlist["key"]
+ if(alert(usr, "Are you sure you want to unban [key]?", "Confirmation", "Yes", "No") == "Yes")
+ if (RemoveBan(banfolder))
+ unbanpanel()
+ else
+ alert(usr,"This ban has already been lifted / does not exist.","Error","Ok")
+ unbanpanel()
+
+ if(href_list["unbane"])
+ UpdateTime()
+ var/reason
+ var/mins = 0
+ var/banfolder = href_list["unbane"]
+ Banlist.cd = "/base/[banfolder]"
+ var/reason2 = Banlist["reason"]
+ var/temp = Banlist["temp"]
+ var/minutes = (Banlist["minutes"] - CMinutes)
+ if(!minutes || minutes < 0) minutes = 0
+ var/banned_key = Banlist["key"]
+ Banlist.cd = "/base"
+
+ switch(alert("Temporary Ban?",,"Yes","No"))
+ if("Yes")
+ temp = 1
+ mins = input(usr,"How long (in minutes)? (Default: 1440)","Ban time",minutes ? minutes : 1440) as num
+ if(!mins)
+ return
+ if(mins >= 525600) mins = 525599
+ reason = input(usr,"Reason?","reason",reason2) as text
+ if(!reason)
+ return
+ if("No")
+ temp = 0
+ reason = input(usr,"Reason?","reason",reason2) as text
+ if(!reason)
+ return
+
+ log_admin("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [GetExp(mins)]")
+
+ ban_unban_log_save("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [GetExp(mins)]")
+ message_admins("\blue [key_name_admin(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [GetExp(mins)]", 1)
+ Banlist.cd = "/base/[banfolder]"
+ Banlist["reason"] << reason
+ Banlist["temp"] << temp
+ Banlist["minutes"] << (mins + CMinutes)
+ Banlist["bannedby"] << usr.ckey
+ Banlist.cd = "/base"
+ feedback_inc("ban_edit",1)
+ unbanpanel()
+
+ /////////////////////////////////////new ban stuff
+
+ if(href_list["jobban2"])
+ var/mob/M = locate(href_list["jobban2"])
+ if(!M) //sanity
+ alert("Mob no longer exists!")
+ return
+ if(!M.ckey) //sanity
+ alert("Mob has no ckey")
+ return
+ if(!job_master)
+ usr << "Job Master has not been setup!"
+ return
+ var/dat = ""
+ var/header = "Job-Ban Panel: [M.name] "
+ var/body
+ var/jobs = ""
+
+ /***********************************WARNING!************************************
+ The jobban stuff looks mangled and disgusting
+ But it looks beautiful in-game
+ -Nodrak
+ ************************************WARNING!***********************************/
+ var/counter = 0
+//Regular jobs
+ //Command (Blue)
+ jobs += ""
+
+ //Security (Red)
+ counter = 0
+ jobs += ""
+
+ //Engineering (Yellow)
+ counter = 0
+ jobs += ""
+
+ //Medical (White)
+ counter = 0
+ jobs += ""
+
+ //Science (Purple)
+ counter = 0
+ jobs += ""
+
+ //Civilian (Grey)
+ counter = 0
+ jobs += ""
+
+ //Non-Human (Green)
+ counter = 0
+ jobs += ""
+ jobs += "Non-human Positions "
+ for(var/jobPos in nonhuman_positions)
+ if(!jobPos) continue
+ var/datum/job/job = job_master.GetJob(jobPos)
+ if(!job) continue
+
+ if(jobban_isbanned(M, job.title))
+ jobs += "[dd_replacetext(job.title, " ", " ")] "
+ counter++
+ else
+ jobs += "[dd_replacetext(job.title, " ", " ")] "
+ counter++
+
+ if(counter >= 5) //So things dont get squiiiiished!
+ jobs += " "
+ counter = 0
+
+ //pAI isn't technically a job, but it goes in here.
+ if(jobban_isbanned(M, "pAI"))
+ jobs += "pAI "
+ else
+ jobs += "pAI "
+
+ jobs += "
"
+
+ //Antagonist (Orange)
+ var/isbanned_dept = jobban_isbanned(M, "Syndicate")
+ jobs += ""
+ jobs += "Antagonist Positions "
+
+ //Traitor
+ if(jobban_isbanned(M, "traitor") || isbanned_dept)
+ jobs += "[dd_replacetext("Traitor", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Traitor", " ", " ")] "
+
+ //Changeling
+ if(jobban_isbanned(M, "changeling") || isbanned_dept)
+ jobs += "[dd_replacetext("Changeling", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Changeling", " ", " ")] "
+
+ //Nuke Operative
+ if(jobban_isbanned(M, "operative") || isbanned_dept)
+ jobs += "[dd_replacetext("Nuke Operative", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Nuke Operative", " ", " ")] "
+
+ //Revolutionary
+ if(jobban_isbanned(M, "revolutionary") || isbanned_dept)
+ jobs += "[dd_replacetext("Revolutionary", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Revolutionary", " ", " ")] "
+
+ jobs += " " //Breaking it up so it fits nicer on the screen every 5 entries
+
+ //Cultist
+ if(jobban_isbanned(M, "cultist") || isbanned_dept)
+ jobs += "[dd_replacetext("Cultist", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Cultist", " ", " ")] "
+
+ //Wizard
+ if(jobban_isbanned(M, "wizard") || isbanned_dept)
+ jobs += "[dd_replacetext("Wizard", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Wizard", " ", " ")] "
+
+/* //Malfunctioning AI //Removed Malf-bans because they're a pain to impliment
+ if(jobban_isbanned(M, "malf AI") || isbanned_dept)
+ jobs += "[dd_replacetext("Malf AI", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Malf AI", " ", " ")] "
+
+ //Alien
+ if(jobban_isbanned(M, "alien candidate") || isbanned_dept)
+ jobs += "[dd_replacetext("Alien", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Alien", " ", " ")] "
+
+ //Infested Monkey
+ if(jobban_isbanned(M, "infested monkey") || isbanned_dept)
+ jobs += "[dd_replacetext("Infested Monkey", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Infested Monkey", " ", " ")] "
+*/
+ jobs += "
"
+
+ body = "[jobs]"
+ dat = "[header][body] "
+ usr << browse(dat, "window=jobban2;size=800x450")
+ return
+
+ //JOBBAN'S INNARDS
+ if(href_list["jobban3"])
+ if (src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))
+ var/mob/M = locate(href_list["jobban4"])
+ if(!M)
+ alert("Mob no longer exists!")
+ return
+ if ((M.client && M.client.holder && (M.client.holder.level > src.level)))
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+ if(!job_master)
+ usr << "Job Master has not been setup!"
+ return
+
+ //get jobs for department if specified, otherwise just returnt he one job in a list.
+ var/list/joblist = list()
+ switch(href_list["jobban3"])
+ if("commanddept")
+ for(var/jobPos in command_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("securitydept")
+ for(var/jobPos in security_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("engineeringdept")
+ for(var/jobPos in engineering_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("medicaldept")
+ for(var/jobPos in medical_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("sciencedept")
+ for(var/jobPos in science_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("civiliandept")
+ for(var/jobPos in civilian_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ if("nonhumandept")
+ joblist += "pAI"
+ for(var/jobPos in nonhuman_positions)
+ if(!jobPos) continue
+ var/datum/job/temp = job_master.GetJob(jobPos)
+ if(!temp) continue
+ joblist += temp.title
+ else
+ joblist += href_list["jobban3"]
+
+ //Create a list of unbanned jobs within joblist
+ var/list/notbannedlist = list()
+ for(var/job in joblist)
+ if(!jobban_isbanned(M, job))
+ notbannedlist += job
+
+ //Banning comes first
+ if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban.
+ var/reason = input(usr,"Reason?","Please State Reason","") as text|null
+ if(reason)
+ var/msg
+ for(var/job in notbannedlist)
+ ban_unban_log_save("[key_name(usr)] jobbanned [key_name(M)] from [job]. reason: [reason]")
+ log_admin("[key_name(usr)] banned [key_name(M)] from [job]")
+ feedback_inc("ban_job",1)
+ feedback_add_details("ban_job","- [job]")
+ jobban_fullban(M, job, reason)
+ if(!msg) msg = job
+ else msg += ", [job]"
+ message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg]", 1)
+ M << "\redYou have been jobbanned by [usr.client.ckey] from: [msg]. "
+ M << "\red The reason is: [reason] "
+ M << "\red Jobban can be lifted only upon request."
+ href_list["jobban2"] = 1 // lets it fall through and refresh
+ return 1
+
+ //Unbanning joblist
+ //all jobs in joblist are banned already OR we didn't give a reason (implying they shouldn't be banned)
+ if(joblist.len) //at least 1 banned job exists in joblist so we have stuff to unban.
+ var/msg
+ for(var/job in joblist)
+ var/reason = jobban_isbanned(M, job)
+ if(!reason) continue //skip if it isn't jobbanned anyway
+ switch(alert("Job: '[job]' Reason: '[reason]' Un-jobban?","Please Confirm","Yes","No"))
+ if("Yes")
+ ban_unban_log_save("[key_name(usr)] unjobbanned [key_name(M)] from [job]")
+ log_admin("[key_name(usr)] unbanned [key_name(M)] from [job]")
+ feedback_inc("ban_job_unban",1)
+ feedback_add_details("ban_job_unban","- [job]")
+ jobban_unban(M, job)
+ if(!msg) msg = job
+ else msg += ", [job]"
+ else
+ continue
+ if(msg)
+ message_admins("\blue [key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg]", 1)
+ M << "\redYou have been un-jobbanned by [usr.client.ckey] from [msg]. "
+ href_list["jobban2"] = 1 // lets it fall through and refresh
+ return 1
+ return 0 //we didn't do anything!
+
+ if (href_list["boot2"])
+ if ((src.rank in list( "Moderator", "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["boot2"])
+ if (ismob(M))
+ if ((M.client && M.client.holder && (M.client.holder.level >= src.level)))
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+ M << "\red You have been kicked from the server"
+ log_admin("[key_name(usr)] booted [key_name(M)].")
+ message_admins("\blue [key_name_admin(usr)] booted [key_name_admin(M)].", 1)
+ //M.client = null
+ del(M.client)
+
+ if (href_list["removejobban"])
+ if ((src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/t = href_list["removejobban"]
+ if(t)
+ log_admin("[key_name(usr)] removed [t]")
+ message_admins("\blue [key_name_admin(usr)] removed [t]", 1)
+ jobban_remove(t)
+ href_list["ban"] = 1 // lets it fall through and refresh
+
+ if (href_list["newban"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["newban"])
+ if(!ismob(M)) return
+ if ((M.client && M.client.holder && (M.client.holder.level >= src.level)))
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+ switch(alert("Temporary Ban?",,"Yes","No", "Cancel"))
+ if("Yes")
+ var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
+ if(!mins)
+ return
+ if(mins >= 525600) mins = 525599
+ var/reason = input(usr,"Reason?","reason","Griefer") as text|null
+ if(!reason)
+ return
+ AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
+ ban_unban_log_save("[usr.client.ckey] has banned [M.ckey]. - Reason: [reason] - This will be removed in [mins] minutes.")
+ M << "\redYou have been banned by [usr.client.ckey].\nReason: [reason]. "
+ M << "\red This is a temporary ban, it will be removed in [mins] minutes."
+ feedback_inc("ban_tmp",1)
+ feedback_inc("ban_tmp_mins",mins)
+ if(config.banappeals)
+ M << "\red To try to resolve this matter head to [config.banappeals]"
+ else
+ M << "\red No ban appeals URL has been set."
+ log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
+ message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
+
+ del(M.client)
+ //del(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends.
+ if("No")
+ var/reason = input(usr,"Reason?","reason","Griefer") as text|null
+ if(!reason)
+ return
+ AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0)
+ M << "\redYou have been banned by [usr.client.ckey].\nReason: [reason]. "
+ M << "\red This is a permanent ban."
+ if(config.banappeals)
+ M << "\red To try to resolve this matter head to [config.banappeals]"
+ else
+ M << "\red No ban appeals URL has been set."
+ ban_unban_log_save("[usr.client.ckey] has permabanned [M.ckey]. - Reason: [reason] - This is a permanent ban.")
+ log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
+ message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
+ feedback_inc("ban_perma",1)
+
+ del(M.client)
+ //del(M)
+ if("Cancel")
+ return
+ if (href_list["newjobban1"])
+ var/mob/M = locate(href_list["newjobban1"])
+ var/dat = ""
+ var/header = "Pick Job to ban this guy from. "
+ var/body
+// var/list/alljobs = get_all_jobs()
+ var/jobs = ""
+ jobs += "Heads "
+ jobs += "Security "
+ jobs += "Engineering "
+ jobs += "Research "
+ jobs += "Medical "
+
+ jobs += "CE+Station Engineer "
+ jobs += "CE+Atmospheric Tech "
+ jobs += "CE+Shaft Miner "
+ jobs += "Chemist+RD+CMO "
+ jobs += "Geneticist+RD+CMO "
+ jobs += "MD+CMO "
+ jobs += "Virologist+RD+CMO "
+ jobs += "Scientist+RD "
+ jobs += "AI+Cyborg "
+ jobs += "Detective+HoS "
+ for(var/datum/job/job in job_master.occupations)
+ if(jobban_isbanned(M, job.title))
+ jobs += "[dd_replacetext(job.title, " ", " ")] "
+ else
+ jobs += "[dd_replacetext(job.title, " ", " ")] " //why doesn't this work the stupid cunt
+
+/* if(jobban_isbanned(M, "Captain"))
+ jobs += "Captain "
+ else
+ jobs += "Captain " //why doesn't this work the stupid cunt
+*/
+ if(jobban_isbanned(M, "Syndicate"))
+ jobs += "[dd_replacetext("Syndicate", " ", " ")] "
+ else
+ jobs += "[dd_replacetext("Syndicate", " ", " ")] " //why doesn't this work the stupid cunt
+
+ body = " [jobs] "
+ dat = "[header][body] "
+ usr << browse(dat, "window=jobban2;size=600x250")
+ return
+ if(href_list["newjobban2"])
+ if ((src.rank in list("Moderator", "Administrator", "Badmin", "Tyrant" )))
+ var/mob/M = locate(href_list["jobban4"])
+ var/job = href_list["newjobban2"]
+ if(!ismob(M)) return
+ //if ((M.client && M.client.holder && (M.client.holder.level >= src.level)))
+ // alert("You cannot perform this action. You must be of a higher administrative rank!")
+ // return
+ switch(alert("Temporary Ban?",,"Yes","No", "Cancel"))
+ if("Yes")
+ var/mins = input(usr,"How long (in days)?","Ban time",7) as num
+ mins = mins * 24 * 60
+ if(!mins)
+ return
+ if(mins >= 525600) mins = 525599
+ var/reason = input(usr,"Reason?","reason","Griefer") as text
+ if(!reason)
+ return
+ if(AddBanjob(M.ckey, M.computer_id, reason, usr.ckey, 1, mins, job))
+ M << "\redYou have been jobbanned from [job] by [usr.client.ckey].\nReason: [reason]. "
+ M << "\red This is a temporary ban, it will be removed in [mins] minutes."
+ if(config.banappeals)
+ M << "\red To try to resolve this matter head to [config.banappeals]"
+ else
+ M << "\red No ban appeals URL has been set."
+ ban_unban_log_save("[usr.client.ckey] has jobbanned [M.ckey] from [job]. - Reason: [reason] - This will be removed in [mins] minutes.")
+ feedback_inc("ban_job",1)
+ feedback_add_details("ban_job","- [job]")
+ log_admin("[usr.client.ckey] has banned [M.ckey] from [job].\nReason: [reason]\nThis will be removed in [mins] minutes.")
+ message_admins("\blue[usr.client.ckey] has banned [M.ckey] from [job].\nReason: [reason]\nThis will be removed in [mins] minutes.")
+
+ //del(M.client)
+ //del(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends.
+ if("No")
+ var/reason = input(usr,"Reason?","reason","Griefer") as text
+ if(!reason)
+ return
+ if(AddBanjob(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, job))
+ M << "\redYou have been banned from [job] by [usr.client.ckey].\nReason: [reason]. "
+ M << "\red This is a permanent ban."
+ if(config.banappeals)
+ M << "\red To try to resolve this matter head to [config.banappeals]"
+ else
+ M << "\red No ban appeals URL has been set."
+ ban_unban_log_save("[usr.client.ckey] has banned [M.ckey] from [job]. - Reason: [reason] - This is a permanent ban.")
+ feedback_inc("ban_job_tmp",1)
+ feedback_add_details("ban_job_tmp","- [job]")
+ log_admin("[usr.client.ckey] has banned [M.ckey] from [job].\nReason: [reason]\nThis is a permanent ban.")
+ message_admins("\blue[usr.client.ckey] has banned [M.ckey] from [job].\nReason: [reason]\nThis is a permanent ban.")
+
+ //del(M.client)
+ //del(M)
+ if("Cancel")
+ return
+
+ if(href_list["unjobbanf"])
+ var/banfolder = href_list["unjobbanf"]
+ Banlist.cd = "/base/[banfolder]"
+ var/key = Banlist["key"]
+ if(alert(usr, "Are you sure you want to unban [key]?", "Confirmation", "Yes", "No") == "Yes")
+ if (RemoveBanjob(banfolder))
+ unjobbanpanel()
+ else
+ alert(usr,"This ban has already been lifted / does not exist.","Error","Ok")
+ unjobbanpanel()
+
+ if(href_list["unjobbane"])
+ return
+/*
+ if (href_list["remove"])
+ if ((src.rank in list( "Admin Candidate", "Trial Admin", "Badmin", "Game Admin", "Game Master" )))
+ var/t = href_list["remove"]
+ if(t && isgoon(t))
+ log_admin("[key_name(usr)] removed [t] from the goonlist.")
+ message_admins("\blue [key_name_admin(usr)] removed [t] from the goonlist.")
+ remove_goon(t)
+*/
+ if (href_list["mute2"])
+ if ((src.rank in list( "Moderator", "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["mute2"])
+ if (ismob(M))
+ if ((M.client && M.client.holder && (M.client.holder.level >= src.level)))
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+ if(!M.client)
+ src << "This mob doesn't have a client tied to it."
+ return
+ M.client.muted = !M.client.muted
+ log_admin("[key_name(usr)] has [(M.client.muted ? "muted" : "voiced")] [key_name(M)].")
+ message_admins("\blue [key_name_admin(usr)] has [(M.client.muted ? "muted" : "voiced")] [key_name_admin(M)].", 1)
+ M << "You have been [(M.client.muted ? "muted" : "voiced")]. Please resolve this in adminhelp."
+ if (href_list["mute_complete"])
+ if ((src.rank in list( "Moderator", "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["mute_complete"])
+ if (ismob(M))
+ if ((M.client && M.client.holder && (M.client.holder.level >= src.level)))
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+ if(!M.client)
+ src << "This mob doesn't have a client tied to it."
+ return
+ M.client.muted_complete = !M.client.muted_complete
+ log_admin("[key_name(usr)] has [(M.client.muted_complete ? "completely muted" : "voiced (complete)")] [key_name(M)].")
+ message_admins("\blue [key_name_admin(usr)] has [(M.client.muted_complete ? "completely muted" : "voiced (complete)")] [key_name_admin(M)].", 1)
+ M << "You have been [(M.client.muted_complete ? "completely muted" : "voiced (complete)")]. You are unable to speak or even adminhelp"
+
+ if (href_list["c_mode"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ if (ticker && ticker.mode)
+ return alert(usr, "The game has already started.", null, null, null, null)
+ var/dat = {"What mode do you wish to play? "}
+ for (var/mode in config.modes)
+ dat += {"[config.mode_names[mode]] "}
+ dat += {"Secret "}
+ dat += {"Random "}
+ dat += {"Now: [master_mode]"}
+ usr << browse(dat, "window=c_mode")
+
+ if (href_list["f_secret"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ if (ticker && ticker.mode)
+ return alert(usr, "The game has already started.", null, null, null, null)
+ if (master_mode != "secret")
+ return alert(usr, "The game mode has to be secret!", null, null, null, null)
+ var/dat = {"What game mode do you want to force secret to be? Use this if you want to change the game mode, but want the players to believe it's secret. This will only work if the current game mode is secret. "}
+ for (var/mode in config.modes)
+ dat += {"[config.mode_names[mode]] "}
+ dat += {"Random (default) "}
+ dat += {"Now: [secret_force_mode]"}
+ usr << browse(dat, "window=f_secret")
+
+ if (href_list["c_mode2"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ if (ticker && ticker.mode)
+ return alert(usr, "The game has already started.", null, null, null, null)
+ master_mode = href_list["c_mode2"]
+ log_admin("[key_name(usr)] set the mode as [master_mode].")
+ message_admins("\blue [key_name_admin(usr)] set the mode as [master_mode].", 1)
+ world << "\blue The mode is now: [master_mode] "
+ Game() // updates the main game menu
+ world.save_mode(master_mode)
+ .(href, list("c_mode"=1))
+
+ if (href_list["f_secret2"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ if (ticker && ticker.mode)
+ return alert(usr, "The game has already started.", null, null, null, null)
+ if (master_mode != "secret")
+ return alert(usr, "The game mode has to be secret!", null, null, null, null)
+ secret_force_mode = href_list["f_secret2"]
+ log_admin("[key_name(usr)] set the forced secret mode as [secret_force_mode].")
+ message_admins("\blue [key_name_admin(usr)] set the forced secret mode as [secret_force_mode].", 1)
+ Game() // updates the main game menu
+ .(href, list("f_secret"=1))
+
+ if (href_list["monkeyone"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["monkeyone"])
+ if(!ismob(M))
+ return
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/N = M
+ log_admin("[key_name(usr)] attempting to monkeyize [key_name(M)]")
+ message_admins("\blue [key_name_admin(usr)] attempting to monkeyize [key_name_admin(M)]", 1)
+ N.monkeyize()
+ if(istype(M, /mob/living/silicon))
+ alert("The AI can't be monkeyized!", null, null, null, null, null)
+ return
+
+ if (href_list["corgione"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["corgione"])
+ if(!ismob(M))
+ return
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/N = M
+ log_admin("[key_name(usr)] attempting to corgize [key_name(M)]")
+ message_admins("\blue [key_name_admin(usr)] attempting to corgize [key_name_admin(M)]", 1)
+ N.corgize()
+ if(istype(M, /mob/living/silicon))
+ alert("The AI can't be corgized!", null, null, null, null, null)
+ return
+
+ if (href_list["forcespeech"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["forcespeech"])
+ if (ismob(M))
+ var/speech = input("What will [key_name(M)] say?.", "Force speech", "")
+ if(!speech)
+ return
+ M.say(speech)
+ speech = copytext(sanitize(speech), 1, MAX_MESSAGE_LEN)
+ log_admin("[key_name(usr)] forced [key_name(M)] to say: [speech]")
+ message_admins("\blue [key_name_admin(usr)] forced [key_name_admin(M)] to say: [speech]")
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+
+ if (href_list["sendtoprison"])
+ if ((src.rank in list( "Moderator", "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["sendtoprison"])
+ if (ismob(M))
+ if(istype(M, /mob/living/silicon/ai))
+ alert("The AI can't be sent to prison you jerk!", null, null, null, null, null)
+ return
+ //strip their stuff before they teleport into a cell :downs:
+ for(var/obj/item/weapon/W in M)
+ if(istype(W, /datum/organ/external))
+ continue
+ //don't strip organs
+ M.u_equip(W)
+ if (M.client)
+ M.client.screen -= W
+ if (W)
+ W.loc = M.loc
+ W.dropped(M)
+ W.layer = initial(W.layer)
+ //teleport person to cell
+ M.Paralyse(5)
+ sleep(5) //so they black out before warping
+ M.loc = pick(prisonwarp)
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/prisoner = M
+ prisoner.equip_if_possible(new /obj/item/clothing/under/color/orange(prisoner), prisoner.slot_w_uniform)
+ prisoner.equip_if_possible(new /obj/item/clothing/shoes/orange(prisoner), prisoner.slot_shoes)
+ spawn(50)
+ M << "\red You have been sent to the prison station!"
+ log_admin("[key_name(usr)] sent [key_name(M)] to the prison station.")
+ message_admins("\blue [key_name_admin(usr)] sent [key_name_admin(M)] to the prison station.", 1)
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+
+/*
+ if (href_list["sendtomaze"])
+ if ((src.rank in list( "Admin Candidate", "Temporary Admin", "Trial Admin", "Badmin", "Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["sendtomaze"])
+ if (ismob(M))
+ if(istype(M, /mob/living/silicon/ai))
+ alert("The AI can't be sent to the maze you jerk!", null, null, null, null, null)
+ return
+ //strip their stuff before they teleport into a cell :downs:
+ for(var/obj/item/weapon/W in M)
+ if(istype(W, /datum/organ/external))
+ continue
+ //don't strip organs
+ M.u_equip(W)
+ if (M.client)
+ M.client.screen -= W
+ if (W)
+ W.loc = M.loc
+ W.dropped(M)
+ W.layer = initial(W.layer)
+ //teleport person to cell
+ M.paralysis += 5
+ sleep(5)
+ //so they black out before warping
+ M.loc = pick(mazewarp)
+ spawn(50)
+ M << "\red You have been sent to the maze! Try and get out alive. In the maze everyone is free game. Kill or be killed."
+ log_admin("[key_name(usr)] sent [key_name(M)] to the maze.")
+ message_admins("\blue [key_name_admin(usr)] sent [key_name_admin(M)] to the maze.", 1)
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+*/
+
+ if (href_list["tdome1"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["tdome1"])
+ if (ismob(M))
+ if(istype(M, /mob/living/silicon/ai))
+ alert("The AI can't be sent to the thunderdome you jerk!", null, null, null, null, null)
+ return
+ for(var/obj/item/W in M)
+ if (istype(W,/obj/item))
+ if(istype(W, /datum/organ/external))
+ continue
+ M.u_equip(W)
+ if (M.client)
+ M.client.screen -= W
+ if (W)
+ W.loc = M.loc
+ W.dropped(M)
+ W.layer = initial(W.layer)
+ M.Paralyse(5)
+ sleep(5)
+ M.loc = pick(tdome1)
+ spawn(50)
+ M << "\blue You have been sent to the Thunderdome."
+ log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Team 1)")
+ message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Team 1)", 1)
+
+ if (href_list["tdome2"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["tdome2"])
+ if (ismob(M))
+ if(istype(M, /mob/living/silicon/ai))
+ alert("The AI can't be sent to the thunderdome you jerk!", null, null, null, null, null)
+ return
+ for(var/obj/item/W in M)
+ if (istype(W,/obj/item))
+ if(istype(W, /datum/organ/external))
+ continue
+ M.u_equip(W)
+ if (M.client)
+ M.client.screen -= W
+ if (W)
+ W.loc = M.loc
+ W.dropped(M)
+ W.layer = initial(W.layer)
+ M.Paralyse(5)
+ sleep(5)
+ M.loc = pick(tdome2)
+ spawn(50)
+ M << "\blue You have been sent to the Thunderdome."
+ log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Team 2)")
+ message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Team 2)", 1)
+
+ if (href_list["tdomeadmin"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["tdomeadmin"])
+ if (ismob(M))
+ if(istype(M, /mob/living/silicon/ai))
+ alert("The AI can't be sent to the thunderdome you jerk!", null, null, null, null, null)
+ return
+ M.Paralyse(5)
+ sleep(5)
+ M.loc = pick(tdomeadmin)
+ spawn(50)
+ M << "\blue You have been sent to the Thunderdome."
+ log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Admin.)")
+ message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Admin.)", 1)
+
+ if (href_list["tdomeobserve"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["tdomeobserve"])
+ if (ismob(M))
+ if(istype(M, /mob/living/silicon/ai))
+ alert("The AI can't be sent to the thunderdome you jerk!", null, null, null, null, null)
+ return
+ for(var/obj/item/W in M)
+ if (istype(W,/obj/item))
+ if(istype(W, /datum/organ/external))
+ continue
+ M.u_equip(W)
+ if (M.client)
+ M.client.screen -= W
+ if (W)
+ W.loc = M.loc
+ W.dropped(M)
+ W.layer = initial(W.layer)
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/observer = M
+ observer.equip_if_possible(new /obj/item/clothing/under/suit_jacket(observer), observer.slot_w_uniform)
+ observer.equip_if_possible(new /obj/item/clothing/shoes/black(observer), observer.slot_shoes)
+ M.Paralyse(5)
+ sleep(5)
+ M.loc = pick(tdomeobserve)
+ spawn(50)
+ M << "\blue You have been sent to the Thunderdome."
+ log_admin("[key_name(usr)] has sent [key_name(M)] to the thunderdome. (Observer.)")
+ message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Observer.)", 1)
+
+ if (href_list["adminauth"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/M = locate(href_list["adminauth"])
+ if (ismob(M) && !M.client.authenticated && !M.client.authenticating)
+ M.client.verbs -= /client/proc/authorize
+ M.client.authenticated = text("admin/[]", usr.client.authenticated)
+ log_admin("[key_name(usr)] authorized [key_name(M)]")
+ message_admins("\blue [key_name_admin(usr)] authorized [key_name_admin(M)]", 1)
+ M.client << text("You have been authorized by []", usr.key)
+
+ if (href_list["revive"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/mob/living/M = locate(href_list["revive"])
+ if (isliving(M))
+ if(config.allow_admin_rev)
+ M.revive()
+ message_admins("\red Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!", 1)
+ log_admin("[key_name(usr)] healed / Rrvived [key_name(M)]")
+ return
+ else
+ alert("Admin revive disabled")
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+
+ if (href_list["makeai"]) //Yes, im fucking lazy, so what? it works ... hopefully
+ if (src.level>=3)
+ var/mob/M = locate(href_list["makeai"])
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ message_admins("\red Admin [key_name_admin(usr)] AIized [key_name_admin(M)]!", 1)
+// if (ticker.mode.name == "AI malfunction")
+// var/obj/O = locate("landmark*ai")
+// M << "\blue You have been teleported to your new starting location! "
+// M.loc = O.loc
+// M.buckled = null
+// else
+// var/obj/S = locate(text("start*AI"))
+// if ((istype(S, /obj/effect/landmark/start) && istype(S.loc, /turf)))
+// M << "\blue You have been teleported to your new starting location! "
+// M.loc = S.loc
+// M.buckled = null
+ // world << "[M.real_name] is the AI! "
+ log_admin("[key_name(usr)] AIized [key_name(M)]")
+ H.AIize()
+ else
+ alert("I cannot allow this.")
+ return
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+
+ if (href_list["makealien"])
+ if (src.level>=3)
+ var/mob/M = locate(href_list["makealien"])
+ if(istype(M, /mob/living/carbon/human))
+ usr.client.cmd_admin_alienize(M)
+ else
+ alert("Wrong mob. Must be human.")
+ return
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+
+ if (href_list["makemetroid"])
+ if (src.level>=3)
+ var/mob/M = locate(href_list["makemetroid"])
+ if(istype(M, /mob/living/carbon/human))
+ usr.client.cmd_admin_metroidize(M)
+ else
+ alert("Wrong mob. Must be human.")
+ return
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+
+ if (href_list["makerobot"])
+ if (src.level>=3)
+ var/mob/M = locate(href_list["makerobot"])
+ if(istype(M, /mob/living/carbon/human))
+ usr.client.cmd_admin_robotize(M)
+ else
+ alert("Wrong mob. Must be human.")
+ return
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+/***************** BEFORE**************
+
+ if (href_list["l_players"])
+ var/dat = "Name/Real Name/Key/IP: "
+ for(var/mob/M in world)
+ var/foo = ""
+ if (ismob(M) && M.client)
+ if(!M.client.authenticated && !M.client.authenticating)
+ foo += text("\[ Authorize | ", src, M)
+ else
+ foo += text("\[ Authorized | ")
+ if(M.start)
+ if(!istype(M, /mob/living/carbon/monkey))
+ foo += text("Monkeyize | ", src, M)
+ else
+ foo += text("Monkeyized | ")
+ if(istype(M, /mob/living/silicon/ai))
+ foo += text("Is an AI | ")
+ else
+ foo += text("Make AI | ", src, M)
+ if(M.z != 2)
+ foo += text("Prison | ", src, M)
+ foo += text("Maze | ", src, M)
+ else
+ foo += text("On Z = 2 | ")
+ else
+ foo += text("Hasn't Entered Game | ")
+ foo += text("Heal/Revive | ", src, M)
+
+ foo += text("Say \]", src, M)
+ dat += text("N: [] R: [] (K: []) (IP: []) [] ", M.name, M.real_name, (M.client ? M.client : "No client"), M.lastKnownIP, foo)
+
+ usr << browse(dat, "window=players;size=900x480")
+
+*****************AFTER******************/
+
+// Now isn't that much better? IT IS NOW A PROC, i.e. kinda like a big panel like unstable
+
+ if (href_list["adminplayeropts"])
+ var/mob/M = locate(href_list["adminplayeropts"])
+ show_player_panel(M)
+
+ if (href_list["adminplayervars"])
+ var/mob/M = locate(href_list["adminplayervars"])
+ if(src && src.owner)
+ if(istype(src.owner,/client))
+ var/client/cl = src.owner
+ cl.debug_variables(M)
+ else if(ismob(src.owner))
+ var/mob/MO = src.owner
+ if(MO.client)
+ var/client/cl = MO.client
+ cl.debug_variables(M)
+
+ if (href_list["adminplayersubtlemessage"])
+ var/mob/M = locate(href_list["adminplayersubtlemessage"])
+ if(src && src.owner)
+ if(istype(src.owner,/client))
+ var/client/cl = src.owner
+ cl.cmd_admin_subtle_message(M)
+ else if(ismob(src.owner))
+ var/mob/MO = src.owner
+ if(MO.client)
+ var/client/cl = MO.client
+ cl.cmd_admin_subtle_message(M)
+
+ if (href_list["adminplayerobservejump"])
+ var/mob/M = locate(href_list["adminplayerobservejump"])
+ if(src && src.owner)
+ if(istype(src.owner,/client))
+ var/client/cl = src.owner
+ cl.admin_observe()
+ sleep(2)
+ cl.jumptomob(M)
+ else if(ismob(src.owner))
+ var/mob/MO = src.owner
+ if(MO.client)
+ var/client/cl = MO.client
+ cl.admin_observe()
+ sleep(2)
+ cl.jumptomob(M)
+
+
+
+
+
+ if (href_list["BlueSpaceArtillery"])
+ var/mob/M = locate(href_list["BlueSpaceArtillery"])
+ if(!M)
+ return
+
+ var/choice = alert(src.owner, "Are you sure you wish to hit [key_name(M)] with Blue Space Artillery?", "Confirm Firing?" , "Yes" , "No")
+ if (choice == "No")
+ return
+
+ if(BSACooldown)
+ src.owner << "Standby! Reload cycle in progress! Gunnary crews ready in five seconds!"
+ return
+
+ BSACooldown = 1
+ spawn(50)
+ BSACooldown = 0
+
+
+ M << "You've been hit by bluespace artillery!"
+ log_admin("[key_name(M)] has been hit by Bluespace Artillery fired by [src.owner]")
+ message_admins("[key_name(M)] has been hit by Bluespace Artillery fired by [src.owner]")
+ var/obj/effect/stop/S
+ S = new /obj/effect/stop
+ S.victim = M
+ S.loc = M.loc
+ spawn(20)
+ del(S)
+
+ var/turf/T = get_turf(M)
+ if(T && (istype(T,/turf/simulated/floor/)))
+ if(prob(80))
+ T:break_tile_to_plating()
+ else
+ T:break_tile()
+
+ if(M.health == 1)
+ M.gib()
+ else
+ M.adjustBruteLoss( min( 99 , (M.health - 1) ) )
+ M.Stun(20)
+ M.Weaken(20)
+ M.stuttering = 20
+
+ if (href_list["CentcommReply"])
+ var/mob/M = locate(href_list["CentcommReply"])
+ if(!M)
+ return
+ if(!istype(M, /mob/living/carbon/human))
+ alert("Centcomm cannot transmit to non-humans.")
+ return
+ if(!istype(M:ears, /obj/item/device/radio/headset))
+ alert("The person you're trying to reply to doesn't have a headset! Centcomm cannot transmit directly to them.")
+ return
+ var/input = input(src.owner, "Please enter a message to reply to [key_name(M)] via their headset.","Outgoing message from Centcomm", "")
+ if(!input)
+ return
+
+ src.owner << "You sent [input] to [M] via a secure channel."
+ log_admin("[src.owner] replied to [key_name(M)]'s Centcomm message with the message [input].")
+ M << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows. [input]. Message ends.\""
+
+ return
+
+ if (href_list["SyndicateReply"])
+ var/mob/M = locate(href_list["SyndicateReply"])
+ if(!M)
+ return
+ if(!istype(M, /mob/living/carbon/human))
+ alert("The Syndicate cannot transmit to non-humans.")
+ return
+ if(!istype(M:ears, /obj/item/device/radio/headset))
+ alert("The person you're trying to reply to doesn't have a headset! The Syndicate cannot transmit directly to them.")
+ return
+ var/input = input(src.owner, "Please enter a message to reply to [key_name(M)] via their headset.","Outgoing message from The Syndicate", "")
+ if(!input)
+ return
+
+ src.owner << "You sent [input] to [M] via a secure channel."
+ log_admin("[src.owner] replied to [key_name(M)]'s Syndicate message with the message [input].")
+ M << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from your benefactor. Message as follows, agent. [input]. Message ends.\""
+
+ return
+
+ if (href_list["jumpto"])
+ if(rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ var/mob/M = locate(href_list["jumpto"])
+ usr.client.jumptomob(M)
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+
+ if (href_list["getmob"])
+ if(rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ var/mob/M = locate(href_list["getmob"])
+ usr.client.Getmob(M)
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+
+ if (href_list["sendmob"])
+ if(rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ var/mob/M = locate(href_list["sendmob"])
+ usr.client.sendmob(M)
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+
+ if (href_list["narrateto"])
+ if(rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ var/mob/M = locate(href_list["narrateto"])
+ usr.client.cmd_admin_direct_narrate(M)
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+
+ if (href_list["subtlemessage"])
+ var/mob/M = locate(href_list["subtlemessage"])
+ usr.client.cmd_admin_subtle_message(M)
+
+ if (href_list["traitor"])
+ if(!ticker || !ticker.mode)
+ alert("The game hasn't started yet!")
+ return
+ var/mob/M = locate(href_list["traitor"])
+ if (!istype(M))
+ player_panel_new()
+ return
+ if(isalien(M))
+ alert("Is an [M.mind ? M.mind.special_role : "Alien"]!", "[M.key]")
+ return
+ if (M:mind)
+ M:mind.edit_memory()
+ return
+ alert("Cannot make this mob a traitor! It has no mind!")
+
+ if (href_list["create_object"])
+ if (src.rank in list("Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ return create_object(usr)
+ else
+ alert("You are not a high enough administrator! Sorry!!!!")
+
+ if (href_list["create_turf"])
+ if (src.rank in list("Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ return create_turf(usr)
+ else
+ alert("You are not a high enough administrator! Sorry!!!!")
+ if (href_list["create_mob"])
+ if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ return create_mob(usr)
+ else
+ alert("You are not a high enough administrator! Sorry!!!!")
+ if (href_list["vmode"])
+ vmode()
+
+ if (href_list["votekill"])
+ votekill()
+
+ if (href_list["voteres"])
+ voteres()
+
+ if (href_list["prom_demot"])
+ if ((src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/client/C = locate(href_list["prom_demot"])
+ if(C.holder && (C.holder.level >= src.level))
+ alert("This cannot be done as [C] is a [C.holder.rank]")
+ return
+ var/dat = "[C] is a [C.holder ? "[C.holder.rank]" : "non-admin"] Change [C]'s rank? "
+ if(src.level == 6)
+ //Game Master
+ dat += {"
+ Senior Game Admin
+ Game Admin
+ Secondary Game Admin
+ Trial admin
+ Temporary Admin
+ Moderator
+ Admin Observer
+ Remove Admin "}
+ else if(src.level == 5)
+ //Senior Admin
+ dat += {"
+ Game Admin
+ Secondary Game Admin
+ Trial admin
+ Temporary Admin
+ Moderator
+ Admin Observer
+ Remove Admin "}
+ else if(src.level == 4)
+ //Game Admin
+ dat += {"
+ Secondary Game Admin
+ Trial admin
+ Temporary Admin
+ Moderator
+ Admin Observer
+ Remove Admin "}
+ else if(src.level == 3)
+ //Secondary Game Admin
+ dat += {"
+ Trial admin
+ Temporary Admin
+ Moderator
+ Admin Observer
+ Remove Admin "}
+ else
+ alert("Not a high enough level admin, sorry.")
+ return
+ usr << browse(dat, "window=prom_demot;size=480x300")
+
+ if (href_list["chgadlvl"])
+ //change admin level
+ var/rank = href_list["chgadlvl"]
+ var/client/C = locate(href_list["client4ad"])
+ if(rank == "Remove")
+ C.clear_admin_verbs()
+ C.update_admins(null)
+ log_admin("[key_name(usr)] has removed [C]'s adminship")
+ message_admins("[key_name_admin(usr)] has removed [C]'s adminship", 1)
+ admins.Remove(C.ckey)
+ else
+ C.clear_admin_verbs()
+ C.update_admins(rank)
+ log_admin("[key_name(usr)] has made [C] a [rank]")
+ message_admins("[key_name_admin(usr)] has made [C] a [rank]", 1)
+ admins[C.ckey] = rank
+
+
+ if (href_list["object_list"])
+ if (src.rank in list("Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ if (config.allow_admin_spawning && ((src.state == 2) || (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))))
+ var/atom/loc = usr.loc
+
+ var/dirty_paths
+ if (istext(href_list["object_list"]))
+ dirty_paths = list(href_list["object_list"])
+ else if (istype(href_list["object_list"], /list))
+ dirty_paths = href_list["object_list"]
+
+ var/paths = list()
+ var/removed_paths = list()
+ for (var/dirty_path in dirty_paths)
+ var/path = text2path(dirty_path)
+ if (!path)
+ removed_paths += dirty_path
+ else if (!ispath(path, /obj) && !ispath(path, /turf) && !ispath(path, /mob))
+ removed_paths += dirty_path
+ else if (ispath(path, /obj/item/weapon/gun/energy/pulse_rifle) && !(src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")))
+ removed_paths += dirty_path
+ else if (ispath(path, /obj/item/weapon/melee/energy/blade))//Not an item one should be able to spawn./N
+ removed_paths += dirty_path
+ else if (ispath(path, /obj/effect/bhole) && !(src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")))
+ removed_paths += dirty_path
+ else if (ispath(path, /mob) && !(src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")))
+ removed_paths += dirty_path
+
+ else
+ paths += path
+
+ if (!paths)
+ return
+ else if (length(paths) > 5)
+ alert("Select less object types, (max 5)")
+ return
+ else if (length(removed_paths))
+ alert("Removed:\n" + dd_list2text(removed_paths, "\n"))
+
+ var/list/offset = dd_text2list(href_list["offset"],",")
+ var/number = dd_range(1, 100, text2num(href_list["object_count"]))
+ var/X = offset.len > 0 ? text2num(offset[1]) : 0
+ var/Y = offset.len > 1 ? text2num(offset[2]) : 0
+ var/Z = offset.len > 2 ? text2num(offset[3]) : 0
+ var/tmp_dir = href_list["object_dir"]
+ var/obj_dir = tmp_dir ? text2num(tmp_dir) : 2
+ if(!obj_dir || !(obj_dir in list(1,2,4,8,5,6,9,10)))
+ obj_dir = 2
+ var/obj_name = sanitize(href_list["object_name"])
+ var/where = href_list["object_where"]
+ if (!( where in list("onfloor","inhand","inmarked") ))
+ where = "onfloor"
+
+ //TODO ERRORAGE
+ if( where == "inhand" )
+ usr << "Support for inhand not available yet. Will spawn on floor."
+ where = "onfloor"
+ //END TODO ERRORAGE
+
+ if ( where == "inhand" ) //Can only give when human or monkey
+ if ( !( ishuman(usr) || ismonkey(usr) ) )
+ usr << "Can only spawn in hand when you're a human or a monkey."
+ where = "onfloor"
+ else if ( usr.get_active_hand() )
+ usr << "Your active hand is full. Spawning on floor."
+ where = "onfloor"
+ if ( where == "inmarked" )
+ if ( !marked_datum )
+ usr << "You don't have any object marked. Abandoning spawn."
+ return
+ else
+ if ( !istype(marked_datum,/atom) )
+ usr << "The object you have marked cannot be used as a target. Target must be of type /atom. Abandoning spawn."
+ return
+
+ var/atom/target //Where the object will be spawned
+ switch ( where )
+ if ( "onfloor" )
+ switch (href_list["offset_type"])
+ if ("absolute")
+ target = locate(0 + X,0 + Y,0 + Z)
+ if ("relative")
+ target = locate(loc.x + X,loc.y + Y,loc.z + Z)
+ if ( "inmarked" )
+ target = marked_datum
+
+
+ //TODO ERRORAGE - Give support for "inhand"
+
+ if(target)
+ for (var/path in paths)
+ for (var/i = 0; i < number; i++)
+ var/atom/O = new path(target)
+ if(O)
+ O.dir = obj_dir
+ if(obj_name)
+ O.name = obj_name
+ if(istype(O,/mob))
+ var/mob/M = O
+ M.real_name = obj_name
+
+
+
+ if (number == 1)
+ log_admin("[key_name(usr)] created a [english_list(paths)]")
+ for(var/path in paths)
+ if(ispath(path, /mob))
+ message_admins("[key_name_admin(usr)] created a [english_list(paths)]", 1)
+ break
+ else
+ log_admin("[key_name(usr)] created [number]ea [english_list(paths)]")
+ for(var/path in paths)
+ if(ispath(path, /mob))
+ message_admins("[key_name_admin(usr)] created [number]ea [english_list(paths)]", 1)
+ break
+ return
+ else
+ alert("You cannot spawn items right now.")
+ return
+
+ if (href_list["secretsfun"])
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/ok = 0
+ switch(href_list["secretsfun"])
+ if("sec_clothes")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SC")
+ for(var/obj/item/clothing/under/O in world)
+ del(O)
+ ok = 1
+ if("sec_all_clothes")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SAC")
+ for(var/obj/item/clothing/O in world)
+ del(O)
+ ok = 1
+ if("sec_classic1")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SC1")
+ for(var/obj/item/clothing/suit/fire/O in world)
+ del(O)
+ for(var/obj/structure/grille/O in world)
+ del(O)
+/* for(var/obj/machinery/vehicle/pod/O in world)
+ for(var/mob/M in src)
+ M.loc = src.loc
+ if (M.client)
+ M.client.perspective = MOB_PERSPECTIVE
+ M.client.eye = M
+ del(O)
+ ok = 1*/
+ if("toxic")
+ /*
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","T")
+ for(var/obj/machinery/atmoalter/siphs/fullairsiphon/O in world)
+ O.t_status = 3
+ for(var/obj/machinery/atmoalter/siphs/scrubbers/O in world)
+ O.t_status = 1
+ O.t_per = 1000000.0
+ for(var/obj/machinery/atmoalter/canister/O in world)
+ if (!( istype(O, /obj/machinery/atmoalter/canister/oxygencanister) ))
+ O.t_status = 1
+ O.t_per = 1000000.0
+ else
+ O.t_status = 3
+ */
+ usr << "HEH"
+ if("monkey")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","M")
+ for(var/mob/living/carbon/human/H in world)
+ spawn(0)
+ H.monkeyize()
+ ok = 1
+ if("corgi")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","M")
+ for(var/mob/living/carbon/human/H in world)
+ spawn(0)
+ H.corgize()
+ ok = 1
+ if("power")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","P")
+ log_admin("[key_name(usr)] made all areas powered", 1)
+ message_admins("\blue [key_name_admin(usr)] made all areas powered", 1)
+ power_restore()
+ if("unpower")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","UP")
+ log_admin("[key_name(usr)] made all areas unpowered", 1)
+ message_admins("\blue [key_name_admin(usr)] made all areas unpowered", 1)
+ power_failure()
+ if("activateprison")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","AP")
+ world << "\blue Transit signature detected. "
+ world << "\blue Incoming shuttle. "
+ /*
+ var/A = locate(/area/shuttle_prison)
+ for(var/atom/movable/AM as mob|obj in A)
+ AM.z = 1
+ AM.Move()
+ */
+ message_admins("\blue [key_name_admin(usr)] sent the prison shuttle to the station.", 1)
+ if("deactivateprison")
+ /*
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","DP")
+ var/A = locate(/area/shuttle_prison)
+ for(var/atom/movable/AM as mob|obj in A)
+ AM.z = 2
+ AM.Move()
+ */
+ message_admins("\blue [key_name_admin(usr)] sent the prison shuttle back.", 1)
+ if("toggleprisonstatus")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","TPS")
+ for(var/obj/machinery/computer/prison_shuttle/PS in world)
+ PS.allowedtocall = !(PS.allowedtocall)
+ message_admins("\blue [key_name_admin(usr)] toggled status of prison shuttle to [PS.allowedtocall].", 1)
+ if("prisonwarp")
+ if(!ticker)
+ alert("The game hasn't started yet!", null, null, null, null, null)
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","PW")
+ message_admins("\blue [key_name_admin(usr)] teleported all players to the prison station.", 1)
+ for(var/mob/living/carbon/human/H in world)
+ var/turf/loc = find_loc(H)
+ var/security = 0
+ if(loc.z > 1 || prisonwarped.Find(H))
+ //don't warp them if they aren't ready or are already there
+ continue
+ H.Paralyse(5)
+ if(H.wear_id)
+ var/obj/item/weapon/card/id/id = H.get_idcard()
+ for(var/A in id.access)
+ if(A == access_security)
+ security++
+ if(!security)
+ //strip their stuff before they teleport into a cell :downs:
+ for(var/obj/item/weapon/W in H)
+ if(istype(W, /datum/organ/external))
+ continue
+ //don't strip organs
+ H.u_equip(W)
+ if (H.client)
+ H.client.screen -= W
+ if (W)
+ W.loc = H.loc
+ W.dropped(H)
+ W.layer = initial(W.layer)
+ //teleport person to cell
+ H.loc = pick(prisonwarp)
+ H.equip_if_possible(new /obj/item/clothing/under/color/orange(H), H.slot_w_uniform)
+ H.equip_if_possible(new /obj/item/clothing/shoes/orange(H), H.slot_shoes)
+ else
+ //teleport security person
+ H.loc = pick(prisonsecuritywarp)
+ prisonwarped += H
+ if("traitor_all")
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ if(!ticker)
+ alert("The game hasn't started yet!")
+ return
+ var/objective = input("Enter an objective")
+ if(!objective)
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","TA([objective])")
+ for(var/mob/living/carbon/human/H in world)
+ if(H.stat == 2 || !H.client || !H.mind) continue
+ if(is_special_character(H)) continue
+ //traitorize(H, objective, 0)
+ ticker.mode.traitors += H.mind
+ H.mind.special_role = "traitor"
+ var/datum/objective/new_objective = new
+ new_objective.owner = H
+ new_objective.explanation_text = objective
+ H.mind.objectives += new_objective
+ ticker.mode.greet_traitor(H)
+ //ticker.mode.forge_traitor_objectives(H.mind)
+ ticker.mode.finalize_traitor(H)
+ for(var/mob/living/silicon/A in world)
+ ticker.mode.traitors += A.mind
+ A.mind.special_role = "traitor"
+ var/datum/objective/new_objective = new
+ new_objective.owner = A
+ new_objective.explanation_text = objective
+ A.mind.objectives += new_objective
+ ticker.mode.greet_traitor(A)
+ ticker.mode.finalize_traitor(A)
+ message_admins("\blue [key_name_admin(usr)] used everyone is a traitor secret. Objective is [objective]", 1)
+ log_admin("[key_name(usr)] used everyone is a traitor secret. Objective is [objective]")
+ else
+ alert("You're not of a high enough rank to do this")
+ if("moveminingshuttle")
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ if(mining_shuttle_moving)
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","ShM")
+ move_mining_shuttle()
+ message_admins("\blue [key_name_admin(usr)] moved mining shuttle", 1)
+ log_admin("[key_name(usr)] moved the mining shuttle")
+ else
+ alert("You're not of a high enough rank to do this")
+ if("moveadminshuttle")
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","ShA")
+ move_admin_shuttle()
+ message_admins("\blue [key_name_admin(usr)] moved the centcom administration shuttle", 1)
+ log_admin("[key_name(usr)] moved the centcom administration shuttle")
+ else
+ alert("You're not of a high enough rank to do this")
+ if("moveferry")
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","ShF")
+ move_ferry()
+ message_admins("\blue [key_name_admin(usr)] moved the centcom ferry", 1)
+ log_admin("[key_name(usr)] moved the centcom ferry")
+ else
+ alert("You're not of a high enough rank to do this")
+ if("movealienship")
+ if ((src.rank in list( "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","ShX")
+ move_alien_ship()
+ message_admins("\blue [key_name_admin(usr)] moved the alien dinghy", 1)
+ log_admin("[key_name(usr)] moved the alien dinghy")
+ else
+ alert("You're not of a high enough rank to do this")
+ if("togglebombcap")
+ if (src.rank in list( "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" ))
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","BC")
+ switch(MAX_EXPLOSION_RANGE)
+ if(14)
+ MAX_EXPLOSION_RANGE = 16
+ if(16)
+ MAX_EXPLOSION_RANGE = 20
+ if(20)
+ MAX_EXPLOSION_RANGE = 28
+ if(28)
+ MAX_EXPLOSION_RANGE = 56
+ if(56)
+ MAX_EXPLOSION_RANGE = 128
+ if(128)
+ MAX_EXPLOSION_RANGE = 14
+ var/range_dev = MAX_EXPLOSION_RANGE *0.25
+ var/range_high = MAX_EXPLOSION_RANGE *0.5
+ var/range_low = MAX_EXPLOSION_RANGE
+ message_admins("\red [key_name_admin(usr)] changed the bomb cap to [range_dev], [range_high], [range_low] ", 1)
+ log_admin("[key_name_admin(usr)] changed the bomb cap to [MAX_EXPLOSION_RANGE]")
+ else
+ alert("No way. You're not of a high enough rank to do this.")
+
+ if("flicklights")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","FL")
+ while(!usr.stat)
+ //knock yourself out to stop the ghosts
+ for(var/mob/M in world)
+ if(M.client && M.stat != 2 && prob(25))
+ var/area/AffectedArea = get_area(M)
+ if(AffectedArea.name != "Space" && AffectedArea.name != "Engine Walls" && AffectedArea.name != "Chemical Lab Test Chamber" && AffectedArea.name != "Escape Shuttle" && AffectedArea.name != "Arrival Area" && AffectedArea.name != "Arrival Shuttle" && AffectedArea.name != "start area" && AffectedArea.name != "Engine Combustion Chamber")
+ AffectedArea.power_light = 0
+ AffectedArea.power_change()
+ spawn(rand(55,185))
+ AffectedArea.power_light = 1
+ AffectedArea.power_change()
+ var/Message = rand(1,4)
+ switch(Message)
+ if(1)
+ M.show_message(text("\blue You shudder as if cold..."), 1)
+ if(2)
+ M.show_message(text("\blue You feel something gliding across your back..."), 1)
+ if(3)
+ M.show_message(text("\blue Your eyes twitch, you feel like something you can't see is here..."), 1)
+ if(4)
+ M.show_message(text("\blue You notice something moving out of the corner of your eye, but nothing is there..."), 1)
+ for(var/obj/W in orange(5,M))
+ if(prob(25) && !W.anchored)
+ step_rand(W)
+ sleep(rand(100,1000))
+ for(var/mob/M in world)
+ if(M.client && M.stat != 2)
+ M.show_message(text("\blue The chilling wind suddenly stops..."), 1)
+ /* if("shockwave")
+ ok = 1
+ world << "\red ALERT: STATION STRESS CRITICAL "
+ sleep(60)
+ world << "\red ALERT: STATION STRESS CRITICAL. TOLERABLE LEVELS EXCEEDED! "
+ sleep(80)
+ world << "\red ALERT: STATION STRUCTURAL STRESS CRITICAL. SAFETY MECHANISMS FAILED! "
+ sleep(40)
+ for(var/mob/M in world)
+ shake_camera(M, 400, 1)
+ for(var/obj/structure/window/W in world)
+ spawn(0)
+ sleep(rand(10,400))
+ W.ex_act(rand(2,1))
+ for(var/obj/structure/grille/G in world)
+ spawn(0)
+ sleep(rand(20,400))
+ G.ex_act(rand(2,1))
+ for(var/obj/machinery/door/D in world)
+ spawn(0)
+ sleep(rand(20,400))
+ D.ex_act(rand(2,1))
+ for(var/turf/station/floor/Floor in world)
+ spawn(0)
+ sleep(rand(30,400))
+ Floor.ex_act(rand(2,1))
+ for(var/obj/structure/cable/Cable in world)
+ spawn(0)
+ sleep(rand(30,400))
+ Cable.ex_act(rand(2,1))
+ for(var/obj/structure/closet/Closet in world)
+ spawn(0)
+ sleep(rand(30,400))
+ Closet.ex_act(rand(2,1))
+ for(var/obj/machinery/Machinery in world)
+ spawn(0)
+ sleep(rand(30,400))
+ Machinery.ex_act(rand(1,3))
+ for(var/turf/station/wall/Wall in world)
+ spawn(0)
+ sleep(rand(30,400))
+ Wall.ex_act(rand(2,1)) */
+ if("wave")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","MW")
+ if ((src.rank in list("Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ meteor_wave()
+ message_admins("[key_name_admin(usr)] has spawned meteors", 1)
+ command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert")
+ world << sound('meteors.ogg')
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+ if("gravanomalies")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","GA")
+ command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert")
+ world << sound('granomalies.ogg')
+ var/turf/T = pick(blobstart)
+ var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 )
+ spawn(rand(50, 300))
+ del(bh)
+ if("timeanomalies")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","STA")
+ command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert")
+ world << sound('spanomalies.ogg')
+ var/list/turfs = list( )
+ var/turf/picked
+ for(var/turf/T in world)
+ if(T.z == 1 && istype(T,/turf/simulated/floor) && !istype(T,/turf/space))
+ turfs += T
+ for(var/turf/T in world)
+ set background = 1
+ if(prob(20) && T.z == 1 && istype(T,/turf/simulated/floor))
+ spawn(50+rand(0,3000))
+ picked = pick(turfs)
+ var/obj/effect/portal/P = new /obj/effect/portal( T )
+ P.target = picked
+ P.creator = null
+ P.icon = 'objects.dmi'
+ P.failchance = 0
+ P.icon_state = "anom"
+ P.name = "wormhole"
+ spawn(rand(300,600))
+ del(P)
+ if("goblob")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","BL")
+ mini_blob_event()
+ message_admins("[key_name_admin(usr)] has spawned blob", 1)
+ if("aliens")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","AL")
+ if(aliens_allowed)
+ alien_infestation()
+ message_admins("[key_name_admin(usr)] has spawned aliens", 1)
+ if("spaceninja")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SN")
+ if(toggle_space_ninja)
+ if(space_ninja_arrival())//If the ninja is actually spawned. They may not be depending on a few factors.
+ message_admins("[key_name_admin(usr)] has sent in a space ninja", 1)
+ if("carp")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","C")
+ var/choice = input("You sure you want to spawn carp?") in list("Badmin", "Cancel")
+ if(choice == "Badmin")
+ message_admins("[key_name_admin(usr)] has spawned carp.", 1)
+ carp_migration()
+ if("radiation")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","R")
+ message_admins("[key_name_admin(usr)] has has irradiated the station", 1)
+ high_radiation_event()
+ if("immovable")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","IR")
+ message_admins("[key_name_admin(usr)] has sent an immovable rod to the station", 1)
+ immovablerod()
+ if("prison_break")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","PB")
+ message_admins("[key_name_admin(usr)] has allowed a prison break", 1)
+ prison_break()
+ if("lightsout")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","LO")
+ message_admins("[key_name_admin(usr)] has broke a lot of lights", 1)
+ lightsout(1,2)
+ if("blackout")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","BO")
+ message_admins("[key_name_admin(usr)] broke all lights", 1)
+ lightsout(0,0)
+ if("virus")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","V")
+ var/answer = alert("Do you want this to be a random disease or do you have something in mind?",,"Virus2","Random","Choose")
+ if(answer=="Random")
+ viral_outbreak()
+ message_admins("[key_name_admin(usr)] has triggered a virus outbreak", 1)
+ else if(answer == "Choose")
+ var/list/viruses = list("fake gbs","gbs","magnitis","wizarditis",/*"beesease",*/"brain rot","cold","retrovirus","flu","pierrot's throat","rhumba beat")
+ var/V = input("Choose the virus to spread", "BIOHAZARD") in viruses
+ viral_outbreak(V)
+ message_admins("[key_name_admin(usr)] has triggered a virus outbreak of [V]", 1)
+ else
+ usr << "Nope"
+ /*
+ var/lesser = (alert("Do you want to infect the mob with a major or minor disease?",,"Major","Minor") == "Minor")
+ var/mob/living/carbon/victim = input("Select a mob to infect", "Virus2") as null|mob in world
+ if(!istype(victim)) return
+ if(lesser)
+ infect_mob_random_lesser(victim)
+ else
+ infect_mob_random_greater(victim)
+ message_admins("[key_name_admin(usr)] has infected [victim] with a [lesser ? "minor" : "major"] virus2.", 1)
+ */
+ if("retardify")
+ if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","RET")
+ for(var/mob/living/carbon/human/H in world)
+ if(H.client)
+ H << "\red You suddenly feel stupid. "
+ H.setBrainLoss(60)
+ message_admins("[key_name_admin(usr)] made everybody retarded")
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+ if("fakeguns")
+ if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","FG")
+ for(var/obj/item/W in world)
+ if(istype(W, /obj/item/clothing) || istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/weapon/disk) || istype(W, /obj/item/weapon/tank))
+ continue
+ W.icon = 'gun.dmi'
+ W.icon_state = "revolver"
+ W.item_state = "gun"
+ message_admins("[key_name_admin(usr)] made every item look like a gun")
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+ if("schoolgirl")
+ if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SG")
+ for(var/obj/item/clothing/under/W in world)
+ W.icon_state = "schoolgirl"
+ W.item_state = "w_suit"
+ W.color = "schoolgirl"
+ message_admins("[key_name_admin(usr)] activated Japanese Animes mode")
+ world << sound('animes.ogg')
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+ if("dorf")
+ if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","DF")
+ for(var/mob/living/carbon/human/B in world)
+ B.face_icon_state = "facial_wise"
+ B.update_face()
+ message_admins("[key_name_admin(usr)] activated dorf mode")
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+ if("ionstorm")
+ if (src.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master"))
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","I")
+ IonStorm()
+ message_admins("[key_name_admin(usr)] triggered an ion storm")
+ var/show_log = alert(usr, "Show ion message?", "Message", "Yes", "No")
+ if(show_log == "Yes")
+ command_alert("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert")
+ world << sound('ionstorm.ogg')
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!")
+ return
+ if("spacevines")
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","K")
+ spacevine_infestation()
+ message_admins("[key_name_admin(usr)] has spawned spacevines", 1)
+ if (usr)
+ log_admin("[key_name(usr)] used secret [href_list["secretsfun"]]")
+ if (ok)
+ world << text("A secret has been activated by []! ", usr.key)
+ return
+
+ if (href_list["secretsadmin"])
+ if ((src.rank in list( "Moderator", "Temporary Admin", "Trial Admin", "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/ok = 0
+ switch(href_list["secretsadmin"])
+ if("clear_bombs")
+ //I do nothing
+ if("list_bombers")
+ var/dat = "Bombing List "
+ for(var/l in bombers)
+ dat += text("[l] ")
+ usr << browse(dat, "window=bombers")
+ if("list_signalers")
+ var/dat = "Showing last [length(lastsignalers)] signalers. "
+ for(var/sig in lastsignalers)
+ dat += "[sig] "
+ usr << browse(dat, "window=lastsignalers;size=800x500")
+ if("list_lawchanges")
+ var/dat = "Showing last [length(lawchanges)] law changes. "
+ for(var/sig in lawchanges)
+ dat += "[sig] "
+ usr << browse(dat, "window=lawchanges;size=800x500")
+ if("list_job_debug")
+ var/dat = "Job Debug info. "
+ if(job_master)
+ for(var/line in job_master.job_debug)
+ dat += "[line] "
+ dat+= "******* "
+ for(var/datum/job/job in job_master.occupations)
+ if(!job) continue
+ dat += "job: [job.title], current_positions: [job.current_positions], total_positions: [job.total_positions] "
+ usr << browse(dat, "window=jobdebug;size=600x500")
+ if("check_antagonist")
+ if (ticker && ticker.current_state >= GAME_STATE_PLAYING)
+ var/dat = "Round Status Round Status "
+ dat += "Current Game Mode: [ticker.mode.name] "
+ dat += "Round Duration: [round(world.time / 36000)]:[add_zero(world.time / 600 % 60, 2)]:[world.time / 100 % 6][world.time / 100 % 10] "
+ dat += "Emergency shuttle "
+ if (!emergency_shuttle.online)
+ dat += "Call Shuttle "
+ else
+ var/timeleft = emergency_shuttle.timeleft()
+ switch(emergency_shuttle.location)
+ if(0)
+ dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)] "
+ dat += "Send Back "
+ if(1)
+ dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)] "
+
+ if(ticker.mode.syndicates.len)
+ dat += "Syndicates "
+ for(var/datum/mind/N in ticker.mode.syndicates)
+ var/mob/M = N.current
+ if(M)
+ dat += "[M.real_name] [M.client ? "" : " (logged out) "][M.stat == 2 ? " (DEAD) " : ""] "
+ dat += "PM "
+ else
+ dat += "Nuclear Operative not found! "
+ dat += "
Nuclear Disk(s) "
+ for(var/obj/item/weapon/disk/nuclear/N in world)
+ dat += "[N.name], "
+ var/atom/disk_loc = N.loc
+ while(!istype(disk_loc, /turf))
+ if(istype(disk_loc, /mob))
+ var/mob/M = disk_loc
+ dat += "carried by [M.real_name] "
+ if(istype(disk_loc, /obj))
+ var/obj/O = disk_loc
+ dat += "in \a [O.name] "
+ disk_loc = disk_loc.loc
+ dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z]) "
+ dat += "
"
+
+ if(ticker.mode.head_revolutionaries.len || ticker.mode.revolutionaries.len)
+ dat += "Revolutionaries "
+ for(var/datum/mind/N in ticker.mode.head_revolutionaries)
+ var/mob/M = N.current
+ if(!M)
+ dat += "Head Revolutionary not found! "
+ else
+ dat += "[M.real_name] (Leader) [M.client ? "" : " (logged out) "][M.stat == 2 ? " (DEAD) " : ""] "
+ dat += "PM "
+ for(var/datum/mind/N in ticker.mode.revolutionaries)
+ var/mob/M = N.current
+ if(M)
+ dat += "[M.real_name] [M.client ? "" : " (logged out) "][M.stat == 2 ? " (DEAD) " : ""] "
+ dat += "PM "
+ dat += "
Target(s) Location "
+ for(var/datum/mind/N in ticker.mode.get_living_heads())
+ var/mob/M = N.current
+ if(M)
+ dat += "[M.real_name] [M.client ? "" : " (logged out) "][M.stat == 2 ? " (DEAD) " : ""] "
+ dat += "PM "
+ var/turf/mob_loc = get_turf_loc(M)
+ dat += "[mob_loc.loc] "
+ else
+ dat += "Head not found! "
+ dat += "
"
+
+ if(ticker.mode.changelings.len > 0)
+ dat += "Changelings "
+ for(var/datum/mind/changeling in ticker.mode.changelings)
+ var/mob/M = changeling.current
+ if(M)
+ dat += "[M.real_name] [M.client ? "" : " (logged out) "][M.stat == 2 ? " (DEAD) " : ""] "
+ dat += "PM "
+ dat += "Show Objective "
+ else
+ dat += "Changeling not found! "
+ dat += "
"
+
+ if(ticker.mode.wizards.len > 0)
+ dat += "Wizards "
+ for(var/datum/mind/wizard in ticker.mode.wizards)
+ var/mob/M = wizard.current
+ if(M)
+ dat += "[M.real_name] [M.client ? "" : " (logged out) "][M.stat == 2 ? " (DEAD) " : ""] "
+ dat += "PM "
+ dat += "Show Objective "
+ else
+ dat += "Wizard not found! "
+ dat += "
"
+
+ if(ticker.mode.cult.len)
+ dat += "Cultists "
+ for(var/datum/mind/N in ticker.mode.cult)
+ var/mob/M = N.current
+ if(M)
+ dat += "[M.real_name] [M.client ? "" : " (logged out) "][M.stat == 2 ? " (DEAD) " : ""] "
+ dat += "PM "
+ dat += "
"
+
+ if(ticker.mode.traitors.len > 0)
+ dat += "Traitors "
+ for(var/datum/mind/traitor in ticker.mode.traitors)
+ var/mob/M = traitor.current
+ if(M)
+ dat += "[M.real_name] [M.client ? "" : " (logged out) "][M.stat == 2 ? " (DEAD) " : ""] "
+ dat += "PM "
+ dat += "Show Objective "
+ else
+ dat += "Traitor not found! "
+ dat += "
"
+
+ dat += ""
+ usr << browse(dat, "window=roundstatus;size=400x500")
+ else
+ alert("The game hasn't started yet!")
+ if("showailaws")
+ for(var/mob/living/silicon/ai/ai in world)
+ usr << "[key_name(ai, usr)]'s Laws:"
+ if (ai.laws == null)
+ usr << "[key_name(ai, usr)]'s Laws are null??"
+ else
+ ai.laws.show_laws(usr)
+ if("showgm")
+ if(!ticker)
+ alert("The game hasn't started yet!")
+ else if (ticker.mode)
+ alert("The game mode is [ticker.mode.name]")
+ else alert("For some reason there's a ticker, but not a game mode")
+ if("manifest")
+ var/dat = "Showing Crew Manifest. "
+ dat += "Name Position "
+ for(var/mob/living/carbon/human/H in world)
+ if(H.ckey)
+ dat += text("[] [] ", H.name, H.get_assignment())
+ dat += "
"
+ usr << browse(dat, "window=manifest;size=440x410")
+ if("DNA")
+ var/dat = "Showing DNA from blood. "
+ dat += "Name DNA Blood Type "
+ for(var/mob/living/carbon/human/H in world)
+ if(H.dna && H.ckey)
+ dat += "[H] [H.dna.unique_enzymes] [H.b_type] "
+ dat += "
"
+ usr << browse(dat, "window=DNA;size=440x410")
+ if("fingerprints")
+ var/dat = "Showing Fingerprints. "
+ dat += "Name Fingerprints "
+ for(var/mob/living/carbon/human/H in world)
+ if(H.ckey)
+ if(H.dna && H.dna.uni_identity)
+ dat += "[H] [md5(H.dna.uni_identity)] "
+ else if(H.dna && !H.dna.uni_identity)
+ dat += "[H] H.dna.uni_identity = null "
+ else if(!H.dna)
+ dat += "[H] H.dna = null "
+ dat += "
"
+ usr << browse(dat, "window=fingerprints;size=440x410")
+ else
+ if (usr)
+ log_admin("[key_name(usr)] used secret [href_list["secretsadmin"]]")
+ if (ok)
+ world << text("A secret has been activated by []! ", usr.key)
+ return
+ if (href_list["secretscoder"])
+ if ((src.rank in list( "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ switch(href_list["secretscoder"])
+ if("spawn_objects")
+ var/dat = "Admin Log "
+ for(var/l in admin_log)
+ dat += "[l] "
+ if(!admin_log.len)
+ dat += "No-one has done anything this round!"
+ usr << browse(dat, "window=admin_log")
+ if("maint_access_brig")
+ for(var/obj/machinery/door/airlock/maintenance/M in world)
+ if (access_maint_tunnels in M.req_access)
+ M.req_access = list(access_brig)
+ message_admins("[key_name_admin(usr)] made all maint doors brig access-only.")
+ if("maint_access_engiebrig")
+ for(var/obj/machinery/door/airlock/maintenance/M in world)
+ if (access_maint_tunnels in M.req_access)
+ M.req_access = list()
+ M.req_one_access = list(access_brig,access_engine)
+ message_admins("[key_name_admin(usr)] made all maint doors engineering and brig access-only.")
+ if("infinite_sec")
+ var/datum/job/J = job_master.GetJob("Security Officer")
+ if(!J) return
+ J.total_positions = -1
+ J.spawn_positions = -1
+ message_admins("[key_name_admin(usr)] has removed the cap on security officers.")
+ return
+ //hahaha
+
+///////////////////////////////////////////////////////////////////////////////////////////////Panels
+
+/obj/admins/proc/show_player_panel(var/mob/M in world)
+ set category = "Admin"
+ set name = "Show Player Panel"
+ set desc="Edit player (respawn, ban, heal, etc)"
+ if(!M)
+ usr << "You seem to be selecting a mob that doesn't exist anymore."
+ return
+ if (!istype(src,/obj/admins))
+ src = usr.client.holder
+ if (!istype(src,/obj/admins))
+ usr << "Error: you are not an admin!"
+ return
+ var/dat = "Options for [M.key] "
+ var/foo = "\[ "
+ if (ismob(M) && M.client)
+ if(!M.client.authenticated && !M.client.authenticating)
+ foo += text("Authorize | ")
+ else
+ foo += text("Authorized | ")
+ foo += text("Promote/Demote | ")
+ if(!istype(M, /mob/new_player))
+ if(!ismonkey(M))
+ foo += text("Monkeyize | ")
+ else
+ foo += text("Monkeyized | ")
+ if(!iscorgi(M))
+ foo += text("Corgize | ")
+ else
+ foo += text("Corgized | ")
+ if(isAI(M))
+ foo += text("Is an AI | ")
+ else if(ishuman(M))
+ foo += text("Make AI | ")
+ foo += text("Make Robot | ")
+ foo += text("Make Alien | ")
+ foo += text("Make Metroid | ")
+ foo += text("Thunderdome 1 | ")
+ foo += text("Thunderdome 2 | ")
+ foo += text("Thunderdome Admin | ")
+ foo += text("Thunderdome Observer | ")
+ foo += text("Prison | ")
+ // foo += text("Maze | ")
+ foo += text("Heal/Revive | ")
+ else
+ foo += text("Hasn't Entered Game | ")
+ foo += text("Forcesay | ")
+ if(M.client)
+ foo += text("Mute: [(M.client.muted ? "Muted" : "Voiced")] | ")
+ foo += text("Complete mute: [(M.client.muted ? "Completely Muted" : "Voiced")] | ")
+ else
+ foo += "Mute unavailable - no client"
+ foo += text("Boot ")
+ foo += text(" ")
+ foo += text("Jump to | ")
+ foo += text("Get | ")
+ foo += text("Send ")
+ foo += text(" ")
+ foo += text("Edit mind | ")
+ foo += text("Narrate to | ")
+ foo += text("Subtle message ")
+ foo += text(" ")
+ foo += text("Ban | ")
+ foo += text("Jobban ")
+ dat += text("[foo]")
+ usr << browse(dat, "window=adminplayeropts;size=480x150")
+
+
+
+/obj/admins/proc/Jobbans()
+
+ if ((src.rank in list( "Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master" )))
+ var/dat = "Job Bans! "
+ for(var/t in jobban_keylist)
+ var/r = t
+ if( findtext(r,"##") )
+ r = copytext( r, 1, findtext(r,"##") )//removes the description
+ dat += text("[t] (unban ) ")
+ dat += "
"
+ usr << browse(dat, "window=ban;size=400x400")
+
+/obj/admins/proc/Game()
+
+ var/dat
+ var/lvl = 0
+ switch(src.rank)
+ if("Moderator")
+ lvl = 1
+ if("Temporary Admin")
+ lvl = 2
+ if("Trial Admin")
+ lvl = 3
+ if("Secondary Game Admin")
+ lvl = 4
+ if("Game Admin")
+ lvl = 5
+ if("Senior Game Admin")
+ lvl = 6
+ if("Game Master")
+ lvl = 7
+
+ dat += " Game Panel \n"
+
+ if(lvl > 0)
+
+// if(lvl >= 2 )
+ dat += "Change Game Mode "
+
+ if(lvl > 0 && master_mode == "secret")
+ dat += "(Force Secret Mode) "
+
+ dat += " "
+
+ if(lvl >= 3 )
+ dat += "Create Object "
+ dat += "Create Turf "
+ if(lvl >= 5)
+ dat += "Create Mob "
+// if(lvl == 6 )
+ usr << browse(dat, "window=admin2;size=210x180")
+ return
+/*
+/obj/admins/proc/goons()
+ var/dat = "GOOOOOOONS Key SA Username "
+ for(var/t in goon_keylist)
+ dat += text("[t] [goon_keylist[ckey(t)]] ")
+ dat += "
"
+ usr << browse(dat, "window=ban;size=300x400")
+
+/obj/admins/proc/beta_testers()
+ var/dat = "Beta testers Key "
+ for(var/t in beta_tester_keylist)
+ dat += text("[t] ")
+ dat += "
"
+ usr << browse(dat, "window=ban;size=300x400")
+*/
+/obj/admins/proc/Secrets()
+ if (!usr.client.holder)
+ return
+
+ var/lvl = 0
+ switch(src.rank)
+ if("Moderator")
+ lvl = 1
+ if("Temporary Admin")
+ lvl = 2
+ if("Trial Admin")
+ lvl = 3
+ if("Secondary Game Admin")
+ lvl = 4
+ if("Game Admin")
+ lvl = 5
+ if("Senior Game Admin")
+ lvl = 6
+ if("Game Master")
+ lvl = 7
+
+ var/dat = {"
+Choose a secret, any secret at all.
+Admin Secrets
+
+Remove all bombs currently in existence
+Bombing List
+Show current traitors and objectives
+Show last [length(lastsignalers)] signalers
+Show last [length(lawchanges)] law changes
+Show AI Laws
+Show Game Mode
+Show Crew Manifest
+List DNA (Blood)
+List Fingerprints
+ "}
+ if(lvl > 2)
+ dat += {"
+'Random' Events
+
+Spawn a wave of meteors
+Spawn a gravitational anomaly (Untested)
+Spawn wormholes (Untested)
+Spawn blob(Untested)
+Trigger an Alien infestation
+Send in a space ninja
+Trigger an Carp migration
+Irradiate the station
+Trigger a Prison Break
+Trigger a Virus Outbreak
+Spawn an Immovable Rod
+Toggle a "lights out" event
+Spawn an Ion Storm
+Spawn Space-Vines
+
+Fun Secrets
+
+Remove 'internal' clothing
+Remove ALL clothing
+Toxic Air (WARNING: dangerous)
+Turn all humans into monkeys
+Remove firesuits, grilles, and pods
+Make all areas powered
+Make all areas unpowered
+Toggle Prison Shuttle Status(Use with S/R)
+Send Prison Shuttle
+Return Prison Shuttle
+Warp all Players to Prison
+Everyone is the traitor
+Ghost Mode
+Make all players retarded
+Make all items look like guns
+Japanese Animes Mode
+Move Administration Shuttle
+Move Ferry
+Move Alien Dinghy
+Move Mining Shuttle
+Break all lights "}
+//Station Shockwave
+
+ if(lvl >= 6)
+ dat += {"
+Toggle bomb cap
+ "}
+
+ dat += " "
+
+ if(lvl >= 5)
+ dat += {"
+Security Level Elevated
+
+Change all maintenance doors to engie/brig access only
+Change all maintenance doors to brig access only
+Remove cap on security officers
+
+Coder Secrets
+
+Show Job Debug
+Admin Log
+
+"}
+ usr << browse(dat, "window=secrets")
+ return
+
+/obj/admins/proc/Voting()
+
+ var/dat
+ var/lvl = 0
+ switch(src.rank)
+ if("Moderator")
+ lvl = 1
+ if("Temporary Admin")
+ lvl = 2
+ if("Trial Admin")
+ lvl = 3
+ if("Secondary Game Admin")
+ lvl = 4
+ if("Game Admin")
+ lvl = 5
+ if("Senior Game Admin")
+ lvl = 6
+ if("Game Master")
+ lvl = 7
+
+
+ dat += "Voting \n"
+
+ if(lvl > 0)
+// if(lvl >= 2 )
+ dat += {"
+Abort Vote
+Start Vote
+Toggle Voting
+"}
+
+// if(lvl >= 3 )
+// if(lvl >= 5)
+// if(lvl == 6 )
+
+ usr << browse(dat, "window=admin2;size=210x160")
+ return
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////admins2.dm merge
+//i.e. buttons/verbs
+
+
+/obj/admins/proc/vmode()
+ set category = "Server"
+ set name = "Start Vote"
+ set desc="Starts vote"
+ if (!usr.client.holder)
+ return
+ var/confirm = alert("What vote would you like to start?", "Vote", "Restart", "Change Game Mode", "Cancel")
+ if(confirm == "Cancel")
+ return
+ if(confirm == "Restart")
+ vote.mode = 0
+ // hack to yield 0=restart, 1=changemode
+ if(confirm == "Change Game Mode")
+ vote.mode = 1
+ if(!ticker)
+ if(going)
+ world << "The game start has been delayed. "
+ going = 0
+ vote.voting = 1
+ // now voting
+ vote.votetime = world.timeofday + config.vote_period*10
+ // when the vote will end
+ spawn(config.vote_period*10)
+ vote.endvote()
+ world << "\red*** A vote to [vote.mode?"change game mode":"restart"] has been initiated by Admin [usr.key]. "
+ world << "\red You have [vote.timetext(config.vote_period)] to vote."
+
+ log_admin("Voting to [vote.mode?"change mode":"restart round"] forced by admin [key_name(usr)]")
+
+ for(var/mob/CM in world)
+ if(CM.client)
+ if(config.vote_no_default || (config.vote_no_dead && CM.stat == 2) || !CM.client.authenticated)
+ CM.client.vote = "none"
+ else
+ CM.client.vote = "default"
+
+ for(var/mob/CM in world)
+ if(CM.client)
+ if(config.vote_no_default || (config.vote_no_dead && CM.stat == 2) || !CM.client.authenticated)
+ CM.client.vote = "none"
+ else
+ CM.client.vote = "default"
+
+/obj/admins/proc/votekill()
+ set category = "Server"
+ set name = "Abort Vote"
+ set desc="Aborts a vote"
+ if(vote.voting == 0)
+ alert("No votes in progress")
+ return
+ world << "\red *** Voting aborted by [usr.client.stealth ? "Admin Candidate" : usr.key]. "
+
+ log_admin("Voting aborted by [key_name(usr)]")
+
+ vote.voting = 0
+ vote.nextvotetime = world.timeofday + 10*config.vote_delay
+
+ for(var/mob/M in world)
+ // clear vote window from all clients
+ if(M.client)
+ M << browse(null, "window=vote")
+ M.client.showvote = 0
+
+/obj/admins/proc/voteres()
+ set category = "Server"
+ set name = "Toggle Voting"
+ set desc="Toggles Votes"
+ var/confirm = alert("What vote would you like to toggle?", "Vote", "Restart [config.allow_vote_restart ? "Off" : "On"]", "Change Game Mode [config.allow_vote_mode ? "Off" : "On"]", "Cancel")
+ if(confirm == "Cancel")
+ return
+ if(confirm == "Restart [config.allow_vote_restart ? "Off" : "On"]")
+ config.allow_vote_restart = !config.allow_vote_restart
+ world << "Player restart voting toggled to [config.allow_vote_restart ? "On" : "Off"] ."
+ log_admin("Restart voting toggled to [config.allow_vote_restart ? "On" : "Off"] by [key_name(usr)].")
+
+ if(config.allow_vote_restart)
+ vote.nextvotetime = world.timeofday
+ if(confirm == "Change Game Mode [config.allow_vote_mode ? "Off" : "On"]")
+ config.allow_vote_mode = !config.allow_vote_mode
+ world << "Player mode voting toggled to [config.allow_vote_mode ? "On" : "Off"] ."
+ log_admin("Mode voting toggled to [config.allow_vote_mode ? "On" : "Off"] by [key_name(usr)].")
+
+ if(config.allow_vote_mode)
+ vote.nextvotetime = world.timeofday
+
+/obj/admins/proc/restart()
+ set category = "Server"
+ set name = "Restart"
+ set desc="Restarts the world"
+ if (!usr.client.holder)
+ return
+ var/confirm = alert("Restart the game world?", "Restart", "Yes", "Cancel")
+ if(confirm == "Cancel")
+ return
+ if(confirm == "Yes")
+ world << "\red Restarting world! \blue Initiated by [usr.client.stealth ? "Admin" : usr.key]!"
+ log_admin("[key_name(usr)] initiated a reboot.")
+
+ feedback_set_details("end_error","admin reboot - by [usr.key] [usr.client.stealth ? "(stealth)" : ""]")
+
+ if(blackbox)
+ blackbox.save_all_data_to_sql()
+
+ sleep(50)
+ world.Reboot()
+
+/obj/admins/proc/announce()
+ set category = "Special Verbs"
+ set name = "Announce"
+ set desc="Announce your desires to the world"
+ var/message = input("Global message to send:", "Admin Announce", null, null) as message
+ if (message)
+ if(usr.client.holder.rank != "Game Admin" && usr.client.holder.rank != "Game Master")
+ message = adminscrub(message,500)
+ world << "\blue [usr.client.stealth ? "Administrator" : usr.key] Announces: \n \t [message]"
+ log_admin("Announce: [key_name(usr)] : [message]")
+
+/obj/admins/proc/toggleooc()
+ set category = "Server"
+ set desc="Toggle dis bitch"
+ set name="Toggle OOC"
+ ooc_allowed = !( ooc_allowed )
+ if (ooc_allowed)
+ world << "The OOC channel has been globally enabled! "
+ else
+ world << "The OOC channel has been globally disabled! "
+ log_admin("[key_name(usr)] toggled OOC.")
+ message_admins("[key_name_admin(usr)] toggled OOC.", 1)
+
+/obj/admins/proc/toggleoocdead()
+ set category = "Server"
+ set desc="Toggle dis bitch"
+ set name="Toggle Dead OOC"
+ dooc_allowed = !( dooc_allowed )
+
+ log_admin("[key_name(usr)] toggled OOC.")
+ message_admins("[key_name_admin(usr)] toggled Dead OOC.", 1)
+
+/obj/admins/proc/toggletraitorscaling()
+ set category = "Server"
+ set desc="Toggle traitor scaling"
+ set name="Toggle Traitor Scaling"
+ traitor_scaling = !traitor_scaling
+ log_admin("[key_name(usr)] toggled Traitor Scaling to [traitor_scaling].")
+ message_admins("[key_name_admin(usr)] toggled Traitor Scaling [traitor_scaling ? "on" : "off"].", 1)
+
+/obj/admins/proc/startnow()
+ set category = "Server"
+ set desc="Start the round RIGHT NOW"
+ set name="Start Now"
+ if(!ticker)
+ alert("Unable to start the game as it is not set up.")
+ return
+ if(ticker.current_state == GAME_STATE_PREGAME)
+ ticker.current_state = GAME_STATE_SETTING_UP
+ log_admin("[usr.key] has started the game.")
+ message_admins("[usr.key] has started the game. ")
+ return 1
+ else
+ alert("Game has already started you fucking jerk, stop spamming up the chat :ARGH:")
+ return 0
+
+/obj/admins/proc/toggleenter()
+ set category = "Server"
+ set desc="People can't enter"
+ set name="Toggle Entering"
+ enter_allowed = !( enter_allowed )
+ if (!( enter_allowed ))
+ world << "New players may no longer enter the game. "
+ else
+ world << "New players may now enter the game. "
+ log_admin("[key_name(usr)] toggled new player game entering.")
+ message_admins("\blue [key_name_admin(usr)] toggled new player game entering.", 1)
+ world.update_status()
+
+/obj/admins/proc/toggleAI()
+ set category = "Server"
+ set desc="People can't be AI"
+ set name="Toggle AI"
+ config.allow_ai = !( config.allow_ai )
+ if (!( config.allow_ai ))
+ world << "The AI job is no longer chooseable. "
+ else
+ world << "The AI job is chooseable now. "
+ log_admin("[key_name(usr)] toggled AI allowed.")
+ world.update_status()
+
+/obj/admins/proc/toggleaban()
+ set category = "Server"
+ set desc="Respawn basically"
+ set name="Toggle Respawn"
+ abandon_allowed = !( abandon_allowed )
+ if (abandon_allowed)
+ world << "You may now respawn. "
+ else
+ world << "You may no longer respawn :( "
+ message_admins("\blue [key_name_admin(usr)] toggled respawn to [abandon_allowed ? "On" : "Off"].", 1)
+ log_admin("[key_name(usr)] toggled respawn to [abandon_allowed ? "On" : "Off"].")
+ world.update_status()
+
+/obj/admins/proc/toggle_aliens()
+ set category = "Server"
+ set desc="Toggle alien mobs"
+ set name="Toggle Aliens"
+ aliens_allowed = !aliens_allowed
+ log_admin("[key_name(usr)] toggled Aliens to [aliens_allowed].")
+ message_admins("[key_name_admin(usr)] toggled Aliens [aliens_allowed ? "on" : "off"].", 1)
+
+/obj/admins/proc/toggle_space_ninja()
+ set category = "Server"
+ set desc="Toggle space ninjas spawning."
+ set name="Toggle Space Ninjas"
+ toggle_space_ninja = !toggle_space_ninja
+ log_admin("[key_name(usr)] toggled Space Ninjas to [toggle_space_ninja].")
+ message_admins("[key_name_admin(usr)] toggled Space Ninjas [toggle_space_ninja ? "on" : "off"].", 1)
+
+/obj/admins/proc/delay()
+ set category = "Server"
+ set desc="Delay the game start"
+ set name="Delay"
+ if (!ticker || ticker.current_state != GAME_STATE_PREGAME)
+ return alert("Too late... The game has already started!", null, null, null, null, null)
+ going = !( going )
+ if (!( going ))
+ world << "The game start has been delayed. "
+ log_admin("[key_name(usr)] delayed the game.")
+ else
+ world << "The game will start soon. "
+ log_admin("[key_name(usr)] removed the delay.")
+
+/obj/admins/proc/adjump()
+ set category = "Server"
+ set desc="Toggle admin jumping"
+ set name="Toggle Jump"
+ config.allow_admin_jump = !(config.allow_admin_jump)
+ message_admins("\blue Toggled admin jumping to [config.allow_admin_jump].")
+
+/obj/admins/proc/adspawn()
+ set category = "Server"
+ set desc="Toggle admin spawning"
+ set name="Toggle Spawn"
+ config.allow_admin_spawning = !(config.allow_admin_spawning)
+ message_admins("\blue Toggled admin item spawning to [config.allow_admin_spawning].")
+
+/obj/admins/proc/adrev()
+ set category = "Server"
+ set desc="Toggle admin revives"
+ set name="Toggle Revive"
+ config.allow_admin_rev = !(config.allow_admin_rev)
+ message_admins("\blue Toggled reviving to [config.allow_admin_rev].")
+
+/obj/admins/proc/immreboot()
+ set category = "Server"
+ set desc="Reboots the server post haste"
+ set name="Immediate Reboot"
+ if( alert("Reboot server?",,"Yes","No") == "No")
+ return
+ world << "\red Rebooting world! \blue Initiated by [usr.client.stealth ? "Admin" : usr.key]!"
+ log_admin("[key_name(usr)] initiated an immediate reboot.")
+
+ feedback_set_details("end_error","immediate admin reboot - by [usr.key] [usr.client.stealth ? "(stealth)" : ""]")
+
+ if(blackbox)
+ blackbox.save_all_data_to_sql()
+
+ world.Reboot()
+
+/client/proc/deadchat()
+ set category = "Admin"
+ set desc="Toggles Deadchat Visibility"
+ set name="Deadchat Visibility"
+ if(deadchat == 0)
+ deadchat = 1
+ usr << "Deadchat turned on"
+ else
+ deadchat = 0
+ usr << "Deadchat turned off"
+
+/client/proc/toggleprayers()
+ set category = "Admin"
+ set desc="Toggles Prayer Visibility"
+ set name="Prayer Visibility"
+ if(seeprayers == 0)
+ seeprayers = 1
+ usr << "Prayer visibility turned on"
+ else
+ seeprayers = 0
+ usr << "Prayer visibility turned off"
+
+/obj/admins/proc/unprison(var/mob/M in world)
+ set category = "Admin"
+ set name = "Unprison"
+ if (M.z == 2)
+ if (config.allow_admin_jump)
+ M.loc = pick(latejoin)
+ message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]", 1)
+ log_admin("[key_name(usr)] has unprisoned [key_name(M)]")
+ else
+ alert("Admin jumping disabled")
+ else
+ alert("[M.name] is not prisoned.")
+
+////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS
+
+/proc/is_special_character(mob/M as mob) // returns 1 for specail characters and 2 for heroes of gamemode
+ if(!ticker || !ticker.mode)
+ return 0
+ if (!istype(M))
+ return 0
+ if((M.mind in ticker.mode.head_revolutionaries) || (M.mind in ticker.mode.revolutionaries))
+ if (ticker.mode.config_tag == "revolution")
+ return 2
+ return 1
+ if(M.mind in ticker.mode.cult)
+ if (ticker.mode.config_tag == "cult")
+ return 2
+ return 1
+ if(M.mind in ticker.mode.malf_ai)
+ if (ticker.mode.config_tag == "malfunction")
+ return 2
+ return 1
+ if(M.mind in ticker.mode.syndicates)
+ if (ticker.mode.config_tag == "nuclear")
+ return 2
+ return 1
+ if(M.mind in ticker.mode.wizards)
+ if (ticker.mode.config_tag == "wizard")
+ return 2
+ return 1
+ if(M.mind in ticker.mode.changelings)
+ if (ticker.mode.config_tag == "changeling")
+ return 2
+ return 1
+
+ for(var/datum/disease/D in M.viruses)
+ if(istype(D, /datum/disease/jungle_fever))
+ if (ticker.mode.config_tag == "monkey")
+ return 2
+ return 1
+ if(isrobot(M))
+ var/mob/living/silicon/robot/R = M
+ if(R.emagged)
+ return 1
+ if(M.mind&&M.mind.special_role)//If they have a mind and special role, they are some type of traitor or antagonist.
+ return 1
+
+ return 0
+
+/*
+/obj/admins/proc/get_sab_desc(var/target)
+ switch(target)
+ if(1)
+ return "Destroy at least 70% of the plasma canisters on the station"
+ if(2)
+ return "Destroy the AI"
+ if(3)
+ var/count = 0
+ for(var/mob/living/carbon/monkey/Monkey in world)
+ if(Monkey.z == 1)
+ count++
+ return "Kill all [count] of the monkeys on the station"
+ if(4)
+ return "Cut power to at least 80% of the station"
+ else
+ return "Error: Invalid sabotage target: [target]"
+*/
+/obj/admins/proc/spawn_atom(var/object as text)
+ set category = "Debug"
+ set desc= "(atom path) Spawn an atom"
+ set name= "Spawn"
+
+ if(usr.client.holder.level >= 5)
+ var/list/types = typesof(/atom)
+
+ var/list/matches = new()
+
+ for(var/path in types)
+ if(findtext("[path]", object))
+ matches += path
+
+ if(matches.len==0)
+ return
+
+ var/chosen
+ if(matches.len==1)
+ chosen = matches[1]
+ else
+ chosen = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches
+ if(!chosen)
+ return
+
+ new chosen(usr.loc)
+
+ log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
+
+ else
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+
+
+/obj/admins/proc/show_traitor_panel(var/mob/M in world)
+ set category = "Admin"
+ set desc = "Edit mobs's memory and role"
+ set name = "Show Traitor Panel"
+
+ if (!M.mind)
+ usr << "Sorry, this mob has no mind!"
+ return
+ M.mind.edit_memory()
+
+
+/obj/admins/proc/toggletintedweldhelmets()
+ set category = "Debug"
+ set desc="Reduces view range when wearing welding helmets"
+ set name="Toggle tinted welding helmes"
+ tinted_weldhelh = !( tinted_weldhelh )
+ if (tinted_weldhelh)
+ world << "The tinted_weldhelh has been enabled! "
+ else
+ world << "The tinted_weldhelh has been disabled! "
+ log_admin("[key_name(usr)] toggled tinted_weldhelh.")
+ message_admins("[key_name_admin(usr)] toggled tinted_weldhelh.", 1)
+
+/obj/admins/proc/toggleguests()
+ set category = "Server"
+ set desc="Guests can't enter"
+ set name="Toggle guests"
+ guests_allowed = !( guests_allowed )
+ if (!( guests_allowed ))
+ world << "Guests may no longer enter the game. "
+ else
+ world << "Guests may now enter the game. "
+ log_admin("[key_name(usr)] toggled guests game entering [guests_allowed?"":"dis"]allowed.")
+ message_admins("\blue [key_name_admin(usr)] toggled guests game entering [guests_allowed?"":"dis"]allowed.", 1)
+
+
+
+/obj/admins/proc/view_txt_log()
+ set category = "Admin"
+ set desc="Shows todays server log in new window"
+ set name="Show Server Log"
+ var/path = "data/logs/[time2text(world.realtime,"YYYY")]/[time2text(world.realtime,"MM")]-[time2text(world.realtime,"Month")]/[time2text(world.realtime,"DD")]-[time2text(world.realtime,"Day")].log"
+ var/output = {"
+
+ [time2text(world.realtime,"Day, MMM DD, YYYY")] - Log
+
+
+
+ [file2text(path)]
+
+
+ "}
+ usr << browse(output,"window=server_logfile")
+ onclose(usr,"server_logfile")
+ return
+
+/obj/admins/proc/view_atk_log()
+ set category = "Admin"
+ set desc="Shows todays server attack log in new window"
+ set name="Show Server Attack Log"
+ var/path = "data/logs/[time2text(world.realtime,"YYYY")]/[time2text(world.realtime,"MM")]-[time2text(world.realtime,"Month")]/[time2text(world.realtime,"DD")]-[time2text(world.realtime,"Day")] Attack.log"
+ var/output = {"
+
+ [time2text(world.realtime,"Day, MMM DD, YYYY")] - Attack Log
+
+
+
+ [file2text(path)]
+
+
+ "}
+ usr << browse(output,"window=server_logfile")
+ onclose(usr,"server_logfile")
+ return
+
+/client/proc/unjobban_panel()
+ set name = "Unjobban Panel"
+ set category = "Admin"
+ if (src.holder)
+ src.holder.unjobbanpanel()
+ return
+
+
+//
+//
+//ALL DONE
+//*********************************************************************************************************
+//TO-DO:
+//
+//
+
+
+/**********************Administration Shuttle**************************/
+
+var/admin_shuttle_location = 0 // 0 = centcom 13, 1 = station
+
+proc/move_admin_shuttle()
+ var/area/fromArea
+ var/area/toArea
+ if (admin_shuttle_location == 1)
+ fromArea = locate(/area/shuttle/administration/station)
+ toArea = locate(/area/shuttle/administration/centcom)
+ else
+ fromArea = locate(/area/shuttle/administration/centcom)
+ toArea = locate(/area/shuttle/administration/station)
+ fromArea.move_contents_to(toArea)
+ if (admin_shuttle_location)
+ admin_shuttle_location = 0
+ else
+ admin_shuttle_location = 1
+ return
+
+/**********************Centcom Ferry**************************/
+
+var/ferry_location = 0 // 0 = centcom , 1 = station
+
+proc/move_ferry()
+ var/area/fromArea
+ var/area/toArea
+ if (ferry_location == 1)
+ fromArea = locate(/area/shuttle/transport1/station)
+ toArea = locate(/area/shuttle/transport1/centcom)
+ else
+ fromArea = locate(/area/shuttle/transport1/centcom)
+ toArea = locate(/area/shuttle/transport1/station)
+ fromArea.move_contents_to(toArea)
+ if (ferry_location)
+ ferry_location = 0
+ else
+ ferry_location = 1
+ return
+
+/**********************Alien ship**************************/
+
+var/alien_ship_location = 1 // 0 = base , 1 = mine
+
+proc/move_alien_ship()
+ var/area/fromArea
+ var/area/toArea
+ if (alien_ship_location == 1)
+ fromArea = locate(/area/shuttle/alien/mine)
+ toArea = locate(/area/shuttle/alien/base)
+ else
+ fromArea = locate(/area/shuttle/alien/base)
+ toArea = locate(/area/shuttle/alien/mine)
+ fromArea.move_contents_to(toArea)
+ if (alien_ship_location)
+ alien_ship_location = 0
+ else
+ alien_ship_location = 1
+ return
\ No newline at end of file
diff --git a/code/modules/admin/new/admin_verbs.dm b/code/modules/admin/new/admin_verbs.dm
new file mode 100644
index 0000000000..bacbe11010
--- /dev/null
+++ b/code/modules/admin/new/admin_verbs.dm
@@ -0,0 +1,797 @@
+//GUYS REMEMBER TO ADD A += to UPDATE_ADMINS
+//AND A -= TO CLEAR_ADMIN_VERBS
+
+
+
+//Some verbs that are still in the code but not used atm
+ // Debug
+// verbs += /client/proc/radio_report //for radio debugging dont think its been used in a very long time
+// verbs += /client/proc/fix_next_move //has not been an issue in a very very long time
+
+ // Mapping helpers added via enable_debug_verbs verb
+// verbs += /client/proc/do_not_use_these
+// verbs += /client/proc/camera_view
+// verbs += /client/proc/sec_camera_report
+// verbs += /client/proc/intercom_view
+// verbs += /client/proc/air_status //Air things
+// verbs += /client/proc/Cell //More air things
+
+/client/proc/update_admins(var/rank)
+
+ if(!holder)
+ holder = new /obj/admins(src)
+
+ holder.rank = rank
+
+ if(!holder.state)
+ var/state = alert("Which state do you want the admin to begin in?", "Admin-state", "Play", "Observe", "Neither")
+ if(state == "Play")
+ holder.state = 1
+ admin_play()
+ return
+ else if(state == "Observe")
+ holder.state = 2
+ admin_observe()
+ return
+ else
+ del(holder)
+ return
+
+ switch (rank)
+ if ("Game Master")
+ holder.level = 6
+
+ if ("Senior Game Admin")
+ holder.level = 5
+
+ if ("Game Admin")
+ holder.level = 4
+
+ if ("Secondary Game Admin")
+ holder.level = 3
+
+ if ("Trial Admin")
+ holder.level = 2
+ if(holder.state == 2) // if observing
+ verbs += /client/proc/debug_variables
+ verbs += /client/proc/cmd_modify_ticker_variables
+ verbs += /client/proc/toggle_view_range
+ verbs += /client/proc/Getmob
+ verbs += /client/proc/Getkey
+ verbs += /client/proc/sendmob
+ verbs += /client/proc/Jump
+ verbs += /client/proc/jumptokey
+ verbs += /client/proc/jumptomob
+ verbs += /client/proc/jumptoturf
+ verbs += /client/proc/jumptocoord
+ verbs += /client/proc/cmd_admin_delete
+ verbs += /client/proc/cmd_admin_add_freeform_ai_law
+ verbs += /client/proc/cmd_admin_rejuvenate
+ verbs += /client/proc/cmd_admin_drop_everything
+ //verbs += /client/proc/cmd_modify_object_variables --Merged with view variables
+
+ if ("Temporary Admin")
+ holder.level = 1
+ if(holder.state == 2) // if observing
+ verbs += /client/proc/debug_variables
+ verbs += /client/proc/cmd_modify_ticker_variables
+ verbs += /client/proc/toggle_view_range
+ verbs += /client/proc/Getmob
+ verbs += /client/proc/Getkey
+ verbs += /client/proc/sendmob
+ verbs += /client/proc/Jump
+ verbs += /client/proc/jumptokey
+ verbs += /client/proc/jumptomob
+ verbs += /client/proc/jumptoturf
+ verbs += /client/proc/jumptocoord
+ verbs += /client/proc/cmd_admin_delete
+ verbs += /client/proc/cmd_admin_add_freeform_ai_law
+ verbs += /client/proc/cmd_admin_rejuvenate
+ verbs += /client/proc/cmd_admin_drop_everything
+ //verbs += /client/proc/cmd_modify_object_variables --Merged with view variables
+
+ if ("Moderator")
+ holder.level = 0
+
+ if ("Admin Observer")
+ holder.level = -1
+
+ if ("Banned")
+ holder.level = -2
+ del(src)
+ return
+
+ else
+ del(holder)
+ return
+
+ if (holder) //THE BELOW handles granting powers. The above is for special cases only!
+ holder.owner = src
+
+ //Admin Observer
+ if (holder.level >= -1)
+ verbs += /client/proc/cmd_admin_say
+ verbs += /client/proc/cmd_admin_gib_self
+ verbs += /client/proc/deadmin_self
+ else return
+
+ //Moderator
+ if (holder.level >= 0)
+ verbs += /obj/admins/proc/announce
+ verbs += /obj/admins/proc/startnow
+ verbs += /obj/admins/proc/toggleAI //Toggle the AI
+ verbs += /obj/admins/proc/toggleenter //Toggle enterting
+ verbs += /obj/admins/proc/toggleguests //Toggle guests entering
+ verbs += /obj/admins/proc/toggleooc //toggle ooc
+ verbs += /obj/admins/proc/toggleoocdead //toggle ooc for dead/unc
+ verbs += /obj/admins/proc/voteres //toggle votes
+ verbs += /obj/admins/proc/vmode
+ verbs += /obj/admins/proc/votekill
+ verbs += /obj/admins/proc/show_player_panel
+ verbs += /client/proc/deadchat //toggles deadchat
+ verbs += /client/proc/cmd_admin_mute
+ verbs += /client/proc/cmd_admin_pm_context
+ verbs += /client/proc/cmd_admin_pm_panel
+ verbs += /client/proc/cmd_admin_subtle_message
+ verbs += /client/proc/warn
+ verbs += /client/proc/dsay
+ verbs += /client/proc/admin_play
+ verbs += /client/proc/admin_observe
+ verbs += /client/proc/game_panel
+ verbs += /client/proc/player_panel
+ verbs += /client/proc/player_panel_new
+ verbs += /client/proc/unban_panel
+ verbs += /client/proc/jobbans
+ verbs += /client/proc/unjobban_panel
+ verbs += /client/proc/voting
+ verbs += /client/proc/hide_verbs
+ verbs += /client/proc/general_report
+ verbs += /client/proc/air_report
+ verbs += /client/proc/deadmin_self
+ //verbs += /client/proc/cmd_admin_prison --Merged with player panel
+ //verbs += /obj/admins/proc/unprison --Merged with player panel
+ else return
+
+ //Temporary Admin
+ if (holder.level >= 1)
+ deadchat = 1
+ seeprayers = 1
+
+ verbs += /obj/admins/proc/toggleaban //abandon mob
+ verbs += /obj/admins/proc/show_traitor_panel
+ verbs += /client/proc/cmd_admin_remove_plasma
+ verbs += /client/proc/admin_call_shuttle
+ verbs += /client/proc/admin_cancel_shuttle
+ verbs += /client/proc/cmd_admin_dress
+ verbs += /client/proc/respawn_character
+ verbs += /client/proc/spawn_xeno
+ verbs += /client/proc/toggleprayers
+ verbs += /client/proc/deadmin_self
+ verbs += /client/proc/tension_report
+ verbs += /client/proc/toggleadminhelpsound
+ verbs += /client/proc/cmd_admin_add_random_ai_law
+ verbs += /client/proc/secrets
+ verbs += /client/proc/play_sound
+ verbs += /client/proc/stealth
+ verbs += /obj/admins/proc/delay //game start delay
+ verbs += /obj/admins/proc/immreboot //immediate reboot
+ verbs += /obj/admins/proc/restart //restart
+ verbs += /client/proc/cmd_admin_check_contents
+ verbs += /client/proc/cmd_admin_create_centcom_report
+ verbs += /client/proc/toggle_hear_deadcast
+ verbs += /client/proc/toggle_hear_radio
+ verbs += /proc/possess
+ verbs += /proc/release
+ verbs += /client/proc/deadmin_self
+ else return
+
+/* //Trial Admin
+ if (holder.level >= 2)
+
+ else return
+*/
+ //Secondary Game Admin
+ if (holder.level >= 3)
+ verbs += /obj/admins/proc/view_txt_log
+ verbs += /obj/admins/proc/view_atk_log
+ verbs += /obj/admins/proc/spawn_atom
+ verbs += /client/proc/cmd_admin_list_open_jobs
+ verbs += /client/proc/cmd_admin_direct_narrate
+ verbs += /client/proc/kill_air
+ verbs += /client/proc/cmd_admin_world_narrate
+ verbs += /client/proc/cmd_debug_del_all
+ verbs += /client/proc/cmd_debug_tog_aliens
+ verbs += /client/proc/mapload
+ verbs += /client/proc/check_words
+ verbs += /client/proc/drop_bomb
+ verbs += /client/proc/cmd_admin_grantfullaccess
+ verbs += /client/proc/cmd_admin_drop_everything
+ verbs += /client/proc/make_sound
+ verbs += /client/proc/play_local_sound
+ verbs += /client/proc/send_space_ninja
+ verbs += /client/proc/restartcontroller //Can call via aproccall --I_hate_easy_things.jpg, Mport --Agouri
+ verbs += /client/proc/Blobize //I need to remember to move/remove this later
+ verbs += /client/proc/toggle_clickproc //TODO ERRORAGE (Temporary proc while the new clickproc is being tested)
+ verbs += /client/proc/toggle_gravity_on
+ verbs += /client/proc/toggle_gravity_off
+ verbs += /client/proc/toggle_random_events
+ verbs += /obj/admins/proc/adrev //toggle admin revives
+ verbs += /obj/admins/proc/adspawn //toggle admin item spawning
+ verbs += /client/proc/debug_variables
+ verbs += /client/proc/cmd_modify_ticker_variables
+ verbs += /client/proc/Debug2 //debug toggle switch
+ verbs += /client/proc/toggle_view_range
+ verbs += /client/proc/Getmob
+ verbs += /client/proc/Getkey
+ verbs += /client/proc/sendmob
+ verbs += /client/proc/Jump
+ verbs += /client/proc/jumptokey
+ verbs += /client/proc/jumptomob
+ verbs += /client/proc/jumptoturf
+ verbs += /client/proc/cmd_admin_delete
+ verbs += /client/proc/cmd_admin_add_freeform_ai_law
+ verbs += /client/proc/cmd_admin_add_random_ai_law
+ verbs += /client/proc/cmd_admin_rejuvenate
+ verbs += /client/proc/hide_most_verbs
+ verbs += /client/proc/jumptocoord
+ verbs += /client/proc/cmd_modify_ticker_variables
+ verbs += /client/proc/deadmin_self
+ //verbs += /client/proc/cmd_mass_modify_object_variables --Merged with view variables
+ //verbs += /client/proc/cmd_admin_explosion --Merged with view variables
+ //verbs += /client/proc/cmd_admin_emp --Merged with view variables
+ //verbs += /client/proc/give_spell --Merged with view variables
+ //verbs += /client/proc/cmd_admin_ninjafy --Merged with view variables
+ //verbs += /client/proc/cmd_switch_radio --removed as tcommsat is staying
+ else return
+
+ //Game Admin
+ if (holder.level >= 4)
+ verbs += /client/proc/ticklag
+ else return
+
+ //Senior Game admin
+ if (holder.level >= 5)
+ verbs += /client/proc/colorooc
+ verbs += /client/proc/strike_team
+ verbs += /client/proc/everyone_random
+ verbs += /client/proc/only_one
+ verbs += /obj/admins/proc/toggle_aliens //toggle aliens
+ verbs += /obj/admins/proc/toggle_space_ninja //toggle ninjas
+ verbs += /client/proc/deadmin_self
+ else return
+
+ //Game Master
+ if (holder.level >= 6)
+ verbs += /obj/admins/proc/adjump
+ verbs += /client/proc/callproc
+ verbs += /client/proc/triple_ai
+ verbs += /client/proc/get_admin_state
+ verbs += /client/proc/reload_admins
+ verbs += /client/proc/cmd_debug_make_powernets
+ verbs += /client/proc/object_talk
+ verbs += /client/proc/enable_debug_verbs
+ verbs += /client/proc/deadmin_self
+ else return
+ return
+
+
+/client/proc/clear_admin_verbs()
+ deadchat = 0
+
+ verbs -= /obj/admins/proc/vmode
+ verbs -= /obj/admins/proc/votekill
+ verbs -= /obj/admins/proc/announce
+ verbs -= /obj/admins/proc/startnow
+ verbs -= /obj/admins/proc/toggleAI //Toggle the AI
+ verbs -= /obj/admins/proc/toggleenter //Toggle enterting
+ verbs -= /obj/admins/proc/toggleguests //Toggle guests entering
+ verbs -= /obj/admins/proc/toggleooc //toggle ooc
+ verbs -= /obj/admins/proc/toggleoocdead //toggle ooc for dead/unc
+ verbs -= /obj/admins/proc/voteres //toggle votes
+ verbs -= /obj/admins/proc/delay //game start delay
+ verbs -= /obj/admins/proc/immreboot //immediate reboot
+ verbs -= /obj/admins/proc/restart //restart
+ verbs -= /obj/admins/proc/show_traitor_panel
+ verbs -= /obj/admins/proc/show_player_panel
+ verbs -= /obj/admins/proc/toggle_aliens //toggle aliens
+ verbs -= /obj/admins/proc/toggle_space_ninja //toggle ninjas
+ verbs -= /obj/admins/proc/adjump
+ verbs -= /obj/admins/proc/view_txt_log
+ verbs -= /obj/admins/proc/view_atk_log
+ verbs -= /obj/admins/proc/spawn_atom
+ verbs -= /obj/admins/proc/adrev //toggle admin revives
+ verbs -= /obj/admins/proc/adspawn //toggle admin item spawning
+ verbs -= /obj/admins/proc/toggleaban //abandon mob
+ verbs -= /client/proc/hide_verbs
+ verbs -= /client/proc/hide_most_verbs
+ verbs -= /client/proc/show_verbs
+ verbs -= /client/proc/colorooc
+ verbs -= /client/proc/triple_ai
+ verbs -= /client/proc/get_admin_state
+ verbs -= /client/proc/reload_admins
+ verbs -= /client/proc/kill_air
+ verbs -= /client/proc/cmd_debug_make_powernets
+ verbs -= /client/proc/object_talk
+ verbs -= /client/proc/strike_team
+ verbs -= /client/proc/cmd_admin_list_open_jobs
+ verbs -= /client/proc/cmd_admin_direct_narrate
+ verbs -= /client/proc/cmd_admin_world_narrate
+ verbs -= /client/proc/callproc
+ verbs -= /client/proc/Cell
+ verbs -= /client/proc/cmd_debug_del_all
+ verbs -= /client/proc/cmd_debug_tog_aliens
+ verbs -= /client/proc/ticklag
+ verbs -= /client/proc/mapload
+ verbs -= /client/proc/check_words
+ verbs -= /client/proc/drop_bomb
+ verbs -= /client/proc/cmd_admin_grantfullaccess
+ verbs -= /client/proc/cmd_admin_drop_everything
+ verbs -= /client/proc/make_sound
+ verbs -= /client/proc/only_one
+ verbs -= /client/proc/send_space_ninja
+ verbs -= /client/proc/debug_variables
+ verbs -= /client/proc/cmd_modify_ticker_variables
+ verbs -= /client/proc/Debug2 //debug toggle switch
+ verbs -= /client/proc/toggle_view_range
+ verbs -= /client/proc/Getmob
+ verbs -= /client/proc/Getkey
+ verbs -= /client/proc/sendmob
+ verbs -= /client/proc/Jump
+ verbs -= /client/proc/jumptokey
+ verbs -= /client/proc/jumptomob
+ verbs -= /client/proc/jumptoturf
+ verbs -= /client/proc/cmd_admin_add_freeform_ai_law
+ verbs -= /client/proc/cmd_admin_add_random_ai_law
+ verbs -= /client/proc/cmd_admin_rejuvenate
+ verbs -= /client/proc/cmd_admin_delete
+ verbs -= /client/proc/toggleadminhelpsound
+ verbs -= /client/proc/cmd_admin_remove_plasma
+ verbs -= /client/proc/admin_call_shuttle
+ verbs -= /client/proc/admin_cancel_shuttle
+ verbs -= /client/proc/cmd_admin_dress
+ verbs -= /client/proc/respawn_character
+ verbs -= /client/proc/spawn_xeno
+ verbs -= /client/proc/cmd_admin_add_random_ai_law
+ verbs -= /client/proc/secrets
+ verbs -= /client/proc/play_sound
+ verbs -= /client/proc/stealth
+ verbs -= /client/proc/cmd_admin_check_contents
+ verbs -= /client/proc/cmd_admin_create_centcom_report
+ verbs -= /client/proc/deadchat //toggles deadchat
+ verbs -= /client/proc/cmd_admin_mute
+ verbs -= /client/proc/cmd_admin_pm_context
+ verbs -= /client/proc/cmd_admin_pm_panel
+ verbs -= /client/proc/cmd_admin_say
+ verbs -= /client/proc/cmd_admin_subtle_message
+ verbs -= /client/proc/warn
+ verbs -= /client/proc/dsay
+ verbs -= /client/proc/admin_play
+ verbs -= /client/proc/admin_observe
+ verbs -= /client/proc/game_panel
+ verbs -= /client/proc/player_panel
+ verbs -= /client/proc/unban_panel
+ verbs -= /client/proc/jobbans
+ verbs -= /client/proc/unjobban_panel
+ verbs -= /client/proc/voting
+ verbs -= /client/proc/hide_verbs
+ verbs -= /client/proc/general_report
+ verbs -= /client/proc/air_report
+ verbs -= /client/proc/cmd_admin_say
+ verbs -= /client/proc/cmd_admin_gib_self
+ verbs -= /client/proc/restartcontroller
+ verbs -= /client/proc/play_local_sound
+ verbs -= /client/proc/enable_debug_verbs
+ verbs -= /client/proc/toggleprayers
+ verbs -= /client/proc/Blobize
+ verbs -= /client/proc/toggle_clickproc //TODO ERRORAGE (Temporary proc while the enw clickproc is being tested)
+ verbs -= /client/proc/toggle_hear_deadcast
+ verbs -= /client/proc/toggle_hear_radio
+ verbs -= /client/proc/tension_report
+ verbs -= /client/proc/player_panel_new
+ verbs -= /client/proc/toggle_gravity_on
+ verbs -= /client/proc/toggle_gravity_off
+ verbs -= /client/proc/toggle_random_events
+ verbs -= /client/proc/deadmin_self
+ verbs -= /client/proc/jumptocoord
+ verbs -= /client/proc/everyone_random
+ verbs -= /proc/possess
+ verbs -= /proc/release
+ //verbs -= /client/proc/give_spell --Merged with view variables
+ //verbs -= /client/proc/cmd_admin_ninjafy --Merged with view variables
+ //verbs -= /client/proc/cmd_modify_object_variables --Merged with view variables
+ //verbs -= /client/proc/cmd_admin_explosion --Merged with view variables
+ //verbs -= /client/proc/cmd_admin_emp --Merged with view variables
+ //verbs -= /client/proc/cmd_admin_godmode --Merged with view variables
+ //verbs -= /client/proc/cmd_admin_gib --Merged with view variables
+ //verbs -= /client/proc/cmd_mass_modify_object_variables --Merged with view variables
+ //verbs -= /client/proc/cmd_admin_attack_log --Merged with view variables
+ //verbs -= /proc/togglebuildmode --Merged with view variables
+ //verbs -= /client/proc/cmd_admin_prison --Merged with player panel
+ //verbs -= /obj/admins/proc/unprison --Merged with player panel
+ //verbs -= /client/proc/cmd_switch_radio --removed because tcommsat is staying
+ verbs -= /client/proc/togglebuildmodeself
+ return
+
+
+/client/proc/admin_observe()
+ set category = "Admin"
+ set name = "Set Observe"
+ if(!holder)
+ alert("You are not an admin")
+ return
+
+ verbs -= /client/proc/admin_play
+ spawn( 1200 )
+ verbs += /client/proc/admin_play
+ var/rank = holder.rank
+ clear_admin_verbs()
+ holder.state = 2
+ update_admins(rank)
+ if(!istype(mob, /mob/dead/observer))
+ mob.adminghostize(1)
+ src << "\blue You are now observing"
+
+/client/proc/admin_play()
+ set category = "Admin"
+ set name = "Set Play"
+ if(!holder)
+ alert("You are not an admin")
+ return
+ verbs -= /client/proc/admin_observe
+ spawn( 1200 )
+ verbs += /client/proc/admin_observe
+ var/rank = holder.rank
+ clear_admin_verbs()
+ holder.state = 1
+ update_admins(rank)
+ if(istype(mob, /mob/dead/observer))
+ mob:reenter_corpse()
+ src << "\blue You are now playing"
+
+/client/proc/get_admin_state()
+ set name = "Get Admin State"
+ set category = "Debug"
+ for(var/mob/M in world)
+ if(M.client && M.client.holder)
+ if(M.client.holder.state == 1)
+ src << "[M.key] is playing - [M.client.holder.state]"
+ else if(M.client.holder.state == 2)
+ src << "[M.key] is observing - [M.client.holder.state]"
+ else
+ src << "[M.key] is undefined - [M.client.holder.state]"
+
+
+/client/proc/player_panel()
+ set name = "Player Panel"
+ set category = "Admin"
+ if(holder)
+ holder.player_panel_old()
+ return
+
+/client/proc/player_panel_new()
+ set name = "Player Panel-New"
+ set category = "Admin"
+ if(holder)
+ holder.player_panel_new()
+ return
+
+/client/proc/jobbans()
+ set name = "Display Job bans"
+ set category = "Admin"
+ if(holder)
+ holder.Jobbans()
+ return
+
+/client/proc/unban_panel()
+ set name = "Unban Panel"
+ set category = "Admin"
+ if(holder)
+ holder.unbanpanel()
+ return
+
+/client/proc/game_panel()
+ set name = "Game Panel"
+ set category = "Admin"
+ if(holder)
+ holder.Game()
+ return
+
+/client/proc/secrets()
+ set name = "Secrets"
+ set category = "Admin"
+ if (holder)
+ holder.Secrets()
+ return
+
+/client/proc/voting()
+ set name = "Voting"
+ set category = "Admin"
+ if (holder)
+ holder.Voting()
+
+/client/proc/colorooc()
+ set category = "Fun"
+ set name = "OOC Text Color"
+ ooccolor = input(src, "Please select your OOC colour.", "OOC colour") as color
+ return
+
+/client/proc/stealth()
+ set category = "Admin"
+ set name = "Stealth Mode"
+ if(!authenticated || !holder)
+ src << "Only administrators may use this command."
+ return
+ stealth = !stealth
+ if(stealth)
+ var/new_key = trim(input("Enter your desired display name.", "Fake Key", key))
+ if(!new_key)
+ stealth = 0
+ return
+ new_key = strip_html(new_key)
+ if(length(new_key) >= 26)
+ new_key = copytext(new_key, 1, 26)
+ fakekey = new_key
+ else
+ fakekey = null
+ log_admin("[key_name(usr)] has turned stealth mode [stealth ? "ON" : "OFF"]")
+ message_admins("[key_name_admin(usr)] has turned stealth mode [stealth ? "ON" : "OFF"]", 1)
+
+#define AUTOBATIME 10
+/client/proc/warn(var/mob/M in world)
+ set category = "Special Verbs"
+ set name = "Warn"
+ set desc = "Warn a player"
+ if(!authenticated || !holder)
+ src << "Only administrators may use this command."
+ return
+ if(M.client && M.client.holder && (M.client.holder.level >= holder.level))
+ alert("You cannot perform this action. You must be of a higher administrative rank!", null, null, null, null, null)
+ return
+ if(!M.client.warned)
+ M << "\red You have been warned by an administrator. This is the only warning you will recieve. "
+ M.client.warned = 1
+ message_admins("\blue [ckey] warned [M.ckey].")
+ else
+ AddBan(M.ckey, M.computer_id, "Autobanning due to previous warn", ckey, 1, AUTOBATIME)
+ M << "\redYou have been autobanned by [ckey]. This is what we in the biz like to call a \"second warning\". "
+ M << "\red This is a temporary ban; it will automatically be removed in [AUTOBATIME] minutes."
+ log_admin("[ckey] warned [M.ckey], resulting in a [AUTOBATIME] minute autoban.")
+ ban_unban_log_save("[ckey] warned [M.ckey], resulting in a [AUTOBATIME] minute autoban.")
+ message_admins("\blue [ckey] warned [M.ckey], resulting in a [AUTOBATIME] minute autoban.")
+ feedback_inc("ban_warn",1)
+
+ del(M.client)
+
+
+/client/proc/drop_bomb() // Some admin dickery that can probably be done better -- TLE
+ set category = "Special Verbs"
+ set name = "Drop Bomb"
+ set desc = "Cause an explosion of varying strength at your location."
+
+ var/turf/epicenter = mob.loc
+ var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb")
+ var/choice = input("What size explosion would you like to produce?") in choices
+ switch(choice)
+ if(null)
+ return 0
+ if("Small Bomb")
+ explosion(epicenter, 1, 2, 3, 3)
+ if("Medium Bomb")
+ explosion(epicenter, 2, 3, 4, 4)
+ if("Big Bomb")
+ explosion(epicenter, 3, 5, 7, 5)
+ if("Custom Bomb")
+ var/devastation_range = input("Devastation range (in tiles):") as num
+ var/heavy_impact_range = input("Heavy impact range (in tiles):") as num
+ var/light_impact_range = input("Light impact range (in tiles):") as num
+ var/flash_range = input("Flash range (in tiles):") as num
+ explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range)
+ message_admins("\blue [ckey] creating an admin explosion at [epicenter.loc].")
+
+/client/proc/give_spell(mob/T as mob in world) // -- Urist
+ set category = "Fun"
+ set name = "Give Spell"
+ set desc = "Gives a spell to a mob."
+ var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spells
+ if(!S) return
+ T.spell_list += new S
+
+/client/proc/make_sound(var/obj/O in world) // -- TLE
+ set category = "Special Verbs"
+ set name = "Make Sound"
+ set desc = "Display a message to everyone who can hear the target"
+ if(O)
+ var/message = input("What do you want the message to be?", "Make Sound") as text|null
+ if(!message)
+ return
+ for (var/mob/V in hearers(O))
+ V.show_message(message, 2)
+
+
+/client/proc/togglebuildmodeself()
+ set name = "Toggle Build Mode Self"
+ set category = "Special Verbs"
+ if(src.mob)
+ togglebuildmode(src.mob)
+
+
+/client/proc/toggleadminhelpsound()
+ set name = "Toggle Adminhelp Sound"
+ set category = "Admin"
+ sound_adminhelp = !sound_adminhelp
+ if(sound_adminhelp)
+ usr << "You will now hear a sound when adminhelps arrive"
+ else
+ usr << "You will no longer hear a sound when adminhelps arrive"
+
+/client/proc/object_talk(var/msg as text) // -- TLE
+ set category = "Special Verbs"
+ set name = "oSay"
+ set desc = "Display a message to everyone who can hear the target"
+ if(mob.control_object)
+ if(!msg)
+ return
+ for (var/mob/V in hearers(mob.control_object))
+ V.show_message("[mob.control_object.name] says: \"" + msg + "\"", 2)
+
+/client/proc/kill_air() // -- TLE
+ set category = "Debug"
+ set name = "Kill Air"
+ set desc = "Toggle Air Processing"
+ if(kill_air)
+ kill_air = 0
+ usr << "Enabled air processing. "
+ else
+ kill_air = 1
+ usr << "Disabled air processing. "
+
+/client/proc/show_verbs()
+ set name = "Toggle admin verb visibility"
+ set category = "Admin"
+ src << "Restoring admin verbs back"
+
+ var/temp = deadchat
+ clear_admin_verbs()
+ update_admins(holder.rank)
+ deadchat = temp
+
+/client/proc/toggle_clickproc() //TODO ERRORAGE (This is a temporary verb here while I test the new clicking proc)
+ set name = "Toggle NewClickProc"
+ set category = "Admin"
+
+ if(!holder) return
+ using_new_click_proc = !using_new_click_proc
+ world << "Testing of new click proc [using_new_click_proc ? "enabled" : "disabled"]"
+
+/client/proc/toggle_hear_deadcast()
+ set name = "Toggle Hear Deadcast"
+ set category = "Admin"
+
+ if(!holder) return
+ STFU_ghosts = !STFU_ghosts
+ usr << "You will now [STFU_ghosts ? "not hear" : "hear"] ghosts"
+
+/client/proc/toggle_hear_radio()
+ set name = "Toggle Hear Radio"
+ set category = "Admin"
+
+ if(!holder) return
+ STFU_radio = !STFU_radio
+ usr << "You will now [STFU_radio ? "not hear" : "hear"] radio chatter from nearby radios or speakers"
+
+/client/proc/deadmin_self()
+ set name = "De-admin self"
+ set category = "Admin"
+
+ if(src.holder)
+ if(alert("Confirm self-deadmin for the round? You can't re-admin yourself without someont promoting you.",,"Yes","No") == "Yes")
+ del(holder)
+ log_admin("[src] deadmined themself.")
+ message_admins("[src] deadmined themself.", 1)
+ src.clear_admin_verbs()
+ src.update_admins(null)
+ admins.Remove(src.ckey)
+ usr << "You are now a normal player."
+
+/client/proc/startSinglo()
+ set name = "Singlo Starter"
+ set category = "Debug"
+ set desc = "Starts a self-sustaining, stable singlo. This artifical singlo does not have a gravitational pull."
+
+ for(var/obj/machinery/emitter/E in world)
+ if(E.anchored)
+ E.active = 1
+
+ for(var/obj/machinery/field_generator/F in world)
+ if(F.anchored)
+ F.Varedit_start = 1
+ spawn(30)
+ for(var/obj/machinery/the_singularitygen/G in world)
+ if(G.anchored)
+ var/obj/machinery/singularity/S = new /obj/machinery/singularity(get_turf(G), 50)
+ spawn(0)
+ del(G)
+ S.energy = 1750
+ S.current_size = 7
+ S.icon = '224x224.dmi'
+ S.icon_state = "singularity_s7"
+ S.pixel_x = -96
+ S.pixel_y = -96
+ S.grav_pull = 0
+ //S.consume_range = 3
+ S.dissipate = 0
+ //S.dissipate_delay = 10
+ //S.dissipate_track = 0
+ //S.dissipate_strength = 10
+
+ for(var/obj/machinery/power/rad_collector/Rad in world)
+ if(Rad.anchored)
+ if(!Rad.P)
+ var/obj/item/weapon/tank/plasma/Plasma = new/obj/item/weapon/tank/plasma(Rad)
+ Plasma.air_contents.toxins = 70
+ Rad.drainratio = 0
+ Rad.P = Plasma
+ Plasma.loc = Rad
+
+ if(!Rad.active)
+ Rad.toggle_power()
+
+ for(var/obj/machinery/power/smes/SMES in world)
+ if(SMES.anchored)
+ SMES.chargemode = 1
+
+/client/proc/hide_most_verbs()//Allows you to keep some functionality while hiding some verbs
+ set name = "Toggle most admin verb visibility"
+ set category = "Admin"
+ src << "Hiding most admin verbs"
+
+ var/temp = deadchat
+ clear_admin_verbs()
+ deadchat = temp
+ verbs -= /client/proc/hide_verbs
+ verbs -= /client/proc/hide_most_verbs
+ verbs += /client/proc/show_verbs
+
+ if(holder.level >= 5)//Senior Game Admin********************************************************************
+ verbs += /client/proc/colorooc
+
+ if(holder.level >= 3)//Secondary Game admin********************************************************************
+ verbs += /client/proc/debug_variables
+ //verbs += /client/proc/cmd_modify_object_variables --merged with view vairiables
+ verbs += /client/proc/Jump
+ verbs += /client/proc/jumptoturf
+ verbs += /client/proc/togglebuildmodeself
+
+ verbs += /client/proc/dsay
+ verbs += /client/proc/admin_play
+ verbs += /client/proc/admin_observe
+ verbs += /client/proc/game_panel
+ verbs += /client/proc/player_panel
+ verbs += /client/proc/cmd_admin_subtle_message
+ verbs += /client/proc/cmd_admin_pm_context
+ verbs += /client/proc/cmd_admin_pm_panel
+ verbs += /client/proc/cmd_admin_gib_self
+
+ verbs += /client/proc/deadchat //toggles deadchat
+ verbs += /obj/admins/proc/toggleooc //toggle ooc
+ verbs += /client/proc/cmd_admin_say//asay
+ verbs += /client/proc/toggleadminhelpsound
+ return
+
+
+/client/proc/hide_verbs()
+ set name = "Toggle admin verb visibility"
+ set category = "Admin"
+ src << "Hiding almost all admin verbs"
+
+ var/temp = deadchat
+ clear_admin_verbs()
+ deadchat = temp
+ verbs -= /client/proc/hide_verbs
+ verbs -= /client/proc/hide_most_verbs
+ verbs += /client/proc/show_verbs
+
+ verbs += /client/proc/deadchat //toggles deadchat
+ verbs += /obj/admins/proc/toggleooc //toggle ooc
+ verbs += /client/proc/cmd_admin_say//asay
+ return
diff --git a/code/modules/admin/new/verbs/modifyvariables.dm b/code/modules/admin/new/verbs/modifyvariables.dm
new file mode 100644
index 0000000000..d1be847c9c
--- /dev/null
+++ b/code/modules/admin/new/verbs/modifyvariables.dm
@@ -0,0 +1,502 @@
+var/list/forbidden_varedit_object_types = list(
+ /obj/admins, //Admins editing their own admin-power object? Yup, sounds like a good idea.
+ /obj/machinery/blackbox_recorder, //Prevents people messing with feedback gathering
+ /datum/feedback_variable //Prevents people messing with feedback gathering
+ )
+
+/client/proc/cmd_modify_object_variables(obj/O as obj|mob|turf|area in world)
+ set category = "Debug"
+ set name = "Edit Variables"
+ set desc="(target) Edit a target item's variables"
+ src.modify_variables(O)
+
+/client/proc/cmd_modify_ticker_variables()
+ set category = "Debug"
+ set name = "Edit Ticker Variables"
+
+ if (ticker == null)
+ src << "Game hasn't started yet."
+ else
+ src.modify_variables(ticker)
+
+/client/proc/mod_list_add_ass() //haha
+
+ var/class = "text"
+ if(src.holder && src.holder.marked_datum)
+ class = input("What kind of variable?","Variable Type") as null|anything in list("text",
+ "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])")
+ else
+ class = input("What kind of variable?","Variable Type") as null|anything in list("text",
+ "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default")
+
+ if(!class)
+ return
+
+ if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])")
+ class = "marked datum"
+
+ var/var_value = null
+
+ switch(class)
+
+ if("text")
+ var_value = input("Enter new text:","Text") as null|text
+
+ if("num")
+ var_value = input("Enter new number:","Num") as null|num
+
+ if("type")
+ var_value = input("Enter type:","Type") as null|anything in typesof(/obj,/mob,/area,/turf)
+
+ if("reference")
+ var_value = input("Select reference:","Reference") as null|mob|obj|turf|area in world
+
+ if("mob reference")
+ var_value = input("Select reference:","Reference") as null|mob in world
+
+ if("file")
+ var_value = input("Pick file:","File") as null|file
+
+ if("icon")
+ var_value = input("Pick icon:","Icon") as null|icon
+
+ if("marked datum")
+ var_value = holder.marked_datum
+
+ if(!var_value) return
+
+ return var_value
+
+
+/client/proc/mod_list_add(var/list/L)
+
+ var/class = "text"
+ if(src.holder && src.holder.marked_datum)
+ class = input("What kind of variable?","Variable Type") as null|anything in list("text",
+ "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])")
+ else
+ class = input("What kind of variable?","Variable Type") as null|anything in list("text",
+ "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default")
+
+ if(!class)
+ return
+
+ if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])")
+ class = "marked datum"
+
+ var/var_value = null
+
+ switch(class)
+
+ if("text")
+ var_value = input("Enter new text:","Text") as text
+
+ if("num")
+ var_value = input("Enter new number:","Num") as num
+
+ if("type")
+ var_value = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf)
+
+ if("reference")
+ var_value = input("Select reference:","Reference") as mob|obj|turf|area in world
+
+ if("mob reference")
+ var_value = input("Select reference:","Reference") as mob in world
+
+ if("file")
+ var_value = input("Pick file:","File") as file
+
+ if("icon")
+ var_value = input("Pick icon:","Icon") as icon
+
+ if("marked datum")
+ var_value = holder.marked_datum
+
+ if(!var_value) return
+
+ switch(alert("Would you like to associate a var with the list entry?",,"Yes","No"))
+ if("Yes")
+ L += var_value
+ L[var_value] = mod_list_add_ass() //haha
+ if("No")
+ L += var_value
+
+/client/proc/mod_list(var/list/L)
+ if(!istype(L,/list)) src << "Not a List."
+
+ var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine", "poo", "icon", "icon_state")
+
+ var/list/names = sortList(L)
+
+ var/variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)"
+
+ if(variable == "(ADD VAR)")
+ mod_list_add(L)
+ return
+
+ if(!variable)
+ return
+
+ var/default
+
+ var/dir
+
+ if (locked.Find(variable) && !(src.holder.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")))
+ return
+
+ if(isnull(variable))
+ usr << "Unable to determine variable type."
+
+ else if(isnum(variable))
+ usr << "Variable appears to be NUM ."
+ default = "num"
+ dir = 1
+
+ else if(istext(variable))
+ usr << "Variable appears to be TEXT ."
+ default = "text"
+
+ else if(isloc(variable))
+ usr << "Variable appears to be REFERENCE ."
+ default = "reference"
+
+ else if(isicon(variable))
+ usr << "Variable appears to be ICON ."
+ variable = "\icon[variable]"
+ default = "icon"
+
+ else if(istype(variable,/atom) || istype(variable,/datum))
+ usr << "Variable appears to be TYPE ."
+ default = "type"
+
+ else if(istype(variable,/list))
+ usr << "Variable appears to be LIST ."
+ default = "list"
+
+ else if(istype(variable,/client))
+ usr << "Variable appears to be CLIENT ."
+ default = "cancel"
+
+ else
+ usr << "Variable appears to be FILE ."
+ default = "file"
+
+ usr << "Variable contains: [variable]"
+ if(dir)
+ switch(variable)
+ if(1)
+ dir = "NORTH"
+ if(2)
+ dir = "SOUTH"
+ if(4)
+ dir = "EAST"
+ if(8)
+ dir = "WEST"
+ if(5)
+ dir = "NORTHEAST"
+ if(6)
+ dir = "SOUTHEAST"
+ if(9)
+ dir = "NORTHWEST"
+ if(10)
+ dir = "SOUTHWEST"
+ else
+ dir = null
+
+ if(dir)
+ usr << "If a direction, direction is: [dir]"
+
+ var/class = "text"
+ if(src.holder && src.holder.marked_datum)
+ class = input("What kind of variable?","Variable Type",default) as null|anything in list("text",
+ "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])")
+ else
+ class = input("What kind of variable?","Variable Type",default) as null|anything in list("text",
+ "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default")
+
+ if(!class)
+ return
+
+ if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])")
+ class = "marked datum"
+
+ switch(class)
+
+ if("list")
+ mod_list(variable)
+
+ if("restore to default")
+ variable = initial(variable)
+
+ if("edit referenced object")
+ modify_variables(variable)
+
+ if("(DELETE FROM LIST)")
+ L -= variable
+ return
+
+ if("text")
+ variable = input("Enter new text:","Text",\
+ variable) as text
+
+ if("num")
+ variable = input("Enter new number:","Num",\
+ variable) as num
+
+ if("type")
+ variable = input("Enter type:","Type",variable) \
+ in typesof(/obj,/mob,/area,/turf)
+
+ if("reference")
+ variable = input("Select reference:","Reference",\
+ variable) as mob|obj|turf|area in world
+
+ if("mob reference")
+ variable = input("Select reference:","Reference",\
+ variable) as mob in world
+
+ if("file")
+ variable = input("Pick file:","File",variable) \
+ as file
+
+ if("icon")
+ variable = input("Pick icon:","Icon",variable) \
+ as icon
+
+ if("marked datum")
+ variable = holder.marked_datum
+
+/client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)
+ var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "urine", "poo", "icon", "icon_state")
+
+ if(!src.authenticated || !src.holder)
+ src << "Only administrators may use this command."
+ return
+
+ for(var/p in forbidden_varedit_object_types)
+ if( istype(O,p) )
+ usr << "\red It is forbidden to edit this object's variables."
+ return
+
+ var/class
+ var/variable
+ var/var_value
+
+ if(param_var_name)
+ if(!param_var_name in O.vars)
+ src << "A variable with this name ([param_var_name]) doesn't exist in this atom ([O])"
+ return
+
+ if (param_var_name == "holder" && holder.rank != "Game Master")
+ src << "No. Stop being stupid."
+ return
+
+ if (locked.Find(param_var_name) && !(src.holder.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")))
+ src << "Editing this variable requires you to be a game master or game admin."
+ return
+
+ variable = param_var_name
+
+ var_value = O.vars[variable]
+
+ if(autodetect_class)
+ if(isnull(var_value))
+ usr << "Unable to determine variable type."
+ class = null
+ autodetect_class = null
+ else if(isnum(var_value))
+ usr << "Variable appears to be NUM ."
+ class = "num"
+ dir = 1
+
+ else if(istext(var_value))
+ usr << "Variable appears to be TEXT ."
+ class = "text"
+
+ else if(isloc(var_value))
+ usr << "Variable appears to be REFERENCE ."
+ class = "reference"
+
+ else if(isicon(var_value))
+ usr << "Variable appears to be ICON ."
+ var_value = "\icon[var_value]"
+ class = "icon"
+
+ else if(istype(var_value,/atom) || istype(var_value,/datum))
+ usr << "Variable appears to be TYPE ."
+ class = "type"
+
+ else if(istype(var_value,/list))
+ usr << "Variable appears to be LIST ."
+ class = "list"
+
+ else if(istype(var_value,/client))
+ usr << "Variable appears to be CLIENT ."
+ class = "cancel"
+
+ else
+ usr << "Variable appears to be FILE ."
+ class = "file"
+
+ else
+
+ var/list/names = list()
+ for (var/V in O.vars)
+ names += V
+
+ names = sortList(names)
+
+ variable = input("Which var?","Var") as null|anything in names
+ if(!variable)
+ return
+ var_value = O.vars[variable]
+
+ if (locked.Find(variable) && !(src.holder.rank in list("Secondary Game Admin", "Game Admin", "Senior Game Admin", "Game Master")))
+ return
+
+ if (variable == "holder" && holder.rank != "Game Master") //Hotfix, a bit ugly but that exploit has been there for ages and now somebody just had to go and tell everyone of it bluh bluh - U
+ return
+
+ if(!autodetect_class)
+
+ var/dir
+ var/default
+ if(isnull(var_value))
+ usr << "Unable to determine variable type."
+
+ else if(isnum(var_value))
+ usr << "Variable appears to be NUM ."
+ default = "num"
+ dir = 1
+
+ else if(istext(var_value))
+ usr << "Variable appears to be TEXT ."
+ default = "text"
+
+ else if(isloc(var_value))
+ usr << "Variable appears to be REFERENCE ."
+ default = "reference"
+
+ else if(isicon(var_value))
+ usr << "Variable appears to be ICON ."
+ var_value = "\icon[var_value]"
+ default = "icon"
+
+ else if(istype(var_value,/atom) || istype(var_value,/datum))
+ usr << "Variable appears to be TYPE ."
+ default = "type"
+
+ else if(istype(var_value,/list))
+ usr << "Variable appears to be LIST ."
+ default = "list"
+
+ else if(istype(var_value,/client))
+ usr << "Variable appears to be CLIENT ."
+ default = "cancel"
+
+ else
+ usr << "Variable appears to be FILE ."
+ default = "file"
+
+ usr << "Variable contains: [var_value]"
+ if(dir)
+ switch(var_value)
+ if(1)
+ dir = "NORTH"
+ if(2)
+ dir = "SOUTH"
+ if(4)
+ dir = "EAST"
+ if(8)
+ dir = "WEST"
+ if(5)
+ dir = "NORTHEAST"
+ if(6)
+ dir = "SOUTHEAST"
+ if(9)
+ dir = "NORTHWEST"
+ if(10)
+ dir = "SOUTHWEST"
+ else
+ dir = null
+ if(dir)
+ usr << "If a direction, direction is: [dir]"
+
+ if(src.holder && src.holder.marked_datum)
+ class = input("What kind of variable?","Variable Type",default) as null|anything in list("text",
+ "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])")
+ else
+ class = input("What kind of variable?","Variable Type",default) as null|anything in list("text",
+ "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default")
+
+ if(!class)
+ return
+
+ var/original_name
+
+ if (!istype(O, /atom))
+ original_name = "\ref[O] ([O])"
+ else
+ original_name = O:name
+
+ if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])")
+ class = "marked datum"
+
+ switch(class)
+
+ if("list")
+ mod_list(O.vars[variable])
+ return
+
+ if("restore to default")
+ O.vars[variable] = initial(O.vars[variable])
+
+ if("edit referenced object")
+ return .(O.vars[variable])
+
+ if("text")
+ var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text
+ if(var_new==null) return
+ O.vars[variable] = var_new
+
+ if("num")
+ if(variable=="luminosity")
+ var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
+ if(var_new == null) return
+ O.sd_SetLuminosity(var_new)
+ else
+ var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
+ if(var_new==null) return
+ O.vars[variable] = var_new
+
+ if("type")
+ var/var_new = input("Enter type:","Type",O.vars[variable]) as null|anything in typesof(/obj,/mob,/area,/turf)
+ if(var_new==null) return
+ O.vars[variable] = var_new
+
+ if("reference")
+ var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob|obj|turf|area in world
+ if(var_new==null) return
+ O.vars[variable] = var_new
+
+ if("mob reference")
+ var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob in world
+ if(var_new==null) return
+ O.vars[variable] = var_new
+
+ if("file")
+ var/var_new = input("Pick file:","File",O.vars[variable]) as null|file
+ if(var_new==null) return
+ O.vars[variable] = var_new
+
+ if("icon")
+ var/var_new = input("Pick icon:","Icon",O.vars[variable]) as null|icon
+ if(var_new==null) return
+ O.vars[variable] = var_new
+
+ if("marked datum")
+ O.vars[variable] = holder.marked_datum
+
+ log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
+ message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]", 1)
+
diff --git a/code/modules/admin/new/verbs/playsound.dm b/code/modules/admin/new/verbs/playsound.dm
new file mode 100644
index 0000000000..79062a0961
--- /dev/null
+++ b/code/modules/admin/new/verbs/playsound.dm
@@ -0,0 +1,98 @@
+/client/proc/play_sound(S as sound)
+ set category = "Fun"
+ set name = "Play Global Sound"
+
+ //if(Debug2)
+ if(!src.authenticated || !src.holder)
+ src << "Only administrators may use this command."
+ return
+
+ var/sound/uploaded_sound = sound(S,0,1,0)
+ uploaded_sound.channel = 777
+ uploaded_sound.priority = 255
+ uploaded_sound.wait = 1
+
+ if(src.holder.rank == "Game Master" || src.holder.rank == "Senior Game Admin" || src.holder.rank == "Game Admin" || src.holder.rank == "Secondary Game Admin")
+ log_admin("[key_name(src)] played sound [S]")
+ message_admins("[key_name_admin(src)] played sound [S]", 1)
+ for(var/mob/M in world)
+ if(M.client)
+ if(M.client.midis)
+ M << uploaded_sound
+ else
+ if(usr.client.canplaysound)
+ usr.client.canplaysound = 0
+ log_admin("[key_name(src)] played sound [S]")
+ message_admins("[key_name_admin(src)] played sound [S]", 1)
+ for(var/mob/M in world)
+ if(M.client)
+ if(M.client.midis)
+ M << uploaded_sound
+ else
+ usr << "You already used up your jukebox monies this round!"
+ del(uploaded_sound)
+
+
+/client/proc/play_local_sound(S as sound)
+ set category = "Fun"
+ set name = "Play Local Sound"
+
+ if(!src.authenticated || !src.holder)
+ src << "Only administrators may use this command."
+ return
+
+ if(src.holder.rank == "Game Master" || src.holder.rank == "Senior Game Admin" || src.holder.rank == "Game Admin" || src.holder.rank == "Secondary Game Admin")
+ log_admin("[key_name(src)] played a local sound [S]")
+ message_admins("[key_name_admin(src)] played a local sound [S]", 1)
+ playsound(get_turf_loc(src.mob), S, 50, 0, 0)
+ return
+
+
+/*
+/client/proc/cuban_pete()
+ set category = "Fun"
+ set name = "Cuban Pete Time"
+
+ message_admins("[key_name_admin(usr)] has declared Cuban Pete Time!", 1)
+ for(var/mob/M in world)
+ if(M.client)
+ if(M.client.midis)
+ M << 'cubanpetetime.ogg'
+
+ for(var/mob/living/carbon/human/CP in world)
+ if(CP.real_name=="Cuban Pete" && CP.key!="Rosham")
+ CP << "Your body can't contain the rhumba beat"
+ CP.gib(1)
+
+
+/client/proc/bananaphone()
+ set category = "Fun"
+ set name = "Banana Phone"
+
+ message_admins("[key_name_admin(usr)] has activated Banana Phone!", 1)
+ for(var/mob/M in world)
+ if(M.client)
+ if(M.client.midis)
+ M << 'bananaphone.ogg'
+
+
+client/proc/space_asshole()
+ set category = "Fun"
+ set name = "Space Asshole"
+
+ message_admins("[key_name_admin(usr)] has played the Space Asshole Hymn.", 1)
+ for(var/mob/M in world)
+ if(M.client)
+ if(M.client.midis)
+ M << 'space_asshole.ogg'
+
+
+client/proc/honk_theme()
+ set category = "Fun"
+ set name = "Honk"
+
+ message_admins("[key_name_admin(usr)] has creeped everyone out with Blackest Honks.", 1)
+ for(var/mob/M in world)
+ if(M.client)
+ if(M.client.midis)
+ M << 'honk_theme.ogg'*/
diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm
index 3722cf009c..80897df1c3 100644
--- a/code/modules/admin/verbs/diagnostics.dm
+++ b/code/modules/admin/verbs/diagnostics.dm
@@ -20,6 +20,7 @@
"}
usr << browse(output,"window=generalreport")
+ //feedback_add_details("admin_verb","SGR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
air_report()
set category = "Debug"
@@ -62,6 +63,7 @@
"}
usr << browse(output,"window=airreport")
+ //feedback_add_details("admin_verb","SAR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
air_status(turf/target as turf)
set category = "Debug"
@@ -80,6 +82,7 @@
usr << "\blue @[target.x],[target.y] ([GM.group_multiplier]): O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("\red BURNING"):(null)]"
for(var/datum/gas/trace_gas in GM.trace_gases)
usr << "[trace_gas.type]: [trace_gas.moles]"
+ //feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
fix_next_move()
set category = "Debug"
@@ -109,6 +112,7 @@
message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [largest_move_time/10] seconds!", 1)
message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!", 1)
message_admins("world.time = [world.time]", 1)
+ //feedback_add_details("admin_verb","UFE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
radio_report()
@@ -146,6 +150,7 @@
output += " [device] "
usr << browse(output,"window=radioreport")
+ //feedback_add_details("admin_verb","RR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
reload_admins()
set name = "Reload Admins"
@@ -175,6 +180,7 @@
var/a_lev = copytext(line, pos + 3, length(line) + 1)
admins[m_key] = a_lev
diary << ("ADMIN: [m_key] = [a_lev]")
+ //feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
jump_to_dead_group()
@@ -193,8 +199,31 @@
dead_groups += group
var/datum/air_group/dest_group = pick(dead_groups)
usr.loc = pick(dest_group.members)
+ //feedback_add_details("admin_verb","JDAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
+ kill_airgroup()
+ set name = "Kill Local Airgroup"
+ set desc = "Use this to allow manual manipulation of atmospherics."
+ set category = "Debug"
+ if(!holder)
+ src << "Only administrators may use this command."
+ return
+
+ if(!air_master)
+ usr << "Cannot find air_system"
+ return
+
+ var/turf/T = get_turf(usr)
+ if(istype(T, /turf/simulated))
+ var/datum/air_group/AG = T:parent
+ AG.next_check = 30
+ AG.group_processing = 0
+ else
+ usr << "Local airgroup is unsimulated!"
+ //feedback_add_details("admin_verb","KLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
tension_report()
set category = "Debug"
set name = "Show Tension Report"
@@ -207,6 +236,12 @@
alert(usr,"No players found. How the fuck are you calling this?","Tension Report")
return 0
+ var/numghosts = 0
+
+ for(var/mob/dead/observer/theghost in world)
+ numghosts ++
+
+
var/output = {"TENSION REPORT
General Statistics
Deaths: [tension_master.deaths]
@@ -214,13 +249,34 @@
Explosions: [tension_master.explosions]
Air alarms: [tension_master.air_alarms]
Adminhelps: [tension_master.adminhelps]
+Ghosts: [numghosts]
Current Status
Tension: [tension_master.score]
+Increase Tension by 50000
Tension per player: [tension_master.score/tension_master.get_num_players()]
-Recommendations: not yet implemented
+Tensioner Debug Data: R1:[tension_master.round1] R2:[tension_master.round2] R3:[tension_master.round3] R4:[tension_master.round4] ES: [tension_master.eversupressed] CD: [tension_master.cooldown]
+Current Tensioner Status: [config.Tensioner_Active]. Toggle?
+Recommendations: All the modes. All of them. Press all of them.
+ Make Tratiors
+ Make Changlings
+ Make Revs
+ Make Wizard (Requires Ghosts)
+ Make Cult
+ Make Nuke Team (Requires Ghosts)
+ Make Malf AI
+ Make Space Ninja (Requires Ghosts)
+ Make Aliens (Requires Ghosts)
+ Make Deathsquad (Syndicate) (Requires Ghosts)
+ Make Deathsquad (Borg) (Requires Ghosts)
+
+
+
"}
- usr << browse(output,"window=tensionreport")
\ No newline at end of file
+ for(var/game in tension_master.antagonistmodes)
+ output += "Points required/Probability for [game]: [tension_master.antagonistmodes[game]] "
+ usr << browse(output,"window=tensionreport;size=480x480")
+ feedback_add_details("admin_verb","STR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm
index 69ffc12b83..47e6131387 100644
--- a/code/modules/admin/verbs/pray.dm
+++ b/code/modules/admin/verbs/pray.dm
@@ -17,6 +17,7 @@
M << "\blue \icon[cross] PRAY: [key_name(src, M)] (PP ) (VV ) (SM ) (JMP ) (CA ): [msg]"
usr << "Your prayers have been received by the gods."
+ //feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//log_admin("HELP: [key_name(src)]: [msg]")
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 501a211db1..93914d171d 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -9,6 +9,7 @@
log_admin("[key_name(usr)] made [key_name(M)] drop everything!")
message_admins("[key_name_admin(usr)] made [key_name_admin(M)] drop everything!", 1)
+ //feedback_add_details("admin_verb","DEVR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_prison(mob/M as mob in world)
set category = "Admin"
@@ -35,6 +36,7 @@
M << "\red You have been sent to the prison station!"
log_admin("[key_name(usr)] sent [key_name(M)] to the prison station.")
message_admins("\blue [key_name_admin(usr)] sent [key_name_admin(M)] to the prison station.", 1)
+ //feedback_add_details("admin_verb","PRISON") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_subtle_message(mob/M as mob in world)
set category = "Special Verbs"
@@ -52,10 +54,11 @@
if(usr)
if (usr.client)
if(usr.client.holder)
- M << "\bold You hear a voice in your head... \italic [msg]"
+ M << "\bold You think... \italic [msg]"
log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]")
message_admins("\blue \bold SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]", 1)
+ //feedback_add_details("admin_verb","SMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_world_narrate() // Allows administrators to fluff events a little easier -- TLE
set category = "Special Verbs"
@@ -72,6 +75,7 @@
world << "[msg]"
log_admin("GlobalNarrate: [key_name(usr)] : [msg]")
message_admins("\blue \bold GlobalNarrate: [key_name_admin(usr)] : [msg] ", 1)
+ //feedback_add_details("admin_verb","GLN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_direct_narrate(mob/M as mob in world) // Targetted narrate -- TLE
set category = "Special Verbs"
@@ -84,6 +88,7 @@
M << msg
log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]")
message_admins("\blue \bold DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg] ", 1)
+ //feedback_add_details("admin_verb","DIRN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_mute(mob/M as mob in world)
set category = "Special Verbs"
@@ -103,6 +108,7 @@
message_admins("[key_name_admin(src)] has [(M.client.muted ? "muted" : "voiced")] [key_name_admin(M)].", 1)
M << "You have been [(M.client.muted ? "muted" : "voiced")]."
+ //feedback_add_details("admin_verb","MUTE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_add_random_ai_law()
@@ -120,6 +126,7 @@
world << sound('ionstorm.ogg')
//IonStorm(0)
+ //feedback_add_details("admin_verb","ION") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/*
Stealth spawns xenos
@@ -136,6 +143,7 @@
return
create_xeno()
+ //feedback_add_details("admin_verb","X") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
//I use this proc for respawn character too. /N
@@ -406,6 +414,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
new_character << "You have been fully respawned. Enjoy the game."
del(G_found)//Don't want to leave ghosts around.
+ //feedback_add_details("admin_verb","RSPCH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return new_character
/client/proc/cmd_admin_add_freeform_ai_law()
@@ -434,11 +443,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(show_log == "Yes")
command_alert("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert")
world << sound('ionstorm.ogg')
+ //feedback_add_details("admin_verb","IONC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_rejuvenate(mob/living/M as mob in world)
set category = "Special Verbs"
set name = "Rejuvenate"
- // All admins should be authenticated, but... what if?
if(!holder)
src << "Only administrators may use this command."
return
@@ -498,6 +507,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("\red Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!", 1)
else
alert("Admin revive disabled")
+ //feedback_add_details("admin_verb","REJU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_create_centcom_report()
set category = "Special Verbs"
@@ -529,6 +539,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
world << sound('commandreport.ogg')
log_admin("[key_name(src)] has created a command report: [input]")
message_admins("[key_name_admin(src)] has created a command report", 1)
+ //feedback_add_details("admin_verb","CCR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in world)
set category = "Admin"
@@ -541,6 +552,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if (alert(src, "Are you sure you want to delete:\n[O]\nat ([O.x], [O.y], [O.z])?", "Confirmation", "Yes", "No") == "Yes")
log_admin("[key_name(usr)] deleted [O] at ([O.x],[O.y],[O.z])")
message_admins("[key_name_admin(usr)] deleted [O] at ([O.x],[O.y],[O.z])", 1)
+ //feedback_add_details("admin_verb","DEL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
del(O)
/client/proc/cmd_admin_list_open_jobs()
@@ -553,6 +565,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(job_master)
for(var/datum/job/job in job_master.occupations)
src << "[job.title]: [job.total_positions]"
+ //feedback_add_details("admin_verb","LFS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
set category = "Special Verbs"
@@ -579,7 +592,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
explosion (O, devastation, heavy, light, flash)
log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flash]) at ([O.x],[O.y],[O.z])")
message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flash]) at ([O.x],[O.y],[O.z])", 1)
-
+ //feedback_add_details("admin_verb","EXPL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
else
return
@@ -602,6 +615,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
empulse(O, heavy, light)
log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])")
message_admins("[key_name_admin(usr)] created an EM PUlse ([heavy],[light]) at ([O.x],[O.y],[O.z])", 1)
+ //feedback_add_details("admin_verb","EMP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
else
@@ -629,6 +643,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
return
M.gib()
+ //feedback_add_details("admin_verb","GIB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_gib_self()
set name = "Gibself"
@@ -637,6 +652,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
return
else
mob.gib()
+ //feedback_add_details("admin_verb","GIBS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/*
/client/proc/cmd_manual_ban()
set name = "Manual Ban"
@@ -708,6 +724,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/list/L = M.get_contents()
for(var/t in L)
usr << "[t]"
+ //feedback_add_details("admin_verb","CC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_remove_plasma(area/A as area)
set category = "Debug"
@@ -716,7 +733,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!holder)
src << "Only administrators may use this command."
return
-
+ //feedback_add_details("admin_verb","STATM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
spawn(1)
for(var/turf/simulated/T in A)
if(T.air)
@@ -738,6 +755,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
view = input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128)
else
view = world.view
+ //feedback_add_details("admin_verb","CVRA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/admin_call_shuttle()
@@ -762,8 +780,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
return
emergency_shuttle.incall()
- world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes. "
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
world << sound('shuttlecalled.ogg')
+ //feedback_add_details("admin_verb","CSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/client/proc/admin_cancel_shuttle()
@@ -782,6 +801,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(confirm != "Yes") return
emergency_shuttle.recall()
+ //feedback_add_details("admin_verb","CCSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
@@ -808,6 +828,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
usr << text("\red Attack Log for [] ", mob)
for(var/t in M.attack_log)
usr << t
+ //feedback_add_details("admin_verb","ATTL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/everyone_random()
@@ -839,6 +860,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
usr << "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet ."
ticker.random_players = 1
+ //feedback_add_details("admin_verb","MER") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/toggle_gravity_on()
set category = "Debug"
@@ -854,6 +876,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
A.gravitychange(1,A)
command_alert("CentComm is now beaming gravitons to your station. We appoligize for any inconvience.")
+ //feedback_add_details("admin_verb","TSGON") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/toggle_gravity_off()
set category = "Debug"
@@ -869,7 +892,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
A.gravitychange(0,A)
command_alert("For budget reasons, Centcomm is no longer beaming gravitons to your station. We appoligize for any inconvience.")
-//CARN
+ //feedback_add_details("admin_verb","TSGOFF") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
/client/proc/toggle_random_events()
set category = "Server"
set name = "Toggle random events on/off"
diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm
index d55c862962..2b6d2adcbe 100644
--- a/code/modules/admin/verbs/striketeam.dm
+++ b/code/modules/admin/verbs/striketeam.dm
@@ -37,7 +37,6 @@ var/global/sent_strike_team = 0
if (emergency_shuttle.direction == 1 && emergency_shuttle.online == 1)
emergency_shuttle.recall()
- world << "\blue Alert: The shuttle is going back! "
var/commando_number = commandos_possible //for selecting a leader
var/leader_selected = 0 //when the leader is chosen. The last person spawned.
@@ -186,6 +185,7 @@ var/global/sent_strike_team = 0
L.implanted = 1
+
var/obj/item/weapon/card/id/W = new(src)
W.name = "[real_name]'s ID Card"
W.icon_state = "centcom"
diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm
index eccd7ea42a..a07c386093 100644
--- a/code/modules/admin/verbs/striketeam_syndicate.dm
+++ b/code/modules/admin/verbs/striketeam_syndicate.dm
@@ -107,6 +107,7 @@ var/global/sent_syndicate_strike_team = 0
message_admins("\blue [key_name_admin(usr)] has spawned a Syndicate strike squad.", 1)
log_admin("[key_name(usr)] used Spawn Syndicate Squad.")
+ //feedback_add_details("admin_verb","SDTHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0)
var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc)
@@ -144,7 +145,7 @@ var/global/sent_syndicate_strike_team = 0
camera.c_tag = real_name
var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src)
- R.set_frequency(1337) //Same frequency as the syndicate team in Nuke mode.
+ R.set_frequency(NUKE_FREQ) //Same frequency as the syndicate team in Nuke mode.
equip_if_possible(R, slot_ears)
equip_if_possible(new /obj/item/clothing/under/syndicate(src), slot_w_uniform)
equip_if_possible(new /obj/item/clothing/shoes/swat(src), slot_shoes)
diff --git a/code/modules/admin/verbs/ticklag.dm b/code/modules/admin/verbs/ticklag.dm
index 59c59ba4b5..9f6fddd832 100644
--- a/code/modules/admin/verbs/ticklag.dm
+++ b/code/modules/admin/verbs/ticklag.dm
@@ -1,20 +1,27 @@
-/client/proc/ticklag(number as num)
+//Merged Doohl's and the existing ticklag as they both had good elements about them ~Carn
+
+/client/proc/ticklag()
set category = "Debug"
- set name = "Ticklag"
- set desc = "Ticklag"
- set hidden = 1
+ set name = "Set Ticklag"
+ set desc = "Sets a new tick lag. Recommend you don't mess with this too much! Stable, time-tested ticklag value is 0.9"
if(Debug2)
if(src.holder)
- if(!src.mob)
- return
- if(src.holder.rank in list("Game Admin", "Game Master"))
- world.tick_lag = number
- log_admin("[key_name(src.mob)] set tick_lag to [number]")
- message_admins("[key_name_admin(usr)] modified world's tick_lag to [number]")
- else
- alert("Fuck off, no crashing dis server")
- return
- else
- alert("Debugging is disabled")
- return
+ if(!src.mob) return
+ if(src.holder.rank in list("Game Admin", "Game Master"))
+ var/newtick = input("Sets a new tick lag. Please don't mess with this too much! The stable, time-tested ticklag value is 0.9","Lag of Tick", world.tick_lag) as num|null
+ //I've used ticks of 2 before to help with serious singulo lags
+ if(newtick && newtick <= 2 && newtick > 0)
+ log_admin("[key_name(src)] has modified world.tick_lag to [newtick]", 0)
+ message_admins("[key_name(src)] has modified world.tick_lag to [newtick]", 0)
+ world.tick_lag = newtick
+ //feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return
+ src << "\red Error: ticklag(): Invalid world.ticklag value. No changes made."
+ return
+
+ src << "\red Error: ticklag(): You are not authorised to use this. Game Admins and higher only."
+ return
+ else
+ src << "\red Error: ticklag(): You must first enable Debugging mode."
+ return
\ No newline at end of file
diff --git a/code/modules/chemical/Chemistry-Machinery.dm b/code/modules/chemical/Chemistry-Machinery.dm
index 57eb90fbea..2e31bce08f 100644
--- a/code/modules/chemical/Chemistry-Machinery.dm
+++ b/code/modules/chemical/Chemistry-Machinery.dm
@@ -462,23 +462,23 @@
if (href_list["create_vaccine"])
if(!src.wait)
var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc)
- var/vaccine_type = text2path(href_list["create_vaccine"])//the path is received as string - converting
- var/datum/disease/D = new vaccine_type
- var/name = input(usr,"Name:","Name the vaccine",D.name)
- if(!name || name == " ") name = D.name
- B.name = "[name] vaccine bottle"
- B.reagents.add_reagent("vaccine",15,vaccine_type)
- del(D)
- wait = 1
- var/datum/reagents/R = beaker.reagents
- var/datum/reagent/blood/Blood = null
- for(var/datum/reagent/blood/L in R.reagent_list)
- if(L)
- Blood = L
- break
- var/list/res = Blood.data["resistances"]
- spawn(res.len*500)
- src.wait = null
+ if(B)
+ var/vaccine_type = text2path(href_list["create_vaccine"])//the path is received as string - converting
+ var/datum/disease/D = new vaccine_type
+ if(D)
+ B.name = "[D.name] vaccine bottle"
+ B.reagents.add_reagent("vaccine",15,vaccine_type)
+ del(D)
+ wait = 1
+ var/datum/reagents/R = beaker.reagents
+ var/datum/reagent/blood/Blood = null
+ for(var/datum/reagent/blood/L in R.reagent_list)
+ if(L)
+ Blood = L
+ break
+ var/list/res = Blood.data["resistances"]
+ spawn(res.len*500)
+ src.wait = null
else
src.temphtml = "The replicator is not ready yet."
src.updateUsrDialog()
diff --git a/code/modules/chemical/Chemistry-Recipes.dm b/code/modules/chemical/Chemistry-Recipes.dm
index b78486260f..0ecef3b724 100644
--- a/code/modules/chemical/Chemistry-Recipes.dm
+++ b/code/modules/chemical/Chemistry-Recipes.dm
@@ -759,13 +759,14 @@ datum
if(M:eyecheck() <= 0)
flick("e_flash", M.flash)
- for(var/i = 1, i <= created_volume, i++)
+ for(var/i = 1, i <= created_volume + rand(1,2), i++)
var/chosen = pick(borks)
var/obj/B = new chosen
- B.loc = get_turf_loc(holder.my_atom)
- if(prob(50))
- for(var/j = 1, j <= rand(1, 3), j++)
- step(B, pick(NORTH,SOUTH,EAST,WEST))
+ if(B)
+ B.loc = get_turf_loc(holder.my_atom)
+ if(prob(50))
+ for(var/j = 1, j <= rand(1, 3), j++)
+ step(B, pick(NORTH,SOUTH,EAST,WEST))
diff --git a/code/modules/chemical/Chemistry-Tools.dm b/code/modules/chemical/Chemistry-Tools.dm
index caff32179b..c19380ddd5 100644
--- a/code/modules/chemical/Chemistry-Tools.dm
+++ b/code/modules/chemical/Chemistry-Tools.dm
@@ -1768,7 +1768,23 @@
icon_state = "pill[rand(1,20)]"
attackby(obj/item/weapon/W as obj, mob/user as mob)
-
+ if (istype(W, /obj/item/weapon/storage/pill_bottle))
+ var/obj/item/weapon/storage/pill_bottle/P = W
+ if (P.mode == 1)
+ for (var/obj/item/weapon/reagent_containers/pill/O in locate(src.x,src.y,src.z))
+ if(P.contents.len < P.storage_slots)
+ O.loc = P
+ P.orient2hud(user)
+ else
+ user << "\blue The pill bottle is full."
+ return
+ user << "\blue You pick up all the pills."
+ else
+ if (P.contents.len < P.storage_slots)
+ loc = P
+ P.orient2hud(user)
+ else
+ user << "\blue The pill bottle is full."
return
attack_self(mob/user as mob)
return
@@ -1871,6 +1887,20 @@
del(D)
del(src)
+/obj/item/weapon/reagent_containers/glass/watercan
+ name = "watering can"
+ desc = "A watering can, for all your watering needs."
+ icon = 'hydroponics.dmi'
+ icon_state = "watercan"
+ item_state = "bucket"
+ m_amt = 200
+ g_amt = 0
+ w_class = 3.0
+ amount_per_transfer_from_this = 20
+ possible_transfer_amounts = list(10,20,30,50,70)
+ volume = 70
+ flags = FPRINT | OPENCONTAINER
+
/obj/item/weapon/reagent_containers/glass/cantister
desc = "It's a canister. Mainly used for transporting fuel."
name = "canister"
@@ -2053,7 +2083,7 @@
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,25,30)
flags = FPRINT | TABLEPASS | OPENCONTAINER
- volume = 30
+ volume = 50
New()
..()
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index 0899491ab8..02043fd7de 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -5,6 +5,7 @@
origin_tech = "magnets=3;biotech=2"
var
list/icon/current = list() //the current hud icons
+
proc
process_hud(var/mob/M) return
@@ -88,25 +89,28 @@
var/client/C = M.client
var/icon/tempHud = 'hud.dmi'
for(var/mob/living/carbon/human/perp in view(M))
+ if(!C) continue
+ var/perpname = "wot"
if(perp.wear_id)
C.images += image(tempHud,perp,"hud[ckey(perp:wear_id:GetJobName())]")
- var/perpname = "wot"
if(istype(perp.wear_id,/obj/item/weapon/card/id))
perpname = perp.wear_id:registered_name
else if(istype(perp.wear_id,/obj/item/device/pda))
var/obj/item/device/pda/tempPda = perp.wear_id
perpname = tempPda.owner
- for (var/datum/data/record/E in data_core.general)
- if (E.fields["name"] == perpname)
- for (var/datum/data/record/R in data_core.security)
- if ((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "*Arrest*"))
- C.images += image(tempHud,perp,"hudwanted")
- break
- else if((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "Incarcerated"))
- C.images += image(tempHud,perp,"hudprisoner")
- break
else
+ perpname = perp.name
C.images += image(tempHud,perp,"hudunknown")
+
+ for (var/datum/data/record/E in data_core.general)
+ if (E.fields["name"] == perpname)
+ for (var/datum/data/record/R in data_core.security)
+ if ((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "*Arrest*"))
+ C.images += image(tempHud,perp,"hudwanted")
+ break
+ else if((R.fields["id"] == E.fields["id"]) && (R.fields["criminal"] == "Incarcerated"))
+ C.images += image(tempHud,perp,"hudprisoner")
+ break
for(var/named in perp.organs)
var/datum/organ/external/E = perp.organs[named]
for(var/obj/item/weapon/implant/I in E.implant)
@@ -116,3 +120,4 @@
if(istype(I,/obj/item/weapon/implant/loyalty))
C.images += image(tempHud,perp,"hud_imp_loyal")
+
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index c0f955315f..374d4dded7 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -28,4 +28,16 @@
/obj/item/clothing/head/helmet/hardhat/dblue
icon_state = "hardhat0_dblue"
item_state = "hardhat0_dblue"
- color = "dblue"
\ No newline at end of file
+ color = "dblue"
+
+/obj/item/clothing/head/helmet/hardhat/pumpkinhead
+ name = "carved pumpkin"
+ desc = "A jack o' lantern! Believed to ward off evil spirits."
+ icon_state = "hardhat0_pumpkin"
+ item_state = "hardhat0_pumpkin"
+ flags = FPRINT | TABLEPASS | HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR
+ brightness_on = 3
+ see_face = 0.0
+ color = "pumpkin"
+ armor = list(melee = 5, bullet = 0, laser = 5,energy = 5, bomb = 5, bio = 0, rad = 0)
+ flags_inv = HIDEMASK|HIDEEARS|HIDEEYES
\ No newline at end of file
diff --git a/code/modules/clothing/jumpsuit.dm b/code/modules/clothing/jumpsuit.dm
index 8ce85fca2f..67e8cd57b5 100644
--- a/code/modules/clothing/jumpsuit.dm
+++ b/code/modules/clothing/jumpsuit.dm
@@ -531,22 +531,6 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
armor = list(melee = 100, bullet = 100, laser = 100,energy = 100, bomb = 100, bio = 100, rad = 100)
-/obj/item/clothing/under/rank/medical_sleeve
- desc = "Made of a special fiber that gives special protection against biohazards. Has a cross on the chest denoting that the wearer is trained medical personnel."
- name = "short sleeve medical jumpsuit"
- icon_state = "medical_sleeve"
- item_state = "w_suit"
- color = "medical_sleeve"
- permeability_coefficient = 0.50
- armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
-
-/obj/item/clothing/under/jumpsuitdown
- desc = "A rolled down jumpsuit. Great for mechanics."
- name = "rolled down jumpsuit"
- icon_state = "jumpsuitdown"
- item_state = "jumpsuitdown"
- color = "jumpsuitdown"
-
// Cheerleader outfits or something
/obj/item/clothing/under/cheerleader
name = "cheerleader uniform"
diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm
index 392c344cff..5166f2707e 100644
--- a/code/modules/clothing/suits/labcoat.dm
+++ b/code/modules/clothing/suits/labcoat.dm
@@ -45,13 +45,3 @@
name = "Scientist Labcoat"
desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder."
icon_state = "labcoat_tox_open"
-
-/obj/item/clothing/suit/storage/labcoat/pink
- name = "Pink Labcoat"
- desc = "A suit that protects against minor chemical spills. Has a pink stripe down from the shoulders."
- icon_state = "labcoat_pink_open"
-
-/obj/item/clothing/suit/storage/labcoat/red
- name = "Red Labcoat"
- desc = "A suit that protects against minor chemical spills. Has a red stripe on the shoulders and rolled up sleeves."
- icon_state = "labcoat_sleeve_open"
\ No newline at end of file
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 9fac994c5f..a2f976ea90 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -6,6 +6,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
+
/obj/item/clothing/suit/storage/wcoat
name = "waistcoat"
desc = "The height of class."
@@ -13,6 +14,24 @@
item_state = "wcoat"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+
+
+
+/obj/item/clothing/suit/bluetag
+ name = "blue laser tag armour"
+ desc = "Blue Pride, Station Wide"
+ icon_state = "bluetag"
+ item_state = "bluetag"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+
+/obj/item/clothing/suit/redtag
+ name = "red laser tag armour"
+ desc = "Pew pew pew"
+ icon_state = "redtag"
+ item_state = "redtag"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+
+
/obj/item/clothing/suit/storage/apron
name = "apron"
desc = "A basic blue apron. It has a large pocket you can store things in."
@@ -21,6 +40,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
allowed = list (/obj/item/weapon/plantbgone,/obj/item/device/analyzer/plant_analyzer,/obj/item/seeds,/obj/item/nutrient,/obj/item/weapon/minihoe)
+
/obj/item/clothing/suit/storage/chef
name = "chef's apron"
desc = "An apron used by a high class chef. Has a few pockets for nic-naks."
@@ -33,6 +53,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
allowed = list (/obj/item/weapon/kitchenknife,/obj/item/weapon/butch)
+
/obj/item/clothing/suit/storage/chef/classic
name = "classic chef's apron"
desc = "A basic, dull, white chef's apron."
@@ -40,18 +61,21 @@
item_state = "apronchef"
body_parts_covered = UPPER_TORSO|LOWER_TORSO
+
/obj/item/clothing/suit/hazardvest
name = "hazard vest"
desc = "A high-visibility vest used in work zones."
icon_state = "hazard"
item_state = "hazard"
+
/obj/item/clothing/suit/suspenders
name = "suspenders"
desc = "They suspend the illusion of the mime's play."
icon = 'belts.dmi'
icon_state = "suspenders"
+
/obj/item/clothing/suit/syndicatefake
name = "red space suit replica"
icon_state = "syndicate"
@@ -62,6 +86,7 @@
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/toy)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
+
/obj/item/clothing/suit/storage/captunic
name = "captain's parade tunic"
desc = "Worn by a Captain to show their class."
@@ -70,6 +95,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT
+
/obj/item/clothing/suit/nun
name = "nun robe"
desc = "Maximum piety in this star system."
@@ -92,14 +118,16 @@
item_state = "chaplain_hoodie"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
+
/obj/item/clothing/suit/hastur
- name = "Hastur's robes"
+ name = "\improper Hastur's robes"
desc = "Robes not meant to be worn by man"
icon_state = "hastur"
item_state = "hastur"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
+
/obj/item/clothing/suit/imperium_monk
name = "imperium monk robes"
desc = "A set of strange robes."
@@ -108,6 +136,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDESHOES|HIDEJUMPSUIT
+
/obj/item/clothing/suit/chickensuit
name = "chicken suit"
desc = "Bwak!"
@@ -116,6 +145,7 @@
body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET|HEAD
flags_inv = HIDESHOES|HIDEJUMPSUIT
+
/obj/item/clothing/suit/monkeysuit
name = "monkey suit"
desc = "A suit that looks like a primate"
@@ -124,6 +154,7 @@
body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS|FEET|HANDS
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
+
/obj/item/clothing/suit/holidaypriest
name = "holiday priest"
desc = "This is a nice holiday my son."
@@ -131,6 +162,8 @@
item_state = "holidaypriest"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
+
+
// BubbleWrap - Nothing to see here
/obj/item/clothing/suit/cardborg
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 880935c27b..67b1fcde75 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -1,15 +1,94 @@
-//add custom items you give to people here, and put their icons in custom_items.dmi
+// Add custom items you give to people here, and put their icons in custom_items.dmi
+// Remember to change 'icon = 'custom_items.dmi'' for items not using /obj/item/fluff as a base
+// Clothing item_state doesn't use custom_items.dmi. Just add them to the normal clothing files.
+
/obj/item/fluff // so that they don't spam up the object tree
icon = 'custom_items.dmi'
w_class = 1.0
-/obj/item/fluff/wes_solari_1
- name = "Family Photograph"
- desc = "A family photograph of a couple and a young child, Written on the back it says \"See you soon Dad -Roy\"."
- icon_state = "wes_solari_1"
+//////////// Clothing
+
+/obj/item/clothing/glasses/meson/fluff/book_berner_1
+ name = "bespectacled mesonic surveyors"
+ desc = "One of the older meson scanner models retrofitted to perform like its modern counterparts."
+ icon = 'custom_items.dmi'
+ icon_state = "book_berner_1"
+
+/obj/item/clothing/glasses/fluff/serithi_artalis_1
+ name = "extranet HUD"
+ desc = "A heads-up display with limited connectivity to the NanoTrasen Extranet, capable of displaying information from official NanoTrasen records."
+ icon = 'custom_items.dmi'
+ icon_state = "serithi_artalis_1"
+
+/obj/item/clothing/head/helmet/hardhat/fluff/greg_anderson_1
+ name = "old hard hat"
+ desc = "An old dented hard hat with the nametag \"Anderson\". It seems to be backwards."
+ icon_state = "hardhat0_dblue" //Already an in-game sprite
+ item_state = "hardhat0_dblue"
+ color = "dblue"
+
+/obj/item/clothing/under/rank/virologist/fluff/cdc_jumpsuit
+ name = "\improper CDC jumpsuit"
+ desc = "A modified standard-issue CDC jumpsuit made of a special fiber that gives special protection against biohazards. It has a biohazard symbol sewn into the back."
+ icon = 'custom_items.dmi'
+ icon_state = "cdc_jumpsuit"
+ color = "cdc_jumpsuit"
+
+/obj/item/clothing/suit/storage/labcoat/fluff/cdc_labcoat
+ name = "\improper CDC labcoat"
+ desc = "A standard-issue CDC labcoat that protects against minor chemical spills. It has the name \"Wiles\" sewn on to the breast pocket."
+ icon = 'custom_items.dmi'
+ icon_state = "labcoat_cdc_open"
+
+/obj/item/clothing/suit/storage/labcoat/fluff/pink
+ name = "pink labcoat"
+ desc = "A suit that protects against minor chemical spills. Has a pink stripe down from the shoulders."
+ icon = 'custom_items.dmi'
+ icon_state = "labcoat_pink_open"
+
+/obj/item/clothing/suit/storage/labcoat/fluff/red
+ name = "red labcoat"
+ desc = "A suit that protects against minor chemical spills. Has a red stripe on the shoulders and rolled up sleeves."
+ icon = 'custom_items.dmi'
+ icon_state = "labcoat_red_open"
+
+/obj/item/clothing/under/rank/medical/fluff/short
+ name = "short sleeve medical jumpsuit"
+ desc = "Made of a special fiber that gives special protection against biohazards. Has a cross on the chest denoting that the wearer is trained medical personnel and short sleeves."
+ icon = 'custom_items.dmi'
+ icon_state = "medical_short"
+ color = "medical_short"
+
+/obj/item/clothing/under/fluff/jumpsuitdown
+ name = "rolled down jumpsuit"
+ desc = "A rolled down jumpsuit. Great for mechanics."
+ icon = 'custom_items.dmi'
+ icon_state = "jumpsuitdown"
+ item_state = "jumpsuitdown"
+ color = "jumpsuitdown"
+
+/obj/item/clothing/under/fluff/olddressuniform
+ name = "retired dress uniform"
+ desc = "A retired Station Head of Staff uniform, phased out twenty years ago for the newer jumpsuit design, but still acceptable dress. Lovingly maintained."
+ icon = 'custom_items.dmi'
+ icon_state = "olddressuniform"
+ item_state = "olddressuniform"
+ color = "olddressuniform"
+
+//////////// Useable Items
+
+/obj/item/weapon/pen/fluff/multi
+ name = "multicolor pen"
+ desc = "It's a cool looking pen. Lots of colors!"
+
+/obj/item/weapon/pen/fluff/fancypen
+ name = "fancy pen"
+ desc = "A fancy metal pen. It uses blue ink. An inscription on one side reads,\"L.L. - L.R.\""
+ icon = 'custom_items.dmi'
+ icon_state = "fancypen"
/obj/item/fluff/victor_kaminsky_1
- name = "\improper Golden Detective's Badge"
+ name = "golden detective's badge"
desc = "NanoTrasen Security Department detective's badge, made from gold. Badge number is 564."
icon_state = "victor_kaminsky_1"
@@ -18,45 +97,48 @@
O.show_message(text("[] shows you: \icon[] [].", user, src, src.name), 1)
src.add_fingerprint(user)
+/obj/item/weapon/clipboard/fluff/smallnote
+ name = "small notebook"
+ desc = "A generic small spiral notebook that flips upwards."
+ icon = 'custom_items.dmi'
+ icon_state = "smallnotetext"
+
+/obj/item/weapon/storage/fluff/maye_daye_1
+ name = "pristine lunchbox"
+ desc = "A pristine stainless steel lunch box. The initials M.D. are engraved on the inside of the lid."
+ icon = 'custom_items.dmi'
+ icon_state = "maye_daye_1"
+
+/obj/item/weapon/reagent_containers/food/drinks/flask/fluff/johann_erzatz_1
+ name = "vintage thermos"
+ desc = "An older thermos with a faint shine."
+ icon = 'custom_items.dmi'
+ icon_state = "johann_erzatz_1"
+ volume = 50
+
+//////////// Misc Items
+
+/obj/item/fluff/wes_solari_1
+ name = "family photograph"
+ desc = "A family photograph of a couple and a young child, Written on the back it says \"See you soon Dad -Roy\"."
+ icon_state = "wes_solari_1"
+
/obj/item/fluff/sarah_calvera_1
- name = "Old Photo"
+ name = "old photo"
desc = "Looks like it was made on a really old, cheap camera. Low quality. The camera shows a young hispanic looking girl with red hair wearing a white dress is standing in front of an old looking wall. On the back there is a note in black marker that reads \"Sara, Siempre pensé que eras tan linda con ese vestido. Tu hermano, Carlos.\""
icon_state = "sarah_calvera_1"
/obj/item/fluff/angelo_wilkerson_1
- name = "Fancy Watch"
+ name = "fancy watch"
desc = "An old and expensive pocket watch. Engraved on the bottom is \"Odium est Source De Dolor\". On the back, there is an engraving that does not match the bottom and looks more recent. \"Angelo, If you find this, you shall never see me again. Please, for your sake, go anywhere and do anything but stay. I'm proud of you and I will always love you. Your father, Jacob Wilkerson.\" Jacob Wilkerson... Wasn't he that serial killer?"
icon_state = "angelo_wilkerson_1"
-/obj/item/clothing/glasses/meson/fluff/book_berner_1
- name = "Bespectacled Mesonic Surveyors"
- desc = "One of the older meson scanner models retrofitted to perform like its modern counterparts."
- icon = 'custom_items.dmi'
- icon_state = "book_berner_1"
-
/obj/item/fluff/sarah_carbrokes_1
- name = "Locket"
+ name = "locket"
desc = "A grey locket with a picture of a black haired man in it. The text above it reads: \"Edwin Carbrokes\"."
icon_state = "sarah_carbrokes_1"
-/obj/item/clothing/glasses/fluff/serithi_artalis_1
- name = "Extranet HUD"
- desc = "A heads-up display with limited connectivity to the NanoTrasen Extranet, capable of displaying information from official NanoTrasen records."
- icon_state = "serithi_artalis_1"
-
-/obj/item/clothing/head/fluff/greg_anderson_1
- name = "old hard hat"
- desc = "An old dented hard hat with the nametag \"Anderson\". It seems to be backwards."
- icon_state = "hardhat0_red"
- flags = FPRINT | TABLEPASS | SUITSPACE
- item_state = "hardhat0_red"
- color = "red"
- armor = list(melee = 30, bullet = 5, laser = 20,energy = 10, bomb = 20, bio = 10, rad = 20)
- flags_inv = 0
-
/obj/item/fluff/ethan_way_1
- name = "Old ID"
+ name = "old ID"
desc = "A scratched and worn identification card; it appears too damaged to inferface with any technology. You can almost make out \"Tom Cabinet\" in the smeared ink."
- icon = 'custom_items.dmi'
icon_state = "ethan_way_1"
- flags = FPRINT | TABLEPASS
\ No newline at end of file
diff --git a/code/modules/food/food.dm b/code/modules/food/food.dm
index f8df8a8c63..33322a3121 100644
--- a/code/modules/food/food.dm
+++ b/code/modules/food/food.dm
@@ -840,12 +840,13 @@
if(!reagents.total_volume)
var/mob/M = usr
var/obj/item/weapon/paper/paper = locate() in src
- M.visible_message( \
- "\blue [M] takes a piece of paper from the cookie!", \
- "\blue You take a piece of paper from the cookie! Read it!" \
- )
- M.put_in_hand(paper)
- paper.add_fingerprint(M)
+ if(paper)
+ M.visible_message( \
+ "\blue [M] takes a piece of paper from the cookie!", \
+ "\blue You take a piece of paper from the cookie! Read it!" \
+ )
+ M.put_in_hand(paper)
+ paper.add_fingerprint(M)
/obj/item/weapon/reagent_containers/food/snacks/badrecipe
name = "Burned mess"
@@ -1719,6 +1720,21 @@
icon_state = "applecakeslice"
bitesize = 2
+/obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie
+ name = "Pumpkin Pie"
+ desc = "A delicious treat for the autumn months."
+ icon_state = "pumpkinpie"
+ slice_path = /obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice
+ slices_num = 5
+ New()
+ ..()
+ reagents.add_reagent("nutriment", 29)
+
+/obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice
+ name = "Pumpkin Pie slice"
+ desc = "A slice of pumpkin pie, with whipped cream on top. Perfection."
+ icon_state = "pumpkinpieslice"
+ bitesize = 2
@@ -2000,6 +2016,8 @@
new /obj/item/weapon/reagent_containers/food/snacks/rawsticks(spawnloc)
user << "You cut the potato."
del(src)
+ else
+ ..()
/obj/item/weapon/reagent_containers/food/snacks/rawsticks
name = "raw potato sticks"
diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm
index 64f43fa243..b6af2806eb 100644
--- a/code/modules/food/recipes_microwave.dm
+++ b/code/modules/food/recipes_microwave.dm
@@ -996,6 +996,16 @@
)
result = /obj/item/weapon/reagent_containers/food/snacks/mysterysoup
+/datum/recipe/pumpkinpie
+ reagents = list("milk" = 5, "sugar" = 5)
+ items = list(
+ /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin,
+ /obj/item/weapon/reagent_containers/food/snacks/flour,
+ /obj/item/weapon/reagent_containers/food/snacks/egg,
+ )
+ result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie
+
+
//////////////////////////////////////////
// bs12 food port stuff
//////////////////////////////////////////
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index 28cde78ffc..806a37dd8f 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -44,6 +44,36 @@ proc/move_mining_shuttle()
else
fromArea = locate(/area/shuttle/mining/station)
toArea = locate(/area/shuttle/mining/outpost)
+
+
+ var/list/dstturfs = list()
+ var/throwy = world.maxy
+
+ for(var/turf/T in toArea)
+ dstturfs += T
+ if(T.y < throwy)
+ throwy = T.y
+
+ // hey you, get out of the way!
+ for(var/turf/T in dstturfs)
+ // find the turf to move things to
+ var/turf/D = locate(T.x, throwy - 1, 1)
+ //var/turf/E = get_step(D, SOUTH)
+ for(var/atom/movable/AM as mob|obj in T)
+ AM.Move(D)
+ // NOTE: Commenting this out to avoid recreating mass driver glitch
+ /*
+ spawn(0)
+ AM.throw_at(E, 1, 1)
+ return
+ */
+
+ if(istype(T, /turf/simulated))
+ del(T)
+
+ for(var/mob/living/carbon/bug in toArea) // If someone somehow is still in the shuttle's docking area...
+ bug.gib()
+
fromArea.move_contents_to(toArea)
if (mining_shuttle_location)
mining_shuttle_location = 0
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 169b75719c..2d65571417 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -84,6 +84,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/Move(NewLoc, direct)
if(NewLoc)
loc = NewLoc
+ for(var/obj/step_trigger/S in NewLoc)
+ S.HasEntered(src)
+
return
loc = get_turf(src) //Get out of closets and such as a ghost
if((direct & NORTH) && y < world.maxy)
@@ -95,6 +98,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if((direct & WEST) && x > 1)
x--
+ for(var/obj/step_trigger/S in locate(x, y, z))
+ S.HasEntered(src)
+
/mob/dead/observer/examine()
if(usr)
usr << desc
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
index a812626b65..446f068632 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
@@ -10,6 +10,7 @@
src.verbs -= /mob/living/carbon/alien/humanoid/verb/ActivateHuggers
src.stand_icon = new /icon('alien.dmi', "aliend_s")
src.lying_icon = new /icon('alien.dmi', "aliend_l")
+ src.resting_icon = new /icon('alien.dmi', "aliend_sleep")
src.icon = src.stand_icon
update_clothing()
src << "\blue Your icons have been generated!"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
index 1f6ae9bead..7c7e5eaedf 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
@@ -9,6 +9,7 @@
src.verbs -= /mob/living/carbon/alien/humanoid/verb/corrode
src.stand_icon = new /icon('alien.dmi', "alienh_s")
src.lying_icon = new /icon('alien.dmi', "alienh_l")
+ src.resting_icon = new /icon('alien.dmi', "alienh_sleep")
src.icon = src.stand_icon
update_clothing()
src << "\blue Your icons have been generated!"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
index 7bd9b41b9b..ecc3b459e6 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
@@ -9,6 +9,7 @@
src.verbs += /mob/living/carbon/alien/humanoid/proc/corrode_target
src.stand_icon = new /icon('alien.dmi', "aliens_s")
src.lying_icon = new /icon('alien.dmi', "aliens_l")
+ src.resting_icon = new /icon('alien.dmi', "aliens_sleep")
src.icon = src.stand_icon
update_clothing()
src << "\blue Your icons have been generated!"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index 8b261940ce..52e422c628 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -10,6 +10,7 @@
if(!istype(src, /mob/living/carbon/alien/humanoid/queen))
stand_icon = new /icon('alien.dmi', "alien_s")
lying_icon = new /icon('alien.dmi', "alien_l")
+ resting_icon = new /icon('alien.dmi', "alienh_sleep")
icon = stand_icon
update_clothing()
src << "\blue Your icons have been generated!"
@@ -330,7 +331,10 @@
if (lying)
if(update_icon)
- icon = lying_icon
+ if(!resting)
+ icon = lying_icon
+ else
+ icon = resting_icon
overlays += body_lying
diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm
index a0ca95b041..1388a1314c 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/life.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm
@@ -14,8 +14,12 @@
if (src.monkeyizing)
return
+ ..()
+
if (src.stat != 2) //still breathing
+
+
//First, resolve location and get a breath
if(air_master.current_cycle%4==2)
diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm
index ae61bbfa03..b975d969cb 100644
--- a/code/modules/mob/living/carbon/alien/larva/life.dm
+++ b/code/modules/mob/living/carbon/alien/larva/life.dm
@@ -14,6 +14,8 @@
if (monkeyizing)
return
+ ..()
+
if (stat != 2) //still breathing
//First, resolve location and get a breath
diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm
index 581179cdd8..4106a1b014 100644
--- a/code/modules/mob/living/carbon/brain/life.dm
+++ b/code/modules/mob/living/carbon/brain/life.dm
@@ -4,6 +4,8 @@
set invisibility = 0
set background = 1
+ ..()
+
var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
if(loc)
environment = loc.return_air()
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index b50b0eb84e..4ca82ab743 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -193,11 +193,13 @@
var/status = ""
var/brutedamage = org.brute_dam
var/burndamage = org.burn_dam
+
if(halloss > 0)
if(prob(30))
brutedamage += halloss
if(prob(30))
burndamage += halloss
+
if(brutedamage > 0)
status = "bruised"
if(brutedamage > 20)
@@ -208,6 +210,7 @@
status += " and "
if(burndamage > 40)
status += "peeling away"
+
else if(burndamage > 10)
status += "blistered"
else if(burndamage > 0)
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 664db918a0..0eae0dd45d 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -509,7 +509,25 @@
else
src << "\blue Unusable emote '[act]'. Say *help for a list."
+
+
+
+
if (message)
+ log_emote("[name]/[key] : [message]")
+
+ //Hearing gasp and such every five seconds is not good emotes were not global for a reason.
+ // Maybe some people are okay with that.
+
+ for(var/mob/M in world)
+ if (!M.client)
+ continue //skip monkeys and leavers
+ if (istype(M, /mob/new_player))
+ continue
+ if(M.stat == 2 && M.client.ghost_sight && !(M in viewers(src,null)))
+ M.show_message(message)
+
+
if (m_type & 1)
for (var/mob/O in viewers(src, null))
O.show_message(message, m_type)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 1b1e2e182b..3da6683204 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -1,5 +1,5 @@
/mob/living/carbon/human/examine()
- set src in oview()
+ set src in view()
if(!usr || !src) return
if(((usr.disabilities & 128) || usr.blinded || usr.stat) && !(istype(usr,/mob/dead/observer/)))
@@ -180,14 +180,14 @@
distance = 1
if (src.stat == 1 || stat == 2)
- msg += "[name] doesn't seem to be responding to anything around [t_him], [t_his] eyes closed as though asleep. \n"
+ msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep. \n"
if((!isbreathing || holdbreath) && distance <= 3)
- msg += "[name] does not appear to be breathing. \n"
+ msg += "[t_He] does not appear to be breathing. \n"
if(istype(usr, /mob/living/carbon/human) && usr.stat == 0 && src.stat == 1 && distance <= 1)
for(var/mob/O in viewers(usr.loc, null))
O.show_message("[usr] checks [src]'s pulse.", 1)
spawn(15)
- usr << "\blue [name] has a pulse!"
+ usr << "\blue [t_He] has a pulse!"
if (src.stat == 2 || (changeling && changeling.changeling_fakedeath == 1))
if(distance <= 1)
@@ -195,7 +195,19 @@
for(var/mob/O in viewers(usr.loc, null))
O.show_message("[usr] checks [src]'s pulse.", 1)
spawn(15)
- usr << "\red [name] has no pulse!"
+ if(!src.client)
+ var/foundghost = 0
+ for(var/mob/dead/observer/G in world)
+ if(G.client)
+ if(G.corpse == src)
+ foundghost++
+ break
+ if(!foundghost)
+ usr << "[t_He] has no pulse and [t_his] soul has departed... "
+ else
+ usr << "[t_He] has no pulse... "
+
+ msg += ""
/* if (src.getBruteLoss())
if (src.getBruteLoss() < 30)
@@ -205,9 +217,9 @@
if (src.cloneloss)
if (src.cloneloss < 30)
- msg += "[src.name] looks slightly... unfinished? \n"
+ msg += "[t_He] looks slightly... unfinished?\n"
else
- msg += "[src.name] looks very... unfinished? \n"
+ msg += "[t_He] looks very... unfinished? \n"
/* if (src.getFireLoss())
if (src.getFireLoss() < 30)
@@ -230,7 +242,10 @@
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
if (!src.client && !admin_observing)
- msg += "[t_He] [t_has] a vacant, braindead stare...\n"
+ msg += "[t_He] [t_has] a vacant stare...\n"
+
+ if (src.digitalcamo)
+ msg += "[t_He] [t_is] repulsively uncanny!\n"
var/list/wound_descriptions = list()
var/list/wound_flavor_text = list()
@@ -509,6 +524,31 @@
// usr << "\red [src.name] is bleeding from a [sizetext] on [t_his] [temp.display_name]."
// continue
+ if(istype(usr, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = usr
+ if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
+ var/perpname = "wot"
+ var/criminal = "None"
+
+ if(wear_id)
+ if(istype(wear_id,/obj/item/weapon/card/id))
+ perpname = wear_id:registered_name
+ else if(istype(wear_id,/obj/item/device/pda))
+ var/obj/item/device/pda/tempPda = wear_id
+ perpname = tempPda.owner
+ else
+ perpname = src.name
+
+ for (var/datum/data/record/E in data_core.general)
+ if (E.fields["name"] == perpname)
+ for (var/datum/data/record/R in data_core.security)
+ if (R.fields["id"] == E.fields["id"])
+ criminal = R.fields["criminal"]
+
+
+ msg += "Criminal status: \[[criminal]\] \n"
+ //msg += "\[Set Hostile Identification\]\n"
+
if(print_flavor_text()) msg += "[print_flavor_text()]\n"
msg += "\blue *---------*"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 97e9e7a97b..88191e9402 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1098,8 +1098,7 @@
else
m_select.screen_loc = null
- var/suit_img //A bit of kludge to make belts go under coats, but on other suits
- var/suit_stain
+
if (wear_suit)
/*if (mutations & FAT && !(wear_suit.flags & ONESIZEFITSALL))
src << "\red You burst out of the [wear_suit.name]!"
@@ -1113,7 +1112,7 @@
c:layer = initial(c:layer)*/
if (istype(wear_suit, /obj/item/clothing/suit))
var/t1 = wear_suit.icon_state
- suit_img = image("icon" = 'suit.dmi', "icon_state" = text("[][]", t1, (!( lying ) ? null : "2")), "layer" = MOB_LAYER)
+ overlays += image("icon" = 'suit.dmi', "icon_state" = text("[][]", t1, (!( lying ) ? null : "2")), "layer" = MOB_LAYER)
if (wear_suit)
if (wear_suit.blood_DNA)
var/icon/stain_icon = null
@@ -1123,7 +1122,7 @@
stain_icon = icon('blood.dmi', "coatblood[!lying ? "" : "2"]")
else
stain_icon = icon('blood.dmi', "suitblood[!lying ? "" : "2"]")
- suit_stain = image("icon" = stain_icon, "layer" = MOB_LAYER)
+ overlays += image("icon" = stain_icon, "layer" = MOB_LAYER)
wear_suit.screen_loc = ui_oclothing
if (istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
if (handcuffed)
@@ -1137,24 +1136,6 @@
hand = 0
drop_item()
hand = h
- // Belt
- var/belt_img //A bit of kludge to make belts go under coats, but on other suits
- if (belt)
- var/t1 = belt.item_state
- if (!t1)
- t1 = belt.icon_state
- belt_img = image("icon" = 'belt.dmi', "icon_state" = text("[][]", t1, (!( lying ) ? null : "2")), "layer" = MOB_LAYER)
- belt.screen_loc = ui_belt
-
- //A bit of kludge to make belts go under coats, but on other suits
- if (istype(wear_suit, /obj/item/clothing/suit/storage/det_suit) || istype(wear_suit, /obj/item/clothing/suit/storage/labcoat))
- overlays += belt_img
- overlays += suit_img
- overlays += suit_stain
- else
- overlays += suit_img
- overlays += suit_stain
- overlays += belt_img
if (lying)
@@ -1188,6 +1169,13 @@
overlays += image("icon" = stain_icon, "layer" = MOB_LAYER)
head.screen_loc = ui_head
+ // Belt
+ if (belt)
+ var/t1 = belt.item_state
+ if (!t1)
+ t1 = belt.icon_state
+ overlays += image("icon" = 'belt.dmi', "icon_state" = text("[][]", t1, (!( lying ) ? null : "2")), "layer" = MOB_LAYER)
+ belt.screen_loc = ui_belt
if ((wear_mask && !(wear_mask.see_face)) || (head && !(head.see_face))) // can't see the face
if (wear_id)
@@ -2437,7 +2425,7 @@ It can still be worn/put on as normal.
var/obj/item/device/pda/pda = wear_id
var/obj/item/weapon/card/id/id = wear_id
if (istype(pda))
- if (pda.id)
+ if (pda.id && istype(pda.id, /obj/item/weapon/card/id))
. = pda.id.assignment
else
. = pda.ownjob
@@ -2594,6 +2582,40 @@ It can still be worn/put on as normal.
spawn( 0 )
O.process()
return
+
+ if (href_list["criminal"])
+ if(istype(usr, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = usr
+ if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
+ var/perpname = "wot"
+ var/modified = 0
+
+ if(wear_id)
+ if(istype(wear_id,/obj/item/weapon/card/id))
+ perpname = wear_id:registered_name
+ else if(istype(wear_id,/obj/item/device/pda))
+ var/obj/item/device/pda/tempPda = wear_id
+ perpname = tempPda.owner
+ else
+ perpname = src.name
+
+ for (var/datum/data/record/E in data_core.general)
+ if (E.fields["name"] == perpname)
+ for (var/datum/data/record/R in data_core.security)
+ if (R.fields["id"] == E.fields["id"])
+
+ var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Released", "Cancel")
+
+ if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
+ if(setcriminal != "Cancel")
+ R.fields["criminal"] = setcriminal
+ modified = 1
+
+ spawn()
+ H.handle_regular_hud_updates()
+
+ if(!modified)
+ usr << "\red Unable to locate a data core entry for this person."
..()
return
@@ -2808,16 +2830,21 @@ It can still be worn/put on as normal.
reset_view(0)
remoteobserve = null
src.verbs -= /mob/living/carbon/human/proc/remoteobserve
+ src.tkdisable = 0
return
if(client.eye != client.mob)
reset_view(0)
remoteobserve = null
+ src.tkdisable = 0
return
var/list/mob/creatures = list()
for(var/mob/living/carbon/h in world)
+ var/turf/temp_turf = get_turf(h)
+ if(temp_turf.z != 1 && temp_turf.z != 5) //Not on mining or the station.
+ continue
creatures += h
var/mob/target = input ("Who do you want to project your mind to ?") as mob in creatures
@@ -2825,6 +2852,8 @@ It can still be worn/put on as normal.
if (target)
reset_view(target)
remoteobserve = target
+ src.tkdisable = 1
else
reset_view(0)
remoteobserve = null
+ src.tkdisable = 0
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 7d434f659a..0340f2a925 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -32,6 +32,30 @@
visible_message("\red [src] has been touched with the stun gloves by [M]! ")
return
+ if(istype(M.gloves , /obj/item/clothing/gloves/boxing/hologlove))
+
+ var/damage = rand(0, 9)
+ if(!damage)
+ playsound(loc, 'punchmiss.ogg', 25, 1, -1)
+ visible_message("\red [M] has attempted to punch [src]! ")
+ return 0
+ var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
+ var/armor_block = run_armor_check(affecting, "melee")
+
+ if(M.mutations & HULK) damage += 5
+ playsound(loc, "punch", 25, 1, -1)
+
+ visible_message("\red [M] has punched [src]! ")
+
+ apply_damage(damage, HALLOSS, affecting, armor_block)
+ if(damage >= 9)
+ visible_message("\red [M] has weakened [src]! ")
+ apply_effect(4, WEAKEN, armor_block)
+ UpdateDamageIcon()
+
+ return
+
+
switch(M.a_intent)
if("help")
if(health > 0)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 26b1d58601..4b96f26273 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -9,6 +9,31 @@ emp_act
*/
/mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone)
+
+ if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/armor/laserproof))
+ if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
+ var/reflectchance = 40 - round(P.damage/3)
+ if(!(def_zone in list("chest", "groin")))
+ reflectchance /= 2
+ if(prob(reflectchance))
+ visible_message("\red The [P.name] gets reflected by [src]'s [wear_suit.name]! ")
+
+ // Find a turf near or on the original location to bounce to
+ if(P.starting)
+ var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
+ var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
+ var/turf/curloc = get_turf(src)
+
+ // redirect the projectile
+ P.original = locate(new_x, new_y, P.z)
+ P.starting = curloc
+ P.current = curloc
+ P.firer = src
+ P.yo = new_y - curloc.y
+ P.xo = new_x - curloc.x
+
+ return -1 // complete projectile permutation
+
if(check_shields(P.damage, "the [P.name]"))
P.on_hit(src, 2)
return 2
@@ -96,14 +121,17 @@ emp_act
var/datum/organ/external/affecting = get_organ(ran_zone(user.zone_sel.selecting))
var/hit_area = affecting.display_name
+
+
+ if((user != src) && check_shields(I.force, "the [I.name]"))
+ return 0
+
if(!affecting.destroyed)
visible_message("\red [src] has been attacked in the [hit_area] with [I.name] by [user]! ")
else
user << "What [affecting]?"
return
- if((user != src) && check_shields(I.force, "the [I.name]"))
- return 0
var/armor = run_armor_check(affecting, "melee", "Your armor has protected you from a hit to the [hit_area].", "Your armor has softened hit to your [hit_area].")
if(armor >= 2) return 0
if(!I.force) return 0
@@ -115,8 +143,8 @@ emp_act
apply_damage(power, I.damtype, affecting, armor, is_cut(I), I.name)
var/bloody = 0
- if((I.damtype == BRUTE) && prob(25 + is_sharp(I) * 50 + (I.force * 2)))
- I.add_blood(src)
+ if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + is_sharp(I) * 50 + (I.force * 2)))
+ I.add_blood(src) //Make the weapon bloody, not the person.
bloody = 1
var/turf/location = loc
if(istype(location, /turf/simulated))
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 4279085a46..317e9824c8 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -25,6 +25,8 @@
if(!loc) // Fixing a null error that occurs when the mob isn't found in the world -- TLE
return
+ ..()
+
//Being buckled to a chair or bed
check_if_buckled()
@@ -125,8 +127,6 @@
if(!currentTurf.sd_lumcount)
playsound_local(src,pick(scarySounds),50, 1, -1)
- ..() //for organs
-
src.moved_recently = max(0, moved_recently-1)
/mob/living/carbon/human
@@ -186,15 +186,24 @@
// a.hallucinate(src)
if(!handling_hal && hallucination > 20)
spawn handle_hallucinations() //The not boring kind!
- hallucination = max(hallucination - 2, 0)
+ hallucination = max(hallucination - 2, 0) // A more compact way of doing it. DMTG
//if(health < 0)
// for(var/obj/a in hallucinations)
// del a
else
- halloss = 0
+ //halloss = 0
for(var/atom/a in hallucinations)
del a
+ if(halloss > 100)
+ src << "You're too tired to keep going..."
+ for(var/mob/O in viewers(src, null))
+ if(O == src)
+ continue
+ O.show_message(text("\red [src] slumps to the ground panting, too weak to continue fighting."), 1)
+ Paralyse(15)
+ setHalLoss(99)
+
if(mutations2 & mSmallsize)
if(!(pass_flags & PASSTABLE))
pass_flags |= PASSTABLE
@@ -448,8 +457,10 @@
return null
update_canmove()
- if(paralysis || resting || stunned || weakened || buckled || (changeling && changeling.changeling_fakedeath)) canmove = 0
- else canmove = 1
+ if(paralysis || stunned || weakened || resting || buckled || (changeling && changeling.changeling_fakedeath))
+ canmove = 0
+ else
+ canmove = 1
handle_breath(datum/gas_mixture/breath)
if(nodamage || (mutations & mNobreath))
@@ -927,7 +938,7 @@
if(getOxyLoss() > 50) Paralyse(3)
if(sleeping)
-// adjustHalLoss(-5)
+ adjustHalLoss(-5)
if(paralysis <= 0)
Paralyse(2)
if (prob(10) && health && !hal_crit) spawn(0) emote("snore")
@@ -1483,4 +1494,4 @@ snippets
plcheck = t_plasma
oxcheck = t_oxygen
G.turf_add(T, G.total_moles())
-*/
+*/
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm
index 737872121c..a4b12e934c 100644
--- a/code/modules/mob/living/carbon/metroid/life.dm
+++ b/code/modules/mob/living/carbon/metroid/life.dm
@@ -5,6 +5,7 @@
if (src.monkeyizing)
return
+ ..()
var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
if(src.loc)
diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm
index f5780ed9c8..ab616822ce 100644
--- a/code/modules/mob/living/carbon/monkey/life.dm
+++ b/code/modules/mob/living/carbon/monkey/life.dm
@@ -23,6 +23,8 @@
if (src.monkeyizing)
return
+ ..()
+
var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
if(src.loc)
environment = loc.return_air()
diff --git a/code/modules/mob/living/carbon/monkey/powers.dm b/code/modules/mob/living/carbon/monkey/powers.dm
index e05cb05de2..9a8f95283e 100644
--- a/code/modules/mob/living/carbon/monkey/powers.dm
+++ b/code/modules/mob/living/carbon/monkey/powers.dm
@@ -3,48 +3,50 @@
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Monkey"
- if(contents.len)
- for(var/obj/item/carried_item in contents)//If the monkey got on objects.
- if(!istype(carried_item, /obj/item/weapon/implant))//If it's not an implant.
- src << "\red You can't be carrying items or have items equipped when vent crawling!"
- return
-
- if(!stat)
- var/obj/machinery/atmospherics/unary/vent_pump/vent_found
- for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
- if(!v.welded)
- vent_found = v
- else
- src << "\red That vent is welded."
- if(vent_found)
- if(vent_found.network&&vent_found.network.normal_members.len)
- var/list/vents = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
- if(temp_vent.loc == loc)
- continue
- vents.Add(temp_vent)
- var/list/choices = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents)
- if(vent.loc.z != loc.z)
- continue
- var/atom/a = get_turf_loc(vent)
- choices.Add(a.loc)
- var/turf/startloc = loc
- var/obj/selection = input("Select a destination.", "Duct System") in choices
- var/selection_position = choices.Find(selection)
- if(loc==startloc)
- var/obj/target_vent = vents[selection_position]
- if(target_vent)
- for(var/mob/O in oviewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("[src] scrambles into the ventillation ducts! "), 1)
- loc = target_vent.loc
+ if(stat == CONSCIOUS)
+ if(!lying)
+ var/obj/machinery/atmospherics/unary/vent_pump/vent_found
+ for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
+ if(!v.welded)
+ vent_found = v
else
- src << "You need to remain still while entering a vent."
+ src << "\red That vent is welded."
+ if(vent_found)
+ if(vent_found.network&&vent_found.network.normal_members.len)
+ var/list/vents = list()
+ for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
+ if(temp_vent.loc == loc)
+ continue
+ vents.Add(temp_vent)
+ var/list/choices = list()
+ for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents)
+ if(vent.loc.z != loc.z)
+ continue
+ var/atom/a = get_turf_loc(vent)
+ choices.Add(a.loc)
+ var/turf/startloc = loc
+ var/obj/selection = input("Select a destination.", "Duct System") in choices
+ var/selection_position = choices.Find(selection)
+ if(loc==startloc)
+ if(contents.len)
+ for(var/obj/item/carried_item in contents)//If the monkey got on objects.
+ if(!istype(carried_item, /obj/item/weapon/implant))//If it's not an implant.
+ src << "\red You can't be carrying items or have items equipped when vent crawling!"
+ return
+ var/obj/target_vent = vents[selection_position]
+ if(target_vent)
+ for(var/mob/O in oviewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("[src] scrambles into the ventillation ducts! "), 1)
+ loc = target_vent.loc
+ else
+ src << "You need to remain still while entering a vent."
+ else
+ src << "This vent is not connected to anything."
else
- src << "This vent is not connected to anything."
+ src << "You must be standing on or beside an air vent to enter it."
else
- src << "You must be standing on or beside an air vent to enter it."
+ src << "You can't vent crawl while you're stunned!"
else
src << "You must be conscious to do this!"
return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/shock.dm b/code/modules/mob/living/carbon/shock.dm
index d7bca33368..f53ca6f66f 100644
--- a/code/modules/mob/living/carbon/shock.dm
+++ b/code/modules/mob/living/carbon/shock.dm
@@ -3,7 +3,7 @@
// proc to find out in how much pain the mob is at the moment
/mob/living/carbon/proc/updateshock()
- src.traumatic_shock = src.getOxyLoss() + src.getToxLoss() + src.getFireLoss() + 1.2*src.getBruteLoss() + 2*src.getCloneLoss()
+ src.traumatic_shock = src.getOxyLoss() + src.getToxLoss() + src.getFireLoss() + 1.2*src.getBruteLoss() + 2*src.getCloneLoss() + src.halloss
if(reagents.has_reagent("alkysine"))
src.traumatic_shock -= 10
if(reagents.has_reagent("inaprovaline"))
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index b1778089a8..78e4257cf8 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -22,18 +22,21 @@
adjustOxyLoss(damage/(blocked+1))
if(CLONE)
adjustCloneLoss(damage/(blocked+1))
+ if(HALLOSS)
+ adjustHalLoss(damage/(blocked+1))
UpdateDamageIcon()
updatehealth()
return 1
-/mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/def_zone = null, var/blocked = 0)
+/mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/def_zone = null, var/blocked = 0, var/halloss = 0)
if(blocked >= 2) return 0
if(brute) apply_damage(brute, BRUTE, def_zone, blocked)
if(burn) apply_damage(burn, BURN, def_zone, blocked)
if(tox) apply_damage(tox, TOX, def_zone, blocked)
if(oxy) apply_damage(oxy, OXY, def_zone, blocked)
if(clone) apply_damage(clone, CLONE, def_zone, blocked)
+ if(halloss) apply_damage(halloss, HALLOSS, def_zone, blocked)
return 1
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 28b98787c1..f272027a12 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1,3 +1,19 @@
+/mob/living/Life()
+
+ ..()
+
+ // While I'm doing a terriblly lazy way of initalizing things, why don't I make it so people's preferences tag along with them. This could be useful in fixing the fucking cloned-as-unknown thing, making me not have to dynamically load them during tensioner, and of course, storing metadata.
+
+ if(!src.storedpreferences)
+ src.storedpreferences = new
+ storedpreferences.savefile_load(src, 0)
+
+
+
+
+ return
+
+
/mob/living/verb/succumb()
set hidden = 1
if ((src.health < 0 && src.health > -95.0))
@@ -227,6 +243,26 @@
else
density = !lying
+
+/mob/living/proc/Examine_OOC()
+ set name = "Examine Meta-Info (OOC)"
+ set category = "OOC"
+ set src in view()
+
+ if(config.allow_Metadata)
+ usr << "[src]'s Metainfo:"
+
+ if(src.storedpreferences)
+ usr << "[src]'s OOC Notes: [src.storedpreferences.metadata]"
+
+ else
+ usr << "[src] does not have any stored infomation!"
+
+ else
+ usr << "OOC Metadata is not supported by this server!"
+
+ return
+
/mob/living/attack_animal(mob/M)
attack_paw(M) // treat it like a normal non-human attack
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 096a517213..1c459ef176 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -142,8 +142,9 @@
//world << "channel_prefix=[channel_prefix]; message_mode=[message_mode]"
if (message_mode)
message = trim(copytext(message, 3))
- if (!ishuman(src) && (message_mode=="department" || (message_mode in radiochannels)))
+ if (!(ishuman(src) || istype(src, /mob/living/simple_animal)) && (message_mode=="department" || (message_mode in radiochannels)))
message_mode = null //only humans can use headsets
+ // Check removed so parrots can use headsets!
if (!message)
return
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index f693944133..3ab582828e 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -301,6 +301,14 @@
if (href_list["showalerts"])
ai_alerts()
+ //Carn: holopad requests
+ if (href_list["jumptoholopad"])
+ var/obj/machinery/hologram/holopad/H = locate(href_list["jumptoholopad"])
+ if(stat == CONSCIOUS)
+ if(H)
+ H.attack_ai(src) //may as well recycle
+ else
+ src << "Unable to locate the holopad. "
if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
var/L = text2num(href_list["lawc"])
diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm
index ce640fc219..79c4a7783c 100644
--- a/code/modules/mob/living/silicon/ai/death.dm
+++ b/code/modules/mob/living/silicon/ai/death.dm
@@ -34,7 +34,7 @@
emergency_shuttle.incall(2)
log_game("All the AIs, comm consoles and boards are destroyed. Shuttle called.")
message_admins("All the AIs, comm consoles and boards are destroyed. Shuttle called.", 1)
- world << "\blue Alert: The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes. "
+ captain_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.")
world << sound('shuttlecalled.ogg')
if(explosive)
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 6e0908137b..78883f7ebd 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -2,9 +2,10 @@
canmove = 0
src.loc = paicard
card = paicard
- if(!card.radio)
- card.radio = new /obj/item/device/radio(src.card)
- radio = card.radio
+ if(card)
+ if(!card.radio)
+ card.radio = new /obj/item/device/radio(src.card)
+ radio = card.radio
..()
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index f5d9676013..30338c21fc 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -170,8 +170,14 @@
if(isnull(P)||P.toff)
return
+ var/AnsweringMS = 0
for (var/obj/machinery/message_server/MS in world)
MS.send_pda_message("[P.owner]","[src]","[t]")
+ if(MS.active)
+ AnsweringMS++
+
+ if(!AnsweringMS)
+ return
tnote += "→ To [P.owner]: [t] "
P.tnote += "← From [src] : [t] "
@@ -195,12 +201,18 @@
else
var/mob/living/silicon/pai/P = target
- tnote += "→ To [P]: [t] "
- P.tnote += "← From [src] : [t] "
-
-
+ var/AnsweringMS = 0
for (var/obj/machinery/message_server/MS in world)
MS.send_pda_message("[P]","[src]","[t]")
+ if(MS.active)
+ AnsweringMS++
+
+ if(!AnsweringMS)
+ return
+
+
+ tnote += "→ To [P]: [t] "
+ P.tnote += "← From [src] : [t] "
if (prob(15)) //Give the AI a chance of intercepting the message
var/who = src
diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm
index e7f4904ede..5afa42ee14 100644
--- a/code/modules/mob/living/silicon/robot/laws.dm
+++ b/code/modules/mob/living/silicon/robot/laws.dm
@@ -93,4 +93,97 @@
/mob/living/silicon/robot/proc/clear_ion_laws()
laws_sanity_check()
- laws.clear_ion_laws()
\ No newline at end of file
+ laws.clear_ion_laws()
+
+/mob/living/silicon/robot/proc/statelaws() // -- TLE
+// set category = "AI Commands"
+// set name = "State Laws"
+ src.say("Current Active Laws:")
+ //src.laws_sanity_check()
+ //src.laws.show_laws(world)
+ var/number = 1
+ sleep(10)
+
+
+
+ if (src.laws.zeroth)
+ if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite
+ src.say("0. [src.laws.zeroth]")
+ sleep(10)
+
+ for (var/index = 1, index <= src.laws.ion.len, index++)
+ var/law = src.laws.ion[index]
+ var/num = ionnum()
+ if (length(law) > 0)
+ if (src.ioncheck[index] == "Yes")
+ src.say("[num]. [law]")
+ sleep(10)
+
+ for (var/index = 1, index <= src.laws.inherent.len, index++)
+ var/law = src.laws.inherent[index]
+
+ if (length(law) > 0)
+ if (src.lawcheck[index+1] == "Yes")
+ src.say("[number]. [law]")
+ sleep(10)
+ number++
+
+
+ for (var/index = 1, index <= src.laws.supplied.len, index++)
+ var/law = src.laws.supplied[index]
+
+ if (length(law) > 0)
+ if(src.lawcheck.len >= number+1)
+ if (src.lawcheck[number+1] == "Yes")
+ src.say("[number]. [law]")
+ sleep(10)
+ number++
+
+
+/mob/living/silicon/robot/verb/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
+ set category = "Robot Commands"
+ set name = "State Laws"
+
+ var/list = "Which laws do you want to include when stating them for the crew? "
+
+
+
+ if (src.laws.zeroth)
+ if (!src.lawcheck[1])
+ src.lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite
+ list += {"[src.lawcheck[1]] 0: [src.laws.zeroth] "}
+
+ for (var/index = 1, index <= src.laws.ion.len, index++)
+ var/law = src.laws.ion[index]
+
+ if (length(law) > 0)
+
+
+ if (!src.ioncheck[index])
+ src.ioncheck[index] = "Yes"
+ list += {"[src.ioncheck[index]] [ionnum()]: [law] "}
+ src.ioncheck.len += 1
+
+ var/number = 1
+ for (var/index = 1, index <= src.laws.inherent.len, index++)
+ var/law = src.laws.inherent[index]
+
+ if (length(law) > 0)
+ src.lawcheck.len += 1
+
+ if (!src.lawcheck[number+1])
+ src.lawcheck[number+1] = "Yes"
+ list += {"[src.lawcheck[number+1]] [number]: [law] "}
+ number++
+
+ for (var/index = 1, index <= src.laws.supplied.len, index++)
+ var/law = src.laws.supplied[index]
+ if (length(law) > 0)
+ src.lawcheck.len += 1
+ if (!src.lawcheck[number+1])
+ src.lawcheck[number+1] = "Yes"
+ list += {"[src.lawcheck[number+1]] [number]: [law] "}
+ number++
+ list += {"State Laws "}
+
+ usr << browse(list, "window=laws")
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 4009499c82..6a07be5709 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -15,19 +15,31 @@
name = real_name
spawn (4)
- if (client)
- connected_ai = activeais()
- if (connected_ai)
- connected_ai.connected_robots += src
-// laws = connected_ai.laws //The borg inherits its AI's laws
- laws = new /datum/ai_laws
- lawsync()
- src << "Unit slaved to [connected_ai.name], downloading laws. "
- lawupdate = 1
+ if(!syndie)
+ if (client)
+ connected_ai = activeais()
+ if (connected_ai)
+ connected_ai.connected_robots += src
+ // laws = connected_ai.laws //The borg inherits its AI's laws
+ laws = new /datum/ai_laws
+ lawsync()
+ src << "Unit slaved to [connected_ai.name], downloading laws. "
+ lawupdate = 1
+ else
+ laws = new /datum/ai_laws/asimov
+ lawupdate = 0
+ src << "Unable to locate an AI, reverting to standard Asimov laws. "
else
- laws = new /datum/ai_laws/nanotrasen
+ laws = new /datum/ai_laws/antimov
lawupdate = 0
- src << "Unable to locate an AI, reverting to standard NanoTrasen laws. "
+ scrambledcodes = 1
+ src << "Follow your laws."
+ cell.maxcharge = 25000
+ cell.charge = 25000
+ module = new /obj/item/weapon/robot_module/syndicate(src)
+ hands.icon_state = "standard"
+ icon_state = "secborg"
+ modtype = "Synd"
radio = new /obj/item/device/radio(src)
camera = new /obj/machinery/camera(src)
@@ -46,6 +58,12 @@
/mob/living/silicon/robot/Del()
if(mmi)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside.
mmi.loc = get_turf(loc)//To hopefully prevent run time errors.
+
+ if(!key)
+ for(var/mob/dead/observer/ghost in world)
+ if(ghost.corpse == src && ghost.client)
+ ghost.client.mob = ghost.corpse
+
if(key)//If there is a client attached to host.
if(client)
client.screen.len = null
@@ -130,6 +148,8 @@
if (sprite == "Non-Humanoid")
src.icon_state = "bloodhound"
modtype = "Sec"
+ //speed = -1 Secborgs have nerfed tasers now, so the speed boost is not necessary
+ nopush = 1
channels = list("Security" = 1)
//feedback_inc("cyborg_security",1)
@@ -200,6 +220,20 @@
viewalerts = 1
src << browse(dat, "window=robotalerts&can_close=0")
+/mob/living/silicon/robot/proc/ai_roster()
+ set category = "Robot Commands"
+ set name = "Show Crew Manifest"
+
+ var/dat = "Crew Roster Crew Roster: "
+
+ for (var/datum/data/record/t in data_core.general)
+ dat += "[t.fields["name"]] - [t.fields["rank"]] "
+
+ dat += ""
+
+ src << browse(dat, "window=airoster")
+ onclose(src, "airoster")
+
/mob/living/silicon/robot/blob_act()
if (stat != 2)
adjustBruteLoss(60)
@@ -517,6 +551,24 @@
if(prob(25))
src << "Hack attempt detected."
return
+
+ else if(istype(W, /obj/item/borg/upgrade/))
+ var/obj/item/borg/upgrade/U = W
+ if(!opened)
+ usr << "You must access the borgs internals!"
+ else if(!src.module && U.require_module)
+ usr << "The borg must choose a module before he can be upgraded!"
+ else if(U.locked)
+ usr << "The upgrade is locked and cannot be used yet!"
+ else
+ if(U.action(src))
+ usr << "You apply the upgrade to [src]!"
+ usr.drop_item()
+ U.loc = src
+ else
+ usr << "Upgrade error!"
+
+
else
spark_system.start()
return ..()
@@ -930,6 +982,26 @@
else
src << "Module isn't activated"
installed_modules()
+
+ if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
+ var/L = text2num(href_list["lawc"])
+ switch(lawcheck[L+1])
+ if ("Yes") lawcheck[L+1] = "No"
+ if ("No") lawcheck[L+1] = "Yes"
+// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
+ checklaws()
+
+ if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
+ var/L = text2num(href_list["lawi"])
+ switch(ioncheck[L])
+ if ("Yes") ioncheck[L] = "No"
+ if ("No") ioncheck[L] = "Yes"
+// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
+ checklaws()
+
+ if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite
+ statelaws()
+
return
/mob/living/silicon/robot/proc/uneq_active()
@@ -1095,7 +1167,26 @@ Frequency:
. = ..()
if ((s_active && !( s_active in contents ) ))
s_active.close(src)
- return
+
+ if(module)
+ if(module.type == /obj/item/weapon/robot_module/janitor) //you'd think checking the module would work
+ var/turf/tile = get_turf(loc)
+
+ tile.clean_blood()
+ for(var/obj/effect/R in tile)
+ if(istype(R, /obj/effect/rune) || istype(R, /obj/effect/decal/cleanable) || istype(R, /obj/effect/overlay))
+ del(R)
+
+ for(var/obj/item/cleaned_item in tile)
+ cleaned_item.clean_blood()
+
+ for(var/mob/living/carbon/human/cleaned_human in tile) //HUE HUE I CLEAN U
+ if(cleaned_human.lying)
+ cleaned_human.clean_blood()
+ cleaned_human << "\red [src] cleans your face!"
+ for(var/obj/item/carried_item in cleaned_human.contents)
+ carried_item.clean_blood()
+ return
/mob/living/silicon/robot/proc/reset_module()
modtype = "robot"
@@ -1111,3 +1202,32 @@ Frequency:
gib()
return
+/mob/living/silicon/robot/proc/UnlinkSelf()
+ if (src.connected_ai)
+ src.connected_ai = null
+ lawupdate = 0
+ lockcharge = 0
+ canmove = 1
+ scrambledcodes = 1
+
+
+
+/mob/living/silicon/robot/proc/ResetSecurityCodes()
+ set category = "Robot Commands"
+ set name = "Reset Identity Codes"
+ set desc = "Scrambles your security and identification codes and resets your current buffers. Unlocks you and but permenantly severs you from your AI and the robotics console."
+
+ var/mob/living/silicon/robot/R = usr
+
+ if(R)
+ R.UnlinkSelf()
+ R << "Buffers flushed and reset. All systems operational."
+ src.verbs -= /mob/living/silicon/robot/proc/ResetSecurityCodes
+
+
+/mob/living/silicon/robot/proc/flashproof()
+ if(module)
+ for(var/obj/item/borg/upgrade/flashproof/F in module.modules)
+ return 1
+
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index ffe76a3b76..ea5a00afb5 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -163,9 +163,7 @@
New()
..()
- src.modules += new /obj/item/weapon/cleaner(src)
- src.modules += new /obj/item/weapon/mop(src)
- src.modules += new /obj/item/weapon/reagent_containers/glass/bucket(src)
+ src.modules += new /obj/item/weapon/soap/nanotrasen(src)
src.modules += new /obj/item/weapon/trashbag(src)
src.emag = new /obj/item/weapon/cleaner(src)
@@ -230,5 +228,8 @@
New()
+ src.modules += new /obj/item/weapon/melee/energy/sword(src)
+ src.modules += new /obj/item/weapon/gun/energy/pulse_rifle/destroyer(src)
src.modules += new /obj/item/weapon/card/emag(src)
+ src.modules += new /obj/item/weapon/tank/jetpack/oxygen(src)
return
diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm
index f0a907d05d..74522c2b0d 100644
--- a/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -5,3 +5,11 @@
if(J.allow_thrust(0.01)) return 1
if(..()) return 1
return 0
+
+ //No longer needed, but I'll leave it here incase we plan to re-use it.
+/mob/living/silicon/robot/movement_delay()
+ var/tally = 0 //Incase I need to add stuff other than "speed" later
+
+ tally = speed
+
+ return tally
diff --git a/code/modules/mob/living/silicon/robot/robot_upgrades.dm b/code/modules/mob/living/silicon/robot/robot_upgrades.dm
new file mode 100644
index 0000000000..fe8d77dd7c
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/robot_upgrades.dm
@@ -0,0 +1,113 @@
+// robot_upgrades.dm
+// Contains various borg upgrades.
+
+/obj/item/borg/upgrade/
+ name = "A borg upgrade module."
+ desc = "Protected by FRM."
+ icon = 'module.dmi'
+ icon_state = "id_mod"
+ var/construction_time = 120
+ var/construction_cost = list("metal"=10000)
+ var/locked = 0
+ var/require_module = 0
+ var/installed = 0
+
+/obj/item/borg/upgrade/proc/action()
+ return
+
+
+/obj/item/borg/upgrade/reset/
+ name = "Borg module reset board"
+ desc = "Used to reset a borg's module. Destroys any other upgrades applied to the borg."
+ require_module = 1
+
+/obj/item/borg/upgrade/reset/action(var/mob/living/silicon/robot/R)
+ R.uneq_all()
+ R.hands.icon_state = "nomod"
+ R.icon_state = "robot"
+ del(R.module)
+ R.module = null
+ R.modtype = "robot"
+ R.real_name = "Cyborg [R.ident]"
+ R.name = R.real_name
+ R.nopush = 0
+ R.updateicon()
+
+ return 1
+
+
+
+/obj/item/borg/upgrade/flashproof/
+ name = "Borg Flash-Supression"
+ desc = "A highly advanced, complicated system for supressing incoming flashes directed at the borg's optical processing system."
+ construction_cost = list("metal"=10000,"gold"=2000,"silver"=3000,"glass"=2000, "diamond"=5000)
+ require_module = 1
+
+
+/obj/item/borg/upgrade/flashproof/New() // Why the fuck does the fabricator make a new instance of all the items?
+ //desc = "Sunglasses with duct tape." // Why? D:
+
+/obj/item/borg/upgrade/flashproof/action(var/mob/living/silicon/robot/R)
+ if(R.module)
+ R.module += src
+
+ return 1
+
+/obj/item/borg/upgrade/restart/
+ name = "Borg emergancy restart module"
+ desc = "Used to force a restart of a disabled-but-repaired borg, bringing it back online."
+ construction_cost = list("metal"=60000 , "glass"=5000)
+
+
+/obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/R)
+ if(!R.key)
+ for(var/mob/dead/observer/ghost in world)
+ if(ghost.corpse == R && ghost.client)
+ ghost.client.mob = ghost.corpse
+
+ if(R.health < 0)
+ usr << "You have to repair the borg before using this module!"
+ return 0
+
+ R.stat = 0
+ return 1
+
+
+/obj/item/borg/upgrade/vtec/
+ name = "Borg VTEC Module"
+ desc = "Used to kick in a borgs VTEC systems, increasing their speed."
+ construction_cost = list("metal"=80000 , "glass"=6000 , "gold"= 5000)
+ require_module = 1
+
+/obj/item/borg/upgrade/vtec/action(var/mob/living/silicon/robot/R)
+ if(R.speed == -1)
+ return 0
+
+ R.speed--
+ return 1
+
+
+/obj/item/borg/upgrade/tasercooler/
+ name = "Borg Rapid Taser Cooling Module"
+ desc = "Used to cool a mounted taser, increasing the potential current in it and thus its recharge rate.."
+ construction_cost = list("metal"=80000 , "glass"=6000 , "gold"= 2000, "diamond" = 500)
+ require_module = 1
+
+
+/obj/item/borg/upgrade/tasercooler/action(var/mob/living/silicon/robot/R)
+ if(R.module != /obj/item/weapon/robot_module/security)
+ R << "Upgrade mounting error! No suitable hardpoint detected!"
+ return 0
+
+ var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in R
+ if(!T)
+ return 0
+
+ if(T.recharge_time <= 2)
+ R << "Maximum cooling achieved for this hardpoint!"
+ return 0
+
+ else
+ T.recharge_time = min(2 , T.recharge_time - 4)
+
+ return 1
\ No newline at end of file
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index fa15f854fd..f3355dba7f 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -420,7 +420,7 @@
set src in usr
if(usr != src)
usr << "No."
- var/msg = input(usr,"Set the flavor text in your 'examine' verb. Don't metagame!","Flavor Text",html_decode(flavor_text)) as message|null
+ var/msg = input(usr,"Set the flavor text in your 'examine' verb. Can also be used for OOC notes about your character.","Flavor Text",html_decode(flavor_text)) as message|null
if(msg != null)
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
@@ -454,14 +454,35 @@
set category = "OOC"
if (!( abandon_allowed ))
+ usr << "\blue Respawn is disabled."
return
if ((stat != 2 || !( ticker )))
usr << "\blue You must be dead to use this! "
return
+ if (ticker.mode.name == ("meteor" || "epidemic"))
+ usr << "\blue Respawn is disabled."
+ return
+ else
+ var/deathtime = world.time - src.timeofdeath
+ var/deathtimeminutes = round(deathtime / 600)
+ var/pluralcheck = "minute"
+ if(deathtimeminutes == 0)
+ pluralcheck = ""
+ else if(deathtimeminutes == 1)
+ pluralcheck = " [deathtimeminutes] minute and"
+ else if(deathtimeminutes > 1)
+ pluralcheck = " [deathtimeminutes] minutes and"
+ var/deathtimeseconds = round((deathtime - deathtimeminutes * 600) / 10,1)
+ usr << "You have been dead for[pluralcheck] [deathtimeseconds] seconds."
+ if (deathtime < 18000)
+ usr << "You must wait 30 minutes to respawn!"
+ return
+ else
+ usr << "You can respawn now, enjoy your new life!"
log_game("[usr.name]/[usr.key] used abandon mob.")
- usr << "\blue Please roleplay correctly! "
+ usr << "\blue Make sure to play a different character, and please roleplay correctly! "
if(!client)
log_game("[usr.key] AM failed due to disconnect.")
@@ -516,6 +537,19 @@
else
usr << "\blue Now you hear speech only from nearest creatures."
+/client/var/ghost_sight = 1
+/client/verb/toggle_ghost_sight()
+ set name = "Ghost sight"
+ set category = "OOC"
+ set desc = "Hear emotes from everywhere"
+ ghost_sight = !ghost_sight
+ if (ghost_sight)
+ usr << "\blue Now you hear all emotes in the world"
+ else
+ usr << "\blue Now you hear emotes only from nearest creatures."
+
+
+
/mob/verb/observe()
set name = "Observe"
set category = "OOC"
@@ -1149,3 +1183,66 @@ note dizziness decrements automatically in the mob's Life() proc.
/mob/proc/AdjustParalysis(amount)
paralysis = max(paralysis + amount,0)
return
+
+// ++++ROCKDTBEN++++ MOB PROCS -- Ask me before touching
+
+/mob/proc/getBruteLoss()
+ return bruteloss
+
+/mob/proc/adjustBruteLoss(var/amount)
+ bruteloss = max(bruteloss + amount, 0)
+
+/mob/proc/getOxyLoss()
+ return oxyloss
+
+/mob/proc/adjustOxyLoss(var/amount)
+ oxyloss = max(oxyloss + amount, 0)
+
+/mob/proc/setOxyLoss(var/amount)
+ oxyloss = amount
+
+/mob/proc/getToxLoss()
+ return toxloss
+
+/mob/proc/adjustToxLoss(var/amount)
+ toxloss = max(toxloss + amount, 0)
+
+/mob/proc/setToxLoss(var/amount)
+ toxloss = amount
+
+/mob/proc/getFireLoss()
+ return fireloss
+
+/mob/proc/adjustFireLoss(var/amount)
+ fireloss = max(fireloss + amount, 0)
+
+/mob/proc/getCloneLoss()
+ return cloneloss
+
+/mob/proc/adjustCloneLoss(var/amount)
+ cloneloss = max(cloneloss + amount, 0)
+
+/mob/proc/setCloneLoss(var/amount)
+ cloneloss = amount
+
+/mob/proc/getHalLoss()
+ return halloss
+
+/mob/proc/adjustHalLoss(var/amount)
+ halloss = max(halloss + amount, 0)
+
+/mob/proc/setHalLoss(var/amount)
+ halloss = amount
+
+
+
+/mob/proc/getBrainLoss()
+ return brainloss
+
+/mob/proc/adjustBrainLoss(var/amount)
+ brainloss = max(brainloss + amount, 0)
+
+/mob/proc/setBrainLoss(var/amount)
+ brainloss = amount
+
+// ++++ROCKDTBEN++++ MOB PROCS //END
\ No newline at end of file
diff --git a/code/modules/mob/mob_cleanup.dm b/code/modules/mob/mob_cleanup.dm
index 0e167a6c5e..766d695597 100644
--- a/code/modules/mob/mob_cleanup.dm
+++ b/code/modules/mob/mob_cleanup.dm
@@ -93,7 +93,7 @@ Put (mob/proc)s here that are in dire need of a code cleanup.
switch(target_zone)
if(1)
- if(isobj(H.head))
+ if(isobj(H.head) && !istype(H.head, /obj/item/weapon/paper))
Cl = H.head
passed = prob(Cl.permeability_coefficient*100*virus.permeability_mod)
// world << "Head pass [passed]"
@@ -191,4 +191,4 @@ Put (mob/proc)s here that are in dire need of a code cleanup.
if(prob(5))
v.carrier = 1
return
- return
\ No newline at end of file
+ return
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 1da6a25f4f..06c4c9cd50 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -201,6 +201,7 @@
//clumsy = 16
//obese = 32
//husk = 64
+ var/tkdisable = 0//For remote viewing and stuff. Disables TK.
var/voice_name = "unidentifiable voice"
var/voice_message = null // When you are not understood by others (replaced with just screeches, hisses, chimpers etc.)
@@ -282,64 +283,10 @@ the mob is also allowed to move without any sort of restriction. For instance, i
var/digitalcamo = 0 // Can they be tracked by the AI?
-
var/list/organs = list( ) //List of organs.
var/list/organs2 = list()
//Singularity wants you!
var/grav_delay = 0
var/being_strangled = 0
-
-
-// ++++ROCKDTBEN++++ MOB PROCS
-
-/mob/proc/getBruteLoss()
- return bruteloss
-
-/mob/proc/adjustBruteLoss(var/amount)
- bruteloss = max(bruteloss + amount, 0)
-
-/mob/proc/getOxyLoss()
- return oxyloss
-
-/mob/proc/adjustOxyLoss(var/amount)
- oxyloss = max(oxyloss + amount, 0)
-
-/mob/proc/setOxyLoss(var/amount)
- oxyloss = amount
-
-/mob/proc/getToxLoss()
- return toxloss
-
-/mob/proc/adjustToxLoss(var/amount)
- toxloss = max(toxloss + amount, 0)
-
-/mob/proc/setToxLoss(var/amount)
- toxloss = amount
-
-/mob/proc/getFireLoss()
- return fireloss
-
-/mob/proc/adjustFireLoss(var/amount)
- fireloss = max(fireloss + amount, 0)
-
-/mob/proc/getCloneLoss()
- return cloneloss
-
-/mob/proc/adjustCloneLoss(var/amount)
- cloneloss = max(cloneloss + amount, 0)
-
-/mob/proc/setCloneLoss(var/amount)
- cloneloss = amount
-
-/mob/proc/getBrainLoss()
- return brainloss
-
-/mob/proc/adjustBrainLoss(var/amount)
- brainloss = max(brainloss + amount, 0)
-
-/mob/proc/setBrainLoss(var/amount)
- brainloss = amount
-
-// ++++ROCKDTBEN++++ MOB PROCS //END
-
+ var/datum/preferences/storedpreferences = null
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index b68d9f0761..7f887d4215 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -89,6 +89,8 @@
/obj/item/weapon/grab/proc/s_click(obj/screen/S as obj)
+ if (!affecting)
+ return
if (assailant.next_move > world.time)
return
if ((!( assailant.canmove ) || assailant.lying))
diff --git a/code/modules/mob/new_player/preferences.dm b/code/modules/mob/new_player/preferences.dm
index 8e23153041..bd7722a90c 100644
--- a/code/modules/mob/new_player/preferences.dm
+++ b/code/modules/mob/new_player/preferences.dm
@@ -129,6 +129,10 @@ datum/preferences
skill_specialization = null
list/skills = list() // skills can range from 0 to 3
+ // OOC Metadata:
+ metadata = ""
+
+
New()
hair_style = new/datum/sprite_accessory/hair/short
facial_hair_style = new/datum/sprite_accessory/facial_hair/shaved
@@ -243,6 +247,10 @@ datum/preferences
dat += "UI Style: [UI == UI_NEW ? "New" : "Old"] "
dat += "Play admin midis: [midis == 1 ? "Yes" : "No"] "
dat += "Ghost ears: [ghost_ears == 0 ? "Nearest Creatures" : "All Speech"] "
+ dat += "Ghost sight: [ghost_sight == 0 ? "Nearest Creatures" : "All Emotes"] "
+
+ if(config.allow_Metadata)
+ dat += "OOC Notes: Edit "
if((user.client) && (user.client.holder) && (user.client.holder.rank) && (user.client.holder.rank == "Game Master"))
dat += "OOC "
@@ -539,6 +547,8 @@ datum/preferences
proc/process_link(mob/user, list/link_tags)
+ if(!usr)
+ return
if(link_tags["occ"])
if(link_tags["cancel"])
user << browse(null, "window=\ref[user]occupation")
@@ -634,11 +644,29 @@ datum/preferences
if(link_tags["age"])
switch(link_tags["age"])
if("input")
- var/new_age = input(user, "Please select type in age: 15-45", "Character Generation") as num
+ var/new_age = input(user, "Please enter an age ([minimum_age]-[maximum_age])", "Character Generation") as num
if(new_age)
- age = max(min(round(text2num(new_age)), 45), 15)
+ age = max(min(round(text2num(new_age)), maximum_age), minimum_age)
if("random")
- age = rand (20, 45)
+ age = rand (minimum_age, maximum_age)
+
+ if(link_tags["OOC"])
+ var/tempnote = ""
+ tempnote = input(user, "Please enter your OOC Notes!:", "OOC notes" , metadata) as text
+ var/list/bad_characters = list("_", "\"", "<", ">", ";", "\[", "\]", "{", "}", "|", "\\","0","1","2","3","4","5","6","7","8","9")
+
+ for(var/c in bad_characters)
+ tempnote = dd_replacetext(tempnote, c, "")
+
+ if(length(tempnote) >= 255)
+ alert("That name is too long. (255 character max, please)")
+ return
+
+ metadata = tempnote
+ return
+
+
+
if(link_tags["b_type"])
switch(link_tags["b_type"])
@@ -783,6 +811,9 @@ datum/preferences
if(link_tags["ghost_ears"])
ghost_ears = !ghost_ears
+ if(link_tags["ghost_sight"])
+ ghost_sight = !ghost_sight
+
if(link_tags["underwear"])
switch(link_tags["underwear"])
if("inputmale")
@@ -991,6 +1022,7 @@ datum/preferences
C.be_syndicate = be_special
if(isnull(src.ghost_ears)) src.ghost_ears = 1 //There were problems where the default was null before someone saved their profile.
C.ghost_ears = src.ghost_ears
+ C.ghost_sight = src.ghost_sight
proc/copydisabilities(mob/living/carbon/human/character)
if(disabilities & 1)
@@ -1012,4 +1044,4 @@ datum/preferences
character.disabilities = disabilities
#undef UI_OLD
-#undef UI_NEW
\ No newline at end of file
+#undef UI_NEW
diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm
index b75fef33f1..1fc8921a9f 100644
--- a/code/modules/mob/new_player/preferences_setup.dm
+++ b/code/modules/mob/new_player/preferences_setup.dm
@@ -15,7 +15,7 @@ datum/preferences
underwear = 1
backbag = 2
b_type = pick("A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-")
- age = rand(19,35)
+ age = rand(minimum_age, maximum_age)
copy_to(H,1)
proc/randomize_name()
@@ -263,4 +263,4 @@ datum/preferences
if(H.name == f_style)
facial_hair_style = H
else
- del(H)
\ No newline at end of file
+ del(H)
diff --git a/code/modules/mob/new_player/savefile.dm b/code/modules/mob/new_player/savefile.dm
index 39f0151271..48f44415f7 100644
--- a/code/modules/mob/new_player/savefile.dm
+++ b/code/modules/mob/new_player/savefile.dm
@@ -141,6 +141,7 @@ datum/preferences/proc/savefile_save(mob/user, slot)
F["UI"] << src.UI
F["midis"] << src.midis
F["ghost_ears"] << src.ghost_ears
+ F["ghost_sight"] << src.ghost_sight
F["pregame_music"] << src.pregame_music
F["ooccolor"] << src.ooccolor
F["lastchangelog"] << src.lastchangelog
@@ -150,6 +151,8 @@ datum/preferences/proc/savefile_save(mob/user, slot)
F["skills"] << src.skills
F["skill_specialization"] << src.skill_specialization
+ F["OOC_Notes"] << src.metadata
+
return 1
// loads the savefile corresponding to the mob's ckey
@@ -212,6 +215,8 @@ datum/preferences/proc/savefile_load(mob/user, slot)
F["ghost_ears"] >> src.ghost_ears
if(isnull(ghost_ears)) ghost_ears = 1 //Hotfix
F["pregame_music"] >> src.pregame_music
+ F["ghost_sight"] >> src.ghost_sight
+ if(isnull(ghost_sight)) ghost_sight = 1 //Hotfix
F["ooccolor"] >> src.ooccolor
F["lastchangelog"] >> src.lastchangelog
F["UI"] >> src.UI
@@ -244,6 +249,11 @@ datum/preferences/proc/savefile_load(mob/user, slot)
if(!job_alt_titles)
job_alt_titles = new()
+ F["OOC_Notes"] >> src.metadata
+
+ if(isnull(metadata))
+ metadata = ""
+
//NOTE: Conversion things go inside this if statement
//When updating the save file remember to add 1 to BOTH the savefile constants
//Also take the old conversion things that no longer apply out of this if
diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm
index a0c5ec9815..b22fcc461e 100644
--- a/code/modules/mob/new_player/sprite_accessories.dm
+++ b/code/modules/mob/new_player/sprite_accessories.dm
@@ -58,6 +58,14 @@
name = "Longest Hair"
icon_state = "hair_vlong"
+ longalt
+ name = "Long Hair Alt"
+ icon_state = "hair_longfringe"
+
+ longestalt
+ name = "Longest Hair Alt"
+ icon_state = "hair_vlongfringe"
+
halfbang
name = "Half-banged Hair"
icon_state = "hair_halfbang"
@@ -89,6 +97,7 @@
mohawk
name = "Mohawk"
icon_state = "hair_d"
+ choose_female = 0 // gross
balding
name = "Balding Hair"
@@ -118,6 +127,7 @@
dreadlocks
name = "Dreadlocks"
icon_state = "hair_dreads"
+ choose_female = 0 // okay.jpg
jensen
name = "Adam Jensen Hair"
@@ -132,14 +142,6 @@
icon_state = "bald"
choose_female = 0
- longalt
- name = "Long Hair Alt"
- icon_state = "hair_longfringe"
-
- longestalt
- name = "Longest Hair Alt"
- icon_state = "hair_vlongfringe"
-
himecut
name = "Hime Cut"
icon_state = "hair_himecut"
@@ -148,6 +150,9 @@
name = "Curls"
icon_state = "hair_curls"
+ spikey
+ name = "Spikey"
+ icon_state = "hair_spikey"
/*
///////////////////////////////////
diff --git a/code/modules/mob/screen.dm b/code/modules/mob/screen.dm
index bdc63af18e..07343b0c6c 100644
--- a/code/modules/mob/screen.dm
+++ b/code/modules/mob/screen.dm
@@ -456,13 +456,16 @@
if("hand")
usr:swap_hand()
if("resist")
- if(usr.next_move < world.time)
+ if(usr.next_move > world.time)
return
usr.next_move = world.time + 20
if ((!( usr.stat ) && usr.canmove && !( usr.restrained() )))
+ var/resisting = 0
for(var/obj/O in usr.requests)
del(O)
+ resisting++
for(var/obj/item/weapon/grab/G in usr.grabbed_by)
+ resisting++
if (G.state == 1)
del(G)
else
@@ -477,9 +480,9 @@
for(var/mob/O in viewers(usr, null))
O.show_message(text("\red [] has broken free of []'s headlock!", usr, G.assailant), 1)
del(G)
- for(var/mob/O in viewers(usr, null))
- O.show_message(text("\red [] resists! ", usr), 1)
-
+ if(resisting)
+ for(var/mob/O in viewers(usr, null))
+ O.show_message(text("\red [] resists! ", usr), 1)
if(usr:handcuffed && usr:canmove && (usr.last_special <= world.time))
var/breakouttime = 1200
var/displaytime = 2
@@ -494,7 +497,8 @@
O.show_message(text("\red [] is trying to break the handcuffs! ", usr), 1)
spawn(0)
if(do_after(usr, 50))
- if(!usr:handcuffed || usr:buckled) return
+ if(!usr:handcuffed || usr:buckled)
+ return
for(var/mob/O in viewers(usr))
O.show_message(text("\red [] manages to break the handcuffs! ", usr), 1)
usr << "\green You successfully break your handcuffs."
@@ -569,11 +573,14 @@
O.show_message(text("\red [] attempts to unbuckle themself! ", usr), 1)
spawn(0)
if(do_after(usr, 1200))
- if(!usr:buckled) return
+ if(!usr:buckled)
+ return
for(var/mob/O in viewers(usr))
O.show_message(text("\red [] manages to unbuckle themself! ", usr), 1)
usr << "\blue You successfully unbuckle yourself."
usr:buckled.manual_unbuckle(usr)
+
+
if("module")
if(issilicon(usr))
if(usr:module)
diff --git a/code/modules/mob/simple_animal/cat.dm b/code/modules/mob/simple_animal/cat.dm
index 18c06a62a2..f75db3dc16 100644
--- a/code/modules/mob/simple_animal/cat.dm
+++ b/code/modules/mob/simple_animal/cat.dm
@@ -12,6 +12,7 @@
emote_see = list("shakes its head", "shivers")
speak_chance = 1
turns_per_move = 5
+ see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meat
response_help = "pets the"
response_disarm = "gently pushes aside the"
diff --git a/code/modules/mob/simple_animal/corgi.dm b/code/modules/mob/simple_animal/corgi.dm
index 2cf1138d77..a6e7e687a2 100644
--- a/code/modules/mob/simple_animal/corgi.dm
+++ b/code/modules/mob/simple_animal/corgi.dm
@@ -18,6 +18,7 @@
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
+ see_in_dark = 5
var/obj/item/inventory_head
var/obj/item/inventory_back
var/obj/item/inventory_mouth
@@ -392,8 +393,4 @@
dir = i
sleep(1)
else
- ..()
-
-/obj/item/weapon/reagent_containers/food/snacks/sliceable/meat/corgi
- name = "Corgi meat"
- desc = "Tastes like... well you know..."
\ No newline at end of file
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/simple_animal/parrot.dm b/code/modules/mob/simple_animal/parrot.dm
new file mode 100644
index 0000000000..fd2135060f
--- /dev/null
+++ b/code/modules/mob/simple_animal/parrot.dm
@@ -0,0 +1,91 @@
+/mob/living/simple_animal/parrot
+ name = "\improper Parrot"
+ desc = "It's a parrot! No dirty words!"
+ icon = 'mob.dmi'
+ icon_state = "cat"
+ icon_living = "cat"
+ icon_dead = "cat_dead"
+ speak = list("Hi","Hello!","Cracker?","BAWWWWK george mellons griffing me")
+ speak_emote = list("squawks","says","yells")
+ emote_hear = list("squawks","bawks")
+ emote_see = list("flutters its wings", "glares at you")
+ speak_chance = 1
+ turns_per_move = 5
+ meat_type = /obj/item/weapon/reagent_containers/food/snacks/cracker/
+ response_help = "pets the"
+ response_disarm = "gently moves aside the"
+ response_harm = "swats the"
+
+ ears = new /obj/item/device/radio/headset/heads/ce()
+
+/mob/living/simple_animal/parrot/DrProfessor
+ name = "Doctor Professor Parrot, PhD"
+ desc = "That's the Doctor Professor. He has more degrees than all of the engineering team put together, and has several published papers on quantum cracker theory."
+ speak = list(":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN RIG SUIT?",":e OH GOD ITS FREE CALL THE SHUTTLE")
+ response_harm = "is attacked in the face by"
+
+/obj/item/weapon/reagent_containers/food/snacks/cracker/
+ name = "Cracker"
+ desc = "It's a salted cracker."
+
+/mob/living/simple_animal/parrot/show_inv(mob/user as mob)
+ user.machine = src
+ if(user.stat) return
+
+ var/dat = " Inventory of [name]
"
+ if(ears)
+ dat += "Headset: [ears] (Remove )"
+ else
+ dat += "Headset: Nothing "
+
+ user << browse(dat, text("window=mob[];size=325x500", name))
+ onclose(user, "mob[real_name]")
+ return
+
+
+
+/mob/living/simple_animal/parrot/Topic(href, href_list)
+ if(usr.stat) return
+
+ //Removing from inventory
+ if(href_list["remove_inv"])
+ if(get_dist(src,usr) > 1 || !(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr)))
+ return
+ var/remove_from = href_list["remove_inv"]
+ switch(remove_from)
+ if("ears")
+ if(ears)
+ src.say(":e BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
+ ears.loc = src.loc
+ ears = null
+ else
+ usr << "\red There is nothing to remove from its [remove_from]."
+ return
+
+ //Adding things to inventory
+ else if(href_list["add_inv"])
+ if(get_dist(src,usr) > 1 || !(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr)))
+ return
+ var/add_to = href_list["add_inv"]
+ if(!usr.get_active_hand())
+ usr << "\red You have nothing in your hand to put on its [add_to]."
+ return
+ switch(add_to)
+ if("ears")
+ if(ears)
+ usr << "\red It's already wearing something."
+ return
+ else
+ var/obj/item/item_to_add = usr.get_active_hand()
+ if(!item_to_add)
+ return
+
+ if( !istype(item_to_add, /obj/item/device/radio/headset) )
+ usr << "\red This object won't fit."
+ return
+
+ usr.drop_item()
+ item_to_add.loc = src
+ src.ears = item_to_add
+ else
+ ..()
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 8b20858d69..fdaa37fb57 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -101,13 +101,13 @@
for(var/obj/effect/landmark/start/sloc in world)
if (sloc.name != "AI")
continue
- if (locate(/mob) in sloc.loc)
+ if (locate(/mob/living) in sloc.loc)
continue
loc_landmark = sloc
if (!loc_landmark)
for(var/obj/effect/landmark/tripai in world)
if (tripai.name == "tripai")
- if(locate(/mob) in tripai.loc)
+ if(locate(/mob/living) in tripai.loc)
continue
loc_landmark = tripai
if (!loc_landmark)
@@ -190,7 +190,8 @@
O.invisibility = 0
O.name = "Cyborg"
O.real_name = "Cyborg"
- O.lastKnownIP = client.address ? client.address : null
+ if(client)
+ O.lastKnownIP = client.address ? client.address : null
if (mind)
mind.transfer_to(O)
if (mind.assigned_role == "Cyborg")
@@ -212,6 +213,8 @@
O << "To use something, simply click or double-click it."
O << {"Use say ":s to speak to fellow cyborgs and the AI through binary."}
+ O.verbs += /mob/living/silicon/robot/proc/ai_roster
+
O.job = "Cyborg"
O.mmi = new /obj/item/device/mmi(O)
@@ -335,4 +338,81 @@
new_corgi << "You are now a Corgi!. "
spawn(0)//To prevent the proc from returning null.
del(src)
- return
\ No newline at end of file
+ return
+
+/mob/living/carbon/human/AIizeSilent()
+ if (monkeyizing)
+ return
+ for(var/name in organs)
+ del(organs[name])
+
+ if(client)
+ src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jams for AIs
+ return ..()
+
+/mob/living/carbon/AIizeSilent()
+ if (monkeyizing)
+ return
+ for(var/obj/item/W in src)
+ drop_from_slot(W)
+ update_clothing()
+ monkeyizing = 1
+ canmove = 0
+ icon = null
+ invisibility = 101
+ return ..()
+
+/mob/proc/AIizeSilent()
+ if(client)
+ client.screen.len = null
+ var/mob/living/silicon/ai/O = new (loc, /datum/ai_laws/nanotrasen,,1)//No MMI but safety is in effect.
+ O.invisibility = 0
+ O.aiRestorePowerRoutine = 0
+ O.lastKnownIP = client.address
+
+ if(mind)
+ mind.transfer_to(O)
+ O.mind.original = O
+ else
+ O.mind = new
+ O.mind.current = O
+ O.mind.original = O
+ O.mind.assigned_role = "AI"
+ O.key = key
+
+ if(!(O.mind in ticker.minds))
+ ticker.minds += O.mind//Adds them to regular mind list.
+
+ O << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras). "
+ O << "To look at other parts of the station, double-click yourself to get a camera menu, use the freelook command, or use the Show Camera List command.. "
+ O << "While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc. "
+ O << "To use something, simply click or double-click it."
+ O << "Currently right-click functions will not work for the AI (except examine), and will either be replaced with dialogs or won't be usable by the AI."
+ if (!(ticker && ticker.mode && (O.mind in ticker.mode.malf_ai)))
+ O.show_laws()
+ O << "These laws may be changed by other players, or by you being the traitor. "
+ O << "IMPORTANT GAMEPLAY ASPECTS: "
+ O << "1.) Act like an AI. If someone is breaking into your upload, say something like \"Alert. Unauthorised Access Detected: AI Upload.\" not \"Help! Urist is trying to subvert me!\""
+ O << "2.) Do not watch the traitor like a hawk alerting the station to his/her every move. This relates to 1."
+ O << "3.) You are theoretically omniscient, but you should not be Beepsky 5000, laying down the law left and right. That is security's job. Instead, try to keep the station productive and effective. (Feel free to report the location of major violence and crimes and all that, just do not be the evil thing looking over peoples shoulders)"
+ O << "4.) Your laws are not in preference, laws do not take preference over one another unless specifically stated in the law."
+ O << " We want everyone to have a good time, so we, the admins, will try to correct you if you stray from these rules. Just try to keep it sensible."
+
+
+ O.verbs += /mob/living/silicon/ai/proc/ai_call_shuttle
+ O.verbs += /mob/living/silicon/ai/proc/show_laws_verb
+ O.verbs += /mob/living/silicon/ai/proc/ai_camera_track
+ O.verbs += /mob/living/silicon/ai/proc/ai_alerts
+ O.verbs += /mob/living/silicon/ai/proc/ai_camera_list
+ O.verbs += /mob/living/silicon/ai/proc/ai_statuschange
+ O.verbs += /mob/living/silicon/ai/proc/ai_roster
+
+// O.verbs += /mob/living/silicon/ai/proc/ai_cancel_call
+ O.job = "AI"
+
+ spawn(0)
+ ainame(O)
+
+ del(src)
+
+ return O
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 8ae74bf437..2ec671495d 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -876,18 +876,19 @@
malfai.malfhack = src
malfai.malfhacking = 1
sleep(600)
- if (!src.aidisabled)
- malfai.malfhack = null
- malfai.malfhacking = 0
- if (ticker.mode.config_tag == "malfunction")
- if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas))
- ticker.mode:apcs++
- if(usr:parent)
- src.malfai = usr:parent
- else
- src.malfai = usr
- malfai << "Hack complete. The APC is now under your exclusive control."
- updateicon()
+ if(src)
+ if (!src.aidisabled)
+ malfai.malfhack = null
+ malfai.malfhacking = 0
+ if (ticker.mode.config_tag == "malfunction")
+ if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas))
+ ticker.mode:apcs++
+ if(usr:parent)
+ src.malfai = usr:parent
+ else
+ src.malfai = usr
+ malfai << "Hack complete. The APC is now under your exclusive control."
+ updateicon()
else if (href_list["occupyapc"])
malfoccupy(usr)
@@ -904,21 +905,17 @@
return
if(src.z != 1)
return
-
src.occupant = new /mob/living/silicon/ai(src,malf.laws,null,1)
src.occupant.adjustOxyLoss(malf.getOxyLoss())
- src.occupant.name = "[malf.name] APC Copy"
-
+ if(!findtext(src.occupant.name,"APC Copy"))
+ src.occupant.name = "[malf.name] APC Copy"
if(malf.parent)
src.occupant.parent = malf.parent
else
src.occupant.parent = malf
-
malf.mind.transfer_to(src.occupant)
-
if(malf.parent)
del(malf)
-
src.occupant.verbs += /mob/living/silicon/ai/proc/corereturn
src.occupant.cancel_camera()
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 8ef892942c..dff76971ef 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -109,6 +109,10 @@
if(S.reagents.has_reagent("plasma", 5))
+ log_attack("[user.name] ([user.ckey]) injected a power cell with plasma. ")
+ log_admin("ATTACK: [user] ([user.ckey]) injected a power cell with plasma.")
+ message_admins("ATTACK: [user] ([user.ckey]) injected a power cell with plasma.")
+
rigged = 1
S.reagents.clear_reagents()
diff --git a/code/modules/power/generator_type2.dm b/code/modules/power/generator_type2.dm
index fe80f97416..0ee1ecf082 100644
--- a/code/modules/power/generator_type2.dm
+++ b/code/modules/power/generator_type2.dm
@@ -55,18 +55,16 @@
hot_air.temperature = hot_air.temperature - energy_transfer/hot_air_heat_capacity
cold_air.temperature = cold_air.temperature + heat/cold_air_heat_capacity
- world << "POWER: [lastgen] W generated at [efficiency*100]% efficiency and sinks sizes [cold_air_heat_capacity], [hot_air_heat_capacity]"
-
if(input1.network)
input1.network.update = 1
if(input2.network)
input2.network.update = 1
- add_avail(lastgen)
+ add_avail(lastgen/5)
// update icon overlays only if displayed level has changed
- var/genlev = max(0, min( round(11*lastgen / 100000), 11))
+ var/genlev = max(0, min( round(11*lastgen / 500000), 11))
if(genlev != lastgenlev)
lastgenlev = genlev
updateicon()
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index a94f99506d..3f9cc58154 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -44,7 +44,7 @@
brightness = 3
desc = "A small lighting fixture."
light_type = /obj/item/weapon/light/bulb
-
+
/obj/machinery/light/small/spot
brightness = 5
@@ -532,6 +532,10 @@
if(S.reagents.has_reagent("plasma", 5))
+ log_attack("[user.name] ([user.ckey]) injected a light with plasma. ")
+ log_admin("ATTACK: [user] ([user.ckey]) injected a light with plasma.")
+ message_admins("ATTACK: [user] ([user.ckey]) injected a light with plasma.")
+
rigged = 1
S.reagents.clear_reagents()
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index 22d810a801..c78517f387 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -437,6 +437,8 @@
//source is an object caused electrocuting (airlock, grille, etc)
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/carbon/M as mob, var/power_source, var/obj/source, var/siemens_coeff = 1.0)
+ if(istype(M.loc,/obj/mecha))
+ return 0
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.gloves)
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index 94b761882b..8a4514cfee 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -14,6 +14,7 @@
last_power = 0
active = 0
locked = 0
+ drainratio = 1
process()
if(P)
@@ -21,7 +22,7 @@
P.air_contents.toxins = 0
eject()
else
- P.air_contents.toxins -= 0.001
+ P.air_contents.toxins -= 0.001*drainratio
return
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index af29baf48f..e8ce8d4a36 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -12,12 +12,15 @@
active_power_usage = 300
var
+ frequency = 1
active = 0
fire_delay = 100
last_shot = 0
shot_number = 0
state = 0
locked = 0
+ energy = 0
+ mega_energy = 0
verb/rotate()
diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm
index c6acb29eb5..1377d5934d 100644
--- a/code/modules/power/singularity/field_generator.dm
+++ b/code/modules/power/singularity/field_generator.dm
@@ -76,7 +76,8 @@ field_generator power level display
power = field_generator_max_power
anchored = 1
warming_up = 3
- turn_on()
+ start_fields()
+ update_icon()
Varedit_start = 0
if(src.active == 2)
diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm
index c39941c8aa..a76077f58e 100644
--- a/code/modules/power/singularity/particle_accelerator/particle.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle.dm
@@ -7,8 +7,9 @@
density = 1
var
movement_range = 10
- energy = 10 //energy in eV?
+ energy = 10 //energy in eV
mega_energy = 0 //energy in MeV
+ frequency = 1
ionizing = 0
particle_type
additional_particles = 0
@@ -41,13 +42,15 @@
var/obj/machinery/rust/particle_catcher/collided_catcher = A
if(particle_type && particle_type != "neutron")
if(collided_catcher.AddParticles(particle_type, 1 + additional_particles))
- collided_catcher.AddEnergy(energy,mega_energy)
+ collided_catcher.parent.AddEnergy(energy,mega_energy)
del (src)
if( istype(A,/obj/machinery/rust/core) )
var/obj/machinery/rust/core/collided_core = A
if(particle_type && particle_type != "neutron")
if(collided_core.AddParticles(particle_type, 1 + additional_particles))
- collided_core.AddEnergy(energy,mega_energy)
+ var/energy_loss_ratio = abs(collided_core.owned_field.frequency - frequency) / 1e9
+ collided_core.owned_field.mega_energy += mega_energy - mega_energy * energy_loss_ratio
+ collided_core.owned_field.energy += energy - energy * energy_loss_ratio
del (src)
return
diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm
index e8a0b969b4..adf09a57d2 100644
--- a/code/modules/power/turbine.dm
+++ b/code/modules/power/turbine.dm
@@ -111,14 +111,14 @@
#define TURBGENG 0.8
/obj/machinery/power/turbine/process()
- if(!compressor.starter)
- return
overlays = null
if(stat & BROKEN)
return
if(!compressor)
stat |= BROKEN
return
+ if(!compressor.starter)
+ return
lastgen = ((compressor.rpm / TURBGENQ)**TURBGENG) *TURBGENQ
add_avail(lastgen)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 665012518a..d01356ccf7 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -107,6 +107,11 @@
update_icon()
return
else if(user.a_intent != "hurt" && load_into_chamber() && istype(in_chamber,/obj/item/projectile/energy/electrode)) //Point blank tasering.
+ if (M.canstun == 0 || M.canweaken == 0)
+ user.visible_message("\red [M] has been stunned with the taser gun by [user] to no effect! ")
+ del(in_chamber)
+ update_icon()
+ return
if (prob(50))
if (M.paralysis < 60 && (!(M.mutations & 8)) )
M.paralysis = 60
@@ -189,6 +194,7 @@
in_chamber.original = targloc
in_chamber.loc = get_turf(user)
+ in_chamber.starting = get_turf(user)
user.next_move = world.time + 4
in_chamber.silenced = silenced
in_chamber.current = curloc
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index 2e86e4fea3..2233b41d55 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -1,5 +1,5 @@
/obj/item/weapon/gun/energy/laser
- name = "\improper Laser Gun"
+ name = "laser gun"
desc = "a basic weapon designed kill with concentrated energy bolts"
icon_state = "laser"
item_state = "laser"
@@ -17,7 +17,7 @@
obj/item/weapon/gun/energy/laser/retro
- name ="\improper Retro Laser"
+ name ="retro laser"
icon_state = "retro"
desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws."
@@ -68,9 +68,84 @@ obj/item/weapon/gun/energy/laser/retro
/obj/item/weapon/gun/energy/lasercannon
- name = "\improper Laser Cannon"
+ name = "laser cannon"
desc = "With the L.A.S.E.R. cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!"
icon_state = "lasercannon"
fire_sound = 'lasercannonfire.ogg'
origin_tech = "combat=4;materials=3;powerstorage=3"
projectile_type = "/obj/item/projectile/beam/heavylaser"
+
+
+
+
+
+////////Laser Tag////////////////////
+
+/obj/item/weapon/gun/energy/laser/bluetag
+ name = "laser tag gun"
+ icon_state = "bluetag"
+ desc = "Standard issue weapon of the Imperial Guard"
+ projectile_type = "/obj/item/projectile/bluetag"
+
+ special_check(var/mob/living/carbon/human/M)
+ if(ishuman(M))
+ if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag))
+ return 1
+ M << "\red You need to be wearing your laser tag vest!"
+ return 0
+ var/charge_tick = 0
+
+
+ New()
+ ..()
+ processing_objects.Add(src)
+
+
+ Del()
+ processing_objects.Remove(src)
+ ..()
+
+
+ process()
+ charge_tick++
+ if(charge_tick < 4) return 0
+ charge_tick = 0
+ if(!power_supply) return 0
+ power_supply.give(100)
+ update_icon()
+ return 1
+
+
+
+/obj/item/weapon/gun/energy/laser/redtag
+ name = "laser tag gun"
+ icon_state = "redtag"
+ desc = "Standard issue weapon of the Imperial Guard"
+ projectile_type = "/obj/item/projectile/redtag"
+ var/charge_tick = 0
+
+ special_check(var/mob/living/carbon/human/M)
+ if(ishuman(M))
+ if(istype(M.wear_suit, /obj/item/clothing/suit/redtag))
+ return 1
+ M << "\red You need to be wearing your laser tag vest!"
+ return 0
+
+ New()
+ ..()
+ processing_objects.Add(src)
+
+
+ Del()
+ processing_objects.Remove(src)
+ ..()
+
+
+ process()
+ charge_tick++
+ if(charge_tick < 4) return 0
+ charge_tick = 0
+ if(!power_supply) return 0
+ power_supply.give(100)
+ update_icon()
+ return 1
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm
index 60ce612f9d..09de911802 100644
--- a/code/modules/projectiles/guns/energy/nuclear.dm
+++ b/code/modules/projectiles/guns/energy/nuclear.dm
@@ -1,5 +1,6 @@
/obj/item/weapon/gun/energy/gun
icon_state = "energystun100"
+ item_state = "energystun100"
name = "energy gun"
desc = "A basic energy-based gun with two settings: Stun and kill."
fire_sound = 'Taser.ogg'
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index ba7dd80b51..618e04722e 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -1,8 +1,9 @@
/obj/item/weapon/gun/energy/taser
- name = "\improper Taser Gun"
+ name = "taser gun"
desc = "A small, low capacity gun used for non-lethal takedowns."
icon_state = "taser"
+ item_state = "taser100"
fire_sound = 'Taser.ogg'
charge_cost = 100
projectile_type = "/obj/item/projectile/energy/electrode"
@@ -18,24 +19,44 @@
M << "\red The gun refuses to fire!"
return 0*/// Can be used to restrict weapon use to implants. - Erthilo
-/obj/item/weapon/gun/energy/taser/cyborg/load_into_chamber()//TOOD: change this over to the slowly recharge other cell
- if(in_chamber)
- if(!istype(in_chamber, projectile_type))
- del(in_chamber)
- in_chamber = new projectile_type(src)
- return 1
- if(isrobot(src.loc))
- var/mob/living/silicon/robot/R = src.loc
- if(R && R.cell)
- R.cell.use(charge_cost)
- in_chamber = new /obj/item/projectile/energy/electrode(src)
- return 1
- return 0
+/obj/item/weapon/gun/energy/taser/cyborg
+ name = "taser gun"
+ desc = "A small, low capacity gun used for non-lethal takedowns."
+ icon_state = "taser"
+ fire_sound = 'Taser.ogg'
+ charge_cost = 100
+ projectile_type = "/obj/item/projectile/energy/electrode"
+ cell_type = "/obj/item/weapon/cell/secborg"
+ var/charge_tick = 0
+ var/recharge_time = 10 //Time it takes for shots to recharge (in seconds)
+ New()
+ ..()
+ processing_objects.Add(src)
+
+
+ Del()
+ processing_objects.Remove(src)
+ ..()
+
+ process() //Every [recharge_time] seconds, recharge a shot for the cyborg
+ charge_tick++
+ if(charge_tick < recharge_time) return 0
+ charge_tick = 0
+
+ if(!power_supply) return 0 //sanity
+ if(isrobot(src.loc))
+ var/mob/living/silicon/robot/R = src.loc
+ if(R && R.cell)
+ R.cell.use(charge_cost) //Take power from the borg...
+ power_supply.give(charge_cost) //... to recharge the shot
+
+ update_icon()
+ return 1
/obj/item/weapon/gun/energy/stunrevolver
- name = "\improper Stun Revolver"
+ name = "stun revolver"
desc = "A high-tech revolver that fires stun cartridges. The stun cartridges can be recharged using a conventional energy weapon recharger."
icon_state = "stunrevolver"
fire_sound = 'Gunshot.ogg'
@@ -47,7 +68,7 @@
/obj/item/weapon/gun/energy/crossbow
- name = "\improper Mini Energy-Crossbow"
+ name = "mini energy-crossbow"
desc = "A weapon favored by many of the syndicates stealth specialists."
icon_state = "crossbow"
w_class = 2.0
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 46f415ac51..ebfd27c485 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -27,7 +27,8 @@
yo = null
xo = null
current = null
- turf/original = null
+ turf/original = null // the original turf clicked
+ turf/starting = null // the projectile's starting turf
p_x = 16
p_y = 16 // the pixel location of the tile that the player clicked. Default is the center
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index d9606bcd98..0c45c0bf38 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -1,11 +1,12 @@
/obj/item/projectile/beam
- name = "\improper Laser"
+ name = "laser"
icon_state = "laser"
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
damage = 40
damage_type = BURN
flag = "laser"
eyeblur = 4
+ var/frequency = 1
var/ID = 0
var/main = 0
@@ -56,20 +57,21 @@
flag = "laser"
eyeblur = 2
+
/obj/item/projectile/beam/heavylaser
- name = "\improper Heavy Laser"
+ name = "heavy laser"
icon_state = "heavylaser"
damage = 60
/obj/item/projectile/beam/pulse
- name = "\improper Pulse"
+ name = "pulse"
icon_state = "u_laser"
damage = 40
/obj/item/projectile/beam/deathlaser
- name = "\improper Death Laser"
+ name = "death laser"
icon_state = "heavylaser"
damage = 60
@@ -79,4 +81,32 @@
+/obj/item/projectile/bluetag
+ name = "lasertag beam"
+ icon_state = "ice_2"
+ pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
+ damage = 0
+ damage_type = BURN
+ flag = "laser"
+ on_hit(var/atom/target, var/blocked = 0)
+ if(istype(target, /mob/living/carbon/human))
+ var/mob/living/carbon/human/M = target
+ if(istype(M.wear_suit, /obj/item/clothing/suit/redtag))
+ M.Weaken(5)
+ return 1
+
+/obj/item/projectile/redtag
+ name = "lasertag beam"
+ icon_state = "laser"
+ pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
+ damage = 0
+ damage_type = BURN
+ flag = "laser"
+
+ on_hit(var/atom/target, var/blocked = 0)
+ if(istype(target, /mob/living/carbon/human))
+ var/mob/living/carbon/human/M = target
+ if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag))
+ M.Weaken(5)
+ return 1
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index c8ead597ef..7821b66cd7 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -1,5 +1,5 @@
/obj/item/projectile/ion
- name = "\improper Ion Bolt"
+ name = "ion bolt"
icon_state = "ion"
damage = 0
damage_type = BURN
@@ -13,7 +13,7 @@
/obj/item/projectile/bullet/gyro
- name ="\improper Rocket"
+ name ="explosive bolt"
icon_state= "bolter"
damage = 50
flag = "bullet"
@@ -24,7 +24,7 @@
return 1
/obj/item/projectile/temp
- name = "\improper Freeze Beam"
+ name = "freeze beam"
icon_state = "ice_2"
damage = 0
damage_type = BURN
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index 027e9afeca..390ea18c29 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -511,7 +511,7 @@
for (var/mob/V in viewers(usr))
V.show_message("[user] dunks [GM.name] into the toilet!", 3)
if(do_after(user, 30))
- if(G.state>1&&!GM.internal)
+ if(G && G.state>1 && !GM.internal)
GM.oxyloss += 5
else if(I.w_class < 4)
@@ -595,6 +595,7 @@
var/count = 1000 //*** can travel 1000 steps before going to the mail room (in case of loops)
var/destinationTag = null // changes if contains a delivery container
var/tomail = 0 //changes if contains wrapped package
+ var/hasmob = 0 //If it contains a mob
// initialize a holder from the contents of a disposal unit
@@ -602,6 +603,20 @@
if(!istype(D, /obj/machinery/disposal/toilet))//So it does not drain gas from a toilet which does not function on it.
gas = D.air_contents// transfer gas resv. into holder object
+ //Check for any living mobs trigger hasmob.
+ //hasmob effects whether the package goes to cargo or its tagged destination.
+ for(var/mob/living/M in D)
+ if(M && M.stat != 2)
+ hasmob = 1
+
+ //Checks 1 contents level deep. This means that players can be sent through disposals...
+ //...but it should require a second person to open the package. (i.e. person inside a wrapped locker)
+ for(var/obj/O in D)
+ if(O.contents)
+ for(var/mob/living/M in O.contents)
+ if(M && M.stat != 2)
+ hasmob = 1
+
// now everything inside the disposal gets put into the holder
// note AM since can contain mobs or objs
for(var/atom/movable/AM in D)
@@ -611,10 +626,10 @@
if(H.mutations & FAT) // is a human and fat?
has_fat_guy = 1 // set flag on holder
*/
- if(istype(AM, /obj/structure/bigDelivery))
+ if(istype(AM, /obj/structure/bigDelivery))// && !hasmob) Already have a check for this.
var/obj/structure/bigDelivery/T = AM
src.destinationTag = T.sortTag
- else if(istype(AM, /obj/item/smallDelivery))
+ if(istype(AM, /obj/item/smallDelivery))// && !hasmob) And that. DMTG
var/obj/item/smallDelivery/T = AM
src.destinationTag = T.sortTag
else if (!src.destinationTag)
diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm
index a53883d511..d57c2404dc 100755
--- a/code/modules/recycling/sortingmachinery.dm
+++ b/code/modules/recycling/sortingmachinery.dm
@@ -2,7 +2,7 @@
desc = "A big wrapped package."
name = "large parcel"
icon = 'storage.dmi'
- icon_state = "deliverycrate"
+ icon_state = "deliverycloset"
var/tmp/obj/wrapped = null
density = 1
var/sortTag = null
@@ -18,10 +18,10 @@
return unwrap()
proc/unwrap()
- if (src.wrapped) //sometimes items can disappear. For example, bombs. --rastaf0
- src.wrapped.loc = (get_turf(src.loc))
- if (istype(src.wrapped,/obj/structure/closet))
- var/obj/structure/closet/O = src.wrapped
+ if(wrapped) //sometimes items can disappear. For example, bombs. --rastaf0
+ wrapped.loc = (get_turf(src.loc))
+ if(istype(wrapped, /obj/structure/closet))
+ var/obj/structure/closet/O = wrapped
O.welded = waswelded
del(src)
return
@@ -172,9 +172,9 @@
afterattack(var/obj/target as obj, mob/user as mob)
- if(istype(target, /obj/structure/table) || istype(target, /obj/structure/rack) || istype(target,/obj/item/smallDelivery))
+ if(!(istype(target, /obj))) //this really shouldn't be necessary (but it is). -Pete
return
- if(!istype(target,/obj))
+ if(istype(target, /obj/structure/table) || istype(target, /obj/structure/rack) || istype(target,/obj/item/smallDelivery))
return
if(target.anchored)
return
@@ -197,10 +197,11 @@
var/obj/structure/closet/crate/O = target
if (src.amount > 3 && !O.opened)
var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc))
+ P.icon_state = "deliverycrate"
P.wrapped = O
O.loc = P
src.amount -= 3
- else if(src.amount > 3)
+ else if(src.amount < 3)
user << "\blue You need more paper."
else if (istype (target, /obj/structure/closet))
var/obj/structure/closet/O = target
@@ -208,17 +209,15 @@
var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc))
P.wrapped = O
P.waswelded = O.welded
- O.opened = 0
O.welded = 1
O.loc = P
src.amount -= 3
- else if(src.amount > 3)
+ else if(src.amount < 3)
user << "\blue You need more paper."
else
user << "\blue The object you are trying to wrap is unsuitable for the sorting machinery!"
if (src.amount <= 0)
new /obj/item/weapon/c_tube( src.loc )
- //SN src = null
del(src)
return
return
diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm
index 721c5f00f7..d4c5de435f 100644
--- a/code/modules/research/message_server.dm
+++ b/code/modules/research/message_server.dm
@@ -54,6 +54,16 @@
var/list/datum/data_pda_msg/pda_msgs = list()
var/list/datum/data_rc_msg/rc_msgs = list()
+ var/active = 1
+
+/obj/machinery/message_server/process()
+ if((stat & (BROKEN|NOPOWER)) && active)
+ active = 0
+ return
+
+ update_icon()
+ return
+
/obj/machinery/message_server/proc/send_pda_message(var/recipient = "",var/sender = "",var/message = "")
pda_msgs += new/datum/data_pda_msg(recipient,sender,message)
@@ -61,8 +71,22 @@
rc_msgs += new/datum/data_rc_msg(recipient,sender,message,stamp,id_auth)
/obj/machinery/message_server/attack_hand(user as mob)
- user << "\blue There seem to be some parts missing from this server. They should arrive on the station in a few days, give or take a few CentCom delays."
+// user << "\blue There seem to be some parts missing from this server. They should arrive on the station in a few days, give or take a few CentCom delays."
+ user << "You toggle PDA message passing from [active ? "On" : "Off"] to [active ? "Off" : "On"]"
+ active = !active
+ update_icon()
+ return
+
+/obj/machinery/message_server/update_icon()
+ if((stat & (BROKEN|NOPOWER)))
+ icon_state = "server-nopower"
+ else if (!active)
+ icon_state = "server-off"
+ else
+ icon_state = "server-on"
+
+ return
/datum/feedback_variable
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index 0e2f65afe4..a309ea13b3 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -277,6 +277,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
if(!linked_destroy.hacked)
if(!linked_destroy.loaded_item)
usr <<"\red The destructive analyzer appears to be empty."
+ screen = 1.0
return
if(linked_destroy.loaded_item.reliability >= 90)
var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech)
diff --git a/code/setup.dm b/code/setup.dm
index 3d174db55f..77356bd1a5 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -1,3 +1,5 @@
+#define PI 3.1415
+
#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol)
#define ONE_ATMOSPHERE 101.325 //kPa
@@ -281,3 +283,9 @@ var/static/list/scarySounds = list('thudswoosh.ogg','Taser.ogg','armbomb.ogg','h
#define SEC_LEVEL_BLUE 1
#define SEC_LEVEL_RED 2
#define SEC_LEVEL_DELTA 3
+
+#define TRANSITIONEDGE 7 //Distance from edge to move to another z-level
+
+// Maximum and minimum character ages.
+var/const/minimum_age = 20
+var/const/maximum_age = 65
diff --git a/code/unused/_debug.dm b/code/unused/_debug.dm
index b9cbcdf430..ced557f197 100644
--- a/code/unused/_debug.dm
+++ b/code/unused/_debug.dm
@@ -615,3 +615,5 @@ Doing this because FindTurfs() isn't even used
playsound(pt.loc, 'explosionfar.ogg', 100, 1,10)
pt.gas.temperature = 500+T0C
pt.ignite()
+
+
diff --git a/code/unused/computer2/med_rec.dm b/code/unused/computer2/med_rec.dm
index 8cb06a40c2..c4a4e2245d 100644
--- a/code/unused/computer2/med_rec.dm
+++ b/code/unused/computer2/med_rec.dm
@@ -409,7 +409,7 @@
var/counter = 1
while(src.active2.fields[text("com_[]", counter)])
counter++
- src.active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2053 []", src.authenticated, src.rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1)
+ src.active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2556 []", src.authenticated, src.rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1)
if (href_list["del_c"])
if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])]))
diff --git a/config/admins.txt b/config/admins.txt
index 4cb2a0656c..36852c83b3 100644
--- a/config/admins.txt
+++ b/config/admins.txt
@@ -1,12 +1,13 @@
-abi79 - Game Master
+abi79 - Retired Admin
arcalane - Game Admin
bobbehluvspropane - Game Admin
cacophony - Game Admin
cajoes - Game Admin
cib - Game Master
compactninja - Game Master
+desiderium - Game Admin
dysthymia - Retired Admin
-doughnuts - Trial Admin
+doughnuts - Game Admin
erthilo - Game Admin
hawkv3 - Game Master
headswe - Game Master
@@ -16,7 +17,7 @@ megacaesar - Game Admin
miniature - Game Master
misterfox - Game Admin
mloc - Game Master
-ridley4 - Trial Admin
+ridley4 - Game Admin
skymarshal - Game Master
spaceman96 - Game Admin
strumpetplaya - Retired Admin
diff --git a/config/config.txt b/config/config.txt
index 94468b193e..c5c4c3fc14 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -78,6 +78,12 @@ TRAITOR_SCALING
## If security is prohibited from being most antagonists
#PROTECT_ROLES_FROM_ANTAGONIST
+## If the auto-tensioner is active by default. It creates more tratiors/other antagonists if it consideers the round slowing down.
+#TENSIONER_ACTIVE
+
+## If metadata is supported
+# ALLOW_METADATA
+
## allow players to initiate a restart vote
ALLOW_VOTE_RESTART
@@ -101,7 +107,7 @@ ALLOW_AI
## disable abandon mob
-NORESPAWN
+# NORESPAWN
## disables calling del(src) on newmobs if they logout before spawnin in
# DONT_DEL_NEWMOB
diff --git a/config/custom_items.txt b/config/custom_items.txt
index 1b79e2ee93..b5c1ac1040 100644
--- a/config/custom_items.txt
+++ b/config/custom_items.txt
@@ -1,9 +1,9 @@
-spaceman96: Trenna Seber: /obj/item/weapon/pen/multi, /obj/item/clothing/suit/storage/labcoat/pink
+spaceman96: Trenna Seber: /obj/item/weapon/pen/fluff/multi, /obj/item/clothing/suit/storage/labcoat/fluff/pink
asanadas: Book Berner: /obj/item/clothing/under/chameleon/psyche, /obj/item/clothing/glasses/meson/fluff/book_berner_1
tastyfish: Cindy Robertson: /obj/item/weapon/wrapping_paper
eternal248: Maximilian Haynes: /obj/item/weapon/paper/certificate
-searif: Yuki Matsuda: /obj/item/weapon/paper/certificate, /obj/item/clothing/under/jumpsuitdown
-erthilo: Farah Lants: /obj/item/clothing/under/rank/medical_sleeve, /obj/item/clothing/suit/storage/labcoat/red, /obj/item/weapon/storage/backpack/medicalsatchel
+searif: Yuki Matsuda: /obj/item/weapon/paper/certificate, /obj/item/clothing/under/fluff/jumpsuitdown
+erthilo: Farah Lants: /obj/item/clothing/under/rank/medical/fluff/short, /obj/item/clothing/suit/storage/labcoat/fluff/red
compactninja: Ysyr Rylias: /obj/item/weapon/reagent_containers/food/drinks/dry_ramen, /obj/item/weapon/reagent_containers/food/drinks/dry_ramen, /obj/item/weapon/reagent_containers/food/drinks/dry_ramen, /obj/item/weapon/reagent_containers/food/drinks/dry_ramen
tzefa: Wes Solari: /obj/item/fluff/wes_solari_1
misterfox: Rashid Siraj: /obj/item/weapon/storage/bible/tajaran
@@ -12,5 +12,13 @@ fniff: Sarah Calvera: /obj/item/fluff/sarah_calvera_1
fniff: Angleo Wilkerson: /obj/item/fluff/angelo_wilkerson_1
gvazdas: Sarah Carbrokes: /obj/item/fluff/sarah_carbrokes_1
serithi: Serithi Artalis: /obj/item/clothing/glasses/fluff/serithi_artalis_1
-deusdactyl: Greg Anderson: /obj/item/clothing/head/fluff/greg_anderson_1
-whitellama: Ethan Way: /obj/item/fluff/ethan_way_1
\ No newline at end of file
+deusdactyl: Greg Anderson: /obj/item/clothing/head/helmet/hardhat/fluff/greg_anderson_1
+whitellama: Ethan Way: /obj/item/fluff/ethan_way_1
+morrinn: Maye Day: /obj/item/weapon/storage/fluff/maye_daye_1
+lexusjjss: Lexus Langg: /obj/item/weapon/clipboard/fluff/smallnote
+lexusjjss: Zachary Tomlinson: /obj/item/weapon/clipboard/fluff/smallnote
+orangebottle: Lillian Levett: /obj/item/weapon/pen/fluff/fancypen
+orangebottle: Lilliana Reade: /obj/item/weapon/pen/fluff/fancypen
+deusdactyl: Roger Wiles: /obj/item/clothing/under/rank/virologist/fluff/cdc_jumpsuit, /obj/item/clothing/suit/storage/labcoat/fluff/cdc_labcoat
+desiderium: Momiji Inubashiri: /obj/item/clothing/under/fluff/olddressuniform
+leonheart11: Johann Erzatz: /obj/item/weapon/reagent_containers/food/drinks/flask/fluff/johann_erzatz_1
\ No newline at end of file
diff --git a/html/archivedchangelog.html b/html/archivedchangelog.html
new file mode 100644
index 0000000000..6c80d65c64
--- /dev/null
+++ b/html/archivedchangelog.html
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/html/bug-minus.png b/html/bug-minus.png
new file mode 100644
index 0000000000..9934db406b
Binary files /dev/null and b/html/bug-minus.png differ
diff --git a/html/burn-exclamation.png b/html/burn-exclamation.png
new file mode 100644
index 0000000000..b2a4f670a8
Binary files /dev/null and b/html/burn-exclamation.png differ
diff --git a/html/changelog.css b/html/changelog.css
new file mode 100644
index 0000000000..a287f98c57
--- /dev/null
+++ b/html/changelog.css
@@ -0,0 +1,35 @@
+.top{font-family:Tahoma,sans-serif;font-size:12px;}
+h2{font-family:Tahoma,sans-serif;}
+a img {border:none;}
+.bgimages16 li {
+ padding:2px 10px 2px 30px;
+ background-position:6px center;
+ background-repeat:no-repeat;
+ border:1px solid #ddd;
+ border-left:4px solid #999;
+ margin-bottom:2px;
+}
+.bugfix {background-image:url(bug-minus.png)}
+.wip {background-image:url(hard-hat-exclamation.png)}
+.tweak {background-image:url(wrench-screwdriver.png)}
+.soundadd {background-image:url(music-plus.png)}
+.sounddel {background-image:url(music-minus.png)}
+.rscdel {background-image:url(cross-circle.png)}
+.rscadd {background-image:url(tick-circle.png)}
+.imageadd {background-image:url(image-plus.png)}
+.imagedel {background-image:url(image-minus.png)}
+.spellcheck {background-image:url(spell-check.png)}
+.experiment {background-image:url(burn-exclamation.png)}
+.sansserif {font-family:Tahoma,sans-serif;font-size:12px;}
+.commit {margin-bottom:20px;font-size:100%;font-weight:normal;}
+.changes {list-style:none;margin:5px 0;padding:0 0 0 25px;font-size:0.8em;}
+.date {margin:10px 0;color:blue;border-bottom:2px solid #00f;width:60%;padding:2px 0;font-size:1em;font-weight:bold;}
+.author {padding-left:10px;margin:0;font-weight:bold;font-size:0.9em;}
+.drop {cursor:pointer;border:1px solid #999;display:inline;font-size:0.9em;padding:1px 20px 1px 5px;line-height:16px;}
+.hidden {display:none;}
+.indrop {margin:2px 0 0 0;clear:both;background:#fff;border:1px solid #ddd;padding:5px 10px;}
+.indrop p {margin:0;font-size:0.8em;line-height:16px;margin:1px 0;}
+.indrop img {margin-right:5px;vertical-align:middle;}
+.closed {background:url(chevron-expand.png) right center no-repeat;}
+.open {background:url(chevron.png) right center no-repeat;}
+.lic {font-size:9px;}
\ No newline at end of file
diff --git a/html/changelog.html b/html/changelog.html
index 4d2044e54b..bff322db99 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -1,11 +1,10 @@
-
-
+
+
- Baystation 12
-
+ Baystation 12 Changelog
+
-
+
+
+
+
+
-Baystation 12
-
+
-Read the player guidelines!
+
-Github change history
+
-
+
+
+
2nd May 2012
+
TG updated:
+
+ Added carved pumpkins/jackolanterns. Carve them with any of the usual things you use to carve things. They work similarly to hardhats.
+ Added pumpkin pie and slices. Made with 5 milk, 5 sugar, 1 pumpkin, 1 flour, 1 egg.
+ Eating corn now makes corn cobs. Carve them with a saw, a knife, or a hatchet to make a corncob pipe.
+ Added the bit of transparency to biohelmets that they were always supposed to have.
+ Adds randomlly spawning rooms to the mining asteroid that contain various goodies.
+ Adds a borg upgrade system. Can be used to reset modules or 'restart' dead cyborgs.
+ Officers can now use huds to modify humans' criminal statuses on the go. To do this, simply examine a human and at the end should be a clickable link to change the status.
+ Cell charger and Recharger are now wrenchable to make them moveable
+ Cats and Dogs can see in the dark.
+ Changed around a few access levels; only jobs who need to do maintenance have access to maintenance tunnels. Also the heads and detective.
+ Shuttle call/recall announcements are now more noticeable.
+ Changes changling unstun time to 45 from 25
+ Can now repair the first stage of deconstruction of rwalls with metal rods.
+ Library machine now has a delay when printing bibles to prevent spam.
+ Bugfix to the 'resist' button, unless I don't understand how it works. I don't see how it could have ever worked before.
+ You can no longer toggle the welding helmet when stunned or restrained.
+ Fix for not being able to use pills as pill-satchels properly.
+
+
Erthilo updated:
+
+ Increases time between random events happening in low population round to a maximum of double. Random events are more likely to happen up to a limit of around 30 active players. Events now fire at the same rate as previously with around 20~ active players. Please report unusually high or low amounts of events on the bug tracker!
+
+
-/tg/station13 Development Team:
-Coders: TLE, NEO, Errorage, muskets, veryinky, Skie, Noise, Numbers, Agouri, Noka, Urist McDorf, Uhangi, Darem, Mport, rastaf0, Doohl, Superxpdude, Rockdtben, ConstantA, Petethegoat, Kor
-Spriters: Agouri, Cheridan, Cruazy Guest, Deeaych, Deuryn, Matty406, Microwave, ShiftyEyesShady, Skie, Uhangi, Veyveyr, Petethegoat, Kor
-Sounds: Skie, Lasty
+
+
1st May 2012
+
Mloc updated:
+
+ Added extra data to ID cards. Fingerprint, blood type, and DNA. Can all be changed in ID computer.
+
+
Erthilo updated:
+
+ You can now respawn after 30 minutes in any mode where the win/loss condition is not all crew dead.
+ New in-hand sprites for energy and taser guns courtesy of Flashkirby99.
+ Fixes emagging doors.
+ NT has recently upgraded their anti-telepathy double glazing. As such, you can no longer remote view people on any level except the station or the mining asteroid!
+ As a side effect of the above, remote viewing and telekinesis cannot be used at the same time.
+
+
+
+
+
30th April 2012
+
Mloc updated:
+
+ Due to new NT hiring protocols, characters can now only be between the ages of 20-65 instead of 15-45.
+
+
Erthilo updated:
+
+ Switched to /tg/'s changelog format! Previous updates can be found here: http://baystation12.net/wiki/index.php/Changelog
+ New green alt satchel for Botanists.
+ Cyborgs can now view crew manifest and also state laws.
+ New ATM sprites.
+ Changes year to 2556 on medical/security records.
+
+
TG updated:
+
+ The escape shuttle will now spend two minutes travelling to CentCom, woo! Objectives are only complete when the shuttle reaches CentCom, and anyone leaving the shuttle during transit time will be lost in deep space! Also, anyone standing in the way of the shuttle when it arrives will be gibbed.
+ Added Antimov module. Very dangerous.
+ Pill bottles now work like ore satchels, click a tile full of pills to pick them all up.
+ Tower caps can now grow randomly as weeds
+ Using a minihoe on a Hydroponics tray removes all the weeds in the tray at once. Using a bucket on a sink now fills it entirely with water, instead of 10 units at a time.
+ You can no longer take photos of photos.
+ Malf AI's hopping between APCs no longer become longer and longer.
+ Secborgs now have modified tasers, it holds 6 shots and recharges one shot every 10 seconds automatically.
+ Turning off PANIC SYPHON now sets scrubbers to scrubbing (default) instead of off. Vents will not appear in the list instead of a timeout message. They also have a link with sets them back to one atmosphere kPa.
+ You now click on AI modules in-hand to set them, instead of just picking them up.
+ Fixes the way the safeguard module is written.
+
+
+
+
+
TG
+
29th April 2012 updated:
+
+ Added new sprites for Killer Tomatoes.
+ Added lasertag vests, guns, projectiles. Sprites for the vests and guns from Muncher. Not actually mapped in. Lasertag guns are only usable if you're wearing the appropriate team vest. Lasertag projectiles will only stun people who are wearing vests belonging to the opposing team.
+ Adds Holodeck, also not mapped in.
+ Janitor borgs have been massively upgraded. They now clean as they move around.
+ Mining shuttle now shunts people where it wants to be. Shuttles now crush people if they fail to move out of where they want to be with the initial shunt.
+ Adds Halloss (Hallucination Damage) as a damage type weapons can do. Halloss can be healed by sleeping.
+ Windows can only be damaged by weapons that do brute or burn.
+ HUD damage indicator now updates with halloss. Inspecting yourself for organ damage now randomly shows damaged organs if you have halloss.
+ Nuke disk now respawns in all rounds.
+ Pinpointers now show the remaining time until a nuke goes off if it's been armed when examined.
+ Instead of z-level transition happening when you reach the edge of the map, it will now happen 7 tiles away from the edge. This means that you will no longer see the black edge, transition will likely happen without you even noticing.
+ Slight changes to examine messages. You cannot examine when blind/unconscious.
+ More new locker sprites!
+ Fixes glass knock sound having a pop at the end of it.
+ Telecomm traffic control now has its own circuitboard and doesn't transform into a server when the monitor is disconnected/reconnected.
+ Using an igniter on a flamethrower that already has one attached no longer uses up the igniter.
+ NTSL bugfixes.
+
+
-
-GoonStation 13 Development Team
- Coders: Stuntwaffle, Showtime, Pantaloons, Nannek, Keelin, Exadv1, hobnob, Justicefries, 0staf, sniperchance, AngriestIBM, BrianOBlivion
- Spriters: Supernorn, Haruhi, Stuntwaffle, Pantaloons, Rho, SynthOrange, I Said No
-
+
-Except where otherwise noted, Goon Station 13 is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License . Rights are currently extended to SomethingAwful Goons only.
-
+/tg/ station 13 Development Team
+
+
+
+ Coders: TLE, NEO, Errorage, muskets, veryinky, Skie, Noise, Numbers, Agouri, Noka, Urist McDorf, Uhangi, Darem, Mport, rastaf0, Doohl, Superxpdude, Rockdtben, ConstantA, Petethegoat, Kor, Polymorph, Carn, Nodrak, Donkie
+ Spriters: Agouri, Cheridan, Cruazy Guest, Deeaych, Deuryn, Matty406, Microwave, ShiftyEyesShady, Skie, Uhangi, Veyveyr, Petethegoat, Kor, Ricotez, Ausops, TankNut
+ Sounds: Skie, Lasty/Vinyl
+ Thanks to: CDK Station devs, GoonStation devs, the original SpaceStation developers and Invisty for the title image
+
+
+
+
+GoonStation 13 Development Team
+
+ Coders: Stuntwaffle, Showtime, Pantaloons, Nannek, Keelin, Exadv1, hobnob, Justicefries, 0staf, sniperchance, AngriestIBM, BrianOBlivion
+ Spriters: Supernorn, Haruhi, Stuntwaffle, Pantaloons, Rho, SynthOrange, I Said No
+
+
-
+