diff --git a/.travis.yml b/.travis.yml
index 75d81c0645..cea5f854c9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ env:
global:
- BASENAME="vorestation" # $BASENAME.dmb, $BASENAME.dme, etc.
- BYOND_MAJOR="513"
- - BYOND_MINOR="1513"
+ - BYOND_MINOR="1520"
- MACRO_COUNT=4
cache:
diff --git a/ATTRIBUTIONS.md b/ATTRIBUTIONS.md
new file mode 100644
index 0000000000..de1166543f
--- /dev/null
+++ b/ATTRIBUTIONS.md
@@ -0,0 +1,39 @@
+**File:** `maps/tether/submaps/om_ships/aro2.dmi`
+**Creator:** Nia Tahl, deriv by Aronai.
+**License:** [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)
+**URL:** [Forum Thread](http://fractalsoftworks.com/forum/index.php?topic=14935.0)
+**Notes:** Permission to use assets also given in writing.
+
+**File:** `maps/tether/submaps/om_ships/cruiser.dmi`
+**Creator:** Gwyvern & Tartiflette
+**License:** [CC BY-NC-SA (Unspecified Version)](https://creativecommons.org/licenses/by-nc-sa/4.0/)
+**URL:** [Forum Thread](http://fractalsoftworks.com/forum/index.php?topic=13667.0)
+**Notes:** Permission to use assets also given in writing.
+
+**File:** `icons/mecha/fighters64x64.dmi`
+**Icon-States:** `baron`, derivs by Aronai.
+**Creator:** Gwyvern & Tartiflette
+**License:** [CC BY-NC-SA (Unspecified Version)](https://creativecommons.org/licenses/by-nc-sa/4.0/)
+**URL:** [Forum Thread](http://fractalsoftworks.com/forum/index.php?topic=13667.0)
+**Notes:** Permission to use assets also given in writing.
+
+**File:** `icons/mecha/fighters64x64.dmi`
+**Icon-States:** `pinnace`, derivs by Aronai.
+**Creator:** Tartiflette
+**License:** [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)
+**URL:** [Forum Thread](http://fractalsoftworks.com/forum/index.php?topic=17856.0)
+**Notes:** Permission to use assets also given in writing.
+
+**File:** `icons/mecha/fighters64x64.dmi`
+**Icon-States:** `allure`, derivs by Aronai.
+**Creator:** Tartiflette
+**License:** [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)
+**URL:** [Forum Thread](http://fractalsoftworks.com/forum/index.php?topic=11646.0)
+**Notes:** Permission to use assets also given in writing.
+
+**File:** `icons/mecha/fighters64x64.dmi`
+**Icon-States:** `scoralis`, derivs by Aronai.
+**Creator:** Nia Tahl
+**License:** [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)
+**URL:** [Forum Thread](http://fractalsoftworks.com/forum/index.php?topic=14935.0)
+**Notes:** Permission to use assets also given in writing.
diff --git a/README.md b/README.md
index f60ad141eb..7fb49ca3dd 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,8 @@ Creative Commons 3.0 BY-NC-SA license
All assets including icons and sound are under a [CC BY-SA 3.0](http://creativecommons.org/licenses/by-sa/3.0/) license unless otherwise indicated.
+Attributions and other licenses with links to original works are noted in [ATTRIBUTIONS.md](./ATTRIBUTIONS.md).
+
### GETTING THE CODE
The simplest way to obtain the code is using the github .zip feature. If you do this, you won't be able to make a Pull Request later, though. You'll need to use the git method.
diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm
index 809cc987eb..86a87223eb 100644
--- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm
@@ -200,8 +200,9 @@
set_frequency(frequency)
/obj/machinery/atmospherics/binary/dp_vent_pump/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W")
+ . = ..()
+ if(Adjacent(user))
+ . += "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W"
/obj/machinery/atmospherics/unary/vent_pump/power_change()
diff --git a/code/ATMOSPHERICS/components/shutoff.dm b/code/ATMOSPHERICS/components/shutoff.dm
index 87d2698841..d7d8076214 100644
--- a/code/ATMOSPHERICS/components/shutoff.dm
+++ b/code/ATMOSPHERICS/components/shutoff.dm
@@ -15,8 +15,8 @@ GLOBAL_LIST_EMPTY(shutoff_valves)
icon_state = "vclamp[open]"
/obj/machinery/atmospherics/valve/shutoff/examine(var/mob/user)
- ..()
- to_chat(user, "The automatic shutoff circuit is [close_on_leaks ? "enabled" : "disabled"].")
+ . = ..()
+ . += "The automatic shutoff circuit is [close_on_leaks ? "enabled" : "disabled"]."
/obj/machinery/atmospherics/valve/shutoff/Initialize()
. = ..()
diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
index 21e1a34d33..bde060a11a 100755
--- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
@@ -185,7 +185,7 @@
var/new_flow_rate = input(usr,"Enter new flow rate (0-[air1.volume]L/s)","Flow Rate Control",src.set_flow_rate) as num
src.set_flow_rate = max(0, min(air1.volume, new_flow_rate))
if(href_list["power"])
- use_power=!use_power
+ update_use_power(!use_power)
src.update_icon()
src.updateUsrDialog()
/*
diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm
index f665ba987a..b4c1e30fba 100644
--- a/code/ATMOSPHERICS/components/unary/cold_sink.dm
+++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm
@@ -178,6 +178,6 @@
..()
/obj/machinery/atmospherics/unary/freezer/examine(mob/user)
- ..(user)
+ . = ..()
if(panel_open)
- to_chat(user, "The maintenance hatch is open.")
+ . += "The maintenance hatch is open."
diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm
index 7fbe881891..3537082ada 100644
--- a/code/ATMOSPHERICS/components/unary/heat_source.dm
+++ b/code/ATMOSPHERICS/components/unary/heat_source.dm
@@ -165,6 +165,6 @@
..()
/obj/machinery/atmospherics/unary/heater/examine(mob/user)
- ..(user)
+ ..()
if(panel_open)
- to_chat(user, "The maintenance hatch is open.")
+ . += "The maintenance hatch is open."
diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm
index 5b0fd20efb..e687eac639 100644
--- a/code/ATMOSPHERICS/components/unary/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm
@@ -47,7 +47,7 @@
var/radio_filter_out
var/radio_filter_in
- var/datum/looping_sound/air_pump/soundloop //Yawn Edit
+ var/datum/looping_sound/air_pump/soundloop
/obj/machinery/atmospherics/unary/vent_pump/on
use_power = USE_POWER_IDLE
@@ -77,7 +77,7 @@
/obj/machinery/atmospherics/unary/vent_pump/Initialize()
. = ..()
- soundloop = new(list(src), FALSE) //Yawn Edit
+ soundloop = new(list(src), FALSE)
/obj/machinery/atmospherics/unary/vent_pump/New()
..()
@@ -95,7 +95,7 @@
if(initial_loc)
initial_loc.air_vent_info -= id_tag
initial_loc.air_vent_names -= id_tag
- QDEL_NULL(soundloop) //Yawn Edit
+ QDEL_NULL(soundloop)
return ..()
/obj/machinery/atmospherics/unary/vent_pump/high_volume
@@ -181,15 +181,15 @@
/obj/machinery/atmospherics/unary/vent_pump/proc/can_pump()
if(stat & (NOPOWER|BROKEN))
- soundloop.stop() //Yawn Edit
+ soundloop.stop()
return 0
if(!use_power)
- soundloop.stop() //Yawn Edit
+ soundloop.stop()
return 0
if(welded)
- soundloop.stop() //Yawn Edit
+ soundloop.stop()
return 0
- soundloop.start() //Yawn Edit
+ soundloop.start()
return 1
/obj/machinery/atmospherics/unary/vent_pump/process()
@@ -414,12 +414,13 @@
..()
/obj/machinery/atmospherics/unary/vent_pump/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W")
+ . = ..()
+ if(Adjacent(user))
+ . += "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W"
else
- to_chat(user, "You are too far away to read the gauge.")
+ . += "You are too far away to read the gauge."
if(welded)
- to_chat(user, "It seems welded shut.")
+ . += "It seems welded shut."
/obj/machinery/atmospherics/unary/vent_pump/power_change()
var/old_stat = stat
diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
index 1c1c696b98..2c51eecfc6 100644
--- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
@@ -287,7 +287,8 @@
deconstruct()
/obj/machinery/atmospherics/unary/vent_scrubber/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W")
+ . = ..()
+ if(Adjacent(user))
+ . += "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W"
else
- to_chat(user, "You are too far away to read the gauge.")
+ . += "You are too far away to read the gauge."
diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm
index dd68782bc5..3ded7b7388 100644
--- a/code/ATMOSPHERICS/components/valve.dm
+++ b/code/ATMOSPHERICS/components/valve.dm
@@ -307,5 +307,5 @@
deconstruct()
/obj/machinery/atmospherics/valve/examine(mob/user)
- ..()
- to_chat(user, "It is [open ? "open" : "closed"].")
+ . = ..()
+ . += "It is [open ? "open" : "closed"]."
diff --git a/code/ATMOSPHERICS/pipes/he_pipes.dm b/code/ATMOSPHERICS/pipes/he_pipes.dm
index 843d349633..8b1b800830 100644
--- a/code/ATMOSPHERICS/pipes/he_pipes.dm
+++ b/code/ATMOSPHERICS/pipes/he_pipes.dm
@@ -88,6 +88,8 @@
if(!parent)
..()
else
+ if(leaking)
+ parent.mingle_with_turf(loc, volume)
var/datum/gas_mixture/pipe_air = return_air()
if(istype(loc, /turf/simulated/))
var/environment_temperature = 0
diff --git a/code/ZAS/Atom.dm b/code/ZAS/Atom.dm
index 0457dce1a5..b395c4551e 100644
--- a/code/ZAS/Atom.dm
+++ b/code/ZAS/Atom.dm
@@ -16,13 +16,19 @@
// Inputs: The turf the airflow is from, which may not be the same as loc. is_zone is for conditionally disallowing merging.
// Outputs: Boolean if airflow can pass.
/atom/proc/CanZASPass(turf/T, is_zone)
+ // Behaviors defined here so when people directly call c_airblock it will still obey can_atmos_pass
switch(can_atmos_pass)
+ if(ATMOS_PASS_YES)
+ return TRUE
+ if(ATMOS_PASS_NO)
+ return FALSE
if(ATMOS_PASS_DENSITY)
return !density
+ if(ATMOS_PASS_PROC)
+ // Cowardly refuse to recursively self-call CanZASPass. The hero BYOND needs?
+ CRASH("can_atmos_pass = ATMOS_PASS_PROC but CanZASPass not overridden on [src] ([type])")
else
- return can_atmos_pass
-
-/turf/can_atmos_pass = ATMOS_PASS_NO
+ CRASH("Invalid can_atmos_pass = [can_atmos_pass] on [src] ([type])")
/turf/CanPass(atom/movable/mover, turf/target)
if(!target) return FALSE
@@ -89,6 +95,15 @@ turf/c_airblock(turf/other)
var/result = 0
for(var/mm in contents)
var/atom/movable/M = mm
- result |= M.c_airblock(other)
+ switch(M.can_atmos_pass)
+ if(ATMOS_PASS_YES)
+ continue
+ if(ATMOS_PASS_NO)
+ return BLOCKED
+ if(ATMOS_PASS_DENSITY)
+ if(M.density)
+ return BLOCKED
+ if(ATMOS_PASS_PROC)
+ result |= M.c_airblock(other)
if(result == BLOCKED) return BLOCKED
return result
diff --git a/code/__defines/ZAS.dm b/code/__defines/ZAS.dm
index 8712dd2bf7..1760505f3a 100644
--- a/code/__defines/ZAS.dm
+++ b/code/__defines/ZAS.dm
@@ -4,3 +4,10 @@
#define BLOCKED 3 // Blocked, zone boundaries will not cross even if opened.
#define ZONE_MIN_SIZE 14 // Zones with less than this many turfs will always merge, even if the connection is not direct
+
+// Used for quickly making certain things allow airflow or not.
+// More complicated, conditional airflow should override CanZASPass().
+#define ATMOS_PASS_YES 1 // Always blocks air and zones.
+#define ATMOS_PASS_NO 2 // Never blocks air or zones.
+#define ATMOS_PASS_DENSITY 3 // Blocks air and zones if density = 1, allows both if density = 0
+#define ATMOS_PASS_PROC 4 // Call CanZASPass() using c_airblock
diff --git a/code/__defines/__513_compatibility.dm b/code/__defines/__513_compatibility.dm
index 7f8d7eb4e6..78583570ff 100644
--- a/code/__defines/__513_compatibility.dm
+++ b/code/__defines/__513_compatibility.dm
@@ -1,6 +1,6 @@
#if DM_VERSION < 513
-#define ismovableatom(A) (istype(A, /atom/movable))
+#define ismovable(A) (istype(A, /atom/movable))
#define islist(L) (istype(L, /list))
@@ -18,8 +18,6 @@
#else
-#define ismovableatom(A) ismovable(A)
-
#define CLAMP01(x) clamp(x, 0, 1)
#define CLAMP(CLVALUE, CLMIN, CLMAX) clamp(CLVALUE, CLMIN, CLMAX)
diff --git a/code/__defines/atmos.dm b/code/__defines/atmos.dm
index 56055273e4..424f2a2639 100644
--- a/code/__defines/atmos.dm
+++ b/code/__defines/atmos.dm
@@ -94,9 +94,3 @@
#define ATMOSTANK_CO2 25000 // CO2 and PH are not critically important for station, only for toxins and alternative coolants, no need to store a lot of those.
#define ATMOSTANK_PHORON 25000
#define ATMOSTANK_NITROUSOXIDE 10000 // N2O doesn't have a real useful use, i guess it's on station just to allow refilling of sec's riot control canisters?
-
-// Used for quickly making certain things allow airflow or not.
-// More complicated, conditional airflow should override CanZASPass().
-#define ATMOS_PASS_YES 1
-#define ATMOS_PASS_NO 0
-#define ATMOS_PASS_DENSITY -1 // Just checks density.
\ No newline at end of file
diff --git a/code/__defines/construction.dm b/code/__defines/construction.dm
index 33d558497d..36073ca4f8 100644
--- a/code/__defines/construction.dm
+++ b/code/__defines/construction.dm
@@ -81,10 +81,28 @@
#define DISPOSAL_PIPE_TAGGER 13
#define DISPOSAL_PIPE_TAGGER_PARTIAL 14
+// Disposals Construction
+// Future: Eliminate these type codes by adding disposals equivilent of pipe_state.
+#define DISPOSAL_PIPE_STRAIGHT 0
+#define DISPOSAL_PIPE_CORNER 1
+#define DISPOSAL_PIPE_JUNCTION 2
+#define DISPOSAL_PIPE_JUNCTION_FLIPPED 3
+#define DISPOSAL_PIPE_JUNCTION_Y 4
+#define DISPOSAL_PIPE_TRUNK 5
+#define DISPOSAL_PIPE_BIN 6
+#define DISPOSAL_PIPE_OUTLET 7
+#define DISPOSAL_PIPE_CHUTE 8
+#define DISPOSAL_PIPE_SORTER 9
+#define DISPOSAL_PIPE_SORTER_FLIPPED 10
+#define DISPOSAL_PIPE_UPWARD 11
+#define DISPOSAL_PIPE_DOWNWARD 12
+#define DISPOSAL_PIPE_TAGGER 13
+#define DISPOSAL_PIPE_TAGGER_PARTIAL 14
+
#define DISPOSAL_SORT_NORMAL 0
#define DISPOSAL_SORT_WILDCARD 1
#define DISPOSAL_SORT_UNTAGGED 2
-//YW Additions end
+
// Macro for easy use of boilerplate code for searching for a valid node connection.
#define STANDARD_ATMOS_CHOOSE_NODE(node_num, direction) \
for(var/obj/machinery/atmospherics/target in get_step(src, direction)) { \
diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm
index 02f1b11ee1..5f67308094 100644
--- a/code/__defines/gamemode.dm
+++ b/code/__defines/gamemode.dm
@@ -35,8 +35,13 @@
#define BE_RAIDER 0x800
#define BE_PLANT 0x1000
#define BE_MUTINEER 0x2000
-#define BE_PAI 0x4000
-#define BE_LOYALIST 0x8000
+#define BE_LOYALIST 0x4000
+#define BE_PAI 0x8000
+//VOREStation Add
+#define BE_LOSTDRONE 0x10000
+#define BE_MAINTPRED 0x20000
+#define BE_MORPH 0x40000
+//VOREStation Add End
var/list/be_special_flags = list(
"Traitor" = BE_TRAITOR,
@@ -45,7 +50,6 @@ var/list/be_special_flags = list(
"Wizard" = BE_WIZARD,
"Malf AI" = BE_MALF,
"Revolutionary" = BE_REV,
- "Loyalist" = BE_LOYALIST,
"Xenomorph" = BE_ALIEN,
"Positronic Brain" = BE_AI,
"Cultist" = BE_CULTIST,
@@ -54,7 +58,13 @@ var/list/be_special_flags = list(
"Raider" = BE_RAIDER,
"Diona" = BE_PLANT,
"Mutineer" = BE_MUTINEER,
- "pAI" = BE_PAI
+ "Loyalist" = BE_LOYALIST,
+ "pAI" = BE_PAI,
+ //VOREStation Add
+ "Lost Drone" = BE_LOSTDRONE,
+ "Maint Pred" = BE_MAINTPRED,
+ "Morph" = BE_MORPH,
+ //VOREStation Add End
)
diff --git a/code/__defines/is_helpers.dm b/code/__defines/is_helpers.dm
index e121f55216..d7bab37345 100644
--- a/code/__defines/is_helpers.dm
+++ b/code/__defines/is_helpers.dm
@@ -13,6 +13,8 @@
#define isitem(D) istype(D, /obj/item)
+#define isradio(A) istype(A, /obj/item/device/radio)
+
#define isairlock(A) istype(A, /obj/machinery/door/airlock)
#define isorgan(A) istype(A, /obj/item/organ/external)
diff --git a/code/__defines/lighting.dm b/code/__defines/lighting.dm
index 2141f3e725..999bb7473a 100644
--- a/code/__defines/lighting.dm
+++ b/code/__defines/lighting.dm
@@ -82,6 +82,7 @@
#define LIGHT_COLOR_INCANDESCENT_TUBE "#FFFEB8"
#define LIGHT_COLOR_INCANDESCENT_BULB "#FFDDBB"
#define LIGHT_COLOR_INCANDESCENT_FLASHLIGHT "#FFCC66"
+#define LIGHT_COLOR_NIGHTSHIFT "#EFCC86"
//Fake ambient occlusion filter
#define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-1, size=2, offset=2, color="#04080F55") //VOREStation Edit for prettier visuals.
diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm
index 0787245d61..17b95a53c2 100644
--- a/code/__defines/machinery.dm
+++ b/code/__defines/machinery.dm
@@ -2,6 +2,7 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define CELLRATE 0.002 // Multiplier for watts per tick <> cell storage (e.g., 0.02 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
// It's a conversion constant. power_used*CELLRATE = charge_provided, or charge_used/CELLRATE = power_provided
+#define SMESRATE 0.03333 // Same for SMESes. A different number for some reason.
#define KILOWATTS *1000
#define MEGAWATTS *1000000
@@ -17,6 +18,7 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define USE_POWER_ACTIVE 2 // Machine is using power at its active power level
// Channel numbers for power.
+#define CURRENT_CHANNEL -1 // Passed as an argument this means "use whatever current channel is"
#define EQUIP 1
#define LIGHT 2
#define ENVIRON 3
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 2026639812..079715550e 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -374,3 +374,7 @@ var/global/list/##LIST_NAME = list();\
#define MOUSE_OPACITY_TRANSPARENT 0
#define MOUSE_OPACITY_ICON 1
#define MOUSE_OPACITY_OPAQUE 2
+
+// Used by radios to indicate that they have sent a message via something other than subspace
+#define RADIO_CONNECTION_FAIL 0
+#define RADIO_CONNECTION_NON_SUBSPACE 1
diff --git a/code/__defines/misc_vr.dm b/code/__defines/misc_vr.dm
index bf6cb4d150..55b92bd490 100644
--- a/code/__defines/misc_vr.dm
+++ b/code/__defines/misc_vr.dm
@@ -48,6 +48,7 @@
#define SHELTER_DEPLOY_BAD_TURFS "bad turfs"
#define SHELTER_DEPLOY_BAD_AREA "bad area"
#define SHELTER_DEPLOY_ANCHORED_OBJECTS "anchored objects"
+#define SHELTER_DEPLOY_SHIP_SPACE "ship not in space"
#define PTO_SECURITY "Security"
#define PTO_MEDICAL "Medical"
@@ -58,3 +59,7 @@
#define PTO_CIVILIAN "Civilian"
#define DEPARTMENT_TALON "ITV Talon"
+
+#define MAT_TITANIUMGLASS "ti-glass"
+#define MAT_PLASTITANIUM "plastitanium"
+#define MAT_PLASTANIUMGLASS "plastitanium glass"
\ No newline at end of file
diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index beeda302eb..c7b1c0eb80 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -14,6 +14,7 @@
#define GODMODE 0x1000
#define FAKEDEATH 0x2000 // Replaces stuff like changeling.changeling_fakedeath.
#define DISFIGURED 0x4000 // Set but never checked. Remove this sometime and replace occurences with the appropriate organ code
+#define DOING_TASK 0x8000 // Performing a do_after or do_mob that's exclusive
// Grab levels.
#define GRAB_PASSIVE 1
@@ -426,4 +427,6 @@
#define EXAMINE_SKIPARMS 0x0020
#define EXAMINE_SKIPHANDS 0x0040
#define EXAMINE_SKIPLEGS 0x0080
-#define EXAMINE_SKIPFEET 0x0100
\ No newline at end of file
+#define EXAMINE_SKIPFEET 0x0100
+
+#define MAX_NUTRITION 5000 //VOREStation Edit
\ No newline at end of file
diff --git a/code/__defines/qdel.dm b/code/__defines/qdel.dm
index 278a2064db..7374438901 100644
--- a/code/__defines/qdel.dm
+++ b/code/__defines/qdel.dm
@@ -25,7 +25,7 @@
//Qdel helper macros.
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE)
#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)
-#define QDEL_NULL(item) qdel(item); item = null
+#define QDEL_NULL(item) if(item) {qdel(item); item = null}
#define QDEL_NULL_LIST QDEL_LIST_NULL
#define QDEL_LIST_NULL(x) if(x) { for(var/y in x) { qdel(y) } ; x = null }
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm
index 4055660a3e..03724307c6 100644
--- a/code/__defines/species_languages.dm
+++ b/code/__defines/species_languages.dm
@@ -54,13 +54,14 @@
#define LANGUAGE_AKHANI "Akhani"
#define LANGUAGE_ALAI "Alai"
#define LANGUAGE_ZADDAT "Vedahq"
+#define LANGUAGE_PROMETHEAN "Promethean"
#define LANGUAGE_BLOB "Blob"
#define LANGUAGE_GIBBERISH "Babel"
// Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
#define RESTRICTED 2 // Language can only be acquired by spawning or an admin.
-#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight.
+#define NONVERBAL 4 // Language uses both verbal and non-verbal components completely to communicate. Out-of-sight speech is garbled.
#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand.
#define HIVEMIND 16 // Broadcast to all mobs with this language.
#define NONGLOBAL 32 // Do not add to general languages list.
diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm
index 37f4bff5f9..0fa2532bf9 100644
--- a/code/__defines/subsystems.dm
+++ b/code/__defines/subsystems.dm
@@ -68,13 +68,15 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_ASSETS -3
#define INIT_ORDER_PLANETS -4
#define INIT_ORDER_HOLOMAPS -5
-#define INIT_ORDER_OVERLAY -6
-#define INIT_ORDER_ALARM -7
+#define INIT_ORDER_NIGHTSHIFT -6
+#define INIT_ORDER_OVERLAY -7
+#define INIT_ORDER_ALARM -8
#define INIT_ORDER_OPENSPACE -10
#define INIT_ORDER_XENOARCH -20
#define INIT_ORDER_CIRCUIT -21
#define INIT_ORDER_AI -22
-#define INIT_ORDER_GAME_MASTER -24
+#define INIT_ORDER_AI_FAST -23
+#define INIT_ORDER_GAME_MASTER -24
#define INIT_ORDER_TICKER -50
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
@@ -83,6 +85,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
#define FIRE_PRIORITY_SHUTTLES 5
#define FIRE_PRIORITY_SUPPLY 5
+#define FIRE_PRIORITY_NIGHTSHIFT 5
#define FIRE_PRIORITY_ORBIT 8
#define FIRE_PRIORITY_VOTE 9
#define FIRE_PRIORITY_AI 10
diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm
index 17a2544850..119f9d554f 100644
--- a/code/_helpers/game.dm
+++ b/code/_helpers/game.dm
@@ -272,17 +272,17 @@
var/list/hearturfs = list()
for(var/thing in hear)
- if(istype(thing,/obj))
+ if(istype(thing, /obj)) //Can't use isobj() because /atom/movable returns true in that, and so lighting overlays would be included
objs += thing
hearturfs |= get_turf(thing)
- else if(istype(thing,/mob))
+ if(ismob(thing))
mobs += thing
hearturfs |= get_turf(thing)
//A list of every mob with a client
for(var/mob in player_list)
//VOREStation Edit - Trying to fix some vorestation bug.
- if(!istype(mob, /mob))
+ if(!ismob(mob))
player_list -= mob
crash_with("There is a null or non-mob reference inside player_list ([mob]).")
continue
diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm
index 33b50af54b..31e19b3082 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -203,6 +203,13 @@ var/global/list/string_slot_flags = list(
var/datum/poster/P = new T
NT_poster_designs += P
+ // VOREStation Add - Vore Modes!
+ paths = typesof(/datum/digest_mode) - /datum/digest_mode/transform
+ for(var/T in paths)
+ var/datum/digest_mode/DM = new T
+ GLOB.digest_modes[DM.id] = DM
+ // VOREStation Add End
+
return 1
/* // Uncomment to debug chemical reaction list.
diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm
index 18cede2ea4..923b8f450f 100644
--- a/code/_helpers/logging.dm
+++ b/code/_helpers/logging.dm
@@ -49,7 +49,7 @@
for(var/client/C in admins)
if(C.is_preference_enabled(/datum/client_preference/debug/show_debug_logs))
- to_chat(C, "DEBUG: [text]")
+ to_chat(C, "DEBUG: [text]")
/proc/log_game(text)
if (config.log_game)
diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm
index 04b8ede203..73ae811193 100644
--- a/code/_helpers/mobs.dm
+++ b/code/_helpers/mobs.dm
@@ -142,9 +142,14 @@ Proc for attack log creation, because really why not
else
return pick("chest", "groin")
-/proc/do_mob(mob/user , mob/target, time = 30, target_zone = 0, uninterruptible = FALSE, progress = TRUE, ignore_movement = FALSE)
+/proc/do_mob(mob/user , mob/target, time = 30, target_zone = 0, uninterruptible = FALSE, progress = TRUE, ignore_movement = FALSE, exclusive = FALSE)
if(!user || !target)
return 0
+ if(!time)
+ return 1 //Done!
+ if(user.status_flags & DOING_TASK)
+ to_chat(user, "You're in the middle of doing something else already.")
+ return 0 //Performing an exclusive do_after or do_mob already
var/user_loc = user.loc
var/target_loc = target.loc
@@ -155,6 +160,10 @@ Proc for attack log creation, because really why not
var/endtime = world.time+time
var/starttime = world.time
+
+ if(exclusive)
+ user.status_flags |= DOING_TASK
+
. = TRUE
while (world.time < endtime)
stoplag(1)
@@ -186,14 +195,20 @@ Proc for attack log creation, because really why not
. = FALSE
break
+ if(exclusive)
+ user.status_flags &= ~DOING_TASK
+
if (progbar)
qdel(progbar)
-/proc/do_after(mob/user, delay, atom/target = null, needhand = TRUE, progress = TRUE, incapacitation_flags = INCAPACITATION_DEFAULT, ignore_movement = FALSE, max_distance = null)
+/proc/do_after(mob/user, delay, atom/target = null, needhand = TRUE, progress = TRUE, incapacitation_flags = INCAPACITATION_DEFAULT, ignore_movement = FALSE, max_distance = null, exclusive = FALSE)
if(!user)
return 0
if(!delay)
return 1 //Okay. Done.
+ if(user.status_flags & DOING_TASK)
+ to_chat(user, "You're in the middle of doing something else already.")
+ return 0 //Performing an exclusive do_after or do_mob already
var/atom/target_loc = null
if(target)
target_loc = target.loc
@@ -214,6 +229,10 @@ Proc for attack log creation, because really why not
var/endtime = world.time + delay
var/starttime = world.time
+
+ if(exclusive)
+ user.status_flags |= DOING_TASK
+
. = 1
while (world.time < endtime)
stoplag(1)
@@ -250,6 +269,9 @@ Proc for attack log creation, because really why not
. = FALSE
break
+ if(exclusive)
+ user.status_flags &= ~DOING_TASK
+
if(progbar)
qdel(progbar)
diff --git a/code/_helpers/time.dm b/code/_helpers/time.dm
index 3846c6fd66..761bd6cae8 100644
--- a/code/_helpers/time.dm
+++ b/code/_helpers/time.dm
@@ -55,7 +55,7 @@ var/next_station_date_change = 1 DAY
if(!station_date || update_time)
var/extra_days = round(station_time_in_ticks / (1 DAY)) DAYS
var/timeofday = world.timeofday + extra_days
- station_date = num2text((text2num(time2text(timeofday, "YYYY"))+544)) + "-" + time2text(timeofday, "MM-DD")
+ station_date = num2text((text2num(time2text(timeofday, "YYYY"))+300)) + "-" + time2text(timeofday, "MM-DD") //VOREStation Edit
return station_date
//ISO 8601
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index fef8f1c1ee..9425868823 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -1276,14 +1276,8 @@ var/mob/dview/dview_mob = new
if(!center)
return
- //VOREStation Add - Emergency Backup
- if(!dview_mob)
- dview_mob = new()
- WARNING("dview mob was lost, and had to be recreated!")
- //VOREStation Add End
-
dview_mob.loc = center
-
+
dview_mob.see_invisible = invis_flags
. = view(range, dview_mob)
diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index c5c48dbbf2..799cc5d113 100644
--- a/code/_onclick/ai.dm
+++ b/code/_onclick/ai.dm
@@ -23,9 +23,10 @@
/mob/living/silicon/ai/ClickOn(var/atom/A, params)
- if(world.time <= next_click)
+ if(!checkClickCooldown())
return
- next_click = world.time + 1
+
+ setClickCooldown(1)
if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
build_click(src, client.buildmode, params, A)
@@ -34,6 +35,9 @@
if(stat)
return
+ if(control_disabled)
+ return
+
var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A)
@@ -44,27 +48,18 @@
if(modifiers["shift"])
ShiftClickOn(A)
return
- if(modifiers["alt"]) // alt and alt-gr (rightalt)
+ if(modifiers["alt"])
AltClickOn(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
- if(control_disabled || !canClick())
- return
-
if(aiCamera.in_camera_mode)
aiCamera.camera_mode_off()
aiCamera.captureimage(A, usr)
return
- /*
- AI restrained() currently does nothing
- if(restrained())
- RestrainedClickOn(A)
- else
- */
A.add_hiddenprint(src)
A.attack_ai(src)
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index ea40e3dc0e..23269f5bab 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -38,10 +38,10 @@
* mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed
*/
/mob/proc/ClickOn(var/atom/A, var/params)
- if(world.time <= next_click) // Hard check, before anything else, to avoid crashing
+ if(!checkClickCooldown()) // Hard check, before anything else, to avoid crashing
return
- next_click = world.time + 1
+ setClickCooldown(1)
if(client && client.buildmode)
build_click(src, client.buildmode, params, A)
@@ -69,9 +69,6 @@
face_atom(A) // change direction to face what you clicked on
- if(!canClick()) // in the year 2000...
- return
-
if(istype(loc, /obj/mecha))
if(!locate(/turf) in list(A, A.loc)) // Prevents inventory from being drilled
return
@@ -156,12 +153,12 @@
return 1
/mob/proc/setClickCooldown(var/timeout)
- next_move = max(world.time + timeout, next_move)
+ next_click = max(world.time + timeout, next_click)
-/mob/proc/canClick()
- if(config.no_click_cooldown || next_move <= world.time)
- return 1
- return 0
+/mob/proc/checkClickCooldown()
+ if(next_click > world.time && !config.no_click_cooldown)
+ return FALSE
+ return TRUE
// Default behavior: ignore double clicks, the second click that makes the doubleclick call already calls for a normal click
/mob/proc/DblClickOn(var/atom/A, var/params)
diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm
index f8bce398a6..0c99425147 100644
--- a/code/_onclick/cyborg.dm
+++ b/code/_onclick/cyborg.dm
@@ -7,9 +7,10 @@
*/
/mob/living/silicon/robot/ClickOn(var/atom/A, var/params)
- if(world.time <= next_click)
+ if(!checkClickCooldown())
return
- next_click = world.time + 1
+
+ setClickCooldown(1)
if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
build_click(src, client.buildmode, params, A)
@@ -35,9 +36,6 @@
if(stat || lockdown || weakened || stunned || paralysis)
return
- if(!canClick())
- return
-
face_atom(A) // change direction to face what you clicked on
if(aiCamera && aiCamera.in_camera_mode)
diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm
index b5299cd77b..c123790b51 100644
--- a/code/_onclick/hud/action.dm
+++ b/code/_onclick/hud/action.dm
@@ -123,7 +123,7 @@
if(modifiers["shift"])
moved = 0
return 1
- if(usr.next_move >= world.time) // Is this needed ?
+ if(!usr.checkClickCooldown())
return
owner.Trigger()
return 1
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 8a61b87251..1258e4ce94 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -236,6 +236,8 @@
mymob.internals = new /obj/screen()
mymob.internals.icon = ui_style
mymob.internals.icon_state = "internal0"
+ if(istype(target.internal, /obj/item/weapon/tank)) //Internals on already? Iight, prove it
+ mymob.internals.icon_state = "internal1"
mymob.internals.name = "internal"
mymob.internals.screen_loc = ui_internal
hud_elements |= mymob.internals
diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm
index e83e5d732c..fa568b8614 100644
--- a/code/_onclick/hud/radial.dm
+++ b/code/_onclick/hud/radial.dm
@@ -17,6 +17,10 @@ GLOBAL_LIST_EMPTY(radial_menus)
var/next_page = FALSE
var/tooltips = FALSE
+/obj/screen/radial/Destroy()
+ parent = null
+ return ..()
+
/obj/screen/radial/slice/MouseEntered(location, control, params)
. = ..()
icon_state = "radial_slice_focus"
@@ -279,6 +283,8 @@ GLOBAL_LIST_EMPTY(radial_menus)
/datum/radial_menu/Destroy()
Reset()
hide()
+ QDEL_LIST_NULL(elements)
+ QDEL_NULL(close_button)
QDEL_NULL(custom_check_callback)
. = ..()
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 2c6408cf7f..e82d3ea5f6 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -54,7 +54,7 @@
/obj/screen/item_action/Click()
if(!usr || !owner)
return 1
- if(!usr.canClick())
+ if(!usr.checkClickCooldown())
return
if(usr.stat || usr.restrained() || usr.stunned || usr.lying)
@@ -85,7 +85,7 @@
name = "storage"
/obj/screen/storage/Click()
- if(!usr.canClick())
+ if(!usr.checkClickCooldown())
return 1
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
return 1
@@ -494,7 +494,7 @@
/obj/screen/inventory/Click()
// At this point in client Click() code we have passed the 1/10 sec check and little else
// We don't even know if it's a middle click
- if(!usr.canClick())
+ if(!usr.checkClickCooldown())
return 1
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
return 1
diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm
index a2d3f0c92b..88309b5074 100644
--- a/code/_onclick/observer.dm
+++ b/code/_onclick/observer.dm
@@ -31,7 +31,7 @@
if(client.buildmode)
build_click(src, client.buildmode, params, A)
return
- if(!canClick()) return
+ if(!checkClickCooldown()) return
setClickCooldown(4)
// You are responsible for checking config.ghost_interaction when you override this function
// Not all of them require checking, see below
diff --git a/code/_onclick/rig.dm b/code/_onclick/rig.dm
index ed7a1c7e2f..e281505dc2 100644
--- a/code/_onclick/rig.dm
+++ b/code/_onclick/rig.dm
@@ -63,7 +63,7 @@
return loc == card
/mob/living/proc/HardsuitClickOn(var/atom/A, var/alert_ai = 0)
- if(!can_use_rig() || !canClick())
+ if(!can_use_rig())
return 0
var/obj/item/weapon/rig/rig = get_rig()
if(istype(rig) && !rig.offline && rig.selected_module)
diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm
index 3b3512bbf9..b99ab68064 100644
--- a/code/controllers/communications.dm
+++ b/code/controllers/communications.dm
@@ -125,7 +125,7 @@ var/const/EXP_FREQ = 1361
var/const/MED_I_FREQ = 1485
var/const/SEC_I_FREQ = 1475
-var/const/TALON_FREQ = 1481 //VOREStation Add
+var/const/TALON_FREQ = 1363 //VOREStation Add
var/list/radiochannels = list(
"Common" = PUB_FREQ,
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index c573a2130c..47c3a9a876 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -271,6 +271,9 @@ var/list/gamemode_cache = list()
// disables the annoying "You have already logged in this round, disconnect or be banned" popup for multikeying, because it annoys the shit out of me when testing.
var/static/disable_cid_warn_popup = FALSE
+ // whether or not to use the nightshift subsystem to perform lighting changes
+ var/static/enable_night_shifts = FALSE
+
/datum/configuration/New()
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
for (var/T in L)
@@ -892,6 +895,9 @@ var/list/gamemode_cache = list()
if("disable_cid_warn_popup")
config.disable_cid_warn_popup = TRUE
+ if("enable_night_shifts")
+ config.enable_night_shifts = TRUE
+
else
log_misc("Unknown setting in configuration: '[name]'")
diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm
index d6e272f9c9..b5fa776f7f 100644
--- a/code/controllers/emergency_shuttle_controller.dm
+++ b/code/controllers/emergency_shuttle_controller.dm
@@ -58,7 +58,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle = new
if (evac)
emergency_shuttle_docked.Announce(replacetext(replacetext(using_map.emergency_shuttle_docked_message, "%dock_name%", "[using_map.dock_name]"), "%ETD%", "[estimated_time] minute\s"))
else
- priority_announcement.Announce(replacetext(replacetext(using_map.shuttle_docked_message, "%dock_name%", "[using_map.dock_name]"), "%ETD%", "[estimated_time] minute\s"))
+ priority_announcement.Announce(replacetext(replacetext(using_map.shuttle_docked_message, "%dock_name%", "[using_map.dock_name]"), "%ETD%", "[estimated_time] minute\s"), "Transfer System", 'sound/AI/tramarrived.ogg') //VOREStation Edit - TTS
//arm the escape pods
if (evac)
@@ -115,7 +115,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle = new
shuttle.move_time = SHUTTLE_TRANSIT_DURATION
var/estimated_time = round(estimate_arrival_time()/60,1)
- priority_announcement.Announce(replacetext(replacetext(using_map.shuttle_called_message, "%dock_name%", "[using_map.dock_name]"), "%ETA%", "[estimated_time] minute\s"))
+ priority_announcement.Announce(replacetext(replacetext(using_map.shuttle_called_message, "%dock_name%", "[using_map.dock_name]"), "%ETA%", "[estimated_time] minute\s"), "Transfer System", 'sound/AI/tramcalled.ogg') //VOREStation Edit - TTS
atc.shift_ending()
//recalls the shuttle
diff --git a/code/controllers/subsystems/ai.dm b/code/controllers/subsystems/ai.dm
index a111b83e43..5ebbb22a2f 100644
--- a/code/controllers/subsystems/ai.dm
+++ b/code/controllers/subsystems/ai.dm
@@ -2,8 +2,8 @@ SUBSYSTEM_DEF(ai)
name = "AI"
init_order = INIT_ORDER_AI
priority = FIRE_PRIORITY_AI
- wait = 5 // This gets run twice a second, however this is technically two loops in one, with the second loop being run every four iterations.
- flags = SS_NO_INIT|SS_TICKER
+ wait = 2 SECONDS
+ flags = SS_NO_INIT
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/processing = list()
@@ -22,15 +22,11 @@ SUBSYSTEM_DEF(ai)
var/list/currentrun = src.currentrun
while(currentrun.len)
- // var/mob/living/L = currentrun[currentrun.len]
var/datum/ai_holder/A = currentrun[currentrun.len]
--currentrun.len
if(!A || QDELETED(A) || A.busy) // Doesn't exist or won't exist soon or not doing it this tick
continue
- if(times_fired % 4 == 0 && A.holder.stat != DEAD)
- A.handle_strategicals()
- if(A.holder.stat != DEAD) // The /TG/ version checks stat twice, presumably in-case processing somehow got the mob killed in that instant.
- A.handle_tactics()
+ A.handle_strategicals()
if(MC_TICK_CHECK)
return
diff --git a/code/controllers/subsystems/aifast.dm b/code/controllers/subsystems/aifast.dm
new file mode 100644
index 0000000000..f045a7fd35
--- /dev/null
+++ b/code/controllers/subsystems/aifast.dm
@@ -0,0 +1,32 @@
+SUBSYSTEM_DEF(aifast)
+ name = "AI (Fast)"
+ init_order = INIT_ORDER_AI_FAST
+ priority = FIRE_PRIORITY_AI
+ wait = 0.25 SECONDS // Every quarter second
+ flags = SS_NO_INIT
+ runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
+
+ var/list/processing = list()
+ var/list/currentrun = list()
+
+/datum/controller/subsystem/aifast/stat_entry(msg_prefix)
+ var/list/msg = list(msg_prefix)
+ msg += "P:[processing.len]"
+ ..(msg.Join())
+
+/datum/controller/subsystem/aifast/fire(resumed = 0)
+ if (!resumed)
+ src.currentrun = processing.Copy()
+
+ //cache for sanic speed (lists are references anyways)
+ var/list/currentrun = src.currentrun
+
+ while(currentrun.len)
+ var/datum/ai_holder/A = currentrun[currentrun.len]
+ --currentrun.len
+ if(!A || QDELETED(A) || A.busy) // Doesn't exist or won't exist soon or not doing it this tick
+ continue
+ A.handle_tactics()
+
+ if(MC_TICK_CHECK)
+ return
diff --git a/code/controllers/subsystems/assets.dm b/code/controllers/subsystems/assets.dm
index cd531db614..2041104a2b 100644
--- a/code/controllers/subsystems/assets.dm
+++ b/code/controllers/subsystems/assets.dm
@@ -6,9 +6,11 @@ SUBSYSTEM_DEF(assets)
var/list/preload = list()
/datum/controller/subsystem/assets/Initialize(timeofday)
- for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
- var/datum/asset/A = new type()
- A.register()
+ for(var/type in typesof(/datum/asset))
+ var/datum/asset/A = type
+ if (type != initial(A._abstract))
+ get_asset_datum(type)
+
preload = cache.Copy() //don't preload assets generated during the round
diff --git a/code/controllers/subsystems/inactivity.dm b/code/controllers/subsystems/inactivity.dm
index 956af04787..e4ab73fcab 100644
--- a/code/controllers/subsystems/inactivity.dm
+++ b/code/controllers/subsystems/inactivity.dm
@@ -16,7 +16,7 @@ SUBSYSTEM_DEF(inactivity)
var/client/C = client_list[client_list.len]
client_list.len--
if(C.is_afk(config.kick_inactive MINUTES) && can_kick(C))
- to_chat(C, "You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.")
+ to_chat_immediate(C, world.time, "You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.")
var/information
if(C.mob)
diff --git a/code/controllers/subsystems/machines.dm b/code/controllers/subsystems/machines.dm
index 7f35bfd971..29d6ecce56 100644
--- a/code/controllers/subsystems/machines.dm
+++ b/code/controllers/subsystems/machines.dm
@@ -121,10 +121,8 @@ SUBSYSTEM_DEF(machines)
while(current_run.len)
var/obj/machinery/M = current_run[current_run.len]
current_run.len--
- if(istype(M) && !QDELETED(M) && !(M.process(wait) == PROCESS_KILL))
- if(M.use_power)
- M.auto_use_power()
- else
+
+ if(!istype(M) || QDELETED(M) || (M.process(wait) == PROCESS_KILL))
global.processing_machines.Remove(M)
if(!QDELETED(M))
DISABLE_BITFIELD(M.datum_flags, DF_ISPROCESSING)
diff --git a/code/controllers/subsystems/nightshift.dm b/code/controllers/subsystems/nightshift.dm
new file mode 100644
index 0000000000..9e89a05cee
--- /dev/null
+++ b/code/controllers/subsystems/nightshift.dm
@@ -0,0 +1,70 @@
+SUBSYSTEM_DEF(nightshift)
+ name = "Night Shift"
+ init_order = INIT_ORDER_NIGHTSHIFT
+ priority = FIRE_PRIORITY_NIGHTSHIFT
+ wait = 60 SECONDS
+ flags = SS_NO_TICK_CHECK
+
+ var/nightshift_active = FALSE
+ var/nightshift_first_check = 30 SECONDS
+
+ var/high_security_mode = FALSE
+
+/datum/controller/subsystem/nightshift/Initialize()
+ if(!config.enable_night_shifts)
+ can_fire = FALSE
+ /*
+ if(config.randomize_shift_time)
+ GLOB.gametime_offset = rand(0, 23) HOURS
+ */
+ return ..()
+
+/datum/controller/subsystem/nightshift/fire(resumed = FALSE)
+ if(round_duration_in_ticks < nightshift_first_check)
+ return
+ check_nightshift()
+
+/datum/controller/subsystem/nightshift/proc/announce(message)
+ var/announce_z
+ if(using_map.station_levels.len)
+ announce_z = pick(using_map.station_levels)
+ //VOREStation Edit - TTS
+ var/pickedsound
+ if(!high_security_mode)
+ if(nightshift_active)
+ pickedsound = 'sound/AI/dim_lights.ogg'
+ else
+ pickedsound = 'sound/AI/bright_lights.ogg'
+ priority_announcement.Announce(message, new_title = "Automated Lighting System Announcement", new_sound = pickedsound, zlevel = announce_z)
+ //VOREStation Edit End
+
+/datum/controller/subsystem/nightshift/proc/check_nightshift(check_canfire=FALSE) //This is called from elsewhere, like setting the alert levels
+ if(check_canfire && !can_fire)
+ return
+ var/emergency = security_level > SEC_LEVEL_GREEN
+ var/announcing = TRUE
+ var/night_time = using_map.get_nightshift()
+ if(high_security_mode != emergency)
+ high_security_mode = emergency
+ if(night_time)
+ announcing = FALSE
+ if(!emergency)
+ announce("Restoring night lighting configuration to normal operation.")
+ else
+ announce("Disabling night lighting: Station is in a state of emergency.")
+ if(emergency)
+ night_time = FALSE
+ if(nightshift_active != night_time)
+ update_nightshift(night_time, announcing)
+
+/datum/controller/subsystem/nightshift/proc/update_nightshift(active, announce = TRUE)
+ nightshift_active = active
+ if(announce)
+ if(active)
+ announce("Good evening, crew. To reduce power consumption and stimulate the circadian rhythms of some species, all of the lights aboard the station have been dimmed for the night.")
+ else
+ announce("Good morning, crew. As it is now day time, all of the lights aboard the station have been restored to their former brightness.")
+ for(var/obj/machinery/power/apc/apc in machines)
+ if(apc.z in using_map.station_levels)
+ apc.set_nightshift(active, TRUE)
+ CHECK_TICK
diff --git a/code/controllers/subsystems/planets.dm b/code/controllers/subsystems/planets.dm
index 9e823fc0db..5d1325bba5 100644
--- a/code/controllers/subsystems/planets.dm
+++ b/code/controllers/subsystems/planets.dm
@@ -6,16 +6,16 @@ SUBSYSTEM_DEF(planets)
flags = SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
- var/list/new_outdoor_turfs = list()
- var/list/new_outdoor_walls = list()
+ var/static/list/new_outdoor_turfs = list()
+ var/static/list/new_outdoor_walls = list()
- var/list/planets = list()
- var/list/z_to_planet = list()
+ var/static/list/planets = list()
+ var/static/list/z_to_planet = list()
- var/list/currentrun = list()
+ var/static/list/currentrun = list()
- var/list/needs_sun_update = list()
- var/list/needs_temp_update = list()
+ var/static/list/needs_sun_update = list()
+ var/static/list/needs_temp_update = list()
/datum/controller/subsystem/planets/Initialize(timeofday)
admin_notice("Initializing planetary weather.", R_DEBUG)
diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm
index 984b4448c1..397f32078c 100644
--- a/code/controllers/subsystems/ticker.dm
+++ b/code/controllers/subsystems/ticker.dm
@@ -72,8 +72,8 @@ var/global/datum/controller/subsystem/ticker/ticker
post_game_tick()
/datum/controller/subsystem/ticker/proc/pregame_welcome()
- to_chat(world, "Welcome to the pregame lobby!")
- to_chat(world, "Please set up your character and select ready. The round will start in [pregame_timeleft] seconds.")
+ to_world("Welcome to the pregame lobby!")
+ to_world("Please set up your character and select ready. The round will start in [pregame_timeleft] seconds.")
// Called during GAME_STATE_PREGAME (RUNLEVEL_LOBBY)
/datum/controller/subsystem/ticker/proc/pregame_tick()
@@ -120,7 +120,7 @@ var/global/datum/controller/subsystem/ticker/ticker
var/list/runnable_modes = config.get_runnable_modes()
if((master_mode == "random") || (master_mode == "secret"))
if(!runnable_modes.len)
- to_chat(world, "Unable to choose playable game mode. Reverting to pregame lobby.")
+ to_world("Unable to choose playable game mode. Reverting to pregame lobby.")
return 0
if(secret_force_mode != "secret")
src.mode = config.pick_mode(secret_force_mode)
@@ -133,7 +133,7 @@ var/global/datum/controller/subsystem/ticker/ticker
src.mode = config.pick_mode(master_mode)
if(!src.mode)
- to_chat(world, "Serious error in mode setup! Reverting to pregame lobby.") //Uses setup instead of set up due to computational context.
+ to_world("Serious error in mode setup! Reverting to pregame lobby.") //Uses setup instead of set up due to computational context.
return 0
job_master.ResetOccupations()
@@ -142,21 +142,21 @@ var/global/datum/controller/subsystem/ticker/ticker
job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
if(!src.mode.can_start())
- to_world("Unable to start [mode.name]. Not enough players readied, [config.player_requirements[mode.config_tag]] players needed. Reverting to pregame lobby.")
+ to_world("Unable to start [mode.name]. Not enough players readied, [config.player_requirements[mode.config_tag]] players needed. Reverting to pregame lobby.")
mode.fail_setup()
mode = null
job_master.ResetOccupations()
return 0
if(hide_mode)
- to_world("The current game mode is - Secret!")
+ to_world("The current game mode is - Secret!")
if(runnable_modes.len)
var/list/tmpmodes = new
for (var/datum/game_mode/M in runnable_modes)
tmpmodes+=M.name
tmpmodes = sortList(tmpmodes)
if(tmpmodes.len)
- to_chat(world, "Possibilities: [english_list(tmpmodes, and_text= "; ", comma_text = "; ")]")
+ to_world("Possibilities: [english_list(tmpmodes, and_text= "; ", comma_text = "; ")]")
else
src.mode.announce()
return 1
@@ -178,7 +178,7 @@ var/global/datum/controller/subsystem/ticker/ticker
//Deleting Startpoints but we need the ai point to AI-ize people later
if (S.name != "AI")
qdel(S)
- to_chat(world, "Enjoy the game!")
+ to_world("Enjoy the game!")
world << sound('sound/AI/welcome.ogg') // Skie
//Holiday Round-start stuff ~Carn
Holiday_Game_Start()
@@ -227,7 +227,7 @@ var/global/datum/controller/subsystem/ticker/ticker
end_game_state = END_GAME_MODE_FINISHED // Only do this cleanup once!
mode.cleanup()
//call a transfer shuttle vote
- to_chat(world, "The round has ended!")
+ to_world("The round has ended!")
SSvote.autotransfer()
// Called during GAME_STATE_FINISHED (RUNLEVEL_POSTGAME)
@@ -240,7 +240,7 @@ var/global/datum/controller/subsystem/ticker/ticker
feedback_set_details("end_proper", "nuke")
restart_timeleft = 1 MINUTE // No point waiting five minutes if everyone's dead.
if(!delay_end)
- to_chat(world, "Rebooting due to destruction of [station_name()] in [round(restart_timeleft/600)] minute\s.")
+ to_world("Rebooting due to destruction of [station_name()] in [round(restart_timeleft/600)] minute\s.")
last_restart_notify = world.time
else
feedback_set_details("end_proper", "proper completion")
@@ -254,12 +254,12 @@ var/global/datum/controller/subsystem/ticker/ticker
if(END_GAME_ENDING)
restart_timeleft -= (world.time - last_fire)
if(delay_end)
- to_chat(world, "An admin has delayed the round end.")
+ to_world("An admin has delayed the round end.")
end_game_state = END_GAME_DELAYED
else if(restart_timeleft <= 0)
world.Reboot()
else if (world.time - last_restart_notify >= 1 MINUTE)
- to_chat(world, "Restarting in [round(restart_timeleft/600, 1)] minute\s.")
+ to_world("Restarting in [round(restart_timeleft/600, 1)] minute\s.")
last_restart_notify = world.time
return
if(END_GAME_DELAYED)
@@ -430,47 +430,47 @@ var/global/datum/controller/subsystem/ticker/ticker
if(captainless)
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
- to_chat(M, "Colony Directorship not forced on anyone.")
+ to_chat(M, "Colony Directorship not forced on anyone.")
/datum/controller/subsystem/ticker/proc/declare_completion()
- to_world("
A round of [mode.name] has ended!
")
+ to_world("
A round of [mode.name] has ended!
")
for(var/mob/Player in player_list)
if(Player.mind && !isnewplayer(Player))
if(Player.stat != DEAD)
var/turf/playerTurf = get_turf(Player)
if(emergency_shuttle.departed && emergency_shuttle.evac)
if(isNotAdminLevel(playerTurf.z))
- to_chat(Player, "You survived the round, but remained on [station_name()] as [Player.real_name].")
+ to_chat(Player, "You survived the round, but remained on [station_name()] as [Player.real_name].")
else
- to_chat(Player, "You managed to survive the events on [station_name()] as [Player.real_name].")
+ to_chat(Player, "You managed to survive the events on [station_name()] as [Player.real_name].")
else if(isAdminLevel(playerTurf.z))
- to_chat(Player, "You successfully underwent crew transfer after events on [station_name()] as [Player.real_name].")
+ to_chat(Player, "You successfully underwent crew transfer after events on [station_name()] as [Player.real_name].")
else if(issilicon(Player))
- to_chat(Player, "You remain operational after the events on [station_name()] as [Player.real_name].")
+ to_chat(Player, "You remain operational after the events on [station_name()] as [Player.real_name].")
else
- to_chat(Player, "You missed the crew transfer after the events on [station_name()] as [Player.real_name].")
+ to_chat(Player, "You missed the crew transfer after the events on [station_name()] as [Player.real_name].")
else
if(istype(Player,/mob/observer/dead))
var/mob/observer/dead/O = Player
if(!O.started_as_observer)
- to_chat(Player, "You did not survive the events on [station_name()]...")
+ to_chat(Player, "You did not survive the events on [station_name()]...")
else
- to_chat(Player, "You did not survive the events on [station_name()]...")
+ to_chat(Player, "You did not survive the events on [station_name()]...")
to_world("
")
for (var/mob/living/silicon/ai/aiPlayer in mob_list)
if (aiPlayer.stat != 2)
- to_world("[aiPlayer.name] (Played by: [aiPlayer.key])'s laws at the end of the round were:")
+ to_world("[aiPlayer.name] (Played by: [aiPlayer.key])'s laws at the end of the round were:")
else
- to_world("[aiPlayer.name] (Played by: [aiPlayer.key])'s laws when it was deactivated were:")
+ to_world("[aiPlayer.name] (Played by: [aiPlayer.key])'s laws when it was deactivated were:")
aiPlayer.show_laws(1)
if (aiPlayer.connected_robots.len)
var/robolist = "The AI's loyal minions were: "
for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots)
robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.key]), ":" (Played by: [robo.key]), "]"
- to_world("[robolist]")
+ to_world("[robolist]")
var/dronecount = 0
@@ -482,15 +482,15 @@ var/global/datum/controller/subsystem/ticker/ticker
if (!robo.connected_ai)
if (robo.stat != 2)
- to_world("[robo.name] (Played by: [robo.key]) survived as an AI-less stationbound synthetic! Its laws were:")
+ to_world("[robo.name] (Played by: [robo.key]) survived as an AI-less stationbound synthetic! Its laws were:")
else
- to_world("[robo.name] (Played by: [robo.key]) was unable to survive the rigors of being a stationbound synthetic without an AI. Its laws were:")
+ to_world("[robo.name] (Played by: [robo.key]) was unable to survive the rigors of being a stationbound synthetic without an AI. Its laws were:")
if(robo) //How the hell do we lose robo between here and the world messages directly above this?
robo.laws.show_laws(world)
if(dronecount)
- to_world("There [dronecount>1 ? "were" : "was"] [dronecount] industrious maintenance [dronecount>1 ? "drones" : "drone"] at the end of this round.")
+ to_world("There [dronecount>1 ? "were" : "was"] [dronecount] industrious maintenance [dronecount>1 ? "drones" : "drone"] at the end of this round.")
mode.declare_completion()//To declare normal completion.
diff --git a/code/datums/ghost_query.dm b/code/datums/ghost_query.dm
index d068e27de2..f3a84d533d 100644
--- a/code/datums/ghost_query.dm
+++ b/code/datums/ghost_query.dm
@@ -125,7 +125,7 @@
/datum/ghost_query/lost_drone
role_name = "Lost Drone"
question = "A lost drone onboard has been discovered by a crewmember and they are attempting to reactivate it. Would you like to play as the drone?"
- //be_special_flag = BE_AI //VOREStation Removal: Positronic role is never used because intended purpose is unfitting, so remove the check
+ be_special_flag = BE_LOSTDRONE //VOREStation Edit
check_bans = list("AI", "Cyborg")
cutoff_number = 1
diff --git a/code/datums/ghost_query_vr.dm b/code/datums/ghost_query_vr.dm
index aba3165c63..75356029be 100644
--- a/code/datums/ghost_query_vr.dm
+++ b/code/datums/ghost_query_vr.dm
@@ -1,9 +1,11 @@
/datum/ghost_query/morph
role_name = "Morph"
+ be_special_flag = BE_MORPH
question = "A weird morphic creature appears to have snuck onstation. Do you want to play as it? ((Expect to be treated as vore predator.))"
cutoff_number = 1
/datum/ghost_query/maints_pred
role_name = "Maintenance Predator"
+ be_special_flag = BE_MAINTPRED
question = "It appears a predatory critter is lurking in the maintenance. Do you want to play as it? ((You get to choose type of critter. Expect to be treated as vore predator.))"
cutoff_number = 1
\ No newline at end of file
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 684505aa57..65576a52a7 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -98,7 +98,6 @@
var/turf/destturf
var/turf/curturf = get_turf(teleatom)
- var/area/destarea = get_area(destination)
if(precision)
var/list/posturfs = circlerangeturfs(destination,precision)
destturf = safepick(posturfs)
@@ -125,8 +124,6 @@
if(C)
C.forceMove(destturf)
- destarea.Entered(teleatom)
-
return 1
/datum/teleport/proc/teleport()
diff --git a/code/datums/outfits/jobs/cargo.dm b/code/datums/outfits/jobs/cargo.dm
index 10ddb9b7b0..1b48efcb9d 100644
--- a/code/datums/outfits/jobs/cargo.dm
+++ b/code/datums/outfits/jobs/cargo.dm
@@ -5,6 +5,7 @@
/decl/hierarchy/outfit/job/cargo/qm
name = OUTFIT_JOB_NAME("Cargo")
uniform = /obj/item/clothing/under/rank/cargo
+ l_ear = /obj/item/device/radio/headset/headset_qm //VOREStation Add
shoes = /obj/item/clothing/shoes/brown
glasses = /obj/item/clothing/glasses/sunglasses
l_hand = /obj/item/weapon/clipboard
diff --git a/code/datums/outfits/outfit_vr.dm b/code/datums/outfits/outfit_vr.dm
index 27e5cde50e..b994a9e205 100644
--- a/code/datums/outfits/outfit_vr.dm
+++ b/code/datums/outfits/outfit_vr.dm
@@ -48,8 +48,8 @@
C.registered_name = H.real_name
return C
-/decl/hierarchy/outfit/solgov/representative
- name = "SolGov Representative"
+/decl/hierarchy/outfit/solcom/representative
+ name = "SolCom Representative"
shoes = /obj/item/clothing/shoes/laceup
l_ear = /obj/item/device/radio/headset/centcom
uniform = /obj/item/clothing/under/suit_jacket/navy
@@ -59,13 +59,13 @@
r_hand = /obj/item/device/pda/centcom
l_hand = /obj/item/weapon/clipboard
-/decl/hierarchy/outfit/solgov/representative/equip_id(mob/living/carbon/human/H)
+/decl/hierarchy/outfit/solcom/representative/equip_id(mob/living/carbon/human/H)
var/obj/item/weapon/card/id/C = ..()
- C.name = "[H.real_name]'s SolGov ID Card"
+ C.name = "[H.real_name]'s SolCom ID Card"
C.icon_state = "lifetime"
C.access = get_all_station_access()
C.access += get_all_centcom_access()
- C.assignment = "SolGov Representative"
+ C.assignment = "SolCom Representative"
C.registered_name = H.real_name
return C
@@ -101,3 +101,76 @@
r_hand = /obj/item/weapon/melee/energy/sword/imperial
l_hand = /obj/item/weapon/shield/energy/imperial
suit_store = /obj/item/weapon/gun/energy/imperial
+
+/*
+SOUTHERN CROSS OUTFITS
+Keep outfits simple. Spawn with basic uniforms and minimal gear. Gear instead goes in lockers. Keep this in mind if editing.
+*/
+
+
+/decl/hierarchy/outfit/job/explorer2
+ name = OUTFIT_JOB_NAME("Explorer")
+ shoes = /obj/item/clothing/shoes/boots/winter/explorer
+ uniform = /obj/item/clothing/under/explorer
+ l_ear = /obj/item/device/radio/headset/explorer
+ id_slot = slot_wear_id
+ pda_slot = slot_l_store
+ pda_type = /obj/item/device/pda/explorer //VORESTation Edit - Better Brown
+ id_type = /obj/item/weapon/card/id/explorer //VOREStation Edit
+ id_pda_assignment = "Explorer"
+ flags = OUTFIT_HAS_BACKPACK|OUTFIT_COMPREHENSIVE_SURVIVAL
+ backpack_contents = list(/obj/item/clothing/accessory/permit/gun/planetside = 1)
+
+/decl/hierarchy/outfit/job/explorer2/post_equip(mob/living/carbon/human/H)
+ ..()
+ for(var/obj/item/clothing/accessory/permit/gun/planetside/permit in H.back.contents)
+ permit.set_name(H.real_name)
+
+/decl/hierarchy/outfit/job/pilot
+ name = OUTFIT_JOB_NAME("Pilot")
+ shoes = /obj/item/clothing/shoes/black
+ uniform = /obj/item/clothing/under/rank/pilot1
+ suit = /obj/item/clothing/suit/storage/toggle/bomber/pilot
+ gloves = /obj/item/clothing/gloves/fingerless
+ glasses = /obj/item/clothing/glasses/fakesunglasses/aviator
+ l_ear = /obj/item/device/radio/headset/pilot/alt
+ id_slot = slot_wear_id
+ pda_slot = slot_belt
+ pda_type = /obj/item/device/pda //VOREStation Edit - Civilian
+ id_pda_assignment = "Pilot"
+ flags = OUTFIT_HAS_BACKPACK|OUTFIT_COMPREHENSIVE_SURVIVAL
+
+/decl/hierarchy/outfit/job/medical/sar
+ name = OUTFIT_JOB_NAME("Field Medic") //VOREStation Edit
+ uniform = /obj/item/clothing/under/utility/blue
+ //suit = /obj/item/clothing/suit/storage/hooded/wintercoat/medical/sar //VOREStation Edit
+ shoes = /obj/item/clothing/shoes/boots/winter/explorer
+ l_ear = /obj/item/device/radio/headset/sar
+ l_hand = /obj/item/weapon/storage/firstaid/regular
+ belt = /obj/item/weapon/storage/belt/medical/emt
+ pda_slot = slot_l_store
+ pda_type = /obj/item/device/pda/sar //VOREStation Add
+ id_pda_assignment = "Field Medic" //VOREStation Edit
+ flags = OUTFIT_HAS_BACKPACK|OUTFIT_EXTENDED_SURVIVAL|OUTFIT_COMPREHENSIVE_SURVIVAL
+
+/decl/hierarchy/outfit/job/pathfinder
+ name = OUTFIT_JOB_NAME("Pathfinder")
+ shoes = /obj/item/clothing/shoes/boots/winter/explorer
+ uniform = /obj/item/clothing/under/explorer //TODO: Uniforms.
+ l_ear = /obj/item/device/radio/headset/pathfinder
+ id_slot = slot_wear_id
+ pda_slot = slot_l_store
+ pda_type = /obj/item/device/pda/pathfinder
+ id_type = /obj/item/weapon/card/id/explorer/head
+ id_pda_assignment = "Pathfinder"
+ flags = OUTFIT_HAS_BACKPACK|OUTFIT_EXTENDED_SURVIVAL|OUTFIT_COMPREHENSIVE_SURVIVAL
+ backpack_contents = list(/obj/item/clothing/accessory/permit/gun/planetside = 1)
+
+/decl/hierarchy/outfit/job/pathfinder/post_equip(mob/living/carbon/human/H)
+ ..()
+ for(var/obj/item/clothing/accessory/permit/gun/planetside/permit in H.back.contents)
+ permit.set_name(H.real_name)
+
+/decl/hierarchy/outfit/job/assistant/explorer
+ id_type = /obj/item/weapon/card/id/explorer
+ flags = OUTFIT_HAS_BACKPACK|OUTFIT_COMPREHENSIVE_SURVIVAL
diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm
index 01e4119b55..c24dfcd922 100644
--- a/code/datums/progressbar.dm
+++ b/code/datums/progressbar.dm
@@ -1,46 +1,70 @@
+#define PROGRESSBAR_HEIGHT 6
+
/datum/progressbar
var/goal = 1
var/image/bar
var/shown = 0
var/mob/user
var/client/client
+ var/listindex
-/datum/progressbar/New(mob/user, goal_number, atom/target)
+/datum/progressbar/New(mob/User, goal_number, atom/target)
. = ..()
- if(!target) target = user
- if (!istype(target))
- EXCEPTION("Invalid target given")
- if (goal_number)
+ if(!istype(target))
+ target = User
+ if(goal_number)
goal = goal_number
- bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0")
- bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
- bar.pixel_y = 32
+ bar = image('icons/effects/progressbar.dmi', target, "prog_bar_0")
+ bar.alpha = 0
bar.plane = PLANE_PLAYER_HUD
- src.user = user
+ bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
+ user = User
if(user)
client = user.client
-/datum/progressbar/Destroy()
- if (client)
- client.images -= bar
- QDEL_NULL(bar)
- user = null
- client = null
- return ..()
+ LAZYINITLIST(user.progressbars)
+ LAZYINITLIST(user.progressbars[bar.loc])
+ var/list/bars = user.progressbars[bar.loc]
+ bars.Add(src)
+ listindex = bars.len
+ animate(bar, pixel_y = 32 + (PROGRESSBAR_HEIGHT * (listindex - 1)), alpha = 255, time = 5, easing = SINE_EASING)
/datum/progressbar/proc/update(progress)
- //to_world("Update [progress] - [goal] - [(progress / goal)] - [((progress / goal) * 100)] - [round(((progress / goal) * 100), 5)]")
- if (!user || !user.client)
+ if(!user || !user.client)
shown = 0
return
- if (user.client != client)
- if (client)
+ if(user.client != client)
+ if(client)
client.images -= bar
- shown = 0
- client = user.client
+ if(user.client)
+ user.client.images += bar
progress = CLAMP(progress, 0, goal)
bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]"
- if (!shown && user.is_preference_enabled(/datum/client_preference/show_progress_bar))
+ if(!shown && user.is_preference_enabled(/datum/client_preference/show_progress_bar))
user.client.images += bar
shown = 1
+
+/datum/progressbar/proc/shiftDown()
+ --listindex
+ var/shiftheight = bar.pixel_y - PROGRESSBAR_HEIGHT
+ animate(bar, pixel_y = shiftheight, time = 5, easing = SINE_EASING)
+
+/datum/progressbar/Destroy()
+ for(var/I in user.progressbars[bar.loc])
+ var/datum/progressbar/P = I
+ if(P != src && P.listindex > listindex)
+ P.shiftDown()
+
+ var/list/bars = user.progressbars[bar.loc]
+ bars.Remove(src)
+ if(!bars.len)
+ LAZYREMOVE(user.progressbars, bar.loc)
+ animate(bar, alpha = 0, time = 5)
+ spawn(5)
+ if(client)
+ client.images -= bar
+ qdel(bar)
+ . = ..()
+
+#undef PROGRESSBAR_HEIGHT
\ No newline at end of file
diff --git a/code/datums/riding.dm b/code/datums/riding.dm
index 4f9513397a..ba96dbc405 100644
--- a/code/datums/riding.dm
+++ b/code/datums/riding.dm
@@ -2,7 +2,7 @@
/datum/riding
var/next_vehicle_move = 0 // Used for move delays
- var/vehicle_move_delay = 2 // Tick delay between movements, lower = faster, higher = slower
+ var/vehicle_move_delay = 2 // Decisecond delay between movements, lower = faster, higher = slower
var/keytype = null // Can give this a type to require the rider to hold the item type inhand to move the ridden atom.
var/nonhuman_key_exemption = FALSE // If true, nonhumans who can't hold keys don't need them, like borgs and simplemobs.
var/key_name = "the keys" // What the 'keys' for the thing being rided on would be called.
@@ -97,11 +97,13 @@
if(world.time < next_vehicle_move)
return
+
next_vehicle_move = world.time + vehicle_move_delay
+
if(keycheck(user))
if(!Process_Spacemove(direction) || !isturf(ridden.loc))
return
- ridden.Move(get_step(ridden, direction))
+ ridden.Move(get_step(ridden, direction), direction, vehicle_move_delay)
handle_vehicle_layer()
handle_vehicle_offsets()
diff --git a/code/datums/supplypacks/medical_vr.dm b/code/datums/supplypacks/medical_vr.dm
index 0538f83867..2d6a340f0a 100644
--- a/code/datums/supplypacks/medical_vr.dm
+++ b/code/datums/supplypacks/medical_vr.dm
@@ -1,3 +1,6 @@
+/datum/supply_pack/med/medical
+ cost = 15
+
/datum/supply_pack/med/medicalbiosuits
contains = list(
/obj/item/clothing/head/bio_hood/scientist = 3,
diff --git a/code/datums/supplypacks/misc.dm b/code/datums/supplypacks/misc.dm
index 7f4f0362db..cb420cd056 100644
--- a/code/datums/supplypacks/misc.dm
+++ b/code/datums/supplypacks/misc.dm
@@ -74,8 +74,17 @@
/obj/item/toy/plushie/squid/blue,
/obj/item/toy/plushie/squid/orange,
/obj/item/toy/plushie/squid/yellow,
- /obj/item/toy/plushie/squid/pink
- )
+ /obj/item/toy/plushie/squid/pink,
+ //VOREStation Add Start
+ /obj/item/toy/plushie/lizardplushie/kobold,
+ /obj/item/toy/plushie/slimeplushie,
+ /obj/item/toy/plushie/box,
+ /obj/item/toy/plushie/borgplushie,
+ /obj/item/toy/plushie/borgplushie/medihound,
+ /obj/item/toy/plushie/borgplushie/scrubpuppy,
+ /obj/item/toy/plushie/foxbear,
+ /obj/item/toy/plushie/nukeplushie)
+ //VOREStation Add End
name = "Plushies Crate"
cost = 15
containertype = /obj/structure/closet/crate
diff --git a/code/datums/uplink/ammunition.dm b/code/datums/uplink/ammunition.dm
index 3ed884316a..8b853aed63 100644
--- a/code/datums/uplink/ammunition.dm
+++ b/code/datums/uplink/ammunition.dm
@@ -65,6 +65,10 @@
name = "Anti-Materiel Rifle ammo box (14.5mm)"
path = /obj/item/weapon/storage/box/sniperammo
+/datum/uplink_item/item/ammo/sniperammo_highvel
+ name = "Anti-Materiel Rifle ammo box (14.5mm sabot)"
+ path = /obj/item/weapon/storage/box/sniperammo/highvel
+
/datum/uplink_item/item/ammo/c545
name = "Rifle Magazine (5.45mm)"
path = /obj/item/ammo_magazine/m545
diff --git a/code/datums/uplink/medical_vr.dm b/code/datums/uplink/medical_vr.dm
index 324398843f..17a3ddf33a 100644
--- a/code/datums/uplink/medical_vr.dm
+++ b/code/datums/uplink/medical_vr.dm
@@ -1,6 +1,26 @@
/**********
* Medical *
**********/
+/datum/uplink_item/item/medical/fire
+ name = "Fire medical kit"
+ item_cost = 10
+ path = /obj/item/weapon/storage/firstaid/fire
+
+/datum/uplink_item/item/medical/toxin
+ name = "Toxin medical kit"
+ item_cost = 10
+ path = /obj/item/weapon/storage/firstaid/toxin
+
+/datum/uplink_item/item/medical/o2
+ name = "Oxygen medical kit"
+ item_cost = 10
+ path = /obj/item/weapon/storage/firstaid/o2
+
+/datum/uplink_item/item/medical/adv
+ name = "Advanced medical kit"
+ item_cost = 10
+ path = /obj/item/weapon/storage/firstaid/adv
+
/datum/uplink_item/item/medical/mre
name = "Meal, Ready to eat (Random)"
item_cost = 5
@@ -26,6 +46,11 @@
item_cost = 5
path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity
+/datum/uplink_item/item/medical/pain
+ name = "Pain injector"
+ item_cost = 5
+ path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/pain
+
/datum/uplink_item/item/medical/brute
name = "Brute injector"
item_cost = 5
@@ -46,12 +71,12 @@
item_cost = 5
path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/oxy
+/datum/uplink_item/item/medical/organ
+ name = "Organ Repair injector"
+ item_cost = 10
+ path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/organ
+
/datum/uplink_item/item/medical/nanites
name = "Healing Nanite pill bottle"
item_cost = 30
path = /obj/item/weapon/storage/pill_bottle/healing_nanites
-
-/datum/uplink_item/item/medical/insiderepair
- name = "Combat organ kit"
- item_cost = 120
- path = /obj/item/weapon/storage/firstaid/insiderepair
diff --git a/code/datums/uplink/tools_vr.dm b/code/datums/uplink/tools_vr.dm
index 5a165f7aac..34794c5cdf 100644
--- a/code/datums/uplink/tools_vr.dm
+++ b/code/datums/uplink/tools_vr.dm
@@ -26,6 +26,11 @@
item_cost = 20
path = /obj/item/modular_computer/laptop/preset/custom_loadout/elite
+/datum/uplink_item/item/tools/inducer
+ name = "Inducer"
+ item_cost = 20
+ path = /obj/item/weapon/inducer/syndicate
+
/datum/uplink_item/item/tools/luxurycapsule
name = "Survival Capsule (Luxury)"
item_cost = 40
@@ -36,6 +41,11 @@
item_cost = 40
path = /obj/item/device/perfect_tele
+/datum/uplink_item/item/tools/uav
+ name = "Recon Skimmer"
+ item_cost = 40
+ path = /obj/item/device/uav
+
/datum/uplink_item/item/tools/barcapsule
name = "Survival Capsule (Bar)"
item_cost = 80
diff --git a/code/datums/wires/smes.dm b/code/datums/wires/smes.dm
index 82d93b9fa8..1751bb6760 100644
--- a/code/datums/wires/smes.dm
+++ b/code/datums/wires/smes.dm
@@ -11,7 +11,7 @@ var/const/SMES_WIRE_FAILSAFES = 16 // Cut to disable failsafes, mend to reenable
/datum/wires/smes/CanUse(var/mob/living/L)
var/obj/machinery/power/smes/buildable/S = holder
- if(S.open_hatch)
+ if(S.panel_open)
return 1
return 0
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index 8d764c13ea..17014d95ed 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -59,22 +59,11 @@
var/damage = 0.0
var/range = 10.0
-
-/obj/effect/list_container
- name = "list container"
-
-/obj/effect/list_container/mobl
- name = "mobl"
- var/master = null
-
- var/list/container = list( )
-
/obj/effect/projection
name = "Projection"
desc = "This looks like a projection of something."
anchored = 1.0
-
/obj/effect/shut_controller
name = "shut controller"
var/moving = null
@@ -144,12 +133,5 @@
user.drop_item()
src.throw_at(target, throw_range, throw_speed, user)
-/obj/effect/stop
- var/victim = null
- icon_state = "empty"
- name = "Geas"
- desc = "You can't resist."
- // name = ""
-
/obj/effect/spawner
name = "object spawner"
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 82872c2f33..b7b66302b5 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -230,13 +230,6 @@
desc = "Heavy-duty switching circuits for power control."
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
-/obj/item/weapon/module/power_control/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
- if (istype(W, /obj/item/device/multitool))
- var/obj/item/weapon/circuitboard/ghettosmes/newcircuit = new/obj/item/weapon/circuitboard/ghettosmes(user.loc)
- qdel(src)
- user.put_in_hands(newcircuit)
-
-
/obj/item/weapon/module/id_auth
name = "\improper ID authentication module"
icon_state = "id_mod"
diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm
index c739ffbf85..d5202bafc2 100644
--- a/code/defines/procs/announce.dm
+++ b/code/defines/procs/announce.dm
@@ -17,22 +17,22 @@
log = do_log
newscast = do_newscast
-/datum/announcement/priority/New(var/do_log = 1, var/new_sound = 'sound/misc/notice2.ogg', var/do_newscast = 0)
+/datum/announcement/priority/New(var/do_log = 1, var/new_sound, var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "Priority Announcement"
announcement_type = "Priority Announcement"
-/datum/announcement/priority/command/New(var/do_log = 1, var/new_sound = 'sound/misc/notice2.ogg', var/do_newscast = 0)
+/datum/announcement/priority/command/New(var/do_log = 1, var/new_sound, var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "[command_name()] Update"
announcement_type = "[command_name()] Update"
-/datum/announcement/priority/security/New(var/do_log = 1, var/new_sound = 'sound/misc/notice2.ogg', var/do_newscast = 0)
+/datum/announcement/priority/security/New(var/do_log = 1, var/new_sound, var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "Security Announcement"
announcement_type = "Security Announcement"
-/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0, zlevel)
+/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0, var/zlevel)
if(!message)
return
var/message_title = new_title ? new_title : title
@@ -52,22 +52,49 @@
Sound(message_sound, zlevels)
Log(message, message_title)
-datum/announcement/proc/Message(var/message as text, var/message_title as text, var/list/zlevels)
- global_announcer.autosay("[message_title]: [message]", announcer ? announcer : ANNOUNCER_NAME, zlevels)
+/datum/announcement/proc/Message(message as text, message_title as text, var/list/zlevels)
+ for(var/mob/M in player_list)
+ if(!istype(M,/mob/new_player) && !isdeaf(M))
+ to_chat(M, "[title]
")
+ to_chat(M, "[message]")
+ if (announcer)
+ to_chat(M, " -[html_encode(announcer)]")
-datum/announcement/minor/Message(var/message as text, var/message_title as text, var/list/zlevels)
- global_announcer.autosay(message, announcer ? announcer : ANNOUNCER_NAME, zlevels)
+// You'll need to update these to_world usages if you want to make these z-level specific ~Aro
+/datum/announcement/minor/Message(message as text, message_title as text)
+ to_world("[message]")
-datum/announcement/priority/Message(var/message as text, var/message_title as text, var/list/zlevels)
- global_announcer.autosay("[message_title]: [message]", announcer ? announcer : ANNOUNCER_NAME, zlevels)
+/datum/announcement/priority/Message(message as text, message_title as text)
+ to_world("[message_title]
")
+ to_world("[message]")
+ if(announcer)
+ to_world(" -[html_encode(announcer)]")
+ to_world("
")
-datum/announcement/priority/command/Message(var/message as text, var/message_title as text, var/list/zlevels)
- global_announcer.autosay("[command_name()] - [message_title]: [message]", ANNOUNCER_NAME, zlevels)
+/datum/announcement/priority/command/Message(message as text, message_title as text, var/list/zlevels)
+ var/command
+ command += "[command_name()] Update
"
+ if (message_title)
+ command += "
[message_title]
"
-datum/announcement/priority/security/Message(var/message as text, var/message_title as text, var/list/zlevels)
- global_announcer.autosay("[message_title]: [message]", ANNOUNCER_NAME, zlevels)
+ command += "
[message]
"
+ command += "
"
+ for(var/mob/M in player_list)
+ if(zlevels && !(get_z(M) in zlevels))
+ continue
+ if(!istype(M,/mob/new_player) && !isdeaf(M))
+ to_chat(M, command)
-datum/announcement/proc/NewsCast(var/message as text, var/message_title as text)
+/datum/announcement/priority/Message(var/message as text, var/message_title as text, var/list/zlevels)
+ global_announcer.autosay("[message_title]: [message]", announcer ? announcer : ANNOUNCER_NAME, channel = "Common", zlevels = zlevels)
+
+/datum/announcement/priority/command/Message(var/message as text, var/message_title as text, var/list/zlevels)
+ global_announcer.autosay("[command_name()] - [message_title]: [message]", ANNOUNCER_NAME, channel = "Common", zlevels = zlevels)
+
+/datum/announcement/priority/security/Message(var/message as text, var/message_title as text, var/list/zlevels)
+ global_announcer.autosay("[message_title]: [message]", ANNOUNCER_NAME, channel = "Common", zlevels = zlevels)
+
+/datum/announcement/proc/NewsCast(var/message as text, var/message_title as text)
if(!newscast)
return
@@ -79,27 +106,27 @@ datum/announcement/proc/NewsCast(var/message as text, var/message_title as text)
news.can_be_redacted = 0
announce_newscaster_news(news)
-datum/announcement/proc/PlaySound(var/message_sound, var/list/zlevels)
- if(!message_sound)
- return
-
+/datum/announcement/proc/PlaySound(var/message_sound, var/list/zlevels)
for(var/mob/M in player_list)
if(zlevels && !(M.z in zlevels))
continue
if(!istype(M,/mob/new_player) && !isdeaf(M))
- M << message_sound
+ M << 'sound/AI/preamble.ogg'
-datum/announcement/proc/Sound(var/message_sound, var/list/zlevels)
+ if(!message_sound)
+ return
+
+ spawn(22) // based on length of preamble.ogg + arbitrary delay
+ for(var/mob/M in player_list)
+ if(zlevels && !(M.z in zlevels))
+ continue
+ if(!istype(M,/mob/new_player) && !isdeaf(M))
+ M << message_sound
+
+/datum/announcement/proc/Sound(var/message_sound, var/list/zlevels)
PlaySound(message_sound, zlevels)
-datum/announcement/priority/Sound(var/message_sound)
- if(message_sound)
- world << message_sound
-
-datum/announcement/priority/command/Sound(var/message_sound)
- PlaySound(message_sound)
-
-datum/announcement/proc/Log(message as text, message_title as text)
+/datum/announcement/proc/Log(message as text, message_title as text)
if(log)
log_game("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]")
message_admins("[key_name_admin(usr)] has made \a [announcement_type].", 1)
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 6c7cb1597b..f403606db2 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -21,14 +21,22 @@
var/requires_power = 1
var/always_unpowered = 0 //this gets overriden to 1 for space in area/New()
- var/power_equip = 1
- var/power_light = 1
- var/power_environ = 1
- var/music = null
- var/used_equip = 0
- var/used_light = 0
- var/used_environ = 0
+ // Power channel status - Is it currently energized?
+ var/power_equip = TRUE
+ var/power_light = TRUE
+ var/power_environ = TRUE
+ // Oneoff power usage - Used once and cleared each power cycle
+ var/oneoff_equip = 0
+ var/oneoff_light = 0
+ var/oneoff_environ = 0
+
+ // Continuous "static" power usage - Do not update these directly!
+ var/static_equip = 0
+ var/static_light = 0
+ var/static_environ = 0
+
+ var/music = null
var/has_gravity = 1
var/secret_name = FALSE // This tells certain things that display areas' names that they shouldn't display this area's name.
var/obj/machinery/power/apc/apc = null
@@ -47,7 +55,7 @@
luminosity = !(dynamic_lighting)
icon_state = ""
-
+
return INITIALIZE_HINT_LATELOAD // Areas tradiationally are initialized AFTER other atoms.
/area/LateInitialize()
@@ -81,7 +89,7 @@
for(var/atom/movable/AM in T)
A.Entered(AM, old_area)
for(var/obj/machinery/M in T)
- M.power_change()
+ M.area_changed(old_area, A)
/area/proc/get_contents()
return contents
@@ -251,33 +259,96 @@
if (fire || eject || party)
updateicon()
-/area/proc/usage(var/chan)
+/area/proc/usage(var/chan, var/include_static = TRUE)
var/used = 0
switch(chan)
if(LIGHT)
- used += used_light
+ used += oneoff_light + (include_static * static_light)
if(EQUIP)
- used += used_equip
+ used += oneoff_equip + (include_static * static_equip)
if(ENVIRON)
- used += used_environ
+ used += oneoff_environ + (include_static * static_environ)
if(TOTAL)
- used += used_light + used_equip + used_environ
+ used += oneoff_light + (include_static * static_light)
+ used += oneoff_equip + (include_static * static_equip)
+ used += oneoff_environ + (include_static * static_environ)
return used
+// Helper for APCs; will generally be called every tick.
/area/proc/clear_usage()
- used_equip = 0
- used_light = 0
- used_environ = 0
+ oneoff_equip = 0
+ oneoff_light = 0
+ oneoff_environ = 0
-/area/proc/use_power(var/amount, var/chan)
+// Use this for a one-time power draw from the area, typically for non-machines.
+/area/proc/use_power_oneoff(var/amount, var/chan)
switch(chan)
if(EQUIP)
- used_equip += amount
+ oneoff_equip += amount
if(LIGHT)
- used_light += amount
+ oneoff_light += amount
if(ENVIRON)
- used_environ += amount
+ oneoff_environ += amount
+ return amount
+// This is used by machines to properly update the area of power changes.
+/area/proc/power_use_change(old_amount, new_amount, chan)
+ use_power_static(new_amount - old_amount, chan) // Simultaneously subtract old_amount and add new_amount.
+
+// Not a proc you want to use directly unless you know what you are doing; see use_power_oneoff above instead.
+/area/proc/use_power_static(var/amount, var/chan)
+ switch(chan)
+ if(EQUIP)
+ static_equip += amount
+ if(LIGHT)
+ static_light += amount
+ if(ENVIRON)
+ static_environ += amount
+
+// This recomputes the continued power usage; can be used for testing or error recovery, but is not called every tick.
+/area/proc/retally_power()
+ static_equip = 0
+ static_light = 0
+ static_environ = 0
+ for(var/obj/machinery/M in src)
+ switch(M.power_channel)
+ if(EQUIP)
+ static_equip += M.get_power_usage()
+ if(LIGHT)
+ static_light += M.get_power_usage()
+ if(ENVIRON)
+ static_environ += M.get_power_usage()
+
+//////////////////////////////////////////////////////////////////
+
+/area/vv_get_dropdown()
+ . = ..()
+ VV_DROPDOWN_OPTION("check_static_power", "Check Static Power")
+
+/area/vv_do_topic(list/href_list)
+ . = ..()
+ IF_VV_OPTION("check_static_power")
+ if(!check_rights(R_DEBUG))
+ return
+ src.check_static_power(usr)
+ href_list["datumrefresh"] = "\ref[src]"
+
+// Debugging proc to report if static power is correct or not.
+/area/proc/check_static_power(var/user)
+ set name = "Check Static Power"
+ var/actual_static_equip = static_equip
+ var/actual_static_light = static_light
+ var/actual_static_environ = static_environ
+ retally_power()
+ if(user)
+ var/list/report = list("[src] ([type]) static power tally:")
+ report += "EQUIP: Actual: [actual_static_equip] Correct: [static_equip] Difference: [actual_static_equip - static_equip]"
+ report += "LIGHT: Actual: [actual_static_light] Correct: [static_light] Difference: [actual_static_light - static_light]"
+ report += "ENVIRON: Actual: [actual_static_environ] Correct: [static_environ] Difference: [actual_static_environ - static_environ]"
+ to_chat(user, report.Join("\n"))
+ return (actual_static_equip == static_equip && actual_static_light == static_light && actual_static_environ == static_environ)
+
+//////////////////////////////////////////////////////////////////
var/list/mob/living/forced_ambiance_list = new
@@ -350,17 +421,20 @@ var/list/mob/living/forced_ambiance_list = new
to_chat(mob, "The sudden appearance of gravity makes you fall to the floor!")
playsound(get_turf(src), "bodyfall", 50, 1)
-/area/proc/prison_break()
+/area/proc/prison_break(break_lights = TRUE, open_doors = TRUE, open_blast_doors = TRUE)
var/obj/machinery/power/apc/theAPC = get_apc()
if(theAPC.operating)
- for(var/obj/machinery/power/apc/temp_apc in src)
- temp_apc.overload_lighting(70)
- for(var/obj/machinery/door/airlock/temp_airlock in src)
- temp_airlock.prison_open()
- for(var/obj/machinery/door/window/temp_windoor in src)
- temp_windoor.open()
- for(var/obj/machinery/door/blast/temp_blast in src)
- temp_blast.open()
+ if(break_lights)
+ for(var/obj/machinery/power/apc/temp_apc in src)
+ temp_apc.overload_lighting(70)
+ if(open_doors)
+ for(var/obj/machinery/door/airlock/temp_airlock in src)
+ temp_airlock.prison_open()
+ for(var/obj/machinery/door/window/temp_windoor in src)
+ temp_windoor.open()
+ if(open_blast_doors)
+ for(var/obj/machinery/door/blast/temp_blast in src)
+ temp_blast.open()
/area/has_gravity()
return has_gravity
diff --git a/code/game/area/areas_vr.dm b/code/game/area/areas_vr.dm
index d422c1cd0f..5396c46e60 100644
--- a/code/game/area/areas_vr.dm
+++ b/code/game/area/areas_vr.dm
@@ -1,6 +1,13 @@
-/area/shuttle_arrived()
- .=..()
- for(var/obj/machinery/telecomms/relay/R in contents)
- R.reset_z()
- for(var/obj/machinery/power/apc/A in contents)
- A.update_area()
+/area
+ var/enter_message
+ var/exit_message
+
+/area/Entered(var/atom/movable/AM, oldLoc)
+ . = ..()
+ if(enter_message && isliving(AM))
+ to_chat(AM, enter_message)
+
+/area/Exited(var/atom/movable/AM, newLoc)
+ . = ..()
+ if(exit_message && isliving(AM))
+ to_chat(AM, exit_message)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 26d8506bf9..5f8ccb3391 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -169,7 +169,7 @@
return found
//All atoms
-/atom/proc/examine(mob/user, var/distance = -1, var/infix = "", var/suffix = "")
+/atom/proc/examine(mob/user, var/infix = "", var/suffix = "")
//This reformat names to get a/an properly working on item descriptions when they are bloody
var/f_name = "\a [src][infix]."
if(src.blood_DNA && !istype(src, /obj/effect/decal))
@@ -182,16 +182,15 @@
else
f_name += "oil-stained [name][infix]."
- to_chat(user, "[bicon(src)] That's [f_name] [suffix]")
- to_chat(user,desc)
+ var/list/output = list("[bicon(src)] That's [f_name] [suffix]", desc)
if(user.client?.examine_text_mode == EXAMINE_MODE_INCLUDE_USAGE)
- to_chat(user, description_info)
+ output += description_info
if(user.client?.examine_text_mode == EXAMINE_MODE_SWITCH_TO_PANEL)
user.client.statpanel = "Examine" // Switch to stat panel
- return distance == -1 || (get_dist(src, user) <= distance)
+ return output
// called by mobs when e.g. having the atom as their machine, pulledby, loc (AKA mob being inside the atom) or buckled var set.
// see code/modules/mob/mob_movement.dm for more.
@@ -587,3 +586,5 @@
>>
"}
+ var/turf/T = get_turf(src)
+ . += "
[ADMIN_COORDJMP(T)]"
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index fa0c99dcb6..87a09d538a 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -1,13 +1,13 @@
/atom/movable
layer = OBJ_LAYER
- appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER //VOREStation Edit
- var/last_move = null
+ appearance_flags = TILE_BOUND|PIXEL_SCALE
+ glide_size = 8
+ var/last_move = null //The direction the atom last moved
var/anchored = 0
// var/elevation = 2 - not used anywhere
var/moving_diagonally
var/move_speed = 10
var/l_move_time = 1
- var/m_flag = 1
var/throwing = 0
var/thrower
var/turf/throw_source = null
@@ -48,83 +48,105 @@
pulledby = null
QDEL_NULL(riding_datum) //VOREStation Add
+
+/atom/movable/vv_get_dropdown()
+ . = ..()
+ VV_DROPDOWN_OPTION("move_atom", "Move To Coordinate")
+
+/atom/vv_do_topic(list/href_list)
+ . = ..()
+ IF_VV_OPTION("move_atom")
+ usr.client.cmd_admin_move_atom(src)
+ href_list["datumrefresh"] = "\ref[src]"
+
/atom/movable/vv_edit_var(var_name, var_value)
if(var_name in GLOB.VVpixelmovement) //Pixel movement is not yet implemented, changing this will break everything irreversibly.
return FALSE
return ..()
////////////////////////////////////////
-// Here's where we rewrite how byond handles movement except slightly different
-// To be removed on step_ conversion
-// All this work to prevent a second bump
-/atom/movable/Move(atom/newloc, direct=0)
- . = FALSE
- if(!newloc || newloc == loc)
- return
-
- if(!direct)
- direct = get_dir(src, newloc)
- set_dir(direct)
-
- if(!loc.Exit(src, newloc))
- return
-
- if(!newloc.Enter(src, src.loc))
- return
-
- if(!check_multi_tile_move_density_dir(direct, locs)) // We're big, and we can't move that way.
- return
-
- // Past this is the point of no return
- if(!locs || locs.len <= 1) // We're not a multi-tile object.
- var/atom/oldloc = loc
- var/area/oldarea = get_area(oldloc)
- var/area/newarea = get_area(newloc)
- loc = newloc
- . = TRUE
- oldloc.Exited(src, newloc)
- if(oldarea != newarea)
- oldarea.Exited(src, newloc)
-
- for(var/i in oldloc)
- if(i == src) // Multi tile objects
- continue
- var/atom/movable/thing = i
- thing.Uncrossed(src)
-
- newloc.Entered(src, oldloc)
- if(oldarea != newarea)
- newarea.Entered(src, oldloc)
-
- for(var/i in loc)
- if(i == src) // Multi tile objects
- continue
- var/atom/movable/thing = i
- thing.Crossed(src)
-
- else if(newloc) // We're a multi-tile object.
- . = doMove(newloc)
-
-//
-////////////////////////////////////////
-
-/atom/movable/Move(atom/newloc, direct = 0)
+/atom/movable/Move(atom/newloc, direct = 0, movetime)
+ // Didn't pass enough info
if(!loc || !newloc)
return FALSE
+
+ // Store this early before we might move, it's used several places
var/atom/oldloc = loc
+ // If we're not moving to the same spot (why? does that even happen?)
if(loc != newloc)
if(!direct)
direct = get_dir(oldloc, newloc)
- if (!(direct & (direct - 1))) //Cardinal move
- . = ..()
- else //Diagonal move, split it into cardinal moves
+ if (IS_CARDINAL(direct)) //Cardinal move
+ // Track our failure if any in this value
+ . = TRUE
+
+ // Face the direction of movement
+ set_dir(direct)
+
+ // Check to make sure we can leave
+ if(!loc.Exit(src, newloc))
+ . = FALSE
+
+ // Check to make sure we can enter, if we haven't already failed
+ if(. && !newloc.Enter(src, src.loc))
+ . = FALSE
+
+ // Check to make sure if we're multi-tile we can move, if we haven't already failed
+ if(. && !check_multi_tile_move_density_dir(direct, locs))
+ . = FALSE
+
+ // Definitely moving if you enter this, no failures so far
+ if(. && locs.len <= 1) // We're not a multi-tile object.
+ var/area/oldarea = get_area(oldloc)
+ var/area/newarea = get_area(newloc)
+ var/old_z = get_z(oldloc)
+ var/dest_z = get_z(newloc)
+
+ // Do The Move
+ glide_for(movetime)
+ loc = newloc
+ . = TRUE
+
+ // So objects can be informed of z-level changes
+ if (old_z != dest_z)
+ onTransitZ(old_z, dest_z)
+
+ // We don't call parent so we are calling this for byond
+ oldloc.Exited(src, newloc)
+ if(oldarea != newarea)
+ oldarea.Exited(src, newloc)
+
+ // Multi-tile objects can't reach here, otherwise you'd need to avoid uncrossing yourself
+ for(var/i in oldloc)
+ var/atom/movable/thing = i
+ // We don't call parent so we are calling this for byond
+ thing.Uncrossed(src)
+
+ // We don't call parent so we are calling this for byond
+ newloc.Entered(src, oldloc)
+ if(oldarea != newarea)
+ newarea.Entered(src, oldloc)
+
+ // Multi-tile objects can't reach here, otherwise you'd need to avoid uncrossing yourself
+ for(var/i in loc)
+ var/atom/movable/thing = i
+ // We don't call parent so we are calling this for byond
+ thing.Crossed(src)
+
+ // We're a multi-tile object (multiple locs)
+ else if(. && newloc)
+ . = doMove(newloc)
+
+ //Diagonal move, split it into cardinal moves
+ else
moving_diagonally = FIRST_DIAG_STEP
var/first_step_dir
// The `&& moving_diagonally` checks are so that a forceMove taking
// place due to a Crossed, Bumped, etc. call will interrupt
// the second half of the diagonal movement, or the second attempt
// at a first half if step() fails because we hit something.
+ glide_for(movetime)
if (direct & NORTH)
if (direct & EAST)
if (step(src, NORTH) && moving_diagonally)
@@ -163,52 +185,51 @@
first_step_dir = WEST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
- if(moving_diagonally == SECOND_DIAG_STEP)
- if(!.)
- set_dir(first_step_dir)
- //else if (!inertia_moving)
- // inertia_next_move = world.time + inertia_move_delay
- // newtonian_move(direct)
+ // If we failed, turn to face the direction of the first step at least
+ if(!. && moving_diagonally == SECOND_DIAG_STEP)
+ set_dir(first_step_dir)
+ // Done, regardless!
moving_diagonally = 0
+ // We return because step above will call Move() and we don't want to do shenanigans back in here again
return
- if(!loc || (loc == oldloc && oldloc != newloc))
+ else if(!loc || (loc == oldloc))
last_move = 0
return
+ // If we moved, call Moved() on ourselves
if(.)
- Moved(oldloc, direct)
+ Moved(oldloc, direct, FALSE, movetime)
- //Polaris stuff
+ // Update timers/cooldown stuff
move_speed = world.time - l_move_time
l_move_time = world.time
- m_flag = 1
- //End
-
- last_move = direct
- set_dir(direct)
- if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
- return FALSE
- //VOREStation Add
- else if(. && riding_datum)
- riding_datum.handle_vehicle_layer()
- riding_datum.handle_vehicle_offsets()
- //VOREStation Add End
+ last_move = direct // The direction you last moved
+ // set_dir(direct) //Don't think this is necessary
//Called after a successful Move(). By this point, we've already moved
-/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
- //if (!inertia_moving)
- // inertia_next_move = world.time + inertia_move_delay
- // newtonian_move(Dir)
- //if (length(client_mobs_in_contents))
- // update_parallax_contents()
-
+/atom/movable/proc/Moved(atom/old_loc, direction, forced = FALSE, movetime)
+ // Handle any buckled mobs on this movable
+ if(has_buckled_mobs())
+ handle_buckled_mob_movement(old_loc, direction, movetime)
+ if(riding_datum)
+ riding_datum.handle_vehicle_layer()
+ riding_datum.handle_vehicle_offsets()
return TRUE
+/atom/movable/set_dir(newdir)
+ . = ..(newdir)
+ if(riding_datum)
+ riding_datum.handle_vehicle_offsets()
+
+/atom/movable/relaymove(mob/user, direction)
+ . = ..()
+ if(riding_datum)
+ riding_datum.handle_ride(user, direction)
+
// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly.
// You probably want CanPass()
/atom/movable/Cross(atom/movable/AM)
- . = TRUE
return CanPass(AM, loc)
/atom/movable/CanPass(atom/movable/mover, turf/target)
@@ -239,72 +260,113 @@
A.Bumped(src)
A.last_bumped = world.time
-/atom/movable/proc/forceMove(atom/destination)
+/atom/movable/proc/forceMove(atom/destination, direction, movetime)
. = FALSE
if(destination)
- . = doMove(destination)
+ . = doMove(destination, direction, movetime)
else
CRASH("No valid destination passed into forceMove")
/atom/movable/proc/moveToNullspace()
return doMove(null)
-/atom/movable/proc/doMove(atom/destination)
- . = FALSE
+/atom/movable/proc/doMove(atom/destination, direction, movetime)
+ var/atom/oldloc = loc
+ var/area/old_area = get_area(oldloc)
+ var/same_loc = oldloc == destination
+
if(destination)
- var/atom/oldloc = loc
- var/same_loc = oldloc == destination
- var/area/old_area = get_area(oldloc)
var/area/destarea = get_area(destination)
+ // Do The Move
+ glide_for(movetime)
+ last_move = isnull(direction) ? 0 : direction
loc = destination
+
+ // Unset this in case it was set in some other proc. We're no longer moving diagonally for sure.
moving_diagonally = 0
+ // We are moving to a different loc
if(!same_loc)
+ // Not moving out of nullspace
if(oldloc)
oldloc.Exited(src, destination)
+ // If it's not the same area, Exited() it
if(old_area && old_area != destarea)
old_area.Exited(src, destination)
- for(var/atom/movable/AM in oldloc)
+
+ // Uncross everything where we left
+ for(var/i in oldloc)
+ var/atom/movable/AM = i
+ if(AM == src)
+ continue
AM.Uncrossed(src)
+
+ // Information about turf and z-levels for source and dest collected
var/turf/oldturf = get_turf(oldloc)
var/turf/destturf = get_turf(destination)
var/old_z = (oldturf ? oldturf.z : null)
var/dest_z = (destturf ? destturf.z : null)
+
+ // So objects can be informed of z-level changes
if (old_z != dest_z)
onTransitZ(old_z, dest_z)
+
+ // Destination atom Entered
destination.Entered(src, oldloc)
+
+ // Entered() the new area if it's not the same area
if(destarea && old_area != destarea)
destarea.Entered(src, oldloc)
- for(var/atom/movable/AM in destination)
+ // We ignore ourselves because if we're multi-tile we might be in both old and new locs
+ for(var/i in destination)
+ var/atom/movable/AM = i
if(AM == src)
continue
AM.Crossed(src, oldloc)
+ // Call our thingy to inform everyone we moved
+ Moved(oldloc, NONE, TRUE)
+
// Break pulling if we are too far to pull now.
if(pulledby && (pulledby.z != src.z || get_dist(pulledby, src) > 1))
pulledby.stop_pulling()
- Moved(oldloc, NONE, TRUE)
- . = TRUE
+ // We moved
+ return TRUE
//If no destination, move the atom into nullspace (don't do this unless you know what you're doing)
- else
- . = TRUE
- if (loc)
- var/atom/oldloc = loc
- var/area/old_area = get_area(oldloc)
- oldloc.Exited(src, null)
- if(old_area)
- old_area.Exited(src, null)
+ else if(oldloc)
loc = null
+ // Uncross everything where we left (no multitile safety like above because we are definitely not still there)
+ for(var/i in oldloc)
+ var/atom/movable/AM = i
+ AM.Uncrossed(src)
+
+ // Exited() our loc and area
+ oldloc.Exited(src, null)
+ if(old_area)
+ old_area.Exited(src, null)
+
+ // We moved
+ return TRUE
+
/atom/movable/proc/onTransitZ(old_z,new_z)
GLOB.z_moved_event.raise_event(src, old_z, new_z)
for(var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care.
var/atom/movable/AM = item
AM.onTransitZ(old_z,new_z)
+
+/atom/movable/proc/glide_for(movetime)
+ if(movetime)
+ glide_size = WORLD_ICON_SIZE/max(DS2TICKS(movetime), 1)
+ spawn(movetime)
+ glide_size = initial(glide_size)
+ else
+ glide_size = initial(glide_size)
+
/////////////////////////////////////////////////////////////////
//called when src is thrown into hit_atom
diff --git a/code/game/atoms_movable_vr.dm b/code/game/atoms_movable_vr.dm
index 0cc6d144be..d529122029 100644
--- a/code/game/atoms_movable_vr.dm
+++ b/code/game/atoms_movable_vr.dm
@@ -1,12 +1,2 @@
/atom/movable/proc/Bump_vr(var/atom/A, yes)
return
-
-/atom/movable/set_dir(newdir)
- . = ..(newdir)
- if(riding_datum)
- riding_datum.handle_vehicle_offsets()
-
-/atom/movable/relaymove(mob/user, direction)
- . = ..()
- if(riding_datum)
- riding_datum.handle_ride(user, direction)
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index 7f963710a1..93d9ff4289 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -24,6 +24,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
var/list/purchased_powers_history = list() //Used for round-end report, includes respec uses too.
var/last_shriek = null // world.time when the ling last used a shriek.
var/next_escape = 0 // world.time when the ling can next use Escape Restraints
+ var/thermal_sight = FALSE // Is our Vision Augmented? With thermals?
/datum/changeling/New(var/gender=FEMALE)
..()
@@ -64,8 +65,8 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
if(!mind) return
if(!mind.changeling) mind.changeling = new /datum/changeling(gender)
- verbs += /datum/changeling/proc/EvolutionMenu
- verbs += /mob/proc/changeling_respec
+ verbs.Add(/datum/changeling/proc/EvolutionMenu)
+ verbs.Add(/mob/proc/changeling_respec)
add_language("Changeling")
var/lesser_form = !ishuman(src)
@@ -84,7 +85,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
if(P.isVerb)
if(lesser_form && !P.allowduringlesserform) continue
if(!(P in src.verbs))
- src.verbs += P.verbpath
+ verbs.Add(P.verbpath)
if(P.make_hud_button)
if(!src.ability_master)
src.ability_master = new /obj/screen/movable/ability_master(src)
@@ -111,7 +112,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
if(!mind || !mind.changeling) return
for(var/datum/power/changeling/P in mind.changeling.purchased_powers)
if(P.isVerb)
- verbs -= P.verbpath
+ verbs.Remove(P.verbpath)
var/obj/screen/ability/verb_based/changeling/C = ability_master.get_ability_by_proc_ref(P.verbpath)
if(C)
ability_master.remove_ability(C)
diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm
index a76311c335..e532396176 100644
--- a/code/game/gamemodes/changeling/powers/absorb.dm
+++ b/code/game/gamemodes/changeling/powers/absorb.dm
@@ -3,11 +3,11 @@
desc = "Permits us to syphon the DNA from a human. They become one with us, and we become stronger if they were of our kind."
ability_icon_state = "ling_absorb_dna"
genomecost = 0
- verbpath = /mob/proc/changeling_absorb_dna
+ verbpath = /mob/living/proc/changeling_absorb_dna
//Absorbs the victim's DNA. Requires a strong grip on the victim.
//Doesn't cost anything as it's the most basic ability.
-/mob/proc/changeling_absorb_dna()
+/mob/living/proc/changeling_absorb_dna()
set category = "Changeling"
set name = "Absorb DNA"
@@ -67,8 +67,7 @@
to_chat(src, "We have absorbed [T]!")
src.visible_message("[src] sucks the fluids from [T]!")
to_chat(T, "You have been absorbed by the changeling!")
- if(src.nutrition < 400)
- src.nutrition = min((src.nutrition + T.nutrition), 400)
+ adjust_nutrition(T.nutrition)
changeling.chem_charges += 10
if(changeling.readapts <= 0)
changeling.readapts = 0 //SANITYYYYYY
diff --git a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm
index e4eb45a9e9..6e29bf939c 100644
--- a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm
+++ b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm
@@ -1,12 +1,11 @@
-//Augmented Eyesight: Gives you thermal and night vision - bye bye, flashlights. Also, high DNA cost because of how powerful it is.
+//Augmented Eyesight: Gives you thermal vision. Also, higher DNA cost because of how powerful it is.
/datum/power/changeling/augmented_eyesight
name = "Augmented Eyesight"
desc = "Creates heat receptors in our eyes and dramatically increases light sensing ability."
- helptext = "Grants us night vision and thermal vision. It may be toggled on or off. We will become more vulnerable to flash-based devices while active."
+ helptext = "Grants us thermal vision. It may be toggled on or off. We will become more vulnerable to flash-based devices while active."
ability_icon_state = "ling_augmented_eyesight"
genomecost = 2
- var/active = 0 //Whether or not vision is enhanced
verbpath = /mob/proc/changeling_augmented_eyesight
/mob/proc/changeling_augmented_eyesight()
@@ -17,23 +16,22 @@
var/datum/changeling/changeling = changeling_power(5,0,100,CONSCIOUS)
if(!changeling)
return 0
- src.mind.changeling.chem_charges -= 5
- src.sight |= SEE_MOBS
- /*
+
var/mob/living/carbon/human/C = src
- active = !active
+ changeling.thermal_sight = !changeling.thermal_sight
+
+ var/active = changeling.thermal_sight
+
if(active)
- to_chat(C, "We feel a minute twitch in our eyes, and darkness creeps away.")
- C.sight |= SEE_MOBS
- C.permanent_sight_flags |= SEE_MOBS
- C.see_in_dark = 8
- C.dna.species.invis_sight = SEE_INVISIBLE_MINIMUM
+ src.mind.changeling.chem_charges -= 5
+ to_chat(C, "We feel a minute twitch in our eyes, and a hidden layer to the world is revealed.")
+ C.add_modifier(/datum/modifier/changeling/thermal_sight, 0, src)
+// C.permanent_sight_flags |= SEE_MOBS
+// C.dna.species.invis_sight = SEE_INVISIBLE_MINIMUM
else
- to_chat(C, "Our vision dulls. Shadows gather.")
- C.sight &= ~SEE_MOBS
- C.permanent_sight_flags &= ~SEE_MOBS
- C.see_in_dark = 0
- C.dna.species.invis_sight = initial(user.dna.species.invis_sight)
+ to_chat(C, "Our vision dulls.")
+ C.remove_modifiers_of_type(/datum/modifier/changeling/thermal_sight)
+// C.permanent_sight_flags &= ~SEE_MOBS
+// C.dna.species.invis_sight = initial(user.dna.species.invis_sight)
return 1
- */
\ No newline at end of file
diff --git a/code/game/gamemodes/changeling/powers/endoarmor.dm b/code/game/gamemodes/changeling/powers/endoarmor.dm
index 536aef26ce..d62c52141a 100644
--- a/code/game/gamemodes/changeling/powers/endoarmor.dm
+++ b/code/game/gamemodes/changeling/powers/endoarmor.dm
@@ -14,7 +14,6 @@
on_expired_text = "Our protective armor underneath our skin fades as we absorb it."
max_health_flat = 50
-//Increases macimum chemical storage
/mob/proc/changeling_endoarmor()
if(ishuman(src))
var/mob/living/carbon/human/H = src
diff --git a/code/game/gamemodes/changeling/powers/fake_death.dm b/code/game/gamemodes/changeling/powers/fake_death.dm
index cd34ebfc5c..65fce3cecf 100644
--- a/code/game/gamemodes/changeling/powers/fake_death.dm
+++ b/code/game/gamemodes/changeling/powers/fake_death.dm
@@ -43,7 +43,10 @@
spawn(rand(2 MINUTES, 4 MINUTES))
//The ling will now be able to choose when to revive
- src.verbs += /mob/proc/changeling_revive
+ verbs.Add(/mob/proc/changeling_revive)
+
+ new /obj/changeling_revive_holder(src)
+
to_chat(src, "We are ready to rise. Use the Revive verb when you are ready.")
feedback_add_details("changeling_powers","FD")
diff --git a/code/game/gamemodes/changeling/powers/respec.dm b/code/game/gamemodes/changeling/powers/respec.dm
index a50a41269f..935092ff65 100644
--- a/code/game/gamemodes/changeling/powers/respec.dm
+++ b/code/game/gamemodes/changeling/powers/respec.dm
@@ -17,6 +17,7 @@
ling_datum.purchased_powers = list() //Then wipe all the powers we bought.
ling_datum.geneticpoints = ling_datum.max_geneticpoints //Now refund our points to the maximum.
ling_datum.chem_recharge_rate = 0.5 //If glands were bought, revert that upgrade.
+ ling_datum.thermal_sight = FALSE
src.mind.changeling.recursive_enhancement = 0 //Ensures this is cleared
ling_datum.chem_storage = 50
diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm
index 61a061170e..420b1173c8 100644
--- a/code/game/gamemodes/changeling/powers/revive.dm
+++ b/code/game/gamemodes/changeling/powers/revive.dm
@@ -82,10 +82,28 @@
C.set_stat(CONSCIOUS)
C.forbid_seeing_deadchat = FALSE
C.timeofdeath = null
- src.verbs -= /mob/proc/changeling_revive
+ verbs.Remove(/mob/proc/changeling_revive)
// re-add our changeling powers
C.make_changeling()
-
-
return 1
+
+//Revive from revival stasis, but one level removed, as the tab refuses to update. Placed in its own tab to avoid hyper-exploding the original tab through the same name being used.
+
+/obj/changeling_revive_holder
+ name = "strange object"
+ desc = "Please report this object's existence to the dev team! You shouldn't see it."
+ mouse_opacity = FALSE
+ alpha = 1
+
+/obj/changeling_revive_holder/verb/ling_revive()
+ set src = usr.contents
+ set category = "Regenerate"
+ set name = "Revive"
+ set desc = "We are ready to revive ourselves on command."
+
+ if(iscarbon(usr))
+ var/mob/living/carbon/C = usr
+ C.changeling_revive()
+
+ qdel(src)
diff --git a/code/game/gamemodes/changeling/powers/unfat_sting.dm b/code/game/gamemodes/changeling/powers/unfat_sting.dm
index ece0d50f46..34ef7b7032 100644
--- a/code/game/gamemodes/changeling/powers/unfat_sting.dm
+++ b/code/game/gamemodes/changeling/powers/unfat_sting.dm
@@ -13,7 +13,6 @@
if(!T) return 0
add_attack_logs(src,T,"Unfat sting (changeling)")
to_chat(T, "you feel a small prick as stomach churns violently and you become to feel skinnier.")
- T.overeatduration = 0
- T.nutrition -= 100
+ T.adjust_nutrition(-100)
feedback_add_details("changeling_powers","US")
return 1
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 1cf204b015..c324a6f092 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -84,9 +84,9 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
..()
examine(mob/user)
- ..()
+ . = ..()
if(iscultist(user))
- to_chat(user, "This spell circle reads: [word1] [word2] [word3].")
+ . += "This spell circle reads: [word1] [word2] [word3]."
attackby(I as obj, user as mob)
@@ -422,10 +422,11 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
return
examine(mob/user)
+ . = ..()
if(!iscultist(user))
- to_chat(user, "An old, dusty tome with frayed edges and a sinister looking cover.")
+ . += "An old, dusty tome with frayed edges and a sinister looking cover."
else
- to_chat(user, "The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood. Contains the details of every ritual his followers could think of. Most of these are useless, though.")
+ . += "The scriptures of Nar-Sie, The One Who Sees, The Geometer of Blood. Contains the details of every ritual his followers could think of. Most of these are useless, though."
/obj/item/weapon/book/tome/cultify()
return
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index d08c49d6a8..42e6a6ddd0 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -306,7 +306,7 @@ var/global/list/additional_antag_types = list()
var/escaped_on_pod_5 = 0
var/escaped_on_shuttle = 0
- var/list/area/escape_locations = list(/area/shuttle/escape/centcom, /area/shuttle/escape_pod1/centcom, /area/shuttle/escape_pod2/centcom, /area/shuttle/escape_pod3/centcom, /area/shuttle/escape_pod5/centcom)
+ var/list/area/escape_locations = list(/area/shuttle/escape, /area/shuttle/escape_pod1/centcom, /area/shuttle/escape_pod2/centcom, /area/shuttle/escape_pod3/centcom, /area/shuttle/escape_pod5/centcom) //VOREStation Edit
for(var/mob/M in player_list)
if(M.client)
diff --git a/code/game/gamemodes/malfunction/malf_hardware.dm b/code/game/gamemodes/malfunction/malf_hardware.dm
index 864ba0722d..8206f9cd5e 100644
--- a/code/game/gamemodes/malfunction/malf_hardware.dm
+++ b/code/game/gamemodes/malfunction/malf_hardware.dm
@@ -64,4 +64,4 @@
T.maxhealth = round(initial(T.maxhealth) * 1.4)
T.shot_delay = round(initial(T.shot_delay) / 2)
T.auto_repair = 1
- T.active_power_usage = round(initial(T.active_power_usage) * 5)
\ No newline at end of file
+ T.update_active_power_usage(round(initial(T.active_power_usage) * 5))
\ No newline at end of file
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index de4bf442af..0b0b8d014c 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -55,7 +55,7 @@
var/obj/effect/meteor/M = new Me(pickedstart)
M.dest = pickedgoal
spawn(0)
- walk_towards(M, M.dest, 1)
+ walk_towards(M, M.dest, 3) //VOREStation Edit - Slower Meteors
return
/proc/spaceDebrisStartLoc(startSide, Z)
@@ -138,14 +138,13 @@
. = ..() //process movement...
- if(.)//.. if did move, ram the turf we get in
- var/turf/T = get_turf(loc)
- ram_turf(T)
+/obj/effect/meteor/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
+ var/turf/T = get_turf(loc)
+ ram_turf(T)
- if(prob(10) && !istype(T, /turf/space))//randomly takes a 'hit' from ramming
- get_hit()
-
- return .
+ if(prob(10) && !istype(T, /turf/space)) //randomly takes a 'hit' from ramming
+ get_hit()
/obj/effect/meteor/Destroy()
walk(src,0) //this cancels the walk_towards() proc
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index b2bd6b80e4..5447431279 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -51,10 +51,10 @@
icon_state = "pinonfar"
/obj/item/weapon/pinpointer/examine(mob/user)
- ..(user)
+ . = ..()
for(var/obj/machinery/nuclearbomb/bomb in machines)
if(bomb.timing)
- to_chat(user, "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]")
+ . += "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]"
diff --git a/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm b/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm
index 3e3e055ad9..82138988b5 100644
--- a/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm
+++ b/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm
@@ -23,8 +23,8 @@
uses = 1
/obj/item/weapon/disposable_teleporter/examine(mob/user)
- ..()
- to_chat(user, "[uses] uses remaining.")
+ . = ..()
+ . += "[uses] uses remaining."
/obj/item/weapon/disposable_teleporter/attack_self(mob/user as mob)
if(!uses)
diff --git a/code/game/gamemodes/technomancer/spells/energy_siphon.dm b/code/game/gamemodes/technomancer/spells/energy_siphon.dm
index 1bfcb4e2d2..21f7c6e1e7 100644
--- a/code/game/gamemodes/technomancer/spells/energy_siphon.dm
+++ b/code/game/gamemodes/technomancer/spells/energy_siphon.dm
@@ -83,7 +83,7 @@
#define SIPHON_CORE_TO_ENERGY 0.5
// This is called every tick, so long as a link exists between the target and the Technomancer.
-/obj/item/weapon/spell/energy_siphon/proc/siphon(atom/movable/siphoning, mob/user)
+/obj/item/weapon/spell/energy_siphon/proc/siphon(atom/movable/siphoning, mob/living/user)
var/list/things_to_drain = things_to_siphon // Temporary list copy of what we're gonna steal from.
var/charge_to_give = 0 // How much energy to give to the Technomancer at the end.
var/flow_remaining = calculate_spell_power(flow_rate)
@@ -141,7 +141,7 @@
if( (core.max_energy - core.energy) < charge_to_give ) // We have some overflow, if this is true.
if(user.isSynthetic()) // Let's do something with it, if we're a robot.
charge_to_give = charge_to_give - (core.max_energy - core.energy)
- user.nutrition = min(user.nutrition + (charge_to_give / SIPHON_FBP_TO_ENERGY), 400)
+ user.adjust_nutrition(charge_to_give / SIPHON_FBP_TO_ENERGY)
to_chat(user, "Redirected energy to internal microcell.")
else
to_chat(user, "Stolen [charge_to_give * CELLRATE] kJ.")
diff --git a/code/game/gamemodes/technomancer/spells/mark_recall.dm b/code/game/gamemodes/technomancer/spells/mark_recall.dm
index 0d35bce53a..1d7088af4a 100644
--- a/code/game/gamemodes/technomancer/spells/mark_recall.dm
+++ b/code/game/gamemodes/technomancer/spells/mark_recall.dm
@@ -7,7 +7,7 @@
obj_path = /obj/item/weapon/spell/mark
ability_icon_state = "tech_mark"
category = UTILITY_SPELLS
-
+//VOREStation Add - Multiple technomancer support
/datum/technomancer_marker
var/weakref/U
var/image/I
@@ -32,7 +32,7 @@
//This is global, to avoid looping through a list of all objects, or god forbid, looping through world.
GLOBAL_LIST_INIT(mark_spells, list())
-
+//VOREStation Add End
/obj/item/weapon/spell/mark
name = "mark"
icon_state = "mark"
@@ -45,6 +45,7 @@ GLOBAL_LIST_INIT(mark_spells, list())
to_chat(user, "You can't teleport here!")
return 0
if(pay_energy(1000))
+ //VOREStation Add - Multiple technomancer support
var/datum/technomancer_marker/marker = GLOB.mark_spells[weakref(user)]
//They have one in the list
if(istype(marker))
@@ -54,6 +55,7 @@ GLOBAL_LIST_INIT(mark_spells, list())
else
to_chat(user, "You mark \the [get_turf(user)] under you.")
GLOB.mark_spells[weakref(user)] = new /datum/technomancer_marker(user)
+ //VOREStation Add End
adjust_instability(5)
return 1
else
@@ -81,7 +83,7 @@ GLOBAL_LIST_INIT(mark_spells, list())
/obj/item/weapon/spell/recall/on_use_cast(var/mob/living/user)
if(pay_energy(3000))
- var/datum/technomancer_marker/marker = GLOB.mark_spells[weakref(user)]
+ var/datum/technomancer_marker/marker = GLOB.mark_spells[weakref(user)] //VOREStation Add - Multiple technomancer support
if(!istype(marker))
to_chat(user, "There's no Mark!")
return 0
@@ -104,7 +106,7 @@ GLOBAL_LIST_INIT(mark_spells, list())
time_left--
sleep(1 SECOND)
- var/turf/target_turf = marker.T
+ var/turf/target_turf = marker.T //VOREStation Edit - Multiple technomancer support
var/turf/old_turf = get_turf(user)
for(var/obj/item/weapon/grab/G in user.contents) // People the Technomancer is grabbing come along for the ride.
diff --git a/code/game/jobs/job/captain_vr.dm b/code/game/jobs/job/captain_vr.dm
index ea9f8ebed9..f08a1b4079 100644
--- a/code/game/jobs/job/captain_vr.dm
+++ b/code/game/jobs/job/captain_vr.dm
@@ -5,6 +5,8 @@
/datum/job/hop
disallow_jobhop = TRUE
pto_type = PTO_CIVILIAN
+ departments = list(DEPARTMENT_COMMAND, DEPARTMENT_CIVILIAN)
+ departments_managed = list(DEPARTMENT_CIVILIAN, DEPARTMENT_CARGO, DEPARTMENT_PLANET)
alt_titles = list("Crew Resources Officer" = /datum/alt_title/cro,
"Deputy Director" = /datum/alt_title/deputy_director)
diff --git a/maps/southern_cross/southern_cross_jobs_vr.dm b/code/game/jobs/job/exploration_vr.dm
similarity index 82%
rename from maps/southern_cross/southern_cross_jobs_vr.dm
rename to code/game/jobs/job/exploration_vr.dm
index ca11728189..987041de61 100644
--- a/maps/southern_cross/southern_cross_jobs_vr.dm
+++ b/code/game/jobs/job/exploration_vr.dm
@@ -39,16 +39,16 @@ var/const/SAR =(1<<14)
faction = "Station"
total_positions = 1
spawn_positions = 1
- supervisors = "the research director"
+ supervisors = "the Head of Personnel"
selection_color = "#d6d05c"
- economic_modifier = 7
+ economic_modifier = 8
minimal_player_age = 7
pto_type = PTO_EXPLORATION
- access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_research, access_gateway)
- minimal_access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_research, access_gateway)
+ access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_gateway)
+ minimal_access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_gateway)
outfit_type = /decl/hierarchy/outfit/job/pathfinder
- job_description = " The Pathfinder's job is to lead and manage expeditions, and is the primary authority on all off-station expeditions."
+ job_description = "The Pathfinder's job is to lead and manage expeditions, and is the primary authority on all off-station expeditions."
/datum/alt_title/pathfinder
title = "Pathfinder"
@@ -59,9 +59,9 @@ var/const/SAR =(1<<14)
departments = list(DEPARTMENT_PLANET)
department_flag = MEDSCI
faction = "Station"
- total_positions = 2
- spawn_positions = 2
- supervisors = "the pathfinder and the head of personnel"
+ total_positions = 4
+ spawn_positions = 4
+ supervisors = "the Pathfinder and the Head of Personnel"
selection_color = "#999440"
economic_modifier = 5
minimal_player_age = 3
@@ -82,12 +82,12 @@ var/const/SAR =(1<<14)
faction = "Station"
total_positions = 3
spawn_positions = 3
- supervisors = "the pathfinder and the research director"
+ supervisors = "the Pathfinder and the Head of Personnel"
selection_color = "#999440"
economic_modifier = 6
pto_type = PTO_EXPLORATION
- access = list(access_explorer, access_research)
- minimal_access = list(access_explorer, access_research)
+ access = list(access_explorer, access_external_airlocks, access_eva)
+ minimal_access = list(access_explorer, access_external_airlocks, access_eva)
outfit_type = /decl/hierarchy/outfit/job/explorer2
job_description = "An Explorer searches for interesting things, and returns them to the station."
@@ -97,12 +97,12 @@ var/const/SAR =(1<<14)
/datum/job/sar
title = "Field Medic"
flag = SAR
- departments = list(DEPARTMENT_PLANET)
+ departments = list(DEPARTMENT_PLANET, DEPARTMENT_MEDICAL)
department_flag = MEDSCI
faction = "Station"
total_positions = 2
spawn_positions = 2
- supervisors = "the pathfinder and the chief medical officer"
+ supervisors = "the Pathfinder and the Chief Medical Officer"
selection_color = "#999440"
economic_modifier = 6
minimal_player_age = 3
diff --git a/code/game/jobs/job/science_vr.dm b/code/game/jobs/job/science_vr.dm
index c9092753e7..d1bd15c364 100644
--- a/code/game/jobs/job/science_vr.dm
+++ b/code/game/jobs/job/science_vr.dm
@@ -5,11 +5,11 @@
access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue,
access_tox_storage, access_teleporter, access_sec_doors,
access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage,
- access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva, access_network, access_maint_tunnels) //Yawn added "access_maint_tunnels"
+ access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva, access_network) //YW Edit access_gateway
minimal_access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue,
access_tox_storage, access_teleporter, access_sec_doors,
access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage,
- access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva, access_network, access_maint_tunnels)
+ access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva, access_network) //YW Edit access_gateway
/datum/job/scientist
spawn_positions = 5
diff --git a/code/game/jobs/job/security_vr.dm b/code/game/jobs/job/security_vr.dm
index e969dcff56..9e55d807b0 100644
--- a/code/game/jobs/job/security_vr.dm
+++ b/code/game/jobs/job/security_vr.dm
@@ -5,11 +5,11 @@
access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory,
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
access_research, access_engine, access_mining, access_construction, access_mailsorting,
- access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_external_airlocks)
+ access_heads, access_hos, access_RC_announce, access_keycard_auth, access_external_airlocks)
minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory,
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
access_research, access_engine, access_mining, access_construction, access_mailsorting,
- access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_external_airlocks)
+ access_heads, access_hos, access_RC_announce, access_keycard_auth, access_external_airlocks)
/datum/job/warden
pto_type = PTO_SECURITY
diff --git a/code/game/machinery/CableLayer.dm b/code/game/machinery/CableLayer.dm
index aa6316033c..d954a80b29 100644
--- a/code/game/machinery/CableLayer.dm
+++ b/code/game/machinery/CableLayer.dm
@@ -13,9 +13,9 @@
cable.amount = 100
..()
-/obj/machinery/cablelayer/Move(new_turf,M_Dir)
- ..()
- layCable(new_turf,M_Dir)
+/obj/machinery/cablelayer/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
+ layCable(loc,direction)
/obj/machinery/cablelayer/attack_hand(mob/user as mob)
if(!cable&&!on)
@@ -49,8 +49,8 @@
to_chat(usr, "There's no more cable on the reel.")
/obj/machinery/cablelayer/examine(mob/user)
- ..()
- to_chat(user, "\The [src]'s cable reel has [cable.amount] length\s left.")
+ . = ..()
+ . += "[src]'s cable reel has [cable.amount] length\s left."
/obj/machinery/cablelayer/proc/load_cable(var/obj/item/stack/cable_coil/CC)
if(istype(CC) && CC.amount)
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index 5de1543426..a410ad79b3 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -67,7 +67,13 @@
var/mob/living/carbon/human/M = locate(/mob/living/carbon/human, src.loc)
if(M.lying)
victim = M
- icon_state = M.pulse ? "table2-active" : "table2-idle"
+ if(M.pulse)
+ if(M.stat)
+ icon_state = "table2-sleep"
+ else
+ icon_state = "table2-active"
+ else
+ icon_state = "table2-dead"
return 1
victim = null
icon_state = "table2-idle"
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index e1c368a1c9..70fd190afe 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -207,8 +207,6 @@
available_chemicals.Cut()
available_chemicals = base_chemicals.Copy()
- idle_power_usage = initial(idle_power_usage)
- active_power_usage = initial(active_power_usage)
for(var/obj/item/weapon/stock_parts/P in component_parts)
if(istype(P, /obj/item/weapon/stock_parts/capacitor))
@@ -216,8 +214,8 @@
cap_rating = max(1, round(cap_rating / 2))
- idle_power_usage /= cap_rating
- active_power_usage /= cap_rating
+ update_idle_power_usage(initial(idle_power_usage) / cap_rating)
+ update_active_power_usage(initial(active_power_usage) / cap_rating)
if(!limited)
for(var/obj/item/weapon/stock_parts/P in component_parts)
diff --git a/code/game/machinery/airconditioner_vr.dm b/code/game/machinery/airconditioner_vr.dm
index 90916c82ca..892c6b4929 100644
--- a/code/game/machinery/airconditioner_vr.dm
+++ b/code/game/machinery/airconditioner_vr.dm
@@ -25,8 +25,9 @@
default_apply_parts()
/obj/machinery/power/thermoregulator/examine(mob/user)
- if(..(user,2))
- to_chat(user, "There is a small display that reads \"[convert_k2c(target_temp)]C\".")
+ . = ..()
+ if(get_dist(user, src) <= 2)
+ . += "There is a small display that reads \"[convert_k2c(target_temp)]C\"."
/obj/machinery/power/thermoregulator/attackby(obj/item/I, mob/user)
if(I.is_screwdriver())
diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm
index 3e2cf0deb4..2d5d0a8747 100644
--- a/code/game/machinery/atmoalter/meter.dm
+++ b/code/game/machinery/atmoalter/meter.dm
@@ -77,24 +77,22 @@
radio_connection.post_signal(src, signal)
/obj/machinery/meter/examine(mob/user)
- var/t = "A gas flow meter. "
+ . = ..()
if(get_dist(user, src) > 3 && !(istype(user, /mob/living/silicon/ai) || istype(user, /mob/observer/dead)))
- t += "You are too far away to read it."
+ . += "You are too far away to read it."
else if(stat & (NOPOWER|BROKEN))
- t += "The display is off."
+ . += "The display is off."
- else if(src.target)
+ else if(target)
var/datum/gas_mixture/environment = target.return_air()
if(environment)
- t += "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)]K ([round(environment.temperature-T0C,0.01)]°C)"
+ . += "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)]K ([round(environment.temperature-T0C,0.01)]°C)"
else
- t += "The sensor error light is blinking."
+ . += "The sensor error light is blinking."
else
- t += "The connect error light is blinking."
-
- to_chat(user,t)
+ . += "The connect error light is blinking."
/obj/machinery/meter/Click()
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 653d3bb374..facb9e4402 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -27,6 +27,8 @@
var/datum/wires/autolathe/wires = null
+ var/filtertext
+
/obj/machinery/autolathe/New()
..()
wires = new(src)
@@ -72,11 +74,14 @@
material_bottom += "[stored_material[material]]/[storage_capacity[material]] | "
dat += "[material_top.Join()][material_bottom.Join()]
"
+ dat += "Filter: [filtertext ? filtertext : "None Set"]
"
dat += "Printable Designs
"
for(var/datum/category_item/autolathe/R in current_category.items)
if(R.hidden && !hacked)
continue
+ if(filtertext && findtext(R.name, filtertext) == 0)
+ continue
var/can_make = 1
var/list/material_string = list()
var/list/multiplier_string = list()
@@ -108,12 +113,14 @@
multiplier_string += "\[x[i]\]"
multiplier_string += "\[x[max_sheets]\]"
- dat += "| [R.hidden ? "*" : ""][can_make ? "" : ""][R.name][can_make ? "" : ""][R.hidden ? "*" : ""][multiplier_string.Join()] | [material_string.Join()] |
"
+ dat += "| [R.hidden ? "*" : ""][can_make ? "" : ""][R.name][can_make ? "" : ""][R.hidden ? "*" : ""][multiplier_string.Join()] | [material_string.Join()] |
"
dat += "
"
- user << browse(dat.Join(), "window=autolathe")
- onclose(user, "autolathe")
+ dat = jointext(dat, null)
+ var/datum/browser/popup = new(user, "autolathe", "Autolathe Production Menu", 550, 700)
+ popup.set_content(dat)
+ popup.open()
/obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(busy)
@@ -229,6 +236,16 @@
to_chat(usr, "The autolathe is busy. Please wait for completion of previous operation.")
return
+ else if(href_list["setfilter"])
+ var/filterstring = input(usr, "Input a filter string, or blank to not filter:", "Design Filter", filtertext) as null|text
+ if(!Adjacent(usr))
+ return
+ if(isnull(filterstring)) //Clicked Cancel
+ return
+ if(filterstring == "") //Cleared value
+ filtertext = null
+ filtertext = sanitize(filterstring, 25)
+
if(href_list["change_category"])
var/choice = input("Which category do you wish to display?") as null|anything in machine_recipes.categories
diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm
index de52a9cc06..6f62b2e056 100644
--- a/code/game/machinery/biogenerator.dm
+++ b/code/game/machinery/biogenerator.dm
@@ -1,7 +1,7 @@
/obj/machinery/biogenerator
name = "biogenerator"
desc = "Converts plants into biomass, which can be used for fertilizer and sort-of-synthetic products."
- icon = 'icons/obj/biogenerator.dmi'
+ icon = 'icons/obj/biogenerator_vr.dmi' //VOREStation Edit
icon_state = "biogen-stand"
density = 1
anchored = 1
diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm
index f7e4749fe3..d40a89c202 100644
--- a/code/game/machinery/bioprinter.dm
+++ b/code/game/machinery/bioprinter.dm
@@ -4,7 +4,7 @@
/obj/machinery/organ_printer
name = "organ printer"
desc = "It's a machine that prints organs."
- icon = 'icons/obj/surgery.dmi'
+ icon = 'icons/obj/surgery_vr.dmi' //VOREStation Edit
icon_state = "bioprinter"
anchored = 1
@@ -69,11 +69,13 @@
return ..()
/obj/machinery/organ_printer/update_icon()
- overlays.Cut()
+ //VOREStation Edit
+ cut_overlays()
if(panel_open)
- overlays += "bioprinter_panel_open"
+ add_overlay("bioprinter_panel_open")
if(printing)
- overlays += "bioprinter_working"
+ add_overlay("bioprinter_working")
+ //VOREStation Edit End
/obj/machinery/organ_printer/New()
..()
@@ -87,9 +89,9 @@
. = ..()
var/biomass = get_biomass_volume()
if(biomass)
- to_chat(user, "It is loaded with [biomass] units of biomass.")
+ . += "It is loaded with [biomass] units of biomass."
else
- to_chat(user, "It is not loaded with any biomass.")
+ . += "It is not loaded with any biomass."
/obj/machinery/organ_printer/RefreshParts()
// Print Delay updating
@@ -161,7 +163,7 @@
container.reagents.remove_reagent("biomass", possible_list[choice][2])
- use_power = USE_POWER_ACTIVE
+ update_use_power(USE_POWER_ACTIVE)
printing = 1
update_icon()
@@ -169,7 +171,7 @@
sleep(print_delay)
- use_power = USE_POWER_IDLE
+ update_use_power(USE_POWER_IDLE)
printing = 0
update_icon()
diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm
index fdd540ce4a..2e5481beb5 100644
--- a/code/game/machinery/camera/presets.dm
+++ b/code/game/machinery/camera/presets.dm
@@ -226,4 +226,4 @@ var/global/list/engineering_networks = list(
mult++
if (isMotion())
mult++
- active_power_usage = mult*initial(active_power_usage)
+ update_active_power_usage(mult * initial(active_power_usage))
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index 636bcca6c0..917fed33eb 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -39,12 +39,11 @@
overlays.Cut()
/obj/machinery/cell_charger/examine(mob/user)
- if(!..(user, 5))
- return
-
- to_chat(user, "[charging ? "[charging]" : "Nothing"] is in [src].")
- if(charging)
- to_chat(user, "Current charge: [charging.charge] / [charging.maxcharge]")
+ . = ..()
+ if(get_dist(user, src) <= 5)
+ . += "[charging ? "[charging]" : "Nothing"] is in [src]."
+ if(charging)
+ . += "Current charge: [charging.charge] / [charging.maxcharge]"
/obj/machinery/cell_charger/attackby(obj/item/weapon/W, mob/user)
if(stat & BROKEN)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index f7c5f5bd43..ebd740e5e5 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -534,9 +534,8 @@
to_chat(user, "You flip the write-protect tab to [read_only ? "protected" : "unprotected"].")
/obj/item/weapon/disk/data/examine(mob/user)
- ..(user)
- to_chat(user, text("The write-protect tab is set to [read_only ? "protected" : "unprotected"]."))
- return
+ . = ..()
+ . += "The write-protect tab is set to [read_only ? "protected" : "unprotected"]."
/*
* Diskette Box
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index c222ba4e64..86f3fe93da 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -5,34 +5,34 @@
icon_keyboard = null
icon_screen = "invaders"
clicksound = null //Gets too spammy and makes no sense for arcade to have the console keyboard noise anyway
- var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2,
- /obj/item/toy/blink = 2,
- /obj/item/clothing/under/syndicate/tacticool = 2,
- /obj/item/toy/sword = 2,
- /obj/item/weapon/gun/projectile/revolver/capgun = 2,
- /obj/item/toy/crossbow = 2,
- /obj/item/clothing/suit/syndicatefake = 2,
- /obj/item/weapon/storage/fancy/crayons = 2,
- /obj/item/toy/spinningtoy = 2,
- /obj/item/toy/prize/ripley = 1,
- /obj/item/toy/prize/fireripley = 1,
- /obj/item/toy/prize/deathripley = 1,
- /obj/item/toy/prize/gygax = 1,
- /obj/item/toy/prize/durand = 1,
- /obj/item/toy/prize/honk = 1,
- /obj/item/toy/prize/marauder = 1,
- /obj/item/toy/prize/seraph = 1,
- /obj/item/toy/prize/mauler = 1,
- /obj/item/toy/prize/odysseus = 1,
- /obj/item/toy/prize/phazon = 1,
- /obj/item/toy/waterflower = 1,
- /obj/random/action_figure = 1,
- /obj/random/plushie = 1,
- /obj/item/toy/cultsword = 1,
- /obj/item/toy/bouquet/fake = 1,
- /obj/item/clothing/accessory/badge/sheriff = 2,
- /obj/item/clothing/head/cowboy_hat/small = 2,
- /obj/item/toy/stickhorse = 2
+ var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2,
+ /obj/item/toy/blink = 2,
+ /obj/item/clothing/under/syndicate/tacticool = 2,
+ /obj/item/toy/sword = 2,
+ /obj/item/weapon/gun/projectile/revolver/capgun = 2,
+ /obj/item/toy/crossbow = 2,
+ /obj/item/clothing/suit/syndicatefake = 2,
+ /obj/item/weapon/storage/fancy/crayons = 2,
+ /obj/item/toy/spinningtoy = 2,
+ /obj/item/toy/prize/ripley = 1,
+ /obj/item/toy/prize/fireripley = 1,
+ /obj/item/toy/prize/deathripley = 1,
+ /obj/item/toy/prize/gygax = 1,
+ /obj/item/toy/prize/durand = 1,
+ /obj/item/toy/prize/honk = 1,
+ /obj/item/toy/prize/marauder = 1,
+ /obj/item/toy/prize/seraph = 1,
+ /obj/item/toy/prize/mauler = 1,
+ /obj/item/toy/prize/odysseus = 1,
+ /obj/item/toy/prize/phazon = 1,
+ /obj/item/weapon/reagent_containers/spray/waterflower = 1,
+ /obj/random/action_figure = 1,
+ /obj/random/plushie = 1,
+ /obj/item/toy/cultsword = 1,
+ /obj/item/toy/bouquet/fake = 1,
+ /obj/item/clothing/accessory/badge/sheriff = 2,
+ /obj/item/clothing/head/cowboy_hat/small = 2,
+ /obj/item/toy/stickhorse = 2
)
/obj/machinery/computer/arcade/New()
@@ -384,7 +384,7 @@
spaceport_freebie = 0
last_spaceport_action = ""
-/obj/machinery/computer/arcade/orion_trail/attack_hand(mob/user)
+/obj/machinery/computer/arcade/orion_trail/attack_hand(mob/living/user)
if(..())
return
if(fuel <= 0 || food <=0 || settlers.len == 0)
@@ -1020,13 +1020,12 @@
var/active = 0 //if the ship is on
/obj/item/weapon/orion_ship/examine(mob/user)
- ..()
- if(!(in_range(user, src)))
- return
- if(!active)
- to_chat(user, span("notice", "There's a little switch on the bottom. It's flipped down."))
- else
- to_chat(user, span("notice", "There's a little switch on the bottom. It's flipped up."))
+ . = ..()
+ if(in_range(user, src))
+ if(!active)
+ . += span("notice", "There's a little switch on the bottom. It's flipped down.")
+ else
+ . += span("notice", "There's a little switch on the bottom. It's flipped up.")
/obj/item/weapon/orion_ship/attack_self(mob/user)
if(active)
diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm
index 9adf2a0a43..fe0a9c8a62 100644
--- a/code/game/machinery/computer/camera.dm
+++ b/code/game/machinery/computer/camera.dm
@@ -119,6 +119,12 @@
check_eye(user)
return 1
+/obj/machinery/computer/security/relaymove(mob/user,direct)
+ var/turf/T = get_turf(current_camera)
+ for(var/i; i < 10; i++)
+ T = get_step(T, direct)
+ jump_on_click(user, T)
+
//Camera control: moving.
/obj/machinery/computer/security/proc/jump_on_click(var/mob/user,var/A)
if(user.machine != src)
@@ -182,25 +188,18 @@
if(istype(L))
L.tracking_cancelled()
current_camera = null
- use_power = USE_POWER_IDLE
+ update_use_power(USE_POWER_IDLE)
//Camera control: mouse.
+/* Oh my god
/atom/DblClick()
..()
if(istype(usr.machine,/obj/machinery/computer/security))
var/obj/machinery/computer/security/console = usr.machine
console.jump_on_click(usr,src)
-//Camera control: arrow keys.
-/mob/Move(n,direct)
- if(istype(machine,/obj/machinery/computer/security))
- var/obj/machinery/computer/security/console = machine
- var/turf/T = get_turf(console.current_camera)
- for(var/i;i<10;i++)
- T = get_step(T,direct)
- console.jump_on_click(src,T)
- return
- return ..(n,direct)
+*/
+//Camera control: arrow keys.
/obj/machinery/computer/security/telescreen
name = "Telescreen"
desc = "Used for watching an empty arena."
diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm
index b4a3c8c3c1..e5a57cfe49 100644
--- a/code/game/machinery/computer/guestpass.dm
+++ b/code/game/machinery/computer/guestpass.dm
@@ -19,11 +19,11 @@
return temp_access
/obj/item/weapon/card/id/guest/examine(mob/user)
- ..(user)
+ . = ..()
if (world.time < expiration_time)
- to_chat(user, "This pass expires at [worldtime2stationtime(expiration_time)].")
+ . += "This pass expires at [worldtime2stationtime(expiration_time)]."
else
- to_chat(user, "It expired at [worldtime2stationtime(expiration_time)].")
+ . += "It expired at [worldtime2stationtime(expiration_time)]."
/obj/item/weapon/card/id/guest/read()
if(!Adjacent(usr))
diff --git a/code/game/machinery/computer/shutoff_monitor.dm b/code/game/machinery/computer/shutoff_monitor.dm
index aed7bd25b9..e2413c5e21 100644
--- a/code/game/machinery/computer/shutoff_monitor.dm
+++ b/code/game/machinery/computer/shutoff_monitor.dm
@@ -5,66 +5,27 @@
icon_screen = "power:0"
light_color = "#a97faa"
circuit = /obj/item/weapon/circuitboard/shutoff_monitor
+ var/datum/nano_module/shutoff_monitor/monitor
-/obj/machinery/computer/shutoff_monitor/attack_hand(var/mob/user)
+/obj/machinery/computer/shutoff_monitor/New()
+ ..()
+ monitor = new(src)
+
+/obj/machinery/computer/shutoff_monitor/Destroy()
+ qdel(monitor)
+ monitor = null
+ ..()
+
+/obj/machinery/computer/shutoff_monitor/attack_hand(var/mob/user as mob)
..()
ui_interact(user)
-/obj/machinery/computer/shutoff_monitor/attack_robot(var/mob/user) // Borgs and AI will want to see this too
- ..()
- ui_interact(user)
-
-/obj/machinery/computer/shutoff_monitor/attack_ai(var/mob/user)
- ui_interact(user)
-
-/obj/machinery/computer/shutoff_monitor/ui_interact(mob/user, ui_key = "shutoff_monitor", var/datum/nanoui/ui = null, var/force_open = 1, var/key_state = null)
- var/data[0]
- data["valves"] = list()
- for(var/obj/machinery/atmospherics/valve/shutoff/S in GLOB.shutoff_valves)
- data["valves"][++data["valves"].len] = list("name" = S.name, "enable" = S.close_on_leaks, "open" = S.open, "x" = S.x, "y" = S.y, "z" = S.z, "ref" = "\ref[S]")
-
- // update the ui if it exists, returns null if no ui is passed/found
- ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
- if(!ui)
- // the ui does not exist, so we'll create a new() one
- // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
- ui = new(user, src, ui_key, "shutoff_monitor.tmpl", "Automated Shutoff Valve Monitor", 625, 700, state = key_state)
- // when the ui is first opened this is the data it will use
- ui.set_initial_data(data)
- // open the new ui window
- ui.open()
- // auto update every 20 Master Controller tick
- ui.set_auto_update(20) // Longer term to reduce the rate of data collection and processing
-
-/obj/machinery/computer/shutoff_monitor/Topic(href, href_list)
- if(..())
- return 1
-
- if(href_list["toggle_enable"])
- var/obj/machinery/atmospherics/valve/shutoff/S = locate(href_list["toggle_enable"])
-
- // Invalid ref
- if(!istype(S))
- return 0
-
- S.close_on_leaks = !S.close_on_leaks
-
- if(href_list["toggle_open"])
- var/obj/machinery/atmospherics/valve/shutoff/S = locate(href_list["toggle_open"])
-
- // Invalid ref
- if(!istype(S))
- return 0
-
- if(S.open)
- S.close()
- else
- S.open()
-
- return
-
+/obj/machinery/computer/shutoff_monitor/ui_interact(mob/user, ui_key = "shutoff_monitor", var/datum/nanoui/ui = null, var/force_open = 1)
+ monitor.ui_interact(user, ui_key, ui, force_open)
/obj/machinery/computer/shutoff_monitor/update_icon()
..()
if(!(stat & (NOPOWER|BROKEN)))
add_overlay("ai-fixer-empty")
+ else
+ cut_overlay("ai-fixer-empty")
\ No newline at end of file
diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm
index ad118c74d7..42e78683ec 100644
--- a/code/game/machinery/computer/timeclock_vr.dm
+++ b/code/game/machinery/computer/timeclock_vr.dm
@@ -209,8 +209,9 @@
/obj/machinery/computer/timeclock/proc/checkCardCooldown()
if(!card)
return FALSE
- if((world.time - card.last_job_switch) < 15 MINUTES)
- to_chat(usr, "You need to wait at least 15 minutes after last duty switch.")
+ var/time_left = 10 MINUTES - (world.time - card.last_job_switch)
+ if(time_left > 0)
+ to_chat(usr, "You need to wait another [round((time_left/10)/60, 1)] minute\s before you can switch.")
return FALSE
return TRUE
@@ -270,4 +271,4 @@
/obj/machinery/computer/timeclock/premade/west
dir = 4
- pixel_x = -26
\ No newline at end of file
+ pixel_x = -26
diff --git a/code/game/machinery/deployable_vr.dm b/code/game/machinery/deployable_vr.dm
new file mode 100644
index 0000000000..9f7e79af5b
--- /dev/null
+++ b/code/game/machinery/deployable_vr.dm
@@ -0,0 +1,176 @@
+/obj/structure/barricade/cutout
+ name = "stand-up figure"
+ desc = "Some sort of wooden stand-up figure..."
+ icon = 'icons/obj/cardboard_cutout.dmi'
+ icon_state = "cutout_basic"
+
+ maxhealth = 15 //Weaker than normal barricade
+ anchored = 0
+
+ var/fake_name = "unknown"
+ var/fake_desc = "You have to be closer to examine this creature."
+ var/construct_name = "basic cutout"
+
+ var/toppled = FALSE
+ var/human_name = TRUE
+
+ var/static/list/cutout_types
+ var/static/list/painters = list(/obj/item/weapon/reagent_containers/glass/paint, /obj/item/device/floor_painter, /obj/item/device/closet_painter)
+
+/obj/structure/barricade/cutout/New()
+ . = ..()
+ color = null
+ if(human_name)
+ fake_name = random_name(pick(list(MALE, FEMALE)))
+ name = fake_name
+ desc = fake_desc
+ if(!cutout_types)
+ cutout_types = list()
+ var/list/types = typesof(/obj/structure/barricade/cutout)
+ for(var/cutout_type in types)
+ var/obj/structure/barricade/cutout/pathed_type = cutout_type
+ cutout_types[initial(pathed_type.construct_name)] = cutout_type
+
+/obj/structure/barricade/cutout/proc/topple()
+ if(toppled)
+ return
+ toppled = TRUE
+ icon_state = "cutout_pushed_over"
+ density = 0
+ name = initial(name)
+ desc = initial(desc)
+ visible_message("[src] topples over!")
+
+/obj/structure/barricade/cutout/proc/untopple()
+ if(!toppled)
+ return
+ toppled = FALSE
+ icon_state = initial(icon_state)
+ density = 1
+ name = fake_name
+ desc = fake_desc
+ visible_message("[src] is uprighted to their proper position.")
+
+/obj/structure/barricade/cutout/CheckHealth()
+ if(!toppled && (health < (maxhealth/2)))
+ topple()
+ ..()
+
+/obj/structure/barricade/cutout/attack_hand(var/mob/user)
+ if((. = ..()))
+ return
+
+ if(toppled)
+ untopple()
+
+/obj/structure/barricade/cutout/examine(var/mob/user)
+ . = ..()
+
+ if(Adjacent(user))
+ . += "... from this distance, they seem to be made of [material.name] ..."
+
+/obj/structure/barricade/cutout/attackby(var/obj/I, var/mob/user)
+ if(is_type_in_list(I, painters))
+ var/choice = input(user, "What would you like to paint the cutout as?", "Cutout Painting") as null|anything in cutout_types
+ if(!choice || !Adjacent(user, src) || I != user.get_active_hand())
+ return TRUE
+ if(do_after(user, 10 SECONDS, src))
+ var/picked_type = cutout_types[choice]
+ new picked_type(loc)
+ qdel(src) //Laaaazy. Technically heals it too. Must be held together with all that paint.
+ return TRUE
+
+ else
+ return ..()
+
+//Variants
+/obj/structure/barricade/cutout/greytide
+ icon_state = "cutout_greytide"
+ construct_name = "greytide"
+/obj/structure/barricade/cutout/clown
+ icon_state = "cutout_clown"
+ construct_name = "clown"
+/obj/structure/barricade/cutout/mime
+ icon_state = "cutout_mime"
+ construct_name = "mime"
+/obj/structure/barricade/cutout/traitor
+ icon_state = "cutout_traitor"
+ construct_name = "criminal employee"
+/obj/structure/barricade/cutout/fluke
+ icon_state = "cutout_fluke"
+ construct_name = "nuclear operative"
+/obj/structure/barricade/cutout/cultist
+ icon_state = "cutout_cultist"
+ construct_name = "presumed cultist"
+/obj/structure/barricade/cutout/servant
+ icon_state = "cutout_servant"
+ construct_name = "druid"
+/obj/structure/barricade/cutout/new_servant
+ icon_state = "cutout_new_servant"
+ construct_name = "other druid"
+/obj/structure/barricade/cutout/viva
+ icon_state = "cutout_viva"
+ human_name = FALSE
+ fake_name = "Unknown"
+ construct_name = "advanced greytide"
+/obj/structure/barricade/cutout/wizard
+ icon_state = "cutout_wizard"
+ construct_name = "wizard"
+/obj/structure/barricade/cutout/shadowling
+ icon_state = "cutout_shadowling"
+ human_name = FALSE
+ fake_name = "Unknown"
+ construct_name = "dark creature"
+/obj/structure/barricade/cutout/fukken_xeno
+ icon_state = "cutout_fukken_xeno"
+ human_name = FALSE
+ fake_name = "xenomorph"
+ construct_name = "alien"
+/obj/structure/barricade/cutout/swarmer
+ icon_state = "cutout_swarmer"
+ human_name = FALSE
+ fake_name = "swarmer"
+ construct_name = "robot"
+/obj/structure/barricade/cutout/free_antag
+ icon_state = "cutout_free_antag"
+ construct_name = "hot lizard"
+/obj/structure/barricade/cutout/deathsquad
+ icon_state = "cutout_deathsquad"
+ construct_name = "unknown"
+/obj/structure/barricade/cutout/ian
+ icon_state = "cutout_ian"
+ human_name = FALSE
+ fake_name = "corgi"
+ construct_name = "dog"
+/obj/structure/barricade/cutout/ntsec
+ icon_state = "cutout_ntsec"
+ construct_name = "nt security"
+/obj/structure/barricade/cutout/lusty
+ icon_state = "cutout_lusty"
+ human_name = FALSE
+ fake_name = "xenomorph"
+ construct_name = "hot alien"
+/obj/structure/barricade/cutout/gondola
+ icon_state = "cutout_gondola"
+ construct_name = "creature"
+/obj/structure/barricade/cutout/monky
+ icon_state = "cutout_monky"
+ human_name = FALSE
+ fake_name = "monkey"
+ construct_name = "monkey"
+/obj/structure/barricade/cutout/law
+ icon_state = "cutout_law"
+ human_name = FALSE
+ fake_name = "Beepsky"
+ construct_name = "lawful robot"
+
+/obj/random/cutout //Random wooden standup figure
+ name = "random wooden figure"
+ desc = "This is a random wooden figure."
+ icon = 'icons/obj/cardboard_cutout.dmi'
+ icon_state = "cutout_random"
+ spawn_nothing_percentage = 80 //Only spawns 20% of the time to avoid being predictable
+
+/obj/random/cutout/item_to_spawn()
+ var/list/cutout_types = subtypesof(/obj/structure/barricade/cutout)
+ return pick(cutout_types)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index bd1d663720..2a14c17bdb 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -390,7 +390,8 @@
else if(electrified_until > 0 && world.time >= electrified_until)
electrify(0)
- ..()
+ if (..() == PROCESS_KILL && !(main_power_lost_until > 0 || backup_power_lost_until > 0 || electrified_until > 0))
+ . = PROCESS_KILL
/obj/machinery/door/airlock/uranium/process()
if(world.time > last_event+20)
@@ -580,6 +581,9 @@ About the new airlock wires panel:
if(backup_power_lost_until == -1 && !backupPowerCablesCut())
backup_power_lost_until = world.time + SecondsToTicks(10)
+ if(main_power_lost_until > 0 || backup_power_lost_until > 0)
+ START_MACHINE_PROCESSING(src)
+
// Disable electricity if required
if(electrified_until && isAllPowerLoss())
electrify(0)
@@ -589,6 +593,9 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/proc/loseBackupPower()
backup_power_lost_until = backupPowerCablesCut() ? -1 : world.time + SecondsToTicks(60)
+ if(backup_power_lost_until > 0)
+ START_MACHINE_PROCESSING(src)
+
// Disable electricity if required
if(electrified_until && isAllPowerLoss())
electrify(0)
@@ -631,6 +638,9 @@ About the new airlock wires panel:
message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]."
src.electrified_until = duration == -1 ? -1 : world.time + SecondsToTicks(duration)
+ if(electrified_until > 0)
+ START_MACHINE_PROCESSING(src)
+
if(feedback && message)
to_chat(usr,message)
@@ -1142,7 +1152,7 @@ About the new airlock wires panel:
if(!has_beeped)
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
has_beeped = 1
- close_door_at = world.time + 6
+ autoclose_in(6)
return
for(var/turf/turf in locs)
@@ -1160,8 +1170,7 @@ About the new airlock wires panel:
var/obj/structure/window/killthis = (locate(/obj/structure/window) in turf)
if(killthis)
killthis.ex_act(2)//Smashin windows
- ..()
- return
+ return ..()
/obj/machinery/door/airlock/proc/lock(var/forced=0)
if(locked)
diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm
index ca7092708d..521f07cf67 100644
--- a/code/game/machinery/doors/airlock_control.dm
+++ b/code/game/machinery/doors/airlock_control.dm
@@ -9,7 +9,8 @@ obj/machinery/door/airlock
var/cur_command = null //the command the door is currently attempting to complete
obj/machinery/door/airlock/process()
- ..()
+ if (..() == PROCESS_KILL && !cur_command)
+ . = PROCESS_KILL
if (arePowerSystemsOn())
execute_current_command()
@@ -22,6 +23,9 @@ obj/machinery/door/airlock/receive_signal(datum/signal/signal)
cur_command = signal.data["command"]
execute_current_command()
+ if(cur_command)
+ START_MACHINE_PROCESSING(src)
+
obj/machinery/door/airlock/proc/execute_current_command()
if(operating)
diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm
index 39ca2d5f40..41e3297c2b 100644
--- a/code/game/machinery/doors/airlock_electronics.dm
+++ b/code/game/machinery/doors/airlock_electronics.dm
@@ -1,5 +1,3 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-
/obj/item/weapon/airlock_electronics
name = "airlock electronics"
icon = 'icons/obj/doors/door_assembly.dmi'
@@ -8,106 +6,148 @@
matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 50)
- req_access = list(access_engine)
+ req_one_access = list(access_engine, access_talon) // Access to unlock the device, ignored if emagged //VOREStation Edit - Add talon
+ var/list/apply_any_access = list(access_engine) // Can apply any access, not just their own
var/secure = 0 //if set, then wires will be randomized and bolts will drop if the door is broken
var/list/conf_access = null
var/one_access = 0 //if set to 1, door would receive req_one_access instead of req_access
var/last_configurator = null
var/locked = 1
+ var/emagged = 0
- attack_self(mob/user as mob)
- if (!ishuman(user) && !istype(user,/mob/living/silicon/robot))
- return ..(user)
+/obj/item/weapon/airlock_electronics/emag_act(var/remaining_charges, var/mob/user)
+ if(!emagged)
+ emagged = 1
+ to_chat(user, "You remove the access restrictions on [src]!")
+ return 1
- var/t1 = text("Access control
\n")
+/obj/item/weapon/airlock_electronics/attack_self(mob/user as mob)
+ if (!ishuman(user) && !istype(user,/mob/living/silicon/robot))
+ return ..(user)
- if (last_configurator)
- t1 += "Operator: [last_configurator]
"
+ var/t1 = text("Access control
\n")
- if (locked)
- t1 += "Swipe ID
"
- else
- t1 += "Block
"
+ if (last_configurator)
+ t1 += "Operator: [last_configurator]
"
- t1 += "Access requirement is set to "
- t1 += one_access ? "ONE
" : "ALL
"
+ if (locked)
+ t1 += "Unlock Interface
"
+ else
+ t1 += "Lock Interface
"
- t1 += conf_access == null ? "All
" : "All
"
+ t1 += "Access requirement is set to "
+ t1 += one_access ? "ONE
" : "ALL
"
- t1 += "
"
+ t1 += conf_access == null ? "All
" : "All
"
- var/list/accesses = get_all_station_access()
- for (var/acc in accesses)
- var/aname = get_access_desc(acc)
+ t1 += "
"
- if (!conf_access || !conf_access.len || !(acc in conf_access))
- t1 += "[aname]
"
- else if(one_access)
- t1 += "[aname]
"
- else
- t1 += "[aname]
"
+ var/list/accesses = get_available_accesses(user)
+ for (var/acc in accesses)
+ var/aname = get_access_desc(acc)
- t1 += text("Close
\n", src)
-
- user << browse(t1, "window=airlock_electronics")
- onclose(user, "airlock")
-
- Topic(href, href_list)
- ..()
- if (usr.stat || usr.restrained() || (!ishuman(usr) && !istype(usr,/mob/living/silicon)))
- return
- if (href_list["close"])
- usr << browse(null, "window=airlock")
- return
-
- if (href_list["login"])
- if(istype(usr,/mob/living/silicon))
- src.locked = 0
- src.last_configurator = usr.name
+ if (!conf_access || !conf_access.len || !(acc in conf_access))
+ t1 += "[aname]
"
+ else if(one_access)
+ t1 += "[aname]
"
else
- var/obj/item/I = usr.get_active_hand()
- if (istype(I, /obj/item/device/pda))
- var/obj/item/device/pda/pda = I
- I = pda.id
- if (I && src.check_access(I))
+ t1 += "[aname]
"
+
+ t1 += text("Close
\n", src)
+
+ user << browse(t1, "window=airlock_electronics")
+ onclose(user, "airlock")
+
+/obj/item/weapon/airlock_electronics/Topic(href, href_list)
+ ..()
+ if (usr.stat || usr.restrained() || (!ishuman(usr) && !istype(usr,/mob/living/silicon)))
+ return
+ if (href_list["close"])
+ usr << browse(null, "window=airlock")
+ return
+
+ if (href_list["login"])
+ if(emagged)
+ src.locked = 0
+ src.last_configurator = usr.name
+ else if(issilicon(usr))
+ src.locked = 0
+ src.last_configurator = usr.name
+ else if(isliving(usr))
+ var/obj/item/weapon/card/id/id
+ if(ishuman(usr))
+ var/mob/living/carbon/human/H = usr
+ id = H.get_idcard()
+ // In their ID slot?
+ if(id && src.check_access(id))
src.locked = 0
- src.last_configurator = I:registered_name
+ src.last_configurator = id.registered_name
+ // Still locked, human handling didn't do it!
+ if(locked)
+ var/obj/item/I = usr.get_active_hand()
+ id = I?.GetID()
+ if(id && src.check_access(id))
+ src.locked = 0
+ src.last_configurator = id.registered_name
- if (locked)
- return
+ if (locked)
+ return
- if (href_list["logout"])
- locked = 1
+ if (href_list["logout"])
+ locked = 1
- if (href_list["one_access"])
- one_access = !one_access
+ if (href_list["one_access"])
+ one_access = !one_access
- if (href_list["access"])
- toggle_access(href_list["access"])
+ if (href_list["access"])
+ toggle_access(href_list["access"])
- attack_self(usr)
+ attack_self(usr)
- proc
- toggle_access(var/acc)
- if (acc == "all")
+/obj/item/weapon/airlock_electronics/proc/toggle_access(var/acc)
+ if (acc == "all")
+ conf_access = null
+ else
+ var/req = text2num(acc)
+
+ if (conf_access == null)
+ conf_access = list()
+
+ if (!(req in conf_access))
+ conf_access += req
+ else
+ conf_access -= req
+ if (!conf_access.len)
conf_access = null
- else
- var/req = text2num(acc)
- if (conf_access == null)
- conf_access = list()
-
- if (!(req in conf_access))
- conf_access += req
- else
- conf_access -= req
- if (!conf_access.len)
- conf_access = null
+/obj/item/weapon/airlock_electronics/proc/get_available_accesses(var/mob/user)
+ var/obj/item/weapon/card/id/id
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ id = H.get_idcard()
+ else if(issilicon(user))
+ var/mob/living/silicon/R = user
+ id = R.idcard
+ // Nothing
+ if(!id || !id.access)
+ return list()
+
+ // Has engineer access, can put any access
+ else if(has_access(null, apply_any_access, id.access))
+ return get_all_station_access()
+
+ // Not an engineer, can only pick your own accesses to program
+ else
+ return id.access
/obj/item/weapon/airlock_electronics/secure
name = "secure airlock electronics"
desc = "designed to be somewhat more resistant to hacking than standard electronics."
origin_tech = list(TECH_DATA = 2)
secure = 1
+
+/obj/item/weapon/airlock_electronics/secure/emag_act(var/remaining_charges, var/mob/user)
+ to_chat(user, "You don't appear to be able to bypass this hardened device!")
+ return -1
diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm
index 36faf82b00..5ff587a7d9 100644
--- a/code/game/machinery/doors/blast_door.dm
+++ b/code/game/machinery/doors/blast_door.dm
@@ -269,7 +269,7 @@
// If for some reason this is actually needed for something important, uncomment this.
/obj/machinery/door/blast/CanZASPass(turf/T, is_zone)
if(is_zone)
- return ATMOS_PASS_YES
+ return TRUE
return ..()
*/
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 6902b7296f..c07d17d9ac 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -9,7 +9,7 @@
anchored = 1
opacity = 1
density = 1
- can_atmos_pass = ATMOS_PASS_DENSITY
+ can_atmos_pass = ATMOS_PASS_PROC
layer = DOOR_OPEN_LAYER
var/open_layer = DOOR_OPEN_LAYER
var/closed_layer = DOOR_CLOSED_LAYER
@@ -82,11 +82,17 @@
/obj/machinery/door/process()
if(close_door_at && world.time >= close_door_at)
if(autoclose)
- close_door_at = next_close_time()
+ close_door_at = world.time + next_close_wait()
spawn(0)
close()
else
close_door_at = 0
+ if (..() == PROCESS_KILL && !close_door_at)
+ return PROCESS_KILL
+
+/obj/machinery/door/proc/autoclose_in(wait)
+ close_door_at = world.time + wait
+ START_MACHINE_PROCESSING(src)
/obj/machinery/door/proc/can_open()
if(!density || operating || !ticker)
@@ -113,7 +119,13 @@
return //VOREStation Edit: unable to open doors
else
bumpopen(M)
-
+ // VOREStation Add - UAVs open public doors
+ if(istype(AM, /obj/item/device/uav))
+ if(check_access(null))
+ open()
+ else
+ do_animate("deny")
+ //VOREStation Add End
if(istype(AM, /mob/living/bot))
var/mob/living/bot/bot = AM
@@ -145,8 +157,8 @@
/obj/machinery/door/CanZASPass(turf/T, is_zone)
if(is_zone)
- return block_air_zones ? ATMOS_PASS_NO : ATMOS_PASS_YES
- return ..()
+ return !block_air_zones // Block merging unless block_air_zones = 0
+ return !density // Block airflow unless density = 0
/obj/machinery/door/proc/bumpopen(mob/user as mob)
if(operating) return
@@ -326,13 +338,13 @@
/obj/machinery/door/examine(mob/user)
. = ..()
if(src.health <= 0)
- to_chat(user, "\The [src] is broken!")
- if(src.health < src.maxhealth / 4)
- to_chat(user, "\The [src] looks like it's about to break!")
+ . += "It is broken!"
+ else if(src.health < src.maxhealth / 4)
+ . += "It looks like it's about to break!"
else if(src.health < src.maxhealth / 2)
- to_chat(user, "\The [src] looks seriously damaged!")
+ . += "It looks seriously damaged!"
else if(src.health < src.maxhealth * 3/4)
- to_chat(user, "\The [src] shows signs of damage!")
+ . += "It shows signs of damage!"
/obj/machinery/door/proc/set_broken()
@@ -427,12 +439,12 @@
operating = 0
if(autoclose)
- close_door_at = next_close_time()
+ autoclose_in(next_close_wait())
return 1
-/obj/machinery/door/proc/next_close_time()
- return world.time + (normalspeed ? 150 : 5)
+/obj/machinery/door/proc/next_close_wait()
+ return (normalspeed ? 150 : 5)
/obj/machinery/door/proc/close(var/forced = 0)
if(!can_close(forced))
@@ -484,8 +496,7 @@
else
source.thermal_conductivity = initial(source.thermal_conductivity)
-/obj/machinery/door/Move(new_loc, new_dir)
- //update_nearby_tiles()
+/obj/machinery/door/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
if(width > 1)
if(dir in list(EAST, WEST))
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index c681a34edb..29125c8500 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -79,14 +79,15 @@
return get_material_by_name(DEFAULT_WALL_MATERIAL)
/obj/machinery/door/firedoor/examine(mob/user)
- . = ..(user, 1)
- if(!. || !density)
- return
+ . = ..()
+
+ if(!Adjacent(user))
+ return .
if(pdiff >= FIREDOOR_MAX_PRESSURE_DIFF)
- to_chat(user, "WARNING: Current pressure differential is [pdiff]kPa! Opening door may result in injury!")
+ . += "WARNING: Current pressure differential is [pdiff]kPa! Opening door may result in injury!"
- to_chat(user, "Sensor readings:")
+ . += "Sensor readings:"
for(var/index = 1; index <= tile_info.len; index++)
var/o = " "
switch(index)
@@ -100,7 +101,7 @@
o += "WEST: "
if(tile_info[index] == null)
o += "DATA UNAVAILABLE"
- to_chat(user, o)
+ . += o
continue
var/celsius = convert_k2c(tile_info[index][1])
var/pressure = tile_info[index][2]
@@ -108,14 +109,14 @@
o += "[celsius]°C "
o += ""
o += "[pressure]kPa"
- to_chat(user, o)
+ . += o
if(islist(users_to_open) && users_to_open.len)
var/users_to_open_string = users_to_open[1]
if(users_to_open.len >= 2)
for(var/i = 2 to users_to_open.len)
users_to_open_string += ", [users_to_open[i]]"
- to_chat(user, "These people have opened \the [src] during an alert: [users_to_open_string].")
+ . += "These people have opened \the [src] during an alert: [users_to_open_string]."
/obj/machinery/door/firedoor/Bumped(atom/AM)
if(p_open || operating)
@@ -350,7 +351,9 @@
/obj/machinery/door/firedoor/process()
..()
- if(density && next_process_time <= world.time)
+ if(!density)
+ return PROCESS_KILL
+ if(next_process_time <= world.time)
next_process_time = world.time + 100 // 10 second delays between process updates
var/changed = 0
lockdown=0
@@ -406,7 +409,10 @@
/obj/machinery/door/firedoor/close()
latetoggle()
- return ..()
+ . = ..()
+ // Queue us for processing when we are closed!
+ if(density)
+ START_MACHINE_PROCESSING(src)
/obj/machinery/door/firedoor/open(var/forced = 0)
if(hatch_open)
diff --git a/code/game/machinery/doors/multi_tile.dm b/code/game/machinery/doors/multi_tile.dm
index 608e02b9a0..f05419cb6d 100644
--- a/code/game/machinery/doors/multi_tile.dm
+++ b/code/game/machinery/doors/multi_tile.dm
@@ -16,7 +16,7 @@
QDEL_NULL(filler2)
return ..()
-/obj/machinery/door/airlock/multi_tile/Move()
+/obj/machinery/door/airlock/multi_tile/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
SetBounds()
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 1396b5f554..f7b8a1222d 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -14,6 +14,7 @@
opacity = 0
var/obj/item/weapon/airlock_electronics/electronics = null
explosion_resistance = 5
+ can_atmos_pass = ATMOS_PASS_PROC
air_properties_vary_with_direction = 1
/obj/machinery/door/window/New()
@@ -94,9 +95,9 @@
/obj/machinery/door/window/CanZASPass(turf/T, is_zone)
if(get_dir(T, loc) == turn(dir, 180))
if(is_zone) // No merging allowed.
- return ATMOS_PASS_NO
- return ..() // Air can flow if open (density == FALSE).
- return ATMOS_PASS_YES // Windoors don't block if not facing the right way.
+ return FALSE
+ return !density // Air can flow if open (density == FALSE).
+ return TRUE // Windoors don't block if not facing the right way.
/obj/machinery/door/window/CheckExit(atom/movable/mover as mob|obj, turf/target as turf)
if(istype(mover) && mover.checkpass(PASSGLASS))
diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm
index dc02084f98..dd0d863091 100644
--- a/code/game/machinery/embedded_controller/airlock_program.dm
+++ b/code/game/machinery/embedded_controller/airlock_program.dm
@@ -210,6 +210,7 @@
//purge apparently means clearing the airlock chamber to vacuum (then refilling, handled later)
target_pressure = 0
state = STATE_DEPRESSURIZE
+ playsound(master, 'sound/AI/airlockout.ogg', 100, 0) //VOREStation Add - TTS
if(!cycle_to_external_air || target_state == TARGET_OUTOPEN) // if going outside, pump internal air into air tank
signalPump(tag_airpump, 1, 0, target_pressure) //send a signal to start depressurizing
else
@@ -218,6 +219,7 @@
else if(chamber_pressure <= target_pressure)
state = STATE_PRESSURIZE
+ playsound(master, 'sound/AI/airlockin.ogg', 100, 0) //VOREStation Add - TTS
if(!cycle_to_external_air || target_state == TARGET_INOPEN) // if going inside, pump air into airlock
signalPump(tag_airpump, 1, 1, target_pressure) //send a signal to start pressurizing
else
@@ -227,6 +229,7 @@
else if(chamber_pressure > target_pressure)
if(!cycle_to_external_air)
state = STATE_DEPRESSURIZE
+ playsound(master, 'sound/AI/airlockout.ogg', 100, 0) //VOREStation Add - TTS
signalPump(tag_airpump, 1, 0, target_pressure) //send a signal to start depressurizing
else
memory["purge"] = 1 // should always purge first if using external air, chamber pressure should never be higher than target pressure here
@@ -234,6 +237,7 @@
memory["target_pressure"] = max(target_pressure, MIN_TARGET_PRESSURE)
if(STATE_PRESSURIZE)
+ playsound(master, 'sound/machines/2beep.ogg', 100, 0) //VOREStation Add - TTS
if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95)
//not done until the pump has reported that it's off
if(memory["pump_status"] != "off")
@@ -245,9 +249,11 @@
cycleDoors(target_state)
state = STATE_IDLE
target_state = TARGET_NONE
+ playsound(master, 'sound/AI/airlockdone.ogg', 100, 0) //VOREStation Add - TTS
if(STATE_DEPRESSURIZE)
+ playsound(master, 'sound/machines/2beep.ogg', 100, 0) //VOREStation Add - TTS
if(memory["chamber_sensor_pressure"] <= max(memory["target_pressure"] * 1.05, MIN_TARGET_PRESSURE))
if(memory["pump_status"] != "off")
signalPump(tag_airpump, 0)
@@ -263,6 +269,7 @@
cycleDoors(target_state)
state = STATE_IDLE
target_state = TARGET_NONE
+ playsound(master, 'sound/AI/airlockdone.ogg', 100, 0) //VOREStation Add - TTS
memory["processing"] = (state != target_state)
diff --git a/code/game/machinery/exonet_node.dm b/code/game/machinery/exonet_node.dm
index 56c8e36edf..1813d2dc71 100644
--- a/code/game/machinery/exonet_node.dm
+++ b/code/game/machinery/exonet_node.dm
@@ -1,8 +1,8 @@
/obj/machinery/exonet_node
name = "exonet node"
desc = null // Gets written in New()
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "exonet_node"
+ icon = 'icons/obj/stationobjs_vr.dmi' //VOREStation Edit
+ icon_state = "exonet" //VOREStation Edit
idle_power_usage = 2500
density = 1
var/on = 1
@@ -44,10 +44,12 @@
// Description: Self explanatory.
/obj/machinery/exonet_node/update_icon()
if(on)
+ /* VOREStation Removal
if(!allow_external_PDAs && !allow_external_communicators && !allow_external_newscasters)
icon_state = "[initial(icon_state)]_idle"
else
- icon_state = initial(icon_state)
+ */
+ icon_state = initial(icon_state)
else
icon_state = "[initial(icon_state)]_off"
@@ -58,13 +60,13 @@
if(toggle)
if(stat & (BROKEN|NOPOWER|EMPED))
on = 0
- idle_power_usage = 0
+ update_idle_power_usage(0)
else
on = 1
- idle_power_usage = 2500
+ update_idle_power_usage(2500)
else
on = 0
- idle_power_usage = 0
+ update_idle_power_usage(0)
update_icon()
// Proc: emp_act()
diff --git a/code/game/machinery/floor_light.dm b/code/game/machinery/floor_light.dm
index 11f5fc26fd..c494782ce1 100644
--- a/code/game/machinery/floor_light.dm
+++ b/code/game/machinery/floor_light.dm
@@ -99,7 +99,7 @@ var/list/floor_light_cache = list()
if(light_range || light_power)
set_light(0)
- active_power_usage = ((light_range + light_power) * 10)
+ update_active_power_usage((light_range + light_power) * 10)
update_icon()
/obj/machinery/floor_light/update_icon()
diff --git a/code/game/machinery/floorlayer.dm b/code/game/machinery/floorlayer.dm
index e7f39ade5f..d8a2b463e2 100644
--- a/code/game/machinery/floorlayer.dm
+++ b/code/game/machinery/floorlayer.dm
@@ -12,8 +12,8 @@
T = new/obj/item/stack/tile/floor(src)
..()
-/obj/machinery/floorlayer/Move(new_turf,M_Dir)
- ..()
+/obj/machinery/floorlayer/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
if(on)
if(mode["dismantle"])
@@ -26,7 +26,7 @@
CollectTiles(old_turf)
- old_turf = new_turf
+ old_turf = loc
/obj/machinery/floorlayer/attack_hand(mob/user as mob)
on=!on
@@ -64,12 +64,11 @@
..()
/obj/machinery/floorlayer/examine(mob/user)
- ..()
+ . = ..()
var/dismantle = mode["dismantle"]
var/laying = mode["laying"]
var/collect = mode["collect"]
- var/message = "\The [src] [!T ? "don't " : ""]has [!T ? "" : "[T.get_amount()] [T] "]tile\s, dismantle is [dismantle ? "on" : "off"], laying is [laying ? "on" : "off"], collect is [collect ? "on" : "off"]."
- to_chat(user,message)
+ . += "[src] [!T ? "don't " : ""]has [!T ? "" : "[T.get_amount()] [T] "]tile\s, dismantle is [dismantle ? "on" : "off"], laying is [laying ? "on" : "off"], collect is [collect ? "on" : "off"]."
/obj/machinery/floorlayer/proc/reset()
on=0
diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm
index 330f0ee796..d77e2dff7a 100644
--- a/code/game/machinery/frame.dm
+++ b/code/game/machinery/frame.dm
@@ -220,9 +220,9 @@
density = TRUE
/obj/structure/frame/examine(mob/user)
- ..()
+ . = ..()
if(circuit)
- to_chat(user, "It has \a [circuit] installed.")
+ . += "It has \a [circuit] installed."
/obj/structure/frame/proc/update_desc()
var/D
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 4fec2cba82..76686aacce 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -92,22 +92,11 @@ var/const/HOLOPAD_MODE = RANGE_BASED
/*This is the proc for special two-way communication between AI and holopad/people talking near holopad.
For the other part of the code, check silicon say.dm. Particularly robot talk.*/
-/obj/machinery/hologram/holopad/hear_talk(mob/living/M, text, verb, datum/language/speaking)
- if(M)
+/obj/machinery/hologram/holopad/hear_talk(mob/M, list/message_pieces, verb)
+ if(M && LAZYLEN(masters))
for(var/mob/living/silicon/ai/master in masters)
- if(!master.say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad.
- if(speaking)
- text = speaking.scramble(text)
- else
- text = stars(text)
- var/name_used = M.GetVoice()
- //This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only.
- var/rendered
- if(speaking)
- rendered = "Holopad received, [name_used] [speaking.format_message(text, verb)]"
- else
- rendered = "Holopad received, [name_used] [verb], \"[text]\""
- master.show_message(rendered, 2)
+ if(masters[master] && M != master)
+ master.relay_speech(M, message_pieces, verb)
/obj/machinery/hologram/holopad/see_emote(mob/living/M, text)
if(M)
@@ -138,6 +127,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
set_light(2) //pad lighting
icon_state = "holopad1"
A.holo = src
+ if(LAZYLEN(masters))
+ START_MACHINE_PROCESSING(src)
return 1
/obj/machinery/hologram/holopad/proc/clear_holo(mob/living/silicon/ai/user)
@@ -158,7 +149,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
continue
use_power(power_per_hologram)
- return 1
+ if(..() == PROCESS_KILL && !LAZYLEN(masters))
+ return PROCESS_KILL
/obj/machinery/hologram/holopad/proc/move_hologram(mob/living/silicon/ai/user)
if(masters[user])
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index cc5b330ba3..a4654a31a4 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -165,21 +165,20 @@
to_chat(usr, "The IV drip is now [mode ? "injecting" : "taking blood"].")
/obj/machinery/iv_drip/examine(mob/user)
- ..(user)
- if(!(user in view(2)) && user != src.loc)
- return
+ . = ..()
- to_chat(user, "The IV drip is [mode ? "injecting" : "taking blood"].")
+ if(get_dist(user, src) <= 2)
+ . += "The IV drip is [mode ? "injecting" : "taking blood"]."
- if(beaker)
- if(beaker.reagents && beaker.reagents.reagent_list.len)
- to_chat(user, "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.")
+ if(beaker)
+ if(beaker.reagents?.reagent_list?.len)
+ . += "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid."
+ else
+ . += "Attached is an empty [beaker]."
else
- to_chat(user, "Attached is an empty [beaker].")
- else
- to_chat(user, "No chemicals are attached.")
+ . += "No chemicals are attached."
- to_chat(user, "[attached ? attached : "No one"] is attached.")
+ . += "[attached ? attached : "No one"] is attached."
/obj/machinery/iv_drip/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSTABLE)) //allow bullets, beams, thrown objects, mice, drones, and the like through.
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index afa853c41a..81efc0f42b 100644
--- a/code/game/machinery/lightswitch.dm
+++ b/code/game/machinery/lightswitch.dm
@@ -50,8 +50,9 @@
set_light(2, 0.1, on ? "#82FF4C" : "#F86060")
/obj/machinery/light_switch/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "A light switch. It is [on? "on" : "off"].")
+ . = ..()
+ if(Adjacent(user))
+ . += "A light switch. It is [on? "on" : "off"]."
/obj/machinery/light_switch/attack_hand(mob/user)
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 9f3132207f..3871908ff2 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -5,12 +5,16 @@ Overview:
of 'Del' removes reference to src machine in global 'machines list'.
Class Variables:
+
+ power_init_complete (boolean)
+ Indicates that we have have registered our static power usage with the area.
+
use_power (num)
current state of auto power use.
Possible Values:
- 0 -- no auto power use
- 1 -- machine is using power at its idle power level
- 2 -- machine is using power at its active power level
+ USE_POWER_OFF:0 -- no auto power use
+ USE_POWER_IDLE:1 -- machine is using power at its idle power level
+ USE_POWER_ACTIVE:2 -- machine is using power at its active power level
active_power_usage (num)
Value for the amount of power to use when in active power mode
@@ -51,28 +55,18 @@ Class Procs:
Destroy() 'game/machinery/machine.dm'
- auto_use_power() 'game/machinery/machine.dm'
- This proc determines how power mode power is deducted by the machine.
- 'auto_use_power()' is called by the 'master_controller' game_controller every
- tick.
+ get_power_usage() 'game/machinery/machinery_power.dm'
+ Returns the amount of power this machine uses every SSmachines cycle.
+ Default definition uses 'use_power', 'active_power_usage', 'idle_power_usage'
- Return Value:
- return:1 -- if object is powered
- return:0 -- if object is not powered.
-
- Default definition uses 'use_power', 'power_channel', 'active_power_usage',
- 'idle_power_usage', 'powered()', and 'use_power()' implement behavior.
-
- powered(chan = EQUIP) 'modules/power/power.dm'
+ powered(chan = CURRENT_CHANNEL) 'game/machinery/machinery_power.dm'
Checks to see if area that contains the object has power available for power
channel given in 'chan'.
- use_power(amount, chan=EQUIP, autocalled) 'modules/power/power.dm'
+ use_power_oneoff(amount, chan=CURRENT_CHANNEL) 'game/machinery/machinery_power.dm'
Deducts 'amount' from the power channel 'chan' of the area that contains the object.
- If it's autocalled then everything is normal, if something else calls use_power we are going to
- need to recalculate the power two ticks in a row.
- power_change() 'modules/power/power.dm'
+ power_change() 'game/machinery/machinery_power.dm'
Called by the area that contains the object when ever that area under goes a
power state change (area runs out of power, or area channel is turned off).
@@ -108,6 +102,7 @@ Class Procs:
var/idle_power_usage = 0
var/active_power_usage = 0
var/power_channel = EQUIP //EQUIP, ENVIRON or LIGHT
+ var/power_init_complete = FALSE
var/list/component_parts = null //list of all the parts used to build it, if made from certain kinds of frames.
var/uid
var/panel_open = 0
@@ -145,7 +140,9 @@ Class Procs:
if(A.loc == src) // If the components are inside the machine, delete them.
qdel(A)
else // Otherwise we assume they were dropped to the ground during deconstruction, and were not removed from the component_parts list by deconstruction code.
- component_parts -= A
+ warning("[A] was still in [src]'s component_parts when it was Destroy()'d")
+ component_parts.Cut()
+ component_parts = null
if(contents) // The same for contents.
for(var/atom/A in contents)
if(ishuman(A))
@@ -157,9 +154,8 @@ Class Procs:
qdel(A)
return ..()
-/obj/machinery/process()//If you dont use process or power why are you here
- if(!(use_power || idle_power_usage || active_power_usage))
- return PROCESS_KILL
+/obj/machinery/process() // Steady power usage is handled separately. If you dont use process why are you here?
+ return PROCESS_KILL
/obj/machinery/emp_act(severity)
if(use_power && stat == 0)
@@ -192,18 +188,20 @@ Class Procs:
else
return
-//sets the use_power var and then forces an area power update
-/obj/machinery/proc/update_use_power(var/new_use_power)
- use_power = new_use_power
-
-/obj/machinery/proc/auto_use_power()
- if(!powered(power_channel))
- return 0
- if(use_power == USE_POWER_IDLE)
- use_power(idle_power_usage, power_channel, 1)
- else if(use_power >= USE_POWER_ACTIVE)
- use_power(active_power_usage, power_channel, 1)
- return 1
+/obj/machinery/vv_edit_var(var/var_name, var/new_value)
+ if(var_name == NAMEOF(src, use_power))
+ update_use_power(new_value)
+ return TRUE
+ else if(var_name == NAMEOF(src, power_channel))
+ update_power_channel(new_value)
+ return TRUE
+ else if(var_name == NAMEOF(src, idle_power_usage))
+ update_idle_power_usage(new_value)
+ return TRUE
+ else if(var_name == NAMEOF(src, active_power_usage))
+ update_active_power_usage(new_value)
+ return TRUE
+ return ..()
/obj/machinery/proc/operable(var/additional_flags = 0)
return !inoperable(additional_flags)
diff --git a/code/game/machinery/machinery_power.dm b/code/game/machinery/machinery_power.dm
new file mode 100644
index 0000000000..aa3d301e53
--- /dev/null
+++ b/code/game/machinery/machinery_power.dm
@@ -0,0 +1,168 @@
+//
+// /obj/machinery POWER USAGE CODE HERE! GO GO GADGET STATIC POWER!
+// Note: You can find /obj/machinery/power power usage code in power.dm
+//
+// The following four machinery variables determine the "static" amount of power used every power cycle:
+// - use_power, idle_power_usage, active_power_usage, power_channel
+//
+// Please never change any of these variables! Use the procs that update them instead!
+//
+
+// Note that we update the area even if the area is unpowered.
+#define REPORT_POWER_CONSUMPTION_CHANGE(old_power, new_power)\
+ if(old_power != new_power){\
+ var/area/A = get_area(src);\
+ if(A) A.power_use_change(old_power, new_power, power_channel)}
+
+// Current power consumption right now.
+#define POWER_CONSUMPTION (use_power == USE_POWER_IDLE ? idle_power_usage : (use_power >= USE_POWER_ACTIVE ? active_power_usage : 0))
+
+// returns true if the area has power on given channel (or doesn't require power).
+// defaults to power_channel
+/obj/machinery/proc/powered(var/chan = CURRENT_CHANNEL) // defaults to power_channel
+ //Don't do this. It allows machines that set use_power to 0 when off (many machines) to
+ //be turned on again and used after a power failure because they never gain the NOPOWER flag.
+ //if(!use_power)
+ // return 1
+
+ var/area/A = get_area(src) // make sure it's in an area
+ if(!A)
+ return 0 // if not, then not powered
+ if(chan == CURRENT_CHANNEL)
+ chan = power_channel
+ return A.powered(chan) // return power status of the area
+
+// called whenever the power settings of the containing area change
+// by default, check equipment channel & set/clear NOPOWER flag
+// Returns TRUE if NOPOWER stat flag changed.
+// can override if needed
+/obj/machinery/proc/power_change()
+ var/oldstat = stat
+ if(powered(power_channel))
+ stat &= ~NOPOWER
+ else
+ stat |= NOPOWER
+ . = (stat != oldstat)
+ return
+
+// Get the amount of power this machine will consume each cycle. Override by experts only!
+/obj/machinery/proc/get_power_usage()
+ return POWER_CONSUMPTION
+
+// DEPRECATED! - USE use_power_oneoff() instead!
+/obj/machinery/proc/use_power(var/amount, var/chan = -1) // defaults to power_channel
+ return src.use_power_oneoff(amount, chan);
+
+// This will have this machine have its area eat this much power next tick, and not afterwards. Do not use for continued power draw.
+// Returns actual amount drawn (In theory this could be less than the amount asked for. In pratice it won't be FOR NOW)
+/obj/machinery/proc/use_power_oneoff(var/amount, var/chan = CURRENT_CHANNEL)
+ var/area/A = get_area(src) // make sure it's in an area
+ if(!A)
+ return
+ if(chan == CURRENT_CHANNEL)
+ chan = power_channel
+ return A.use_power_oneoff(amount, chan)
+
+// Check if we CAN use a given amount of extra power as a one off. Returns amount we could use without actually using it.
+// For backwards compatibilty this returns true if the channel is powered. This is consistant with pre-static-power
+// behavior of APC powerd machines, but at some point we might want to make this a bit cooler.
+/obj/machinery/proc/can_use_power_oneoff(var/amount, var/chan = CURRENT_CHANNEL)
+ if(powered(chan))
+ return amount // If channel is powered then you can do it.
+ return 0
+
+// Do not do power stuff in New/Initialize until after ..()
+/obj/machinery/Initialize()
+ . = ..()
+ var/power = POWER_CONSUMPTION
+ REPORT_POWER_CONSUMPTION_CHANGE(0, power)
+ power_init_complete = TRUE
+
+// Or in Destroy at all, but especially after the ..().
+/obj/machinery/Destroy()
+ if(ismovable(loc))
+ GLOB.moved_event.unregister(loc, src, .proc/update_power_on_move) // Unregister just in case
+ var/power = POWER_CONSUMPTION
+ REPORT_POWER_CONSUMPTION_CHANGE(power, 0)
+ . = ..()
+
+// Registering moved_event observers for all machines is too expensive. Instead we do it ourselves.
+// 99% of machines are always on a turf anyway, very few need recursive move handling.
+/obj/machinery/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
+ update_power_on_move(src, old_loc, loc)
+ if(ismovable(loc)) // Register for recursive movement (if the thing we're inside moves)
+ GLOB.moved_event.register(loc, src, .proc/update_power_on_move)
+ if(ismovable(old_loc)) // Unregister recursive movement.
+ GLOB.moved_event.unregister(old_loc, src, .proc/update_power_on_move)
+
+/obj/machinery/proc/update_power_on_move(atom/movable/mover, atom/old_loc, atom/new_loc)
+ var/area/old_area = get_area(old_loc)
+ var/area/new_area = get_area(new_loc)
+ if(old_area != new_area)
+ area_changed(old_area, new_area)
+
+/obj/machinery/proc/area_changed(area/old_area, area/new_area)
+ if(old_area == new_area || !power_init_complete)
+ return
+ var/power = POWER_CONSUMPTION
+ if(!power)
+ return // This is the most likely case anyway.
+
+ if(old_area)
+ old_area.power_use_change(power, 0, power_channel) // Remove our usage from old area
+ if(new_area)
+ new_area.power_use_change(0, power, power_channel) // Add our usage to new area
+ power_change() // Force check in case the old area was powered and the new one isn't or vice versa.
+
+//
+// Usage Update Procs - These procs are the only allowed way to modify these four variables:
+// - use_power, idle_power_usage, active_power_usage, power_channel
+//
+
+// Sets the use_power var and then forces an area power update
+/obj/machinery/proc/update_use_power(var/new_use_power)
+ if(use_power == new_use_power)
+ return
+ if(!power_init_complete)
+ use_power = new_use_power
+ return TRUE // We'll be retallying anyway.
+ var/old_power = POWER_CONSUMPTION
+ use_power = new_use_power
+ var/new_power = POWER_CONSUMPTION
+ REPORT_POWER_CONSUMPTION_CHANGE(old_power, new_power)
+ return TRUE
+
+// Sets the power_channel var and then forces an area power update.
+/obj/machinery/proc/update_power_channel(var/new_channel)
+ if(power_channel == new_channel)
+ return
+ if(!power_init_complete)
+ power_channel = new_channel
+ return TRUE // We'll be retallying anyway.
+ var/power = POWER_CONSUMPTION
+ REPORT_POWER_CONSUMPTION_CHANGE(power, 0) // Subtract from old channel
+ power_channel = new_channel
+ REPORT_POWER_CONSUMPTION_CHANGE(0, power) // Add to new channel
+ return TRUE
+
+// Sets the idle_power_usage var and then forces an area power update if use_power was USE_POWER_IDLE
+/obj/machinery/proc/update_idle_power_usage(var/new_power_usage)
+ if(idle_power_usage == new_power_usage)
+ return
+ var/old_power = idle_power_usage
+ idle_power_usage = new_power_usage
+ if(power_init_complete && use_power == USE_POWER_IDLE) // If this is the channel in use
+ REPORT_POWER_CONSUMPTION_CHANGE(old_power, new_power_usage)
+
+// Sets the active_power_usage var and then forces an area power update if use_power was USE_POWER_ACTIVE
+/obj/machinery/proc/update_active_power_usage(var/new_power_usage)
+ if(active_power_usage == new_power_usage)
+ return
+ var/old_power = active_power_usage
+ active_power_usage = new_power_usage
+ if(power_init_complete && use_power == USE_POWER_ACTIVE) // If this is the channel in use
+ REPORT_POWER_CONSUMPTION_CHANGE(old_power, new_power_usage)
+
+#undef REPORT_POWER_CONSUMPTION_CHANGE
+#undef POWER_CONSUMPTION
diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm
index ebbda06d6d..26a7936e1c 100644
--- a/code/game/machinery/magnet.dm
+++ b/code/game/machinery/magnet.dm
@@ -143,7 +143,7 @@
// Update power usage:
if(on)
update_use_power(USE_POWER_ACTIVE)
- active_power_usage = electricity_level*15
+ update_active_power_usage(electricity_level * 15)
else
update_use_power(USE_POWER_OFF)
diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm
index 10c96a6b6a..b40314d2c2 100644
--- a/code/game/machinery/oxygen_pump.dm
+++ b/code/game/machinery/oxygen_pump.dm
@@ -148,9 +148,9 @@
/obj/machinery/oxygen_pump/examine(var/mob/user)
. = ..()
if(tank)
- to_chat(user, "The meter shows [round(tank.air_contents.return_pressure())] kPa.")
+ . += "The meter shows [round(tank.air_contents.return_pressure())] kPa."
else
- to_chat(user, "It is missing a tank!")
+ . += "It is missing a tank!"
/obj/machinery/oxygen_pump/process()
diff --git a/code/game/machinery/pda_multicaster.dm b/code/game/machinery/pda_multicaster.dm
index aab6a31ded..29de5307cf 100644
--- a/code/game/machinery/pda_multicaster.dm
+++ b/code/game/machinery/pda_multicaster.dm
@@ -1,8 +1,8 @@
/obj/machinery/pda_multicaster
name = "\improper PDA multicaster"
desc = "This machine mirrors messages sent to it to specific departments."
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "controller"
+ icon = 'icons/obj/stationobjs_vr.dmi' //VOREStation Edit
+ icon_state = "pdamulti" //VOREStation Edit
density = 1
anchored = 1
circuit = /obj/item/weapon/circuitboard/telecomms/pda_multicaster
@@ -19,6 +19,7 @@
"engineering" = new /obj/item/device/pda/multicaster/engineering(src),
"medical" = new /obj/item/device/pda/multicaster/medical(src),
"research" = new /obj/item/device/pda/multicaster/research(src),
+ "exploration" = new /obj/item/device/pda/multicaster/exploration(src), //VOREStation Add,
"cargo" = new /obj/item/device/pda/multicaster/cargo(src),
"civilian" = new /obj/item/device/pda/multicaster/civilian(src))
@@ -43,7 +44,7 @@
if(on)
icon_state = initial(icon_state)
else
- icon_state = "[initial(icon_state)]-p"
+ icon_state = "[initial(icon_state)]_off" //VOREStation Edit
/obj/machinery/pda_multicaster/attackby(obj/item/I, mob/user)
if(I.is_screwdriver())
@@ -77,15 +78,15 @@
if(stat & (BROKEN|NOPOWER|EMPED))
on = 0
update_PDAs(1) // 1 being to turn off.
- idle_power_usage = 0
+ update_idle_power_usage(0)
else
on = 1
update_PDAs(0)
- idle_power_usage = 750
+ update_idle_power_usage(750)
else
on = 0
update_PDAs(1)
- idle_power_usage = 0
+ update_idle_power_usage(0)
update_icon()
/obj/machinery/pda_multicaster/process()
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index 13b1dc1bb7..f5f2532080 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -132,12 +132,6 @@ Buildable meters
src.set_dir(turn(src.dir, 270))
fixdir()
-// If you want to disable pipe dir changing when pulled, uncomment this
-// /obj/item/pipe/Move()
-// var/old_dir = dir
-// . = ..()
-// set_dir(old_dir) //pipes changing direction when moved is just annoying and buggy
-
// Don't let pulling a pipe straighten it out.
/obj/item/pipe/binary/bendable/Move()
var/old_bent = !IS_CARDINAL(dir)
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 9eb323dfa3..a071013080 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -157,7 +157,7 @@ Nah
/obj/machinery/pipedispenser/disposal/Topic(href, href_list)
if(href_list["makepipe"] || href_list["setlayer"] || href_list["makemeter"]) // Asking the disposal machine to do atmos stuff?
return // That's a no no.
- if(..())
+ if((. = ..()))
return
if(href_list["dmake"])
if(!wait)
@@ -169,8 +169,7 @@ Nah
C.add_fingerprint(usr)
C.update()
wait = 1
- spawn(15)
- wait = 0
+ VARSET_IN(src, wait, FALSE, 15)
return
// adding a pipe dispensers that spawn unhooked from the ground
diff --git a/code/game/machinery/pipe/pipe_recipes.dm b/code/game/machinery/pipe/pipe_recipes.dm
index 9d916472bb..8937a45608 100644
--- a/code/game/machinery/pipe/pipe_recipes.dm
+++ b/code/game/machinery/pipe/pipe_recipes.dm
@@ -4,7 +4,7 @@
var/global/list/atmos_pipe_recipes = null
var/global/list/disposal_pipe_recipes = null
-var/global/list/all_pipe_recipes = null
+var/global/list/all_pipe_recipes = null // VOREStation Add
/hook/startup/proc/init_pipe_recipes()
global.atmos_pipe_recipes = list(
@@ -52,40 +52,37 @@ var/global/list/all_pipe_recipes = null
)
global.disposal_pipe_recipes = list(
"Disposal Pipes" = list(
- new /datum/pipe_recipe/disposal("Pipe", DISPOSAL_PIPE_STRAIGHT, "conpipe-s", PIPE_STRAIGHT),
- new /datum/pipe_recipe/disposal("Bent Pipe", DISPOSAL_PIPE_CORNER, "conpipe-c"),
- new /datum/pipe_recipe/disposal("Junction", DISPOSAL_PIPE_JUNCTION, "conpipe-j1", PIPE_TRIN_M, "conpipe-j2"),
- new /datum/pipe_recipe/disposal("Y-Junction", DISPOSAL_PIPE_JUNCTION_Y, "conpipe-y"),
- new /datum/pipe_recipe/disposal("Sort Junction", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, "conpipe-j2s", DISPOSAL_SORT_NORMAL),
- new /datum/pipe_recipe/disposal("Sort Junction (Wildcard)",DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, "conpipe-j2s", DISPOSAL_SORT_WILDCARD),
- new /datum/pipe_recipe/disposal("Sort Junction (Untagged)",DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, "conpipe-j2s", DISPOSAL_SORT_UNTAGGED),
- new /datum/pipe_recipe/disposal("Tagger", DISPOSAL_PIPE_TAGGER, "pipe-tagger", PIPE_STRAIGHT),
- new /datum/pipe_recipe/disposal("Tagger (Partial)", DISPOSAL_PIPE_TAGGER_PARTIAL, "pipe-tagger-partial", PIPE_STRAIGHT),
- new /datum/pipe_recipe/disposal("Trunk", DISPOSAL_PIPE_TRUNK, "conpipe-t"),
- new /datum/pipe_recipe/disposal("Upwards", DISPOSAL_PIPE_UPWARD, "pipe-u"),
- new /datum/pipe_recipe/disposal("Downwards", DISPOSAL_PIPE_DOWNWARD, "pipe-d"),
- new /datum/pipe_recipe/disposal("Bin", DISPOSAL_PIPE_BIN, "disposal", PIPE_ONEDIR),
- new /datum/pipe_recipe/disposal("Outlet", DISPOSAL_PIPE_OUTLET, "outlet"),
- new /datum/pipe_recipe/disposal("Chute", DISPOSAL_PIPE_CHUTE, "intake"),
+ new /datum/pipe_recipe/disposal("Pipe", DISPOSAL_PIPE_STRAIGHT, "conpipe-s", PIPE_STRAIGHT),
+ new /datum/pipe_recipe/disposal("Bent Pipe", DISPOSAL_PIPE_CORNER, "conpipe-c"),
+ new /datum/pipe_recipe/disposal("Junction", DISPOSAL_PIPE_JUNCTION, "conpipe-j1", PIPE_TRIN_M),
+ new /datum/pipe_recipe/disposal("Y-Junction", DISPOSAL_PIPE_JUNCTION_Y, "conpipe-y"),
+ new /datum/pipe_recipe/disposal("Sort Junction", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_NORMAL),
+ new /datum/pipe_recipe/disposal("Sort Junction (Wildcard)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_WILDCARD),
+ new /datum/pipe_recipe/disposal("Sort Junction (Untagged)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_UNTAGGED),
+ new /datum/pipe_recipe/disposal("Tagger", DISPOSAL_PIPE_TAGGER, "pipe-tagger", PIPE_STRAIGHT),
+ new /datum/pipe_recipe/disposal("Tagger (Partial)", DISPOSAL_PIPE_TAGGER_PARTIAL, "pipe-tagger-partial", PIPE_STRAIGHT),
+ new /datum/pipe_recipe/disposal("Trunk", DISPOSAL_PIPE_TRUNK, "conpipe-t"),
+ new /datum/pipe_recipe/disposal("Upwards", DISPOSAL_PIPE_UPWARD, "pipe-u"),
+ new /datum/pipe_recipe/disposal("Downwards", DISPOSAL_PIPE_DOWNWARD, "pipe-d"),
+ new /datum/pipe_recipe/disposal("Bin", DISPOSAL_PIPE_BIN, "disposal", PIPE_ONEDIR),
+ new /datum/pipe_recipe/disposal("Outlet", DISPOSAL_PIPE_OUTLET, "outlet"),
+ new /datum/pipe_recipe/disposal("Chute", DISPOSAL_PIPE_CHUTE, "intake"),
)
)
- global.all_pipe_recipes = disposal_pipe_recipes + atmos_pipe_recipes
+ global.all_pipe_recipes = disposal_pipe_recipes + atmos_pipe_recipes // VOREStation Add
return TRUE
//
// New method of handling pipe construction. Instead of numeric constants and a giant switch statement of doom
// every pipe type has a datum instance which describes its name, placement rules and construction method, dispensing etc.
// The advantages are obvious, mostly in simplifying the code of the dispenser, and the ability to add new pipes without hassle.
+// icon_state and icon_state_m must be from among those available from the dmi files included in /datum/asset/iconsheet/pipes
//
/datum/pipe_recipe
- var/name = "Abstract Pipe (fixme)" // Recipe name
- var/pipe_type // The type PATH of what actual pipe the fitting becomes, used by RCD to print the pipe.
- var/icon = 'icons/obj/pipe-item.dmi' // This tells the RPD which icon file to look for preview images in.
- var/icon_state // This tells the RPD what kind of pipe icon to render for the preview.
- var/icon_state_m // This stores the mirrored version of the regular state (if available).
- var/dirtype // If using an RPD, this tells more about what previews to show.
- var/subtype = 0 // Used for certain disposals pipes types.
- var/paintable = FALSE // If TRUE, allow the RPD to paint this pipe.
+ var/name = "Abstract Pipe (fixme)" // Recipe name
+ var/icon_state = null // This tells the RPD what kind of pipe icon to render for the preview.
+ var/icon_state_m = null // This stores the mirrored version of the regular state (if available).
+ var/dirtype // If using an RPD, this tells more about what previews to show.
// Render an HTML link to select this pipe type. Returns text.
/datum/pipe_recipe/proc/Render(dispenser)
@@ -100,8 +97,10 @@ var/global/list/all_pipe_recipes = null
//
/datum/pipe_recipe/pipe
var/obj/item/pipe/construction_type // The type PATH to the type of pipe fitting object the recipe makes.
+ var/obj/machinery/atmospherics/pipe_type // The type PATH of what actual pipe the fitting becomes.
+ var/paintable = FALSE // If TRUE, allow the RPD to paint this pipe. // VOREStation Add
-/datum/pipe_recipe/pipe/New(var/label, var/obj/machinery/atmospherics/path, var/colorable=FALSE)
+/datum/pipe_recipe/pipe/New(var/label, var/obj/machinery/atmospherics/path)
name = label
pipe_type = path
construction_type = initial(path.construction_type)
@@ -109,7 +108,7 @@ var/global/list/all_pipe_recipes = null
dirtype = initial(construction_type.dispenser_class)
if (dirtype == PIPE_TRIN_M)
icon_state_m = "[icon_state]m"
- paintable = colorable
+ paintable = ispath(path, /obj/machinery/atmospherics/pipe) && !(ispath(path, /obj/machinery/atmospherics/pipe/vent)) // VOREStation Add
// Render an HTML link to select this pipe type
/datum/pipe_recipe/pipe/Render(dispenser)
@@ -141,25 +140,17 @@ var/global/list/all_pipe_recipes = null
// Subtype for disposal pipes
//
/datum/pipe_recipe/disposal
- icon = 'icons/obj/pipes/disposal.dmi'
+ var/pipe_type // pipe_type is one of the DISPOSAL_PIPE_ ptype constants.
+ var/subtype // subtype is one of the DISPOSAL_SORT_ constants.
-/datum/pipe_recipe/disposal/New(var/label, var/path, var/state, dt=PIPE_DIRECTIONAL, var/state_mirror=0, var/sort=0)
+/datum/pipe_recipe/disposal/New(var/label, var/ptype, var/state, dt=PIPE_DIRECTIONAL, var/sort=0)
name = label
icon_state = state
- pipe_type = path
+ pipe_type = ptype
dirtype = dt
subtype = sort
if (dirtype == PIPE_TRIN_M)
- icon_state_m = state_mirror
-
-// Render an HTML link to select this pipe type
-/datum/pipe_recipe/disposal/Render(dispenser)
- var/dat = ..(dispenser)
-
- // Blah blah, add corner pipes because dispensers have no directional information. Look up for more info.
- if(istype(dispenser, /obj/machinery/pipedispenser) && (dirtype == PIPE_BENDABLE))
- dat += "Bent [name]
"
- return dat
+ icon_state_m = replacetext(state, "j1", "j2")
/datum/pipe_recipe/disposal/Params()
var/param = "dmake=[pipe_type]"
diff --git a/code/game/machinery/pipe/pipelayer.dm b/code/game/machinery/pipe/pipelayer.dm
index 366a351d6b..8b49989e61 100644
--- a/code/game/machinery/pipe/pipelayer.dm
+++ b/code/game/machinery/pipe/pipelayer.dm
@@ -42,15 +42,15 @@
..()
// Whenever we move, if enabled try and lay pipe
-/obj/machinery/pipelayer/Move(new_turf,M_Dir)
- ..()
+/obj/machinery/pipelayer/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
if(on && a_dis)
dismantleFloor(old_turf)
- layPipe(old_turf, M_Dir, old_dir)
+ layPipe(old_turf, direction, old_dir)
- old_turf = new_turf
- old_dir = turn(M_Dir, 180)
+ old_turf = loc
+ old_dir = turn(direction, 180)
/obj/machinery/pipelayer/attack_hand(mob/user as mob)
if(..())
@@ -115,8 +115,8 @@
..()
/obj/machinery/pipelayer/examine(mob/user)
- ..()
- to_chat(user, "\The [src] has [metal] sheet\s, is set to produce [P_type_t], and auto-dismantling is [!a_dis?"de":""]activated.")
+ . = ..()
+ . += "[src] has [metal] sheet\s, is set to produce [P_type_t], and auto-dismantling is [!a_dis?"de":""]activated."
/obj/machinery/pipelayer/proc/reset()
on = 0
diff --git a/code/game/machinery/pointdefense.dm b/code/game/machinery/pointdefense.dm
index 3ca0ed601e..f135bdd568 100644
--- a/code/game/machinery/pointdefense.dm
+++ b/code/game/machinery/pointdefense.dm
@@ -158,9 +158,9 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
underlays += I
/obj/machinery/power/pointdefense/examine(mob/user)
- ..()
+ . = ..()
if(powernet)
- to_chat(user, "It is connected to a power cable below.")
+ . += "It is connected to a power cable below."
/obj/machinery/power/pointdefense/get_description_interaction()
. = ..()
@@ -268,6 +268,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
s.set_up(5, 1, src)
s.start()
visible_message("[src] sputters as browns out while attempting to fire.")
+ flick(src, "[initial(icon_state)]_off")
return
//We throw a laser but it doesnt have to hit for meteor to explode
var/obj/item/projectile/beam/pointdefense/beam = new(get_turf(src))
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 1312c0cc3b..06acd97d0b 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -26,13 +26,13 @@
return
/obj/machinery/recharger/examine(mob/user)
- if(!..(user, 5))
- return
+ . = ..()
- to_chat(user, "[charging ? "[charging]" : "Nothing"] is in [src].")
- if(charging)
- var/obj/item/weapon/cell/C = charging.get_cell()
- to_chat(user, "Current charge: [C.charge] / [C.maxcharge]")
+ if(get_dist(user, src) <= 5)
+ . += "[charging ? "[charging]" : "Nothing"] is in [src]."
+ if(charging)
+ var/obj/item/weapon/cell/C = charging.get_cell()
+ . += "Current charge: [C.charge] / [C.maxcharge]"
/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob)
var/allowed = 0
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 3f60e0ae07..75cc5b55cc 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -62,6 +62,9 @@
recharge_amount = cell.give(recharge_amount)
use_power(recharge_amount / CELLRATE)
+ else
+ // Since external power is offline, draw operating current from the internal cell
+ cell.use(get_power_usage() * CELLRATE)
if(icon_update_tick >= 10)
icon_update_tick = 0
@@ -71,19 +74,6 @@
if(occupant || recharge_amount)
update_icon()
-//since the recharge station can still be on even with NOPOWER. Instead it draws from the internal cell.
-/obj/machinery/recharge_station/auto_use_power()
- if(!(stat & NOPOWER))
- return ..()
-
- if(!has_cell_power())
- return 0
- if(use_power == USE_POWER_IDLE)
- cell.use(idle_power_usage * CELLRATE)
- else if(use_power >= USE_POWER_ACTIVE)
- cell.use(active_power_usage * CELLRATE)
- return 1
-
//Processes the occupant, drawing from the internal power cell if needed.
/obj/machinery/recharge_station/proc/process_occupant()
if(isrobot(occupant))
@@ -115,8 +105,8 @@
H.adjustBrainLoss(-(rand(1,3)))
// Also recharge their internal battery.
- if(H.isSynthetic() && H.nutrition < 450)
- H.nutrition = min(H.nutrition+10, 450)
+ if(H.isSynthetic() && H.nutrition < 500) //VOREStation Edit
+ H.nutrition = min(H.nutrition+10, 500) //VOREStation Edit
cell.use(7000/450*10)
// And clear up radiation
@@ -125,8 +115,8 @@
/obj/machinery/recharge_station/examine(mob/user)
- ..(user)
- to_chat(user, "The charge meter reads: [round(chargepercentage())]%")
+ . = ..()
+ . += "The charge meter reads: [round(chargepercentage())]%"
/obj/machinery/recharge_station/proc/chargepercentage()
if(!cell)
diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm
index 1b9d89dc00..9977e765e9 100644
--- a/code/game/machinery/seed_extractor.dm
+++ b/code/game/machinery/seed_extractor.dm
@@ -1,7 +1,7 @@
/obj/machinery/seed_extractor
name = "seed extractor"
desc = "Extracts and bags seeds from produce."
- icon = 'icons/obj/hydroponics_machines.dmi'
+ icon = 'icons/obj/hydroponics_machines_vr.dmi' //VOREStation Edit
icon_state = "sextractor"
density = 1
anchored = 1
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index f45872c2d8..77a35d2829 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -29,13 +29,13 @@
set_light(0)
/obj/machinery/space_heater/examine(mob/user)
- ..(user)
+ . = ..()
- to_chat(user, "The heater is [on ? "on" : "off"] and the hatch is [panel_open ? "open" : "closed"].")
+ . += "The heater is [on ? "on" : "off"] and the hatch is [panel_open ? "open" : "closed"]."
if(panel_open)
- to_chat(user, "The power cell is [cell ? "installed" : "missing"].")
+ . += "The power cell is [cell ? "installed" : "missing"]."
else
- to_chat(user, "The charge meter reads [cell ? round(cell.percent(),1) : 0]%")
+ . += "The charge meter reads [cell ? round(cell.percent(),1) : 0]%"
return
/obj/machinery/space_heater/powered()
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index 0780b5905a..14b85a7861 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -148,9 +148,9 @@
return 0
/obj/machinery/status_display/examine(mob/user)
- . = ..(user)
+ . = ..()
if(mode != STATUS_DISPLAY_BLANK && mode != STATUS_DISPLAY_ALERT)
- to_chat(user, "The display says:
\t[sanitize(message1)]
\t[sanitize(message2)]")
+ . += "The display says:
\t[sanitize(message1)]
\t[sanitize(message2)]"
/obj/machinery/status_display/proc/set_message(m1, m2)
if(m1)
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 27ce3db4f1..5f3b462452 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -789,7 +789,7 @@
if(shock(user, 100))
return
- usr.set_machine(src)
+ user.set_machine(src)
var/dat = "Suit Cycler Interface"
@@ -798,7 +798,7 @@
else if(locked)
dat += "
The [model_text ? "[model_text] " : ""]suit cycler is currently locked. Please contact your system administrator."
- if(allowed(usr))
+ if(allowed(user))
dat += "
\[unlock unit\]"
else
dat += "Suit cycler
"
@@ -972,7 +972,7 @@
occupant.loc = get_turf(occupant)
occupant = null
- add_fingerprint(usr)
+ add_fingerprint(user)
updateUsrDialog()
update_icon()
diff --git a/code/game/machinery/supplybeacon.dm b/code/game/machinery/supplybeacon.dm
index df40ba1a7d..20be7d52ca 100644
--- a/code/game/machinery/supplybeacon.dm
+++ b/code/game/machinery/supplybeacon.dm
@@ -80,7 +80,7 @@
return
set_light(3, 3, "#00CCAA")
icon_state = "beacon_active"
- use_power = USE_POWER_IDLE
+ update_use_power(USE_POWER_IDLE)
if(user) to_chat(user, "You activate the beacon. The supply drop will be dispatched soon.")
/obj/machinery/power/supply_beacon/proc/deactivate(var/mob/user, var/permanent)
@@ -90,7 +90,7 @@
else
icon_state = "beacon"
set_light(0)
- use_power = USE_POWER_OFF
+ update_use_power(USE_POWER_OFF)
target_drop_time = null
if(user) to_chat(user, "You deactivate the beacon.")
diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index f392eb5218..165df28298 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -12,7 +12,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/obj/machinery/telecomms/broadcaster
name = "Subspace Broadcaster"
- icon = 'icons/obj/stationobjs.dmi'
+ //icon = 'icons/obj/stationobjs.dmi' //VOREStation Removal - use parent icon
icon_state = "broadcaster"
desc = "A dish-shaped machine used to broadcast processed subspace signals."
density = 1
@@ -86,8 +86,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"], DATA_NORMAL,
signal.data["compression"], signal.data["level"], signal.frequency,
- signal.data["verb"], signal.data["language"], forced_radios)
-
+ signal.data["verb"], forced_radios)
/** #### - Simple Broadcast - #### **/
@@ -113,7 +112,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"], DATA_FAKE,
signal.data["compression"], signal.data["level"], signal.frequency,
- signal.data["verb"], signal.data["language"], forced_radios)
+ signal.data["verb"], forced_radios)
if(!message_delay)
message_delay = 1
@@ -139,8 +138,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/obj/machinery/telecomms/allinone
name = "Telecommunications Mainframe"
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "comm_server"
+ //icon = 'icons/obj/stationobjs.dmi' //VOREStation Removal - use parent icon
+ icon_state = "allinone" //VOREStation Edit
desc = "A compact machine used for portable subspace telecommuniations processing."
density = 1
use_power = USE_POWER_IDLE
@@ -272,7 +271,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"], DATA_NORMAL,
signal.data["compression"], list(0), connection.frequency,
- signal.data["verb"], signal.data["language"], forced_radios)
+ signal.data["verb"], forced_radios)
else
if(intercept)
Broadcast_Message(signal.data["connection"], signal.data["mob"],
@@ -281,7 +280,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"], DATA_ANTAG,
signal.data["compression"], list(0), connection.frequency,
- signal.data["verb"], signal.data["language"], forced_radios)
+ signal.data["verb"], forced_radios)
/**
@@ -341,11 +340,10 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
**/
/proc/Broadcast_Message(var/datum/radio_frequency/connection, var/mob/M,
- var/vmask, var/vmessage, var/obj/item/device/radio/radio,
- var/message, var/name, var/job, var/realname, var/vname,
+ var/vmask, var/list/vmessage_pieces, var/obj/item/device/radio/radio,
+ var/list/message_pieces, var/name, var/job, var/realname, var/vname,
var/data, var/compression, var/list/level, var/freq, var/verbage = "says",
- var/datum/language/speaking = null, var/list/forced_radios)
-
+ var/list/forced_radios)
/* ###### Prepare the radio connection ###### */
@@ -355,7 +353,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
for(var/obj/item/device/radio/R in forced_radios)
//Cursory check to ensure they are 'on' and stuff
- if(R.receive_range(display_freq, list(0)))
+ if(R.receive_range(display_freq, list(0)) > -1)
radios |= R
// --- Broadcast only to intercom devices ---
@@ -412,7 +410,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
for (var/mob/R in receive)
/* --- Loop through the receivers and categorize them --- */
- if (!R.is_preference_enabled(/datum/client_preference/holder/hear_radio))
+ if(!R.is_preference_enabled(/datum/client_preference/holder/hear_radio))
continue
if(istype(R, /mob/new_player)) // we don't want new players to hear messages. rare but generates runtimes.
@@ -429,10 +427,10 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
// --- Can understand the speech ---
- if (!M || R.say_understands(M))
+ if(!M || R.say_understands(M))
// - Not human or wearing a voice mask -
- if (!M || !ishuman(M) || vmask)
+ if(!M || !ishuman(M) || vmask)
heard_masked += R
// - Human and not wearing voice mask -
@@ -443,7 +441,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
else
// - The speaker has a prespecified "voice message" to display if not understood -
- if (vmessage)
+ if(vmessage_pieces)
heard_voice += R
// - Just display a garbled message -
@@ -452,7 +450,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/* ###### Begin formatting and sending the message ###### */
- if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled) || length(heard_gibberish))
+ if(length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled) || length(heard_gibberish))
/* --- Some miscellaneous variables to format the string output --- */
var/freq_text = get_frequency_name(display_freq)
@@ -468,12 +466,11 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
// --- Filter the message; place it in quotes apply a verb ---
-
var/quotedmsg = null
if(M)
- quotedmsg = M.say_quote(message)
+ quotedmsg = "[M.say_quote(multilingual_to_message(message_pieces))], \"[multilingual_to_message(message_pieces)]\""
else
- quotedmsg = "says, \"[message]\""
+ quotedmsg = "says, \"[multilingual_to_message(message_pieces)]\""
// --- This following recording is intended for research and feedback in the use of department radio channels ---
@@ -514,44 +511,36 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
//End of research and feedback code.
/* ###### Send the message ###### */
-
-
/* --- Process all the mobs that heard a masked voice (understood) --- */
-
- if (length(heard_masked))
+ if(length(heard_masked))
for (var/mob/R in heard_masked)
- R.hear_radio(message,verbage, speaking, part_a, part_b, part_c, M, 0, name)
+ R.hear_radio(message_pieces, verbage, part_a, part_b, part_c, M, 0, name)
/* --- Process all the mobs that heard the voice normally (understood) --- */
-
- if (length(heard_normal))
+ if(length(heard_normal))
for (var/mob/R in heard_normal)
- R.hear_radio(message, verbage, speaking, part_a, part_b, part_c, M, 0, realname)
+ R.hear_radio(message_pieces, verbage, part_a, part_b, part_c, M, 0, realname)
/* --- Process all the mobs that heard the voice normally (did not understand) --- */
-
- if (length(heard_voice))
+ if(length(heard_voice))
for (var/mob/R in heard_voice)
- R.hear_radio(message,verbage, speaking, part_a, part_b, part_c, M,0, vname)
+ R.hear_radio(message_pieces, verbage, part_a, part_b, part_c, M,0, vname)
/* --- Process all the mobs that heard a garbled voice (did not understand) --- */
// Displays garbled message (ie "f*c* **u, **i*er!")
-
- if (length(heard_garbled))
+ if(length(heard_garbled))
for (var/mob/R in heard_garbled)
- R.hear_radio(message, verbage, speaking, part_a, part_b, part_c, M, 1, vname)
-
+ R.hear_radio(message_pieces, verbage, part_a, part_b, part_c, M, 1, vname)
/* --- Complete gibberish. Usually happens when there's a compressed message --- */
-
- if (length(heard_gibberish))
+ if(length(heard_gibberish))
for (var/mob/R in heard_gibberish)
- R.hear_radio(message, verbage, speaking, part_a, part_b, part_c, M, 1)
+ R.hear_radio(message_pieces, verbage, part_a, part_b, part_c, M, 1)
return 1
-/proc/Broadcast_SimpleMessage(var/source, var/frequency, var/text, var/data, var/mob/M, var/compression, var/level, var/list/forced_radios)
-
+/proc/Broadcast_SimpleMessage(var/source, var/frequency, list/message_pieces, var/data, var/mob/M, var/compression, var/level, var/list/forced_radios)
+ var/text = multilingual_to_message(message_pieces)
/* ###### Prepare the radio connection ###### */
if(!M)
@@ -633,7 +622,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
// --- Can understand the speech ---
- if (R.say_understands(M))
+ if(R.say_understands(M))
heard_normal += R
@@ -646,7 +635,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/* ###### Begin formatting and sending the message ###### */
- if (length(heard_normal) || length(heard_garbled) || length(heard_gibberish))
+ if(length(heard_normal) || length(heard_garbled) || length(heard_gibberish))
/* --- Some miscellaneous variables to format the string output --- */
var/part_a = "" // goes in the actual output
@@ -701,7 +690,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/* --- Process all the mobs that heard the voice normally (understood) --- */
- if (length(heard_normal))
+ if(length(heard_normal))
var/rendered = "[part_a][source][part_b]\"[text]\"[part_c]"
for (var/mob/R in heard_normal)
@@ -710,7 +699,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/* --- Process all the mobs that heard a garbled voice (did not understand) --- */
// Displays garbled message (ie "f*c* **u, **i*er!")
- if (length(heard_garbled))
+ if(length(heard_garbled))
var/quotedmsg = "\"[stars(text)]\""
var/rendered = "[part_a][source][part_b][quotedmsg][part_c]"
@@ -720,7 +709,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/* --- Complete gibberish. Usually happens when there's a compressed message --- */
- if (length(heard_gibberish))
+ if(length(heard_gibberish))
var/quotedmsg = "\"[Gibberish(text, compression + 50)]\""
var/rendered = "[part_a][Gibberish(source, compression + 50)][part_b][quotedmsg][part_c]"
diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm
index 5ee974e571..050502c420 100644
--- a/code/game/machinery/telecomms/machine_interactions.dm
+++ b/code/game/machinery/telecomms/machine_interactions.dm
@@ -229,11 +229,11 @@
if(href_list["range_down"])
if(overmap_range > overmap_range_min)
overmap_range--
- idle_power_usage = initial(idle_power_usage)**(overmap_range+1)
+ update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1))
if(href_list["range_up"])
if(overmap_range < overmap_range_max)
overmap_range++
- idle_power_usage = initial(idle_power_usage)**(overmap_range+1)
+ update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1))
// RECEIVER
/obj/machinery/telecomms/receiver/Options_Menu()
@@ -245,11 +245,11 @@
if(href_list["range_down"])
if(overmap_range > overmap_range_min)
overmap_range--
- idle_power_usage = initial(idle_power_usage)**(overmap_range+1)
+ update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1))
if(href_list["range_up"])
if(overmap_range < overmap_range_max)
overmap_range++
- idle_power_usage = initial(idle_power_usage)**(overmap_range+1)
+ update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1))
/obj/machinery/telecomms/Topic(href, href_list)
diff --git a/code/game/machinery/telecomms/presets_vr.dm b/code/game/machinery/telecomms/presets_vr.dm
index 01a07a5f5e..3b252f92ce 100644
--- a/code/game/machinery/telecomms/presets_vr.dm
+++ b/code/game/machinery/telecomms/presets_vr.dm
@@ -4,5 +4,6 @@
produces_heat = 0
autolinkers = list("hb_relay")
-/obj/machinery/telecomms/relay/proc/reset_z()
- listening_level = z
+/obj/machinery/telecomms/relay/onTransitZ(oldz, newz)
+ . = ..()
+ listening_level = newz
diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm
index 38f1adbdfc..1d765375be 100644
--- a/code/game/machinery/telecomms/telecomunications.dm
+++ b/code/game/machinery/telecomms/telecomunications.dm
@@ -16,6 +16,7 @@
var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms
+ icon = 'icons/obj/stationobjs_vr.dmi' //VOREStation Add
var/list/links = list() // list of machines this machine is linked to
var/traffic = 0 // value increases as traffic increases
var/netspeed = 5 // how much traffic to lose per tick (50 gigabytes/second * netspeed)
@@ -246,7 +247,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/receiver
name = "Subspace Receiver"
- icon = 'icons/obj/stationobjs.dmi'
+ //icon = 'icons/obj/stationobjs.dmi' //VOREStation Removal - use parent icon
icon_state = "broadcast receiver"
desc = "This machine has a dish-like shape and green lights. It is designed to detect and process subspace radio activity."
density = 1
@@ -340,7 +341,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/hub
name = "Telecommunication Hub"
- icon = 'icons/obj/stationobjs.dmi'
+ //icon = 'icons/obj/stationobjs.dmi' //VOREStation Removal - use parent icon
icon_state = "hub"
desc = "A mighty piece of hardware used to send/receive massive amounts of data."
density = 1
@@ -351,11 +352,9 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
circuit = /obj/item/weapon/circuitboard/telecomms/hub
long_range_link = 1
netspeed = 40
- var/list/telecomms_map
/obj/machinery/telecomms/hub/Initialize()
. = ..()
- LAZYINITLIST(telecomms_map)
component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
@@ -364,20 +363,6 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
component_parts += new /obj/item/stack/cable_coil(src, 2)
RefreshParts()
-/obj/machinery/telecomms/hub/process()
- . = ..()
- telecomms_map.Cut()
-
- if(!on)
- return
-
- for(var/M in links)
- if(istype(M,/obj/machinery/telecomms/receiver) || istype(M,/obj/machinery/telecomms/relay))
- var/obj/machinery/telecomms/R = M
- if(!R.on)
- continue
- telecomms_map |= R.listening_level
-
/obj/machinery/telecomms/hub/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
if(is_freq_listening(signal))
if(istype(machine_from, /obj/machinery/telecomms/receiver))
@@ -399,7 +384,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/relay
name = "Telecommunication Relay"
- icon = 'icons/obj/stationobjs.dmi'
+ //icon = 'icons/obj/stationobjs.dmi' //VOREStation Removal - use parent icon
icon_state = "relay"
desc = "A mighty piece of hardware used to send massive amounts of data far away."
density = 1
@@ -465,7 +450,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/bus
name = "Bus Mainframe"
- icon = 'icons/obj/stationobjs.dmi'
+ //icon = 'icons/obj/stationobjs.dmi' //VOREStation Removal - use parent icon
icon_state = "bus"
desc = "A mighty piece of hardware used to send massive amounts of data quickly."
density = 1
@@ -526,7 +511,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/processor
name = "Processor Unit"
- icon = 'icons/obj/stationobjs.dmi'
+ //icon = 'icons/obj/stationobjs.dmi' //VOREStation Removal - use parent icon
icon_state = "processor"
desc = "This machine is used to process large quantities of information."
density = 1
@@ -578,7 +563,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/server
name = "Telecommunication Server"
- icon = 'icons/obj/stationobjs.dmi'
+ //icon = 'icons/obj/stationobjs.dmi' //VOREStation Removal - use parent icon
icon_state = "comm_server"
desc = "A machine used to store data and network statistics."
density = 1
@@ -601,7 +586,6 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
var/encryption = "null" // encryption key: ie "password"
var/salt = "null" // encryption salt: ie "123comsat"
// would add up to md5("password123comsat")
- var/language = "human"
var/obj/item/device/radio/headset/server_radio = null
/obj/machinery/telecomms/server/New()
@@ -642,12 +626,11 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
log.parameters["mobtype"] = signal.data["mobtype"]
log.parameters["job"] = signal.data["job"]
log.parameters["key"] = signal.data["key"]
- log.parameters["vmessage"] = signal.data["message"]
+ log.parameters["vmessage"] = multilingual_to_message(signal.data["message"])
log.parameters["vname"] = signal.data["vname"]
- log.parameters["message"] = signal.data["message"]
+ log.parameters["message"] = multilingual_to_message(signal.data["message"])
log.parameters["name"] = signal.data["name"]
log.parameters["realname"] = signal.data["realname"]
- log.parameters["language"] = signal.data["language"]
var/race = "unknown"
if(ishuman(M))
@@ -676,7 +659,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
// If the signal is still compressed, make the log entry gibberish
if(signal.data["compression"] > 0)
- log.parameters["message"] = Gibberish(signal.data["message"], signal.data["compression"] + 50)
+ log.parameters["message"] = Gibberish(multilingual_to_message(signal.data["message"]), signal.data["compression"] + 50)
log.parameters["job"] = Gibberish(signal.data["job"], signal.data["compression"] + 50)
log.parameters["name"] = Gibberish(signal.data["name"], signal.data["compression"] + 50)
log.parameters["realname"] = Gibberish(signal.data["realname"], signal.data["compression"] + 50)
@@ -752,17 +735,10 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
return FALSE
//Items don't have a Z when inside an object or mob
- var/turf/src_turf = get_turf(A)
- var/turf/dst_turf = get_turf(B)
+ var/turf/src_z = get_z(A)
+ var/turf/dst_z = get_z(B)
//Nullspace, probably.
- if(!src_turf || !dst_turf)
- return FALSE
-
- var/src_z = src_turf.z
- var/dst_z = dst_turf.z
-
- //Mysterious!
if(!src_z || !dst_z)
return FALSE
@@ -770,11 +746,4 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
if(ad_hoc && src_z == dst_z)
return TRUE
- //Let's look at hubs and see what we got.
- var/can_comm = FALSE
- for(var/obj/machinery/telecomms/hub/H in telecomms_list)
- if((src_z in H.telecomms_map) && (dst_z in H.telecomms_map))
- can_comm = TRUE
- break
-
- return can_comm
+ return src_z in using_map.get_map_levels(dst_z)
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index bfc8e308a3..c27de5c31c 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -168,6 +168,7 @@
/obj/machinery/teleport/hub
name = "teleporter hub"
desc = "It's the hub of a teleporting machine."
+ icon = 'icons/obj/teleporter_vr.dmi' //VOREStation Add
icon_state = "tele0"
dir = 4
var/accurate = 0
@@ -323,6 +324,7 @@
/obj/machinery/teleport/station
name = "station"
desc = "It's the station thingy of a teleport thingy." //seriously, wtf.
+ icon = 'icons/obj/teleporter_vr.dmi' //VOREStation Add
icon_state = "controller"
dir = 4
var/active = 0
@@ -401,6 +403,7 @@
O.show_message("Test firing!", 2)
com.teleport()
use_power(5000)
+ flick(src, "controller-c") //VOREStation Add
spawn(30)
active=0
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 6537b70dfa..7cfef19b80 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -949,7 +949,7 @@
/obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3)
contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/mtearseed = 2,
/obj/item/seeds/nettleseed = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/shandseed = 2,)
- premium = list(/obj/item/toy/waterflower = 1)
+ premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1)
/**
* Populate hydroseeds product_records
@@ -1014,7 +1014,8 @@
/obj/item/weapon/storage/toolbox/lunchbox/mars = 3,
/obj/item/weapon/storage/toolbox/lunchbox/cti = 3,
/obj/item/weapon/storage/toolbox/lunchbox/nymph = 3,
- /obj/item/weapon/storage/toolbox/lunchbox/syndicate = 3)
+ /obj/item/weapon/storage/toolbox/lunchbox/syndicate = 3,
+ /obj/item/trash/bowl = 10) //VOREStation Add
contraband = list(/obj/item/weapon/material/knife/butch = 2)
/obj/machinery/vending/sovietsoda
@@ -1124,7 +1125,17 @@
/obj/item/toy/plushie/carp = 1,
/obj/item/toy/plushie/deer = 1,
/obj/item/toy/plushie/tabby_cat = 1,
- /obj/item/device/threadneedle = 3)
+ /obj/item/device/threadneedle = 3,
+ //VOREStation Add Start
+ /obj/item/toy/plushie/lizardplushie/kobold = 1,
+ /obj/item/toy/plushie/slimeplushie = 1,
+ /obj/item/toy/plushie/box = 1,
+ /obj/item/toy/plushie/borgplushie = 1,
+ /obj/item/toy/plushie/borgplushie/medihound = 1,
+ /obj/item/toy/plushie/borgplushie/scrubpuppy = 1,
+ /obj/item/toy/plushie/foxbear = 1,
+ /obj/item/toy/plushie/nukeplushie = 1)
+ //VOREStation Add End
premium = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne = 1,
/obj/item/weapon/storage/trinketbox = 2)
prices = list(/obj/item/weapon/storage/fancy/heartbox = 15,
@@ -1153,7 +1164,17 @@
/obj/item/toy/plushie/carp = 50,
/obj/item/toy/plushie/deer = 50,
/obj/item/toy/plushie/tabby_cat = 50,
- /obj/item/device/threadneedle = 2)
+ /obj/item/device/threadneedle = 2,
+ //VOREStation Add Start
+ /obj/item/toy/plushie/lizardplushie/kobold = 50,
+ /obj/item/toy/plushie/slimeplushie = 50,
+ /obj/item/toy/plushie/box = 50,
+ /obj/item/toy/plushie/borgplushie = 50,
+ /obj/item/toy/plushie/borgplushie/medihound = 50,
+ /obj/item/toy/plushie/borgplushie/scrubpuppy = 50,
+ /obj/item/toy/plushie/foxbear = 50,
+ /obj/item/toy/plushie/nukeplushie = 50)
+ //VOREStation Add End
/obj/machinery/vending/fishing
name = "Loot Trawler"
diff --git a/code/game/machinery/vending_vr.dm b/code/game/machinery/vending_vr.dm
index ed06132e7f..892bb0bf48 100644
--- a/code/game/machinery/vending_vr.dm
+++ b/code/game/machinery/vending_vr.dm
@@ -22,35 +22,6 @@
/obj/item/clothing/glasses/omnihud/med = 4, /obj/item/device/glasses_kit = 1, /obj/item/weapon/storage/quickdraw/syringe_case = 4)
..()
-//Custom vendors
-/obj/machinery/vending/dinnerware
- name = "Dinnerware"
- desc = "A kitchen and restaurant equipment vendor."
- product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..."
- icon_state = "dinnerware"
- products = list(
- /obj/item/weapon/tray = 8,
- /obj/item/weapon/material/kitchen/utensil/fork = 6,
- /obj/item/weapon/material/knife/plastic = 6,
- /obj/item/weapon/material/kitchen/utensil/spoon = 6,
- /obj/item/weapon/material/knife = 3,
- /obj/item/weapon/material/kitchen/rollingpin = 2,
- /obj/item/weapon/reagent_containers/food/drinks/glass2/square = 8,
- /obj/item/weapon/reagent_containers/food/drinks/glass2/shake = 8,
- /obj/item/weapon/glass_extra/stick = 15,
- /obj/item/weapon/glass_extra/straw = 15,
- /obj/item/clothing/suit/chef/classic = 2,
- /obj/item/weapon/storage/toolbox/lunchbox = 3,
- /obj/item/weapon/storage/toolbox/lunchbox/heart = 3,
- /obj/item/weapon/storage/toolbox/lunchbox/cat = 3,
- /obj/item/weapon/storage/toolbox/lunchbox/nt = 3,
- /obj/item/weapon/storage/toolbox/lunchbox/mars = 3,
- /obj/item/weapon/storage/toolbox/lunchbox/cti = 3,
- /obj/item/weapon/storage/toolbox/lunchbox/nymph = 3,
- /obj/item/weapon/storage/toolbox/lunchbox/syndicate = 3,
- /obj/item/trash/bowl = 30)
- contraband = list(/obj/item/weapon/material/knife/butch = 2)
-
//I want this not just as part of the zoo. ;v
/obj/machinery/vending/food
name = "Food-O-Mat"
@@ -136,6 +107,7 @@
product_ads = "The true life juice!;Vampire's choice!;Home-grown blood only!;Donate today, be saved tomorrow!;Approved by Zeng-Hu Pharmaceuticals Incorporated!; Curse you, Vey-Med artificial blood!"
icon = 'icons/obj/vending_vr.dmi'
icon_state = "blood"
+ vend_delay = 7
idle_power_usage = 211
req_access = list(access_medical)
products = list(/obj/item/weapon/reagent_containers/blood/prelabeled/APlus = 3,/obj/item/weapon/reagent_containers/blood/prelabeled/AMinus = 3,
@@ -634,6 +606,9 @@
/obj/item/clothing/under/dress/sailordress = 5,
/obj/item/clothing/under/dress/sari = 5,
/obj/item/clothing/under/dress/sari/green = 5,
+ /obj/item/clothing/under/dress/qipao = 5,
+ /obj/item/clothing/under/dress/qipao/red = 5,
+ /obj/item/clothing/under/dress/qipao/white = 5,
/obj/item/clothing/under/shorts/red = 5,
/obj/item/clothing/under/shorts/green = 5,
/obj/item/clothing/under/shorts/blue = 5,
@@ -801,6 +776,9 @@
/obj/item/clothing/under/dress/sailordress = 100,
/obj/item/clothing/under/dress/sari = 100,
/obj/item/clothing/under/dress/sari/green = 100,
+ /obj/item/clothing/under/dress/qipao = 100,
+ /obj/item/clothing/under/dress/qipao/red = 100,
+ /obj/item/clothing/under/dress/qipao/white = 100,
/obj/item/clothing/under/shorts/red = 100,
/obj/item/clothing/under/shorts/green = 100,
/obj/item/clothing/under/shorts/blue = 100,
diff --git a/code/game/machinery/vitals_monitor.dm b/code/game/machinery/vitals_monitor.dm
new file mode 100644
index 0000000000..a26c3ff706
--- /dev/null
+++ b/code/game/machinery/vitals_monitor.dm
@@ -0,0 +1,149 @@
+/obj/item/weapon/circuitboard/machine/vitals_monitor
+ name = "circuit board (vitals monitor)"
+ build_path = /obj/machinery/vitals_monitor
+ board_type = new /datum/frame/frame_types/machine
+ origin_tech = list(TECH_DATA = 3, TECH_BIO = 4, TECH_ENGINEERING = 2)
+ req_components = list(
+ /obj/item/weapon/stock_parts/console_screen = 1,
+ /obj/item/weapon/cell/high = 1
+ )
+
+/obj/machinery/vitals_monitor
+ name = "vitals monitor"
+ desc = "A bulky yet mobile machine, showing some odd graphs."
+ icon = 'icons/obj/heartmonitor.dmi'
+ icon_state = "base"
+ anchored = FALSE
+ power_channel = EQUIP
+ idle_power_usage = 10
+ active_power_usage = 100
+
+ var/mob/living/carbon/human/victim
+ var/beep = TRUE
+
+/obj/machinery/vitals_monitor/Initialize()
+ . = ..()
+ default_apply_parts()
+
+/obj/machinery/vitals_monitor/Destroy()
+ victim = null
+ . = ..()
+
+/obj/machinery/vitals_monitor/examine(mob/user)
+ . = ..()
+ if(victim)
+ if(stat & NOPOWER)
+ . += "It's unpowered."
+ return
+ . += "Vitals of [victim]:"
+ . += "Pulse: [victim.get_pulse(GETPULSE_TOOL)]"
+
+ var/brain_activity = "none"
+ var/breathing = "none"
+
+ if(victim.stat != DEAD && !(victim.status_flags & FAKEDEATH))
+ var/obj/item/organ/internal/brain/brain = victim.internal_organs_by_name[O_BRAIN]
+ if(istype(brain))
+ if(victim.getBrainLoss())
+ brain_activity = "anomalous"
+ else if(victim.stat == UNCONSCIOUS)
+ brain_activity = "weak"
+ else
+ brain_activity = "normal"
+
+ var/obj/item/organ/internal/lungs/lungs = victim.internal_organs_by_name[O_LUNGS]
+ if(istype(lungs))
+ var/oxyloss = victim.getOxyLoss()
+ if(oxyloss > 50)
+ breathing = "erratic"
+ else if(oxyloss > 10)
+ breathing = "shallow"
+ else
+ breathing = "normal"
+
+ . += "Brain activity: [brain_activity]"
+ . += "Breathing: [breathing]"
+
+/obj/machinery/vitals_monitor/process()
+ if(QDELETED(victim))
+ victim = null
+ update_icon()
+ update_use_power(USE_POWER_IDLE)
+ if(victim && !Adjacent(victim))
+ victim = null
+ update_icon()
+ update_use_power(USE_POWER_IDLE)
+ if(victim)
+ update_icon()
+ if(beep && victim && victim.pulse)
+ playsound(src, 'sound/machines/quiet_beep.ogg')
+
+/obj/machinery/vitals_monitor/MouseDrop(over_object, src_location, over_location)
+ if(!CanMouseDrop(over_object))
+ return
+ if(victim)
+ victim = null
+ update_use_power(USE_POWER_IDLE)
+ else if(ishuman(over_object))
+ victim = over_object
+ update_use_power(USE_POWER_ACTIVE)
+ visible_message("\The [src] is now showing data for [victim].")
+
+/obj/machinery/vitals_monitor/update_icon()
+ cut_overlays()
+ if(stat & NOPOWER)
+ return
+ add_overlay("screen")
+
+ if(!victim)
+ return
+
+ switch(victim.pulse)
+ if(PULSE_NONE)
+ add_overlay("pulse_flatline")
+ add_overlay("pulse_warning")
+ if(PULSE_SLOW, PULSE_NORM,)
+ add_overlay("pulse_normal")
+ if(PULSE_FAST, PULSE_2FAST)
+ add_overlay("pulse_veryfast")
+ if(PULSE_THREADY)
+ add_overlay("pulse_thready")
+ add_overlay("pulse_warning")
+
+ var/obj/item/organ/internal/brain/brain = victim.internal_organs_by_name[O_BRAIN]
+ if(istype(brain) && victim.stat != DEAD && !(victim.status_flags & FAKEDEATH))
+ if(victim.getBrainLoss())
+ add_overlay("brain_verybad")
+ add_overlay("brain_warning")
+ else if(victim.stat == UNCONSCIOUS)
+ add_overlay("brain_bad")
+ else
+ add_overlay("brain_ok")
+ else
+ add_overlay("brain_warning")
+
+ var/obj/item/organ/internal/lungs/lungs = victim.internal_organs_by_name[O_LUNGS]
+ if(istype(lungs) && victim.stat != DEAD && !(victim.status_flags & FAKEDEATH))
+ var/oxyloss = victim.getOxyLoss()
+ if(oxyloss > 50)
+ add_overlay("breathing_shallow")
+ add_overlay("breathing_warning")
+ else if(oxyloss > 10)
+ add_overlay("breathing_shallow")
+ else
+ add_overlay("breathing_normal")
+ else
+ add_overlay("breathing_warning")
+
+/obj/machinery/vitals_monitor/verb/toggle_beep()
+ set name = "Toggle Monitor Beeping"
+ set category = "Object"
+ set src in view(1)
+
+ var/mob/user = usr
+ if(!istype(user))
+ return
+
+ if(CanInteract(user, physical_state))
+ beep = !beep
+ to_chat(user, "You turn the sound on \the [src] [beep ? "on" : "off"].")
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index fd46233390..2a6b90cdc6 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -1,8 +1,8 @@
/obj/machinery/washing_machine
name = "Washing Machine"
desc = "Not a hiding place."
- icon = 'icons/obj/machines/washing_machine.dmi'
- icon_state = "wm_10"
+ icon = 'icons/obj/machines/washing_machine_vr.dmi' //VOREStation Edit
+ icon_state = "wm_1" //VOREStation Edit
density = 1
anchored = 1.0
clicksound = "button"
@@ -85,7 +85,12 @@
usr.loc = src.loc
/obj/machinery/washing_machine/update_icon()
- icon_state = "wm_[state][panel_open]"
+ //VOREStation Edit
+ cut_overlays()
+ icon_state = "wm_[state]"
+ if(panel_open)
+ add_overlay("panel")
+ //VOREStation Edit End
/obj/machinery/washing_machine/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(state == 2 && washing.len < 1)
diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm
index b58956579a..b5d3351b21 100644
--- a/code/game/mecha/combat/combat.dm
+++ b/code/game/mecha/combat/combat.dm
@@ -119,134 +119,6 @@
melee_can_hit = 1
return
-/*
-/obj/mecha/combat/proc/mega_shake(target)
- if(!istype(target, /obj) && !istype(target, /mob)) return
- if(istype(target, /mob))
- var/mob/M = target
- M.make_dizzy(3)
- M.adjustBruteLoss(1)
- M.updatehealth()
- for (var/mob/V in viewers(src))
- V.show_message("[src.name] shakes [M] like a rag doll.")
- return
-*/
-
-/*
- if(energy>0 && can_move)
- if(step(src,direction))
- can_move = 0
- spawn(step_in) can_move = 1
- if(overload)
- energy = energy-2
- health--
- else
- energy--
- return 1
-
- return 0
-*/
-/*
-/obj/mecha/combat/hear_talk(mob/M as mob, text)
- ..()
- if(am && M==occupant)
- if(findtext(text,""))
- sam()
- return
-
-/obj/mecha/combat/proc/sam()
- if(am)
- var/window = {"
-
-
-
-
-
-
-
-
- "}
- occupant << browse(window, "window=sam;size=800x600;")
- onclose(occupant, "sam", src)
- return
-*/
/obj/mecha/combat/moved_inside(var/mob/living/carbon/human/H as mob)
if(..())
if(H.client)
@@ -275,10 +147,3 @@
if(top_filter.get("close"))
am = null
return
- /*
- if(top_filter.get("saminput"))
- if(md5(top_filter.get("saminput")) == am)
- occupant_message("From the lies of the Antipath, Circuit preserve us.")
- am = null
- return
- */
diff --git a/code/game/mecha/combat/fighter.dm b/code/game/mecha/combat/fighter.dm
index 171c96395e..5b04451dce 100644
--- a/code/game/mecha/combat/fighter.dm
+++ b/code/game/mecha/combat/fighter.dm
@@ -8,7 +8,7 @@
var/stabilization_enabled = TRUE //If our anti-space-drift is on
var/ground_capable = FALSE //If we can fly over normal turfs and not just space
- icon = 'icons/mecha/fighters64x64.dmi'
+ icon = 'icons/mecha/fighters64x64.dmi' //See ATTRIBUTIONS.md for details on license
icon_state = ""
initial_icon = ""
@@ -208,16 +208,6 @@
else
who << sound('sound/mecha/fighter_entered.ogg',volume=50)
-////////////// Equipment //////////////
-
-// For 64x64 fighters
-/obj/item/mecha_parts/mecha_equipment/omni_shield/fighter64
- shield_type = /obj/item/shield_projector/rectangle/mecha/fighter64
-/obj/item/shield_projector/rectangle/mecha/fighter64
- shift_x = 16
- shift_y = 16
-
-
////////////// Gunpod //////////////
/obj/mecha/combat/fighter/gunpod
@@ -316,7 +306,7 @@
. = ..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
ME.attach(src)
- ME = new /obj/item/mecha_parts/mecha_equipment/omni_shield/fighter64
+ ME = new /obj/item/mecha_parts/mecha_equipment/omni_shield
ME.attach(src)
/obj/effect/decal/mecha_wreckage/baron
diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm
index 8f72de5f51..48394f47f4 100644
--- a/code/game/mecha/combat/phazon.dm
+++ b/code/game/mecha/combat/phazon.dm
@@ -18,6 +18,7 @@
internal_damage_threshold = 25
force = 15
var/phasing = 0
+ var/can_phase = TRUE
var/phasing_energy_drain = 200
max_equip = 4
@@ -38,13 +39,13 @@
/obj/mecha/combat/phazon/Bump(var/atom/obstacle)
if(phasing && get_charge()>=phasing_energy_drain)
spawn()
- if(can_move)
- can_move = 0
+ if(can_phase)
+ can_phase = FALSE
flick("[initial_icon]-phase", src)
src.loc = get_step(src,src.dir)
src.use_power(phasing_energy_drain)
sleep(step_in*3)
- can_move = 1
+ can_phase = TRUE
else
. = ..()
return
diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm
index c031e0941a..56a2169b06 100644
--- a/code/game/mecha/equipment/mecha_equipment.dm
+++ b/code/game/mecha/equipment/mecha_equipment.dm
@@ -38,8 +38,8 @@
return 0
/obj/item/mecha_parts/mecha_equipment/examine(mob/user)
- ..()
- to_chat(user, "\The [src] will fill [equip_type?"a [equip_type]":"any"] slot.")
+ . = ..()
+ . += "[src] will fill [equip_type?"a [equip_type]":"any"] slot."
/obj/item/mecha_parts/mecha_equipment/New()
..()
diff --git a/code/game/mecha/equipment/tools/energy_relay.dm b/code/game/mecha/equipment/tools/energy_relay.dm
index d6917a0de1..0e02f927e4 100644
--- a/code/game/mecha/equipment/tools/energy_relay.dm
+++ b/code/game/mecha/equipment/tools/energy_relay.dm
@@ -111,5 +111,5 @@
if(pow_chan)
var/delta = min(12, ER.chassis.cell.maxcharge-cur_charge)
ER.chassis.give_power(delta)
- A.use_power(delta*ER.coeff, pow_chan)
+ A.use_power_oneoff(delta*ER.coeff, pow_chan)
return
\ No newline at end of file
diff --git a/code/game/mecha/equipment/tools/extinguisher.dm b/code/game/mecha/equipment/tools/extinguisher.dm
index d383573017..4ed6735b62 100644
--- a/code/game/mecha/equipment/tools/extinguisher.dm
+++ b/code/game/mecha/equipment/tools/extinguisher.dm
@@ -14,14 +14,14 @@
. = ..()
reagents = new/datum/reagents(max_water)
reagents.my_atom = src
- reagents.add_reagent("water", max_water)
+ reagents.add_reagent("firefoam", max_water) //VOREStation Edit
/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch.
if(!action_checks(target) || get_dist(chassis, target)>3) return
if(get_dist(chassis, target)>2) return
set_ready_state(0)
if(do_after_cooldown(target))
- if( istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1)
+ if( istype(target, /obj/structure/reagent_dispensers) && get_dist(chassis,target) <= 1) //VOREStation Edit
var/obj/o = target
var/amount = o.reagents.trans_to_obj(src, 200)
occupant_message("[amount] units transferred into internal tank.")
diff --git a/code/game/mecha/equipment/tools/shield_omni.dm b/code/game/mecha/equipment/tools/shield_omni.dm
index 8088cf296a..1d230c4deb 100644
--- a/code/game/mecha/equipment/tools/shield_omni.dm
+++ b/code/game/mecha/equipment/tools/shield_omni.dm
@@ -75,6 +75,14 @@
. = ..()
my_mech = loc
GLOB.moved_event.register(my_mech, src, /obj/item/shield_projector/proc/update_shield_positions)
+ update_shift(my_mech)
+
+/obj/item/shield_projector/rectangle/mecha/proc/update_shift(atom/movable/mech)
+ var/icon/my_icon = icon(mech.icon) //holy heck
+ var/x_dif = (my_icon.Width() - world.icon_size) / 2
+ shift_x = round(x_dif, 1)
+ var/y_dif = (my_icon.Height() - world.icon_size) / 2
+ shift_y = round(y_dif, 1)
/obj/item/shield_projector/rectangle/mecha/Destroy()
GLOB.moved_event.unregister(my_mech, src, /obj/item/shield_projector/proc/update_shield_positions)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index d9198cc6e7..ba863c8c31 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -95,6 +95,11 @@
var/list/cargo = list()
var/cargo_capacity = 3
+ var/static/image/radial_image_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject"),
+ var/static/image/radial_image_airtoggle = image(icon= 'icons/mob/radial.dmi', icon_state = "radial_airtank"),
+ var/static/image/radial_image_lighttoggle = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_light"),
+ var/static/image/radial_image_statpanel = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine2")
+
/obj/mecha/drain_power(var/drain_check)
@@ -267,33 +272,75 @@
return 0
/obj/mecha/examine(mob/user)
- ..(user)
+ . = ..()
var/integrity = health/initial(health)*100
switch(integrity)
if(85 to 100)
- to_chat(user, "It's fully intact.")
+ . += "It's fully intact."
if(65 to 85)
- to_chat(user, "It's slightly damaged.")
+ . += "It's slightly damaged."
if(45 to 65)
- to_chat(user, "It's badly damaged.")
+ . += "It's badly damaged."
if(25 to 45)
- to_chat(user, "It's heavily damaged.")
+ . += "It's heavily damaged."
else
- to_chat(user, "It's falling apart.")
- if(equipment && equipment.len)
- to_chat(user, "It's equipped with:")
+ . += "It's falling apart."
+ if(equipment?.len)
+ . += "It's equipped with:"
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
- to_chat(user, "[bicon(ME)] [ME]")
- return
-
+ . += "[bicon(ME)] [ME]"
/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits.
return
-/obj/mecha/hear_talk(mob/M as mob, text)
- if(M==occupant && radio.broadcasting)
- radio.talk_into(M, text)
- return
+/obj/mecha/hear_talk(mob/M, list/message_pieces, verb)
+ if(M == occupant && radio.broadcasting)
+ radio.talk_into(M, message_pieces)
+
+/obj/mecha/proc/check_occupant_radial(var/mob/user)
+ if(!user)
+ return FALSE
+ if(user.stat)
+ return FALSE
+ if(user != occupant)
+ return FALSE
+ if(user.incapacitated())
+ return FALSE
+
+ return TRUE
+
+/obj/mecha/proc/show_radial_occupant(var/mob/user)
+ var/list/choices = list(
+ "Eject" = radial_image_eject,
+ "Toggle Airtank" = radial_image_airtoggle,
+ "Toggle Light" = radial_image_lighttoggle,
+ "View Stats" = radial_image_statpanel
+ )
+ var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, .proc/check_occupant_radial, user), require_near = TRUE, tooltips = TRUE)
+ if(!check_occupant_radial(user))
+ return
+ if(!choice)
+ return
+ switch(choice)
+ if("Eject")
+ go_out()
+ add_fingerprint(usr)
+ if("Toggle Airtank")
+ use_internal_tank = !use_internal_tank
+ occupant_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].")
+ log_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].")
+ if("Toggle Light")
+ lights = !lights
+ if(lights)
+ set_light(light_range + lights_power)
+ else
+ set_light(light_range - lights_power)
+ occupant_message("Toggled lights [lights?"on":"off"].")
+ log_message("Toggled lights [lights?"on":"off"].")
+ playsound(src, 'sound/mecha/heavylightswitch.ogg', 50, 1)
+ if("View Stats")
+ occupant << browse(src.get_stats_html(), "window=exosuit")
+
////////////////////////////
///// Action processing ////
@@ -324,6 +371,9 @@
/obj/mecha/proc/click_action(atom/target,mob/user, params)
if(!src.occupant || src.occupant != user ) return
if(user.stat) return
+ if(target == src && user == occupant)
+ show_radial_occupant(user)
+ return
if(state)
occupant_message("Maintenance protocols in effect")
return
@@ -383,11 +433,9 @@
//////// Movement procs ////////
//////////////////////////////////
-/obj/mecha/Move()
+/obj/mecha/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
- if(.)
- MoveAction()
- return
+ MoveAction()
/obj/mecha/proc/MoveAction() //Allows mech equipment to do an action once the mech moves
if(!equipment.len)
@@ -608,6 +656,10 @@
return
/obj/mecha/attack_hand(mob/user as mob)
+ if(user == occupant)
+ show_radial_occupant(user)
+ return
+
user.setClickCooldown(user.get_attack_speed())
src.log_message("Attack by hand/paw. Attacker - [user].",1)
diff --git a/code/game/objects/banners.dm b/code/game/objects/banners.dm
index d38afacaf4..d3614f03c2 100644
--- a/code/game/objects/banners.dm
+++ b/code/game/objects/banners.dm
@@ -31,8 +31,10 @@
desc = "A banner with the symbol of the Solar Confederate Government."
catalogue_data = list(/datum/category_item/catalogue/information/organization/solgov)
+/* //VOREStation Removal
/obj/item/weapon/banner/virgov
name = "\improper VirGov banner"
icon_state = "banner-virgov"
desc = "A banner with the symbol of the local government, the Vir Governmental Authority, also known as VirGov."
- //catalogue_data = list(/datum/category_item/catalogue/information/organization/virgov) YW Edit
\ No newline at end of file
+ catalogue_data = list(/datum/category_item/catalogue/information/organization/virgov)
+*/
diff --git a/code/game/objects/banners_vr.dm b/code/game/objects/banners_vr.dm
new file mode 100644
index 0000000000..75b014b1cc
--- /dev/null
+++ b/code/game/objects/banners_vr.dm
@@ -0,0 +1,2 @@
+/obj/item/weapon/banner/solgov
+ name = "\improper SolCom banner"
\ No newline at end of file
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index cc1e327478..c1e6b9adda 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -176,19 +176,16 @@
add_fingerprint(user)
return M
-/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
- if(has_buckled_mobs())
- for(var/A in buckled_mobs)
- var/mob/living/L = A
-// if(!L.Move(newloc, direct))
- if(!L.forceMove(newloc, direct))
- loc = L.loc
- last_move = L.last_move
- L.inertia_dir = last_move
- return FALSE
- else
- L.set_dir(dir)
- return TRUE
+/atom/movable/proc/handle_buckled_mob_movement(atom/old_loc, direct, movetime)
+ for(var/A in buckled_mobs)
+ var/mob/living/L = A
+ if(!L.Move(loc, direct, movetime))
+ L.forceMove(loc, direct, movetime)
+ L.last_move = last_move
+ L.inertia_dir = last_move
+
+ if(!buckle_dir)
+ L.set_dir(dir)
/atom/movable/proc/can_buckle_check(mob/living/M, forced = FALSE)
if(!buckled_mobs)
diff --git a/code/game/objects/effects/alien/aliens.dm b/code/game/objects/effects/alien/aliens.dm
index d8b0821a4d..203b768d75 100644
--- a/code/game/objects/effects/alien/aliens.dm
+++ b/code/game/objects/effects/alien/aliens.dm
@@ -160,18 +160,32 @@
#define WEED_NODE_BASE "nodebase"
/obj/effect/alien/weeds
- name = "weeds"
- desc = "Weird purple weeds."
+ name = "growth"
+ desc = "Weird organic growth."
icon_state = "weeds"
-
anchored = 1
density = 0
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
+
var/health = 15
var/obj/effect/alien/weeds/node/linked_node = null
var/static/list/weedImageCache
+/obj/effect/alien/weeds/Initialize(var/mapload, var/node, var/newcolor)
+ . = ..()
+ if(isspace(loc))
+ return INITIALIZE_HINT_QDEL
+
+ linked_node = node
+ if(newcolor)
+ color = newcolor
+
+ if(icon_state == "weeds")
+ icon_state = pick("weeds", "weeds1", "weeds2")
+
+ fullUpdateWeedOverlays()
+
/obj/effect/alien/weeds/Destroy()
var/turf/T = get_turf(src)
// To not mess up the overlay updates.
@@ -181,50 +195,43 @@
W.updateWeedOverlays()
linked_node = null
- ..()
+ return ..()
/obj/effect/alien/weeds/node
icon_state = "weednode"
- name = "purple sac"
- desc = "Weird purple octopus-like thing."
+ name = "glowing growth"
+ desc = "Weird glowing organic growth."
layer = ABOVE_TURF_LAYER+0.01
light_range = NODERANGE
+
var/node_range = NODERANGE
+ var/set_color = "#321D37"
- var/set_color = null
+/obj/effect/alien/weeds/node/Initialize(var/mapload, var/node, var/newcolor)
+ . = ..()
-/obj/effect/alien/weeds/node/New()
- ..(src.loc, src)
+ for(var/obj/effect/alien/weeds/existing in loc)
+ if(existing == src)
+ continue
+ else
+ qdel(existing)
-/obj/effect/alien/weeds/node/Initialize()
- ..()
- START_PROCESSING(SSobj, src)
+ if(newcolor)
+ set_color = newcolor
+ if(set_color)
+ color = set_color
- spawn(1 SECOND)
- if(color)
- set_color = color
+ START_PROCESSING(SSobj, src) // Only the node processes in a subsystem, the rest are process()'d by the node
/obj/effect/alien/weeds/node/Destroy()
STOP_PROCESSING(SSobj, src)
- ..()
-
-/obj/effect/alien/weeds/New(pos, node)
- ..()
- if(istype(loc, /turf/space))
- qdel(src)
- return
- linked_node = node
- if(icon_state == "weeds")icon_state = pick("weeds", "weeds1", "weeds2")
-
- fullUpdateWeedOverlays()
+ return ..()
/obj/effect/alien/weeds/proc/updateWeedOverlays()
+ cut_overlays()
- overlays.Cut()
-
- if(!weedImageCache || !weedImageCache.len)
+ if(!weedImageCache)
weedImageCache = list()
-// weedImageCache.len = 4
weedImageCache[WEED_NORTH_EDGING] = image('icons/mob/alien.dmi', "weeds_side_n", layer=2.11, pixel_y = -32)
weedImageCache[WEED_SOUTH_EDGING] = image('icons/mob/alien.dmi', "weeds_side_s", layer=2.11, pixel_y = 32)
weedImageCache[WEED_EAST_EDGING] = image('icons/mob/alien.dmi', "weeds_side_e", layer=2.11, pixel_x = -32)
@@ -234,18 +241,14 @@
var/turf/S = get_step(src, SOUTH)
var/turf/E = get_step(src, EAST)
var/turf/W = get_step(src, WEST)
- if(!locate(/obj/effect/alien) in N.contents)
- if(istype(N, /turf/simulated/floor))
- overlays += weedImageCache[WEED_SOUTH_EDGING]
- if(!locate(/obj/effect/alien) in S.contents)
- if(istype(S, /turf/simulated/floor))
- overlays += weedImageCache[WEED_NORTH_EDGING]
- if(!locate(/obj/effect/alien) in E.contents)
- if(istype(E, /turf/simulated/floor))
- overlays += weedImageCache[WEED_WEST_EDGING]
- if(!locate(/obj/effect/alien) in W.contents)
- if(istype(W, /turf/simulated/floor))
- overlays += weedImageCache[WEED_EAST_EDGING]
+ if(istype(N, /turf/simulated/floor) && !locate(/obj/effect/alien) in N.contents)
+ add_overlay(weedImageCache[WEED_SOUTH_EDGING])
+ if(istype(S, /turf/simulated/floor) && !locate(/obj/effect/alien) in S.contents)
+ add_overlay(weedImageCache[WEED_NORTH_EDGING])
+ if(istype(E, /turf/simulated/floor) && !locate(/obj/effect/alien) in E.contents)
+ add_overlay(weedImageCache[WEED_WEST_EDGING])
+ if(istype(W, /turf/simulated/floor) && !locate(/obj/effect/alien) in W.contents)
+ add_overlay(weedImageCache[WEED_EAST_EDGING])
/obj/effect/alien/weeds/proc/fullUpdateWeedOverlays()
for (var/obj/effect/alien/weeds/W in range(1,src))
@@ -253,70 +256,51 @@
return
+// NB: This is not actually called by a processing subsystem, it's called by the node processing
/obj/effect/alien/weeds/process()
set background = 1
var/turf/U = get_turf(src)
-/*
- if (locate(/obj/movable, U))
- U = locate(/obj/movable, U)
- if(U.density == 1)
- qdel(src)
- return
-Alien plants should do something if theres a lot of poison
- if(U.poison> 200000)
- health -= round(U.poison/200000)
- update()
- return
-*/
- if (istype(U, /turf/space))
+
+ if(isspace(U))
qdel(src)
return
- if(!linked_node || (get_dist(linked_node, src) > linked_node.node_range) )
+ if(!linked_node)
return
- if(linked_node != src)
- color = linked_node.set_color
+ if(get_dist(linked_node, src) > linked_node.node_range)
+ return
- direction_loop:
- for(var/dirn in cardinal)
- var/turf/T = get_step(src, dirn)
+ for(var/dirn in cardinal)
+ var/turf/T1 = get_turf(src)
+ var/turf/T2 = get_step(src, dirn)
- if (!istype(T) || T.density || locate(/obj/effect/alien/weeds) in T || istype(T.loc, /area/arrival) || istype(T, /turf/space))
- continue
+ if(!istype(T2) || locate(/obj/effect/alien/weeds) in T2 || istype(T2.loc, /area/arrival) || isspace(T2))
+ continue
- // if (locate(/obj/movable, T)) // don't propogate into movables
- // continue
+ if(T1.c_airblock(T2) == BLOCKED)
+ continue
- for(var/obj/O in T)
- if(!O.CanZASPass(U))
- continue direction_loop
+ new /obj/effect/alien/weeds(T2, linked_node, color)
- var/obj/effect/E = new /obj/effect/alien/weeds(T, linked_node)
+/obj/effect/alien/weeds/node/process()
+ set background = 1
+ . = ..()
- E.color = color
+ var/list/nearby_weeds = list()
+ for(var/obj/effect/alien/weeds/W in orange(node_range, src))
+ nearby_weeds |= W
- if(istype(src, /obj/effect/alien/weeds/node))
- var/obj/effect/alien/weeds/node/N = src
- var/list/nearby_weeds = list()
- for(var/obj/effect/alien/weeds/W in range(N.node_range,src))
- nearby_weeds |= W
+ for(var/nbw in nearby_weeds)
+ var/obj/effect/alien/weeds/W = nbw
- for(var/obj/effect/alien/weeds/W in nearby_weeds)
- if(!W)
- continue
+ if(!W.linked_node)
+ W.linked_node = src
- if(!W.linked_node)
- W.linked_node = src
-
- W.color = W.linked_node.set_color
-
- if(W == src)
- continue
-
- if(prob(max(10, 40 - (5 * nearby_weeds.len))))
- W.process()
+ W.color = W.linked_node.set_color
+ if(prob(max(10, 40 - (5 * nearby_weeds.len))))
+ W.process()
/obj/effect/alien/weeds/ex_act(severity)
switch(severity)
diff --git a/code/game/objects/effects/chem/foam.dm b/code/game/objects/effects/chem/foam.dm
index 5a461e1525..993cbc6edc 100644
--- a/code/game/objects/effects/chem/foam.dm
+++ b/code/game/objects/effects/chem/foam.dm
@@ -14,23 +14,25 @@
var/amount = 3
var/expand = 1
var/metal = 0
+ var/dries = 1 //VOREStation Add
+ var/slips = 0 //VOREStation Add
/obj/effect/effect/foam/Initialize(var/mapload, var/ismetal = 0)
. = ..()
- icon_state = "[ismetal? "m" : ""]foam"
+ //icon_state = "[ismetal? "m" : ""]foam" //VOREStation Removal
metal = ismetal
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
-
- addtimer(CALLBACK(src, .proc/post_spread), 3 + metal * 3)
- addtimer(CALLBACK(src, .proc/pre_harden), 12 SECONDS)
- addtimer(CALLBACK(src, .proc/harden), 15 SECONDS)
+ if(dries) //VOREStation Add
+ addtimer(CALLBACK(src, .proc/post_spread), 3 + metal * 3)
+ addtimer(CALLBACK(src, .proc/pre_harden), 12 SECONDS)
+ addtimer(CALLBACK(src, .proc/harden), 15 SECONDS)
/obj/effect/effect/foam/proc/post_spread()
process()
checkReagents()
/obj/effect/effect/foam/proc/pre_harden()
- STOP_PROCESSING(SSobj, src)
+ return //VOREStation Edit
/obj/effect/effect/foam/proc/harden()
if(metal)
@@ -83,7 +85,7 @@
return
if(metal)
return
- if(istype(AM, /mob/living))
+ if(slips && istype(AM, /mob/living)) //VOREStation Add
var/mob/living/M = AM
M.slip("the foam", 6)
diff --git a/code/game/objects/effects/chem/foam_vr.dm b/code/game/objects/effects/chem/foam_vr.dm
new file mode 100644
index 0000000000..b7a22e629e
--- /dev/null
+++ b/code/game/objects/effects/chem/foam_vr.dm
@@ -0,0 +1,20 @@
+/obj/effect/effect/foam/firefighting
+ name = "firefighting foam"
+ icon_state = "mfoam" //Whiter
+ color = "#A6FAFF"
+ var/lifetime = 3
+ dries = FALSE // We do this ourselves
+ slips = FALSE
+
+/obj/effect/effect/foam/firefighting/Initialize()
+ . = ..()
+ START_PROCESSING(SSobj, src)
+
+/obj/effect/effect/foam/firefighting/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/effect/effect/foam/firefighting/process()
+ if(lifetime-- <= 0)
+ flick("[icon_state]-disolve", src)
+ QDEL_IN(src, 5)
\ No newline at end of file
diff --git a/code/game/objects/effects/chem/water.dm b/code/game/objects/effects/chem/water.dm
index 7de9b9f8ff..72934e2da1 100644
--- a/code/game/objects/effects/chem/water.dm
+++ b/code/game/objects/effects/chem/water.dm
@@ -21,7 +21,7 @@
step_towards(src, target)
var/turf/T = get_turf(src)
if(T && reagents)
- reagents.touch_turf(T)
+ reagents.touch_turf(T, reagents.total_volume) //VOREStation Add
var/mob/M
for(var/atom/A in T)
if(!ismob(A) && A.simulated) // Mobs are handled differently
diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm
index fba219e924..ce0f117e5a 100644
--- a/code/game/objects/effects/decals/Cleanable/humans.dm
+++ b/code/game/objects/effects/decals/Cleanable/humans.dm
@@ -159,8 +159,8 @@ var/global/list/image/splatter_cache=list()
icon_state = "writing1"
/obj/effect/decal/cleanable/blood/writing/examine(mob/user)
- ..(user)
- to_chat(user, "It reads: \"[message]\"")
+ . = ..()
+ . += "It reads: \"[message]\""
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
diff --git a/code/game/objects/effects/decals/posters/polarisposters_vr.dm b/code/game/objects/effects/decals/posters/polarisposters_vr.dm
new file mode 100644
index 0000000000..5045346289
--- /dev/null
+++ b/code/game/objects/effects/decals/posters/polarisposters_vr.dm
@@ -0,0 +1,5 @@
+/datum/poster/nanotrasen/nt_7
+ name = "SolCom"
+ desc = "This poster showcases an TCG emblem. The outer ring reads,\
+ \"NIL MORTALIBUS ARDUI EST\".\
+ Commonwealth of Sol-Procyon."
diff --git a/code/game/objects/effects/decals/posters/voreposters_vr.dm b/code/game/objects/effects/decals/posters/voreposters_vr.dm
index bd951f88b3..6f4935718d 100644
--- a/code/game/objects/effects/decals/posters/voreposters_vr.dm
+++ b/code/game/objects/effects/decals/posters/voreposters_vr.dm
@@ -42,3 +42,11 @@
icon_state = "sbsposter11"
name = "Fear"
desc = "Depicted on this poster is a monster crackling with crimson energy that seems to drip off its body. The word 'RUN' is printed across the bottom."
+/datum/poster/vore_12
+ icon_state = "sbsposter12"
+ name = "Baa"
+ desc = "A lewd exclusive poster of a certain security commander, taken from a old 'New Ewe' magazine!"
+/datum/poster/vore_13
+ icon_state = "sbsposter13"
+ name = "Ammer"
+ desc = "You see a blue panda on the poster. She's awfully smug about her size."
\ No newline at end of file
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index 00896e7107..b872f9b3d3 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -113,12 +113,11 @@ steam.start() -- spawns the effect
T.hotspot_expose(1000,100)
return ..()
-/obj/effect/effect/sparks/Move()
- ..()
- var/turf/T = src.loc
- if (istype(T, /turf))
+/obj/effect/effect/sparks/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
+ if(isturf(loc))
+ var/turf/T = loc
T.hotspot_expose(1000,100)
- return
/datum/effect/effect/system/spark_spread
var/total_sparks = 0 // To stop it being spammed and lagging!
@@ -225,8 +224,8 @@ steam.start() -- spawns the effect
time_to_live = 600
//var/list/projectiles
-/obj/effect/effect/smoke/bad/Move()
- ..()
+/obj/effect/effect/smoke/bad/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
for(var/mob/living/L in get_turf(src))
affect(L)
@@ -281,8 +280,8 @@ steam.start() -- spawns the effect
STOP_PROCESSING(SSobj, src)
return ..()
-/obj/effect/effect/smoke/elemental/Move()
- ..()
+/obj/effect/effect/smoke/elemental/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
for(var/mob/living/L in range(1, src))
affect(L)
diff --git a/code/game/objects/effects/explosion_particles.dm b/code/game/objects/effects/explosion_particles.dm
index 63b2a09c24..12a1e92020 100644
--- a/code/game/objects/effects/explosion_particles.dm
+++ b/code/game/objects/effects/explosion_particles.dm
@@ -12,10 +12,6 @@
qdel(src)
return
-/obj/effect/expl_particles/Move()
- ..()
- return
-
/datum/effect/system/expl_particles
var/number = 10
var/turf/location
diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm
index d7ab1ebfa6..5958f79d00 100644
--- a/code/game/objects/effects/misc.dm
+++ b/code/game/objects/effects/misc.dm
@@ -40,9 +40,11 @@
/obj/effect/temporary_effect/shuttle_landing
name = "shuttle landing"
desc = "You better move if you don't want to go splat!"
+ //VOREStation Edit Start
icon = 'icons/goonstation/featherzone.dmi'
icon_state = "hazard-corners"
time_to_die = 5 SECONDS
+ //VOREStation Edit End
// The manifestation of Zeus's might. Or just a really unlucky day.
// This is purely a visual effect, this isn't the part of the code that hurts things.
diff --git a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm
index d4f65fc9d1..e48606a2ac 100644
--- a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm
+++ b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm
@@ -74,7 +74,7 @@
light_power = 0.5
light_color = "#8837A3"
-/obj/effect/projectile/tungsten/impact
+/obj/effect/projectile/impact/tungsten
icon_state = "impact_mhd_laser"
light_range = 4
light_power = 3
diff --git a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm
index d901aeaa61..a5c70aab2c 100644
--- a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm
+++ b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm
@@ -86,7 +86,7 @@
light_power = 0.5
light_color = "#FF0D00"
-/obj/effect/projectile/tungsten/muzzle
+/obj/effect/projectile/muzzle/tungsten
icon_state = "muzzle_mhd_laser"
light_range = 4
light_power = 3
diff --git a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm
index 59d56b6c7c..4326bc536d 100644
--- a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm
+++ b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm
@@ -109,12 +109,18 @@
light_power = 0.5
light_color = "#0066FF"
-/obj/effect/projectile/tungsten/tracer
+/obj/effect/projectile/tracer/tungsten
icon_state = "mhd_laser"
light_range = 4
light_power = 3
light_color = "#3300ff"
+/obj/effect/projectile/tracer/cannon
+ icon_state = "cannon"
+ light_range = 1
+ light_power = 0.5
+ light_color = "#f6f2b6"
+
//VOREStation edit: medigun
/obj/effect/projectile/tracer/medigun
icon = 'icons/obj/projectiles_vr.dmi'
@@ -122,4 +128,4 @@
light_range = 2
light_power = 0.5
light_color = "#80F5FF"
-//VOREStation edit ends
\ No newline at end of file
+//VOREStation edit ends
diff --git a/code/game/objects/effects/zone_divider.dm b/code/game/objects/effects/zone_divider.dm
index 01e6834f16..acab441d52 100644
--- a/code/game/objects/effects/zone_divider.dm
+++ b/code/game/objects/effects/zone_divider.dm
@@ -7,6 +7,7 @@
anchored = 1
density = 0
opacity = 0
+ can_atmos_pass = ATMOS_PASS_PROC
/obj/effect/zone_divider/CanZASPass(turf/T, is_zone)
// Special case to prevent us from being part of a zone during the first air master tick.
@@ -15,5 +16,5 @@
if(air_master && air_master.current_cycle == 0)
spawn(1)
air_master.mark_for_update(get_turf(src))
- return ATMOS_PASS_NO
- return is_zone ? ATMOS_PASS_NO : ATMOS_PASS_YES // Anything except zones can pass
+ return FALSE
+ return is_zone ? FALSE : TRUE // Anything except zones can pass
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index f6fb3c94cf..be8deb5df6 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -197,7 +197,7 @@
src.loc = T
// See inventory_sizes.dm for the defines.
-/obj/item/examine(mob/user, var/distance = -1)
+/obj/item/examine(mob/user)
var/size
switch(src.w_class)
if(ITEMSIZE_TINY)
@@ -210,7 +210,7 @@
size = "bulky"
if(ITEMSIZE_HUGE)
size = "huge"
- return ..(user, distance, "", "It is a [size] item.")
+ return ..(user, "", "It is a [size] item.")
/obj/item/attack_hand(mob/living/user as mob)
if (!user) return
@@ -636,6 +636,11 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
//Looking through a scope or binoculars should /not/ improve your periphereal vision. Still, increase viewsize a tiny bit so that sniping isn't as restricted to NSEW
/obj/item/var/ignore_visor_zoom_restriction = FALSE
+/obj/item/on_loc_moved(var/oldloc)
+ . = ..()
+ if(zoom)
+ zoom() // aka unzoom
+
/obj/item/proc/zoom(var/tileoffset = 14,var/viewsize = 9) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view
var/devicename
diff --git a/code/game/objects/items/bells.dm b/code/game/objects/items/bells.dm
index c7aa08a440..af9d7ce0f8 100644
--- a/code/game/objects/items/bells.dm
+++ b/code/game/objects/items/bells.dm
@@ -13,9 +13,9 @@
var/static/radial_pickup = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pickup")
/obj/item/weapon/deskbell/examine(mob/user)
- ..()
+ . = ..()
if(broken)
- to_chat(user,"It looks damaged, the ringer is stuck firmly inside.")
+ . += "It looks damaged, the ringer is stuck firmly inside."
/obj/item/weapon/deskbell/attack(mob/target as mob, mob/living/user as mob)
if(!broken)
@@ -49,7 +49,7 @@
// Once the player has decided their option, choose the behaviour that will happen under said option.
switch(choice)
if("examine")
- examine(user)
+ user.examinate(src)
if("use")
if(check_ability(user))
diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm
index 1105cf8388..181eea4137 100644
--- a/code/game/objects/items/bodybag.dm
+++ b/code/game/objects/items/bodybag.dm
@@ -242,13 +242,13 @@
syringe.reagents.trans_to_mob(H, 30, CHEM_BLOOD)
/obj/structure/closet/body_bag/cryobag/examine(mob/user)
- ..()
+ . = ..()
if(Adjacent(user)) //The bag's rather thick and opaque from a distance.
- to_chat(user, "You peer into \the [src].")
+ . += "You peer into \the [src]."
if(syringe)
- to_chat(user, "It has a syringe added to it.")
+ . += "It has a syringe added to it."
for(var/mob/living/L in contents)
- L.examine(user)
+ . += L.examine(user)
/obj/structure/closet/body_bag/cryobag/attackby(obj/item/W, mob/user)
if(opened)
diff --git a/code/game/objects/items/contraband_vr.dm b/code/game/objects/items/contraband_vr.dm
index a7b0c48aa9..b7b70f74a6 100644
--- a/code/game/objects/items/contraband_vr.dm
+++ b/code/game/objects/items/contraband_vr.dm
@@ -101,11 +101,11 @@
icon_type = "cigar"
/obj/item/weapon/miscdisc
- name = "wah thing"
- desc = "wahwahwah wahwahwa"
+ name = "strange artefact"
+ desc = "A large disc-shaped item, with a red, opaque crystal embedded in the center. It is some what heavy. There are indentations along the ring of the disc. Alien scripture lines the disc."
icon_state = "wahdisc"
icon = 'icons/obj/contraband_vr.dmi'
w_class = ITEMSIZE_NORMAL
/obj/item/weapon/miscdisc/attack_self(mob/living/user as mob)
- to_chat(user, "LORE.")
\ No newline at end of file
+ to_chat(user, "As you hold the large disc in your open palm, fingers cusped around the edge, the crystal embedded in the item begins to vibrate. It lifts itself from the disc a few cenimetres, before beginning to glow with a bright red light. The glow lasts for a few seconds, before the crystal embeds itself back into the disc with a quick snap.")
\ No newline at end of file
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 45ad1fa5b8..198288311c 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -109,7 +109,7 @@
qdel(src)
return
-/obj/item/weapon/pen/crayon/attack(mob/M as mob, mob/user as mob)
+/obj/item/weapon/pen/crayon/attack(mob/living/M as mob, mob/living/user as mob)
if(M == user)
to_chat(user, "You take a bite of the crayon and swallow it.")
user.nutrition += 1
@@ -195,7 +195,7 @@
shadeColour = input(user, "Please select the shade colour.", "Marker colour") as color
return
-/obj/item/weapon/pen/crayon/marker/attack(mob/M as mob, mob/user as mob)
+/obj/item/weapon/pen/crayon/marker/attack(mob/living/M as mob, mob/living/user as mob)
if(M == user)
to_chat(user, "You take a bite of the marker and swallow it.")
user.nutrition += 1
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 9488be9e82..c3f70abc12 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -68,8 +68,9 @@ var/global/list/obj/item/device/pda/PDAs = list()
var/spam_proof = FALSE // If true, it can't be spammed by random events.
/obj/item/device/pda/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "The time [stationtime2text()] is displayed in the corner of the screen.")
+ . = ..()
+ if(Adjacent(user))
+ . += "The time [stationtime2text()] is displayed in the corner of the screen."
/obj/item/device/pda/CtrlClick()
if(issilicon(usr))
diff --git a/code/game/objects/items/devices/PDA/PDA_vr.dm b/code/game/objects/items/devices/PDA/PDA_vr.dm
index 6a6da399eb..32551625c9 100644
--- a/code/game/objects/items/devices/PDA/PDA_vr.dm
+++ b/code/game/objects/items/devices/PDA/PDA_vr.dm
@@ -1,6 +1,12 @@
/obj/item/device/pda
var/delete_id = FALSE //Guaranteed deletion of ID upon deletion of PDA
+/obj/item/device/pda/multicaster/exploration/New()
+ ..()
+ owner = "Exploration Department"
+ name = "Exploration Department (Relay)"
+ cartridges_to_send_to = exploration_cartridges
+
/obj/item/device/pda/centcom
default_cartridge = /obj/item/weapon/cartridge/captain
icon_state = "pda-h"
@@ -8,13 +14,13 @@
// hidden = 1
/obj/item/device/pda/pathfinder
- default_cartridge = /obj/item/weapon/cartridge/signal/science
+ default_cartridge = /obj/item/weapon/cartridge/explorer
icon_state = "pda-lawyer-old"
/obj/item/device/pda/explorer
- default_cartridge = /obj/item/weapon/cartridge/signal/science
+ default_cartridge = /obj/item/weapon/cartridge/explorer
icon_state = "pda-det"
/obj/item/device/pda/sar
- default_cartridge = /obj/item/weapon/cartridge/medical
+ default_cartridge = /obj/item/weapon/cartridge/sar
icon_state = "pda-h"
diff --git a/code/game/objects/items/devices/PDA/cart_vr.dm b/code/game/objects/items/devices/PDA/cart_vr.dm
new file mode 100644
index 0000000000..fc4e3d098a
--- /dev/null
+++ b/code/game/objects/items/devices/PDA/cart_vr.dm
@@ -0,0 +1,17 @@
+var/list/exploration_cartridges = list(
+ /obj/item/weapon/cartridge/explorer,
+ /obj/item/weapon/cartridge/sar
+ )
+
+/obj/item/weapon/cartridge/explorer
+ name = "\improper Explorator cartridge"
+ icon_state = "cart-e"
+ access_reagent_scanner = 1
+ access_atmos = 1
+
+/obj/item/weapon/cartridge/sar
+ name = "\improper Med-Exp cartridge"
+ icon_state = "cart-m"
+ access_medical = 1
+ access_reagent_scanner = 1
+ access_atmos = 1
diff --git a/code/game/objects/items/devices/advnifrepair.dm b/code/game/objects/items/devices/advnifrepair.dm
index ab71b97324..b3b54e56c7 100644
--- a/code/game/objects/items/devices/advnifrepair.dm
+++ b/code/game/objects/items/devices/advnifrepair.dm
@@ -56,8 +56,9 @@
return 1
/obj/item/device/nifrepairer/examine(mob/user)
- if(..(user, 1))
+ . = ..()
+ if(Adjacent(user))
if(supply.total_volume)
- to_chat(user, "\The [src] contains [supply.total_volume] units of programmed nanites, ready for dispensing.")
+ . += "\The [src] contains [supply.total_volume] units of programmed nanites, ready for dispensing."
else
- to_chat(user, "\The [src] is empty and ready to accept nanopaste.")
+ . += "\The [src] is empty and ready to accept nanopaste."
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index 05260e3d2f..f20e340f34 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -115,6 +115,9 @@
show_message(span("critical", "\The [user] is transferring you into \the [src]!"))
if(do_after(user, 100))
+ if(carded_ai)
+ to_chat(user, "Transfer failed: Existing AI found on remote device. Remove existing AI to install a new one.")
+ return 0
if(istype(ai.loc, /turf/))
new /obj/structure/AIcore/deactivated(get_turf(ai))
diff --git a/code/game/objects/items/devices/binoculars.dm b/code/game/objects/items/devices/binoculars.dm
index a971115ada..ca28fe8df3 100644
--- a/code/game/objects/items/devices/binoculars.dm
+++ b/code/game/objects/items/devices/binoculars.dm
@@ -1,6 +1,7 @@
/obj/item/device/binoculars
name = "binoculars"
desc = "A pair of binoculars."
+ icon = 'icons/obj/device_vr.dmi' //VOREStation Edit
icon_state = "binoculars"
force = 5.0
w_class = ITEMSIZE_SMALL
diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm
index fae2d4586f..392af1b870 100644
--- a/code/game/objects/items/devices/communicator/communicator.dm
+++ b/code/game/objects/items/devices/communicator/communicator.dm
@@ -108,9 +108,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
// Parameters: user - the user doing the examining
// Description: Allows the user to click a link when examining to look at video if one is going.
/obj/item/device/communicator/examine(mob/user)
- . = ..(user, 1)
- if(. && video_source)
- to_chat(user, "It looks like it's on a video call: \[view\]")
+ . = ..()
+ if(Adjacent(user) && video_source)
+ . += "It looks like it's on a video call: \[view\]"
// Proc: initialize_exonet()
// Parameters: 1 (user - the person the communicator belongs to)
@@ -131,28 +131,22 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
// Parameters: 1 (user - the person examining the device)
// Description: Shows all the voice mobs inside the device, and their status.
/obj/item/device/communicator/examine(mob/user)
- if(!..(user))
- return
-
- var/msg = ""
+ . = ..()
+
for(var/mob/living/voice/voice in contents)
- msg += "On the screen, you can see a image feed of [voice].\n"
- msg += ""
-
+ . += "On the screen, you can see a image feed of [voice]."
+
if(voice && voice.key)
switch(voice.stat)
if(CONSCIOUS)
if(!voice.client)
- msg += "[voice] appears to be asleep.\n" //afk
+ . += "[voice] appears to be asleep." //afk
if(UNCONSCIOUS)
- msg += "[voice] doesn't appear to be conscious.\n"
+ . += "[voice] doesn't appear to be conscious."
if(DEAD)
- msg += "[voice] appears to have died...\n" //Hopefully this never has to be used.
+ . += "[voice] appears to have died..." //Hopefully this never has to be used.
else
- msg += "The device doesn't appear to be transmitting any data.\n"
- msg += ""
- to_chat(user, msg)
- return
+ . += "The device doesn't appear to be transmitting any data."
// Proc: emp_act()
// Parameters: None
diff --git a/code/game/objects/items/devices/communicator/phone.dm b/code/game/objects/items/devices/communicator/phone.dm
index 3042b06fa9..d7816fbb82 100644
--- a/code/game/objects/items/devices/communicator/phone.dm
+++ b/code/game/objects/items/devices/communicator/phone.dm
@@ -227,12 +227,12 @@
..()
// Proc: hear_talk()
-// Parameters: 4 (M - the mob the speech originated from, text - what is being said, verb - the word used to describe how text is being said, speaking - language
-// being used)
+// Parameters: 3 (M - the mob the speech originated from,
+// list/message_pieces - what is being said w/ baked languages,
+// verb - the word used to describe how text is being said)
// Description: Relays the speech to all linked communicators.
-/obj/item/device/communicator/hear_talk(mob/living/M, text, verb, datum/language/speaking)
+/obj/item/device/communicator/hear_talk(mob/M, list/message_pieces, verb)
for(var/obj/item/device/communicator/comm in communicating)
-
var/turf/T = get_turf(comm)
if(!T) return
//VOREStation Edit Start for commlinks
@@ -246,18 +246,10 @@
//VOREStation Edit End
for(var/mob/mob in mobs_to_relay)
- //Can whoever is hearing us understand?
- if(!mob.say_understands(M, speaking))
- if(speaking)
- text = speaking.scramble(text)
- else
- text = stars(text)
+ var/message = mob.combine_message(message_pieces, verb, M)
var/name_used = M.GetVoice()
var/rendered = null
- if(speaking) //Language being used
- rendered = "[bicon(src)] [name_used] [speaking.format_message(text, verb)]"
- else
- rendered = "[bicon(src)] [name_used] [verb], \"[text]\""
+ rendered = "[bicon(src)] [name_used] [message]"
mob.show_message(rendered, 2)
// Proc: show_message()
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index 6930e5f26d..8f300aaaf7 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -86,23 +86,20 @@
set_light(0)
/obj/item/device/flashlight/examine(mob/user)
- ..()
+ . = ..()
if(power_use && brightness_level)
- var/tempdesc
- tempdesc += "\The [src] is set to [brightness_level]. "
+ . += "\The [src] is set to [brightness_level]."
if(cell)
- tempdesc += "\The [src] has a \the [cell] attached. "
+ . += "\The [src] has a \the [cell] attached."
if(cell.charge <= cell.maxcharge*0.25)
- tempdesc += "It appears to have a low amount of power remaining."
+ . += "It appears to have a low amount of power remaining."
else if(cell.charge > cell.maxcharge*0.25 && cell.charge <= cell.maxcharge*0.5)
- tempdesc += "It appears to have an average amount of power remaining."
+ . += "It appears to have an average amount of power remaining."
else if(cell.charge > cell.maxcharge*0.5 && cell.charge <= cell.maxcharge*0.75)
- tempdesc += "It appears to have an above average amount of power remaining."
+ . += "It appears to have an above average amount of power remaining."
else if(cell.charge > cell.maxcharge*0.75 && cell.charge <= cell.maxcharge)
- tempdesc += "It appears to have a high amount of power remaining."
-
- to_chat(user, "[tempdesc]")
+ . += "It appears to have a high amount of power remaining."
/obj/item/device/flashlight/attack_self(mob/user)
if(power_use)
@@ -421,7 +418,7 @@
. = ..()
if(.)
- user.visible_message("[user] cracks and shakes the glowstick.", "You crack and shake the glowstick, turning it on!")
+ user.visible_message("[user] cracks and shakes \the [name].", "You crack and shake \the [src], turning it on!")
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/glowstick/red
diff --git a/code/game/objects/items/devices/floor_painter.dm b/code/game/objects/items/devices/floor_painter.dm
index 72e6d2ced7..d84f4bc3ca 100644
--- a/code/game/objects/items/devices/floor_painter.dm
+++ b/code/game/objects/items/devices/floor_painter.dm
@@ -110,8 +110,8 @@
choose_colour()
/obj/item/device/floor_painter/examine(mob/user)
- ..(user)
- to_chat(user, "It is configured to produce the '[decal]' decal with a direction of '[paint_dir]' using [paint_colour] paint.")
+ . = ..()
+ . += "It is configured to produce the '[decal]' decal with a direction of '[paint_dir]' using [paint_colour] paint."
/obj/item/device/floor_painter/verb/choose_colour()
set name = "Choose Colour"
diff --git a/code/game/objects/items/devices/geiger.dm b/code/game/objects/items/devices/geiger.dm
index c6f7c3f9f1..b9b177e683 100644
--- a/code/game/objects/items/devices/geiger.dm
+++ b/code/game/objects/items/devices/geiger.dm
@@ -33,9 +33,9 @@
update_sound()
/obj/item/device/geiger/examine(mob/user)
- ..(user)
+ . = ..()
get_radiation()
- to_chat(user, "[scanning ? "Ambient" : "Stored"] radiation level: [radiation_count ? radiation_count : "0"]Bq.")
+ . += "[scanning ? "Ambient" : "Stored"] radiation level: [radiation_count ? radiation_count : "0"]Bq."
/obj/item/device/geiger/rad_act(amount)
if(!amount || !scanning)
diff --git a/code/game/objects/items/devices/holowarrant.dm b/code/game/objects/items/devices/holowarrant.dm
index bcf456126e..854282f55a 100644
--- a/code/game/objects/items/devices/holowarrant.dm
+++ b/code/game/objects/items/devices/holowarrant.dm
@@ -13,11 +13,11 @@
/obj/item/device/holowarrant/examine(mob/user)
. = ..()
if(active)
- to_chat(user, "It's a holographic warrant for '[active.fields["namewarrant"]]'.")
+ . += "It's a holographic warrant for '[active.fields["namewarrant"]]'."
if(in_range(user, src) || istype(user, /mob/observer/dead))
- show_content(user)
+ show_content(user) //Opens a browse window, not chatbox related
else
- to_chat(user, "You have to go closer if you want to read it.")
+ . += "You have to go closer if you want to read it."
//hit yourself with it
/obj/item/device/holowarrant/attack_self(mob/living/user as mob)
diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm
index f85e424604..3ce7a0b236 100644
--- a/code/game/objects/items/devices/lightreplacer.dm
+++ b/code/game/objects/items/devices/lightreplacer.dm
@@ -64,8 +64,9 @@
..()
/obj/item/device/lightreplacer/examine(mob/user)
- if(..(user, 2))
- to_chat(user, "It has [uses] lights remaining.")
+ . = ..()
+ if(get_dist(user, src) <= 2)
+ . += "It has [uses] lights remaining."
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/material) && W.get_material_name() == "glass")
diff --git a/code/game/objects/items/devices/locker_painter.dm b/code/game/objects/items/devices/locker_painter.dm
index 816c9790ff..3d41d9fcab 100644
--- a/code/game/objects/items/devices/locker_painter.dm
+++ b/code/game/objects/items/devices/locker_painter.dm
@@ -125,8 +125,8 @@
choose_colour_secure()
/obj/item/device/closet_painter/examine(mob/user)
- ..(user)
- to_chat(user, "It is configured to produce the '[colour]' paint scheme or the '[colour_secure]' secure closet paint scheme.")
+ . = ..()
+ . += "It is configured to produce the '[colour]' paint scheme or the '[colour_secure]' secure closet paint scheme."
/obj/item/device/closet_painter/verb/choose_colour()
set name = "Choose Colour"
diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm
index 0a12b31df2..7e7bbdb629 100644
--- a/code/game/objects/items/devices/megaphone.dm
+++ b/code/game/objects/items/devices/megaphone.dm
@@ -10,53 +10,52 @@
var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TERRORIST!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "GLORY TO ALMACH!")
/obj/item/device/megaphone/proc/can_broadcast(var/mob/living/user)
- if (user.client)
+ if(user.client)
if(user.client.prefs.muted & MUTE_IC)
to_chat(user, "You cannot speak in IC (muted).")
- return 0
+ return FALSE
if(!(ishuman(user) || user.isSynthetic()))
to_chat(user, "You don't know how to use this!")
- return 0
+ return FALSE
if(user.silent)
- return 0
- if(spamcheck)
- to_chat(user, "\The [src] needs to recharge!")
- return 0
- return 1
+ return FALSE
+ if(spamcheck > world.time)
+ to_chat(user, "[src] needs to recharge!")
+ return FALSE
+ if(loc != user)
+ return FALSE
+ if(user.stat != CONSCIOUS)
+ return FALSE
+ return TRUE
/obj/item/device/megaphone/proc/do_broadcast(var/mob/living/user, var/message)
- if ((src.loc == user && usr.stat == 0))
- if(emagged)
- if(insults)
- user.audible_message("[user] broadcasts, \"[pick(insultmsg)]\"")
- insults--
- else
- to_chat(user, "*BZZZZzzzzzt*")
+ if(emagged)
+ if(insults)
+ user.audible_message("[user.GetVoice()][user.GetAltName()] broadcasts, \"[pick(insultmsg)]\"")
+ insults--
else
- user.audible_message("[user] broadcasts, \"[message]\"")
-
- spamcheck = 1
- spawn(20)
- spamcheck = 0
- return
-
-/obj/item/device/megaphone/attack_self(mob/living/user as mob)
- if(!can_broadcast(user))
- return
+ to_chat(user, "*BZZZZzzzzzt*")
+ else
+ user.audible_message("[user.GetVoice()][user.GetAltName()] broadcasts, \"[message]\"")
+/obj/item/device/megaphone/attack_self(var/mob/living/user)
var/message = sanitize(input(user, "Shout a message?", "Megaphone", null) as text)
if(!message)
return
message = capitalize(message)
+ if(!can_broadcast(user))
+ return
+
+ spamcheck = world.time + 20
do_broadcast(user, message)
/obj/item/device/megaphone/emag_act(var/remaining_charges, var/mob/user)
if(!emagged)
- to_chat(user, "You overload \the [src]'s voice synthesizer.")
- emagged = 1
+ to_chat(user, "You overload [src]'s voice synthesizer.")
+ emagged = TRUE
insults = rand(1, 3)//to prevent caps spam.
- return 1
+ return TRUE
/obj/item/device/megaphone/super
name = "gigaphone"
@@ -130,41 +129,35 @@
broadcast_color = new_color
/obj/item/device/megaphone/super/do_broadcast(var/mob/living/user, var/message)
- if ((src.loc == user && usr.stat == 0))
- if(emagged)
- if(insults)
- user.audible_message("[user] broadcasts, \"[pick(insultmsg)]\"")
- if(broadcast_size >= 11)
- var/turf/T = get_turf(user)
- playsound(T, 'sound/items/AirHorn.ogg', 100, 1)
- for(var/mob/living/carbon/M in oviewers(4, T))
- if(M.get_ear_protection() >= 2)
- continue
- M.sleeping = 0
- M.stuttering += 20
- M.ear_deaf += 30
- M.Weaken(3)
- if(prob(30))
- M.Stun(10)
- M.Paralyse(4)
- else
- M.make_jittery(50)
- insults--
- else
- user.audible_message("*BZZZZzzzzzt*")
- if(prob(40) && insults <= 0)
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(2, 1, get_turf(user))
- s.start()
- user.visible_message("\The [src] sparks violently!")
- spawn(30)
- explosion(get_turf(src), -1, -1, 1, 3, adminlog = 1)
- qdel(src)
- return
+ if(emagged)
+ if(insults)
+ user.audible_message("[user.GetVoice()][user.GetAltName()] broadcasts, \"[pick(insultmsg)]\"")
+ if(broadcast_size >= 11)
+ var/turf/T = get_turf(user)
+ playsound(T, 'sound/items/AirHorn.ogg', 100, 1)
+ for(var/mob/living/carbon/M in oviewers(4, T))
+ if(M.get_ear_protection() >= 2)
+ continue
+ M.sleeping = 0
+ M.stuttering += 20
+ M.ear_deaf += 30
+ M.Weaken(3)
+ if(prob(30))
+ M.Stun(10)
+ M.Paralyse(4)
+ else
+ M.make_jittery(50)
+ insults--
else
- user.audible_message("[user] broadcasts, \"[message]\"")
-
- spamcheck = 1
- spawn(20)
- spamcheck = 0
- return
+ user.audible_message("*BZZZZzzzzzt*")
+ if(prob(40) && insults <= 0)
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(2, 1, get_turf(user))
+ s.start()
+ user.visible_message("\The [src] sparks violently!")
+ spawn(30)
+ explosion(get_turf(src), -1, -1, 1, 3, adminlog = 1)
+ qdel(src)
+ return
+ else
+ user.audible_message("[user.GetVoice()][user.GetAltName()] broadcasts, \"[message]\"")
diff --git a/code/game/objects/items/devices/modkit.dm b/code/game/objects/items/devices/modkit.dm
index 1ceaa3e9d1..6847bb6fb0 100644
--- a/code/game/objects/items/devices/modkit.dm
+++ b/code/game/objects/items/devices/modkit.dm
@@ -63,8 +63,8 @@
qdel(src)
/obj/item/device/modkit/examine(mob/user)
- ..(user)
- to_chat(user, "It looks as though it modifies hardsuits to fit [target_species] users.")
+ . = ..()
+ . += "It looks as though it modifies hardsuits to fit [target_species] users."
/obj/item/device/modkit/tajaran
name = "tajaran hardsuit modification kit"
diff --git a/code/game/objects/items/devices/pipe_painter.dm b/code/game/objects/items/devices/pipe_painter.dm
index 8a32988fb6..59e386b608 100644
--- a/code/game/objects/items/devices/pipe_painter.dm
+++ b/code/game/objects/items/devices/pipe_painter.dm
@@ -27,5 +27,5 @@
mode = input("Which colour do you want to use?", "Pipe painter", mode) in modes
/obj/item/device/pipe_painter/examine(mob/user)
- ..(user)
- to_chat(user, "It is in [mode] mode.")
+ . = ..()
+ . += "It is in [mode] mode."
diff --git a/code/game/objects/items/devices/radio/encryptionkey_vr.dm b/code/game/objects/items/devices/radio/encryptionkey_vr.dm
index 5be1effb35..1f6110d16a 100644
--- a/code/game/objects/items/devices/radio/encryptionkey_vr.dm
+++ b/code/game/objects/items/devices/radio/encryptionkey_vr.dm
@@ -17,10 +17,38 @@
/obj/item/device/encryptionkey/heads/rd
name = "research director's encryption key"
icon_state = "rd_cypherkey"
- channels = list("Command" = 1, "Science" = 1, "Explorer" = 1)
+ channels = list("Command" = 1, "Science" = 1)
/obj/item/device/encryptionkey/ert
channels = list("Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1, "Service" = 1, "Explorer" = 1)
/obj/item/device/encryptionkey/omni //Literally only for the admin intercoms
channels = list("Mercenary" = 1, "Raider" = 1, "Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1, "Service" = 1, "Explorer" = 1)
+
+/obj/item/device/encryptionkey/pathfinder
+ name = "pathfinder's encryption key"
+ icon_state = "com_cypherkey"
+ channels = list("Command" = 1, "Explorer" = 1)
+
+/obj/item/device/encryptionkey/qm
+ name = "quartermaster's encryption key"
+ icon_state = "qm_cypherkey"
+ channels = list("Command" = 1, "Supply" = 1)
+
+/obj/item/device/encryptionkey/pilot
+ name = "pilot's encryption key"
+ icon_state = "cypherkey"
+ channels = list("Explorer" = 1)
+
+/obj/item/device/encryptionkey/explorer
+ name = "explorer's encryption key"
+ icon_state = "rob_cypherkey"
+ channels = list("Explorer" = 1)
+
+/obj/item/device/encryptionkey/sar
+ name = "fm's encryption key"
+ icon_state = "med_cypherkey"
+ channels = list("Medical" = 1, "Explorer" = 1)
+
+/obj/item/device/encryptionkey/talon
+ channels = list("Talon" = 1)
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 67ad07567f..47de7ff7dd 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -37,21 +37,23 @@
return list_secure_channels()
/obj/item/device/radio/headset/examine(mob/user)
- if(!(..(user, 1) && radio_desc))
- return
+ . = ..()
- to_chat(user, "The following channels are available:")
- to_chat(user, radio_desc)
+ if(radio_desc && Adjacent(user))
+ . += "The following channels are available:"
+ . += radio_desc
-/obj/item/device/radio/headset/handle_message_mode(mob/living/M as mob, message, channel)
- if (channel == "special")
- if (translate_binary)
+/obj/item/device/radio/headset/handle_message_mode(mob/living/M as mob, list/message_pieces, channel)
+ if(channel == "special")
+ if(translate_binary)
var/datum/language/binary = GLOB.all_languages["Robot Talk"]
- binary.broadcast(M, message)
- if (translate_hive)
+ binary.broadcast(M, M.strip_prefixes(multilingual_to_message(message_pieces)))
+ return RADIO_CONNECTION_NON_SUBSPACE
+ if(translate_hive)
var/datum/language/hivemind = GLOB.all_languages["Hivemind"]
- hivemind.broadcast(M, message)
- return null
+ hivemind.broadcast(M, M.strip_prefixes(multilingual_to_message(message_pieces)))
+ return RADIO_CONNECTION_NON_SUBSPACE
+ return RADIO_CONNECTION_FAIL
return ..()
diff --git a/code/game/objects/items/devices/radio/headset_vr.dm b/code/game/objects/items/devices/radio/headset_vr.dm
index 14398d9f59..9204c81dd1 100644
--- a/code/game/objects/items/devices/radio/headset_vr.dm
+++ b/code/game/objects/items/devices/radio/headset_vr.dm
@@ -48,4 +48,83 @@
M.mob_radio.forceMove(M.loc)
M.mob_radio = null
return
- ..()
\ No newline at end of file
+ ..()
+
+/obj/item/device/radio/headset/headset_cargo
+ desc = "A headset used by the QM's slaves."
+
+/obj/item/device/radio/headset/headset_cargo/alt
+ desc = "A bowman headset used by the QM's slaves."
+
+/obj/item/device/radio/headset/headset_qm
+ name = "qm radio headset"
+ desc = "A headset used by the QM."
+ icon_state = "cargo_headset"
+ ks2type = /obj/item/device/encryptionkey/qm
+
+/obj/item/device/radio/headset/headset_qm/alt
+ name = "qm bowman headset"
+ desc = "A bowman headset used by the QM."
+ icon_state = "cargo_headset_alt"
+
+/obj/item/device/radio/headset/pathfinder
+ name = "pathfinder's headset"
+ desc = "Headset used by pathfinders for exploring. Access to the explorer and command channels."
+ icon_state = "exp_headset"
+ adhoc_fallback = TRUE
+ ks2type = /obj/item/device/encryptionkey/pathfinder
+
+/obj/item/device/radio/headset/pathfinder/alt
+ name = "pathfinder's bowman headset"
+ desc = "Bowman headset used by pathfinders for exploring. Access to the explorer and command channels."
+ icon_state = "exp_headset_alt"
+
+/obj/item/device/radio/headset/pilot
+ name = "pilot's headset"
+ desc = "A headset used by pilots, has access to the explorer channel."
+ icon_state = "pilot_headset"
+ adhoc_fallback = TRUE
+ ks2type = /obj/item/device/encryptionkey/pilot
+
+/obj/item/device/radio/headset/pilot/alt
+ name = "pilot's bowman headset"
+ desc = "A bowman headset used by pilots, has access to the explorer channel."
+ icon_state = "pilot_headset_alt"
+
+/obj/item/device/radio/headset/explorer
+ name = "explorer's headset"
+ desc = "Headset used by explorers for exploring. Access to the explorer channel."
+ icon_state = "exp_headset"
+ adhoc_fallback = TRUE
+ ks2type = /obj/item/device/encryptionkey/explorer
+
+/obj/item/device/radio/headset/explorer/alt
+ name = "explorer's bowman headset"
+ desc = "Bowman headset used by explorers for exploring. Access to the explorer channel."
+ icon_state = "exp_headset_alt"
+
+/obj/item/device/radio/headset/sar
+ name = "fm radio headset"
+ desc = "A headset for field medics."
+ icon_state = "sar_headset"
+ adhoc_fallback = TRUE
+ ks2type = /obj/item/device/encryptionkey/sar
+
+/obj/item/device/radio/headset/sar/alt
+ name = "fm radio bowman headset"
+ desc = "A bowman headset for field medics."
+ icon_state = "sar_headset_alt"
+
+/obj/item/device/radio/headset/volunteer
+ name = "volunteer's headset"
+ desc = "A headset used by volunteers to expedition teams, has access to the exploration channel."
+ icon_state = "pilot_headset"
+ adhoc_fallback = TRUE
+ ks2type = /obj/item/device/encryptionkey/pilot
+
+/obj/item/device/radio/headset/talon
+ name = "talon headset"
+ desc = "A headset for communication between the crew of the ITV Talon."
+ adhoc_fallback = TRUE
+ icon_state = "pilot_headset"
+ ks2type = /obj/item/device/encryptionkey/talon
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 69b5192abb..4ef7cc576a 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -11,10 +11,10 @@ var/global/list/default_internal_channels = list(
num2text(MED_I_FREQ)=list(access_medical_equip),
num2text(SEC_FREQ) = list(access_security),
num2text(SEC_I_FREQ)=list(access_security),
- num2text(SCI_FREQ) = list(access_tox, access_robotics, access_xenobiology, access_explorer),
+ num2text(SCI_FREQ) = list(access_tox, access_robotics, access_xenobiology),
num2text(SUP_FREQ) = list(access_cargo, access_mining_station),
num2text(SRV_FREQ) = list(access_janitor, access_library, access_hydroponics, access_bar, access_kitchen),
- num2text(EXP_FREQ) = list(access_explorer, access_pilot, access_rd)
+ num2text(EXP_FREQ) = list(access_explorer, access_pilot)
)
var/global/list/default_medbay_channels = list(
@@ -287,7 +287,7 @@ var/global/list/default_medbay_channels = list(
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels) //BS12 EDIT
var/datum/radio_frequency/connection = null
if(channel && channels && channels.len > 0)
- if (channel == "department")
+ if(channel == "department")
channel = channels[1]
connection = secure_radio_connections[channel]
else
@@ -303,11 +303,11 @@ var/global/list/default_medbay_channels = list(
A.SetName(from)
Broadcast_Message(connection, A,
0, "*garbled automated announcement*", src,
- message, from, "Automated Announcement", from, "synthesized voice",
- 4, 0, zlevels, connection.frequency, "states")
+ message_to_multilingual(message), from, "Automated Announcement", from, "synthesized voice",
+ DATA_FAKE, 0, zlevels, connection.frequency, "states")
// Interprets the message mode when talking into a radio, possibly returning a connection datum
-/obj/item/device/radio/proc/handle_message_mode(mob/living/M as mob, message, message_mode)
+/obj/item/device/radio/proc/handle_message_mode(mob/living/M as mob, list/message_pieces, message_mode)
// If a channel isn't specified, send to common.
if(!message_mode || message_mode == "headset")
return radio_connection
@@ -321,16 +321,17 @@ var/global/list/default_medbay_channels = list(
return secure_radio_connections[message_mode]
// If we were to send to a channel we don't have, drop it.
- return null
+ return RADIO_CONNECTION_FAIL
-/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel, var/verb = "says", var/datum/language/speaking = null)
- if(!on) return FALSE // the device has to be on
+/obj/item/device/radio/talk_into(mob/living/M as mob, list/message_pieces, channel, var/verb = "says")
+ if(!on)
+ return FALSE // the device has to be on
// Fix for permacell radios, but kinda eh about actually fixing them.
- if(!M || !message) return FALSE
+ if(!M || !message_pieces)
+ return FALSE
- if(speaking && (speaking.flags & (SIGNLANG|NONVERBAL))) return FALSE
-
- if(istype(M)) M.trigger_aiming(TARGET_CAN_RADIO)
+ if(istype(M))
+ M.trigger_aiming(TARGET_CAN_RADIO)
// Uncommenting this. To the above comment:
// The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom
@@ -352,11 +353,18 @@ var/global/list/default_medbay_channels = list(
*/
//#### Grab the connection datum ####//
- var/datum/radio_frequency/connection = handle_message_mode(M, message, channel)
- if (!istype(connection))
+ var/message_mode = handle_message_mode(M, message_pieces, channel)
+ switch(message_mode)
+ if(RADIO_CONNECTION_FAIL)
+ return FALSE
+ if(RADIO_CONNECTION_NON_SUBSPACE)
+ return TRUE
+
+ if(!istype(message_mode, /datum/radio_frequency))
return FALSE
var/pos_z = get_z(src)
+ var/datum/radio_frequency/connection = message_mode
//#### Tagging the signal with all appropriate identity values ####//
@@ -417,7 +425,7 @@ var/global/list/default_medbay_channels = list(
"name" = displayname, // the mob's display name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
- "vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood
+ "vmessage" = message_to_multilingual(pick(M.speak_emote)), // the message to display if the voice wasn't understood
"vname" = M.voice_name, // the name to display if the voice wasn't understood
"vmask" = voicemask, // 1 if the mob is using a voice gas mask
@@ -426,7 +434,7 @@ var/global/list/default_medbay_channels = list(
// Other tags:
"compression" = rand(45,50), // compressed radio signal
- "message" = message, // the actual sent message
+ "message" = message_pieces, // the actual sent message
"connection" = connection, // the radio connection to use
"radio" = src, // stores the radio used for transmission
"slow" = 0, // how much to sleep() before broadcasting - simulates net lag
@@ -435,7 +443,6 @@ var/global/list/default_medbay_channels = list(
"server" = null, // the last server to log this signal
"reject" = 0, // if nonzero, the signal will not be accepted by any broadcasting machinery
"level" = pos_z, // The source's z level
- "language" = speaking,
"verb" = verb
)
signal.frequency = connection.frequency // Quick frequency set
@@ -472,7 +479,6 @@ var/global/list/default_medbay_channels = list(
signal.transmission_method = TRANSMISSION_SUBSPACE
//#### Sending the signal to all subspace receivers ####//
-
for(var/obj/machinery/telecomms/receiver/R in telecomms_list)
R.receive_signal(signal)
@@ -487,7 +493,7 @@ var/global/list/default_medbay_channels = list(
else if(adhoc_fallback) //Less huzzah, we have to fallback
to_chat(loc, "\The [src] pings as it falls back to local radio transmission.")
subspace_transmission = FALSE
-
+
else //Oh well
return FALSE
@@ -520,16 +526,14 @@ var/global/list/default_medbay_channels = list(
//Nothing handled any sort of remote radio-ing and returned before now, just squawk on this zlevel.
return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
- src, message, displayname, jobname, real_name, M.voice_name,
- filter_type, signal.data["compression"], using_map.get_map_levels(pos_z), connection.frequency, verb, speaking)
+ src, message_pieces, displayname, jobname, real_name, M.voice_name,
+ filter_type, signal.data["compression"], using_map.get_map_levels(pos_z), connection.frequency, verb)
-/obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)
- if (broadcasting)
+/obj/item/device/radio/hear_talk(mob/M as mob, list/message_pieces, var/verb = "says")
+ if(broadcasting)
if(get_dist(src, M) <= canhear_range)
- talk_into(M, msg,null,verb,speaking)
-
-
+ talk_into(M, message_pieces, null, verb)
/obj/item/device/radio/proc/receive_range(freq, level)
// check if this radio can receive on the given frequency, and if so,
@@ -577,12 +581,12 @@ var/global/list/default_medbay_channels = list(
/obj/item/device/radio/examine(mob/user)
. = ..()
- if ((in_range(src, user) || loc == user))
- if (b_stat)
- user.show_message("\The [src] can be attached and modified!")
+
+ if((in_range(src, user) || loc == user))
+ if(b_stat)
+ . += "\The [src] can be attached and modified!"
else
- user.show_message("\The [src] can not be modified or attached!")
- return
+ . += "\The [src] can not be modified or attached!"
/obj/item/device/radio/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
diff --git a/code/game/objects/items/devices/radio/radiopack.dm b/code/game/objects/items/devices/radio/radiopack.dm
index c2ba25ecc2..8f2e849320 100644
--- a/code/game/objects/items/devices/radio/radiopack.dm
+++ b/code/game/objects/items/devices/radio/radiopack.dm
@@ -132,22 +132,13 @@
return -1
if(!listening)
return -1
- if(is_jammed(src))
+ if(!on)
return -1
- if (!on)
+ if(!freq)
return -1
- if (!freq) //recieved on main frequency
- if (!listening)
- return -1
- else
- var/accept = (freq==frequency && listening)
- if (!accept)
- for (var/ch_name in channels)
- var/datum/radio_frequency/RF = secure_radio_connections[ch_name]
- if (RF && RF.frequency==freq && (channels[ch_name]&FREQ_LISTENING))
- accept = 1
- break
- if (!accept)
- return -1
- return canhear_range
+ //Only listen on main freq
+ if(freq == frequency)
+ return canhear_range
+ else
+ return -1
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index a085e59d24..06197f202d 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -492,7 +492,7 @@ HALOGEN COUNTER - Radcount on mobs
for(var/potential_color in S.slime_mutation)
var/mob/living/simple_mob/slime/xenobio/slime = potential_color
mutations.Add(initial(slime.slime_color))
- user.show_message("Potental to mutate into [english_list(mutations)] colors.
Extract potential: [S.cores]
Nutrition: [S.nutrition]/[S.get_max_nutrition()]")
+ user.show_message("Potental to mutate into [english_list(mutations)] colors.
Extract potential: [S.cores]
Nutrition: [S.nutrition]/[S.max_nutrition]")
if (S.nutrition < S.get_starve_nutrition())
user.show_message("Warning: Subject is starving!")
diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm
index 1f15d36b12..03d0bdd60c 100644
--- a/code/game/objects/items/devices/spy_bug.dm
+++ b/code/game/objects/items/devices/spy_bug.dm
@@ -84,9 +84,9 @@
camtype = /obj/machinery/camera/bug/spy
/obj/item/device/camerabug/examine(mob/user)
- . = ..(user, 0)
- if(.)
- to_chat(user, "It has a tiny camera inside. Needs to be both configured and brought in contact with monitor device to be fully functional.")
+ . = ..()
+ if(get_dist(user, src) == 0)
+ . += "It has a tiny camera inside. Needs to be both configured and brought in contact with monitor device to be fully functional."
/obj/item/device/camerabug/attackby(obj/item/W as obj, mob/living/user as mob)
if(istype(W, /obj/item/device/bug_monitor))
@@ -126,10 +126,7 @@
linkedmonitor.unpair(src)
linkedmonitor = null
..()
-/*
-/obj/item/device/camerabug/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
- radio.hear_talk(M, msg, speaking)
-*/
+
/obj/item/device/bug_monitor
name = "mobile camera pod monitor"
desc = "A portable camera console designed to work with mobile camera pods."
@@ -208,10 +205,7 @@
return
return 1
-/*
-/obj/item/device/bug_monitor/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
- return radio.hear_talk(M, msg, speaking)
-*/
+
/obj/item/device/bug_monitor/spy
name = "\improper PDA"
desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge."
@@ -221,9 +215,9 @@
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3)
/obj/item/device/bug_monitor/spy/examine(mob/user)
- . = ..(user, 1)
- if(.)
- to_chat(user, "The time '12:00' is blinking in the corner of the screen and \the [src] looks very cheaply made.")
+ . = ..()
+ if(Adjacent(user))
+ . += "The time '12:00' is blinking in the corner of the screen and \the [src] looks very cheaply made."
/obj/machinery/camera/bug/check_eye(var/mob/user as mob)
return 0
diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm
index e11cce4762..8c8a208db8 100644
--- a/code/game/objects/items/devices/suit_cooling.dm
+++ b/code/game/objects/items/devices/suit_cooling.dm
@@ -173,24 +173,25 @@
icon_state = "suitcooler0"
/obj/item/device/suit_cooling_unit/examine(mob/user)
- if(!..(user, 1))
- return
+ . = ..()
- if (on)
- if (attached_to_suit(src.loc))
- to_chat(user, "It's switched on and running.")
+ if(Adjacent(user))
+
+ if (on)
+ if (attached_to_suit(src.loc))
+ . += "It's switched on and running."
+ else
+ . += "It's switched on, but not attached to anything."
else
- to_chat(user, "It's switched on, but not attached to anything.")
- else
- to_chat(user, "It is switched off.")
+ . += "It is switched off."
- if (cover_open)
- if(cell)
- to_chat(user, "The panel is open, exposing the [cell].")
+ if (cover_open)
+ if(cell)
+ . += "The panel is open, exposing the [cell]."
+ else
+ . += "The panel is open."
+
+ if (cell)
+ . += "The charge meter reads [round(cell.percent())]%."
else
- to_chat(user, "The panel is open.")
-
- if (cell)
- to_chat(user, "The charge meter reads [round(cell.percent())]%.")
- else
- to_chat(user, "It doesn't have a power cell installed.")
+ . += "It doesn't have a power cell installed."
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index c2320dcf44..bdb35fb643 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -86,15 +86,10 @@
update_icon()
-/obj/item/device/taperecorder/hear_talk(mob/living/M as mob, msg, var/verb="says", datum/language/speaking=null)
+/obj/item/device/taperecorder/hear_talk(mob/M, list/message_pieces, verb)
+ var/msg = multilingual_to_message(message_pieces, requires_machine_understands = TRUE, with_capitalization = TRUE)
if(mytape && recording)
-
- if(speaking)
- if(!speaking.machine_understands)
- msg = speaking.scramble(msg)
- mytape.record_speech("[M.name] [speaking.format_message_plain(msg, verb)]")
- else
- mytape.record_speech("[M.name] [verb], \"[msg]\"")
+ mytape.record_speech("[M.name] [verb], \"[msg]\"")
/obj/item/device/taperecorder/see_emote(mob/M as mob, text, var/emote_type)
diff --git a/code/game/objects/items/devices/translator.dm b/code/game/objects/items/devices/translator.dm
index fc6352de29..868481d51e 100644
--- a/code/game/objects/items/devices/translator.dm
+++ b/code/game/objects/items/devices/translator.dm
@@ -33,8 +33,8 @@
icon_state = "[initial(icon_state)]"
to_chat(user, "You disable \the [src].")
-/obj/item/device/universal_translator/hear_talk(var/mob/speaker, var/message, var/vrb, var/datum/language/language)
- if(!listening || !istype(speaker))
+/obj/item/device/universal_translator/hear_talk(mob/M, list/message_pieces, verb)
+ if(!listening || !istype(M))
return
//Show the "I heard something" animation.
@@ -46,34 +46,38 @@
return
var/mob/living/L = loc
+ if(visual && ((L.sdisabilities & BLIND) || L.eye_blind))
+ return
+ if(audio && ((L.sdisabilities & DEAF) || L.ear_deaf))
+ return
- if(!language)
- return //Borgs were causing runtimes when passing language=null
+ // Using two for loops kinda sucks, but I think it's more efficient
+ // to shortcut past string building if we're just going to discard the string
+ // anyways.
+ if(user_understands(M, L, message_pieces))
+ return
- if (language && (language.flags & NONVERBAL))
- return //Not gonna translate sign language
+ var/new_message = ""
- if (!language.machine_understands)
- return //Any other languages that it can't translate.
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ if(S.speaking.flags & NONVERBAL)
+ continue
+ if(!S.speaking.machine_understands)
+ new_message += stars(S.message) + " "
+ continue
- if (visual && ((L.sdisabilities & BLIND) || L.eye_blind))
- return //Can't see the screen, don't get the message
+ new_message += (S.message + " ")
- if (audio && ((L.sdisabilities & DEAF) || L.ear_deaf))
- return //Can't hear the translation, don't get the message
+ if(!L.say_understands(null, langset))
+ new_message = langset.scramble(new_message)
- //Only translate if they can't understand, otherwise pointlessly spammy
- //I'll just assume they don't look at the screen in that case
+ to_chat(L, "[src] translates, \"[new_message]\"")
- //They don't understand the spoken language we're translating FROM
- if(!L.say_understands(speaker,language))
- //They understand the output language
- if(L.say_understands(null,langset))
- to_chat(L, "[src] translates, \"[message]\"")
-
- //They don't understand the output language
- else
- to_chat(L, "[src] translates, \"[langset.scramble(message)]\"")
+/obj/item/device/universal_translator/proc/user_understands(mob/M, mob/living/L, list/message_pieces)
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ if(S.speaking && !L.say_understands(M, S.speaking))
+ return FALSE
+ return TRUE
//Let's try an ear-worn version
/obj/item/device/universal_translator/ear
diff --git a/code/game/objects/items/devices/translocator_vr.dm b/code/game/objects/items/devices/translocator_vr.dm
index f171f147c3..40c61b1c2c 100644
--- a/code/game/objects/items/devices/translocator_vr.dm
+++ b/code/game/objects/items/devices/translocator_vr.dm
@@ -25,9 +25,15 @@
var/list/warned_users = list()
var/list/logged_events = list()
+ var/list/radial_images = list()
+
+ var/static/radial_plus = image(icon = 'icons/mob/radial_vr.dmi', icon_state = "tl_plus")
+ var/static/radial_set = image(icon = 'icons/mob/radial_vr.dmi', icon_state = "tl_set")
+ var/static/radial_seton = image(icon = 'icons/mob/radial_vr.dmi', icon_state = "tl_seton")
/obj/item/device/perfect_tele/Initialize()
. = ..()
+
flags |= NOBLUDGEON
if(cell_type)
power_source = new cell_type(src)
@@ -37,6 +43,8 @@
spk.set_up(5, 0, src)
spk.attach(src)
+ rebuild_radial_images()
+
/obj/item/device/perfect_tele/Destroy()
// Must clear the beacon's backpointer or we won't GC. Someday maybe do something nicer even.
for(var/obj/item/device/perfect_tele_beacon/B in beacons)
@@ -56,6 +64,28 @@
..()
+/obj/item/device/perfect_tele/proc/rebuild_radial_images()
+ radial_images.Cut()
+
+ var/index = 1
+ for(var/bcn in beacons) //Grumble
+ var/image/I = image(icon = 'icons/mob/radial_vr.dmi', icon_state = "tl_[index]")
+
+ var/obj/item/device/perfect_tele_beacon/beacon = beacons[bcn]
+ if(destination == beacon)
+ I.overlays += radial_seton
+ else
+ I.overlays += radial_set
+
+ radial_images[bcn] = I
+
+ index++
+
+ if(beacons_left)
+ var/image/I = image(icon = 'icons/mob/radial_vr.dmi', icon_state = "tl_[index]")
+ I.overlays += radial_plus
+ radial_images["New Beacon"] = I
+
/obj/item/device/perfect_tele/attack_hand(mob/user)
if(user.get_inactive_hand() == src)
unload_ammo(user)
@@ -74,6 +104,13 @@
else
to_chat(user,"[src] does not have a power cell.")
+/obj/item/device/perfect_tele/proc/check_menu(var/mob/living/user)
+ if(!istype(user))
+ return FALSE
+ if(user.incapacitated() || !user.Adjacent(src))
+ return FALSE
+ return TRUE
+
/obj/item/device/perfect_tele/attack_self(mob/user)
if(loc_network)
for(var/obj/item/device/perfect_tele_beacon/stationary/nb in premade_tele_beacons)
@@ -87,7 +124,45 @@
and tele-vore. Make sure you carefully examine someone's OOC prefs before teleporting them if you are \
going to use this device for ERP purposes. This device records all warnings given and teleport events for \
admin review in case of pref-breaking, so just don't do it.","OOC WARNING")
+
+ var/choice = show_radial_menu(user, src, radial_images, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
+
+ if(!choice)
+ return
+
+ else if(choice == "New Beacon")
+ if(beacons_left <= 0)
+ to_chat(user, "The translocator can't support any more beacons!")
+ return
+ var/new_name = html_encode(input(user,"New beacon's name (2-20 char):","[src]") as text|null)
+ if(!check_menu(user))
+ return
+
+ if(length(new_name) > 20 || length(new_name) < 2)
+ to_chat(user, "Entered name length invalid (must be longer than 2, no more than than 20).")
+ return
+
+ if(new_name in beacons)
+ to_chat(user, "No duplicate names, please. '[new_name]' exists already.")
+ return
+
+ var/obj/item/device/perfect_tele_beacon/nb = new(get_turf(src))
+ nb.tele_name = new_name
+ nb.tele_hand = src
+ nb.creator = user.ckey
+ beacons[new_name] = nb
+ beacons_left--
+ if(isliving(user))
+ var/mob/living/L = user
+ L.put_in_any_hand_if_possible(nb)
+ rebuild_radial_images()
+
+ else
+ destination = beacons[choice]
+ rebuild_radial_images()
+
+ /* Ye olde text-based way
var/choice = alert(user,"What do you want to do?","[src]","Create Beacon","Cancel","Target Beacon")
switch(choice)
if("Create Beacon")
@@ -124,6 +199,7 @@
to_chat(user,"Destination set to '[target]'.")
else
return
+ */
/obj/item/device/perfect_tele/attackby(obj/W, mob/user)
if(istype(W,cell_type) && !power_source)
diff --git a/code/game/objects/items/devices/tvcamera.dm b/code/game/objects/items/devices/tvcamera.dm
index 3fdaa5e79f..e8b6df0b98 100644
--- a/code/game/objects/items/devices/tvcamera.dm
+++ b/code/game/objects/items/devices/tvcamera.dm
@@ -22,9 +22,9 @@
..()
/obj/item/device/tvcamera/examine()
- ..()
- to_chat(usr, "Video feed is [camera.status ? "on" : "off"]")
- to_chat(usr, "Audio feed is [radio.broadcasting ? "on" : "off"]")
+ . = ..()
+ . += "Video feed is [camera.status ? "on" : "off"]"
+ . += "Audio feed is [radio.broadcasting ? "on" : "off"]"
/obj/item/device/tvcamera/Initialize()
. = ..()
@@ -38,9 +38,9 @@
radio.icon_state = src.icon_state
update_icon()
-/obj/item/device/tvcamera/hear_talk(mob/living/M, msg, var/verb="says", datum/language/speaking=null)
- radio.hear_talk(M,msg,verb,speaking)
- ..()
+/obj/item/device/tvcamera/hear_talk(mob/M, list/message_pieces, verb)
+ radio.hear_talk(M, message_pieces, verb)
+ . = ..()
/obj/item/device/tvcamera/attack_self(mob/user)
add_fingerprint(user)
diff --git a/code/game/objects/items/paintkit.dm b/code/game/objects/items/paintkit.dm
index 4b3bd408d2..a0bebc699f 100644
--- a/code/game/objects/items/paintkit.dm
+++ b/code/game/objects/items/paintkit.dm
@@ -11,8 +11,8 @@
var/list/allowed_types = list()
/obj/item/device/kit/examine()
- ..()
- to_chat(usr, "It has [uses] use\s left.")
+ . = ..()
+ . += "It has [uses] use\s left."
/obj/item/device/kit/proc/use(var/amt, var/mob/user)
uses -= amt
@@ -216,11 +216,11 @@
/obj/item/device/kit/paint/examine()
- ..()
- to_chat(usr, "This kit will convert an exosuit into: [new_name].")
- to_chat(usr, "This kit can be used on the following exosuit models:")
+ . = ..()
+ . += "This kit will convert an exosuit into: [new_name]."
+ . += "This kit can be used on the following exosuit models:"
for(var/exotype in allowed_types)
- to_chat(usr, "- [capitalize(exotype)]")
+ . += "- [capitalize(exotype)]"
/obj/item/device/kit/paint/customize(var/obj/mecha/M, var/mob/user)
if(!can_customize(M))
diff --git a/code/game/objects/items/robobag.dm b/code/game/objects/items/robobag.dm
index f367f6a145..33c3ba89ed 100644
--- a/code/game/objects/items/robobag.dm
+++ b/code/game/objects/items/robobag.dm
@@ -27,9 +27,9 @@
var/obj/item/clothing/accessory/badge/corptag // The tag on the bag.
/obj/structure/closet/body_bag/cryobag/robobag/examine(mob/user)
- ..()
- if(Adjacent(user) && corptag)
- to_chat(user, "\The [src] has a [corptag] attached to it.")
+ . = ..()
+ if(corptag && Adjacent(user))
+ . += "[src] has a [corptag] attached to it."
/obj/structure/closet/body_bag/cryobag/robobag/update_icon()
overlays.Cut()
diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm
index c3bc83d3b9..982236f43c 100644
--- a/code/game/objects/items/shooting_range.dm
+++ b/code/game/objects/items/shooting_range.dm
@@ -18,12 +18,12 @@
break
..() // delete target
- Move()
- ..()
+ Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
// After target moves, check for nearby stakes. If associated, move to target
for(var/obj/structure/target_stake/M in view(3,src))
if(M.density == 0 && M.pinned_target == src)
- M.loc = loc
+ M.forceMove(loc)
// This may seem a little counter-intuitive but I assure you that's for a purpose.
// Stakes are the ones that carry targets, yes, but in the stake code we set
diff --git a/code/game/objects/items/stacks/fifty_spawner.dm b/code/game/objects/items/stacks/fifty_spawner.dm
index 6cd9051c6f..81dfce9691 100644
--- a/code/game/objects/items/stacks/fifty_spawner.dm
+++ b/code/game/objects/items/stacks/fifty_spawner.dm
@@ -9,9 +9,13 @@
/obj/fiftyspawner/Initialize()
..() //We're not returning . because we're going to ask to be deleted.
- var/obj/item/stack/M = new type_to_spawn(get_turf(src))
+ var/turf/T = get_turf(src)
+ var/obj/item/stack/M = new type_to_spawn(T)
M.amount = M.max_amount //some stuff spawns with 60, we're still calling it fifty
M.update_icon() // Some stacks have different sprites depending on how full they are.
+ var/obj/structure/closet/C = locate() in T
+ if(C)
+ C.contents += M
return INITIALIZE_HINT_QDEL //Bye!
/obj/fiftyspawner/rods
diff --git a/code/game/objects/items/stacks/marker_beacons.dm b/code/game/objects/items/stacks/marker_beacons.dm
index 93462c640e..88eb8e6271 100644
--- a/code/game/objects/items/stacks/marker_beacons.dm
+++ b/code/game/objects/items/stacks/marker_beacons.dm
@@ -42,9 +42,9 @@ var/list/marker_beacon_colors = list(
update_icon()
/obj/item/stack/marker_beacon/examine(mob/user)
- ..()
- to_chat(user, "Use in-hand to place a [singular_name].")
- to_chat(user, "Alt-click to select a color. Current color is [picked_color].")
+ . = ..()
+ . += "Use in-hand to place a [singular_name]."
+ . += "Alt-click to select a color. Current color is [picked_color]."
/obj/item/stack/marker_beacon/update_icon()
icon_state = "[initial(icon_state)][lowertext(picked_color)]"
@@ -93,8 +93,8 @@ var/list/marker_beacon_colors = list(
update_icon()
/obj/structure/marker_beacon/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to select a color. Current color is [picked_color].")
+ . = ..()
+ . += "Alt-click to select a color. Current color is [picked_color]."
/obj/structure/marker_beacon/update_icon()
while(!picked_color || !marker_beacon_colors[picked_color])
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 8887dd0053..20f098e5d1 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -111,7 +111,7 @@
continue
if(used == amount)
break
- if(!do_mob(user, M, W.damage/3))
+ if(!do_mob(user, M, W.damage/3, exclusive = TRUE))
to_chat(user, "You must stand still to bandage wounds.")
break
@@ -174,7 +174,7 @@
continue
if(used == amount)
break
- if(!do_mob(user, M, W.damage/5))
+ if(!do_mob(user, M, W.damage/5, exclusive = TRUE))
to_chat(user, "You must stand still to bandage wounds.")
break
@@ -234,7 +234,7 @@
else
user.visible_message("\The [user] starts salving wounds on [M]'s [affecting.name].", \
"You start salving the wounds on [M]'s [affecting.name]." )
- if(!do_mob(user, M, 10))
+ if(!do_mob(user, M, 10, exclusive = TRUE))
to_chat(user, "You must stand still to salve wounds.")
return 1
if(affecting.is_salved()) // We do a second check after the delay, in case it was bandaged after the first check.
@@ -281,7 +281,7 @@
continue
//if(used == amount) //VOREStation Edit
// break //VOREStation Edit
- if(!do_mob(user, M, W.damage/5))
+ if(!do_mob(user, M, W.damage/5, exclusive = TRUE))
to_chat(user, "You must stand still to bandage wounds.")
break
if(affecting.is_bandaged() && affecting.is_disinfected()) // We do a second check after the delay, in case it was bandaged after the first check.
@@ -336,7 +336,7 @@
else
user.visible_message("\The [user] starts salving wounds on [M]'s [affecting.name].", \
"You start salving the wounds on [M]'s [affecting.name]." )
- if(!do_mob(user, M, 10))
+ if(!do_mob(user, M, 10, exclusive = TRUE))
to_chat(user, "You must stand still to salve wounds.")
return 1
if(affecting.is_salved()) // We do a second check after the delay, in case it was bandaged after the first check.
@@ -383,7 +383,7 @@
to_chat(user, "You can't apply a splint to the arm you're using!")
return
user.visible_message("[user] starts to apply \the [src] to their [limb].", "You start to apply \the [src] to your [limb].", "You hear something being wrapped.")
- if(do_after(user, 50, M))
+ if(do_after(user, 50, M, exclusive = TRUE))
if(affecting.splinted)
to_chat(user, "[M]'s [limb] is already splinted!")
return
diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm
index bc1f6486c1..3d5aeffa3d 100644
--- a/code/game/objects/items/stacks/nanopaste.dm
+++ b/code/game/objects/items/stacks/nanopaste.dm
@@ -16,7 +16,7 @@
if (istype(M,/mob/living/silicon/robot)) //Repairing cyborgs
var/mob/living/silicon/robot/R = M
if (R.getBruteLoss() || R.getFireLoss())
- if(do_after(user,7 * toolspeed))
+ if(do_after(user, 7 * toolspeed, exclusive = TRUE))
R.adjustBruteLoss(-15)
R.adjustFireLoss(-15)
R.updatehealth()
@@ -51,9 +51,9 @@
else if(can_use(1))
user.setClickCooldown(user.get_attack_speed(src))
if(S.open >= 2)
- if(do_after(user,5 * toolspeed))
+ if(do_after(user, 5 * toolspeed, exclusive = TRUE))
S.heal_damage(restoration_internal, restoration_internal, robo_repair = 1)
- else if(do_after(user,5 * toolspeed))
+ else if(do_after(user, 5 * toolspeed, exclusive = TRUE))
S.heal_damage(restoration_external,restoration_external, robo_repair =1)
H.updatehealth()
use(1)
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 324ade23ce..1aa69305f5 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -58,11 +58,13 @@
item_state = initial(icon_state)
/obj/item/stack/examine(mob/user)
- if(..(user, 1))
+ . = ..()
+
+ if(Adjacent(user))
if(!uses_charge)
- to_chat(user, "There are [src.amount] [src.singular_name]\s in the stack.")
+ . += "There are [src.amount] [src.singular_name]\s in the stack."
else
- to_chat(user, "There is enough charge for [get_amount()].")
+ . += "There is enough charge for [get_amount()]."
/obj/item/stack/attack_self(mob/user as mob)
list_recipes(user)
@@ -143,7 +145,7 @@
if (recipe.time)
to_chat(user, "Building [recipe.title] ...")
- if (!do_after(user, recipe.time))
+ if (!do_after(user, recipe.time, exclusive = TRUE))
return
if (use(required))
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index cb177e0080..5eb7a8f69a 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -154,8 +154,9 @@
drop_sound = 'sound/items/drop/gun.ogg'
examine(mob/user)
- if(..(user, 2) && bullets)
- to_chat(user, "It is loaded with [bullets] foam darts!")
+ . = ..()
+ if(bullets && get_dist(user, src) <= 2)
+ . += "It is loaded with [bullets] foam darts!"
attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/toy/ammo/crossbow))
@@ -315,8 +316,8 @@
update_icon()
/obj/item/toy/sword/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to recolor it.")
+ . = ..()
+ . += "Alt-click to recolor it."
/obj/item/toy/sword/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/device/multitool) && !active)
@@ -379,75 +380,6 @@
playsound(src, 'sound/effects/snap.ogg', 50, 1)
qdel(src)
-/*
- * Water flower
- */
-/obj/item/toy/waterflower
- name = "water flower"
- desc = "A seemingly innocent sunflower...with a twist."
- icon = 'icons/obj/device.dmi'
- drop_sound = 'sound/items/drop/food.ogg'
- icon_state = "sunflower"
- item_state = "sunflower"
- var/empty = 0
- slot_flags = SLOT_HOLSTER
-
-/obj/item/toy/waterflower/New()
- var/datum/reagents/R = new/datum/reagents(10)
- reagents = R
- R.my_atom = src
- R.add_reagent("water", 10)
-
-/obj/item/toy/waterflower/attack(mob/living/carbon/human/M as mob, mob/user as mob)
- return
-
-/obj/item/toy/waterflower/afterattack(atom/A as mob|obj, mob/user as mob)
-
- if (istype(A, /obj/item/weapon/storage/backpack ))
- return
-
- else if (locate (/obj/structure/table, src.loc))
- return
-
- else if (istype(A, /obj/structure/reagent_dispensers/watertank) && get_dist(src,A) <= 1)
- A.reagents.trans_to_obj(src, 10)
- to_chat(user, "You refill your flower!")
- return
-
- else if (src.reagents.total_volume < 1)
- src.empty = 1
- to_chat(user, "Your flower has run dry!")
- return
-
- else
- src.empty = 0
-
-
- var/obj/effect/decal/D = new/obj/effect/decal/(get_turf(src))
- D.name = "water"
- D.icon = 'icons/obj/chemical.dmi'
- D.icon_state = "chempuff"
- D.create_reagents(5)
- src.reagents.trans_to_obj(D, 1)
- playsound(src.loc, 'sound/effects/spray3.ogg', 50, 1, -6)
-
- spawn(0)
- for(var/i=0, i<1, i++)
- step_towards(D,A)
- D.reagents.touch_turf(get_turf(D))
- for(var/atom/T in get_turf(D))
- D.reagents.touch(T)
- if(ismob(T) && T:client)
- to_chat(T:client, "\The [user] has sprayed you with water!")
- sleep(4)
- qdel(D)
-
- return
-
-/obj/item/toy/waterflower/examine(mob/user)
- if(..(user, 0))
- to_chat(user, "[bicon(src)] [src.reagents.total_volume] units of water left!")
-
/*
* Bosun's whistle
*/
@@ -893,11 +825,11 @@
var/obj/item/stored_item // Note: Stored items can't be bigger than the plushie itself.
/obj/structure/plushie/examine(mob/user)
- ..()
+ . = ..()
if(opened)
- to_chat(user, "You notice an incision has been made on [src].")
+ . += "You notice an incision has been made on [src]."
if(in_range(user, src) && stored_item)
- to_chat(user, "You can see something in there...")
+ . += "You can see something in there..."
/obj/structure/plushie/attack_hand(mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
@@ -992,11 +924,11 @@
/obj/item/toy/plushie/examine(mob/user)
- ..()
+ . = ..()
if(opened)
- to_chat(user, "You notice an incision has been made on [src].")
+ . += "You notice an incision has been made on [src]."
if(in_range(user, src) && stored_item)
- to_chat(user, "You can see something in there...")
+ . += "You can see something in there..."
/obj/item/toy/plushie/attack_self(mob/user as mob)
if(stored_item && opened && !searching)
diff --git a/code/game/objects/items/toys_vr.dm b/code/game/objects/items/toys_vr.dm
new file mode 100644
index 0000000000..1b456393db
--- /dev/null
+++ b/code/game/objects/items/toys_vr.dm
@@ -0,0 +1,53 @@
+/obj/item/toy/plushie/lizardplushie
+ name = "lizard plushie"
+ desc = "An adorable stuffed toy that resembles a lizardperson."
+ icon = 'icons/obj/toy_vr.dmi'
+ icon_state = "plushie_lizard"
+ attack_verb = list("clawed", "hissed", "tail slapped")
+
+/obj/item/toy/plushie/lizardplushie/kobold
+ name = "kobold plushie"
+ desc = "An adorable stuffed toy that resembles a kobold."
+ icon = 'icons/obj/toy_vr.dmi'
+ icon_state = "kobold"
+
+/obj/item/toy/plushie/slimeplushie
+ name = "slime plushie"
+ desc = "An adorable stuffed toy that resembles a slime. It is practically just a hacky sack."
+ icon = 'icons/obj/toy_vr.dmi'
+ icon_state = "plushie_slime"
+ attack_verb = list("blorbled", "slimed", "absorbed", "glomped")
+ gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy
+
+/obj/item/toy/plushie/box
+ name = "cardboard plushie"
+ desc = "A toy box plushie, it holds cotten. Only a baddie would place a bomb through the postal system..."
+ icon = 'icons/obj/toy_vr.dmi'
+ icon_state = "box"
+ attack_verb = list("open", "closed", "packed", "hidden", "rigged", "bombed", "sent", "gave")
+
+/obj/item/toy/plushie/borgplushie
+ name = "robot plushie"
+ desc = "An adorable stuffed toy of a robot."
+ icon = 'icons/obj/toy_vr.dmi'
+ icon_state = "securityk9"
+ attack_verb = list("beeped", "booped", "pinged")
+
+/obj/item/toy/plushie/borgplushie/medihound
+ icon_state = "medihound"
+
+/obj/item/toy/plushie/borgplushie/scrubpuppy
+ icon_state = "scrubpuppy"
+
+/obj/item/toy/plushie/foxbear
+ name = "toy fox"
+ desc = "Issa fox!"
+ icon = 'icons/obj/toy_vr.dmi'
+ icon_state = "fox"
+
+/obj/item/toy/plushie/nukeplushie
+ name = "operative plushie"
+ desc = "A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious."
+ icon = 'icons/obj/toy_vr.dmi'
+ icon_state = "plushie_nuke"
+ attack_verb = list("shot", "nuked", "detonated")
diff --git a/code/game/objects/items/uav.dm b/code/game/objects/items/uav.dm
new file mode 100644
index 0000000000..166ad9e9a5
--- /dev/null
+++ b/code/game/objects/items/uav.dm
@@ -0,0 +1,360 @@
+#define UAV_OFF 0
+#define UAV_ON 1
+#define UAV_PAIRING 2
+#define UAV_PACKED 3
+
+/obj/item/device/uav
+ name = "recon skimmer"
+ desc = "A semi-portable reconisance drone that folds into a backpack-sized carrying case."
+ icon = 'icons/obj/uav.dmi'
+ icon_state = "uav"
+
+ var/obj/item/weapon/cell/cell
+ var/cell_type = null //Can put a starting cell here
+
+ density = 1 //Is dense, but not anchored, so you can swap with it
+ slowdown = 3 //Heevvee.
+
+ health = 100
+ var/power_per_process = 50 // About 6.5 minutes of use on a high-cell (10,000)
+ var/state = UAV_OFF
+
+ var/datum/effect/effect/system/ion_trail_follow/ion_trail
+
+ var/list/mob/living/masters
+
+ // So you know which is which
+ var/nickname = "Generic Droan"
+
+ // Radial menu
+ var/static/image/radial_pickup = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pickup")
+ var/static/image/radial_wrench = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_wrench")
+ var/static/image/radial_power = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_power")
+ var/static/image/radial_pair = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pair")
+
+ // Movement cooldown
+ var/next_move = 0
+
+ // Idle shutdown time
+ var/no_masters_time = 0
+
+/obj/item/device/uav/loaded
+ cell_type = /obj/item/weapon/cell/high
+
+/obj/item/device/uav/Initialize()
+ . = ..()
+
+ if(!cell && cell_type)
+ cell = new cell_type
+
+ ion_trail = new /datum/effect/effect/system/ion_trail_follow()
+ ion_trail.set_up(src)
+ ion_trail.stop()
+
+/obj/item/device/uav/Destroy()
+ qdel_null(cell)
+ qdel_null(ion_trail)
+ LAZYCLEARLIST(masters)
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/item/device/uav/examine(mob/user)
+ . = ..()
+ if(Adjacent(user))
+ . += "It has '[nickname]' scribbled on the side."
+ if(!cell)
+ . += "It appears to be missing a power cell."
+
+ if(health <= (initial(health)/4))
+ . += "It looks like it might break at any second!"
+ else if(health <= (initial(health)/2))
+ . += "It looks pretty beaten up..."
+
+/obj/item/device/uav/attack_hand(var/mob/user)
+ //Has to be on the ground to work with it properly
+ if(!isturf(loc))
+ return ..()
+
+ var/list/options = list(
+ "Pick Up" = radial_pickup,
+ "(Dis)Assemble" = radial_wrench,
+ "Toggle Power" = radial_power,
+ "Pairing Mode" = radial_pair)
+ var/choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
+
+ switch(choice)
+ // Can pick up when off or packed
+ if("Pick Up")
+ if(state == UAV_OFF || state == UAV_PACKED)
+ return ..()
+ else
+ to_chat(user,"Turn [nickname] off or pack it first!")
+ return
+ // Can disasemble or reassemble from packed or off (and this one takes time)
+ if("(Dis)Assemble")
+ if(can_transition_to(state == UAV_PACKED ? UAV_OFF : UAV_PACKED, user) && do_after(user, 10 SECONDS, src))
+ return toggle_packed(user)
+ // Can toggle power from on and off
+ if("Toggle Power")
+ if(can_transition_to(state == UAV_ON ? UAV_OFF : UAV_ON, user))
+ return toggle_power(user)
+ // Can pair when off
+ if("Pairing Mode")
+ if(can_transition_to(state == UAV_PAIRING ? UAV_OFF : UAV_PAIRING, user))
+ return toggle_pairing(user)
+
+/obj/item/device/uav/attackby(var/obj/item/I, var/mob/user)
+ if(istype(I, /obj/item/modular_computer) && state == UAV_PAIRING)
+ var/obj/item/modular_computer/MC = I
+ LAZYDISTINCTADD(MC.paired_uavs, weakref(src))
+ playsound(src, 'sound/machines/buttonbeep.ogg', 50, 1)
+ visible_message("[user] pairs [I] to [nickname]")
+ toggle_pairing()
+
+ else if(I.is_screwdriver() && cell)
+ if(do_after(user, 3 SECONDS, src))
+ to_chat(user, "You remove [cell] into [nickname].")
+ playsound(src, I.usesound, 50, 1)
+ power_down()
+ cell.forceMove(get_turf(src))
+ cell = null
+
+ else if(istype(I, /obj/item/weapon/cell) && !cell)
+ if(do_after(user, 3 SECONDS, src))
+ to_chat(user, "You insert [I] into [nickname].")
+ playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
+ power_down()
+ user.remove_from_mob(I)
+ I.forceMove(src)
+ cell = I
+
+ else if(istype(I, /obj/item/weapon/pen) || istype(I, /obj/item/device/flashlight/pen))
+ var/tmp_label = sanitizeSafe(input(user, "Enter a nickname for [src]", "Nickname", nickname), MAX_NAME_LEN)
+ if(length(tmp_label) > 50 || length(tmp_label) < 3)
+ to_chat(user, "The nickname must be between 3 and 50 characters.")
+ else
+ to_chat(user, "You scribble your new nickname on the side of [src].")
+ nickname = tmp_label
+ desc = initial(desc) + " This one has '[nickname]' scribbled on the side."
+ else
+ return ..()
+
+/obj/item/device/uav/proc/can_transition_to(var/new_state, var/mob/user)
+ switch(state) //Current one
+ if(UAV_ON)
+ if(new_state == UAV_OFF || new_state == UAV_PACKED)
+ . = TRUE
+ if(UAV_OFF)
+ if(new_state == UAV_ON || new_state == UAV_PACKED || new_state == UAV_PAIRING)
+ . = TRUE
+ if(UAV_PAIRING)
+ if(new_state == UAV_OFF)
+ . = TRUE
+ if(UAV_PACKED)
+ if(new_state == UAV_OFF)
+ . = TRUE
+
+ if(!.)
+ if(user)
+ to_chat(user, "You can't do that while [nickname] is in this state.")
+ return FALSE
+
+/obj/item/device/uav/update_icon()
+ cut_overlays()
+ switch(state)
+ if(UAV_PAIRING)
+ add_overlay("[initial(icon_state)]_pairing")
+ icon_state = "[initial(icon_state)]"
+ if(UAV_ON)
+ icon_state = "[initial(icon_state)]_on"
+ if(UAV_OFF)
+ icon_state = "[initial(icon_state)]"
+ if(UAV_PACKED)
+ icon_state = "[initial(icon_state)]_packed"
+
+/obj/item/device/uav/process()
+ if(cell?.use(power_per_process) != power_per_process)
+ visible_message("[src] sputters and thuds to the ground, inert.")
+ playsound(src, 'sound/items/drop/metalboots.ogg', 75, 1)
+ power_down()
+ health -= initial(health)*0.25 //Lose 25% of your original health
+
+ if(LAZYLEN(masters))
+ no_masters_time = 0
+ else if(no_masters_time++ > 50)
+ power_down()
+
+/obj/item/device/uav/proc/toggle_pairing()
+ switch(state)
+ if(UAV_PAIRING)
+ state = UAV_OFF
+ update_icon()
+ return TRUE
+ if(UAV_OFF)
+ state = UAV_PAIRING
+ update_icon()
+ return TRUE
+ return FALSE
+
+/obj/item/device/uav/proc/toggle_power()
+ switch(state)
+ if(UAV_OFF)
+ power_up()
+ return TRUE
+ if(UAV_ON)
+ power_down()
+ return TRUE
+ return FALSE
+
+/obj/item/device/uav/proc/toggle_packed()
+ if(UAV_ON)
+ power_down()
+ switch(state)
+ if(UAV_OFF) //Packing
+ state = UAV_PACKED
+ w_class = ITEMSIZE_LARGE
+ slowdown = 1
+ density = FALSE
+ update_icon()
+ return TRUE
+ if(UAV_PACKED) //Unpacking
+ state = UAV_OFF
+ w_class = ITEMSIZE_HUGE
+ slowdown = 3
+ density = TRUE
+ update_icon()
+ return TRUE
+ return FALSE
+
+/obj/item/device/uav/proc/power_up()
+ if(state != UAV_OFF || !isturf(loc))
+ return
+ if(cell?.use(power_per_process) != power_per_process)
+ visible_message("[src] sputters and chugs as it tries, and fails, to power up.")
+ return
+
+ state = UAV_ON
+ update_icon()
+ start_hover()
+ set_light(4, 4, "#FFFFFF")
+ START_PROCESSING(SSobj, src)
+ no_masters_time = 0
+ visible_message("[nickname] buzzes and lifts into the air.")
+
+/obj/item/device/uav/proc/power_down()
+ if(state != UAV_ON)
+ return
+
+ state = UAV_OFF
+ update_icon()
+ stop_hover()
+ set_light(0)
+ LAZYCLEARLIST(masters)
+ STOP_PROCESSING(SSobj, src)
+ visible_message("[nickname] gracefully settles onto the ground.")
+
+//////////////// Helpers
+/obj/item/device/uav/get_cell()
+ return cell
+
+/obj/item/device/uav/relaymove(var/mob/user, direction, signal = 1)
+ if(signal && state == UAV_ON && (weakref(user) in masters))
+ if(next_move <= world.time)
+ next_move = world.time + (1 SECOND/signal)
+ step(src, direction)
+ return TRUE // Even if we couldn't step, we're taking credit for absorbing the move
+ return FALSE
+
+/obj/item/device/uav/proc/get_status_string()
+ return "[nickname] - [get_x(src)],[get_y(src)],[get_z(src)] - I:[health]/[initial(health)] - C:[cell ? "[cell.charge]/[cell.maxcharge]" : "Not Installed"]"
+
+/obj/item/device/uav/proc/add_master(var/mob/living/M)
+ LAZYDISTINCTADD(masters, weakref(M))
+
+/obj/item/device/uav/proc/remove_master(var/mob/living/M)
+ LAZYREMOVE(masters, weakref(M))
+
+/obj/item/device/uav/check_eye()
+ if(state == UAV_ON)
+ return 0
+ else
+ return -1
+
+/obj/item/device/uav/proc/start_hover()
+ if(!ion_trail.on) //We'll just use this to store if we're floating or not
+ ion_trail.start()
+ var/amplitude = 2 //maximum displacement from original position
+ var/period = 36 //time taken for the mob to go up >> down >> original position, in deciseconds. Should be multiple of 4
+
+ var/top = old_y + amplitude
+ var/bottom = old_y - amplitude
+ var/half_period = period / 2
+ var/quarter_period = period / 4
+
+ animate(src, pixel_y = top, time = quarter_period, easing = SINE_EASING | EASE_OUT, loop = -1) //up
+ animate(pixel_y = bottom, time = half_period, easing = SINE_EASING, loop = -1) //down
+ animate(pixel_y = old_y, time = quarter_period, easing = SINE_EASING | EASE_IN, loop = -1) //back
+
+/obj/item/device/uav/proc/stop_hover()
+ if(ion_trail.on)
+ ion_trail.stop()
+ animate(src, pixel_y = old_y, time = 5, easing = SINE_EASING | EASE_IN) //halt animation
+
+/obj/item/device/uav/hear_talk(var/mob/M, list/message_pieces, verb)
+ var/name_used = M.GetVoice()
+ for(var/wr_master in masters)
+ var/weakref/wr = wr_master
+ var/mob/master = wr.resolve()
+ var/message = master.combine_message(message_pieces, verb, M)
+ var/rendered = "UAV received: [name_used] [message]"
+ master.show_message(rendered, 2)
+
+/obj/item/device/uav/see_emote(var/mob/living/M, text)
+ for(var/wr_master in masters)
+ var/weakref/wr = wr_master
+ var/mob/master = wr.resolve()
+ var/rendered = "UAV received, [text]"
+ master.show_message(rendered, 2)
+
+/obj/item/device/uav/show_message(msg, type, alt, alt_type)
+ for(var/wr_master in masters)
+ var/weakref/wr = wr_master
+ var/mob/master = wr.resolve()
+ var/rendered = "UAV received, [msg]"
+ master.show_message(rendered, type)
+
+/obj/item/device/uav/take_damage(var/damage)
+ health -= damage
+ CheckHealth()
+ return
+
+/obj/item/device/uav/attack_generic(var/mob/user, var/damage, var/attack_verb)
+ visible_message("[user] [attack_verb] the [src]!")
+ playsound(src, 'sound/weapons/smash.ogg', 50, 1)
+ user.do_attack_animation(src)
+ health -= damage
+ CheckHealth()
+ return
+
+/obj/item/device/uav/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ die()
+ if(2.0)
+ health -= 25
+ CheckHealth()
+
+/obj/item/device/uav/proc/CheckHealth()
+ if(health <= 0)
+ die()
+
+/obj/item/device/uav/proc/die()
+ visible_message("[src] shorts out and explodes!")
+ power_down()
+ var/turf/T = get_turf(src)
+ qdel(src)
+ explosion(T, -1, 0, 1, 2) //Not very large
+
+#undef UAV_OFF
+#undef UAV_ON
+#undef UAV_PACKED
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index 034063c453..5a0deea83a 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -27,27 +27,29 @@
var/window_type = /obj/structure/window/reinforced/full
var/material_to_use = DEFAULT_WALL_MATERIAL // So badmins can make RCDs that print diamond walls.
var/make_rwalls = FALSE // If true, when building walls, they will be reinforced.
-
+/* VOREStation Removal - Unused
/obj/item/weapon/rcd/Initialize()
+
src.spark_system = new /datum/effect/effect/system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
return ..()
-
+*/
/obj/item/weapon/rcd/Destroy()
QDEL_NULL(spark_system)
spark_system = null
return ..()
/obj/item/weapon/rcd/examine(mob/user)
- ..()
- to_chat(user, display_resources())
+ . = ..()
+ . += display_resources()
// Used to show how much stuff (matter units, cell charge, etc) is left inside.
/obj/item/weapon/rcd/proc/display_resources()
return "It currently holds [stored_matter]/[max_stored_matter] matter-units."
// Used to add new cartridges.
+/* VOREStation Tweak - Wow this is annoying, moved to _vr file for overhaul
/obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/rcd_ammo))
var/obj/item/weapon/rcd_ammo/cartridge = W
@@ -61,9 +63,10 @@
to_chat(user, span("notice", "The RCD now holds [stored_matter]/[max_stored_matter] matter-units."))
return TRUE
return ..()
-
+*/
// Changes which mode it is on.
/obj/item/weapon/rcd/attack_self(mob/living/user)
+/* VOREStation Removal - Moved to VR
if(mode_index >= modes.len) // Shouldn't overflow unless someone messes with it in VV poorly but better safe than sorry.
mode_index = 1
else
@@ -74,7 +77,7 @@
if(prob(20))
src.spark_system.start()
-
+*/
// Removes resources if the RCD can afford it.
/obj/item/weapon/rcd/proc/consume_resources(amount)
if(!can_afford(amount))
@@ -118,6 +121,7 @@
rcd_beam = beam_origin.Beam(A, icon_state = "rped_upgrade", time = max(true_delay, 5))
busy = TRUE
+ perform_effect(A, true_delay) //VOREStation Add
if(do_after(user, true_delay, target = A))
busy = FALSE
// Doing another check in case we lost matter during the delay for whatever reason.
diff --git a/code/game/objects/items/weapons/RCD_vr.dm b/code/game/objects/items/weapons/RCD_vr.dm
new file mode 100644
index 0000000000..5cfc822efa
--- /dev/null
+++ b/code/game/objects/items/weapons/RCD_vr.dm
@@ -0,0 +1,218 @@
+/obj/item/weapon/rcd
+ icon = 'icons/obj/tools_vr.dmi'
+ icon_state = "rcd"
+ item_state = "rcd"
+ item_icons = list(
+ slot_l_hand_str = 'icons/mob/items/lefthand_vr.dmi',
+ slot_r_hand_str = 'icons/mob/items/righthand_vr.dmi',
+ )
+ var/ammostate
+ var/list/effects = list()
+
+ var/static/image/radial_image_airlock = image(icon = 'icons/mob/radial.dmi', icon_state = "airlock"),
+ var/static/image/radial_image_decon = image(icon= 'icons/mob/radial.dmi', icon_state = "delete"),
+ var/static/image/radial_image_grillewind = image(icon = 'icons/mob/radial.dmi', icon_state = "grillewindow"),
+ var/static/image/radial_image_floorwall = image(icon = 'icons/mob/radial.dmi', icon_state = "wallfloor")
+
+// Ammo for the (non-electric) RCDs.
+/obj/item/weapon/rcd_ammo
+ name = "compressed matter cartridge"
+ desc = "Highly compressed matter for the RCD."
+ icon = 'icons/obj/tools_vr.dmi'
+ icon_state = "rcdammo"
+ item_state = "rcdammo"
+ item_icons = list(
+ slot_l_hand_str = 'icons/mob/items/lefthand_vr.dmi',
+ slot_r_hand_str = 'icons/mob/items/righthand_vr.dmi',
+ )
+
+/obj/item/weapon/rcd/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/item/weapon/rcd/consume_resources(amount)
+ . = ..()
+ update_icon()
+
+/obj/item/weapon/rcd/update_icon()
+ var/nearest_ten = round((stored_matter/max_stored_matter)*10, 1)
+
+ //Just to prevent updates every use
+ if(ammostate == nearest_ten)
+ return //No change
+ ammostate = nearest_ten
+
+ cut_overlays()
+
+ //Main sprite update
+ if(!nearest_ten)
+ icon_state = "[initial(icon_state)]_empty"
+ else
+ icon_state = "[initial(icon_state)]"
+
+ add_overlay("[initial(icon_state)]_charge[nearest_ten]")
+
+/obj/item/weapon/rcd/proc/perform_effect(var/atom/A, var/time_taken)
+ effects[A] = new /obj/effect/constructing_effect(get_turf(A), time_taken, modes[mode_index])
+
+/obj/item/weapon/rcd/use_rcd(atom/A, mob/living/user)
+ . = ..()
+ cleanup_effect(A)
+
+/obj/item/weapon/rcd/proc/cleanup_effect(var/atom/A)
+ if(A in effects)
+ qdel(effects[A])
+ effects -= A
+
+/obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user)
+ if(istype(W, /obj/item/weapon/rcd_ammo))
+ var/obj/item/weapon/rcd_ammo/cartridge = W
+ var/can_store = min(max_stored_matter - stored_matter, cartridge.remaining)
+ if(can_store <= 0)
+ to_chat(user, span("warning", "There's either no space or \the [cartridge] is empty!"))
+ return FALSE
+ stored_matter += can_store
+ cartridge.remaining -= can_store
+ if(!cartridge.remaining)
+ to_chat(user, span("warning", "\The [cartridge] dissolves as it empties of compressed matter."))
+ user.drop_from_inventory(W)
+ qdel(W)
+ playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
+ to_chat(user, span("notice", "The RCD now holds [stored_matter]/[max_stored_matter] matter-units."))
+ update_icon()
+ return TRUE
+ return ..()
+
+/obj/item/weapon/rcd/proc/check_menu(mob/living/user)
+ if(!istype(user))
+ return FALSE
+ if(user.incapacitated() || !user.Adjacent(src))
+ return FALSE
+ return TRUE
+
+/obj/item/weapon/rcd/attack_self(mob/living/user)
+ ..()
+ var/list/choices = list(
+ "Airlock" = radial_image_airlock,
+ "Deconstruct" = radial_image_decon,
+ "Grilles & Windows" = radial_image_grillewind,
+ "Floors & Walls" = radial_image_floorwall
+ )
+ /* We don't have these features yet
+ if(upgrade & RCD_UPGRADE_FRAMES)
+ choices += list(
+ "Machine Frames" = image(icon = 'icons/mob/radial.dmi', icon_state = "machine"),
+ "Computer Frames" = image(icon = 'icons/mob/radial.dmi', icon_state = "computer_dir"),
+ )
+ if(upgrade & RCD_UPGRADE_SILO_LINK)
+ choices += list(
+ "Silo Link" = image(icon = 'icons/obj/mining.dmi', icon_state = "silo"),
+ )
+ if(mode == RCD_AIRLOCK)
+ choices += list(
+ "Change Access" = image(icon = 'icons/mob/radial.dmi', icon_state = "access"),
+ "Change Airlock Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlocktype")
+ )
+ else if(mode == RCD_WINDOWGRILLE)
+ choices += list(
+ "Change Window Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "windowtype")
+ )
+ */
+ var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
+ if(!check_menu(user))
+ return
+ switch(choice)
+ if("Floors & Walls")
+ mode_index = modes.Find(RCD_FLOORWALL)
+ if("Airlock")
+ mode_index = modes.Find(RCD_AIRLOCK)
+ if("Deconstruct")
+ mode_index = modes.Find(RCD_DECONSTRUCT)
+ if("Grilles & Windows")
+ mode_index = modes.Find(RCD_WINDOWGRILLE)
+ /* We don't have these features yet
+ if("Machine Frames")
+ mode = RCD_MACHINE
+ if("Computer Frames")
+ mode = RCD_COMPUTER
+ change_computer_dir(user)
+ return
+ if("Change Access")
+ change_airlock_access(user)
+ return
+ if("Change Airlock Type")
+ change_airlock_setting(user)
+ return
+ if("Change Window Type")
+ toggle_window_type(user)
+ return
+ if("Silo Link")
+ toggle_silo_link(user)
+ return
+ */
+ else
+ return
+ playsound(src, 'sound/effects/pop.ogg', 50, FALSE)
+ to_chat(user, "You change RCD's mode to '[choice]'.")
+
+//////////////////
+/obj/item/weapon/rcd/electric/update_icon()
+ return
+
+/obj/item/weapon/rcd/shipwright
+ icon_state = "swrcd"
+ item_state = "ircd"
+ can_remove_rwalls = TRUE
+ make_rwalls = TRUE
+
+//////////////////
+/obj/item/weapon/rcd_ammo/examine(mob/user)
+ . = ..()
+ . += display_resources()
+
+// Used to show how much stuff (matter units, cell charge, etc) is left inside.
+/obj/item/weapon/rcd_ammo/proc/display_resources()
+ return "It currently holds [remaining]/[initial(remaining)] matter-units."
+
+//////////////////
+/obj/effect/constructing_effect
+ icon = 'icons/effects/effects_rcd.dmi'
+ icon_state = ""
+ plane = TURF_PLANE
+ layer = ABOVE_TURF_LAYER
+ anchored = TRUE
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ var/status = 0
+ var/delay = 0
+
+/obj/effect/constructing_effect/Initialize(mapload, rcd_delay, rcd_status)
+ . = ..()
+ status = rcd_status
+ delay = rcd_delay
+ if (status == RCD_DECONSTRUCT)
+ addtimer(CALLBACK(src, /atom/.proc/update_icon), 11)
+ delay -= 11
+ icon_state = "rcd_end_reverse"
+ else
+ update_icon()
+
+/obj/effect/constructing_effect/update_icon()
+ icon_state = "rcd"
+ if (delay < 10)
+ icon_state += "_shortest"
+ else if (delay < 20)
+ icon_state += "_shorter"
+ else if (delay < 37)
+ icon_state += "_short"
+ if (status == RCD_DECONSTRUCT)
+ icon_state += "_reverse"
+
+/obj/effect/constructing_effect/proc/end_animation()
+ if (status == RCD_DECONSTRUCT)
+ qdel(src)
+ else
+ icon_state = "rcd_end"
+ addtimer(CALLBACK(src, .proc/end), 15)
+
+/obj/effect/constructing_effect/proc/end()
+ qdel(src)
diff --git a/code/game/objects/items/weapons/RPD_vr.dm b/code/game/objects/items/weapons/RPD_vr.dm
new file mode 100644
index 0000000000..c627956d63
--- /dev/null
+++ b/code/game/objects/items/weapons/RPD_vr.dm
@@ -0,0 +1,377 @@
+#define PAINT_MODE -2
+#define EATING_MODE -1
+#define ATMOS_MODE 0
+#define DISPOSALS_MODE 1
+#define TRANSIT_MODE 2
+
+/obj/item/weapon/pipe_dispenser
+ name = "Rapid Piping Device (RPD)"
+ desc = "A device used to rapidly pipe things."
+ icon = 'icons/obj/tools_vr.dmi'
+ icon_state = "rpd"
+ item_state = "rpd"
+ item_icons = list(
+ slot_l_hand_str = 'icons/mob/items/lefthand_vr.dmi',
+ slot_r_hand_str = 'icons/mob/items/righthand_vr.dmi',
+ )
+ flags = NOBLUDGEON
+ force = 10
+ throwforce = 10
+ throw_speed = 1
+ throw_range = 5
+ w_class = ITEMSIZE_NORMAL
+ matter = list(MAT_STEEL = 50000, MAT_GLASS = 25000)
+ var/datum/effect/effect/system/spark_spread/spark_system
+ var/mode = ATMOS_MODE
+ var/p_dir = NORTH // Next pipe will be built with this dir
+ var/p_flipped = FALSE // If the next pipe should be built flipped
+ var/paint_color = "grey" // Pipe color index for next pipe painted/built.
+ var/screen = ATMOS_MODE // Starts on the atmos tab.
+ var/piping_layer = PIPING_LAYER_DEFAULT
+ var/wrench_mode = FALSE
+ var/obj/item/weapon/tool/wrench/tool
+ var/datum/pipe_recipe/recipe // pipe recipie selected for display/construction
+ var/static/datum/pipe_recipe/first_atmos
+ var/static/datum/pipe_recipe/first_disposal
+ var/static/datum/asset/iconsheet/pipes/icon_assets
+ var/static/list/pipe_layers = list(
+ "Regular" = PIPING_LAYER_REGULAR,
+ "Supply" = PIPING_LAYER_SUPPLY,
+ "Scrubber" = PIPING_LAYER_SCRUBBER,
+ "Fuel" = PIPING_LAYER_FUEL,
+ "Aux" = PIPING_LAYER_AUX
+ )
+
+/obj/item/weapon/pipe_dispenser/Initialize()
+ . = ..()
+ src.spark_system = new /datum/effect/effect/system/spark_spread
+ spark_system.set_up(5, 0, src)
+ spark_system.attach(src)
+ tool = new /obj/item/weapon/tool/wrench/cyborg(src) // RPDs have wrenches inside of them, so that they can wrench down spawned pipes without being used as superior wrenches themselves.
+
+/obj/item/weapon/pipe_dispenser/proc/SetupPipes()
+ if(!first_atmos)
+ first_atmos = atmos_pipe_recipes[atmos_pipe_recipes[1]][1]
+ recipe = first_atmos
+ if(!first_disposal)
+ first_disposal = disposal_pipe_recipes[disposal_pipe_recipes[1]][1]
+
+/obj/item/weapon/pipe_dispenser/Destroy()
+ qdel_null(spark_system)
+ qdel_null(tool)
+ return ..()
+
+/obj/item/weapon/pipe_dispenser/suicide_act(mob/user)
+ var/datum/gender/TU = gender_datums[user.get_visible_gender()]
+ user.visible_message("[user] points the end of the RPD down [TU.his] throat and presses a button! It looks like [TU.hes] trying to commit suicide...")
+ playsound(get_turf(user), 'sound/machines/click.ogg', 50, 1)
+ playsound(get_turf(user), 'sound/items/deconstruct.ogg', 50, 1)
+ return(BRUTELOSS)
+
+/obj/item/weapon/pipe_dispenser/attack_self(mob/user)
+ src.interact(user)
+
+// TODO - Wouldn't it be nice to have nanoui?
+/obj/item/weapon/pipe_dispenser/interact(mob/user)
+ SetupPipes()
+ if(!icon_assets)
+ icon_assets = get_asset_datum(/datum/asset/iconsheet/pipes)
+ icon_assets.send(user)
+
+ var/list/lines = list()
+ if(mode >= ATMOS_MODE)
+ lines += "Direction:
"
+ switch(recipe.dirtype)
+
+ if(PIPE_STRAIGHT) // Straight, N-S, W-E
+ lines += render_dir_img(recipe.icon_state,user,NORTH,"Vertical","↕")
+ lines += render_dir_img(recipe.icon_state,user,EAST,"Horizontal","↔")
+
+ if(PIPE_BENDABLE) // Bent, N-W, N-E etc
+ lines += render_dir_img(recipe.icon_state,user,NORTH,"Vertical","↕")
+ lines += render_dir_img(recipe.icon_state,user,EAST,"Horizontal","↔")
+ lines += "
"
+ lines += render_dir_img(recipe.icon_state,user,NORTHWEST,"West to North","╝")
+ lines += render_dir_img(recipe.icon_state,user,NORTHEAST,"North to East","╚")
+ lines += render_dir_img(recipe.icon_state,user,SOUTHWEST,"South to West","╗")
+ lines += render_dir_img(recipe.icon_state,user,SOUTHEAST,"East to South","╔")
+
+ if(PIPE_TRINARY) // Manifold
+ lines += render_dir_img(recipe.icon_state,user,NORTH,"West South East","╦")
+ lines += render_dir_img(recipe.icon_state,user,EAST,"North West South","╣")
+ lines += render_dir_img(recipe.icon_state,user,SOUTH,"East North West","╩")
+ lines += render_dir_img(recipe.icon_state,user,WEST,"South East North","╠")
+
+ if(PIPE_TRIN_M) // Mirrored ones
+ //each mirror icon is 45 anticlockwise from it's real direction
+ lines += render_dir_img(recipe.icon_state,user,NORTH,"West South East","╦")
+ lines += render_dir_img(recipe.icon_state,user,EAST,"North West South","╣")
+ lines += render_dir_img(recipe.icon_state,user,SOUTH,"East North West","╩")
+ lines += render_dir_img(recipe.icon_state,user,WEST,"South East North","╠")
+ lines += "
"
+ lines += render_dir_img(recipe.icon_state_m,user,SOUTH,"West South East","╦", 1)
+ lines += render_dir_img(recipe.icon_state_m,user,WEST,"South East North","╠", 1)
+ lines += render_dir_img(recipe.icon_state_m,user,NORTH,"East North West","╩", 1)
+ lines += render_dir_img(recipe.icon_state_m,user,EAST,"North West South","╣", 1)
+
+ if(PIPE_DIRECTIONAL) // Stuff with four directions - includes pumps etc.
+ lines += render_dir_img(recipe.icon_state,user,NORTH,"North","↑")
+ lines += render_dir_img(recipe.icon_state,user,EAST,"East","→")
+ lines += render_dir_img(recipe.icon_state,user,SOUTH,"South","↓")
+ lines += render_dir_img(recipe.icon_state,user,WEST,"West","←")
+
+ if(PIPE_ONEDIR) // Single icon_state (eg 4-way manifolds)
+ lines += render_dir_img(recipe.icon_state,user,SOUTH,"Pipe","↕")
+ lines += "
"
+
+ if(mode == ATMOS_MODE || mode == PAINT_MODE)
+ lines += "Color:
"
+ var/i = 0
+ for(var/c in pipe_colors)
+ ++i
+ lines += "
[c]"
+ if(i == 4)
+ lines += "
"
+ i = 0
+ lines += "
"
+
+ lines += ""
+
+ lines += ""
+
+ if(screen == ATMOS_MODE)
+ for(var/category in atmos_pipe_recipes)
+ lines += "[category]:
"
+
+ if(category == "Pipes")
+ lines += "
"
+ for(var/pipename in pipe_layers)
+ var/pipelayer = pipe_layers[pipename]
+ lines += "
[pipename] "
+ lines += "
"
+ lines += "
"
+ for(var/i in 1 to atmos_pipe_recipes[category].len)
+ var/datum/pipe_recipe/PI = atmos_pipe_recipes[category][i]
+ lines += "
"
+ lines += "
"
+ else if(screen == DISPOSALS_MODE)
+ for(var/category in disposal_pipe_recipes)
+ lines += "[category]:
"
+ for(var/i in 1 to disposal_pipe_recipes[category].len)
+ var/datum/pipe_recipe/PI = disposal_pipe_recipes[category][i]
+ lines += "
"
+ lines += "
"
+
+ var/dat = lines.Join()
+ var/datum/browser/popup = new(user, "rpd", name, 300, 800, src)
+ popup.set_content("[dat]")
+ popup.add_head_content(icon_assets.css_tag())
+ popup.open()
+
+/obj/item/weapon/pipe_dispenser/Topic(href, href_list, state = global.inventory_state)
+ SetupPipes()
+ if(..())
+ return 1
+ if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
+ return 1
+ var/playeffect = TRUE // Do we spark the device
+ var/anyclicked = FALSE // Tells us if we need to refresh the window.
+ if(href_list["paint_color"])
+ paint_color = href_list["paint_color"]
+ playeffect = FALSE
+ anyclicked = TRUE
+ if(href_list["mode"])
+ mode = text2num(href_list["mode"])
+ anyclicked = TRUE
+ if(href_list["screen"])
+ if(mode == screen)
+ mode = text2num(href_list["screen"])
+ screen = text2num(href_list["screen"])
+ switch(screen)
+ if(DISPOSALS_MODE)
+ recipe = first_disposal
+ if(ATMOS_MODE)
+ recipe = first_atmos
+ p_dir = NORTH
+ playeffect = FALSE
+ anyclicked = TRUE
+ if(href_list["piping_layer"])
+ piping_layer = text2num(href_list["piping_layer"])
+ playeffect = FALSE
+ anyclicked = TRUE
+ if(href_list["pipe_type"])
+ recipe = all_pipe_recipes[href_list["category"]][text2num(href_list["pipe_type"])]
+ if(recipe.dirtype == PIPE_ONEDIR) // One hell of a hack for the fact that the image previews for the onedir types only show on the south, but the default pipe type is north.
+ p_dir = SOUTH // Did I fuck this up? Maybe. Or maybe it's just the icon files not being ready for an RPD.
+ else // If going to try and fix this hack, be aware the pipe dispensers might rely on pipes defaulting south instead of north.
+ p_dir = NORTH
+ p_flipped = FALSE
+ anyclicked = TRUE
+ if(href_list["dir"])
+ p_dir = text2dir(href_list["dir"])
+ p_flipped = text2num(href_list["flipped"])
+ playeffect = FALSE
+ anyclicked = TRUE
+ if(href_list["switch_wrench"])
+ wrench_mode = text2num(href_list["wrench_mode"])
+ anyclicked = TRUE
+ if(anyclicked)
+ if(playeffect)
+ spark_system.start()
+ playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
+ src.interact(usr)
+
+/obj/item/weapon/pipe_dispenser/afterattack(atom/A, mob/user as mob, proximity)
+ if(!user.IsAdvancedToolUser() || istype(A, /turf/space/transit) || !proximity)
+ return ..()
+
+ //So that changing the menu settings doesn't affect the pipes already being built.
+ var/queued_piping_layer = piping_layer
+ var/queued_p_dir = p_dir
+ var/queued_p_flipped = p_flipped
+
+ //make sure what we're clicking is valid for the current mode
+ var/static/list/make_pipe_whitelist // This should probably be changed to be in line with polaris standards. Oh well.
+ if(!make_pipe_whitelist)
+ make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe))
+ var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist))
+
+ . = FALSE
+ switch(mode) //if we've gotten this var, the target is valid
+ if(PAINT_MODE) //Paint pipes
+ if(!istype(A, /obj/machinery/atmospherics/pipe))
+ return ..()
+ var/obj/machinery/atmospherics/pipe/P = A
+ playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
+ P.change_color(pipe_colors[paint_color])
+ user.visible_message("[user] paints \the [P] [paint_color].", "You paint \the [P] [paint_color].")
+ return
+
+ if(EATING_MODE) //Eating pipes
+ if(!(istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct)))
+ return ..()
+ to_chat(user, "You start destroying a pipe...")
+ playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
+ if(do_after(user, 2, target = A))
+ activate()
+ animate_deletion(A)
+
+ if(ATMOS_MODE) //Making pipes
+ if(!can_make_pipe)
+ return ..()
+ playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
+ if (istype(recipe, /datum/pipe_recipe/meter))
+ to_chat(user, "You start building a meter...")
+ if(do_after(user, 2, target = A))
+ activate()
+ var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A))
+ PM.setAttachLayer(queued_piping_layer)
+ if(wrench_mode)
+ do_wrench(PM, user)
+ else if(istype(recipe, /datum/pipe_recipe/pipe))
+ var/datum/pipe_recipe/pipe/R = recipe
+ to_chat(user, "You start building a pipe...")
+ if(do_after(user, 2, target = A))
+ activate()
+ var/obj/machinery/atmospherics/path = R.pipe_type
+ var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe
+ var/obj/item/pipe/P = new pipe_item_type(get_turf(A), path, queued_p_dir)
+
+ P.update()
+ P.add_fingerprint(usr)
+ if (R.paintable)
+ P.color = pipe_colors[paint_color]
+ P.setPipingLayer(queued_piping_layer)
+ if(queued_p_flipped)
+ P.do_a_flip()
+ if(wrench_mode)
+ do_wrench(P, user)
+ else
+ build_effect(P)
+
+ if(DISPOSALS_MODE) //Making disposals pipes
+ var/datum/pipe_recipe/disposal/R = recipe
+ if(!istype(R) || !can_make_pipe)
+ return ..()
+ A = get_turf(A)
+ if(istype(A, /turf/unsimulated))
+ to_chat(user, "[src]'s error light flickers; there's something in the way!")
+ return
+ to_chat(user, "You start building a disposals pipe...")
+ playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
+ if(do_after(user, 4, target = A))
+ var/obj/structure/disposalconstruct/C = new(A, R.pipe_type, queued_p_dir, queued_p_flipped, R.subtype)
+
+ if(!C.can_place())
+ to_chat(user, "There's not enough room to build that here!")
+ qdel(C)
+ return
+
+ activate()
+
+ C.add_fingerprint(usr)
+ C.update_icon()
+ if(wrench_mode)
+ do_wrench(C, user)
+ else
+ build_effect(C)
+
+ else
+ return ..()
+
+/obj/item/weapon/pipe_dispenser/proc/build_effect(var/obj/P, var/time = 1.5)
+ set waitfor = FALSE
+ P.filters += filter(type = "angular_blur", size = 30)
+ animate(P.filters[P.filters.len], size = 0, time = time)
+ var/outline = filter(type = "outline", size = 1, color = "#22AAFF")
+ P.filters += outline
+ sleep(time)
+ P.filters -= outline
+ P.filters -= filter(type = "angular_blur", size = 0)
+
+/obj/item/weapon/pipe_dispenser/proc/animate_deletion(var/obj/P, var/time = 1.5)
+ set waitfor = FALSE
+ P.filters += filter(type = "angular_blur", size = 0)
+ animate(P.filters[P.filters.len], size = 30, time = time)
+ sleep(time)
+ if(!QDELETED(P))
+ P.filters -= filter(type = "angular_blur", size = 30)
+ qdel(P)
+
+/obj/item/weapon/pipe_dispenser/proc/activate()
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
+
+/obj/item/weapon/pipe_dispenser/proc/do_wrench(var/atom/target, mob/user)
+ var/resolved = target.attackby(tool,user)
+ if(!resolved && tool && target)
+ tool.afterattack(target,user,1)
+
+/obj/item/weapon/pipe_dispenser/proc/render_dir_img(icon_state, user, _dir, title, noimg, flipped = FALSE)
+ var/dirtext = dir2text(_dir)
+ var/attrs = " style=\"height:34px;width:34px;display:inline-block\""
+ if(_dir == p_dir && flipped == p_flipped)
+ attrs += " class=\"linkOn\""
+ if(icon_state)
+ var/img_tag = icon_assets.icon_tag(icon_state, _dir)
+ return "[img_tag]"
+ else
+ return "[noimg]"
+
+
+#undef PAINT_MODE
+#undef EATING_MODE
+#undef ATMOS_MODE
+#undef DISPOSALS_MODE
diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm
index 8684a9c058..b8eded77c6 100644
--- a/code/game/objects/items/weapons/RSF.dm
+++ b/code/game/objects/items/weapons/RSF.dm
@@ -8,8 +8,8 @@ RSF
name = "\improper Rapid-Service-Fabricator"
desc = "A device used to rapidly deploy service items."
description_info = "Control Clicking on the device will allow you to choose the glass it dispenses when in the proper mode."
- icon = 'icons/obj/tools.dmi'
- icon_state = "rcd"
+ icon = 'icons/obj/tools_vr.dmi' //VOREStation Edit
+ icon_state = "rsf" //VOREStation Edit
opacity = 0
density = 0
anchored = 0.0
@@ -33,8 +33,9 @@ RSF
w_class = ITEMSIZE_NORMAL
/obj/item/weapon/rsf/examine(mob/user)
- if(..(user, 0))
- to_chat(user,"It currently holds [stored_matter]/30 fabrication-units.")
+ . = ..()
+ if(get_dist(user, src) == 0)
+ . += "It currently holds [stored_matter]/30 fabrication-units."
/obj/item/weapon/rsf/attackby(obj/item/weapon/W as obj, 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 f3df3c914b..ffa3753233 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -149,22 +149,21 @@ CIGARETTE PACKETS ARE IN FANCY.DM
..()
/obj/item/clothing/mask/smokable/examine(mob/user)
- ..()
- if(is_pipe)
- return
- var/smoke_percent = round((smoketime / max_smoketime) * 100)
- switch(smoke_percent)
- if(90 to INFINITY)
- to_chat(user, "[src] is still fresh.")
- if(60 to 90)
- to_chat(user, "[src] has a good amount of burn time remaining.")
- if(30 to 60)
- to_chat(user, "[src] is about half finished.")
- if(10 to 30)
- to_chat(user, "[src] is starting to burn low.")
- else
- to_chat(user, "[src] is nearly burnt out!")
-
+ . = ..()
+
+ if(!is_pipe)
+ var/smoke_percent = round((smoketime / max_smoketime) * 100)
+ switch(smoke_percent)
+ if(90 to INFINITY)
+ . += "[src] is still fresh."
+ if(60 to 90)
+ . += "[src] has a good amount of burn time remaining."
+ if(30 to 60)
+ . += "[src] is about half finished."
+ if(10 to 30)
+ . += "[src] is starting to burn low."
+ else
+ . += "[src] is nearly burnt out!"
/obj/item/clothing/mask/smokable/proc/light(var/flavor_text = "[usr] lights the [name].")
if(!src.lit)
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/power.dm b/code/game/objects/items/weapons/circuitboards/machinery/power.dm
index 9bd5f98bad..e874d04d49 100644
--- a/code/game/objects/items/weapons/circuitboards/machinery/power.dm
+++ b/code/game/objects/items/weapons/circuitboards/machinery/power.dm
@@ -18,14 +18,7 @@
build_path = /obj/machinery/power/smes/batteryrack
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 2)
- req_components = list(/obj/item/weapon/cell = 3)
-
-/obj/item/weapon/circuitboard/ghettosmes
- name = T_BOARD("makeshift PSU")
- desc = "An APC circuit repurposed into some power storage device controller"
- build_path = /obj/machinery/power/smes/batteryrack/makeshift
- board_type = new /datum/frame/frame_types/machine
- req_components = list(/obj/item/weapon/cell = 3)
+ req_components = list(/obj/item/weapon/stock_parts/capacitor/ = 3, /obj/item/weapon/stock_parts/matter_bin/ = 1)
/obj/item/weapon/circuitboard/grid_checker
name = T_BOARD("power grid checker")
diff --git a/code/game/objects/items/weapons/ecigs.dm b/code/game/objects/items/weapons/ecigs.dm
new file mode 100644
index 0000000000..29ae810f9f
--- /dev/null
+++ b/code/game/objects/items/weapons/ecigs.dm
@@ -0,0 +1,227 @@
+/obj/item/clothing/mask/smokable/ecig
+ name = "electronic cigarette"
+ desc = "Device with modern approach to smoking."
+ icon = 'icons/obj/ecig.dmi'
+ var/active = 0
+ //var/obj/item/weapon/cell/ec_cell = /obj/item/weapon/cell/device
+ var/cartridge_type = /obj/item/weapon/reagent_containers/ecig_cartridge/med_nicotine
+ var/obj/item/weapon/reagent_containers/ecig_cartridge/ec_cartridge
+ w_class = ITEMSIZE_TINY
+ slot_flags = SLOT_EARS | SLOT_MASK
+ attack_verb = list("attacked", "poked", "battered")
+ body_parts_covered = 0
+ var/brightness_on = 1
+ chem_volume = 0 //ecig has no storage on its own but has reagent container created by parent obj
+ item_state = "ecigoff"
+ var/icon_off
+ var/icon_empty
+ var/ecig_colors = list(null, COLOR_DARK_GRAY, COLOR_RED_GRAY, COLOR_BLUE_GRAY, COLOR_GREEN_GRAY, COLOR_PURPLE_GRAY)
+
+/obj/item/clothing/mask/smokable/ecig/New()
+ ..()
+ ec_cartridge = new cartridge_type(src)
+
+/obj/item/clothing/mask/smokable/ecig/simple
+ name = "simple electronic cigarette"
+ desc = "A cheap Lucky 1337 electronic cigarette, styled like a traditional cigarette."
+ icon_state = "ccigoff"
+ icon_off = "ccigoff"
+ icon_empty = "ccigoff"
+ icon_on = "ccigon"
+
+/obj/item/clothing/mask/smokable/ecig/util
+ name = "electronic cigarette"
+ desc = "A popular utilitarian model electronic cigarette, the ONI-55. Comes in a variety of colors."
+ icon_state = "ecigoff1"
+ icon_off = "ecigoff1"
+ icon_empty = "ecigoff1"
+ icon_on = "ecigon"
+/obj/item/clothing/mask/smokable/ecig/util/New()
+ ..()
+ color = pick(ecig_colors)
+
+/obj/item/clothing/mask/smokable/ecig/deluxe
+ name = "deluxe electronic cigarette"
+ desc = "A premium model eGavana MK3 electronic cigarette, shaped like a cigar."
+ icon_state = "pcigoff1"
+ icon_off = "pcigoff1"
+ icon_empty = "pcigoff2"
+ icon_on = "pcigon"
+
+/obj/item/clothing/mask/smokable/ecig/process()
+ if(ishuman(loc))
+ var/mob/living/carbon/human/C = loc
+ if (src == C.wear_mask && C.check_has_mouth()) // if it's in the human/monkey mouth, transfer reagents to the mob
+ if (!active || !ec_cartridge || !ec_cartridge.reagents.total_volume)//no cartridge
+ active=0//autodisable the cigarette
+ STOP_PROCESSING(SSobj, src)
+ update_icon()
+ return
+ ec_cartridge.reagents.trans_to_mob(C, REM, CHEM_INGEST, 0.4) // Most of it is not inhaled... balance reasons.
+
+/obj/item/clothing/mask/smokable/ecig/update_icon()
+ if (active)
+ item_state = icon_on
+ icon_state = icon_on
+ set_light(brightness_on)
+ else if (ec_cartridge)
+ set_light(0)
+ item_state = icon_off
+ icon_state = icon_off
+ else
+ icon_state = icon_empty
+ item_state = icon_empty
+ set_light(0)
+ if(ismob(loc))
+ var/mob/living/M = loc
+ M.update_inv_wear_mask(0)
+ M.update_inv_l_hand(0)
+ M.update_inv_r_hand(1)
+
+
+/obj/item/clothing/mask/smokable/ecig/attackby(var/obj/item/I, var/mob/user as mob)
+ if(istype(I, /obj/item/weapon/reagent_containers/ecig_cartridge))
+ if (ec_cartridge)//can't add second one
+ to_chat(user, "A cartridge has already been installed. ")
+ else//fits in new one
+ user.remove_from_mob(I)
+ I.forceMove(src)//I.loc=src
+ ec_cartridge = I
+ update_icon()
+ to_chat(user, "You insert [I] into [src]. ")
+
+/obj/item/clothing/mask/smokable/ecig/attack_self(mob/user as mob)
+ if (active)
+ active=0
+ STOP_PROCESSING(SSobj, src)
+ to_chat(user, "You turn off \the [src]. ")
+ update_icon()
+ else
+ if (!ec_cartridge)
+ to_chat(user, "You can't use it with no cartridge installed!. ")
+ return
+ active=1
+ START_PROCESSING(SSobj, src)
+ to_chat(user, "You turn on \the [src]. ")
+ update_icon()
+
+/obj/item/clothing/mask/smokable/ecig/attack_hand(mob/user as mob)//eject cartridge
+ if(user.get_inactive_hand() == src)//if being hold
+ if (ec_cartridge)
+ active=0
+ user.put_in_hands(ec_cartridge)
+ to_chat(user, "You eject [ec_cartridge] from \the [src]. ")
+ ec_cartridge = null
+ update_icon()
+ else
+ ..()
+
+/obj/item/weapon/reagent_containers/ecig_cartridge
+ name = "tobacco flavour cartridge"
+ desc = "A small metal cartridge, used with electronic cigarettes, which contains an atomizing coil and a solution to be atomized."
+ w_class = ITEMSIZE_TINY
+ icon = 'icons/obj/ecig.dmi'
+ icon_state = "ecartridge"
+ matter = list("metal" = 50, "glass" = 10)
+ volume = 20
+ flags = OPENCONTAINER
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/New()
+ create_reagents(volume)
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/examine(mob/user as mob)//to see how much left
+ . = ..()
+ . += "The cartridge has [reagents.total_volume] units of liquid remaining."
+
+//flavours
+/obj/item/weapon/reagent_containers/ecig_cartridge/blank
+ name = "ecigarette cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil."
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/blanknico
+ name = "flavorless nicotine cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says you can add whatever flavoring agents you want."
+/obj/item/weapon/reagent_containers/ecig_cartridge/blanknico/New()
+ ..()
+ reagents.add_reagent("nicotine", 5)
+ reagents.add_reagent("water", 10)
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/med_nicotine
+ name = "tobacco flavour cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its tobacco flavored."
+/obj/item/weapon/reagent_containers/ecig_cartridge/med_nicotine/New()
+ ..()
+ reagents.add_reagent("nicotine", 5)
+ reagents.add_reagent("water", 15)
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/high_nicotine
+ name = "high nicotine tobacco flavour cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its tobacco flavored, with extra nicotine."
+/obj/item/weapon/reagent_containers/ecig_cartridge/high_nicotine/New()
+ ..()
+ reagents.add_reagent("nicotine", 10)
+ reagents.add_reagent("water", 10)
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/orange
+ name = "orange flavour cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its orange flavored."
+/obj/item/weapon/reagent_containers/ecig_cartridge/orange/New()
+ ..()
+ reagents.add_reagent("nicotine", 5)
+ reagents.add_reagent("water", 10)
+ reagents.add_reagent("orangejuice", 5)
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/mint
+ name = "mint flavour cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its mint flavored."
+/obj/item/weapon/reagent_containers/ecig_cartridge/mint/New()
+ ..()
+ reagents.add_reagent("nicotine", 5)
+ reagents.add_reagent("water", 10)
+ reagents.add_reagent("menthol", 5)
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/watermelon
+ name = "watermelon flavour cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its watermelon flavored."
+/obj/item/weapon/reagent_containers/ecig_cartridge/watermelon/New()
+ ..()
+ reagents.add_reagent("nicotine", 5)
+ reagents.add_reagent("water", 10)
+ reagents.add_reagent("watermelonjuice", 5)
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/grape
+ name = "grape flavour cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its grape flavored."
+/obj/item/weapon/reagent_containers/ecig_cartridge/grape/New()
+ ..()
+ reagents.add_reagent("nicotine", 5)
+ reagents.add_reagent("water", 10)
+ reagents.add_reagent("grapejuice", 5)
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/lemonlime
+ name = "lemon-lime flavour cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its lemon-lime flavored."
+/obj/item/weapon/reagent_containers/ecig_cartridge/lemonlime/New()
+ ..()
+ reagents.add_reagent("nicotine", 5)
+ reagents.add_reagent("water", 10)
+ reagents.add_reagent("lemon_lime", 5)
+
+/obj/item/weapon/reagent_containers/ecig_cartridge/coffee
+ name = "coffee flavour cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label says its coffee flavored."
+/obj/item/weapon/reagent_containers/ecig_cartridge/coffee/New()
+ ..()
+ reagents.add_reagent("nicotine", 5)
+ reagents.add_reagent("water", 10)
+ reagents.add_reagent("coffee", 5)
+/*
+/obj/item/weapon/reagent_containers/ecig_cartridge/cannabis
+ name = "herb flavour cartridge"
+ desc = "A small metal cartridge which contains an atomizing coil and a solution to be atomized. The label seems to be suspiciously scuffed off..."
+/obj/item/weapon/reagent_containers/ecig_cartridge/cannabis/New()
+ ..()
+ reagents.add_reagent("nicotine", 5)
+ reagents.add_reagent("water", 10)
+ reagents.add_reagent("cannabis", 5)
+*/
diff --git a/code/game/objects/items/weapons/explosives_vr.dm b/code/game/objects/items/weapons/explosives_vr.dm
index a82ca02bbc..ce7a182fd6 100644
--- a/code/game/objects/items/weapons/explosives_vr.dm
+++ b/code/game/objects/items/weapons/explosives_vr.dm
@@ -8,7 +8,7 @@
target = src
var/turf/T = get_turf(target)
- if(T.z in using_map.map_levels)
+ if(T.z in using_map.station_levels)
target.visible_message("\The [src] lets out a loud beep as safeties trigger, before imploding and falling apart.")
target.overlays -= image_overlay
qdel(src)
diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm
index f44abcb96b..c50998557e 100644
--- a/code/game/objects/items/weapons/extinguisher.dm
+++ b/code/game/objects/items/weapons/extinguisher.dm
@@ -1,7 +1,7 @@
/obj/item/weapon/extinguisher
name = "fire extinguisher"
desc = "A traditional red fire extinguisher."
- icon = 'icons/obj/items.dmi'
+ icon = 'icons/obj/items_vr.dmi' //VOREStation Edit
icon_state = "fire_extinguisher0"
item_state = "fire_extinguisher"
hitsound = 'sound/weapons/smash.ogg'
@@ -36,12 +36,13 @@
/obj/item/weapon/extinguisher/Initialize()
create_reagents(max_water)
- reagents.add_reagent("water", max_water)
+ reagents.add_reagent("firefoam", max_water) //VOREStation Edit
. = ..()
/obj/item/weapon/extinguisher/examine(mob/user)
- if(..(user, 0))
- to_chat(user, "[bicon(src)] [src.name] contains [src.reagents.total_volume] units of water left!")
+ . = ..()
+ if(get_dist(user, src) == 0)
+ . += "[src] has [src.reagents.total_volume] units of foam left!" //VOREStation Edit - Foam not water
/obj/item/weapon/extinguisher/attack_self(mob/user as mob)
safety = !safety
@@ -70,7 +71,7 @@
/obj/item/weapon/extinguisher/afterattack(var/atom/target, var/mob/user, var/flag)
//TODO; Add support for reagents in water.
- if( istype(target, /obj/structure/reagent_dispensers/watertank) && flag)
+ if( istype(target, /obj/structure/reagent_dispensers) && flag) //VOREStation Edit
var/obj/o = target
var/amount = o.reagents.trans_to_obj(src, 50)
to_chat(user, "You fill [src] with [amount] units of the contents of [target].")
diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm
index 27c917df28..94ca8b7cd2 100644
--- a/code/game/objects/items/weapons/gift_wrappaper.dm
+++ b/code/game/objects/items/weapons/gift_wrappaper.dm
@@ -164,8 +164,9 @@
/obj/item/weapon/wrapping_paper/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "There is about [src.amount] square units of paper left!")
+ . = ..()
+ if(Adjacent(user))
+ . += "There is about [src.amount] square units of paper left!"
/obj/item/weapon/wrapping_paper/attack(mob/target as mob, mob/user as mob)
if (!istype(target, /mob/living/carbon/human)) return
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index 41fa67f1d5..157c64f09f 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -118,9 +118,9 @@
to_chat(user, "\The [W] is empty.")
/obj/item/weapon/grenade/chem_grenade/examine(mob/user)
- ..(user)
+ . = ..()
if(detonator)
- to_chat(user, "With attached [detonator.name]")
+ . += "It has [detonator.name] attached to it."
/obj/item/weapon/grenade/chem_grenade/activate(mob/user as mob)
if(active) return
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index ac24d42255..fdab7aaf39 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -45,13 +45,12 @@
/obj/item/weapon/grenade/examine(mob/user)
- if(..(user, 0))
+ . = ..()
+ if(get_dist(user, src) == 0)
if(det_time > 1)
- to_chat(user, "The timer is set to [det_time/10] seconds.")
- return
- if(det_time == null)
- return
- to_chat(user, "\The [src] is set for instant detonation.")
+ . += "The timer is set to [det_time/10] seconds."
+ else if(det_time == null)
+ . += "\The [src] is set for instant detonation."
/obj/item/weapon/grenade/attack_self(mob/user as mob)
diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm b/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm
index 56204be984..1a80762396 100644
--- a/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm
+++ b/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm
@@ -6,7 +6,7 @@
/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked/detonate()
if(locked)
var/turf/T = get_turf(src)
- if(T.z in using_map.map_levels)
+ if(T.z in using_map.station_levels)
icon_state = initial(icon_state)
active = 0
return 0
diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm
index c43217919a..5b1f6752ae 100644
--- a/code/game/objects/items/weapons/id cards/station_ids.dm
+++ b/code/game/objects/items/weapons/id cards/station_ids.dm
@@ -32,12 +32,11 @@
var/survey_points = 0 // For redeeming at explorer equipment vendors.
/obj/item/weapon/card/id/examine(mob/user)
- set src in oview(1)
- if(in_range(usr, src))
- show(usr)
- to_chat(usr,desc)
+ . = ..()
+ if(in_range(user, src))
+ show(user) //Not chat related
else
- to_chat(usr, "It is too far away.")
+ . += "It is too far away to read."
/obj/item/weapon/card/id/proc/prevent_tracking()
return 0
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index 0de385500e..34f44ffc8d 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -227,7 +227,8 @@ Implant Specifics:
"}
Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
return dat
-/obj/item/weapon/implant/explosive/hear_talk(mob/M as mob, msg)
+/obj/item/weapon/implant/explosive/hear_talk(mob/M, list/message_pieces, verb)
+ var/msg = multilingual_to_message(message_pieces)
hear(msg)
return
diff --git a/code/game/objects/items/weapons/implants/implant_vr.dm b/code/game/objects/items/weapons/implants/implant_vr.dm
index 17d1d6f6d2..133bcb48f4 100644
--- a/code/game/objects/items/weapons/implants/implant_vr.dm
+++ b/code/game/objects/items/weapons/implants/implant_vr.dm
@@ -60,12 +60,13 @@
Function: Resizes the host whenever specific verbal command is received
"}
return dat
-/obj/item/weapon/implant/sizecontrol/hear_talk(mob/M, msg)
+/obj/item/weapon/implant/sizecontrol/hear_talk(mob/M, list/message_pieces)
if(M == imp_in)
return
if(owner)
if(M != owner)
return
+ var/msg = multilingual_to_message(message_pieces)
if(findtext(msg,"ignore"))
return
var/list/replacechars = list("'" = "",">" = "","<" = "","(" = "",")" = "", "~" = "")
diff --git a/code/game/objects/items/weapons/implants/implantcircuits.dm b/code/game/objects/items/weapons/implants/implantcircuits.dm
index 7c9391c631..ffe6547fcb 100644
--- a/code/game/objects/items/weapons/implants/implantcircuits.dm
+++ b/code/game/objects/items/weapons/implants/implantcircuits.dm
@@ -36,7 +36,7 @@
IC.emp_act(severity)
/obj/item/weapon/implant/integrated_circuit/examine(mob/user)
- IC.examine(user)
+ return IC.examine(user)
/obj/item/weapon/implant/integrated_circuit/attackby(var/obj/item/O, var/mob/user)
if(O.is_crowbar() || istype(O, /obj/item/device/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || O.is_screwdriver() || istype(O, /obj/item/weapon/cell/device) )
diff --git a/code/game/objects/items/weapons/implants/implantreagent_vr.dm b/code/game/objects/items/weapons/implants/implantreagent_vr.dm
index 4597cbe0a8..5642d1bfd6 100644
--- a/code/game/objects/items/weapons/implants/implantreagent_vr.dm
+++ b/code/game/objects/items/weapons/implants/implantreagent_vr.dm
@@ -38,11 +38,12 @@
/obj/item/weapon/implant/reagent_generator/process()
var/before_gen
- if(imp_in && generated_reagents)
+ if(isliving(imp_in) && generated_reagents)
before_gen = reagents.total_volume
+ var/mob/living/L = imp_in
if(reagents.total_volume < reagents.maximum_volume)
- if(imp_in.nutrition >= gen_cost)
- do_generation()
+ if(L.nutrition >= gen_cost)
+ do_generation(L)
else
return
else
@@ -55,8 +56,8 @@
else if(reagents.total_volume == reagents.maximum_volume && before_gen < reagents.maximum_volume)
to_chat(imp_in, "[pick(full_message)]")
-/obj/item/weapon/implant/reagent_generator/proc/do_generation()
- imp_in.nutrition -= gen_cost
+/obj/item/weapon/implant/reagent_generator/proc/do_generation(var/mob/living/L)
+ L.adjust_nutrition(-gen_cost)
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent])
@@ -69,7 +70,7 @@
do_reagent_implant(usr)
/mob/living/carbon/human/proc/do_reagent_implant(var/mob/living/carbon/human/user = usr)
- if(!isliving(user) || !user.canClick())
+ if(!isliving(user) || !user.checkClickCooldown())
return
if(user.incapacitated() || user.stat > CONSCIOUS)
diff --git a/code/game/objects/items/weapons/inducer_vr.dm b/code/game/objects/items/weapons/inducer_vr.dm
new file mode 100644
index 0000000000..998447b5fa
--- /dev/null
+++ b/code/game/objects/items/weapons/inducer_vr.dm
@@ -0,0 +1,280 @@
+/obj/item/weapon/inducer
+ name = "industrial inducer"
+ desc = "A tool for inductively charging internal power cells."
+ icon = 'icons/obj/tools_vr.dmi'
+ icon_state = "inducer-engi"
+ item_state = "inducer-engi"
+ item_icons = list(
+ slot_l_hand_str = 'icons/mob/items/lefthand_vr.dmi',
+ slot_r_hand_str = 'icons/mob/items/righthand_vr.dmi',
+ )
+ force = 7
+
+ var/powertransfer = 1000 //Transfer per time when charging something
+ var/cell_type = /obj/item/weapon/cell/high //Type of cell to spawn in it
+ var/charge_guns = FALSE //Can it charge guns?
+
+ var/datum/effect/effect/system/spark_spread/spark_system
+ var/obj/item/weapon/cell/cell
+ var/recharging = FALSE
+ var/opened = FALSE
+
+/obj/item/weapon/inducer/unloaded
+ cell_type = null
+ opened = TRUE
+
+/obj/item/weapon/inducer/Initialize()
+ . = ..()
+ if(!cell && cell_type)
+ cell = new cell_type
+
+/obj/item/weapon/inducer/proc/induce(var/obj/item/weapon/cell/target, coefficient)
+ var/totransfer = min(cell.charge,(powertransfer * coefficient))
+ var/transferred = target.give(totransfer)
+ cell.use(transferred)
+ cell.update_icon()
+ target.update_icon()
+
+/obj/item/weapon/inducer/get_cell()
+ return cell
+
+/obj/item/weapon/inducer/emp_act(severity)
+ . = ..()
+ if(cell)
+ cell.emp_act(severity)
+
+/obj/item/weapon/inducer/attack(mob/living/M, mob/living/user)
+ if(user.a_intent == I_HURT)
+ return ..()
+ else
+ return 0 //No accidental bludgeons!
+
+/obj/item/weapon/inducer/afterattack(atom/A, mob/living/carbon/user, proximity)
+ if(user.a_intent == I_HURT)
+ return ..()
+
+ if(cantbeused(user))
+ return
+
+ if(recharge(A, user))
+ return
+
+ return ..()
+
+/obj/item/weapon/inducer/proc/cantbeused(mob/user)
+ if(!user.IsAdvancedToolUser())
+ to_chat(user, "You don't have the dexterity to use [src]!")
+ return TRUE
+
+ if(!cell)
+ to_chat(user, "[src] doesn't have a power cell installed!")
+ return TRUE
+
+ if(!cell.charge)
+ to_chat(user, "[src]'s battery is dead!")
+ return TRUE
+ return FALSE
+
+
+/obj/item/weapon/inducer/attackby(obj/item/W, mob/user)
+ if(W.is_screwdriver())
+ playsound(src, W.usesound, 50, 1)
+ if(!opened)
+ to_chat(user, "You open the battery compartment.")
+ opened = TRUE
+ update_icon()
+ return
+ else
+ to_chat(user, "You close the battery compartment.")
+ opened = FALSE
+ update_icon()
+ return
+ if(istype(W, /obj/item/weapon/cell))
+ if(opened)
+ if(!cell)
+ user.drop_from_inventory(W)
+ W.forceMove(src)
+ to_chat(user, "You insert [W] into [src].")
+ cell = W
+ update_icon()
+ return
+ else
+ to_chat(user, "[src] already has \a [cell] installed!")
+ return
+
+ if(cantbeused(user))
+ return
+
+ if(recharge(W, user))
+ return
+
+ return ..()
+
+/obj/item/weapon/inducer/proc/recharge(atom/movable/A, mob/user)
+ if(!isturf(A) && user.loc == A)
+ return FALSE
+ if(recharging)
+ return TRUE
+ else
+ recharging = TRUE
+
+ if(istype(A, /obj/item/weapon/gun/energy) && !charge_guns)
+ to_chat(user, "Error unable to interface with device.")
+ return FALSE
+
+ //The cell we hopefully eventually find
+ var/obj/item/weapon/cell/C
+
+ //Synthetic humanoids
+ if(ishuman(A))
+ var/mob/living/carbon/human/H = A
+ if(H.isSynthetic())
+ C = new /obj/item/weapon/cell/standin(null, H) // o o f
+
+ //Borg frienbs
+ else if(isrobot(A))
+ var/mob/living/silicon/robot/R = A
+ C = R.cell
+
+ //Can set different coefficients per item if you want
+ var/coefficient = 1
+
+ //Last ditch effort
+ var/obj/O //For updating icons, just in case they have a battery meter icon
+ if(!C && isobj(A))
+ O = A
+ C = O.get_cell()
+
+ if(C)
+ var/done_any = FALSE
+
+ if(C.charge >= C.maxcharge)
+ to_chat(user, "[A] is fully charged ([round(C.charge)] / [C.maxcharge])!")
+ recharging = FALSE
+ return TRUE
+ user.visible_message("[user] starts recharging [A] with [src].", "You start recharging [A] with [src].")
+
+ var/datum/beam/charge_beam = user.Beam(A, icon_state = "rped_upgrade", time = 20 SECONDS)
+ var/filter = filter(type = "outline", size = 1, color = "#22AAFF")
+ A.filters += filter
+
+ spark_system = new /datum/effect/effect/system/spark_spread
+ spark_system.set_up(5, 0, get_turf(A))
+ spark_system.attach(A)
+
+ while(C.charge < C.maxcharge)
+ if(do_after(user, 2 SECONDS, target = user) && cell.charge)
+ done_any = TRUE
+ induce(C, coefficient)
+ spark_system.start()
+ if(O)
+ O.update_icon()
+ else
+ break
+
+ QDEL_NULL(charge_beam)
+ QDEL_NULL(spark_system)
+ if(A)
+ A.filters -= filter
+
+ if(done_any) // Only show a message if we succeeded at least once
+ user.visible_message("[user] recharged [A]!", "You recharged [A]!")
+
+ recharging = FALSE
+ return TRUE
+ else //Couldn't find a cell
+ to_chat(user, "Error unable to interface with device.")
+
+ recharging = FALSE
+
+/obj/item/weapon/inducer/attack_self(mob/user)
+ if(opened && cell)
+ user.visible_message("[user] removes [cell] from [src]!", "You remove [cell].")
+ cell.update_icon()
+ user.put_in_hands(cell)
+ cell = null
+ update_icon()
+
+/obj/item/weapon/inducer/examine(mob/living/M)
+ . = ..()
+ if(cell)
+ . += "Its display shows: [round(cell.charge)] / [cell.maxcharge]."
+ else
+ . += "Its display is dark."
+ if(opened)
+ . += "Its battery compartment is open."
+
+/obj/item/weapon/inducer/update_icon()
+ ..()
+ cut_overlays()
+ if(opened)
+ if(!cell)
+ add_overlay("inducer-nobat")
+ else
+ add_overlay("inducer-bat")
+
+//////// Variants
+/obj/item/weapon/inducer/sci
+ name = "inducer"
+ desc = "A tool for inductively charging internal power cells. This one has a science color scheme, and is less potent than its engineering counterpart."
+ icon_state = "inducer-sci"
+ item_state = "inducer-sci"
+ cell_type = null
+ powertransfer = 500
+ opened = TRUE
+
+/obj/item/weapon/inducer/sci/Initialize()
+ . = ..()
+ update_icon() //To get the 'open' state applied
+
+/obj/item/weapon/inducer/syndicate
+ name = "suspicious inducer"
+ desc = "A tool for inductively charging internal power cells. This one has a suspicious colour scheme, and seems to be rigged to transfer charge at a much faster rate."
+ icon_state = "inducer-syndi"
+ item_state = "inducer-syndi"
+ powertransfer = 2000
+ cell_type = /obj/item/weapon/cell/super
+ charge_guns = TRUE
+
+/obj/item/weapon/inducer/hybrid
+ name = "hybrid-tech inducer"
+ desc = "A tool for inductively charging internal power cells. This one has some flashy bits and recharges devices slower, but seems to recharge itself between uses."
+ icon_state = "inducer-hybrid"
+ item_state = "inducer-hybrid"
+ powertransfer = 250
+ cell_type = /obj/item/weapon/cell/void
+ charge_guns = TRUE
+
+// A 'human stand-in' cell for recharging 'nutrition' on synthetic humans (wow this is terrible! \o/)
+#define NUTRITION_COEFF 0.05 // 1000 charge = 50 nutrition at 0.05
+/obj/item/weapon/cell/standin
+ name = "don't spawn this"
+ desc = "this is for weird code use, don't spawn it!!!"
+
+ charge = 100
+ maxcharge = 100
+
+ var/mob/living/carbon/human/hume
+
+/obj/item/weapon/cell/standin/New(newloc, var/mob/living/carbon/human/H)
+ ..()
+ hume = H
+ charge = H.nutrition
+ maxcharge = initial(H.nutrition)
+
+ QDEL_IN(src, 20 SECONDS)
+
+
+/obj/item/weapon/cell/standin/give(var/amount)
+ . = ..(amount * NUTRITION_COEFF) //Shrink amount to store
+ hume.adjust_nutrition(.) //Add the amount we really stored
+ . /= NUTRITION_COEFF //Inflate amount to take from the giver
+
+#undef NUTRITION_COEFF
+
+// Various sideways-defined get_cells
+/obj/mecha/get_cell()
+ return cell
+
+/obj/vehicle/get_cell()
+ return cell
diff --git a/code/game/objects/items/weapons/material/chainsaw.dm b/code/game/objects/items/weapons/material/chainsaw.dm
index 4a8662c053..fe99fad674 100644
--- a/code/game/objects/items/weapons/material/chainsaw.dm
+++ b/code/game/objects/items/weapons/material/chainsaw.dm
@@ -113,9 +113,9 @@ obj/item/weapon/chainsaw/proc/get_fuel()
return reagents.get_reagent_amount("fuel")
obj/item/weapon/chainsaw/examine(mob/user)
- if(..(user,0))
- if(max_fuel)
- to_chat(usr, "The [src] feels like it contains roughtly [get_fuel()] units of fuel left.")
+ . = ..()
+ if(max_fuel && get_dist(user, src) == 0)
+ . += "The [src] feels like it contains roughtly [get_fuel()] units of fuel left."
obj/item/weapon/chainsaw/suicide_act(mob/user)
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
diff --git a/code/game/objects/items/weapons/material/gravemarker.dm b/code/game/objects/items/weapons/material/gravemarker.dm
index cad9df3c8f..d3c615e8fd 100644
--- a/code/game/objects/items/weapons/material/gravemarker.dm
+++ b/code/game/objects/items/weapons/material/gravemarker.dm
@@ -36,13 +36,11 @@
..()
/obj/item/weapon/material/gravemarker/examine(mob/user)
- ..()
- if(get_dist(src, user) < 4)
- if(grave_name)
- to_chat(user, "Here Lies [grave_name]")
- if(get_dist(src, user) < 2)
- if(epitaph)
- to_chat(user, epitaph)
+ . = ..()
+ if(grave_name && get_dist(src, user) < 4)
+ . += "Here Lies [grave_name]"
+ if(epitaph && get_dist(src, user) < 2)
+ . += epitaph
/obj/item/weapon/material/gravemarker/update_icon()
if(icon_changes)
diff --git a/code/game/objects/items/weapons/material/shards_vr.dm b/code/game/objects/items/weapons/material/shards_vr.dm
new file mode 100644
index 0000000000..e59966c9b1
--- /dev/null
+++ b/code/game/objects/items/weapons/material/shards_vr.dm
@@ -0,0 +1,5 @@
+/obj/item/weapon/material/shard/titaniumglass/New(loc)
+ ..(loc, MAT_TITANIUMGLASS)
+
+/obj/item/weapon/material/shard/plastitaniumglass/New(loc)
+ ..(loc, MAT_PLASTANIUMGLASS)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/material/whetstone.dm b/code/game/objects/items/weapons/material/whetstone.dm
index 628f450e3d..65faf1fa7c 100644
--- a/code/game/objects/items/weapons/material/whetstone.dm
+++ b/code/game/objects/items/weapons/material/whetstone.dm
@@ -41,7 +41,8 @@
/obj/item/weapon/material/sharpeningkit/examine(mob/user, distance)
. = ..()
- to_chat(user, "There [uses == 1 ? "is" : "are"] [uses] [material] [uses == 1 ? src.material.sheet_singular_name : src.material.sheet_plural_name] left for use.")
+ . += "There [uses == 1 ? "is" : "are"] [uses] [material] [uses == 1 ? src.material.sheet_singular_name : src.material.sheet_plural_name] left for use."
+
/obj/item/weapon/material/sharpeningkit/Initialize()
. = ..()
setrepair()
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index 9145786d69..21d4d53a5c 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -86,14 +86,12 @@
return null
/obj/item/weapon/melee/energy/examine(mob/user)
- if(!..(user, 1))
- return
-
- if(use_cell)
+ . = ..()
+ if(use_cell && Adjacent(user))
if(bcell)
- to_chat(user, "The blade is [round(bcell.percent())]% charged.")
- if(!bcell)
- to_chat(user, "The blade does not have a power source installed.")
+ . += "The blade is [round(bcell.percent())]% charged."
+ else
+ . += "The blade does not have a power source installed."
/obj/item/weapon/melee/energy/attack_self(mob/living/user as mob)
if(use_cell)
@@ -200,8 +198,8 @@
update_icon()
/obj/item/weapon/melee/energy/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to recolor it.")
+ . = ..()
+ . += "Alt-click to recolor it."
/*
* Energy Axe
diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm
index 744a92e370..4d78a09bc5 100644
--- a/code/game/objects/items/weapons/shields.dm
+++ b/code/game/objects/items/weapons/shields.dm
@@ -215,8 +215,8 @@
update_icon()
/obj/item/weapon/shield/energy/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to recolor it.")
+ . = ..()
+ . += "Alt-click to recolor it."
/obj/item/weapon/shield/riot/tele
name = "telescopic shield"
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index 6b347e0cb6..88f6caeb74 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -363,13 +363,12 @@
max_storage_space = ITEMSIZE_COST_NORMAL * 5
/obj/item/weapon/storage/backpack/parachute/examine(mob/user)
- var/msg = desc
- if(get_dist(src, user) <= 1)
+ . = ..()
+ if(Adjacent(user))
if(parachute)
- msg += " It seems to be packed."
+ . += "It seems to be packed."
else
- msg += " It seems to be unpacked."
- to_chat(user, msg)
+ . += "It seems to be unpacked."
/obj/item/weapon/storage/backpack/parachute/handleParachute()
parachute = FALSE //If you parachute in, the parachute has probably been used.
diff --git a/code/game/objects/items/weapons/storage/backpack_vr.dm b/code/game/objects/items/weapons/storage/backpack_vr.dm
index b14fbf5ff0..4c9ff8c2db 100644
--- a/code/game/objects/items/weapons/storage/backpack_vr.dm
+++ b/code/game/objects/items/weapons/storage/backpack_vr.dm
@@ -137,3 +137,53 @@
/obj/item/weapon/storage/backpack/ert
max_storage_space = INVENTORY_DUFFLEBAG_SPACE
+
+/obj/item/weapon/storage/backpack/satchel/explorer
+ name = "explorer satchel"
+ desc = "A satchel for carrying a large number of supplies easily."
+ icon = 'icons/obj/storage_vr.dmi'
+ icon_override = 'icons/mob/back_vr.dmi'
+ item_state = "satchel-explorer"
+ icon_state = "satchel-explorer"
+/obj/item/weapon/storage/backpack/explorer
+ name = "explorer backpack"
+ desc = "A backpack for carrying a large number of supplies easily."
+ icon = 'icons/obj/storage_vr.dmi'
+ icon_override = 'icons/mob/back_vr.dmi'
+ item_state = "explorerpack"
+ icon_state = "explorerpack"
+/obj/item/weapon/storage/backpack/satchel/roboticist
+ name = "roboticist satchel"
+ desc = "A satchel for carrying a large number of spare parts easily."
+ icon = 'icons/obj/storage_vr.dmi'
+ icon_override = 'icons/mob/back_vr.dmi'
+ item_state = "satchel-robo"
+ icon_state = "satchel-robo"
+/obj/item/weapon/storage/backpack/roboticist
+ name = "roboticist backpack"
+ desc = "A backpack for carrying a large number of spare parts easily."
+ icon = 'icons/obj/storage_vr.dmi'
+ icon_override = 'icons/mob/back_vr.dmi'
+ item_state = "backpack-robo"
+ icon_state = "backpack-robo"
+/obj/item/weapon/storage/backpack/vietnam
+ name = "vietnam backpack"
+ desc = "There are tangos in the trees! We need napalm right now! Why is my gun jammed?"
+ icon = 'icons/obj/storage_vr.dmi'
+ icon_override = 'icons/mob/back_vr.dmi'
+ item_state = "nambackpack"
+ icon_state = "nambackpack"
+/obj/item/weapon/storage/backpack/russian
+ name = "russian backpack"
+ desc = "Useful for carrying large quantities of vodka."
+ icon = 'icons/obj/storage_vr.dmi'
+ icon_override = 'icons/mob/back_vr.dmi'
+ item_state = "ru_rucksack"
+ icon_state = "ru_rucksack"
+/obj/item/weapon/storage/backpack/korean
+ name = "korean backpack"
+ desc = "Insert witty description here."
+ icon = 'icons/obj/storage_vr.dmi'
+ icon_override = 'icons/mob/back_vr.dmi'
+ item_state = "kr_rucksack"
+ icon_state = "kr_rucksack"
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index 005def5410..f431bc74fe 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -142,34 +142,36 @@
if(O)
gather_all(get_turf(src), user)
+/obj/item/weapon/storage/bag/ore/proc/rangedload(atom/A, mob/user)
+ var/obj/item/weapon/ore/O = locate() in get_turf(A)
+ if(O)
+ gather_all(get_turf(A), user)
/obj/item/weapon/storage/bag/ore/examine(mob/user)
- ..()
+ . = ..()
if(!Adjacent(user)) //Can only check the contents of ore bags if you can physically reach them.
- return
+ return .
if(istype(user, /mob/living))
add_fingerprint(user)
if(!contents.len)
- to_chat(user, "It is empty.")
- return
+ . += "It is empty."
- if(world.time > last_update + 10)
+ else if(world.time > last_update + 10)
update_ore_count()
last_update = world.time
- to_chat(user, "It holds:")
- for(var/ore in stored_ore)
- to_chat(user, "- [stored_ore[ore]] [ore]")
- return
+ . += "It holds:"
+ for(var/ore in stored_ore)
+ . += "- [stored_ore[ore]] [ore]"
/obj/item/weapon/storage/bag/ore/open(mob/user as mob) //No opening it for the weird UI of having shit-tons of ore inside it.
if(world.time > last_update + 10)
update_ore_count()
last_update = world.time
- examine(user)
+ user.examinate(src)
/obj/item/weapon/storage/bag/ore/proc/update_ore_count() //Stolen from ore boxes.
@@ -337,6 +339,21 @@
desc = ""
capacity = 500//Borgs get more because >specialization
+// -----------------------------
+// Food Bag (Service Hound)
+// -----------------------------
+/obj/item/weapon/storage/bag/dogborg
+ name = "dog bag"
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "foodbag"
+ desc = "A bag for storing things of all kinds."
+ max_storage_space = ITEMSIZE_COST_NORMAL * 25
+ max_w_class = ITEMSIZE_NORMAL
+ w_class = ITEMSIZE_SMALL
+ can_hold = list(/obj/item/weapon/reagent_containers/food/snacks,/obj/item/weapon/reagent_containers/food/condiment,
+ /obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/coin,/obj/item/weapon/spacecash,
+ /obj/item/weapon/reagent_containers/food/snacks/grown,/obj/item/seeds,/obj/item/weapon/grown,/obj/item/weapon/reagent_containers/pill)
+
// -----------------------------
// Cash Bag
// -----------------------------
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 926e6bc5c5..66b3547d6c 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -204,6 +204,11 @@
desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death."
starts_with = list(/obj/item/ammo_casing/a145 = 7)
+/obj/item/weapon/storage/box/sniperammo/highvel
+ name = "box of 14.5mm sabot shells"
+ desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death."
+ starts_with = list(/obj/item/ammo_casing/a145/highvel = 7)
+
/obj/item/weapon/storage/box/flashbangs
name = "box of flashbangs (WARNING)"
desc = "WARNING: These devices are extremely dangerous and can cause blindness or deafness in repeated use."
diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm
index 830f5a2631..926255c620 100644
--- a/code/game/objects/items/weapons/storage/fancy.dm
+++ b/code/game/objects/items/weapons/storage/fancy.dm
@@ -26,17 +26,15 @@
return
/obj/item/weapon/storage/fancy/examine(mob/user)
- if(!..(user, 1))
- return
+ . = ..()
- if(contents.len <= 0)
- to_chat(user, "There are no [icon_type]s left in the box.")
- else if(contents.len == 1)
- to_chat(user, "There is one [icon_type] left in the box.")
- else
- to_chat(user, "There are [contents.len] [icon_type]s in the box.")
-
- return
+ if(Adjacent(user))
+ if(!contents.len)
+ . += "There are no [icon_type]s left in the box."
+ else if(contents.len == 1)
+ . += "There is one [icon_type] left in the box."
+ else
+ . += "There are [contents.len] [icon_type]s in the box."
/*
* Egg Box
diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm
index c47e564e01..703649f4f1 100644
--- a/code/game/objects/items/weapons/storage/firstaid.dm
+++ b/code/game/objects/items/weapons/storage/firstaid.dm
@@ -10,26 +10,26 @@
/obj/item/weapon/storage/firstaid
name = "first aid kit"
desc = "It's an emergency medical kit for those serious boo-boos."
- icon = 'icons/obj/storage_vr.dmi'
+ icon = 'icons/obj/storage.dmi'
icon_state = "firstaid"
throw_speed = 2
throw_range = 8
max_storage_space = ITEMSIZE_COST_SMALL * 7 // 14
-// var/list/icon_variety // VOREStation edit
+ var/list/icon_variety
drop_sound = 'sound/items/drop/box.ogg'
/obj/item/weapon/storage/firstaid/Initialize()
. = ..()
-// if(icon_variety) // VOREStation edit
-// icon_state = pick(icon_variety)
-// icon_variety = null
+ if(icon_variety)
+ icon_state = pick(icon_variety)
+ icon_variety = null
/obj/item/weapon/storage/firstaid/fire
name = "fire first aid kit"
desc = "It's an emergency medical kit for when the toxins lab spontaneously burns down."
icon_state = "ointment"
item_state_slots = list(slot_r_hand_str = "firstaid-ointment", slot_l_hand_str = "firstaid-ointment")
-// icon_variety = list("ointment","firefirstaid") // VOREStation edit
+ //icon_variety = list("ointment","firefirstaid") //VOREStation Removal
starts_with = list(
/obj/item/device/healthanalyzer,
/obj/item/weapon/reagent_containers/hypospray/autoinjector,
@@ -57,7 +57,7 @@
desc = "Used to treat when one has a high amount of toxins in their body."
icon_state = "antitoxin"
item_state_slots = list(slot_r_hand_str = "firstaid-toxin", slot_l_hand_str = "firstaid-toxin")
-// icon_variety = list("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") // VOREStation edit
+ //icon_variety = list("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3") //VOREStation Removal
starts_with = list(
/obj/item/weapon/reagent_containers/syringe/antitoxin,
/obj/item/weapon/reagent_containers/syringe/antitoxin,
@@ -135,7 +135,7 @@
/obj/item/weapon/surgical/FixOVein,
/obj/item/stack/medical/advanced/bruise_pack,
/obj/item/stack/nanopaste,
- ///obj/item/device/healthanalyzer/advanced, //VOREStation Removal,
+ /obj/item/device/healthanalyzer/advanced,
/obj/item/weapon/autopsy_scanner
)
@@ -150,7 +150,7 @@
/obj/item/weapon/surgical/bonegel,
/obj/item/weapon/surgical/FixOVein,
/obj/item/stack/medical/advanced/bruise_pack,
- ///obj/item/device/healthanalyzer/advanced, //VOREStation Removal,
+ /obj/item/device/healthanalyzer/advanced,
/obj/item/weapon/autopsy_scanner
)
diff --git a/code/game/objects/items/weapons/storage/firstaid_vr.dm b/code/game/objects/items/weapons/storage/firstaid_vr.dm
index e73cbf9f85..038708895c 100644
--- a/code/game/objects/items/weapons/storage/firstaid_vr.dm
+++ b/code/game/objects/items/weapons/storage/firstaid_vr.dm
@@ -1,9 +1,148 @@
+/obj/item/weapon/storage/firstaid
+ icon = 'icons/obj/storage_vr.dmi'
+
+/obj/item/weapon/storage/firstaid/fire
+ starts_with = list(
+ /obj/item/weapon/storage/pill_bottle/kelotane,
+ /obj/item/stack/medical/ointment,
+ /obj/item/stack/medical/ointment,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn
+ )
+
+/obj/item/weapon/storage/firstaid/regular
+ starts_with = list(
+ /obj/item/stack/medical/bruise_pack,
+ /obj/item/stack/medical/bruise_pack,
+ /obj/item/stack/medical/bruise_pack,
+ /obj/item/stack/medical/bruise_pack,
+ /obj/item/stack/medical/ointment,
+ /obj/item/stack/medical/ointment,
+ /obj/item/weapon/storage/pill_bottle/paracetamol
+ )
+
+/obj/item/weapon/storage/firstaid/toxin
+ starts_with = list(
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/rad,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/rad,
+ /obj/item/weapon/storage/pill_bottle/antitox
+ )
+
+/obj/item/weapon/storage/firstaid/o2
+ starts_with = list(
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy,
+ /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy,
+ /obj/item/weapon/storage/pill_bottle/inaprovaline,
+ /obj/item/weapon/storage/pill_bottle/iron,
+ /obj/item/weapon/storage/pill_bottle/dexalin
+ )
+
+/obj/item/weapon/storage/firstaid/adv
+ starts_with = list(
+ /obj/item/weapon/storage/pill_bottle/assorted,
+ /obj/item/stack/medical/advanced/bruise_pack,
+ /obj/item/stack/medical/advanced/bruise_pack,
+ /obj/item/stack/medical/advanced/bruise_pack,
+ /obj/item/stack/medical/advanced/ointment,
+ /obj/item/stack/medical/advanced/ointment,
+ /obj/item/stack/medical/splint
+ )
+
+/obj/item/weapon/storage/firstaid/combat
+ starts_with = list(
+ /obj/item/weapon/storage/pill_bottle/vermicetol,
+ /obj/item/weapon/storage/pill_bottle/dermaline,
+ /obj/item/weapon/storage/pill_bottle/dexalin_plus,
+ /obj/item/weapon/storage/pill_bottle/carthatoline,
+ /obj/item/weapon/storage/pill_bottle/tramadol,
+ /obj/item/weapon/storage/pill_bottle/corophizine,
+ /obj/item/weapon/storage/pill_bottle/combat,
+ /obj/item/stack/medical/splint,
+ /obj/item/device/healthanalyzer/advanced
+ )
+
+/obj/item/weapon/storage/firstaid/surgery
+ can_hold = list(
+ /obj/item/weapon/surgical/bonesetter,
+ /obj/item/weapon/surgical/cautery,
+ /obj/item/weapon/surgical/circular_saw,
+ /obj/item/weapon/surgical/hemostat,
+ /obj/item/weapon/surgical/retractor,
+ /obj/item/weapon/surgical/scalpel,
+ /obj/item/weapon/surgical/surgicaldrill,
+ /obj/item/weapon/surgical/bonegel,
+ /obj/item/weapon/surgical/FixOVein,
+ /obj/item/stack/medical/advanced/bruise_pack,
+ /obj/item/stack/nanopaste,
+ /obj/item/device/healthanalyzer,
+ /obj/item/weapon/autopsy_scanner
+ )
+
+ starts_with = list(
+ /obj/item/weapon/surgical/bonesetter,
+ /obj/item/weapon/surgical/cautery,
+ /obj/item/weapon/surgical/circular_saw,
+ /obj/item/weapon/surgical/hemostat,
+ /obj/item/weapon/surgical/retractor,
+ /obj/item/weapon/surgical/scalpel,
+ /obj/item/weapon/surgical/surgicaldrill,
+ /obj/item/weapon/surgical/bonegel,
+ /obj/item/weapon/surgical/FixOVein,
+ /obj/item/stack/medical/advanced/bruise_pack,
+ /obj/item/device/healthanalyzer,
+ /obj/item/weapon/autopsy_scanner
+ )
+
/obj/item/weapon/storage/firstaid/clotting
icon_state = "clottingkit"
/obj/item/weapon/storage/firstaid/bonemed
icon_state = "pinky"
+/obj/item/weapon/storage/pill_bottle/antitox
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/antitox = 14)
+
+/obj/item/weapon/storage/pill_bottle/bicaridine
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/bicaridine = 14)
+
+/obj/item/weapon/storage/pill_bottle/dexalin_plus
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/dexalin_plus = 14)
+
+/obj/item/weapon/storage/pill_bottle/dermaline
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/dermaline = 14)
+
+/obj/item/weapon/storage/pill_bottle/dylovene
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/dylovene = 14)
+
+/obj/item/weapon/storage/pill_bottle/inaprovaline
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/inaprovaline = 14)
+
+/obj/item/weapon/storage/pill_bottle/kelotane
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/kelotane = 14)
+
+/obj/item/weapon/storage/pill_bottle/spaceacillin
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/spaceacillin = 14)
+
+/obj/item/weapon/storage/pill_bottle/tramadol
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/tramadol = 14)
+
+/obj/item/weapon/storage/pill_bottle/citalopram
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/citalopram = 14)
+
+/obj/item/weapon/storage/pill_bottle/carbon
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/carbon = 14)
+
+/obj/item/weapon/storage/pill_bottle/iron
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/iron = 14)
+
/obj/item/weapon/storage/pill_bottle/adminordrazine
name = "pill bottle (Adminordrazine)"
desc = "It's magic. We don't have to explain it."
@@ -17,67 +156,73 @@
/obj/item/weapon/storage/pill_bottle/rezadone
name = "pill bottle (Rezadone)"
desc = "A powder with almost magical properties, this substance can effectively treat genetic damage in humanoids, though excessive consumption has side effects."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/rezadone = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/rezadone = 14)
wrapper_color = COLOR_GREEN_GRAY
/obj/item/weapon/storage/pill_bottle/peridaxon
name = "pill bottle (Peridaxon)"
desc = "Used to encourage recovery of internal organs and nervous systems. Medicate cautiously."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/peridaxon = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/peridaxon = 14)
wrapper_color = COLOR_PURPLE
/obj/item/weapon/storage/pill_bottle/carthatoline
name = "pill bottle (Carthatoline)"
desc = "Carthatoline is strong evacuant used to treat severe poisoning."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/carthatoline = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/carthatoline = 14)
wrapper_color = COLOR_GREEN_GRAY
/obj/item/weapon/storage/pill_bottle/alkysine
name = "pill bottle (Alkysine)"
desc = "Alkysine is a drug used to lessen the damage to neurological tissue after a catastrophic injury. Can heal brain tissue."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/alkysine = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/alkysine = 14)
wrapper_color = COLOR_YELLOW
/obj/item/weapon/storage/pill_bottle/imidazoline
name = "pill bottle (Imidazoline)"
desc = "Heals eye damage."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/imidazoline = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/imidazoline = 14)
wrapper_color = COLOR_PURPLE_GRAY
/obj/item/weapon/storage/pill_bottle/osteodaxon
name = "pill bottle (Osteodaxon)"
desc = "An experimental drug used to heal bone fractures."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/osteodaxon = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/osteodaxon = 14)
wrapper_color = COLOR_WHITE
/obj/item/weapon/storage/pill_bottle/myelamine
name = "pill bottle (Myelamine)"
desc = "Used to rapidly clot internal hemorrhages by increasing the effectiveness of platelets."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/myelamine = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/myelamine = 14)
wrapper_color = COLOR_PALE_PURPLE_GRAY
/obj/item/weapon/storage/pill_bottle/hyronalin
name = "pill bottle (Hyronalin)"
desc = "Hyronalin is a medicinal drug used to counter the effect of radiation poisoning."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/hyronalin = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/hyronalin = 14)
wrapper_color = COLOR_TEAL
/obj/item/weapon/storage/pill_bottle/arithrazine
name = "pill bottle (Arithrazine)"
desc = "Arithrazine is an unstable medication used for the most extreme cases of radiation poisoning."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/arithrazine = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/arithrazine = 14)
wrapper_color = COLOR_TEAL
/obj/item/weapon/storage/pill_bottle/corophizine
name = "pill bottle (Corophizine)"
desc = "A wide-spectrum antibiotic drug. Powerful and uncomfortable in equal doses."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/corophizine = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/corophizine = 14)
wrapper_color = COLOR_PALE_GREEN_GRAY
+/obj/item/weapon/storage/pill_bottle/vermicetol
+ name = "pill bottle (Vermicetol)"
+ desc = "Contains pills used to stabilize the extremely injured."
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/vermicetol = 14)
+ wrapper_color = COLOR_MAROON
+
/obj/item/weapon/storage/pill_bottle/healing_nanites
name = "pill bottle (Healing nanites)"
desc = "Miniature medical robots that swiftly restore bodily damage."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/healing_nanites = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/healing_nanites = 14)
/obj/item/weapon/storage/pill_bottle/sleevingcure
name = "pill bottle (Vey-Med Resleeving Booster)"
@@ -87,23 +232,6 @@
/obj/item/weapon/storage/pill_bottle/sleevingcure/full
starts_with = list(/obj/item/weapon/reagent_containers/pill/sleevingcure = 14)
-/obj/item/weapon/storage/firstaid/insiderepair
- name = "combat organ kit"
- desc = "Contains advanced organ medical treatments."
- icon_state = "bezerk"
- item_state_slots = list(slot_r_hand_str = "firstaid-advanced", slot_l_hand_str = "firstaid-advanced")
- starts_with = list(
- /obj/item/weapon/storage/pill_bottle/rezadone,
- /obj/item/weapon/storage/pill_bottle/peridaxon,
- /obj/item/weapon/storage/pill_bottle/carthatoline,
- /obj/item/weapon/storage/pill_bottle/alkysine,
- /obj/item/weapon/storage/pill_bottle/imidazoline,
- /obj/item/weapon/storage/pill_bottle/osteodaxon,
- /obj/item/weapon/storage/pill_bottle/myelamine,
- /obj/item/weapon/storage/pill_bottle/arithrazine,
- /obj/item/device/healthanalyzer/advanced
- )
-
/obj/item/weapon/storage/mrebag/pill
name = "vacuum-sealed pill"
desc = "A small vacuum-sealed package containing a singular pill. For emergencies only."
@@ -119,5 +247,39 @@
/obj/item/weapon/storage/pill_bottle/paracetamol
name = "pill bottle (Paracetamol)"
desc = "Contains over the counter medicine to treat pain."
- starts_with = list(/obj/item/weapon/reagent_containers/pill/paracetamol = 7)
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/paracetamol = 14)
wrapper_color = COLOR_GRAY
+
+/obj/item/weapon/storage/pill_bottle/dexalin
+ name = "pill bottle (Dexalin)"
+ desc = "Contains pills used to treat oxygen deprivation."
+ starts_with = list(/obj/item/weapon/reagent_containers/pill/dexalin = 14)
+ wrapper_color = "#3366cc"
+
+/obj/item/weapon/storage/pill_bottle/assorted
+ name = "pill bottle (Assorted)"
+ desc = "Commonly found on paramedics, these assorted pill bottles contain basic treatments for nonstandard injuries."
+ starts_with = list(
+ /obj/item/weapon/reagent_containers/pill/inaprovaline = 3,
+ /obj/item/weapon/reagent_containers/pill/antitox = 3,
+ /obj/item/weapon/reagent_containers/pill/iron = 2,
+ /obj/item/weapon/reagent_containers/pill/tramadol = 2,
+ /obj/item/weapon/reagent_containers/pill/hyronalin = 3,
+ /obj/item/weapon/reagent_containers/pill/spaceacillin
+ )
+ wrapper_color = COLOR_BLACK
+
+/obj/item/weapon/storage/pill_bottle/combat
+ name = "pill bottle (Combat)"
+ desc = "A pill bottle filled with some of the rarest medical treatmeants to exist."
+ max_storage_space = ITEMSIZE_COST_TINY * 20
+ starts_with = list(
+ /obj/item/weapon/reagent_containers/pill/peridaxon = 5,
+ /obj/item/weapon/reagent_containers/pill/rezadone = 5,
+ /obj/item/weapon/reagent_containers/pill/myelamine = 3,
+ /obj/item/weapon/reagent_containers/pill/osteodaxon = 3,
+ /obj/item/weapon/reagent_containers/pill/arithrazine = 2,
+ /obj/item/weapon/reagent_containers/pill/alkysine = 1,
+ /obj/item/weapon/reagent_containers/pill/imidazoline = 1
+ )
+ wrapper_color = COLOR_BLACK
diff --git a/code/game/objects/items/weapons/storage/mre.dm b/code/game/objects/items/weapons/storage/mre.dm
index 582af52f43..50536564d3 100644
--- a/code/game/objects/items/weapons/storage/mre.dm
+++ b/code/game/objects/items/weapons/storage/mre.dm
@@ -24,7 +24,7 @@ MRE Stuff
/obj/item/weapon/storage/mre/examine(mob/user)
. = ..()
- to_chat(user, meal_desc)
+ . += meal_desc
/obj/item/weapon/storage/mre/update_icon()
if(opened)
diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm
index df775b3cc0..c8bc129e3d 100644
--- a/code/game/objects/items/weapons/storage/secure.dm
+++ b/code/game/objects/items/weapons/storage/secure.dm
@@ -29,8 +29,9 @@
use_sound = 'sound/items/storage/briefcase.ogg'
examine(mob/user)
- if(..(user, 1))
- to_chat(user, "The service panel is [src.open ? "open" : "closed"].")
+ . = ..()
+ if(Adjacent(user))
+ . += "The service panel is [src.open ? "open" : "closed"]."
attackby(obj/item/weapon/W as obj, mob/user as mob)
if(locked)
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index 1b25d5e19a..d14a4ab29b 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -722,10 +722,10 @@
..()
/obj/item/weapon/storage/trinketbox/examine(mob/user)
- ..()
+ . = ..()
if(open && contents.len)
var/display_item = contents[1]
- to_chat(user, "\The [src] contains \the [display_item]!")
+ . += "\The [src] contains \the [display_item]!"
/obj/item/weapon/storage/AllowDrop()
return TRUE
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index 3bf10a4b78..a875dbfa3c 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -101,13 +101,13 @@
set_light(0)
/obj/item/weapon/melee/baton/examine(mob/user)
- if(!..(user, 1))
- return
+ . = ..()
- if(bcell)
- to_chat(user, "The baton is [round(bcell.percent())]% charged.")
- if(!bcell)
- to_chat(user, "The baton does not have a power source installed.")
+ if(Adjacent(user, src))
+ if(bcell)
+ . += "The baton is [round(bcell.percent())]% charged."
+ if(!bcell)
+ . += "The baton does not have a power source installed."
/obj/item/weapon/melee/baton/attackby(obj/item/weapon/W, mob/user)
if(use_external_power)
diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm
index ec9e62c86b..204ebb6f89 100644
--- a/code/game/objects/items/weapons/swords_axes_etc.dm
+++ b/code/game/objects/items/weapons/swords_axes_etc.dm
@@ -14,7 +14,6 @@
desc = "Murder device."
icon = 'icons/obj/weapons.dmi'
icon_state = "baton"
- item_state = "classic_baton"
slot_flags = SLOT_BELT
force = 10
drop_sound = 'sound/items/drop/metalweapon.ogg'
diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm
index 528b8eb447..eec15d1e94 100644
--- a/code/game/objects/items/weapons/tanks/jetpack.dm
+++ b/code/game/objects/items/weapons/tanks/jetpack.dm
@@ -30,7 +30,7 @@
/obj/item/weapon/tank/jetpack/examine(mob/user)
. = ..()
if(air_contents.total_moles < 5)
- to_chat(user, "The meter on \the [src] indicates you are almost out of gas!")
+ . += "The meter on \the [src] indicates you are almost out of gas!"
playsound(user, 'sound/effects/alert.ogg', 50, 1)
/obj/item/weapon/tank/jetpack/verb/toggle_rockets()
@@ -116,8 +116,8 @@
var/obj/item/weapon/rig/holder
/obj/item/weapon/tank/jetpack/rig/examine()
- to_chat(usr, "It's a jetpack. If you can see this, report it on the bug tracker.")
- return 0
+ . = ..()
+ . += "It's a jetpack. If you can see this, report it on the bug tracker."
/obj/item/weapon/tank/jetpack/rig/allow_thrust(num, mob/living/user as mob)
diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm
index 6d6839a4a5..c2a342b618 100644
--- a/code/game/objects/items/weapons/tanks/tank_types.dm
+++ b/code/game/objects/items/weapons/tanks/tank_types.dm
@@ -22,9 +22,9 @@
return
/obj/item/weapon/tank/oxygen/examine(mob/user)
- if(..(user, 0) && air_contents.gas["oxygen"] < 10)
- to_chat(user, text("The meter on \the [src] indicates you are almost out of oxygen!"))
- //playsound(usr, 'sound/effects/alert.ogg', 50, 1)
+ . = ..()
+ if(loc == user && (air_contents.gas["oxygen"] < 10))
+ . += "The meter on \the [src] indicates you are almost out of oxygen!"
/obj/item/weapon/tank/oxygen/yellow
desc = "A tank of oxygen, this one is yellow."
@@ -60,8 +60,9 @@
icon_state = "oxygen"
/obj/item/weapon/tank/air/examine(mob/user)
- if(..(user, 0) && air_contents.gas["oxygen"] < 1 && loc==user)
- to_chat(user, "The meter on the [src.name] indicates you are almost out of air!")
+ . = ..()
+ if(loc == user && (air_contents.gas["oxygen"] < 1))
+ . += "The meter on \the [src] indicates you are almost out of air!"
user << sound('sound/effects/alert.ogg')
/obj/item/weapon/tank/air/Initialize()
@@ -153,8 +154,9 @@
return
/obj/item/weapon/tank/emergency/oxygen/examine(mob/user)
- if(..(user, 0) && air_contents.gas["oxygen"] < 0.2 && loc==user)
- to_chat(user, text("The meter on the [src.name] indicates you are almost out of air!"))
+ . = ..()
+ if(loc == user && (air_contents.gas["oxygen"] < 0.2))
+ . += "The meter on the [src.name] indicates you are almost out of air!"
user << sound('sound/effects/alert.ogg')
/obj/item/weapon/tank/emergency/oxygen/engi
@@ -228,8 +230,9 @@
return
/obj/item/weapon/tank/nitrogen/examine(mob/user)
- if(..(user, 0) && air_contents.gas["nitrogen"] < 10)
- to_chat(user, text("The meter on \the [src] indicates you are almost out of nitrogen!"))
+ . = ..()
+ if(loc == user && (air_contents.gas["nitrogen"] < 10))
+ . += "The meter on \the [src] indicates you are almost out of nitrogen!"
//playsound(user, 'sound/effects/alert.ogg', 50, 1)
/obj/item/weapon/tank/stasis/nitro_cryo // Synthmorph bags need to have initial pressure within safe bounds for human atmospheric pressure, but low temperature to stop unwanted degredation.
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index bfb484b307..f176046ef7 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -82,8 +82,8 @@ var/list/global/tank_gauge_cache = list()
. = ..()
/obj/item/weapon/tank/examine(mob/user)
- . = ..(user, 0)
- if(.)
+ . = ..()
+ if(loc == user)
var/celsius_temperature = air_contents.temperature - T0C
var/descriptive
switch(celsius_temperature)
@@ -101,12 +101,12 @@ var/list/global/tank_gauge_cache = list()
descriptive = "cold"
else
descriptive = "bitterly cold"
- to_chat(user, "\The [src] feels [descriptive].")
+ . += "\The [src] feels [descriptive]."
if(src.proxyassembly.assembly || wired)
- to_chat(user, "It seems to have [wired? "some wires ": ""][wired && src.proxyassembly.assembly? "and ":""][src.proxyassembly.assembly ? "some sort of assembly ":""]attached to it.")
+ . += "It seems to have [wired? "some wires ": ""][wired && src.proxyassembly.assembly? "and ":""][src.proxyassembly.assembly ? "some sort of assembly ":""]attached to it."
if(src.valve_welded)
- to_chat(user, "\The [src] emergency relief valve has been welded shut!")
+ . += "\The [src] emergency relief valve has been welded shut!"
/obj/item/weapon/tank/attackby(obj/item/weapon/W as obj, mob/user as mob)
diff --git a/code/game/objects/items/weapons/tools/combitool.dm b/code/game/objects/items/weapons/tools/combitool.dm
index b154f059af..43bb2794fe 100644
--- a/code/game/objects/items/weapons/tools/combitool.dm
+++ b/code/game/objects/items/weapons/tools/combitool.dm
@@ -22,12 +22,12 @@
var/list/tools = list()
var/current_tool = 1
-/obj/item/weapon/combitool/examine()
- ..()
- if(loc == usr && tools.len)
- to_chat(usr, "It has the following fittings:")
+/obj/item/weapon/combitool/examine(mob/user)
+ . = ..()
+ if(loc == user && tools.len)
+ . += "It has the following fittings:"
for(var/obj/item/tool in tools)
- to_chat(usr, "[bicon(tool)] - [tool.name][tools[current_tool]==tool?" (selected)":""]")
+ . += "[bicon(tool)] - [tool.name][tools[current_tool]==tool?" (selected)":""]")
/obj/item/weapon/combitool/New()
..()
diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm
index ece27fb2c9..e6c2cb3630 100644
--- a/code/game/objects/items/weapons/tools/weldingtool.dm
+++ b/code/game/objects/items/weapons/tools/weldingtool.dm
@@ -56,9 +56,9 @@
return ..()
/obj/item/weapon/weldingtool/examine(mob/user)
- if(..(user, 0))
- if(max_fuel)
- to_chat(user, "[bicon(src)] The [src.name] contains [get_fuel()]/[src.max_fuel] units of fuel!")
+ . = ..()
+ if(max_fuel && loc == user)
+ . += "It contains [get_fuel()]/[src.max_fuel] units of fuel!"
/obj/item/weapon/weldingtool/attack(atom/A, mob/living/user, def_zone)
if(ishuman(A) && user.a_intent == I_HELP)
@@ -68,6 +68,11 @@
if(!S || S.robotic < ORGAN_ROBOT || S.open == 3)
return ..()
+ //VOREStation Add - No welding nanoform limbs
+ if(S.robotic > ORGAN_LIFELIKE)
+ return ..()
+ //VOREStation Add End
+
if(S.organ_tag == BP_HEAD)
if(H.head && istype(H.head,/obj/item/clothing/head/helmet/space))
to_chat(user, "You can't apply [src] through [H.head]!")
@@ -557,13 +562,12 @@
return power_supply
/obj/item/weapon/weldingtool/electric/examine(mob/user)
- if(get_dist(src, user) > 1)
- to_chat(user, desc)
- else
+ . = ..()
+ if(Adjacent(user))
if(power_supply)
- to_chat(user, "[bicon(src)] The [src.name] has [get_fuel()] charge left.")
+ . += "It [src.name] has [get_fuel()] charge left."
else
- to_chat(user, "[bicon(src)] The [src.name] has no power cell!")
+ . += "It [src.name] has no power cell!"
/obj/item/weapon/weldingtool/electric/get_fuel()
if(use_external_power)
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index ff982da257..82e6ff7699 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -99,7 +99,6 @@
anchored = 0
can_buckle = 1
- buckle_movable = 1
buckle_lying = 0
buckle_dir = SOUTH
@@ -122,18 +121,6 @@
if(!has_buckled_mobs())
qdel(src)
-/obj/effect/energy_net/Move()
- ..()
- if(has_buckled_mobs())
- for(var/A in buckled_mobs)
- var/mob/living/occupant = A
- occupant.buckled = null
- occupant.forceMove(src.loc)
- occupant.buckled = src
- if (occupant && (src.loc != occupant.loc))
- unbuckle_mob(occupant)
- qdel(src)
-
/obj/effect/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
user.setClickCooldown(user.get_attack_speed())
visible_message("[user] begins to tear at \the [src]!")
diff --git a/code/game/objects/items/weapons/weldbackpack.dm b/code/game/objects/items/weapons/weldbackpack.dm
index 2f946a5942..f603aa6498 100644
--- a/code/game/objects/items/weapons/weldbackpack.dm
+++ b/code/game/objects/items/weapons/weldbackpack.dm
@@ -144,9 +144,8 @@
src.add_fingerprint(usr)
/obj/item/weapon/weldpack/examine(mob/user)
- ..(user)
- to_chat(user, "[bicon(src)] [src.reagents.total_volume] units of fuel left!")
- return
+ . = ..()
+ . += "It has [src.reagents.total_volume] units of fuel left!"
/obj/item/weapon/weldpack/survival
name = "emergency welding kit"
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index faafdb62f3..2a361f1d46 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -142,6 +142,7 @@
return
/mob/proc/unset_machine()
+ machine?.remove_visual(src)
src.machine = null
/mob/proc/set_machine(var/obj/O)
@@ -162,9 +163,9 @@
/obj/proc/hides_under_flooring()
return 0
-/obj/proc/hear_talk(mob/M as mob, text, verb, datum/language/speaking)
+/obj/proc/hear_talk(mob/M, list/message_pieces, verb)
if(talking_atom)
- talking_atom.catchMessage(text, M)
+ talking_atom.catchMessage(multilingual_to_message(message_pieces), M)
/*
var/mob/mo = locate(/mob) in src
if(mo)
diff --git a/code/game/objects/random/guns_and_ammo.dm b/code/game/objects/random/guns_and_ammo.dm
index 62dde5a3df..a3411ef6fe 100644
--- a/code/game/objects/random/guns_and_ammo.dm
+++ b/code/game/objects/random/guns_and_ammo.dm
@@ -400,4 +400,136 @@
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
/obj/item/weapon/storage/box/shotgunammo
)
- )
\ No newline at end of file
+ )
+
+// Not strictly a gun, but is used in PoIs to spawn the dropped guns of mercs, or a busted version.
+/obj/random/projectile/scrapped_gun
+ name = "broken gun spawner"
+ desc = "Spawns a random broken gun, or rarely a fully functional one."
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "revolver"
+
+/obj/random/projectile/scrapped_gun/item_to_spawn()
+ return pickweight(list(
+ /obj/random/projectile/scrapped_pistol = 10,
+ /obj/random/projectile/scrapped_smg = 5,
+ /obj/random/projectile/scrapped_laser = 5,
+ /obj/random/projectile/scrapped_shotgun = 3,
+ /obj/random/projectile/scrapped_ionrifle = 3,
+ /obj/random/projectile/scrapped_bulldog = 1,
+ /obj/random/projectile/scrapped_flechette = 1,
+ /obj/random/projectile/scrapped_grenadelauncher = 1,
+ /obj/random/projectile/scrapped_dartgun = 1
+ ))
+
+/obj/random/projectile/scrapped_shotgun
+ name = "broken shotgun spawner"
+ desc = "Loot for PoIs, or their mobs."
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "shotgun"
+
+/obj/random/projectile/scrapped_shotgun/item_to_spawn()
+ return pickweight(list(
+ /obj/item/weapon/broken_gun/pumpshotgun = 10,
+ /obj/item/weapon/broken_gun/pumpshotgun_combat = 5,
+ /obj/item/weapon/gun/projectile/shotgun/pump = 3,
+ /obj/item/weapon/gun/projectile/shotgun/pump/combat = 1
+ ))
+
+/obj/random/projectile/scrapped_smg
+ name = "broken smg spawner"
+ desc = "Loot for PoIs, or their mobs."
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "revolver"
+
+/obj/random/projectile/scrapped_smg/item_to_spawn()
+ return pickweight(list(
+ /obj/item/weapon/broken_gun/c20r = 10,
+ /obj/item/weapon/gun/projectile/automatic/c20r = 3
+ ))
+
+/obj/random/projectile/scrapped_pistol
+ name = "broken pistol spawner"
+ desc = "Loot for PoIs, or their mobs."
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "revolver"
+
+/obj/random/projectile/scrapped_pistol/item_to_spawn()
+ return pickweight(list(
+ /obj/item/weapon/broken_gun/silenced45 = 10,
+ /obj/item/weapon/gun/projectile/silenced = 3
+ ))
+
+/obj/random/projectile/scrapped_laser
+ name = "broken laser spawner"
+ desc = "Loot for PoIs, or their mobs."
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "revolver"
+
+/obj/random/projectile/scrapped_laser/item_to_spawn()
+ return pickweight(list(
+ /obj/item/weapon/broken_gun/laserrifle = 10,
+ /obj/item/weapon/broken_gun/laser_retro = 5,
+ /obj/item/weapon/gun/energy/laser = 3,
+ /obj/item/weapon/gun/energy/retro = 1
+ ))
+
+/obj/random/projectile/scrapped_ionrifle
+ name = "broken ionrifle spawner"
+ desc = "Loot for PoIs, or their mobs."
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "revolver"
+
+/obj/random/projectile/scrapped_ionrifle/item_to_spawn()
+ return pickweight(list(
+ /obj/item/weapon/broken_gun/ionrifle = 10,
+ /obj/item/weapon/gun/energy/ionrifle = 3
+ ))
+
+/obj/random/projectile/scrapped_bulldog
+ name = "broken z8 spawner"
+ desc = "Loot for PoIs, or their mobs."
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "revolver"
+
+/obj/random/projectile/scrapped_bulldog/item_to_spawn()
+ return pickweight(list(
+ /obj/item/weapon/broken_gun/z8 = 10,
+ /obj/item/weapon/gun/projectile/automatic/z8 = 3
+ ))
+
+/obj/random/projectile/scrapped_flechette
+ name = "broken flechette spawner"
+ desc = "Loot for PoIs, or their mobs."
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "revolver"
+
+/obj/random/projectile/scrapped_flechette/item_to_spawn()
+ return pickweight(list(
+ /obj/item/weapon/broken_gun/flechette = 10,
+ /obj/item/weapon/gun/magnetic/railgun/flechette = 3
+ ))
+
+/obj/random/projectile/scrapped_grenadelauncher
+ name = "broken grenadelauncher spawner"
+ desc = "Loot for PoIs, or their mobs."
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "revolver"
+
+/obj/random/projectile/scrapped_grenadelauncher/item_to_spawn()
+ return pickweight(list(
+ /obj/item/weapon/broken_gun/grenadelauncher = 10,
+ /obj/item/weapon/gun/launcher/grenade = 3
+ ))
+
+/obj/random/projectile/scrapped_dartgun
+ name = "broken dartgun spawner"
+ desc = "Loot for PoIs, or their mobs."
+ icon = 'icons/obj/gun.dmi'
+ icon_state = "revolver"
+
+/obj/random/projectile/scrapped_dartgun/item_to_spawn()
+ return pickweight(list(
+ /obj/item/weapon/broken_gun/dartgun = 10,
+ /obj/item/weapon/gun/projectile/dartgun = 3
+ ))
diff --git a/code/game/objects/random/mapping.dm b/code/game/objects/random/mapping.dm
index d39983af2f..bc6d29a5a5 100644
--- a/code/game/objects/random/mapping.dm
+++ b/code/game/objects/random/mapping.dm
@@ -389,7 +389,7 @@
/obj/item/device/pda/clown,
/obj/item/clothing/mask/gas/clown_hat,
/obj/item/weapon/bikehorn,
- /obj/item/toy/waterflower,
+ /obj/item/weapon/reagent_containers/spray/waterflower,
/obj/item/weapon/pen/crayon/rainbow,
/obj/structure/closet/crate
),
diff --git a/code/game/objects/random/misc.dm b/code/game/objects/random/misc.dm
index 4e29ac66ec..fe53d2ef55 100644
--- a/code/game/objects/random/misc.dm
+++ b/code/game/objects/random/misc.dm
@@ -469,7 +469,18 @@
/obj/item/toy/plushie/spider,
/obj/item/toy/plushie/tabby_cat,
/obj/item/toy/plushie/tuxedo_cat,
- /obj/item/toy/plushie/white_cat)
+ /obj/item/toy/plushie/white_cat,
+ //VOREStation Add Start
+ /obj/item/toy/plushie/lizardplushie,
+ /obj/item/toy/plushie/lizardplushie/kobold,
+ /obj/item/toy/plushie/slimeplushie,
+ /obj/item/toy/plushie/box,
+ /obj/item/toy/plushie/borgplushie,
+ /obj/item/toy/plushie/borgplushie/medihound,
+ /obj/item/toy/plushie/borgplushie/scrubpuppy,
+ /obj/item/toy/plushie/foxbear,
+ /obj/item/toy/plushie/nukeplushie)
+ //VOREStation Add End
/obj/random/plushielarge
name = "random large plushie"
@@ -504,7 +515,7 @@
/obj/item/toy/balloon,
/obj/item/toy/crossbow,
/obj/item/toy/blink,
- /obj/item/toy/waterflower,
+ /obj/item/weapon/reagent_containers/spray/waterflower,
/obj/item/toy/eight_ball,
/obj/item/toy/eight_ball/conch,
/obj/item/toy/prize/ripley,
@@ -700,3 +711,16 @@
/obj/item/weapon/reagent_containers/food/condiment/small/packet/crayon/purple,
/obj/item/weapon/reagent_containers/food/condiment/small/packet/crayon/grey,
/obj/item/weapon/reagent_containers/food/condiment/small/packet/crayon/brown)
+
+/obj/random/thermalponcho
+ name = "random thermal poncho"
+ desc = "This is a thermal poncho spawn."
+ icon = 'icons/obj/clothing/ties.dmi'
+ icon_state = "classicponcho"
+
+/obj/random/thermalponcho/item_to_spawn()
+ return pick(prob(5);/obj/item/clothing/accessory/poncho/thermal,
+ prob(3);/obj/item/clothing/accessory/poncho/thermal/red,
+ prob(3);/obj/item/clothing/accessory/poncho/thermal/green,
+ prob(3);/obj/item/clothing/accessory/poncho/thermal/purple,
+ prob(3);/obj/item/clothing/accessory/poncho/thermal/blue)
diff --git a/code/game/objects/random/mob.dm b/code/game/objects/random/mob.dm
index 966498a2bd..ac89272f52 100644
--- a/code/game/objects/random/mob.dm
+++ b/code/game/objects/random/mob.dm
@@ -104,6 +104,15 @@
prob(33);/mob/living/simple_mob/animal/giant_spider/frost,
prob(45);/mob/living/simple_mob/animal/sif/shantak)
+/obj/random/mob/sif/kururak
+ name = "Random Kururak"
+ desc = "This is a random kururak, either waking or hibernating. Will be hostile if more than one are waking."
+ icon_state = "frost"
+
+/obj/random/mob/sif/kururak/item_to_spawn()
+ return pick(prob(1);/mob/living/simple_mob/animal/sif/kururak/hibernate,
+ prob(20);/mob/living/simple_mob/animal/sif/kururak)
+
/obj/random/mob/spider
name = "Random Spider" //Spiders should patrol where they spawn.
desc = "This is a random boring spider."
@@ -163,6 +172,7 @@
/obj/random/mob/robotic/item_to_spawn() //Hivebots have a total number of 'lots' equal to the lesser drone, at 60.
return pick(prob(60);/mob/living/simple_mob/mechanical/combat_drone/lesser,
prob(50);/mob/living/simple_mob/mechanical/combat_drone,
+ prob(50);/mob/living/simple_mob/mechanical/mining_drone,
prob(15);/mob/living/simple_mob/mechanical/mecha/ripley,
prob(15);/mob/living/simple_mob/mechanical/mecha/odysseus,
prob(10);/mob/living/simple_mob/mechanical/hivebot,
@@ -174,6 +184,25 @@
prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong,
prob(5);/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong/guard)
+/obj/random/mob/robotic/drone
+ name = "Random Drone"
+ desc = "This is a random drone."
+ icon_state = "drone_dead"
+
+ overwrite_hostility = 1
+
+ mob_faction = "malf_drone"
+ mob_returns_home = 1
+ mob_wander = 1
+ mob_wander_distance = 5
+ mob_hostile = 1
+ mob_retaliate = 1
+
+/obj/random/mob/robotic/drone/item_to_spawn()
+ return pick(prob(6);/mob/living/simple_mob/mechanical/combat_drone/lesser,
+ prob(1);/mob/living/simple_mob/mechanical/combat_drone,
+ prob(3);/mob/living/simple_mob/mechanical/mining_drone)
+
/obj/random/mob/robotic/hivebot
name = "Random Hivebot"
desc = "This is a random hivebot."
@@ -203,3 +232,129 @@
prob(30);/mob/living/simple_mob/animal/passive/mouse/brown,
prob(30);/mob/living/simple_mob/animal/passive/mouse/gray,
prob(25);/obj/random/mouseremains) //because figuring out how to come up with it picking nothing is beyond my coding ability.
+
+// Mercs
+/obj/random/mob/merc
+ name = "Random Mercenary"
+ desc = "This is a random PoI mercenary."
+ icon_state = "syndicate"
+
+ mob_faction = "syndicate"
+ mob_returns_home = 1
+ mob_wander_distance = 7 // People like to wander, and these people probably have a lot of stuff to guard.
+
+/obj/random/mob/merc/item_to_spawn()
+ return pick(prob(60);/mob/living/simple_mob/humanoid/merc/melee/poi,
+ prob(40);/mob/living/simple_mob/humanoid/merc/melee/sword/poi,
+ prob(40);/mob/living/simple_mob/humanoid/merc/ranged/poi,
+ prob(30);/mob/living/simple_mob/humanoid/merc/ranged/smg/poi,
+ prob(20);/mob/living/simple_mob/humanoid/merc/ranged/laser/poi,
+ prob(5);/mob/living/simple_mob/humanoid/merc/ranged/ionrifle/poi,
+ prob(10);/mob/living/simple_mob/humanoid/merc/ranged/grenadier/poi,
+ prob(10);/mob/living/simple_mob/humanoid/merc/ranged/rifle/poi,
+ prob(15);/mob/living/simple_mob/humanoid/merc/ranged/rifle/mag/poi,
+ prob(10);/mob/living/simple_mob/humanoid/merc/ranged/technician/poi
+ )
+
+/obj/random/mob/merc/armored
+ name = "Random Armored Infantry Merc"
+ desc = "This is a random PoI exo or robot for mercs."
+ icon_state = "drone3"
+
+/obj/random/mob/merc/armored/item_to_spawn()
+ return pick(prob(30);/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark,
+ prob(40);/mob/living/simple_mob/mechanical/mecha/combat/gygax/medgax,
+ prob(40);/mob/living/simple_mob/mechanical/mecha/combat/gygax,
+ prob(10);/mob/living/simple_mob/mechanical/mecha/combat/durand/defensive/mercenary,
+ prob(60);/mob/living/simple_mob/mechanical/mecha/hoverpod/manned,
+ prob(5);/mob/living/simple_mob/mechanical/mecha/combat/marauder,
+ prob(1);/mob/living/simple_mob/mechanical/mecha/combat/marauder/seraph,
+ prob(15);/mob/living/simple_mob/mechanical/mecha/odysseus/manned,
+ prob(15);/mob/living/simple_mob/mechanical/mecha/odysseus/murdysseus/manned,
+ prob(60);/mob/living/simple_mob/mechanical/mecha/ripley/manned
+ )
+
+/obj/random/mob/merc/all
+ name = "Random Mercenary All"
+ desc = "A random PoI mercenary, including armored."
+
+/obj/random/mob/merc/all/item_to_spawn()
+ return pick(prob(20);/obj/random/mob/merc,
+ prob(1);/obj/random/mob/merc/armored
+ )
+
+// Multiple mobs, one spawner.
+/obj/random/mob/multiple
+ name = "Random Multiple Mob Spawner"
+ desc = "A base multiple-mob spawner. Takes lists of lists."
+
+/obj/random/mob/multiple/spawn_item()
+ var/list/things_to_make = item_to_spawn()
+
+ for(var/new_type in things_to_make)
+
+ var/mob/living/simple_mob/M = new new_type(src.loc)
+
+ if(!istype(M))
+ continue
+
+ if(M.has_AI())
+ var/datum/ai_holder/AI = M.ai_holder
+ AI.go_sleep() //Don't fight eachother while we're still setting up!
+ AI.returns_home = mob_returns_home
+ AI.wander = mob_wander
+ AI.max_home_distance = mob_wander_distance
+ if(overwrite_hostility)
+ AI.hostile = mob_hostile
+ AI.retaliate = mob_retaliate
+ AI.go_wake() //Now you can kill eachother if your faction didn't override.
+
+ if(pixel_x || pixel_y)
+ M.pixel_x = pixel_x
+ M.pixel_y = pixel_y
+
+/obj/random/mob/multiple/sifmobs
+ name = "Random Sifmob Pack"
+ desc = "A pack of random neutral sif mobs."
+
+/obj/random/mob/multiple/sifmobs/item_to_spawn()
+ return pick(
+ prob(60);list(
+ /mob/living/simple_mob/animal/sif/diyaab,
+ /mob/living/simple_mob/animal/sif/diyaab,
+ /mob/living/simple_mob/animal/sif/diyaab
+ ),
+ prob(15);list(
+ /mob/living/simple_mob/animal/sif/duck,
+ /mob/living/simple_mob/animal/sif/duck,
+ /mob/living/simple_mob/animal/sif/duck
+ ),
+ prob(10);list(
+ /mob/living/simple_mob/animal/sif/shantak/retaliate,
+ /mob/living/simple_mob/animal/sif/shantak/retaliate,
+ /mob/living/simple_mob/animal/sif/shantak/retaliate,
+ /mob/living/simple_mob/animal/sif/shantak/leader/autofollow/retaliate
+ ),
+ prob(5);list(
+ /mob/living/simple_mob/animal/sif/kururak/leader,
+ /mob/living/simple_mob/animal/sif/kururak,
+ /mob/living/simple_mob/animal/sif/kururak
+ ),
+ prob(5);list(
+ /mob/living/simple_mob/animal/sif/glitterfly,
+ /mob/living/simple_mob/animal/sif/glitterfly,
+ /mob/living/simple_mob/animal/sif/glitterfly,
+ /mob/living/simple_mob/animal/sif/glitterfly,
+ /mob/living/simple_mob/animal/sif/glitterfly
+ ),
+ prob(1);list(
+ /mob/living/simple_mob/animal/goat,
+ /mob/living/simple_mob/animal/goat
+ ),
+ prob(1);list(
+ /mob/living/simple_mob/animal/sif/sakimm/intelligent,
+ /mob/living/simple_mob/animal/sif/sakimm,
+ /mob/living/simple_mob/animal/sif/sakimm,
+ /mob/living/simple_mob/animal/sif/sakimm
+ )
+ )
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 3e571009d2..f89aa2edc9 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -8,11 +8,21 @@
var/parts
var/list/climbers = list()
var/block_turf_edges = FALSE // If true, turf edge icons will not be made on the turf this occupies.
+
+ var/list/connections = list("0", "0", "0", "0")
+ var/list/other_connections = list("0", "0", "0", "0")
+ var/list/blend_objects = newlist() // Objects which to blend with
+ var/list/noblend_objects = newlist() //Objects to avoid blending with (such as children of listed blend objects.
+
+/obj/structure/Initialize()
+ . = ..()
+ if(climbable)
+ verbs += /obj/structure/proc/climb_on
/obj/structure/Destroy()
if(parts)
new parts(loc)
- . = ..()
+ return ..()
/obj/structure/attack_hand(mob/user)
if(breakable)
@@ -46,13 +56,7 @@
if(3.0)
return
-/obj/structure/New()
- ..()
- if(climbable)
- verbs += /obj/structure/proc/climb_on
-
/obj/structure/proc/climb_on()
-
set name = "Climb structure"
set desc = "Climbs onto a structure."
set category = "Object"
@@ -61,7 +65,6 @@
do_climb(usr)
/obj/structure/MouseDrop_T(mob/target, mob/user)
-
var/mob/living/H = user
if(istype(H) && can_climb(H) && target == user)
do_climb(target)
@@ -185,3 +188,72 @@
user.do_attack_animation(src)
spawn(1) qdel(src)
return 1
+
+/obj/structure/proc/can_visually_connect()
+ return anchored
+
+/obj/structure/proc/can_visually_connect_to(var/obj/structure/S)
+ return istype(S, src)
+
+/obj/structure/proc/update_connections(propagate = 0)
+ var/list/dirs = list()
+ var/list/other_dirs = list()
+
+ for(var/obj/structure/S in orange(src, 1))
+ if(can_visually_connect_to(S))
+ if(S.can_visually_connect())
+ if(propagate)
+ //S.update_connections() //Not here
+ S.update_icon()
+ dirs += get_dir(src, S)
+
+ if(!can_visually_connect())
+ connections = list("0", "0", "0", "0")
+ other_connections = list("0", "0", "0", "0")
+ return FALSE
+
+ for(var/direction in cardinal)
+ var/turf/T = get_step(src, direction)
+ var/success = 0
+ for(var/b_type in blend_objects)
+ if(istype(T, b_type))
+ success = 1
+ if(propagate)
+ var/turf/simulated/wall/W = T
+ if(istype(W))
+ W.update_connections(1)
+ if(success)
+ break
+ if(success)
+ break
+ if(!success)
+ for(var/obj/O in T)
+ for(var/b_type in blend_objects)
+ if(istype(O, b_type))
+ success = 1
+ for(var/obj/structure/S in T)
+ if(istype(S, src))
+ success = 0
+ for(var/nb_type in noblend_objects)
+ if(istype(O, nb_type))
+ success = 0
+
+ if(success)
+ break
+ if(success)
+ break
+
+ if(success)
+ dirs += get_dir(src, T)
+ other_dirs += get_dir(src, T)
+
+ refresh_neighbors()
+
+ connections = dirs_to_corner_states(dirs)
+ other_connections = dirs_to_corner_states(other_dirs)
+ return TRUE
+
+/obj/structure/proc/refresh_neighbors()
+ for(var/thing in RANGE_TURFS(1, src))
+ var/turf/T = thing
+ T.update_icon()
diff --git a/code/game/objects/structures/barsign.dm b/code/game/objects/structures/barsign.dm
index 13babf8a3d..cd1c448b2f 100644
--- a/code/game/objects/structures/barsign.dm
+++ b/code/game/objects/structures/barsign.dm
@@ -14,16 +14,16 @@
. -= "Off"
/obj/structure/sign/double/barsign/examine(mob/user)
- ..()
+ . = ..()
switch(icon_state)
if("Off")
- to_chat(user, "It appears to be switched off.")
+ . += "It appears to be switched off."
if("narsiebistro")
- to_chat(user, "It shows a picture of a large black and red being. Spooky!")
+ . += "It shows a picture of a large black and red being. Spooky!"
if("on", "empty")
- to_chat(user, "The lights are on, but there's no picture.")
+ . += "The lights are on, but there's no picture."
else
- to_chat(user, "It says '[icon_state]'")
+ . += "It says '[icon_state]'"
/obj/structure/sign/double/barsign/New()
..()
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index 9f1af1cf1b..4180b78ec3 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -170,16 +170,14 @@ LINEN BINS
/obj/structure/bedsheetbin/examine(mob/user)
- ..(user)
+ . = ..()
if(amount < 1)
- to_chat(user, "There are no bed sheets in the bin.")
- return
- if(amount == 1)
- to_chat(user, "There is one bed sheet in the bin.")
- return
- to_chat(user, "There are [amount] bed sheets in the bin.")
-
+ . += "There are no bed sheets in the bin."
+ else if(amount == 1)
+ . += "There is one bed sheet in the bin."
+ else
+ . += "There are [amount] bed sheets in the bin."
/obj/structure/bedsheetbin/update_icon()
switch(amount)
diff --git a/code/game/objects/structures/bedsheet_bin_vr.dm b/code/game/objects/structures/bedsheet_bin_vr.dm
new file mode 100644
index 0000000000..e62ea51557
--- /dev/null
+++ b/code/game/objects/structures/bedsheet_bin_vr.dm
@@ -0,0 +1,15 @@
+/obj/item/weapon/bedsheet/cosmos
+ icon = 'icons/obj/items_vr.dmi'
+ icon_state = "sheetcosmos"
+
+/obj/item/weapon/bedsheet/cosmosdouble
+ icon = 'icons/obj/items_vr.dmi'
+ icon_state = "doublesheetcosmos"
+
+/obj/item/weapon/bedsheet/pirate
+ icon = 'icons/obj/items_vr.dmi'
+ icon_state = "sheetpirate"
+
+/obj/item/weapon/bedsheet/piratedouble
+ icon = 'icons/obj/items_vr.dmi'
+ icon_state = "doublesheetpirate"
diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm
index 26e040c7e9..85996cd61b 100644
--- a/code/game/objects/structures/catwalk.dm
+++ b/code/game/objects/structures/catwalk.dm
@@ -1,102 +1,119 @@
-// Based on catwalk.dm from https://github.com/Endless-Horizon/CEV-Eris
/obj/structure/catwalk
name = "catwalk"
desc = "Cats really don't like these things."
- plane = DECAL_PLANE
- layer = ABOVE_UTILITY
icon = 'icons/turf/catwalks.dmi'
icon_state = "catwalk"
+ plane = DECAL_PLANE
+ layer = ABOVE_UTILITY
density = 0
+ anchored = 1.0
+ var/hatch_open = FALSE
+ var/plating_color = null
+ var/obj/item/stack/tile/plated_tile = null
+ var/static/plating_colors = list(
+ /obj/item/stack/tile/floor = "#858a8f",
+ /obj/item/stack/tile/floor/dark = "#4f4f4f",
+ /obj/item/stack/tile/floor/white = "#e8e8e8")
var/health = 100
var/maxhealth = 100
- anchored = 1.0
/obj/structure/catwalk/Initialize()
. = ..()
- for(var/obj/structure/catwalk/O in range(1))
- O.update_icon()
for(var/obj/structure/catwalk/C in get_turf(src))
if(C != src)
- warning("Duplicate [type] in [loc] ([x], [y], [z])")
- return INITIALIZE_HINT_QDEL
+ qdel(C)
+ update_connections(1)
update_icon()
+
/obj/structure/catwalk/Destroy()
- var/turf/location = loc
- . = ..()
- location.alpha = initial(location.alpha)
- for(var/obj/structure/catwalk/L in orange(location, 1))
- L.update_icon()
+ redraw_nearby_catwalks()
+ update_falling()
+ return ..()
+
+/obj/structure/catwalk/proc/update_falling()
+ spawn(1) //We get called in Destroy() and things. We might not be gone yet, so let's just put this off.
+ if(istype(loc, /turf/simulated/open))
+ var/turf/simulated/open/O = loc
+ O.update() //Will cause anything on the open turf to fall if it should
+
+/obj/structure/catwalk/proc/redraw_nearby_catwalks()
+ for(var/direction in alldirs)
+ var/obj/structure/catwalk/L = locate() in get_step(src, direction)
+ if(L)
+ L.update_connections()
+ L.update_icon() //so siding get updated properly
+
/obj/structure/catwalk/update_icon()
- var/connectdir = 0
- for(var/direction in cardinal)
- if(locate(/obj/structure/catwalk, get_step(src, direction)))
- connectdir |= direction
-
- //Check the diagonal connections for corners, where you have, for example, connections both north and east. In this case it checks for a north-east connection to determine whether to add a corner marker or not.
- var/diagonalconnect = 0 //1 = NE; 2 = SE; 4 = NW; 8 = SW
- //NORTHEAST
- if(connectdir & NORTH && connectdir & EAST)
- if(locate(/obj/structure/catwalk, get_step(src, NORTHEAST)))
- diagonalconnect |= 1
- //SOUTHEAST
- if(connectdir & SOUTH && connectdir & EAST)
- if(locate(/obj/structure/catwalk, get_step(src, SOUTHEAST)))
- diagonalconnect |= 2
- //NORTHWEST
- if(connectdir & NORTH && connectdir & WEST)
- if(locate(/obj/structure/catwalk, get_step(src, NORTHWEST)))
- diagonalconnect |= 4
- //SOUTHWEST
- if(connectdir & SOUTH && connectdir & WEST)
- if(locate(/obj/structure/catwalk, get_step(src, SOUTHWEST)))
- diagonalconnect |= 8
-
- icon_state = "catwalk[connectdir]-[diagonalconnect]"
-
+ update_connections()
+ cut_overlays()
+ icon_state = ""
+ var/image/I
+ if(!hatch_open)
+ for(var/i = 1 to 4)
+ I = image(icon, "catwalk[connections[i]]", dir = 1<<(i-1))
+ add_overlay(I)
+ if(plating_color)
+ I = image(icon, "plated")
+ I.color = plating_color
+ add_overlay(I)
/obj/structure/catwalk/ex_act(severity)
switch(severity)
- if(1.0)
+ if(1)
+ new /obj/item/stack/rods(src.loc)
qdel(src)
- if(2.0)
+ if(2)
+ new /obj/item/stack/rods(src.loc)
qdel(src)
- if(3.0)
- qdel(src)
- return
+
+/obj/structure/catwalk/attack_robot(var/mob/user)
+ if(Adjacent(user))
+ attack_hand(user)
+
+/obj/structure/catwalk/proc/deconstruct(mob/user)
+ playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ to_chat(user, "Slicing \the [src] joints ...")
+ new /obj/item/stack/rods(src.loc)
+ new /obj/item/stack/rods(src.loc)
+ //Lattice would delete itself, but let's save ourselves a new obj
+ if(istype(src.loc, /turf/space) || istype(src.loc, /turf/simulated/open))
+ new /obj/structure/lattice/(src.loc)
+ if(plated_tile)
+ new plated_tile(src.loc)
+ qdel(src)
/obj/structure/catwalk/attackby(obj/item/C as obj, mob/user as mob)
- if(istype(C, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = C
- if(WT.isOn())
- if(WT.remove_fuel(0, user))
- to_chat(user, "Slicing lattice joints ...")
- new /obj/item/stack/rods(src.loc)
- new /obj/item/stack/rods(src.loc)
- new /obj/structure/lattice(src.loc)
- qdel(src)
- if(C.is_screwdriver())
- if(health < maxhealth)
- to_chat(user, "You begin repairing \the [src.name] with \the [C.name].")
- if(do_after(user, 20, src))
- health = maxhealth
- else
- take_damage(C.force)
- user.setClickCooldown(user.get_attack_speed(C))
- return ..()
+ if(C.is_crowbar() && plated_tile)
+ hatch_open = !hatch_open
+ if(hatch_open)
+ playsound(src, 'sound/items/Crowbar.ogg', 100, 2)
+ to_chat(user, "You pry open \the [src]'s maintenance hatch.")
+ update_falling()
+ else
+ playsound(src, 'sound/items/Deconstruct.ogg', 100, 2)
+ to_chat(user, "You shut \the [src]'s maintenance hatch.")
+ update_icon()
+ return
+ if(istype(C, /obj/item/stack/tile/floor) && !plated_tile)
+ var/obj/item/stack/tile/floor/ST = C
+ to_chat(user, "Placing tile...")
+ if (!do_after(user, 10))
+ return
+ if(!ST.use(1))
+ return
+ to_chat(user, "You plate \the [src]")
+ name = "plated catwalk"
+ plated_tile = C.type
+ src.add_fingerprint(user)
+ for(var/tiletype in plating_colors)
+ if(istype(ST, tiletype))
+ plating_color = plating_colors[tiletype]
+ update_icon()
-/obj/structure/catwalk/Crossed()
- . = ..()
- if(isliving(usr) && !usr.is_incorporeal())
- playsound(src, pick('sound/effects/footstep/catwalk1.ogg', 'sound/effects/footstep/catwalk2.ogg', 'sound/effects/footstep/catwalk3.ogg', 'sound/effects/footstep/catwalk4.ogg', 'sound/effects/footstep/catwalk5.ogg'), 25, 1)
-
-/obj/structure/catwalk/CheckExit(atom/movable/O, turf/target)
- if(O.checkpass(PASSGRILLE))
- return 1
- if(target && target.z < src.z)
- return 0
- return 1
+/obj/structure/catwalk/refresh_neighbors()
+ return
/obj/structure/catwalk/take_damage(amount)
health -= amount
@@ -104,4 +121,66 @@
visible_message("\The [src] breaks down!")
playsound(loc, 'sound/effects/grillehit.ogg', 50, 1)
new /obj/item/stack/rods(get_turf(src))
- Destroy()
\ No newline at end of file
+ Destroy()
+
+/obj/structure/catwalk/Crossed()
+ . = ..()
+ if(isliving(usr) && !usr.is_incorporeal())
+ playsound(src, pick('sound/effects/footstep/catwalk1.ogg', 'sound/effects/footstep/catwalk2.ogg', 'sound/effects/footstep/catwalk3.ogg', 'sound/effects/footstep/catwalk4.ogg', 'sound/effects/footstep/catwalk5.ogg'), 25, 1)
+
+/obj/effect/catwalk_plated
+ name = "plated catwalk spawner"
+ icon = 'icons/turf/catwalks.dmi'
+ icon_state = "catwalk_plated"
+ density = 1
+ anchored = 1.0
+ var/activated = FALSE
+ plane = DECAL_PLANE
+ layer = ABOVE_UTILITY
+ var/tile = /obj/item/stack/tile/floor
+ var/platecolor = "#858a8f"
+
+/obj/effect/catwalk_plated/Initialize(mapload)
+ . = ..()
+ activate()
+
+/obj/effect/catwalk_plated/CanPass()
+ return 0
+
+/obj/effect/catwalk_plated/attack_hand()
+ attack_generic()
+
+/obj/effect/catwalk_plated/attack_ghost()
+ attack_generic()
+
+/obj/effect/catwalk_plated/attack_generic()
+ activate()
+
+/obj/effect/catwalk_plated/proc/activate()
+ if(activated) return
+
+ if(locate(/obj/structure/catwalk) in loc)
+ warning("Frame Spawner: A catwalk already exists at [loc.x]-[loc.y]-[loc.z]")
+ else
+ var/obj/structure/catwalk/C = new /obj/structure/catwalk(loc)
+ C.plated_tile = tile
+ C.plating_color = platecolor
+ C.name = "plated catwalk"
+ C.update_icon()
+ activated = 1
+ /* We don't have wallframes - yet
+ for(var/turf/T in orange(src, 1))
+ for(var/obj/effect/wallframe_spawn/other in T)
+ if(!other.activated) other.activate()
+ */
+ qdel(src)
+
+/obj/effect/catwalk_plated/dark
+ icon_state = "catwalk_plateddark"
+ tile = /obj/item/stack/tile/floor/dark
+ platecolor = "#4f4f4f"
+
+/obj/effect/catwalk_plated/white
+ icon_state = "catwalk_platedwhite"
+ tile = /obj/item/stack/tile/floor/white
+ platecolor = "#e8e8e8"
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index b75e3de6ed..55cb97c3cb 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -58,24 +58,25 @@
update_icon()
/obj/structure/closet/examine(mob/user)
- if(!src.opened && (..(user, 1) || isobserver(user)))
+ . = ..()
+ if(Adjacent(user) || isobserver(user))
var/content_size = 0
for(var/obj/item/I in src.contents)
if(!I.anchored)
content_size += CEILING(I.w_class/2, 1)
if(!content_size)
- to_chat(user, "It is empty.")
+ . += "It is empty."
else if(storage_capacity > content_size*4)
- to_chat(user, "It is barely filled.")
+ . += "It is barely filled."
else if(storage_capacity > content_size*2)
- to_chat(user, "It is less than half full.")
+ . += "It is less than half full."
else if(storage_capacity > content_size)
- to_chat(user, "There is still some free space.")
+ . += "There is still some free space."
else
- to_chat(user, "It is full.")
+ . += "It is full."
if(!src.opened && isobserver(user))
- to_chat(user, "It contains: [counting_english_list(contents)]")
+ . += "It contains: [counting_english_list(contents)]"
/obj/structure/closet/CanPass(atom/movable/mover, turf/target)
if(wall_mounted)
diff --git a/code/game/objects/structures/crates_lockers/closets/coffin.dm b/code/game/objects/structures/crates_lockers/closets/coffin.dm
index 9257c2d3a3..7ea80de7ff 100644
--- a/code/game/objects/structures/crates_lockers/closets/coffin.dm
+++ b/code/game/objects/structures/crates_lockers/closets/coffin.dm
@@ -161,4 +161,7 @@
var/datum/gas_mixture/above_air = return_air()
grave_breath.adjust_gas(gasid, BREATH_MOLES)
grave_breath.temperature = (above_air.temperature) - 30 //Underground
- return grave_breath
\ No newline at end of file
+ return grave_breath
+
+/obj/structure/closet/grave/dirthole
+ name = "hole"
diff --git a/maps/southern_cross/structures/closets/misc_vr.dm b/code/game/objects/structures/crates_lockers/closets/misc_vr.dm
similarity index 64%
rename from maps/southern_cross/structures/closets/misc_vr.dm
rename to code/game/objects/structures/crates_lockers/closets/misc_vr.dm
index 11ebc922d4..851da13468 100644
--- a/maps/southern_cross/structures/closets/misc_vr.dm
+++ b/code/game/objects/structures/crates_lockers/closets/misc_vr.dm
@@ -1,4 +1,42 @@
+//Gun Cabinets
+
+/obj/structure/closet/secure_closet/guncabinet/sidearm
+ name = "emergency weapon cabinet"
+ req_one_access = list(access_armory,access_captain)
+
+ starts_with = list(
+ /obj/item/weapon/gun/energy/gun = 4)
+
+
+/obj/structure/closet/secure_closet/guncabinet/rifle
+ name = "rifle cabinet"
+ req_one_access = list(access_explorer,access_brig)
+
+ starts_with = list(
+ /obj/item/ammo_magazine/clip/c762/hunter = 9,
+ /obj/item/weapon/gun/projectile/shotgun/pump/rifle = 2)
+
+/obj/structure/closet/secure_closet/guncabinet/rifle/Initialize()
+ if(prob(85))
+ starts_with += /obj/item/weapon/gun/projectile/shotgun/pump/rifle
+ else
+ starts_with += /obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever
+ return ..()
+
+/obj/structure/closet/secure_closet/guncabinet/phase
+ name = "explorer weapon cabinet"
+ req_one_access = list(access_explorer,access_brig)
+
+ starts_with = list(
+ /obj/item/weapon/gun/energy/phasegun = 2,
+ /obj/item/weapon/gun/energy/phasegun/pistol,
+ /obj/item/weapon/cell/device/weapon = 2,
+ /obj/item/clothing/accessory/permit/gun/planetside)
+
+//Explorer Lockers
+
/obj/structure/closet/secure_closet/explorer
+ name = "explorer locker"
icon = 'icons/obj/closet_vr.dmi'
icon_state = "secureexp1"
icon_closed = "secureexp"
@@ -6,6 +44,7 @@
icon_opened = "secureexpopen"
icon_broken = "secureexpbroken"
icon_off = "secureexpoff"
+ req_access = list(access_explorer)
starts_with = list(
/obj/item/clothing/under/explorer,
@@ -14,6 +53,8 @@
/obj/item/clothing/shoes/boots/winter/explorer,
/obj/item/clothing/gloves/black,
/obj/item/device/radio/headset/explorer,
+ /obj/item/device/radio/headset/explorer/alt,
+ /obj/item/weapon/cartridge/explorer,
/obj/item/device/flashlight,
/obj/item/device/gps/explorer,
/obj/item/weapon/storage/box/flare,
@@ -28,8 +69,25 @@
/obj/item/weapon/reagent_containers/food/snacks/liquidprotein,
/obj/item/device/cataloguer)
+/obj/structure/closet/secure_closet/explorer/Initialize()
+ if(prob(50))
+ starts_with += /obj/item/weapon/storage/backpack
+ else
+ starts_with += /obj/item/weapon/storage/backpack/satchel/norm
+ return ..()
+
+//SAR Lockers
+
/obj/structure/closet/secure_closet/sar
name = "field medic locker"
+ desc = "Supplies for a wilderness first responder."
+ icon_state = "medical1"
+ icon_closed = "medical"
+ icon_locked = "medical1"
+ icon_opened = "medicalopen"
+ icon_broken = "medicalbroken"
+ icon_off = "medicaloff"
+ req_access = list(access_medical_equip)
starts_with = list(
/obj/item/weapon/storage/backpack/dufflebag/emt,
@@ -45,7 +103,8 @@
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/sar,
/obj/item/clothing/shoes/boots/winter/explorer,
/obj/item/device/radio/headset/sar,
- /obj/item/weapon/cartridge/medical,
+ /obj/item/device/radio/headset/sar/alt,
+ /obj/item/weapon/cartridge/sar,
/obj/item/device/flashlight,
/obj/item/weapon/tank/emergency/oxygen/engi,
/obj/item/clothing/glasses/hud/health,
@@ -64,7 +123,12 @@
/obj/item/bodybag/cryobag,
/obj/item/device/cataloguer/compact)
+//Pilot Locker
+
/obj/structure/closet/secure_closet/pilot
+ name = "pilot locker"
+ req_access = list(access_pilot)
+
starts_with = list(
/obj/item/weapon/storage/backpack/parachute,
/obj/item/weapon/material/knife/tacknife/survival,
@@ -76,7 +140,9 @@
/obj/item/clothing/mask/gas/half,
/obj/item/clothing/shoes/black,
/obj/item/clothing/gloves/fingerless,
+ /obj/item/device/radio/headset/pilot,
/obj/item/device/radio/headset/pilot/alt,
+ /obj/item/weapon/cartridge/explorer,
/obj/item/device/flashlight,
/obj/item/weapon/reagent_containers/food/snacks/liquidfood,
/obj/item/weapon/reagent_containers/food/snacks/liquidprotein,
@@ -87,6 +153,13 @@
/obj/item/device/gps/explorer,
/obj/item/device/cataloguer/compact)
+/obj/structure/closet/secure_closet/pilot/Initialize()
+ if(prob(50))
+ starts_with += /obj/item/weapon/storage/backpack
+ else
+ starts_with += /obj/item/weapon/storage/backpack/satchel/norm
+ return ..()
+
/obj/structure/closet/secure_closet/pathfinder
name = "pathfinder locker"
icon = 'icons/obj/closet_vr.dmi'
@@ -104,7 +177,9 @@
/obj/item/clothing/mask/gas/explorer,
/obj/item/clothing/shoes/boots/winter/explorer,
/obj/item/clothing/gloves/black,
- /obj/item/device/radio/headset/explorer,
+ /obj/item/device/radio/headset/pathfinder,
+ /obj/item/device/radio/headset/pathfinder/alt,
+ /obj/item/weapon/cartridge/explorer,
/obj/item/device/flashlight,
/obj/item/device/gps/explorer,
/obj/item/weapon/storage/box/flare,
@@ -128,3 +203,17 @@
else
starts_with += /obj/item/weapon/storage/backpack/satchel/norm
return ..()
+
+//Exotic Seeds Crate
+
+/obj/structure/closet/crate/hydroponics/exotic
+ name = "exotic seeds crate"
+ desc = "All you need to destroy that pesky planet."
+
+ starts_with = list(
+ /obj/item/seeds/random = 6,
+ /obj/item/seeds/replicapod = 2,
+ /obj/item/seeds/ambrosiavulgarisseed = 2,
+ /obj/item/seeds/kudzuseed,
+ /obj/item/seeds/libertymycelium,
+ /obj/item/seeds/reishimycelium)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
index c292a548be..d7b6ed4e80 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
@@ -47,8 +47,8 @@
/obj/item/clothing/under/rank/cargo/jeans,
/obj/item/clothing/under/rank/cargo/jeans/female,
/obj/item/clothing/shoes/brown,
- /obj/item/device/radio/headset/headset_cargo,
- /obj/item/device/radio/headset/headset_cargo/alt,
+ /obj/item/device/radio/headset/headset_qm, //VOREStation Edit,
+ /obj/item/device/radio/headset/headset_qm/alt, //VOREStation Edit,
/obj/item/clothing/gloves/black,
/obj/item/clothing/gloves/fingerless,
/obj/item/clothing/suit/fire/firefighter,
diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
index b15f45d6fb..903a058f9c 100644
--- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
@@ -21,32 +21,35 @@
/obj/structure/closet/emcloset/Initialize()
switch (pickweight(list("small" = 55, "aid" = 25, "tank" = 10, "both" = 10)))
+ //VOREStation Block Edit Start - Modified List
if ("small")
starts_with = list(
/obj/item/weapon/tank/emergency/oxygen = 2,
/obj/item/clothing/mask/breath = 2,
- /obj/item/clothing/suit/space/emergency,
- /obj/item/clothing/head/helmet/space/emergency)
+ /obj/item/clothing/suit/space/emergency = 2,
+ /obj/item/clothing/head/helmet/space/emergency = 2)
if ("aid")
starts_with = list(
/obj/item/weapon/tank/emergency/oxygen,
/obj/item/weapon/storage/toolbox/emergency,
/obj/item/clothing/mask/breath,
- /obj/item/weapon/storage/firstaid/o2,
/obj/item/clothing/suit/space/emergency,
/obj/item/clothing/head/helmet/space/emergency)
if ("tank")
starts_with = list(
/obj/item/weapon/tank/emergency/oxygen/engi = 2,
- /obj/item/clothing/mask/breath = 2)
+ /obj/item/clothing/mask/breath = 2,
+ /obj/item/clothing/suit/space/emergency = 2,
+ /obj/item/clothing/head/helmet/space/emergency = 2)
if ("both")
starts_with = list(
/obj/item/weapon/storage/toolbox/emergency,
- /obj/item/weapon/tank/emergency/oxygen/engi,
- /obj/item/clothing/mask/breath,
/obj/item/weapon/storage/firstaid/o2,
+ /obj/item/weapon/tank/emergency/oxygen/engi = 2,
+ /obj/item/clothing/mask/breath = 2,
/obj/item/clothing/suit/space/emergency = 2,
/obj/item/clothing/head/helmet/space/emergency = 2)
+ //VOREStation Block Edit End
return ..()
diff --git a/code/game/objects/structures/crates_lockers/vehiclecage.dm b/code/game/objects/structures/crates_lockers/vehiclecage.dm
index bd525832c1..b565124e78 100644
--- a/code/game/objects/structures/crates_lockers/vehiclecage.dm
+++ b/code/game/objects/structures/crates_lockers/vehiclecage.dm
@@ -9,9 +9,9 @@
var/paint_color = "#666666"
/obj/structure/vehiclecage/examine(mob/user)
- ..()
+ . = ..()
if(my_vehicle)
- to_chat(user, "It seems to contain \the [my_vehicle].")
+ . += "It seems to contain \the [my_vehicle]."
/obj/structure/vehiclecage/Initialize()
. = ..()
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index f8ea5d2f77..e0a94e285b 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -145,7 +145,7 @@
bound_height = width * world.icon_size
update_state()
- Move()
+ Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
if(dir in list(EAST, WEST))
bound_width = width * world.icon_size
diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm
index ae5cba7cf0..b3f174e25a 100644
--- a/code/game/objects/structures/electricchair.dm
+++ b/code/game/objects/structures/electricchair.dm
@@ -56,7 +56,7 @@
return
if(!A.powered(EQUIP))
return
- A.use_power(EQUIP, 5000)
+ A.use_power_oneoff(5000, EQUIP)
var/light = A.power_light
A.updateicon()
diff --git a/code/game/objects/structures/fence.dm b/code/game/objects/structures/fence.dm
index bb99d37d3a..839269847a 100644
--- a/code/game/objects/structures/fence.dm
+++ b/code/game/objects/structures/fence.dm
@@ -32,9 +32,9 @@
switch(hole_size)
if(MEDIUM_HOLE)
- user.show_message("There is a large hole in \the [src].")
+ . += "There is a large hole in it."
if(LARGE_HOLE)
- user.show_message("\The [src] has been completely cut through.")
+ . += "It has been completely cut through."
/obj/structure/fence/get_description_interaction()
var/list/results = list()
diff --git a/code/game/objects/structures/fitness.dm b/code/game/objects/structures/fitness.dm
index 158bf5533b..f0b121a1aa 100644
--- a/code/game/objects/structures/fitness.dm
+++ b/code/game/objects/structures/fitness.dm
@@ -57,7 +57,7 @@
flick("[icon_state]_[weight]", src)
if(do_after(user, 20 + (weight * 10)))
playsound(src.loc, 'sound/effects/weightdrop.ogg', 25, 1)
- user.nutrition -= weight * 10
+ user.adjust_nutrition(weight * -10)
to_chat(user, "You lift the weights [qualifiers[weight]].")
being_used = 0
else
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora/flora.dm
similarity index 92%
rename from code/game/objects/structures/flora.dm
rename to code/game/objects/structures/flora/flora.dm
index a5a8704dc1..a0f2c8c307 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora/flora.dm
@@ -1,478 +1,493 @@
-
-/obj/structure/flora
- name = "flora"
- desc = "A perfectly generic plant."
-
- anchored = TRUE // Usually, plants don't move. Usually.
- plane = DECAL_PLANE
- layer = BELOW_MOB_LAYER
-
- var/randomize_size = FALSE
- var/max_x_scale = 1.25
- var/max_y_scale = 1.25
- var/min_x_scale = 0.9
- var/min_y_scale = 0.9
-
- var/harvest_tool = null // The type of item used to harvest the plant.
- var/harvest_count = 0
-
- var/randomize_harvest_count = TRUE
- var/max_harvests = 0
- var/min_harvests = -1
- var/list/harvest_loot = null // Should be an associative list for things to spawn, and their weights. An example would be a branch from a tree.
-
-/obj/structure/flora/Initialize()
- ..()
-
- if(randomize_size)
- icon_scale_x = rand(min_x_scale * 100, max_x_scale * 100) / 100
- icon_scale_y = rand(min_y_scale * 100, max_y_scale * 100) / 100
-
- if(prob(50))
- icon_scale_x *= -1
- update_transform()
-
- if(randomize_harvest_count)
- max_harvests = max(0, rand(min_harvests, max_harvests)) // Incase you want to weight it more toward 'not harvestable', set min_harvests to a negative value.
-
-/obj/structure/flora/examine(mob/user)
- . = ..(user)
- if(harvest_count < max_harvests)
- to_chat(user, "\The [src] seems to have something hanging from it.")
-
-/obj/structure/flora/attackby(var/obj/item/weapon/W, var/mob/living/user)
- if(can_harvest(W))
- var/harvest_spawn = pickweight(harvest_loot)
- var/atom/movable/AM = spawn_harvest(harvest_spawn, user)
-
- if(!AM)
- to_chat(user, "You fail to harvest anything from \the [src].")
-
- else
- to_chat(user, "You harvest \the [AM] from \the [src].")
- return
-
- ..(W, user)
-
-/obj/structure/flora/proc/can_harvest(var/obj/item/I)
- . = FALSE
- if(harvest_tool && istype(I, harvest_tool) && harvest_loot && harvest_loot.len && harvest_count < max_harvests)
- . = TRUE
- return .
-
-/obj/structure/flora/proc/spawn_harvest(var/path = null, var/mob/user = null)
- if(!ispath(path))
- return 0
- var/turf/Target = get_turf(src)
- if(user)
- Target = get_turf(user)
-
- var/atom/movable/AM = new path(Target)
-
- harvest_count++
- return AM
-
-//bushes
-/obj/structure/flora/bush
- name = "bush"
- icon = 'icons/obj/flora/snowflora.dmi'
- icon_state = "snowbush1"
-
-/obj/structure/flora/bush/New()
- ..()
- icon_state = "snowbush[rand(1, 6)]"
-
-/obj/structure/flora/pottedplant
- name = "potted plant"
- desc = "Really ties the room together."
- icon = 'icons/obj/plants.dmi'
- icon_state = "plant-26"
-
- anchored = FALSE
-
-//newbushes
-
-/obj/structure/flora/ausbushes
- name = "bush"
- icon = 'icons/obj/flora/ausflora.dmi'
- icon_state = "firstbush_1"
-
-/obj/structure/flora/ausbushes/New()
- ..()
- icon_state = "firstbush_[rand(1, 4)]"
-
-/obj/structure/flora/ausbushes/reedbush
- icon_state = "reedbush_1"
-
-/obj/structure/flora/ausbushes/reedbush/New()
- ..()
- icon_state = "reedbush_[rand(1, 4)]"
-
-/obj/structure/flora/ausbushes/leafybush
- icon_state = "leafybush_1"
-
-/obj/structure/flora/ausbushes/leafybush/New()
- ..()
- icon_state = "leafybush_[rand(1, 3)]"
-
-/obj/structure/flora/ausbushes/palebush
- icon_state = "palebush_1"
-
-/obj/structure/flora/ausbushes/palebush/New()
- ..()
- icon_state = "palebush_[rand(1, 4)]"
-
-/obj/structure/flora/ausbushes/stalkybush
- icon_state = "stalkybush_1"
-
-/obj/structure/flora/ausbushes/stalkybush/New()
- ..()
- icon_state = "stalkybush_[rand(1, 3)]"
-
-/obj/structure/flora/ausbushes/grassybush
- icon_state = "grassybush_1"
-
-/obj/structure/flora/ausbushes/grassybush/New()
- ..()
- icon_state = "grassybush_[rand(1, 4)]"
-
-/obj/structure/flora/ausbushes/fernybush
- icon_state = "fernybush_1"
-
-/obj/structure/flora/ausbushes/fernybush/New()
- ..()
- icon_state = "fernybush_[rand(1, 3)]"
-
-/obj/structure/flora/ausbushes/sunnybush
- icon_state = "sunnybush_1"
-
-/obj/structure/flora/ausbushes/sunnybush/New()
- ..()
- icon_state = "sunnybush_[rand(1, 3)]"
-
-/obj/structure/flora/ausbushes/genericbush
- icon_state = "genericbush_1"
-
-/obj/structure/flora/ausbushes/genericbush/New()
- ..()
- icon_state = "genericbush_[rand(1, 4)]"
-
-/obj/structure/flora/ausbushes/pointybush
- icon_state = "pointybush_1"
-
-/obj/structure/flora/ausbushes/pointybush/New()
- ..()
- icon_state = "pointybush_[rand(1, 4)]"
-
-/obj/structure/flora/ausbushes/lavendergrass
- icon_state = "lavendergrass_1"
-
-/obj/structure/flora/ausbushes/lavendergrass/New()
- ..()
- icon_state = "lavendergrass_[rand(1, 4)]"
-
-/obj/structure/flora/ausbushes/ywflowers
- icon_state = "ywflowers_1"
-
-/obj/structure/flora/ausbushes/ywflowers/New()
- ..()
- icon_state = "ywflowers_[rand(1, 3)]"
-
-/obj/structure/flora/ausbushes/brflowers
- icon_state = "brflowers_1"
-
-/obj/structure/flora/ausbushes/brflowers/New()
- ..()
- icon_state = "brflowers_[rand(1, 3)]"
-
-/obj/structure/flora/ausbushes/ppflowers
- icon_state = "ppflowers_1"
-
-/obj/structure/flora/ausbushes/ppflowers/New()
- ..()
- icon_state = "ppflowers_[rand(1, 3)]"
-
-/obj/structure/flora/ausbushes/sparsegrass
- icon_state = "sparsegrass_1"
-
-/obj/structure/flora/ausbushes/sparsegrass/New()
- ..()
- icon_state = "sparsegrass_[rand(1, 3)]"
-
-/obj/structure/flora/ausbushes/fullgrass
- icon_state = "fullgrass_1"
-
-/obj/structure/flora/ausbushes/fullgrass/New()
- ..()
- icon_state = "fullgrass_[rand(1, 3)]"
-
-/obj/structure/flora/skeleton
- name = "hanging skeleton model"
- icon = 'icons/obj/plants.dmi' //what an interesting plant
- icon_state = "hangskele"
- desc = "It's an anatomical model of a human skeletal system made of plaster."
-
- plane = OBJ_PLANE
-
-//potted plants credit: Flashkirby
-/obj/structure/flora/pottedplant
- name = "potted plant"
- desc = "Really brings the room together."
- icon = 'icons/obj/plants.dmi'
- icon_state = "plant-01"
-
- plane = OBJ_PLANE
- var/obj/item/stored_item
-
-/obj/structure/flora/pottedplant/examine(mob/user)
- ..()
- if(in_range(user, src) && stored_item)
- to_chat(user, "You can see something in there...")
-
-/obj/structure/flora/pottedplant/attackby(obj/item/I, mob/user)
- if(stored_item)
- to_chat(user, "[I] won't fit in. There already appears to be something in here...")
- return
-
- if(I.w_class > ITEMSIZE_TINY)
- to_chat(user, "[I] is too big to fit inside [src].")
- return
-
- if(do_after(user, 10))
- user.drop_from_inventory(I, src)
- I.forceMove(src)
- stored_item = I
- src.visible_message("\icon[src] \icon[I] [user] places [I] into [src].")
- return
- else
- to_chat(user, "You refrain from putting things into the plant pot.")
- return
-
- ..()
-
-/obj/structure/flora/pottedplant/attack_hand(mob/user)
- if(!stored_item)
- to_chat(user, "You see nothing of interest in [src]...")
- else
- if(do_after(user, 10))
- to_chat(user, "You find \icon[stored_item] [stored_item] in [src]!")
- stored_item.forceMove(get_turf(src))
- stored_item = null
- ..()
-
-
-/obj/structure/flora/pottedplant/large
- name = "large potted plant"
- desc = "This is a large plant. Three branches support pairs of waxy leaves."
- icon_state = "plant-26"
-
-/obj/structure/flora/pottedplant/fern
- name = "potted fern"
- desc = "This is an ordinary looking fern. It looks like it could do with some water."
- icon_state = "plant-02"
-
-/obj/structure/flora/pottedplant/overgrown
- name = "overgrown potted plants"
- desc = "This is an assortment of colourful plants. Some parts are overgrown."
- icon_state = "plant-03"
-
-/obj/structure/flora/pottedplant/bamboo
- name = "potted bamboo"
- desc = "These are bamboo shoots. The tops looks like they've been cut short."
- icon_state = "plant-04"
-
-/obj/structure/flora/pottedplant/largebush
- name = "large potted bush"
- desc = "This is a large bush. The leaves stick upwards in an odd fashion."
- icon_state = "plant-05"
-
-/obj/structure/flora/pottedplant/thinbush
- name = "thin potted bush"
- desc = "This is a thin bush. It appears to be flowering."
- icon_state = "plant-06"
-
-/obj/structure/flora/pottedplant/mysterious
- name = "mysterious potted bulbs"
- desc = "This is a mysterious looking plant. Touching the bulbs cause them to shrink."
- icon_state = "plant-07"
- catalogue_data = list(/datum/category_item/catalogue/flora/eyebulbs)
-
-/obj/structure/flora/pottedplant/smalltree
- name = "small potted tree"
- desc = "This is a small tree. It is rather pleasant."
- icon_state = "plant-08"
-
-/obj/structure/flora/pottedplant/unusual
- name = "unusual potted plant"
- desc = "This is an unusual plant. It's bulbous ends emit a soft blue light."
- icon_state = "plant-09"
- light_range = 2
- light_power = 0.6
- light_color = "#33CCFF"
- catalogue_data = list(/datum/category_item/catalogue/flora/sif_tree)
-
-/obj/structure/flora/pottedplant/orientaltree
- name = "potted oriental tree"
- desc = "This is a rather oriental style tree. Its flowers are bright pink."
- icon_state = "plant-10"
-
-/obj/structure/flora/pottedplant/smallcactus
- name = "small potted cactus"
- desc = "This is a small cactus. Its needles are sharp."
- icon_state = "plant-11"
-
-/obj/structure/flora/pottedplant/tall
- name = "tall potted plant"
- desc = "This is a tall plant. Tiny pores line its surface."
- icon_state = "plant-12"
-
-/obj/structure/flora/pottedplant/sticky
- name = "sticky potted plant"
- desc = "This is an odd plant. Its sticky leaves trap insects."
- icon_state = "plant-13"
-
-/obj/structure/flora/pottedplant/smelly
- name = "smelly potted plant"
- desc = "This is some kind of tropical plant. It reeks of rotten eggs."
- icon_state = "plant-14"
-
-/obj/structure/flora/pottedplant/small
- name = "small potted plant"
- desc = "This is a pot of assorted small flora. Some look familiar."
- icon_state = "plant-15"
-
-/obj/structure/flora/pottedplant/aquatic
- name = "aquatic potted plant"
- desc = "This is apparently an aquatic plant. It's probably fake."
- icon_state = "plant-16"
-
-/obj/structure/flora/pottedplant/shoot
- name = "small potted shoot"
- desc = "This is a small shoot. It still needs time to grow."
- icon_state = "plant-17"
-
-/obj/structure/flora/pottedplant/flower
- name = "potted flower"
- desc = "This is a slim plant. Sweet smelling flowers are supported by spindly stems."
- icon_state = "plant-18"
-
-/obj/structure/flora/pottedplant/crystal
- name = "crystalline potted plant"
- desc = "These are rather cubic plants. Odd crystal formations grow on the end."
- icon_state = "plant-19"
-
-/obj/structure/flora/pottedplant/subterranean
- name = "subterranean potted plant"
- desc = "This is a subterranean plant. It's bulbous ends glow faintly."
- icon_state = "plant-20"
- light_range = 2
- light_power = 0.6
- light_color = "#FF6633"
-
-/obj/structure/flora/pottedplant/minitree
- name = "potted tree"
- desc = "This is a miniature tree. Apparently it was grown to 1/5 scale."
- icon_state = "plant-21"
-
-/obj/structure/flora/pottedplant/stoutbush
- name = "stout potted bush"
- desc = "This is a stout bush. Its leaves point up and outwards."
- icon_state = "plant-22"
-
-/obj/structure/flora/pottedplant/drooping
- name = "drooping potted plant"
- desc = "This is a small plant. The drooping leaves make it look like its wilted."
- icon_state = "plant-23"
-
-/obj/structure/flora/pottedplant/tropical
- name = "tropical potted plant"
- desc = "This is some kind of tropical plant. It hasn't begun to flower yet."
- icon_state = "plant-24"
-
-/obj/structure/flora/pottedplant/dead
- name = "dead potted plant"
- desc = "This is the dried up remains of a dead plant. Someone should replace it."
- icon_state = "plant-25"
-
-/obj/structure/flora/pottedplant/decorative
- name = "decorative potted plant"
- desc = "This is a decorative shrub. It's been trimmed into the shape of an apple."
- icon_state = "applebush"
-
-/obj/structure/flora/pottedplant/xmas
- name = "small christmas tree"
- desc = "This is a tiny well lit decorative christmas tree."
- icon_state = "plant-xmas"
-
-/obj/structure/flora/sif
- icon = 'icons/obj/flora/sifflora.dmi'
-
-/obj/structure/flora/sif/attack_hand(mob/user)
- if (user.a_intent == I_HURT)
- if(do_after(user, 5 SECONDS))
- user.visible_message("\The [user] digs up \the [src.name].", "You dig up \the [src.name].")
- qdel(src)
- else
- user.visible_message("\The [user] pokes \the [src.name].", "You poke \the [src.name].")
-
-/datum/category_item/catalogue/flora/subterranean_bulbs
- name = "Sivian Flora - Subterranean Bulbs"
- desc = "A plant which is native to Sif, it continues the trend of being a bioluminescent specimen. These plants \
- are generally suited for conditions experienced in caverns, which are generally dark and cold. It is not \
- known why this plant evolved to be bioluminescent, however this property has, unintentionally, allowed for \
- it to spread much farther than before, with the assistance of humans.\
-
\
- In Sif's early history, Sivian settlers found this plant while they were establishing mines. Their ability \
- to emit low, but consistant amounts of light made them desirable to the settlers. They would often cultivate \
- this plant inside man-made tunnels and mines to act as a backup source of light that would not need \
- electricity. This technique has saved many lost miners, and this practice continues to this day."
- value = CATALOGUER_REWARD_EASY
-
-/obj/structure/flora/sif/subterranean
- name = "subterranean plant"
- desc = "This is a subterranean plant. It's bulbous ends glow faintly."
- icon_state = "glowplant"
- light_range = 2
- light_power = 0.6
- light_color = "#FF6633"
- catalogue_data = list(/datum/category_item/catalogue/flora/subterranean_bulbs)
-
-/obj/structure/flora/sif/subterranean/Initialize()
- icon_state = "[initial(icon_state)][rand(1,2)]"
- . = ..()
-
-
-/datum/category_item/catalogue/flora/eyebulbs
- name = "Sivian Flora - Eyebulbs"
- desc = "A plant native to Sif. On the end of its stems are bulbs which visually resemble \
- eyes, which shrink when touched. One theory is that the bulbs are a result of mimicry, appearing as eyeballs to protect from predators.
\
- These plants have no known use."
- value = CATALOGUER_REWARD_EASY
-
-/obj/structure/flora/sif/eyes
- name = "mysterious bulbs"
- desc = "This is a mysterious looking plant. They kind of look like eyeballs. Creepy."
- icon_state = "eyeplant"
- catalogue_data = list(/datum/category_item/catalogue/flora/eyebulbs)
-
-/obj/structure/flora/sif/eyes/Initialize()
- icon_state = "[initial(icon_state)][rand(1,3)]"
- . = ..()
-
-/datum/category_item/catalogue/flora/mosstendrils
- name = "Sivian Flora - Moss Stalks"
- desc = "A plant native to Sif. The plant is most closely related to the common, dense moss found covering Sif's terrain. \
- It has evolved a method of camouflage utilizing white hairs on its dorsal sides to make it appear as a small mound of snow from \
- above. It has no known use, though it is a common furnishing in contemporary homes."
- value = CATALOGUER_REWARD_TRIVIAL
-
-/obj/structure/flora/sif/tendrils
- name = "stocky tendrils"
- desc = "A 'plant' made up of hardened moss. It has tiny hairs that bunch together to look like snow."
- icon_state = "grass"
- randomize_size = TRUE
- catalogue_data = list(/datum/category_item/catalogue/flora/mosstendrils)
-
-/obj/structure/flora/sif/tendrils/Initialize()
- icon_state = "[initial(icon_state)][rand(1,3)]"
- . = ..()
+
+/obj/structure/flora
+ name = "flora"
+ desc = "A perfectly generic plant."
+
+ anchored = TRUE // Usually, plants don't move. Usually.
+ plane = DECAL_PLANE
+ layer = BELOW_MOB_LAYER
+
+ var/randomize_size = FALSE
+ var/max_x_scale = 1.25
+ var/max_y_scale = 1.25
+ var/min_x_scale = 0.9
+ var/min_y_scale = 0.9
+
+ var/harvest_tool = null // The type of item used to harvest the plant.
+ var/harvest_count = 0
+
+ var/randomize_harvest_count = TRUE
+ var/max_harvests = 0
+ var/min_harvests = -1
+ var/list/harvest_loot = null // Should be an associative list for things to spawn, and their weights. An example would be a branch from a tree.
+
+/obj/structure/flora/Initialize()
+ ..()
+
+ if(randomize_size)
+ icon_scale_x = rand(min_x_scale * 100, max_x_scale * 100) / 100
+ icon_scale_y = rand(min_y_scale * 100, max_y_scale * 100) / 100
+
+ if(prob(50))
+ icon_scale_x *= -1
+ update_transform()
+
+ if(randomize_harvest_count)
+ max_harvests = max(0, rand(min_harvests, max_harvests)) // Incase you want to weight it more toward 'not harvestable', set min_harvests to a negative value.
+
+/obj/structure/flora/examine(mob/user)
+ . = ..()
+ if(harvest_count < max_harvests)
+ . += get_harvestable_desc()
+
+/obj/structure/flora/proc/get_harvestable_desc()
+ return "\The [src] seems to have something hanging from it."
+
+/obj/structure/flora/attackby(var/obj/item/weapon/W, var/mob/living/user)
+ if(can_harvest(W))
+ var/harvest_spawn = pickweight(harvest_loot)
+ var/atom/movable/AM = spawn_harvest(harvest_spawn, user)
+
+ if(!AM)
+ to_chat(user, "You fail to harvest anything from \the [src].")
+
+ else
+ to_chat(user, "You harvest \the [AM] from \the [src].")
+ return
+
+ ..(W, user)
+
+/obj/structure/flora/proc/can_harvest(var/obj/item/I)
+ . = FALSE
+ if(harvest_tool && istype(I, harvest_tool) && harvest_loot && harvest_loot.len && harvest_count < max_harvests)
+ . = TRUE
+ return .
+
+/obj/structure/flora/proc/spawn_harvest(var/path = null, var/mob/user = null)
+ if(!ispath(path))
+ return 0
+ var/turf/Target = get_turf(src)
+ if(user)
+ Target = get_turf(user)
+
+ var/atom/movable/AM = new path(Target)
+
+ harvest_count++
+ return AM
+
+//bushes
+/obj/structure/flora/bush
+ name = "bush"
+ icon = 'icons/obj/flora/snowflora.dmi'
+ icon_state = "snowbush1"
+
+/obj/structure/flora/bush/New()
+ ..()
+ icon_state = "snowbush[rand(1, 6)]"
+
+/obj/structure/flora/pottedplant
+ name = "potted plant"
+ desc = "Really ties the room together."
+ icon = 'icons/obj/plants.dmi'
+ icon_state = "plant-26"
+
+ anchored = FALSE
+
+//newbushes
+
+/obj/structure/flora/ausbushes
+ name = "bush"
+ icon = 'icons/obj/flora/ausflora.dmi'
+ icon_state = "firstbush_1"
+
+/obj/structure/flora/ausbushes/New()
+ ..()
+ icon_state = "firstbush_[rand(1, 4)]"
+
+/obj/structure/flora/ausbushes/reedbush
+ icon_state = "reedbush_1"
+
+/obj/structure/flora/ausbushes/reedbush/New()
+ ..()
+ icon_state = "reedbush_[rand(1, 4)]"
+
+/obj/structure/flora/ausbushes/leafybush
+ icon_state = "leafybush_1"
+
+/obj/structure/flora/ausbushes/leafybush/New()
+ ..()
+ icon_state = "leafybush_[rand(1, 3)]"
+
+/obj/structure/flora/ausbushes/palebush
+ icon_state = "palebush_1"
+
+/obj/structure/flora/ausbushes/palebush/New()
+ ..()
+ icon_state = "palebush_[rand(1, 4)]"
+
+/obj/structure/flora/ausbushes/stalkybush
+ icon_state = "stalkybush_1"
+
+/obj/structure/flora/ausbushes/stalkybush/New()
+ ..()
+ icon_state = "stalkybush_[rand(1, 3)]"
+
+/obj/structure/flora/ausbushes/grassybush
+ icon_state = "grassybush_1"
+
+/obj/structure/flora/ausbushes/grassybush/New()
+ ..()
+ icon_state = "grassybush_[rand(1, 4)]"
+
+/obj/structure/flora/ausbushes/fernybush
+ icon_state = "fernybush_1"
+
+/obj/structure/flora/ausbushes/fernybush/New()
+ ..()
+ icon_state = "fernybush_[rand(1, 3)]"
+
+/obj/structure/flora/ausbushes/sunnybush
+ icon_state = "sunnybush_1"
+
+/obj/structure/flora/ausbushes/sunnybush/New()
+ ..()
+ icon_state = "sunnybush_[rand(1, 3)]"
+
+/obj/structure/flora/ausbushes/genericbush
+ icon_state = "genericbush_1"
+
+/obj/structure/flora/ausbushes/genericbush/New()
+ ..()
+ icon_state = "genericbush_[rand(1, 4)]"
+
+/obj/structure/flora/ausbushes/pointybush
+ icon_state = "pointybush_1"
+
+/obj/structure/flora/ausbushes/pointybush/New()
+ ..()
+ icon_state = "pointybush_[rand(1, 4)]"
+
+/obj/structure/flora/ausbushes/lavendergrass
+ icon_state = "lavendergrass_1"
+
+/obj/structure/flora/ausbushes/lavendergrass/New()
+ ..()
+ icon_state = "lavendergrass_[rand(1, 4)]"
+
+/obj/structure/flora/ausbushes/ywflowers
+ icon_state = "ywflowers_1"
+
+/obj/structure/flora/ausbushes/ywflowers/New()
+ ..()
+ icon_state = "ywflowers_[rand(1, 3)]"
+
+/obj/structure/flora/ausbushes/brflowers
+ icon_state = "brflowers_1"
+
+/obj/structure/flora/ausbushes/brflowers/New()
+ ..()
+ icon_state = "brflowers_[rand(1, 3)]"
+
+/obj/structure/flora/ausbushes/ppflowers
+ icon_state = "ppflowers_1"
+
+/obj/structure/flora/ausbushes/ppflowers/New()
+ ..()
+ icon_state = "ppflowers_[rand(1, 3)]"
+
+/obj/structure/flora/ausbushes/sparsegrass
+ icon_state = "sparsegrass_1"
+
+/obj/structure/flora/ausbushes/sparsegrass/New()
+ ..()
+ icon_state = "sparsegrass_[rand(1, 3)]"
+
+/obj/structure/flora/ausbushes/fullgrass
+ icon_state = "fullgrass_1"
+
+/obj/structure/flora/ausbushes/fullgrass/New()
+ ..()
+ icon_state = "fullgrass_[rand(1, 3)]"
+
+/obj/structure/flora/skeleton
+ name = "hanging skeleton model"
+ icon = 'icons/obj/plants.dmi' //what an interesting plant
+ icon_state = "hangskele"
+ desc = "It's an anatomical model of a human skeletal system made of plaster."
+
+ plane = OBJ_PLANE
+
+//potted plants credit: Flashkirby
+/obj/structure/flora/pottedplant
+ name = "potted plant"
+ desc = "Really brings the room together."
+ icon = 'icons/obj/plants.dmi'
+ icon_state = "plant-01"
+
+ plane = OBJ_PLANE
+ var/obj/item/stored_item
+
+/obj/structure/flora/pottedplant/examine(mob/user)
+ . = ..()
+ if(in_range(user, src) && stored_item)
+ . += "You can see something in there..."
+
+/obj/structure/flora/pottedplant/attackby(obj/item/I, mob/user)
+ if(stored_item)
+ to_chat(user, "[I] won't fit in. There already appears to be something in here...")
+ return
+
+ if(I.w_class > ITEMSIZE_TINY)
+ to_chat(user, "[I] is too big to fit inside [src].")
+ return
+
+ if(do_after(user, 10))
+ user.drop_from_inventory(I, src)
+ I.forceMove(src)
+ stored_item = I
+ src.visible_message("[bicon(src)] [bicon(I)] [user] places [I] into [src].")
+ return
+ else
+ to_chat(user, "You refrain from putting things into the plant pot.")
+ return
+
+ ..()
+
+/obj/structure/flora/pottedplant/attack_hand(mob/user)
+ if(!stored_item)
+ to_chat(user, "You see nothing of interest in [src]...")
+ else
+ if(do_after(user, 10))
+ to_chat(user, "You find [bicon(stored_item)] [stored_item] in [src]!")
+ stored_item.forceMove(get_turf(src))
+ stored_item = null
+ ..()
+
+
+/obj/structure/flora/pottedplant/large
+ name = "large potted plant"
+ desc = "This is a large plant. Three branches support pairs of waxy leaves."
+ icon_state = "plant-26"
+
+/obj/structure/flora/pottedplant/fern
+ name = "potted fern"
+ desc = "This is an ordinary looking fern. It looks like it could do with some water."
+ icon_state = "plant-02"
+
+/obj/structure/flora/pottedplant/overgrown
+ name = "overgrown potted plants"
+ desc = "This is an assortment of colourful plants. Some parts are overgrown."
+ icon_state = "plant-03"
+
+/obj/structure/flora/pottedplant/bamboo
+ name = "potted bamboo"
+ desc = "These are bamboo shoots. The tops looks like they've been cut short."
+ icon_state = "plant-04"
+
+/obj/structure/flora/pottedplant/largebush
+ name = "large potted bush"
+ desc = "This is a large bush. The leaves stick upwards in an odd fashion."
+ icon_state = "plant-05"
+
+/obj/structure/flora/pottedplant/thinbush
+ name = "thin potted bush"
+ desc = "This is a thin bush. It appears to be flowering."
+ icon_state = "plant-06"
+
+/obj/structure/flora/pottedplant/mysterious
+ name = "mysterious potted bulbs"
+ desc = "This is a mysterious looking plant. Touching the bulbs cause them to shrink."
+ icon_state = "plant-07"
+ catalogue_data = list(/datum/category_item/catalogue/flora/eyebulbs)
+
+/obj/structure/flora/pottedplant/smalltree
+ name = "small potted tree"
+ desc = "This is a small tree. It is rather pleasant."
+ icon_state = "plant-08"
+
+/obj/structure/flora/pottedplant/unusual
+ name = "unusual potted plant"
+ desc = "This is an unusual plant. It's bulbous ends emit a soft blue light."
+ icon_state = "plant-09"
+ light_range = 2
+ light_power = 0.6
+ light_color = "#33CCFF"
+ catalogue_data = list(/datum/category_item/catalogue/flora/sif_tree)
+
+/obj/structure/flora/pottedplant/orientaltree
+ name = "potted oriental tree"
+ desc = "This is a rather oriental style tree. Its flowers are bright pink."
+ icon_state = "plant-10"
+
+/obj/structure/flora/pottedplant/smallcactus
+ name = "small potted cactus"
+ desc = "This is a small cactus. Its needles are sharp."
+ icon_state = "plant-11"
+
+/obj/structure/flora/pottedplant/tall
+ name = "tall potted plant"
+ desc = "This is a tall plant. Tiny pores line its surface."
+ icon_state = "plant-12"
+
+/obj/structure/flora/pottedplant/sticky
+ name = "sticky potted plant"
+ desc = "This is an odd plant. Its sticky leaves trap insects."
+ icon_state = "plant-13"
+
+/obj/structure/flora/pottedplant/smelly
+ name = "smelly potted plant"
+ desc = "This is some kind of tropical plant. It reeks of rotten eggs."
+ icon_state = "plant-14"
+
+/obj/structure/flora/pottedplant/small
+ name = "small potted plant"
+ desc = "This is a pot of assorted small flora. Some look familiar."
+ icon_state = "plant-15"
+
+/obj/structure/flora/pottedplant/aquatic
+ name = "aquatic potted plant"
+ desc = "This is apparently an aquatic plant. It's probably fake."
+ icon_state = "plant-16"
+
+/obj/structure/flora/pottedplant/shoot
+ name = "small potted shoot"
+ desc = "This is a small shoot. It still needs time to grow."
+ icon_state = "plant-17"
+
+/obj/structure/flora/pottedplant/flower
+ name = "potted flower"
+ desc = "This is a slim plant. Sweet smelling flowers are supported by spindly stems."
+ icon_state = "plant-18"
+
+/obj/structure/flora/pottedplant/crystal
+ name = "crystalline potted plant"
+ desc = "These are rather cubic plants. Odd crystal formations grow on the end."
+ icon_state = "plant-19"
+
+/obj/structure/flora/pottedplant/subterranean
+ name = "subterranean potted plant"
+ desc = "This is a subterranean plant. It's bulbous ends glow faintly."
+ icon_state = "plant-20"
+ light_range = 2
+ light_power = 0.6
+ light_color = "#FF6633"
+
+/obj/structure/flora/pottedplant/minitree
+ name = "potted tree"
+ desc = "This is a miniature tree. Apparently it was grown to 1/5 scale."
+ icon_state = "plant-21"
+
+/obj/structure/flora/pottedplant/stoutbush
+ name = "stout potted bush"
+ desc = "This is a stout bush. Its leaves point up and outwards."
+ icon_state = "plant-22"
+
+/obj/structure/flora/pottedplant/drooping
+ name = "drooping potted plant"
+ desc = "This is a small plant. The drooping leaves make it look like its wilted."
+ icon_state = "plant-23"
+
+/obj/structure/flora/pottedplant/tropical
+ name = "tropical potted plant"
+ desc = "This is some kind of tropical plant. It hasn't begun to flower yet."
+ icon_state = "plant-24"
+
+/obj/structure/flora/pottedplant/dead
+ name = "dead potted plant"
+ desc = "This is the dried up remains of a dead plant. Someone should replace it."
+ icon_state = "plant-25"
+
+/obj/structure/flora/pottedplant/decorative
+ name = "decorative potted plant"
+ desc = "This is a decorative shrub. It's been trimmed into the shape of an apple."
+ icon_state = "applebush"
+
+/obj/structure/flora/pottedplant/xmas
+ name = "small christmas tree"
+ desc = "This is a tiny well lit decorative christmas tree."
+ icon_state = "plant-xmas"
+
+/obj/structure/flora/sif
+ icon = 'icons/obj/flora/sifflora.dmi'
+
+/obj/structure/flora/sif/attack_hand(mob/user)
+ if (user.a_intent == I_HURT)
+ if(do_after(user, 5 SECONDS))
+ user.visible_message("\The [user] digs up \the [src.name].", "You dig up \the [src.name].")
+ qdel(src)
+ else
+ user.visible_message("\The [user] pokes \the [src.name].", "You poke \the [src.name].")
+
+/datum/category_item/catalogue/flora/subterranean_bulbs
+ name = "Sivian Flora - Subterranean Bulbs"
+ desc = "A plant which is native to Sif, it continues the trend of being a bioluminescent specimen. These plants \
+ are generally suited for conditions experienced in caverns, which are generally dark and cold. It is not \
+ known why this plant evolved to be bioluminescent, however this property has, unintentionally, allowed for \
+ it to spread much farther than before, with the assistance of humans.\
+
\
+ In Sif's early history, Sivian settlers found this plant while they were establishing mines. Their ability \
+ to emit low, but consistant amounts of light made them desirable to the settlers. They would often cultivate \
+ this plant inside man-made tunnels and mines to act as a backup source of light that would not need \
+ electricity. This technique has saved many lost miners, and this practice continues to this day."
+ value = CATALOGUER_REWARD_EASY
+
+/obj/structure/flora/sif/subterranean
+ name = "subterranean plant"
+ desc = "This is a subterranean plant. It's bulbous ends glow faintly."
+ icon_state = "glowplant"
+ light_range = 2
+ light_power = 0.6
+ light_color = "#FF6633"
+ catalogue_data = list(/datum/category_item/catalogue/flora/subterranean_bulbs)
+
+/obj/structure/flora/sif/subterranean/Initialize()
+ icon_state = "[initial(icon_state)][rand(1,2)]"
+ . = ..()
+
+
+/datum/category_item/catalogue/flora/eyebulbs
+ name = "Sivian Flora - Eyebulbs"
+ desc = "A plant native to Sif. On the end of its stems are bulbs which visually resemble \
+ eyes, which shrink when touched. One theory is that the bulbs are a result of mimicry, appearing as eyeballs to protect from predators.
\
+ These plants have no known use."
+ value = CATALOGUER_REWARD_EASY
+
+/obj/structure/flora/sif/eyes
+ name = "mysterious bulbs"
+ desc = "This is a mysterious looking plant. They kind of look like eyeballs. Creepy."
+ icon_state = "eyeplant"
+ catalogue_data = list(/datum/category_item/catalogue/flora/eyebulbs)
+
+/obj/structure/flora/sif/eyes/Initialize()
+ icon_state = "[initial(icon_state)][rand(1,3)]"
+ . = ..()
+
+/datum/category_item/catalogue/flora/mosstendrils
+ name = "Sivian Flora - Moss Stalks"
+ desc = "A plant native to Sif. The plant is most closely related to the common, dense moss found covering Sif's terrain. \
+ It has evolved a method of camouflage utilizing white hairs on its dorsal sides to make it appear as a small mound of snow from \
+ above. It has no known use, though it is a common furnishing in contemporary homes."
+ value = CATALOGUER_REWARD_TRIVIAL
+
+/obj/structure/flora/sif/tendrils
+ name = "stocky tendrils"
+ desc = "A 'plant' made up of hardened moss. It has tiny hairs that bunch together to look like snow."
+ icon_state = "grass"
+ randomize_size = TRUE
+ catalogue_data = list(/datum/category_item/catalogue/flora/mosstendrils)
+
+ harvest_tool = /obj/item/weapon/material/knife
+ max_harvests = 1
+ min_harvests = -4
+ harvest_loot = list(
+ /obj/item/seeds/wabback = 15,
+ /obj/item/seeds/blackwabback = 1,
+ /obj/item/seeds/wildwabback = 30
+ )
+
+/obj/structure/flora/sif/tendrils/Initialize()
+ icon_state = "[initial(icon_state)][rand(1,3)]"
+ . = ..()
+
+/obj/structure/flora/sif/tendrils/get_harvestable_desc()
+ return "\The [src] seems to be growing over something."
diff --git a/code/game/objects/structures/flora_vr.dm b/code/game/objects/structures/flora/flora_vr.dm
similarity index 100%
rename from code/game/objects/structures/flora_vr.dm
rename to code/game/objects/structures/flora/flora_vr.dm
diff --git a/code/game/objects/structures/flora/grass.dm b/code/game/objects/structures/flora/grass.dm
index d5e7e965a8..92717f4beb 100644
--- a/code/game/objects/structures/flora/grass.dm
+++ b/code/game/objects/structures/flora/grass.dm
@@ -11,7 +11,6 @@
..()
icon_state = "snowgrass[rand(1, 3)]bb"
-
/obj/structure/flora/grass/green
icon_state = "snowgrass1gb"
diff --git a/code/game/objects/structures/flora/trees.dm b/code/game/objects/structures/flora/trees.dm
index 7cb1c3de3e..97625c7c5f 100644
--- a/code/game/objects/structures/flora/trees.dm
+++ b/code/game/objects/structures/flora/trees.dm
@@ -308,7 +308,9 @@
max_harvests = 2
min_harvests = -4
harvest_loot = list(
- /obj/item/weapon/reagent_containers/food/snacks/siffruit = 5
+ /obj/item/weapon/reagent_containers/food/snacks/siffruit = 20,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/sifpod = 5,
+ /obj/item/seeds/sifbulb = 1
)
var/light_shift = 0
diff --git a/code/game/objects/structures/gravemarker.dm b/code/game/objects/structures/gravemarker.dm
index 1df13a6eb4..d5b7773910 100644
--- a/code/game/objects/structures/gravemarker.dm
+++ b/code/game/objects/structures/gravemarker.dm
@@ -30,13 +30,11 @@
color = material.icon_colour
/obj/structure/gravemarker/examine(mob/user)
- ..()
- if(get_dist(src, user) < 4)
- if(grave_name)
- to_chat(user, "Here Lies [grave_name]")
- if(get_dist(src, user) < 2)
- if(epitaph)
- to_chat(user, epitaph)
+ . = ..()
+ if(grave_name && get_dist(src, user) < 4)
+ . += "Here Lies [grave_name]"
+ if(epitaph && get_dist(src, user) < 2)
+ . += epitaph
/obj/structure/gravemarker/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSTABLE))
diff --git a/code/game/objects/structures/holoplant.dm b/code/game/objects/structures/holoplant.dm
index 9a46b8ca15..bf2365a7b1 100644
--- a/code/game/objects/structures/holoplant.dm
+++ b/code/game/objects/structures/holoplant.dm
@@ -48,13 +48,13 @@
plant = prepare_icon(emagged ? "emagged" : null)
overlays += plant
set_light(2)
- use_power = USE_POWER_ACTIVE
+ update_use_power(USE_POWER_ACTIVE)
/obj/machinery/holoplant/proc/deactivate()
overlays -= plant
QDEL_NULL(plant)
set_light(0)
- use_power = USE_POWER_OFF
+ update_use_power(USE_POWER_OFF)
/obj/machinery/holoplant/power_change()
..()
diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm
index 93c48fe8a9..b7807711e3 100644
--- a/code/game/objects/structures/janicart.dm
+++ b/code/game/objects/structures/janicart.dm
@@ -24,10 +24,9 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
/obj/structure/janitorialcart/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "[src] [bicon(src)] contains [reagents.total_volume] unit\s of liquid!")
- //everything else is visible, so doesn't need to be mentioned
-
+ . = ..()
+ if(Adjacent(user))
+ . += "It contains [reagents.total_volume] unit\s of liquid!"
/obj/structure/janitorialcart/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/storage/bag/trash) && !mybag)
@@ -186,12 +185,11 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
/obj/structure/bed/chair/janicart/examine(mob/user)
- if(!..(user, 1))
- return
-
- to_chat(user, "[bicon(src)] This [callme] contains [reagents.total_volume] unit\s of water!")
- if(mybag)
- to_chat(user, "\A [mybag] is hanging on the [callme].")
+ . = ..()
+ if(Adjacent(user))
+ . += "This [callme] contains [reagents.total_volume] unit\s of water!"
+ if(mybag)
+ . += "\A [mybag] is hanging on the [callme]."
/obj/structure/bed/chair/janicart/attackby(obj/item/I, mob/user)
@@ -230,15 +228,6 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
to_chat(user, "You'll need the keys in one of your hands to drive this [callme].")
-/obj/structure/bed/chair/janicart/Move()
- ..()
- if(has_buckled_mobs())
- for(var/A in buckled_mobs)
- var/mob/living/L = A
- if(L.buckled == src)
- L.loc = loc
-
-
/obj/structure/bed/chair/janicart/post_buckle_mob(mob/living/M)
update_mob()
return ..()
diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm
index e14c9ba9e3..b11f7aa36c 100644
--- a/code/game/objects/structures/loot_piles.dm
+++ b/code/game/objects/structures/loot_piles.dm
@@ -40,6 +40,10 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
var/list/uncommon_loot = list() // Uncommon is actually maybe some useful items, usually the reason someone bothers looking inside.
var/list/rare_loot = list() // Rare is really powerful, or at least unique items.
+/obj/structure/loot_pile/attack_ai(var/mob/user)
+ if(isrobot(user) && Adjacent(user))
+ return attack_hand(user)
+
/obj/structure/loot_pile/attack_hand(mob/user)
//Human mob
if(isliving(user))
@@ -351,8 +355,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
/obj/item/weapon/circuitboard/atmos_alert,
/obj/item/weapon/circuitboard/airalarm,
/obj/item/weapon/circuitboard/fax,
- /obj/item/weapon/circuitboard/ghettosmes,
/obj/item/weapon/circuitboard/jukebox,
+ /obj/item/weapon/circuitboard/batteryrack,
/obj/item/weapon/circuitboard/message_monitor,
/obj/item/weapon/circuitboard/rcon_console,
/obj/item/weapon/smes_coil,
diff --git a/code/game/objects/structures/medical_stand_vr.dm b/code/game/objects/structures/medical_stand_vr.dm
index 60bddde660..9e0b2cdf37 100644
--- a/code/game/objects/structures/medical_stand_vr.dm
+++ b/code/game/objects/structures/medical_stand_vr.dm
@@ -342,24 +342,24 @@
return
if(beaker)
- to_chat(user, "The IV drip is [mode ? "injecting" : "taking blood"].")
- to_chat(user, "It is set to transfer [transfer_amount]u of chemicals per cycle.")
+ . += "The IV drip is [mode ? "injecting" : "taking blood"]."
+ . += "It is set to transfer [transfer_amount]u of chemicals per cycle."
if(beaker.reagents && beaker.reagents.total_volume)
- to_chat(user, "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.")
+ . += "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid."
else
- to_chat(user, "Attached is an empty [beaker].")
- to_chat(user, "[attached ? attached : "No one"] is hooked up to it.")
+ . += "Attached is an empty [beaker]."
+ . += "[attached ? attached : "No one"] is hooked up to it."
else
- to_chat(user, "There is no vessel.")
+ . += "There is no vessel."
if(tank)
if (!is_loosen)
- to_chat(user, "\The [tank] connected.")
- to_chat(user, "The meter shows [round(tank.air_contents.return_pressure())]. The valve is [valve_opened == TRUE ? "open" : "closed"].")
+ . += "\The [tank] connected."
+ . += "The meter shows [round(tank.air_contents.return_pressure())]. The valve is [valve_opened == TRUE ? "open" : "closed"]."
if (tank.distribute_pressure == 0)
- to_chat(user, "Use wrench to replace tank.")
+ . += "Use wrench to replace tank."
else
- to_chat(user, "There is no tank.")
+ . += "There is no tank."
/obj/structure/medical_stand/process()
//Gas Stuff
diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm
index 17e594c4c3..1c6476d1d1 100644
--- a/code/game/objects/structures/mop_bucket.dm
+++ b/code/game/objects/structures/mop_bucket.dm
@@ -17,8 +17,9 @@ GLOBAL_LIST_BOILERPLATE(all_mopbuckets, /obj/structure/mopbucket)
..()
/obj/structure/mopbucket/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "[src] [bicon(src)] contains [reagents.total_volume] unit\s of water!")
+ . = ..()
+ if(Adjacent(user))
+ . += "It contains [reagents.total_volume] unit\s of water!"
/obj/structure/mopbucket/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/mop) || istype(I, /obj/item/weapon/soap) || istype(I, /obj/item/weapon/reagent_containers/glass/rag)) //VOREStation Edit - "Allows soap and rags to be used on mopbuckets"
diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm
index f3bfc92d8e..c701ae9015 100644
--- a/code/game/objects/structures/noticeboard.dm
+++ b/code/game/objects/structures/noticeboard.dm
@@ -51,21 +51,18 @@
return
/obj/structure/noticeboard/attack_hand(var/mob/user)
- examine(user)
+ user.examinate(src)
// Since Topic() never seems to interact with usr on more than a superficial
// level, it should be fine to let anyone mess with the board other than ghosts.
/obj/structure/noticeboard/examine(var/mob/user)
- if(!user)
- user = usr
- if(user.Adjacent(src))
+ . = ..()
+ if(Adjacent(user))
var/dat = "Noticeboard
"
for(var/obj/item/weapon/paper/P in src)
dat += "[P.name] Write Remove
"
user << browse("Notices[dat]","window=noticeboard")
onclose(user, "noticeboard")
- else
- ..()
/obj/structure/noticeboard/Topic(href, href_list)
..()
diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm
index 8027b5db5e..17b457b49e 100644
--- a/code/game/objects/structures/railing.dm
+++ b/code/game/objects/structures/railing.dm
@@ -46,11 +46,11 @@
if(health < maxhealth)
switch(health / maxhealth)
if(0.0 to 0.5)
- to_chat(user, "It looks severely damaged!")
+ . += "It looks severely damaged!"
if(0.25 to 0.5)
- to_chat(user, "It looks damaged!")
+ . += "It looks damaged!"
if(0.5 to 1.0)
- to_chat(user, "It has a few scrapes and dents.")
+ . += "It has a few scrapes and dents."
/obj/structure/railing/take_damage(amount)
health -= amount
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index 1a9d4e7315..b053e33805 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -286,15 +286,10 @@
held = null
-/obj/structure/bed/roller/Move()
- ..()
+/obj/structure/bed/roller/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
+
playsound(src, 'sound/effects/roll.ogg', 100, 1)
- if(has_buckled_mobs())
- for(var/A in buckled_mobs)
- var/mob/living/L = A
-
- if(L.buckled == src)
- L.loc = src.loc
/obj/structure/bed/roller/post_buckle_mob(mob/living/M as mob)
if(M.buckled == src)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index 5be1d6d198..dbd437fe33 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -140,22 +140,24 @@
return
..()
-/obj/structure/bed/chair/office/Move()
- ..()
+/obj/structure/bed/chair/office/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
+
playsound(src, 'sound/effects/roll.ogg', 100, 1)
- if(has_buckled_mobs())
- for(var/A in buckled_mobs)
- var/mob/living/occupant = A
- occupant.buckled = null
- occupant.Move(src.loc)
- occupant.buckled = src
- if (occupant && (src.loc != occupant.loc))
- if (propelled)
- for (var/mob/O in src.loc)
- if (O != occupant)
- Bump(O)
- else
- unbuckle_mob()
+
+/obj/structure/bed/chair/office/handle_buckled_mob_movement(atom/new_loc, direction, movetime)
+ for(var/A in buckled_mobs)
+ var/mob/living/occupant = A
+ occupant.buckled = null
+ occupant.Move(loc, direction, movetime)
+ occupant.buckled = src
+ if (occupant && (loc != occupant.loc))
+ if (propelled)
+ for (var/mob/O in src.loc)
+ if (O != occupant)
+ Bump(O)
+ else
+ unbuckle_mob()
/obj/structure/bed/chair/office/Bump(atom/A)
..()
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs_vr.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs_vr.dm
index 79b970e1cf..fa28f71bad 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs_vr.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs_vr.dm
@@ -120,6 +120,7 @@
desc = "Like a normal chair, but more stationary."
icon_state = "bay_chair_preview"
base_icon = "bay_chair"
+ buckle_movable = 1
/obj/structure/bed/chair/bay/chair/padded/red/New(var/newloc, var/new_material, var/new_padding_material)
..(newloc, new_material, "carpet")
@@ -192,7 +193,6 @@
desc = "It's a chair. Only for the highest ranked asses."
icon_state = "capchair_preview"
base_icon = "capchair"
- buckle_movable = 1
/obj/structure/bed/chair/bay/comfy/captain/update_icon()
..()
@@ -209,6 +209,7 @@
desc = "A comfortable, secure seat. It has a sturdy-looking buckling system for smoother flights."
base_icon = "shuttle_chair"
icon_state = "shuttle_chair_preview"
+ buckle_movable = 0
var/buckling_sound = 'sound/effects/metal_close.ogg'
var/padding = "blue"
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index 8a3902fa1d..639020ba5d 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -91,8 +91,9 @@
create_track()
driving = 0
-/obj/structure/bed/chair/wheelchair/Move()
- ..()
+/obj/structure/bed/chair/wheelchair/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
+
cut_overlays()
playsound(src, 'sound/effects/roll.ogg', 75, 1)
if(has_buckled_mobs())
diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm
index 55d8b37d0f..1e9c091ccb 100644
--- a/code/game/objects/structures/target_stake.dm
+++ b/code/game/objects/structures/target_stake.dm
@@ -8,11 +8,11 @@
w_class = ITEMSIZE_HUGE
var/obj/item/target/pinned_target // the current pinned target
- Move()
- ..()
+ Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
// Move the pinned target along with the stake
if(pinned_target in view(3, src))
- pinned_target.loc = loc
+ pinned_target.forceMove(loc)
else // Sanity check: if the pinned target can't be found in immediate view
pinned_target = null
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index d8542d0c96..3df62610c9 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -3,7 +3,7 @@
desc = "A window."
icon = 'icons/obj/structures_vr.dmi' // VOREStation Edit - New icons
density = 1
- can_atmos_pass = ATMOS_PASS_DENSITY
+ can_atmos_pass = ATMOS_PASS_PROC
w_class = ITEMSIZE_NORMAL
layer = WINDOW_LAYER
@@ -25,27 +25,27 @@
var/fulltile = FALSE // Set to true on full-tile variants.
/obj/structure/window/examine(mob/user)
- . = ..(user)
+ . = ..()
if(health == maxhealth)
- to_chat(user, "It looks fully intact.")
+ . += "It looks fully intact."
else
var/perc = health / maxhealth
if(perc > 0.75)
- to_chat(user, "It has a few cracks.")
+ . += "It has a few cracks."
else if(perc > 0.5)
- to_chat(user, "It looks slightly damaged.")
+ . += "It looks slightly damaged."
else if(perc > 0.25)
- to_chat(user, "It looks moderately damaged.")
+ . += "It looks moderately damaged."
else
- to_chat(user, "It looks heavily damaged.")
+ . += "It looks heavily damaged."
if(silicate)
if (silicate < 30)
- to_chat(user, "It has a thin layer of silicate.")
+ . += "It has a thin layer of silicate."
else if (silicate < 70)
- to_chat(user, "It is covered in silicate.")
+ . += "It is covered in silicate."
else
- to_chat(user, "There is a thick layer of silicate covering it.")
+ . += "There is a thick layer of silicate covering it."
/obj/structure/window/take_damage(var/damage = 0, var/sound_effect = 1)
var/initialhealth = health
@@ -144,8 +144,8 @@
/obj/structure/window/CanZASPass(turf/T, is_zone)
if(is_fulltile() || get_dir(T, loc) == turn(dir, 180)) // Make sure we're handling the border correctly.
- return anchored ? ATMOS_PASS_NO : ATMOS_PASS_YES // If it's anchored, it'll block air.
- return ATMOS_PASS_YES // Don't stop airflow from the other sides.
+ return !anchored // If it's anchored, it'll block air.
+ return TRUE // Don't stop airflow from the other sides.
/obj/structure/window/CheckExit(atom/movable/O as mob|obj, target as turf)
if(istype(O) && O.checkpass(PASSGLASS))
@@ -413,7 +413,7 @@
/obj/structure/window/Move()
var/ini_dir = dir
update_nearby_tiles(need_rebuild=1)
- ..()
+ . = ..()
set_dir(ini_dir)
update_nearby_tiles(need_rebuild=1)
diff --git a/code/game/objects/structures/window_vr.dm b/code/game/objects/structures/window_vr.dm
new file mode 100644
index 0000000000..8a13a9c50d
--- /dev/null
+++ b/code/game/objects/structures/window_vr.dm
@@ -0,0 +1,37 @@
+/obj/structure/window/titanium
+ name = "ti-glass window"
+ desc = "A titanium alloy window, combining the strength of titanium with the transparency of glass. It seems to be very strong."
+ basestate = "window"
+ icon_state = "window"
+ color = "#A7A3A6"
+ shardtype = /obj/item/weapon/material/shard/titaniumglass
+ glasstype = /obj/item/stack/material/glass/titanium
+ reinf = 0
+ maximal_heat = T0C + 5000
+ damage_per_fire_tick = 1.0
+ maxhealth = 100.0
+ force_threshold = 10
+
+/obj/structure/window/titanium/full
+ icon_state = "window-full"
+ maxhealth = 200
+ fulltile = TRUE
+
+/obj/structure/window/plastitanium
+ name = "plastanium glass window"
+ desc = "A plastitanium alloy window, combining the strength of plastitanium with the transparency of glass. It seems to be very strong."
+ basestate = "window"
+ icon_state = "window"
+ color = "#676366"
+ shardtype = /obj/item/weapon/material/shard/plastitaniumglass
+ glasstype = /obj/item/stack/material/glass/plastitanium
+ reinf = 0
+ maximal_heat = T0C + 7000
+ damage_per_fire_tick = 1.0
+ maxhealth = 120.0
+ force_threshold = 10
+
+/obj/structure/window/plastitanium/full
+ icon_state = "window-full"
+ maxhealth = 250
+ fulltile = TRUE
\ No newline at end of file
diff --git a/code/game/turfs/simulated/outdoors/grass.dm b/code/game/turfs/simulated/outdoors/grass.dm
index e557fb16da..553b4858bb 100644
--- a/code/game/turfs/simulated/outdoors/grass.dm
+++ b/code/game/turfs/simulated/outdoors/grass.dm
@@ -12,6 +12,13 @@ var/list/grass_types = list(
)
var/grass_chance = 20
+ var/animal_chance = 1
+
+ // Weighted spawn list.
+ var/list/animal_types = list(
+ /mob/living/simple_mob/animal/passive/tindalos = 1
+ )
+
var/list/grass_types = list(
/obj/structure/flora/ausbushes/sparsegrass,
/obj/structure/flora/ausbushes/fullgrass
@@ -32,6 +39,16 @@ var/list/grass_types = list(
grass_chance = 5
var/tree_chance = 2
+ animal_chance = 0 //VOREStation Edit
+
+ animal_types = list(
+ /mob/living/simple_mob/animal/sif/diyaab = 10,
+ /mob/living/simple_mob/animal/sif/glitterfly = 2,
+ /mob/living/simple_mob/animal/sif/duck = 2,
+ /mob/living/simple_mob/animal/sif/shantak/retaliate = 2,
+ /obj/random/mob/multiple/sifmobs = 1
+ )
+
grass_types = list(
/obj/structure/flora/sif/eyes = 1,
/obj/structure/flora/sif/tendrils = 10
@@ -53,6 +70,11 @@ var/list/grass_types = list(
if(grass_chance && prob(grass_chance) && !check_density())
var/grass_type = pickweight(grass_types)
new grass_type(src)
+
+ if(animal_chance && prob(animal_chance) && !check_density())
+ var/animal_type = pickweight(animal_types)
+ new animal_type(src)
+
. = ..()
/turf/simulated/floor/outdoors/grass/forest
diff --git a/code/game/turfs/simulated/wall_types_vr.dm b/code/game/turfs/simulated/wall_types_vr.dm
index 6ebf9df004..87a6582f1f 100644
--- a/code/game/turfs/simulated/wall_types_vr.dm
+++ b/code/game/turfs/simulated/wall_types_vr.dm
@@ -71,3 +71,15 @@ var/list/flesh_overlay_cache = list()
/turf/simulated/shuttle/wall/flock/Initialize()
. = ..()
set_light(3,3,"#26c5a9")
+
+/turf/simulated/wall/rplastitanium
+ icon_state = "rwall-plastitanium"
+ icon = 'icons/turf/wall_masks_vr.dmi'
+/turf/simulated/wall/rplastitanium/Initialize(mapload)
+ . = ..(mapload, MAT_PLASTITANIUM,MAT_PLASTITANIUM,MAT_PLASTITANIUM)
+
+ /turf/simulated/wall/plastitanium
+ icon_state = "wall-plastitanium"
+ icon = 'icons/turf/wall_masks_vr.dmi'
+/turf/simulated/wall/plastitanium/Initialize(mapload)
+ . = ..(mapload, MAT_PLASTITANIUM, null,MAT_PLASTITANIUM)
\ No newline at end of file
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index cbb9c6dbb7..add0b3b11d 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -120,21 +120,21 @@
//Appearance
/turf/simulated/wall/examine(mob/user)
- . = ..(user)
+ . = ..()
if(!damage)
- to_chat(user, "It looks fully intact.")
+ . += "It looks fully intact."
else
var/dam = damage / material.integrity
if(dam <= 0.3)
- to_chat(user, "It looks slightly damaged.")
+ . += "It looks slightly damaged."
else if(dam <= 0.6)
- to_chat(user, "It looks moderately damaged.")
+ . += "It looks moderately damaged."
else
- to_chat(user, "It looks heavily damaged.")
+ . += "It looks heavily damaged."
if(locate(/obj/effect/overlay/wallrot) in src)
- to_chat(user, "There is fungus growing on [src].")
+ . += "There is fungus growing on [src]."
//Damage
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 96edd3c9d4..6575e47a54 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -157,19 +157,14 @@ var/const/enterloopsanity = 100
if(ismob(A))
var/mob/M = A
- if(!M.lastarea)
- M.lastarea = get_area(M.loc)
- if(M.lastarea.has_gravity == 0)
+ if(M.lastarea?.has_gravity == 0)
inertial_drift(M)
if(M.flying) //VORESTATION Edit Start. This overwrites the above is_space without touching it all that much.
M.make_floating(1) //VOREStation Edit End.
else if(!is_space())
M.inertia_dir = 0
M.make_floating(0)
- if(isliving(M))
- var/mob/living/L = M
- L.handle_footstep(src)
- ..()
+
var/objects = 0
if(A && (A.flags & PROXMOVE))
for(var/atom/movable/thing in range(1))
diff --git a/code/game/verbs/character_directory.dm b/code/game/verbs/character_directory.dm
index 1b45091cf7..99f95700b8 100644
--- a/code/game/verbs/character_directory.dm
+++ b/code/game/verbs/character_directory.dm
@@ -18,7 +18,8 @@
var/mob/living/carbon/human/H = C.mob
if(data_core && data_core.general)
if(!find_general_record("name", H.real_name))
- continue
+ if(!find_record("name", H.real_name, data_core.hidden_general))
+ continue
curID++
html += ""
html += "
[H.real_name]
"
diff --git a/code/global.dm b/code/global.dm
index 31535369df..7360e625fa 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -37,7 +37,7 @@ var/const/star_name = "Virgo-Erigone"
var/const/starsys_name = "Virgo-Erigone"
var/const/game_version = "VOREStation"
var/changelog_hash = ""
-var/game_year = (text2num(time2text(world.realtime, "YYYY")) + 544)
+var/game_year = (text2num(time2text(world.realtime, "YYYY")) + 300) //VOREStation Edit
var/round_progressing = 1
var/master_mode = "extended" // "extended"
diff --git a/code/global_vr.dm b/code/global_vr.dm
index d8d1887bde..457a37ea0a 100644
--- a/code/global_vr.dm
+++ b/code/global_vr.dm
@@ -4,7 +4,8 @@
robot_module_types += "Janihound"
robot_module_types += "Sci-borg"
robot_module_types += "Pupdozer"
- robot_module_types += "Servicehound" //YW changes
+ robot_module_types += "Service-Hound"
+ robot_module_types += "KMine"
robot_module_types += "BoozeHound" //YW changes
return 1
diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm
index fc1a8e05ca..48eb275a9e 100644
--- a/code/modules/admin/DB ban/functions.dm
+++ b/code/modules/admin/DB ban/functions.dm
@@ -83,7 +83,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
var/sql = "INSERT INTO erro_ban (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`) VALUES (null, Now(), '[serverip]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], [(rounds)?"[rounds]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', '[ip]', '[a_ckey]', '[a_computerid]', '[a_ip]', '[who]', '[adminwho]', '', null, null, null, null, null)"
var/DBQuery/query_insert = dbcon.NewQuery(sql)
query_insert.Execute()
- to_chat(usr, "
Ban saved to database.")
+ to_chat(usr, "
Ban saved to database.")
message_admins("[key_name_admin(usr)] has added a [bantype_str] for [ckey] [(job)?"([job])":""] [(duration > 0)?"([duration] minutes)":""] with the reason: \"[reason]\" to the ban database.",1)
@@ -137,17 +137,17 @@ datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "")
ban_number++;
if(ban_number == 0)
- to_chat(usr, "
Database update failed due to no bans fitting the search criteria. If this is not a legacy ban you should contact the database admin.")
+ to_chat(usr, "
Database update failed due to no bans fitting the search criteria. If this is not a legacy ban you should contact the database admin.")
return
if(ban_number > 1)
- to_chat(usr, "
Database update failed due to multiple bans fitting the search criteria. Note down the ckey, job and current time and contact the database admin.")
+ to_chat(usr, "
Database update failed due to multiple bans fitting the search criteria. Note down the ckey, job and current time and contact the database admin.")
return
if(istext(ban_id))
ban_id = text2num(ban_id)
if(!isnum(ban_id))
- to_chat(usr, "
Database update failed due to a ban ID mismatch. Contact the database admin.")
+ to_chat(usr, "
Database update failed due to a ban ID mismatch. Contact the database admin.")
return
DB_ban_unban_by_id(ban_id)
@@ -173,7 +173,7 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
duration = query.item[2]
reason = query.item[3]
else
- to_chat(usr, "Invalid ban id. Contact the database admin")
+ to_chat(usr, "
Invalid ban id. Contact the database admin")
return
reason = sql_sanitize_text(reason)
@@ -205,12 +205,8 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
if(alert("Unban [pckey]?", "Unban?", "Yes", "No") == "Yes")
DB_ban_unban_by_id(banid)
return
- else
- to_chat(usr, "Cancelled")
- return
- else
- to_chat(usr, "Cancelled")
- return
+ to_chat(usr, "
Cancelled")
+ return
datum/admins/proc/DB_ban_unban_by_id(var/id)
@@ -232,11 +228,11 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
ban_number++;
if(ban_number == 0)
- to_chat(usr, "
Database update failed due to a ban id not being present in the database.")
+ to_chat(usr, "
Database update failed due to a ban id not being present in the database.")
return
if(ban_number > 1)
- to_chat(usr, "
Database update failed due to multiple bans having the same ID. Contact the database admin.")
+ to_chat(usr, "
Database update failed due to multiple bans having the same ID. Contact the database admin.")
return
if(!src.owner || !istype(src.owner, /client))
@@ -272,7 +268,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
establish_db_connection()
if(!dbcon.IsConnected())
- to_chat(usr, "
Failed to establish database connection")
+ to_chat(usr, "
Failed to establish database connection")
return
var/output = "
"
diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm
index 944cdc552a..15d29eb1f0 100644
--- a/code/modules/admin/NewBan.dm
+++ b/code/modules/admin/NewBan.dm
@@ -106,7 +106,7 @@ var/savefile/Banlist
Banlist.cd = "/base"
if ( Banlist.dir.Find("[ckey][computerid]") )
- to_chat(usr, "Ban already exists.")
+ to_chat(usr, "Ban already exists.")
return 0
else
Banlist.dir.Add("[ckey][computerid]")
diff --git a/code/modules/admin/ToRban.dm b/code/modules/admin/ToRban.dm
index 1e2d5ef49c..dbf373b3ff 100644
--- a/code/modules/admin/ToRban.dm
+++ b/code/modules/admin/ToRban.dm
@@ -38,7 +38,7 @@
F["last_update"] << world.realtime
log_misc("ToR data updated!")
if(usr)
- to_chat(usr, "ToRban updated.")
+ to_chat(usr, "ToRban updated.")
return 1
log_misc("ToR data update aborted: no data.")
return 0
@@ -73,16 +73,16 @@
var/choice = input(src,"Please select an IP address to remove from the ToR banlist:","Remove ToR ban",null) as null|anything in F.dir
if(choice)
F.dir.Remove(choice)
- to_chat(src, "Address removed")
+ to_chat(src, "Address removed")
if("remove all")
- to_chat(src, "[TORFILE] was [fdel(TORFILE)?"":"not "]removed.")
+ to_chat(src, "[TORFILE] was [fdel(TORFILE)?"":"not "]removed.")
if("find")
var/input = input(src,"Please input an IP address to search for:","Find ToR ban",null) as null|text
if(input)
if(ToRban_isbanned(input))
- to_chat(src, "Address is a known ToR address")
+ to_chat(src, "Address is a known ToR address")
else
- to_chat(src, "Address is not a known ToR address")
+ to_chat(src, "Address is not a known ToR address")
return
#undef TORFILE
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 6fc26c7d48..ccf0b4ef94 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -5,7 +5,7 @@ var/global/floorIsLava = 0
////////////////////////////////
/proc/message_admins(var/msg)
- msg = "ADMIN LOG: [msg]"
+ msg = "ADMIN LOG: [msg]"
//log_adminwarn(msg) //log_and_message_admins is for this
for(var/client/C in admins)
@@ -13,7 +13,7 @@ var/global/floorIsLava = 0
to_chat(C,msg)
/proc/msg_admin_attack(var/text) //Toggleable Attack Messages
- var/rendered = "ATTACK: [text]"
+ var/rendered = "ATTACK: [text]"
for(var/client/C in admins)
if((R_ADMIN|R_MOD) & C.holder.rights)
if(C.is_preference_enabled(/datum/client_preference/mod/show_attack_logs))
@@ -877,7 +877,7 @@ var/datum/announcement/minor/admin_min_announcer = new
if(!check_rights(R_SERVER|R_EVENT))
return
if(SSticker.current_state > GAME_STATE_PREGAME)
- to_chat(usr, "Error: Start Now: Game has already started.")
+ to_chat(usr, "Error: Start Now: Game has already started.")
return
if(!SSticker.start_immediately)
SSticker.start_immediately = TRUE
@@ -885,11 +885,11 @@ var/datum/announcement/minor/admin_min_announcer = new
if(SSticker.current_state == GAME_STATE_INIT)
msg = " (The server is still setting up, but the round will be started as soon as possible.)"
log_admin("[key_name(usr)] has started the game.[msg]")
- message_admins("[key_name_admin(usr)] has started the game.[msg]")
+ message_admins("[key_name_admin(usr)] has started the game.[msg]")
feedback_add_details("admin_verb","SN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
else
SSticker.start_immediately = FALSE
- to_chat(world, "Immediate game start canceled. Normal startup resumed.")
+ to_world("Immediate game start canceled. Normal startup resumed.")
log_and_message_admins("cancelled immediate game start.")
/datum/admins/proc/toggleenter()
diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm
index 8dc1e9de74..1342fc2f5f 100644
--- a/code/modules/admin/admin_investigate.dm
+++ b/code/modules/admin/admin_investigate.dm
@@ -23,7 +23,7 @@
if(!message) return
var/F = investigate_subject2file(subject)
if(!F) return
- to_chat(F, "[time2text(world.timeofday,"hh:mm")] \ref[src] ([x],[y],[z]) || [src] [message]
")
+ to_chat(F, "[time2text(world.timeofday,"hh:mm")] \ref[src] ([x],[y],[z]) || [src] [message]
")
//ADMINVERBS
/client/proc/investigate_show( subject in list("hrefs","notes","singulo","telesci") )
@@ -34,7 +34,7 @@
if("singulo", "telesci") //general one-round-only stuff
var/F = investigate_subject2file(subject)
if(!F)
- to_chat(src, "Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed.")
+ to_chat(src, "Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed.")
return
src << browse(F,"window=investigate[subject];size=800x300")
@@ -43,8 +43,8 @@
if(href_logfile)
src << browse(href_logfile,"window=investigate[subject];size=800x300")
else
- to_chat(src, "Error: admin_investigate: No href logfile found.")
+ to_chat(src, "Error: admin_investigate: No href logfile found.")
return
else
- to_chat(src, "Error: admin_investigate: Href Logging is not on.")
+ to_chat(src, "Error: admin_investigate: Href Logging is not on.")
return
diff --git a/code/modules/admin/admin_memo.dm b/code/modules/admin/admin_memo.dm
index 007ca49ba5..fc38dda9d5 100644
--- a/code/modules/admin/admin_memo.dm
+++ b/code/modules/admin/admin_memo.dm
@@ -22,11 +22,11 @@
return
if("")
F.dir.Remove(ckey)
- to_chat(src, "Memo removed")
+ to_chat(src, "Memo removed")
return
if( findtext(memo,"