diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ef0d97119409..414e78d92ae6 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -58,11 +58,6 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: '3.x'
- - name: Setup Cache
- uses: actions/cache@v3
- with:
- path: $HOME/spaceman_dmm/$SPACEMAN_DMM_VERSION
- key: ${{ runner.os }}-spacemandmm-${{ env.SPACEMAN_DMM_VERSION }}
- name: Install OpenDream
uses: robinraju/release-downloader@v1.9
with:
@@ -71,7 +66,7 @@ jobs:
fileName: "DMCompiler_linux-x64.tar.gz"
extract: true
- name: Run OpenDream
- run: ./DMCompiler_linux-x64/DMCompiler nebula.dme --suppress-unimplemented --skip-anything-typecheck --version=${BYOND_MAJOR}.${BYOND_MINOR} | python tools/od_annotator/__main__.py "$@"
+ run: ./DMCompiler_linux-x64/DMCompiler nebula.dme --define=UNIT_TEST --suppress-unimplemented --skip-anything-typecheck --version=${BYOND_MAJOR}.${BYOND_MINOR} | bash test/annotate_od.sh
Code:
runs-on: ubuntu-22.04
steps:
diff --git a/code/__defines/MC.dm b/code/__defines/MC.dm
index ddc5a1c7516f..f01b2f954289 100644
--- a/code/__defines/MC.dm
+++ b/code/__defines/MC.dm
@@ -24,7 +24,7 @@
if (Datum.is_processing) {\
if(Datum.is_processing != #Processor)\
{\
- PRINT_STACK_TRACE("Failed to start processing. [log_info_line(Datum)] is already being processed by [Datum.is_processing] but queue attempt occured on [#Processor]."); \
+ PRINT_STACK_TRACE("Failed to start processing. [log_info_line(Datum)] is already being processed by [Datum.is_processing] but queue attempt occurred on [#Processor]."); \
}\
} else {\
Datum.is_processing = Processor._internal_name;\
@@ -36,7 +36,7 @@ if(Datum.is_processing) {\
if(Processor.processing.Remove(Datum)) {\
Datum.is_processing = null;\
} else {\
- PRINT_STACK_TRACE("Failed to stop processing. [log_info_line(Datum)] is being processed by [Datum.is_processing] but de-queue attempt occured on [#Processor]."); \
+ PRINT_STACK_TRACE("Failed to stop processing. [log_info_line(Datum)] is being processed by [Datum.is_processing] but de-queue attempt occurred on [#Processor]."); \
}\
}
diff --git a/code/__defines/bodytype.dm b/code/__defines/bodytype.dm
index a44b77cc47ff..ca9dccfe6082 100644
--- a/code/__defines/bodytype.dm
+++ b/code/__defines/bodytype.dm
@@ -18,7 +18,7 @@
// Bodytype feature flags
/// Does not create DNA. Replaces SPECIES_FLAG_NO_SCAN.
#define BODY_FLAG_NO_DNA BITFLAG(0)
-/// Cannot suffer halloss/recieves deceptive health indicator.
+/// Cannot suffer halloss/receives deceptive health indicator.
#define BODY_FLAG_NO_PAIN BITFLAG(1)
/// Cannot eat food/drink drinks even if a stomach organ is present.
#define BODY_FLAG_NO_EAT BITFLAG(2)
diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm
index 169309b2dfdc..5e04e9499632 100644
--- a/code/__defines/flags.dm
+++ b/code/__defines/flags.dm
@@ -86,6 +86,7 @@ The latter will result in a linter warning and will not work correctly.
#define ITEM_FLAG_PADDED BITFLAG(13) // When set on gloves, will act like pulling punches in unarmed combat.
#define ITEM_FLAG_CAN_TAPE BITFLAG(14) // Whether the item can be taped onto something using tape
#define ITEM_FLAG_IS_WEAPON BITFLAG(15) // Item is considered a weapon. Currently only used for force-based worth calculation.
+#define ITEM_FLAG_MAGNETISED BITFLAG(16) // When worn on feet and standing on an appropriate spot, will prevent slipping.
// Flags for pass_flags (/atom/var/pass_flags)
#define PASS_FLAG_TABLE BITFLAG(0)
diff --git a/code/__defines/hud.dm b/code/__defines/hud.dm
index 7cb67e0fd28a..3353b89d20ae 100644
--- a/code/__defines/hud.dm
+++ b/code/__defines/hud.dm
@@ -1,23 +1,31 @@
-// Keys used to set and retrieve icons from the UI decl system.
-#define UI_ICON_INTERACTION "icon_interaction"
-#define UI_ICON_ZONE_SELECT "icon_zone_sel"
-#define UI_ICON_MOVEMENT "icon_movement"
-#define UI_ICON_INVENTORY "icon_inventory"
-#define UI_ICON_ATTACK "icon_attack"
-#define UI_ICON_HANDS "icon_hands"
-#define UI_ICON_INTERNALS "icon_internals"
-#define UI_ICON_HEALTH "icon_health"
-#define UI_ICON_CRIT_MARKER "icon_crit_marker"
-#define UI_ICON_NUTRITION "icon_nutrition"
-#define UI_ICON_HYDRATION "icon_hydration"
-#define UI_ICON_FIRE_INTENT "icon_fire_intent"
-#define UI_ICON_UP_HINT "icon_uphint"
-#define UI_ICON_STATUS "icon_status"
-#define UI_ICON_STATUS_FIRE "icon_status_fire"
-#define UI_ICON_CHARGE "icon_charge"
+// Keys used to create HUD elements, and to set and retrieve icons from the UI decl system.
+#define HUD_STAMINA /decl/hud_element/stamina
+#define HUD_DROP /decl/hud_element/drop
+#define HUD_RESIST /decl/hud_element/resist
+#define HUD_THROW /decl/hud_element/throw_toggle
+#define HUD_MANEUVER /decl/hud_element/maneuver
+#define HUD_ZONE_SELECT /decl/hud_element/zone_selector
+#define HUD_MOVEMENT /decl/hud_element/movement
+#define HUD_INVENTORY /decl/hud_element/inventory
+#define HUD_ATTACK /decl/hud_element/attack
+#define HUD_HANDS /decl/hud_element/hands
+#define HUD_INTERNALS /decl/hud_element/internals
+#define HUD_HEALTH /decl/hud_element/health
+#define HUD_INTENT /decl/hud_element/intent
+#define HUD_CRIT_MARKER /decl/hud_element/crit
+#define HUD_NUTRITION /decl/hud_element/nutrition
+#define HUD_HYDRATION /decl/hud_element/hydration
+#define HUD_FIRE_INTENT /decl/hud_element/gun_mode
+#define HUD_UP_HINT /decl/hud_element/upward
+#define HUD_BODYTEMP /decl/hud_element/bodytemp
+#define HUD_PRESSURE /decl/hud_element/pressure
+#define HUD_TOX /decl/hud_element/toxins
+#define HUD_OXY /decl/hud_element/oxygen
+#define HUD_FIRE /decl/hud_element/fire
+#define HUD_CHARGE /decl/hud_element/charge
+#define HUD_ROBOT_MODULE /decl/hud_element/module_selection
#define GET_HUD_ALERT(M, A) ((istype(M?.hud_used, /datum/hud) && (A in M.hud_used.alerts)) ? M.hud_used.alerts[A] : 0)
-
#define CLEAR_HUD_ALERTS(M) if(istype(M?.hud_used, /datum/hud) && M.hud_used.alerts) { M.hud_used.alerts = null; }
#define SET_HUD_ALERT(M, A, V) if(istype(M?.hud_used, /datum/hud)) { LAZYSET(M.hud_used.alerts, A, V); }
#define SET_HUD_ALERT_MIN(M, A, V) if(istype(M?.hud_used, /datum/hud) && V < LAZYACCESS(M.hud_used.alerts, A)) { LAZYSET(M.hud_used.alerts, A, V); }
diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm
index d6591b17acf4..b7018659403b 100644
--- a/code/__defines/machinery.dm
+++ b/code/__defines/machinery.dm
@@ -155,7 +155,7 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define PART_CARD /obj/item/stock_parts/computer/card_slot // ID Card slot component of this computer. Mostly for HoP modification console that needs ID slot for modification.
#define PART_PRINTER /obj/item/stock_parts/computer/nano_printer // Nano Printer component of this computer, for your everyday paperwork needs.
#define PART_DRIVE /obj/item/stock_parts/computer/hard_drive/portable // Portable data storage
-#define PART_AI /obj/item/stock_parts/computer/ai_slot // AI slot, an intellicard housing that allows modifications of AIs.
+#define PART_AI /obj/item/stock_parts/computer/ai_slot // AI slot, an intelliCard housing that allows modifications of AIs.
#define PART_TESLA /obj/item/stock_parts/computer/tesla_link // Tesla Link, Allows remote charging from nearest APC.
#define PART_SCANNER /obj/item/stock_parts/computer/scanner // One of several optional scanner attachments.
#define PART_D_SLOT /obj/item/stock_parts/computer/drive_slot // Portable drive slot.
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 55fbbecd14d4..85583c6cedf8 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -142,6 +142,11 @@
#define CONFIG_SERVER_JOIN_WHITELIST 3
#define CONFIG_SERVER_CONNECT_WHITELIST 4
+// Coating name color config enums
+#define CONFIG_COATING_COLOR_NONE 1
+#define CONFIG_COATING_COLOR_MIXTURE 2
+#define CONFIG_COATING_COLOR_COMPONENTS 3
+
// Location for server whitelist file to load from.
#define CONFIG_SERVER_WHITELIST_FILE "config/server_whitelist.txt"
@@ -252,6 +257,7 @@
//Inserts 'a' or 'an' before X in ways \a doesn't allow
#define ADD_ARTICLE(X) "[(lowertext(X[1]) in global.vowels) ? "an" : "a"] [X]"
+#define ADD_ARTICLE_GENDER(X, GENDER) (GENDER == PLURAL ? "some [X]" : ADD_ARTICLE(X))
//Request Console Department Types
#define RC_ASSIST 1 //Request Assistance
@@ -376,5 +382,11 @@
#define CRAYON_DRAW_LETTER "letter"
#define CRAYON_DRAW_ARROW "arrow"
+// Enum for results of is_space_movement_permitted()
+#define SPACE_MOVE_SUPPORTED (-1)
+#define SPACE_MOVE_FORBIDDEN 0
+#define SPACE_MOVE_PERMITTED 1
+
// Default UI style applied to client prefs.
#define DEFAULT_UI_STYLE /decl/ui_style/midnight
+
diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index 022c6011a7ad..00633e438b2f 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -272,8 +272,6 @@
#define SPECIES_HUMAN "Human"
#define SPECIES_MONKEY "Monkey"
-#define SPECIES_ALIEN "Humanoid"
-#define SPECIES_GOLEM "Golem"
#define SURGERY_CLOSED 0
#define SURGERY_OPEN 1
diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm
index 13861c4d9f5d..127f3b2d1149 100644
--- a/code/__defines/subsystems.dm
+++ b/code/__defines/subsystems.dm
@@ -43,14 +43,14 @@
#define SS_INIT_OVERLAY 1
#define SS_INIT_DEFAULT 0
#define SS_INIT_AIR -1
-#define SS_INIT_VIS_CONTENTS -2
-#define SS_INIT_MISC_LATE -3
-#define SS_INIT_MISC_CODEX -4
-#define SS_INIT_ALARM -5
-#define SS_INIT_SHUTTLE -6
-#define SS_INIT_GOALS -7
-#define SS_INIT_LIGHTING -8
-#define SS_INIT_WEATHER -9
+#define SS_INIT_MISC_LATE -2
+#define SS_INIT_MISC_CODEX -3
+#define SS_INIT_ALARM -4
+#define SS_INIT_SHUTTLE -5
+#define SS_INIT_GOALS -6
+#define SS_INIT_LIGHTING -7
+#define SS_INIT_WEATHER -8
+#define SS_INIT_VIS_CONTENTS -9
#define SS_INIT_ZCOPY -10
#define SS_INIT_HOLOMAP -11
#define SS_INIT_XENOARCH -12
diff --git a/code/_helpers/animations.dm b/code/_helpers/animations.dm
index be0d2188f5a3..e549a677f797 100644
--- a/code/_helpers/animations.dm
+++ b/code/_helpers/animations.dm
@@ -69,11 +69,20 @@
animate(time = 1)
animate(alpha = 0, time = 3, easing = CIRCULAR_EASING|EASE_OUT)
+// Shake animation stolen from Polaris.
+/atom
+ /// How much to shake the atom when struck.
+ /// Larger objs should have smaller numbers or it looks weird.
+ var/shake_animation_degrees = 4
+
/atom/proc/shake_animation(var/intensity = 8)
var/init_px = pixel_x
var/shake_dir = pick(-1, 1)
- animate(src, transform=turn(matrix(), intensity*shake_dir), pixel_x=init_px + 2*shake_dir, time=1)
- animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
+ var/matrix/M = matrix()
+ M.Scale(icon_scale_x, icon_scale_y)
+ M.Translate(0, 16*(icon_scale_y-1))
+ animate(src, transform=turn(M, shake_animation_degrees * shake_dir), pixel_x=init_px + 2*shake_dir, time=1)
+ animate(transform=M, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE)
if(!segments)
diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm
index 5360486eec8a..6c040f5a57c9 100644
--- a/code/_helpers/mobs.dm
+++ b/code/_helpers/mobs.dm
@@ -40,7 +40,7 @@
var/user_loc = user.loc
var/drifting = 0
- if(!user.Process_Spacemove(0) && user.inertia_dir)
+ if(user.is_space_movement_permitted() == SPACE_MOVE_FORBIDDEN && user.inertia_dir)
drifting = 1
var/target_loc = target.loc
@@ -101,7 +101,7 @@
var/atom/original_loc = user.loc
var/drifting = 0
- if(!user.Process_Spacemove(0) && user.inertia_dir)
+ if(user.is_space_movement_permitted() == SPACE_MOVE_FORBIDDEN && user.inertia_dir)
drifting = 1
var/holding = user.get_active_held_item()
diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm
index e25429b8fe50..103e0b49b97f 100644
--- a/code/_helpers/text.dm
+++ b/code/_helpers/text.dm
@@ -84,7 +84,7 @@
//Run sanitize(), but remove <, >, " first to prevent displaying them as > < &34; in some places after html_encode().
//Best used for sanitize object names, window titles.
-//If you have a problem with sanitize() in chat, when quotes and >, < are displayed as html entites -
+//If you have a problem with sanitize() in chat, when quotes and >, < are displayed as html entities -
//this is a problem of double-encode(when & becomes &), use sanitize() with encode=0, but not the sanitize_safe()!
/proc/sanitize_safe(input, max_length = MAX_MESSAGE_LEN, encode = TRUE, trim = TRUE, extra = TRUE, ascii_only = FALSE)
return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'")), max_length, encode, trim, extra, ascii_only)
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index 88f8f402528e..02c769ae10af 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -275,7 +275,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
return 0
return 1
-//Ensure the frequency is within bounds of what it should be sending/recieving at
+//Ensure the frequency is within bounds of what it should be sending/receiving at
/proc/sanitize_frequency(var/f, var/low = PUBLIC_LOW_FREQ, var/high = PUBLIC_HIGH_FREQ)
return clamp(round(f), low, high)
diff --git a/code/_helpers/visual_filters.dm b/code/_helpers/visual_filters.dm
index 10e485e18543..6c4f9939736e 100644
--- a/code/_helpers/visual_filters.dm
+++ b/code/_helpers/visual_filters.dm
@@ -1,15 +1,18 @@
-// These involve BYOND's built in filters that do visual effects, and not stuff that distinguishes between things.
+// These involve BYOND's built-in filters that do visual effects, and not stuff that distinguishes between things.
// All of this ported from TG.
// And then ported to Nebula from Polaris.
/atom/movable
- var/list/filter_data // For handling persistent filters
+ VAR_PRIVATE/list/filter_data // For handling persistent filters
// Defining this for future proofing and ease of searching for erroneous usage.
/image/proc/add_filter(filter_name, priority, list/params)
filters += filter(arglist(params))
return TRUE
+/atom/movable/proc/has_filter(filter_name)
+ return (name in filter_data)
+
/atom/movable/proc/add_filter(filter_name, priority, list/params, force_update = FALSE)
// Check if we already have a filter and hence don't need to rebuild filters.
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 90653cccc970..372ede052d3c 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -41,7 +41,7 @@
After that, mostly just check your state, check whether you're holding an item,
check whether you're adjacent to the target, then pass off the click to whoever
- is recieving it.
+ is receiving it.
The most common are:
* mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves
* atom/attackby(item,user) - used only when adjacent
diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm
index ec0965a969f3..9102b1b0e88e 100644
--- a/code/_onclick/drag_drop.dm
+++ b/code/_onclick/drag_drop.dm
@@ -1,6 +1,6 @@
/*
The below procs are called on the atom you're dragging. In a lot of circumstances we want to use the
- recieving object instead, so that's the default action. This allows you to drag
+ receiving object instead, so that's the default action. This allows you to drag
almost anything into a trash can.
*/
diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index 5ac7ac42bd02..41016eea0b09 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -32,17 +32,13 @@
#define ui_storage1 "RIGHT-3:16,BOTTOM:5"
#define ui_storage2 "RIGHT-4:16,BOTTOM:5"
-#define ui_alien_head "CENTER-3:12,BOTTOM:5" //aliens
-#define ui_alien_oclothing "CENTER-2:14,BOTTOM:5"//aliens
-
-#define ui_inv1 "CENTER-1,BOTTOM:5" //borgs
-#define ui_inv2 "CENTER,BOTTOM:5" //borgs
-#define ui_inv3 "CENTER+1,BOTTOM:5" //borgs
-#define ui_borg_store "CENTER+2,BOTTOM:5" //borgs
-#define ui_borg_inventory "CENTER-2,BOTTOM:5"//borgs
-#define ui_borg_drop_grab "CENTER-3,BOTTOM:5"//borgs
-#define ui_monkey_mask "LEFT+4:14,BOTTOM:5" //monkey
-#define ui_monkey_back "LEFT+5:14,BOTTOM:5" //monkey
+// Robot defines.
+#define ui_inv1 "CENTER-1,BOTTOM:21"
+#define ui_inv2 "CENTER,BOTTOM:21"
+#define ui_inv3 "CENTER+1,BOTTOM:21"
+#define ui_borg_store "CENTER+2,BOTTOM:21"
+#define ui_borg_inventory "CENTER-2,BOTTOM:21"
+#define ui_borg_drop_grab "CENTER-3,BOTTOM:21"
#define ui_construct_health "RIGHT:00,CENTER:15" //same height as humans, hugging the right border
#define ui_construct_fire "RIGHT-1:16,CENTER+1:13" //above health, slightly to the left
@@ -57,18 +53,17 @@
#define ui_attack_selector "RIGHT-2:27,BOTTOM+2:9"
#define ui_zonesel "RIGHT-1:28,BOTTOM:5"
#define ui_acti_alt "RIGHT-1:28,BOTTOM:5" //alternative intent switcher for when the interface is hidden
-#define ui_stamina "RIGHT-3:24,BOTTOM+1:5"
+#define ui_stamina "RIGHT-2:24,BOTTOM:8"
#define ui_borg_pull "RIGHT-3:24,BOTTOM+1:7"
#define ui_borg_module "RIGHT-2:26,BOTTOM+1:7"
#define ui_borg_panel "RIGHT-1:28,BOTTOM+1:7"
//Gun buttons
-#define ui_gun1 "RIGHT-2:26,BOTTOM+2:7"
-#define ui_gun2 "RIGHT-1:28, BOTTOM+3:7"
-#define ui_gun3 "RIGHT-2:26,BOTTOM+3:7"
+#define ui_gun1 "RIGHT-1:28,BOTTOM+3:7"
+#define ui_gun2 "RIGHT-2:28,BOTTOM+3:7"
+#define ui_gun3 "RIGHT-3:28,BOTTOM+3:7"
#define ui_gun_select "RIGHT-1:28,BOTTOM+2:7"
-#define ui_gun4 "RIGHT-3:24,BOTTOM+2:7"
//Upper-middle right (damage indicators and up hint)
#define ui_up_hint "RIGHT-1:28,TOP-1:29"
@@ -87,9 +82,9 @@
#define ui_temp "RIGHT-1:28,CENTER-1:13"
#define ui_health "RIGHT-1:28,CENTER:15"
#define ui_internal "RIGHT-1:28,CENTER+1:17"
- //borgs
-#define ui_borg_health "RIGHT-1:28,CENTER-1:13" //borgs have the health display where humans have the pressure damage indicator.
-#define ui_alien_health "RIGHT-1:28,CENTER-1:13" //aliens have the health display where humans have the pressure damage indicator.
+
+// Robots have the health display where humans have the pressure damage indicator.
+#define ui_borg_health "RIGHT-1:28,CENTER-1:13"
//Pop-up inventory
#define ui_shoes "LEFT+1:8,BOTTOM:5"
@@ -105,22 +100,6 @@
#define ui_head "LEFT+1:8,BOTTOM+3:11"
-//Intent small buttons
-#define ui_help_small "RIGHT-3:8,BOTTOM:1"
-#define ui_disarm_small "RIGHT-3:15,BOTTOM:18"
-#define ui_grab_small "RIGHT-3:32,BOTTOM:18"
-#define ui_harm_small "RIGHT-3:39,BOTTOM:1"
-
-//#define ui_swapbutton "6:-16,1:5" //Unused
-
-//#define ui_headset "BOTTOM,8"
-#define ui_hand "CENTER-1:14,BOTTOM:5"
-#define ui_hstore1 "CENTER-2,CENTER-2"
-//#define ui_resist "RIGHT+1,BOTTOM-1"
-#define ui_sleep "RIGHT+1, TOP-13"
-#define ui_rest "RIGHT+1, TOP-14"
-
-
#define ui_iarrowleft "BOTTOM-1,RIGHT-4"
#define ui_iarrowright "BOTTOM-1,RIGHT-2"
diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm
index e122262cdb96..54ff72145076 100644
--- a/code/_onclick/hud/action.dm
+++ b/code/_onclick/hud/action.dm
@@ -34,6 +34,12 @@
/datum/action/Destroy()
if(owner)
Remove(owner)
+ QDEL_NULL(button)
+ if(target)
+ var/obj/item/target_item = target
+ if(istype(target_item) && target_item.action == src)
+ target_item.action = null
+ target = null
return ..()
/datum/action/proc/SetTarget(var/atom/Target)
diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm
deleted file mode 100644
index 651c4d1e007f..000000000000
--- a/code/_onclick/hud/ai.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/mob/living/silicon/ai
- hud_used = /datum/hud/ai
-
-/datum/hud/ai
- action_intent_type = null // no selector
-
-/datum/hud/ai/FinalizeInstantiation()
- var/list/ai_hud_data = decls_repository.get_decls_of_subtype(/decl/ai_hud)
- for(var/elem_type in ai_hud_data)
- adding += new /obj/screen/ai_button(null, mymob, null, null, null, null, ai_hud_data[elem_type])
- ..()
diff --git a/code/_onclick/hud/animal.dm b/code/_onclick/hud/animal.dm
deleted file mode 100644
index 8b372aabdcc6..000000000000
--- a/code/_onclick/hud/animal.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-
-/mob/living/simple_animal
- hud_used = /datum/hud/animal
-
-/datum/hud/animal/FinalizeInstantiation()
-
- var/ui_style = get_ui_style_data()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
-
- move_intent = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_MOVEMENT)
- move_intent.icon_state = mymob.move_intent.hud_icon_state
- adding += move_intent
- ..()
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
deleted file mode 100644
index 48829da57dda..000000000000
--- a/code/_onclick/hud/hud.dm
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- The hud datum
- Used to show and hide huds for all the different mob types,
- including inventories and item quick actions.
-*/
-
-/mob
- var/datum/hud/hud_used
-
-/mob/proc/InitializeHud()
- if(istype(hud_used))
- QDEL_NULL(hud_used)
- hud_used = initial(hud_used)
- if(ispath(hud_used))
- hud_used = new hud_used(src)
- if(istype(hud_used))
- hud_used.refresh_hud_icons()
- refresh_lighting_master()
-
-/datum/hud
- var/mob/mymob
-
- var/hud_shown = 1 //Used for the HUD toggle (F12)
- var/inventory_shown = TRUE //the inventory
- var/hotkey_ui_hidden = FALSE //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons)
-
- var/default_ui_style = DEFAULT_UI_STYLE
-
- var/list/alerts
-
- var/list/hand_hud_objects
- var/list/swaphand_hud_objects
- var/obj/screen/movement/move_intent
- var/obj/screen/stamina/stamina_bar
-
- var/action_intent_type = /obj/screen/intent
- var/obj/screen/intent/action_intent
-
- var/list/adding = list()
- var/list/other = list()
- var/list/hud_elements = list()
- var/list/obj/screen/hotkeybuttons
-
- var/obj/screen/action_button/hide_toggle/hide_actions_toggle
- var/action_buttons_hidden = FALSE
-
-/datum/hud/New(mob/owner)
- mymob = owner
- instantiate()
- ..()
-
-/datum/hud/proc/refresh_hud_icons()
- for(var/obj/screen/elem in mymob?.client?.screen)
- elem.queue_icon_update()
-
-/datum/hud/Destroy()
- . = ..()
- stamina_bar = null
- action_intent = null
- move_intent = null
- adding = null
- other = null
- hotkeybuttons = null
- mymob = null
- QDEL_NULL_LIST(hand_hud_objects)
- QDEL_NULL_LIST(swaphand_hud_objects)
-
-/datum/hud/proc/update_stamina()
- if(mymob && stamina_bar)
- stamina_bar.set_invisibility(INVISIBILITY_MAXIMUM)
- var/stamina = mymob.get_stamina()
- if(stamina < 100)
- stamina_bar.set_invisibility(INVISIBILITY_NONE)
- stamina_bar.icon_state = "prog_bar_[floor(stamina/5)*5][(stamina >= 5) && (stamina <= 25) ? "_fail" : null]"
-
-/datum/hud/proc/hide_inventory()
- inventory_shown = FALSE
- hidden_inventory_update()
- persistent_inventory_update()
-
-/datum/hud/proc/show_inventory()
- inventory_shown = TRUE
- hidden_inventory_update()
- persistent_inventory_update()
-
-/datum/hud/proc/hidden_inventory_update()
- var/decl/species/species = mymob?.get_species()
- if(istype(species?.species_hud))
- refresh_inventory_slots(species.species_hud.hidden_slots, (inventory_shown && hud_shown))
-
-/datum/hud/proc/persistent_inventory_update()
- var/decl/species/species = mymob?.get_species()
- if(istype(species?.species_hud))
- refresh_inventory_slots(species.species_hud.persistent_slots, hud_shown)
-
-/datum/hud/proc/refresh_inventory_slots(var/list/checking_slots, var/show_hud)
-
- for(var/slot in checking_slots)
-
- var/datum/inventory_slot/inv_slot = mymob.get_inventory_slot_datum(slot)
- if(!istype(inv_slot))
- continue
-
- // Check if we're even wearing anything in that slot.
- var/obj/item/gear = inv_slot.get_equipped_item()
- if(!istype(gear))
- continue
-
- // We're not showing anything, hide it.
- gear.reconsider_client_screen_presence(mymob?.client, slot)
- if(!show_hud)
- inv_slot.hide_slot()
- else
- inv_slot.show_slot()
-
-/datum/hud/proc/instantiate()
- if(ismob(mymob) && mymob.client)
- FinalizeInstantiation()
- return TRUE
- return FALSE
-
-/datum/hud/proc/FinalizeInstantiation()
-
- SHOULD_CALL_PARENT(TRUE)
-
- if(!action_intent && action_intent_type) // Everyone needs an intent selector.
- action_intent = new action_intent_type(null, mymob)
- adding |= action_intent
- hud_elements |= action_intent
-
- BuildInventoryUI()
- BuildHandsUI()
-
- if(mymob.client)
- mymob.client.screen = list()
- if(length(hand_hud_objects))
- mymob.client.screen |= hand_hud_objects
- if(length(swaphand_hud_objects))
- mymob.client.screen |= swaphand_hud_objects
- if(length(hud_elements))
- mymob.client.screen |= hud_elements
- if(length(adding))
- mymob.client.screen |= adding
- if(length(hotkeybuttons))
- mymob.client.screen |= hotkeybuttons
-
- hide_inventory()
-
-/datum/hud/proc/get_ui_style_data()
- RETURN_TYPE(/decl/ui_style)
- . = GET_DECL(mymob?.client?.prefs?.UI_style) || GET_DECL(default_ui_style)
- if(!.)
- var/list/available_styles = get_ui_styles()
- if(length(available_styles))
- . = available_styles[1]
-
-/datum/hud/proc/get_ui_color()
- var/decl/ui_style/ui_style = get_ui_style_data()
- if(!ui_style?.use_ui_color)
- return COLOR_WHITE
- return mymob?.client?.prefs?.UI_style_color || COLOR_WHITE
-
-/datum/hud/proc/get_ui_alpha()
- return mymob?.client?.prefs?.UI_style_alpha || 255
-
-/datum/hud/proc/rebuild_hands()
-
- var/decl/ui_style/ui_style = get_ui_style_data()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
-
- // Build held item boxes for missing slots.
- var/list/held_slots = mymob.get_held_item_slots()
-
- // Sort our slots for display.
- var/list/gripper_datums = list()
- for(var/hand_tag in held_slots)
- gripper_datums += mymob.get_inventory_slot_datum(hand_tag)
- gripper_datums = sortTim(gripper_datums, /proc/cmp_gripper_asc)
-
- for(var/datum/inventory_slot/gripper/inv_slot in gripper_datums)
-
- // Re-order the held slot list so it aligns with the display order.
- var/hand_tag = inv_slot.slot_id
- held_slots -= hand_tag
- held_slots += hand_tag
-
- var/obj/screen/inventory/inv_box
- for(var/obj/screen/inventory/existing_box in hand_hud_objects)
- if(existing_box.slot_id == hand_tag)
- inv_box = existing_box
- break
-
- if(!inv_box)
- inv_box = new /obj/screen/inventory/hand(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HANDS)
- else
- inv_box.set_ui_style(ui_style, UI_ICON_HANDS)
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
-
- LAZYDISTINCTADD(hand_hud_objects, inv_box)
-
- inv_box.SetName(hand_tag)
- inv_box.slot_id = hand_tag
- inv_box.update_icon()
-
- // Clear held item boxes with no held slot.
- for(var/obj/screen/inventory/inv_box in hand_hud_objects)
- if(!(inv_box.slot_id in held_slots))
- if(mymob.client)
- mymob.client.screen -= inv_box
- LAZYREMOVE(hand_hud_objects, inv_box)
- qdel(inv_box)
-
- // Rebuild offsets for the hand elements.
- var/hand_y_offset = 21
- var/list/elements = hand_hud_objects?.Copy()
- while(length(elements))
- var/copy_index = min(length(elements), 2)+1
- var/list/sublist = elements.Copy(1, copy_index)
- elements.Cut(1, copy_index)
- var/obj/screen/inventory/inv_box
- if(length(sublist) == 1)
- inv_box = sublist[1]
- inv_box.screen_loc = "CENTER,BOTTOM:[hand_y_offset]"
- else
- inv_box = sublist[1]
- inv_box.screen_loc = "CENTER:-[world.icon_size/2],BOTTOM:[hand_y_offset]"
- inv_box = sublist[2]
- inv_box.screen_loc = "CENTER:[world.icon_size/2],BOTTOM:[hand_y_offset]"
- hand_y_offset += world.icon_size
-
- if(mymob.client && islist(hand_hud_objects) && length(hand_hud_objects))
- mymob.client.screen |= hand_hud_objects
-
- // Make sure all held items are on the screen and set to the correct screen loc.
- var/datum/inventory_slot/inv_slot
- for(var/obj/inv_elem in hand_hud_objects)
- inv_slot = mymob.get_inventory_slot_datum(inv_elem.name)
- if(inv_slot)
- inv_slot.ui_loc = inv_elem.screen_loc
- var/obj/item/held = inv_slot.get_equipped_item()
- if(held)
- held.screen_loc = inv_slot.ui_loc
- if(mymob.client)
- mymob.client.screen |= held // just to make sure it's visible post-login
-
- if(length(swaphand_hud_objects))
- var/hand_x_offset = -(world.icon_size/2)
- for(var/i = 1 to length(swaphand_hud_objects))
- var/obj/swap_elem = swaphand_hud_objects[i]
- swap_elem.screen_loc = "CENTER:[hand_x_offset],BOTTOM:[hand_y_offset]"
- if(i > 1) // first two elems share a slot
- hand_x_offset += world.icon_size
- if(mymob.client)
- mymob.client.screen |= swap_elem
-
-/datum/hud/proc/BuildInventoryUI()
-
- var/decl/ui_style/ui_style = get_ui_style_data()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
-
- var/has_hidden_gear = FALSE
-
- // Draw the various inventory equipment slots.
- var/obj/screen/inventory/inv_box
- var/list/held_slots = mymob.get_held_item_slots()
- var/list/inventory_slots = mymob.get_inventory_slots()
- for(var/gear_slot in inventory_slots)
-
- if(gear_slot in held_slots)
- continue
-
- inv_box = new /obj/screen/inventory(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INVENTORY)
-
- var/datum/inventory_slot/inv_slot = inventory_slots[gear_slot]
- inv_box.SetName(inv_slot.slot_name)
- inv_box.slot_id = inv_slot.slot_id
- inv_box.icon_state = inv_slot.slot_state
- inv_box.screen_loc = inv_slot.ui_loc
-
- if(inv_slot.slot_dir)
- inv_box.set_dir(inv_slot.slot_dir)
-
- if(inv_slot.can_be_hidden)
- other += inv_box
- has_hidden_gear = TRUE
- else
- adding += inv_box
-
- if(has_hidden_gear)
- adding += new /obj/screen/toggle(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INVENTORY)
-
-/datum/hud/proc/BuildHandsUI()
-
- var/list/held_slots = mymob.get_held_item_slots()
- if(length(held_slots) <= 0)
- return
-
- var/decl/ui_style/ui_style = get_ui_style_data()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
-
- // Swap hand and quick equip screen elems.
- var/obj/screen/using = new /obj/screen/equip(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HANDS)
- adding += using
- LAZYADD(swaphand_hud_objects, using)
-
- if(length(held_slots) > 1)
-
- using = new /obj/screen/inventory/swaphand(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HANDS)
- adding += using
- LAZYADD(swaphand_hud_objects, using)
- using = new /obj/screen/inventory/swaphand/right(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HANDS)
- adding += using
- LAZYADD(swaphand_hud_objects, using)
-
- // Actual hand elems.
- rebuild_hands()
-
-/mob/verb/minimize_hud(full = FALSE as null)
- set name = "Minimize Hud"
- set hidden = TRUE
-
- if(isnull(hud_used))
- to_chat(usr, SPAN_WARNING("This mob type does not use a HUD."))
- return
-
- if(!client || !istype(hud_used))
- return
-
- if(hud_used.hud_shown)
- hud_used.hud_shown = 0
- if(hud_used.adding)
- client.screen -= hud_used.adding
- if(hud_used.other)
- client.screen -= hud_used.other
- if(hud_used.hotkeybuttons)
- client.screen -= hud_used.hotkeybuttons
-
- //Due to some poor coding some things need special treatment:
- //These ones are a part of 'adding', 'other' or 'hotkeybuttons' but we want them to stay
- if(!full)
- if(LAZYLEN(hud_used.hand_hud_objects))
- client.screen += hud_used.hand_hud_objects // we want the hands to be visible
- if(LAZYLEN(hud_used.swaphand_hud_objects))
- client.screen += hud_used.swaphand_hud_objects // we want the hands swap thingy to be visible
- client.screen += hud_used.action_intent // we want the intent swticher visible
- hud_used.action_intent.screen_loc = ui_acti_alt // move this to the alternative position, where zone_select usually is.
- else
- client.screen -= healths
- client.screen -= internals
- client.screen -= gun_setting_icon
-
- //These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone.
- client.screen -= zone_sel //zone_sel is a mob variable for some reason.
-
- else
- hud_used.hud_shown = 1
- if(hud_used.adding)
- client.screen += hud_used.adding
- if(hud_used.other && hud_used.inventory_shown)
- client.screen += hud_used.other
- if(hud_used.hotkeybuttons && !hud_used.hotkey_ui_hidden)
- client.screen += hud_used.hotkeybuttons
- if(healths)
- client.screen |= healths
- if(internals)
- client.screen |= internals
- if(gun_setting_icon)
- client.screen |= gun_setting_icon
-
- hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position
- client.screen += zone_sel //This one is a special snowflake
-
- hud_used.hidden_inventory_update()
- hud_used.persistent_inventory_update()
- update_action_buttons()
-
-//Similar to minimize_hud() but keeps zone_sel, gun_setting_icon, and healths.
-/mob/proc/toggle_zoom_hud()
- if(!istype(hud_used))
- return
- if(!ishuman(src))
- return
- if(!client)
- return
- if(client.view != world.view)
- return
-
- if(hud_used.hud_shown)
- hud_used.hud_shown = 0
- if(hud_used.adding)
- client.screen -= hud_used.adding
- if(hud_used.other)
- client.screen -= hud_used.other
- if(hud_used.hotkeybuttons)
- client.screen -= hud_used.hotkeybuttons
- client.screen -= internals
- client.screen += hud_used.action_intent //we want the intent swticher visible
- else
- hud_used.hud_shown = 1
- if(hud_used.adding)
- client.screen += hud_used.adding
- if(hud_used.other && hud_used.inventory_shown)
- client.screen += hud_used.other
- if(hud_used.hotkeybuttons && !hud_used.hotkey_ui_hidden)
- client.screen += hud_used.hotkeybuttons
- if(internals)
- client.screen |= internals
- hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position
-
- hud_used.hidden_inventory_update()
- hud_used.persistent_inventory_update()
- update_action_buttons()
-
-/client/proc/reset_click_catchers()
-
- var/xmin = -(round(last_view_x_dim*0.5))
- var/xmax = last_view_x_dim - abs(xmin)
- var/ymin = -(round(last_view_y_dim*0.5))
- var/ymax = last_view_y_dim - abs(ymin)
-
- var/list/click_catchers = get_click_catchers()
- for(var/obj/screen/click_catcher/catcher in click_catchers)
- if(catcher.x_offset <= xmin || catcher.x_offset >= xmax || catcher.y_offset <= ymin || catcher.y_offset >= ymax)
- screen -= catcher
- else
- screen |= catcher
-
-/mob/proc/add_click_catcher()
- client.reset_click_catchers()
-
-/mob/new_player/add_click_catcher()
- return
diff --git a/code/_onclick/hud/hud_elements/_hud_element.dm b/code/_onclick/hud/hud_elements/_hud_element.dm
new file mode 100644
index 000000000000..6fce5a0eba1b
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/_hud_element.dm
@@ -0,0 +1,24 @@
+/decl/hud_element
+ abstract_type = /decl/hud_element
+ /// /obj/screen path to create
+ var/elem_type
+ /// Index value for /datum/hud; defaults to src.type if null
+ var/elem_reference_type
+ /// Adds element to hidable list (inventory)
+ var/elem_is_hidable = FALSE
+ /// Adds element to hotkey list
+ var/elem_is_hotkey = FALSE
+ /// Adds element to aux list (hidden by F12)
+ var/elem_is_auxilliary = TRUE
+ /// Updates element icon in mob Life() proc
+ var/elem_updates_in_life = FALSE
+
+/decl/hud_element/validate()
+ . = ..()
+ if(!ispath(elem_type, /obj/screen))
+ . += "invalid elem_type ([elem_type || null]))"
+
+/decl/hud_element/Initialize()
+ . = ..()
+ if(isnull(elem_reference_type))
+ elem_reference_type = type
diff --git a/code/_onclick/hud/hud_elements/hud_auxilliary.dm b/code/_onclick/hud/hud_elements/hud_auxilliary.dm
new file mode 100644
index 000000000000..42ae7a89178c
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/hud_auxilliary.dm
@@ -0,0 +1,42 @@
+/decl/hud_element/movement
+ elem_type = /obj/screen/movement
+
+/decl/hud_element/internals
+ elem_type = /obj/screen/internals
+
+/decl/hud_element/zone_selector
+ elem_type = /obj/screen/zone_selector
+
+/decl/hud_element/upward
+ elem_type = /obj/screen/look_upward
+
+/decl/hud_element/throw_toggle
+ elem_type = /obj/screen/throw_toggle
+
+/decl/hud_element/maneuver
+ elem_type = /obj/screen/maneuver
+
+/decl/hud_element/drop
+ elem_type = /obj/screen/drop
+
+/decl/hud_element/resist
+ elem_type = /obj/screen/resist
+
+/decl/hud_element/attack
+ elem_type = /obj/screen/default_attack_selector
+
+/decl/hud_element/stamina
+ elem_type = /obj/screen/stamina
+ elem_updates_in_life = TRUE
+
+/decl/hud_element/charge
+ elem_type = /obj/screen/need/cell_charge
+ elem_updates_in_life = TRUE
+
+/decl/hud_element/nutrition
+ elem_type = /obj/screen/need/nutrition
+ elem_updates_in_life = TRUE
+
+/decl/hud_element/hydration
+ elem_type = /obj/screen/need/hydration
+ elem_updates_in_life = TRUE
diff --git a/code/_onclick/hud/hud_elements/hud_health.dm b/code/_onclick/hud/hud_elements/hud_health.dm
new file mode 100644
index 000000000000..955c4d8d576c
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/hud_health.dm
@@ -0,0 +1,7 @@
+/decl/hud_element/health
+ elem_type = /obj/screen/health
+ elem_updates_in_life = TRUE
+
+/decl/hud_element/health/organs
+ elem_type = /obj/screen/health/organs
+ elem_reference_type = /decl/hud_element/health
diff --git a/code/_onclick/hud/hud_elements/hud_permanent.dm b/code/_onclick/hud/hud_elements/hud_permanent.dm
new file mode 100644
index 000000000000..518a698775ca
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/hud_permanent.dm
@@ -0,0 +1,3 @@
+/decl/hud_element/intent
+ elem_type = /obj/screen/intent
+ elem_is_auxilliary = FALSE
diff --git a/code/_onclick/hud/hud_elements/hud_robot.dm b/code/_onclick/hud/hud_elements/hud_robot.dm
new file mode 100644
index 000000000000..a47c9c7866f0
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/hud_robot.dm
@@ -0,0 +1,62 @@
+/datum/hud/robot
+ gun_mode_toggle_type = /obj/screen/gun/mode
+ omit_hud_elements = list(
+ /decl/hud_element/health,
+ /decl/hud_element/charge,
+ /decl/hud_element/bodytemp,
+ /decl/hud_element/oxygen,
+ /decl/hud_element/toxins,
+ /decl/hud_element/pressure,
+ /decl/hud_element/nutrition,
+ /decl/hud_element/hydration,
+ /decl/hud_element/maneuver,
+ /decl/hud_element/movement,
+ /decl/hud_element/resist,
+ /decl/hud_element/drop,
+ /decl/hud_element/throw_toggle,
+ /decl/hud_element/internals,
+ )
+ additional_hud_elements = list(
+ /decl/hud_element/health/robot,
+ /decl/hud_element/charge/robot,
+ /decl/hud_element/oxygen/robot,
+ /decl/hud_element/module_selection,
+ /decl/hud_element/robot_inventory,
+ /decl/hud_element/robot_radio,
+ /decl/hud_element/robot_panel,
+ /decl/hud_element/robot_store,
+ /decl/hud_element/robot_drop_grab
+ )
+
+/decl/hud_element/oxygen/robot
+ elem_reference_type = /decl/hud_element/oxygen
+ elem_type = /obj/screen/warning/oxygen/robot
+
+/decl/hud_element/health/robot
+ elem_reference_type = /decl/hud_element/health
+ elem_type = /obj/screen/health/robot
+
+/decl/hud_element/charge/robot
+ elem_reference_type = /decl/hud_element/charge
+ elem_type = /obj/screen/need/cell_charge/robot
+
+/decl/hud_element/robot_inventory
+ elem_type = /obj/screen/robot/inventory
+ elem_is_auxilliary = FALSE
+
+/decl/hud_element/module_selection
+ elem_type = /obj/screen/robot/module/select
+ elem_is_auxilliary = FALSE
+
+/decl/hud_element/robot_radio
+ elem_type = /obj/screen/robot/radio
+
+/decl/hud_element/robot_panel
+ elem_type = /obj/screen/robot/panel
+
+/decl/hud_element/robot_store
+ elem_type = /obj/screen/robot/store
+
+/decl/hud_element/robot_drop_grab
+ elem_type = /obj/screen/robot/drop_grab
+ elem_updates_in_life = TRUE
diff --git a/code/_onclick/hud/hud_elements/hud_stubs.dm b/code/_onclick/hud/hud_elements/hud_stubs.dm
new file mode 100644
index 000000000000..261ae0d74e8b
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/hud_stubs.dm
@@ -0,0 +1,9 @@
+// Should not actually be used; defined for icon checks and HUD styles.
+/decl/hud_element/inventory
+ elem_type = /obj/screen/inventory
+/decl/hud_element/hands
+ elem_type = /obj/screen/inventory/hand
+/decl/hud_element/crit
+ elem_type = /obj/screen
+/decl/hud_element/gun_mode
+ elem_type = /obj/screen/gun
diff --git a/code/_onclick/hud/hud_elements/hud_warnings.dm b/code/_onclick/hud/hud_elements/hud_warnings.dm
new file mode 100644
index 000000000000..091aefa24c44
--- /dev/null
+++ b/code/_onclick/hud/hud_elements/hud_warnings.dm
@@ -0,0 +1,19 @@
+/decl/hud_element/fire
+ elem_type = /obj/screen/warning/fire
+ elem_updates_in_life = TRUE
+
+/decl/hud_element/oxygen
+ elem_type = /obj/screen/warning/oxygen
+ elem_updates_in_life = TRUE
+
+/decl/hud_element/toxins
+ elem_type = /obj/screen/warning/toxin
+ elem_updates_in_life = TRUE
+
+/decl/hud_element/bodytemp
+ elem_type = /obj/screen/warning/bodytemp
+ elem_updates_in_life = TRUE
+
+/decl/hud_element/pressure
+ elem_type = /obj/screen/warning/pressure
+ elem_updates_in_life = TRUE
diff --git a/code/_onclick/hud/hud_types/_hud.dm b/code/_onclick/hud/hud_types/_hud.dm
new file mode 100644
index 000000000000..d0a95fe197f5
--- /dev/null
+++ b/code/_onclick/hud/hud_types/_hud.dm
@@ -0,0 +1,591 @@
+/*
+ The hud datum
+ Used to show and hide huds for all the different mob types,
+ including inventories and item quick actions.
+*/
+
+/mob
+ var/datum/hud/hud_used
+
+/mob/proc/get_hud_element(hud_key)
+ if(!istype(hud_used))
+ return FALSE
+ return hud_used.get_element(hud_key)
+
+/mob/proc/refresh_hud_element(hud_key)
+ if(!istype(hud_used))
+ return FALSE
+ return hud_used.refresh_element(hud_key)
+
+/mob/proc/initialize_hud()
+ if(istype(hud_used))
+ QDEL_NULL(hud_used)
+ hud_used = initial(hud_used)
+ if(ispath(hud_used))
+ hud_used = new hud_used(src)
+ if(istype(hud_used))
+ hud_used.refresh_hud_icons()
+ refresh_lighting_master()
+
+/datum/hud
+ /// A reference to our owning mob.
+ var/mob/mymob
+ /// Used for the HUD toggle (F12)
+ VAR_PRIVATE/hud_shown = TRUE
+ // Used for showing or hiding the equipment buttons on the left.
+ VAR_PRIVATE/inventory_shown = TRUE
+ /// This is to hide the buttons that can be used via hotkeys. (hud_elements_hotkeys list of buttons)
+ VAR_PRIVATE/hotkey_ui_hidden = FALSE
+ /// Defines an assumed default /decl/ui_style for elements to use.
+ VAR_PRIVATE/default_ui_style = DEFAULT_UI_STYLE
+
+ /// Assoc list of current /decl/hud_element to values. Cannot be private, used by macro.
+ var/list/alerts
+
+ /// List of elements related to hand slots.
+ VAR_PRIVATE/list/obj/screen/hud_elements_hands
+ /// List of elements related to swapping hand slots.
+ VAR_PRIVATE/list/obj/screen/hud_elements_swap
+ /// List of elements related to hotkeys.
+ VAR_PRIVATE/list/obj/screen/hud_elements_hotkeys
+ /// List of elements that are hidden by the inventory toggle.
+ VAR_PRIVATE/list/obj/screen/hud_elements_hidable
+ /// List of elements that are not hidden by anything.
+ VAR_PRIVATE/list/obj/screen/hud_elements_unhidable
+ /// List of elements that are hidden by F12.
+ VAR_PRIVATE/list/obj/screen/hud_elements_auxilliary
+ /// List of elements that update icon in Life()
+ VAR_PRIVATE/list/obj/screen/hud_elements_update_in_life
+ /// Combined list of the above, used for qdel.
+ VAR_PRIVATE/list/obj/screen/all_hud_elements
+
+ /// List of /decl/hud_element types to use to populate this HUD on creation.
+ VAR_PROTECTED/list/hud_elements_to_create = list(
+ /decl/hud_element/movement,
+ /decl/hud_element/stamina,
+ /decl/hud_element/health,
+ /decl/hud_element/internals,
+ /decl/hud_element/charge,
+ /decl/hud_element/zone_selector,
+ /decl/hud_element/nutrition,
+ /decl/hud_element/hydration,
+ /decl/hud_element/upward,
+ /decl/hud_element/throw_toggle,
+ /decl/hud_element/maneuver,
+ /decl/hud_element/drop,
+ /decl/hud_element/resist,
+ /decl/hud_element/intent,
+ /decl/hud_element/fire,
+ /decl/hud_element/oxygen,
+ /decl/hud_element/toxins,
+ /decl/hud_element/bodytemp,
+ /decl/hud_element/pressure
+ )
+ /// /decl/hud_element types to be inserted into hud_elements_to_create during init.
+ VAR_PROTECTED/list/additional_hud_elements
+ /// /decl/hud_element types to be removed from hud_elements_to_create during init.
+ VAR_PROTECTED/list/omit_hud_elements
+ /// Elem type to created object dict; used to retrieve/update elements.
+ VAR_PRIVATE/list/hud_elem_decl_to_object = list()
+
+ // TODO: move these onto the HUD datum properly.
+ var/action_buttons_hidden = FALSE
+ var/obj/screen/action_button/hide_toggle/hide_actions_toggle
+
+ // TODO: declify these.
+ VAR_PROTECTED/gun_mode_toggle_type
+ VAR_PRIVATE/obj/screen/gun/mode/gun_mode_toggle
+ VAR_PRIVATE/obj/screen/gun/move/gun_move_toggle
+ VAR_PRIVATE/obj/screen/gun/item/gun_item_use_toggle
+ VAR_PRIVATE/obj/screen/gun/radio/gun_radio_use_toggle
+
+
+/datum/hud/New(mob/owner)
+ mymob = owner
+ instantiate()
+ ..()
+
+/datum/hud/Destroy()
+ . = ..()
+
+ LAZYCLEARLIST(hud_elements_hands)
+ LAZYCLEARLIST(hud_elements_swap)
+ LAZYCLEARLIST(hud_elements_hotkeys)
+ LAZYCLEARLIST(hud_elements_hidable)
+ LAZYCLEARLIST(hud_elements_unhidable)
+ LAZYCLEARLIST(hud_elements_auxilliary)
+ LAZYCLEARLIST(hud_elem_decl_to_object)
+ QDEL_NULL_LIST(all_hud_elements)
+
+ if(mymob)
+ if(mymob.hud_used == src)
+ mymob.hud_used = null
+ mymob = null
+
+/datum/hud/proc/is_hud_shown()
+ return hud_shown
+
+/datum/hud/proc/get_element(hud_key)
+ return hud_elem_decl_to_object[hud_key]
+
+/datum/hud/proc/refresh_element(hud_key)
+ var/obj/screen/elem = get_element(hud_key)
+ return elem?.update_icon() || FALSE
+
+/datum/hud/proc/refresh_hud_icons()
+ for(var/obj/screen/elem in mymob?.client?.screen)
+ elem.queue_icon_update()
+
+/datum/hud/proc/is_inventory_shown()
+ return inventory_shown
+
+/datum/hud/proc/hide_inventory()
+ inventory_shown = FALSE
+ if(LAZYLEN(hud_elements_hidable))
+ mymob?.client?.screen -= hud_elements_hidable
+ hidden_inventory_update()
+ persistent_inventory_update()
+
+/datum/hud/proc/show_inventory()
+ inventory_shown = TRUE
+ if(LAZYLEN(hud_elements_hidable))
+ mymob?.client?.screen += hud_elements_hidable
+ hidden_inventory_update()
+ persistent_inventory_update()
+
+/datum/hud/proc/hidden_inventory_update()
+ var/decl/species/species = mymob?.get_species()
+ if(istype(species?.species_hud))
+ refresh_inventory_slots(species.species_hud.hidden_slots, (inventory_shown && hud_shown))
+
+/datum/hud/proc/persistent_inventory_update()
+ var/decl/species/species = mymob?.get_species()
+ if(istype(species?.species_hud))
+ refresh_inventory_slots(species.species_hud.persistent_slots, hud_shown)
+
+/datum/hud/proc/refresh_inventory_slots(var/list/checking_slots, var/show_hud)
+
+ for(var/slot in checking_slots)
+
+ var/datum/inventory_slot/inv_slot = mymob.get_inventory_slot_datum(slot)
+ if(!istype(inv_slot))
+ continue
+
+ // Check if we're even wearing anything in that slot.
+ var/obj/item/gear = inv_slot.get_equipped_item()
+ if(!istype(gear))
+ continue
+
+ // We're not showing anything, hide it.
+ gear.reconsider_client_screen_presence(mymob?.client, slot)
+ if(!show_hud)
+ inv_slot.hide_slot()
+ else
+ inv_slot.show_slot()
+
+/datum/hud/proc/instantiate()
+ if(ismob(mymob) && mymob.client)
+ finalize_instantiation()
+ refresh_hud_icons()
+ return TRUE
+ return FALSE
+
+/datum/hud/proc/handle_life_hud_update()
+ for(var/obj/screen/elem as anything in hud_elements_update_in_life)
+ elem.update_icon()
+
+/datum/hud/proc/finalize_instantiation()
+
+ SHOULD_CALL_PARENT(TRUE)
+
+ var/decl/ui_style/ui_style = get_ui_style_data()
+ var/ui_color = get_ui_color()
+ var/ui_alpha = get_ui_alpha()
+
+ LAZYINITLIST(hud_elements_to_create)
+ if(length(additional_hud_elements))
+ hud_elements_to_create |= additional_hud_elements
+ if(length(omit_hud_elements))
+ hud_elements_to_create -= omit_hud_elements
+ UNSETEMPTY(hud_elements_to_create)
+
+ for(var/hud_elem_type in hud_elements_to_create)
+ var/decl/hud_element/hud_element = GET_DECL(hud_elem_type)
+ create_and_register_element(hud_element, ui_style, ui_color, ui_alpha)
+
+ //Handle the gun settings buttons
+ if(!gun_mode_toggle && gun_mode_toggle_type)
+ gun_mode_toggle = new gun_mode_toggle_type(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT)
+ LAZYADD(hud_elements_auxilliary, gun_mode_toggle)
+ gun_item_use_toggle = new(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT)
+ gun_move_toggle = new(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT)
+ gun_radio_use_toggle = new(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT)
+
+ build_inventory_ui()
+ build_hands_ui()
+
+ LAZYINITLIST(all_hud_elements)
+ if(LAZYLEN(hud_elements_hands))
+ all_hud_elements |= hud_elements_hands
+ if(LAZYLEN(hud_elements_swap))
+ all_hud_elements |= hud_elements_swap
+ if(LAZYLEN(hud_elements_hotkeys))
+ all_hud_elements |= hud_elements_hotkeys
+ if(LAZYLEN(hud_elements_hidable))
+ all_hud_elements |= hud_elements_hidable
+ if(LAZYLEN(hud_elements_unhidable))
+ all_hud_elements |= hud_elements_unhidable
+ if(LAZYLEN(hud_elements_auxilliary))
+ all_hud_elements |= hud_elements_auxilliary
+ UNSETEMPTY(all_hud_elements)
+
+ if(mymob.client)
+ mymob.client.screen = list()
+ if(LAZYLEN(all_hud_elements))
+ mymob.client.screen |= all_hud_elements
+
+ hide_inventory()
+
+/datum/hud/proc/get_ui_style_data()
+ RETURN_TYPE(/decl/ui_style)
+ . = GET_DECL(mymob?.client?.prefs?.UI_style) || GET_DECL(default_ui_style)
+ if(!.)
+ var/list/available_styles = get_ui_styles()
+ if(length(available_styles))
+ . = available_styles[1]
+
+/datum/hud/proc/get_ui_color()
+ var/decl/ui_style/ui_style = get_ui_style_data()
+ if(!ui_style?.use_ui_color)
+ return COLOR_WHITE
+ return mymob?.client?.prefs?.UI_style_color || COLOR_WHITE
+
+/datum/hud/proc/get_ui_alpha()
+ return mymob?.client?.prefs?.UI_style_alpha || 255
+
+/datum/hud/proc/rebuild_hands()
+
+ var/decl/ui_style/ui_style = get_ui_style_data()
+ var/ui_color = get_ui_color()
+ var/ui_alpha = get_ui_alpha()
+
+ // Build held item boxes for missing slots.
+ var/list/held_slots = mymob.get_held_item_slots()
+
+ // Sort our slots for display.
+ var/list/gripper_datums = list()
+ for(var/hand_tag in held_slots)
+ gripper_datums += mymob.get_inventory_slot_datum(hand_tag)
+ gripper_datums = sortTim(gripper_datums, /proc/cmp_gripper_asc)
+
+ for(var/datum/inventory_slot/gripper/inv_slot in gripper_datums)
+
+ // Re-order the held slot list so it aligns with the display order.
+ var/hand_tag = inv_slot.slot_id
+ held_slots -= hand_tag
+ held_slots += hand_tag
+
+ var/obj/screen/inventory/inv_box
+ for(var/obj/screen/inventory/existing_box in hud_elements_hands)
+ if(existing_box.slot_id == hand_tag)
+ inv_box = existing_box
+ break
+
+ if(!inv_box)
+ inv_box = new /obj/screen/inventory/hand(null, mymob, ui_style, ui_color, ui_alpha, HUD_HANDS)
+ else
+ inv_box.set_ui_style(ui_style, HUD_HANDS)
+ inv_box.color = ui_color
+ inv_box.alpha = ui_alpha
+
+ LAZYDISTINCTADD(hud_elements_hands, inv_box)
+
+ inv_box.SetName(hand_tag)
+ inv_box.slot_id = hand_tag
+ inv_box.update_icon()
+
+ // Clear held item boxes with no held slot.
+ for(var/obj/screen/inventory/inv_box in hud_elements_hands)
+ if(!(inv_box.slot_id in held_slots))
+ if(mymob.client)
+ mymob.client.screen -= inv_box
+ LAZYREMOVE(hud_elements_hands, inv_box)
+ qdel(inv_box)
+
+ // Rebuild offsets for the hand elements.
+ var/hand_y_offset = 21
+ var/list/elements = hud_elements_hands?.Copy()
+ while(length(elements))
+ var/copy_index = min(length(elements), 2)+1
+ var/list/sublist = elements.Copy(1, copy_index)
+ elements.Cut(1, copy_index)
+ var/obj/screen/inventory/inv_box
+ if(length(sublist) == 1)
+ inv_box = sublist[1]
+ inv_box.screen_loc = "CENTER,BOTTOM:[hand_y_offset]"
+ else
+ inv_box = sublist[1]
+ inv_box.screen_loc = "CENTER:-[world.icon_size/2],BOTTOM:[hand_y_offset]"
+ inv_box = sublist[2]
+ inv_box.screen_loc = "CENTER:[world.icon_size/2],BOTTOM:[hand_y_offset]"
+ hand_y_offset += world.icon_size
+
+ if(mymob.client && islist(hud_elements_hands) && length(hud_elements_hands))
+ mymob.client.screen |= hud_elements_hands
+
+ // Make sure all held items are on the screen and set to the correct screen loc.
+ var/datum/inventory_slot/inv_slot
+ for(var/obj/inv_elem in hud_elements_hands)
+ inv_slot = mymob.get_inventory_slot_datum(inv_elem.name)
+ if(inv_slot)
+ inv_slot.ui_loc = inv_elem.screen_loc
+ var/obj/item/held = inv_slot.get_equipped_item()
+ if(held)
+ held.screen_loc = inv_slot.ui_loc
+ if(mymob.client)
+ mymob.client.screen |= held // just to make sure it's visible post-login
+
+ if(length(hud_elements_swap))
+ var/hand_x_offset = -(world.icon_size/2)
+ for(var/i = 1 to length(hud_elements_swap))
+ var/obj/swap_elem = hud_elements_swap[i]
+ swap_elem.screen_loc = "CENTER:[hand_x_offset],BOTTOM:[hand_y_offset]"
+ if(i > 1) // first two elems share a slot
+ hand_x_offset += world.icon_size
+ if(mymob.client)
+ mymob.client.screen |= swap_elem
+
+/datum/hud/proc/build_inventory_ui()
+
+ var/decl/ui_style/ui_style = get_ui_style_data()
+ var/ui_color = get_ui_color()
+ var/ui_alpha = get_ui_alpha()
+
+ var/has_hidden_gear = FALSE
+
+ // Draw the various inventory equipment slots.
+ var/obj/screen/inventory/inv_box
+ var/list/held_slots = mymob.get_held_item_slots()
+ var/list/inventory_slots = mymob.get_inventory_slots()
+ for(var/gear_slot in inventory_slots)
+
+ if(gear_slot in held_slots)
+ continue
+
+ inv_box = new /obj/screen/inventory(null, mymob, ui_style, ui_color, ui_alpha, HUD_INVENTORY)
+
+ var/datum/inventory_slot/inv_slot = inventory_slots[gear_slot]
+ inv_box.SetName(inv_slot.slot_name)
+ inv_box.slot_id = inv_slot.slot_id
+ inv_box.icon_state = inv_slot.slot_state
+ inv_box.screen_loc = inv_slot.ui_loc
+
+ if(inv_slot.slot_dir)
+ inv_box.set_dir(inv_slot.slot_dir)
+
+ if(inv_slot.can_be_hidden)
+ LAZYDISTINCTADD(hud_elements_hidable, inv_box)
+ has_hidden_gear = TRUE
+ else
+ hud_elements_auxilliary += inv_box
+
+ if(has_hidden_gear)
+ hud_elements_auxilliary += new /obj/screen/toggle(null, mymob, ui_style, ui_color, ui_alpha, HUD_INVENTORY)
+
+/datum/hud/proc/build_hands_ui()
+
+ var/list/held_slots = mymob.get_held_item_slots()
+ if(length(held_slots) <= 0)
+ return
+
+ var/decl/ui_style/ui_style = get_ui_style_data()
+ var/ui_color = get_ui_color()
+ var/ui_alpha = get_ui_alpha()
+
+ // Swap hand and quick equip screen elems.
+ var/obj/screen/using = new /obj/screen/equip(null, mymob, ui_style, ui_color, ui_alpha, HUD_HANDS)
+ LAZYADD(hud_elements_swap, using)
+ if(length(held_slots) > 1)
+
+ using = new /obj/screen/inventory/swaphand(null, mymob, ui_style, ui_color, ui_alpha, HUD_HANDS)
+ LAZYADD(hud_elements_swap, using)
+ using = new /obj/screen/inventory/swaphand/right(null, mymob, ui_style, ui_color, ui_alpha, HUD_HANDS)
+ LAZYADD(hud_elements_swap, using)
+
+ // Actual hand elems.
+ rebuild_hands()
+
+/datum/hud/proc/toggle_show_inventory()
+ if(inventory_shown)
+ hide_inventory()
+ else
+ show_inventory()
+ return TRUE
+
+/datum/hud/proc/toggle_action_buttons_hidden()
+ action_buttons_hidden = !action_buttons_hidden
+ return action_buttons_hidden
+
+/datum/hud/proc/toggle_minimize(var/full)
+ if(hud_shown)
+ hud_shown = FALSE
+ if(hud_elements_auxilliary)
+ mymob?.client?.screen -= hud_elements_auxilliary
+ if(hud_elements_hidable)
+ mymob?.client?.screen -= hud_elements_hidable
+ if(hud_elements_hotkeys)
+ mymob?.client?.screen -= hud_elements_hotkeys
+ if(!full)
+ if(LAZYLEN(hud_elements_hands))
+ mymob?.client?.screen += hud_elements_hands // we want the hands to be visible
+ if(LAZYLEN(hud_elements_swap))
+ mymob?.client?.screen += hud_elements_swap // we want the hands swap thingy to be visible
+ else
+ hud_shown = TRUE
+ if(LAZYLEN(hud_elements_auxilliary))
+ mymob?.client?.screen |= hud_elements_auxilliary
+ if(LAZYLEN(hud_elements_hidable) && inventory_shown)
+ mymob?.client?.screen |= hud_elements_hidable
+ if(LAZYLEN(hud_elements_hotkeys) && !hotkey_ui_hidden)
+ mymob?.client?.screen |= hud_elements_hotkeys
+ hidden_inventory_update()
+ persistent_inventory_update()
+
+/datum/hud/proc/toggle_zoom_hud()
+ if(hud_shown)
+ hud_shown = FALSE
+ if(LAZYLEN(hud_elements_auxilliary))
+ mymob?.client?.screen -= hud_elements_auxilliary
+ if(LAZYLEN(hud_elements_hidable))
+ mymob?.client?.screen -= hud_elements_hidable
+ if(LAZYLEN(hud_elements_hotkeys))
+ mymob?.client?.screen -= hud_elements_hotkeys
+ else
+ hud_shown = TRUE
+ if(LAZYLEN(hud_elements_auxilliary))
+ mymob?.client?.screen += hud_elements_auxilliary
+ if(LAZYLEN(hud_elements_hidable) && inventory_shown)
+ mymob?.client?.screen += hud_elements_hidable
+ if(LAZYLEN(hud_elements_hotkeys) && !hotkey_ui_hidden)
+ mymob?.client?.screen += hud_elements_hotkeys
+ hidden_inventory_update()
+ persistent_inventory_update()
+
+/datum/hud/proc/toggle_hotkeys()
+ if(hotkey_ui_hidden)
+ mymob?.client?.screen += hud_elements_hotkeys
+ hotkey_ui_hidden = 0
+ else
+ mymob?.client?.screen -= hud_elements_hotkeys
+ hotkey_ui_hidden = TRUE
+
+/mob/verb/toggle_hotkey_verbs()
+ set category = "OOC"
+ set name = "Toggle hotkey buttons"
+ set desc = "This disables or enables the user interface buttons which can be used with hotkeys."
+ if(!istype(hud_used))
+ return
+ hud_used.toggle_hotkeys()
+
+/mob/verb/minimize_hud(full = FALSE as null)
+ set name = "Minimize Hud"
+ set hidden = TRUE
+ if(isnull(hud_used))
+ to_chat(usr, SPAN_WARNING("This mob type does not use a HUD."))
+ return
+ if(!client || !istype(hud_used))
+ return
+ hud_used.toggle_minimize(full)
+ update_action_buttons()
+
+//Similar to minimize_hud() but keeps zone_selector, gun_setting_itoggle, and health_warning.
+/mob/proc/toggle_zoom_hud()
+ if(!istype(hud_used))
+ return
+ if(!ishuman(src))
+ return
+ if(!client)
+ return
+ if(client.view != world.view)
+ return
+
+ hud_used.toggle_zoom_hud()
+ update_action_buttons()
+
+/client/proc/reset_click_catchers()
+
+ var/xmin = -(round(last_view_x_dim*0.5))
+ var/xmax = last_view_x_dim - abs(xmin)
+ var/ymin = -(round(last_view_y_dim*0.5))
+ var/ymax = last_view_y_dim - abs(ymin)
+
+ var/list/click_catchers = get_click_catchers()
+ for(var/obj/screen/click_catcher/catcher in click_catchers)
+ if(catcher.x_offset <= xmin || catcher.x_offset >= xmax || catcher.y_offset <= ymin || catcher.y_offset >= ymax)
+ screen -= catcher
+ else
+ screen |= catcher
+
+/mob/proc/add_click_catcher()
+ client.reset_click_catchers()
+
+/mob/new_player/add_click_catcher()
+ return
+
+//These are called by the on-screen buttons, adjusting what the victim can and cannot do.
+/datum/hud/proc/add_gun_icons()
+ // This can runtime if someone manages to throw a gun out of their hand before the proc is called.
+ if(!gun_item_use_toggle)
+ return TRUE
+ if(mymob?.client)
+ mymob.client.screen |= gun_item_use_toggle
+ mymob.client.screen |= gun_move_toggle
+ mymob.client.screen |= gun_radio_use_toggle
+
+/datum/hud/proc/remove_gun_icons()
+ if(mymob?.client)
+ mymob.client.screen -= gun_item_use_toggle
+ mymob.client.screen -= gun_move_toggle
+ mymob.client.screen -= gun_radio_use_toggle
+
+/datum/hud/proc/update_hand_elements()
+ for(var/atom/hand as anything in hud_elements_hands)
+ hand.update_icon()
+
+
+/datum/hud/proc/update_gun_mode_icons(target_permissions)
+ if(gun_move_toggle)
+ if(!(target_permissions & TARGET_CAN_MOVE))
+ gun_move_toggle.SetName("Allow Movement")
+ else
+ gun_move_toggle.SetName("Disallow Movement")
+ gun_move_toggle.update_icon()
+ if(gun_item_use_toggle)
+ if(!(target_permissions & TARGET_CAN_CLICK))
+ gun_item_use_toggle.SetName("Allow Item Use")
+ else
+ gun_item_use_toggle.SetName("Disallow Item Use")
+ gun_item_use_toggle.update_icon()
+ if(gun_radio_use_toggle)
+ if(!(target_permissions & TARGET_CAN_RADIO))
+ gun_radio_use_toggle.SetName("Allow Radio Use")
+ else
+ gun_radio_use_toggle.SetName("Disallow Radio Use")
+ gun_radio_use_toggle.update_icon()
+
+/datum/hud/proc/create_and_register_element(decl/hud_element/ui_elem, decl/ui_style/ui_style, ui_color, ui_alpha)
+ if(!istype(ui_elem) || !ui_elem.elem_type)
+ return FALSE
+ var/obj/screen/elem = new ui_elem.elem_type(null, mymob, ui_style, ui_color, ui_alpha, ui_elem.elem_reference_type)
+ if(ui_elem.elem_is_hotkey)
+ LAZYDISTINCTADD(hud_elements_hotkeys, elem)
+ else if(ui_elem.elem_is_auxilliary)
+ LAZYDISTINCTADD(hud_elements_auxilliary, elem)
+ else if(ui_elem.elem_is_hidable)
+ LAZYDISTINCTADD(hud_elements_hidable, elem)
+ else
+ LAZYDISTINCTADD(hud_elements_unhidable, elem)
+ if(ui_elem.elem_updates_in_life)
+ LAZYDISTINCTADD(hud_elements_update_in_life, elem)
+ hud_elem_decl_to_object[ui_elem.elem_reference_type] = elem
+ return elem
diff --git a/code/_onclick/hud/hud_types/ai.dm b/code/_onclick/hud/hud_types/ai.dm
new file mode 100644
index 000000000000..e6f0c0394aab
--- /dev/null
+++ b/code/_onclick/hud/hud_types/ai.dm
@@ -0,0 +1,25 @@
+/mob/living/silicon/ai
+ hud_used = /datum/hud/ai
+
+/datum/hud/ai
+ omit_hud_elements = list(
+ /decl/hud_element/intent,
+ /decl/hud_element/health,
+ /decl/hud_element/charge,
+ /decl/hud_element/bodytemp,
+ /decl/hud_element/oxygen,
+ /decl/hud_element/toxins,
+ /decl/hud_element/pressure,
+ /decl/hud_element/nutrition,
+ /decl/hud_element/hydration,
+ /decl/hud_element/maneuver,
+ /decl/hud_element/movement,
+ /decl/hud_element/resist,
+ /decl/hud_element/drop,
+ /decl/hud_element/throw_toggle,
+ /decl/hud_element/internals
+ )
+
+/datum/hud/ai/New()
+ additional_hud_elements = subtypesof(/decl/hud_element/ai)
+ ..()
diff --git a/code/_onclick/hud/ai_hud.dm b/code/_onclick/hud/hud_types/ai_hud.dm
similarity index 81%
rename from code/_onclick/hud/ai_hud.dm
rename to code/_onclick/hud/hud_types/ai_hud.dm
index fa4e2200bb63..555c40a5d6f5 100644
--- a/code/_onclick/hud/ai_hud.dm
+++ b/code/_onclick/hud/hud_types/ai_hud.dm
@@ -1,5 +1,6 @@
-/decl/ai_hud
- abstract_type = /decl/ai_hud
+/decl/hud_element/ai
+ abstract_type = /decl/hud_element/ai
+ elem_type = /obj/screen/ai_button
var/screen_loc
var/name
var/icon_state
@@ -7,137 +8,137 @@
var/list/input_procs
var/list/input_args
-/decl/ai_hud/ai_core
+/decl/hud_element/ai/core
screen_loc = ui_ai_core
name = "AI Core"
icon_state = "ai_core"
proc_path = /mob/living/silicon/ai/proc/core
-/decl/ai_hud/ai_announcement
+/decl/hud_element/ai/announcement
screen_loc = ui_ai_announcement
name = "AI Announcement"
icon_state = "announcement"
proc_path = /mob/living/silicon/ai/proc/ai_announcement
-/decl/ai_hud/ai_cam_track
+/decl/hud_element/ai/cam_track
screen_loc = ui_ai_cam_track
name = "Track With Camera"
icon_state = "track"
proc_path = /mob/living/silicon/ai/proc/ai_camera_track
input_procs = list(/mob/living/silicon/ai/proc/trackable_mobs = (AI_BUTTON_PROC_BELONGS_TO_CALLER|AI_BUTTON_INPUT_REQUIRES_SELECTION))
-/decl/ai_hud/ai_cam_light
+/decl/hud_element/ai/cam_light
screen_loc = ui_ai_cam_light
name = "Toggle Camera Lights"
icon_state = "camera_light"
proc_path = /mob/living/silicon/ai/proc/toggle_camera_light
-/decl/ai_hud/ai_cam_change_channel
+/decl/hud_element/ai/cam_change_channel
screen_loc = ui_ai_cam_change_channel
name = "Jump to Camera Channel"
icon_state = "camera"
proc_path = /mob/living/silicon/ai/proc/ai_channel_change
input_procs = list(/mob/living/silicon/ai/proc/get_camera_channel_list = (AI_BUTTON_PROC_BELONGS_TO_CALLER|AI_BUTTON_INPUT_REQUIRES_SELECTION))
-/decl/ai_hud/ai_sensor
+/decl/hud_element/ai/sensor
screen_loc = ui_ai_sensor
name = "Set Sensor Mode"
icon_state = "ai_sensor"
proc_path = /mob/living/silicon/ai/proc/sensor_mode
-/decl/ai_hud/ai_manifest
+/decl/hud_element/ai/manifest
screen_loc = ui_ai_crew_manifest
name = "Show Crew Manifest"
icon_state = "manifest"
proc_path = /mob/living/silicon/ai/proc/run_program
input_args = list("crewmanifest")
-/decl/ai_hud/ai_take_image
+/decl/hud_element/ai/take_image
screen_loc = ui_ai_take_image
name = "Toggle Camera Mode"
icon_state = "take_picture"
proc_path = /mob/living/silicon/ai/proc/ai_take_image
-/decl/ai_hud/ai_view_images
+/decl/hud_element/ai/view_images
screen_loc = ui_ai_view_images
name = "View Images"
icon_state = "view_images"
proc_path = /mob/living/silicon/ai/proc/ai_view_images
-/decl/ai_hud/ai_laws
+/decl/hud_element/ai/laws
screen_loc = ui_ai_state_laws
name = "State Laws"
icon_state = "state_laws"
proc_path = /mob/living/silicon/ai/proc/ai_checklaws
-/decl/ai_hud/ai_call_shuttle
+/decl/hud_element/ai/call_shuttle
screen_loc = ui_ai_call_shuttle
name = "Call Shuttle"
icon_state = "call_shuttle"
proc_path = /mob/living/silicon/ai/proc/ai_call_shuttle
-/decl/ai_hud/ai_up
+/decl/hud_element/ai/up
screen_loc = ui_ai_up
name = "Move Upwards"
icon_state = "ai_up"
proc_path = /mob/verb/up
-/decl/ai_hud/ai_down
+/decl/hud_element/ai/down
screen_loc = ui_ai_down
name = "Move Downwards"
icon_state = "ai_down"
proc_path = /mob/verb/down
-/decl/ai_hud/ai_color
+/decl/hud_element/ai/color
screen_loc = ui_ai_color
name = "Change Floor Color"
icon_state = "ai_floor"
proc_path = /mob/living/silicon/ai/proc/change_floor
-/decl/ai_hud/ai_hologram
+/decl/hud_element/ai/hologram
screen_loc = ui_ai_holo_change
name = "Change Hologram"
icon_state = "ai_holo_change"
proc_path = /mob/living/silicon/ai/proc/ai_hologram_change
-/decl/ai_hud/ai_crew_monitor
+/decl/hud_element/ai/crew_monitor
screen_loc = ui_ai_crew_mon
name = "Crew Monitor"
icon_state = "crew_monitor"
proc_path = /mob/living/silicon/ai/proc/run_program
input_args = list("sensormonitor")
-/decl/ai_hud/ai_power_override
+/decl/hud_element/ai/power_override
screen_loc = ui_ai_power_override
name = "Toggle Power Override"
icon_state = "ai_p_override"
proc_path = /mob/living/silicon/ai/proc/ai_power_override
-/decl/ai_hud/ai_shutdown
+/decl/hud_element/ai/shutdown
screen_loc = ui_ai_shutdown
name = "Shutdown"
icon_state = "ai_shutdown"
proc_path = /mob/living/silicon/ai/proc/ai_shutdown
-/decl/ai_hud/ai_move_hologram
+/decl/hud_element/ai/move_hologram
screen_loc = ui_ai_holo_mov
name = "Toggle Hologram Movement"
icon_state = "ai_holo_mov"
proc_path = /mob/living/silicon/ai/proc/toggle_hologram_movement
-/decl/ai_hud/ai_core_icon
+/decl/hud_element/ai/core_icon
screen_loc = ui_ai_core_icon
name = "Pick Icon"
icon_state = "ai_core_pick"
proc_path = /mob/living/silicon/ai/proc/pick_icon
-/decl/ai_hud/ai_status
+/decl/hud_element/ai/status
screen_loc = ui_ai_status
name = "Pick Status"
icon_state = "ai_status"
proc_path = /mob/living/silicon/ai/proc/ai_statuschange
-/decl/ai_hud/ai_inbuilt_comp
+/decl/hud_element/ai/inbuilt_comp
screen_loc = ui_ai_crew_rec
name = "Inbuilt Computer"
icon_state = "ai_crew_rec"
diff --git a/code/_onclick/hud/hud_types/animal.dm b/code/_onclick/hud/hud_types/animal.dm
new file mode 100644
index 000000000000..84c9d7736b79
--- /dev/null
+++ b/code/_onclick/hud/hud_types/animal.dm
@@ -0,0 +1,11 @@
+/datum/hud/animal
+ hud_elements_to_create = list(
+ /decl/hud_element/movement,
+ /decl/hud_element/stamina,
+ /decl/hud_element/health,
+ /decl/hud_element/zone_selector,
+ /decl/hud_element/upward,
+ /decl/hud_element/maneuver,
+ /decl/hud_element/resist,
+ /decl/hud_element/intent
+ )
diff --git a/code/_onclick/hud/hud_types/human.dm b/code/_onclick/hud/hud_types/human.dm
new file mode 100644
index 000000000000..9f08721970ef
--- /dev/null
+++ b/code/_onclick/hud/hud_types/human.dm
@@ -0,0 +1,10 @@
+/mob/living/human
+ hud_used = /datum/hud/human
+
+/datum/hud/human
+ gun_mode_toggle_type = /obj/screen/gun/mode
+ omit_hud_elements = list(/decl/hud_element/health)
+ additional_hud_elements = list(
+ /decl/hud_element/health/organs,
+ /decl/hud_element/attack
+ )
diff --git a/code/_onclick/hud/hud_types/other_mobs.dm b/code/_onclick/hud/hud_types/other_mobs.dm
new file mode 100644
index 000000000000..96c117e4d465
--- /dev/null
+++ b/code/_onclick/hud/hud_types/other_mobs.dm
@@ -0,0 +1,61 @@
+/datum/hud/animal/construct
+ omit_hud_elements = list(/decl/hud_element/health)
+ additional_hud_elements = list(/decl/hud_element/health/construct)
+
+/decl/hud_element/health/construct
+ elem_reference_type = /decl/hud_element/health
+ elem_type = /obj/screen/health/construct
+
+/datum/hud/animal/construct/get_ui_style_data()
+ return GET_DECL(/decl/ui_style/construct)
+
+/datum/hud/animal/construct/juggernaut/get_ui_style_data()
+ return GET_DECL(/decl/ui_style/construct/juggernaut)
+
+/datum/hud/animal/construct/harvester/get_ui_style_data()
+ return GET_DECL(/decl/ui_style/construct/harvester)
+
+/datum/hud/animal/construct/wraith/get_ui_style_data()
+ return GET_DECL(/decl/ui_style/construct/wraith)
+
+/datum/hud/animal/construct/artificer/get_ui_style_data()
+ return GET_DECL(/decl/ui_style/construct/artificer)
+
+/datum/hud/animal/construct/get_ui_color()
+ return COLOR_WHITE
+
+/datum/hud/animal/construct/get_ui_alpha()
+ return 255
+
+/decl/ui_style/construct
+ name = "Construct"
+ restricted = TRUE
+ override_icons = list(
+ (HUD_FIRE) = 'icons/mob/screen/styles/constructs/status_fire.dmi',
+ (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/constructs/zone_selector.dmi'
+ )
+ uid = "ui_style_construct"
+/decl/ui_style/construct/juggernaut
+ name = "Juggernaut"
+ uid = "ui_style_construct_juggernaut"
+/decl/ui_style/construct/juggernaut/Initialize()
+ override_icons[HUD_HEALTH] = 'icons/mob/screen/styles/constructs/juggernaut/health.dmi'
+ return ..()
+/decl/ui_style/construct/harvester
+ name = "Harvester"
+ uid = "ui_style_construct_harvester"
+/decl/ui_style/construct/harvester/Initialize()
+ override_icons[HUD_HEALTH] = 'icons/mob/screen/styles/constructs/harvester/health.dmi'
+ return ..()
+/decl/ui_style/construct/wraith
+ name = "Wraith"
+ uid = "ui_style_construct_wraith"
+/decl/ui_style/construct/wraith/Initialize()
+ override_icons[HUD_HEALTH] = 'icons/mob/screen/styles/constructs/wraith/health.dmi'
+ return ..()
+/decl/ui_style/construct/artificer
+ name = "Artificer"
+ uid = "ui_style_construct_artificer"
+/decl/ui_style/construct/artificer/Initialize()
+ override_icons[HUD_HEALTH] = 'icons/mob/screen/styles/constructs/artificer/health.dmi'
+ return ..()
diff --git a/code/_onclick/hud/hud_types/pai.dm b/code/_onclick/hud/hud_types/pai.dm
new file mode 100644
index 000000000000..4521b70b5823
--- /dev/null
+++ b/code/_onclick/hud/hud_types/pai.dm
@@ -0,0 +1,6 @@
+/datum/hud/pai
+ hud_elements_to_create = list(/decl/hud_element/health/robot)
+
+/datum/hud/pai/New()
+ hud_elements_to_create += subtypesof(/decl/hud_element/pai)
+ ..()
diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/hud_types/robot.dm
similarity index 51%
rename from code/_onclick/hud/robot.dm
rename to code/_onclick/hud/hud_types/robot.dm
index b0680d9f047a..0f53b8f70777 100644
--- a/code/_onclick/hud/robot.dm
+++ b/code/_onclick/hud/hud_types/robot.dm
@@ -1,5 +1,3 @@
-var/global/obj/screen/robot_inventory
-
/mob/living/silicon/robot
hud_used = /datum/hud/robot
@@ -8,10 +6,11 @@ var/global/obj/screen/robot_inventory
restricted = TRUE
uid = "ui_style_robot"
override_icons = list(
- UI_ICON_HEALTH = 'icons/mob/screen/styles/robot/health.dmi',
- UI_ICON_STATUS_FIRE = 'icons/mob/screen/styles/robot/status_fire.dmi',
- UI_ICON_UP_HINT = 'icons/mob/screen/styles/robot/uphint.dmi',
- UI_ICON_ZONE_SELECT = 'icons/mob/screen/styles/robot/zone_selector.dmi'
+ (HUD_HEALTH) = 'icons/mob/screen/styles/robot/health.dmi',
+ (HUD_FIRE) = 'icons/mob/screen/styles/robot/status_fire.dmi',
+ (HUD_OXY) = 'icons/mob/screen/styles/robot/status_oxy.dmi',
+ (HUD_UP_HINT) = 'icons/mob/screen/styles/robot/uphint.dmi',
+ (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/robot/zone_selector.dmi'
)
/datum/hud/robot/get_ui_style_data()
@@ -23,51 +22,18 @@ var/global/obj/screen/robot_inventory
/datum/hud/robot/get_ui_alpha()
return 255
-/datum/hud/robot/FinalizeInstantiation()
-
+// TODO: Convert robots to use inventory slots.
+/datum/hud/robot/finalize_instantiation()
var/mob/living/silicon/robot/R = mymob
if(!istype(R))
- ..()
- return
-
- var/decl/ui_style/ui_style = get_ui_style_data()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
-
- //Radio
- adding += new /obj/screen/robot_radio(null, mymob)
-
- //Module select
+ return ..()
R.inv1 = new(null, mymob)
R.inv2 = new(null, mymob)
R.inv3 = new(null, mymob)
- adding += R.inv1
- adding += R.inv2
- adding += R.inv3
- //End of module select
-
- // Drop UI
- R.ui_drop_grab = new(null, mymob)
- adding += R.ui_drop_grab
-
- adding += new /obj/screen/robot_panel(null, mymob)
- adding += new /obj/screen/robot_store(null, mymob)
-
- R.hands = new /obj/screen/robot_module/select(null, mymob)
- robot_inventory = new /obj/screen/robot_inventory( null, mymob)
- R.cells = new /obj/screen/robot_charge( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_CHARGE)
- R.healths = new /obj/screen/robot_health( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HEALTH)
- R.bodytemp = new /obj/screen/bodytemp( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS)
- R.oxygen = new /obj/screen/robot_oxygen( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS)
- R.fire = new /obj/screen/robot_fire( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS_FIRE)
- R.up_hint = new /obj/screen/up_hint( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_UP_HINT)
- R.zone_sel = new( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_ZONE_SELECT)
- R.gun_setting_icon = new /obj/screen/gun/mode( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT)
- R.item_use_icon = new /obj/screen/gun/item( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT)
- R.gun_move_icon = new /obj/screen/gun/move( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT)
- R.radio_use_icon = new /obj/screen/gun/radio( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT)
-
- hud_elements = list(R.zone_sel, R.oxygen, R.fire, R.up_hint, R.hands, R.healths, R.cells, robot_inventory, R.gun_setting_icon)
+ LAZYINITLIST(hud_elements_auxilliary)
+ hud_elements_auxilliary += R.inv1
+ hud_elements_auxilliary += R.inv2
+ hud_elements_auxilliary += R.inv3
..()
/datum/hud/proc/toggle_show_robot_modules()
@@ -135,7 +101,6 @@ var/global/obj/screen/robot_inventory
else
//Modules display is hidden
- //R.client.screen -= robot_inventory //"store" icon
for(var/atom/A in R.module.equipment)
if( (A != R.module_state_1) && (A != R.module_state_2) && (A != R.module_state_3) )
//Module is not currently active
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
deleted file mode 100644
index 7dc1d837d915..000000000000
--- a/code/_onclick/hud/human.dm
+++ /dev/null
@@ -1,111 +0,0 @@
-/mob/living/human
- hud_used = /datum/hud/human
-
-/datum/hud/human/FinalizeInstantiation()
-
- var/decl/ui_style/ui_style = get_ui_style_data()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
-
- var/mob/living/human/target = mymob
- var/datum/hud_data/hud_data = istype(target?.species?.species_hud) ? target.species.species_hud : new
-
- hotkeybuttons = list() //These can be disabled for hotkey usersx
-
- stamina_bar = new(null, mymob)
- adding += stamina_bar
-
- if(hud_data.has_m_intent)
- move_intent = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_MOVEMENT)
- move_intent.icon_state = mymob.move_intent.hud_icon_state
- src.adding += move_intent
-
- if(hud_data.has_drop)
- src.hotkeybuttons += new /obj/screen/drop(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTERACTION)
-
- if(hud_data.has_resist)
- src.hotkeybuttons += new /obj/screen/resist(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTERACTION)
-
- mymob.maneuver_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTERACTION)
- src.hotkeybuttons += mymob.maneuver_icon
- hud_elements |= mymob.maneuver_icon
-
- if(hud_data.has_throw)
- mymob.throw_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTERACTION)
- src.hotkeybuttons += mymob.throw_icon
- hud_elements |= mymob.throw_icon
-
- if(hud_data.has_internals)
- mymob.internals = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTERNALS)
- hud_elements |= mymob.internals
-
- if(hud_data.has_warnings)
- mymob.healths = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS)
- hud_elements |= mymob.healths
-
- mymob.oxygen = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS)
- hud_elements |= mymob.oxygen
-
- mymob.toxin = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS)
- hud_elements |= mymob.toxin
-
- mymob.fire = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS_FIRE)
- hud_elements |= mymob.fire
-
- if(hud_data.has_pressure)
- mymob.pressure = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS)
- hud_elements |= mymob.pressure
-
- if(hud_data.has_bodytemp)
- mymob.bodytemp = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS)
- hud_elements |= mymob.bodytemp
-
- if(target.isSynthetic())
- target.cells = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_CHARGE)
- hud_elements |= target.cells
-
- else if(hud_data.has_nutrition)
- mymob.nutrition_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_NUTRITION)
- hud_elements |= mymob.nutrition_icon
-
- mymob.hydration_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HYDRATION)
- hud_elements |= mymob.hydration_icon
-
- if(hud_data.has_up_hint)
- mymob.up_hint = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_UP_HINT)
- hud_elements |= mymob.up_hint
-
- mymob.pain = new(null, mymob)
- hud_elements |= mymob.pain
-
- mymob.zone_sel = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_ZONE_SELECT)
- mymob.zone_sel.update_icon()
- hud_elements |= mymob.zone_sel
-
- target.attack_selector = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_ATTACK)
- hud_elements |= target.attack_selector
-
- //Handle the gun settings buttons
- mymob.gun_setting_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT)
- hud_elements |= mymob.gun_setting_icon
-
- mymob.item_use_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT)
- mymob.gun_move_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT)
- mymob.radio_use_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT)
-
- ..()
-
-/mob/living/human/verb/toggle_hotkey_verbs()
- set category = "OOC"
- set name = "Toggle hotkey buttons"
- set desc = "This disables or enables the user interface buttons which can be used with hotkeys."
-
- if(!istype(hud_used))
- return
-
- if(hud_used.hotkey_ui_hidden)
- client.screen += hud_used.hotkeybuttons
- hud_used.hotkey_ui_hidden = 0
- else
- client.screen -= hud_used.hotkeybuttons
- hud_used.hotkey_ui_hidden = 1
diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm
deleted file mode 100644
index 26437535d2bf..000000000000
--- a/code/_onclick/hud/other_mobs.dm
+++ /dev/null
@@ -1,63 +0,0 @@
-/datum/hud/construct/get_ui_style_data()
- return GET_DECL(/decl/ui_style/construct)
-
-/datum/hud/construct/juggernaut/get_ui_style_data()
- return GET_DECL(/decl/ui_style/construct/juggernaut)
-
-/datum/hud/construct/harvester/get_ui_style_data()
- return GET_DECL(/decl/ui_style/construct/harvester)
-
-/datum/hud/construct/wraith/get_ui_style_data()
- return GET_DECL(/decl/ui_style/construct/wraith)
-
-/datum/hud/construct/artificer/get_ui_style_data()
- return GET_DECL(/decl/ui_style/construct/artificer)
-
-/datum/hud/construct/get_ui_color()
- return COLOR_WHITE
-
-/datum/hud/construct/get_ui_alpha()
- return 255
-
-/datum/hud/construct/FinalizeInstantiation()
- var/decl/ui_style/ui_style = get_ui_style_data()
- var/ui_color = get_ui_color()
- var/ui_alpha = get_ui_alpha()
- mymob.fire = new /obj/screen/construct_fire(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS_FIRE)
- mymob.healths = new /obj/screen/construct_health(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HEALTH)
- mymob.zone_sel = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_ZONE_SELECT)
- adding += list(mymob.fire, mymob.healths, mymob.zone_sel)
- ..()
-
-/decl/ui_style/construct
- name = "Construct"
- restricted = TRUE
- override_icons = list(
- UI_ICON_STATUS_FIRE = 'icons/mob/screen/styles/constructs/status_fire.dmi',
- UI_ICON_ZONE_SELECT = 'icons/mob/screen/styles/constructs/zone_selector.dmi'
- )
- uid = "ui_style_construct"
-/decl/ui_style/construct/juggernaut
- name = "Juggernaut"
- uid = "ui_style_construct_juggernaut"
-/decl/ui_style/construct/juggernaut/Initialize()
- override_icons[UI_ICON_HEALTH] = 'icons/mob/screen/styles/constructs/juggernaut/health.dmi'
- return ..()
-/decl/ui_style/construct/harvester
- name = "Harvester"
- uid = "ui_style_construct_harvester"
-/decl/ui_style/construct/harvester/Initialize()
- override_icons[UI_ICON_HEALTH] = 'icons/mob/screen/styles/constructs/harvester/health.dmi'
- return ..()
-/decl/ui_style/construct/wraith
- name = "Wraith"
- uid = "ui_style_construct_wraith"
-/decl/ui_style/construct/wraith/Initialize()
- override_icons[UI_ICON_HEALTH] = 'icons/mob/screen/styles/constructs/wraith/health.dmi'
- return ..()
-/decl/ui_style/construct/artificer
- name = "Artificer"
- uid = "ui_style_construct_artificer"
-/decl/ui_style/construct/artificer/Initialize()
- override_icons[UI_ICON_HEALTH] = 'icons/mob/screen/styles/constructs/artificer/health.dmi'
- return ..()
diff --git a/code/_onclick/hud/pai.dm b/code/_onclick/hud/pai.dm
deleted file mode 100644
index 5111dade42ce..000000000000
--- a/code/_onclick/hud/pai.dm
+++ /dev/null
@@ -1,9 +0,0 @@
-/datum/hud/pai/FinalizeInstantiation()
- for(var/pai_hud_type in subtypesof(/obj/screen/pai))
- var/obj/screen/pai/hud_elem = pai_hud_type
- if(TYPE_IS_ABSTRACT(hud_elem))
- continue
- adding += new hud_elem(null, mymob)
-
- ..()
- hide_inventory()
diff --git a/code/_onclick/hud/screen/_screen.dm b/code/_onclick/hud/screen/_screen.dm
index 4e891170d7bd..b3608bbf1cd9 100644
--- a/code/_onclick/hud/screen/_screen.dm
+++ b/code/_onclick/hud/screen/_screen.dm
@@ -26,12 +26,18 @@
var/requires_ui_style = TRUE
/// Whether or not we look for/draw an additional detail overlay.
var/apply_screen_overlay = TRUE
- /// Reference to our last set ui_style
+
+ // Do we take supplied color in Initialize()?
+ var/use_supplied_ui_color = FALSE
+ // Do we take supplied alpha in Initialize()?
+ var/use_supplied_ui_alpha = FALSE
+ // Do we take supplied icon in Initialize()?
+ var/use_supplied_ui_icon = TRUE
/obj/screen/Initialize(mapload, mob/_owner, decl/ui_style/ui_style, ui_color, ui_alpha, ui_cat)
if(requires_ui_style)
- if(!istext(ui_cat) && !istext(ui_style_category))
+ if(!ispath(ui_cat, /decl/hud_element) && !ispath(ui_style_category, /decl/hud_element))
PRINT_STACK_TRACE("Screen object [type] initializing with invalid UI style category: [ui_cat || "NULL"], [ui_style_category || "NULL"].")
return INITIALIZE_HINT_QDEL
if(!istype(ui_style))
@@ -51,9 +57,9 @@
return INITIALIZE_HINT_QDEL
set_ui_style(ui_style, ui_cat)
- if(!isnull(ui_color))
+ if(!isnull(ui_color) && use_supplied_ui_color)
color = ui_color
- if(!isnull(ui_alpha))
+ if(!isnull(ui_alpha) && use_supplied_ui_alpha)
alpha = ui_alpha
return ..()
@@ -72,9 +78,9 @@
return FALSE
/obj/screen/proc/set_ui_style(decl/ui_style/ui_style, ui_cat)
- if(istext(ui_cat))
+ if(!isnull(ui_cat))
ui_style_category = ui_cat
- if(istype(ui_style) && ui_style_category)
+ if(istype(ui_style) && ui_style_category && use_supplied_ui_icon)
icon = ui_style.get_icon(ui_style_category)
update_icon()
diff --git a/code/_onclick/hud/screen/robot/screen_robot.dm b/code/_onclick/hud/screen/robot/screen_robot.dm
new file mode 100644
index 000000000000..594388da5aa0
--- /dev/null
+++ b/code/_onclick/hud/screen/robot/screen_robot.dm
@@ -0,0 +1,7 @@
+/obj/screen/robot
+ abstract_type = /obj/screen/robot
+ icon = 'icons/mob/screen/styles/robot/panel.dmi'
+ requires_ui_style = FALSE
+ use_supplied_ui_alpha = FALSE
+ use_supplied_ui_color = FALSE
+ use_supplied_ui_icon = FALSE
diff --git a/code/_onclick/hud/screen/robot/screen_robot_drop_grab.dm b/code/_onclick/hud/screen/robot/screen_robot_drop_grab.dm
new file mode 100644
index 000000000000..c3e71cef3d06
--- /dev/null
+++ b/code/_onclick/hud/screen/robot/screen_robot_drop_grab.dm
@@ -0,0 +1,23 @@
+/obj/screen/robot/drop_grab
+ name = "drop grab"
+ icon = 'icons/mob/screen/styles/robot/drop_grab.dmi'
+ icon_state = "drop_grab"
+ screen_loc = ui_borg_drop_grab
+ invisibility = INVISIBILITY_MAXIMUM
+ alpha = 0
+
+/obj/screen/robot/drop_grab/handle_click(mob/user, params)
+ if(isrobot(user))
+ var/mob/living/silicon/robot/R = user
+ R.drop_item()
+ update_icon()
+
+/obj/screen/robot/drop_grab/on_update_icon()
+ . = ..()
+ var/mob/living/owner = owner_ref?.resolve()
+ if(istype(owner) && length(owner.get_active_grabs()))
+ set_invisibility(INVISIBILITY_NONE)
+ alpha = 255
+ else
+ set_invisibility(INVISIBILITY_ABSTRACT)
+ alpha = 0
diff --git a/code/_onclick/hud/screen/screen_robot_inventory.dm b/code/_onclick/hud/screen/robot/screen_robot_inventory.dm
similarity index 61%
rename from code/_onclick/hud/screen/screen_robot_inventory.dm
rename to code/_onclick/hud/screen/robot/screen_robot_inventory.dm
index ebe63dcf3df5..a6360e2eaaab 100644
--- a/code/_onclick/hud/screen/screen_robot_inventory.dm
+++ b/code/_onclick/hud/screen/robot/screen_robot_inventory.dm
@@ -1,11 +1,9 @@
-/obj/screen/robot_inventory
+/obj/screen/robot/inventory
name = "inventory"
- icon = 'icons/mob/screen/styles/robot/panel.dmi'
icon_state = "inventory"
screen_loc = ui_borg_inventory
- requires_ui_style = FALSE
-/obj/screen/robot_inventory/handle_click(mob/user, params)
+/obj/screen/robot/inventory/handle_click(mob/user, params)
if(isrobot(user))
var/mob/living/silicon/robot/R = user
if(R.module)
diff --git a/code/_onclick/hud/screen/robot/screen_robot_module.dm b/code/_onclick/hud/screen/robot/screen_robot_module.dm
new file mode 100644
index 000000000000..95e662167ec2
--- /dev/null
+++ b/code/_onclick/hud/screen/robot/screen_robot_module.dm
@@ -0,0 +1,17 @@
+/obj/screen/robot/module/select
+ name = "module"
+ icon = 'icons/mob/screen/styles/robot/module.dmi'
+ icon_state = "nomod"
+ screen_loc = ui_borg_module
+
+/obj/screen/robot/module/select/on_update_icon()
+ . = ..()
+ icon_state = initial(icon_state)
+ var/mob/living/silicon/robot/owner = owner_ref?.resolve()
+ if(istype(owner) && owner.modtype)
+ icon_state = lowertext(owner.modtype)
+
+/obj/screen/robot/module/select/handle_click(mob/user, params)
+ if(isrobot(user))
+ var/mob/living/silicon/robot/R = user
+ R.pick_module()
diff --git a/code/_onclick/hud/screen/screen_robot_modules.dm b/code/_onclick/hud/screen/robot/screen_robot_modules.dm
similarity index 72%
rename from code/_onclick/hud/screen/screen_robot_modules.dm
rename to code/_onclick/hud/screen/robot/screen_robot_modules.dm
index 12d82511fe10..8574676abda1 100644
--- a/code/_onclick/hud/screen/screen_robot_modules.dm
+++ b/code/_onclick/hud/screen/robot/screen_robot_modules.dm
@@ -1,35 +1,33 @@
-/obj/screen/robot_modules_background
+/obj/screen/robot/modules_background
name = "module"
icon_state = "block"
icon = 'icons/mob/screen/styles/robot/modules_background.dmi'
- requires_ui_style = FALSE
-/obj/screen/robot_module
+/obj/screen/robot/module
dir = SOUTHWEST
- requires_ui_style = FALSE
icon = 'icons/mob/screen/styles/robot/inventory.dmi'
var/module_index
-/obj/screen/robot_module/handle_click(mob/user, params)
+/obj/screen/robot/module/handle_click(mob/user, params)
if(isrobot(user) && !isnull(module_index))
var/mob/living/silicon/robot/robot = user
robot.toggle_module(module_index)
return TRUE
return ..()
-/obj/screen/robot_module/one
+/obj/screen/robot/module/one
name = "module1"
icon_state = "inv1"
screen_loc = ui_inv1
module_index = 1
-/obj/screen/robot_module/two
+/obj/screen/robot/module/two
name = "module2"
icon_state = "inv2"
screen_loc = ui_inv2
module_index = 2
-/obj/screen/robot_module/three
+/obj/screen/robot/module/three
name = "module3"
icon_state = "inv3"
screen_loc = ui_inv3
diff --git a/code/_onclick/hud/screen/robot/screen_robot_panel.dm b/code/_onclick/hud/screen/robot/screen_robot_panel.dm
new file mode 100644
index 000000000000..9f39909a52f9
--- /dev/null
+++ b/code/_onclick/hud/screen/robot/screen_robot_panel.dm
@@ -0,0 +1,9 @@
+/obj/screen/robot/panel
+ name = "panel"
+ icon_state = "panel"
+ screen_loc = ui_borg_panel
+
+/obj/screen/robot/panel/handle_click(mob/user, params)
+ if(isrobot(user))
+ var/mob/living/silicon/robot/R = user
+ R.installed_modules()
diff --git a/code/_onclick/hud/screen/screen_robot_radio.dm b/code/_onclick/hud/screen/robot/screen_robot_radio.dm
similarity index 50%
rename from code/_onclick/hud/screen/screen_robot_radio.dm
rename to code/_onclick/hud/screen/robot/screen_robot_radio.dm
index e1046ddfc75b..5207edef2b47 100644
--- a/code/_onclick/hud/screen/screen_robot_radio.dm
+++ b/code/_onclick/hud/screen/robot/screen_robot_radio.dm
@@ -1,12 +1,10 @@
-/obj/screen/robot_radio
+/obj/screen/robot/radio
name = "radio"
dir = SOUTHWEST
- icon = 'icons/mob/screen/styles/robot/panel.dmi'
icon_state = "radio"
screen_loc = ui_movi
- requires_ui_style = FALSE
-/obj/screen/robot_radio/handle_click(mob/user, params)
+/obj/screen/robot/radio/handle_click(mob/user, params)
if(isrobot(user))
var/mob/living/silicon/robot/R = user
R.radio_menu()
\ No newline at end of file
diff --git a/code/_onclick/hud/screen/screen_robot_store.dm b/code/_onclick/hud/screen/robot/screen_robot_store.dm
similarity index 62%
rename from code/_onclick/hud/screen/screen_robot_store.dm
rename to code/_onclick/hud/screen/robot/screen_robot_store.dm
index 8ea81ab05638..93f1a652b96e 100644
--- a/code/_onclick/hud/screen/screen_robot_store.dm
+++ b/code/_onclick/hud/screen/robot/screen_robot_store.dm
@@ -1,11 +1,9 @@
-/obj/screen/robot_store
+/obj/screen/robot/store
name = "store"
- icon = 'icons/mob/screen/styles/robot/panel.dmi'
icon_state = "store"
screen_loc = ui_borg_store
- requires_ui_style = FALSE
-/obj/screen/robot_store/handle_click(mob/user, params)
+/obj/screen/robot/store/handle_click(mob/user, params)
if(isrobot(user))
var/mob/living/silicon/robot/R = user
if(R.module)
diff --git a/code/_onclick/hud/screen/robot/screen_robot_warnings.dm b/code/_onclick/hud/screen/robot/screen_robot_warnings.dm
new file mode 100644
index 000000000000..c6365ba40d83
--- /dev/null
+++ b/code/_onclick/hud/screen/robot/screen_robot_warnings.dm
@@ -0,0 +1,4 @@
+/obj/screen/health/robot
+ name = "health"
+ icon_state = "health0"
+ screen_loc = ui_borg_health
diff --git a/code/_onclick/hud/screen/screen_action_button.dm b/code/_onclick/hud/screen/screen_action_button.dm
index df79fa29ce41..f0d4d6cbf79a 100644
--- a/code/_onclick/hud/screen/screen_action_button.dm
+++ b/code/_onclick/hud/screen/screen_action_button.dm
@@ -3,6 +3,14 @@
requires_ui_style = FALSE
var/datum/action/action
+/obj/screen/action_button/Destroy()
+ if(!QDELETED(action))
+ if(action.button == src)
+ action.button = null
+ QDEL_NULL(action)
+ action = null
+ return ..()
+
/obj/screen/action_button/Initialize(mapload, mob/_owner, ui_style, ui_color, ui_alpha, ui_cat, _action)
action = _action
return ..()
@@ -64,8 +72,7 @@
/obj/screen/action_button/hide_toggle/handle_click(mob/user, params)
if(!istype(user.hud_used))
return
- user.hud_used.action_buttons_hidden = !user.hud_used.action_buttons_hidden
- hidden = user.hud_used.action_buttons_hidden
+ hidden = user.hud_used.toggle_action_buttons_hidden()
if(hidden)
name = "Show Buttons"
else
diff --git a/code/_onclick/hud/screen/screen_ai_button.dm b/code/_onclick/hud/screen/screen_ai_button.dm
index e2060d6b8a1e..f1aaea0360f1 100644
--- a/code/_onclick/hud/screen/screen_ai_button.dm
+++ b/code/_onclick/hud/screen/screen_ai_button.dm
@@ -1,6 +1,10 @@
/obj/screen/ai_button
- icon = 'icons/mob/screen/ai.dmi'
- requires_ui_style = FALSE
+ icon = 'icons/mob/screen/ai.dmi'
+ requires_ui_style = FALSE
+ use_supplied_ui_alpha = FALSE
+ use_supplied_ui_color = FALSE
+ use_supplied_ui_icon = FALSE
+
var/ai_verb
var/list/input_procs
var/list/input_args
@@ -40,15 +44,17 @@
call(A, ai_verb)(arglist(input_arguments))
return TRUE
-/obj/screen/ai_button/Initialize(mapload, mob/_owner, ui_style, ui_color, ui_alpha, ui_cat, decl/ai_hud/ai_hud_data)
+/obj/screen/ai_button/Initialize(mapload, mob/_owner, ui_style, ui_color, ui_alpha, ui_cat)
. = ..()
- name = ai_hud_data.name
- icon_state = ai_hud_data.icon_state
- screen_loc = ai_hud_data.screen_loc
- ai_verb = ai_hud_data.proc_path
- input_procs = ai_hud_data.input_procs?.Copy()
- input_args = ai_hud_data.input_args?.Copy()
+ var/decl/hud_element/ai/ai_hud_data = GET_DECL(ui_cat)
+ if(istype(ai_hud_data))
+ name = ai_hud_data.name
+ icon_state = ai_hud_data.icon_state
+ screen_loc = ai_hud_data.screen_loc
+ ai_verb = ai_hud_data.proc_path
+ input_procs = ai_hud_data.input_procs?.Copy()
+ input_args = ai_hud_data.input_args?.Copy()
if(!LAZYLEN(template_icon))
template_icon = list(icon)
diff --git a/code/_onclick/hud/screen/screen_attack_selector.dm b/code/_onclick/hud/screen/screen_attack_selector.dm
index 537d2ccce389..ee9f4c019cfc 100644
--- a/code/_onclick/hud/screen/screen_attack_selector.dm
+++ b/code/_onclick/hud/screen/screen_attack_selector.dm
@@ -1,13 +1,9 @@
/obj/screen/default_attack_selector
- name = "default attack selector"
- icon_state = "attack_none"
- screen_loc = ui_attack_selector
-
-/obj/screen/default_attack_selector/Destroy()
- var/mob/living/human/owner = owner_ref?.resolve()
- if(istype(owner) && owner.attack_selector == src)
- owner.attack_selector = null
- . = ..()
+ name = "default attack selector"
+ icon_state = "attack_none"
+ screen_loc = ui_attack_selector
+ use_supplied_ui_color = TRUE
+ use_supplied_ui_alpha = TRUE
/obj/screen/default_attack_selector/handle_click(mob/user, params)
@@ -31,4 +27,4 @@
..()
var/mob/living/human/owner = owner_ref?.resolve()
var/decl/natural_attack/attack = istype(owner) && owner.default_attack
- icon_state = attack?.selector_icon_state || "attack_none"
+ icon_state = (istype(attack) && attack.selector_icon_state) ? attack.selector_icon_state : "attack_none"
diff --git a/code/_onclick/hud/screen/screen_constructs.dm b/code/_onclick/hud/screen/screen_constructs.dm
index 96932a2d22c0..a0082f804fd6 100644
--- a/code/_onclick/hud/screen/screen_constructs.dm
+++ b/code/_onclick/hud/screen/screen_constructs.dm
@@ -4,6 +4,6 @@
icon_state = "fire0"
screen_loc = ui_construct_fire
-/obj/screen/construct_health
+/obj/screen/health/construct
name = "health"
screen_loc = ui_construct_health
diff --git a/code/_onclick/hud/screen/screen_gun.dm b/code/_onclick/hud/screen/screen_gun.dm
index 86bba4206e74..e0bc13fee624 100644
--- a/code/_onclick/hud/screen/screen_gun.dm
+++ b/code/_onclick/hud/screen/screen_gun.dm
@@ -39,7 +39,7 @@
name = "Disallow Radio Use"
icon_state = "no_radio1"
base_icon_state = "no_radio"
- screen_loc = ui_gun4
+ screen_loc = ui_gun3
toggle_flag = TARGET_CAN_RADIO
/obj/screen/gun/mode
diff --git a/code/_onclick/hud/screen/screen_health.dm b/code/_onclick/hud/screen/screen_health.dm
new file mode 100644
index 000000000000..2322dd2ee220
--- /dev/null
+++ b/code/_onclick/hud/screen/screen_health.dm
@@ -0,0 +1,66 @@
+/obj/screen/health
+ name = "health"
+ icon_state = "health0"
+ screen_loc = ui_health
+
+/obj/screen/health/handle_click(mob/user, params)
+ if(ishuman(user))
+ var/mob/living/human/human_user = user
+ human_user.check_self_injuries()
+ return TRUE
+
+/obj/screen/health/on_update_icon()
+ . = ..()
+ var/mob/living/owner = owner_ref?.resolve()
+ if(!istype(owner) || owner.stat == DEAD)
+ icon_state = "health7"
+ else
+ icon_state = "health[round(((100-owner.get_health_percent())/100) * 6, 1)]"
+
+/obj/screen/health/organs/on_update_icon()
+
+ var/mob/living/human/owner = owner_ref?.resolve()
+ if(!istype(owner))
+ return
+
+ cut_overlays()
+
+ // We don't check can_feel_pain() here, otherwise FBP don't get variable health indicators.
+ if(owner.has_chemical_effect(CE_PAINKILLER, 100))
+ icon_state = "health_numb"
+ compile_overlays()
+ return
+
+ icon_state = "blank"
+
+ // Generate a by-limb health display.
+ var/no_damage = 1
+ var/trauma_val = 0 // Used in calculating softcrit/hardcrit indicators.
+
+ var/decl/species/my_species = owner.get_species()
+ trauma_val = max(owner.shock_stage, owner.get_shock())/ (my_species.total_health-100)
+
+ for(var/obj/item/organ/external/E in owner.get_external_organs())
+ if(no_damage && (E.brute_dam || E.burn_dam))
+ no_damage = 0
+ var/damage_image = E.get_damage_hud_image()
+ if(damage_image)
+ add_overlay(damage_image)
+
+ // Apply a fire overlay if we're burning.
+ var/crit_markers = get_ui_icon(owner.client?.prefs?.UI_style, HUD_CRIT_MARKER)
+ if(crit_markers)
+ if(owner.is_on_fire())
+ add_overlay(image(crit_markers, "burning"))
+ // Show a general pain/crit indicator if needed.
+ if(owner.is_asystole())
+ add_overlay(image(crit_markers, "hardcrit"))
+ else if(trauma_val)
+ if(trauma_val > 0.7)
+ add_overlay(image(crit_markers, "softcrit"))
+ if(trauma_val >= 1)
+ add_overlay(image(crit_markers, "hardcrit"))
+ else if(no_damage)
+ add_overlay(image(crit_markers, "fullhealth"))
+
+ compile_overlays()
diff --git a/code/_onclick/hud/screen/screen_intent.dm b/code/_onclick/hud/screen/screen_intent.dm
index ca75b836812a..f05060384fb4 100644
--- a/code/_onclick/hud/screen/screen_intent.dm
+++ b/code/_onclick/hud/screen/screen_intent.dm
@@ -48,6 +48,19 @@
icon = intent.icon
icon_state = selected ? intent.icon_state : "[intent.icon_state]_off"
+/obj/screen/intent_button/MouseEntered(location, control, params)
+ if(intent && (intent.name || intent.desc))
+ openToolTip(user = usr, tip_src = src, params = params, content = intent.desc)
+ return ..()
+
+/obj/screen/intent_button/MouseDown()
+ closeToolTip(usr)
+ return ..()
+
+/obj/screen/intent_button/MouseExited()
+ closeToolTip(usr)
+ return ..()
+
/obj/screen/intent
name = "intent"
icon = 'icons/screen/intents.dmi'
@@ -67,7 +80,7 @@
verbs.Cut()
/obj/screen/intent/Destroy()
- QDEL_NULL(intent_selectors)
+ QDEL_NULL_LIST(intent_selectors)
vis_contents.Cut()
return ..()
@@ -98,20 +111,21 @@
var/decl/intent/owner_intent = owner.get_intent()
var/i = 1
- var/list/all_intents = owner.get_available_intents()
+ var/list/unused_selectors = intent_selectors?.Copy()
+ var/list/all_intents = owner.get_available_intents(skip_update = TRUE)
for(var/decl/intent/intent as anything in all_intents)
var/obj/screen/intent_button/intent_button = get_intent_button(i)
if(intent == owner_intent)
intent_button.set_selected(intent)
else
intent_button.set_deselected(intent)
+ LAZYREMOVE(unused_selectors, intent_button)
i++
apply_intent_button_offset(intent_button, i, length(all_intents))
add_vis_contents(intent_button)
- if(i < length(intent_selectors))
- for(var/index = i+1 to length(intent_selectors))
- remove_vis_contents(intent_selectors[index])
+ if(length(unused_selectors))
+ remove_vis_contents(unused_selectors)
/obj/screen/intent/binary
intent_width = 32
diff --git a/code/_onclick/hud/screen/screen_internal.dm b/code/_onclick/hud/screen/screen_internal.dm
index 856132a3faac..20b9d82120f9 100644
--- a/code/_onclick/hud/screen/screen_internal.dm
+++ b/code/_onclick/hud/screen/screen_internal.dm
@@ -3,6 +3,14 @@
icon_state = "internal0"
screen_loc = ui_internal
+/obj/screen/internals/on_update_icon()
+ . = ..()
+ var/mob/living/owner = owner_ref?.resolve()
+ if(istype(owner) && owner.get_internals())
+ icon_state = "internal1"
+ else
+ icon_state = "internal0"
+
/obj/screen/internals/handle_click(mob/user, params)
if(isliving(user))
var/mob/living/M = user
diff --git a/code/_onclick/hud/screen/screen_inventory.dm b/code/_onclick/hud/screen/screen_inventory.dm
index cc4a4835b826..3714bc5fb107 100644
--- a/code/_onclick/hud/screen/screen_inventory.dm
+++ b/code/_onclick/hud/screen/screen_inventory.dm
@@ -1,4 +1,6 @@
/obj/screen/inventory
+ use_supplied_ui_color = TRUE
+ use_supplied_ui_alpha = TRUE
var/slot_id //The indentifier for the slot. It has nothing to do with ID cards.
var/weakref/mouse_over_atom_ref
diff --git a/code/_onclick/hud/screen/screen_module.dm b/code/_onclick/hud/screen/screen_module.dm
deleted file mode 100644
index 8b3c162f43e2..000000000000
--- a/code/_onclick/hud/screen/screen_module.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/obj/screen/robot_module/select
- name = "module"
- icon = 'icons/mob/screen/styles/robot/module.dmi'
- icon_state = "nomod"
- screen_loc = ui_borg_module
- requires_ui_style = FALSE
-
-/obj/screen/robot_module/select/handle_click(mob/user, params)
- if(isrobot(user))
- var/mob/living/silicon/robot/R = user
- R.pick_module()
diff --git a/code/_onclick/hud/screen/screen_movement.dm b/code/_onclick/hud/screen/screen_movement.dm
index 674882295dda..0fd4f4fb52d9 100644
--- a/code/_onclick/hud/screen/screen_movement.dm
+++ b/code/_onclick/hud/screen/screen_movement.dm
@@ -1,7 +1,9 @@
/obj/screen/movement
- name = "movement method"
- screen_loc = ui_movi
- icon_state = "creeping"
+ name = "movement method"
+ screen_loc = ui_movi
+ icon_state = "creeping"
+ use_supplied_ui_color = TRUE
+ use_supplied_ui_alpha = TRUE
/obj/screen/movement/handle_click(mob/user, params)
if(istype(user))
diff --git a/code/_onclick/hud/screen/screen_needs.dm b/code/_onclick/hud/screen/screen_needs.dm
index 8a4c66ca08b9..61c43f42c5ba 100644
--- a/code/_onclick/hud/screen/screen_needs.dm
+++ b/code/_onclick/hud/screen/screen_needs.dm
@@ -1,117 +1,104 @@
// Yes, these use icon state. Yes, these are terrible. The alternative is duplicating
// a bunch of fairly blobby logic for every click override on these objects.
-/obj/screen/food
+/obj/screen/need
+ use_supplied_ui_color = TRUE
+ use_supplied_ui_alpha = TRUE
+ screen_loc = ui_nutrition_small
+
+/obj/screen/need/nutrition
name = "nutrition"
icon = 'icons/mob/screen/styles/nutrition.dmi'
pixel_w = 8
icon_state = "nutrition1"
- screen_loc = ui_nutrition_small
-/obj/screen/food/handle_click(mob/user, params)
- if(user.nutrition_icon == src)
- switch(icon_state)
- if("nutrition0")
- to_chat(user, SPAN_WARNING("You are completely stuffed."))
- if("nutrition1")
- to_chat(user, SPAN_NOTICE("You are not hungry."))
- if("nutrition2")
- to_chat(user, SPAN_NOTICE("You are a bit peckish."))
- if("nutrition3")
- to_chat(user, SPAN_WARNING("You are quite hungry."))
- if("nutrition4")
- to_chat(user, SPAN_DANGER("You are starving!"))
+/obj/screen/need/nutrition/handle_click(mob/user, params)
+ switch(icon_state)
+ if("nutrition0")
+ to_chat(user, SPAN_WARNING("You are completely stuffed."))
+ if("nutrition1")
+ to_chat(user, SPAN_NOTICE("You are not hungry."))
+ if("nutrition2")
+ to_chat(user, SPAN_NOTICE("You are a bit peckish."))
+ if("nutrition3")
+ to_chat(user, SPAN_WARNING("You are quite hungry."))
+ if("nutrition4")
+ to_chat(user, SPAN_DANGER("You are starving!"))
-/obj/screen/drink
+/obj/screen/need/nutrition/on_update_icon()
+ . = ..()
+ var/mob/living/owner = owner_ref?.resolve()
+ if(!istype(owner) || owner.isSynthetic())
+ invisibility = INVISIBILITY_ABSTRACT
+ return
+ invisibility = INVISIBILITY_NONE
+ switch(owner.get_nutrition())
+ if(450 to INFINITY)
+ icon_state = "nutrition0"
+ if(350 to 450)
+ icon_state = "nutrition1"
+ if(250 to 350)
+ icon_state = "nutrition2"
+ if(150 to 250)
+ icon_state = "nutrition3"
+ else
+ icon_state = "nutrition4"
+
+/obj/screen/need/hydration
name = "hydration"
icon = 'icons/mob/screen/styles/hydration.dmi'
icon_state = "hydration1"
- screen_loc = ui_nutrition_small
-
-/obj/screen/drink/handle_click(mob/user, params)
- if(user.hydration_icon == src)
- switch(icon_state)
- if("hydration0")
- to_chat(user, SPAN_WARNING("You are overhydrated."))
- if("hydration1")
- to_chat(user, SPAN_NOTICE("You are not thirsty."))
- if("hydration2")
- to_chat(user, SPAN_NOTICE("You are a bit thirsty."))
- if("hydration3")
- to_chat(user, SPAN_WARNING("You are quite thirsty."))
- if("hydration4")
- to_chat(user, SPAN_DANGER("You are dying of thirst!"))
-/obj/screen/bodytemp
- name = "body temperature"
- icon = 'icons/mob/screen/styles/status.dmi'
- icon_state = "temp1"
- screen_loc = ui_temp
+/obj/screen/need/hydration/handle_click(mob/user, params)
+ switch(icon_state)
+ if("hydration0")
+ to_chat(user, SPAN_WARNING("You are overhydrated."))
+ if("hydration1")
+ to_chat(user, SPAN_NOTICE("You are not thirsty."))
+ if("hydration2")
+ to_chat(user, SPAN_NOTICE("You are a bit thirsty."))
+ if("hydration3")
+ to_chat(user, SPAN_WARNING("You are quite thirsty."))
+ if("hydration4")
+ to_chat(user, SPAN_DANGER("You are dying of thirst!"))
-/obj/screen/bodytemp/handle_click(mob/user, params)
- if(user.bodytemp == src)
- switch(icon_state)
- if("temp4")
- to_chat(user, SPAN_DANGER("You are being cooked alive!"))
- if("temp3")
- to_chat(user, SPAN_DANGER("Your body is burning up!"))
- if("temp2")
- to_chat(user, SPAN_DANGER("You are overheating."))
- if("temp1")
- to_chat(user, SPAN_WARNING("You are uncomfortably hot."))
- if("temp-4")
- to_chat(user, SPAN_DANGER("You are being frozen solid!"))
- if("temp-3")
- to_chat(user, SPAN_DANGER("You are freezing cold!"))
- if("temp-2")
- to_chat(user, SPAN_WARNING("You are dangerously chilled!"))
- if("temp-1")
- to_chat(user, SPAN_NOTICE("You are uncomfortably cold."))
- else
- to_chat(user, SPAN_NOTICE("Your body is at a comfortable temperature."))
-
-/obj/screen/pressure
- name = "pressure"
- icon = 'icons/mob/screen/styles/status.dmi'
- icon_state = "pressure0"
- screen_loc = ui_temp
-
-/obj/screen/pressure/handle_click(mob/user, params)
- if(user.pressure == src)
- switch(icon_state)
- if("pressure2")
- to_chat(user, SPAN_DANGER("The air pressure here is crushing!"))
- if("pressure1")
- to_chat(user, SPAN_WARNING("The air pressure here is dangerously high."))
- if("pressure-1")
- to_chat(user, SPAN_WARNING("The air pressure here is dangerously low."))
- if("pressure-2")
- to_chat(user, SPAN_DANGER("There is nearly no air pressure here!"))
- else
- to_chat(user, SPAN_NOTICE("The local air pressure is comfortable."))
-
-/obj/screen/toxins
- name = "toxin"
- icon = 'icons/mob/screen/styles/status.dmi'
- icon_state = "tox0"
- screen_loc = ui_temp
-
-/obj/screen/toxins/handle_click(mob/user, params)
- if(user.toxin == src)
- if(icon_state == "tox0")
- to_chat(user, SPAN_NOTICE("The air is clear of toxins."))
+/obj/screen/need/hydration/on_update_icon()
+ . = ..()
+ var/mob/living/owner = owner_ref?.resolve()
+ if(!istype(owner) || owner.isSynthetic())
+ invisibility = INVISIBILITY_ABSTRACT
+ return
+ invisibility = INVISIBILITY_NONE
+ switch(owner.get_hydration())
+ if(450 to INFINITY)
+ icon_state = "hydration0"
+ if(350 to 450)
+ icon_state = "hydration1"
+ if(250 to 350)
+ icon_state = "hydration2"
+ if(150 to 250)
+ icon_state = "hydration3"
else
- to_chat(user, SPAN_DANGER("The air is eating away at your skin!"))
+ icon_state = "hydration4"
-/obj/screen/oxygen
- name = "oxygen"
- icon = 'icons/mob/screen/styles/status.dmi'
- icon_state = "oxy0"
- screen_loc = ui_temp
+/obj/screen/need/cell_charge
+ name = "cell"
+ icon_state = "charge-empty"
+ screen_loc = ui_nutrition
-/obj/screen/oxygen/handle_click(mob/user, params)
- if(user.oxygen == src)
- if(icon_state == "oxy0")
- to_chat(user, SPAN_NOTICE("You are breathing easy."))
- else
- to_chat(user, SPAN_DANGER("You cannot breathe!"))
+/obj/screen/need/cell_charge/robot
+ screen_loc = ui_toxin
+
+/obj/screen/need/cell_charge/on_update_icon()
+ . = ..()
+ var/mob/living/owner = owner_ref?.resolve()
+ if(!istype(owner) || !owner.isSynthetic())
+ invisibility = INVISIBILITY_ABSTRACT
+ return
+ invisibility = INVISIBILITY_NONE
+ var/obj/item/cell/cell = owner.get_cell()
+ if(cell)
+ var/chargeNum = clamp(ceil(cell.percent()/25), 0, 4) //0-100 maps to 0-4, but give it a paranoid clamp just in case.
+ icon_state = "charge[chargeNum]"
+ else
+ icon_state = "charge-empty"
diff --git a/code/_onclick/hud/screen/screen_pai.dm b/code/_onclick/hud/screen/screen_pai.dm
index 51ceb9d7c27e..08de1ff85060 100644
--- a/code/_onclick/hud/screen/screen_pai.dm
+++ b/code/_onclick/hud/screen/screen_pai.dm
@@ -3,15 +3,9 @@
abstract_type = /obj/screen/pai
requires_ui_style = FALSE
user_incapacitation_flags = INCAPACITATION_KNOCKOUT
-
-/obj/screen/pai/shell
- name = "Toggle Chassis"
-
-/obj/screen/pai/rest
- name = "Rest"
-
-/obj/screen/pai/light
- name = "Toggle Light"
+ use_supplied_ui_alpha = FALSE
+ use_supplied_ui_color = FALSE
+ use_supplied_ui_icon = FALSE
/obj/screen/pai/software
name = "Software Interface"
@@ -74,3 +68,24 @@
var/stat_silicon_subsystem/SSS = pai.silicon_subsystems_by_name[ss_name]
if(istype(SSS))
SSS.Click()
+
+/decl/hud_element/pai
+ abstract_type = /decl/hud_element/pai
+
+/decl/hud_element/pai/shell
+ elem_type = /obj/screen/pai/shell
+
+/decl/hud_element/pai/rest
+ elem_type = /obj/screen/pai/rest
+
+/decl/hud_element/pai/light
+ elem_type = /obj/screen/pai/light
+
+/decl/hud_element/pai/software
+ elem_type = /obj/screen/pai/software
+
+/decl/hud_element/pai/chassis
+ elem_type = /obj/screen/pai/chassis
+
+/decl/hud_element/pai/subsystems
+ elem_type = /obj/screen/pai/subsystems
diff --git a/code/_onclick/hud/screen/screen_robot_drop_grab.dm b/code/_onclick/hud/screen/screen_robot_drop_grab.dm
deleted file mode 100644
index 38232bf14d70..000000000000
--- a/code/_onclick/hud/screen/screen_robot_drop_grab.dm
+++ /dev/null
@@ -1,15 +0,0 @@
-/obj/screen/robot_drop_grab
- name = "drop grab"
- icon = 'icons/mob/screen/styles/robot/drop_grab.dmi'
- icon_state = "drop_grab"
- screen_loc = ui_borg_drop_grab
- invisibility = INVISIBILITY_MAXIMUM
- alpha = 0
- requires_ui_style = FALSE
-
-/obj/screen/robot_drop_grab/handle_click(mob/user, params)
- if(isrobot(user))
- var/mob/living/silicon/robot/R = user
- R.drop_item()
- set_invisibility(INVISIBILITY_MAXIMUM)
- alpha = 0
diff --git a/code/_onclick/hud/screen/screen_robot_panel.dm b/code/_onclick/hud/screen/screen_robot_panel.dm
deleted file mode 100644
index c712a6374423..000000000000
--- a/code/_onclick/hud/screen/screen_robot_panel.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-/obj/screen/robot_panel
- name = "panel"
- icon = 'icons/mob/screen/styles/robot/panel.dmi'
- icon_state = "panel"
- screen_loc = ui_borg_panel
- requires_ui_style = FALSE
-
-/obj/screen/robot_panel/handle_click(mob/user, params)
- if(isrobot(user))
- var/mob/living/silicon/robot/R = user
- R.installed_modules()
diff --git a/code/_onclick/hud/screen/screen_robot_warnings.dm b/code/_onclick/hud/screen/screen_robot_warnings.dm
deleted file mode 100644
index 6cff60008fd2..000000000000
--- a/code/_onclick/hud/screen/screen_robot_warnings.dm
+++ /dev/null
@@ -1,19 +0,0 @@
-/obj/screen/robot_charge
- name = "cell"
- icon_state = "charge-empty"
- screen_loc = ui_toxin
-
-/obj/screen/robot_health
- name = "health"
- icon_state = "health0"
- screen_loc = ui_borg_health
-
-/obj/screen/robot_oxygen
- name = "oxygen"
- icon_state = "oxy0"
- screen_loc = ui_oxygen
-
-/obj/screen/robot_fire
- name = "fire"
- icon_state = "fire0"
- screen_loc = ui_fire
diff --git a/code/_onclick/hud/screen/screen_stamina.dm b/code/_onclick/hud/screen/screen_stamina.dm
index 09051b8c74b4..b70d9e743618 100644
--- a/code/_onclick/hud/screen/screen_stamina.dm
+++ b/code/_onclick/hud/screen/screen_stamina.dm
@@ -1,7 +1,21 @@
/obj/screen/stamina
- name = "stamina"
- icon = 'icons/effects/progressbar.dmi'
- icon_state = "prog_bar_100"
- invisibility = INVISIBILITY_MAXIMUM
- screen_loc = ui_stamina
+ name = "stamina"
+ icon = 'icons/effects/progressbar.dmi'
+ icon_state = "prog_bar_100"
+ invisibility = INVISIBILITY_MAXIMUM
+ screen_loc = ui_stamina
requires_ui_style = FALSE
+ layer = HUD_BASE_LAYER + 0.1 // needs to layer over the movement intent element
+
+/obj/screen/stamina/on_update_icon()
+ . = ..()
+ var/mob/living/owner = owner_ref?.resolve()
+ if(!istype(owner))
+ set_invisibility(INVISIBILITY_MAXIMUM)
+ else
+ var/stamina = owner.get_stamina()
+ if(stamina < 100)
+ set_invisibility(INVISIBILITY_NONE)
+ icon_state = "prog_bar_[floor(stamina/5)*5][(stamina >= 5) && (stamina <= 25) ? "_fail" : null]"
+ else
+ set_invisibility(INVISIBILITY_MAXIMUM)
diff --git a/code/_onclick/hud/screen/screen_toggle.dm b/code/_onclick/hud/screen/screen_toggle.dm
index ddeb923911b8..4f534e230f33 100644
--- a/code/_onclick/hud/screen/screen_toggle.dm
+++ b/code/_onclick/hud/screen/screen_toggle.dm
@@ -6,10 +6,4 @@
/obj/screen/toggle/handle_click(mob/user, params)
if(!user.hud_used)
return
- if(user.hud_used.inventory_shown)
- user.client.screen -= user.hud_used.other
- user.hud_used.hide_inventory()
- else
- user.client.screen += user.hud_used.other
- user.hud_used.show_inventory()
- return TRUE
+ return user.hud_used.toggle_show_inventory()
diff --git a/code/_onclick/hud/screen/screen_up_hint.dm b/code/_onclick/hud/screen/screen_up_hint.dm
index 5a1a2b796fc1..4a97f61be1a5 100644
--- a/code/_onclick/hud/screen/screen_up_hint.dm
+++ b/code/_onclick/hud/screen/screen_up_hint.dm
@@ -1,14 +1,16 @@
-/obj/screen/up_hint
- name = "up hint"
- icon_state = "uphint0"
- screen_loc = ui_up_hint
+/obj/screen/look_upward
+ name = "up hint"
+ icon_state = "uphint0"
+ screen_loc = ui_up_hint
+ use_supplied_ui_color = TRUE
+ use_supplied_ui_alpha = TRUE
-/obj/screen/up_hint/handle_click(mob/user, params)
+/obj/screen/look_upward/handle_click(mob/user, params)
if(isliving(user))
var/mob/living/L = user
L.lookup()
-/obj/screen/up_hint/on_update_icon()
+/obj/screen/look_upward/on_update_icon()
var/mob/owner = owner_ref?.resolve()
var/turf/above = istype(owner) ? GetAbove(get_turf(owner)) : null
icon_state = "uphint[!!(istype(above) && TURF_IS_MIMICKING(above))]"
diff --git a/code/_onclick/hud/screen/screen_warning.dm b/code/_onclick/hud/screen/screen_warning.dm
new file mode 100644
index 000000000000..f7aad53c4872
--- /dev/null
+++ b/code/_onclick/hud/screen/screen_warning.dm
@@ -0,0 +1,12 @@
+/obj/screen/warning
+ use_supplied_ui_color = TRUE
+ use_supplied_ui_alpha = TRUE
+ var/base_state
+ var/check_alert
+
+/obj/screen/warning/on_update_icon()
+ . = ..()
+ if(base_state && check_alert)
+ var/mob/living/owner = owner_ref?.resolve()
+ if(istype(owner))
+ icon_state = "[base_state][GET_HUD_ALERT(owner, check_alert)]"
diff --git a/code/_onclick/hud/screen/screen_warning_bodytemp.dm b/code/_onclick/hud/screen/screen_warning_bodytemp.dm
new file mode 100644
index 000000000000..88bdafba7dfa
--- /dev/null
+++ b/code/_onclick/hud/screen/screen_warning_bodytemp.dm
@@ -0,0 +1,90 @@
+
+/obj/screen/warning/bodytemp
+ name = "body temperature"
+ icon = 'icons/mob/screen/styles/status_bodytemp.dmi'
+ icon_state = "temp1"
+ screen_loc = ui_temp
+
+/obj/screen/warning/bodytemp/on_update_icon()
+ . = ..()
+
+ var/mob/living/owner = owner_ref?.resolve()
+ if(!istype(owner))
+ return
+
+ var/decl/species/my_species = owner.get_species()
+ if(!my_species)
+ switch(owner.bodytemperature) //310.055 optimal body temp
+ if(370 to INFINITY)
+ icon_state = "temp4"
+ if(350 to 370)
+ icon_state = "temp3"
+ if(335 to 350)
+ icon_state = "temp2"
+ if(320 to 335)
+ icon_state = "temp1"
+ if(300 to 320)
+ icon_state = "temp0"
+ if(295 to 300)
+ icon_state = "temp-1"
+ if(280 to 295)
+ icon_state = "temp-2"
+ if(260 to 280)
+ icon_state = "temp-3"
+ else
+ icon_state = "temp-4"
+ return
+
+ var/heat_1 = owner.get_mob_temperature_threshold(HEAT_LEVEL_1)
+ var/cold_1 = owner.get_mob_temperature_threshold(COLD_LEVEL_1)
+
+ //TODO: precalculate all of this stuff when the species datum is created
+ var/base_temperature = my_species.body_temperature
+ if(base_temperature == null) //some species don't have a set metabolic temperature
+ base_temperature = (heat_1 + cold_1)/2
+
+ if (owner.bodytemperature >= base_temperature)
+ var/temp_step = (heat_1 - base_temperature)/4
+ if (owner.bodytemperature >= heat_1)
+ icon_state = "temp4"
+ else if (owner.bodytemperature >= base_temperature + temp_step*3)
+ icon_state = "temp3"
+ else if (owner.bodytemperature >= base_temperature + temp_step*2)
+ icon_state = "temp2"
+ else if (owner.bodytemperature >= base_temperature + temp_step*1)
+ icon_state = "temp1"
+ else
+ icon_state = "temp0"
+ else if (owner.bodytemperature < base_temperature)
+ var/temp_step = (base_temperature - cold_1)/4
+ if (owner.bodytemperature <= cold_1)
+ icon_state = "temp-4"
+ else if (owner.bodytemperature <= base_temperature - temp_step*3)
+ icon_state = "temp-3"
+ else if (owner.bodytemperature <= base_temperature - temp_step*2)
+ icon_state = "temp-2"
+ else if (owner.bodytemperature <= base_temperature - temp_step*1)
+ icon_state = "temp-1"
+ else
+ icon_state = "temp0"
+
+/obj/screen/warning/bodytemp/handle_click(mob/user, params)
+ switch(icon_state)
+ if("temp4")
+ to_chat(user, SPAN_DANGER("You are being cooked alive!"))
+ if("temp3")
+ to_chat(user, SPAN_DANGER("Your body is burning up!"))
+ if("temp2")
+ to_chat(user, SPAN_DANGER("You are overheating."))
+ if("temp1")
+ to_chat(user, SPAN_WARNING("You are uncomfortably hot."))
+ if("temp-4")
+ to_chat(user, SPAN_DANGER("You are being frozen solid!"))
+ if("temp-3")
+ to_chat(user, SPAN_DANGER("You are freezing cold!"))
+ if("temp-2")
+ to_chat(user, SPAN_WARNING("You are dangerously chilled!"))
+ if("temp-1")
+ to_chat(user, SPAN_NOTICE("You are uncomfortably cold."))
+ else
+ to_chat(user, SPAN_NOTICE("Your body is at a comfortable temperature."))
diff --git a/code/_onclick/hud/screen/screen_warning_fire.dm b/code/_onclick/hud/screen/screen_warning_fire.dm
new file mode 100644
index 000000000000..ec39eb5fa636
--- /dev/null
+++ b/code/_onclick/hud/screen/screen_warning_fire.dm
@@ -0,0 +1,6 @@
+/obj/screen/warning/fire
+ name = "fire"
+ icon_state = "fire0"
+ screen_loc = ui_fire
+ base_state = "fire"
+ check_alert = /decl/hud_element/fire
diff --git a/code/_onclick/hud/screen/screen_warning_oxygen.dm b/code/_onclick/hud/screen/screen_warning_oxygen.dm
new file mode 100644
index 000000000000..f964f7017a6c
--- /dev/null
+++ b/code/_onclick/hud/screen/screen_warning_oxygen.dm
@@ -0,0 +1,34 @@
+/obj/screen/warning/oxygen
+ name = "oxygen"
+ icon = 'icons/mob/screen/styles/status_oxy.dmi'
+ icon_state = "oxy0"
+ screen_loc = ui_temp
+ base_state = "oxy"
+ check_alert = /decl/hud_element/oxygen
+
+/obj/screen/warning/oxygen/handle_click(mob/user, params)
+ if(icon_state == "oxy0")
+ to_chat(user, SPAN_NOTICE("You are breathing easy."))
+ else
+ to_chat(user, SPAN_DANGER("You cannot breathe!"))
+
+// Robots use this warning icon as an environment indicator, not based on our own tolerances.
+/obj/screen/warning/oxygen/robot
+ screen_loc = ui_oxygen
+
+/obj/screen/warning/oxygen/robot/on_update_icon()
+ var/mob/living/owner = owner_ref?.resolve()
+ if(!istype(owner))
+ return
+ var/datum/gas_mixture/environment = owner.loc?.return_air()
+ if(!environment)
+ return
+ var/decl/species/species = get_species_by_key(global.using_map.default_species)
+ if(!species.breath_type || environment.gas[species.breath_type] > species.breath_pressure)
+ for(var/gas in species.poison_types)
+ if(environment.gas[gas])
+ icon_state = "oxy1"
+ return
+ icon_state = "oxy0"
+ else
+ icon_state = "oxy1"
diff --git a/code/_onclick/hud/screen/screen_warning_pressure.dm b/code/_onclick/hud/screen/screen_warning_pressure.dm
new file mode 100644
index 000000000000..cd77e8d8c0db
--- /dev/null
+++ b/code/_onclick/hud/screen/screen_warning_pressure.dm
@@ -0,0 +1,20 @@
+/obj/screen/warning/pressure
+ name = "pressure"
+ icon = 'icons/mob/screen/styles/status_pressure.dmi'
+ icon_state = "pressure0"
+ screen_loc = ui_temp
+ base_state = "pressure"
+ check_alert = /decl/hud_element/pressure
+
+/obj/screen/warning/pressure/handle_click(mob/user, params)
+ switch(icon_state)
+ if("pressure2")
+ to_chat(user, SPAN_DANGER("The air pressure here is crushing!"))
+ if("pressure1")
+ to_chat(user, SPAN_WARNING("The air pressure here is dangerously high."))
+ if("pressure-1")
+ to_chat(user, SPAN_WARNING("The air pressure here is dangerously low."))
+ if("pressure-2")
+ to_chat(user, SPAN_DANGER("There is nearly no air pressure here!"))
+ else
+ to_chat(user, SPAN_NOTICE("The local air pressure is comfortable."))
diff --git a/code/_onclick/hud/screen/screen_warning_toxins.dm b/code/_onclick/hud/screen/screen_warning_toxins.dm
new file mode 100644
index 000000000000..ef8c391491be
--- /dev/null
+++ b/code/_onclick/hud/screen/screen_warning_toxins.dm
@@ -0,0 +1,13 @@
+/obj/screen/warning/toxin
+ name = "toxin"
+ icon = 'icons/mob/screen/styles/status_tox.dmi'
+ icon_state = "tox0"
+ screen_loc = ui_temp
+ base_state = "tox"
+ check_alert = /decl/hud_element/toxins
+
+/obj/screen/warning/toxin/handle_click(mob/user, params)
+ if(icon_state == "tox0")
+ to_chat(user, SPAN_NOTICE("The air is clear of toxins."))
+ else
+ to_chat(user, SPAN_DANGER("The air is eating away at your skin!"))
diff --git a/code/_onclick/hud/screen/screen_warnings.dm b/code/_onclick/hud/screen/screen_warnings.dm
deleted file mode 100644
index d89eb94e10b2..000000000000
--- a/code/_onclick/hud/screen/screen_warnings.dm
+++ /dev/null
@@ -1,20 +0,0 @@
-/obj/screen/fire_warning
- name = "fire"
- icon_state = "fire0"
- screen_loc = ui_fire
-
-/obj/screen/health_warning
- name = "health"
- icon_state = "health0"
- screen_loc = ui_health
-
-/obj/screen/health_warning/handle_click(mob/user, params)
- if(ishuman(user))
- var/mob/living/human/human_user = user
- human_user.check_self_injuries()
- return TRUE
-
-/obj/screen/warning_cells
- name = "cell"
- icon_state = "charge-empty"
- screen_loc = ui_nutrition
diff --git a/code/_onclick/hud/screen/screen_zone_selector.dm b/code/_onclick/hud/screen/screen_zone_selector.dm
index 0850498b7f2a..51b36db21255 100644
--- a/code/_onclick/hud/screen/screen_zone_selector.dm
+++ b/code/_onclick/hud/screen/screen_zone_selector.dm
@@ -2,7 +2,6 @@
name = "damage zone"
icon_state = "zone_sel_tail"
screen_loc = ui_zonesel
- var/selecting = BP_CHEST
/obj/screen/zone_selector/handle_click(mob/user, params)
var/list/PL = params2list(params)
@@ -61,16 +60,16 @@
if(25 to 27)
if(icon_x in 15 to 17)
new_selecting = BP_EYES
- set_selected_zone(new_selecting)
+ user.set_target_zone(new_selecting)
return TRUE
-/obj/screen/zone_selector/proc/set_selected_zone(bodypart)
- var/old_selecting = selecting
- selecting = bodypart
- if(old_selecting != selecting)
+/obj/screen/zone_selector/proc/set_selected_zone(new_zone, old_zone)
+ if(new_zone != old_zone)
update_icon()
return TRUE
/obj/screen/zone_selector/rebuild_screen_overlays()
..()
- add_overlay(image('icons/mob/zone_sel.dmi', "[selecting]"))
+ var/mob/living/owner = owner_ref?.resolve()
+ if(istype(owner))
+ add_overlay(image('icons/mob/zone_sel.dmi', "[owner.selected_zone]"))
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index f3d74569b41b..3a3c22928073 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -33,7 +33,8 @@
user.visible_message(
SPAN_DANGER("\The [user] shakes \the [src]!"),
- SPAN_DANGER("You shake \the [src]!"))
+ SPAN_DANGER("You shake \the [src]!")
+ )
object_shaken()
return TRUE
diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm
index d91f03f89eed..05694e4565d7 100644
--- a/code/controllers/communications.dm
+++ b/code/controllers/communications.dm
@@ -94,13 +94,13 @@ var/global/const/EXTERNAL_AIR_FREQ = 1381 // Used by some external airlocks.
//Other devices can then choose to send signals to only those devices that belong to a particular filter.
//This is done for performance, so we don't send signals to lots of machines unnecessarily.
-//This filter is special because devices belonging to default also recieve signals sent to any other filter.
+//This filter is special because devices belonging to default also receive signals sent to any other filter.
var/global/const/RADIO_DEFAULT = "radio_default"
-//This filter is special because devices belonging to it do not recieve any signals at all. Useful for devices which only transmit.
+//This filter is special because devices belonging to it do not receive any signals at all. Useful for devices which only transmit.
var/global/const/RADIO_NULL = "radio_null"
var/global/const/RADIO_TO_AIRALARM = "radio_airalarm" //air alarms
-var/global/const/RADIO_FROM_AIRALARM = "radio_airalarm_rcvr" //devices interested in recieving signals from air alarms
+var/global/const/RADIO_FROM_AIRALARM = "radio_airalarm_rcvr" //devices interested in receiving signals from air alarms
var/global/const/RADIO_CHAT = "radio_telecoms"
var/global/const/RADIO_ATMOSIA = "radio_atmos"
var/global/const/RADIO_NAVBEACONS = "radio_navbeacon"
diff --git a/code/controllers/subsystems/icon_updates.dm b/code/controllers/subsystems/icon_updates.dm
index 7ad1540578ba..de98f51b0343 100644
--- a/code/controllers/subsystems/icon_updates.dm
+++ b/code/controllers/subsystems/icon_updates.dm
@@ -7,7 +7,6 @@ SUBSYSTEM_DEF(icon_update)
// Linked lists, queue_refs[x] should have null or args stored in queue_args[x]
var/list/queue_refs = list() // Atoms
- var/list/queue_args = list() // null or args
/datum/controller/subsystem/icon_update/stat_entry()
..("Queue: [queue_refs.len]")
@@ -16,56 +15,43 @@ SUBSYSTEM_DEF(icon_update)
fire(FALSE, TRUE)
/datum/controller/subsystem/icon_update/fire(resumed = FALSE, no_mc_tick = FALSE)
- if(!queue_refs.len)
+ var/list/cached_refs = queue_refs // local variables are quicker to access than instance variables. it's still the same list though
+ if(!cached_refs.len)
suspend()
return
- while (queue_refs.len)
-
- if(Master.map_loading)
- return
-
- // Pops the atom and its args
- var/atom/A = queue_refs[queue_refs.len]
- var/myArgs = queue_args[queue_args.len]
-
- queue_refs.len -= 1
- queue_args.len -= 1
-
+ var/static/count = 1 // proc-level static var, as with SSgarbage, in case a runtime makes this proc end early
+ while (count <= length(cached_refs)) // if we kept a copy of the queue to avoid mutating it while we run, this could possibly be made a lot faster by just using a for loop?
+ if(Master.map_loading) // we started loading a map mid-run, so stop and clean up
+ break
+ // Pops the atom from the queue
+ var/atom/A = cached_refs[count++] // count is used to cut our list later and save time
if(QDELETED(A))
continue
-
A.icon_update_queued = FALSE
-
- if (islist(myArgs))
- A.update_icon(arglist(myArgs))
- else
- A.update_icon()
-
+ A.update_icon()
if (no_mc_tick)
CHECK_TICK
else if (MC_TICK_CHECK)
- return
+ break
+ cached_refs.Cut(1, count)
+ count = 1
/atom
var/icon_update_queued = FALSE
-/atom/proc/queue_icon_update(...)
+/atom/proc/queue_icon_update()
// Skips if this is already queued
- if(!icon_update_queued)
-
- icon_update_queued = TRUE
- SSicon_update.queue_refs.Add(src)
-
- // Makes sure these are in sync, in case runtimes/badmin
- var/length = length(SSicon_update.queue_refs)
- SSicon_update.queue_args.len = length
- SSicon_update.queue_args[length] = args.len ? args : null
-
- // SSicon_update sleeps when it runs out of things in its
- // queue, so wake it up.
- if(!Master.map_loading) // Don't wake early if we're loading a map, it'll get woken up when the map loads.
- SSicon_update.wake()
+ if(icon_update_queued)
+ return
+ icon_update_queued = TRUE
+ // This is faster than using Add() because BYOND.
+ SSicon_update.queue_refs[++SSicon_update.queue_refs.len] = src
+
+ // SSicon_update sleeps when it runs out of things in its
+ // queue, so wake it up.
+ if(!Master.map_loading) // Don't wake early if we're loading a map, it'll get woken up when the map loads.
+ SSicon_update.wake()
/datum/controller/subsystem/icon_update/StartLoadingMap()
suspend()
diff --git a/code/controllers/subsystems/initialization/modpacks.dm b/code/controllers/subsystems/initialization/modpacks.dm
index f2f6c65a2e69..7a44aec55c6f 100644
--- a/code/controllers/subsystems/initialization/modpacks.dm
+++ b/code/controllers/subsystems/initialization/modpacks.dm
@@ -6,7 +6,7 @@ SUBSYSTEM_DEF(modpacks)
// Compiled modpack information.
var/list/default_submap_whitelisted_species = list()
- var/list/default_submap_blacklisted_species = list(SPECIES_ALIEN, SPECIES_GOLEM)
+ var/list/default_submap_blacklisted_species = list()
var/list/modpack_nanoui_directories = list()
/datum/controller/subsystem/modpacks/Initialize()
diff --git a/code/controllers/subsystems/lighting.dm b/code/controllers/subsystems/lighting.dm
index 61f8b083a33b..068353abbe0c 100644
--- a/code/controllers/subsystems/lighting.dm
+++ b/code/controllers/subsystems/lighting.dm
@@ -57,7 +57,10 @@ SUBSYSTEM_DEF(lighting)
var/datum/level_data/level = SSmapping.levels_by_z[zlevel]
for (var/turf/tile as anything in block(1, 1, zlevel, level.level_max_width, level.level_max_height)) // include TRANSITIONEDGE turfs
if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(tile))
- tile.lighting_build_overlay()
+ if(!isnull(tile.lighting_overlay))
+ log_warning("Attempted to create lighting_overlay on [tile.get_log_info_line()] when it already had one.")
+ continue
+ new /atom/movable/lighting_overlay(tile)
overlaycount++
CHECK_TICK
diff --git a/code/controllers/subsystems/machines.dm b/code/controllers/subsystems/machines.dm
index 674ec094cc68..19a5202daa38 100644
--- a/code/controllers/subsystems/machines.dm
+++ b/code/controllers/subsystems/machines.dm
@@ -7,7 +7,7 @@
if (Datum.is_processing) {\
if(Datum.is_processing != "SSmachines.[#List]")\
{\
- PRINT_STACK_TRACE("Failed to start processing. [log_info_line(Datum)] is already being processed by [Datum.is_processing] but queue attempt occured on SSmachines.[#List]."); \
+ PRINT_STACK_TRACE("Failed to start processing. [log_info_line(Datum)] is already being processed by [Datum.is_processing] but queue attempt occurred on SSmachines.[#List]."); \
}\
} else {\
Datum.is_processing = "SSmachines.[#List]";\
diff --git a/code/controllers/subsystems/spacedrift.dm b/code/controllers/subsystems/spacedrift.dm
index 31b4d0fae597..331e856cdf49 100644
--- a/code/controllers/subsystems/spacedrift.dm
+++ b/code/controllers/subsystems/spacedrift.dm
@@ -34,9 +34,9 @@ SUBSYSTEM_DEF(spacedrift)
return
continue
- if (!AM.loc || AM.loc != AM.inertia_last_loc || AM.Process_Spacemove(0))
+ if (!AM.loc || AM.loc != AM.inertia_last_loc || AM.is_space_movement_permitted() != SPACE_MOVE_FORBIDDEN)
AM.inertia_dir = 0
-
+
AM.inertia_ignore = null
if (!AM.inertia_dir)
diff --git a/code/controllers/subsystems/throwing.dm b/code/controllers/subsystems/throwing.dm
index 4dc2001e17ed..0849837efd8f 100644
--- a/code/controllers/subsystems/throwing.dm
+++ b/code/controllers/subsystems/throwing.dm
@@ -33,7 +33,7 @@ SUBSYSTEM_DEF(throwing)
continue
if (QDELETED(TT))
if(!QDELETED(AM))
- AM.end_throw()
+ AM.end_throw(TT)
processing -= AM
if (MC_TICK_CHECK)
return
@@ -103,7 +103,7 @@ SUBSYSTEM_DEF(throwing)
/datum/thrownthing/Destroy()
SSthrowing.processing -= thrownthing
- thrownthing.end_throw()
+ thrownthing.end_throw(src)
thrownthing = null
target = null
thrower = null
@@ -192,7 +192,7 @@ SUBSYSTEM_DEF(throwing)
if(!QDELETED(thrownthing))
thrownthing.fall()
- thrownthing.end_throw()
+ thrownthing.end_throw(src)
qdel(src)
/datum/thrownthing/proc/hit_atom(atom/A)
diff --git a/code/controllers/subsystems/vis_contents.dm b/code/controllers/subsystems/vis_contents.dm
index b18e803da68e..3cafe0983796 100644
--- a/code/controllers/subsystems/vis_contents.dm
+++ b/code/controllers/subsystems/vis_contents.dm
@@ -21,26 +21,24 @@ SUBSYSTEM_DEF(vis_contents_update)
// Largely copied from SSicon_update.
/datum/controller/subsystem/vis_contents_update/fire(resumed = FALSE, no_mc_tick = FALSE)
- if(!queue_refs.len)
+ var/list/cached_refs = queue_refs // cache the instance var for more speed
+ if(!length(cached_refs))
suspend()
return
var/i = 0
- while (i < queue_refs.len)
- i++
- var/atom/A = queue_refs[i]
+ while (i < length(cached_refs))
+ if(Master.map_loading)
+ break
+ var/atom/A = cached_refs[++i]
if(QDELETED(A))
continue
- if(Master.map_loading)
- queue_refs.Cut(1, i+1)
- return
A.vis_update_queued = FALSE
- A.update_vis_contents(force_no_queue = TRUE)
+ A.update_vis_contents()
if (no_mc_tick)
CHECK_TICK
else if (MC_TICK_CHECK)
- queue_refs.Cut(1, i+1)
- return
- queue_refs.Cut()
+ break
+ cached_refs.Cut(1, i+1)
/atom
var/vis_update_queued = FALSE
@@ -49,8 +47,8 @@ SUBSYSTEM_DEF(vis_contents_update)
if(vis_update_queued)
return
vis_update_queued = TRUE
- SSvis_contents_update.queue_refs.Add(src)
- if(!Master.map_loading) // Don't wake early if we're loading a map, it'll get woken up when the map loads.
+ SSvis_contents_update.queue_refs[++SSvis_contents_update.queue_refs.len] = src
+ if(SSvis_contents_update.suspended && !Master.map_loading) // Don't wake early if we're loading a map, it'll get woken up when the map loads.
SSvis_contents_update.wake()
// Horrible colon syntax below is because vis_contents
@@ -70,8 +68,8 @@ SUBSYSTEM_DEF(vis_contents_update)
/atom/proc/get_vis_contents_to_add()
return
-/atom/proc/update_vis_contents(force_no_queue = FALSE)
- if(!force_no_queue && (!SSvis_contents_update.initialized || TICK_CHECK))
+/atom/proc/update_vis_contents()
+ if(Master.map_loading || SSvis_contents_update.init_state == SS_INITSTATE_NONE || TICK_CHECK)
queue_vis_contents_update()
return
vis_update_queued = FALSE
diff --git a/code/controllers/subsystems/vote.dm b/code/controllers/subsystems/vote.dm
index fb2a258791c9..5acccf7afe08 100644
--- a/code/controllers/subsystems/vote.dm
+++ b/code/controllers/subsystems/vote.dm
@@ -12,7 +12,7 @@ SUBSYSTEM_DEF(vote)
var/list/old_votes //Stores completed votes for reference.
var/queued_auto_vote //Used if a vote queues another vote to happen after it.
- var/list/voting = list() //Clients recieving UI updates.
+ var/list/voting = list() //Clients receiving UI updates.
var/list/vote_prototypes //To run checks on whether they are available.
/datum/controller/subsystem/vote/Initialize()
diff --git a/code/datums/communication/dsay.dm b/code/datums/communication/dsay.dm
index 273f17a36b74..c329b243c89b 100644
--- a/code/datums/communication/dsay.dm
+++ b/code/datums/communication/dsay.dm
@@ -10,8 +10,9 @@
mute_setting = MUTE_DEADCHAT
show_preference_setting = /datum/client_preference/show_dsay
+// Changes the default speech_method kwarg.
/decl/communication_channel/dsay/communicate(communicator, message, speech_method = /decl/dsay_communication/say)
- ..()
+ return ..()
/decl/communication_channel/dsay/can_communicate(var/client/communicator, var/message, var/speech_method_type)
var/decl/dsay_communication/speech_method = GET_DECL(speech_method_type)
diff --git a/code/datums/config/config_types/config_client.dm b/code/datums/config/config_types/config_client.dm
index 7219bc3189fb..ed8a0224daff 100644
--- a/code/datums/config/config_types/config_client.dm
+++ b/code/datums/config/config_types/config_client.dm
@@ -51,7 +51,7 @@
/decl/config/toggle/popup_admin_pm
uid = "popup_admin_pm"
desc = list(
- "Remove the # to show a popup 'reply to' window to every non-admin that recieves an adminPM.",
+ "Remove the # to show a popup 'reply to' window to every non-admin that receives an adminPM.",
"The intention is to make adminPMs more visible. (although I fnd popups annoying so this defaults to off)."
)
diff --git a/code/datums/config/config_types/config_game_world.dm b/code/datums/config/config_types/config_game_world.dm
index f7749cfce81a..66b154dd6dc6 100644
--- a/code/datums/config/config_types/config_game_world.dm
+++ b/code/datums/config/config_types/config_game_world.dm
@@ -22,7 +22,8 @@
/decl/config/toggle/humans_need_surnames,
/decl/config/toggle/roundstart_level_generation,
/decl/config/toggle/lights_start_on,
- /decl/config/toggle/on/cisnormativity
+ /decl/config/toggle/on/cisnormativity,
+ /decl/config/enum/colored_coating_names
)
/decl/config/num/exterior_ambient_light
@@ -134,4 +135,14 @@
/decl/config/toggle/on/cisnormativity
uid = "cisnormativity"
- desc = "If true, when bodytype is changed in character creation, selected pronouns are also changed."
\ No newline at end of file
+ desc = "If true, when bodytype is changed in character creation, selected pronouns are also changed."
+
+/decl/config/enum/colored_coating_names
+ uid = "colored_coating_names"
+ desc = "Determines the coloring of various strings representing coatings on objects (blood, oil, mud, etc)."
+ default_value = CONFIG_COATING_COLOR_MIXTURE
+ enum_map = list(
+ "none" = CONFIG_COATING_COLOR_NONE,
+ "mixture" = CONFIG_COATING_COLOR_MIXTURE,
+ "components" = CONFIG_COATING_COLOR_COMPONENTS
+ )
\ No newline at end of file
diff --git a/code/datums/movement/mob.dm b/code/datums/movement/mob.dm
index cb703f6ca937..996c62150859 100644
--- a/code/datums/movement/mob.dm
+++ b/code/datums/movement/mob.dm
@@ -62,21 +62,28 @@
return (MOVEMENT_PROCEED|MOVEMENT_HANDLED)
/datum/movement_handler/mob/space
- var/allow_move
+ var/last_space_move_result
+
+// Notes on space movement chain:
+// - owning mob calls MayMove() via normal movement handler chain
+// - MayMove() sets last_space_move_result based on is_space_movement_permitted() (checks for footing, magboots, etc)
+// - last_space_move_result is checked in DoMove() and passed to try_space_move() as a param, which returns TRUE/FALSE
+// - if the original move result was forbidden, or try_space_move() fails, the handler prevents movement.
+// - Otherwise it goes ahead and lets the mob move.
// Space movement
/datum/movement_handler/mob/space/DoMove(direction, mob/mover, is_external)
if(mob.has_gravity() || (IS_NOT_SELF(mover) && is_external))
return
- if(!allow_move || !mob.space_do_move(allow_move, direction))
+ if(last_space_move_result == SPACE_MOVE_FORBIDDEN || !mob.try_space_move(last_space_move_result, direction))
return MOVEMENT_HANDLED
/datum/movement_handler/mob/space/MayMove(mob/mover, is_external)
if(IS_NOT_SELF(mover) && is_external)
return MOVEMENT_PROCEED
if(!mob.has_gravity())
- allow_move = mob.Process_Spacemove(1)
- if(!allow_move)
+ last_space_move_result = mob.is_space_movement_permitted(allow_movement = TRUE)
+ if(last_space_move_result == SPACE_MOVE_FORBIDDEN)
return MOVEMENT_STOP
return MOVEMENT_PROCEED
diff --git a/code/datums/movement/robot.dm b/code/datums/movement/robot.dm
index 258c5e840b4c..2674938b3cc0 100644
--- a/code/datums/movement/robot.dm
+++ b/code/datums/movement/robot.dm
@@ -16,8 +16,11 @@
// Use power while moving.
/datum/movement_handler/robot/use_power/DoMove(direction, mob/mover, is_external)
var/datum/robot_component/actuator/A = robot.get_component("actuator")
- if(!robot.cell_use_power(A.active_usage * robot.power_efficiency))
+ if(!is_external && !robot.cell_use_power(A.active_usage * robot.power_efficiency))
return MOVEMENT_HANDLED
+ return MOVEMENT_PROCEED
/datum/movement_handler/robot/use_power/MayMove(mob/mover, is_external)
- return (!robot.lockcharge && robot.is_component_functioning("actuator")) ? MOVEMENT_PROCEED : MOVEMENT_STOP
+ if(is_external || (!robot.incapacitated() && !robot.lockcharge && robot.is_component_functioning("actuator")))
+ return MOVEMENT_PROCEED
+ return MOVEMENT_STOP
diff --git a/code/datums/observation/zone_selected.dm b/code/datums/observation/zone_selected.dm
index 1b5272c33df9..8a4c7bc58756 100644
--- a/code/datums/observation/zone_selected.dm
+++ b/code/datums/observation/zone_selected.dm
@@ -17,7 +17,6 @@
* Zone Selected Handling *
*******************/
-/obj/screen/zone_selector/set_selected_zone(bodypart)
- var/old_selecting = selecting
+/obj/screen/zone_selector/set_selected_zone(new_zone, old_zone)
if((. = ..()))
- RAISE_EVENT(/decl/observ/zone_selected, src, old_selecting, selecting)
\ No newline at end of file
+ RAISE_EVENT(/decl/observ/zone_selected, src, old_zone, new_zone)
\ No newline at end of file
diff --git a/code/datums/extensions/storage/_storage.dm b/code/datums/storage/_storage.dm
similarity index 99%
rename from code/datums/extensions/storage/_storage.dm
rename to code/datums/storage/_storage.dm
index 4ff70967e1c6..07d0d0871521 100644
--- a/code/datums/extensions/storage/_storage.dm
+++ b/code/datums/storage/_storage.dm
@@ -380,7 +380,7 @@ var/global/list/_test_storage_items = list()
/datum/storage/proc/can_view(mob/viewer)
return (holder in viewer.contents) || viewer.Adjacent(holder)
-///Overridable sound playback parameters. Since not all sounds are created equal.
+///Overrideable sound playback parameters. Since not all sounds are created equal.
/datum/storage/proc/play_open_sound(volume = 50)
if(!length(open_sound) || !holder)
return
diff --git a/code/datums/extensions/storage/_storage_ui.dm b/code/datums/storage/_storage_ui.dm
similarity index 100%
rename from code/datums/extensions/storage/_storage_ui.dm
rename to code/datums/storage/_storage_ui.dm
diff --git a/code/datums/extensions/storage/subtypes_backpack.dm b/code/datums/storage/subtypes_backpack.dm
similarity index 96%
rename from code/datums/extensions/storage/subtypes_backpack.dm
rename to code/datums/storage/subtypes_backpack.dm
index 3523c4968260..360c835727d1 100644
--- a/code/datums/extensions/storage/subtypes_backpack.dm
+++ b/code/datums/storage/subtypes_backpack.dm
@@ -4,7 +4,6 @@
open_sound = 'sound/effects/storage/unzip.ogg'
/datum/storage/backpack/holding
- max_w_class = ITEM_SIZE_NORMAL
max_storage_space = 56
/datum/storage/backpack/holding/can_be_inserted(obj/item/W, mob/user, stop_messages = 0, click_params)
diff --git a/code/datums/extensions/storage/subtypes_bag.dm b/code/datums/storage/subtypes_bag.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_bag.dm
rename to code/datums/storage/subtypes_bag.dm
diff --git a/code/datums/extensions/storage/subtypes_basket.dm b/code/datums/storage/subtypes_basket.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_basket.dm
rename to code/datums/storage/subtypes_basket.dm
diff --git a/code/datums/extensions/storage/subtypes_belt.dm b/code/datums/storage/subtypes_belt.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_belt.dm
rename to code/datums/storage/subtypes_belt.dm
diff --git a/code/datums/extensions/storage/subtypes_box.dm b/code/datums/storage/subtypes_box.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_box.dm
rename to code/datums/storage/subtypes_box.dm
diff --git a/code/datums/extensions/storage/subtypes_excavation.dm b/code/datums/storage/subtypes_excavation.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_excavation.dm
rename to code/datums/storage/subtypes_excavation.dm
diff --git a/code/datums/extensions/storage/subtypes_firstaid.dm b/code/datums/storage/subtypes_firstaid.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_firstaid.dm
rename to code/datums/storage/subtypes_firstaid.dm
diff --git a/code/datums/extensions/storage/subtypes_holster.dm b/code/datums/storage/subtypes_holster.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_holster.dm
rename to code/datums/storage/subtypes_holster.dm
diff --git a/code/datums/extensions/storage/subtypes_misc.dm b/code/datums/storage/subtypes_misc.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_misc.dm
rename to code/datums/storage/subtypes_misc.dm
diff --git a/code/datums/extensions/storage/subtypes_mre.dm b/code/datums/storage/subtypes_mre.dm
similarity index 95%
rename from code/datums/extensions/storage/subtypes_mre.dm
rename to code/datums/storage/subtypes_mre.dm
index b5045c1fc1b2..696f0343718f 100644
--- a/code/datums/extensions/storage/subtypes_mre.dm
+++ b/code/datums/storage/subtypes_mre.dm
@@ -20,7 +20,7 @@
/datum/storage/mrebag/open(mob/user)
if(!opened)
- to_chat(user, "The pouch heats up as you break the vaccum seal.")
+ to_chat(user, "The pouch heats up as you break the vacuum seal.")
. = ..()
/datum/storage/mrebag/dessert
diff --git a/code/datums/extensions/storage/subtypes_part_replacer.dm b/code/datums/storage/subtypes_part_replacer.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_part_replacer.dm
rename to code/datums/storage/subtypes_part_replacer.dm
diff --git a/code/datums/extensions/storage/subtypes_pills.dm b/code/datums/storage/subtypes_pills.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_pills.dm
rename to code/datums/storage/subtypes_pills.dm
diff --git a/code/datums/extensions/storage/subtypes_pockets.dm b/code/datums/storage/subtypes_pockets.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_pockets.dm
rename to code/datums/storage/subtypes_pockets.dm
diff --git a/code/datums/extensions/storage/subtypes_secure.dm b/code/datums/storage/subtypes_secure.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_secure.dm
rename to code/datums/storage/subtypes_secure.dm
diff --git a/code/datums/extensions/storage/subtypes_sheets.dm b/code/datums/storage/subtypes_sheets.dm
similarity index 97%
rename from code/datums/extensions/storage/subtypes_sheets.dm
rename to code/datums/storage/subtypes_sheets.dm
index a72c49ab856d..578282c8d4b9 100644
--- a/code/datums/extensions/storage/subtypes_sheets.dm
+++ b/code/datums/storage/subtypes_sheets.dm
@@ -77,7 +77,7 @@
return FALSE
//I would prefer to drop a new stack, but the item/attack_hand code
- // that calls this can't recieve a different object than you clicked on.
+ // that calls this can't receive a different object than you clicked on.
//Therefore, make a new stack internally that has the remainder.
// -Sayu
diff --git a/code/datums/extensions/storage/subtypes_slides.dm b/code/datums/storage/subtypes_slides.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_slides.dm
rename to code/datums/storage/subtypes_slides.dm
diff --git a/code/datums/extensions/storage/subtypes_specialized.dm b/code/datums/storage/subtypes_specialized.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_specialized.dm
rename to code/datums/storage/subtypes_specialized.dm
diff --git a/code/datums/extensions/storage/subtypes_structure.dm b/code/datums/storage/subtypes_structure.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_structure.dm
rename to code/datums/storage/subtypes_structure.dm
diff --git a/code/datums/extensions/storage/subtypes_tray.dm b/code/datums/storage/subtypes_tray.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_tray.dm
rename to code/datums/storage/subtypes_tray.dm
diff --git a/code/datums/extensions/storage/subtypes_wallet.dm b/code/datums/storage/subtypes_wallet.dm
similarity index 100%
rename from code/datums/extensions/storage/subtypes_wallet.dm
rename to code/datums/storage/subtypes_wallet.dm
diff --git a/code/datums/supplypacks/custodial.dm b/code/datums/supplypacks/custodial.dm
index 9dc185965993..9409c0b8912e 100644
--- a/code/datums/supplypacks/custodial.dm
+++ b/code/datums/supplypacks/custodial.dm
@@ -10,7 +10,7 @@
/obj/item/lightreplacer,
/obj/item/chems/spray/cleaner,
/obj/item/box/lights/mixed,
- /obj/item/chems/glass/rag,
+ /obj/item/chems/rag,
/obj/item/grenade/chem_grenade/cleaner = 3,
/obj/structure/mopbucket)
containertype = /obj/structure/closet/crate/large
@@ -33,7 +33,7 @@
/obj/item/grenade/chem_grenade/cleaner = 3,
/obj/item/box/detergent = 3,
/obj/item/chems/glass/bucket,
- /obj/item/chems/glass/rag,
+ /obj/item/chems/rag,
/obj/item/chems/spray/cleaner = 2,
/obj/item/soap)
containertype = /obj/structure/closet/crate/large
diff --git a/code/datums/supplypacks/dispcarts.dm b/code/datums/supplypacks/dispcarts.dm
index dcaddd40fcb8..723e6f9443cc 100644
--- a/code/datums/supplypacks/dispcarts.dm
+++ b/code/datums/supplypacks/dispcarts.dm
@@ -86,6 +86,9 @@ PACK(syrup_chocolate, /obj/item/chems/chem_disp_cartridge/syrup_chocolate, "Reag
PACK(syrup_caramel, /obj/item/chems/chem_disp_cartridge/syrup_caramel, "Reagent refill - Caramel Syrup", "caramel syrup reagent cartridge crate")
PACK(syrup_vanilla, /obj/item/chems/chem_disp_cartridge/syrup_vanilla, "Reagent refill - Vanilla Syrup", "vanilla syrup reagent cartridge crate")
PACK(syrup_pumpkin, /obj/item/chems/chem_disp_cartridge/syrup_pumpkin, "Reagent refill - Pumpkin Spice Syrup", "pumpkin spice syrup reagent cartridge crate")
+PACK(syrup_lavender, /obj/item/chems/chem_disp_cartridge/syrup_lavender, "Reagent refill - Lavender Syrup", "lavender syrup reagent cartridge crate")
+PACK(cinnamon, /obj/item/chems/chem_disp_cartridge/cinnamon, "Reagent refill - Cinnamon", "cinnamon reagent cartridge crate")
+
#undef SEC_PACK
#undef PACK
diff --git a/code/datums/supplypacks/livecargo.dm b/code/datums/supplypacks/livecargo.dm
index 44900acbba45..4013f1887b24 100644
--- a/code/datums/supplypacks/livecargo.dm
+++ b/code/datums/supplypacks/livecargo.dm
@@ -9,12 +9,19 @@
containername = "monkey crate"
/decl/hierarchy/supply_pack/livecargo/spidercubes
- name = "Inert - Spiders"
+ name = "Inert - Spider Cubes"
contains = list(/obj/item/box/animal_cubes/spiders)
containertype = /obj/structure/closet/crate/secure
containername = "spiderling crate"
- contraband = 1
- security_level = null
+ access = access_research
+
+/decl/hierarchy/supply_pack/livecargo/carpcubes
+ name = "Inert - Space Carp Cubes"
+ contains = list(/obj/item/box/animal_cubes/carp)
+ containertype = /obj/structure/closet/crate/secure
+ containername = "space carp crate"
+ access = access_chemistry
+
//actual live animals
/decl/hierarchy/supply_pack/livecargo/corgi
diff --git a/code/datums/uplink/ammunition.dm b/code/datums/uplink/ammunition.dm
index 2ee116a6b7e4..4c0f2ba93ab3 100644
--- a/code/datums/uplink/ammunition.dm
+++ b/code/datums/uplink/ammunition.dm
@@ -50,13 +50,13 @@
/datum/uplink_item/item/ammo/shotgun_shells
name = "Ammobox of Shotgun Shells"
- desc = "An ammobox with 2 sets of shell holders. Contains 8 buckshot shells total."
+ desc = "An ammo box with 2 sets of shell holders. Contains 8 buckshot shells total."
item_cost = 8
path = /obj/item/box/ammo/shotgunshells
/datum/uplink_item/item/ammo/shotgun_slugs
name = "Ammobox of Shotgun Slugs"
- desc = "An ammobox with 2 sets of shell holders. Contains 8 slugs total."
+ desc = "An ammo box with 2 sets of shell holders. Contains 8 slugs total."
item_cost = 8
path = /obj/item/box/ammo/shotgunammo
diff --git a/code/datums/uplink/badassery.dm b/code/datums/uplink/badassery.dm
index 14954c31afdb..43375e941cb9 100644
--- a/code/datums/uplink/badassery.dm
+++ b/code/datums/uplink/badassery.dm
@@ -11,7 +11,7 @@
/datum/uplink_item/item/badassery/balloon/random
name = "For showing 'Whatevah~' (Useless Balloon)"
- desc = "Randomly selects a ballon for you!"
+ desc = "Randomly selects a balloon for you!"
path = /obj/item/toy/balloon
/datum/uplink_item/item/badassery/balloon/random/get_goods(var/obj/item/uplink/U, var/loc)
diff --git a/code/datums/uplink/devices_and_tools.dm b/code/datums/uplink/devices_and_tools.dm
index a6628ebabefa..7536a5d65616 100644
--- a/code/datums/uplink/devices_and_tools.dm
+++ b/code/datums/uplink/devices_and_tools.dm
@@ -104,7 +104,7 @@
/datum/uplink_item/item/tools/flashdark
name = "Flashdark"
- desc = "A device similar to a flash light that absorbs the surrounding light, casting a shadowy, black mass."
+ desc = "A device similar to a flashlight that absorbs the surrounding light, casting a shadowy, black mass."
item_cost = 32
path = /obj/item/flashlight/flashdark
diff --git a/code/datums/uplink/highly_visible_and_dangerous_weapons.dm b/code/datums/uplink/highly_visible_and_dangerous_weapons.dm
index 097666428c62..c64cf84b614a 100644
--- a/code/datums/uplink/highly_visible_and_dangerous_weapons.dm
+++ b/code/datums/uplink/highly_visible_and_dangerous_weapons.dm
@@ -51,7 +51,7 @@
/datum/uplink_item/item/visible_weapons/energy_gun
name = "Energy Gun"
- desc = "A energy based sidearm with three different lethality settings."
+ desc = "An energy-based sidearm with three different lethality settings."
item_cost = 32
path = /obj/item/gun/energy/gun
@@ -71,14 +71,14 @@
//These are for traitors (or other antags, perhaps) to have the option of purchasing some merc gear.
/datum/uplink_item/item/visible_weapons/smg
name = "Standard Submachine Gun"
- desc = "A quick-firing weapon with three togglable fire modes."
+ desc = "A quick-firing weapon with three toggleable fire modes."
item_cost = 52
path = /obj/item/gun/projectile/automatic/smg
antag_roles = list(/decl/special_role/mercenary)
/datum/uplink_item/item/visible_weapons/assaultrifle
name = "Assault Rifle"
- desc = "A common rifle with three togglable fire modes."
+ desc = "A common rifle with three toggleable fire modes."
item_cost = 60
path = /obj/item/gun/projectile/automatic/assault_rifle
antag_roles = list(/decl/special_role/mercenary)
@@ -98,7 +98,7 @@
/datum/uplink_item/item/visible_weapons/combat_shotgun
name = "Pump Shotgun"
- desc = "A high compacity, pump-action shotgun regularly used for repelling boarding parties in close range scenarios."
+ desc = "A high capacity, pump-action shotgun regularly used for repelling boarding parties in close range scenarios."
item_cost = 52
path = /obj/item/gun/projectile/shotgun/pump
antag_roles = list(/decl/special_role/mercenary)
@@ -111,7 +111,7 @@
/datum/uplink_item/item/visible_weapons/flechetterifle
name = "Flechette Rifle"
- desc = "A railgun with two togglable fire modes, able to launch flechette ammunition at incredible speeds."
+ desc = "A railgun with two toggleable fire modes, able to launch flechette ammunition at incredible speeds."
item_cost = 60
path = /obj/item/gun/magnetic/railgun/flechette
antag_roles = list(/decl/special_role/mercenary)
diff --git a/code/datums/uplink/implants.dm b/code/datums/uplink/implants.dm
index 94bdff821a27..0495c267c1b8 100644
--- a/code/datums/uplink/implants.dm
+++ b/code/datums/uplink/implants.dm
@@ -6,7 +6,7 @@
/datum/uplink_item/item/implants/imp_freedom
name = "Freedom Implant"
- desc = "An implant with an emotive trigger that can break you free of restraints. Show Security who has the real upperhand!"
+ desc = "An implant with an emotive trigger that can break you free of restraints. Show Security who has the real upper hand!"
item_cost = 24
path = /obj/item/box/syndie_kit/imp_freedom
diff --git a/code/datums/uplink/medical.dm b/code/datums/uplink/medical.dm
index 599c0f83f6a6..4aef274b938c 100644
--- a/code/datums/uplink/medical.dm
+++ b/code/datums/uplink/medical.dm
@@ -18,7 +18,7 @@
/datum/uplink_item/item/medical/stasis
name = "Stasis Bag"
- desc = "Reusable bag designed to slow down life functions of occupant, especially useful if short on time or in a hostile enviroment."
+ desc = "Reusable bag designed to slow down life functions of occupant, especially useful if short on time or in a hostile environment."
item_cost = 24
path = /obj/item/bodybag/cryobag
diff --git a/code/datums/uplink/stealth_and_camouflage_items.dm b/code/datums/uplink/stealth_and_camouflage_items.dm
index 9a9d21c0761a..d2f189c5dd24 100644
--- a/code/datums/uplink/stealth_and_camouflage_items.dm
+++ b/code/datums/uplink/stealth_and_camouflage_items.dm
@@ -42,7 +42,7 @@
/datum/uplink_item/item/stealth_items/voice
name = "Modified Gas Mask"
- desc = "A fully functioning gas mask that is able to conceal your face and has a built in voice modulator, \
+ desc = "A fully functioning gas mask that is able to conceal your face and has a built-in voice modulator, \
so you can become a true shadow operative!"
item_cost = 20
path = /obj/item/clothing/mask/chameleon/voice
diff --git a/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm b/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm
index d085b9438d99..45deaffbf371 100644
--- a/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm
+++ b/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm
@@ -17,7 +17,7 @@
/datum/uplink_item/item/stealthy_weapons/concealed_cane
name = "Concealed Cane Sword"
- desc = "A cane used by a true gentlemen, especially ones with sharp intentions."
+ desc = "A cane used by a true gentleman, especially ones with sharp intentions."
item_cost = 8
path = /obj/item/cane/fancy/sword
diff --git a/code/datums/wires/radio.dm b/code/datums/wires/radio.dm
index 22b951263c56..d2d868a4a7d1 100644
--- a/code/datums/wires/radio.dm
+++ b/code/datums/wires/radio.dm
@@ -3,7 +3,7 @@
wire_count = 3
descriptions = list(
new /datum/wire_description(WIRE_SIGNAL, "This wire connects several radio components."),
- new /datum/wire_description(WIRE_RECEIVE, "This wire runs to the radio reciever.", SKILL_EXPERT),
+ new /datum/wire_description(WIRE_RECEIVE, "This wire runs to the radio receiver.", SKILL_EXPERT),
new /datum/wire_description(WIRE_TRANSMIT, "This wire runs to the radio transmitter.")
)
diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm
index 56b88e8f986c..ea8bcbc016f7 100644
--- a/code/datums/wires/wires.dm
+++ b/code/datums/wires/wires.dm
@@ -192,7 +192,7 @@ var/global/list/wireColourNames = list("darkred" = "dark red")
usr.unset_machine(holder)
//
-// Overridable Procs
+// Overrideable Procs
//
// Called when wires cut/mended.
diff --git a/code/game/antagonist/antagonist_objectives.dm b/code/game/antagonist/antagonist_objectives.dm
index 5e0f27068cff..51caf655579f 100644
--- a/code/game/antagonist/antagonist_objectives.dm
+++ b/code/game/antagonist/antagonist_objectives.dm
@@ -17,7 +17,7 @@
/mob/proc/add_objectives()
set name = "Get Objectives"
- set desc = "Recieve optional objectives."
+ set desc = "Receive optional objectives."
set category = "OOC"
src.verbs -= /mob/proc/add_objectives
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 95cf7d39aee6..443f0046748c 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -422,7 +422,7 @@ var/global/list/mob/living/forced_ambiance_list = new
if(isspaceturf(get_turf(mob))) // Can't fall onto nothing.
return
- if(mob.Check_Shoegrip())
+ if(!mob.can_slip(magboots_only = TRUE))
return
if(ishuman(mob))
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 196f4cc44e5c..a9fc6994d811 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -277,23 +277,20 @@
- `user`: The mob examining this atom
- `distance`: The distance this atom is from the `user`
- - `infix`: TODO
- - `suffix`: TODO
+ - `infix`: An optional string appended directly to the 'That's an X' string, between the name the end of the sentence.
+ - `suffix`: An optional string appended in a separate sentence after the initial introduction line.
- Return: `TRUE` when the call chain is valid, otherwise `FALSE`
- Events: `atom_examined`
*/
/atom/proc/examine(mob/user, distance, infix = "", suffix = "")
SHOULD_CALL_PARENT(TRUE)
- //This reformat names to get a/an properly working on item descriptions when they are bloody
- var/f_name = "\a [src][infix]."
- if(blood_color && !istype(src, /obj/effect/decal))
- if(gender == PLURAL)
- f_name = "some "
- else
- f_name = "a "
- f_name += "stained [name][infix]!"
+ //This reformats names to get a/an properly working on item descriptions when they are bloody or coated in reagents.
+ var/examine_prefix = get_examine_prefix()
+ if(examine_prefix)
+ examine_prefix += " " // add a space to the end to be polite
+ var/composed_name = ADD_ARTICLE_GENDER("[examine_prefix][name]", gender)
- to_chat(user, "[html_icon(src)] That's [f_name] [suffix]")
+ to_chat(user, "[html_icon(src)] That's [composed_name][infix][get_examine_punctuation()] [suffix]")
to_chat(user, desc)
var/list/alt_interactions = get_alt_interactions(user)
@@ -375,13 +372,18 @@
/**
Update this atom's icon.
+ If prior to the first SSicon_update flush (i.e. it's during init), icon updates are forced to queue instead.
+ This saves a lot of init time.
- Events: `updated_icon`
*/
/atom/proc/update_icon()
SHOULD_CALL_PARENT(TRUE)
- on_update_icon(arglist(args))
- RAISE_EVENT(/decl/observ/updated_icon, src)
+ if(SSicon_update.init_state == SS_INITSTATE_NONE)
+ queue_icon_update()
+ else
+ on_update_icon()
+ RAISE_EVENT(/decl/observ/updated_icon, src)
/**
Update this atom's icon.
@@ -618,7 +620,7 @@
Used for atoms performing audible actions
- `message`: The string to show to anyone who can hear this atom
- - `dead_message?`: The string deaf mobs will see
+ - `deaf_message?`: The string deaf mobs will see
- `hearing_distance?`: The number of tiles away the message can be heard. Defaults to world.view
- `check_ghosts?`: TRUE if ghosts should hear the message if their preferences allow
- `radio_message?`: The string to send over radios
@@ -966,7 +968,7 @@
/atom/proc/get_thermal_mass()
return 0
-/atom/proc/get_thermal_mass_coefficient()
+/atom/proc/get_thermal_mass_coefficient(delta)
return 1
/atom/proc/spark_act(obj/effect/sparks/sparks)
@@ -1003,5 +1005,15 @@
return required_dexterity
/atom/proc/immune_to_floor_hazards()
- return !simulated
-
+ return !simulated || !has_gravity()
+/// The punctuation used for the "That's an X." string.
+/atom/proc/get_examine_punctuation()
+ // Could theoretically check if reagents in a coating are 'dangerous' or 'suspicious' (blood, acid, etc)
+ // in an override, but that'd require setting such a var on a bunch of materials and I'm lazy.
+ return blood_color ? "!" : "."
+
+/// The prefix that goes before the atom name on examine.
+/atom/proc/get_examine_prefix()
+ if(blood_color)
+ return FONT_COLORED(blood_color, "stained")
+ return null
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 9c481be8d469..918c145cce6b 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -49,7 +49,7 @@
//call this proc to start space drifting
/atom/movable/proc/space_drift(direction)//move this down
- if(!loc || direction & (UP|DOWN) || Process_Spacemove(0))
+ if(!loc || direction & (UP|DOWN) || is_space_movement_permitted() != SPACE_MOVE_FORBIDDEN)
inertia_dir = 0
inertia_ignore = null
return 0
@@ -62,29 +62,22 @@
return 1
//return 0 to space drift, 1 to stop, -1 for mobs to handle space slips
-/atom/movable/proc/Process_Spacemove(var/allow_movement)
+/atom/movable/proc/is_space_movement_permitted(allow_movement = FALSE)
if(!simulated)
- return 1
-
+ return SPACE_MOVE_PERMITTED
if(has_gravity())
- return 1
-
+ return SPACE_MOVE_PERMITTED
if(length(grabbed_by))
- return 1
-
+ return SPACE_MOVE_PERMITTED
if(throwing)
- return 1
-
+ return SPACE_MOVE_PERMITTED
if(anchored)
- return 1
-
+ return SPACE_MOVE_PERMITTED
if(!isturf(loc))
- return 1
-
+ return SPACE_MOVE_PERMITTED
if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier
- return -1
-
- return 0
+ return SPACE_MOVE_SUPPORTED
+ return SPACE_MOVE_FORBIDDEN
/atom/movable/attack_hand(mob/user)
// Unbuckle anything buckled to us.
@@ -502,7 +495,7 @@
return 0
return max(ITEM_SIZE_MIN, get_object_size()) * THERMAL_MASS_CONSTANT
-/atom/movable/get_thermal_mass_coefficient()
+/atom/movable/get_thermal_mass_coefficient(delta)
if(!simulated)
return 0
return (max(ITEM_SIZE_MIN, MOB_SIZE_MIN) * THERMAL_MASS_CONSTANT) / get_thermal_mass()
@@ -566,7 +559,7 @@
appearance_flags &= ~remove_flags
return old_appearance != appearance_flags
-/atom/movable/proc/end_throw()
+/atom/movable/proc/end_throw(datum/thrownthing/TT)
throwing = null
/atom/movable/proc/reset_movement_delay()
diff --git a/code/game/atoms_temperature.dm b/code/game/atoms_temperature.dm
index 2beb585761a0..099b566cf783 100644
--- a/code/game/atoms_temperature.dm
+++ b/code/game/atoms_temperature.dm
@@ -21,7 +21,7 @@
if(user && heated_by)
visible_message(SPAN_NOTICE("\The [user] carefully heats \the [src] with \the [heated_by]."))
// Update our own heat.
- var/altered_temp = max(temperature + (get_thermal_mass_coefficient() * diff_temp * (heated_by ? heated_by.get_manual_heat_source_coefficient() : 1)), 0)
+ var/altered_temp = max(temperature + (get_thermal_mass_coefficient(diff_temp) * diff_temp * (heated_by ? heated_by.get_manual_heat_source_coefficient() : 1)), 0)
ADJUST_ATOM_TEMPERATURE(src, min(adjust_temp, altered_temp))
return TRUE
@@ -51,11 +51,11 @@
// Get our ambient temperature if possible.
var/adjust_temp = get_ambient_temperature()
- var/thermal_mass_coefficient = get_thermal_mass_coefficient() * get_ambient_temperature_coefficient()
+ var/diff_temp = adjust_temp - temperature
+ var/thermal_mass_coefficient = get_thermal_mass_coefficient(diff_temp) * get_ambient_temperature_coefficient()
// Determine if our temperature needs to change.
var/old_temp = temperature
- var/diff_temp = adjust_temp - temperature
if(abs(diff_temp) >= (thermal_mass_coefficient * ATOM_TEMPERATURE_EQUILIBRIUM_THRESHOLD))
var/altered_temp = max(temperature + (thermal_mass_coefficient * diff_temp), 0)
ADJUST_ATOM_TEMPERATURE(src, (diff_temp > 0) ? min(adjust_temp, altered_temp) : max(adjust_temp, altered_temp))
diff --git a/code/game/machinery/_machines_base/machinery.dm b/code/game/machinery/_machines_base/machinery.dm
index d6fafc99f1e5..cff48f06503d 100644
--- a/code/game/machinery/_machines_base/machinery.dm
+++ b/code/game/machinery/_machines_base/machinery.dm
@@ -240,6 +240,9 @@ Class Procs:
/obj/machinery/CouldNotUseTopic(var/mob/user)
user.unset_machine()
+// This must not be converted to use OnTopic.
+// mechanics_text and power_text can be done at a distance (via examination)
+// while the TOPIC_REFRESH handling must come after OnTopic has resolved in the parent call of Topic.
/obj/machinery/Topic(href, href_list, datum/topic_state/state)
if(href_list["mechanics_text"] && construct_state) // This is an OOC examine thing handled via Topic; specifically bypass all checks, but do nothing other than message to chat.
var/list/info = get_tool_manipulation_info()
@@ -254,6 +257,13 @@ Class Procs:
. = ..()
if(. == TOPIC_REFRESH)
updateUsrDialog() // Update legacy UIs to the extent possible.
+ SSnano.update_uis(src) // And our modern NanoUI ones, too.
+ update_icon() // A lot of machines like to do icon updates on refresh, so we'll handle it for them here.
+ else if(. == TOPIC_CLOSE)
+ usr.unset_machine()
+ var/datum/nanoui/open_ui = SSnano.get_open_ui(usr, src, "main")
+ if(open_ui)
+ open_ui.close()
/obj/machinery/proc/get_tool_manipulation_info()
return construct_state?.mechanics_info()
diff --git a/code/game/machinery/_machines_base/machinery_public_vars.dm b/code/game/machinery/_machines_base/machinery_public_vars.dm
index d1288ef7817b..594aa0238e02 100644
--- a/code/game/machinery/_machines_base/machinery_public_vars.dm
+++ b/code/game/machinery/_machines_base/machinery_public_vars.dm
@@ -17,7 +17,7 @@ Must be implemented by subtypes.
// Reads off the var value and returns it
/decl/public_access/public_variable/proc/access_var(datum/owner)
-// Writes to the var. Returns true if change occured, false otherwise.
+// Writes to the var. Returns true if change occurred, false otherwise.
// Subtypes shall call parent, and perform the actual write if the return value is true.
// If the var has_updates, you must never modify the var except through this proc.
/decl/public_access/public_variable/proc/write_var(datum/owner, new_value)
diff --git a/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm b/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm
index 15cc987b4060..82c1e1736196 100644
--- a/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm
+++ b/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm
@@ -169,7 +169,7 @@
/obj/item/stock_parts/subspace/filter
name = "hyperwave filter"
icon_state = "hyperwave_filter"
- desc = "A tiny device capable of filtering and converting super-intense radiowaves."
+ desc = "A tiny device capable of filtering and converting super-intense radio waves."
origin_tech = @'{"programming":4,"magnets":2}'
material = /decl/material/solid/metal/steel
matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT)
diff --git a/code/game/machinery/_machines_base/stock_parts/network_receiver.dm b/code/game/machinery/_machines_base/stock_parts/network_receiver.dm
index 644941d02cda..1b09080e57c1 100644
--- a/code/game/machinery/_machines_base/stock_parts/network_receiver.dm
+++ b/code/game/machinery/_machines_base/stock_parts/network_receiver.dm
@@ -1,4 +1,4 @@
-// A reciever that allows for non-network machines to have public vars and methods interacted with by networks
+// A receiver that allows for non-network machines to have public vars and methods interacted with by networks
/obj/item/stock_parts/network_receiver
name = "network receiver"
diff --git a/code/game/machinery/_machines_base/stock_parts/radio/stock_parts_radio.dm b/code/game/machinery/_machines_base/stock_parts/radio/stock_parts_radio.dm
index e1a967194179..9cca4b1b98a1 100644
--- a/code/game/machinery/_machines_base/stock_parts/radio/stock_parts_radio.dm
+++ b/code/game/machinery/_machines_base/stock_parts/radio/stock_parts_radio.dm
@@ -24,7 +24,7 @@
id_tag = new_tag
set_frequency(frequency, filter)
-/obj/item/stock_parts/radio/proc/get_receive_filter() // what filter should we register with to recieve updates on?
+/obj/item/stock_parts/radio/proc/get_receive_filter() // what filter should we register with to receive updates on?
return RADIO_NULL
/obj/item/stock_parts/radio/proc/set_frequency(new_frequency, new_filter)
diff --git a/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm b/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm
index e56703abc157..bd43db38d6c3 100644
--- a/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm
+++ b/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm
@@ -20,7 +20,7 @@
/obj/item/stock_parts/keyboard
name = "input controller"
- desc = "A standard part required by many machines to recieve user input."
+ desc = "A standard part required by many machines to receive user input."
icon_state = "input"
origin_tech = @'{"materials":1}'
material = /decl/material/solid/organic/plastic
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 1028e2d4098e..11d4e5c9b63b 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -667,7 +667,7 @@
var/device_id = href_list["id_tag"]
switch(href_list["command"])
if("set_external_pressure")
- var/input_pressure = input(user, "What pressure you like the system to mantain?", "Pressure Controls") as num|null
+ var/input_pressure = input(user, "What pressure you like the system to maintain?", "Pressure Controls") as num|null
if(isnum(input_pressure) && CanUseTopic(user, state))
send_signal(device_id, list(href_list["command"] = input_pressure))
return TOPIC_REFRESH
diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm
index 721eddb4ad96..65ecb25cd2e3 100644
--- a/code/game/machinery/atmo_control.dm
+++ b/code/game/machinery/atmo_control.dm
@@ -114,9 +114,6 @@
data["automation"] = automation
-/obj/machinery/computer/air_control/Process()
- ..()
-
/obj/machinery/computer/air_control/receive_signal(datum/signal/signal)
if(!signal || signal.encryption)
return
@@ -148,56 +145,56 @@
if(href_list["in_refresh_status"])
input_info = null
refreshing_input = TRUE
- signal.data = list ("tag" = input_tag, "status" = 1)
+ signal.data = list("tag" = input_tag, "status" = 1)
. = 1
if(href_list["in_toggle_injector"])
input_info = null
refreshing_input = TRUE
- signal.data = list ("tag" = input_tag, "power_toggle" = 1)
+ signal.data = list("tag" = input_tag, "power_toggle" = 1)
. = 1
if(href_list["in_set_flowrate"])
input_info = null
refreshing_input = TRUE
- input_flow_setting = input("What would you like to set the rate limit to?", "Set Volume", input_flow_setting) as num|null
+ input_flow_setting = input(user, "What would you like to set the rate limit to?", "Set Volume", input_flow_setting) as num|null
input_flow_setting = clamp(input_flow_setting, 0, ATMOS_DEFAULT_VOLUME_PUMP+500)
- signal.data = list ("tag" = input_tag, "set_volume_rate" = input_flow_setting)
+ signal.data = list("tag" = input_tag, "set_volume_rate" = input_flow_setting)
. = 1
if(href_list["in_set_max"])
input_info = null
refreshing_input = TRUE
input_flow_setting = ATMOS_DEFAULT_VOLUME_PUMP+500
- signal.data = list ("tag" = input_tag, "set_volume_rate" = input_flow_setting)
+ signal.data = list("tag" = input_tag, "set_volume_rate" = input_flow_setting)
. = 1
if(href_list["out_refresh_status"])
output_info = null
refreshing_output = TRUE
- signal.data = list ("tag" = output_tag, "status" = 1)
+ signal.data = list("tag" = output_tag, "status" = 1)
. = 1
if(href_list["out_toggle_power"])
output_info = null
refreshing_output = TRUE
- signal.data = list ("tag" = output_tag, "power_toggle" = 1, "status" = 1)
+ signal.data = list("tag" = output_tag, "power_toggle" = 1, "status" = 1)
. = 1
if(href_list["out_set_pressure"])
output_info = null
refreshing_output = TRUE
- pressure_setting = input("How much pressure would you like to output?", "Set Pressure", pressure_setting) as num|null
+ pressure_setting = input(user, "How much pressure would you like to output?", "Set Pressure", pressure_setting) as num|null
pressure_setting = clamp(pressure_setting, 0, MAX_PUMP_PRESSURE)
- signal.data = list ("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]", "status" = 1)
+ signal.data = list("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]", "status" = 1)
. = 1
if(href_list["s_out_set_pressure"])
output_info = null
refreshing_output = TRUE
- pressure_setting = input("How much pressure would you like to maintain inside the core?", "Set Core Pressure", pressure_setting) as num|null
+ pressure_setting = input(user, "How much pressure would you like to maintain inside the core?", "Set Core Pressure", pressure_setting) as num|null
pressure_setting = clamp(pressure_setting, 0, MAX_PUMP_PRESSURE)
- signal.data = list ("tag" = output_tag, "set_external_pressure" = pressure_setting, "checks" = 1, "status" = 1)
+ signal.data = list("tag" = output_tag, "set_external_pressure" = pressure_setting, "checks" = 1, "status" = 1)
. = 1
if(href_list["s_set_default"])
@@ -210,11 +207,11 @@
output_info = null
refreshing_output = TRUE
pressure_setting = MAX_PUMP_PRESSURE
- signal.data = list ("tag" = output_tag, "set_internal_pressure" = pressure_setting, "status" = 1)
+ signal.data = list("tag" = output_tag, "set_internal_pressure" = pressure_setting, "status" = 1)
. = 1
if(href_list["set_frequency"])
- var/F = input("What frequency would you like to set this to? (Decimal is added automatically)", "Adjust Frequency", frequency) as num|null
+ var/F = input(user, "What frequency would you like to set this to? (Decimal is added automatically)", "Adjust Frequency", frequency) as num|null
if(F)
frequency = F
set_frequency(F)
@@ -291,7 +288,7 @@
else
..(signal)
-/obj/machinery/computer/air_control/fuel_injection/Topic(href, href_list)
+/obj/machinery/computer/air_control/fuel_injection/OnTopic(mob/user, href_list, datum/topic_state/state)
if((. = ..()))
return
diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm
index 4dd3caeb6fd1..3b0ef569f603 100644
--- a/code/game/machinery/atmoalter/meter.dm
+++ b/code/game/machinery/atmoalter/meter.dm
@@ -1,6 +1,6 @@
/obj/machinery/meter
name = "meter"
- desc = "A gas flow meter."
+ desc = "A meter that monitors gas composition, pressure, and temperature in the attached pipe."
icon = 'icons/obj/meter.dmi'
icon_state = "meterX"
var/atom/target = null //A pipe for the base type
diff --git a/code/game/machinery/computer/area_atmos.dm b/code/game/machinery/computer/area_atmos.dm
index f287fbbc0b3f..d6b82399d7ce 100644
--- a/code/game/machinery/computer/area_atmos.dm
+++ b/code/game/machinery/computer/area_atmos.dm
@@ -88,25 +88,25 @@
show_browser(user, "[dat]", "window=miningshuttle;size=400x400")
status = ""
-/obj/machinery/computer/area_atmos/Topic(href, href_list)
- if(..())
+/obj/machinery/computer/area_atmos/OnTopic(mob/user, href_list)
+ if((. = ..()))
return
- usr.set_machine(src)
-
if(href_list["scan"])
scanscrubbers()
+ return TOPIC_REFRESH
else if(href_list["toggle"])
var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber = locate(href_list["scrub"])
if(!validscrubber(scrubber))
- spawn(20)
+ spawn(2 SECONDS)
status = "ERROR: Couldn't connect to scrubber! (timeout)"
connectedscrubbers -= scrubber
- src.updateUsrDialog()
- return
+ updateUsrDialog()
+ return TOPIC_REFRESH
scrubber.update_use_power(text2num(href_list["toggle"]) ? POWER_USE_ACTIVE : POWER_USE_IDLE)
+ return TOPIC_REFRESH
/obj/machinery/computer/area_atmos/proc/validscrubber(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber)
if(!isobj(scrubber) || get_dist(scrubber.loc, src.loc) > src.range || scrubber.loc.z != src.loc.z)
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index 0c145faa9de9..da48f9028515 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -7,15 +7,18 @@
light_color = "#00b000"
var/hack_icon = "error"
- var/noserver = "ALERT: No server detected."
- var/incorrectkey = "ALERT: Incorrect decryption key!"
- var/defaultmsg = "Welcome. Please select an option."
- var/rebootmsg = "%$&(£: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!"
- var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message
- var/hacking = 0 // Is it being hacked into by the AI/Cyborg
- var/emag = 0 // When it is emagged.
+ var/const/noserver = "ALERT: No server detected."
+ var/const/incorrectkey = "ALERT: Incorrect decryption key!"
+ var/const/defaultmsg = "Welcome. Please select an option."
+ var/const/rebootmsg = "%$&(£: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!"
+
+ var/const/SCREEN_MAIN_MENU = 0
+ var/const/SCREEN_MESSAGE_LOGS = 1
+ var/const/SCREEN_HACKING = 2
+ var/screen = SCREEN_MAIN_MENU
+ var/hacking = FALSE // Is it being hacked into by a silicon?
var/message = "System bootup complete. Please select an option." // The message that shows on the main menu.
- var/auth = 0 // Are they authenticated?
+ var/auth = FALSE // Are they authenticated?
var/obj/machinery/network/message_server/tracking_linked_server
/obj/machinery/computer/message_monitor/Initialize()
@@ -43,7 +46,7 @@
return ..()
if(!istype(user))
return TRUE
- if(IS_SCREWDRIVER(O) && emag)
+ if(IS_SCREWDRIVER(O) && emagged)
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
to_chat(user, "It is too hot to mess with!")
return TRUE
@@ -53,11 +56,11 @@
// Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online.
// It'll take more time if there's more characters in the password.
- if(!emag && operable())
+ if(!emagged && operable())
var/obj/machinery/network/message_server/linked_server = get_message_server()
if(linked_server)
- emag = 1
- screen = 2
+ emagged = TRUE
+ screen = SCREEN_HACKING
spark_at(src, amount = 5)
var/obj/item/paper/monitorkey/MK = new(loc)
// Will help make emagging the console not so easy to get away with.
@@ -70,7 +73,7 @@
to_chat(user, "A no server error appears on the screen.")
/obj/machinery/computer/message_monitor/on_update_icon()
- if(emag || hacking)
+ if(emagged || hacking)
icon_screen = hack_icon
else
icon_screen = initial(icon_screen)
@@ -82,10 +85,16 @@
/obj/machinery/computer/message_monitor/interact(var/mob/living/user)
//If the computer is being hacked or is emagged, display the reboot message.
- if(hacking || emag)
+ if(hacking || emagged)
message = rebootmsg
var/obj/machinery/network/message_server/linked_server = get_message_server()
+ // This must run early so that changing the message actually works.
+ if(hacking || emagged)
+ screen = SCREEN_HACKING
+ else if(!auth || !linked_server || (linked_server.stat & (NOPOWER|BROKEN)))
+ message = auth ? noserver : message
+ screen = SCREEN_MAIN_MENU
var/list/dat = list()
dat += "
Message Monitor Console"
dat += "Message Monitor Console
"
@@ -98,16 +107,9 @@
dat += " \[Unauthenticated\] /"
dat += " Server Power: [linked_server?.active ? "\[On\]":"\[Off\]"]
"
- if(hacking || emag)
- screen = 2
- else if(!auth || !linked_server || (linked_server.stat & (NOPOWER|BROKEN)))
- if(!linked_server || (linked_server.stat & (NOPOWER|BROKEN)))
- message = noserver
- screen = 0
-
switch(screen)
//Main menu
- if(0)
+ if(SCREEN_MAIN_MENU)
// = TAB
var/i = 0
dat += " [++i]. Link To A Server"
@@ -123,10 +125,32 @@
if((isAI(user) || isrobot(user)) && player_is_antag(user.mind))
//Malf/Traitor AIs can bruteforce into the system to gain the Key.
dat += "*&@#. Bruteforce Key"
-
+ //Request Console Logs
+ if(SCREEN_MESSAGE_LOGS)
+ var/index = 0
+ /* data_rc_msg
+ X - 5%
+ var/rec_dpt = "Unspecified" //name of the person - 15%
+ var/send_dpt = "Unspecified" //name of the sender- 15%
+ var/message = "Blank" //transferred message - 300px
+ var/stamp = "Unstamped" - 15%
+ var/id_auth = "Unauthenticated" - 15%
+ var/priority = "Normal" - 10%
+ */
+ dat += "Back - Refresh
"
+ dat += {"| X | Sending Dep. | Receiving Dep. |
+ Message | Stamp | ID Auth. | Priority. |
"}
+ for(var/datum/data_rc_msg/rc in linked_server.rc_msgs)
+ if(++index > 3000)
+ break
+ // Del - Sender - Recepient - Message
+ // X - Al Green - Your Mom - WHAT UP!?
+ dat += {"| X | [rc.send_dpt] |
+ [rc.rec_dpt] | [rc.message] | [rc.stamp] | [rc.id_auth] | [rc.priority] |
"}
+ dat += "
"
//Hacking screen.
- if(2)
- if(isAI(user) || isrobot(user))
+ if(SCREEN_HACKING)
+ if(issilicon(user))
dat += "Brute-forcing for server key.
It will take 20 seconds for every character that the password has."
dat += "In the meantime, this console can reveal your true intentions if you let someone access it. Make sure no humans enter the room during that time."
else
@@ -166,35 +190,7 @@
10010000001100100011101010111001001101001011011100110011
10010000001110100011010000110000101110100001000000111010
001101001011011010110010100101110"}
-
- //Request Console Logs
- if(4)
-
- var/index = 0
- /* data_rc_msg
- X - 5%
- var/rec_dpt = "Unspecified" //name of the person - 15%
- var/send_dpt = "Unspecified" //name of the sender- 15%
- var/message = "Blank" //transferred message - 300px
- var/stamp = "Unstamped" - 15%
- var/id_auth = "Unauthenticated" - 15%
- var/priority = "Normal" - 10%
- */
- dat += "Back - Refresh
"
- dat += {"| X | Sending Dep. | Receiving Dep. |
- Message | Stamp | ID Auth. | Priority. |
"}
- for(var/datum/data_rc_msg/rc in linked_server.rc_msgs)
- index++
- if(index > 3000)
- break
- // Del - Sender - Recepient - Message
- // X - Al Green - Your Mom - WHAT UP!?
- dat += {"| X | [rc.send_dpt] |
- [rc.rec_dpt] | [rc.message] | [rc.stamp] | [rc.id_auth] | [rc.priority] |
"}
- dat += "
"
-
dat += ""
- message = defaultmsg
var/datum/browser/written_digital/popup = new(user, "message", "Message Monitoring Console", 700, 700)
popup.set_content(JOINTEXT(dat))
popup.open()
@@ -207,15 +203,16 @@
else
var/currentKey = linked_server.decryptkey
to_chat(user, "Brute-force completed! The key is '[currentKey]'.")
- src.hacking = 0
+ hacking = FALSE
update_icon()
- src.screen = 0 // Return the screen back to normal
+ screen = SCREEN_MAIN_MENU // Return the screen back to normal
+ message = defaultmsg // reset it for the next interaction
/obj/machinery/computer/message_monitor/proc/UnemagConsole()
- src.emag = 0
+ emagged = FALSE
update_icon()
-/obj/machinery/computer/message_monitor/Topic(href, href_list)
+/obj/machinery/computer/message_monitor/OnTopic(mob/user, href_list)
if((. = ..()))
return
@@ -223,19 +220,24 @@
var/obj/machinery/network/message_server/linked_server = get_message_server()
if (href_list["auth"])
if(auth)
- auth = 0
- screen = 0
+ auth = FALSE
+ screen = SCREEN_MAIN_MENU
+ message = defaultmsg // reset it for the next interaction
+ . = TOPIC_REFRESH
else
- var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
- if(dkey && dkey != "")
- if(linked_server && linked_server.decryptkey == dkey)
- auth = 1
+ var/dkey = trim(input(user, "Please enter the decryption key.") as text|null)
+ . = TOPIC_HANDLED
+ if(dkey)
+ . = TOPIC_REFRESH
+ if(linked_server?.decryptkey == dkey)
+ auth = TRUE
else
message = incorrectkey
//Turn the server on/off.
if (href_list["active"] && auth && linked_server)
linked_server.active = !linked_server.active
+ . = TOPIC_REFRESH
//Find a server
if (href_list["find"])
@@ -245,7 +247,7 @@
if((MS.z in local_zs) && !(MS.stat & (BROKEN|NOPOWER)))
local_message_servers += MS
if(length(local_message_servers) > 1)
- tracking_linked_server = input(usr,"Please select a server.", "Select a server.", null) as null|anything in local_message_servers
+ tracking_linked_server = input(user, "Please select a server.", "Select a server.", null) as null|anything in local_message_servers
message = "NOTICE: Server selected."
else if(length(local_message_servers) > 0)
tracking_linked_server = local_message_servers[1]
@@ -253,47 +255,53 @@
else
message = noserver
linked_server = get_message_server()
+ . = TOPIC_REFRESH
//Clears the request console logs - KEY REQUIRED
if (href_list["clearr"])
if(!linked_server || (linked_server.stat & (NOPOWER|BROKEN)))
message = noserver
+ . = TOPIC_REFRESH
else if(auth)
linked_server.rc_msgs = list()
message = "NOTICE: Logs cleared."
+ . = TOPIC_REFRESH
//Change the password - KEY REQUIRED
if (href_list["pass"])
if(!linked_server || (linked_server.stat & (NOPOWER|BROKEN)))
message = noserver
- else
- if(auth)
- var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
- if(dkey && dkey != "")
- if(linked_server.decryptkey == dkey)
- var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):"))
- if(length(newkey) <= 3)
- message = "NOTICE: Decryption key too short!"
- else if(length(newkey) > 16)
- message = "NOTICE: Decryption key too long!"
- else if(newkey && newkey != "")
- linked_server.decryptkey = newkey
- message = "NOTICE: Decryption key set."
- else
- message = incorrectkey
+ . = TOPIC_REFRESH
+ else if(auth)
+ var/dkey = trim(input(user, "Please enter the decryption key.") as text|null)
+ . = TOPIC_HANDLED
+ if(dkey)
+ . = TOPIC_REFRESH
+ if(linked_server.decryptkey == dkey)
+ var/newkey = trim(input(user,"Please enter the new key (3 - 16 characters max):"))
+ if(length(newkey) <= 3)
+ message = "NOTICE: Decryption key too short!"
+ else if(length(newkey) > 16)
+ message = "NOTICE: Decryption key too long!"
+ else if(newkey && newkey != "")
+ linked_server.decryptkey = newkey
+ message = "NOTICE: Decryption key set."
+ else
+ message = incorrectkey
//Hack the Console to get the password
if (href_list["hack"])
- if((isAI(usr) || isrobot(usr)) && player_is_antag(usr.mind))
- src.hacking = 1
- src.screen = 2
- update_icon()
+ if(issilicon(user) && player_is_antag(user.mind))
+ hacking = TRUE
+ screen = SCREEN_HACKING
+ . = TOPIC_REFRESH
//Time it takes to bruteforce is dependant on the password length.
- addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/computer/message_monitor, BruteForceConsole), usr, linked_server), 100*length(linked_server.decryptkey))
+ addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/computer/message_monitor, BruteForceConsole), user, linked_server), 10 SECONDS * length(linked_server.decryptkey))
//Delete the request console log.
if (href_list["deleter"])
- //Are they on the view logs screen?
- if(screen == 4)
+ . = TOPIC_REFRESH
+ //Make sure they're still on the view logs screen.
+ if(screen == SCREEN_MESSAGE_LOGS)
if(!linked_server || (linked_server.stat & (NOPOWER|BROKEN)))
message = noserver
else //if(istype(href_list["delete"], /datum/data_pda_msg))
@@ -304,14 +312,16 @@
if(href_list["viewr"])
if(linked_server == null || (linked_server.stat & (NOPOWER|BROKEN)))
message = noserver
- else
- if(auth)
- src.screen = 4
+ . = TOPIC_REFRESH
+ else if(auth)
+ screen = SCREEN_MESSAGE_LOGS
+ . = TOPIC_REFRESH
if (href_list["back"])
- src.screen = 0
-
- return interact(usr)
+ screen = SCREEN_MAIN_MENU
+ message = defaultmsg // reset it for the next interaction
+ . = TOPIC_REFRESH
+ // don't call interact() here, let the prior Topic() call do that via our TOPIC_REFRESH return value
/obj/machinery/computer/message_monitor/proc/BruteForceConsole(var/mob/user, var/decrypting)
var/obj/machinery/network/message_server/linked_server = get_message_server()
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index 84a1b64504fa..b3903352d555 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -50,8 +50,8 @@
show_browser(user, dat, "window=computer;size=400x500")
onclose(user, "computer")
-/obj/machinery/computer/prisoner/Topic(href, href_list)
- if(..())
+/obj/machinery/computer/prisoner/OnTopic(mob/user, href_list)
+ if((. = ..()))
return
. = TOPIC_REFRESH
@@ -68,15 +68,15 @@
if(I) I.activate(10)
else if(href_list["lock"])
- if(src.allowed(usr))
+ if(allowed(user))
screen = !screen
else
- to_chat(usr, "Unauthorized Access.")
+ to_chat(user, "Unauthorized Access.")
else if(href_list["warn"])
- var/warning = sanitize(input(usr,"Message:","Enter your message here!",""))
- if(!warning) return
+ var/warning = sanitize(input(user,"Message:","Enter your message here!",""))
+ if(!warning) return TOPIC_HANDLED
var/obj/item/implant/I = locate(href_list["warn"])
- if((I)&&(I.imp_in))
+ if(I?.imp_in)
var/mob/living/R = I.imp_in
to_chat(R, "You hear a voice in your head saying: '[warning]'")
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 1be24240e750..b845e67c52b3 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -49,6 +49,8 @@
normalspeed = 1
var/hasShocked = 0 //Prevents multiple shocks from happening
var/secured_wires = FALSE
+ /// This state overrides the density-based state while we're doing animations and such.
+ var/animating_state = 0
var/open_sound_powered = 'sound/machines/airlock_open.ogg'
var/open_sound_unpowered = 'sound/machines/airlock_open_force.ogg'
@@ -124,7 +126,7 @@ About the new airlock wires panel:
*/
/obj/machinery/door/airlock/bumpopen(mob/living/user) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite
- if(!issilicon(usr))
+ if(!issilicon(user))
if(src.isElectrified())
if(!src.justzap)
if(src.shock(user, 100))
@@ -290,29 +292,22 @@ About the new airlock wires panel:
else
return 0
-/obj/machinery/door/airlock/on_update_icon(state=0, override=0)
-
+/obj/machinery/door/airlock/on_update_icon()
if(set_dir_on_update)
if((connections & (NORTH|SOUTH)) == (NORTH|SOUTH))
set_dir(EAST)
else if ((connections & (EAST|WEST)) == (EAST|WEST))
set_dir(SOUTH)
+ var/state = animating_state || (density ? AIRLOCK_CLOSED : AIRLOCK_OPEN)
switch(state)
- if(0)
- if(density)
- icon_state = icon_state_closed
- state = AIRLOCK_CLOSED
- else
- icon_state = icon_state_open
- state = AIRLOCK_OPEN
- if(AIRLOCK_OPEN)
- icon_state = icon_state_open
if(AIRLOCK_CLOSED)
icon_state = icon_state_closed
- if(AIRLOCK_OPENING, AIRLOCK_CLOSING, AIRLOCK_EMAG, AIRLOCK_DENY)
- icon_state = ""
-
+ if(AIRLOCK_OPEN)
+ icon_state = icon_state_open
+ else
+ icon_state = "" // this should never happen, this is just what the old code did in this case
+ animating_state = null
set_airlock_overlays(state)
/obj/machinery/door/airlock/proc/set_airlock_overlays(state)
@@ -432,18 +427,21 @@ About the new airlock wires panel:
if("opening")
set_airlock_overlays(AIRLOCK_OPENING)
flick("opening", src)//[stat ? "_stat":]
- update_icon(AIRLOCK_OPEN)
+ animating_state = AIRLOCK_OPEN
+ update_icon()
if("closing")
set_airlock_overlays(AIRLOCK_CLOSING)
flick("closing", src)
- update_icon(AIRLOCK_CLOSED)
+ animating_state = AIRLOCK_CLOSED
+ update_icon()
if("deny")
set_airlock_overlays(AIRLOCK_DENY)
if(density && arePowerSystemsOn())
flick("deny", src)
if(speaker)
playsound(loc, open_failure_access_denied, 50, 0)
- update_icon(AIRLOCK_CLOSED)
+ animating_state = AIRLOCK_CLOSED
+ update_icon()
if("emag")
set_airlock_overlays(AIRLOCK_EMAG)
if(density && arePowerSystemsOn())
@@ -536,7 +534,7 @@ About the new airlock wires panel:
src.attack_ai(user)
/obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if (src.isElectrified())
+ if (isElectrified())
if (istype(mover, /obj/item))
var/obj/item/i = mover
if(i.material && i.material.conductive)
@@ -544,9 +542,9 @@ About the new airlock wires panel:
return ..()
/obj/machinery/door/airlock/physical_attack_hand(mob/user)
- if(!issilicon(usr))
- if(src.isElectrified())
- if(src.shock(user, 100))
+ if(!issilicon(user))
+ if(isElectrified())
+ if(shock(user, 100))
return TRUE
. = ..()
@@ -566,63 +564,77 @@ About the new airlock wires panel:
return ..()
-/obj/machinery/door/airlock/Topic(href, href_list)
- if(..())
- return 1
+/obj/machinery/door/airlock/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
var/activate = text2num(href_list["activate"])
switch (href_list["command"])
if("idscan")
set_idscan(activate, 1)
+ . = TOPIC_REFRESH
if("main_power")
if(!main_power_lost_until)
- src.loseMainPower()
+ loseMainPower()
+ . = TOPIC_REFRESH
if("backup_power")
if(!backup_power_lost_until)
- src.loseBackupPower()
+ loseBackupPower()
+ . = TOPIC_REFRESH
if("bolts")
- if(src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
- to_chat(usr, "The door bolt control wire is cut - Door bolts permanently dropped.")
- else if(activate && src.lock())
- to_chat(usr, "The door bolts have been dropped.")
- else if(!activate && src.unlock())
- to_chat(usr, "The door bolts have been raised.")
+ if(isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
+ to_chat(user, "The door bolt control wire is cut - Door bolts permanently dropped.")
+ . = TOPIC_HANDLED
+ else if(activate && lock())
+ to_chat(user, "The door bolts have been dropped.")
+ . = TOPIC_REFRESH
+ else if(!activate && unlock())
+ to_chat(user, "The door bolts have been raised.")
+ . = TOPIC_REFRESH
if("electrify_temporary")
electrify(30 * activate, 1)
+ . = TOPIC_REFRESH
if("electrify_permanently")
electrify(-1 * activate, 1)
+ . = TOPIC_REFRESH
if("open")
- if(src.welded)
- to_chat(usr, text("The airlock has been welded shut!"))
- else if(src.locked)
- to_chat(usr, text("The door bolts are down!"))
+ if(welded)
+ to_chat(user, text("The airlock has been welded shut!"))
+ . = TOPIC_HANDLED
+ else if(locked)
+ to_chat(user, text("The door bolts are down!"))
+ . = TOPIC_HANDLED
else if(activate && density)
open()
+ . = TOPIC_REFRESH
else if(!activate && !density)
close()
+ . = TOPIC_REFRESH
if("safeties")
set_safeties(!activate, 1)
if("timing")
// Door speed control
if(src.isWireCut(AIRLOCK_WIRE_SPEED))
- to_chat(usr, text("The timing wire is cut - Cannot alter timing."))
+ to_chat(user, text("The timing wire is cut - Cannot alter timing."))
+ . = TOPIC_HANDLED
else if (activate && src.normalspeed)
- normalspeed = 0
+ normalspeed = FALSE
+ . = TOPIC_REFRESH
else if (!activate && !src.normalspeed)
- normalspeed = 1
+ normalspeed = TRUE
+ . = TOPIC_REFRESH
if("lights")
// Lights
- if(src.isWireCut(AIRLOCK_WIRE_LIGHT))
- to_chat(usr, "The lights wire is cut - The door lights are permanently disabled.")
+ if(isWireCut(AIRLOCK_WIRE_LIGHT))
+ to_chat(user, "The lights wire is cut - The door lights are permanently disabled.")
else if (!activate && src.lights)
lights = 0
- to_chat(usr, "The door lights have been disabled.")
+ . = TOPIC_REFRESH
+ to_chat(user, "The door lights have been disabled.")
else if (activate && !src.lights)
lights = 1
- to_chat(usr, "The door lights have been enabled.")
-
- update_icon()
- return 1
+ . = TOPIC_REFRESH
+ to_chat(user, "The door lights have been enabled.")
//returns 1 on success, 0 on failure
/obj/machinery/door/airlock/proc/cut_bolts(var/obj/item/item, var/mob/user)
diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm
index 6533978f8529..dbca57d4ca78 100644
--- a/code/game/machinery/doors/airlock_electronics.dm
+++ b/code/game/machinery/doors/airlock_electronics.dm
@@ -17,7 +17,7 @@
var/secure = 0 //if set, then wires will be randomized and bolts will drop if the door is broken
/obj/item/stock_parts/circuitboard/airlock_electronics/secure
name = "secure airlock electronics"
- desc = "designed to be somewhat more resistant to hacking than standard electronics."
+ desc = "Airlock control electronics, designed to be somewhat more resistant to hacking than standard electronics."
origin_tech = @'{"programming":2}'
secure = TRUE
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index fab7e5836fe0..d6e1916fb871 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -10,7 +10,7 @@
/obj/machinery/door/firedoor
name = "emergency shutter"
- desc = "Emergency air-tight shutters, capable of sealing off breached areas."
+ desc = "Emergency airtight shutters, capable of sealing off breached areas."
icon = 'icons/obj/doors/hazard/door.dmi'
var/panel_file = 'icons/obj/doors/hazard/panel.dmi'
var/welded_file = 'icons/obj/doors/hazard/welded.dmi'
diff --git a/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm b/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm
index dabbb7680fbb..66aa8d5c057c 100644
--- a/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm
+++ b/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm
@@ -1,7 +1,7 @@
///Provides remote access to a controller (since they must be unique).
/obj/machinery/dummy_airlock_controller
name = "remote airlock control terminal"
- desc = "A secondary airlock control terminal meant to be subordinated to a master airlock control terminal to allow remotely controlling the later from the former."
+ desc = "A secondary airlock control terminal meant to be subordinated to a master airlock control terminal to allow remotely controlling the latter from the former."
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "airlock_control_off"
layer = ABOVE_OBJ_LAYER
diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller.dm b/code/game/machinery/embedded_controller/airlock_docking_controller.dm
index 87696262c887..026318090b40 100644
--- a/code/game/machinery/embedded_controller/airlock_docking_controller.dm
+++ b/code/game/machinery/embedded_controller/airlock_docking_controller.dm
@@ -69,7 +69,7 @@
disable_override()
else
enable_override()
- return TRUE
+ return TOPIC_REFRESH
. = ..(command)
. = airlock_program.receive_user_command(command) || . //pass along to subprograms; bypass shortcircuit
@@ -129,6 +129,7 @@
/datum/computer/file/embedded_program/airlock/docking/receive_user_command(command)
if (master_prog.undocked() || master_prog.override_enabled) //only allow the port to be used as an airlock if nothing is docked here or the override is enabled
return ..(command)
+ return TOPIC_NOACTION
/datum/computer/file/embedded_program/airlock/docking/proc/open_doors()
toggleDoor(memory["interior_status"], tag_interior_door, memory["secure"], "open")
diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm b/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm
index eca7ae8fb8ce..ea88e24d38da 100644
--- a/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm
+++ b/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm
@@ -46,8 +46,8 @@
ui.open()
ui.set_auto_update(1)
-/obj/machinery/embedded_controller/radio/docking_port_multi/Topic(href, href_list)
- return 1 // Apparently we swallow all input (this is corrected legacy code)
+/obj/machinery/embedded_controller/radio/docking_port_multi/OnTopic(user, href_list)
+ return TOPIC_HANDLED // Apparently we swallow all input (this is corrected legacy code)
diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm
index eda2a4421eb4..467b170bd841 100644
--- a/code/game/machinery/embedded_controller/airlock_program.dm
+++ b/code/game/machinery/embedded_controller/airlock_program.dm
@@ -145,7 +145,7 @@
/datum/computer/file/embedded_program/airlock/receive_user_command(command)
var/shutdown_pump = 0
- . = TRUE
+ . = TOPIC_REFRESH
switch(command)
if("cycle_ext")
//If airlock is already cycled in this direction, just toggle the doors.
@@ -188,7 +188,7 @@
toggleDoor(memory["interior_status"], tag_interior_door, !memory["secure"])
memory["secure"] = !memory["secure"]
else
- . = FALSE
+ . = TOPIC_NOACTION
if(shutdown_pump)
signalPump(tag_airpump, 0) //send a signal to stop pressurizing
diff --git a/code/game/machinery/embedded_controller/docking_program.dm b/code/game/machinery/embedded_controller/docking_program.dm
index 5a8dbad94e82..c247336a132b 100644
--- a/code/game/machinery/embedded_controller/docking_program.dm
+++ b/code/game/machinery/embedded_controller/docking_program.dm
@@ -57,7 +57,7 @@
var/response_sent = 0 //so we don't spam confirmation messages
var/override_enabled = 0 //when enabled, do not open/close doors or cycle airlocks and wait for the player to do it manually
- var/received_confirm = 0 //for undocking, whether the server has recieved a confirmation from the client
+ var/received_confirm = 0 //for undocking, whether the server has received a confirmation from the client
var/docking_codes //would only allow docking when receiving signal with these, if set
var/display_name //how would it show up on docking monitoring program, area name + coordinates if unset
@@ -78,8 +78,8 @@
/datum/computer/file/embedded_program/docking/receive_user_command(command)
if(command == "dock" || command == "undock")
- if(!tag_target) //Prevents from self destructing if no docking buddy
- return FALSE
+ if(!tag_target) //Prevents from self-destructing if no docking buddy
+ return TOPIC_NOACTION
var/datum/signal/signal = new()
signal.data["tag"] = tag_target
@@ -87,7 +87,8 @@
signal.data["recipient"] = id_tag
signal.data["code"] = docking_codes
receive_signal(signal)
- return TRUE
+ return TOPIC_REFRESH
+ return TOPIC_NOACTION
/datum/computer/file/embedded_program/docking/get_receive_filters()
return list("[id_tag]" = "primary controller")
diff --git a/code/game/machinery/embedded_controller/docking_program_multi.dm b/code/game/machinery/embedded_controller/docking_program_multi.dm
index c525e650e890..45da8d68e822 100644
--- a/code/game/machinery/embedded_controller/docking_program_multi.dm
+++ b/code/game/machinery/embedded_controller/docking_program_multi.dm
@@ -135,10 +135,11 @@
else
override_enabled = 1
broadcast_override_status()
- return TRUE
+ return TOPIC_REFRESH
- if (!docking_enabled|| override_enabled) //only allow the port to be used as an airlock if nothing is docked here or the override is enabled
+ if (!docking_enabled || override_enabled) //only allow the port to be used as an airlock if nothing is docked here or the override is enabled
return ..(command)
+ return TOPIC_NOACTION
/datum/computer/file/embedded_program/airlock/multi_docking/get_receive_filters()
return ..() + master_tag // master_tag is specifically to get "dock_status"
diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm
index 2f893501f6e8..5b622e965a41 100644
--- a/code/game/machinery/embedded_controller/embedded_controller_base.dm
+++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm
@@ -28,14 +28,14 @@
update_icon()
//spawn(5) program.process() //no, program.process sends some signals and machines respond and we here again and we lag -rastaf0
-/obj/machinery/embedded_controller/Topic(href, href_list)
- if(..())
- update_icon()
+/obj/machinery/embedded_controller/OnTopic(mob/user, href_list)
+ if((. = ..()))
return
- if(usr)
- usr.set_machine(src)
+ if(user)
+ user.set_machine(src)
if(program)
return program.receive_user_command(href_list["command"]) // Any further sanitization should be done in here.
+ return TOPIC_NOACTION
/obj/machinery/embedded_controller/Process()
if(program)
diff --git a/code/game/machinery/embedded_controller/embedded_program_base.dm b/code/game/machinery/embedded_controller/embedded_program_base.dm
index e6bcb5b68c33..31e409c555f9 100644
--- a/code/game/machinery/embedded_controller/embedded_program_base.dm
+++ b/code/game/machinery/embedded_controller/embedded_program_base.dm
@@ -16,7 +16,7 @@
return ..()
/datum/computer/file/embedded_program/proc/receive_user_command(command)
- return FALSE
+ return TOPIC_NOACTION
// Returns all filters on which you want to receive signals
/datum/computer/file/embedded_program/proc/get_receive_filters(var/for_ui = FALSE)
diff --git a/code/game/machinery/embedded_controller/simple_docking_controller.dm b/code/game/machinery/embedded_controller/simple_docking_controller.dm
index 332077048e63..52dae59a4531 100644
--- a/code/game/machinery/embedded_controller/simple_docking_controller.dm
+++ b/code/game/machinery/embedded_controller/simple_docking_controller.dm
@@ -63,7 +63,7 @@
..(signal, receive_method, receive_param)
/datum/computer/file/embedded_program/docking/simple/receive_user_command(command)
- . = TRUE
+ . = TOPIC_REFRESH
switch(command)
if("force_door")
if (override_enabled)
@@ -74,7 +74,7 @@
else
enable_override()
else
- . = FALSE
+ . = TOPIC_NOACTION
//tell the docking port to start getting ready for docking - e.g. pressurize
/datum/computer/file/embedded_program/docking/simple/prepare_for_docking()
diff --git a/code/game/machinery/embedded_controller/tin_can.dm b/code/game/machinery/embedded_controller/tin_can.dm
index d2cada82a3d4..1dcf86bdcfe4 100644
--- a/code/game/machinery/embedded_controller/tin_can.dm
+++ b/code/game/machinery/embedded_controller/tin_can.dm
@@ -44,34 +44,34 @@
..()
/datum/computer/file/embedded_program/airlock/tin_can/receive_user_command(command)
- . = TRUE
+ . = TOPIC_REFRESH
switch(command)
if("toggle_door_safety")
door_safety = !door_safety
toggleDoor(memory["exterior_status"], tag_exterior_door, door_safety)
if("evacuate_atmos")
if(state == STATE_EVACUATE)
- return
+ return TOPIC_HANDLED
state = STATE_EVACUATE
toggleDoor(memory["exterior_status"], tag_exterior_door, door_safety, "close")
- signalPump(tag_pump_out_internal, 1, 0, 0) // Interior pump, target is a vaccum
+ signalPump(tag_pump_out_internal, 1, 0, 0) // Interior pump, target is a vacuum
signalPump(tag_pump_out_external, 1, 1, 10000) // Exterior pump, target is infinite
if("fill_atmos")
if(state == STATE_FILL)
- return
+ return TOPIC_HANDLED
state = STATE_FILL
toggleDoor(memory["exterior_status"], tag_exterior_door, door_safety, "close")
signalPump(tag_pump_out_internal, 1, 1, memory["external_sensor_pressure"]) // Interior pump, target is exterior pressure
signalPump(tag_pump_out_external, 1, 0, 0) // Exterior pump, target is zero, to intake
if("seal")
if(state == STATE_SEALED)
- return
+ return TOPIC_HANDLED
state = STATE_SEALED
toggleDoor(memory["exterior_status"], tag_exterior_door, door_safety, "close")
signalPump(tag_pump_out_internal, 0)
signalPump(tag_pump_out_external, 0)
else
- . = FALSE
+ . = TOPIC_NOACTION
/datum/computer/file/embedded_program/airlock/tin_can/process()
if(door_safety)
diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm
index 47f7eab52117..26a071ea6aef 100644
--- a/code/game/machinery/igniter.dm
+++ b/code/game/machinery/igniter.dm
@@ -1,6 +1,6 @@
/obj/machinery/igniter
name = "igniter"
- desc = "It's useful for igniting flammable items."
+ desc = "A device that ignites flammable items and gases nearby when activated."
icon = 'icons/obj/machines/igniter.dmi'
icon_state = "igniter1"
var/on = 0
diff --git a/code/game/machinery/kitchen/cooking_machines/fryer.dm b/code/game/machinery/kitchen/cooking_machines/fryer.dm
index 0be1e523f110..090c58670cf6 100644
--- a/code/game/machinery/kitchen/cooking_machines/fryer.dm
+++ b/code/game/machinery/kitchen/cooking_machines/fryer.dm
@@ -1,6 +1,6 @@
/obj/machinery/cooker/fryer
name = "deep fryer"
- desc = "Deep fried everything."
+ desc = "Deep-fried everything."
icon_state = "fryer_off"
can_cook_mobs = 1
cook_type = "deep fried"
diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm
index bda3e44c704c..886b8ce43997 100644
--- a/code/game/machinery/kitchen/microwave.dm
+++ b/code/game/machinery/kitchen/microwave.dm
@@ -87,7 +87,7 @@
dispose()
return
else if(dirty==100) // The microwave is all dirty so can't be used!
- if(istype(O, /obj/item/chems/spray/cleaner) || istype(O, /obj/item/chems/glass/rag)) // If they're trying to clean it then let them
+ if(istype(O, /obj/item/chems/spray/cleaner) || istype(O, /obj/item/chems/rag)) // If they're trying to clean it then let them
user.visible_message(
SPAN_NOTICE("\The [user] starts to clean [src]."),
SPAN_NOTICE("You start to clean [src].")
diff --git a/code/game/machinery/mech_recharger.dm b/code/game/machinery/mech_recharger.dm
index bd9e8be69364..5c2449e37ed2 100644
--- a/code/game/machinery/mech_recharger.dm
+++ b/code/game/machinery/mech_recharger.dm
@@ -1,6 +1,6 @@
/obj/machinery/mech_recharger
name = "exosuit dock"
- desc = "A exosuit recharger, built into the floor."
+ desc = "An exosuit recharger, built into the floor."
icon = 'icons/mecha/mech_bay.dmi'
icon_state = "recharge_floor"
density = FALSE
diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm
index 2e01d1262171..b129241b2ea4 100644
--- a/code/game/machinery/navbeacon.dm
+++ b/code/game/machinery/navbeacon.dm
@@ -29,7 +29,7 @@ var/global/list/navbeacons = list()
navbeacons += src
/obj/machinery/navbeacon/hide(var/intact)
- set_invisibility(intact ? 101 : 0)
+ set_invisibility(intact ? INVISIBILITY_ABSTRACT : INVISIBILITY_NONE)
update_icon()
/obj/machinery/navbeacon/on_update_icon()
@@ -73,100 +73,80 @@ var/global/list/navbeacons = list()
var/ai = isAI(user)
var/turf/T = loc
if(!T.is_plating())
- return // prevent intraction when T-scanner revealed
+ return // prevent intraction when T-scanner revealed
- if(!open && !ai) // can't alter controls if not open, unless you're an AI
+ if(!open && !ai) // can't alter controls if not open, unless you're an AI
to_chat(user, "The beacon's control cover is closed.")
return
- var/t
-
- if(locked && !ai)
- t = {"Navigation Beacon
-(swipe card to unlock controls)
-Location: [location ? location : "(none)"]
-Transponder Codes:"}
-
- for(var/key in codes)
- t += "- [key] ... [codes[key]]"
- t+= "
"
-
- else
-
- t = {"Navigation Beacon
-(swipe card to lock controls)
-Location: [location ? location : "(none)"]
-Transponder Codes:"}
-
- for(var/key in codes)
- t += "- [key] ... [codes[key]]"
- t += " (edit)"
- t += " (delete)
"
- t += "(add new)
"
- t+= "
"
-
- show_browser(user, t, "window=navbeacon")
+ var/restricted = locked && !ai
+ var/list/dat = list({"Navigation Beacon
+(swipe card to [locked ? "unlock" : "lock"] controls)
+Location: [restricted ? "" : ""][location ? location : "(none)"][restricted ? "" : ""]
+Transponder Codes:"})
+
+ for(var/key in codes)
+ dat += "- [key] ... [codes[key]]"
+ if(!restricted)
+ dat += " (edit)"
+ dat += " (delete)
"
+ if(!restricted)
+ dat += "(add new)
"
+ dat += "
"
+
+ show_browser(user, JOINTEXT(dat), "window=navbeacon")
onclose(user, "navbeacon")
return
-/obj/machinery/navbeacon/Topic(href, href_list)
- ..()
- if (usr.stat)
+/obj/machinery/navbeacon/OnTopic(mob/user, href_list, datum/topic_state/state)
+ if((. = ..()))
return
- if ((in_range(src, usr) && isturf(src.loc)) || (issilicon(usr)))
- if(open && !locked)
- usr.set_machine(src)
-
- if(href_list["locedit"])
- var/newloc = sanitize(input("Enter New Location", "Navigation Beacon", location) as text|null)
- if(newloc)
- location = newloc
- updateDialog()
-
- else if(href_list["edit"])
- var/codekey = href_list["code"]
+ if(!open || locked)
+ return TOPIC_NOACTION
- var/newkey = input("Enter Transponder Code Key", "Navigation Beacon", codekey) as text|null
- if(!newkey)
- return
+ if(href_list["locedit"])
+ var/newloc = sanitize(input(user, "Enter New Location", "Navigation Beacon", location) as text|null)
+ if(newloc)
+ location = newloc
+ return TOPIC_REFRESH
- var/codeval = codes[codekey]
- var/newval = input("Enter Transponder Code Value", "Navigation Beacon", codeval) as text|null
- if(!newval)
- newval = codekey
- return
+ else if(href_list["edit"])
+ var/codekey = href_list["code"]
- codes.Remove(codekey)
- codes[newkey] = newval
+ var/newkey = sanitize(input(user, "Enter Transponder Code Key", "Navigation Beacon", codekey) as text|null)
+ if(!newkey)
+ return TOPIC_HANDLED
- updateDialog()
+ var/codeval = codes[codekey]
+ var/newval = sanitize(input(user, "Enter Transponder Code Value", "Navigation Beacon", codeval || "1") as text|null)
+ if(!newval)
+ return TOPIC_HANDLED
- else if(href_list["delete"])
- var/codekey = href_list["code"]
- codes.Remove(codekey)
- updateDialog()
+ codes -= codekey
+ codes[newkey] = newval
+ return TOPIC_REFRESH
- else if(href_list["add"])
+ else if(href_list["delete"])
+ var/codekey = href_list["code"]
+ codes -= codekey
+ return TOPIC_REFRESH
- var/newkey = input("Enter New Transponder Code Key", "Navigation Beacon") as text|null
- if(!newkey)
- return
+ else if(href_list["add"])
- var/newval = input("Enter New Transponder Code Value", "Navigation Beacon") as text|null
- if(!newval)
- newval = "1"
- return
+ var/newkey = sanitize(input(user, "Enter New Transponder Code Key", "Navigation Beacon") as text|null)
+ if(!newkey)
+ return TOPIC_HANDLED
- if(!codes)
- codes = new()
+ var/newval = sanitize(input(user, "Enter New Transponder Code Value", "Navigation Beacon", "1") as text|null)
+ if(!newval)
+ return TOPIC_HANDLED
- codes[newkey] = newval
-
- updateDialog()
+ codes[newkey] = newval
+ return TOPIC_REFRESH
/obj/machinery/navbeacon/Destroy()
- navbeacons.Remove(src)
- . = ..()
+ global.navbeacons -= src
+ return ..()
// Patrol beacon types below. So many.
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index 50cf312569bd..20c88ea60823 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -112,42 +112,59 @@ var/global/list/allCasters = list() //Global list that will contain reference to
desc = "A standard newsfeed handler. All the news you absolutely have no use for, in one place!"
icon = 'icons/obj/terminals.dmi'
icon_state = "newscaster_normal"
- //var/list/datum/feed_channel/channel_list = list() //This list will contain the names of the feed channels. Each name will refer to a data region where the messages of the feed channels are stored.
- //OBSOLETE: We're now using a global news network
- var/screen = 0 //Or maybe I'll make it into a list within a list afterwards... whichever I prefer, go fuck yourselves :3
- // 0 = welcome screen - main menu
- // 1 = view feed channels
- // 2 = create feed channel
- // 3 = create feed story
- // 4 = feed story submited sucessfully
- // 5 = feed channel created successfully
- // 6 = ERROR: Cannot create feed story
- // 7 = ERROR: Cannot create feed channel
- // 8 = print newspaper
- // 9 = viewing channel feeds
- // 10 = censor feed story
- // 11 = censor feed channel
- //Holy shit this is outdated, made this when I was still starting newscasters :3
+ var/const/SCREEN_WELCOME = 0
+ var/const/SCREEN_VIEW_CHANNELS = 1
+ var/const/SCREEN_CREATE_CHANNEL = 2
+ var/const/SCREEN_CREATE_STORY = 3
+ var/const/SCREEN_STORY_SUBMITTED = 4
+ var/const/SCREEN_CHANNEL_SUBMITTED = 5
+ var/const/SCREEN_STORY_FAILED = 6
+ var/const/SCREEN_CHANNEL_FAILED = 7
+ var/const/SCREEN_CHOOSE_PRINT = 8
+ var/const/SCREEN_VIEW_STORIES = 9
+ var/const/SCREEN_CENSOR_STORY = 10
+ var/const/SCREEN_CENSOR_CHANNEL = 11
+ var/const/SCREEN_PICK_CENSOR_CHANNEL = 12
+ var/const/SCREEN_PICK_CENSOR_STORY = 13
+ var/const/SCREEN_MAKE_WANTED_ISSUE = 14
+ var/const/SCREEN_WANTED_CONFIRMED = 15
+ var/const/SCREEN_WANTED_FAILED = 16
+ var/const/SCREEN_WANTED_DELETED = 17
+ var/const/SCREEN_WANTED_VIEW = 18
+ var/const/SCREEN_WANTED_EDITED = 19
+ var/const/SCREEN_PRINT_COMPLETE = 20
+ var/const/SCREEN_PRINT_FAILED = 21
+ var/screen = SCREEN_WELCOME
var/paper_remaining = 0
- var/securityCaster = 0
- // 0 = Caster cannot be used to issue wanted posters
- // 1 = the opposite
- var/unit_no = 0 //Each newscaster has a unit number
- //var/datum/feed_message/wanted //We're gonna use a feed_message to store data of the wanted person because fields are similar
- //var/wanted_issue = 0 //OBSOLETE
- // 0 = there's no WANTED issued, we don't need a special icon_state
- // 1 = Guess what.
- var/alert_delay = 500
- var/alert = 0
- // 0 = there hasn't been a news/wanted update in the last alert_delay
- // 1 = there has
- var/scanned_user = "Unknown" //Will contain the name of the person who currently uses the newscaster
- var/msg = ""; //Feed message
- var/datum/news_photo/photo_data = null
- var/channel_name = ""; //the feed channel which will be receiving the feed, or being created
- var/c_locked=0; //Will our new channel be locked to public submissions?
- var/hitstaken = 0 //Death at 3 hits from an item with force>=15
- var/datum/feed_channel/viewing_channel = null
+ /// (BOOL) Whether or not the newscaster can be used to create wanted issues.
+ var/securityCaster = FALSE
+ /// The unique unit number identifying a specific newscaster, useful for forensics.
+ var/unit_no = 0
+ var/alert_delay = 1 MINUTE
+ /// Whether or not the alert overlay state should be used to inform about a recent news/wanted update in the last alert_delay.
+ var/alert = FALSE
+ /// The name (based on an ID) of the user currently operating the newscaster.
+ var/scanned_user = "Unknown"
+
+ // Temporary variables used while creating a new story.
+ /// The text content of the feed message to create.
+ var/tmp/msg = "" //Feed message
+ /// The photo to attach to the news story. A wrapper for a photo object with additional metadata.
+ var/tmp/datum/news_photo/photo_data = null
+
+ // Temporary variable used while creating a new channel.
+ /// Whether or not the currently-being-created channel will be locked to public submissions.
+ var/tmp/c_locked = FALSE
+
+ // Temporary variable used for both creating a new channel and creating a new story.
+ /// The name of the feed channel to either create, or submit a new story to.
+ var/tmp/channel_name = ""
+
+ /// A hit counter that determines cosmetic damage overlays, up to 3. Currently never incremented.
+ var/hitstaken = 0
+
+ /// The channel that's currently open.
+ var/tmp/datum/feed_channel/viewing_channel = null
light_range = 0
anchored = TRUE
obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED
@@ -208,7 +225,7 @@ var/global/list/allCasters = list() //Global list that will contain reference to
src.scan_user(human_or_robot_user) //Newscaster scans you
switch(screen)
- if(0)
+ if(SCREEN_WELCOME)
dat += "Welcome to Newscasting Unit #[src.unit_no].
Interface & News networks Operational."
if(news_network.wanted_issue)
dat+= "
Read Wanted Issue"
@@ -228,7 +245,7 @@ var/global/list/allCasters = list() //Global list that will contain reference to
dat+="
Censor Feed Stories"
dat+="
Mark Feed Channel with [global.using_map.company_name] D-Notice"
dat+="
The newscaster recognises you as: [src.scanned_user]"
- if(1)
+ if(SCREEN_VIEW_CHANNELS)
dat+= "Local Feed Channels
"
if( !length(news_network.network_channels) )
dat+="No active channels found..."
@@ -239,14 +256,14 @@ var/global/list/allCasters = list() //Global list that will contain reference to
else
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : null ]
"
dat+="
Refresh"
- dat+="
Back"
- if(2)
+ dat+="
Back"
+ if(SCREEN_CREATE_CHANNEL)
dat+="Creating new Feed Channel..."
dat+="
Channel Name: [src.channel_name]
"
dat+="Channel Author: [src.scanned_user]
"
dat+="Will Accept Public Feeds: [(src.c_locked) ? ("NO") : ("YES")]
"
- dat+="
Submit
Cancel
"
- if(3)
+ dat+="
Submit
Cancel
"
+ if(SCREEN_CREATE_STORY)
dat+="Creating new Feed Message..."
dat+="
Receiving Channel: [src.channel_name]
" //MARK
dat+="Message Author: [src.scanned_user]
"
@@ -258,14 +275,14 @@ var/global/list/allCasters = list() //Global list that will contain reference to
dat+="
Delete Photo"
else
dat+="Attach Photo"
- dat+="
Submit
Cancel
"
- if(4)
+ dat+="
Submit
Cancel
"
+ if(SCREEN_STORY_SUBMITTED)
dat+="Feed story successfully submitted to [src.channel_name].
"
- dat+="
Return
"
- if(5)
+ dat+="
Return
"
+ if(SCREEN_CHANNEL_SUBMITTED)
dat+="Feed Channel [src.channel_name] created successfully.
"
- dat+="
Return
"
- if(6)
+ dat+="
Return
"
+ if(SCREEN_STORY_FAILED)
dat+="ERROR: Could not submit Feed story to Network.
"
if(src.channel_name=="")
dat+="Invalid receiving channel name.
"
@@ -274,8 +291,8 @@ var/global/list/allCasters = list() //Global list that will contain reference to
if(src.msg == "" || src.msg == "\[REDACTED\]")
dat+="Invalid message body.
"
- dat+="
Return
"
- if(7)
+ dat+="
Return
"
+ if(SCREEN_CHANNEL_FAILED)
dat+="ERROR: Could not submit Feed Channel to Network.
"
var/list/existing_authors = list()
for(var/datum/feed_channel/FC in news_network.network_channels)
@@ -296,8 +313,8 @@ var/global/list/allCasters = list() //Global list that will contain reference to
dat+="Channel name already in use.
"
if(src.scanned_user=="Unknown")
dat+="Channel author unverified.
"
- dat+="
Return
"
- if(8)
+ dat+="
Return
"
+ if(SCREEN_CHOOSE_PRINT)
var/total_num=length(news_network.network_channels)
var/active_num=total_num
var/message_num=0
@@ -309,8 +326,8 @@ var/global/list/allCasters = list() //Global list that will contain reference to
dat+="Network currently serves a total of [total_num] Feed channels, [active_num] of which are active, and a total of [message_num] Feed Stories." //TODO: CONTINUE
dat+="
Liquid Paper remaining: [(src.paper_remaining) *100 ] cm^3"
dat+="
Print Paper"
- dat+="
Cancel"
- if(9)
+ dat+="
Cancel"
+ if(SCREEN_VIEW_STORIES)
dat+="[src.viewing_channel.channel_name]: \[created by: [src.viewing_channel.author]\] \[views: [++src.viewing_channel.views]\]
"
if(src.viewing_channel.censored)
dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the [station_name()], and marked with a [global.using_map.company_name] D-Notice.
"
@@ -332,8 +349,8 @@ var/global/list/allCasters = list() //Global list that will contain reference to
dat+="
"
dat+="\[Story by [MESSAGE.author] - [MESSAGE.time_stamp]\]
"
dat+="
Refresh"
- dat+="
Back"
- if(10)
+ dat+="
Back"
+ if(SCREEN_CENSOR_STORY)
dat+="[global.using_map.company_name] Feed Censorship Tool
"
dat+="NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.
"
dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it."
@@ -343,8 +360,8 @@ var/global/list/allCasters = list() //Global list that will contain reference to
else
for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : null ]
"
- dat+="
Cancel"
- if(11)
+ dat+="
Cancel"
+ if(SCREEN_CENSOR_CHANNEL)
dat+="[global.using_map.company_name] D-Notice Handler
"
dat+="A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the [station_name()]'s"
dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed"
@@ -355,8 +372,8 @@ var/global/list/allCasters = list() //Global list that will contain reference to
for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : null ]
"
- dat+="
Back"
- if(12)
+ dat+="
Back"
+ if(SCREEN_PICK_CENSOR_STORY)
dat+="[src.viewing_channel.channel_name]: \[ created by: [src.viewing_channel.author] \]
"
dat+="[(src.viewing_channel.author=="\[REDACTED\]") ? ("Undo Author censorship") : ("Censor channel Author")]
"
@@ -367,8 +384,8 @@ var/global/list/allCasters = list() //Global list that will contain reference to
for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages)
dat+="-[MESSAGE.body]
\[[MESSAGE.message_type] by [MESSAGE.author]\]
"
dat+="[(MESSAGE.body == "\[REDACTED\]") ? ("Undo story censorship") : ("Censor story")] - [(MESSAGE.author == "\[REDACTED\]") ? ("Undo Author Censorship") : ("Censor message Author")]
"
- dat+="
Back"
- if(13)
+ dat+="
Back"
+ if(SCREEN_PICK_CENSOR_CHANNEL)
dat+="[src.viewing_channel.channel_name]: \[ created by: [src.viewing_channel.author] \]
"
dat+="Channel messages listed below. If you deem them dangerous to the [station_name()], you can Bestow a D-Notice upon the channel.
"
if(src.viewing_channel.censored)
@@ -381,8 +398,8 @@ var/global/list/allCasters = list() //Global list that will contain reference to
for(var/datum/feed_message/MESSAGE in src.viewing_channel.messages)
dat+="-[MESSAGE.body]
\[[MESSAGE.message_type] by [MESSAGE.author]\]
"
- dat+="
Back"
- if(14)
+ dat+="
Back"
+ if(SCREEN_MAKE_WANTED_ISSUE)
dat+="Wanted Issue Handler:"
var/wanted_already = 0
var/end_param = 1
@@ -409,11 +426,11 @@ var/global/list/allCasters = list() //Global list that will contain reference to
dat+="
[(wanted_already) ? ("Edit Issue") : ("Submit")]"
if(wanted_already)
dat+="
Take down Issue"
- dat+="
Cancel"
- if(15)
+ dat+="
Cancel"
+ if(SCREEN_WANTED_CONFIRMED)
dat+="Wanted issue for [src.channel_name] is now in Network Circulation.
"
- dat+="
Return
"
- if(16)
+ dat+="
Return
"
+ if(SCREEN_WANTED_FAILED)
dat+="ERROR: Wanted Issue rejected by Network.
"
if(src.channel_name=="" || src.channel_name == "\[REDACTED\]")
dat+="Invalid name for person wanted.
"
@@ -421,11 +438,11 @@ var/global/list/allCasters = list() //Global list that will contain reference to
dat+="Issue author unverified.
"
if(src.msg == "" || src.msg == "\[REDACTED\]")
dat+="Invalid description.
"
- dat+="
Return
"
- if(17)
+ dat+="
Return
"
+ if(SCREEN_WANTED_DELETED)
dat+="Wanted Issue successfully deleted from Circulation
"
- dat+="
Return
"
- if(18)
+ dat+="
Return
"
+ if(SCREEN_WANTED_VIEW)
dat+="-- STATIONWIDE WANTED ISSUE --
\[Submitted by: [news_network.wanted_issue.backup_author]\]
"
dat+="Criminal: [news_network.wanted_issue.author]
"
dat+="Description: [news_network.wanted_issue.body]
"
@@ -435,290 +452,284 @@ var/global/list/allCasters = list() //Global list that will contain reference to
dat+="
"
else
dat+="None"
- dat+="
Back
"
- if(19)
+ dat+="
Back
"
+ if(SCREEN_WANTED_EDITED)
dat+="Wanted issue for [src.channel_name] successfully edited.
"
- dat+="
Return
"
- if(20)
+ dat+="
Return
"
+ if(SCREEN_PRINT_COMPLETE)
dat+="Printing successful. Please receive your newspaper from the bottom of the machine.
"
- dat+="Return"
- if(21)
+ dat+="Return"
+ if(SCREEN_PRINT_FAILED)
dat+="Unable to print newspaper. Insufficient paper. Please notify maintenance personnel to refill machine storage.
"
- dat+="Return"
- else
- dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
+ dat+="Return"
var/processed_dat = human_or_robot_user.handle_reading_literacy(human_or_robot_user, dat, digital = TRUE)
if(processed_dat)
show_browser(human_or_robot_user, processed_dat, "window=newscaster_main;size=400x600")
onclose(human_or_robot_user, "newscaster_main")
-/obj/machinery/newscaster/Topic(href, href_list)
- if(..())
+// This really needs to be rewritten, desperately.
+// TODO: Rewrite newscasters to use files, networks, mainframes, etc. Also make it use NanoUI.
+/obj/machinery/newscaster/OnTopic(mob/user, href_list, datum/topic_state/state)
+ if((. = ..())) // already handled in parent
return
- if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && isturf(src.loc))) || (issilicon(usr)))
- usr.set_machine(src)
- if(href_list["set_channel_name"])
- src.channel_name = sanitize_safe(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", ""), MAX_LNAME_LEN)
- src.updateUsrDialog()
- //src.update_icon()
-
- else if(href_list["set_channel_lock"])
- src.c_locked = !src.c_locked
- src.updateUsrDialog()
- //src.update_icon()
-
- else if(href_list["submit_new_channel"])
- //var/list/existing_channels = list() //OBSOLETE
- var/list/existing_authors = list()
- for(var/datum/feed_channel/FC in news_network.network_channels)
- //existing_channels += FC.channel_name
- if(FC.author == "\[REDACTED\]")
- existing_authors += FC.backup_author
- else
- existing_authors +=FC.author
- var/check = 0
- for(var/datum/feed_channel/FC in news_network.network_channels)
- if(FC.channel_name == src.channel_name)
- check = 1
- break
- if(src.channel_name == "" || src.channel_name == "\[REDACTED\]" || src.scanned_user == "Unknown" || check || (src.scanned_user in existing_authors) )
- src.screen=7
- else
- var/choice = alert("Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel")
- if(choice=="Confirm")
- news_network.CreateFeedChannel(src.channel_name, src.scanned_user, c_locked)
- src.screen=5
- src.updateUsrDialog()
- //src.update_icon()
-
- else if(href_list["set_channel_receiving"])
- //var/list/datum/feed_channel/available_channels = list()
- var/list/available_channels = list()
- for(var/datum/feed_channel/F in news_network.network_channels)
- if( (!F.locked || F.author == scanned_user) && !F.censored)
- available_channels += F.channel_name
- src.channel_name = input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels
- src.updateUsrDialog()
-
- else if(href_list["set_new_message"])
- src.msg = pencode2html(sanitize(input(usr, "Write your Feed story", "Network Channel Handler", "") as message|null))
- src.updateUsrDialog()
-
- else if(href_list["set_attachment"])
- AttachPhoto(usr)
- src.updateUsrDialog()
-
- else if(href_list["submit_new_message"])
- if(src.msg =="" || src.msg=="\[REDACTED\]" || src.scanned_user == "Unknown" || src.channel_name == "" )
- src.screen=6
- else
- var/image = photo_data ? photo_data.photo : null
- SSstatistics.add_field("newscaster_stories",1)
- news_network.SubmitArticle(src.msg, src.scanned_user, src.channel_name, image, 0)
- if(photo_data)
- qdel(photo_data)
- photo_data = null
- src.screen=4
-
- src.updateUsrDialog()
-
- else if(href_list["create_channel"])
- src.screen=2
- src.updateUsrDialog()
-
- else if(href_list["create_feed_story"])
- src.screen=3
- src.updateUsrDialog()
-
- else if(href_list["menu_paper"])
- src.screen=8
- src.updateUsrDialog()
- else if(href_list["print_paper"])
- if(!src.paper_remaining)
- src.screen=21
+ // no need to do set_machine, that's done in CouldUseTopic
+ if(href_list["set_channel_name"])
+ channel_name = sanitize_safe(input(user, "Provide a Feed Channel Name", "Network Channel Handler", ""), MAX_LNAME_LEN)
+ . = TOPIC_REFRESH
+
+ else if(href_list["set_channel_lock"])
+ c_locked = !c_locked
+ . = TOPIC_REFRESH
+
+ else if(href_list["submit_new_channel"])
+ var/list/existing_authors = list()
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ if(FC.author == "\[REDACTED\]")
+ existing_authors += FC.backup_author
else
- src.print_paper()
- src.screen = 20
- src.updateUsrDialog()
-
- else if(href_list["menu_censor_story"])
- src.screen=10
- src.updateUsrDialog()
-
- else if(href_list["menu_censor_channel"])
- src.screen=11
- src.updateUsrDialog()
-
- else if(href_list["menu_wanted"])
- var/already_wanted = 0
- if(news_network.wanted_issue)
- already_wanted = 1
-
- if(already_wanted)
- src.channel_name = news_network.wanted_issue.author
- src.msg = news_network.wanted_issue.body
- src.screen = 14
- src.updateUsrDialog()
-
- else if(href_list["set_wanted_name"])
- src.channel_name = sanitize_safe(input(usr, "Provide the name of the Wanted person", "Network Security Handler", ""), MAX_LNAME_LEN)
- src.updateUsrDialog()
-
- else if(href_list["set_wanted_desc"])
- src.msg = sanitize(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", ""))
- src.updateUsrDialog()
-
- else if(href_list["submit_wanted"])
- var/input_param = text2num(href_list["submit_wanted"])
- if(src.msg == "" || src.channel_name == "" || src.scanned_user == "Unknown")
- src.screen = 16
- else
- var/choice = alert("Please confirm Wanted Issue [(input_param==1) ? ("creation.") : ("edit.")]","Network Security Handler","Confirm","Cancel")
- if(choice=="Confirm")
- if(input_param==1) //If input_param == 1 we're submitting a new wanted issue. At 2 we're just editing an existing one. See the else below
- var/datum/feed_message/WANTED = new /datum/feed_message
- WANTED.author = src.channel_name
- WANTED.body = src.msg
- WANTED.backup_author = src.scanned_user //I know, a bit wacky
- if(photo_data)
- WANTED.img = photo_data.photo.img
- news_network.wanted_issue = WANTED
- news_network.alert_readers()
- src.screen = 15
- else
- if(news_network.wanted_issue.is_admin_message)
- alert("The wanted issue has been distributed by a [global.using_map.company_name] higherup. You cannot edit it.","Ok")
- return
- news_network.wanted_issue.author = src.channel_name
- news_network.wanted_issue.body = src.msg
- news_network.wanted_issue.backup_author = src.scanned_user
- if(photo_data)
- news_network.wanted_issue.img = photo_data.photo.img
- src.screen = 19
-
- src.updateUsrDialog()
-
- else if(href_list["cancel_wanted"])
- if(news_network.wanted_issue.is_admin_message)
- alert("The wanted issue has been distributed by a [global.using_map.company_name] higherup. You cannot take it down.","Ok")
- return
- var/choice = alert("Please confirm Wanted Issue removal","Network Security Handler","Confirm","Cancel")
+ existing_authors +=FC.author
+ var/check = 0
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ if(FC.channel_name == channel_name)
+ check = 1
+ break
+ if(channel_name == "" || channel_name == "\[REDACTED\]" || scanned_user == "Unknown" || check || (scanned_user in existing_authors) )
+ screen = SCREEN_CHANNEL_FAILED
+ else
+ var/choice = alert(user, "Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel")
if(choice=="Confirm")
- news_network.wanted_issue = null
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- NEWSCASTER.update_icon()
- src.screen=17
- src.updateUsrDialog()
-
- else if(href_list["view_wanted"])
- src.screen=18
- src.updateUsrDialog()
- else if(href_list["censor_channel_author"])
- var/datum/feed_channel/FC = locate(href_list["censor_channel_author"])
- if(FC.is_admin_channel)
- alert("This channel was created by a [global.using_map.company_name] Officer. You cannot censor it.","Ok")
- return
- if(FC.author != "\[REDACTED\]")
- FC.backup_author = FC.author
- FC.author = "\[REDACTED\]"
- else
- FC.author = FC.backup_author
- FC.update()
- src.updateUsrDialog()
-
- else if(href_list["censor_channel_story_author"])
- var/datum/feed_message/MSG = locate(href_list["censor_channel_story_author"])
- if(MSG.is_admin_message)
- alert("This message was created by a [global.using_map.company_name] Officer. You cannot censor its author.","Ok")
- return
- if(MSG.author != "\[REDACTED\]")
- MSG.backup_author = MSG.author
- MSG.author = "\[REDACTED\]"
- else
- MSG.author = MSG.backup_author
- MSG.parent_channel.update()
- src.updateUsrDialog()
-
- else if(href_list["censor_channel_story_body"])
- var/datum/feed_message/MSG = locate(href_list["censor_channel_story_body"])
- if(MSG.is_admin_message)
- alert("This channel was created by a [global.using_map.company_name] Officer. You cannot censor it.","Ok")
- return
- if(MSG.body != "\[REDACTED\]")
- MSG.backup_body = MSG.body
- MSG.backup_caption = MSG.caption
- MSG.backup_img = MSG.img
- MSG.body = "\[REDACTED\]"
- MSG.caption = "\[REDACTED\]"
- MSG.img = null
- else
- MSG.body = MSG.backup_body
- MSG.caption = MSG.caption
- MSG.img = MSG.backup_img
-
- MSG.parent_channel.update()
- src.updateUsrDialog()
-
- else if(href_list["pick_d_notice"])
- var/datum/feed_channel/FC = locate(href_list["pick_d_notice"])
- src.viewing_channel = FC
- src.screen=13
- src.updateUsrDialog()
-
- else if(href_list["toggle_d_notice"])
- var/datum/feed_channel/FC = locate(href_list["toggle_d_notice"])
- if(FC.is_admin_channel)
- alert("This channel was created by a [global.using_map.company_name] Officer. You cannot place a D-Notice upon it.","Ok")
- return
- FC.censored = !FC.censored
- FC.update()
- src.updateUsrDialog()
-
- else if(href_list["view"])
- src.screen=1
- src.updateUsrDialog()
-
- else if(href_list["setScreen"]) //Brings us to the main menu and resets all fields~
- src.screen = text2num(href_list["setScreen"])
- if (src.screen == 0)
- src.scanned_user = "Unknown"
- msg = ""
- src.c_locked=0;
- channel_name=""
- src.viewing_channel = null
- if (photo_data)
- qdel(photo_data)
- photo_data = null
- src.updateUsrDialog()
-
- else if(href_list["show_channel"])
- var/datum/feed_channel/FC = locate(href_list["show_channel"])
- src.viewing_channel = FC
- src.screen = 9
- src.updateUsrDialog()
-
- else if(href_list["pick_censor_channel"])
- var/datum/feed_channel/FC = locate(href_list["pick_censor_channel"])
- src.viewing_channel = FC
- src.screen = 12
- src.updateUsrDialog()
-
- else if(href_list["refresh"])
- src.updateUsrDialog()
+ news_network.CreateFeedChannel(channel_name, scanned_user, c_locked)
+ screen = SCREEN_CHANNEL_SUBMITTED
+ . = TOPIC_REFRESH
+
+ else if(href_list["set_channel_receiving"])
+ var/list/available_channels = list()
+ for(var/datum/feed_channel/F in news_network.network_channels)
+ if( (!F.locked || F.author == scanned_user) && !F.censored)
+ available_channels += F.channel_name
+ channel_name = input(user, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels
+ . = TOPIC_REFRESH
+
+ else if(href_list["set_new_message"])
+ msg = pencode2html(sanitize(input(user, "Write your Feed story", "Network Channel Handler", "") as message|null))
+ . = TOPIC_REFRESH
+
+ else if(href_list["set_attachment"])
+ AttachPhoto(user)
+ . = TOPIC_REFRESH
+
+ else if(href_list["submit_new_message"])
+ if(msg =="" || msg=="\[REDACTED\]" || scanned_user == "Unknown" || channel_name == "" )
+ screen = SCREEN_STORY_FAILED
+ else
+ var/image = photo_data ? photo_data.photo : null
+ SSstatistics.add_field("newscaster_stories",1)
+ news_network.SubmitArticle(msg, scanned_user, channel_name, image, 0)
+ if(photo_data)
+ qdel(photo_data)
+ photo_data = null
+ screen = SCREEN_STORY_SUBMITTED
+
+ . = TOPIC_REFRESH
+
+ else if(href_list["create_channel"])
+ screen = SCREEN_CREATE_CHANNEL
+ . = TOPIC_REFRESH
+
+ else if(href_list["create_feed_story"])
+ screen = SCREEN_CREATE_STORY
+ . = TOPIC_REFRESH
+
+ else if(href_list["menu_paper"])
+ screen = SCREEN_CHOOSE_PRINT
+ . = TOPIC_REFRESH
+ else if(href_list["print_paper"])
+ if(!paper_remaining)
+ screen = SCREEN_PRINT_FAILED
+ else
+ print_paper()
+ screen = SCREEN_PRINT_COMPLETE
+ . = TOPIC_REFRESH
+
+ else if(href_list["menu_censor_story"])
+ screen = SCREEN_CENSOR_STORY
+ . = TOPIC_REFRESH
+
+ else if(href_list["menu_censor_channel"])
+ screen = SCREEN_CENSOR_CHANNEL
+ . = TOPIC_REFRESH
+
+ else if(href_list["menu_wanted"])
+ var/already_wanted = 0
+ if(news_network.wanted_issue)
+ already_wanted = 1
+
+ if(already_wanted)
+ channel_name = news_network.wanted_issue.author
+ msg = news_network.wanted_issue.body
+ screen = SCREEN_MAKE_WANTED_ISSUE
+ . = TOPIC_REFRESH
+
+ else if(href_list["set_wanted_name"])
+ channel_name = sanitize_safe(input(user, "Provide the name of the Wanted person", "Network Security Handler", ""), MAX_LNAME_LEN)
+ . = TOPIC_REFRESH
+
+ else if(href_list["set_wanted_desc"])
+ msg = sanitize(input(user, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", ""))
+ . = TOPIC_REFRESH
+
+ else if(href_list["submit_wanted"])
+ var/input_param = text2num(href_list["submit_wanted"])
+ if(msg == "" || channel_name == "" || scanned_user == "Unknown")
+ screen = SCREEN_WANTED_FAILED
+ else
+ var/choice = alert(user, "Please confirm Wanted Issue [(input_param==1) ? ("creation.") : ("edit.")]","Network Security Handler","Confirm","Cancel")
+ if(choice=="Confirm")
+ if(input_param==1) //If input_param == 1 we're submitting a new wanted issue. At 2 we're just editing an existing one. See the else below
+ var/datum/feed_message/WANTED = new /datum/feed_message
+ WANTED.author = channel_name
+ WANTED.body = msg
+ WANTED.backup_author = scanned_user //I know, a bit wacky
+ if(photo_data)
+ WANTED.img = photo_data.photo.img
+ news_network.wanted_issue = WANTED
+ news_network.alert_readers()
+ screen = SCREEN_WANTED_CONFIRMED
+ else
+ if(news_network.wanted_issue.is_admin_message)
+ alert(user, "The wanted issue has been distributed by a [global.using_map.company_name] higherup. You cannot edit it.","Ok")
+ return TOPIC_HANDLED
+ news_network.wanted_issue.author = channel_name
+ news_network.wanted_issue.body = msg
+ news_network.wanted_issue.backup_author = scanned_user
+ if(photo_data)
+ news_network.wanted_issue.img = photo_data.photo.img
+ screen = SCREEN_WANTED_EDITED
+
+ . = TOPIC_REFRESH
+
+ else if(href_list["cancel_wanted"])
+ if(news_network.wanted_issue.is_admin_message)
+ alert(user, "The wanted issue has been distributed by a [global.using_map.company_name] higherup. You cannot take it down.","Ok")
+ return
+ var/choice = alert(user, "Please confirm Wanted Issue removal","Network Security Handler","Confirm","Cancel")
+ if(choice=="Confirm")
+ news_network.wanted_issue = null
+ for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
+ NEWSCASTER.update_icon()
+ screen = SCREEN_WANTED_DELETED
+ . = TOPIC_REFRESH
+
+ else if(href_list["view_wanted"])
+ screen = SCREEN_WANTED_VIEW
+ . = TOPIC_REFRESH
+ else if(href_list["censor_channel_author"])
+ var/datum/feed_channel/FC = locate(href_list["censor_channel_author"])
+ if(FC.is_admin_channel)
+ alert(user, "This channel was created by a [global.using_map.company_name] Officer. You cannot censor it.","Ok")
+ return TOPIC_HANDLED
+ if(FC.author != "\[REDACTED\]")
+ FC.backup_author = FC.author
+ FC.author = "\[REDACTED\]"
+ else
+ FC.author = FC.backup_author
+ FC.update()
+ . = TOPIC_REFRESH
+
+ else if(href_list["censor_channel_story_author"])
+ var/datum/feed_message/MSG = locate(href_list["censor_channel_story_author"])
+ if(MSG.is_admin_message)
+ alert(user, "This message was created by a [global.using_map.company_name] Officer. You cannot censor its author.","Ok")
+ return TOPIC_HANDLED
+ if(MSG.author != "\[REDACTED\]")
+ MSG.backup_author = MSG.author
+ MSG.author = "\[REDACTED\]"
+ else
+ MSG.author = MSG.backup_author
+ MSG.parent_channel.update()
+ . = TOPIC_REFRESH
+
+ else if(href_list["censor_channel_story_body"])
+ var/datum/feed_message/MSG = locate(href_list["censor_channel_story_body"])
+ if(MSG.is_admin_message)
+ alert(user, "This channel was created by a [global.using_map.company_name] Officer. You cannot censor it.","Ok")
+ return TOPIC_HANDLED
+ if(MSG.body != "\[REDACTED\]")
+ MSG.backup_body = MSG.body
+ MSG.backup_caption = MSG.caption
+ MSG.backup_img = MSG.img
+ MSG.body = "\[REDACTED\]"
+ MSG.caption = "\[REDACTED\]"
+ MSG.img = null
+ else
+ MSG.body = MSG.backup_body
+ MSG.caption = MSG.caption
+ MSG.img = MSG.backup_img
+
+ MSG.parent_channel.update()
+ . = TOPIC_REFRESH
+
+ else if(href_list["pick_d_notice"])
+ var/datum/feed_channel/FC = locate(href_list["pick_d_notice"])
+ viewing_channel = FC
+ screen = SCREEN_PICK_CENSOR_CHANNEL
+ . = TOPIC_REFRESH
+
+ else if(href_list["toggle_d_notice"])
+ var/datum/feed_channel/FC = locate(href_list["toggle_d_notice"])
+ if(FC.is_admin_channel)
+ alert(user, "This channel was created by a [global.using_map.company_name] Officer. You cannot place a D-Notice upon it.","Ok")
+ return TOPIC_HANDLED
+ FC.censored = !FC.censored
+ FC.update()
+ . = TOPIC_REFRESH
+
+ else if(href_list["view"])
+ screen = SCREEN_VIEW_CHANNELS
+ . = TOPIC_REFRESH
+
+ else if(href_list["setScreen"]) //Brings us to the main menu and resets all fields~
+ screen = text2num(href_list["setScreen"])
+ if (screen == SCREEN_WELCOME)
+ scanned_user = "Unknown"
+ msg = ""
+ c_locked=0
+ channel_name=""
+ viewing_channel = null
+ if (photo_data)
+ qdel(photo_data)
+ photo_data = null
+ . = TOPIC_REFRESH
+
+ else if(href_list["show_channel"])
+ var/datum/feed_channel/FC = locate(href_list["show_channel"])
+ viewing_channel = FC
+ screen = SCREEN_VIEW_STORIES
+ . = TOPIC_REFRESH
+
+ else if(href_list["pick_censor_channel"])
+ var/datum/feed_channel/FC = locate(href_list["pick_censor_channel"])
+ viewing_channel = FC
+ screen = SCREEN_PICK_CENSOR_CHANNEL
+ . = TOPIC_REFRESH
+
+ else if(href_list["refresh"])
+ . = TOPIC_REFRESH
/datum/news_photo
- var/is_synth = 0
+ /// This var is currently unused.
+ var/is_synth = FALSE
+ /// The actual photo object to display to the user. TODO: Refactor to just copy the image from a photo?
var/obj/item/photo/photo = null
-/datum/news_photo/New(var/obj/item/photo/p, var/synth)
+/datum/news_photo/New(obj/item/photo/p, synth = FALSE)
is_synth = synth
photo = p
/obj/machinery/newscaster/proc/AttachPhoto(mob/user)
if(photo_data)
- qdel(photo_data)
- photo_data = null
+ QDEL_NULL(photo_data)
return
if(istype(user.get_active_held_item(), /obj/item/photo))
@@ -730,13 +741,14 @@ var/global/list/allCasters = list() //Global list that will contain reference to
if (!selection)
return
- photo_data = new(selection, 1)
+ photo_data = new(selection, TRUE)
//########################################################################################################################
//###################################### NEWSPAPER! ######################################################################
//########################################################################################################################
+// TODO: Rewrite newspapers to use pencode? Also change the name from The Griffon and do something about unnecessary mentions of space.
/obj/item/newspaper
name = "newspaper"
desc = "An issue of The Griffon, the space newspaper."
@@ -837,36 +849,37 @@ var/global/list/allCasters = list() //Global list that will contain reference to
to_chat(user, "The paper is full of unintelligible symbols!")
-/obj/item/newspaper/Topic(href, href_list)
- var/mob/living/U = usr
- ..()
- if ((src in U.contents) || ( isturf(loc) && in_range(src, U) ))
- U.set_machine(src)
- if(href_list["next_page"])
- if(curr_page==src.pages+1)
- return //Don't need that at all, but anyway.
- if(src.curr_page == src.pages) //We're at the middle, get to the end
- src.screen = 2
- else
- if(curr_page == 0) //We're at the start, get to the middle
- src.screen=1
- src.curr_page++
- playsound(src.loc, "pageturn", 50, 1)
+/obj/item/newspaper/DefaultTopicState()
+ return global.physical_no_access_topic_state
- else if(href_list["prev_page"])
- if(curr_page == 0)
- return
- if(curr_page == 1)
- src.screen = 0
+/obj/item/newspaper/OnTopic(mob/user, href_list, datum/topic_state/state)
+ if((. = ..()))
+ return
+ if(href_list["next_page"])
+ if(curr_page==src.pages+1)
+ return //Don't need that at all, but anyway.
+ if(src.curr_page == src.pages) //We're at the middle, get to the end
+ src.screen = 2
+ else
+ if(curr_page == 0) //We're at the start, get to the middle
+ src.screen=1
+ src.curr_page++
+ playsound(src.loc, "pageturn", 50, 1)
- else
- if(curr_page == src.pages+1) //we're at the end, let's go back to the middle.
- src.screen = 1
- src.curr_page--
- playsound(src.loc, "pageturn", 50, 1)
+ else if(href_list["prev_page"])
+ if(curr_page == 0)
+ return
+ if(curr_page == 1)
+ src.screen = 0
+
+ else
+ if(curr_page == src.pages+1) //we're at the end, let's go back to the middle.
+ src.screen = 1
+ src.curr_page--
+ playsound(src.loc, "pageturn", 50, 1)
- if (ismob(src.loc))
- src.attack_self(src.loc)
+ if (ismob(src.loc))
+ src.attack_self(src.loc)
/obj/item/newspaper/attackby(obj/item/W, mob/user)
diff --git a/code/game/machinery/nuclear_bomb.dm b/code/game/machinery/nuclear_bomb.dm
index dd3da2e44ae5..28272033fa96 100644
--- a/code/game/machinery/nuclear_bomb.dm
+++ b/code/game/machinery/nuclear_bomb.dm
@@ -220,9 +220,9 @@ var/global/bomb_set
return 1
return 0
-/obj/machinery/nuclearbomb/Topic(href, href_list)
- if(..())
- return 1
+/obj/machinery/nuclearbomb/OnTopic(mob/user, href_list, datum/topic_state/state)
+ if((. = ..()))
+ return
if(href_list["auth"])
if(auth)
@@ -230,13 +230,14 @@ var/global/bomb_set
yes_code = 0
auth = null
else
- var/obj/item/I = usr.get_active_held_item()
+ var/obj/item/I = user.get_active_held_item()
if(istype(I, /obj/item/disk/nuclear))
- if(!usr.try_unequip(I, src))
- return 1
+ if(!user.try_unequip(I, src))
+ return TOPIC_HANDLED
auth = I
- if(is_auth(usr))
+ if(is_auth(user))
if(href_list["type"])
+ . = TOPIC_REFRESH
if(href_list["type"] == "E")
if(code == r_code)
yes_code = 1
@@ -259,52 +260,56 @@ var/global/bomb_set
if(yes_code)
if(href_list["time"])
if(timing)
- to_chat(usr, "Cannot alter the timing during countdown.")
- return
+ to_chat(user, SPAN_WARNING("Cannot alter the timing during countdown."))
+ return TOPIC_HANDLED
var/time = text2num(href_list["time"])
timeleft += time
timeleft = clamp(timeleft, minTime, maxTime)
+ . = TOPIC_HANDLED
if(href_list["timer"])
if(timing == -1)
- return 1
+ return TOPIC_NOACTION
if(!anchored)
- to_chat(usr, "\The [src] needs to be anchored.")
- return 1
+ to_chat(user, SPAN_WARNING("\The [src] needs to be anchored."))
+ return TOPIC_HANDLED
if(safety)
- to_chat(usr, "The safety is still on.")
- return 1
+ to_chat(user, SPAN_WARNING("The safety is still on."))
+ return TOPIC_HANDLED
if(wires.IsIndexCut(NUCLEARBOMB_WIRE_TIMING))
- to_chat(usr, "Nothing happens, something might be wrong with the wiring.")
- return 1
+ to_chat(user, SPAN_WARNING("Nothing happens, something might be wrong with the wiring."))
+ return TOPIC_HANDLED
if(!timing && !safety)
- start_bomb(usr)
+ start_bomb(user)
+ . = TOPIC_HANDLED
else
check_cutoff()
+ . = TOPIC_HANDLED
if(href_list["safety"])
if (wires.IsIndexCut(NUCLEARBOMB_WIRE_SAFETY))
- to_chat(usr, "Nothing happens, something might be wrong with the wiring.")
- return 1
+ to_chat(user, SPAN_WARNING("Nothing happens, something might be wrong with the wiring."))
+ return TOPIC_HANDLED
safety = !safety
if(safety)
secure_device()
update_icon()
+ return TOPIC_REFRESH
if(href_list["anchor"])
if(removal_stage == 5)
anchored = FALSE
- visible_message("\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
- return 1
+ visible_message(SPAN_WARNING("\The [src] makes a highly-unpleasant crunching noise. It looks like the anchoring bolts have been cut."), blind_message = SPAN_NOTICE("You hear a highly-unpleasant crunching noise."))
+ return TOPIC_HANDLED
if(!isspaceturf(get_turf(src)))
anchored = !anchored
if(anchored)
- visible_message("With a steely snap, bolts slide out of \the [src] and anchor it to the flooring.")
+ visible_message(SPAN_WARNING("With a steely snap, bolts slide out of \the [src] and anchor it to the flooring."), blind_message = SPAN_NOTICE("You hear a steely snap."))
else
secure_device()
- visible_message("The anchoring bolts slide back into the depths of \the [src].")
+ visible_message(SPAN_WARNING("The anchoring bolts slide back into the depths of \the [src]."), blind_message = SPAN_NOTICE("You hear a steely snap."))
+ return TOPIC_HANDLED
else
- to_chat(usr, "There is nothing to anchor to!")
- return 1
+ to_chat(user, SPAN_WARNING("There is nothing to anchor to!"))
/obj/machinery/nuclearbomb/proc/start_bomb(user)
timing = 1
@@ -472,12 +477,10 @@ var/global/bomb_set
/obj/machinery/nuclearbomb/station/attackby(obj/item/O, mob/user)
return TRUE // cannot be moved
-/obj/machinery/nuclearbomb/station/Topic(href, href_list)
- if((. = ..()))
- return
-
+/obj/machinery/nuclearbomb/station/OnTopic(mob/user, href_list, datum/topic_state/state)
if(href_list["anchor"])
- return
+ return TOPIC_NOACTION
+ return ..()
/obj/machinery/nuclearbomb/station/start_bomb(mob/user)
for(var/inserter in inserters)
diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm
index aeb5ac90cac6..615a1243831f 100644
--- a/code/game/machinery/oxygen_pump.dm
+++ b/code/game/machinery/oxygen_pump.dm
@@ -90,8 +90,7 @@
visible_message(SPAN_NOTICE("\The [user] detaches \the [contained] and it rapidly retracts back into \the [src]!"))
else
visible_message(SPAN_NOTICE("\The [contained] rapidly retracts back into \the [src]!"))
- if(breather.internals)
- breather.internals.icon_state = "internal0"
+ breather.refresh_hud_element(HUD_INTERNALS)
breather = null
update_use_power(POWER_USE_IDLE)
@@ -220,9 +219,9 @@
// auto update every Master Controller tick
ui.set_auto_update(1)
-/obj/machinery/oxygen_pump/Topic(href, href_list)
- if(..())
- return 1
+/obj/machinery/oxygen_pump/OnTopic(mob/user, href_list, datum/topic_state/state)
+ if((. = ..()))
+ return
if (href_list["dist_p"])
if (href_list["dist_p"] == "reset")
@@ -233,4 +232,4 @@
var/cp = text2num(href_list["dist_p"])
tank.distribute_pressure += cp
tank.distribute_pressure = min(max(round(tank.distribute_pressure), 0), TANK_MAX_RELEASE_PRESSURE)
- return 1
+ . = TOPIC_REFRESH // Refreshing is handled in machinery/Topic
diff --git a/code/game/machinery/pager.dm b/code/game/machinery/pager.dm
index 0777eb14361f..9bee6cc752c1 100644
--- a/code/game/machinery/pager.dm
+++ b/code/game/machinery/pager.dm
@@ -43,16 +43,14 @@
else
to_chat(user,"No valid destinations were found for the page.")
-/obj/machinery/network/pager/Topic(href, href_list)
- if(..())
- return 1
- if(stat & NOPOWER)
+/obj/machinery/network/pager/OnTopic(mob/user, href_list, datum/topic_state/state)
+ if((. = ..()))
return
if(!acknowledged && href_list["ack"])
playsound(src, 'sound/machines/ping.ogg', 60)
visible_message("Page acknowledged.")
acknowledged = 1
+ . = TOPIC_REFRESH
var/obj/machinery/network/message_server/MS = get_message_server(z)
- if(!MS)
- return
- MS.send_to_department(department,"Page to [location.proper_name] was acknowledged.", "*ack*")
+ if(MS)
+ MS.send_to_department(department,"Page to [location.proper_name] was acknowledged.", "*ack*")
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 286ac6310cc4..0fde815d1326 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -199,9 +199,9 @@ var/global/list/turret_icons
return ..()
-/obj/machinery/porta_turret/Topic(href, href_list)
- if(..())
- return 1
+/obj/machinery/porta_turret/OnTopic(mob/user, href_list, datum/topic_state/state)
+ if((. = ..()))
+ return
if(href_list["command"] && href_list["value"])
var/value = text2num(href_list["value"])
@@ -221,8 +221,7 @@ var/global/list/turret_icons
check_access = value
else if(href_list["command"] == "check_anomalies")
check_anomalies = value
-
- return 1
+ . = TOPIC_REFRESH
/obj/machinery/porta_turret/physically_destroyed(skip_qdel)
if(installation)
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index fc240f89e810..b507e3092765 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -120,7 +120,7 @@
/obj/machinery/recharger/wallcharger
name = "wall recharger"
- desc = "A heavy duty wall recharger specialized for energy weaponry."
+ desc = "A heavy-duty wall recharger specialized for energy weaponry."
icon = 'icons/obj/machines/recharger_wall.dmi'
icon_state = "wrecharger0"
active_power_usage = 50 KILOWATTS //It's more specialized than the standalone recharger (guns and batons only) so make it more powerful
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 64a7cb962357..bed171138642 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -1,6 +1,6 @@
/obj/machinery/recharge_station
name = "robot recharging station"
- desc = "A heavy duty rapid charging system, designed to quickly recharge autonomous system power reserves."
+ desc = "A heavy-duty rapid charging system, designed to quickly recharge autonomous system power reserves."
icon = 'icons/obj/objects.dmi'
icon_state = "borgcharger0"
density = TRUE
diff --git a/code/game/machinery/self_destruct.dm b/code/game/machinery/self_destruct.dm
index 3cf9137e831f..3d1f841884df 100644
--- a/code/game/machinery/self_destruct.dm
+++ b/code/game/machinery/self_destruct.dm
@@ -1,6 +1,6 @@
/obj/machinery/self_destruct
name = "\improper Nuclear Cylinder Inserter"
- desc = "A hollow space used to insert nuclear cylinders for arming the self destruct."
+ desc = "A hollow space used to insert nuclear cylinders for arming the self-destruct mechanism."
icon = 'icons/obj/machines/self_destruct.dmi'
icon_state = "empty"
density = FALSE
@@ -48,10 +48,10 @@
return
var/obj/machinery/nuclearbomb/nuke = locate(/obj/machinery/nuclearbomb/station) in get_area(src)
if(!nuke)
- to_chat(user, "Unable to interface with the self destruct terminal, unable to disarm.")
+ to_chat(user, "Unable to interface with the self-destruct terminal, unable to disarm.")
return
if(nuke.timing)
- to_chat(user, "The self destruct sequence is in progress, unable to disarm.")
+ to_chat(user, "The self-destruct sequence is in progress, unable to disarm.")
return
user.visible_message("[user] begins extracting [cylinder].", "You begin extracting [cylinder].")
if(do_after(user, 40, src))
diff --git a/code/game/machinery/self_destruct_storage.dm b/code/game/machinery/self_destruct_storage.dm
index d8cd3e9d3a08..afaf920ef1da 100644
--- a/code/game/machinery/self_destruct_storage.dm
+++ b/code/game/machinery/self_destruct_storage.dm
@@ -1,6 +1,6 @@
/obj/machinery/nuclear_cylinder_storage
name = "nuclear cylinder storage"
- desc = "It's a secure, armored storage unit embeded into the floor for storing the nuclear cylinders."
+ desc = "It's a secure, armored storage unit embedded into the floor for storing the nuclear cylinders."
icon = 'icons/obj/machines/self_destruct_storage.dmi'
icon_state = "base"
anchored = TRUE
diff --git a/code/game/machinery/smartfridge/_smartfridge.dm b/code/game/machinery/smartfridge/_smartfridge.dm
index 28f51fab493c..c446e87a4389 100644
--- a/code/game/machinery/smartfridge/_smartfridge.dm
+++ b/code/game/machinery/smartfridge/_smartfridge.dm
@@ -201,35 +201,30 @@
ui.set_initial_data(data)
ui.open()
-/obj/machinery/smartfridge/Topic(href, href_list)
- if(..()) return 0
-
- var/mob/user = usr
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, "main")
+/obj/machinery/smartfridge/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["close"])
- user.unset_machine()
- ui.close()
- return 0
+ return TOPIC_CLOSE
if(href_list["vend"])
var/index = text2num(href_list["vend"])
- var/amount = text2num(href_list["amount"])
var/datum/stored_items/I = item_records[index]
var/count = I.get_amount()
+ var/amount = clamp(text2num(href_list["amount"]), 0, count)
// Sanity check, there are probably ways to press the button when it shouldn't be possible.
- if(count > 0)
- if((count - amount) < 0)
- amount = count
- for(var/i = 1 to amount)
- I.get_product(get_turf(src))
- update_icon()
- var/vend_state = "[icon_state]-vend"
- if (check_state_in_icon(vend_state, icon)) //Show the vending animation if needed
- flick(vend_state, src)
- return 1
- return 0
+ if(amount <= 0)
+ return TOPIC_REFRESH // you must be confused, we have none of that here!
+ for(var/i = 1 to amount)
+ I.get_product(get_turf(src))
+ update_icon()
+ var/vend_state = "[icon_state]-vend"
+ if (check_state_in_icon(vend_state, icon)) //Show the vending animation if needed
+ flick(vend_state, src)
+ return TOPIC_REFRESH
+ return TOPIC_NOACTION
/obj/machinery/smartfridge/proc/throw_item()
var/obj/throw_item = null
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index 77dcbafee909..30d1ae2ef8c6 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -23,7 +23,8 @@
var/active = 0
var/heating_power = 40 KILOWATTS
-/obj/machinery/space_heater/on_update_icon(var/rebuild_overlay = 0)
+/obj/machinery/space_heater/on_update_icon()
+ . = ..()
if(!on)
icon_state = "sheater-off"
set_light(0)
@@ -36,11 +37,8 @@
else
icon_state = "sheater-standby"
set_light(0)
-
- if(rebuild_overlay)
- overlays.Cut()
- if(panel_open)
- overlays += "sheater-open"
+ if(panel_open)
+ add_overlay("sheater-open")
/obj/machinery/space_heater/examine(mob/user)
. = ..()
@@ -54,59 +52,57 @@
/obj/machinery/space_heater/state_transition(decl/machine_construction/new_state, mob/user)
. = ..()
- if(istype(new_state, /decl/machine_construction/default/panel_open) && CanInteract(user, DefaultTopicState()))
- interact(user)
+ if(istype(new_state, /decl/machine_construction/default/panel_closed) || !CanInteract(user, DefaultTopicState()))
+ SSnano.close_uis(src)
+ else if(istype(new_state, /decl/machine_construction/default/panel_open))
+ SSnano.update_uis(src)
/obj/machinery/space_heater/interface_interact(mob/user)
if(panel_open)
interact(user)
return TRUE
-/obj/machinery/space_heater/interact(mob/user)
- if(panel_open)
- var/list/dat = list()
- var/obj/item/cell/cell = get_cell()
- dat += "Power cell: "
- if(cell)
- dat += "Installed
"
- else
- dat += "Removed
"
-
- dat += "Power Level: [cell ? round(cell.percent(),1) : 0]%
"
-
- dat += "Set Temperature: "
-
- dat += "-"
-
- dat += " [set_temperature]K ([set_temperature-T0C]°C)"
- dat += "+
"
-
- var/datum/browser/popup = new(user, "spaceheater", "Space Heater Control Panel")
- popup.set_content(jointext(dat, null))
- popup.open()
+/obj/machinery/space_heater/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, datum/topic_state/state = global.physical_no_access_topic_state)
+ if(!panel_open)
+ SSnano.close_uis(src) // should be handled in state_transition, but just in case
+ return
+ var/obj/item/cell/cell = get_cell()
+ var/list/data = list(
+ "has_cell" = !!cell,
+ "cell_percent" = cell?.percent(),
+ "set_temperature" = set_temperature,
+ )
+ // update the ui if it exists, returns null if no ui is passed/found
+ ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "space_heater.tmpl", "Space Heater Control Panel")
+ ui.set_initial_data(data)
+ ui.open()
/obj/machinery/space_heater/physical_attack_hand(mob/user)
if(!panel_open)
on = !on
- user.visible_message("[user] switches [on ? "on" : "off"] \the [src].","You switch [on ? "on" : "off"] \the [src].")
+ user.visible_message(
+ SPAN_NOTICE("[user] switches [on ? "on" : "off"] \the [src]."),
+ SPAN_NOTICE("You switch [on ? "on" : "off"] \the [src]."),
+ SPAN_NOTICE("You hear a [on ? "machine rumble to life" : "rumbling machine go silent"].")
+ )
update_icon()
return TRUE
return FALSE
-/obj/machinery/space_heater/Topic(href, href_list, state = global.physical_topic_state)
- if (..())
- show_browser(usr, null, "window=spaceheater")
- usr.unset_machine()
- return 1
-
- switch(href_list["op"])
- if("temp")
- var/value = text2num(href_list["val"])
-
- // limit to 0-90 degC
- set_temperature = clamp(set_temperature + value, T0C, T0C + 90)
-
- updateDialog()
+// This machine has physical, mechanical buttons.
+/obj/machinery/space_heater/DefaultTopicState()
+ return global.physical_topic_state
+
+/obj/machinery/space_heater/OnTopic(mob/user, href_list, state)
+ if ((. = ..()))
+ return
+ if(href_list["adj_temp"])
+ var/old_temperature = set_temperature
+ set_temperature = clamp(round(set_temperature + text2num(href_list["adj_temp"])), T0C, 90 CELSIUS) // 90C is pretty damn hot but okay
+ if(old_temperature != set_temperature)
+ . = TOPIC_REFRESH
/obj/machinery/space_heater/power_change()
. = ..()
diff --git a/code/game/machinery/suit_cycler.dm b/code/game/machinery/suit_cycler.dm
index 7f899870a1cb..fd147aef4247 100644
--- a/code/game/machinery/suit_cycler.dm
+++ b/code/game/machinery/suit_cycler.dm
@@ -10,17 +10,17 @@
initial_access = list(list(access_captain, access_bridge))
- var/active = 0 // PLEASE HOLD.
- var/safeties = 1 // The cycler won't start with a living thing inside it unless safeties are off.
- var/irradiating = 0 // If this is > 0, the cycler is decontaminating whatever is inside it.
+ var/active = FALSE // PLEASE HOLD.
+ var/safeties = TRUE //! The cycler won't start with a living thing inside it unless safeties are off.
+ var/irradiating = 0 //! The number of Process() ticks we should irradiate our contents for. If > 0, will irradiate contents. Decrements every Process().
var/radiation_level = 2 // 1 is removing germs, 2 is removing blood, 3 is removing contaminants.
- var/model_text = "" // Some flavour text for the topic box.
- var/locked = 1 // If locked, nothing can be taken from or added to the cycler.
- var/can_repair = 1 // If set, the cycler can repair voidsuits.
- var/electrified = 0 // If set, will shock users.
+ var/model_text = "" //! Some flavour text for the topic box.
+ var/locked = TRUE //! If locked, nothing can be taken from or added to the cycler.
+ var/can_repair = TRUE //! If TRUE, the cycler can repair voidsuits.
+ var/electrified = 0 //! The number of Process() ticks we should shock users for. If > 0, will shock users. Decrements every Process().
- // Possible modifications to pick between
- var/list/available_modifications = list(
+ /// Possible suit modifier decls to pick between
+ var/list/decl/item_modifier/space_suit/available_modifications = list(
/decl/item_modifier/space_suit/engineering,
/decl/item_modifier/space_suit/mining,
/decl/item_modifier/space_suit/medical,
@@ -31,7 +31,7 @@
)
// Extra modifications to add when emagged, duplicates won't be added
- var/emagged_modifications = list(
+ var/list/decl/item_modifier/space_suit/emagged_modifications = list(
/decl/item_modifier/space_suit/engineering,
/decl/item_modifier/space_suit/mining,
/decl/item_modifier/space_suit/medical,
@@ -269,7 +269,7 @@
available_modifications |= additional_modifications
emagged = 1
- safeties = 0
+ safeties = FALSE
req_access = list()
updateUsrDialog()
return 1
@@ -320,95 +320,98 @@
popup.set_content(JOINTEXT(dat))
popup.open()
-/obj/machinery/suit_cycler/Topic(href, href_list)
+/obj/machinery/suit_cycler/OnTopic(user, href_list)
if((. = ..()))
return
if(href_list["eject_suit"])
- if(!suit) return
+ if(!suit) return TOPIC_NOACTION
suit.dropInto(loc)
set_suit(null)
else if(href_list["eject_helmet"])
- if(!helmet) return
+ if(!helmet) return TOPIC_NOACTION
helmet.dropInto(loc)
set_helmet(null)
else if(href_list["eject_boots"])
- if(!boots) return
+ if(!boots) return TOPIC_NOACTION
boots.dropInto(loc)
set_boots(null)
else if(href_list["select_department"])
- var/choice = input("Please select the target department paintjob.", "Suit cycler", target_modification) as null|anything in available_modifications
- if(choice && CanPhysicallyInteract(usr))
+ var/choice = input(user, "Please select the target department paintjob.", "Suit cycler", target_modification) as null|anything in available_modifications
+ . = TOPIC_HANDLED // no matter what, we've prompted for user input so we cancel any further behavior on subtypes
+ if(choice && CanPhysicallyInteract(user))
target_modification = choice
+ . = TOPIC_REFRESH
else if(href_list["select_bodytype"])
var/choice = input("Please select the target body configuration.","Suit cycler",null) as null|anything in available_bodytypes
- if(choice && CanPhysicallyInteract(usr))
+ . = TOPIC_HANDLED
+ if(choice && CanPhysicallyInteract(user))
target_bodytype = choice
+ . = TOPIC_REFRESH
else if(href_list["select_rad_level"])
var/choices = list(1,2,3)
if(emagged)
choices = list(1,2,3,4,5)
var/choice = input("Please select the desired radiation level.","Suit cycler",null) as null|anything in choices
+ . = TOPIC_HANDLED
if(choice)
radiation_level = choice
+ . = TOPIC_REFRESH
else if(href_list["repair_suit"])
-
- if(!suit || !can_repair) return
- active = 1
- spawn(100)
- repair_suit()
- finished_job()
+ if(!suit || !can_repair) return TOPIC_NOACTION
+ active = TRUE
+ addtimer(CALLBACK(src, PROC_REF(repair_suit)), 10 SECONDS)
+ . = TOPIC_REFRESH
else if(href_list["apply_paintjob"])
-
- if(!suit && !helmet) return
- active = 1
- spawn(100)
- apply_paintjob()
- finished_job()
+ if(!suit && !helmet) return TOPIC_NOACTION
+ active = TRUE
+ addtimer(CALLBACK(src, PROC_REF(apply_paintjob)), 10 SECONDS)
+ . = TOPIC_REFRESH
else if(href_list["toggle_safties"])
safeties = !safeties
+ . = TOPIC_REFRESH
else if(href_list["toggle_lock"])
-
- if(allowed(usr))
+ if(allowed(user))
locked = !locked
- to_chat(usr, "You [locked ? "lock" : "unlock"] [src].")
+ to_chat(user, "You [locked ? "lock" : "unlock"] [src].")
+ . = TOPIC_REFRESH
else
- to_chat(usr, FEEDBACK_ACCESS_DENIED)
+ to_chat(user, FEEDBACK_ACCESS_DENIED)
+ . = TOPIC_HANDLED
else if(href_list["begin_decontamination"])
-
if(safeties && occupant)
- to_chat(usr, SPAN_DANGER("\The [src] has detected an occupant. Please remove the occupant before commencing the decontamination cycle."))
- return
+ to_chat(user, SPAN_DANGER("\The [src] has detected an occupant. Please remove the occupant before commencing the decontamination cycle."))
+ return TOPIC_HANDLED
- active = 1
+ active = TRUE
irradiating = 10
- update_icon()
- updateUsrDialog()
-
- sleep(10)
+ . = TOPIC_REFRESH
+ addtimer(CALLBACK(src, PROC_REF(finish_decontamination)), 1 SECOND)
+ update_icon()
+/obj/machinery/suit_cycler/proc/finish_decontamination()
+ if(active && operable()) // doesn't currently use power when active, but maybe it should?
if(helmet)
if(radiation_level > 2)
helmet.decontaminate()
if(radiation_level > 1)
helmet.clean()
-
if(suit)
if(radiation_level > 2)
suit.decontaminate()
if(radiation_level > 1)
suit.clean()
-
if(boots)
if(radiation_level > 2)
boots.decontaminate()
if(radiation_level > 1)
boots.clean()
-
+ // maybe add a failure message if it's been interrupted by the time decontamination finishes?
+ // Update post-decontamination
update_icon()
updateUsrDialog()
@@ -420,7 +423,7 @@
return
if(active && stat & (BROKEN|NOPOWER))
- active = 0
+ active = FALSE
irradiating = 0
electrified = 0
update_icon()
@@ -447,7 +450,7 @@
/obj/machinery/suit_cycler/proc/finished_job()
var/turf/T = get_turf(src)
T.visible_message(SPAN_NOTICE("\The [src] pings loudly."))
- active = 0
+ active = FALSE
updateUsrDialog()
update_icon()
@@ -457,6 +460,7 @@
suit.breaches = list()
suit.calc_breach_damage()
+ finished_job()
/obj/machinery/suit_cycler/verb/leave()
set name = "Eject Cycler"
@@ -492,11 +496,9 @@
if(helmet)
target_modification.RefitItem(helmet)
helmet.refit_for_bodytype(target_bodytype)
- helmet.SetName("refitted [helmet.name]")
if(suit)
target_modification.RefitItem(suit)
suit.refit_for_bodytype(target_bodytype)
- suit.SetName("refitted [suit.name]")
if(boots)
boots.refit_for_bodytype(target_bodytype)
- boots.SetName("refitted [initial(boots.name)]")
+ finished_job()
diff --git a/code/game/machinery/supplybeacon.dm b/code/game/machinery/supplybeacon.dm
index 831363ce53e5..b74a93b635dc 100644
--- a/code/game/machinery/supplybeacon.dm
+++ b/code/game/machinery/supplybeacon.dm
@@ -101,7 +101,7 @@
target_drop_time = world.time + drop_delay
if(world.time >= target_drop_time)
deactivate(permanent = TRUE)
- command_announcement.Announce("Nyx Rapid Fabrication priority supply request #[rand(1000,9999)]-[rand(100,999)] recieved. Shipment dispatched via ballistic supply pod for immediate delivery. Have a nice day.", "Thank You For Your Patronage")
+ command_announcement.Announce("Nyx Rapid Fabrication priority supply request #[rand(1000,9999)]-[rand(100,999)] received. Shipment dispatched via ballistic supply pod for immediate delivery. Have a nice day.", "Thank You For Your Patronage")
addtimer(CALLBACK(src, PROC_REF(drop_cargo)), rand(20 SECONDS, 30 SECONDS))
/obj/structure/supply_beacon/proc/drop_cargo(var/drop_x, var/drop_y, var/drop_z)
diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm
index c7c2924326f2..235da1f889fd 100644
--- a/code/game/machinery/turret_control.dm
+++ b/code/game/machinery/turret_control.dm
@@ -136,10 +136,9 @@
ui.open()
ui.set_auto_update(1)
-/obj/machinery/turretid/Topic(href, href_list)
- if(..())
- return 1
-
+/obj/machinery/turretid/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["command"] && href_list["value"])
var/log_action = null
@@ -167,10 +166,10 @@
check_anomalies = value
if(!isnull(log_action))
- log_and_message_admins("has [log_action]", usr, loc)
+ log_and_message_admins("has [log_action]", user, loc)
updateTurrets()
- return 1
+ return TOPIC_REFRESH
/obj/machinery/turretid/proc/updateTurrets()
var/datum/turret_checks/TC = new
diff --git a/code/game/machinery/vending/food.dm b/code/game/machinery/vending/food.dm
index 8abc07f5536a..2a4fb62f3352 100644
--- a/code/game/machinery/vending/food.dm
+++ b/code/game/machinery/vending/food.dm
@@ -198,7 +198,7 @@
/obj/machinery/vending/cola
name = "Robust Softdrinks"
- desc = "A softdrink vendor provided by Robust Industries, LLC."
+ desc = "A soft drinks vendor provided by Robust Industries, LLC."
icon = 'icons/obj/machines/vending/drinks.dmi'
vend_delay = 11
base_type = /obj/machinery/vending/cola
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index bf5c37416308..6f573835da35 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -9,7 +9,7 @@
/obj/machinery/washing_machine
name = "washing machine"
- desc = "A commerical washing machine used to wash clothing items and linens. It requires detergent for efficient washing."
+ desc = "A commercial washing machine used to wash clothing items and linens. It requires detergent for efficient washing."
icon = 'icons/obj/machines/washing_machine.dmi'
icon_state = "wm_00"
density = TRUE
diff --git a/code/game/objects/__objs.dm b/code/game/objects/__objs.dm
index 812aaa9ddcad..d950aa3925cb 100644
--- a/code/game/objects/__objs.dm
+++ b/code/game/objects/__objs.dm
@@ -31,6 +31,10 @@
if(isnull(current_health))
current_health = get_max_health()
+/obj/object_shaken()
+ shake_animation()
+ return ..()
+
/obj/hitby(atom/movable/AM, var/datum/thrownthing/TT)
. = ..()
if(. && !anchored)
@@ -415,3 +419,58 @@
if(dumped_reagents && last_loc && !QDELETED(last_loc) && last_loc.reagents?.total_volume)
last_loc.reagents.handle_update()
HANDLE_REACTIONS(last_loc.reagents)
+
+// Used by HE pipes and forging bars/billets. Defaults are for HE pipes.
+/obj/proc/animate_heat_glow(icon_temperature, scale_sub = 500, scale_div = 1500, scale_max = 2000, skip_filter = FALSE, anim_time = 2 SECONDS)
+
+ var/scale = max((icon_temperature - scale_sub) / scale_div, 0)
+ var/h_r = heat2color_r(icon_temperature)
+ var/h_g = heat2color_g(icon_temperature)
+ var/h_b = heat2color_b(icon_temperature)
+
+ var/base_color = get_color()
+ var/b_r = HEX_RED(base_color)
+ var/b_g = HEX_GREEN(base_color)
+ var/b_b = HEX_BLUE(base_color)
+
+ if(icon_temperature < scale_max)
+ h_r = b_r + (h_r - b_r)*scale
+ h_g = b_g + (h_g - b_g)*scale
+ h_b = b_b + (h_b - b_b)*scale
+
+ var/scale_color = rgb(h_r, h_g, h_b)
+ var/list/animate_targets = get_above_oo() + src
+ for (var/thing in animate_targets)
+ var/atom/movable/AM = thing
+ if(anim_time > 0)
+ animate(AM, color = scale_color, time = anim_time, easing = SINE_EASING)
+ else
+ color = scale_color
+ if(!skip_filter)
+ animate_filter("glow", list(color = scale_color, time = anim_time, easing = LINEAR_EASING))
+
+ set_light(min(3, scale*2.5), min(3, scale*2.5), scale_color)
+
+/obj/proc/update_heat_glow(anim_time)
+
+ // We have no real way to find temperature bounds without a material that has a melting point.
+ var/decl/material/my_material = get_material()
+ if(!istype(my_material) || !my_material.glows_with_heat || isnull(my_material.melting_point) || QDELETED(src))
+ set_light(0, 0)
+ if(isatom(loc))
+ loc.update_icon()
+ return
+
+ var/temperature_percentage
+ if(temperature >= my_material.melting_point) // We should have melted...
+ temperature_percentage = 1
+ else if(temperature <= T20C) // Arbitrary point for the sake of not trying to find a proportional temperature delta with ice
+ temperature_percentage = 0
+ else
+ temperature_percentage = (my_material.melting_point - T20C) / (temperature - T20C)
+ if(temperature_percentage < 0.25)
+ set_light(0, 0)
+ else
+ animate_heat_glow(temperature, scale_sub = round((my_material.melting_point - T20C) * 0.25) + T20C, scale_div = round(my_material.melting_point * 0.75), scale_max = my_material.melting_point, skip_filter = TRUE, anim_time = anim_time)
+ if(isatom(loc))
+ loc.update_icon()
diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm
index 77bb9276f642..f2198e90718e 100644
--- a/code/game/objects/effects/decals/Cleanable/humans.dm
+++ b/code/game/objects/effects/decals/Cleanable/humans.dm
@@ -15,7 +15,7 @@
persistent = TRUE
appearance_flags = NO_CLIENT_COLOR
cleanable_scent = "blood"
- scent_descriptor = SCENT_DESC_ODOR
+ scent_descriptor = "odour"
var/base_icon = 'icons/effects/blood.dmi'
var/basecolor=COLOR_BLOOD_HUMAN // Color when wet.
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 66319d3ee89b..d8cd0b321ec1 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -14,7 +14,7 @@
var/cleanable_scent
var/scent_type = /datum/extension/scent/custom
var/scent_intensity = /decl/scent_intensity/normal
- var/scent_descriptor = SCENT_DESC_SMELL
+ var/scent_descriptor = "smell"
var/scent_range = 2
/obj/effect/decal/cleanable/Initialize(var/ml, var/_age)
diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm
index 9bb48d1f6701..e7f36574fa55 100644
--- a/code/game/objects/effects/decals/decal.dm
+++ b/code/game/objects/effects/decals/decal.dm
@@ -9,3 +9,6 @@
/obj/effect/decal/lava_act()
. = !throwing ? ..() : FALSE
+
+/obj/effect/decal/get_examine_prefix()
+ return null
\ No newline at end of file
diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm
index 35c5a8f2eef5..ac3664d7559a 100644
--- a/code/game/objects/effects/decals/misc.dm
+++ b/code/game/objects/effects/decals/misc.dm
@@ -1,6 +1,6 @@
/obj/effect/decal/point
name = "arrow"
- desc = "It's an arrow hanging in mid-air. There may be a wizard about."
+ desc = "It's an arrow hanging in midair. There may be a wizard about."
icon = 'icons/effects/markers.dmi'
icon_state = "arrow"
layer = POINTER_LAYER
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index ef3126355291..d5bcac25da97 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -107,12 +107,16 @@ steam.start() -- spawns the effect
/obj/effect/sparks/struck
spark_sound = "light_bic"
+/obj/effect/sparks/silent
+ spark_sound = null
+
/obj/effect/sparks/Initialize()
. = ..()
// this is 2 seconds so that it doesn't appear to freeze after its last move, which ends up making it look like timers are broken
// if you change the number of or delay between moves in spread(), this may need to be changed
QDEL_IN(src, 2 SECONDS)
- playsound(loc, spark_sound, 100, 1)
+ if(spark_sound)
+ playsound(loc, spark_sound, 100, 1)
set_light(lit_light_range, lit_light_power, lit_light_color)
if(isturf(loc))
var/turf/T = loc
@@ -140,6 +144,9 @@ steam.start() -- spawns the effect
/datum/effect/effect/system/spark_spread
var/spark_type = /obj/effect/sparks
+/datum/effect/effect/system/spark_spread/silent
+ spark_type = /obj/effect/sparks/silent
+
/datum/effect/effect/system/spark_spread/non_electrical
spark_type = /obj/effect/sparks/struck
diff --git a/code/game/objects/item_mob_overlay.dm b/code/game/objects/item_mob_overlay.dm
index 5739ddef4b1a..30a942c61231 100644
--- a/code/game/objects/item_mob_overlay.dm
+++ b/code/game/objects/item_mob_overlay.dm
@@ -43,7 +43,7 @@ var/global/list/icon_state_cache = list()
return out.Copy()
/proc/_fetch_icon_state_cache_entry(checkicon)
- if(isnull(checkicon) || !(isfile(checkicon) || isicon(checkicon)))
+ if(!checkicon)
return null
// if we want to let people del icons (WHY???) then we can use weakreF()
// but right now it's cheaper to just use checkicon directly
diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm
index 7c41d0aa13fb..27bc8a998ed6 100644
--- a/code/game/objects/items/__item.dm
+++ b/code/game/objects/items/__item.dm
@@ -38,7 +38,7 @@
var/max_pressure_protection // Set this variable if the item protects its wearer against high pressures below an upper bound. Keep at null to disable protection.
var/min_pressure_protection // Set this variable if the item protects its wearer against low pressures above a lower bound. Keep at null to disable protection. 0 represents protection against hard vacuum.
- var/datum/action/item_action/action = null
+ var/datum/action/item_action/action
var/action_button_name //It is also the text which gets displayed on the action button. If not set it defaults to 'Use [name]'. If it's not set, there'll be no button.
var/action_button_desc //A description for action button which will be displayed as tooltip.
var/default_action_type = /datum/action/item_action // Specify the default type and behavior of the action button for this atom.
@@ -242,6 +242,14 @@
QDEL_NULL(hidden_uplink)
QDEL_NULL(coating)
+ if(istype(action))
+ if(action.target == src)
+ action.target = null
+ if(!QDELETED(action))
+ QDEL_NULL(action)
+ else
+ action = null
+
if(ismob(loc))
var/mob/M = loc
LAZYREMOVE(M.pinned, src)
@@ -391,6 +399,13 @@
if(drying_wetness > 0 && drying_wetness != initial(drying_wetness))
desc_comp += "\The [src] is [get_dryness_text()]."
+ if(coating?.total_volume)
+ desc_comp += "It is covered in [coating.get_coated_name()]." // It is covered in dilute oily slimy bloody mud.
+
+ if(check_rights(R_DEBUG, 0, user))
+ to_chat(user, "\The [src] has a temperature of [temperature]K.")
+
+
return ..(user, distance, "", jointext(desc_comp, "
"))
/obj/item/check_mousedrop_adjacency(var/atom/over, var/mob/user)
@@ -499,7 +514,7 @@
return TRUE
return ..()
-/obj/item/end_throw()
+/obj/item/end_throw(datum/thrownthing/TT)
. = ..()
squash_item()
@@ -876,7 +891,7 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.
if(!istype(user.hud_used))
return
- if(user.hud_used.hud_shown)
+ if(user.hud_used.is_hud_shown())
user.toggle_zoom_hud() // If the user has already limited their HUD this avoids them having a HUD when they zoom in
user.client.view = viewsize
zoom = 1
@@ -924,7 +939,7 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.
return
user.client.view = world.view
- if(!user.hud_used.hud_shown)
+ if(istype(user.hud_used) && !user.hud_used.is_hud_shown())
user.toggle_zoom_hud()
user.client.pixel_x = 0
user.client.pixel_y = 0
@@ -935,13 +950,10 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.
return 0 // Process Kill
/obj/item/proc/get_examine_name()
- . = name
- if(coating?.total_volume)
- . = SPAN_WARNING("stained [.]")
- if(gender == PLURAL)
- . = "some [.]"
- else
- . = "\a [.]"
+ var/examine_prefix = get_examine_prefix()
+ if(examine_prefix)
+ examine_prefix += " "
+ return ADD_ARTICLE_GENDER("[examine_prefix][name]", gender)
/obj/item/proc/get_examine_line()
. = "[html_icon(src)] [get_examine_name()]"
@@ -1049,6 +1061,13 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.
if(coating.total_volume <= MINIMUM_CHEMICAL_VOLUME)
clean(FALSE)
+/obj/item/proc/transfer_coating_to(atom/target, amount = 1, multiplier = 1, copy = 0, defer_update = FALSE, transferred_phases = (MAT_PHASE_LIQUID | MAT_PHASE_SOLID))
+ if(!coating)
+ return
+ coating.trans_to(target, amount, multiplier)
+ if(coating.total_volume <= MINIMUM_CHEMICAL_VOLUME)
+ clean(FALSE)
+
/obj/item/clean(clean_forensics=TRUE)
. = ..()
QDEL_NULL(coating)
@@ -1153,8 +1172,13 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.
/obj/item/proc/loadout_should_keep(obj/item/new_item, mob/wearer)
return type != new_item.type && !replaced_in_loadout
+/obj/item/dropped(mob/user, slot)
+ . = ..()
+ user?.clear_available_intents()
+
/obj/item/equipped(mob/user, slot)
. = ..()
+ user?.clear_available_intents()
// delay for 1ds to allow the rest of the call stack to resolve
if(!QDELETED(src) && !QDELETED(user) && user.get_equipped_slot_for_item(src) == slot)
try_burn_wearer(user, slot, 1)
@@ -1285,3 +1309,14 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.
squash_item()
if(!QDELETED(src))
physically_destroyed()
+
+/obj/item/proc/get_provided_intents(mob/wielder)
+ return null
+
+/obj/item/get_examine_prefix()
+ if(coating?.total_volume)
+ var/coating_string = coating.get_coated_adjectives() // component coloring is handled in here
+ if(get_config_value(/decl/config/enum/colored_coating_names) == CONFIG_COATING_COLOR_MIXTURE)
+ coating_string = FONT_COLORED(coating.get_color(), coating_string)
+ return coating_string
+ return ..()
diff --git a/code/game/objects/items/lockpicks.dm b/code/game/objects/items/artifice/lockpicks.dm
similarity index 97%
rename from code/game/objects/items/lockpicks.dm
rename to code/game/objects/items/artifice/lockpicks.dm
index cc799780b688..99c3eccabbec 100644
--- a/code/game/objects/items/lockpicks.dm
+++ b/code/game/objects/items/artifice/lockpicks.dm
@@ -35,7 +35,7 @@
/obj/item/lockpick_roll
name = "roll of lockpicks"
- desc = "A stitched roll used to store thin, strangely-shaped tools commonly used used to pick locks."
+ desc = "A stitched roll used to store thin, strangely-shaped tools commonly used to pick locks."
icon = 'icons/obj/items/lockpick_roll.dmi'
icon_state = ICON_STATE_WORLD
material = /decl/material/solid/organic/leather
diff --git a/code/game/objects/items/blackout.dm b/code/game/objects/items/blackout.dm
index d0528dc93ec0..4bc3d51b6f41 100644
--- a/code/game/objects/items/blackout.dm
+++ b/code/game/objects/items/blackout.dm
@@ -9,7 +9,7 @@
/obj/item/blackout
name = "blackout pulser"
- desc = "A complicated eletronic device of unknown purpose"
+ desc = "A complicated electronic device of unknown purpose."
icon = 'icons/obj/items/blackout.dmi'
icon_state = "device_blackout-off"
max_health = ITEM_HEALTH_NO_DAMAGE
diff --git a/code/game/objects/items/blades/knife.dm b/code/game/objects/items/blades/knife.dm
index 8362cbbfb371..986f54da39dd 100644
--- a/code/game/objects/items/blades/knife.dm
+++ b/code/game/objects/items/blades/knife.dm
@@ -5,3 +5,6 @@
item_flags = ITEM_FLAG_CAN_HIDE_IN_SHOES | ITEM_FLAG_IS_WEAPON
w_class = ITEM_SIZE_SMALL
base_parry_chance = 20
+
+/obj/item/bladed/knife/iron
+ material = /decl/material/solid/metal/iron
diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm
index 5a082bb9180c..8d9e6d3d06b9 100644
--- a/code/game/objects/items/blueprints.dm
+++ b/code/game/objects/items/blueprints.dm
@@ -55,7 +55,7 @@
if(istype(T) && length(global.using_map.overmap_ids))
var/obj/effect/overmap/visitable/sector/S = global.overmap_sectors[num2text(T.z)]
if(!S) // The blueprints are useless now, but keep them around for fluff.
- desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your wherabouts."
+ desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your whereabouts."
return FALSE
name += " - [S.name]"
@@ -91,7 +91,7 @@
for(var/obj/effect/overmap/visitable/sector/planetoid/E in map)
valid_z_levels |= E.map_z
return TRUE
- desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your wherabouts."
+ desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your whereabouts."
return FALSE
//For use on /obj/effect/overmap/visitable/ship/landable ships.
@@ -111,7 +111,7 @@
area_prefix = S.name
return TRUE
// The blueprints are useless now, but keep them around for fluff.
- desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your wherabouts."
+ desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your whereabouts."
return FALSE
/obj/item/blueprints/shuttle/proc/update_linked_name(atom/namee, old_name, new_name)
@@ -122,7 +122,7 @@
events_repository.unregister(/decl/observ/name_set, destroyed, src, PROC_REF(update_linked_name))
events_repository.unregister(/decl/observ/destroyed, destroyed, src, PROC_REF(on_shuttle_destroy))
name = initial(name)
- desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your wherabouts."
+ desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your whereabouts."
valid_z_levels = list()
area_prefix = null
diff --git a/code/game/objects/items/books/fluff/science.dm b/code/game/objects/items/books/fluff/science.dm
index 728b5599e2f5..eee65121cb97 100644
--- a/code/game/objects/items/books/fluff/science.dm
+++ b/code/game/objects/items/books/fluff/science.dm
@@ -5,7 +5,7 @@
title = "Spectroscopy: Analysing the Anomalies of the Cosmos"
fluff_text = {"
It's perhaps one of the most exciting times to be alive, with the recent breakthroughs in understanding and categorisation of things we may one day no longer call
- 'anomalies,' but rather 'infrequent or rare occurrences of certain celestial weather or phenomena.' Perhaps a little more long winded, but no less eloquent all the
+ 'anomalies,' but rather 'infrequent or rare occurrences of certain celestial weather or phenomena.' Perhaps a little more long-winded, but no less eloquent all the
same! Why, look at the strides we're making in piercing the walls of spacetime or our steadily improving ability to clarify and stabilise subspace emissions; it's
certainly an exciting time to be alive. For the moment, the Hydrolian hasn't seen two spatial anomalies alike but the day will come and it is soon, I can feel it.
"}
@@ -16,7 +16,7 @@
author = "Jasper Pascal, Senior Lecturer in Materials Analysis at the University of Jol'Nar"
title = "Materials Analysis and the Chemical Implications"
fluff_text = {"
- In today's high tech research fields, leaps and bounds are being made every day. Whether it's great strides forward in our understanding of the physical universe
+ In today's high-tech research fields, leaps and bounds are being made every day. Whether it's great strides forward in our understanding of the physical universe
or the operation of some fancy new piece of equipment, it seems like all the cool fields are producing new toys to play with, leaving doddery old fields such as
materials analysis and chemistry relegated to the previous few centuries, when we were still learning the makeup and structure of the elements.
diff --git a/code/game/objects/items/weapons/circuitboards/broken.dm b/code/game/objects/items/circuitboards/broken.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/broken.dm
rename to code/game/objects/items/circuitboards/broken.dm
diff --git a/code/game/objects/items/weapons/circuitboards/circuitboard.dm b/code/game/objects/items/circuitboards/circuitboard.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/circuitboard.dm
rename to code/game/objects/items/circuitboards/circuitboard.dm
diff --git a/code/game/objects/items/weapons/circuitboards/computer/air_management.dm b/code/game/objects/items/circuitboards/computer/air_management.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/computer/air_management.dm
rename to code/game/objects/items/circuitboards/computer/air_management.dm
diff --git a/code/game/objects/items/weapons/circuitboards/computer/computer.dm b/code/game/objects/items/circuitboards/computer/computer.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/computer/computer.dm
rename to code/game/objects/items/circuitboards/computer/computer.dm
diff --git a/code/game/objects/items/weapons/circuitboards/computer/holodeckcontrol.dm b/code/game/objects/items/circuitboards/computer/holodeckcontrol.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/computer/holodeckcontrol.dm
rename to code/game/objects/items/circuitboards/computer/holodeckcontrol.dm
diff --git a/code/game/objects/items/weapons/circuitboards/computer/modular.dm b/code/game/objects/items/circuitboards/computer/modular.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/computer/modular.dm
rename to code/game/objects/items/circuitboards/computer/modular.dm
diff --git a/code/game/objects/items/weapons/circuitboards/computer/shuttle.dm b/code/game/objects/items/circuitboards/computer/shuttle.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/computer/shuttle.dm
rename to code/game/objects/items/circuitboards/computer/shuttle.dm
diff --git a/code/game/objects/items/weapons/circuitboards/computer/station_alert.dm b/code/game/objects/items/circuitboards/computer/station_alert.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/computer/station_alert.dm
rename to code/game/objects/items/circuitboards/computer/station_alert.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm b/code/game/objects/items/circuitboards/machinery/biogenerator.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm
rename to code/game/objects/items/circuitboards/machinery/biogenerator.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/chemistry.dm b/code/game/objects/items/circuitboards/machinery/chemistry.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/chemistry.dm
rename to code/game/objects/items/circuitboards/machinery/chemistry.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/cloning.dm b/code/game/objects/items/circuitboards/machinery/cloning.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/cloning.dm
rename to code/game/objects/items/circuitboards/machinery/cloning.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/commsantenna.dm b/code/game/objects/items/circuitboards/machinery/commsantenna.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/commsantenna.dm
rename to code/game/objects/items/circuitboards/machinery/commsantenna.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/docking_beacon.dm b/code/game/objects/items/circuitboards/machinery/docking_beacon.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/docking_beacon.dm
rename to code/game/objects/items/circuitboards/machinery/docking_beacon.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/engineering_circuits.dm b/code/game/objects/items/circuitboards/machinery/engineering_circuits.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/engineering_circuits.dm
rename to code/game/objects/items/circuitboards/machinery/engineering_circuits.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/forensic.dm b/code/game/objects/items/circuitboards/machinery/forensic.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/forensic.dm
rename to code/game/objects/items/circuitboards/machinery/forensic.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/holomap.dm b/code/game/objects/items/circuitboards/machinery/holomap.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/holomap.dm
rename to code/game/objects/items/circuitboards/machinery/holomap.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/household.dm b/code/game/objects/items/circuitboards/machinery/household.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/household.dm
rename to code/game/objects/items/circuitboards/machinery/household.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/mech_recharger.dm b/code/game/objects/items/circuitboards/machinery/mech_recharger.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/mech_recharger.dm
rename to code/game/objects/items/circuitboards/machinery/mech_recharger.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/medical.dm b/code/game/objects/items/circuitboards/machinery/medical.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/medical.dm
rename to code/game/objects/items/circuitboards/machinery/medical.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/mining.dm b/code/game/objects/items/circuitboards/machinery/mining.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/mining.dm
rename to code/game/objects/items/circuitboards/machinery/mining.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/mining_drill.dm b/code/game/objects/items/circuitboards/machinery/mining_drill.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/mining_drill.dm
rename to code/game/objects/items/circuitboards/machinery/mining_drill.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/network.dm b/code/game/objects/items/circuitboards/machinery/network.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/network.dm
rename to code/game/objects/items/circuitboards/machinery/network.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/oxyregenerator.dm b/code/game/objects/items/circuitboards/machinery/oxyregenerator.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/oxyregenerator.dm
rename to code/game/objects/items/circuitboards/machinery/oxyregenerator.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/pacman.dm b/code/game/objects/items/circuitboards/machinery/pacman.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/pacman.dm
rename to code/game/objects/items/circuitboards/machinery/pacman.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/portable_atmospherics.dm b/code/game/objects/items/circuitboards/machinery/portable_atmospherics.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/portable_atmospherics.dm
rename to code/game/objects/items/circuitboards/machinery/portable_atmospherics.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/power.dm b/code/game/objects/items/circuitboards/machinery/power.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/power.dm
rename to code/game/objects/items/circuitboards/machinery/power.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm b/code/game/objects/items/circuitboards/machinery/recharge_station.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm
rename to code/game/objects/items/circuitboards/machinery/recharge_station.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/research.dm b/code/game/objects/items/circuitboards/machinery/research.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/research.dm
rename to code/game/objects/items/circuitboards/machinery/research.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/self_destruct_storage.dm b/code/game/objects/items/circuitboards/machinery/self_destruct_storage.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/self_destruct_storage.dm
rename to code/game/objects/items/circuitboards/machinery/self_destruct_storage.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/shieldgen.dm b/code/game/objects/items/circuitboards/machinery/shieldgen.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/shieldgen.dm
rename to code/game/objects/items/circuitboards/machinery/shieldgen.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/shipsensors.dm b/code/game/objects/items/circuitboards/machinery/shipsensors.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/shipsensors.dm
rename to code/game/objects/items/circuitboards/machinery/shipsensors.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm b/code/game/objects/items/circuitboards/machinery/telecomms.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/telecomms.dm
rename to code/game/objects/items/circuitboards/machinery/telecomms.dm
diff --git a/code/game/objects/items/weapons/circuitboards/machinery/unary_atmos.dm b/code/game/objects/items/circuitboards/machinery/unary_atmos.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/machinery/unary_atmos.dm
rename to code/game/objects/items/circuitboards/machinery/unary_atmos.dm
diff --git a/code/game/objects/items/weapons/circuitboards/other.dm b/code/game/objects/items/circuitboards/other.dm
similarity index 100%
rename from code/game/objects/items/weapons/circuitboards/other.dm
rename to code/game/objects/items/circuitboards/other.dm
diff --git a/code/game/objects/items/weapons/circuitboards/wall.dm b/code/game/objects/items/circuitboards/wall.dm
similarity index 98%
rename from code/game/objects/items/weapons/circuitboards/wall.dm
rename to code/game/objects/items/circuitboards/wall.dm
index 6aab1dd838e4..fe150c173d20 100644
--- a/code/game/objects/items/weapons/circuitboards/wall.dm
+++ b/code/game/objects/items/circuitboards/wall.dm
@@ -4,7 +4,7 @@
name = "circuitboard (fire alarm)"
icon = 'icons/obj/doors/door_assembly.dmi'
icon_state = "door_electronics"
- desc = "A circuit. It has a label on it, it says \"Can handle heat levels up to 40 degrees celsius!\"."
+ desc = "A circuit. It has a label on it, it says \"Can handle heat levels up to 40 degrees Celsius!\"."
build_path = /obj/machinery/firealarm
board_type = "wall"
origin_tech = @'{"programming":1,"engineering":1}'
diff --git a/code/game/objects/items/cryobag.dm b/code/game/objects/items/cryobag.dm
index b9dd96121a5c..b5d5f68a3e08 100644
--- a/code/game/objects/items/cryobag.dm
+++ b/code/game/objects/items/cryobag.dm
@@ -2,7 +2,7 @@
/obj/item/bodybag/cryobag
name = "stasis bag"
desc = "A folded, reusable bag designed to prevent additional damage to an occupant, especially useful if short on time or in \
- a hostile enviroment."
+ a hostile environment."
icon = 'icons/obj/closets/cryobag.dmi'
icon_state = "bodybag_folded"
origin_tech = @'{"biotech":4}'
@@ -25,7 +25,7 @@
/obj/structure/closet/body_bag/cryobag
name = "stasis bag"
desc = "A reusable plastic bag designed to prevent additional damage to an occupant, especially useful if short on time or in \
- a hostile enviroment."
+ a hostile environment."
icon = 'icons/obj/closets/cryobag.dmi'
item_path = /obj/item/bodybag/cryobag
material = /decl/material/solid/organic/plastic
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index ffd39d55806b..9516a2a65a52 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -1,5 +1,5 @@
/obj/item/aicard
- name = "inteliCard"
+ name = "intelliCard"
icon = 'icons/obj/items/device/ai_card.dmi'
icon_state = ICON_STATE_WORLD
w_class = ITEM_SIZE_SMALL
diff --git a/code/game/objects/items/devices/boombox.dm b/code/game/objects/items/devices/boombox.dm
index aef407430fd1..1b9c5ecbc428 100644
--- a/code/game/objects/items/devices/boombox.dm
+++ b/code/game/objects/items/devices/boombox.dm
@@ -1,6 +1,6 @@
/obj/item/boombox
name = "boombox"
- desc = "A device used to emit rhythmic sounds, colloquialy refered to as a 'boombox'. It's in a retro style (massive), and absolutely unwieldy."
+ desc = "A device used to emit rhythmic sounds, colloquially referred to as a 'boombox'. It's in a retro style (massive), and absolutely unwieldy."
icon = 'icons/obj/items/device/boombox.dmi'
icon_state = "off"
item_state = "boombox"
diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm
index 4508758e19d3..7704fb75550a 100644
--- a/code/game/objects/items/devices/gps.dm
+++ b/code/game/objects/items/devices/gps.dm
@@ -1,7 +1,7 @@
var/global/list/all_gps_units = list()
/obj/item/gps
name = "global coordinate system"
- desc = "A handheld relay used to triangulates the approximate co-ordinates of the device."
+ desc = "A handheld relay used to triangulate the approximate coordinates of the device in spacetime."
icon = 'icons/obj/items/device/locator.dmi'
icon_state = ICON_STATE_WORLD
origin_tech = @'{"materials":2,"programming":2,"wormholes":2}'
diff --git a/code/game/objects/items/devices/whistle.dm b/code/game/objects/items/devices/hailer.dm
similarity index 100%
rename from code/game/objects/items/devices/whistle.dm
rename to code/game/objects/items/devices/hailer.dm
diff --git a/code/game/objects/items/devices/modkit.dm b/code/game/objects/items/devices/modkit.dm
index d3d7035496c2..1bdc6b37d749 100644
--- a/code/game/objects/items/devices/modkit.dm
+++ b/code/game/objects/items/devices/modkit.dm
@@ -52,7 +52,7 @@
user.visible_message("\The [user] opens \the [src] and modifies \the [O].","You open \the [src] and modify \the [O].")
- I.refit_for_bodytype(target_bodytype)
+ I.refit_for_bodytype(target_bodytype, skip_rename = TRUE)
if (istype(I, /obj/item/clothing/head/helmet))
parts &= ~MODKIT_HELMET
diff --git a/code/game/objects/items/devices/personal_shield.dm b/code/game/objects/items/devices/personal_shield.dm
index 95be1abc4669..c83b7522cc8d 100644
--- a/code/game/objects/items/devices/personal_shield.dm
+++ b/code/game/objects/items/devices/personal_shield.dm
@@ -1,6 +1,6 @@
/obj/item/personal_shield
name = "personal shield"
- desc = "Truely a life-saver: this device protects its user from being hit by objects moving very, very fast, though only for a few shots."
+ desc = "Truly a lifesaver: this device protects its user from being hit by objects moving very, very fast, though only for a few shots."
icon = 'icons/obj/items/weapon/batterer.dmi'
icon_state = ICON_STATE_WORLD
material = /decl/material/solid/organic/plastic
diff --git a/code/game/objects/items/devices/radio/headsets_shared.dm b/code/game/objects/items/devices/radio/headsets_shared.dm
index 6c5551ea9839..ead756343e37 100644
--- a/code/game/objects/items/devices/radio/headsets_shared.dm
+++ b/code/game/objects/items/devices/radio/headsets_shared.dm
@@ -52,7 +52,7 @@
/obj/item/radio/headset/headset_sci
name = "science radio headset"
- desc = "A sciency headset. Like usual."
+ desc = "A science-y headset. Like usual."
icon = 'icons/obj/items/device/radio/headsets/headset_science.dmi'
encryption_keys = list(/obj/item/encryptionkey/sci)
@@ -63,7 +63,7 @@
/obj/item/radio/headset/headset_eng
name = "engineering radio headset"
- desc = "When the engineers wish to gossip like highschoolers."
+ desc = "When the engineers wish to gossip like high-schoolers."
icon = 'icons/obj/items/device/radio/headsets/headset_engineering.dmi'
encryption_keys = list(/obj/item/encryptionkey/eng)
diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm
index 0726d380a410..de538c7e0035 100644
--- a/code/game/objects/items/devices/radio/intercom.dm
+++ b/code/game/objects/items/devices/radio/intercom.dm
@@ -82,4 +82,5 @@
..(locked_frequency)
/obj/item/radio/intercom/locked/entertainment
- locked_frequency = 1461
\ No newline at end of file
+ broadcasting = TRUE
+ locked_frequency = 1461
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index 2e5b4f58e200..22eba630568e 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -380,13 +380,13 @@
var/list/timestamp = new/list()
var/ruined = 0
var/doctored = 0
+ /// Whether we draw the ruined ribbon overlay when ruined.
+ var/draw_ribbon_if_ruined = TRUE
-//draw_ribbon: Whether we draw the ruined ribbon overlay. Only used by quantum tape.
-//#FIXME: Probably should be handled better.
-/obj/item/magnetic_tape/on_update_icon(var/draw_ribbon = TRUE)
+/obj/item/magnetic_tape/on_update_icon()
. = ..()
icon_state = get_world_inventory_state()
- if(draw_ribbon && ruined && max_capacity)
+ if(draw_ribbon_if_ruined && ruined && max_capacity)
add_overlay(overlay_image(icon, "[icon_state]_ribbonoverlay", flags = RESET_COLOR))
/obj/item/magnetic_tape/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
@@ -524,13 +524,11 @@
desc = "Quantum-enriched self-repairing nanotape, used for magnetic storage of information."
icon = 'icons/obj/items/device/tape_recorder/tape_casette_loose.dmi'
ruined = TRUE
+ draw_ribbon_if_ruined = FALSE
/obj/item/magnetic_tape/loose/fix()
return
-/obj/item/magnetic_tape/loose/on_update_icon()
- . = ..(FALSE)
-
/obj/item/magnetic_tape/loose/get_loose_tape()
return
diff --git a/code/game/objects/items/flame/flame_fuelled_lighter_zippo.dm b/code/game/objects/items/flame/flame_fuelled_lighter_zippo.dm
index 6869f3eedd1d..50a734b487f1 100644
--- a/code/game/objects/items/flame/flame_fuelled_lighter_zippo.dm
+++ b/code/game/objects/items/flame/flame_fuelled_lighter_zippo.dm
@@ -1,6 +1,6 @@
/obj/item/flame/fuelled/lighter/zippo
name = "zippo lighter"
- desc = "It's a zippo-styled lighter, using a replacable flint in a fetching steel case. It makes a clicking sound that everyone loves."
+ desc = "It's a zippo-styled lighter, using a replaceable flint in a fetching steel case. It makes a clicking sound that everyone loves."
icon = 'icons/obj/items/flame/zippo.dmi'
max_fuel = 10
material = /decl/material/solid/metal/stainlesssteel
diff --git a/code/game/objects/items/flashlights/floodlamp.dm b/code/game/objects/items/flashlights/floodlamp.dm
index 3c8eb02b88ad..c98063000b84 100644
--- a/code/game/objects/items/flashlights/floodlamp.dm
+++ b/code/game/objects/items/flashlights/floodlamp.dm
@@ -1,7 +1,7 @@
//hand portable floodlights for emergencies. Less bulky than the large ones. But also less light. Unused green variant in the sheet.
/obj/item/flashlight/lamp/floodlamp
name = "flood lamp"
- desc = "A portable emergency flood light with a ultra-bright LED."
+ desc = "A portable emergency floodlight with a ultra-bright LED."
icon = 'icons/obj/lighting/floodlamp.dmi'
on = 0
w_class = ITEM_SIZE_LARGE
diff --git a/code/game/objects/items/flashlights/lavalamp.dm b/code/game/objects/items/flashlights/lavalamp.dm
index 92f434c88526..e5d123aa20a9 100644
--- a/code/game/objects/items/flashlights/lavalamp.dm
+++ b/code/game/objects/items/flashlights/lavalamp.dm
@@ -1,7 +1,7 @@
//Lava Lamps: Because we're already stuck in the 70ies with those fax machines.
/obj/item/flashlight/lamp/lava
name = "lava lamp"
- desc = "A kitchy throwback decorative light. Noir Edition."
+ desc = "A kitschy throwback decorative light. Noir Edition."
icon = 'icons/obj/lighting/lavalamp.dmi'
icon_state = "lavalamp"
on = 0
@@ -22,32 +22,32 @@
add_overlay(I)
/obj/item/flashlight/lamp/lava/red
- desc = "A kitchy red decorative light."
+ desc = "A kitschy red decorative light."
light_color = COLOR_RED
/obj/item/flashlight/lamp/lava/blue
- desc = "A kitchy blue decorative light"
+ desc = "A kitschy blue decorative light"
light_color = COLOR_BLUE
/obj/item/flashlight/lamp/lava/cyan
- desc = "A kitchy cyan decorative light"
+ desc = "A kitschy cyan decorative light"
light_color = COLOR_CYAN
/obj/item/flashlight/lamp/lava/green
- desc = "A kitchy green decorative light"
+ desc = "A kitschy green decorative light"
light_color = COLOR_GREEN
/obj/item/flashlight/lamp/lava/orange
- desc = "A kitchy orange decorative light"
+ desc = "A kitschy orange decorative light"
light_color = COLOR_ORANGE
/obj/item/flashlight/lamp/lava/purple
- desc = "A kitchy purple decorative light"
+ desc = "A kitschy purple decorative light"
light_color = COLOR_PURPLE
/obj/item/flashlight/lamp/lava/pink
- desc = "A kitchy pink decorative light"
+ desc = "A kitschy pink decorative light"
light_color = COLOR_PINK
/obj/item/flashlight/lamp/lava/yellow
- desc = "A kitchy yellow decorative light"
+ desc = "A kitschy yellow decorative light"
light_color = COLOR_YELLOW
diff --git a/code/game/objects/items/flashlights/misc.dm b/code/game/objects/items/flashlights/misc.dm
index d8fe75b4d740..cdd07f77f43b 100644
--- a/code/game/objects/items/flashlights/misc.dm
+++ b/code/game/objects/items/flashlights/misc.dm
@@ -15,7 +15,7 @@
/obj/item/flashlight/maglight
name = "maglight"
- desc = "A very, very heavy duty flashlight."
+ desc = "A very, very heavy-duty flashlight."
icon = 'icons/obj/lighting/maglight.dmi'
_base_attack_force = 10
attack_verb = list ("smacked", "thwacked", "thunked")
diff --git a/code/game/objects/items/paintkit.dm b/code/game/objects/items/paintkit.dm
index 576c58a9dc61..fc70e8902a54 100644
--- a/code/game/objects/items/paintkit.dm
+++ b/code/game/objects/items/paintkit.dm
@@ -71,12 +71,12 @@
// Mechs are handled in their attackby (mech_interaction.dm).
/obj/item/kit/paint
name = "exosuit decal kit"
- desc = "A kit containing all the needed tools and parts to repaint a exosuit."
+ desc = "A kit containing all the needed tools and parts to repaint an exosuit."
abstract_type = /obj/item/kit/paint
/obj/item/kit/paint/examine(mob/user)
. = ..()
- to_chat(user, "This kit will add a '[new_name]' decal to a exosuit'.")
+ to_chat(user, "This kit will add a '[new_name]' decal to an exosuit'.")
// exosuit kits.
/obj/item/kit/paint/flames_red
diff --git a/code/game/objects/items/rescuebag.dm b/code/game/objects/items/rescuebag.dm
index da10d3c85002..6e69603618ea 100644
--- a/code/game/objects/items/rescuebag.dm
+++ b/code/game/objects/items/rescuebag.dm
@@ -2,7 +2,7 @@
/obj/item/bodybag/rescue
name = "rescue bag"
desc = "A folded, reusable bag designed to prevent additional damage to an occupant, especially useful if short on time or in \
- a hostile enviroment."
+ a hostile environment."
icon = 'icons/obj/closets/rescuebag.dmi'
icon_state = "folded"
origin_tech = @'{"biotech":2}'
@@ -60,7 +60,7 @@
/obj/structure/closet/body_bag/rescue
name = "rescue bag"
desc = "A reusable plastic bag designed to prevent additional damage to an occupant, especially useful if short on time or in \
- a hostile enviroment."
+ a hostile environment."
icon = 'icons/obj/closets/rescuebag.dmi'
item_path = /obj/item/bodybag/rescue
storage_types = CLOSET_STORAGE_MOBS
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 061307ecad8b..1dd4881d7c09 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -203,7 +203,7 @@
else
R.module.equipment += new/obj/item/tank/jetpack/carbondioxide
for(var/obj/item/tank/jetpack/carbondioxide in R.module.equipment)
- R.internals = src
+ R.set_internals(src)
//R.icon_state="Miner+j"
return 1
diff --git a/code/game/objects/items/stacks/medical/medical_resin.dm b/code/game/objects/items/stacks/medical/medical_resin.dm
index 78d0ef6eea82..c7ab7c5f060c 100644
--- a/code/game/objects/items/stacks/medical/medical_resin.dm
+++ b/code/game/objects/items/stacks/medical/medical_resin.dm
@@ -1,7 +1,7 @@
/obj/item/stack/medical/resin
name = "resin patches"
singular_name = "resin patch"
- desc = "A resin-based patching kit used to repair crystalline bodyparts. The label is written in a colourful, angular, unreadable script."
+ desc = "A resin-based patching kit used to repair crystalline body parts. The label is written in a colourful, angular, unreadable script."
icon_state = "resin-pack"
heal_brute = 10
heal_burn = 10
@@ -12,7 +12,7 @@
/obj/item/stack/medical/resin/crafted
name = "resin globules"
- desc = "A lump of slick, shiny resin. Used to repair damage to crystalline bodyparts."
+ desc = "A lump of slick, shiny resin. Used to repair damage to crystalline body parts."
singular_name = "resin globule"
icon_state = "resin-lump"
heal_brute = 5
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index 02e51277a757..028e5a4a01a1 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -10,7 +10,7 @@
/obj/item/stack/tile
name = "tile"
singular_name = "tile"
- desc = "A non-descript floor tile."
+ desc = "A nondescript floor tile."
randpixel = 7
w_class = ITEM_SIZE_NORMAL
max_amount = 100
@@ -319,7 +319,7 @@
/obj/item/stack/tile/roof
name = "roofing tile"
singular_name = "roofing tile"
- desc = "A non-descript roofing tile."
+ desc = "A nondescript roofing tile."
matter_multiplier = 0.3
icon_state = "tile"
material = /decl/material/solid/metal/steel
diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/stools.dm b/code/game/objects/items/stools.dm
similarity index 100%
rename from code/game/objects/structures/stool_bed_chair_nest_sofa/stools.dm
rename to code/game/objects/items/stools.dm
diff --git a/code/game/objects/items/weapons/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm
similarity index 100%
rename from code/game/objects/items/weapons/tools/crowbar.dm
rename to code/game/objects/items/tools/crowbar.dm
diff --git a/code/game/objects/items/weapons/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm
similarity index 100%
rename from code/game/objects/items/weapons/tools/screwdriver.dm
rename to code/game/objects/items/tools/screwdriver.dm
diff --git a/code/game/objects/items/weapons/tools/shears.dm b/code/game/objects/items/tools/shears.dm
similarity index 100%
rename from code/game/objects/items/weapons/tools/shears.dm
rename to code/game/objects/items/tools/shears.dm
diff --git a/code/game/objects/items/weapons/tools/wirecutter.dm b/code/game/objects/items/tools/wirecutter.dm
similarity index 100%
rename from code/game/objects/items/weapons/tools/wirecutter.dm
rename to code/game/objects/items/tools/wirecutter.dm
diff --git a/code/game/objects/items/weapons/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm
similarity index 100%
rename from code/game/objects/items/weapons/tools/wrench.dm
rename to code/game/objects/items/tools/wrench.dm
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 53ec5ef987f7..6a100e476002 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -388,12 +388,12 @@
/obj/item/toy/figure/geneticist
name = "Geneticist action figure"
- desc = "A \"Space Life\" brand Geneticist action figure, which was recently dicontinued."
+ desc = "A \"Space Life\" brand Geneticist action figure, which was recently discontinued."
icon_state = "geneticist"
/obj/item/toy/figure/hop
- name = "Head of Personel action figure"
- desc = "A \"Space Life\" brand Head of Personel action figure."
+ name = "Head of Personnel action figure"
+ desc = "A \"Space Life\" brand Head of Personnel action figure."
icon_state = "hop"
/obj/item/toy/figure/hos
@@ -576,9 +576,7 @@
//Office Desk Toys
/obj/item/toy/desk
- name = "desk toy master"
- desc = "A object that does not exist. Parent Item"
-
+ abstract_type = /obj/item/toy/desk
var/on = 0
var/activation_sound = 'sound/effects/flashlight.ogg'
@@ -598,7 +596,7 @@
/obj/item/toy/desk/newtoncradle
name = "\improper Newton's cradle"
- desc = "A ancient 21th century super-weapon model demonstrating that Sir Isaac Newton is the deadliest sonuvabitch in space."
+ desc = "An ancient 21st century super-weapon model demonstrating that Sir Isaac Newton is the deadliest sonuvabitch in space."
icon_state = "newtoncradle"
/obj/item/toy/desk/fan
@@ -613,7 +611,7 @@
/obj/item/toy/desk/dippingbird
name = "dipping bird toy"
- desc = "A ancient human bird idol, worshipped by clerks and desk jockeys."
+ desc = "An ancient human bird idol, worshipped by clerks and desk jockeys."
icon_state= "dippybird"
// tg station ports
diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm
index 8c88b8edc0df..e41bd958bf21 100644
--- a/code/game/objects/items/trash.dm
+++ b/code/game/objects/items/trash.dm
@@ -166,7 +166,7 @@
/obj/item/trash/stick
name = "stick"
- desc = "a stick from some snack food item or a lollipop, not even useful as crafting material."
+ desc = "A stick from some snack food item or a lollipop, not even useful as crafting material."
icon_state = "stick"
/obj/item/trash/use_on_mob(mob/living/target, mob/living/user, animate = TRUE)
diff --git a/code/game/objects/items/waterskin.dm b/code/game/objects/items/waterskin.dm
index 73852feaef06..a9b1b3261a62 100644
--- a/code/game/objects/items/waterskin.dm
+++ b/code/game/objects/items/waterskin.dm
@@ -44,7 +44,7 @@
add_overlay(stopper_overlay)
/obj/item/chems/glass/waterskin/crafted
- desc = "A long and rather unwieldly water-carrying vessel."
+ desc = "A long and rather unwieldy water-carrying vessel."
icon = 'icons/obj/items/waterskin_crafted.dmi'
material = /decl/material/solid/organic/leather
color = /decl/material/solid/organic/leather::color
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index f367fe6ebb2a..e8e041f23016 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -75,7 +75,7 @@
icon_state = "data_2"
/obj/item/card/data/disk
- desc = "A plastic magstripe card for simple and speedy data storage and transfer. This one inexplicibly looks like a floppy disk."
+ desc = "A plastic magstripe card for simple and speedy data storage and transfer. This one inexplicably looks like a floppy disk."
icon_state = "data_3"
/obj/item/card/data/get_assembly_detail_color()
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index cdaab55ecaa5..5b9e2a62d934 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -465,7 +465,7 @@
/obj/item/shockpaddles/robot
name = "defibrillator paddles"
- desc = "A pair of advanced shockpaddles powered by a robot's internal power cell, able to penetrate thick clothing."
+ desc = "A pair of advanced shock paddles powered by a robot's internal power cell, able to penetrate thick clothing."
chargecost = 50
combat = 1
cooldowntime = (3 SECONDS)
@@ -542,7 +542,7 @@
*/
/obj/item/shockpaddles/standalone
- desc = "A pair of shockpaddles powered by an experimental miniaturized reactor" //Inspired by the advanced e-gun
+ desc = "A pair of shock paddles powered by an experimental miniaturized reactor" //Inspired by the advanced e-gun
var/fail_counter = 0
/obj/item/shockpaddles/standalone/Destroy()
diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm
index db8e711d5628..f67a1791c48d 100644
--- a/code/game/objects/items/weapons/dice.dm
+++ b/code/game/objects/items/weapons/dice.dm
@@ -1,6 +1,6 @@
/obj/item/dice
name = "d6"
- desc = "A dice with six sides."
+ desc = "A die with six sides."
icon = 'icons/obj/dice.dmi'
icon_state = "d66"
w_class = ITEM_SIZE_TINY
@@ -37,31 +37,31 @@
/obj/item/dice/d4
name = "d4"
- desc = "A dice with four sides."
+ desc = "A die with four sides."
icon_state = "d44"
sides = 4
/obj/item/dice/d8
name = "d8"
- desc = "A dice with eight sides."
+ desc = "A die with eight sides."
icon_state = "d88"
sides = 8
/obj/item/dice/d10
name = "d10"
- desc = "A dice with ten sides."
+ desc = "A die with ten sides."
icon_state = "d1010"
sides = 10
/obj/item/dice/d12
name = "d12"
- desc = "A dice with twelve sides."
+ desc = "A die with twelve sides."
icon_state = "d1212"
sides = 12
/obj/item/dice/d20
name = "d20"
- desc = "A dice with twenty sides."
+ desc = "A die with twenty sides."
icon_state = "d2020"
sides = 20
@@ -76,7 +76,7 @@
/obj/item/dice/d100
name = "d100"
- desc = "A dice with ten sides. This one is for the tens digit."
+ desc = "A die with ten sides. This one is for the tens digit."
icon_state = "d10010"
sides = 10
diff --git a/code/game/objects/items/weapons/ecigs.dm b/code/game/objects/items/weapons/ecigs.dm
index 0a55a70a9509..11fa6ec87de2 100644
--- a/code/game/objects/items/weapons/ecigs.dm
+++ b/code/game/objects/items/weapons/ecigs.dm
@@ -64,7 +64,7 @@
/obj/item/clothing/mask/smokable/ecig/deluxe
name = "deluxe electronic cigarette"
- desc = "A premium model eGavana MK3 electronic cigarette, shaped like a cigar."
+ desc = "A premium model eHavana MK3 electronic cigarette, shaped like a cigar."
icon = 'icons/clothing/mask/smokables/cigarette_electronic_deluxe.dmi'
/obj/item/clothing/mask/smokable/ecig/deluxe/setup_power_supply(loaded_cell_type, accepted_cell_type, power_supply_extension_type, charge_value)
diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm
index ee776a0e051e..b48963aecd7a 100644
--- a/code/game/objects/items/weapons/extinguisher.dm
+++ b/code/game/objects/items/weapons/extinguisher.dm
@@ -60,7 +60,7 @@
return
if(user.buckled && isobj(user.buckled))
addtimer(CALLBACK(src, PROC_REF(propel_object), user.buckled, user, get_dir(A, user)), 0)
- else if(!user.check_space_footing())
+ else if(user.can_slip(magboots_only = TRUE))
var/old_dir = user.dir
step(user, get_dir(A, user))
user.set_dir(old_dir)
diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm
index a59f5ec44ba6..62f1c7e3fe4a 100644
--- a/code/game/objects/items/weapons/gift_wrappaper.dm
+++ b/code/game/objects/items/weapons/gift_wrappaper.dm
@@ -9,7 +9,7 @@
*/
/obj/item/a_gift
name = "gift"
- desc = "PRESENTS!!!! eek!"
+ desc = "PRESENTS!!!! Eek!"
icon = 'icons/obj/items/gift_wrapped.dmi'
icon_state = "gift"
item_state = "gift"
diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm
index 69ac907bcac4..138a3b7df34c 100644
--- a/code/game/objects/items/weapons/grenades/flashbang.dm
+++ b/code/game/objects/items/weapons/grenades/flashbang.dm
@@ -91,7 +91,7 @@
detonate()
/obj/item/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve
- desc = "Use of this weapon may constiute a war crime in your area, consult your local captain."
+ desc = "Use of this weapon may constitute a war crime in your area, consult your local captain."
name = "clusterbang"
icon = 'icons/obj/items/grenades/clusterbang.dmi'
diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/locator.dm
similarity index 96%
rename from code/game/objects/items/weapons/teleportation.dm
rename to code/game/objects/items/weapons/locator.dm
index 3cb9f4a5dfcd..a6ad7b1def9d 100644
--- a/code/game/objects/items/weapons/teleportation.dm
+++ b/code/game/objects/items/weapons/locator.dm
@@ -1,15 +1,9 @@
-/* Teleportation devices.
- * Contains:
- * Locator
- * Hand-tele
- */
-
/*
* Locator
*/
/obj/item/locator
name = "locator"
- desc = "Used to track those with locater implants."
+ desc = "Used to track those with locator implants."
icon = 'icons/obj/items/device/locator.dmi'
icon_state = ICON_STATE_WORLD
var/temp = null
diff --git a/code/game/objects/items/weapons/material/coins.dm b/code/game/objects/items/weapons/material/coins.dm
index 19198cdc5bde..1cdd0270a96d 100644
--- a/code/game/objects/items/weapons/material/coins.dm
+++ b/code/game/objects/items/weapons/material/coins.dm
@@ -16,7 +16,7 @@
. = ..()
icon_state = "coin[rand(1,10)]"
if(material)
- desc = "A old-style coin stamped out of [material.solid_name]."
+ desc = "An old-style coin stamped out of [material.solid_name]."
set_extension(src, /datum/extension/tool, list(TOOL_SCREWDRIVER = TOOL_QUALITY_BAD))
// "Coin Flipping, A.wav" by InspectorJ (www.jshaw.co.uk) of Freesound.org
diff --git a/code/game/objects/items/weapons/material/folding.dm b/code/game/objects/items/weapons/material/folding.dm
index 38cfa3a24761..5d298afbd27b 100644
--- a/code/game/objects/items/weapons/material/folding.dm
+++ b/code/game/objects/items/weapons/material/folding.dm
@@ -62,7 +62,7 @@
/obj/item/knife/folding/tacticool
name = "folding knife"
- desc = "A small folding knife with a polymer handle and a blackened steel blade. These are typically marketed for self defense purposes."
+ desc = "A small folding knife with a polymer handle and a blackened steel blade. These are typically marketed for self-defense purposes."
icon = 'icons/obj/items/weapon/knives/folding/tacticool.dmi'
valid_handle_colors = list("#0f0f2a", "#2a0f0f", "#0f2a0f", COLOR_GRAY20, COLOR_DARK_GUNMETAL)
diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm
index 9df9b46dc099..fc19d7e17dd6 100644
--- a/code/game/objects/items/weapons/material/knives.dm
+++ b/code/game/objects/items/weapons/material/knives.dm
@@ -101,7 +101,7 @@
//random stuff
/obj/item/knife/hook
- name = "meat hook"
+ name = "hook"
desc = "A sharp, metal hook what sticks into things."
icon = 'icons/obj/items/weapon/knives/hook.dmi'
sharp = FALSE
@@ -119,7 +119,7 @@
//Utility knives
/obj/item/knife/utility
name = "utility knife"
- desc = "An utility knife with a polymer handle, commonly used through human space."
+ desc = "A utility knife with a polymer handle, commonly used through human space."
icon = 'icons/obj/items/weapon/knives/utility.dmi'
w_class = ITEM_SIZE_SMALL
draw_handle = TRUE
diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm
index 8040747110e6..3715ccf13ea0 100644
--- a/code/game/objects/items/weapons/material/misc.dm
+++ b/code/game/objects/items/weapons/material/misc.dm
@@ -37,7 +37,7 @@
/obj/item/harpoon/bomb/proc/handle_afterbomb()
spent = TRUE
SetName("broken harpoon")
- desc = "A short spear with just a barb - if it once had a spearhead, it doesn't any more."
+ desc = "A short spear with just a barb; if it once had a spearhead, it doesn't anymore."
icon_state = "harpoon_bomb_spent"
sharp = FALSE
edge = FALSE
diff --git a/code/game/objects/items/weapons/material/swiss.dm b/code/game/objects/items/weapons/material/swiss.dm
index 44f237dc8534..69d051a3aa9f 100644
--- a/code/game/objects/items/weapons/material/swiss.dm
+++ b/code/game/objects/items/weapons/material/swiss.dm
@@ -150,7 +150,7 @@
/obj/item/knife/folding/swiss/explorer
name = "explorer's combi-knife"
- desc = "A small, purple, multi-purpose folding knife. This one adds a wood saw and pry bar."
+ desc = "A small, purple, multi-purpose folding knife. This one adds a wood saw and prybar."
handle_color = COLOR_PURPLE
tools = list(SWISSKNF_LBLADE, SWISSKNF_SBLADE, SWISSKNF_CLIFTER, SWISSKNF_COPENER, SWISSKNF_WBLADE, SWISSKNF_CROWBAR)
diff --git a/code/game/objects/items/weapons/nuclear_cylinder.dm b/code/game/objects/items/weapons/nuclear_cylinder.dm
index 24f097cf1e18..8e5f910bb93c 100644
--- a/code/game/objects/items/weapons/nuclear_cylinder.dm
+++ b/code/game/objects/items/weapons/nuclear_cylinder.dm
@@ -1,6 +1,6 @@
/obj/item/nuclear_cylinder
name = "\improper nuclear cylinder"
- desc = "This cylinder is used in the self destruct system of the ship."
+ desc = "This cylinder is used in the self-destruct system of the ship."
icon = 'icons/obj/items/nuclear_cylinder.dmi'
icon_state = "nuclear_cylinder"
item_state = "nuclear"
diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm
deleted file mode 100644
index 81ae83daba05..000000000000
--- a/code/game/objects/items/weapons/policetape.dm
+++ /dev/null
@@ -1,569 +0,0 @@
-#define MAX_BARRICADE_TAPE_LENGTH 32 //Maximum length of a continuous line of tape someone can place down.
-#define TAPE_BARRICADE_V_NEIGHBORS (NORTH | SOUTH)
-#define TAPE_BARRICADE_H_NEIGHBORS (EAST | WEST)
-#define TAPE_BARRICADE_IS_CORNER_NEIGHBORS(X) ((X ^ TAPE_BARRICADE_V_NEIGHBORS) && (X ^ TAPE_BARRICADE_H_NEIGHBORS))
-#define TAPE_BARRICADE_IS_V_NEIGHBORS(X) ((X & TAPE_BARRICADE_V_NEIGHBORS) == TAPE_BARRICADE_V_NEIGHBORS && !((X & TAPE_BARRICADE_H_NEIGHBORS) == TAPE_BARRICADE_H_NEIGHBORS)) //Check we have neighbors connection on the vertical plane
-#define TAPE_BARRICADE_IS_H_NEIGHBORS(X) ((X & TAPE_BARRICADE_H_NEIGHBORS) == TAPE_BARRICADE_H_NEIGHBORS && !((X & TAPE_BARRICADE_V_NEIGHBORS) == TAPE_BARRICADE_V_NEIGHBORS)) //Check we have neighbors connection on the horizontal plane
-#define TAPE_BARRICADE_IS_3W_V_NEIGHBORS(X) (TAPE_BARRICADE_IS_V_NEIGHBORS(X) && ((X & TAPE_BARRICADE_H_NEIGHBORS) > 0))
-#define TAPE_BARRICADE_IS_3W_H_NEIGHBORS(X) (TAPE_BARRICADE_IS_H_NEIGHBORS(X) && ((X & TAPE_BARRICADE_V_NEIGHBORS) > 0))
-#define TAPE_BARRICADE_IS_4W_NEIGHBORS(X) (((X & TAPE_BARRICADE_V_NEIGHBORS) == TAPE_BARRICADE_V_NEIGHBORS) && ((X & TAPE_BARRICADE_H_NEIGHBORS) == TAPE_BARRICADE_H_NEIGHBORS))
-#define CONNECTION_BITS_TO_TEXT(X) "[(X & WEST) > 0][(X & EAST) > 0][(X & SOUTH) > 0][(X & NORTH) > 0]"
-#define TAPE_BARRICADE_GET_NB_NEIGHBORS(X) (((X & NORTH) > 0) + ((X & SOUTH) > 0) + ((X & EAST) > 0) + ((X & WEST) > 0))
-
-var/global/list/image/hazard_overlays //Cached hazard floor overlays for the barricade tape
-
-////////////////////////////////////////////////////////////////////
-// Barricade Tape Template
-////////////////////////////////////////////////////////////////////
-//Singletons with data on the various templates of barricade tape
-/decl/barricade_tape_template
- var/tape_kind = "barricade" //Used as a prefix to the word "tape" when refering to the tape and roll
- var/tape_desc = "A tape barricade." //Description for the tape barricade
- var/roll_desc = "A roll of barricade tape." //Description for the tape roll
- var/icon_file = 'icons/policetape.dmi' //Icon file used for both the tape and roll
- var/base_icon_state = "tape" //For the barricade. Icon state used to fetch the applied tape directional icons for various states
- var/list/req_access //Access required to automatically pass through tape barricades
- var/tape_color //Color of the tape
- var/detail_overlay //Overlay for the applied tape
- var/detail_color //Color for the detail overlay
-
-/decl/barricade_tape_template/proc/make_line_barricade(var/mob/user, var/turf/T, var/pdir)
- var/obj/structure/tape_barricade/bar = new(T,,,src)
- bar.add_fingerprint(user)
- return bar
-
-/decl/barricade_tape_template/proc/make_door_barricade(var/mob/user, var/obj/door)
- var/obj/structure/tape_barricade/door/bar = new(get_turf(door))
- bar.set_tape_template(src)
- bar.set_dir(door.dir)
- bar.add_fingerprint(user)
- return bar
-
-////////////////////////////////////////////////////////////////////
-// Barricade Tape Roll
-////////////////////////////////////////////////////////////////////
-/obj/item/stack/tape_roll/barricade_tape
- name = "barricade tape roll"
- desc = "A roll of high visibility, non-sticky barricade tape. Used to deter passersby from crossing it."
- icon = 'icons/policetape.dmi'
- icon_state = "tape"
- w_class = ITEM_SIZE_SMALL
- var/tmp/turf/start //The turf we started unrolling from
- var/tmp/weakref/unroller //The mob currently unrolling us
- var/decl/barricade_tape_template/tape_template //Template containing details on how the tape roll will look and behave, along with what it will place down
-
-/obj/item/stack/tape_roll/barricade_tape/Initialize()
- . = ..()
- apply_template()
-
-/obj/item/stack/tape_roll/barricade_tape/Destroy()
- stop_unrolling()
- return ..()
-
-/**Update our appearence and data to match the specified tape template. */
-/obj/item/stack/tape_roll/barricade_tape/proc/apply_template()
- if(ispath(tape_template))
- tape_template = GET_DECL(tape_template)
- if(!tape_template)
- return
-
- SetName("[tape_template.tape_kind] tape roll")
- desc = tape_template.roll_desc
- icon = tape_template.icon_file
- set_color(tape_template.tape_color)
- update_icon()
-
-/obj/item/stack/tape_roll/barricade_tape/on_update_icon()
- . = ..()
- if(ismob(loc))
- add_overlay(overlay_image(icon, start? "stop" : "start", flags = RESET_COLOR))
-
-/obj/item/stack/tape_roll/barricade_tape/dropped(mob/user)
- stop_unrolling()
- update_icon()
- return ..()
-
-/obj/item/stack/tape_roll/barricade_tape/on_picked_up(mob/user)
- stop_unrolling()
- update_icon()
- return ..()
-
-/obj/item/stack/tape_roll/barricade_tape/attack_hand()
- . = ..()
- if(. && !QDELETED(src))
- update_icon()
-
-/**Callback used when whoever holds us moved to a new turf. */
-/obj/item/stack/tape_roll/barricade_tape/proc/user_moved_unrolling(var/mob/M, var/atom/old_loc, var/atom/new_loc)
- if(QDELETED(src))
- return //Destructor will handle the rest
- if(QDELETED(M) || !can_use(1) || M.incapacitated())
- stop_unrolling()
- return
-
- if((old_loc.x != new_loc.x && old_loc.y != new_loc.y) || old_loc.z != new_loc.z)
- to_chat(M, SPAN_WARNING("\The [src] can only be laid horizontally or vertically."))
- stop_unrolling()
- return
- //Use a length of tape and place a barricade line
- if(!place_line(M, new_loc, get_dir(old_loc, new_loc)))
- stop_unrolling()
- return
- if(get_dist(start, new_loc) >= MAX_BARRICADE_TAPE_LENGTH)
- to_chat(M, SPAN_WARNING("You've stretched this line of tape to the maximum!"))
- stop_unrolling()
- return
-
-/obj/item/stack/tape_roll/barricade_tape/proc/stop_unrolling()
- if(!start && !unroller)
- return
- var/mob/_uroller = unroller.resolve()
- if(_uroller)
- events_repository.unregister(/decl/observ/moved, _uroller, src, PROC_REF(user_moved_unrolling))
- unroller = null
- start = null
- slowdown_general = initial(slowdown_general)
- if(_uroller)
- to_chat(_uroller, SPAN_NOTICE("You stop unrolling \the [src]."))
- if(!QDELETED(src))
- update_icon()
- return TRUE
-
-/obj/item/stack/tape_roll/barricade_tape/proc/start_unrolling(var/mob/user)
- if(start && unroller)
- return
- start = get_turf(src)
- unroller = weakref(user)
- slowdown_general = initial(slowdown_general) + 2 //While unrolling you're slightly slower
- events_repository.unregister(/decl/observ/moved, user, src, PROC_REF(user_moved_unrolling))
- events_repository.register(/decl/observ/moved, user, src, PROC_REF(user_moved_unrolling))
- to_chat(user, SPAN_NOTICE("You start unrolling \the [src]."))
- //Place the first one immediately
- place_line(user, get_turf(user), user.dir)
- update_icon()
- return TRUE
-
-/**Place a tape line on the current turf. */
-/obj/item/stack/tape_roll/barricade_tape/proc/place_line(var/mob/user, var/turf/T, var/pdir)
- if(!T || T.is_open() || T.is_wall())
- to_chat(user, SPAN_WARNING("You can't place tape here!"))
- return
- if(locate(/obj/structure/tape_barricade) in T)
- return //Can't place 2 on the same tile!
-
- if(!can_use(1))
- to_chat(user, SPAN_WARNING("You are out of [tape_template.tape_kind] tape!"))
- return
- use(1)
- playsound(user, 'sound/effects/pageturn2.ogg', 50, TRUE)
-
- var/obj/structure/tape_barricade/barricade = tape_template.make_line_barricade(user, T, pdir)
- if(barricade)
- barricade.matter = matter_per_piece?.Copy()
- barricade.update_neighbors()
- return barricade
-
-/obj/item/stack/tape_roll/barricade_tape/attack_self(mob/user)
- if(start)
- stop_unrolling()
- return
- if(!can_use(1))
- return //This shouldn't happen, but if it does, don't let them exploit it
-
- start_unrolling(user)
-
-/obj/item/stack/tape_roll/barricade_tape/afterattack(var/atom/A, mob/user, proximity)
- if(!proximity)
- return
-
- if (istype(A, /obj/machinery/door/airlock))
- if(!can_use(4))
- to_chat(user, SPAN_WARNING("There isn't enough [plural_name] in \the [src] to barricade \the [A]. You need at least 4 [plural_name]."))
- return
-
- var/obj/structure/tape_barricade/door/bar = tape_template.make_door_barricade(user, A)
- if(bar)
- bar.matter = matter_per_piece?.Copy()
- if(bar.matter)
- for(var/mat in bar.matter)
- bar.matter[mat] = round(bar.matter[mat] * 4)
-
- to_chat(user, SPAN_NOTICE("You finish placing \the [src]."))
- use(4)
-
-////////////////////////////////////////////////////////////////////
-// Tape Line Barricade
-////////////////////////////////////////////////////////////////////
-/obj/structure/tape_barricade
- name = "tape line"
- desc = "A line of barricade tape."
- icon = 'icons/policetape.dmi'
- icon_state = "tape_2w_0"
- dir = SOUTH //This structure will try to turn its icon depending on what neighbors it has
- layer = ABOVE_DOOR_LAYER
- pass_flags = PASS_FLAG_TABLE //About the height of table
- anchored = TRUE
- material = /decl/material/solid/organic/plastic
- current_health = 5
- var/neighbors = 0 //Contains all the direction flags of all the neighboring tape_barricades
- var/is_lifted = 0 //Whether the tape is lifted and we're allowing everyone passage.
- var/is_crumpled = 0 //Whether the tape was damaged
- var/decl/barricade_tape_template/tape_template //Details about the behavior and looks of the barricade
-
-/obj/structure/tape_barricade/Initialize(ml, _mat, _reinf_mat, var/decl/barricade_tape_template/_tape_template)
- . = ..()
- if(!hazard_overlays)
- hazard_overlays = list()
- hazard_overlays["[NORTH]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "N")
- hazard_overlays["[EAST]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "E")
- hazard_overlays["[SOUTH]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "S")
- hazard_overlays["[WEST]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "W")
- set_tape_template(_tape_template)
-
-/obj/structure/tape_barricade/LateInitialize()
- . = ..()
- build_connection_bits()
- update_neighbors()
-
-/obj/structure/tape_barricade/Destroy()
- var/turf/old_loc = get_turf(src)
- . = ..()
- if(istype(old_loc))
- update_neighbors(old_loc)
-
-/obj/structure/tape_barricade/proc/set_tape_template(var/decl/barricade_tape_template/tmpl)
- if(tmpl)
- tape_template = tmpl
- if(ispath(tape_template))
- tape_template = GET_DECL(tape_template)
- if(!tape_template)
- return
-
- SetName("[tape_template.tape_kind] tape line")
- desc = tape_template.tape_desc
- icon = tape_template.icon_file
- req_access = tape_template.req_access
- set_color(tape_template.tape_color)
- update_icon()
-
-/**Cause neighbors to update their icon. */
-/obj/structure/tape_barricade/proc/update_neighbors(var/location = loc)
- for (var/look_dir in global.cardinal)
- var/obj/structure/tape_barricade/B = locate(/obj/structure/tape_barricade, get_step(location, look_dir))
- if(!QDELETED(B))
- B.update_icon()
-
- if(!QDELETED(src))
- update_icon()
-
-/**Updates our connection bits to keep track of the things we're connected to */
-/obj/structure/tape_barricade/proc/build_connection_bits()
- neighbors = 0
- for (var/look_dir in global.cardinal)
- var/turf/target_turf = get_step(src, look_dir)
- if(target_turf)
- var/obj/structure/tape_barricade/B = locate(/obj/structure/tape_barricade) in target_turf
- //We connect to walls and other tape_barricades
- if((B && !QDELETED(B)) || (!B && target_turf.is_wall()))
- neighbors |= look_dir
-
-/**Allow sutypes to override with their own forced icon state name.*/
-/obj/structure/tape_barricade/proc/icon_name_override()
- return
-
-/obj/structure/tape_barricade/on_update_icon()
- . = ..()
- if(isnull(tape_template) || ispath(tape_template))
- return
- //Look up our neighbors
- build_connection_bits()
-
- var/icon_name = icon_name_override()
- if(!icon_name)
- //Build the icon state from whethere we've got a right angle with out neighbors or not
- if(TAPE_BARRICADE_IS_4W_NEIGHBORS(neighbors))
- set_dir(SOUTH)
- icon_name = "4w"
-
- //3 Ways
- else if(TAPE_BARRICADE_IS_3W_H_NEIGHBORS(neighbors))
- set_dir(neighbors & TAPE_BARRICADE_V_NEIGHBORS)
- icon_name = "3w"
- else if(TAPE_BARRICADE_IS_3W_V_NEIGHBORS(neighbors))
- set_dir(neighbors & TAPE_BARRICADE_H_NEIGHBORS)
- icon_name = "3w"
-
- //Lines
- else if(TAPE_BARRICADE_IS_H_NEIGHBORS(neighbors))
- set_dir(EAST)
- icon_name = "2w"
- else if(TAPE_BARRICADE_IS_V_NEIGHBORS(neighbors))
- set_dir(SOUTH)
- icon_name = "2w"
-
- //Endpoints/corners
- else
- if(neighbors > 0)
- set_dir(neighbors) //Make sure if we have no connections we don't set a bad dir
- icon_name = "dir"
-
- icon_state = "[tape_template.base_icon_state]_[icon_name]_[is_crumpled]"
-
- //Overlays
- if(tape_template.detail_overlay)
- var/image/ovr = overlay_image(icon, "[tape_template.base_icon_state]_[icon_name]_[tape_template.detail_overlay]", tape_template.detail_color, RESET_COLOR)
- ovr.dir = dir
- add_overlay(ovr)
-
-/obj/structure/tape_barricade/attack_hand(mob/user)
-
- if(user.check_intent(I_FLAG_HARM))
- user.visible_message(SPAN_DANGER("\The [user] tears \the [src]!"))
- physically_destroyed()
- return TRUE
-
- if (!user.check_intent(I_FLAG_HELP) || !allowed(user) || !user.check_dexterity(DEXTERITY_SIMPLE_MACHINES, TRUE))
- return ..()
-
- if(TAPE_BARRICADE_IS_CORNER_NEIGHBORS(neighbors) || (TAPE_BARRICADE_GET_NB_NEIGHBORS(neighbors) > 2))
- to_chat(user, SPAN_WARNING("You can't lift up the pole. Try lifting the line itself."))
- return TRUE
-
- if(!allowed(user))
- user.visible_message(SPAN_NOTICE("\The [user] carelessly pulls \the [src] out of the way."))
- crumple()
- else
- user.visible_message(SPAN_NOTICE("\The [user] lifts \the [src], officially allowing passage."))
-
- for(var/obj/structure/tape_barricade/B in get_tape_line())
- B.lift(10 SECONDS) //~10 seconds
- return TRUE
-
-/obj/structure/tape_barricade/dismantle_structure(mob/user)
- for (var/obj/structure/tape_barricade/B in get_tape_line())
- if(B == src || QDELETED(B))
- continue
- if(B.neighbors & get_dir(B, src))
- B.physically_destroyed()
- . = ..()
-
-/obj/structure/tape_barricade/CanPass(atom/movable/mover, turf/target, height, air_group)
- if(!is_lifted && ismob(mover))
- var/mob/M = mover
- if (!allowed(M) && M.check_intent(I_FLAG_HELP))
- return FALSE
- return ..()
-
-/obj/structure/tape_barricade/Crossed(atom/movable/AM)
- . = ..()
- if(is_lifted || !isliving(AM))
- return
- var/mob/living/M = AM
- add_fingerprint(M)
- shake_animation(2)
- if (!allowed(M)) //only select few learn art of not crumpling the tape
- to_chat(M, SPAN_NOTICE("You are not supposed to go past \the [src]..."))
- if(!M.check_intent(I_FLAG_HELP))
- crumple()
-
-/obj/structure/tape_barricade/proc/crumple()
- if(!is_crumpled)
- playsound(src, 'sound/effects/rip1.ogg', 60, TRUE)
- take_damage(5)
- is_crumpled = TRUE
- update_icon()
-
-/**Temporarily lifts the tape line, allowing passage to anyone for the specified time, until the timer expires. */
-/obj/structure/tape_barricade/proc/lift(var/time)
- if(!is_lifted)
- is_lifted = TRUE
- layer = ABOVE_HUMAN_LAYER
- pass_flags = PASS_FLAG_MOB
- pixel_y += 8
- addtimer(CALLBACK(src, PROC_REF(on_unlift)), time, TIMER_UNIQUE)
- playsound(src, 'sound/effects/pageturn2.ogg', 50, TRUE)
-
-/**Called by timer when the tape line falls back in place. */
-/obj/structure/tape_barricade/proc/on_unlift()
- is_lifted = FALSE
- pass_flags = initial(pass_flags)
- reset_plane_and_layer()
- pixel_y -= 8
- playsound(src, 'sound/effects/pageturn2.ogg', 20, TRUE)
-
-// Returns a list of all tape objects connected to src, including itself.
-/obj/structure/tape_barricade/proc/get_tape_line(var/list/ignored, var/line_index = 0)
- //Don't include more in the line than this
- if(line_index >= MAX_BARRICADE_TAPE_LENGTH)
- return list()
-
- var/list/dirs = list()
- if(neighbors & NORTH)
- dirs += NORTH
- if(neighbors & SOUTH)
- dirs += SOUTH
- if(neighbors & WEST)
- dirs += WEST
- if(neighbors & EAST)
- dirs += EAST
-
- //Grab all cached connected neighbors
- LAZYDISTINCTADD(ignored, src)
- var/list/obj/structure/tape_barricade/tapeline = list(src)
- for(var/look_dir in dirs)
- var/turf/T = get_step(src, look_dir)
- var/obj/structure/tape_barricade/B = locate() in T
- if(!QDELETED(B) && !(B in ignored))
- if(TAPE_BARRICADE_IS_CORNER_NEIGHBORS(neighbors) || (TAPE_BARRICADE_GET_NB_NEIGHBORS(neighbors) > 2))
- continue //We stop at intersections, and corners
- tapeline += B.get_tape_line(ignored, line_index + 1) //Pass us to prevent infinite loops, and adding us to the resulting line
- return tapeline
-
-////////////////////////////////////////////////////////////////////
-// Door Tape Barricade
-////////////////////////////////////////////////////////////////////
-
-//Barricade over a single door
-/obj/structure/tape_barricade/door
- icon_state = "tape_door_0"
- layer = ABOVE_DOOR_LAYER
-
-/obj/structure/tape_barricade/door/update_neighbors()
- //We completely ignore neighbors
- neighbors = 0
-
-/obj/structure/tape_barricade/door/icon_name_override()
- return "door" //Override the icon picking to pick this icon label instead
-
-////////////////////////////////////////////////////////////////////
-// Police Tape
-////////////////////////////////////////////////////////////////////
-/decl/barricade_tape_template/police
- tape_kind = "police"
- tape_desc = "A length of police tape. Do not cross."
- roll_desc = "A roll of police tape used to block off crime scenes from the public."
- tape_color = COLOR_RED
- req_access = list(access_security)
-
-/obj/item/stack/tape_roll/barricade_tape/police
- tape_template = /decl/barricade_tape_template/police
-
-//mapper type
-/obj/structure/tape_barricade/police
- icon_state = "tape_door_0"
- color = COLOR_RED
- tape_template = /decl/barricade_tape_template/police
-
-////////////////////////////////////////////////////////////////////
-// Engineering Tape
-////////////////////////////////////////////////////////////////////
-/decl/barricade_tape_template/engineering
- tape_kind = "engineering"
- tape_desc = "A length of engineering tape. Better not cross it."
- roll_desc = "A roll of engineering tape used to block off working areas from the public."
- tape_color = COLOR_ORANGE
- req_access = list(list(access_engine,access_atmospherics))
-
-/obj/item/stack/tape_roll/barricade_tape/engineering
- tape_template = /decl/barricade_tape_template/engineering
-
-//mapper type
-/obj/structure/tape_barricade/engineering
- icon_state = "stripetape_door_0"
- color = COLOR_ORANGE
- tape_template = /decl/barricade_tape_template/engineering
-
-////////////////////////////////////////////////////////////////////
-// Atmospheric Tape
-////////////////////////////////////////////////////////////////////
-/decl/barricade_tape_template/atmos
- tape_kind = "atmospherics"
- tape_desc = "A length of atmospherics tape. Better not cross it."
- roll_desc = "A roll of atmospherics tape used to block off working areas from the public."
- tape_color = COLOR_BLUE_LIGHT
- req_access = list(list(access_engine,access_atmospherics))
- base_icon_state = "stripetape"
- detail_overlay = "stripes"
- detail_color = COLOR_YELLOW
-
-/obj/item/stack/tape_roll/barricade_tape/atmos
- tape_template = /decl/barricade_tape_template/atmos
-
-//mapper type
-/obj/structure/tape_barricade/atmos
- icon_state = "stripetape_h_0"
- color = COLOR_BLUE_LIGHT
- tape_template = /decl/barricade_tape_template/atmos
-
-////////////////////////////////////////////////////////////////////
-// Research Tape
-////////////////////////////////////////////////////////////////////
-/decl/barricade_tape_template/research
- tape_kind = "research"
- tape_desc = "A length of research tape. Better not cross it."
- roll_desc = "A roll of research tape used to block off working areas from the public."
- tape_color = COLOR_WHITE
- req_access = list(access_research)
-
-/obj/item/stack/tape_roll/barricade_tape/research
- tape_template = /decl/barricade_tape_template/research
-
-//mapper type
-/obj/structure/tape_barricade/research
- color = COLOR_WHITE
- tape_template = /decl/barricade_tape_template/research
-
-////////////////////////////////////////////////////////////////////
-// Medical Tape
-////////////////////////////////////////////////////////////////////
-/decl/barricade_tape_template/medical
- tape_kind = "medical"
- tape_desc = "A length of medical tape. Better not cross it."
- roll_desc = "A roll of medical tape used to block off working areas from the public."
- tape_color = COLOR_PALE_BLUE_GRAY
- req_access = list(access_medical)
- base_icon_state = "stripetape"
- detail_overlay = "stripes"
- detail_color = COLOR_PALE_BLUE_GRAY
-
-/obj/item/stack/tape_roll/barricade_tape/medical
- tape_template = /decl/barricade_tape_template/medical
-
-//mapper type
-/obj/structure/tape_barricade/medical
- icon_state = "stripetape_h_0"
- color = COLOR_PALE_BLUE_GRAY
- tape_template = /decl/barricade_tape_template/medical
-
-////////////////////////////////////////////////////////////////////
-// Bureacratic Tape
-////////////////////////////////////////////////////////////////////
-/decl/barricade_tape_template/bureaucracy
- tape_kind = "red"
- tape_desc = "A length of bureaucratic red tape. Safely ignored, but darn obstructive sometimes."
- roll_desc = "A roll of bureaucratic red tape used to block any meaningful work from being done."
- tape_color = COLOR_RED
- base_icon_state = "stripetape"
- detail_overlay = "stripes"
- detail_color = COLOR_RED
-
-/obj/item/stack/tape_roll/barricade_tape/bureaucracy
- tape_template = /decl/barricade_tape_template/bureaucracy
-
-//mapper type
-/obj/structure/tape_barricade/bureaucracy
- icon_state = "stripetape_h_0"
- color = COLOR_RED
- tape_template = /decl/barricade_tape_template/bureaucracy
-
-#undef MAX_BARRICADE_TAPE_LENGTH
-#undef TAPE_BARRICADE_IS_CORNER_NEIGHBORS
-#undef TAPE_BARRICADE_V_NEIGHBORS
-#undef TAPE_BARRICADE_H_NEIGHBORS
-#undef TAPE_BARRICADE_IS_V_NEIGHBORS
-#undef TAPE_BARRICADE_IS_H_NEIGHBORS
-#undef TAPE_BARRICADE_IS_3W_V_NEIGHBORS
-#undef TAPE_BARRICADE_IS_3W_H_NEIGHBORS
-#undef TAPE_BARRICADE_IS_4W_NEIGHBORS
-#undef CONNECTION_BITS_TO_TEXT
-#undef TAPE_BARRICADE_GET_NB_NEIGHBORS
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index fb4d2bb67566..7a234732c98e 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -410,7 +410,7 @@
/obj/item/backpack/messenger/chem
name = "pharmacy messenger bag"
- desc = "A serile backpack worn over one shoulder. This one is in Chemistry colors."
+ desc = "A sterile backpack worn over one shoulder. This one is in Chemistry colors."
icon = 'icons/obj/items/storage/backpack/messenger_chem.dmi'
/obj/item/backpack/messenger/med
diff --git a/code/game/objects/items/weapons/storage/basket.dm b/code/game/objects/items/weapons/storage/basket.dm
index 8c7661451a91..b16df16f5755 100644
--- a/code/game/objects/items/weapons/storage/basket.dm
+++ b/code/game/objects/items/weapons/storage/basket.dm
@@ -22,4 +22,4 @@
icon = 'icons/obj/items/storage/baskets/basket_large.dmi'
w_class = ITEM_SIZE_GARGANTUAN
storage = /datum/storage/basket/large
- slowdown_general = 1 // Large and unwieldly
+ slowdown_general = 1 // Large and unwieldy
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 639d83a17547..0b46f4484c5e 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -284,7 +284,7 @@
/obj/item/box/trackimp
name = "boxed tracking implant kit"
- desc = "Box full of scum-bag tracking utensils."
+ desc = "Box full of scumbag-tracking utensils."
icon_state = "implant"
/obj/item/box/trackimp/WillContain()
return list(/obj/item/implantcase/tracking = 4,
@@ -359,11 +359,18 @@
/obj/item/box/animal_cubes/spiders
name = "spiderling cube box"
- desc = "Drymate brand Instant spiders. WHY WOULD YOU ORDER THIS!?"
+ desc = "Drymate brand spider cubes. WHY WOULD YOU ORDER THIS!?"
/obj/item/box/animal_cubes/spiders/WillContain()
return list(/obj/item/food/animal_cube/wrapped/spider = 5)
+/obj/item/box/animal_cubes/carp
+ name = "space carp cube box"
+ desc = "Drymate brand carp cubes. Allergen information: May contain traces of pike."
+
+/obj/item/box/animal_cubes/carp/WillContain()
+ return list(/obj/item/food/animal_cube/wrapped/carp = 5)
+
/obj/item/box/ids
name = "box of spare IDs"
desc = "Has so many empty IDs."
@@ -567,7 +574,7 @@
/obj/item/box/armband/engine
name = "box of spare engineering armbands"
- desc = "A box full of engineering armbands. For use in emergencies when provisional engineering peronnel are needed."
+ desc = "A box full of engineering armbands. For use in emergencies when provisional engineering personnel are needed."
/obj/item/box/armband/engine/WillContain()
return list(/obj/item/clothing/armband/engine = 5)
@@ -717,7 +724,7 @@
/obj/item/box/parts_pack
name = "parts pack"
- desc = "A densely-stuffed box containing some small eletrical parts."
+ desc = "A densely-stuffed box containing some small electrical parts."
icon = 'icons/obj/items/storage/part_pack.dmi'
icon_state = "part"
w_class = ITEM_SIZE_SMALL
diff --git a/code/game/objects/items/weapons/storage/misc.dm b/code/game/objects/items/weapons/storage/misc.dm
index 1a0d7dd5c71f..921f48977969 100644
--- a/code/game/objects/items/weapons/storage/misc.dm
+++ b/code/game/objects/items/weapons/storage/misc.dm
@@ -93,7 +93,7 @@
/obj/item/chewables/rollable/fine
name = "bag of Golden Sol tobacco"
- desc = "A exclusive brand of overpriced tobacco, allegedly grown at a lagrange point station in Sol system."
+ desc = "An exclusive brand of overpriced tobacco, allegedly grown at a lagrange point station in Sol system."
icon_state = "rollfine"
/obj/item/chewables/rollable/fine/WillContain()
@@ -132,7 +132,7 @@
/obj/item/chewables/candy/cookies
name = "pack of Getmore Cookies"
- desc = "A pack of delicious cookies, and possibly the only product in Getmores Chocolate Corp lineup that has any trace of chocolate in it."
+ desc = "A pack of delicious cookies, and possibly the only product in Getmore Chocolate Corp's lineup that has any trace of chocolate in it."
icon_state = "cookiebag"
storage = /datum/storage/chewables/cookies
diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm
index 44fa64eac6f0..a69f68703139 100644
--- a/code/game/objects/items/weapons/tanks/jetpack.dm
+++ b/code/game/objects/items/weapons/tanks/jetpack.dm
@@ -36,7 +36,7 @@
src.stabilization_on = !( src.stabilization_on )
to_chat(usr, "You toggle the stabilization [stabilization_on? "on":"off"].")
-/obj/item/tank/jetpack/on_update_icon(override)
+/obj/item/tank/jetpack/on_update_icon()
. = ..()
if(on)
add_overlay("[icon_state]-on")
@@ -110,8 +110,8 @@
starting_pressure = list(/decl/material/gas/carbon_dioxide = 6 ATM)
/obj/item/tank/jetpack/rig
- name = "integrated manuvering module thrusterpack"
- desc = "The 'manuvering' part of a manuvering jet module for a hardsuit. You could... probably use this standalone?"
+ name = "integrated maneuvering module thrusterpack"
+ desc = "The 'maneuvering' part of a maneuvering jet module for a hardsuit. You could... probably use this standalone?"
starting_pressure = list(/decl/material/gas/oxygen = 6 ATM)
var/obj/item/rig/holder
diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm
index 2a25e4e607fe..f5b1580e8a67 100644
--- a/code/game/objects/items/weapons/tanks/tank_types.dm
+++ b/code/game/objects/items/weapons/tanks/tank_types.dm
@@ -87,8 +87,8 @@
w_class = ITEM_SIZE_NORMAL
/obj/item/tank/emergency/oxygen/double/red //firefighting tank, fits on belt, back or suitslot
- name = "self contained breathing apparatus"
- desc = "A self contained breathing apparatus, well known as SCBA. Generally filled with oxygen."
+ name = "self-contained breathing apparatus"
+ desc = "A self-contained breathing apparatus, well known as SCBA. Generally filled with oxygen."
icon = 'icons/obj/items/tanks/tank_scuba.dmi'
slot_flags = SLOT_LOWER_BODY | SLOT_BACK
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index 185f9f0166d9..b2ecbe81e5ab 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -35,7 +35,6 @@ var/global/list/global/tank_gauge_cache = list()
var/gauge_icon = "indicator_tank"
var/gauge_cap = 6
- var/previous_gauge_pressure = null
var/datum/gas_mixture/air_contents = null
var/distribute_pressure = ONE_ATMOSPHERE
@@ -63,7 +62,7 @@ var/global/list/global/tank_gauge_cache = list()
air_contents.update_values()
START_PROCESSING(SSobj, src)
- update_icon(TRUE)
+ update_icon()
/obj/item/tank/Destroy()
QDEL_NULL(air_contents)
@@ -134,7 +133,7 @@ var/global/list/global/tank_gauge_cache = list()
if(C.use(1))
wired = 1
to_chat(user, "You attach the wires to the tank.")
- update_icon(TRUE)
+ update_icon()
return TRUE
if(IS_WIRECUTTER(W))
@@ -157,7 +156,7 @@ var/global/list/global/tank_gauge_cache = list()
assy.a_right = null
proxyassembly.assembly = null
qdel(assy)
- update_icon(TRUE)
+ update_icon()
else
to_chat(user, "You slip and bump the igniter!")
@@ -169,7 +168,7 @@ var/global/list/global/tank_gauge_cache = list()
if(do_after(user, 10, src))
to_chat(user, "You quickly clip the wire from the tank.")
wired = 0
- update_icon(TRUE)
+ update_icon()
else
to_chat(user, "There are no wires to cut!")
@@ -283,8 +282,8 @@ var/global/list/global/tank_gauge_cache = list()
// auto update every Master Controller tick
ui.set_auto_update(1)
-/obj/item/tank/Topic(user, href_list, state = global.inventory_topic_state)
- ..()
+/obj/item/tank/DefaultTopicState()
+ return global.inventory_topic_state
/obj/item/tank/OnTopic(user, href_list)
if (href_list["dist_p"])
@@ -378,17 +377,17 @@ var/global/list/global/tank_gauge_cache = list()
air_contents.react()
check_status()
-/obj/item/tank/on_update_icon(var/override)
+// TODO: Check if this works without the override argument. Everything in tank code seems to call it, so...
+/obj/item/tank/on_update_icon()
. = ..()
- var/list/overlays_to_add
- if(override && (proxyassembly.assembly || wired))
- LAZYADD(overlays_to_add, overlay_image('icons/obj/items/tanks/tank_components.dmi', "bomb_assembly"))
+ if(proxyassembly?.assembly || wired)
+ add_overlay(overlay_image('icons/obj/items/tanks/tank_components.dmi', "bomb_assembly"))
if(proxyassembly.assembly)
var/mutable_appearance/bombthing = new(proxyassembly.assembly)
bombthing.appearance_flags = RESET_COLOR
bombthing.pixel_y = -1
bombthing.pixel_x = -3
- LAZYADD(overlays_to_add, bombthing)
+ add_overlay(bombthing)
if(gauge_icon)
var/gauge_pressure = 0
@@ -398,13 +397,10 @@ var/global/list/global/tank_gauge_cache = list()
gauge_pressure = -1
else
gauge_pressure = round((gauge_pressure/TANK_IDEAL_PRESSURE)*gauge_cap)
- if(override || (previous_gauge_pressure != gauge_pressure))
- var/indicator = "[gauge_icon][(gauge_pressure == -1) ? "overload" : gauge_pressure]"
- if(!tank_gauge_cache[indicator])
- tank_gauge_cache[indicator] = image('icons/obj/items/tanks/tank_indicators.dmi', indicator)
- LAZYADD(overlays_to_add, tank_gauge_cache[indicator])
- previous_gauge_pressure = gauge_pressure
- add_overlay(overlays_to_add)
+ var/indicator = "[gauge_icon][(gauge_pressure == -1) ? "overload" : gauge_pressure]"
+ if(!tank_gauge_cache[indicator])
+ tank_gauge_cache[indicator] = image('icons/obj/items/tanks/tank_indicators.dmi', indicator)
+ add_overlay(tank_gauge_cache[indicator])
//Handle exploding, leaking, and rupturing of the tank
/obj/item/tank/proc/check_status()
@@ -534,7 +530,7 @@ var/global/list/global/tank_gauge_cache = list()
proxyassembly.assembly = new /obj/item/assembly_holder(src)
proxyassembly.assembly.master = proxyassembly
proxyassembly.assembly.update_icon()
- update_icon(TRUE)
+ update_icon()
/////////////////////////////////
///Pulled from rewritten bomb.dm
@@ -571,7 +567,7 @@ var/global/list/global/tank_gauge_cache = list()
S.master = proxyassembly //Tell the assembly about its new owner
S.forceMove(src) //Move the assembly
- update_icon(TRUE)
+ update_icon()
/obj/item/tank/proc/cause_explosion() //This happens when a bomb is told to explode
var/obj/item/assembly_holder/assy = proxyassembly.assembly
@@ -588,7 +584,7 @@ var/global/list/global/tank_gauge_cache = list()
assy.master = null
proxyassembly.assembly = null
qdel(assy)
- update_icon(TRUE)
+ update_icon()
air_contents.add_thermal_energy(15000)
diff --git a/code/game/objects/items/weapons/tech_disks.dm b/code/game/objects/items/weapons/tech_disks.dm
index 91922a2853d9..012acea79a65 100644
--- a/code/game/objects/items/weapons/tech_disks.dm
+++ b/code/game/objects/items/weapons/tech_disks.dm
@@ -3,7 +3,7 @@
///////////////////////////////////////////////////////////////////////////////
/obj/item/disk
name = "data disk"
- desc = "A standard 3.5 inch floppy disk for storing computer files... What's even an inch?"
+ desc = "A standard 3.5-inch floppy disk for storing computer files... What's even an inch?"
icon = 'icons/obj/items/device/diskette.dmi'
icon_state = ICON_STATE_WORLD
w_class = ITEM_SIZE_TINY
diff --git a/code/game/objects/items/weapons/towels.dm b/code/game/objects/items/weapons/towels.dm
index 3b111a31629c..23bada102c8c 100644
--- a/code/game/objects/items/weapons/towels.dm
+++ b/code/game/objects/items/weapons/towels.dm
@@ -1,5 +1,6 @@
/obj/item/towel
name = "towel"
+ desc = "A soft cotton towel."
icon = 'icons/obj/items/towel.dmi'
icon_state = ICON_STATE_WORLD
item_flags = ITEM_FLAG_IS_BELT
@@ -8,8 +9,12 @@
w_class = ITEM_SIZE_NORMAL
attack_verb = list("whipped")
hitsound = 'sound/weapons/towelwhip.ogg'
- desc = "A soft cotton towel."
material = /decl/material/solid/organic/cloth
+ material_alteration = MAT_FLAG_ALTERATION_ALL
+ /// Are we currently laying flat on the ground, or are we rolled up?
+ var/laid_out = FALSE
+ /// A string added to the end of the material description, e.g. "used to dry yourself off". Optional, used by doormats.
+ var/additional_description
/obj/item/towel/Initialize()
. = ..()
@@ -20,32 +25,77 @@
STOP_PROCESSING(SSobj, src)
return ..()
+// Does not rely on ATOM_IS_OPEN_CONTAINER because we want to be able to pour in but not out.
+/obj/item/towel/can_be_poured_into(atom/source)
+ return (reagents?.maximum_volume > 0)
+
+/obj/item/towel/proc/update_material_description()
+ if(!istype(material) || !(material_alteration & MAT_FLAG_ALTERATION_DESC))
+ return
+ var/is_soft = material.hardness < (MAT_VALUE_RIGID + MAT_VALUE_FLEXIBLE) / 2 // if we're closer to being flexible than rigid, we're considered soft
+ // todo: 'roughness' var to go along with hardness? sand is soft but rough, and maybe some sort of future plastic or rubber is hard but lush
+ // would this have any use aside from fluff strings? sandpaper grit maybe?
+ desc = "A [is_soft ? "soft" : "rugged"] [material.adjective_name] [base_name][additional_description ? " [additional_description]" : null]." // 'a soft cotton towel' by default. also supports 'a rugged leather doormat used to blah blah' etc
+
+/obj/item/towel/examine(mob/user, distance, infix, suffix)
+ . = ..()
+ if(reagents?.total_volume && distance <= 1)
+ var/liquid_adjective = "damp"
+ switch(reagents.total_volume / reagents.maximum_volume)
+ if(0 to 0.1)
+ return // not enough to even bother worrying about
+ if(0.4 to 0.6)
+ liquid_adjective = "wet"
+ if(0.6 to 0.8)
+ liquid_adjective = "drenched"
+ if(0.8 to 1)
+ liquid_adjective = "soaked through"
+ if(1)
+ liquid_adjective = "entirely saturated"
+ to_chat(user, "It is [liquid_adjective] with [reagents.get_coated_name()].")
+
+/obj/item/towel/set_material(new_material)
+ . = ..()
+ if(istype(material))
+ update_material_description()
+
// Slowly dry out.
/obj/item/towel/Process()
if(reagents?.total_volume)
- reagents.remove_any(max(1, round(reagents.total_volume * 0.05)))
+ reagents.remove_any(max(MINIMUM_CHEMICAL_VOLUME, CHEMS_QUANTIZE(reagents.total_volume * 0.05)))
if(!reagents?.total_volume)
return PROCESS_KILL
/obj/item/towel/initialize_reagents()
- create_reagents(50)
+ create_reagents(round(50 * (w_class / ITEM_SIZE_NORMAL))) // larger towels have more room, smaller ones have less
. = ..()
+/obj/item/towel/update_name()
+ if(reagents?.total_volume)
+ if(!REAGENTS_FREE_SPACE(reagents))
+ name_prefix = "waterlogged"
+ else
+ name_prefix = "damp"
+ else
+ name_prefix = null
+ return ..()
+
/obj/item/towel/on_reagent_change()
if(!(. = ..()))
return
+ update_name()
if(reagents?.total_volume)
- SetName("damp [initial(name)]")
if(!is_processing)
START_PROCESSING(SSobj, src)
- else
- SetName(initial(name))
- if(is_processing)
- STOP_PROCESSING(SSobj, src)
+ else if(is_processing)
+ STOP_PROCESSING(SSobj, src)
/obj/item/towel/use_on_mob(mob/living/target, mob/living/user, animate = TRUE)
- if(user.check_intent(I_FLAG_HARM))
- return ..()
+ if(!user.check_intent(I_FLAG_HARM) && dry_mob(target, user))
+ return TRUE
+ return ..()
+
+/obj/item/towel/proc/dry_mob(mob/living/target, mob/living/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
var/reagent_space = reagents.maximum_volume - reagents.total_volume
if(reagent_space <= 0)
@@ -63,79 +113,132 @@
/obj/item/towel/attack_self(mob/user)
if(user.check_intent(I_FLAG_GRAB))
- lay_out()
+ lay_out(user)
return TRUE
if(!user.check_intent(I_FLAG_HARM))
return use_on_mob(user, user)
return ..()
+/obj/item/towel/on_update_icon()
+ . = ..()
+ icon_state = get_world_inventory_state()
+ if(laid_out)
+ icon_state = "[ICON_STATE_WORLD]-flat" // 'inventory-flat' is nonsensical
+
+// walking on a towel gets it dirty, so watch your step
+// this is a good thing for doormats though.
+/obj/item/towel/Crossed(atom/movable/crosser)
+ . = ..()
+ if(!isliving(crosser))
+ return
+ var/mob/living/crossy_mob = crosser
+ var/list/obj/item/targets = crossy_mob.get_walking_contaminant_targets()
+ if(!LAZYLEN(targets) || !REAGENTS_FREE_SPACE(reagents))
+ return
+ // i didn't wanna use process() to make it so that you can stand on it longer to clean your feet more
+ // and clicking on it picks it up, so i went with this overcomplicated garbage instead!
+ // basically: your move intent (creeping, walking, running) determines how much is cleaned
+ // if you walk slowly you'll always get totally cleaned
+ var/variability = 20 // by default cleans 80-120% (clamped 0-100) of reagents when walking normally
+ if(MOVING_DELIBERATELY(crossy_mob)) // always 100% cleaned when moving slowly
+ variability = 0
+ else if(MOVING_QUICKLY(crossy_mob))
+ variability = 70 // 30-170%, clamped to be 30-100%
+ for(var/obj/item/target in targets)
+ var/datum/reagents/target_coating = target.coating
+ if(!target_coating?.total_volume)
+ continue
+ var/fraction_cleaned = clamp(CHEMS_QUANTIZE(rand(100 - variability, 100 + variability) / 100), 0, 100)
+ target.transfer_coating_to(src, fraction_cleaned * target_coating.total_volume)
+ if(!REAGENTS_FREE_SPACE(reagents))
+ break
+
/obj/item/towel/random/Initialize()
. = ..()
set_color(get_random_colour())
/obj/item/towel/gold
- name = "gold towel"
paint_color = "#ffd700"
/obj/item/towel/red
- name = "red towel"
paint_color = "#ff0000"
/obj/item/towel/purple
- name = "purple towel"
paint_color = "#800080"
/obj/item/towel/cyan
- name = "cyan towel"
paint_color = "#00ffff"
/obj/item/towel/orange
- name = "orange towel"
paint_color = "#ff8c00"
/obj/item/towel/pink
- name = "pink towel"
paint_color = "#ff6666"
/obj/item/towel/light_blue
- name = "light blue towel"
paint_color = "#3fc0ea"
/obj/item/towel/black
- name = "black towel"
paint_color = "#222222"
/obj/item/towel/brown
- name = "black towel"
paint_color = "#854636"
/obj/item/towel/fleece // loot from the king of goats. it's a golden towel
- name = "golden fleece"
+ name = "fleece" // sets its name to 'golden fleece' due to material
desc = "The legendary Golden Fleece of Jason made real."
_base_attack_force = 1
attack_verb = list("smote")
material = /decl/material/solid/metal/gold
-/obj/item/towel/verb/lay_out()
- set name = "Lay Out Towel"
- set category = "Object"
-
- if(usr.incapacitated())
- return
-
- if(usr.drop_from_inventory(src))
- usr.visible_message(
- SPAN_NOTICE("[usr] lay out \the [src] on the ground."),
- SPAN_NOTICE("You lay out \the [src] on the ground."))
- icon = 'icons/obj/items/towel_flat.dmi'
- pixel_x = 0
- pixel_y = 0
- pixel_z = 0
+/obj/item/towel/fleece/update_material_description()
+ return FALSE
+
+/obj/item/towel/proc/lay_out(mob/user)
+ if(laid_out)
+ return FALSE
+ if(user.incapacitated())
+ return FALSE
+ if(!user.drop_from_inventory(src))
+ return FALSE
+ user.visible_message(
+ SPAN_NOTICE("[user] lays out \the [src] on the ground."),
+ SPAN_NOTICE("You lay out \the [src] on the ground."))
+ laid_out = TRUE
+ set_dir(user.dir)
+ reset_offsets()
+ update_icon()
+ return TRUE
/obj/item/towel/on_picked_up(mob/user)
..()
- if(icon != initial(icon))
- icon = initial(icon)
+ if(laid_out)
+ laid_out = FALSE
+ reset_offsets(0)
+ update_icon()
user.visible_message(
- SPAN_NOTICE("[user] rolled up \the [src]."),
+ SPAN_NOTICE("[user] rolls up \the [src]."),
SPAN_NOTICE("You pick up and fold \the [src]."))
+
+/obj/item/towel/doormat
+ name = "doormat"
+ icon = 'icons/obj/items/doormat.dmi'
+ w_class = ITEM_SIZE_LARGE
+ item_flags = ITEM_FLAG_NO_BLUDGEON // you can't towel whip someone with a doormat, it's too unwieldy
+ slot_flags = SLOT_NONE
+ additional_description = "used to wipe your feet when entering a building"
+ material = /decl/material/solid/organic/skin/fur
+ color = /decl/material/solid/organic/skin/fur::color
+ material_alteration = MAT_FLAG_ALTERATION_ALL
+
+/obj/item/towel/doormat/Crossed(atom/movable/crosser)
+ var/had_space = REAGENTS_FREE_SPACE(reagents)
+ . = ..()
+ if(isliving(crosser) && had_space && !REAGENTS_FREE_SPACE(reagents))
+ // this sucks, ideally we'd have a 'dirty' or 'wet' overlay to use for it, but i'm no spriter
+ visible_message(SPAN_WARNING("\The [src] is completely waterlogged!"))
+
+/// A mapping subtype for a doormat that's already been laid out.
+/obj/item/towel/doormat/flat
+ laid_out = TRUE
+ icon_state = ICON_STATE_WORLD + "-flat"
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/electric_welder.dm b/code/game/objects/items/welding/electric_welder.dm
similarity index 86%
rename from code/game/objects/items/weapons/electric_welder.dm
rename to code/game/objects/items/welding/electric_welder.dm
index cb949be907df..b3bd71761965 100644
--- a/code/game/objects/items/weapons/electric_welder.dm
+++ b/code/game/objects/items/welding/electric_welder.dm
@@ -42,10 +42,11 @@
var/obj/item/cell/cell = get_cell()
return cell ? cell.charge : 0
-/obj/item/weldingtool/electric/attackby(var/obj/item/W, var/mob/user)
- if(istype(W,/obj/item/stack/material/rods) || istype(W, /obj/item/chems/welder_tank))
- return FALSE // NO ELECTRIC FLAMETHROWER
- return ..()
+/obj/item/weldingtool/electric/insert_tank(var/obj/item/chems/welder_tank/T, var/mob/user, var/no_updates = FALSE, var/quiet = FALSE)
+ return FALSE // No tanks!
+
+/obj/item/weldingtool/electric/attempt_modify(var/obj/item/W, var/mob/user)
+ return FALSE // NO ELECTRIC FLAMETHROWER
/obj/item/weldingtool/electric/use_fuel(var/amount)
var/obj/item/cell/cell = get_cell()
diff --git a/code/game/objects/items/weapons/weldbackpack.dm b/code/game/objects/items/welding/weldbackpack.dm
similarity index 100%
rename from code/game/objects/items/weapons/weldbackpack.dm
rename to code/game/objects/items/welding/weldbackpack.dm
diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/welding/weldingtool.dm
similarity index 72%
rename from code/game/objects/items/weapons/tools/weldingtool.dm
rename to code/game/objects/items/welding/weldingtool.dm
index 615c00682916..6a2158acb84d 100644
--- a/code/game/objects/items/weapons/tools/weldingtool.dm
+++ b/code/game/objects/items/welding/weldingtool.dm
@@ -379,149 +379,5 @@
material = /decl/material/solid/metal/steel
matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT)
-//////////////////////////////////////////////////////////////////
-// Welding tool tanks
-//////////////////////////////////////////////////////////////////
-/obj/item/chems/welder_tank
- name = "welding tank"
- base_name = "welding tank"
- desc = "An interchangeable fuel tank meant for a welding tool."
- icon = 'icons/obj/items/tool/welders/welder_tanks.dmi'
- icon_state = "tank_normal"
- w_class = ITEM_SIZE_SMALL
- atom_flags = ATOM_FLAG_OPEN_CONTAINER
- obj_flags = OBJ_FLAG_HOLLOW
- volume = 20
- show_reagent_name = TRUE
- current_health = 40
- max_health = 40
- material = /decl/material/solid/metal/steel
- var/can_refuel = TRUE
- var/size_in_use = ITEM_SIZE_NORMAL
- var/unlit_force = 7
- var/lit_force = 11
-
-/obj/item/chems/welder_tank/populate_reagents()
- add_to_reagents(/decl/material/liquid/fuel, reagents.maximum_volume)
-
-/obj/item/chems/welder_tank/examine(mob/user, distance)
- . = ..()
- if(distance > 1)
- return
- if(reagents.total_volume <= 0)
- to_chat(user, "It is empty.")
- else
- to_chat(user, "It contains [reagents.total_volume] units of liquid.")
- to_chat(user, " It can hold up to [reagents.maximum_volume] units.")
-
-/obj/item/chems/welder_tank/afterattack(obj/O, mob/user, proximity, click_parameters)
- if (!ATOM_IS_OPEN_CONTAINER(src) || !proximity)
- return
- if(standard_dispenser_refill(user, O))
- return TRUE
- if(standard_pour_into(user, O))
- return TRUE
- if(handle_eaten_by_mob(user, O) != EATEN_INVALID)
- return TRUE
- if(user.check_intent(I_FLAG_HARM))
- if(standard_splash_mob(user, O))
- return TRUE
- if(reagents && reagents.total_volume)
- to_chat(user, SPAN_DANGER("You splash the contents of \the [src] onto \the [O]."))
- reagents.splash(O, reagents.total_volume)
- return TRUE
- return ..()
-
-/obj/item/chems/welder_tank/standard_dispenser_refill(mob/user, obj/structure/reagent_dispensers/target, skip_container_check = FALSE)
- if(!can_refuel)
- to_chat(user, SPAN_DANGER("\The [src] does not have a refuelling port."))
- return FALSE
- . = ..()
- if(.)
- playsound(src.loc, 'sound/effects/refill.ogg', 50, TRUE, -6)
-
-/obj/item/chems/welder_tank/standard_pour_into(mob/user, atom/target)
- if(!can_refuel)
- to_chat(user, SPAN_DANGER("\The [src] is sealed shut."))
- return FALSE
- . = ..()
-
-/obj/item/chems/welder_tank/standard_splash_mob(mob/user, mob/target)
- if(!can_refuel)
- to_chat(user, SPAN_DANGER("\The [src] is sealed shut."))
- return FALSE
- . = ..()
-
-/obj/item/chems/welder_tank/handle_eaten_by_mob(mob/user, mob/target)
- if(!can_refuel)
- to_chat(user, SPAN_DANGER("\The [src] is sealed shut."))
- return EATEN_UNABLE
- return ..()
-
-/obj/item/chems/welder_tank/get_alt_interactions(var/mob/user)
- . = ..()
- if(!can_refuel)
- LAZYREMOVE(., /decl/interaction_handler/set_transfer/chems)
-
-/obj/item/chems/welder_tank/mini
- name = "small welding tank"
- base_name = "small welding tank"
- icon_state = "tank_small"
- w_class = ITEM_SIZE_TINY
- volume = 5
- size_in_use = ITEM_SIZE_SMALL
- unlit_force = 5
- lit_force = 7
- _base_attack_force = 4
-
-/obj/item/chems/welder_tank/large
- name = "large welding tank"
- base_name = "large welding tank"
- icon_state = "tank_large"
- w_class = ITEM_SIZE_SMALL
- volume = 40
- size_in_use = ITEM_SIZE_NORMAL
- _base_attack_force = 6
-
-/obj/item/chems/welder_tank/huge
- name = "huge welding tank"
- base_name = "huge welding tank"
- icon_state = "tank_huge"
- w_class = ITEM_SIZE_NORMAL
- volume = 80
- size_in_use = ITEM_SIZE_LARGE
- unlit_force = 9
- lit_force = 15
- _base_attack_force = 8
-
-/obj/item/chems/welder_tank/experimental
- name = "experimental welding tank"
- base_name = "experimental welding tank"
- icon_state = "tank_experimental"
- w_class = ITEM_SIZE_NORMAL
- volume = 40
- can_refuel = FALSE
- size_in_use = ITEM_SIZE_LARGE
- unlit_force = 9
- lit_force = 15
- show_reagent_name = FALSE
- _base_attack_force = 8
- var/tmp/last_gen = 0
-
-/obj/item/chems/welder_tank/experimental/Initialize(ml, material_key)
- . = ..()
- atom_flags &= ~ATOM_FLAG_OPEN_CONTAINER
- START_PROCESSING(SSobj, src)
-
-/obj/item/chems/welder_tank/experimental/Destroy()
- STOP_PROCESSING(SSobj, src)
- return ..()
-
-/obj/item/chems/welder_tank/experimental/Process()
- if(REAGENT_VOLUME(reagents, /decl/material/liquid/fuel) < reagents.maximum_volume)
- var/gen_amount = ((world.time-last_gen)/25)
- add_to_reagents(/decl/material/liquid/fuel, gen_amount)
- last_gen = world.time
-
#undef WELDING_TOOL_HOTSPOT_TEMP_ACTIVE
#undef WELDING_TOOL_HOTSPOT_TEMP_IDLE
\ No newline at end of file
diff --git a/code/game/objects/items/welding/weldingtool_tank.dm b/code/game/objects/items/welding/weldingtool_tank.dm
new file mode 100644
index 000000000000..7b5b455663a0
--- /dev/null
+++ b/code/game/objects/items/welding/weldingtool_tank.dm
@@ -0,0 +1,143 @@
+//////////////////////////////////////////////////////////////////
+// Welding tool tanks
+//////////////////////////////////////////////////////////////////
+/obj/item/chems/welder_tank
+ name = "welding tank"
+ base_name = "welding tank"
+ desc = "An interchangeable fuel tank meant for a welding tool."
+ icon = 'icons/obj/items/tool/welders/welder_tanks.dmi'
+ icon_state = "tank_normal"
+ w_class = ITEM_SIZE_SMALL
+ atom_flags = ATOM_FLAG_OPEN_CONTAINER
+ obj_flags = OBJ_FLAG_HOLLOW
+ volume = 20
+ show_reagent_name = TRUE
+ current_health = 40
+ max_health = 40
+ material = /decl/material/solid/metal/steel
+ var/can_refuel = TRUE
+ var/size_in_use = ITEM_SIZE_NORMAL
+ var/unlit_force = 7
+ var/lit_force = 11
+
+/obj/item/chems/welder_tank/populate_reagents()
+ add_to_reagents(/decl/material/liquid/fuel, reagents.maximum_volume)
+
+/obj/item/chems/welder_tank/examine(mob/user, distance)
+ . = ..()
+ if(distance > 1)
+ return
+ if(reagents.total_volume <= 0)
+ to_chat(user, "It is empty.")
+ else
+ to_chat(user, "It contains [reagents.total_volume] units of liquid.")
+ to_chat(user, " It can hold up to [reagents.maximum_volume] units.")
+
+/obj/item/chems/welder_tank/afterattack(obj/O, mob/user, proximity, click_parameters)
+ if (!ATOM_IS_OPEN_CONTAINER(src) || !proximity)
+ return
+ if(standard_dispenser_refill(user, O))
+ return TRUE
+ if(standard_pour_into(user, O))
+ return TRUE
+ if(handle_eaten_by_mob(user, O) != EATEN_INVALID)
+ return TRUE
+ if(user.check_intent(I_FLAG_HARM))
+ if(standard_splash_mob(user, O))
+ return TRUE
+ if(reagents && reagents.total_volume)
+ to_chat(user, SPAN_DANGER("You splash the contents of \the [src] onto \the [O]."))
+ reagents.splash(O, reagents.total_volume)
+ return TRUE
+ return ..()
+
+/obj/item/chems/welder_tank/standard_dispenser_refill(mob/user, obj/structure/reagent_dispensers/target, skip_container_check = FALSE)
+ if(!can_refuel)
+ to_chat(user, SPAN_DANGER("\The [src] does not have a refuelling port."))
+ return FALSE
+ . = ..()
+ if(.)
+ playsound(src.loc, 'sound/effects/refill.ogg', 50, TRUE, -6)
+
+/obj/item/chems/welder_tank/standard_pour_into(mob/user, atom/target)
+ if(!can_refuel)
+ to_chat(user, SPAN_DANGER("\The [src] is sealed shut."))
+ return FALSE
+ . = ..()
+
+/obj/item/chems/welder_tank/standard_splash_mob(mob/user, mob/target)
+ if(!can_refuel)
+ to_chat(user, SPAN_DANGER("\The [src] is sealed shut."))
+ return FALSE
+ . = ..()
+
+/obj/item/chems/welder_tank/handle_eaten_by_mob(mob/user, mob/target)
+ if(!can_refuel)
+ to_chat(user, SPAN_DANGER("\The [src] is sealed shut."))
+ return EATEN_UNABLE
+ return ..()
+
+/obj/item/chems/welder_tank/get_alt_interactions(var/mob/user)
+ . = ..()
+ if(!can_refuel)
+ LAZYREMOVE(., /decl/interaction_handler/set_transfer/chems)
+
+/obj/item/chems/welder_tank/mini
+ name = "small welding tank"
+ base_name = "small welding tank"
+ icon_state = "tank_small"
+ w_class = ITEM_SIZE_TINY
+ volume = 5
+ size_in_use = ITEM_SIZE_SMALL
+ unlit_force = 5
+ lit_force = 7
+ _base_attack_force = 4
+
+/obj/item/chems/welder_tank/large
+ name = "large welding tank"
+ base_name = "large welding tank"
+ icon_state = "tank_large"
+ w_class = ITEM_SIZE_SMALL
+ volume = 40
+ size_in_use = ITEM_SIZE_NORMAL
+ _base_attack_force = 6
+
+/obj/item/chems/welder_tank/huge
+ name = "huge welding tank"
+ base_name = "huge welding tank"
+ icon_state = "tank_huge"
+ w_class = ITEM_SIZE_NORMAL
+ volume = 80
+ size_in_use = ITEM_SIZE_LARGE
+ unlit_force = 9
+ lit_force = 15
+ _base_attack_force = 8
+
+/obj/item/chems/welder_tank/experimental
+ name = "experimental welding tank"
+ base_name = "experimental welding tank"
+ icon_state = "tank_experimental"
+ w_class = ITEM_SIZE_NORMAL
+ volume = 40
+ can_refuel = FALSE
+ size_in_use = ITEM_SIZE_LARGE
+ unlit_force = 9
+ lit_force = 15
+ show_reagent_name = FALSE
+ _base_attack_force = 8
+ var/tmp/last_gen = 0
+
+/obj/item/chems/welder_tank/experimental/Initialize(ml, material_key)
+ . = ..()
+ atom_flags &= ~ATOM_FLAG_OPEN_CONTAINER
+ START_PROCESSING(SSobj, src)
+
+/obj/item/chems/welder_tank/experimental/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/item/chems/welder_tank/experimental/Process()
+ if(REAGENT_VOLUME(reagents, /decl/material/liquid/fuel) < reagents.maximum_volume)
+ var/gen_amount = ((world.time-last_gen)/25)
+ add_to_reagents(/decl/material/liquid/fuel, gen_amount)
+ last_gen = world.time
\ No newline at end of file
diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm
index 1e9a08082aab..a600a4a68c59 100644
--- a/code/game/objects/random/random.dm
+++ b/code/game/objects/random/random.dm
@@ -24,6 +24,8 @@
return
var/type_to_spawn = item_to_spawn()
+ if(!type_to_spawn)
+ return
if(islist(type_to_spawn))
for(var/spawn_type in type_to_spawn)
LAZYADD(., create_instance(spawn_type, loc))
diff --git a/code/game/objects/random/subtypes/misc.dm b/code/game/objects/random/subtypes/misc.dm
index 9686e9846b0e..01f0b1fb231c 100644
--- a/code/game/objects/random/subtypes/misc.dm
+++ b/code/game/objects/random/subtypes/misc.dm
@@ -225,7 +225,7 @@
/obj/random/soap/spawn_choices()
var/static/list/spawnable_choices = list(
/obj/item/soap = 12,
- /obj/item/chems/glass/rag = 2,
+ /obj/item/chems/rag = 2,
/obj/item/chems/spray/cleaner = 2,
/obj/item/grenade/chem_grenade/cleaner = 1
)
diff --git a/code/game/objects/random/subtypes/suits.dm b/code/game/objects/random/subtypes/suits.dm
index a219f0b7a2a4..093f23509f62 100644
--- a/code/game/objects/random/subtypes/suits.dm
+++ b/code/game/objects/random/subtypes/suits.dm
@@ -5,6 +5,17 @@
icon_state = "generic"
/obj/random/hardsuit/spawn_choices()
+ var/static/list/spawnable_choices = list(
+ /obj/item/rig/industrial,
+ /obj/item/rig/eva,
+ /obj/item/rig/light
+ )
+ return spawnable_choices
+
+/obj/random/hardsuit/heist
+ name = "Random Heist Hardsuit"
+
+/obj/random/hardsuit/heist/spawn_choices()
var/static/list/spawnable_choices = list(
/obj/item/rig/industrial,
/obj/item/rig/eva,
diff --git a/code/game/objects/random/subtypes/tech.dm b/code/game/objects/random/subtypes/tech.dm
index 26c057122136..23c298283fae 100644
--- a/code/game/objects/random/subtypes/tech.dm
+++ b/code/game/objects/random/subtypes/tech.dm
@@ -15,8 +15,8 @@
return spawnable_choices
/obj/random/powercell
- name = "random powercell"
- desc = "This is a random powercell."
+ name = "random power cell"
+ desc = "This is a random power cell."
icon = 'icons/obj/power.dmi'
icon_state = "hcell"
diff --git a/code/game/objects/random/subtypes/tools.dm b/code/game/objects/random/subtypes/tools.dm
index 0e4c773171fa..ed0a73164cb1 100644
--- a/code/game/objects/random/subtypes/tools.dm
+++ b/code/game/objects/random/subtypes/tools.dm
@@ -17,8 +17,8 @@
return spawnable_choices
/obj/random/tool/power
- name = "random powertool"
- desc = "This is a random rare powertool for maintenance"
+ name = "random power tool"
+ desc = "This is a random rare power tool for maintenance"
/obj/random/tool/power/spawn_choices()
var/static/list/spawnable_choices = list(
diff --git a/code/game/objects/structures/__structure.dm b/code/game/objects/structures/__structure.dm
index 7beee9b0878d..7d04f64b1694 100644
--- a/code/game/objects/structures/__structure.dm
+++ b/code/game/objects/structures/__structure.dm
@@ -137,7 +137,9 @@
else
damage *= STRUCTURE_BRITTLE_MATERIAL_DAMAGE_MULTIPLIER
- playsound(loc, hitsound, 60, 1)
+ if(!silent)
+ playsound(loc, hitsound, 60, 1)
+
var/current_max_health = get_max_health()
current_health = clamp(current_health - damage, 0, current_max_health)
show_damage_message(current_health/current_max_health)
@@ -340,4 +342,3 @@ Note: This proc can be overwritten to allow for different types of auto-alignmen
visible_message(SPAN_DANGER("\The [src] was hit by \the [AM]."))
playsound(src.loc, hitsound, 100, 1)
take_damage(AM.get_thrown_attack_force() * (TT.speed/THROWFORCE_SPEED_DIVISOR), AM.atom_damage_type)
-
diff --git a/code/game/objects/structures/_structure_materials.dm b/code/game/objects/structures/_structure_materials.dm
index db8065e41d4d..604a48b49acd 100644
--- a/code/game/objects/structures/_structure_materials.dm
+++ b/code/game/objects/structures/_structure_materials.dm
@@ -3,6 +3,7 @@
var/decl/material/reinf_material
var/material_alteration
var/dismantled
+ var/name_prefix
/obj/structure/get_material()
RETURN_TYPE(/decl/material)
@@ -37,10 +38,14 @@
/obj/structure/proc/update_material_name(var/override_name)
var/base_name = override_name || initial(name)
+ var/new_name
if(istype(material) && (material_alteration & MAT_FLAG_ALTERATION_NAME))
- SetName("[material.adjective_name] [base_name]")
+ new_name = "[material.adjective_name] [base_name]"
else
- SetName(base_name)
+ new_name = base_name
+ if(name_prefix)
+ new_name = "[name_prefix] [new_name]"
+ SetName(new_name)
/obj/structure/proc/update_material_desc(var/override_desc)
var/base_desc = override_desc || initial(desc)
diff --git a/code/game/objects/structures/beds/bed.dm b/code/game/objects/structures/beds/bed.dm
new file mode 100644
index 000000000000..fdcdff9a143e
--- /dev/null
+++ b/code/game/objects/structures/beds/bed.dm
@@ -0,0 +1,160 @@
+// Beds... get your mind out of the gutter, they're for sleeping!
+// TODO by end of Q2 2025: Repath /obj/structure/bed/chair to just /obj/structure/chair.
+// Remaining steps:
+// - Move padding interactions and padding_color var onto an extension
+// - Allow /obj/structure/grab_attack to handle buckling
+/obj/structure/bed
+ name = "bed"
+ desc = "A raised, padded platform for sleeping on. This one has straps for ensuring restful snoozing in microgravity."
+ icon = 'icons/obj/furniture.dmi'
+ icon_state = "bed"
+ anchored = TRUE
+ can_buckle = TRUE
+ buckle_dir = SOUTH
+ buckle_lying = TRUE
+ buckle_sound = 'sound/effects/buckle.ogg'
+ material = DEFAULT_FURNITURE_MATERIAL
+ material_alteration = MAT_FLAG_ALTERATION_ALL
+ tool_interaction_flags = TOOL_INTERACTION_DECONSTRUCT
+ parts_amount = 2
+ parts_type = /obj/item/stack/material/rods
+ user_comfort = 1
+ obj_flags = OBJ_FLAG_SUPPORT_MOB
+ var/base_icon = "bed"
+ var/padding_color
+
+/obj/structure/bed/user_can_mousedrop_onto(mob/user, atom/being_dropped, incapacitation_flags, params)
+ if(user == being_dropped)
+ return user.Adjacent(src) && !user.incapacitated(INCAPACITATION_STUNNED|INCAPACITATION_KNOCKOUT)
+ return ..()
+
+/obj/structure/bed/get_base_value()
+ . = round(..() * 2.5) // Utility structures should be worth more than their matter (wheelchairs, rollers, etc).
+
+/obj/structure/bed/get_surgery_surface_quality(mob/living/victim, mob/living/user)
+ return OPERATE_PASSABLE
+
+/obj/structure/bed/get_surgery_success_modifier(delicate)
+ return delicate ? -5 : 0
+
+/obj/structure/bed/update_material_name()
+ if(reinf_material)
+ SetName("[reinf_material.adjective_name] [initial(name)]")
+ else if(material)
+ SetName("[material.adjective_name] [initial(name)]")
+ else
+ SetName(initial(name))
+
+/obj/structure/bed/update_material_desc()
+ if(reinf_material)
+ desc = "[initial(desc)] It's made of [material.use_name] and covered with [reinf_material.use_name]."
+ else
+ desc = "[initial(desc)] It's made of [material.use_name]."
+
+// Reuse the cache/code from stools, todo maybe unify.
+/obj/structure/bed/on_update_icon()
+ ..()
+ icon_state = base_icon
+ if(istype(reinf_material))
+ if(material_alteration & MAT_FLAG_ALTERATION_COLOR)
+ add_overlay(overlay_image(icon, "[icon_state]_padding", padding_color || reinf_material.color, RESET_COLOR))
+ else
+ add_overlay(overlay_image(icon, "[icon_state]_padding"))
+
+/obj/structure/bed/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(istype(mover) && mover.checkpass(PASS_FLAG_TABLE))
+ return 1
+ return ..()
+
+/obj/structure/bed/explosion_act(severity)
+ . = ..()
+ if(. && !QDELETED(src) && (severity == 1 || (severity == 2 && prob(50)) || (severity == 3 && prob(5))))
+ physically_destroyed()
+
+/obj/structure/bed/proc/can_apply_padding()
+ return TRUE
+
+/obj/structure/bed/attackby(obj/item/used_item, mob/user)
+
+ if((. = ..()))
+ return
+
+ if(istype(used_item, /obj/item/stack) && can_apply_padding())
+
+ if(reinf_material)
+ to_chat(user, SPAN_WARNING("\The [src] is already padded."))
+ return TRUE
+
+ var/obj/item/stack/cloth = used_item
+ if(cloth.get_amount() < 1)
+ to_chat(user, SPAN_WARNING("You need at least one unit of material to pad \the [src]."))
+ return TRUE
+
+ var/padding_type
+ var/new_padding_color
+ if(istype(used_item, /obj/item/stack/tile) || istype(used_item, /obj/item/stack/material/bolt))
+ padding_type = used_item.material?.type
+ new_padding_color = used_item.paint_color
+
+ if(padding_type)
+ var/decl/material/padding_mat = GET_DECL(padding_type)
+ if(!istype(padding_mat) || !(padding_mat.flags & MAT_FLAG_PADDING))
+ padding_type = null
+
+ if(!padding_type)
+ to_chat(user, SPAN_WARNING("You cannot pad \the [src] with that."))
+ return TRUE
+
+ cloth.use(1)
+ if(!isturf(src.loc))
+ src.forceMove(get_turf(src))
+ playsound(src.loc, 'sound/effects/rustle5.ogg', 50, 1)
+ to_chat(user, SPAN_NOTICE("You add padding to \the [src]."))
+ add_padding(padding_type, new_padding_color)
+ return TRUE
+
+ if(IS_WIRECUTTER(used_item))
+ if(!reinf_material)
+ to_chat(user, SPAN_WARNING("\The [src] has no padding to remove."))
+ else
+ to_chat(user, SPAN_NOTICE("You remove the padding from \the [src]."))
+ playsound(src, 'sound/items/Wirecutter.ogg', 100, 1)
+ remove_padding()
+ return TRUE
+
+/obj/structure/bed/grab_attack(obj/item/grab/grab, mob/user)
+ var/mob/living/victim = grab.get_affecting_mob()
+ if(istype(victim) && istype(user))
+ user.visible_message(SPAN_NOTICE("\The [user] attempts to put \the [victim] onto \the [src]!"))
+ if(do_after(user, 2 SECONDS, src) && !QDELETED(victim) && !QDELETED(user) && !QDELETED(grab) && user_buckle_mob(victim, user))
+ qdel(grab)
+ return TRUE
+ return ..()
+
+/obj/structure/bed/proc/add_padding(var/padding_type, var/new_padding_color)
+ reinf_material = GET_DECL(padding_type)
+ padding_color = new_padding_color
+ update_icon()
+
+/obj/structure/bed/proc/remove_padding()
+ if(reinf_material)
+ var/list/res = reinf_material.create_object(get_turf(src))
+ if(padding_color)
+ for(var/obj/item/thing in res)
+ thing.set_color(padding_color)
+ reinf_material = null
+ padding_color = null
+ update_icon()
+
+/obj/structure/bed/psych
+ name = "psychiatrist's couch"
+ desc = "For prime comfort during psychiatric evaluations."
+ icon_state = "psychbed"
+ material = /decl/material/solid/organic/wood/walnut
+
+/obj/structure/bed/psych/leather
+ reinf_material = /decl/material/solid/organic/leather
+
+/obj/structure/bed/padded
+ material = /decl/material/solid/metal/aluminium
+ reinf_material = /decl/material/solid/organic/cloth
diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/bedroll.dm b/code/game/objects/structures/beds/bedroll.dm
similarity index 100%
rename from code/game/objects/structures/stool_bed_chair_nest_sofa/bedroll.dm
rename to code/game/objects/structures/beds/bedroll.dm
diff --git a/code/game/objects/structures/beds/mattress.dm b/code/game/objects/structures/beds/mattress.dm
new file mode 100644
index 000000000000..8532a77a9e1a
--- /dev/null
+++ b/code/game/objects/structures/beds/mattress.dm
@@ -0,0 +1,15 @@
+/*
+ * Mattresses
+ */
+// TODO: These sprites are terrible. Replace?
+/obj/structure/mattress
+ name = "mattress"
+ icon = 'icons/obj/furniture.dmi'
+ icon_state = "mattress"
+ desc = "A bare mattress. It doesn't look very comfortable."
+ anchored = FALSE
+
+/obj/structure/mattress/dirty
+ name = "dirty mattress"
+ icon_state = "dirty_mattress"
+ desc = "A dirty, smelly mattress covered in body fluids. You wouldn't want to touch this."
diff --git a/code/game/objects/structures/beds/rollerbed.dm b/code/game/objects/structures/beds/rollerbed.dm
new file mode 100644
index 000000000000..4c0285d3b788
--- /dev/null
+++ b/code/game/objects/structures/beds/rollerbed.dm
@@ -0,0 +1,153 @@
+/*
+ * Roller beds
+ */
+/obj/structure/bed/roller
+ name = "roller bed"
+ icon = 'icons/obj/structures/rollerbed.dmi'
+ icon_state = "down"
+ anchored = FALSE
+ buckle_pixel_shift = list("x" = 0, "y" = 0, "z" = 6)
+ movable_flags = MOVABLE_FLAG_WHEELED
+ tool_interaction_flags = 0
+ var/item_form_type = /obj/item/roller //The folded-up object path.
+ var/obj/item/chems/beaker
+ var/iv_attached = 0
+ var/iv_stand = TRUE
+
+/obj/structure/bed/roller/on_update_icon()
+ cut_overlays()
+ if(density)
+ icon_state = "up"
+ else
+ icon_state = "down"
+ if(beaker)
+ var/image/iv = image(icon, "iv[iv_attached]")
+ var/percentage = round((beaker.reagents.total_volume / beaker.volume) * 100, 25)
+ var/image/filling = image(icon, "iv_filling[percentage]")
+ filling.color = beaker.reagents.get_color()
+ iv.overlays += filling
+ if(percentage < 25)
+ iv.overlays += image(icon, "light_low")
+ if(density)
+ iv.pixel_y = 6
+ add_overlay(iv)
+
+/obj/structure/bed/roller/can_apply_padding()
+ return FALSE
+
+/obj/structure/bed/roller/attackby(obj/item/I, mob/user)
+ if(iv_stand && !beaker && istype(I, /obj/item/chems))
+ if(!user.try_unequip(I, src))
+ return TRUE
+ to_chat(user, "You attach \the [I] to \the [src].")
+ beaker = I
+ queue_icon_update()
+ return TRUE
+ return ..()
+
+/obj/structure/bed/roller/attack_hand(mob/user)
+ if(!beaker || buckled_mob || !user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE))
+ return ..()
+ remove_beaker(user)
+ return TRUE
+
+/obj/structure/bed/roller/proc/collapse(mob/user)
+ visible_message("[user] collapses [src].")
+ new item_form_type(get_turf(src))
+ qdel(src)
+
+/obj/structure/bed/roller/post_buckle_mob(mob/living/M)
+ . = ..()
+ if(M == buckled_mob)
+ set_density(1)
+ queue_icon_update()
+ else
+ set_density(0)
+ if(iv_attached)
+ detach_iv(M, usr)
+ queue_icon_update()
+
+/obj/structure/bed/roller/Process()
+ if(!iv_attached || !buckled_mob || !beaker)
+ return PROCESS_KILL
+
+ //SSObj fires twice as fast as SSMobs, so gotta slow down to not OD our victims.
+ if(SSobj.times_fired % 2)
+ return
+
+ if(beaker.volume > 0)
+ beaker.reagents.trans_to_mob(buckled_mob, beaker.amount_per_transfer_from_this, CHEM_INJECT)
+ queue_icon_update()
+
+/obj/structure/bed/roller/proc/remove_beaker(mob/user)
+ to_chat(user, "You detach \the [beaker] to \the [src].")
+ iv_attached = FALSE
+ beaker.dropInto(loc)
+ beaker = null
+ queue_icon_update()
+
+/obj/structure/bed/roller/proc/attach_iv(mob/living/human/target, mob/user)
+ if(!beaker)
+ return
+ if(do_IV_hookup(target, user, beaker))
+ iv_attached = TRUE
+ queue_icon_update()
+ START_PROCESSING(SSobj,src)
+
+/obj/structure/bed/roller/proc/detach_iv(mob/living/human/target, mob/user)
+ visible_message("\The [target] is taken off the IV on \the [src].")
+ iv_attached = FALSE
+ queue_icon_update()
+ STOP_PROCESSING(SSobj,src)
+
+/obj/structure/bed/roller/handle_mouse_drop(atom/over, mob/user, params)
+ if(ishuman(user) || isrobot(user))
+ if(over == buckled_mob && beaker)
+ if(iv_attached)
+ detach_iv(buckled_mob, user)
+ else
+ attach_iv(buckled_mob, user)
+ return TRUE
+ if(ishuman(over))
+ var/mob/M = over
+ if(loc == M.loc && user_buckle_mob(M, user))
+ attach_iv(buckled_mob, user)
+ return TRUE
+ if(beaker)
+ remove_beaker(user)
+ return TRUE
+ if(!buckled_mob)
+ collapse(user)
+ return TRUE
+ . = ..()
+
+/obj/item/roller
+ name = "roller bed"
+ desc = "A collapsed roller bed that can be carried around."
+ icon = 'icons/obj/items/rollerbed.dmi'
+ icon_state = ICON_STATE_WORLD
+ slot_flags = SLOT_BACK
+ w_class = ITEM_SIZE_LARGE
+ pickup_sound = 'sound/foley/pickup2.ogg'
+ material = /decl/material/solid/metal/steel
+ matter = list(
+ /decl/material/solid/organic/plastic = MATTER_AMOUNT_SECONDARY,
+ /decl/material/solid/organic/cloth = MATTER_AMOUNT_REINFORCEMENT,
+ )
+ var/structure_form_type = /obj/structure/bed/roller //The deployed form path.
+
+/obj/item/roller/get_single_monetary_worth()
+ . = structure_form_type ? atom_info_repository.get_combined_worth_for(structure_form_type) : ..()
+
+/obj/item/roller/attack_self(mob/user)
+ var/obj/structure/bed/roller/R = new structure_form_type(user.loc)
+ R.add_fingerprint(user)
+ qdel(src)
+
+/obj/item/robot_rack/roller
+ name = "roller bed rack"
+ desc = "A rack for carrying collapsed roller beds. Can also be used for carrying ironing boards."
+ icon = 'icons/obj/items/rollerbed.dmi'
+ icon_state = ICON_STATE_WORLD
+ object_type = /obj/item/roller
+ interact_type = /obj/structure/bed/roller
\ No newline at end of file
diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/simple_bed.dm b/code/game/objects/structures/beds/simple_bed.dm
similarity index 100%
rename from code/game/objects/structures/stool_bed_chair_nest_sofa/simple_bed.dm
rename to code/game/objects/structures/beds/simple_bed.dm
diff --git a/code/game/objects/structures/beds/travois.dm b/code/game/objects/structures/beds/travois.dm
new file mode 100644
index 000000000000..b1ce37f85400
--- /dev/null
+++ b/code/game/objects/structures/beds/travois.dm
@@ -0,0 +1,18 @@
+/*
+ * Travois used to drag mobs in low-tech settings.
+ */
+// TODO: Should this really be a bed subtype?
+// Only really needs the base_icon and grab_attack handling from beds, doesn't it?
+/obj/structure/bed/travois
+ name = "travois"
+ anchored = FALSE
+ icon_state = ICON_STATE_WORLD
+ base_icon = ICON_STATE_WORLD
+ icon = 'icons/obj/structures/travois.dmi'
+ buckle_pixel_shift = list("x" = 0, "y" = 0, "z" = 6)
+ movable_flags = MOVABLE_FLAG_WHEELED
+ user_comfort = 0
+ material = /decl/material/solid/organic/wood/oak
+
+/obj/structure/bed/travois/can_apply_padding()
+ return FALSE
\ No newline at end of file
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index 50fb98d51d08..5f4dcebb62d3 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -24,7 +24,7 @@ LINEN BINS
if(do_after(user, 50, src))
to_chat(user, "You cut \the [src] into pieces!")
for(var/i in 1 to rand(2,5))
- new /obj/item/chems/glass/rag(get_turf(src))
+ new /obj/item/chems/rag(get_turf(src))
qdel(src)
return TRUE
return ..()
diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/pew.dm b/code/game/objects/structures/benches/bench.dm
similarity index 68%
rename from code/game/objects/structures/stool_bed_chair_nest_sofa/pew.dm
rename to code/game/objects/structures/benches/bench.dm
index 59da1232a7c8..c2b6fb98c3bb 100644
--- a/code/game/objects/structures/stool_bed_chair_nest_sofa/pew.dm
+++ b/code/game/objects/structures/benches/bench.dm
@@ -1,3 +1,4 @@
+// These are benches with backs. For backless benches that can't be buckled to, check for /obj/structure/table/bench.
/obj/structure/bed/chair/bench
name = "bench"
desc = "A simple slatted bench."
@@ -112,43 +113,3 @@
/obj/structure/bed/chair/bench/ebony
color = WOOD_COLOR_BLACK
material = /decl/material/solid/organic/wood/ebony
-
-/obj/structure/bed/chair/bench/pew
- name = "pew"
- desc = "A long bench with a backboard, commonly found in places of worship, courtrooms and so on. Not known for being particularly comfortable."
- icon = 'icons/obj/structures/pews.dmi'
- icon_state = "pew_standing"
- base_icon = "pew"
-
-/obj/structure/bed/chair/bench/pew/get_material_icon()
- return material?.pew_icon
-
-/obj/structure/bed/chair/bench/pew/single
- name = "backed chair"
- desc = "A tall chair with a sturdy back. Not very comfortable."
- base_icon = "pew_standing"
- connect_neighbors = FALSE
-
-/obj/structure/bed/chair/bench/pew/mahogany
- color = /decl/material/solid/organic/wood/mahogany::color
- material = /decl/material/solid/organic/wood/mahogany
-
-/obj/structure/bed/chair/bench/pew/ebony
- color = /decl/material/solid/organic/wood/ebony::color
- material = /decl/material/solid/organic/wood/ebony
-
-/obj/structure/bed/chair/bench/lounge
- name = "lounge"
- desc = "An elegant lounge, perfect for reclining on."
- icon = 'icons/obj/structures/lounge.dmi'
- icon_state = "lounge_standing"
- base_icon = "lounge"
-
-/obj/structure/bed/chair/bench/lounge/get_material_icon()
- return icon
-
-/obj/structure/bed/chair/bench/lounge/mapped
- color = /decl/material/solid/organic/wood/mahogany::color
- material = /decl/material/solid/organic/wood/mahogany
- reinf_material = /decl/material/solid/organic/cloth
- padding_color = COLOR_RED_GRAY
diff --git a/code/game/objects/structures/benches/lounge.dm b/code/game/objects/structures/benches/lounge.dm
new file mode 100644
index 000000000000..046ccc3c034e
--- /dev/null
+++ b/code/game/objects/structures/benches/lounge.dm
@@ -0,0 +1,15 @@
+/obj/structure/bed/chair/bench/lounge
+ name = "lounge"
+ desc = "An elegant lounge, perfect for reclining on."
+ icon = 'icons/obj/structures/lounge.dmi'
+ icon_state = "lounge_standing"
+ base_icon = "lounge"
+
+/obj/structure/bed/chair/bench/lounge/get_material_icon()
+ return icon
+
+/obj/structure/bed/chair/bench/lounge/mapped
+ color = /decl/material/solid/organic/wood/mahogany::color
+ material = /decl/material/solid/organic/wood/mahogany
+ reinf_material = /decl/material/solid/organic/cloth
+ padding_color = COLOR_RED_GRAY
diff --git a/code/game/objects/structures/benches/pew.dm b/code/game/objects/structures/benches/pew.dm
new file mode 100644
index 000000000000..272d62c51165
--- /dev/null
+++ b/code/game/objects/structures/benches/pew.dm
@@ -0,0 +1,23 @@
+/obj/structure/bed/chair/bench/pew
+ name = "pew"
+ desc = "A long bench with a backboard, commonly found in places of worship, courtrooms and so on. Not known for being particularly comfortable."
+ icon = 'icons/obj/structures/pews.dmi'
+ icon_state = "pew_standing"
+ base_icon = "pew"
+
+/obj/structure/bed/chair/bench/pew/get_material_icon()
+ return material?.pew_icon
+
+/obj/structure/bed/chair/bench/pew/single
+ name = "backed chair"
+ desc = "A tall chair with a sturdy back. Not very comfortable."
+ base_icon = "pew_standing"
+ connect_neighbors = FALSE
+
+/obj/structure/bed/chair/bench/pew/mahogany
+ color = /decl/material/solid/organic/wood/mahogany::color
+ material = /decl/material/solid/organic/wood/mahogany
+
+/obj/structure/bed/chair/bench/pew/ebony
+ color = /decl/material/solid/organic/wood/ebony::color
+ material = /decl/material/solid/organic/wood/ebony
diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/chairs.dm b/code/game/objects/structures/chairs/chairs.dm
similarity index 100%
rename from code/game/objects/structures/stool_bed_chair_nest_sofa/chairs.dm
rename to code/game/objects/structures/chairs/chairs.dm
diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/rustic_chairs.dm b/code/game/objects/structures/chairs/rustic_chairs.dm
similarity index 100%
rename from code/game/objects/structures/stool_bed_chair_nest_sofa/rustic_chairs.dm
rename to code/game/objects/structures/chairs/rustic_chairs.dm
diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/wheelchair.dm b/code/game/objects/structures/chairs/wheelchair.dm
similarity index 100%
rename from code/game/objects/structures/stool_bed_chair_nest_sofa/wheelchair.dm
rename to code/game/objects/structures/chairs/wheelchair.dm
diff --git a/code/game/objects/structures/filter_stand.dm b/code/game/objects/structures/chemistry/filter_stand.dm
similarity index 100%
rename from code/game/objects/structures/filter_stand.dm
rename to code/game/objects/structures/chemistry/filter_stand.dm
diff --git a/code/game/objects/structures/chemistry/_chemistry.dm b/code/game/objects/structures/chemistry/heater.dm
similarity index 97%
rename from code/game/objects/structures/chemistry/_chemistry.dm
rename to code/game/objects/structures/chemistry/heater.dm
index 338fdd8a24bc..7050d2f9ee86 100644
--- a/code/game/objects/structures/chemistry/_chemistry.dm
+++ b/code/game/objects/structures/chemistry/heater.dm
@@ -1,6 +1,6 @@
/obj/structure/fire_source/heater
name = "heater"
- desc = "An small, squat burner, generally used for heating reagents."
+ desc = "A small, squat burner, generally used for heating reagents."
icon = 'icons/obj/structures/alembic.dmi'
icon_state = ICON_STATE_WORLD
material = /decl/material/solid/stone/pottery
diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm
index ba9e023a08e3..629490936d77 100644
--- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm
@@ -35,7 +35,7 @@
*/
/obj/structure/closet/chefcloset
name = "chef's closet"
- desc = "It's a storage unit for foodservice garments."
+ desc = "It's a storage unit for food service garments."
closet_appearance = /decl/closet_appearance/wardrobe/black
/obj/structure/closet/chefcloset/WillContain()
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 909998d0bc77..c4259273a4b0 100644
--- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
@@ -16,7 +16,7 @@
*/
/obj/structure/closet/emcloset
name = "emergency closet"
- desc = "It's a storage unit for emergency breathmasks and o2 tanks."
+ desc = "It's a storage unit for emergency breath masks and oxygen tanks."
closet_appearance = /decl/closet_appearance/oxygen
/obj/structure/closet/emcloset/WillContain()
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index d3aa1f21c39c..9182d57f4e69 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -90,7 +90,7 @@
/obj/structure/closet/crate/internals
name = "internals crate"
- desc = "A internals crate."
+ desc = "An internals crate."
/obj/structure/closet/crate/internals/fuel
name = "\improper Fuel tank crate"
@@ -179,7 +179,7 @@
/obj/structure/closet/crate/radiation
name = "radioactive crate"
- desc = "A leadlined crate with a radiation sign on it."
+ desc = "A lead-lined crate with a radiation sign on it."
closet_appearance = /decl/closet_appearance/crate/radiation
/obj/structure/closet/crate/radiation_gear
@@ -197,7 +197,7 @@
/obj/structure/closet/crate/secure/explosives
name = "explosives crate"
- desc = "A secure exploxives crate."
+ desc = "A secure explosives crate."
closet_appearance = /decl/closet_appearance/crate/secure/hazard
/obj/structure/closet/crate/secure/shuttle
diff --git a/code/game/objects/structures/crematorium.dm b/code/game/objects/structures/crematorium.dm
index 61b227552247..bb05961a107a 100644
--- a/code/game/objects/structures/crematorium.dm
+++ b/code/game/objects/structures/crematorium.dm
@@ -1,6 +1,6 @@
/obj/structure/crematorium
name = "crematorium"
- desc = "A human incinerator. Works well on barbeque nights."
+ desc = "A human incinerator. Works well on barbecue nights."
icon = 'icons/obj/structures/crematorium.dmi'
icon_state = "crematorium_closed"
density = TRUE
diff --git a/code/game/objects/structures/fires.dm b/code/game/objects/structures/fires.dm
index 4da0fe525978..e112d5cc5374 100644
--- a/code/game/objects/structures/fires.dm
+++ b/code/game/objects/structures/fires.dm
@@ -202,6 +202,9 @@
else
to_chat(user, "\The [src] is empty.")
+ if(check_rights(R_DEBUG, 0, user))
+ to_chat(user, "\The [src] has a temperature of [temperature]K, an effective burn temperature of [get_effective_burn_temperature()]K and a fuel value of [fuel].")
+
/obj/structure/fire_source/attack_hand(var/mob/user)
var/list/removable_atoms = get_removable_atoms()
diff --git a/code/game/objects/structures/fishtanks.dm b/code/game/objects/structures/fishtanks.dm
index b6724f467752..f11786c8c397 100644
--- a/code/game/objects/structures/fishtanks.dm
+++ b/code/game/objects/structures/fishtanks.dm
@@ -37,11 +37,13 @@ var/global/list/fishtank_cache = list()
fill_type = /decl/material/liquid/water
fill_amt = 300
-/obj/structure/glass_tank/Initialize()
+/obj/structure/glass_tank/Initialize(mapload)
tank_overlay = new(loc, src)
initialize_reagents()
. = ..()
- update_icon(TRUE)
+ update_icon()
+ if(!mapload)
+ update_nearby_tiles()
/obj/structure/glass_tank/Destroy()
if(!QDELETED(tank_overlay))
@@ -107,11 +109,19 @@ var/global/list/global/aquarium_states_and_layers = list(
"z" = FLY_LAYER + 0.01
)
-/obj/structure/glass_tank/on_update_icon(propagate = 0)
+/obj/structure/glass_tank/update_nearby_tiles(need_rebuild)
+ . = ..()
+ for(var/obj/structure/glass_tank/tank in orange(1, src))
+ if(tank.type != type)
+ continue
+ tank.update_icon()
+
+/obj/structure/glass_tank/on_update_icon()
var/list/connect_dirs = list()
- for(var/obj/structure/glass_tank/A in orange(1, src))
- if(A.type == type)
- connect_dirs |= get_dir(src, A)
+ for(var/obj/structure/glass_tank/tank in orange(1, src))
+ if(tank.type != type)
+ continue
+ connect_dirs |= get_dir(src, tank)
var/list/c_states = dirs_to_unified_corner_states(connect_dirs)
if(tank_overlay)
@@ -129,16 +139,13 @@ var/global/list/global/aquarium_states_and_layers = list(
tank_overlay.add_overlay(global.fishtank_cache[cache_key])
// Update overlays with contents.
+ // TODO: Can this just use vis_contents...?
+ // Or add its contents to vis_contents on some sort of helper atom,
+ // which has the VIS_UNDERLAY flag so it shows up under the transparent part?
icon_state = "base"
..()
- for(var/atom/movable/AM in contents)
- if(AM.simulated)
- add_overlay(AM)
-
- if(propagate)
- for(var/obj/structure/glass_tank/A in orange(1, src))
- if(A.type == type)
- A.update_icon()
+ for(var/atom/movable/AM in get_contained_external_atoms())
+ add_overlay(AM)
/obj/structure/glass_tank/can_climb(var/mob/living/user, post_climb_check=0)
if (!user.can_touch(src) || !(atom_flags & ATOM_FLAG_CLIMBABLE) || (!post_climb_check && (user in climbers)))
diff --git a/code/game/objects/structures/flora/tree.dm b/code/game/objects/structures/flora/tree.dm
index a088f2297cf2..13dcf346bcc1 100644
--- a/code/game/objects/structures/flora/tree.dm
+++ b/code/game/objects/structures/flora/tree.dm
@@ -20,9 +20,6 @@
var/protects_against_weather = TRUE
/// What kind of tree stump we leaving behind.
var/stump_type
- /// How much to shake the tree when struck.
- /// Larger trees should have smaller numbers or it looks weird.
- var/shake_animation_degrees = 4
/// Marker for repeating the cut sound effect and animation.
var/someone_is_cutting = FALSE
@@ -55,32 +52,21 @@
/obj/structure/flora/tree/take_damage(damage, damage_type = BRUTE, damage_flags, inflicter, armor_pen = 0, silent, do_update_health)
. = ..()
if(!QDELETED(src) && damage >= 5)
- shake()
+ shake_animation()
// We chop several times to cut down a tree.
/obj/structure/flora/tree/play_cut_sound(mob/user)
- shake()
+ shake_animation()
while(someone_is_cutting)
sleep(1 SECOND)
if(QDELETED(src))
return
- shake()
+ shake_animation()
playsound(src, 'sound/items/axe_wood.ogg', 40, TRUE)
if(QDELETED(src) || QDELETED(user) || !user.Adjacent(src))
return
return ..()
-// Tree shake animation stolen from Polaris.
-/obj/structure/flora/tree/proc/shake()
- set waitfor = FALSE
- var/init_px = pixel_x
- var/shake_dir = pick(-1, 1)
- var/matrix/M = matrix()
- M.Scale(icon_scale_x, icon_scale_y)
- M.Translate(0, 16*(icon_scale_y-1))
- animate(src, transform=turn(M, shake_animation_degrees * shake_dir), pixel_x=init_px + 2*shake_dir, time=1)
- animate(transform=M, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
-
/obj/structure/flora/tree/create_dismantled_products(turf/T)
if(log_type)
LAZYADD(., new log_type(T, rand(max(1,round(log_amount*0.5)), log_amount), material?.type, reinf_material?.type))
diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm
index b2ed1afb24a0..fb9f17eeb078 100644
--- a/code/game/objects/structures/janicart.dm
+++ b/code/game/objects/structures/janicart.dm
@@ -111,49 +111,50 @@
ui.set_initial_data(data)
ui.open()
-/obj/structure/janitorialcart/Topic(href, href_list)
- if(!in_range(src, usr))
- return
- if(!isliving(usr))
- return
- var/mob/living/user = usr
-
- if(href_list["take"])
- switch(href_list["take"])
- if("garbage")
- if(mybag)
- user.put_in_hands(mybag)
- to_chat(user, "You take [mybag] from [src].")
- mybag = null
- if("mop")
- if(mymop)
- user.put_in_hands(mymop)
- to_chat(user, "You take [mymop] from [src].")
- mymop = null
- if("spray")
- if(myspray)
- user.put_in_hands(myspray)
- to_chat(user, "You take [myspray] from [src].")
- myspray = null
- if("replacer")
- if(myreplacer)
- user.put_in_hands(myreplacer)
- to_chat(user, "You take [myreplacer] from [src].")
- myreplacer = null
- if("sign")
- if(signs)
- var/obj/item/caution/Sign = locate() in src
- if(Sign)
- user.put_in_hands(Sign)
- to_chat(user, "You take \a [Sign] from [src].")
- signs--
- else
- warning("[src] signs ([signs]) didn't match contents")
- signs = 0
-
- update_icon()
- updateUsrDialog()
-
+/obj/structure/janitorialcart/OnTopic(mob/user, href_list)
+ switch(href_list["take"])
+ if("garbage")
+ if(mybag)
+ user.put_in_hands(mybag)
+ to_chat(user, "You take [mybag] from [src].")
+ mybag = null
+ return TOPIC_REFRESH
+ return TOPIC_HANDLED
+ if("mop")
+ if(mymop)
+ user.put_in_hands(mymop)
+ to_chat(user, "You take [mymop] from [src].")
+ mymop = null
+ return TOPIC_REFRESH
+ return TOPIC_HANDLED
+ if("spray")
+ if(myspray)
+ user.put_in_hands(myspray)
+ to_chat(user, "You take [myspray] from [src].")
+ myspray = null
+ return TOPIC_REFRESH
+ return TOPIC_HANDLED
+ if("replacer")
+ if(myreplacer)
+ user.put_in_hands(myreplacer)
+ to_chat(user, "You take [myreplacer] from [src].")
+ myreplacer = null
+ return TOPIC_REFRESH
+ return TOPIC_HANDLED
+ if("sign")
+ if(signs)
+ var/obj/item/caution/Sign = locate() in src
+ if(Sign)
+ user.put_in_hands(Sign)
+ to_chat(user, "You take \a [Sign] from [src].")
+ signs--
+ else
+ warning("[src] signs ([signs]) didn't match contents")
+ signs = 0
+ return TOPIC_REFRESH
+ return TOPIC_HANDLED
+ else
+ return TOPIC_NOACTION
/obj/structure/janitorialcart/on_update_icon()
..()
diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm
index 2ae373f0513d..ae06bb484e42 100644
--- a/code/game/objects/structures/railing.dm
+++ b/code/game/objects/structures/railing.dm
@@ -70,7 +70,8 @@ WOOD_RAILING_SUBTYPE(yew)
else
obj_flags &= (~OBJ_FLAG_CONDUCTIBLE)
- update_icon(FALSE)
+ update_connections()
+ update_icon()
/obj/structure/railing/get_material_health_modifier()
. = 0.2
@@ -98,7 +99,8 @@ WOOD_RAILING_SUBTYPE(yew)
return !density
return TRUE
-/obj/structure/railing/proc/NeighborsCheck(var/UpdateNeighbors = 1)
+// TODO: Make railings use the normal structure smoothing system! This sucks!
+/obj/structure/railing/update_connections(propagate = FALSE)
neighbor_status = 0
var/Rturn = turn(dir, -90)
var/Lturn = turn(dir, 90)
@@ -106,35 +108,40 @@ WOOD_RAILING_SUBTYPE(yew)
for(var/obj/structure/railing/R in loc)
if ((R.dir == Lturn) && R.anchored)
neighbor_status |= 32
- if (UpdateNeighbors)
- R.update_icon(0)
+ if (propagate)
+ R.update_connections()
+ R.update_icon()
if ((R.dir == Rturn) && R.anchored)
neighbor_status |= 2
- if (UpdateNeighbors)
- R.update_icon(0)
+ if (propagate)
+ R.update_connections()
+ R.update_icon()
for (var/obj/structure/railing/R in get_step(src, Lturn))
if ((R.dir == dir) && R.anchored)
neighbor_status |= 16
- if (UpdateNeighbors)
- R.update_icon(0)
+ if (propagate)
+ R.update_connections()
+ R.update_icon()
for (var/obj/structure/railing/R in get_step(src, Rturn))
if ((R.dir == dir) && R.anchored)
neighbor_status |= 1
- if (UpdateNeighbors)
- R.update_icon(0)
+ if (propagate)
+ R.update_connections()
+ R.update_icon()
for (var/obj/structure/railing/R in get_step(src, (Lturn + dir)))
if ((R.dir == Rturn) && R.anchored)
neighbor_status |= 64
- if (UpdateNeighbors)
- R.update_icon(0)
+ if (propagate)
+ R.update_connections()
+ R.update_icon()
for (var/obj/structure/railing/R in get_step(src, (Rturn + dir)))
if ((R.dir == Lturn) && R.anchored)
neighbor_status |= 4
- if (UpdateNeighbors)
- R.update_icon(0)
+ if (propagate)
+ R.update_connections()
+ R.update_icon()
-/obj/structure/railing/on_update_icon(var/update_neighbors = TRUE)
- NeighborsCheck(update_neighbors)
+/obj/structure/railing/on_update_icon()
..()
if (!neighbor_status || !anchored)
icon_state = "railing0-[density]"
@@ -188,6 +195,7 @@ WOOD_RAILING_SUBTYPE(yew)
forceMove(get_step(src, dir))
set_dir(turn(dir, 180))
+ update_connections(TRUE)
update_icon()
/obj/structure/railing/CheckExit(var/atom/movable/O, var/turf/target)
@@ -260,6 +268,7 @@ WOOD_RAILING_SUBTYPE(yew)
else
user.visible_message("\The [user] wrenches \the [src] closed.", "You wrench \the [src] closed.")
density = TRUE
+ update_connections(TRUE)
update_icon()
return TRUE
// Repair
@@ -288,6 +297,7 @@ WOOD_RAILING_SUBTYPE(yew)
if(do_after(user, 10, src) && density)
to_chat(user, (anchored ? "You have unfastened \the [src] from the floor." : "You have fastened \the [src] to the floor."))
anchored = !anchored
+ update_connections(TRUE)
update_icon()
return TRUE
diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm
index 10db1cd1afb3..5257b0607a9f 100644
--- a/code/game/objects/structures/safe.dm
+++ b/code/game/objects/structures/safe.dm
@@ -85,20 +85,18 @@ FLOOR SAFES
show_browser(user, "[name][dat]", "window=safe;size=350x300")
return TRUE
-/obj/structure/safe/Topic(href, href_list)
- if(!ishuman(usr)) return
- var/mob/living/human/user = usr
+/obj/structure/safe/DefaultTopicState()
+ return global.physical_no_access_topic_state
+/obj/structure/safe/OnTopic(mob/user, href_list, state)
if(href_list["open"])
if(check_unlocked())
to_chat(user, "You [open ? "close" : "open"] [src].")
open = !open
- update_icon()
- updateUsrDialog()
- return
+ return TOPIC_REFRESH
else
to_chat(user, "You can't [open ? "close" : "open"] [src], the lock is engaged!")
- return
+ return TOPIC_HANDLED
var/canhear = locate(/obj/item/clothing/neck/stethoscope) in user.get_held_items()
if(href_list["decrement"])
@@ -112,8 +110,7 @@ FLOOR SAFES
if(canhear)
to_chat(user, "You hear a [pick("click", "chink", "clink")] from [src].")
check_unlocked(user, canhear)
- updateUsrDialog()
- return
+ return TOPIC_REFRESH
if(href_list["increment"])
dial = increment(dial)
@@ -126,17 +123,15 @@ FLOOR SAFES
if(canhear)
to_chat(user, "You hear a [pick("click", "chink", "clink")] from [src].")
check_unlocked(user, canhear)
- updateUsrDialog()
- return
+ return TOPIC_REFRESH
if(href_list["retrieve"])
- close_browser(user, "window=safe") // Close the menu
-
+ if(!open)
+ return TOPIC_CLOSE // Close the menu
var/obj/item/P = locate(href_list["retrieve"]) in src
- if(open)
- if(P && in_range(src, user))
- user.put_in_hands(P)
- updateUsrDialog()
+ if(P && CanPhysicallyInteract(user))
+ user.put_in_hands(P)
+ return TOPIC_REFRESH
/obj/structure/safe/attackby(obj/item/I, mob/user)
diff --git a/code/game/objects/structures/signs/department_signs.dm b/code/game/objects/structures/signs/department_signs.dm
index 9493d2d622f8..92fa661be71e 100644
--- a/code/game/objects/structures/signs/department_signs.dm
+++ b/code/game/objects/structures/signs/department_signs.dm
@@ -23,24 +23,24 @@
/obj/structure/sign/department/xenobio_1
name = "\improper XENOBIOLOGY"
- desc = "A sign labelling an area as a place where xenobiological entites are researched."
+ desc = "A sign labelling an area as a place where xenobiological entities are researched."
icon_state = "xenobio"
/obj/structure/sign/department/xenobio_2
name = "\improper XENOBIOLOGY"
- desc = "A sign labelling an area as a place where xenobiological entites are researched."
+ desc = "A sign labelling an area as a place where xenobiological entities are researched."
icon = 'icons/obj/signs/location_signs.dmi'
icon_state = "xenobio2"
/obj/structure/sign/department/xenobio_3
name = "\improper XENOBIOLOGY"
- desc = "A sign labelling an area as a place where xenobiological entites are researched."
+ desc = "A sign labelling an area as a place where xenobiological entities are researched."
icon = 'icons/obj/signs/location_signs.dmi'
icon_state = "xenobio3"
/obj/structure/sign/department/xenobio_4
name = "\improper XENOBIOLOGY"
- desc = "A sign labelling an area as a place where xenobiological entites are researched."
+ desc = "A sign labelling an area as a place where xenobiological entities are researched."
icon = 'icons/obj/signs/location_signs.dmi'
icon_state = "xenobio4"
@@ -176,6 +176,6 @@
/obj/structure/sign/department/star_of_life
name = "emergency"
- desc = "The blue six pointed star with a rod of Asclepius is the intergalactic symbol of emergency medical services."
+ desc = "The blue six-pointed star with a rod of Asclepius is the intergalactic symbol of emergency medical services."
icon = 'icons/obj/signs/medical.dmi'
icon_state = "staroflife"
\ No newline at end of file
diff --git a/code/game/objects/structures/signs/plaques.dm b/code/game/objects/structures/signs/plaques.dm
index e455131d89aa..19d72c4e1efc 100644
--- a/code/game/objects/structures/signs/plaques.dm
+++ b/code/game/objects/structures/signs/plaques.dm
@@ -31,7 +31,7 @@
/obj/structure/sign/plaque/golden/medical
name = "medical certificate"
- desc = "A picture next to a long winded description of medical certifications and degrees."
+ desc = "A picture next to a long-winded description of medical certifications and degrees."
/obj/structure/sign/plaque/ai_dev
name = "\improper AI developers plaque"
diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/sofa.dm b/code/game/objects/structures/sofa.dm
similarity index 100%
rename from code/game/objects/structures/stool_bed_chair_nest_sofa/sofa.dm
rename to code/game/objects/structures/sofa.dm
diff --git a/code/game/objects/structures/stool_bed_chair_nest_sofa/bed.dm b/code/game/objects/structures/stool_bed_chair_nest_sofa/bed.dm
deleted file mode 100644
index f1ec03d9f7cf..000000000000
--- a/code/game/objects/structures/stool_bed_chair_nest_sofa/bed.dm
+++ /dev/null
@@ -1,350 +0,0 @@
-/* Beds... get your mind out of the gutter, they're for sleeping!
- * Contains:
- * Beds
- * Roller beds
- * Mattresses
- */
-
-/*
- * Beds
- */
-/obj/structure/bed
- name = "bed"
- desc = "A raised, padded platform for sleeping on. This one has straps for ensuring restful snoozing in microgravity."
- icon = 'icons/obj/furniture.dmi'
- icon_state = "bed"
- anchored = TRUE
- can_buckle = TRUE
- buckle_dir = SOUTH
- buckle_lying = TRUE
- buckle_sound = 'sound/effects/buckle.ogg'
- material = DEFAULT_FURNITURE_MATERIAL
- material_alteration = MAT_FLAG_ALTERATION_ALL
- tool_interaction_flags = TOOL_INTERACTION_DECONSTRUCT
- parts_amount = 2
- parts_type = /obj/item/stack/material/rods
- user_comfort = 1
- obj_flags = OBJ_FLAG_SUPPORT_MOB
- var/base_icon = "bed"
- var/padding_color
-
-/obj/structure/bed/user_can_mousedrop_onto(mob/user, atom/being_dropped, incapacitation_flags, params)
- if(user == being_dropped)
- return user.Adjacent(src) && !user.incapacitated(INCAPACITATION_STUNNED|INCAPACITATION_KNOCKOUT)
- return ..()
-
-/obj/structure/bed/get_base_value()
- . = round(..() * 2.5) // Utility structures should be worth more than their matter (wheelchairs, rollers, etc).
-
-/obj/structure/bed/get_surgery_surface_quality(mob/living/victim, mob/living/user)
- return OPERATE_PASSABLE
-
-/obj/structure/bed/get_surgery_success_modifier(delicate)
- return delicate ? -5 : 0
-
-/obj/structure/bed/update_material_name()
- if(reinf_material)
- SetName("[reinf_material.adjective_name] [initial(name)]")
- else if(material)
- SetName("[material.adjective_name] [initial(name)]")
- else
- SetName(initial(name))
-
-/obj/structure/bed/update_material_desc()
- if(reinf_material)
- desc = "[initial(desc)] It's made of [material.use_name] and covered with [reinf_material.use_name]."
- else
- desc = "[initial(desc)] It's made of [material.use_name]."
-
-// Reuse the cache/code from stools, todo maybe unify.
-/obj/structure/bed/on_update_icon()
- ..()
- icon_state = base_icon
- if(istype(reinf_material))
- if(material_alteration & MAT_FLAG_ALTERATION_COLOR)
- add_overlay(overlay_image(icon, "[icon_state]_padding", padding_color || reinf_material.color, RESET_COLOR))
- else
- add_overlay(overlay_image(icon, "[icon_state]_padding"))
-
-/obj/structure/bed/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(istype(mover) && mover.checkpass(PASS_FLAG_TABLE))
- return 1
- return ..()
-
-/obj/structure/bed/explosion_act(severity)
- . = ..()
- if(. && !QDELETED(src) && (severity == 1 || (severity == 2 && prob(50)) || (severity == 3 && prob(5))))
- physically_destroyed()
-
-/obj/structure/bed/proc/can_apply_padding()
- return TRUE
-
-/obj/structure/bed/attackby(obj/item/used_item, mob/user)
-
- if((. = ..()))
- return
-
- if(istype(used_item, /obj/item/stack) && can_apply_padding())
-
- if(reinf_material)
- to_chat(user, SPAN_WARNING("\The [src] is already padded."))
- return TRUE
-
- var/obj/item/stack/cloth = used_item
- if(cloth.get_amount() < 1)
- to_chat(user, SPAN_WARNING("You need at least one unit of material to pad \the [src]."))
- return TRUE
-
- var/padding_type
- var/new_padding_color
- if(istype(used_item, /obj/item/stack/tile) || istype(used_item, /obj/item/stack/material/bolt))
- padding_type = used_item.material?.type
- new_padding_color = used_item.paint_color
-
- if(padding_type)
- var/decl/material/padding_mat = GET_DECL(padding_type)
- if(!istype(padding_mat) || !(padding_mat.flags & MAT_FLAG_PADDING))
- padding_type = null
-
- if(!padding_type)
- to_chat(user, SPAN_WARNING("You cannot pad \the [src] with that."))
- return TRUE
-
- cloth.use(1)
- if(!isturf(src.loc))
- src.forceMove(get_turf(src))
- playsound(src.loc, 'sound/effects/rustle5.ogg', 50, 1)
- to_chat(user, SPAN_NOTICE("You add padding to \the [src]."))
- add_padding(padding_type, new_padding_color)
- return TRUE
-
- if(IS_WIRECUTTER(used_item))
- if(!reinf_material)
- to_chat(user, SPAN_WARNING("\The [src] has no padding to remove."))
- else
- to_chat(user, SPAN_NOTICE("You remove the padding from \the [src]."))
- playsound(src, 'sound/items/Wirecutter.ogg', 100, 1)
- remove_padding()
- return TRUE
-
-/obj/structure/bed/grab_attack(obj/item/grab/grab, mob/user)
- var/mob/living/victim = grab.get_affecting_mob()
- if(istype(victim) && istype(user))
- user.visible_message(SPAN_NOTICE("\The [user] attempts to put \the [victim] onto \the [src]!"))
- if(do_after(user, 2 SECONDS, src) && !QDELETED(victim) && !QDELETED(user) && !QDELETED(grab) && user_buckle_mob(victim, user))
- qdel(grab)
- return TRUE
- return ..()
-
-/obj/structure/bed/proc/add_padding(var/padding_type, var/new_padding_color)
- reinf_material = GET_DECL(padding_type)
- padding_color = new_padding_color
- update_icon()
-
-/obj/structure/bed/proc/remove_padding()
- if(reinf_material)
- var/list/res = reinf_material.create_object(get_turf(src))
- if(padding_color)
- for(var/obj/item/thing in res)
- thing.set_color(padding_color)
- reinf_material = null
- padding_color = null
- update_icon()
-
-/obj/structure/bed/psych
- name = "psychiatrist's couch"
- desc = "For prime comfort during psychiatric evaluations."
- icon_state = "psychbed"
- material = /decl/material/solid/organic/wood/walnut
-
-/obj/structure/bed/psych/leather
- reinf_material = /decl/material/solid/organic/leather
-
-/obj/structure/bed/padded
- material = /decl/material/solid/metal/aluminium
- reinf_material = /decl/material/solid/organic/cloth
-
-/*
- * Travois used to drag mobs in low-tech settings.
- */
-/obj/structure/bed/travois
- name = "travois"
- anchored = FALSE
- icon_state = ICON_STATE_WORLD
- base_icon = ICON_STATE_WORLD
- icon = 'icons/obj/structures/travois.dmi'
- buckle_pixel_shift = list("x" = 0, "y" = 0, "z" = 6)
- movable_flags = MOVABLE_FLAG_WHEELED
- user_comfort = 0
- material = /decl/material/solid/organic/wood/oak
-
-/obj/structure/bed/travois/can_apply_padding()
- return FALSE
-
-/*
- * Roller beds
- */
-/obj/structure/bed/roller
- name = "roller bed"
- icon = 'icons/obj/structures/rollerbed.dmi'
- icon_state = "down"
- anchored = FALSE
- buckle_pixel_shift = list("x" = 0, "y" = 0, "z" = 6)
- movable_flags = MOVABLE_FLAG_WHEELED
- tool_interaction_flags = 0
- var/item_form_type = /obj/item/roller //The folded-up object path.
- var/obj/item/chems/beaker
- var/iv_attached = 0
- var/iv_stand = TRUE
-
-/obj/structure/bed/roller/on_update_icon()
- cut_overlays()
- if(density)
- icon_state = "up"
- else
- icon_state = "down"
- if(beaker)
- var/image/iv = image(icon, "iv[iv_attached]")
- var/percentage = round((beaker.reagents.total_volume / beaker.volume) * 100, 25)
- var/image/filling = image(icon, "iv_filling[percentage]")
- filling.color = beaker.reagents.get_color()
- iv.overlays += filling
- if(percentage < 25)
- iv.overlays += image(icon, "light_low")
- if(density)
- iv.pixel_y = 6
- add_overlay(iv)
-
-/obj/structure/bed/roller/can_apply_padding()
- return FALSE
-
-/obj/structure/bed/roller/attackby(obj/item/I, mob/user)
- if(iv_stand && !beaker && istype(I, /obj/item/chems))
- if(!user.try_unequip(I, src))
- return TRUE
- to_chat(user, "You attach \the [I] to \the [src].")
- beaker = I
- queue_icon_update()
- return TRUE
- return ..()
-
-/obj/structure/bed/roller/attack_hand(mob/user)
- if(!beaker || buckled_mob || !user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE))
- return ..()
- remove_beaker(user)
- return TRUE
-
-/obj/structure/bed/roller/proc/collapse(mob/user)
- visible_message("[user] collapses [src].")
- new item_form_type(get_turf(src))
- qdel(src)
-
-/obj/structure/bed/roller/post_buckle_mob(mob/living/M)
- . = ..()
- if(M == buckled_mob)
- set_density(1)
- queue_icon_update()
- else
- set_density(0)
- if(iv_attached)
- detach_iv(M, usr)
- queue_icon_update()
-
-/obj/structure/bed/roller/Process()
- if(!iv_attached || !buckled_mob || !beaker)
- return PROCESS_KILL
-
- //SSObj fires twice as fast as SSMobs, so gotta slow down to not OD our victims.
- if(SSobj.times_fired % 2)
- return
-
- if(beaker.volume > 0)
- beaker.reagents.trans_to_mob(buckled_mob, beaker.amount_per_transfer_from_this, CHEM_INJECT)
- queue_icon_update()
-
-/obj/structure/bed/roller/proc/remove_beaker(mob/user)
- to_chat(user, "You detach \the [beaker] to \the [src].")
- iv_attached = FALSE
- beaker.dropInto(loc)
- beaker = null
- queue_icon_update()
-
-/obj/structure/bed/roller/proc/attach_iv(mob/living/human/target, mob/user)
- if(!beaker)
- return
- if(do_IV_hookup(target, user, beaker))
- iv_attached = TRUE
- queue_icon_update()
- START_PROCESSING(SSobj,src)
-
-/obj/structure/bed/roller/proc/detach_iv(mob/living/human/target, mob/user)
- visible_message("\The [target] is taken off the IV on \the [src].")
- iv_attached = FALSE
- queue_icon_update()
- STOP_PROCESSING(SSobj,src)
-
-/obj/structure/bed/roller/handle_mouse_drop(atom/over, mob/user, params)
- if(ishuman(user) || isrobot(user))
- if(over == buckled_mob && beaker)
- if(iv_attached)
- detach_iv(buckled_mob, user)
- else
- attach_iv(buckled_mob, user)
- return TRUE
- if(ishuman(over))
- var/mob/M = over
- if(loc == M.loc && user_buckle_mob(M, user))
- attach_iv(buckled_mob, user)
- return TRUE
- if(beaker)
- remove_beaker(user)
- return TRUE
- if(!buckled_mob)
- collapse(user)
- return TRUE
- . = ..()
-
-/obj/item/roller
- name = "roller bed"
- desc = "A collapsed roller bed that can be carried around."
- icon = 'icons/obj/items/rollerbed.dmi'
- icon_state = ICON_STATE_WORLD
- slot_flags = SLOT_BACK
- w_class = ITEM_SIZE_LARGE
- pickup_sound = 'sound/foley/pickup2.ogg'
- material = /decl/material/solid/metal/steel
- matter = list(
- /decl/material/solid/organic/plastic = MATTER_AMOUNT_SECONDARY,
- /decl/material/solid/organic/cloth = MATTER_AMOUNT_REINFORCEMENT,
- )
- var/structure_form_type = /obj/structure/bed/roller //The deployed form path.
-
-/obj/item/roller/get_single_monetary_worth()
- . = structure_form_type ? atom_info_repository.get_combined_worth_for(structure_form_type) : ..()
-
-/obj/item/roller/attack_self(mob/user)
- var/obj/structure/bed/roller/R = new structure_form_type(user.loc)
- R.add_fingerprint(user)
- qdel(src)
-
-/obj/item/robot_rack/roller
- name = "roller bed rack"
- desc = "A rack for carrying collapsed roller beds. Can also be used for carrying ironing boards."
- icon = 'icons/obj/items/rollerbed.dmi'
- icon_state = ICON_STATE_WORLD
- object_type = /obj/item/roller
- interact_type = /obj/structure/bed/roller
-/*
- * Mattresses
- */
-/obj/structure/mattress
- name = "mattress"
- icon = 'icons/obj/furniture.dmi'
- icon_state = "mattress"
- desc = "A bare mattress. It doesn't look very comfortable."
- anchored = FALSE
-
-/obj/structure/mattress/dirty
- name = "dirty mattress"
- icon_state = "dirty_mattress"
- desc = "A dirty, smelly mattress covered in body fluids. You wouldn't want to touch this."
diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm
index b7fba083f5c9..0c9982cc9a63 100644
--- a/code/game/objects/structures/transit_tubes.dm
+++ b/code/game/objects/structures/transit_tubes.dm
@@ -380,7 +380,7 @@
// Parse the icon_state into a list of directions.
-// This means that mappers can use Dream Maker's built in
+// This means that mappers can use Dream Maker's built-in
// "Generate Instances from Icon-states" option to get all
// variations. Additionally, as a separate proc, sub-types
// can handle it more intelligently.
diff --git a/code/game/objects/structures/under_wardrobe.dm b/code/game/objects/structures/under_wardrobe.dm
index e8f8ab1e513f..815a1405394a 100644
--- a/code/game/objects/structures/under_wardrobe.dm
+++ b/code/game/objects/structures/under_wardrobe.dm
@@ -69,49 +69,44 @@
return ..()
-/obj/structure/undies_wardrobe/Topic(href, href_list, state)
- if(..())
- return TRUE
+/obj/structure/undies_wardrobe/OnTopic(mob/user, href_list, state)
+ if((. = ..()))
+ return
- var/mob/living/human/H = usr
if(href_list["select_underwear"])
var/datum/category_group/underwear/UWC = global.underwear.categories_by_name[href_list["select_underwear"]]
if(!UWC)
- return
- var/datum/category_item/underwear/UWI = input("Select your desired underwear:", "Choose underwear") as null|anything in exclude_none(UWC.items)
+ return TOPIC_HANDLED
+ var/datum/category_item/underwear/UWI = input(user, "Select your desired underwear:", "Choose underwear") as null|anything in exclude_none(UWC.items)
if(!UWI)
- return
+ return TOPIC_HANDLED
var/list/metadata_list = list()
for(var/tweak in UWI.tweaks)
var/datum/gear_tweak/gt = tweak
- var/metadata = gt.get_metadata(H, title = "Adjust underwear")
+ var/metadata = gt.get_metadata(user, title = "Adjust underwear")
if(!metadata)
- return
+ return TOPIC_HANDLED
metadata_list["[gt]"] = metadata
- if(!CanInteract(H, state))
- return
+ if(!CanInteract(user, state))
+ return TOPIC_HANDLED
- var/id = H.GetIdCard()
+ var/id = user.GetIdCard()
if(!id)
- audible_message("No ID card detected. Unable to acquire your underwear quota for this shift.", WARDROBE_BLIND_MESSAGE(H))
- return
+ audible_message("No ID card detected. Unable to acquire your underwear quota for this shift.", WARDROBE_BLIND_MESSAGE(user))
+ return TOPIC_HANDLED
var/current_quota = LAZYACCESS(amount_of_underwear_by_id_card, id)
if(current_quota >= length(global.underwear.categories))
- audible_message("You have already used up your underwear quota for this shift. Please return previously acquired items to increase it.", WARDROBE_BLIND_MESSAGE(H))
- return
+ audible_message("You have already used up your underwear quota for this shift. Please return previously acquired items to increase it.", WARDROBE_BLIND_MESSAGE(user))
+ return TOPIC_HANDLED
LAZYSET(amount_of_underwear_by_id_card, id, ++current_quota)
- var/obj/UW = UWI.create_underwear(H, metadata_list)
- UW.forceMove(loc)
- H.put_in_hands(UW)
-
- . = TRUE
-
- if(.)
- interact(H)
+ var/obj/UW = UWI.create_underwear(user, metadata_list)
+ UW.dropInto(loc)
+ user.put_in_hands(UW)
+ . = TOPIC_REFRESH
/obj/structure/undies_wardrobe/proc/exclude_none(var/list/L)
. = L.Copy()
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 549d7d913abd..6a9c9f095515 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -497,7 +497,7 @@ var/global/list/hygiene_props = list()
/decl/barricade_tape_template/toilet
tape_kind = "toilet paper"
tape_desc = "A length of toilet paper. Seems like custodia is marking their territory again."
- roll_desc = "A unbranded roll of standard issue two ply toilet paper. Refined from carefully rendered down sea shells due to the government's 'Abuse Of The Trees Act'."
+ roll_desc = "An unbranded roll of standard-issue two-ply toilet paper. Refined from carefully rendered-down seashells due to the government's 'Abuse Of The Trees Act'."
base_icon_state = "stripetape"
tape_color = COLOR_WHITE
detail_overlay = "stripes"
@@ -530,7 +530,7 @@ var/global/list/hygiene_props = list()
////////////////////////////////////////////////////
/obj/item/paper/crumpled/bog
name = "sheet of toilet paper"
- desc = "A single sheet of toilet paper. Two ply."
+ desc = "A single sheet of toilet paper. Two-ply."
icon = 'icons/obj/items/paperwork/toilet_paper.dmi'
/obj/structure/hygiene/faucet
diff --git a/code/game/turfs/floors/floor_icon.dm b/code/game/turfs/floors/floor_icon.dm
index c4c7cbb83153..b7decba1b908 100644
--- a/code/game/turfs/floors/floor_icon.dm
+++ b/code/game/turfs/floors/floor_icon.dm
@@ -102,25 +102,20 @@
add_overlay(I)
pixel_z = default_pixel_z
-/turf/floor/on_update_icon(var/update_neighbors)
+/turf/floor/on_update_icon()
. = ..()
color = get_color()
cut_overlays()
- update_height_appearance() // Also refreshes out base layer.
- update_floor_icon(update_neighbors)
+ update_height_appearance() // Also refreshes our base layer.
+ update_floor_icon()
for(var/image/I in decals)
if(I.layer < layer)
continue
add_overlay(I)
- if(update_neighbors)
- for(var/turf/floor/F in orange(src, 1))
- F.queue_ao()
- F.queue_icon_update()
-
compile_overlays()
/turf/floor/proc/update_floor_strings()
@@ -132,7 +127,7 @@
SetName(initial(name))
desc = initial(desc)
-/turf/floor/proc/update_floor_icon(update_neighbors)
+/turf/floor/proc/update_floor_icon()
var/decl/flooring/use_flooring = get_topmost_flooring()
if(istype(use_flooring))
use_flooring.update_turf_icon(src)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 1c8db5bd16e0..86e5fbd5b82c 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -54,7 +54,7 @@
// get overridden almost immediately.
// TL;DR: just leave these vars alone.
- var/is_outside = OUTSIDE_AREA
+ var/is_outside = OUTSIDE_AREA // non-tmp to allow visibility in mapper.
var/tmp/obj/abstract/weather_system/weather
var/tmp/last_outside_check = OUTSIDE_UNCERTAIN
@@ -118,6 +118,10 @@
else if (permit_ao)
queue_ao()
+ // we're being loaded in a new z-level, we need to build lighting
+ if(mapload && !changing_turf && SSlighting.initialized)
+ lighting_build_overlay()
+
if(simulated)
updateVisibility(src, FALSE)
@@ -416,15 +420,15 @@
L.Add(t)
return L
-/turf/proc/contains_dense_objects(exceptions)
+/turf/proc/contains_dense_objects(list/exceptions)
if(density)
- return 1
+ return TRUE
for(var/atom/A in src)
+ if(exceptions && (exceptions == A || (islist(exceptions) && (A in exceptions))))
+ continue
if(A.density && !(A.atom_flags & ATOM_FLAG_CHECKS_BORDER))
- if(exceptions && (exceptions == A || (A in exceptions)))
- continue
- return 1
- return 0
+ return TRUE
+ return FALSE
/turf/proc/remove_cleanables()
for(var/obj/effect/decal/cleanable/cleanable in src)
diff --git a/code/game/turfs/unsimulated.dm b/code/game/turfs/unsimulated/_unsimulated.dm
similarity index 87%
rename from code/game/turfs/unsimulated.dm
rename to code/game/turfs/unsimulated/_unsimulated.dm
index 45e70ce956e8..813899f2fca3 100644
--- a/code/game/turfs/unsimulated.dm
+++ b/code/game/turfs/unsimulated/_unsimulated.dm
@@ -3,6 +3,7 @@
initial_gas = GAS_STANDARD_AIRMIX
abstract_type = /turf/unsimulated
simulated = FALSE
+ dynamic_lighting = FALSE
// Shortcut a bunch of simulation stuff since this turf just needs to sit there.
// We don't even call Initialize(), how cool is that???
@@ -28,3 +29,9 @@
/turf/unsimulated/get_movable_alpha_mask_state(atom/movable/mover)
return null
+
+// For the purposes of spacemove/spacedrift.
+/turf/unsimulated/is_floor()
+ return !density
+/turf/unsimulated/is_wall()
+ return !is_floor()
diff --git a/code/game/turfs/unsimulated/floor.dm b/code/game/turfs/unsimulated/floor.dm
index c7d8fc3c6f11..83e5dd866713 100644
--- a/code/game/turfs/unsimulated/floor.dm
+++ b/code/game/turfs/unsimulated/floor.dm
@@ -16,9 +16,6 @@
/turf/unsimulated/floor/rescue_base
icon_state = "asteroidfloor"
-/turf/unsimulated/floor/shuttle_ceiling
- icon_state = "reinforced"
-
/turf/unsimulated/floor/snow
name = "snow"
icon = 'icons/turf/flooring/snow.dmi'
diff --git a/code/modules/ZAS/Airflow.dm b/code/modules/ZAS/Airflow.dm
index ca6abe6fa8f1..a7f409af231a 100644
--- a/code/modules/ZAS/Airflow.dm
+++ b/code/modules/ZAS/Airflow.dm
@@ -51,7 +51,7 @@ Contains helper procs for airflow, called by /connection_group.
return FALSE
/mob/living/human/handle_airflow_stun()
- if(!slip_chance())
+ if(!get_eva_slip_prob())
to_chat(src, SPAN_NOTICE("Air suddenly rushes past you!"))
return FALSE
. = ..()
@@ -91,14 +91,7 @@ Contains helper procs for airflow, called by /connection_group.
return 1
/mob/AirflowCanMove(n)
- if(status_flags & GODMODE)
- return 0
- if(buckled)
- return 0
- var/obj/item/shoes = get_equipped_item(slot_shoes_str)
- if(istype(shoes) && (shoes.item_flags & ITEM_FLAG_NOSLIP))
- return 0
- return 1
+ return can_slip(magboots_only = TRUE)
/atom/movable/Bump(atom/A)
if(airflow_speed > 0 && airflow_dest)
diff --git a/code/modules/ZAS/Fire.dm b/code/modules/ZAS/Fire.dm
index 10ecd938f694..b4b955ecf4e1 100644
--- a/code/modules/ZAS/Fire.dm
+++ b/code/modules/ZAS/Fire.dm
@@ -352,7 +352,7 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin
legs_exposure = 0
if(C.body_parts_covered & SLOT_ARMS)
arms_exposure = 0
- //minimize this for low-pressure enviroments
+ //minimize this for low-pressure environments
var/mx = 5 * firelevel/vsc.fire_firelevel_multiplier * min(pressure / ONE_ATMOSPHERE, 1)
//Always check these damage procs first if fire damage isn't working. They're probably what's wrong.
diff --git a/code/modules/admin/quantum_mechanic.dm b/code/modules/admin/quantum_mechanic.dm
index 28cf80af10ed..d9977490a913 100644
--- a/code/modules/admin/quantum_mechanic.dm
+++ b/code/modules/admin/quantum_mechanic.dm
@@ -274,7 +274,7 @@
// ID
/obj/item/card/id/quantum
- desc = "An ID straight from the Department of Spaciotemporal Affairs. This one looks highly classified."
+ desc = "An ID straight from the Department of Spatiotemporal Affairs. This one looks highly classified."
/obj/item/card/id/quantum/Initialize()
. = ..()
diff --git a/code/modules/admin/verbs/SDQL_2/SDQL_2.dm b/code/modules/admin/verbs/SDQL_2/SDQL_2.dm
index 0331cb89a492..71b7f7208c8a 100644
--- a/code/modules/admin/verbs/SDQL_2/SDQL_2.dm
+++ b/code/modules/admin/verbs/SDQL_2/SDQL_2.dm
@@ -149,7 +149,7 @@
to_chat(usr, "Query executed on [objs.len] object\s.")
catch(var/exception/e)
- to_chat(usr, "An exception has occured during the execution of your query and your query has been aborted.")
+ to_chat(usr, "An exception has occurred during the execution of your query and your query has been aborted.")
to_chat(usr, EXCEPTION_TEXT(e))
return
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 7371ff70873f..2ec60c912eb9 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -46,12 +46,12 @@
else to_chat(src, "Error: Private-Message: Client not found. They may have lost connection, so please be patient!")
return
- var/recieve_pm_type = "Player"
+ var/receive_pm_type = "Player"
if(holder)
//mod PMs are maroon
//PMs sent from admins and mods display their rank
if(holder)
- recieve_pm_type = holder.rank
+ receive_pm_type = holder.rank
else if(C && !C.holder)
to_chat(src, "Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.")
@@ -104,12 +104,12 @@
// We are sending this quite early because of a return in the popup code.
SSwebhooks.send(WEBHOOK_AHELP_SENT, list("name" = "Reply Sent ([ticket.id]) (Game ID: [game_id])", "body" = "**[sender_lite.key_name(FALSE, FALSE)]** to **[receiver_lite.key_name(FALSE, FALSE)]**: [msg]"))
- var/recieve_message
+ var/receive_message
if(holder && !C.holder)
- recieve_message = "-- Click the [recieve_pm_type]'s name to reply --\n"
+ receive_message = "-- Click the [receive_pm_type]'s name to reply --\n"
if(C.adminhelped)
- to_chat(C, recieve_message)
+ to_chat(C, receive_message)
C.adminhelped = 0
//AdminPM popup for ApocStation and anybody else who wants to use it.
@@ -117,7 +117,7 @@
spawn(0) //so we don't hold the caller proc up
var/sender = src
var/sendername = key
- var/reply = sanitize(input(C, msg,"[recieve_pm_type] PM from [sendername]", "") as text|null) //show message and await a reply
+ var/reply = sanitize(input(C, msg,"[receive_pm_type] PM from [sendername]", "") as text|null) //show message and await a reply
if(C && reply)
if(sender)
C.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them
@@ -134,7 +134,7 @@
sender_message += ""
to_chat(src, sender_message)
- var/receiver_message = "" + create_text_tag("pm_in", "", C) + " \[[recieve_pm_type] PM\] [get_options_bar(src, C.holder ? 1 : 0, C.holder ? 1 : 0, 1)]"
+ var/receiver_message = "" + create_text_tag("pm_in", "", C) + " \[[receive_pm_type] PM\] [get_options_bar(src, C.holder ? 1 : 0, C.holder ? 1 : 0, 1)]"
if(C.holder)
receiver_message += " ([(ticket.status == TICKET_OPEN) ? "TAKE" : "JOIN"]) (CLOSE)"
receiver_message += ": [generate_ahelp_key_words(C.mob, msg)]"
@@ -145,7 +145,7 @@
window_flash(C)
- //play the recieving admin the adminhelp sound (if they have them enabled)
+ //play the receiving admin the adminhelp sound (if they have them enabled)
//non-admins shouldn't be able to disable this
if(C.get_preference_value(/datum/client_preference/staff/play_adminhelp_ping) == PREF_HEAR)
sound_to(C, 'sound/effects/adminhelp.ogg')
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index c23689af34ca..017f1c2bb561 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -195,7 +195,7 @@
M.visible_message(result[1], result[1], narrate = TRUE)
log_and_message_admins(" - VisibleNarrate [result[2]]/[result[3]] on [A]: [result[4]]")
-// Visible narrate, it's as if it's a audible message
+// Visible narrate, it's as if it's an audible message
/client/proc/cmd_admin_audible_narrate(var/atom/A)
set category = "Special Verbs"
set name = "Audible Narrate"
diff --git a/code/modules/alarm/atmosphere_alarm.dm b/code/modules/alarm/atmosphere_alarm.dm
index 8786d19fd737..48e134a457dd 100644
--- a/code/modules/alarm/atmosphere_alarm.dm
+++ b/code/modules/alarm/atmosphere_alarm.dm
@@ -1,9 +1,6 @@
/datum/alarm_handler/atmosphere
category = NETWORK_ALARM_ATMOS
-/datum/alarm_handler/atmosphere/triggerAlarm(var/atom/origin, var/atom/source, var/duration = 0, var/severity = 1)
- ..()
-
/datum/alarm_handler/atmosphere/major_alarms(var/z_level)
. = list()
for(var/datum/alarm/A in ..())
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index d8bcb207a121..f759887ff62d 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -1,6 +1,6 @@
/obj/item/assembly/mousetrap
name = "rat trap"
- desc = "A handy little spring-loaded trap for catching pesty rodents."
+ desc = "A handy little spring-loaded trap for catching pesky pests."
icon_state = "mousetrap"
origin_tech = @'{"combat":1}'
material = /decl/material/solid/organic/wood/oak
diff --git a/code/modules/atmospherics/components/binary_devices/oxyregenerator.dm b/code/modules/atmospherics/components/binary_devices/oxyregenerator.dm
index 2fd2be5111f0..d6c54d48acc2 100644
--- a/code/modules/atmospherics/components/binary_devices/oxyregenerator.dm
+++ b/code/modules/atmospherics/components/binary_devices/oxyregenerator.dm
@@ -136,13 +136,12 @@
ui.open()
ui.set_auto_update(1)
-/obj/machinery/atmospherics/binary/oxyregenerator/Topic(href, href_list)
- if(..())
- return 1
+/obj/machinery/atmospherics/binary/oxyregenerator/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["toggleStatus"])
update_use_power(!use_power)
- update_icon()
- return 1
+ return TOPIC_REFRESH
if(href_list["setPower"]) //setting power to 0 is redundant anyways
power_setting = clamp(text2num(href_list["setPower"]), 1, 5)
- return 1
+ return TOPIC_REFRESH
diff --git a/code/modules/atmospherics/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/components/binary_devices/passive_gate.dm
index dfa4e594c86a..c55ea099f96c 100644
--- a/code/modules/atmospherics/components/binary_devices/passive_gate.dm
+++ b/code/modules/atmospherics/components/binary_devices/passive_gate.dm
@@ -138,40 +138,48 @@
ui.set_auto_update(1) // auto update every Master Controller tick
-/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list)
- if(..()) return 1
+/obj/machinery/atmospherics/binary/passive_gate/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["toggle_valve"])
unlocked = !unlocked
-
- if(href_list["regulate_mode"])
- switch(href_list["regulate_mode"])
- if ("off") regulate_mode = REGULATE_NONE
- if ("input") regulate_mode = REGULATE_INPUT
- if ("output") regulate_mode = REGULATE_OUTPUT
+ . = TOPIC_REFRESH
+
+ switch(href_list["regulate_mode"])
+ if ("off")
+ regulate_mode = REGULATE_NONE
+ . = TOPIC_REFRESH
+ if ("input")
+ regulate_mode = REGULATE_INPUT
+ . = TOPIC_REFRESH
+ if ("output")
+ regulate_mode = REGULATE_OUTPUT
+ . = TOPIC_REFRESH
switch(href_list["set_press"])
if ("min")
target_pressure = 0
+ . = TOPIC_REFRESH
if ("max")
target_pressure = max_pressure_setting
+ . = TOPIC_REFRESH
if ("set")
- var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure Control",src.target_pressure) as num
- src.target_pressure = clamp(new_pressure, 0, max_pressure_setting)
+ var/new_pressure = input(user, "Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure Control",target_pressure) as num
+ target_pressure = clamp(new_pressure, 0, max_pressure_setting)
+ . = TOPIC_REFRESH
switch(href_list["set_flow_rate"])
if ("min")
set_flow_rate = 0
+ . = TOPIC_REFRESH
if ("max")
set_flow_rate = air1.volume
+ . = TOPIC_REFRESH
if ("set")
- var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[air1.volume]kPa)","Flow Rate Control",src.set_flow_rate) as num
- src.set_flow_rate = clamp(new_flow_rate, 0, air1.volume)
-
- usr.set_machine(src) //Is this even needed with NanoUI?
- src.update_icon()
- src.add_fingerprint(usr)
- return
+ var/new_flow_rate = input(user, "Enter new flow rate limit (0-[air1.volume]kPa)","Flow Rate Control",set_flow_rate) as num
+ set_flow_rate = clamp(new_flow_rate, 0, air1.volume)
+ . = TOPIC_REFRESH
/obj/machinery/atmospherics/binary/passive_gate/proc/toggle_unlocked()
unlocked = !unlocked
diff --git a/code/modules/atmospherics/components/binary_devices/pipeturbine.dm b/code/modules/atmospherics/components/binary_devices/pipeturbine.dm
index e72a09e8d18e..510fe486f1e5 100644
--- a/code/modules/atmospherics/components/binary_devices/pipeturbine.dm
+++ b/code/modules/atmospherics/components/binary_devices/pipeturbine.dm
@@ -75,7 +75,7 @@
/obj/machinery/turbinemotor
name = "motor"
- desc = "Electrogenerator. Converts rotation into power."
+ desc = "A turbine motor. Converts rotation into power."
icon = 'icons/obj/pipeturbine.dmi'
icon_state = "motor"
anchored = FALSE
diff --git a/code/modules/atmospherics/components/binary_devices/pump.dm b/code/modules/atmospherics/components/binary_devices/pump.dm
index 156e19f2f39a..b1ec04c332d7 100644
--- a/code/modules/atmospherics/components/binary_devices/pump.dm
+++ b/code/modules/atmospherics/components/binary_devices/pump.dm
@@ -18,7 +18,7 @@ Thus, the two variables affect pump operation are set in New():
level = LEVEL_BELOW_PLATING
name = "gas pump"
- desc = "A pump."
+ desc = "A pump that can pressurize gas and restrict flow to one direction."
var/target_pressure = ONE_ATMOSPHERE
@@ -141,27 +141,25 @@ Thus, the two variables affect pump operation are set in New():
ui_interact(user)
return TRUE
-/obj/machinery/atmospherics/binary/pump/Topic(href,href_list)
- if((. = ..())) return
+/obj/machinery/atmospherics/binary/pump/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["power"])
update_use_power(!use_power)
- . = 1
+ . = TOPIC_REFRESH
switch(href_list["set_press"])
if ("min")
target_pressure = 0
- . = 1
+ . = TOPIC_REFRESH
if ("max")
target_pressure = max_pressure_setting
- . = 1
+ . = TOPIC_REFRESH
if ("set")
- var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure control",src.target_pressure) as num
- src.target_pressure = clamp(new_pressure, 0, max_pressure_setting)
- . = 1
-
- if(.)
- src.update_icon()
+ var/new_pressure = input(user, "Enter new output pressure (0-[max_pressure_setting]kPa)", "Pressure control", target_pressure) as num
+ target_pressure = clamp(new_pressure, 0, max_pressure_setting)
+ . = TOPIC_REFRESH
/obj/machinery/atmospherics/binary/pump/cannot_transition_to(state_path, mob/user)
if(state_path == /decl/machine_construction/default/deconstructed)
diff --git a/code/modules/atmospherics/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/components/binary_devices/volume_pump.dm
index 88dfdd3675e1..f39465004901 100644
--- a/code/modules/atmospherics/components/binary_devices/volume_pump.dm
+++ b/code/modules/atmospherics/components/binary_devices/volume_pump.dm
@@ -4,7 +4,7 @@
level = LEVEL_BELOW_PLATING
name = "high power gas pump"
- desc = "A pump. Has double the power rating of the standard gas pump."
+ desc = "A pump that can pressurize gas and restrict flow to one direction. Has double the power rating of the standard gas pump."
idle_power_usage = 450 // oversized pumps means oversized idle use
power_rating = 45000 // 45000 W ~ 60 HP
diff --git a/code/modules/atmospherics/components/omni_devices/filter.dm b/code/modules/atmospherics/components/omni_devices/filter.dm
index 434e0f8f5bd6..1c140c763a77 100644
--- a/code/modules/atmospherics/components/omni_devices/filter.dm
+++ b/code/modules/atmospherics/components/omni_devices/filter.dm
@@ -3,6 +3,7 @@
//--------------------------------------------
/obj/machinery/atmospherics/omni/filter
name = "omni gas filter"
+ desc = "A device that can separate components of a gas mixture and redirect them to different pipes."
icon_state = "map_filter"
core_icon = "filter"
@@ -167,15 +168,18 @@
var/decl/material/gas/G = GET_DECL(P.filtering)
return G.gas_symbol
-/obj/machinery/atmospherics/omni/filter/Topic(href, href_list)
- if(..()) return 1
+/obj/machinery/atmospherics/omni/filter/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
switch(href_list["command"])
if("power")
+ . = TOPIC_REFRESH
if(!configuring)
update_use_power(!use_power)
else
update_use_power(POWER_USE_OFF)
if("configure")
+ . = TOPIC_REFRESH
configuring = !configuring
if(configuring)
update_use_power(POWER_USE_OFF)
@@ -186,16 +190,16 @@
if("set_flow_rate")
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num
set_flow_rate = clamp(0, new_flow_rate, max_flow_rate)
+ . = TOPIC_REFRESH
if("switch_mode")
switch_mode(dir_flag(href_list["dir"]), mode_return_switch(href_list["mode"]))
+ . = TOPIC_REFRESH
if("switch_filter")
var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in gas_decls_by_symbol_cache
+ . = TOPIC_HANDLED
if(global.materials_by_gas_symbol[new_filter])
switch_filter(dir_flag(href_list["dir"]), ATM_FILTER, global.materials_by_gas_symbol[new_filter])
-
- update_icon()
- SSnano.update_uis(src)
- return
+ . = TOPIC_REFRESH
/obj/machinery/atmospherics/omni/filter/proc/mode_return_switch(var/mode)
switch(mode)
diff --git a/code/modules/atmospherics/components/omni_devices/mixer.dm b/code/modules/atmospherics/components/omni_devices/mixer.dm
index 51cc1b4be454..483e114a9f60 100644
--- a/code/modules/atmospherics/components/omni_devices/mixer.dm
+++ b/code/modules/atmospherics/components/omni_devices/mixer.dm
@@ -3,6 +3,7 @@
//--------------------------------------------
/obj/machinery/atmospherics/omni/mixer
name = "omni gas mixer"
+ desc = "A device that combines two or more gases to produce a mix with a specific ratio."
icon_state = "map_mixer"
core_icon = "mixer"
@@ -185,16 +186,19 @@
return data
-/obj/machinery/atmospherics/omni/mixer/Topic(href, href_list)
- if(..()) return 1
+/obj/machinery/atmospherics/omni/mixer/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
switch(href_list["command"])
if("power")
+ . = TOPIC_REFRESH
if(!configuring)
update_use_power(!use_power)
else
update_use_power(POWER_USE_OFF)
if("configure")
+ . = TOPIC_REFRESH
configuring = !configuring
if(configuring)
update_use_power(POWER_USE_OFF)
@@ -203,18 +207,18 @@
if(configuring && !use_power)
switch(href_list["command"])
if("set_flow_rate")
- var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num
+ var/new_flow_rate = input(user, "Enter new flow rate limit (0-[max_flow_rate]L/s)", "Flow Rate Control", set_flow_rate) as num
set_flow_rate = clamp(0, new_flow_rate, max_flow_rate)
+ . = TOPIC_REFRESH
if("switch_mode")
switch_mode(dir_flag(href_list["dir"]), href_list["mode"])
+ . = TOPIC_REFRESH
if("switch_con")
change_concentration(dir_flag(href_list["dir"]))
+ . = TOPIC_REFRESH
if("switch_conlock")
con_lock(dir_flag(href_list["dir"]))
-
- update_icon()
- SSnano.update_uis(src)
- return
+ . = TOPIC_REFRESH
/obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/mode = ATM_NONE)
if(mode != ATM_INPUT && mode != ATM_OUTPUT)
diff --git a/code/modules/atmospherics/components/portables_connector.dm b/code/modules/atmospherics/components/portables_connector.dm
index d02606404037..d6898b129870 100644
--- a/code/modules/atmospherics/components/portables_connector.dm
+++ b/code/modules/atmospherics/components/portables_connector.dm
@@ -3,7 +3,7 @@
icon_state = "map_connector"
name = "connector port"
- desc = "For connecting portable devices related to atmospherics control."
+ desc = "A connector port with a flexible tube that can be attached to portable atmospherics devices using a wrench."
dir = SOUTH
initialize_directions = SOUTH
@@ -69,7 +69,7 @@
/obj/machinery/atmospherics/portables_connector/cannot_transition_to(state_path, mob/user)
if(state_path == /decl/machine_construction/default/deconstructed)
if (connected_device)
- return SPAN_WARNING("You cannot unwrench \the [src], dettach \the [connected_device] first.")
+ return SPAN_WARNING("You cannot unwrench \the [src], detach \the [connected_device] first.")
if (locate(/obj/machinery/portable_atmospherics, src.loc))
return MCS_BLOCK
return ..()
\ No newline at end of file
diff --git a/code/modules/atmospherics/components/tvalve.dm b/code/modules/atmospherics/components/tvalve.dm
index 326dfddbe776..eca39ebd9377 100644
--- a/code/modules/atmospherics/components/tvalve.dm
+++ b/code/modules/atmospherics/components/tvalve.dm
@@ -4,7 +4,7 @@
var/base_icon_state = "tvalve"
name = "manual switching valve"
- desc = "A pipe valve."
+ desc = "A pipe valve that switches gas flow between two branches, and must be operated by hand."
level = LEVEL_BELOW_PLATING
dir = SOUTH
@@ -30,12 +30,12 @@
/obj/machinery/atmospherics/tvalve/buildable
uncreated_component_parts = null
-/obj/machinery/atmospherics/tvalve/on_update_icon(animation)
- if(animation)
- flick("[base_icon_state][src.state][!src.state]",src)
- else
- icon_state = "[base_icon_state][state]"
+/obj/machinery/atmospherics/tvalve/proc/do_turn_animation()
+ update_icon()
+ flick("[base_icon_state][src.state][!src.state]",src)
+/obj/machinery/atmospherics/tvalve/on_update_icon()
+ icon_state = "[base_icon_state][state]"
build_device_underlays(FALSE)
/obj/machinery/atmospherics/tvalve/hide(var/i)
@@ -105,8 +105,8 @@
return TRUE
/obj/machinery/atmospherics/tvalve/proc/user_toggle()
- update_icon(1)
- sleep(10)
+ do_turn_animation()
+ sleep(1 SECOND)
toggle()
/obj/machinery/atmospherics/tvalve/Process()
@@ -176,7 +176,7 @@
/obj/machinery/atmospherics/tvalve/digital // can be controlled by AI
name = "digital switching valve"
- desc = "A digitally controlled valve."
+ desc = "A digitally-controlled pipe valve that switches gas flow between two branches."
icon = 'icons/atmos/digital_tvalve.dmi'
icon_state = "map_tvalve0"
diff --git a/code/modules/atmospherics/components/unary/cold_sink.dm b/code/modules/atmospherics/components/unary/cold_sink.dm
index 59cd07c11829..5a15543df5ab 100644
--- a/code/modules/atmospherics/components/unary/cold_sink.dm
+++ b/code/modules/atmospherics/components/unary/cold_sink.dm
@@ -69,22 +69,20 @@
// auto update every Master Controller tick
ui.set_auto_update(1)
-/obj/machinery/atmospherics/unary/freezer/Topic(href, href_list)
- if(..())
- return 1
+/obj/machinery/atmospherics/unary/freezer/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["toggleStatus"])
update_use_power(!use_power)
+ . = TOPIC_REFRESH
if(href_list["temp"])
var/amount = text2num(href_list["temp"])
- if(amount > 0)
- set_temperature = min(set_temperature + amount, 1000)
- else
- set_temperature = max(set_temperature + amount, 0)
+ set_temperature = clamp(set_temperature + amount, 0, 1000)
+ . = TOPIC_REFRESH
if(href_list["setPower"]) //setting power to 0 is redundant anyways
var/new_setting = clamp(text2num(href_list["setPower"]), 0, 100)
set_power_level(new_setting)
-
- add_fingerprint(usr)
+ . = TOPIC_REFRESH
/obj/machinery/atmospherics/unary/freezer/Process()
..()
diff --git a/code/modules/atmospherics/components/unary/heat_source.dm b/code/modules/atmospherics/components/unary/heat_source.dm
index a476f6fc5204..17e7623e7e71 100644
--- a/code/modules/atmospherics/components/unary/heat_source.dm
+++ b/code/modules/atmospherics/components/unary/heat_source.dm
@@ -87,22 +87,20 @@
// auto update every Master Controller tick
ui.set_auto_update(1)
-/obj/machinery/atmospherics/unary/heater/Topic(href, href_list)
- if(..())
- return 1
+/obj/machinery/atmospherics/unary/heater/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["toggleStatus"])
update_use_power(!use_power)
+ . = TOPIC_REFRESH
if(href_list["temp"])
var/amount = text2num(href_list["temp"])
- if(amount > 0)
- set_temperature = min(set_temperature + amount, max_temperature)
- else
- set_temperature = max(set_temperature + amount, 0)
+ set_temperature = clamp(set_temperature + amount, 0, max_temperature)
+ . = TOPIC_REFRESH
if(href_list["setPower"]) //setting power to 0 is redundant anyways
var/new_setting = clamp(text2num(href_list["setPower"]), 0, 100)
set_power_level(new_setting)
-
- add_fingerprint(usr)
+ . = TOPIC_REFRESH
//upgrading parts
/obj/machinery/atmospherics/unary/heater/RefreshParts()
diff --git a/code/modules/atmospherics/components/unary/outlet_injector.dm b/code/modules/atmospherics/components/unary/outlet_injector.dm
index 2c0ed7952a96..80bd794da66e 100644
--- a/code/modules/atmospherics/components/unary/outlet_injector.dm
+++ b/code/modules/atmospherics/components/unary/outlet_injector.dm
@@ -76,7 +76,7 @@
/obj/machinery/atmospherics/unary/outlet_injector/OnTopic(mob/user, href_list, datum/topic_state/state)
if((. = ..()))
return
- if(href_list["toggle_power"])
+ if(href_list["toggle_power"]) // todo: this could easily be refhacked if you don't have a multitool
update_use_power(!use_power)
to_chat(user, "The multitool emits a short beep confirming the change.")
return TOPIC_REFRESH
diff --git a/code/modules/atmospherics/components/unary/thermal_plate.dm b/code/modules/atmospherics/components/unary/thermal_plate.dm
index 9f07a26b3b43..6619e07e85d6 100644
--- a/code/modules/atmospherics/components/unary/thermal_plate.dm
+++ b/code/modules/atmospherics/components/unary/thermal_plate.dm
@@ -1,6 +1,8 @@
#define RADIATION_CAPACITY 30000 //Radiation isn't particularly effective (TODO BALANCE)
+// LMAO? This should probably be removed.
+// Check Q2 2025 if this is gone yet or not.
/obj/machinery/atmospherics/unary/thermal_plate
//Based off Heat Reservoir and Space Heater
//Transfers heat between a pipe system and environment, based on which has a greater thermal energy concentration
@@ -8,8 +10,8 @@
icon = 'icons/obj/atmospherics/cold_sink.dmi'
icon_state = "intact_off"
- name = "Thermal Transfer Plate"
- desc = "Transfers heat to and from an area"
+ name = "thermal transfer plate"
+ desc = "A device that transfers heat to and from an area."
uncreated_component_parts = null
frame_type = /obj/item/pipe
construct_state = /decl/machine_construction/pipe
diff --git a/code/modules/atmospherics/components/unary/vent_pump.dm b/code/modules/atmospherics/components/unary/vent_pump.dm
index 1ddb358e0eca..d304cd337cbd 100644
--- a/code/modules/atmospherics/components/unary/vent_pump.dm
+++ b/code/modules/atmospherics/components/unary/vent_pump.dm
@@ -11,8 +11,8 @@
icon = 'icons/atmos/vent_pump.dmi'
icon_state = "map_vent"
- name = "Air Vent"
- desc = "Has a valve and pump attached to it."
+ name = "air vent"
+ desc = "A vent that moves air into or out of the attached pipe system, and uses a valve and pump to prevent backflow."
use_power = POWER_USE_OFF
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 30000 // 30000 W ~ 40 HP
@@ -160,6 +160,7 @@
/obj/machinery/atmospherics/unary/vent_pump/high_volume
name = "large air vent"
+ desc = "A high-volume vent that moves lots of air into or out of the attached pipe system, and uses a valve and pump to prevent backflow."
power_channel = EQUIP
power_rating = 45000
base_type = /obj/machinery/atmospherics/unary/vent_pump/high_volume/buildable
@@ -356,7 +357,7 @@
/obj/machinery/atmospherics/unary/vent_pump/OnTopic(mob/user, href_list, datum/topic_state/state)
if((. = ..()))
return
- if(href_list["switchMode"])
+ if(href_list["switchMode"]) // todo: this could easily be refhacked if you don't have a multitool
toggle_pump_dir()
to_chat(user, "The multitool emits a short beep confirming the change.")
return TOPIC_REFRESH
diff --git a/code/modules/atmospherics/components/valve.dm b/code/modules/atmospherics/components/valve.dm
index ccf203513a29..8e70f7cc077c 100644
--- a/code/modules/atmospherics/components/valve.dm
+++ b/code/modules/atmospherics/components/valve.dm
@@ -3,7 +3,7 @@
icon_state = "map_valve0"
name = "manual valve"
- desc = "A pipe valve."
+ desc = "A valve that controls flow through a pipe network, and must be operated by hand."
level = LEVEL_BELOW_PLATING
dir = SOUTH
@@ -33,12 +33,12 @@
open = 1
icon_state = "map_valve1"
-/obj/machinery/atmospherics/valve/on_update_icon(animation)
- if(animation)
- flick("valve[src.open][!src.open]",src)
- else
- icon_state = "valve[open]"
+/obj/machinery/atmospherics/valve/proc/do_turn_animation()
+ update_icon()
+ flick("valve[src.open][!src.open]",src)
+/obj/machinery/atmospherics/valve/on_update_icon()
+ icon_state = "valve[open]"
build_device_underlays(FALSE)
/obj/machinery/atmospherics/valve/hide(var/i)
@@ -94,8 +94,8 @@
return TRUE
/obj/machinery/atmospherics/valve/proc/user_toggle()
- update_icon(1)
- sleep(10)
+ do_turn_animation()
+ sleep(1 SECOND)
toggle()
/obj/machinery/atmospherics/valve/Process()
@@ -150,7 +150,7 @@
/obj/machinery/atmospherics/valve/digital // can be controlled by AI
name = "digital valve"
- desc = "A digitally controlled valve."
+ desc = "A digitally-controlled valve that controls flow through a pipe network."
icon = 'icons/atmos/digital_valve.dmi'
uncreated_component_parts = list(
/obj/item/stock_parts/radio/receiver/buildable,
diff --git a/code/modules/atmospherics/datum_pipeline.dm b/code/modules/atmospherics/datum_pipeline.dm
index 55a58d0138fe..8cdb4d002dba 100644
--- a/code/modules/atmospherics/datum_pipeline.dm
+++ b/code/modules/atmospherics/datum_pipeline.dm
@@ -168,7 +168,7 @@
/datum/pipeline/proc/mingle_with_turf(turf/target, mingle_volume)
- if(!isturf(target))
+ if(!isturf(target) || !istype(air))
return
var/datum/gas_mixture/air_sample = air.remove_volume(mingle_volume)
diff --git a/code/modules/atmospherics/he_pipes.dm b/code/modules/atmospherics/he_pipes.dm
index 380adf9245f4..3898b49f36e5 100644
--- a/code/modules/atmospherics/he_pipes.dm
+++ b/code/modules/atmospherics/he_pipes.dm
@@ -107,6 +107,13 @@
else
set_light(0, 0)
+ //fancy radiation glowing
+ if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K
+ if(abs(pipe_air.temperature - icon_temperature) > 10)
+ animate_heat_glow(pipe_air.temperature)
+ else
+ set_light(0, 0)
+
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction
icon = 'icons/atmos/junction.dmi'
icon_state = "11"
diff --git a/code/modules/atmospherics/pipes.dm b/code/modules/atmospherics/pipes.dm
index 832e0186318a..28ef33e36441 100644
--- a/code/modules/atmospherics/pipes.dm
+++ b/code/modules/atmospherics/pipes.dm
@@ -223,7 +223,7 @@
icon = 'icons/atmos/pipes.dmi'
icon_state = "11"
name = "pipe"
- desc = "A one meter section of regular pipe."
+ desc = "A one-meter section of regular pipe."
volume = ATMOS_DEFAULT_VOLUME_PIPE
@@ -265,7 +265,7 @@
smoke.start()
qdel(src)
-/obj/machinery/atmospherics/pipe/simple/on_update_icon(var/safety = 0)
+/obj/machinery/atmospherics/pipe/simple/on_update_icon()
if(!atmos_initalized)
return
@@ -285,7 +285,7 @@
/obj/machinery/atmospherics/pipe/simple/visible/scrubbers
name = "scrubbers pipe"
- desc = "A one meter section of scrubbers pipe."
+ desc = "A one-meter section of scrubbers pipe."
icon_state = "11-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
icon_connect_type = "-scrubbers"
@@ -293,7 +293,7 @@
/obj/machinery/atmospherics/pipe/simple/visible/supply
name = "air supply pipe"
- desc = "A one meter section of supply pipe."
+ desc = "A one-meter section of supply pipe."
icon_state = "11-supply"
connect_types = CONNECT_TYPE_SUPPLY
icon_connect_type = "-supply"
@@ -333,7 +333,7 @@
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers
name = "scrubbers pipe"
- desc = "A one meter section of scrubbers pipe."
+ desc = "A one-meter section of scrubbers pipe."
icon_state = "11-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
icon_connect_type = "-scrubbers"
@@ -341,7 +341,7 @@
/obj/machinery/atmospherics/pipe/simple/hidden/supply
name = "air supply pipe"
- desc = "A one meter section of supply pipe."
+ desc = "A one-meter section of supply pipe."
icon_state = "11-supply"
connect_types = CONNECT_TYPE_SUPPLY
icon_connect_type = "-supply"
@@ -391,7 +391,7 @@
pipe_class = PIPE_CLASS_TRINARY
connect_dir_type = NORTH | EAST | WEST
-/obj/machinery/atmospherics/pipe/manifold/on_update_icon(var/safety = 0)
+/obj/machinery/atmospherics/pipe/manifold/on_update_icon()
if(!atmos_initalized)
return
@@ -416,7 +416,7 @@
level = LEVEL_ABOVE_PLATING
/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers
- name="Scrubbers pipe manifold"
+ name = "scrubbers pipe manifold"
desc = "A manifold composed of scrubbers pipes."
icon_state = "map-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
@@ -424,7 +424,7 @@
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold/visible/supply
- name="Air supply pipe manifold"
+ name = "air supply pipe manifold"
desc = "A manifold composed of supply pipes."
icon_state = "map-supply"
connect_types = CONNECT_TYPE_SUPPLY
@@ -463,7 +463,7 @@
alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game
/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers
- name="Scrubbers pipe manifold"
+ name = "scrubbers pipe manifold"
desc = "A manifold composed of scrubbers pipes."
icon_state = "map-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
@@ -471,7 +471,7 @@
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold/hidden/supply
- name="Air supply pipe manifold"
+ name = "air supply pipe manifold"
desc = "A manifold composed of supply pipes."
icon_state = "map-supply"
connect_types = CONNECT_TYPE_SUPPLY
@@ -521,7 +521,7 @@
rotate_class = PIPE_ROTATE_ONEDIR
connect_dir_type = NORTH | SOUTH | EAST | WEST
-/obj/machinery/atmospherics/pipe/manifold4w/on_update_icon(var/safety = 0)
+/obj/machinery/atmospherics/pipe/manifold4w/on_update_icon()
if(!atmos_initalized)
return
@@ -641,7 +641,7 @@
initialize_directions = SOUTH
build_icon_state = "cap"
-/obj/machinery/atmospherics/pipe/cap/on_update_icon(var/safety = 0)
+/obj/machinery/atmospherics/pipe/cap/on_update_icon()
icon_state = "cap[icon_connect_type]"
color = get_color()
@@ -699,13 +699,13 @@
connect_types = CONNECT_TYPE_FUEL
/obj/machinery/atmospherics/pipe/simple/visible/universal
- name="Universal pipe adapter"
+ name = "universal pipe adapter"
desc = "An adapter for regular, supply, scrubbers, and fuel pipes."
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER|CONNECT_TYPE_FUEL|CONNECT_TYPE_HE
icon_state = "map_universal"
build_icon_state = "universal"
-/obj/machinery/atmospherics/pipe/simple/visible/universal/on_update_icon(var/safety = 0)
+/obj/machinery/atmospherics/pipe/simple/visible/universal/on_update_icon()
if(!atmos_initalized)
return
@@ -717,13 +717,13 @@
universal_underlays(direction)
/obj/machinery/atmospherics/pipe/simple/hidden/universal
- name="Universal pipe adapter"
- desc = "An adapter for regular, supply and scrubbers pipes."
+ name = "universal pipe adapter"
+ desc = "An adapter for regular, supply, scrubbers, and fuel pipes."
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER|CONNECT_TYPE_FUEL|CONNECT_TYPE_HE
icon_state = "map_universal"
build_icon_state = "universal"
-/obj/machinery/atmospherics/pipe/simple/hidden/universal/on_update_icon(var/safety = 0)
+/obj/machinery/atmospherics/pipe/simple/hidden/universal/on_update_icon()
if(!atmos_initalized)
return
diff --git a/code/modules/augment/active.dm b/code/modules/augment/active.dm
index ff063b65cc41..e338d1e763c8 100644
--- a/code/modules/augment/active.dm
+++ b/code/modules/augment/active.dm
@@ -19,6 +19,6 @@
//Need to change icon?
/obj/item/organ/internal/augment/active/refresh_action_button()
. = ..()
- if(.)
+ if(. && istype(action))
action.button_icon_state = icon_state
action.button?.update_icon()
diff --git a/code/modules/augment/active/tool/engineering.dm b/code/modules/augment/active/tool/engineering.dm
index b46692f220d6..20fec8cfe1a6 100644
--- a/code/modules/augment/active/tool/engineering.dm
+++ b/code/modules/augment/active/tool/engineering.dm
@@ -33,7 +33,7 @@
/obj/item/screwdriver/finger
name = "digital screwdriver"
- desc = "A nifty powertool at your literal fingertips."
+ desc = "A nifty power tool at your literal fingertips."
icon_state = "screwdriver_finger"
icon = 'icons/obj/augment_tools.dmi'
@@ -43,7 +43,7 @@
/obj/item/crowbar/finger
name = "digital prybar"
- desc = "A somewhat awkward to use prybar. It doubles as bottle opener."
+ desc = "A somewhat awkward to use prybar. It doubles as a bottle opener."
icon_state = "prybar_finger"
icon = 'icons/obj/augment_tools.dmi'
diff --git a/code/modules/augment/passive/boost/muscle.dm b/code/modules/augment/passive/boost/muscle.dm
index ca38a5cd2ffe..913214d9619a 100644
--- a/code/modules/augment/passive/boost/muscle.dm
+++ b/code/modules/augment/passive/boost/muscle.dm
@@ -7,7 +7,7 @@
name = "mechanical muscles"
allowed_organs = list(BP_AUGMENT_R_LEG, BP_AUGMENT_L_LEG)
icon_state = "muscule"
- desc = "Nanofiber tendons powered by an array of actuators to help the wearer mantain speed even while encumbered. You may want to install these in pairs to see a result."
+ desc = "Nanofiber tendons powered by an array of actuators to help the wearer maintain speed even while encumbered. You may want to install these in pairs to see a result."
material = /decl/material/solid/metal/steel
origin_tech = @'{"materials":4,"magnets":3,"biotech":3}'
var/obj/item/organ/internal/augment/boost/muscle/other //we need two for these
diff --git a/code/modules/awaymissions/artillery.dm b/code/modules/awaymissions/artillery.dm
index 592d71f285ff..644356e53d76 100644
--- a/code/modules/awaymissions/artillery.dm
+++ b/code/modules/awaymissions/artillery.dm
@@ -1,57 +1,53 @@
-
-/obj/machinery/artillerycontrol
- var/reload = 180
- name = "superluminal artillery control"
- icon_state = "control_boxp1"
- icon = 'icons/obj/machines/particle_accelerator2.dmi'
- density = TRUE
- anchored = TRUE
-
-/obj/machinery/artillerycontrol/Process()
- if(src.reload<180)
- src.reload++
-
/obj/structure/artilleryplaceholder
name = "artillery"
+ desc = "The ship's old superluminal artillery cannon. Looks inoperative."
icon = 'icons/obj/machines/artillery.dmi'
anchored = TRUE
density = TRUE
- desc = "The ship's old superluminal artillery cannon. Looks inoperative."
/obj/structure/artilleryplaceholder/decorative
density = FALSE
+/obj/machinery/artillerycontrol
+ name = "superluminal artillery control"
+ icon_state = "control_boxp1"
+ icon = 'icons/obj/machines/particle_accelerator2.dmi'
+ density = TRUE
+ anchored = TRUE
+ var/tmp/time_to_reload = 360 SECONDS // originally this was 180 ticks at 1 tick per 2 seconds
+ var/reload_cooldown = 0 // The world.time value after which we will be able to fire.
+
/obj/machinery/artillerycontrol/interface_interact(mob/user)
interact(user)
return TRUE
/obj/machinery/artillerycontrol/interact(mob/user)
user.set_machine(src)
- var/dat = "Superluminal Artillery Control:
"
+ var/dat = list("Superluminal Artillery Control:
")
dat += "Locked on
"
- dat += "Charge progress: [reload]/180:
"
+ dat += "Charge progress: [round(100 - ((reload_cooldown - world.time) / time_to_reload))]%
"
dat += "Open Fire
"
dat += "Deployment of weapon authorized by
[global.using_map.company_name] Naval Command
Remember, friendly fire is grounds for termination of your contract and life.
"
- show_browser(user, dat, "window=scroll")
- onclose(user, "scroll")
-
-/obj/machinery/artillerycontrol/Topic(href, href_list, state = global.physical_topic_state)
- if(..())
- return 1
-
- if ((usr.contents.Find(src) || (in_range(src, usr) && isturf(src.loc))) || (issilicon(usr)))
- var/area/thearea = input("Area to jump bombard", "Open Fire") as null|anything in teleportlocs
- thearea = thearea ? teleportlocs[thearea] : thearea
- if (!thearea || CanUseTopic(usr, global.physical_topic_state) != STATUS_INTERACTIVE)
- return
- if (src.reload < 180)
- return
- if ((usr.contents.Find(src) || (in_range(src, usr) && isturf(src.loc))) || (issilicon(usr)))
- command_announcement.Announce("Wormhole artillery fire detected. Brace for impact.")
- log_and_message_admins("has launched an artillery strike.", 1)
- var/list/L = list()
- for(var/turf/T in get_area_turfs(thearea))
- L+=T
- var/loc = pick(L)
- explosion(loc,2,5,11)
- reload = 0
+ show_browser(user, JOINTEXT(dat), "window=superlumcontrol")
+ onclose(user, "superlumcontrol")
+
+/obj/machinery/artillerycontrol/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
+
+ var/area/thearea = input("Area to jump bombard", "Open Fire") as null|anything in teleportlocs
+ thearea = thearea ? teleportlocs[thearea] : null
+ if (!thearea)
+ return
+ if (world.time < reload_cooldown)
+ return
+ command_announcement.Announce("Wormhole artillery fire detected. Brace for impact.")
+ log_and_message_admins("has launched an artillery strike.", user, get_turf(src))
+ var/list/turf/candidates = list()
+ // this is slow (in world loop) but we don't have a better way unless we pre-register a list of areas -> z-levels
+ // and this code isn't hot code at all
+ for(var/turf/tile in thearea)
+ candidates += tile
+ var/turf/target_loc = pick(candidates)
+ explosion(target_loc, 2, 5, 11)
+ reload_cooldown = world.time + time_to_reload
diff --git a/code/modules/awaymissions/pamphlet.dm b/code/modules/awaymissions/pamphlet.dm
index c97ef5ee9035..49dbb1237f44 100644
--- a/code/modules/awaymissions/pamphlet.dm
+++ b/code/modules/awaymissions/pamphlet.dm
@@ -8,7 +8,7 @@
winning dental plan- but that's not all the Gateway project has to offer.
\
Because we care about you, we feel it is only fair to make sure you know the risks \
before you commit to joining the Gateway project. All away destinations have \
- been fully scanned by a expeditionary team, and are certified to be 100% safe. \
+ been fully scanned by an expeditionary team, and are certified to be 100% safe. \
We've even left a case of space beer along with the basic materials you'll need to expand \
the Project's operational area and start your new life.
\
Gateway Operation Basics
\
diff --git a/code/modules/barricade_tape/barricade_tape.dm b/code/modules/barricade_tape/barricade_tape.dm
new file mode 100644
index 000000000000..b0f81d840a3f
--- /dev/null
+++ b/code/modules/barricade_tape/barricade_tape.dm
@@ -0,0 +1,252 @@
+#define MAX_BARRICADE_TAPE_LENGTH 32 //Maximum length of a continuous line of tape someone can place down.
+#define TAPE_BARRICADE_V_NEIGHBORS (NORTH | SOUTH)
+#define TAPE_BARRICADE_H_NEIGHBORS (EAST | WEST)
+#define TAPE_BARRICADE_IS_CORNER_NEIGHBORS(X) ((X ^ TAPE_BARRICADE_V_NEIGHBORS) && (X ^ TAPE_BARRICADE_H_NEIGHBORS))
+#define TAPE_BARRICADE_IS_V_NEIGHBORS(X) ((X & TAPE_BARRICADE_V_NEIGHBORS) == TAPE_BARRICADE_V_NEIGHBORS && !((X & TAPE_BARRICADE_H_NEIGHBORS) == TAPE_BARRICADE_H_NEIGHBORS)) //Check we have neighbors connection on the vertical plane
+#define TAPE_BARRICADE_IS_H_NEIGHBORS(X) ((X & TAPE_BARRICADE_H_NEIGHBORS) == TAPE_BARRICADE_H_NEIGHBORS && !((X & TAPE_BARRICADE_V_NEIGHBORS) == TAPE_BARRICADE_V_NEIGHBORS)) //Check we have neighbors connection on the horizontal plane
+#define TAPE_BARRICADE_IS_3W_V_NEIGHBORS(X) (TAPE_BARRICADE_IS_V_NEIGHBORS(X) && ((X & TAPE_BARRICADE_H_NEIGHBORS) > 0))
+#define TAPE_BARRICADE_IS_3W_H_NEIGHBORS(X) (TAPE_BARRICADE_IS_H_NEIGHBORS(X) && ((X & TAPE_BARRICADE_V_NEIGHBORS) > 0))
+#define TAPE_BARRICADE_IS_4W_NEIGHBORS(X) (((X & TAPE_BARRICADE_V_NEIGHBORS) == TAPE_BARRICADE_V_NEIGHBORS) && ((X & TAPE_BARRICADE_H_NEIGHBORS) == TAPE_BARRICADE_H_NEIGHBORS))
+#define CONNECTION_BITS_TO_TEXT(X) "[(X & WEST) > 0][(X & EAST) > 0][(X & SOUTH) > 0][(X & NORTH) > 0]"
+#define TAPE_BARRICADE_GET_NB_NEIGHBORS(X) (((X & NORTH) > 0) + ((X & SOUTH) > 0) + ((X & EAST) > 0) + ((X & WEST) > 0))
+
+var/global/list/image/hazard_overlays //Cached hazard floor overlays for the barricade tape
+
+////////////////////////////////////////////////////////////////////
+// Tape Line Barricade
+////////////////////////////////////////////////////////////////////
+/obj/structure/tape_barricade
+ name = "tape line"
+ desc = "A line of barricade tape."
+ icon = 'icons/policetape.dmi'
+ icon_state = "tape_2w_0"
+ dir = SOUTH //This structure will try to turn its icon depending on what neighbors it has
+ layer = ABOVE_DOOR_LAYER
+ pass_flags = PASS_FLAG_TABLE //About the height of table
+ anchored = TRUE
+ material = /decl/material/solid/organic/plastic
+ current_health = 5
+ var/neighbors = 0 //Contains all the direction flags of all the neighboring tape_barricades
+ var/is_lifted = 0 //Whether the tape is lifted and we're allowing everyone passage.
+ var/is_crumpled = 0 //Whether the tape was damaged
+ var/decl/barricade_tape_template/tape_template //Details about the behavior and looks of the barricade
+
+/obj/structure/tape_barricade/Initialize(ml, _mat, _reinf_mat, var/decl/barricade_tape_template/_tape_template)
+ . = ..()
+ if(!hazard_overlays)
+ hazard_overlays = list()
+ hazard_overlays["[NORTH]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "N")
+ hazard_overlays["[EAST]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "E")
+ hazard_overlays["[SOUTH]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "S")
+ hazard_overlays["[WEST]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "W")
+ set_tape_template(_tape_template)
+
+/obj/structure/tape_barricade/LateInitialize()
+ . = ..()
+ build_connection_bits()
+ update_neighbors()
+
+/obj/structure/tape_barricade/Destroy()
+ var/turf/old_loc = get_turf(src)
+ . = ..()
+ if(istype(old_loc))
+ update_neighbors(old_loc)
+
+/obj/structure/tape_barricade/proc/set_tape_template(var/decl/barricade_tape_template/tmpl)
+ if(tmpl)
+ tape_template = tmpl
+ if(ispath(tape_template))
+ tape_template = GET_DECL(tape_template)
+ if(!tape_template)
+ return
+
+ SetName("[tape_template.tape_kind] tape line")
+ desc = tape_template.tape_desc
+ icon = tape_template.icon_file
+ req_access = tape_template.req_access
+ set_color(tape_template.tape_color)
+ update_icon()
+
+/**Cause neighbors to update their icon. */
+/obj/structure/tape_barricade/proc/update_neighbors(var/location = loc)
+ for (var/look_dir in global.cardinal)
+ var/obj/structure/tape_barricade/B = locate(/obj/structure/tape_barricade, get_step(location, look_dir))
+ if(!QDELETED(B))
+ B.update_icon()
+
+ if(!QDELETED(src))
+ update_icon()
+
+/**Updates our connection bits to keep track of the things we're connected to */
+/obj/structure/tape_barricade/proc/build_connection_bits()
+ neighbors = 0
+ for (var/look_dir in global.cardinal)
+ var/turf/target_turf = get_step(src, look_dir)
+ if(target_turf)
+ var/obj/structure/tape_barricade/B = locate(/obj/structure/tape_barricade) in target_turf
+ //We connect to walls and other tape_barricades
+ if((B && !QDELETED(B)) || (!B && target_turf.is_wall()))
+ neighbors |= look_dir
+
+/**Allow sutypes to override with their own forced icon state name.*/
+/obj/structure/tape_barricade/proc/icon_name_override()
+ return
+
+/obj/structure/tape_barricade/on_update_icon()
+ . = ..()
+ if(isnull(tape_template) || ispath(tape_template))
+ return
+ //Look up our neighbors
+ build_connection_bits()
+
+ var/icon_name = icon_name_override()
+ if(!icon_name)
+ //Build the icon state from whethere we've got a right angle with out neighbors or not
+ if(TAPE_BARRICADE_IS_4W_NEIGHBORS(neighbors))
+ set_dir(SOUTH)
+ icon_name = "4w"
+
+ //3 Ways
+ else if(TAPE_BARRICADE_IS_3W_H_NEIGHBORS(neighbors))
+ set_dir(neighbors & TAPE_BARRICADE_V_NEIGHBORS)
+ icon_name = "3w"
+ else if(TAPE_BARRICADE_IS_3W_V_NEIGHBORS(neighbors))
+ set_dir(neighbors & TAPE_BARRICADE_H_NEIGHBORS)
+ icon_name = "3w"
+
+ //Lines
+ else if(TAPE_BARRICADE_IS_H_NEIGHBORS(neighbors))
+ set_dir(EAST)
+ icon_name = "2w"
+ else if(TAPE_BARRICADE_IS_V_NEIGHBORS(neighbors))
+ set_dir(SOUTH)
+ icon_name = "2w"
+
+ //Endpoints/corners
+ else
+ if(neighbors > 0)
+ set_dir(neighbors) //Make sure if we have no connections we don't set a bad dir
+ icon_name = "dir"
+
+ icon_state = "[tape_template.base_icon_state]_[icon_name]_[is_crumpled]"
+
+ //Overlays
+ if(tape_template.detail_overlay)
+ var/image/ovr = overlay_image(icon, "[tape_template.base_icon_state]_[icon_name]_[tape_template.detail_overlay]", tape_template.detail_color, RESET_COLOR)
+ ovr.dir = dir
+ add_overlay(ovr)
+
+/obj/structure/tape_barricade/attack_hand(mob/user)
+
+ if(user.check_intent(I_FLAG_HARM))
+ user.visible_message(SPAN_DANGER("\The [user] tears \the [src]!"))
+ physically_destroyed()
+ return TRUE
+
+ if (!user.check_intent(I_FLAG_HELP) || !allowed(user) || !user.check_dexterity(DEXTERITY_SIMPLE_MACHINES, TRUE))
+ return ..()
+
+ if(TAPE_BARRICADE_IS_CORNER_NEIGHBORS(neighbors) || (TAPE_BARRICADE_GET_NB_NEIGHBORS(neighbors) > 2))
+ to_chat(user, SPAN_WARNING("You can't lift up the pole. Try lifting the line itself."))
+ return TRUE
+
+ if(!allowed(user))
+ user.visible_message(SPAN_NOTICE("\The [user] carelessly pulls \the [src] out of the way."))
+ crumple()
+ else
+ user.visible_message(SPAN_NOTICE("\The [user] lifts \the [src], officially allowing passage."))
+
+ for(var/obj/structure/tape_barricade/B in get_tape_line())
+ B.lift(10 SECONDS) //~10 seconds
+ return TRUE
+
+/obj/structure/tape_barricade/dismantle_structure(mob/user)
+ for (var/obj/structure/tape_barricade/B in get_tape_line())
+ if(B == src || QDELETED(B))
+ continue
+ if(B.neighbors & get_dir(B, src))
+ B.physically_destroyed()
+ . = ..()
+
+/obj/structure/tape_barricade/CanPass(atom/movable/mover, turf/target, height, air_group)
+ if(!is_lifted && ismob(mover))
+ var/mob/M = mover
+ if (!allowed(M) && M.check_intent(I_FLAG_HELP))
+ return FALSE
+ return ..()
+
+/obj/structure/tape_barricade/Crossed(atom/movable/AM)
+ . = ..()
+ if(is_lifted || !isliving(AM))
+ return
+ var/mob/living/M = AM
+ add_fingerprint(M)
+ shake_animation(2)
+ if (!allowed(M)) //only select few learn art of not crumpling the tape
+ to_chat(M, SPAN_NOTICE("You are not supposed to go past \the [src]..."))
+ if(!M.check_intent(I_FLAG_HELP))
+ crumple()
+
+/obj/structure/tape_barricade/proc/crumple()
+ if(!is_crumpled)
+ playsound(src, 'sound/effects/rip1.ogg', 60, TRUE)
+ take_damage(5)
+ is_crumpled = TRUE
+ update_icon()
+
+/**Temporarily lifts the tape line, allowing passage to anyone for the specified time, until the timer expires. */
+/obj/structure/tape_barricade/proc/lift(var/time)
+ if(!is_lifted)
+ is_lifted = TRUE
+ layer = ABOVE_HUMAN_LAYER
+ pass_flags = PASS_FLAG_MOB
+ pixel_y += 8
+ addtimer(CALLBACK(src, PROC_REF(on_unlift)), time, TIMER_UNIQUE)
+ playsound(src, 'sound/effects/pageturn2.ogg', 50, TRUE)
+
+/**Called by timer when the tape line falls back in place. */
+/obj/structure/tape_barricade/proc/on_unlift()
+ is_lifted = FALSE
+ pass_flags = initial(pass_flags)
+ reset_plane_and_layer()
+ pixel_y -= 8
+ playsound(src, 'sound/effects/pageturn2.ogg', 20, TRUE)
+
+// Returns a list of all tape objects connected to src, including itself.
+/obj/structure/tape_barricade/proc/get_tape_line(var/list/ignored, var/line_index = 0)
+ //Don't include more in the line than this
+ if(line_index >= MAX_BARRICADE_TAPE_LENGTH)
+ return list()
+
+ var/list/dirs = list()
+ if(neighbors & NORTH)
+ dirs += NORTH
+ if(neighbors & SOUTH)
+ dirs += SOUTH
+ if(neighbors & WEST)
+ dirs += WEST
+ if(neighbors & EAST)
+ dirs += EAST
+
+ //Grab all cached connected neighbors
+ LAZYDISTINCTADD(ignored, src)
+ var/list/obj/structure/tape_barricade/tapeline = list(src)
+ for(var/look_dir in dirs)
+ var/turf/T = get_step(src, look_dir)
+ var/obj/structure/tape_barricade/B = locate() in T
+ if(!QDELETED(B) && !(B in ignored))
+ if(TAPE_BARRICADE_IS_CORNER_NEIGHBORS(neighbors) || (TAPE_BARRICADE_GET_NB_NEIGHBORS(neighbors) > 2))
+ continue //We stop at intersections, and corners
+ tapeline += B.get_tape_line(ignored, line_index + 1) //Pass us to prevent infinite loops, and adding us to the resulting line
+ return tapeline
+
+#undef TAPE_BARRICADE_IS_CORNER_NEIGHBORS
+#undef TAPE_BARRICADE_V_NEIGHBORS
+#undef TAPE_BARRICADE_H_NEIGHBORS
+#undef TAPE_BARRICADE_IS_V_NEIGHBORS
+#undef TAPE_BARRICADE_IS_H_NEIGHBORS
+#undef TAPE_BARRICADE_IS_3W_V_NEIGHBORS
+#undef TAPE_BARRICADE_IS_3W_H_NEIGHBORS
+#undef TAPE_BARRICADE_IS_4W_NEIGHBORS
+#undef CONNECTION_BITS_TO_TEXT
+#undef TAPE_BARRICADE_GET_NB_NEIGHBORS
\ No newline at end of file
diff --git a/code/modules/barricade_tape/barricade_tape_roll.dm b/code/modules/barricade_tape/barricade_tape_roll.dm
new file mode 100644
index 000000000000..6ebf3b5d5d6b
--- /dev/null
+++ b/code/modules/barricade_tape/barricade_tape_roll.dm
@@ -0,0 +1,151 @@
+////////////////////////////////////////////////////////////////////
+// Barricade Tape Roll
+////////////////////////////////////////////////////////////////////
+/obj/item/stack/tape_roll/barricade_tape
+ name = "barricade tape roll"
+ desc = "A roll of high visibility, non-sticky barricade tape. Used to deter passersby from crossing it."
+ icon = 'icons/policetape.dmi'
+ icon_state = "tape"
+ w_class = ITEM_SIZE_SMALL
+ var/tmp/turf/start //The turf we started unrolling from
+ var/tmp/weakref/unroller //The mob currently unrolling us
+ var/decl/barricade_tape_template/tape_template //Template containing details on how the tape roll will look and behave, along with what it will place down
+
+/obj/item/stack/tape_roll/barricade_tape/Initialize()
+ . = ..()
+ apply_template()
+
+/obj/item/stack/tape_roll/barricade_tape/Destroy()
+ stop_unrolling()
+ return ..()
+
+/**Update our appearence and data to match the specified tape template. */
+/obj/item/stack/tape_roll/barricade_tape/proc/apply_template()
+ if(ispath(tape_template))
+ tape_template = GET_DECL(tape_template)
+ if(!tape_template)
+ return
+
+ SetName("[tape_template.tape_kind] tape roll")
+ desc = tape_template.roll_desc
+ icon = tape_template.icon_file
+ set_color(tape_template.tape_color)
+ update_icon()
+
+/obj/item/stack/tape_roll/barricade_tape/on_update_icon()
+ . = ..()
+ if(ismob(loc))
+ add_overlay(overlay_image(icon, start? "stop" : "start", flags = RESET_COLOR))
+
+/obj/item/stack/tape_roll/barricade_tape/dropped(mob/user)
+ stop_unrolling()
+ update_icon()
+ return ..()
+
+/obj/item/stack/tape_roll/barricade_tape/on_picked_up(mob/user)
+ stop_unrolling()
+ update_icon()
+ return ..()
+
+/obj/item/stack/tape_roll/barricade_tape/attack_hand()
+ . = ..()
+ if(. && !QDELETED(src))
+ update_icon()
+
+/**Callback used when whoever holds us moved to a new turf. */
+/obj/item/stack/tape_roll/barricade_tape/proc/user_moved_unrolling(var/mob/M, var/atom/old_loc, var/atom/new_loc)
+ if(QDELETED(src))
+ return //Destructor will handle the rest
+ if(QDELETED(M) || !can_use(1) || M.incapacitated())
+ stop_unrolling()
+ return
+
+ if((old_loc.x != new_loc.x && old_loc.y != new_loc.y) || old_loc.z != new_loc.z)
+ to_chat(M, SPAN_WARNING("\The [src] can only be laid horizontally or vertically."))
+ stop_unrolling()
+ return
+ //Use a length of tape and place a barricade line
+ if(!place_line(M, new_loc, get_dir(old_loc, new_loc)))
+ stop_unrolling()
+ return
+ if(get_dist(start, new_loc) >= MAX_BARRICADE_TAPE_LENGTH)
+ to_chat(M, SPAN_WARNING("You've stretched this line of tape to the maximum!"))
+ stop_unrolling()
+ return
+
+/obj/item/stack/tape_roll/barricade_tape/proc/stop_unrolling()
+ if(!start && !unroller)
+ return
+ var/mob/_uroller = unroller.resolve()
+ if(_uroller)
+ events_repository.unregister(/decl/observ/moved, _uroller, src, PROC_REF(user_moved_unrolling))
+ unroller = null
+ start = null
+ slowdown_general = initial(slowdown_general)
+ if(_uroller)
+ to_chat(_uroller, SPAN_NOTICE("You stop unrolling \the [src]."))
+ if(!QDELETED(src))
+ update_icon()
+ return TRUE
+
+/obj/item/stack/tape_roll/barricade_tape/proc/start_unrolling(var/mob/user)
+ if(start && unroller)
+ return
+ start = get_turf(src)
+ unroller = weakref(user)
+ slowdown_general = initial(slowdown_general) + 2 //While unrolling you're slightly slower
+ events_repository.unregister(/decl/observ/moved, user, src, PROC_REF(user_moved_unrolling))
+ events_repository.register(/decl/observ/moved, user, src, PROC_REF(user_moved_unrolling))
+ to_chat(user, SPAN_NOTICE("You start unrolling \the [src]."))
+ //Place the first one immediately
+ place_line(user, get_turf(user), user.dir)
+ update_icon()
+ return TRUE
+
+/**Place a tape line on the current turf. */
+/obj/item/stack/tape_roll/barricade_tape/proc/place_line(var/mob/user, var/turf/T, var/pdir)
+ if(!T || T.is_open() || T.is_wall())
+ to_chat(user, SPAN_WARNING("You can't place tape here!"))
+ return
+ if(locate(/obj/structure/tape_barricade) in T)
+ return //Can't place 2 on the same tile!
+
+ if(!can_use(1))
+ to_chat(user, SPAN_WARNING("You are out of [tape_template.tape_kind] tape!"))
+ return
+ use(1)
+ playsound(user, 'sound/effects/pageturn2.ogg', 50, TRUE)
+
+ var/obj/structure/tape_barricade/barricade = tape_template.make_line_barricade(user, T, pdir)
+ if(barricade)
+ barricade.matter = matter_per_piece?.Copy()
+ barricade.update_neighbors()
+ return barricade
+
+/obj/item/stack/tape_roll/barricade_tape/attack_self(mob/user)
+ if(start)
+ stop_unrolling()
+ return
+ if(!can_use(1))
+ return //This shouldn't happen, but if it does, don't let them exploit it
+
+ start_unrolling(user)
+
+/obj/item/stack/tape_roll/barricade_tape/afterattack(var/atom/A, mob/user, proximity)
+ if(!proximity)
+ return
+
+ if (istype(A, /obj/machinery/door/airlock))
+ if(!can_use(4))
+ to_chat(user, SPAN_WARNING("There isn't enough [plural_name] in \the [src] to barricade \the [A]. You need at least 4 [plural_name]."))
+ return
+
+ var/obj/structure/tape_barricade/door/bar = tape_template.make_door_barricade(user, A)
+ if(bar)
+ bar.matter = matter_per_piece?.Copy()
+ if(bar.matter)
+ for(var/mat in bar.matter)
+ bar.matter[mat] = round(bar.matter[mat] * 4)
+
+ to_chat(user, SPAN_NOTICE("You finish placing \the [src]."))
+ use(4)
\ No newline at end of file
diff --git a/code/modules/barricade_tape/barricade_tape_subtypes.dm b/code/modules/barricade_tape/barricade_tape_subtypes.dm
new file mode 100644
index 000000000000..44cf66cef298
--- /dev/null
+++ b/code/modules/barricade_tape/barricade_tape_subtypes.dm
@@ -0,0 +1,136 @@
+////////////////////////////////////////////////////////////////////
+// Door Tape Barricade
+////////////////////////////////////////////////////////////////////
+
+//Barricade over a single door
+/obj/structure/tape_barricade/door
+ icon_state = "tape_door_0"
+ layer = ABOVE_DOOR_LAYER
+
+/obj/structure/tape_barricade/door/update_neighbors()
+ //We completely ignore neighbors
+ neighbors = 0
+
+/obj/structure/tape_barricade/door/icon_name_override()
+ return "door" //Override the icon picking to pick this icon label instead
+
+////////////////////////////////////////////////////////////////////
+// Police Tape
+////////////////////////////////////////////////////////////////////
+/decl/barricade_tape_template/police
+ tape_kind = "police"
+ tape_desc = "A length of police tape. Do not cross."
+ roll_desc = "A roll of police tape used to block off crime scenes from the public."
+ tape_color = COLOR_RED
+ req_access = list(access_security)
+
+/obj/item/stack/tape_roll/barricade_tape/police
+ tape_template = /decl/barricade_tape_template/police
+
+//mapper type
+/obj/structure/tape_barricade/police
+ icon_state = "tape_door_0"
+ color = COLOR_RED
+ tape_template = /decl/barricade_tape_template/police
+
+////////////////////////////////////////////////////////////////////
+// Engineering Tape
+////////////////////////////////////////////////////////////////////
+/decl/barricade_tape_template/engineering
+ tape_kind = "engineering"
+ tape_desc = "A length of engineering tape. Better not cross it."
+ roll_desc = "A roll of engineering tape used to block off working areas from the public."
+ tape_color = COLOR_ORANGE
+ req_access = list(list(access_engine,access_atmospherics))
+
+/obj/item/stack/tape_roll/barricade_tape/engineering
+ tape_template = /decl/barricade_tape_template/engineering
+
+//mapper type
+/obj/structure/tape_barricade/engineering
+ icon_state = "stripetape_door_0"
+ color = COLOR_ORANGE
+ tape_template = /decl/barricade_tape_template/engineering
+
+////////////////////////////////////////////////////////////////////
+// Atmospheric Tape
+////////////////////////////////////////////////////////////////////
+/decl/barricade_tape_template/atmos
+ tape_kind = "atmospherics"
+ tape_desc = "A length of atmospherics tape. Better not cross it."
+ roll_desc = "A roll of atmospherics tape used to block off working areas from the public."
+ tape_color = COLOR_BLUE_LIGHT
+ req_access = list(list(access_engine,access_atmospherics))
+ base_icon_state = "stripetape"
+ detail_overlay = "stripes"
+ detail_color = COLOR_YELLOW
+
+/obj/item/stack/tape_roll/barricade_tape/atmos
+ tape_template = /decl/barricade_tape_template/atmos
+
+//mapper type
+/obj/structure/tape_barricade/atmos
+ icon_state = "stripetape_h_0"
+ color = COLOR_BLUE_LIGHT
+ tape_template = /decl/barricade_tape_template/atmos
+
+////////////////////////////////////////////////////////////////////
+// Research Tape
+////////////////////////////////////////////////////////////////////
+/decl/barricade_tape_template/research
+ tape_kind = "research"
+ tape_desc = "A length of research tape. Better not cross it."
+ roll_desc = "A roll of research tape used to block off working areas from the public."
+ tape_color = COLOR_WHITE
+ req_access = list(access_research)
+
+/obj/item/stack/tape_roll/barricade_tape/research
+ tape_template = /decl/barricade_tape_template/research
+
+//mapper type
+/obj/structure/tape_barricade/research
+ color = COLOR_WHITE
+ tape_template = /decl/barricade_tape_template/research
+
+////////////////////////////////////////////////////////////////////
+// Medical Tape
+////////////////////////////////////////////////////////////////////
+/decl/barricade_tape_template/medical
+ tape_kind = "medical"
+ tape_desc = "A length of medical tape. Better not cross it."
+ roll_desc = "A roll of medical tape used to block off working areas from the public."
+ tape_color = COLOR_PALE_BLUE_GRAY
+ req_access = list(access_medical)
+ base_icon_state = "stripetape"
+ detail_overlay = "stripes"
+ detail_color = COLOR_PALE_BLUE_GRAY
+
+/obj/item/stack/tape_roll/barricade_tape/medical
+ tape_template = /decl/barricade_tape_template/medical
+
+//mapper type
+/obj/structure/tape_barricade/medical
+ icon_state = "stripetape_h_0"
+ color = COLOR_PALE_BLUE_GRAY
+ tape_template = /decl/barricade_tape_template/medical
+
+////////////////////////////////////////////////////////////////////
+// Bureacratic Tape
+////////////////////////////////////////////////////////////////////
+/decl/barricade_tape_template/bureaucracy
+ tape_kind = "red"
+ tape_desc = "A length of bureaucratic red tape. Safely ignored, but darn obstructive sometimes."
+ roll_desc = "A roll of bureaucratic red tape used to block any meaningful work from being done."
+ tape_color = COLOR_RED
+ base_icon_state = "stripetape"
+ detail_overlay = "stripes"
+ detail_color = COLOR_RED
+
+/obj/item/stack/tape_roll/barricade_tape/bureaucracy
+ tape_template = /decl/barricade_tape_template/bureaucracy
+
+//mapper type
+/obj/structure/tape_barricade/bureaucracy
+ icon_state = "stripetape_h_0"
+ color = COLOR_RED
+ tape_template = /decl/barricade_tape_template/bureaucracy
\ No newline at end of file
diff --git a/code/modules/barricade_tape/barricade_tape_template.dm b/code/modules/barricade_tape/barricade_tape_template.dm
new file mode 100644
index 000000000000..2b386b4dc4db
--- /dev/null
+++ b/code/modules/barricade_tape/barricade_tape_template.dm
@@ -0,0 +1,26 @@
+////////////////////////////////////////////////////////////////////
+// Barricade Tape Template
+////////////////////////////////////////////////////////////////////
+//Singletons with data on the various templates of barricade tape
+/decl/barricade_tape_template
+ var/tape_kind = "barricade" //Used as a prefix to the word "tape" when refering to the tape and roll
+ var/tape_desc = "A tape barricade." //Description for the tape barricade
+ var/roll_desc = "A roll of barricade tape." //Description for the tape roll
+ var/icon_file = 'icons/policetape.dmi' //Icon file used for both the tape and roll
+ var/base_icon_state = "tape" //For the barricade. Icon state used to fetch the applied tape directional icons for various states
+ var/list/req_access //Access required to automatically pass through tape barricades
+ var/tape_color //Color of the tape
+ var/detail_overlay //Overlay for the applied tape
+ var/detail_color //Color for the detail overlay
+
+/decl/barricade_tape_template/proc/make_line_barricade(var/mob/user, var/turf/T, var/pdir)
+ var/obj/structure/tape_barricade/bar = new(T,,,src)
+ bar.add_fingerprint(user)
+ return bar
+
+/decl/barricade_tape_template/proc/make_door_barricade(var/mob/user, var/obj/door)
+ var/obj/structure/tape_barricade/door/bar = new(get_turf(door))
+ bar.set_tape_template(src)
+ bar.set_dir(door.dir)
+ bar.add_fingerprint(user)
+ return bar
\ No newline at end of file
diff --git a/code/modules/blob/blob.dm b/code/modules/blob/blob.dm
index 5de1ac052b18..5780a8f2ca98 100644
--- a/code/modules/blob/blob.dm
+++ b/code/modules/blob/blob.dm
@@ -12,19 +12,19 @@
layer = BLOB_SHIELD_LAYER
- max_health = 30
+ max_health = 15
- var/regen_rate = 5
- var/brute_resist = 4.3
- var/fire_resist = 0.8
- var/laser_resist = 2 // Special resist for laser based weapons - Emitters or handheld energy weaponry. Damage is divided by this and THEN by fire_resist.
+ var/regen_rate = 2.5
+ var/brute_damage_divisor = 4.3
+ var/fire_damage_divisor = 1.1
+ var/laser_damage_divisor = 2 // Special resist for laser based weapons - Emitters or handheld energy weaponry. Damage is divided by this and THEN by fire_damage_divisor.
var/expandType = /obj/effect/blob
- var/secondary_core_growth_chance = 5 //% chance to grow a secondary blob core instead of whatever was suposed to grown. Secondary cores are considerably weaker, but still nasty.
+ var/secondary_core_growth_chance = 2.5 //% chance to grow a secondary blob core instead of whatever was suposed to grown. Secondary cores are considerably weaker, but still nasty.
var/damage_min = 15
var/damage_max = 30
var/pruned = FALSE
var/product = /obj/item/blob_tendril
- var/attack_freq = 5 //see proc/attempt_attack; lower is more often, min 1
+ var/attack_freq = 7.5 //see proc/attempt_attack; lower is more often, min 1
/obj/effect/blob/Initialize()
. = ..()
@@ -42,7 +42,7 @@
/obj/effect/blob/explosion_act(var/severity)
SHOULD_CALL_PARENT(FALSE)
- take_damage(rand(140 - (severity * 40), 140 - (severity * 20)) / brute_resist)
+ take_damage(rand(140 - (severity * 40), 140 - (severity * 20)) / brute_damage_divisor)
/obj/effect/blob/on_update_icon()
if(current_health > get_max_health() / 2)
@@ -123,7 +123,7 @@
/obj/effect/blob/proc/do_pulse(var/forceLeft, var/list/dirs)
set waitfor = FALSE
- sleep(4)
+ sleep(8)
var/pushDir = pick(dirs)
var/turf/T = get_step(src, pushDir)
var/obj/effect/blob/B = (locate() in T)
@@ -156,9 +156,9 @@
switch(Proj.atom_damage_type)
if(BRUTE)
- take_damage(Proj.damage / brute_resist, Proj.atom_damage_type)
+ take_damage(Proj.damage / brute_damage_divisor, Proj.atom_damage_type)
if(BURN)
- take_damage((Proj.damage / laser_resist) / fire_resist, Proj.atom_damage_type)
+ take_damage((Proj.damage / laser_damage_divisor) / fire_damage_divisor, Proj.atom_damage_type)
return 0
/obj/effect/blob/attackby(var/obj/item/W, var/mob/user)
@@ -182,11 +182,11 @@
var/damage = 0
switch(W.atom_damage_type)
if(BURN)
- damage = (W.expend_attack_force(user) / fire_resist)
+ damage = (W.expend_attack_force(user) / fire_damage_divisor)
if(IS_WELDER(W))
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
if(BRUTE)
- damage = (W.expend_attack_force(user) / brute_resist)
+ damage = (W.expend_attack_force(user) / brute_damage_divisor)
take_damage(damage, W.atom_damage_type)
return TRUE
@@ -195,7 +195,7 @@
name = "master nucleus"
desc = "A massive, fragile nucleus guarded by a shield of thick tendrils."
icon_state = "blob_core"
- max_health = 450
+ max_health = 225
damage_min = 30
damage_max = 40
expandType = /obj/effect/blob/shield
@@ -216,28 +216,28 @@ regen() will cover update_icon() for this proc
/obj/effect/blob/core/proc/process_core_health()
switch(get_health_percent())
if(75 to INFINITY)
- brute_resist = 3.5
- fire_resist = 2
+ brute_damage_divisor = 3.5
+ fire_damage_divisor = 2.5
attack_freq = 5
regen_rate = 2
times_to_pulse = 4
if(reported_low_damage)
report_shield_status("high")
if(50 to 74)
- brute_resist = 2.5
- fire_resist = 1.5
+ brute_damage_divisor = 2.5
+ fire_damage_divisor = 2
attack_freq = 4
regen_rate = 3
times_to_pulse = 3
if(34 to 49)
- brute_resist = 1
- fire_resist = 0.8
+ brute_damage_divisor = 1
+ fire_damage_divisor = 1.1
attack_freq = 3
regen_rate = 4
times_to_pulse = 2
if(-INFINITY to 33)
- brute_resist = 0.5
- fire_resist = 0.3
+ brute_damage_divisor = 0.5
+ fire_damage_divisor = 0.35
regen_rate = 5
times_to_pulse = 1
if(!reported_low_damage)
@@ -278,7 +278,7 @@ regen() will cover update_icon() for this proc
name = "auxiliary nucleus"
desc = "An interwoven mass of tendrils. A glowing nucleus pulses at its center."
icon_state = "blob_node"
- max_health = 125
+ max_health = 65
regen_rate = 1
damage_min = 15
damage_max = 20
@@ -296,10 +296,10 @@ regen() will cover update_icon() for this proc
name = "shielding mass"
desc = "A pulsating mass of interwoven tendrils. These seem particularly robust, but not quite as active."
icon_state = "blob_idle"
- max_health = 120
+ max_health = 60
damage_min = 13
damage_max = 25
- attack_freq = 7
+ attack_freq = 8
regen_rate = 4
expandType = /obj/effect/blob/ravaging
light_color = BLOB_COLOR_SHIELD
@@ -328,7 +328,7 @@ regen() will cover update_icon() for this proc
/obj/effect/blob/ravaging
name = "ravaging mass"
desc = "A mass of interwoven tendrils. They thrash around haphazardly at anything in reach."
- max_health = 20
+ max_health = 10
damage_min = 27
damage_max = 36
attack_freq = 3
diff --git a/code/modules/bodytype/bodytype_quadruped.dm b/code/modules/bodytype/bodytype_quadruped.dm
index ab5bbdd75e6f..359a7d0d28a9 100644
--- a/code/modules/bodytype/bodytype_quadruped.dm
+++ b/code/modules/bodytype/bodytype_quadruped.dm
@@ -16,12 +16,12 @@
BP_L_FOOT = list("path" = /obj/item/organ/external/foot/quadruped),
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/quadruped)
)
- var/ridable = TRUE
+ var/rideable = TRUE
var/riding_offset = @"{'x':0,'y':0,'z':8}"
/decl/bodytype/quadruped/apply_appearance(var/mob/living/human/H)
. = ..()
- H.can_buckle = ridable
+ H.can_buckle = rideable
H.buckle_pixel_shift = riding_offset
/decl/bodytype/quadruped/get_ignited_icon_state(mob/living/victim)
diff --git a/code/modules/butchery/butchery_products.dm b/code/modules/butchery/butchery_products.dm
index d12b2980a3af..f4e76d9af464 100644
--- a/code/modules/butchery/butchery_products.dm
+++ b/code/modules/butchery/butchery_products.dm
@@ -128,7 +128,7 @@
/obj/item/food/butchery/offal
name = "offal"
- desc = "An assortmant of organs and lumps of unidentified gristle. Packed with nutrients and bile."
+ desc = "An assortment of organs and lumps of unidentified gristle. Packed with nutrients and bile."
icon = 'icons/obj/food/butchery/offal.dmi'
material = /decl/material/solid/organic/meat/gut
nutriment_amt = 15
diff --git a/code/modules/butchery/butchery_products_meat.dm b/code/modules/butchery/butchery_products_meat.dm
index aa4cdbd9a514..9907f21994ce 100644
--- a/code/modules/butchery/butchery_products_meat.dm
+++ b/code/modules/butchery/butchery_products_meat.dm
@@ -30,7 +30,7 @@
return ..()
/obj/item/food/butchery/meat/syntiflesh
- desc = "A slab of flesh synthetized from reconstituted biomass or artificially grown from chemicals."
+ desc = "A slab of flesh synthesized from reconstituted biomass or artificially grown from chemicals."
meat_name = "synthetic"
// Seperate definitions because some food likes to know if it's human.
@@ -60,7 +60,7 @@
butchery_data = /decl/butchery_data/animal/small/fowl
/obj/item/food/butchery/meat/corgi
- desc = "Tastes like... well you know..."
+ desc = "Tastes like... well, you know..."
butchery_data = /decl/butchery_data/animal/corgi
/obj/item/food/butchery/meat/xeno
diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm
index f83344b4841e..b27ec40f29d6 100644
--- a/code/modules/client/asset_cache.dm
+++ b/code/modules/client/asset_cache.dm
@@ -122,7 +122,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the
//all of our asset datums, used for referring to these later
var/global/list/asset_datums = list()
-//get a assetdatum or make a new one
+//get an assetdatum or make a new one
/proc/get_asset_datum(var/type)
if (!(type in asset_datums))
return new type()
diff --git a/code/modules/client/ui_styles/_helpers.dm b/code/modules/client/ui_styles/_helpers.dm
index 97d99ab4f2fa..c7c7cc06da71 100644
--- a/code/modules/client/ui_styles/_helpers.dm
+++ b/code/modules/client/ui_styles/_helpers.dm
@@ -5,9 +5,10 @@
if(!ui.restricted || !filter_available)
LAZYADD(., ui)
-/proc/get_default_ui_icon(ui_key)
- return get_ui_icon(global.using_map.default_ui_style, ui_key)
+/proc/get_ui_icon(decl/ui_style/ui_style, ui_key)
-/proc/get_ui_icon(ui_style, ui_key)
- var/decl/ui_style/style = GET_DECL(ui_style)
- return style?.get_icon(ui_key) || get_default_ui_icon(ui_key)
+ if(ispath(ui_style))
+ ui_style = GET_DECL(ui_style)
+ if(!istype(ui_style))
+ ui_style = GET_DECL(global.using_map.default_ui_style)
+ return ui_style.get_icon(ui_key)
diff --git a/code/modules/client/ui_styles/_ui_style.dm b/code/modules/client/ui_styles/_ui_style.dm
index d7a51a45f87c..808709107dcd 100644
--- a/code/modules/client/ui_styles/_ui_style.dm
+++ b/code/modules/client/ui_styles/_ui_style.dm
@@ -7,22 +7,29 @@
var/name
/// Associative mapping of UI icon key to icon file.
var/list/icons = list(
- UI_ICON_ATTACK = 'icons/mob/screen/styles/midnight/attack_selector.dmi',
- UI_ICON_FIRE_INTENT = 'icons/mob/screen/styles/midnight/fire_intent.dmi',
- UI_ICON_HANDS = 'icons/mob/screen/styles/midnight/hands.dmi',
- UI_ICON_HEALTH = 'icons/mob/screen/styles/health.dmi',
- UI_ICON_CRIT_MARKER = 'icons/mob/screen/styles/crit_markers.dmi',
- UI_ICON_HYDRATION = 'icons/mob/screen/styles/hydration.dmi',
- UI_ICON_INTERACTION = 'icons/mob/screen/styles/midnight/interaction.dmi',
- UI_ICON_INTERNALS = 'icons/mob/screen/styles/internals.dmi',
- UI_ICON_INVENTORY = 'icons/mob/screen/styles/midnight/inventory.dmi',
- UI_ICON_MOVEMENT = 'icons/mob/screen/styles/midnight/movement.dmi',
- UI_ICON_NUTRITION = 'icons/mob/screen/styles/nutrition.dmi',
- UI_ICON_STATUS_FIRE = 'icons/mob/screen/styles/status_fire.dmi',
- UI_ICON_STATUS = 'icons/mob/screen/styles/status.dmi',
- UI_ICON_UP_HINT = 'icons/mob/screen/styles/midnight/uphint.dmi',
- UI_ICON_ZONE_SELECT = 'icons/mob/screen/styles/midnight/zone_selector.dmi',
- UI_ICON_CHARGE = 'icons/mob/screen/styles/charge.dmi'
+ (HUD_ATTACK) = 'icons/mob/screen/styles/midnight/attack_selector.dmi',
+ (HUD_FIRE_INTENT) = 'icons/mob/screen/styles/midnight/fire_intent.dmi',
+ (HUD_HANDS) = 'icons/mob/screen/styles/midnight/hands.dmi',
+ (HUD_HEALTH) = 'icons/mob/screen/styles/health.dmi',
+ (HUD_CRIT_MARKER) = 'icons/mob/screen/styles/crit_markers.dmi',
+ (HUD_HYDRATION) = 'icons/mob/screen/styles/hydration.dmi',
+ (HUD_RESIST) = 'icons/mob/screen/styles/midnight/interaction_resist.dmi',
+ (HUD_THROW) = 'icons/mob/screen/styles/midnight/interaction_throw.dmi',
+ (HUD_DROP) = 'icons/mob/screen/styles/midnight/interaction_drop.dmi',
+ (HUD_MANEUVER) = 'icons/mob/screen/styles/midnight/interaction_maneuver.dmi',
+ (HUD_INTERNALS) = 'icons/mob/screen/styles/internals.dmi',
+ (HUD_INVENTORY) = 'icons/mob/screen/styles/midnight/inventory.dmi',
+ (HUD_MOVEMENT) = 'icons/mob/screen/styles/midnight/movement.dmi',
+ (HUD_NUTRITION) = 'icons/mob/screen/styles/nutrition.dmi',
+ (HUD_FIRE) = 'icons/mob/screen/styles/status_fire.dmi',
+ (HUD_PRESSURE) = 'icons/mob/screen/styles/status_pressure.dmi',
+ (HUD_BODYTEMP) = 'icons/mob/screen/styles/status_bodytemp.dmi',
+ (HUD_TOX) = 'icons/mob/screen/styles/status_tox.dmi',
+ (HUD_OXY) = 'icons/mob/screen/styles/status_oxy.dmi',
+ (HUD_UP_HINT) = 'icons/mob/screen/styles/midnight/uphint.dmi',
+ (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/midnight/zone_selector.dmi',
+ (HUD_CHARGE) = 'icons/mob/screen/styles/charge.dmi',
+ (HUD_INTENT) = 'icons/screen/intents.dmi'
)
/// A subset of UI keys to icon files used to override the above.
var/list/override_icons
@@ -68,4 +75,4 @@
. += "icon [check_icon] for key [ui_key] is missing states: '[jointext(missing_states, "', '")]'"
/decl/ui_style/proc/get_icon(var/ui_key)
- return istext(ui_key) && length(icons) ? icons[ui_key] : null
+ return (!isnull(ui_key) && !isnum(ui_key) && length(icons)) ? icons[ui_key] : null
diff --git a/code/modules/client/ui_styles/_ui_style_states.dm b/code/modules/client/ui_styles/_ui_style_states.dm
index 881a423335e8..480ae2158929 100644
--- a/code/modules/client/ui_styles/_ui_style_states.dm
+++ b/code/modules/client/ui_styles/_ui_style_states.dm
@@ -1,19 +1,26 @@
var/global/list/_ui_all_keys = list(
- UI_ICON_INTERACTION,
- UI_ICON_ZONE_SELECT,
- UI_ICON_MOVEMENT,
- UI_ICON_INVENTORY,
- UI_ICON_ATTACK,
- UI_ICON_HANDS,
- UI_ICON_INTERNALS,
- UI_ICON_HEALTH,
- UI_ICON_NUTRITION,
- UI_ICON_HYDRATION,
- UI_ICON_FIRE_INTENT,
- UI_ICON_UP_HINT,
- UI_ICON_STATUS,
- UI_ICON_STATUS_FIRE,
- UI_ICON_CHARGE
+ (HUD_DROP),
+ (HUD_RESIST),
+ (HUD_ZONE_SELECT),
+ (HUD_MOVEMENT),
+ (HUD_INVENTORY),
+ (HUD_ATTACK),
+ (HUD_HANDS),
+ (HUD_INTERNALS),
+ (HUD_HEALTH),
+ (HUD_NUTRITION),
+ (HUD_HYDRATION),
+ (HUD_FIRE_INTENT),
+ (HUD_UP_HINT),
+ (HUD_PRESSURE),
+ (HUD_BODYTEMP),
+ (HUD_TOX),
+ (HUD_OXY),
+ (HUD_FIRE),
+ (HUD_CHARGE),
+ (HUD_THROW),
+ (HUD_MANEUVER),
+ (HUD_INTENT)
)
var/global/list/_ui_expected_states
@@ -26,10 +33,21 @@ var/global/list/_ui_expected_states
// Set hardcoded strings.
global._ui_expected_states = list(
- UI_ICON_ATTACK = list(
+ (HUD_INTENT) = list(
+ "blank",
+ "intent_harm",
+ "intent_grab",
+ "intent_help",
+ "intent_disarm",
+ "intent_harm_off",
+ "intent_grab_off",
+ "intent_help_off",
+ "intent_disarm_off"
+ ),
+ (HUD_ATTACK) = list(
"attack_none"
),
- UI_ICON_FIRE_INTENT = list(
+ (HUD_FIRE_INTENT) = list(
"no_walk0",
"no_walk1",
"no_run0",
@@ -41,14 +59,14 @@ var/global/list/_ui_expected_states
"gun0",
"gun1"
),
- UI_ICON_HANDS = list(
+ (HUD_HANDS) = list(
"hand_base",
"hand_selected",
"act_equip",
"hand1",
"hand2"
),
- UI_ICON_HEALTH = list(
+ (HUD_HEALTH) = list(
"health0",
"health1",
"health2",
@@ -59,48 +77,67 @@ var/global/list/_ui_expected_states
"health7",
"health_numb"
),
- UI_ICON_CRIT_MARKER = list(
+ (HUD_CRIT_MARKER) = list(
"softcrit",
"hardcrit",
"fullhealth",
"burning"
),
- UI_ICON_HYDRATION = list(
+ (HUD_HYDRATION) = list(
"hydration0",
"hydration1",
"hydration2",
"hydration3",
"hydration4"
),
- UI_ICON_INTERACTION = list(
- "act_resist",
+ (HUD_RESIST) = list(
+ "act_resist"
+ ),
+ (HUD_THROW) = list(
"act_throw_off",
"act_throw_on",
- "act_drop",
+ ),
+ (HUD_DROP) = list(
+ "act_drop"
+ ),
+ (HUD_MANEUVER) = list(
"maneuver_off",
"maneuver_on"
),
- UI_ICON_INTERNALS = list(
+ (HUD_INTERNALS) = list(
"internal0",
"internal1"
),
- UI_ICON_INVENTORY = list(
+ (HUD_INVENTORY) = list(
"other"
),
- UI_ICON_MOVEMENT = list(),
- UI_ICON_NUTRITION = list(
+ (HUD_MOVEMENT) = list(
+ "creeping",
+ "walking",
+ "running"
+ ),
+ (HUD_NUTRITION) = list(
"nutrition0",
"nutrition1",
"nutrition2",
"nutrition3",
"nutrition4"
),
- UI_ICON_STATUS_FIRE = list(
+ (HUD_FIRE) = list(
"fire0",
"fire1",
"fire2"
),
- UI_ICON_STATUS = list(
+ (HUD_OXY) = list(
+ "oxy0",
+ "oxy1",
+ "oxy2"
+ ),
+ (HUD_TOX) = list(
+ "tox0",
+ "tox1"
+ ),
+ (HUD_BODYTEMP) = list(
"temp-4",
"temp-3",
"temp-2",
@@ -109,32 +146,34 @@ var/global/list/_ui_expected_states
"temp1",
"temp2",
"temp3",
- "temp4",
- "tox0",
- "tox1",
- "oxy0",
- "oxy1",
- "oxy2",
+ "temp4"
+ ),
+ (HUD_PRESSURE) = list(
"pressure-2",
"pressure-1",
"pressure0",
"pressure1",
"pressure2"
),
- UI_ICON_UP_HINT = list(
+ (HUD_UP_HINT) = list(
"uphint0",
"uphint1"
),
- UI_ICON_ZONE_SELECT = list(
+ (HUD_ZONE_SELECT) = list(
"zone_sel_tail"
),
- UI_ICON_CHARGE = list(
+ (HUD_CHARGE) = list(
"charge0",
"charge1",
"charge2",
"charge3",
"charge4",
- "charge-empty"
+ "charge-empty",
+ "blank"
+ ),
+ (HUD_THROW) = list(
+ "act_throw_on",
+ "act_throw_off"
)
)
@@ -143,25 +182,25 @@ var/global/list/_ui_expected_states
for(var/attack_type in all_attacks)
var/decl/natural_attack/attack = all_attacks[attack_type]
if(attack.selector_icon_state)
- global._ui_expected_states[UI_ICON_ATTACK] |= attack.selector_icon_state
+ global._ui_expected_states[HUD_ATTACK] |= attack.selector_icon_state
// Collect hand slot sates.
for(var/slot in global.all_hand_slots)
- global._ui_expected_states[UI_ICON_HANDS] |= "hand_[slot]"
+ global._ui_expected_states[HUD_HANDS] |= "hand_[slot]"
for(var/gripper_type in subtypesof(/datum/inventory_slot/gripper))
var/datum/inventory_slot/gripper/gripper = gripper_type
if(TYPE_IS_ABSTRACT(gripper))
continue
var/ui_label = initial(gripper.ui_label)
if(ui_label)
- global._ui_expected_states[UI_ICON_HANDS] |= "hand_[ui_label]"
+ global._ui_expected_states[HUD_HANDS] |= "hand_[ui_label]"
// Collect movement intent states.
var/list/all_movement = decls_repository.get_decls_of_subtype(/decl/move_intent)
for(var/movement_type in all_movement)
var/decl/move_intent/movement = all_movement[movement_type]
if(movement.hud_icon_state)
- global._ui_expected_states[UI_ICON_MOVEMENT] |= movement.hud_icon_state
+ global._ui_expected_states[HUD_MOVEMENT] |= movement.hud_icon_state
// Collect inventory slot states.
for(var/inventory_slot_type in subtypesof(/datum/inventory_slot))
@@ -170,6 +209,6 @@ var/global/list/_ui_expected_states
continue
var/slot_string = initial(slot.slot_state)
if(slot_string)
- global._ui_expected_states[UI_ICON_INVENTORY] |= slot_string
+ global._ui_expected_states[HUD_INVENTORY] |= slot_string
return global._ui_expected_states
diff --git a/code/modules/client/ui_styles/ui_style_subtypes.dm b/code/modules/client/ui_styles/ui_style_subtypes.dm
index 7b1f311ebd71..f80a00d7b8b1 100644
--- a/code/modules/client/ui_styles/ui_style_subtypes.dm
+++ b/code/modules/client/ui_styles/ui_style_subtypes.dm
@@ -7,56 +7,68 @@
name = "Orange"
uid = "ui_style_orange"
override_icons = list(
- (UI_ICON_ATTACK) = 'icons/mob/screen/styles/orange/attack_selector.dmi',
- (UI_ICON_FIRE_INTENT) = 'icons/mob/screen/styles/orange/fire_intent.dmi',
- (UI_ICON_HANDS) = 'icons/mob/screen/styles/orange/hands.dmi',
- (UI_ICON_INTERACTION) = 'icons/mob/screen/styles/orange/interaction.dmi',
- (UI_ICON_INVENTORY) = 'icons/mob/screen/styles/orange/inventory.dmi',
- (UI_ICON_MOVEMENT) = 'icons/mob/screen/styles/orange/movement.dmi',
- (UI_ICON_UP_HINT) = 'icons/mob/screen/styles/orange/uphint.dmi',
- (UI_ICON_ZONE_SELECT) = 'icons/mob/screen/styles/orange/zone_selector.dmi'
+ (HUD_ATTACK) = 'icons/mob/screen/styles/orange/attack_selector.dmi',
+ (HUD_FIRE_INTENT) = 'icons/mob/screen/styles/orange/fire_intent.dmi',
+ (HUD_HANDS) = 'icons/mob/screen/styles/orange/hands.dmi',
+ (HUD_DROP) = 'icons/mob/screen/styles/orange/interaction_drop.dmi',
+ (HUD_THROW) = 'icons/mob/screen/styles/orange/interaction_throw.dmi',
+ (HUD_RESIST) = 'icons/mob/screen/styles/orange/interaction_resist.dmi',
+ (HUD_MANEUVER) = 'icons/mob/screen/styles/orange/interaction_maneuver.dmi',
+ (HUD_INVENTORY) = 'icons/mob/screen/styles/orange/inventory.dmi',
+ (HUD_MOVEMENT) = 'icons/mob/screen/styles/orange/movement.dmi',
+ (HUD_UP_HINT) = 'icons/mob/screen/styles/orange/uphint.dmi',
+ (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/orange/zone_selector.dmi'
)
/decl/ui_style/old
name = "Old"
uid = "ui_style_old"
override_icons = list(
- (UI_ICON_ATTACK) = 'icons/mob/screen/styles/old/attack_selector.dmi',
- (UI_ICON_FIRE_INTENT) = 'icons/mob/screen/styles/old/fire_intent.dmi',
- (UI_ICON_HANDS) = 'icons/mob/screen/styles/old/hands.dmi',
- (UI_ICON_INTERACTION) = 'icons/mob/screen/styles/old/interaction.dmi',
- (UI_ICON_INVENTORY) = 'icons/mob/screen/styles/old/inventory.dmi',
- (UI_ICON_MOVEMENT) = 'icons/mob/screen/styles/old/movement.dmi',
- (UI_ICON_UP_HINT) = 'icons/mob/screen/styles/old/uphint.dmi',
- (UI_ICON_ZONE_SELECT) = 'icons/mob/screen/styles/old/zone_selector.dmi'
+ (HUD_ATTACK) = 'icons/mob/screen/styles/old/attack_selector.dmi',
+ (HUD_FIRE_INTENT) = 'icons/mob/screen/styles/old/fire_intent.dmi',
+ (HUD_HANDS) = 'icons/mob/screen/styles/old/hands.dmi',
+ (HUD_DROP) = 'icons/mob/screen/styles/old/interaction_drop.dmi',
+ (HUD_THROW) = 'icons/mob/screen/styles/old/interaction_throw.dmi',
+ (HUD_RESIST) = 'icons/mob/screen/styles/old/interaction_resist.dmi',
+ (HUD_MANEUVER) = 'icons/mob/screen/styles/old/interaction_maneuver.dmi',
+ (HUD_INVENTORY) = 'icons/mob/screen/styles/old/inventory.dmi',
+ (HUD_MOVEMENT) = 'icons/mob/screen/styles/old/movement.dmi',
+ (HUD_UP_HINT) = 'icons/mob/screen/styles/old/uphint.dmi',
+ (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/old/zone_selector.dmi'
)
/decl/ui_style/old_noborder
name = "Old (no border)"
uid = "ui_style_old_noborder"
override_icons = list(
- (UI_ICON_ATTACK) = 'icons/mob/screen/styles/old/attack_selector.dmi',
- (UI_ICON_FIRE_INTENT) = 'icons/mob/screen/styles/old/fire_intent.dmi',
- (UI_ICON_HANDS) = 'icons/mob/screen/styles/old/hands.dmi',
- (UI_ICON_INTERACTION) = 'icons/mob/screen/styles/old/interaction.dmi',
- (UI_ICON_INVENTORY) = 'icons/mob/screen/styles/old_noborder/inventory.dmi',
- (UI_ICON_MOVEMENT) = 'icons/mob/screen/styles/old/movement.dmi',
- (UI_ICON_UP_HINT) = 'icons/mob/screen/styles/old_noborder/uphint.dmi',
- (UI_ICON_ZONE_SELECT) = 'icons/mob/screen/styles/old_noborder/zone_selector.dmi'
+ (HUD_ATTACK) = 'icons/mob/screen/styles/old/attack_selector.dmi',
+ (HUD_FIRE_INTENT) = 'icons/mob/screen/styles/old/fire_intent.dmi',
+ (HUD_HANDS) = 'icons/mob/screen/styles/old/hands.dmi',
+ (HUD_DROP) = 'icons/mob/screen/styles/old/interaction_drop.dmi',
+ (HUD_THROW) = 'icons/mob/screen/styles/old/interaction_throw.dmi',
+ (HUD_RESIST) = 'icons/mob/screen/styles/old/interaction_resist.dmi',
+ (HUD_MANEUVER) = 'icons/mob/screen/styles/old/interaction_maneuver.dmi',
+ (HUD_INVENTORY) = 'icons/mob/screen/styles/old_noborder/inventory.dmi',
+ (HUD_MOVEMENT) = 'icons/mob/screen/styles/old/movement.dmi',
+ (HUD_UP_HINT) = 'icons/mob/screen/styles/old_noborder/uphint.dmi',
+ (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/old_noborder/zone_selector.dmi'
)
/decl/ui_style/white
name = "White"
uid = "ui_style_white"
override_icons = list(
- (UI_ICON_ATTACK) = 'icons/mob/screen/styles/white/attack_selector.dmi',
- (UI_ICON_FIRE_INTENT) = 'icons/mob/screen/styles/white/fire_intent.dmi',
- (UI_ICON_HANDS) = 'icons/mob/screen/styles/white/hands.dmi',
- (UI_ICON_INTERACTION) = 'icons/mob/screen/styles/white/interaction.dmi',
- (UI_ICON_INVENTORY) = 'icons/mob/screen/styles/white/inventory.dmi',
- (UI_ICON_MOVEMENT) = 'icons/mob/screen/styles/white/movement.dmi',
- (UI_ICON_UP_HINT) = 'icons/mob/screen/styles/white/uphint.dmi',
- (UI_ICON_ZONE_SELECT) = 'icons/mob/screen/styles/white/zone_selector.dmi'
+ (HUD_ATTACK) = 'icons/mob/screen/styles/white/attack_selector.dmi',
+ (HUD_FIRE_INTENT) = 'icons/mob/screen/styles/white/fire_intent.dmi',
+ (HUD_HANDS) = 'icons/mob/screen/styles/white/hands.dmi',
+ (HUD_DROP) = 'icons/mob/screen/styles/white/interaction_drop.dmi',
+ (HUD_THROW) = 'icons/mob/screen/styles/white/interaction_throw.dmi',
+ (HUD_RESIST) = 'icons/mob/screen/styles/white/interaction_resist.dmi',
+ (HUD_MANEUVER) = 'icons/mob/screen/styles/white/interaction_maneuver.dmi',
+ (HUD_INVENTORY) = 'icons/mob/screen/styles/white/inventory.dmi',
+ (HUD_MOVEMENT) = 'icons/mob/screen/styles/white/movement.dmi',
+ (HUD_UP_HINT) = 'icons/mob/screen/styles/white/uphint.dmi',
+ (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/white/zone_selector.dmi'
)
use_overlay_color = TRUE
use_ui_color = TRUE
@@ -65,14 +77,17 @@
name = "Minimalist"
uid = "ui_style_minimalist"
override_icons = list(
- (UI_ICON_ATTACK) = 'icons/mob/screen/styles/minimalist/attack_selector.dmi',
- (UI_ICON_FIRE_INTENT) = 'icons/mob/screen/styles/minimalist/fire_intent.dmi',
- (UI_ICON_HANDS) = 'icons/mob/screen/styles/minimalist/hands.dmi',
- (UI_ICON_INTERACTION) = 'icons/mob/screen/styles/minimalist/interaction.dmi',
- (UI_ICON_INVENTORY) = 'icons/mob/screen/styles/minimalist/inventory.dmi',
- (UI_ICON_MOVEMENT) = 'icons/mob/screen/styles/minimalist/movement.dmi',
- (UI_ICON_UP_HINT) = 'icons/mob/screen/styles/minimalist/uphint.dmi',
- (UI_ICON_ZONE_SELECT) = 'icons/mob/screen/styles/minimalist/zone_selector.dmi'
+ (HUD_ATTACK) = 'icons/mob/screen/styles/minimalist/attack_selector.dmi',
+ (HUD_FIRE_INTENT) = 'icons/mob/screen/styles/minimalist/fire_intent.dmi',
+ (HUD_HANDS) = 'icons/mob/screen/styles/minimalist/hands.dmi',
+ (HUD_DROP) = 'icons/mob/screen/styles/minimalist/interaction_drop.dmi',
+ (HUD_RESIST) = 'icons/mob/screen/styles/minimalist/interaction_resist.dmi',
+ (HUD_THROW) = 'icons/mob/screen/styles/minimalist/interaction_throw.dmi',
+ (HUD_MANEUVER) = 'icons/mob/screen/styles/minimalist/interaction_maneuver.dmi',
+ (HUD_INVENTORY) = 'icons/mob/screen/styles/minimalist/inventory.dmi',
+ (HUD_MOVEMENT) = 'icons/mob/screen/styles/minimalist/movement.dmi',
+ (HUD_UP_HINT) = 'icons/mob/screen/styles/minimalist/uphint.dmi',
+ (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/minimalist/zone_selector.dmi'
)
use_overlay_color = TRUE
use_ui_color = TRUE
@@ -81,23 +96,18 @@
name = "Underworld"
uid = "ui_style_underworld"
restricted = FALSE
- icons = list(
- (UI_ICON_ATTACK) = 'icons/mob/screen/styles/underworld/attack_selector.dmi',
- (UI_ICON_FIRE_INTENT) = 'icons/mob/screen/styles/underworld/fire_intent.dmi',
- (UI_ICON_HANDS) = 'icons/mob/screen/styles/underworld/hands.dmi',
- (UI_ICON_HEALTH) = 'icons/mob/screen/styles/health.dmi',
- (UI_ICON_CRIT_MARKER) = 'icons/mob/screen/styles/crit_markers.dmi',
- (UI_ICON_HYDRATION) = 'icons/mob/screen/styles/hydration.dmi',
- (UI_ICON_INTERACTION) = 'icons/mob/screen/styles/underworld/interaction.dmi',
- (UI_ICON_INTERNALS) = 'icons/mob/screen/styles/internals.dmi',
- (UI_ICON_INVENTORY) = 'icons/mob/screen/styles/underworld/inventory.dmi',
- (UI_ICON_MOVEMENT) = 'icons/mob/screen/styles/underworld/movement.dmi',
- (UI_ICON_NUTRITION) = 'icons/mob/screen/styles/nutrition.dmi',
- (UI_ICON_STATUS_FIRE) = 'icons/mob/screen/styles/status_fire.dmi',
- (UI_ICON_STATUS) = 'icons/mob/screen/styles/status.dmi',
- (UI_ICON_UP_HINT) = 'icons/mob/screen/styles/underworld/uphint.dmi',
- (UI_ICON_ZONE_SELECT) = 'icons/mob/screen/styles/underworld/zone_selector.dmi',
- (UI_ICON_CHARGE) = 'icons/mob/screen/styles/charge.dmi'
+ override_icons = list(
+ (HUD_ATTACK) = 'icons/mob/screen/styles/underworld/attack_selector.dmi',
+ (HUD_FIRE_INTENT) = 'icons/mob/screen/styles/underworld/fire_intent.dmi',
+ (HUD_HANDS) = 'icons/mob/screen/styles/underworld/hands.dmi',
+ (HUD_DROP) = 'icons/mob/screen/styles/underworld/interaction_drop.dmi',
+ (HUD_RESIST) = 'icons/mob/screen/styles/underworld/interaction_resist.dmi',
+ (HUD_THROW) = 'icons/mob/screen/styles/underworld/interaction_throw.dmi',
+ (HUD_MANEUVER) = 'icons/mob/screen/styles/underworld/interaction_maneuver.dmi',
+ (HUD_INVENTORY) = 'icons/mob/screen/styles/underworld/inventory.dmi',
+ (HUD_MOVEMENT) = 'icons/mob/screen/styles/underworld/movement.dmi',
+ (HUD_UP_HINT) = 'icons/mob/screen/styles/underworld/uphint.dmi',
+ (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/underworld/zone_selector.dmi'
)
use_overlay_color = TRUE
use_ui_color = TRUE
diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm
index b6cc37b0adae..032f327ee0fa 100644
--- a/code/modules/clothing/_clothing.dm
+++ b/code/modules/clothing/_clothing.dm
@@ -285,7 +285,7 @@
update_wearer_vision()
return ..()
-/obj/item/clothing/proc/refit_for_bodytype(var/target_bodytype)
+/obj/item/clothing/proc/refit_for_bodytype(target_bodytype, skip_rename = FALSE)
bodytype_equip_flags = 0
decls_repository.get_decls_of_subtype(/decl/bodytype) // Make sure they're prefetched so the below list is populated
@@ -297,6 +297,9 @@
if(species_icon && (check_state_in_icon(ICON_STATE_INV, species_icon) || check_state_in_icon(ICON_STATE_WORLD, species_icon)))
icon = species_icon
+ if(!skip_rename)
+ SetName("refitted [initial(name)]")
+
if(last_icon != icon)
reconsider_single_icon()
update_clothing_icon()
diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm
index 4a85cb47cef1..39ea1c743a97 100644
--- a/code/modules/clothing/chameleon.dm
+++ b/code/modules/clothing/chameleon.dm
@@ -190,7 +190,7 @@
/obj/item/clothing/shoes/chameleon
name = "black shoes"
icon = 'icons/clothing/feet/colored_shoes.dmi'
- desc = "They're comfy black shoes, with clever cloaking technology built in. It seems to have a small dial on the back of each shoe."
+ desc = "They're comfy black shoes, with clever cloaking technology built-in. It seems to have a small dial on the back of each shoe."
origin_tech = @'{"esoteric":3}'
item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON
bodytype_equip_flags = null
@@ -284,7 +284,7 @@
/obj/item/clothing/mask/chameleon
name = "gas mask"
icon = 'icons/clothing/mask/gas_mask_full.dmi'
- desc = "It looks like a plain gask mask, but on closer inspection, it seems to have a small dial inside."
+ desc = "It looks like a plain gas mask, but on closer inspection, it seems to have a small dial inside."
origin_tech = @'{"esoteric":3}'
item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON
bodytype_equip_flags = null
diff --git a/code/modules/clothing/costumes/misc.dm b/code/modules/clothing/costumes/misc.dm
index 13495b75d2f8..b44cfb42bc78 100644
--- a/code/modules/clothing/costumes/misc.dm
+++ b/code/modules/clothing/costumes/misc.dm
@@ -77,7 +77,7 @@
/obj/item/clothing/costume/oldman
name = "old man's suit"
- desc = "A classic suit for the older gentleman with built in back support."
+ desc = "A classic suit for the older gentleman with built-in back support."
icon = 'icons/clothing/costumes/uniform_lawyer_old.dmi'
/obj/item/clothing/costume/lawyer
diff --git a/code/modules/clothing/dresses/misc.dm b/code/modules/clothing/dresses/misc.dm
index 20085a74b6cb..49c74faa645e 100644
--- a/code/modules/clothing/dresses/misc.dm
+++ b/code/modules/clothing/dresses/misc.dm
@@ -1,6 +1,6 @@
/obj/item/clothing/dress/green
name = "green dress"
- desc = "A simple, tight fitting green dress."
+ desc = "A simple, tight-fitting green dress."
icon = 'icons/clothing/dresses/dress_green.dmi'
/obj/item/clothing/dress/yellow
@@ -15,28 +15,28 @@
/obj/item/clothing/dress/pink
name = "pink dress"
- desc = "A simple, tight fitting pink dress."
+ desc = "A simple, tight-fitting pink dress."
icon = 'icons/clothing/dresses/dress_pink.dmi'
/obj/item/clothing/dress/purple
name = "purple dress"
- desc= "A simple, tight fitting purple dress."
+ desc= "A simple, tight-fitting purple dress."
icon = 'icons/clothing/dresses/dress_purple.dmi'
/obj/item/clothing/dress/saloon
name = "saloon girl dress"
- desc = "A old western inspired gown for the girl who likes to drink."
+ desc = "An old western-inspired gown for the girl who likes to drink."
icon = 'icons/clothing/dresses/dress_saloon.dmi'
/obj/item/clothing/dress/cap
name = "captain's dress uniform"
- desc = "Feminine fashion for the style concious captain."
+ desc = "Feminine fashion for the style-conscious captain."
icon = 'icons/clothing/dresses/uniform_captain_dress.dmi'
body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_ARMS
/obj/item/clothing/dress/hop
name = "head of personnel dress uniform"
- desc = "Feminine fashion for the style concious HoP."
+ desc = "Feminine fashion for the style-conscious HoP."
icon = 'icons/clothing/dresses/dress_hop.dmi'
body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_ARMS
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 17022402e0aa..5341391d4d38 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -87,7 +87,7 @@
/obj/item/clothing/glasses/threedglasses
name = "3D glasses"
- desc = "A long time ago, people used these glasses to makes images from screens threedimensional."
+ desc = "A long time ago, people used these glasses to makes images from screens three-dimensional."
icon = 'icons/clothing/eyes/glasses_3d.dmi'
body_parts_covered = 0
diff --git a/code/modules/clothing/glasses/sunglasses.dm b/code/modules/clothing/glasses/sunglasses.dm
index c31ff5ec7554..7cb0c0d47084 100644
--- a/code/modules/clothing/glasses/sunglasses.dm
+++ b/code/modules/clothing/glasses/sunglasses.dm
@@ -1,6 +1,6 @@
/obj/item/clothing/glasses/sunglasses
name = "sunglasses"
- desc = "Glasses with treated lenses to prevent glare. They provide some rudamentary protection from dazzling attacks."
+ desc = "Glasses with treated lenses to prevent glare. They provide some rudimentary protection from dazzling attacks."
icon = 'icons/clothing/eyes/sunglasses.dmi'
darkness_view = -1
flash_protection = FLASH_PROTECTION_NONE
diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm
index ae91f9dcc1f0..9b94599c1820 100644
--- a/code/modules/clothing/head/_head.dm
+++ b/code/modules/clothing/head/_head.dm
@@ -35,10 +35,10 @@
else if(!on && light_applied)
set_light(0)
light_applied = 0
- update_icon(user)
+ update_icon()
user.update_action_buttons()
-/obj/item/clothing/head/on_update_icon(var/mob/user)
+/obj/item/clothing/head/on_update_icon()
. = ..()
update_clothing_icon()
if(on)
diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm
index 4c51dbe3bb9a..d5918f6a7a2e 100644
--- a/code/modules/clothing/head/collectable.dm
+++ b/code/modules/clothing/head/collectable.dm
@@ -7,8 +7,8 @@
armor = null
/obj/item/clothing/head/collectable/petehat
- name = "ultra rare hat"
- desc = "an ultra rare hat. It commands a certain respect."
+ name = "ultra-rare hat"
+ desc = "An ultra-rare hat. It commands a certain respect."
icon = 'icons/clothing/head/pete.dmi'
/obj/item/clothing/head/collectable/xenom
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index 42e08ecd5fe3..3e71ff98b2c1 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -82,7 +82,7 @@
to_chat(user, "You lower the visor on \the [src].")
update_icon()
-/obj/item/clothing/head/helmet/riot/on_update_icon(mob/user)
+/obj/item/clothing/head/helmet/riot/on_update_icon()
. = ..()
icon_state = get_world_inventory_state()
if(up && check_state_in_icon("[icon_state]_up", icon))
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index a435e585d3c5..dd2a2d3cac89 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -33,7 +33,7 @@
/obj/item/clothing/head/that
name = "top-hat"
- desc = "It's an amish looking hat."
+ desc = "It's an Amish-looking hat."
icon = 'icons/clothing/head/tophat.dmi'
siemens_coefficient = 0.9
@@ -78,7 +78,7 @@
/obj/item/clothing/head/rabbitears
name = "rabbit ears"
- desc = "Wearing these makes you looks useless, and only good for your sex appeal."
+ desc = "Wearing these makes you look useless, and only good for your sex appeal."
icon = 'icons/clothing/head/bunny.dmi'
body_parts_covered = 0
flags_inv = 0
@@ -109,6 +109,7 @@
name = "green bandana"
desc = "It's a green bandana with some fine nanotech lining."
icon = 'icons/clothing/head/bandana/green.dmi'
+
/obj/item/clothing/head/bandana/orange //themij: Taryn Kifer
name = "orange bandana"
desc = "An orange piece of cloth, worn on the head."
@@ -220,7 +221,7 @@
/obj/item/clothing/head/tank
name = "padded cap"
- desc = "A padded skullcup for those prone to bumping their heads against hard surfaces."
+ desc = "A padded skullcap for those prone to bumping their head against hard surfaces."
icon = 'icons/clothing/head/tank.dmi'
flags_inv = BLOCK_HEAD_HAIR
color = "#5f5f5f"
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 01d01335e585..b4ffdd62b8f6 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -84,7 +84,7 @@
/obj/item/clothing/head/welding/knight
name = "knightly welding helmet"
- desc = "A painted welding helmet, this one looks like a knights helmet."
+ desc = "A painted welding helmet, this one looks like a knight's helmet."
icon = 'icons/clothing/head/welding/knight.dmi'
/obj/item/clothing/head/welding/fancy
@@ -214,7 +214,7 @@
. = ..()
update_icon()
-/obj/item/clothing/head/cakehat/on_update_icon(mob/user)
+/obj/item/clothing/head/cakehat/on_update_icon()
. = ..()
z_flags &= ~ZMM_MANGLE_PLANES
if(is_on_fire() && check_state_in_icon("[icon_state]-flame", icon))
@@ -224,7 +224,7 @@
add_overlay(emissive_overlay(icon, "[icon_state]-flame"))
z_flags |= ZMM_MANGLE_PLANES
-// Overidable so species with limited headspace in the sprite bounding area can offset it (scavs)
+// Overrideable so species with limited headspace in the sprite bounding area can offset it (scavs)
/obj/item/clothing/head/cakehat/proc/get_mob_flame_overlay(var/image/overlay, var/bodytype)
if(overlay && check_state_in_icon("[overlay.icon_state]-flame", overlay.icon))
return emissive_overlay(overlay.icon, "[overlay.icon_state]-flame")
diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm
index 885b9195403b..d90327115d41 100644
--- a/code/modules/clothing/head/soft_caps.dm
+++ b/code/modules/clothing/head/soft_caps.dm
@@ -80,7 +80,7 @@
/obj/item/clothing/head/soft/sec
name = "security cap"
- desc = "It's a field cap in tasteful red color."
+ desc = "It's a field cap."
color = COLOR_NT_RED
/obj/item/clothing/head/soft/black
diff --git a/code/modules/clothing/jumpsuits/job.dm b/code/modules/clothing/jumpsuits/job.dm
index 90eb1ae24bbe..5c637e6e892e 100644
--- a/code/modules/clothing/jumpsuits/job.dm
+++ b/code/modules/clothing/jumpsuits/job.dm
@@ -144,7 +144,7 @@
)
/obj/item/clothing/jumpsuit/psych
- desc = "A basic white jumpsuit. It has turqouise markings that denote the wearer as a psychiatrist."
+ desc = "A basic white jumpsuit. It has turquoise markings that denote the wearer as a psychiatrist."
name = "psychiatrist's jumpsuit"
icon = 'icons/clothing/jumpsuits/jumpsuit_psych.dmi'
diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm
index 06d78421b29e..e20814e2ec38 100644
--- a/code/modules/clothing/masks/breath.dm
+++ b/code/modules/clothing/masks/breath.dm
@@ -22,12 +22,12 @@
permeability_coefficient = 0.01
/obj/item/clothing/mask/breath/emergency
- desc = "A close-fitting mask that is used by the wallmounted emergency oxygen pump."
+ desc = "A close-fitting mask that is used by the wall-mounted emergency oxygen pump."
name = "emergency mask"
permeability_coefficient = 0.50
/obj/item/clothing/mask/breath/scba
- desc = "A close-fitting self contained breathing apparatus mask. Can be connected to an air supply."
+ desc = "A close-fitting self-contained breathing apparatus mask. Can be connected to an air supply."
name = "\improper SCBA mask"
icon = 'icons/clothing/mask/breath_scuba.dmi'
item_flags = ITEM_FLAG_AIRTIGHT|ITEM_FLAG_FLEXIBLEMATERIAL
diff --git a/code/modules/clothing/masks/chewable.dm b/code/modules/clothing/masks/chewable.dm
index 84d490148fb9..682c68bc51fd 100644
--- a/code/modules/clothing/masks/chewable.dm
+++ b/code/modules/clothing/masks/chewable.dm
@@ -1,6 +1,6 @@
/obj/item/clothing/mask/chewable
+ abstract_type = /obj/item/clothing/mask/chewable
name = "chewable item master"
- desc = "You're not sure what this is. You should probably ahelp it."
icon = 'icons/clothing/mask/chewables/lollipop.dmi'
body_parts_covered = 0
bodytype_equip_flags = null
@@ -55,7 +55,7 @@
/obj/item/clothing/mask/chewable/tobacco
name = "wad"
- desc = "A chewy wad of tobacco. Cut in long strands and treated with syrups so it doesn't taste like a ash-tray when you stuff it into your face."
+ desc = "A chewy wad of tobacco. Cut in long strands and treated with syrups so it doesn't taste like an ashtray when you stuff it into your face."
throw_speed = 0.5
icon = 'icons/clothing/mask/chewables/chew.dmi'
type_butt = /obj/item/trash/cigbutt/spitwad
@@ -89,14 +89,14 @@
/obj/item/clothing/mask/chewable/tobacco/lenni
name = "chewing tobacco"
- desc = "A chewy wad of tobacco. Cut in long strands and treated with syrups so it tastes less like a ash-tray when you stuff it into your face."
+ desc = "A chewy wad of tobacco. Cut in long strands and treated with syrups so it tastes less like an ashtray when you stuff it into your face."
/obj/item/clothing/mask/chewable/tobacco/lenni/populate_reagents()
add_to_reagents(/decl/material/solid/tobacco, 2)
/obj/item/clothing/mask/chewable/tobacco/redlady
name = "chewing tobacco"
- desc = "A chewy wad of fine tobacco. Cut in long strands and treated with syrups so it doesn't taste like a ash-tray when you stuff it into your face"
+ desc = "A chewy wad of fine tobacco. Cut in long strands and treated with syrups so it doesn't taste like an ashtray when you stuff it into your face"
/obj/item/clothing/mask/chewable/tobacco/redlady/populate_reagents()
add_to_reagents(/decl/material/solid/tobacco/fine, 2)
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index 7ceb955904cb..afabff1f337f 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -146,7 +146,7 @@
/obj/item/clothing/mask/rubber/barros
name = "Amaya Barros mask"
- desc = "Current Secretary-General of Sol Cental Government. Not that the real thing would visit this pigsty."
+ desc = "Current Secretary-General of Sol Central Government. Not that the real thing would visit this pigsty."
icon = 'icons/clothing/mask/barros.dmi'
visible_name = "Amaya Barros"
diff --git a/code/modules/clothing/masks/smokable.dm b/code/modules/clothing/masks/smokable.dm
index 675783b875e1..4aa4fd8cb5ef 100644
--- a/code/modules/clothing/masks/smokable.dm
+++ b/code/modules/clothing/masks/smokable.dm
@@ -1,6 +1,6 @@
/obj/item/clothing/mask/smokable
+ abstract_type = /obj/item/clothing/mask/smokable
name = "smokable item"
- desc = "You're not sure what this is. You should probably ahelp it."
icon = 'icons/clothing/mask/smokables/cigarette.dmi'
body_parts_covered = 0
bodytype_equip_flags = null
@@ -492,7 +492,7 @@
/////////////////
/obj/item/clothing/mask/smokable/pipe
name = "smoking pipe"
- desc = "A pipe, for smoking. Probably made of meershaum or something."
+ desc = "A pipe, for smoking. Probably made of meerschaum or something."
icon = 'icons/clothing/mask/smokables/pipe.dmi'
w_class = ITEM_SIZE_TINY
smoketime = 0
diff --git a/code/modules/clothing/neck/ties.dm b/code/modules/clothing/neck/ties.dm
index 2d25065164bb..faada300effc 100644
--- a/code/modules/clothing/neck/ties.dm
+++ b/code/modules/clothing/neck/ties.dm
@@ -34,6 +34,10 @@
name = "long yellow tie"
color = "#c4c83d"
+/obj/item/clothing/neck/tie/long/blue
+ name = "long blue tie"
+ color = "#3d62c8"
+
/obj/item/clothing/neck/tie/navy
name = "navy tie"
color = "#182e44"
diff --git a/code/modules/clothing/pants/detective.dm b/code/modules/clothing/pants/detective.dm
index 13d85c27507e..5fa9349d8f6d 100644
--- a/code/modules/clothing/pants/detective.dm
+++ b/code/modules/clothing/pants/detective.dm
@@ -16,3 +16,10 @@
/obj/item/clothing/neck/tie/long/red,
/obj/item/clothing/suit/jacket/vest/black
)
+
+/obj/item/clothing/pants/slacks/outfit/detective_grey
+ starting_accessories = list(
+ /obj/item/clothing/shirt/button,
+ /obj/item/clothing/neck/tie/long/blue,
+ /obj/item/clothing/suit/jacket/vest/gray
+ )
diff --git a/code/modules/clothing/pants/misc.dm b/code/modules/clothing/pants/misc.dm
index 766522826607..9fa43b93a094 100644
--- a/code/modules/clothing/pants/misc.dm
+++ b/code/modules/clothing/pants/misc.dm
@@ -1,6 +1,6 @@
/obj/item/clothing/pants/fire_overpants
name = "fire overpants"
- desc = "some overpants made of fire-resistant synthetic fibers. To be worn over the uniform."
+ desc = "Some overpants made of fire-resistant synthetic fibers, worn over one's uniform."
icon = 'icons/clothing/pants/overpants.dmi'
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50
diff --git a/code/modules/clothing/shirts/sweaters.dm b/code/modules/clothing/shirts/sweaters.dm
index 1e19f372e890..5065789b2ed0 100644
--- a/code/modules/clothing/shirts/sweaters.dm
+++ b/code/modules/clothing/shirts/sweaters.dm
@@ -4,6 +4,6 @@
icon = 'icons/clothing/shirts/uniform_turtleneck.dmi'
/obj/item/clothing/shirt/sweater/turquoise
- name = "turqouise turtleneck"
- desc = "A turqouise sweater and a pair of dark blue slacks."
+ name = "turquoise turtleneck"
+ desc = "A turquoise sweater and a pair of dark blue slacks."
icon = 'icons/clothing/shirts/uniform_turtleneck_blue.dmi'
diff --git a/code/modules/clothing/shirts/syndicate.dm b/code/modules/clothing/shirts/syndicate.dm
index ab2498cc055b..a131a36a7e79 100644
--- a/code/modules/clothing/shirts/syndicate.dm
+++ b/code/modules/clothing/shirts/syndicate.dm
@@ -1,6 +1,6 @@
/obj/item/clothing/shirt/syndicate
name = "tactical turtleneck"
- desc = "It's some non-descript, slightly suspicious looking, turtleneck sweater."
+ desc = "It's some nondescript, slightly suspicious looking, turtleneck sweater."
icon = 'icons/clothing/shirts/sweater_tactical.dmi'
armor = list(
ARMOR_MELEE = ARMOR_MELEE_SMALL,
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index cbf5a0a004e7..2ca4054eebf9 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -1,4 +1,3 @@
-//Note that despite the use of the NOSLIP flag, magboots are still hardcoded to prevent spaceslipping in Check_Shoegrip().
/obj/item/clothing/shoes/magboots
name = "magboots"
desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle. They're large enough to be worn over other footwear."
@@ -31,12 +30,14 @@
/obj/item/clothing/shoes/magboots/attack_self(mob/user)
if(magpulse)
item_flags &= ~ITEM_FLAG_NOSLIP
+ item_flags &= ~ITEM_FLAG_MAGNETISED
magpulse = 0
set_slowdown()
set_base_attack_force(3)
to_chat(user, "You disable the mag-pulse traction system.")
else
item_flags |= ITEM_FLAG_NOSLIP
+ item_flags |= ITEM_FLAG_MAGNETISED
magpulse = 1
set_slowdown()
set_base_attack_force(5)
@@ -115,6 +116,6 @@
/obj/item/clothing/shoes/magboots/examine(mob/user)
. = ..()
var/state = "disabled"
- if(item_flags & ITEM_FLAG_NOSLIP)
+ if(item_flags & ITEM_FLAG_MAGNETISED)
state = "enabled"
to_chat(user, "Its mag-pulse traction system appears to be [state].")
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 53579e0dd79a..a2d298807ddb 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -153,7 +153,7 @@
/obj/item/clothing/shoes/athletic
name = "athletic shoes"
- desc = "A pair of sleek atheletic shoes. Made by and for the sporty types."
+ desc = "A pair of sleek athletic shoes. Made by and for the sporty types."
icon = 'icons/clothing/feet/sports.dmi'
/obj/item/clothing/shoes/dress/sneakies
diff --git a/code/modules/clothing/skirts/job.dm b/code/modules/clothing/skirts/job.dm
index 11cbba468ba5..2f4dd7a17c0b 100644
--- a/code/modules/clothing/skirts/job.dm
+++ b/code/modules/clothing/skirts/job.dm
@@ -1,6 +1,6 @@
/obj/item/clothing/skirt/research_director
name = "chief science officer dress uniform"
- desc = "Feminine fashion for the style concious CSO. Its fabric provides minor protection from biological contaminants."
+ desc = "Feminine fashion for the style-conscious CSO. Its fabric provides minor protection from biological contaminants."
icon = 'icons/clothing/dresses/dress_rd.dmi'
armor = list(
ARMOR_BIO = ARMOR_BIO_MINOR
diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm
index e37955054baa..75ba84eb56bc 100644
--- a/code/modules/clothing/spacesuits/miscellaneous.dm
+++ b/code/modules/clothing/spacesuits/miscellaneous.dm
@@ -1,7 +1,7 @@
//Orange emergency space suit
/obj/item/clothing/head/helmet/space/emergency
name = "emergency space helmet"
- desc = "A simple helmet with a built in light, smells like mothballs."
+ desc = "A simple helmet with a built-in light, smells like mothballs."
flash_protection = FLASH_PROTECTION_NONE
/obj/item/clothing/suit/space/emergency
diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm
index f6a35661567b..6ba6b837d81c 100644
--- a/code/modules/clothing/spacesuits/rig/modules/combat.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm
@@ -200,7 +200,7 @@
/obj/item/rig_module/mounted
name = "mounted gun"
- desc = "Somesort of mounted gun."
+ desc = "Some sort of mounted gun."
selectable = 1
usable = 1
module_cooldown = 0
diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm
index c263a126afda..5536a7500307 100644
--- a/code/modules/clothing/spacesuits/rig/modules/computer.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm
@@ -104,7 +104,7 @@
if(!card)
card = new /obj/item/aicard(src)
- // Terminal interaction only works with an inteliCarded AI.
+ // Terminal interaction only works with an intelliCarded AI.
if(!istype(card))
return 0
@@ -328,7 +328,7 @@
/obj/item/rig_module/power_sink
name = "hardsuit power sink"
- desc = "An heavy-duty power sink."
+ desc = "A heavy-duty power sink."
icon_state = "powersink"
toggleable = 1
activates_on_touch = 1
diff --git a/code/modules/clothing/spacesuits/rig/modules/modules.dm b/code/modules/clothing/spacesuits/rig/modules/modules.dm
index 893ec665f882..a616b18c7574 100644
--- a/code/modules/clothing/spacesuits/rig/modules/modules.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/modules.dm
@@ -10,7 +10,7 @@
/obj/item/rig_module
name = "hardsuit upgrade"
- desc = "It looks pretty sciency."
+ desc = "It looks pretty science-y."
icon = 'icons/obj/rig_modules.dmi'
icon_state = "module"
material = /decl/material/solid/metal/steel
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index f9f4f356c2bb..719db3034b77 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -183,7 +183,7 @@
set_extension(piece, armor_type, armor, armor_degradation_speed)
set_slowdown_and_vision(!offline)
- update_icon(1)
+ update_icon()
/obj/item/rig/Destroy()
QDEL_NULL(gloves)
@@ -232,7 +232,7 @@
piece.max_pressure_protection = initial(piece.max_pressure_protection)
piece.min_pressure_protection = initial(piece.min_pressure_protection)
piece.item_flags &= ~ITEM_FLAG_AIRTIGHT
- update_icon(1)
+ update_icon()
/obj/item/rig/proc/toggle_seals(var/mob/initiator,var/instant)
@@ -346,7 +346,7 @@
canremove = !seal_target
if(airtight)
update_component_sealed()
- update_icon(1)
+ update_icon()
return 0
// Success!
@@ -363,7 +363,7 @@
module.deactivate()
if(airtight)
update_component_sealed()
- update_icon(1)
+ update_icon()
/obj/item/rig/proc/update_component_sealed()
@@ -386,7 +386,7 @@
helmet.flags_inv &= ~(HIDEMASK)
else
helmet.flags_inv |= HIDEMASK
- update_icon(1)
+ update_icon()
/obj/item/rig/Process()
@@ -444,7 +444,7 @@
return 1
return 0
-/obj/item/rig/proc/check_power_cost(var/mob/living/user, var/cost, var/use_unconcious, var/obj/item/rig_module/mod, var/user_is_ai)
+/obj/item/rig/proc/check_power_cost(var/mob/living/user, var/cost, var/use_unconscious, var/obj/item/rig_module/mod, var/user_is_ai)
if(!istype(user))
return 0
@@ -457,7 +457,7 @@
fail_msg = "You must be wearing \the [src] to do this."
if(sealing)
fail_msg = "The hardsuit is in the process of adjusting seals and cannot be activated."
- else if(!fail_msg && ((use_unconcious && user.stat > 1) || (!use_unconcious && user.stat)))
+ else if(!fail_msg && ((use_unconscious && user.stat > 1) || (!use_unconscious && user.stat)))
fail_msg = "You are in no fit state to do that."
else if(!cell)
fail_msg = "There is no cell installed in the suit."
diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces.dm b/code/modules/clothing/spacesuits/rig/rig_pieces.dm
index a5a4899da019..82834970b6d5 100644
--- a/code/modules/clothing/spacesuits/rig/rig_pieces.dm
+++ b/code/modules/clothing/spacesuits/rig/rig_pieces.dm
@@ -23,10 +23,11 @@
light_wedge = LIGHT_WIDE
bodytype_equip_flags = null
-/obj/item/clothing/head/helmet/space/rig/on_update_icon(mob/user)
+/obj/item/clothing/head/helmet/space/rig/on_update_icon()
. = ..()
icon_state = get_world_inventory_state()
- if(user?.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon))
+ var/mob/mob_loc = loc
+ if(istype(mob_loc) && mob_loc.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon))
icon_state = "[icon_state]-sealed"
/obj/item/clothing/head/helmet/space/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE)
@@ -43,10 +44,11 @@
bodytype_equip_flags = null
gender = PLURAL
-/obj/item/clothing/gloves/rig/on_update_icon(mob/user)
+/obj/item/clothing/gloves/rig/on_update_icon()
. = ..()
icon_state = get_world_inventory_state()
- if(user?.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon))
+ var/mob/mob_loc = loc
+ if(istype(mob_loc) && mob_loc.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon))
icon_state = "[icon_state]-sealed"
/obj/item/clothing/gloves/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE)
@@ -63,10 +65,11 @@
bodytype_equip_flags = null
gender = PLURAL
-/obj/item/clothing/shoes/magboots/rig/on_update_icon(mob/user)
+/obj/item/clothing/shoes/magboots/rig/on_update_icon()
. = ..()
icon_state = get_world_inventory_state()
- if(user?.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon))
+ var/mob/mob_loc = loc
+ if(istype(mob_loc) && mob_loc.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon))
icon_state = "[icon_state]-sealed"
/obj/item/clothing/shoes/magboots/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE)
@@ -89,10 +92,11 @@
can_breach = 1
var/list/supporting_limbs = list() //If not-null, automatically splints breaks. Checked when removing the suit.
-/obj/item/clothing/suit/space/rig/on_update_icon(mob/user)
+/obj/item/clothing/suit/space/rig/on_update_icon()
. = ..()
icon_state = get_world_inventory_state()
- if(user?.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon))
+ var/mob/mob_loc = loc
+ if(istype(mob_loc) && mob_loc.check_rig_status() && check_state_in_icon("[icon_state]-sealed", icon))
icon_state = "[icon_state]-sealed"
/obj/item/clothing/suit/space/rig/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing = TRUE)
diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm
index 61612dc84e6a..d36aa54c14dc 100644
--- a/code/modules/clothing/spacesuits/rig/suits/light.dm
+++ b/code/modules/clothing/spacesuits/rig/suits/light.dm
@@ -47,7 +47,7 @@
icon = 'icons/clothing/rigs/rig_hacker.dmi'
req_access = list(access_hacked)
airtight = 0
- seal_delay = 5 //not being vaccum-proof has an upside I guess
+ seal_delay = 5 //not being vacuum-proof has an upside I guess
helmet = /obj/item/clothing/head/lightrig/hacker
chest = /obj/item/clothing/suit/lightrig/hacker
@@ -74,7 +74,7 @@
icon = 'icons/clothing/rigs/chests/chest_hacker.dmi'
/obj/item/clothing/shoes/lightrig/hacker
siemens_coefficient = 0.2
- item_flags = ITEM_FLAG_NOSLIP //All the other rigs have magboots anyways, hopefully gives the hacker suit something more going for it.
+ item_flags = ITEM_FLAG_NOSLIP | ITEM_FLAG_MAGNETISED //All the other rigs have magboots anyways, hopefully gives the hacker suit something more going for it.
icon = 'icons/clothing/rigs/boots/boots_hacker.dmi'
/obj/item/clothing/gloves/lightrig/hacker
siemens_coefficient = 0
diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm
index 4d6c335a8c02..fe48b0e24b0d 100644
--- a/code/modules/clothing/spacesuits/rig/suits/station.dm
+++ b/code/modules/clothing/spacesuits/rig/suits/station.dm
@@ -389,7 +389,7 @@
/obj/item/clothing/head/helmet/space/rig/zero
camera = null
- desc = "A bubble helmet that maximizes the field of view. A state of the art holographic display provides a stream of information"
+ desc = "A bubble helmet that maximizes the field of view. A state-of-the-art holographic display provides a stream of information"
icon = 'icons/clothing/rigs/helmets/helmet_null.dmi'
/obj/item/clothing/suit/space/rig/zero
diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm
index 896bd3db2416..3c7ecb38b48b 100644
--- a/code/modules/clothing/spacesuits/spacesuits.dm
+++ b/code/modules/clothing/spacesuits/spacesuits.dm
@@ -103,7 +103,7 @@
overlay.icon_state = "[overlay.icon_state]_dark"
. = ..()
-/obj/item/clothing/head/helmet/space/on_update_icon(mob/user)
+/obj/item/clothing/head/helmet/space/on_update_icon()
. = ..()
var/base_icon_state = get_world_inventory_state()
if(!base_icon_state)
diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm
index f420dc44078a..74a7ace494e3 100644
--- a/code/modules/clothing/spacesuits/void/station.dm
+++ b/code/modules/clothing/spacesuits/void/station.dm
@@ -323,7 +323,7 @@
//Atmospherics
/obj/item/clothing/head/helmet/space/void/atmos/alt
- name = "heavy duty atmospherics voidsuit helmet"
+ name = "heavy-duty atmospherics voidsuit helmet"
desc = "A voidsuit helmet plated with an expensive heat and radiation resistant ceramic."
icon = 'icons/clothing/spacesuit/void/atmos_alt/helmet.dmi'
armor = list(
@@ -336,7 +336,7 @@
)
/obj/item/clothing/suit/space/void/atmos/alt
- name = "heavy duty atmos voidsuit"
+ name = "heavy-duty atmos voidsuit"
desc = "An expensive voidsuit, rated to withstand extreme heat and even minor radiation without exceeding room temperature within."
icon = 'icons/clothing/spacesuit/void/atmos_alt/suit.dmi'
armor = list(
@@ -388,9 +388,9 @@
//Pilot
/obj/item/clothing/head/helmet/space/void/expedition
- desc = "An atmos resistant helmet for space and planet exploration."
- name = "pilot voidsuit helmet"
- icon = 'icons/clothing/spacesuit/void/pilot/helmet.dmi'
+ desc = "An atmos-resistant helmet for space and planet exploration."
+ name = "expedition voidsuit helmet"
+ icon = 'icons/clothing/spacesuit/void/expedition/helmet.dmi'
armor = list(
ARMOR_MELEE = ARMOR_MELEE_KNIVES,
ARMOR_BULLET = ARMOR_BALLISTIC_MINOR,
@@ -400,9 +400,9 @@
)
/obj/item/clothing/suit/space/void/expedition
- desc = "An atmos resistant voidsuit for space and planet exploration."
- name = "pilot voidsuit"
- icon = 'icons/clothing/spacesuit/void/pilot/suit.dmi'
+ desc = "An atmos-resistant voidsuit for space and planet exploration."
+ name = "expedition voidsuit"
+ icon = 'icons/clothing/spacesuit/void/expedition/suit.dmi'
armor = list(
ARMOR_MELEE = ARMOR_MELEE_KNIVES,
ARMOR_BULLET = ARMOR_BALLISTIC_MINOR,
diff --git a/code/modules/clothing/spacesuits/void/void.dm b/code/modules/clothing/spacesuits/void/void.dm
index 7f2d8ecfe174..d0836d07b4cb 100644
--- a/code/modules/clothing/spacesuits/void/void.dm
+++ b/code/modules/clothing/spacesuits/void/void.dm
@@ -93,12 +93,12 @@ else if(##equipment_var) {\
if(tank && distance <= 1)
to_chat(user, "The wrist-mounted pressure gauge reads [max(round(tank.air_contents.return_pressure()),0)] kPa remaining in \the [tank].")
-/obj/item/clothing/suit/space/void/refit_for_bodytype(var/target_bodytype)
+/obj/item/clothing/suit/space/void/refit_for_bodytype(target_bodytype, skip_rename = FALSE)
..()
if(istype(helmet))
- helmet.refit_for_bodytype(target_bodytype)
+ helmet.refit_for_bodytype(target_bodytype, skip_rename)
if(istype(boots))
- boots.refit_for_bodytype(target_bodytype)
+ boots.refit_for_bodytype(target_bodytype, skip_rename)
/obj/item/clothing/suit/space/void/equipped(mob/M)
..()
diff --git a/code/modules/clothing/suits/armor/merc.dm b/code/modules/clothing/suits/armor/merc.dm
index a138ef7b732a..7d8c6ea3bf05 100644
--- a/code/modules/clothing/suits/armor/merc.dm
+++ b/code/modules/clothing/suits/armor/merc.dm
@@ -9,7 +9,7 @@
/obj/item/clothing/armor_attachment/plate/merc
name = "heavy armor plate"
- desc = "A diamond-reinforced titanium armor plate, providing state of the art protection. Attaches to a plate carrier."
+ desc = "A diamond-reinforced titanium armor plate, providing state-of-the-art protection. Attaches to a plate carrier."
icon = 'icons/clothing/accessories/armor/armor_merc.dmi'
armor = list(
ARMOR_MELEE = ARMOR_MELEE_RESISTANT,
diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm
index 4c8fba5849f8..bce77c8c0725 100644
--- a/code/modules/clothing/suits/bio.dm
+++ b/code/modules/clothing/suits/bio.dm
@@ -2,7 +2,7 @@
/obj/item/clothing/head/bio_hood
name = "bio hood"
icon = 'icons/clothing/head/biosuit/_biosuit.dmi'
- desc = "A hood that protects the head and face from biological comtaminants."
+ desc = "A hood that protects the head and face from biological contaminants."
permeability_coefficient = 0
armor = list(
ARMOR_BIO = ARMOR_BIO_SHIELDED,
diff --git a/code/modules/clothing/suits/dashiki.dm b/code/modules/clothing/suits/dashiki.dm
index c61e603a7ae9..70dafd614fa2 100644
--- a/code/modules/clothing/suits/dashiki.dm
+++ b/code/modules/clothing/suits/dashiki.dm
@@ -1,16 +1,16 @@
/obj/item/clothing/suit/dashiki
name = "black dashiki"
- desc = "An ornately embroidered pullover garmant sporting a v-shaped collar. This one is green and black."
+ desc = "An ornately embroidered pullover garment sporting a V-shaped collar. This one is green and black."
icon = 'icons/clothing/suits/dashiki/dashiki.dmi'
slot_flags = SLOT_OVER_BODY
accessory_slot = ACCESSORY_SLOT_DECOR
/obj/item/clothing/suit/dashiki/red
name = "red dashiki"
- desc = "An ornately embroidered pullover garmant sporting a v-shaped collar. This one is red."
+ desc = "An ornately embroidered pullover garment sporting a V-shaped collar. This one is red."
icon = 'icons/clothing/suits/dashiki/dashiki_red.dmi'
/obj/item/clothing/suit/dashiki/blue
name = "blue dashiki"
- desc = "An ornately embroidered pullover garmant sporting a v-shaped collar. This one is blue."
+ desc = "An ornately embroidered pullover garment sporting a V-shaped collar. This one is blue."
icon = 'icons/clothing/suits/dashiki/dashiki_blue.dmi'
diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm
index f617d8bbc165..fd5da2f0d8fd 100644
--- a/code/modules/clothing/suits/jobs.dm
+++ b/code/modules/clothing/suits/jobs.dm
@@ -21,7 +21,7 @@
/obj/item/clothing/suit/apron/colourable
desc = "A basic apron, good for protecting your clothes."
icon = 'icons/clothing/suits/apron_colourable.dmi'
- color = null
+ paint_color = null
material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC
//Captain
diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm
index 24f7d5f0a72c..764b696000de 100644
--- a/code/modules/clothing/suits/labcoat.dm
+++ b/code/modules/clothing/suits/labcoat.dm
@@ -39,7 +39,7 @@
/obj/item/clothing/suit/toggle/labcoat/mad
name = "The Mad's labcoat"
- desc = "It makes you look capable of konking someone on the noggin and shooting them into space."
+ desc = "It makes you look capable of conking someone on the noggin and shooting them into space."
color = COLOR_GREEN
/obj/item/clothing/suit/toggle/labcoat/chemist
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 900580dffe8e..25aa1a94bbdd 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -87,9 +87,10 @@
body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_FEET|SLOT_ARMS
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
+// todo: remove 40k reference?
/obj/item/clothing/suit/imperium_monk
name = "Imperium monk"
- desc = "Have YOU killed a xenos today?"
+ desc = "Have YOU killed a xeno today?"
icon = 'icons/clothing/suits/w40k.dmi'
body_parts_covered = SLOT_HEAD|SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_FEET|SLOT_ARMS
flags_inv = HIDESHOES|HIDEJUMPSUIT
diff --git a/code/modules/clothing/suits/robes.dm b/code/modules/clothing/suits/robes.dm
index eabd216c555a..c401e157ee00 100644
--- a/code/modules/clothing/suits/robes.dm
+++ b/code/modules/clothing/suits/robes.dm
@@ -7,6 +7,7 @@
body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS
material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC
slot_flags = SLOT_UPPER_BODY | SLOT_OVER_BODY
+ valid_accessory_slots = UNIFORM_DEFAULT_ACCESSORIES
accessory_slot = ACCESSORY_SLOT_DECOR
/obj/item/clothing/suit/robe/sleeved
diff --git a/code/modules/clothing/suits/wizard.dm b/code/modules/clothing/suits/wizard.dm
index c8f0208fb4d5..d302f06103f5 100644
--- a/code/modules/clothing/suits/wizard.dm
+++ b/code/modules/clothing/suits/wizard.dm
@@ -7,7 +7,7 @@
/obj/item/clothing/suit/wizrobe/red
name = "red wizard robe"
- desc = "A rather ratty red robe."
+ desc = "A rather ratty red robe."
icon = 'icons/clothing/suits/wizard/red.dmi'
/obj/item/clothing/suit/wizrobe/marisa
diff --git a/code/modules/clothing/tail/_tail.dm b/code/modules/clothing/tail/_tail.dm
new file mode 100644
index 000000000000..19c7294be60e
--- /dev/null
+++ b/code/modules/clothing/tail/_tail.dm
@@ -0,0 +1,7 @@
+// Tail accessories. Currently only used by Scavstation for tailbells and tailgloves.
+/obj/item/clothing/tail
+ abstract_type = /obj/item/clothing/tail
+ w_class = ITEM_SIZE_SMALL
+ accessory_slot = ACCESSORY_SLOT_MEDAL
+ fallback_slot = slot_w_uniform_str
+ slot_flags = SLOT_UPPER_BODY
diff --git a/code/modules/clothing/webbing/misc.dm b/code/modules/clothing/webbing/misc.dm
index 74d41a0c4913..c390a9bf2edf 100644
--- a/code/modules/clothing/webbing/misc.dm
+++ b/code/modules/clothing/webbing/misc.dm
@@ -6,7 +6,7 @@
/obj/item/clothing/webbing/bandolier
name = "bandolier"
- desc = "A lightweight synthethic bandolier with straps for holding ammunition or other small objects."
+ desc = "A lightweight synthetic bandolier with straps for holding ammunition or other small objects."
icon = 'icons/obj/items/bandolier.dmi'
storage = /datum/storage/pockets/bandolier
diff --git a/code/modules/codex/categories/category_reactions.dm b/code/modules/codex/categories/category_reactions.dm
index c46829e0dfa7..913e1469029a 100644
--- a/code/modules/codex/categories/category_reactions.dm
+++ b/code/modules/codex/categories/category_reactions.dm
@@ -19,7 +19,7 @@
/decl/codex_category/materials/chemistry/compounds
name = "Compounds"
- desc = "Chemical reactions with non-medical, mundane, interesting or spectacular effects."
+ desc = "Chemical reactions with nonmedical, mundane, interesting or spectacular effects."
guide_name = "Compounds"
reaction_category = REACTION_TYPE_COMPOUND
diff --git a/code/modules/codex/categories/category_surgery.dm b/code/modules/codex/categories/category_surgery.dm
index 7bf78fccfc73..df818b89c80d 100644
--- a/code/modules/codex/categories/category_surgery.dm
+++ b/code/modules/codex/categories/category_surgery.dm
@@ -26,7 +26,7 @@
Use a scalpel to make an incision.
Use a retractor to widen the incision, if necessary.
Use a hemostat to clamp any bleeders, if necessary.
- On bodyparts with bone encasement, like the skull and ribs, use a circular saw to open the encasing bone.
+ On body parts with bone encasement, like the skull and ribs, use a circular saw to open the encasing bone.
Closing an incision
diff --git a/code/modules/codex/entries/guides.dm b/code/modules/codex/entries/guides.dm
index 747a279d6915..7f3ec5d857f5 100644
--- a/code/modules/codex/entries/guides.dm
+++ b/code/modules/codex/entries/guides.dm
@@ -559,7 +559,7 @@
- - Mass spectrometry - MS is the procedure used used to measure and quantify the components of matter. The most prized tool in the field of
+
- Mass spectrometry - MS is the procedure used to measure and quantify the components of matter. The most prized tool in the field of
'Materials analysis.'
- Radiometric dating - MS applied using the right carrier reagents can be used to accurately determine the age of a sample.
- Dissonance ratio - This is a pseudoarbitrary value indicating the overall presence of a particular element in a greater composite.
diff --git a/code/modules/codex/entries/medical.dm b/code/modules/codex/entries/medical.dm
index 69add447b6a7..0ab7f3ca37e3 100644
--- a/code/modules/codex/entries/medical.dm
+++ b/code/modules/codex/entries/medical.dm
@@ -43,8 +43,8 @@
deprivation, irradiation, shock, and chemicals inside the occupant, at least until the bag is opened again.
\
\
Stasis bags can only be used once, and are rather costly, so use them well. They are ideal for situations where someone may die \
- before being able to bring them back to safety, or if they are in a hostile enviroment, such as in vacuum or in a toxins leak, as \
- the bag will protect the occupant from most outside enviromental hazards. If you open a bag by mistake, closing the bag with no \
+ before being able to bring them back to safety, or if they are in a hostile environment, such as in vacuum or in a toxins leak, as \
+ the bag will protect the occupant from most outside environmental hazards. If you open a bag by mistake, closing the bag with no \
occupant will not use up the bag, and you can pick it back up.
\
\
You can use a health analyzer to scan the occupant's vitals without opening the bag by clicking the occupied bag with the analyzer."
diff --git a/code/modules/crafting/forging/bellows.dm b/code/modules/crafting/forging/bellows.dm
index 3402f4c2cfa7..4a3afdfe1838 100644
--- a/code/modules/crafting/forging/bellows.dm
+++ b/code/modules/crafting/forging/bellows.dm
@@ -24,7 +24,7 @@
to_chat(user, SPAN_NOTICE("You begin working \the [src], stoking \the [stoking] to a hotter flame."))
start_working()
while(user.do_skilled(3 SECONDS, work_skill, src))
- if(QDELETED(src) || QDELETED(user) || user.get_stamina() <= 0)
+ if(QDELETED(src) || QDELETED(user) || user.get_stamina() < 25 || !user.get_empty_hand_slot())
break
stoking = locate() in get_step(loc, EAST)
if(!istype(stoking) || !stoking.lit)
diff --git a/code/modules/crafting/stack_recipes/_recipe.dm b/code/modules/crafting/stack_recipes/_recipe.dm
index 7c481de823a3..527af535c37f 100644
--- a/code/modules/crafting/stack_recipes/_recipe.dm
+++ b/code/modules/crafting/stack_recipes/_recipe.dm
@@ -342,10 +342,7 @@
else
. = jointext(list() + material_strings + name, " ")
if(apply_article)
- if(gender == PLURAL)
- . = "some [.]"
- else
- . = ADD_ARTICLE(.)
+ . = ADD_ARTICLE_GENDER(., gender)
/decl/stack_recipe/proc/req_mat_to_type(decl/material/mat, mat_req)
if(mat_req != MATERIAL_FORBIDDEN)
diff --git a/code/modules/crafting/stack_recipes/recipes_cardstock.dm b/code/modules/crafting/stack_recipes/recipes_cardstock.dm
index d15f0f027e2a..30e9e6f5e3a4 100644
--- a/code/modules/crafting/stack_recipes/recipes_cardstock.dm
+++ b/code/modules/crafting/stack_recipes/recipes_cardstock.dm
@@ -1,7 +1,7 @@
/decl/stack_recipe/cardstock
abstract_type = /decl/stack_recipe/cardstock
craft_stack_types = /obj/item/stack/material/cardstock
- available_to_map_tech_level = MAP_TECH_LEVEL_SPACE // not exactly high tech, but donuts etc are not medieval
+ available_to_map_tech_level = MAP_TECH_LEVEL_SPACE // not exactly high-tech, but donuts etc are not medieval
/decl/stack_recipe/cardstock/box
result_type = /obj/item/box
diff --git a/code/modules/crafting/stack_recipes/recipes_soft.dm b/code/modules/crafting/stack_recipes/recipes_soft.dm
index 32422a175490..27f9c6328ceb 100644
--- a/code/modules/crafting/stack_recipes/recipes_soft.dm
+++ b/code/modules/crafting/stack_recipes/recipes_soft.dm
@@ -44,6 +44,12 @@
result_type = /obj/item/stack/material/brick
test_result_type = /obj/item/stack/material/brick/clay
+/decl/stack_recipe/soft/bar
+ name = "bar"
+ name_plural = "bars"
+ result_type = /obj/item/stack/material/bar
+ test_result_type = /obj/item/stack/material/bar/wax
+
/decl/stack_recipe/soft/stack/spawn_result(mob/user, location, amount, decl/material/mat, decl/material/reinf_mat, paint_color, spent_type, spent_amount = 1)
var/obj/item/stack/S = ..()
if(istype(S))
diff --git a/code/modules/crafting/stack_recipes/recipes_textiles.dm b/code/modules/crafting/stack_recipes/recipes_textiles.dm
index 3f39d08385e6..4b49616eef76 100644
--- a/code/modules/crafting/stack_recipes/recipes_textiles.dm
+++ b/code/modules/crafting/stack_recipes/recipes_textiles.dm
@@ -157,6 +157,6 @@
available_to_map_tech_level = MAP_TECH_LEVEL_MEDIEVAL
/decl/stack_recipe/textiles/rag
- result_type = /obj/item/chems/glass/rag
+ result_type = /obj/item/chems/rag
crafting_extra_cost_factor = 1 // whatever you produce is going to be a rag, there's no wastage
difficulty = MAT_VALUE_TRIVIAL_DIY
diff --git a/code/modules/detectivework/microscope/dnascanner.dm b/code/modules/detectivework/microscope/dnascanner.dm
index 964b8c2f2e34..f49762151815 100644
--- a/code/modules/detectivework/microscope/dnascanner.dm
+++ b/code/modules/detectivework/microscope/dnascanner.dm
@@ -1,7 +1,7 @@
//DNA machine
/obj/machinery/forensic/dnascanner
name = "DNA analyzer"
- desc = "A high tech machine that is designed to read DNA samples properly."
+ desc = "A high-tech machine that is designed to read DNA samples properly."
icon = 'icons/obj/forensics.dmi'
icon_state = "dna_open"
anchored = TRUE
diff --git a/code/modules/detectivework/tools/crimekit.dm b/code/modules/detectivework/tools/crimekit.dm
index c3756e4e01a7..4dc2965ca768 100644
--- a/code/modules/detectivework/tools/crimekit.dm
+++ b/code/modules/detectivework/tools/crimekit.dm
@@ -1,7 +1,7 @@
//crime scene kit
/obj/item/briefcase/crimekit
name = "crime scene kit"
- desc = "A stainless steel-plated carrycase for all your forensic needs. Feels heavy."
+ desc = "A stainless steel-plated carrying case for all your forensic needs. Feels heavy."
icon = 'icons/obj/items/storage/crime_kit.dmi'
material = /decl/material/solid/organic/leather/synth
matter = list(/decl/material/solid/metal/stainlesssteel = MATTER_AMOUNT_REINFORCEMENT)
diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm
index 0068fd756616..3bfc7ebe8944 100644
--- a/code/modules/detectivework/tools/rag.dm
+++ b/code/modules/detectivework/tools/rag.dm
@@ -1,4 +1,4 @@
-/obj/item/chems/glass/rag
+/obj/item/chems/rag
name = "rag"
desc = "For cleaning up messes, you suppose."
w_class = ITEM_SIZE_TINY
@@ -15,20 +15,14 @@
VAR_PRIVATE/_on_fire = 0
VAR_PRIVATE/burn_time = 20 //if the rag burns for too long it turns to ashes
-/obj/item/chems/glass/rag/get_edible_material_amount(mob/eater)
+/obj/item/chems/rag/get_edible_material_amount(mob/eater)
return 0
-/obj/item/chems/glass/rag/get_utensil_food_type()
- return null
-
-/obj/item/chems/glass/rag/get_atoms_can_be_placed_into()
- return null
-
-/obj/item/chems/glass/rag/Initialize()
+/obj/item/chems/rag/Initialize()
. = ..()
update_name()
-/obj/item/chems/glass/rag/Destroy()
+/obj/item/chems/rag/Destroy()
var/obj/item/chems/drinks/bottle/bottle = loc
if(istype(bottle) && bottle.rag == src)
bottle.rag = null
@@ -36,10 +30,10 @@
STOP_PROCESSING(SSobj, src) //so we don't continue turning to ash while gc'd
. = ..()
-/obj/item/chems/glass/rag/is_on_fire()
+/obj/item/chems/rag/is_on_fire()
return _on_fire
-/obj/item/chems/glass/rag/attack_self(mob/user)
+/obj/item/chems/rag/attack_self(mob/user)
if(is_on_fire() && user.try_unequip(src))
user.visible_message(SPAN_NOTICE("\The [user] stamps out [src]."), SPAN_NOTICE("You stamp out [src]."))
extinguish_fire()
@@ -51,7 +45,7 @@
return ..()
-/obj/item/chems/glass/rag/attackby(obj/item/W, mob/user)
+/obj/item/chems/rag/attackby(obj/item/W, mob/user)
if(W.isflamesource())
if(is_on_fire())
to_chat(user, SPAN_WARNING("\The [src] is already blazing merrily!"))
@@ -65,7 +59,7 @@
return TRUE
return ..()
-/obj/item/chems/glass/rag/update_name()
+/obj/item/chems/rag/update_name()
if(is_on_fire())
name_prefix = "burning"
else if(reagents && reagents.total_volume)
@@ -74,14 +68,14 @@
name_prefix = "dry"
. = ..()
-/obj/item/chems/glass/rag/on_update_icon()
+/obj/item/chems/rag/on_update_icon()
. = ..()
icon_state = "rag[is_on_fire()? "lit" : ""]"
var/obj/item/chems/drinks/bottle/B = loc
if(istype(B))
B.update_icon()
-/obj/item/chems/glass/rag/proc/remove_contents(mob/user, atom/trans_dest = null)
+/obj/item/chems/rag/proc/remove_contents(mob/user, atom/trans_dest = null)
if(!trans_dest && !user.loc)
return
if(reagents?.total_volume <= 0)
@@ -103,7 +97,7 @@
)
update_name()
-/obj/item/chems/glass/rag/proc/wipe_down(atom/target, mob/user)
+/obj/item/chems/rag/proc/wipe_down(atom/target, mob/user)
if(!reagents?.total_volume)
to_chat(user, SPAN_WARNING("The [initial(name)] is dry."))
@@ -114,7 +108,7 @@
user.visible_message(SPAN_NOTICE("\The [user] finishes wiping off \the [target]."))
reagents.touch_atom(target)
-/obj/item/chems/glass/rag/use_on_mob(mob/living/target, mob/living/user, animate = TRUE)
+/obj/item/chems/rag/use_on_mob(mob/living/target, mob/living/user, animate = TRUE)
if(is_on_fire())
user.visible_message(
@@ -159,28 +153,23 @@
return ..()
-/obj/item/chems/glass/rag/afterattack(atom/A, mob/user, proximity)
- if(!proximity)
- return
-
- if(istype(A, /obj/structure/reagent_dispensers))
- if(!REAGENTS_FREE_SPACE(reagents))
- to_chat(user, "\The [src] is already soaked.")
- return
+/obj/item/chems/rag/afterattack(atom/target, mob/user, proximity)
+ if(!proximity || !istype(target))
+ return FALSE
- if(A.reagents && A.reagents.trans_to_obj(src, reagents.maximum_volume))
- user.visible_message("\The [user] soaks [src] using [A].", "You soak [src] using [A].")
- update_name()
- return
+ if(standard_dispenser_refill(user, target)) //Are they clicking a water tank/some dispenser?
+ update_name()
+ return TRUE
- if(!is_on_fire() && istype(A) && (src in user))
- if(ATOM_IS_OPEN_CONTAINER(A) && !isturf(A) && !(A in user))
- remove_contents(user, A)
- else if(!ismob(A)) //mobs are handled in use_on_mob() - this prevents us from wiping down people while smothering them.
- wipe_down(A, user)
- return
+ if(!is_on_fire() && (src in user))
+ if(ATOM_IS_OPEN_CONTAINER(target) && !isturf(target) && !(target in user))
+ remove_contents(user, target)
+ else if(!ismob(target)) //mobs are handled in use_on_mob() - this prevents us from wiping down people while smothering them.
+ wipe_down(target, user) // todo: test if this check is necessary, smothering returns TRUE which should prevent afterattack
+ return TRUE
+ return FALSE
-/obj/item/chems/glass/rag/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/item/chems/rag/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature >= 50 + T0C)
ignite_fire()
if(exposed_temperature >= 900 + T0C)
@@ -191,7 +180,7 @@
//rag must have a minimum of 2 units welder fuel and at least 80% of the reagents must be welder fuel.
//maybe generalize flammable reagents someday
-/obj/item/chems/glass/rag/can_ignite()
+/obj/item/chems/rag/can_ignite()
var/total_fuel = 0
var/total_volume = 0
if(reagents)
@@ -201,7 +190,7 @@
total_fuel += REAGENT_VOLUME(reagents, rtype) * R.accelerant_value
. = (total_fuel >= 2 && total_fuel >= total_volume*0.5)
-/obj/item/chems/glass/rag/ignite_fire()
+/obj/item/chems/rag/ignite_fire()
if(is_on_fire())
return
if(!can_ignite())
@@ -212,7 +201,7 @@
update_name()
update_icon()
-/obj/item/chems/glass/rag/extinguish_fire(mob/user, no_message = FALSE)
+/obj/item/chems/rag/extinguish_fire(mob/user, no_message = FALSE)
STOP_PROCESSING(SSobj, src)
set_light(0)
_on_fire = FALSE
@@ -223,10 +212,11 @@
visible_message("\The [src] falls apart!")
new /obj/effect/decal/cleanable/ash(get_turf(src))
qdel(src)
+ return
update_name()
update_icon()
-/obj/item/chems/glass/rag/Process()
+/obj/item/chems/rag/Process()
if(!can_ignite())
visible_message("\The [src] burns out.")
extinguish_fire()
diff --git a/code/modules/economy/cael/ATM.dm b/code/modules/economy/cael/ATM.dm
index 2af8810c19cb..c2e50a639305 100644
--- a/code/modules/economy/cael/ATM.dm
+++ b/code/modules/economy/cael/ATM.dm
@@ -248,28 +248,29 @@
else
return
-/obj/machinery/atm/Topic(var/href, var/href_list)
+/obj/machinery/atm/OnTopic(mob/user, href_list)
if((. = ..()))
return
if(href_list["choice"])
+ . = TOPIC_REFRESH
switch(href_list["choice"])
if("transfer")
if(authenticated_account)
var/transfer_amount = text2num(href_list["funds_amount"])
transfer_amount = round(transfer_amount, 0.01)
if(transfer_amount <= 0)
- alert("That is not a valid amount.")
+ alert(user, "That is not a valid amount.")
else if(transfer_amount <= authenticated_account.money)
var/target_account_number = text2num(href_list["target_acc_number"])
var/transfer_purpose = href_list["purpose"]
var/datum/money_account/target_account = get_account(target_account_number)
if(target_account && authenticated_account.transfer(target_account, transfer_amount, transfer_purpose))
- to_chat(usr, "[html_icon(src)]Funds transfer successful.")
+ to_chat(user, "[html_icon(src)]Funds transfer successful.")
else
- to_chat(usr, "[html_icon(src)]Funds transfer failed.")
+ to_chat(user, "[html_icon(src)]Funds transfer failed.")
else
- to_chat(usr, "[html_icon(src)]You don't have enough funds to do that!")
+ to_chat(user, "[html_icon(src)]You don't have enough funds to do that!")
if("view_screen")
view_screen = text2num(href_list["view_screen"])
if("change_security_level")
@@ -283,7 +284,7 @@
if(held_card)
login_card = held_card
else
- login_card = scan_user(usr)
+ login_card = scan_user(user)
if(!ticks_left_locked_down)
var/tried_account_num = text2num(href_list["account_num"])
@@ -317,11 +318,11 @@
if(failed_account)
failed_account.log_msg("Unauthorized login attempt", machine_id)
else
- to_chat(usr, "[html_icon(src)] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining.")
+ to_chat(user, "[html_icon(src)] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining.")
previous_account_number = tried_account_num
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 1)
else
- to_chat(usr, "[html_icon(src)] Unable to log in to account, additional information may be required.")
+ to_chat(user, "[html_icon(src)] Unable to log in to account, additional information may be required.")
number_incorrect_tries = 0
else
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
@@ -331,7 +332,7 @@
//create a transaction log entry
authenticated_account.log_msg("Remote terminal access", machine_id)
- to_chat(usr, "[html_icon(src)] Access granted. Welcome user '[authenticated_account.owner_name].'")
+ to_chat(user, "[html_icon(src)] Access granted. Welcome user '[authenticated_account.owner_name].'")
previous_account_number = tried_account_num
if("e_withdrawal")
@@ -339,10 +340,10 @@
amount = round(amount, 0.01)
var/obj/item/charge_stick/E = charge_stick_type
if(amount <= 0)
- alert("That is not a valid amount.")
+ alert(user, "That is not a valid amount.")
else if(amount > initial(E.max_worth))
var/decl/currency/cur = GET_DECL(initial(E.currency) || global.using_map.default_currency)
- alert("That amount exceeds the maximum amount holdable by charge sticks from this machine ([cur.format_value(initial(E.max_worth))]).")
+ alert(user, "That amount exceeds the maximum amount holdable by charge sticks from this machine ([cur.format_value(initial(E.max_worth))]).")
else if(authenticated_account && amount > 0)
//create an entry in the account transaction log
if(authenticated_account.withdraw(amount, "Credit withdrawal", machine_id))
@@ -350,27 +351,26 @@
E = new charge_stick_type(loc)
E.adjust_worth(amount)
E.creator = authenticated_account.owner_name
- usr.put_in_hands(E)
+ user.put_in_hands(E)
else
- to_chat(usr, "[html_icon(src)]You don't have enough funds to do that!")
+ to_chat(user, "[html_icon(src)]You don't have enough funds to do that!")
if("withdrawal")
var/amount = max(text2num(href_list["funds_amount"]),0)
amount = round(amount, 0.01)
if(amount <= 0)
- alert("That is not a valid amount.")
+ alert(user, "That is not a valid amount.")
else if(authenticated_account && amount > 0)
//remove the money
- // TODO: Jesus Christ why does this entire proc use usr
if(authenticated_account.withdraw(amount, "Credit withdrawal", machine_id))
playsound(src, 'sound/machines/chime.ogg', 50, 1)
- var/cash_turf = get_turf(usr)
+ var/cash_turf = get_turf(user)
var/obj/item/cash/cash = new(cash_turf, null, amount)
if(QDELETED(cash))
cash = locate() in cash_turf
if(cash)
- usr.put_in_hands(cash)
+ user.put_in_hands(cash)
else
- to_chat(usr, "[html_icon(src)]You don't have enough funds to do that!")
+ to_chat(user, "[html_icon(src)]You don't have enough funds to do that!")
if("balance_statement")
if(authenticated_account)
var/txt
@@ -428,20 +428,20 @@
if(!held_card)
//this might happen if the user had the browser window open when somebody emagged it
if(emagged > 0)
- to_chat(usr, "[html_icon(src)] The ATM card reader rejected your ID because this machine has been sabotaged!")
+ to_chat(user, "[html_icon(src)] The ATM card reader rejected your ID because this machine has been sabotaged!")
else
- var/obj/item/I = usr.get_active_held_item()
+ var/obj/item/I = user.get_active_held_item()
if (istype(I, /obj/item/card/id))
- if(!usr.try_unequip(I, src))
+ if(!user.try_unequip(I, src))
return
held_card = I
else
- release_held_id(usr)
+ release_held_id(user)
if("logout")
authenticated_account = null
account_security_level = 0
-
- interact(usr)
+ else
+ . = TOPIC_NOACTION // Unhandled, href hack or just a subtype's command?
/obj/machinery/atm/proc/scan_user(mob/living/human/human_user)
if(!authenticated_account)
diff --git a/code/modules/economy/cael/Accounts_DB.dm b/code/modules/economy/cael/Accounts_DB.dm
index 2fa3a9c13d8c..8d8b7f4c8a5b 100644
--- a/code/modules/economy/cael/Accounts_DB.dm
+++ b/code/modules/economy/cael/Accounts_DB.dm
@@ -85,13 +85,12 @@
ui.set_initial_data(data)
ui.open()
-/obj/machinery/computer/account_database/Topic(href, href_list)
- if(..())
- return 1
-
- var/datum/nanoui/ui = SSnano.get_open_ui(usr, src, "main")
+/obj/machinery/computer/account_database/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["choice"])
+ . = TOPIC_REFRESH
switch(href_list["choice"])
if("create_account")
creating_new_account = 1
@@ -117,24 +116,22 @@
new_account.deposit(starting_funds, "New account activation", machine_id)
creating_new_account = 0
- ui.close()
+ . = TOPIC_CLOSE
creating_new_account = 0
if("insert_card")
if(held_card)
held_card.dropInto(loc)
- if(ishuman(usr) && !usr.get_active_held_item())
- usr.put_in_hands(held_card)
+ if(ishuman(user) && !user.get_active_held_item())
+ user.put_in_hands(held_card)
held_card = null
- SSnano.update_uis(src)
else
- var/obj/item/I = usr.get_active_held_item()
+ var/obj/item/I = user.get_active_held_item()
if (istype(I, /obj/item/card/id))
- if(!usr.try_unequip(I, src))
+ if(!user.try_unequip(I, src))
return
held_card = I
- SSnano.update_uis(src)
if("view_account_detail")
var/index = text2num(href_list["account_index"])
@@ -227,6 +224,6 @@
"}
P.info = text
- state("The terminal prints out a report.")
-
- return 1
+ visible_message(SPAN_NOTICE("[html_icon(src)] \The [src] prints out \the [P]."))
+ else
+ . = TOPIC_NOACTION
diff --git a/code/modules/economy/worth_items.dm b/code/modules/economy/worth_items.dm
index ce2d11ae8be7..3c754456b70e 100644
--- a/code/modules/economy/worth_items.dm
+++ b/code/modules/economy/worth_items.dm
@@ -60,7 +60,7 @@
additional_value += (25 * total_coverage)
if(item_flags)
- for(var/flag in list(ITEM_FLAG_PADDED, ITEM_FLAG_NOSLIP, ITEM_FLAG_BLOCK_GAS_SMOKE_EFFECT, ITEM_FLAG_SILENT, ITEM_FLAG_NOCUFFS))
+ for(var/flag in list(ITEM_FLAG_PADDED, ITEM_FLAG_NOSLIP, ITEM_FLAG_MAGNETISED, ITEM_FLAG_BLOCK_GAS_SMOKE_EFFECT, ITEM_FLAG_SILENT, ITEM_FLAG_NOCUFFS))
if(item_flags & flag)
additional_value += 15
diff --git a/code/modules/events/meteors.dm b/code/modules/events/meteors.dm
index 739666996062..521a4bbb2f2c 100644
--- a/code/modules/events/meteors.dm
+++ b/code/modules/events/meteors.dm
@@ -431,7 +431,7 @@ var/global/list/meteors_major = list(
//Missiles, for events and so on
/obj/effect/meteor/destroyer/missile
name = "photon torpedo"
- desc = "An advanded warhead designed to tactically destroy space installations."
+ desc = "An advanced warhead designed to tactically destroy space installations."
icon = 'icons/obj/missile.dmi'
icon_state = "photon"
meteordrop = null
diff --git a/code/modules/events/money_lotto.dm b/code/modules/events/money_lotto.dm
index 0cd4a07d1fbb..7760e51327f6 100644
--- a/code/modules/events/money_lotto.dm
+++ b/code/modules/events/money_lotto.dm
@@ -20,7 +20,7 @@
var/channel = "Nyx Daily"
var/decl/currency/cur = GET_DECL(winner_account?.currency || global.using_map.default_currency)
- var/body = "Nyx Daily wishes to congratulate [winner_name] for recieving the Nyx Stellar Slam Lottery, and receiving the out of this world sum of [cur.format_value(winner_sum)]!"
+ var/body = "Nyx Daily wishes to congratulate [winner_name] for receiving the Nyx Stellar Slam Lottery, and receiving the out of this world sum of [cur.format_value(winner_sum)]!"
if(!deposit_success)
body += "
Unfortunately, we were unable to verify the account details provided, so we were unable to transfer the money. In order to have your winnings re-sent, send a cheque containing a processing fee of [cur.format_value(5000)] to the ND 'Stellar Slam' office on the Nyx gateway with your updated details."
winner_account = null
diff --git a/code/modules/fabrication/_fabricator.dm b/code/modules/fabrication/_fabricator.dm
index b7c4f920ca22..43ae48853311 100644
--- a/code/modules/fabrication/_fabricator.dm
+++ b/code/modules/fabrication/_fabricator.dm
@@ -1,6 +1,6 @@
/obj/machinery/fabricator
name = "autolathe"
- desc = "It produces common day to day items from a variety of materials."
+ desc = "It produces common day-to-day items from a variety of materials."
icon = 'icons/obj/machines/fabricators/autolathe.dmi'
icon_state = "autolathe"
density = TRUE
diff --git a/code/modules/fabrication/designs/general/designs_general.dm b/code/modules/fabrication/designs/general/designs_general.dm
index fda6ce15bad0..4e09933a75e8 100644
--- a/code/modules/fabrication/designs/general/designs_general.dm
+++ b/code/modules/fabrication/designs/general/designs_general.dm
@@ -244,5 +244,5 @@
/datum/fabricator_recipe/chipboard/yew/get_resources()
resources = list(
/decl/material/solid/organic/wood/yew = ceil((SHEET_MATERIAL_AMOUNT * FABRICATOR_EXTRA_COST_FACTOR)/2),
- /decl/material/solid/organic/plastic = ceil((SHEET_MATERIAL_AMOUNT * FABRICATOR_EXTRA_COST_FACTOR)/2)
+ /decl/material/solid/organic/plastic = ceil((SHEET_MATERIAL_AMOUNT * FABRICATOR_EXTRA_COST_FACTOR)/2)
)
diff --git a/code/modules/fabrication/designs/industrial/designs_exosuit_components.dm b/code/modules/fabrication/designs/industrial/designs_exosuit_components.dm
index f2cb06e60801..af7684561604 100644
--- a/code/modules/fabrication/designs/industrial/designs_exosuit_components.dm
+++ b/code/modules/fabrication/designs/industrial/designs_exosuit_components.dm
@@ -102,6 +102,9 @@
/datum/fabricator_recipe/industrial/exosuit_gear/drill
path = /obj/item/mech_equipment/drill
+/datum/fabricator_recipe/industrial/exosuit_gear/ionjets
+ path = /obj/item/mech_equipment/ionjets
+
/datum/fabricator_recipe/industrial/exosuit_gear/mounted
path = /obj/item/mech_equipment/mounted_system/taser
diff --git a/code/modules/fabrication/designs/pipe/device_pipe_datums.dm b/code/modules/fabrication/designs/pipe/device_pipe_datums.dm
index 829699096898..87d1753cbe2f 100644
--- a/code/modules/fabrication/designs/pipe/device_pipe_datums.dm
+++ b/code/modules/fabrication/designs/pipe/device_pipe_datums.dm
@@ -4,7 +4,6 @@
pipe_color = PIPE_COLOR_WHITE
name = "connector"
- desc = "a connector for canisters."
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_FUEL
build_icon_state = "connector"
constructed_path = /obj/machinery/atmospherics/portables_connector
@@ -13,7 +12,6 @@
/datum/fabricator_recipe/pipe/device/adapter
name = "universal pipe adapter"
- desc = "an adapter designed to fit any type of pipe."
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER|CONNECT_TYPE_FUEL|CONNECT_TYPE_HE
build_icon_state = "universal"
constructed_path = /obj/machinery/atmospherics/pipe/simple/hidden/universal
@@ -22,7 +20,6 @@
/datum/fabricator_recipe/pipe/device/unaryvent
name = "unary vent"
- desc = "a unary vent"
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_FUEL
build_icon_state = "uvent"
constructed_path = /obj/machinery/atmospherics/unary/vent_pump
@@ -30,12 +27,10 @@
/datum/fabricator_recipe/pipe/device/unaryvent/large
name = "high volume unary vent"
- desc = "a high volume unary vent"
constructed_path = /obj/machinery/atmospherics/unary/vent_pump/high_volume
/datum/fabricator_recipe/pipe/device/gaspump
name = "gas pump"
- desc = "a pump. For gasses."
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_FUEL
build_icon_state = "pump"
constructed_path = /obj/machinery/atmospherics/binary/pump
@@ -43,7 +38,6 @@
/datum/fabricator_recipe/pipe/device/pressureregulator
name = "pressure regulator"
- desc = "a device that regulates pressure."
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_FUEL
build_icon_state = "passivegate"
constructed_path = /obj/machinery/atmospherics/binary/passive_gate
@@ -51,7 +45,6 @@
/datum/fabricator_recipe/pipe/device/hpgaspump
name = "high powered gas pump"
- desc = "a high powered pump. For gasses."
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_FUEL
build_icon_state = "volumepump"
constructed_path = /obj/machinery/atmospherics/binary/pump/high_power
@@ -59,7 +52,6 @@
/datum/fabricator_recipe/pipe/device/scrubber
name = "scrubber"
- desc = "scrubs out undesirable gasses"
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SCRUBBER
build_icon_state = "scrubber"
constructed_path = /obj/machinery/atmospherics/unary/vent_scrubber
@@ -67,7 +59,6 @@
/datum/fabricator_recipe/pipe/device/meter
name = "meter"
- desc = "a meter that monitors pressure and temperature on the attached pipe."
path = /obj/item/machine_chassis/pipe_meter
pipe_color = null
connect_types = null
@@ -78,7 +69,6 @@
/datum/fabricator_recipe/pipe/device/omnimixer
name = "omni gas mixer"
- desc = "a device that takes in two or three gasses and mixes them into a precise output."
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_FUEL
build_icon_state = "omni_mixer"
constructed_path = /obj/machinery/atmospherics/omni/mixer
@@ -86,7 +76,6 @@
/datum/fabricator_recipe/pipe/device/omnifilter
name = "omni gas filter"
- desc = "a device that filters out undesireable elements"
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_FUEL
build_icon_state = "omni_filter"
constructed_path = /obj/machinery/atmospherics/omni/filter
@@ -94,7 +83,6 @@
/datum/fabricator_recipe/pipe/device/manualvalve
name = "manual valve"
- desc = "a valve that has to be manipulated by hand"
build_icon_state = "mvalve"
constructed_path = /obj/machinery/atmospherics/valve
pipe_class = PIPE_CLASS_BINARY
@@ -103,7 +91,6 @@
/datum/fabricator_recipe/pipe/device/digitalvalve
name = "digital valve"
- desc = "a valve controlled electronically"
build_icon_state = "dvalve"
constructed_path = /obj/machinery/atmospherics/valve/digital
pipe_class = PIPE_CLASS_BINARY
@@ -112,7 +99,6 @@
/datum/fabricator_recipe/pipe/device/autoshutoff
name = "automatic shutoff valve"
- desc = "a valve that can automatically shut itself off"
build_icon_state = "svalve"
constructed_path = /obj/machinery/atmospherics/valve/shutoff
pipe_class = PIPE_CLASS_BINARY
@@ -121,7 +107,6 @@
/datum/fabricator_recipe/pipe/device/mtvalve
name = "manual t-valve"
- desc = "a three-way valve. T-shaped."
build_icon_state = "mtvalve"
constructed_path = /obj/machinery/atmospherics/tvalve
pipe_class = PIPE_CLASS_TRINARY
@@ -129,7 +114,6 @@
/datum/fabricator_recipe/pipe/device/mtvalvem
name = "manual t-valve (mirrored)"
- desc = "a three-way valve. T-shaped."
build_icon_state = "mtvalvem"
constructed_path = /obj/machinery/atmospherics/tvalve/mirrored
pipe_class = PIPE_CLASS_TRINARY
@@ -137,7 +121,6 @@
/datum/fabricator_recipe/pipe/device/dtvalve
name = "digital t-valve"
- desc = "a three-way valve. T-shaped. This one can be controlled electronically."
build_icon = 'icons/atmos/digital_tvalve.dmi'
build_icon_state = "map_tvalve0"
constructed_path = /obj/machinery/atmospherics/tvalve/digital
@@ -146,7 +129,6 @@
/datum/fabricator_recipe/pipe/device/dtvalvem
name = "digital t-valve (mirrored)"
- desc = "a three-way valve. T-shaped. This one can be controlled electronically."
build_icon = 'icons/atmos/digital_tvalve.dmi'
build_icon_state = "map_tvalvem0"
constructed_path = /obj/machinery/atmospherics/tvalve/mirrored/digital
@@ -155,7 +137,6 @@
/datum/fabricator_recipe/pipe/device/air_sensor
name = "gas sensor"
- desc = "a sensor. It detects gasses."
path = /obj/item/machine_chassis/air_sensor
build_icon_state = "gsensor1"
build_icon = 'icons/obj/machines/gas_sensor.dmi'
@@ -167,7 +148,6 @@
/datum/fabricator_recipe/pipe/device/outlet_injector
name = "injector outlet"
- desc = "Passively injects gas into its surroundings. Has a valve attached to it that can control flow rate."
build_icon = 'icons/atmos/injector.dmi'
build_icon_state = "map_injector"
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_FUEL
@@ -178,7 +158,6 @@
/datum/fabricator_recipe/pipe/device/drain
name = "gutter"
- desc = "You probably can't get sucked down the plughole."
build_icon = 'icons/obj/drain.dmi'
build_icon_state = "drain"
path = /obj/item/drain
@@ -190,7 +169,6 @@
/datum/fabricator_recipe/pipe/device/drain/bath
name = "sealable gutter"
- desc = "You probably can't get sucked down the plughole. Specially not when it's closed!"
build_icon = 'icons/obj/drain.dmi'
build_icon_state = "drain_bath"
path = /obj/item/drain/bath
@@ -202,7 +180,6 @@
/datum/fabricator_recipe/pipe/device/tank
name = "pressure tank"
- desc = "A large vessel containing pressurized gas."
build_icon = 'icons/atmos/tank.dmi'
build_icon_state = "air"
path = /obj/item/pipe/tank
@@ -213,7 +190,6 @@
/datum/fabricator_recipe/pipe/device/plate
name = "thermal plate"
- desc = "A device which transfers heat to and from an area."
build_icon = 'icons/obj/atmospherics/cold_sink.dmi'
build_icon_state = "exposed"
path = /obj/item/pipe
@@ -223,7 +199,6 @@
/datum/fabricator_recipe/pipe/device/igniter
name = "igniter"
- desc = "A device which will ignite surrounding gasses."
build_icon = 'icons/obj/machines/igniter.dmi'
build_icon_state = "igniter1"
path = /obj/item/machine_chassis/igniter
diff --git a/code/modules/fabrication/designs/pipe/disposal_pipe_datums.dm b/code/modules/fabrication/designs/pipe/disposal_pipe_datums.dm
index 0340a6c60f43..57c4aa6220fb 100644
--- a/code/modules/fabrication/designs/pipe/disposal_pipe_datums.dm
+++ b/code/modules/fabrication/designs/pipe/disposal_pipe_datums.dm
@@ -7,7 +7,6 @@
var/turn = DISPOSAL_FLIP_FLIP
name = "disposal pipe segment"
- desc = "A huge pipe segment used for constructing disposal systems."
build_icon = 'icons/obj/pipes/disposal_pipe.dmi'
build_icon_state = "pipe-s"
path = /obj/structure/disposalconstruct
@@ -17,56 +16,48 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/bent
name = "bent disposal pipe segment"
- desc = "A huge pipe segment used for constructing disposal systems."
build_icon_state = "pipe-c"
turn = DISPOSAL_FLIP_RIGHT
constructed_path = /obj/structure/disposalpipe/segment/bent
/datum/fabricator_recipe/pipe/disposal_dispenser/junction
name = "disposal pipe junction"
- desc = "A huge pipe segment used for constructing disposal systems."
build_icon_state = "pipe-j1"
turn = DISPOSAL_FLIP_RIGHT|DISPOSAL_FLIP_FLIP
constructed_path = /obj/structure/disposalpipe/junction
/datum/fabricator_recipe/pipe/disposal_dispenser/junctionm
name = "disposal pipe junction (mirrored)"
- desc = "A huge pipe segment used for constructing disposal systems."
build_icon_state = "pipe-j2"
turn = DISPOSAL_FLIP_LEFT|DISPOSAL_FLIP_FLIP
constructed_path = /obj/structure/disposalpipe/junction/mirrored
/datum/fabricator_recipe/pipe/disposal_dispenser/yjunction
name = "disposal pipe y-junction"
- desc = "A huge pipe segment used for constructing disposal systems."
build_icon_state = "pipe-y"
turn = DISPOSAL_FLIP_LEFT|DISPOSAL_FLIP_RIGHT
constructed_path = /obj/structure/disposalpipe/junction
/datum/fabricator_recipe/pipe/disposal_dispenser/trunk
name = "disposal pipe trunk"
- desc = "A huge pipe segment used for constructing disposal systems."
build_icon_state = "pipe-t"
constructed_path = /obj/structure/disposalpipe/trunk
turn = DISPOSAL_FLIP_NONE
/datum/fabricator_recipe/pipe/disposal_dispenser/up
name = "disposal pipe upwards segment"
- desc = "A huge pipe segment used for constructing disposal systems."
build_icon_state = "pipe-u"
constructed_path = /obj/structure/disposalpipe/up
turn = DISPOSAL_FLIP_NONE
/datum/fabricator_recipe/pipe/disposal_dispenser/down
name = "disposal pipe downwards segment"
- desc = "A huge pipe segment used for constructing disposal systems."
build_icon_state = "pipe-d"
constructed_path = /obj/structure/disposalpipe/down
turn = DISPOSAL_FLIP_NONE
/datum/fabricator_recipe/pipe/disposal_dispenser/device
name = "disposal bin"
- desc = "A bin used to dispose of trash."
build_icon = 'icons/obj/pipes/disposal_bin.dmi'
build_icon_state = "disposal"
path = /obj/structure/disposalconstruct/machine
@@ -75,7 +66,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/outlet
name = "disposal outlet"
- desc = "an outlet that ejects things from a disposal network."
build_icon = 'icons/obj/pipes/disposal_outlet.dmi'
build_icon_state = "outlet"
path = /obj/structure/disposalconstruct/machine/outlet
@@ -83,7 +73,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/chute
name = "disposal chute"
- desc = "A chute to put things into a disposal network."
build_icon = 'icons/obj/pipes/disposal_chute.dmi'
build_icon_state = "chute"
constructed_path = /obj/machinery/disposal/deliveryChute
@@ -91,7 +80,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/sorting
name = "disposal sorter"
- desc = "Sorts things in a disposal system"
build_icon_state = "pipe-j1s"
turn = DISPOSAL_FLIP_RIGHT|DISPOSAL_FLIP_FLIP
constructed_path = /obj/structure/disposalpipe/sortjunction
@@ -99,7 +87,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/sorting/wildcard
name = "wildcard disposal sorter"
- desc = "Sorts things in a disposal system"
build_icon_state = "pipe-j1s"
turn = DISPOSAL_FLIP_RIGHT|DISPOSAL_FLIP_FLIP
constructed_path = /obj/structure/disposalpipe/sortjunction/wildcard
@@ -107,7 +94,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/sorting/untagged
name = "untagged disposal sorter"
- desc = "Sorts things in a disposal system"
build_icon_state = "pipe-j1s"
turn = DISPOSAL_FLIP_RIGHT|DISPOSAL_FLIP_FLIP
constructed_path = /obj/structure/disposalpipe/sortjunction/untagged
@@ -115,7 +101,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/sortingm
name = "disposal sorter (mirrored)"
- desc = "Sorts things in a disposal system"
build_icon_state = "pipe-j2s"
turn = DISPOSAL_FLIP_LEFT|DISPOSAL_FLIP_FLIP
constructed_path = /obj/structure/disposalpipe/sortjunction/flipped
@@ -123,7 +108,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/sorting/wildcardm
name = "wildcard disposal sorter (mirrored)"
- desc = "Sorts things in a disposal system"
build_icon_state = "pipe-j2s"
turn = DISPOSAL_FLIP_LEFT|DISPOSAL_FLIP_FLIP
constructed_path = /obj/structure/disposalpipe/sortjunction/wildcard/flipped
@@ -131,7 +115,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/sorting/untaggedm
name = "untagged disposal sorter (mirrored)"
- desc = "Sorts things in a disposal system"
build_icon_state = "pipe-j2s"
turn = DISPOSAL_FLIP_LEFT|DISPOSAL_FLIP_FLIP
constructed_path = /obj/structure/disposalpipe/sortjunction/untagged/flipped
@@ -139,7 +122,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/tagger
name = "disposal tagger"
- desc = "It tags things."
build_icon_state = "pipe-tagger"
turn = DISPOSAL_FLIP_FLIP
constructed_path = /obj/structure/disposalpipe/tagger
@@ -147,7 +129,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/tagger/partial
name = "disposal partial tagger"
- desc = "It tags things."
build_icon_state = "pipe-tagger-partial"
turn = DISPOSAL_FLIP_FLIP
constructed_path = /obj/structure/disposalpipe/tagger/partial
@@ -155,7 +136,6 @@
/datum/fabricator_recipe/pipe/disposal_dispenser/device/diversion
name = "disposal diverter"
- desc = "A huge pipe segment used for constructing disposal systems."
build_icon_state = "pipe-j1s"
turn = DISPOSAL_FLIP_FLIP | DISPOSAL_FLIP_RIGHT
constructed_path = /obj/structure/disposalpipe/diversion_junction
diff --git a/code/modules/fabrication/designs/pipe/pipe_datum_base.dm b/code/modules/fabrication/designs/pipe/pipe_datum_base.dm
index 8d3c48485e8c..75c5b9e1773b 100644
--- a/code/modules/fabrication/designs/pipe/pipe_datum_base.dm
+++ b/code/modules/fabrication/designs/pipe/pipe_datum_base.dm
@@ -18,6 +18,12 @@
)
max_amount = 10
+/datum/fabricator_recipe/pipe/New()
+ . = ..()
+ if(isnull(desc) && ispath(constructed_path))
+ var/obj/constructed_obj = constructed_path
+ desc = initial(constructed_obj.desc)
+
/datum/fabricator_recipe/pipe/get_resources()
resources = list()
var/list/building_cost = atom_info_repository.get_matter_for(constructed_path)
diff --git a/code/modules/fabrication/designs/pipe/pipe_datums.dm b/code/modules/fabrication/designs/pipe/pipe_datums.dm
index 58ca5c3bde85..70f0a7c6320c 100644
--- a/code/modules/fabrication/designs/pipe/pipe_datums.dm
+++ b/code/modules/fabrication/designs/pipe/pipe_datums.dm
@@ -2,19 +2,16 @@
#define PIPE_BENT 5
/datum/fabricator_recipe/pipe
- name = "a pipe fitting"
- desc = "a straight pipe segment."
+ name = "pipe fitting"
rotate_class = PIPE_ROTATE_TWODIR
/datum/fabricator_recipe/pipe/bent
name = "bent pipe fitting"
- desc = "a bent pipe segment"
dir = PIPE_BENT
rotate_class = PIPE_ROTATE_TWODIR
/datum/fabricator_recipe/pipe/manifold
name = "pipe manifold fitting"
- desc = "a pipe manifold segment"
build_icon_state = "manifold"
constructed_path = /obj/machinery/atmospherics/pipe/manifold/hidden
pipe_class = PIPE_CLASS_TRINARY
@@ -22,7 +19,6 @@
/datum/fabricator_recipe/pipe/manifold4w
name = "four-way pipe manifold fitting"
- desc = "a four-way pipe manifold segment"
build_icon_state = "manifold4w"
constructed_path = /obj/machinery/atmospherics/pipe/manifold4w/hidden
pipe_class = PIPE_CLASS_QUATERNARY
@@ -30,7 +26,6 @@
/datum/fabricator_recipe/pipe/cap
name = "pipe cap fitting"
- desc = "a pipe cap for a regular pipe."
build_icon_state = "cap"
constructed_path = /obj/machinery/atmospherics/pipe/cap/hidden
pipe_class = PIPE_CLASS_UNARY
@@ -38,7 +33,6 @@
/datum/fabricator_recipe/pipe/up
name = "upward pipe fitting"
- desc = "an upward pipe."
build_icon_state = "up"
constructed_path = /obj/machinery/atmospherics/pipe/zpipe/up
rotate_class = PIPE_ROTATE_STANDARD
@@ -46,7 +40,6 @@
/datum/fabricator_recipe/pipe/down
name = "downward pipe fitting"
- desc = "a downward pipe."
build_icon_state = "down"
constructed_path = /obj/machinery/atmospherics/pipe/zpipe/down
rotate_class = PIPE_ROTATE_STANDARD
@@ -61,18 +54,15 @@
pipe_class = PIPE_CLASS_BINARY
name = "supply pipe fitting"
- desc = "a straight supply pipe segment."
rotate_class = PIPE_ROTATE_TWODIR
/datum/fabricator_recipe/pipe/supply/bent
name = "bent supply pipe fitting"
- desc = "a bent supply pipe segment"
dir = PIPE_BENT
rotate_class = PIPE_ROTATE_TWODIR
/datum/fabricator_recipe/pipe/supply/manifold
name = "supply pipe manifold fitting"
- desc = "a supply pipe manifold segment"
build_icon_state = "manifold"
constructed_path = /obj/machinery/atmospherics/pipe/manifold/hidden/supply
pipe_class = PIPE_CLASS_TRINARY
@@ -80,7 +70,6 @@
/datum/fabricator_recipe/pipe/supply/manifold4w
name = "four-way supply pipe manifold fitting"
- desc = "a four-way supply pipe manifold segment"
build_icon_state = "manifold4w"
constructed_path = /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply
pipe_class = PIPE_CLASS_QUATERNARY
@@ -88,7 +77,6 @@
/datum/fabricator_recipe/pipe/supply/cap
name = "supply pipe cap fitting"
- desc = "a pipe cap for a regular pipe."
build_icon_state = "cap"
constructed_path = /obj/machinery/atmospherics/pipe/cap/hidden/supply
pipe_class = PIPE_CLASS_UNARY
@@ -96,14 +84,12 @@
/datum/fabricator_recipe/pipe/supply/up
name = "upward supply pipe fitting"
- desc = "an upward supply pipe segment."
build_icon_state = "up"
constructed_path = /obj/machinery/atmospherics/pipe/zpipe/up/supply
rotate_class = PIPE_ROTATE_STANDARD
/datum/fabricator_recipe/pipe/supply/down
name = "downward supply pipe fitting"
- desc = "a downward supply pipe segment."
build_icon_state = "down"
constructed_path = /obj/machinery/atmospherics/pipe/zpipe/down/supply
rotate_class = PIPE_ROTATE_STANDARD
@@ -117,18 +103,15 @@
pipe_class = PIPE_CLASS_BINARY
name = "scrubber pipe fitting"
- desc = "a straight scrubber pipe segment"
rotate_class = PIPE_ROTATE_TWODIR
/datum/fabricator_recipe/pipe/scrubber/bent
name = "bent scrubber pipe fitting"
- desc = "a bent scrubber pipe segment"
rotate_class = PIPE_ROTATE_TWODIR
dir = PIPE_BENT
/datum/fabricator_recipe/pipe/scrubber/manifold
name = "scrubber pipe manifold fitting"
- desc = "a scrubber pipe manifold segment"
build_icon_state = "manifold"
constructed_path = /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers
pipe_class = PIPE_CLASS_TRINARY
@@ -136,7 +119,6 @@
/datum/fabricator_recipe/pipe/scrubber/manifold4w
name = "four-way scrubber pipe manifold fitting"
- desc = "a four-way scrubber pipe manifold segment"
build_icon_state = "manifold4w"
constructed_path = /obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers
pipe_class = PIPE_CLASS_QUATERNARY
@@ -144,7 +126,6 @@
/datum/fabricator_recipe/pipe/scrubber/cap
name = "scrubber pipe cap fitting"
- desc = "a pipe cap for a scrubber pipe."
build_icon_state = "cap"
constructed_path = /obj/machinery/atmospherics/pipe/cap/hidden/scrubbers
pipe_class = PIPE_CLASS_UNARY
@@ -152,14 +133,12 @@
/datum/fabricator_recipe/pipe/scrubber/up
name = "upward scrubber pipe fitting"
- desc = "an upward scrubber pipe segment."
build_icon_state = "up"
constructed_path = /obj/machinery/atmospherics/pipe/zpipe/up/scrubbers
rotate_class = PIPE_ROTATE_STANDARD
/datum/fabricator_recipe/pipe/scrubber/down
name = "downward scrubber pipe fitting"
- desc = "a downward scrubber pipe segment."
build_icon_state = "down"
constructed_path = /obj/machinery/atmospherics/pipe/zpipe/down/scrubbers
rotate_class = PIPE_ROTATE_STANDARD
@@ -173,18 +152,15 @@
pipe_class = PIPE_CLASS_BINARY
name = "fuel pipe fitting"
- desc = "a striaght fuel pipe segment"
rotate_class = PIPE_ROTATE_TWODIR
/datum/fabricator_recipe/pipe/fuel/bent
name = "bent fuel pipe fitting"
- desc = "a bent fuel pipe segment"
rotate_class = PIPE_ROTATE_TWODIR
dir = PIPE_BENT
/datum/fabricator_recipe/pipe/fuel/manifold
name = "fuel pipe manifold fitting"
- desc = "a fuel pipe manifold segment"
build_icon_state = "manifold"
constructed_path = /obj/machinery/atmospherics/pipe/manifold/hidden/fuel
pipe_class = PIPE_CLASS_TRINARY
@@ -192,7 +168,6 @@
/datum/fabricator_recipe/pipe/fuel/manifold4w
name = "four-way supply pipe manifold fitting"
- desc = "a four-way fuel pipe manifold segment"
build_icon_state = "manifold4w"
constructed_path = /obj/machinery/atmospherics/pipe/manifold4w/hidden/fuel
pipe_class = PIPE_CLASS_QUATERNARY
@@ -200,7 +175,6 @@
/datum/fabricator_recipe/pipe/fuel/cap
name = "fuel pipe cap fitting"
- desc = "a pipe cap for a fuel pipe."
build_icon_state = "cap"
constructed_path = /obj/machinery/atmospherics/pipe/cap/hidden/fuel
pipe_class = PIPE_CLASS_UNARY
@@ -208,14 +182,12 @@
/datum/fabricator_recipe/pipe/fuel/up
name = "upward fuel pipe fitting"
- desc = "an upward fuel pipe segment."
build_icon_state = "up"
constructed_path = /obj/machinery/atmospherics/pipe/zpipe/up/fuel
rotate_class = PIPE_ROTATE_STANDARD
/datum/fabricator_recipe/pipe/fuel/down
name = "downward fuel pipe fitting"
- desc = "a downward fuel pipe segment."
build_icon_state = "down"
constructed_path = /obj/machinery/atmospherics/pipe/zpipe/down/fuel
rotate_class = PIPE_ROTATE_STANDARD
@@ -229,13 +201,11 @@
pipe_class = PIPE_CLASS_BINARY
name = "heat exchanger pipe fitting"
- desc = "a heat exchanger pipe segment"
build_icon_state = "he"
rotate_class = PIPE_ROTATE_TWODIR
/datum/fabricator_recipe/pipe/he/bent
name = "bent heat exchanger pipe fitting"
- desc = "a bent heat exchanger pipe segment"
connect_types = CONNECT_TYPE_HE
rotate_class = PIPE_ROTATE_TWODIR
build_icon_state = "he"
@@ -243,7 +213,6 @@
/datum/fabricator_recipe/pipe/he/junction
name = "heat exchanger junction"
- desc = "a heat exchanger junction"
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE|CONNECT_TYPE_FUEL
build_icon_state = "junction"
constructed_path = /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction
@@ -251,7 +220,6 @@
/datum/fabricator_recipe/pipe/he/exchanger
name = "heat exchanger"
- desc = "a heat exchanger"
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_FUEL
build_icon_state = "heunary"
constructed_path = /obj/machinery/atmospherics/unary/heat_exchanger
diff --git a/code/modules/fluids/fluid_mapped.dm b/code/modules/fluids/fluid_mapped.dm
index 5ea97d7a585f..3a286cf7b36c 100644
--- a/code/modules/fluids/fluid_mapped.dm
+++ b/code/modules/fluids/fluid_mapped.dm
@@ -25,12 +25,25 @@
/obj/abstract/landmark/mapped_fluid/Initialize()
..()
- var/turf/my_turf = get_turf(src)
- if(my_turf)
- my_turf.add_to_reagents(fluid_type, fluid_initial)
- return INITIALIZE_HINT_QDEL
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/abstract/landmark/mapped_fluid/LateInitialize()
+ ..()
+ if(fluid_initial > 0)
+ var/turf/my_turf = get_turf(src)
+ if(my_turf)
+ my_turf.add_to_reagents(fluid_type, fluid_initial)
+ qdel(src)
/obj/abstract/landmark/mapped_fluid/fuel
name = "spilled fuel"
fluid_type = /decl/material/liquid/fuel
fluid_initial = 10
+
+/obj/abstract/landmark/mapped_fluid/fill
+ name = "mapped fluid fill"
+
+/obj/abstract/landmark/mapped_fluid/fill/LateInitialize()
+ var/turf/my_turf = get_turf(loc)
+ fluid_initial = -(my_turf.get_physical_height())
+ ..()
diff --git a/code/modules/food/plates/plate_tray.dm b/code/modules/food/plates/plate_tray.dm
index 2b05fabfbf85..5bc0488090ce 100644
--- a/code/modules/food/plates/plate_tray.dm
+++ b/code/modules/food/plates/plate_tray.dm
@@ -157,10 +157,10 @@ TRAY TYPES GO HERE
/obj/item/plate/tray/metal/silver
name = "platter"
- desc = "You lazy bum."
+ desc = "The new generation is so lazy, they expect everything to be handed to them on this."
material = /decl/material/solid/metal/silver
/obj/item/plate/tray/metal/gold
name = "platter"
- desc = "A gold tray to serve food on. But oh sofancy."
+ desc = "A gold tray to serve food on. Heavy, but oh-so-fancy."
material = /decl/material/solid/metal/gold
\ No newline at end of file
diff --git a/code/modules/games/boardgame.dm b/code/modules/games/boardgame.dm
index 5c7765027cb7..4aa01e0697da 100644
--- a/code/modules/games/boardgame.dm
+++ b/code/modules/games/boardgame.dm
@@ -1,6 +1,6 @@
/obj/item/board
name = "board"
- desc = "A standard 16\" checkerboard. Well used." //Goddamn imperial system.
+ desc = "A standard 16\" checkerboard. Well-used." //Goddamn imperial system.
icon = 'icons/obj/pieces.dmi'
icon_state = "board"
material = /decl/material/solid/organic/wood/oak
@@ -236,7 +236,7 @@
/obj/item/checker/bishop
name = "bishop"
- desc = "What corruption occured, urging holy men to fight?"
+ desc = "What corruption occurred, urging holy men to fight?"
/obj/item/checker/bishop/red
piece_color ="red"
diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm
index 8084a66d09df..cd9bf8848097 100644
--- a/code/modules/games/cards.dm
+++ b/code/modules/games/cards.dm
@@ -106,7 +106,7 @@ var/global/list/card_decks = list()
/obj/item/deck/compact
name = "compact deck of cards"
- desc = "A deck of playing cards. Looks like this one hasn't numbers from two to five, and jokers."
+ desc = "A deck of playing cards. Looks like this one is missing numbers from two to five, and both jokers."
icon_state = "deck"
/obj/item/deck/compact/generate_cards()
@@ -266,7 +266,7 @@ var/global/list/card_decks = list()
/obj/item/pack
name = "card pack"
- desc = "For those with disposible income."
+ desc = "For those with disposable income."
icon_state = "card_pack"
icon = 'icons/obj/items/playing_cards.dmi'
w_class = ITEM_SIZE_SMALL
@@ -292,7 +292,10 @@ var/global/list/card_decks = list()
icon_state = "empty"
w_class = ITEM_SIZE_TINY
material = /decl/material/solid/organic/cardboard
+ dir = NORTH // our default dir is expected to be north, e.g. we've been placed by someone facing north
var/concealed = 0
+ /// Whether or not we should shift our icons according to our dir or not.
+ var/is_on_table = FALSE
var/list/datum/playingcard/cards = list()
/obj/item/hand/attack_self(var/mob/user)
@@ -337,43 +340,42 @@ var/global/list/card_decks = list()
for(var/datum/playingcard/P in cards)
to_chat(user, "\The [APPEND_FULLSTOP_IF_NEEDED(P.name)]")
-/obj/item/hand/on_update_icon(var/direction = 0)
+/obj/item/hand/on_update_icon()
. = ..()
- if(!cards.len)
- qdel(src)
- return
- else if(cards.len > 1)
- name = "hand of cards"
- desc = "Some playing cards."
- else if(concealed)
- name = "single playing card"
- desc = "An unknown playing card, concealed."
- else
- var/datum/playingcard/P = cards[1]
- name = "[P.name]"
- desc = "[P.desc]"
-
- overlays.Cut()
-
- if(cards.len == 1)
- var/datum/playingcard/P = cards[1]
- var/image/I = P.card_image(concealed, src.icon)
- I.pixel_x += (-5+rand(10))
- I.pixel_y += (-5+rand(10))
- overlays += I
- return
+ var/card_count = length(cards)
+ switch(card_count)
+ if(0)
+ qdel(src)
+ return
+ if(1)
+ var/datum/playingcard/top_card = cards[1]
+ if(concealed)
+ name = "single playing card"
+ desc = "An unknown playing card, concealed."
+ else
+ name = top_card.name
+ desc = top_card.desc
+ var/image/I = top_card.card_image(concealed, src.icon)
+ I.pixel_x += (-5+rand(10))
+ I.pixel_y += (-5+rand(10))
+ add_overlay(I)
+ compile_overlays()
+ return
+ else
+ name = "hand of cards"
+ desc = "Some playing cards."
- var/offset = floor(20/cards.len)
+ var/offset = floor(20/card_count)
var/matrix/M = matrix()
- if(direction)
- switch(direction)
+ if(is_on_table)
+ switch(dir)
if(NORTH)
- M.Translate( 0, 0)
+ M.Translate( 0, 0) // Technically redundant but it makes the logic clearer.
if(SOUTH)
M.Translate( 0, 4)
if(WEST)
- M.Turn(90)
+ M.Turn(-90)
M.Translate( 3, 0)
if(EAST)
M.Turn(90)
@@ -381,29 +383,36 @@ var/global/list/card_decks = list()
var/i = 0
for(var/datum/playingcard/P in cards)
var/image/I = P.card_image(concealed, src.icon)
- //I.pixel_x = origin+(offset*i)
- switch(direction)
+ switch(dir)
if(SOUTH)
I.pixel_x = 8-(offset*i)
if(WEST)
I.pixel_y = -6+(offset*i)
if(EAST)
I.pixel_y = 8-(offset*i)
- else
+ if(NORTH)
I.pixel_x = -7+(offset*i)
+ // other dirs are explicitly unsupported!
I.transform = M
- overlays += I
+ add_overlay(I)
i++
+ compile_overlays() // these should be as responsive as possible
/obj/item/hand/dropped(mob/user)
..()
- if(locate(/obj/structure/table, loc))
- src.update_icon(user.dir)
+ if(locate(/obj/structure/table) in loc)
+ is_on_table = TRUE
+ set_dir(user.dir)
else
- update_icon()
+ is_on_table = FALSE
+ set_dir(initial(dir))
+ update_icon()
/obj/item/hand/on_picked_up(mob/user)
- src.update_icon()
+ ..()
+ is_on_table = FALSE
+ set_dir(initial(dir))
+ update_icon()
/*** A special thing that steals a card from a deck, probably lost in maint somewhere. ***/
/obj/item/hand/missing_card
diff --git a/code/modules/gemstones/gemstone_cuts.dm b/code/modules/gemstones/gemstone_cuts.dm
index 4b8b15fb7d84..a880d09644f6 100644
--- a/code/modules/gemstones/gemstone_cuts.dm
+++ b/code/modules/gemstones/gemstone_cuts.dm
@@ -66,7 +66,7 @@
/decl/gemstone_cut/octagon
name = "octagon"
adjective = "octagon-cut"
- desc = "A octagon-cut gemstone."
+ desc = "An octagon-cut gemstone."
icon = 'icons/obj/items/gemstones/octagon.dmi'
/decl/gemstone_cut/round
diff --git a/code/modules/genetics/plants/trait_biolum.dm b/code/modules/genetics/plants/trait_biolum.dm
index 26c5d38b69d5..a4b8e623e183 100644
--- a/code/modules/genetics/plants/trait_biolum.dm
+++ b/code/modules/genetics/plants/trait_biolum.dm
@@ -5,4 +5,4 @@
/decl/plant_trait/biolum/get_extended_data(val, datum/seed/grown_seed)
if(val)
- return "It is [grown_seed?.get_trait(TRAIT_BIOLUM_COLOUR) ? "bio-luminescent" : "bio-luminescent"]."
+ return "It is [grown_seed?.get_trait(TRAIT_BIOLUM_COLOUR) ? "bioluminescent" : "bioluminescent"]."
diff --git a/code/modules/goals/definitions/personal_achievement.dm b/code/modules/goals/definitions/personal_achievement.dm
index bf83f3303e92..12849c7f7851 100644
--- a/code/modules/goals/definitions/personal_achievement.dm
+++ b/code/modules/goals/definitions/personal_achievement.dm
@@ -32,5 +32,5 @@
completion_message = "Yeah! Smash the state!"
/datum/goal/achievement/newshound
- description = "Catch up on the news with a newspaper, none of that new-fangled digital media."
+ description = "Catch up on the news with a newspaper, none of that newfangled digital media."
completion_message = "You feel much more in-the-know."
\ No newline at end of file
diff --git a/code/modules/holodeck/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm
index 843d0ed4d48f..f5db252b01db 100644
--- a/code/modules/holodeck/HolodeckControl.dm
+++ b/code/modules/holodeck/HolodeckControl.dm
@@ -100,40 +100,37 @@
onclose(user, "computer")
return
-/obj/machinery/computer/holodeck_control/Topic(href, href_list)
- if(..())
- return 1
- if((usr.contents.Find(src) || (in_range(src, usr) && isturf(src.loc))) || (issilicon(usr)))
- usr.set_machine(src)
-
- if(href_list["program"])
- var/prog = href_list["program"]
- if(prog in global.using_map.holodeck_programs)
- loadProgram(global.using_map.holodeck_programs[prog])
-
- else if(href_list["AIoverride"])
- if(!issilicon(usr))
- return
+/obj/machinery/computer/holodeck_control/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
+ if(href_list["program"])
+ var/prog = href_list["program"]
+ if(prog in global.using_map.holodeck_programs)
+ loadProgram(global.using_map.holodeck_programs[prog])
+ . = TOPIC_REFRESH
- if(safety_disabled && emagged)
- return //if a traitor has gone through the trouble to emag the thing, let them keep it.
+ else if(href_list["AIoverride"])
+ if(!issilicon(usr))
+ return TOPIC_HANDLED
- safety_disabled = !safety_disabled
- update_projections()
- if(safety_disabled)
- log_and_message_admins("overrode the holodeck's safeties")
- else
- log_and_message_admins("restored the holodeck's safeties")
+ if(safety_disabled && emagged)
+ return TOPIC_HANDLED //if a traitor has gone through the trouble to emag the thing, let them keep it.
- else if(href_list["gravity"])
- toggleGravity(linkedholodeck)
+ safety_disabled = !safety_disabled
+ update_projections()
+ if(safety_disabled)
+ log_and_message_admins("overrode the holodeck's safeties")
+ else
+ log_and_message_admins("restored the holodeck's safeties")
+ . = TOPIC_REFRESH
- else if(href_list["togglehololock"])
- togglelock(usr)
+ else if(href_list["gravity"])
+ toggleGravity(linkedholodeck)
+ . = TOPIC_REFRESH
- src.add_fingerprint(usr)
- src.updateUsrDialog()
- return
+ else if(href_list["togglehololock"])
+ togglelock(usr)
+ . = TOPIC_REFRESH
/obj/machinery/computer/holodeck_control/emag_act(var/remaining_charges, var/mob/user)
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
diff --git a/code/modules/hud/_hud_condition.dm b/code/modules/hud/_hud_condition.dm
deleted file mode 100644
index ce592c6918fc..000000000000
--- a/code/modules/hud/_hud_condition.dm
+++ /dev/null
@@ -1,15 +0,0 @@
-// decl stubs for future implementation work.
-/decl/hud_element
- abstract_type = /decl/hud_element
-/decl/hud_element/condition
- abstract_type = /decl/hud_element/condition
-
-/decl/hud_element/condition/pressure
-
-/decl/hud_element/condition/fire
-
-/decl/hud_element/condition/oxygen
-
-/decl/hud_element/condition/toxins
-
-/decl/hud_element/condition/carbon_dioxide
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 3e145679b348..7083722c41ca 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -183,11 +183,10 @@
return
var/mob/living/M = AM
- if(M.buckled || MOVING_DELIBERATELY(M))
+ if(MOVING_DELIBERATELY(M))
return
- var/obj/item/shoes = M.get_equipped_item(slot_shoes_str)
- if(shoes && shoes.item_flags & ITEM_FLAG_NOSLIP)
+ if(!M.can_slip() || M.immune_to_floor_hazards())
return
to_chat(M, SPAN_DANGER("You slipped on \the [src]!"))
diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm
index 418afb41d29c..17fbe753529f 100644
--- a/code/modules/hydroponics/seed_machines.dm
+++ b/code/modules/hydroponics/seed_machines.dm
@@ -153,13 +153,12 @@
ui.open()
ui.set_auto_update(1)
-/obj/machinery/botany/Topic(href, href_list)
-
- if(..())
- return 1
+/obj/machinery/botany/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["eject_packet"])
- if(!seed) return
+ if(!seed) return TOPIC_REFRESH // You must be mistaken! We have no seed.
seed.dropInto(loc)
if(seed.seed.name == "new line" || isnull(SSplants.seeds[seed.seed.name]))
@@ -168,76 +167,59 @@
SSplants.seeds[seed.seed.name] = seed.seed
seed.update_seed()
- visible_message("[html_icon(src)] [src] beeps and spits out [seed].")
+ visible_message("[html_icon(src)] \The [src] beeps and spits out [seed].")
seed = null
+ . = TOPIC_REFRESH
if(href_list["eject_disk"])
- if(!loaded_disk) return
+ if(!loaded_disk) return TOPIC_REFRESH
loaded_disk.dropInto(loc)
- visible_message("[html_icon(src)] [src] beeps and spits out [loaded_disk].")
+ visible_message("[html_icon(src)] \The [src] beeps and spits out [loaded_disk].")
loaded_disk = null
+ . = TOPIC_REFRESH
- usr.set_machine(src)
- src.add_fingerprint(usr)
-
-/obj/machinery/botany/extractor/Topic(href, href_list)
-
- if(..())
- return 1
-
- var/mob/user = usr
- user.set_machine(src)
- src.add_fingerprint(user)
+/obj/machinery/botany/extractor/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["scan_genome"])
-
- if(!seed) return
-
+ if(!seed) return TOPIC_REFRESH
last_action = world.time
- active = 1
-
- if(seed && seed.seed)
- if(prob(user.skill_fail_chance(SKILL_BOTANY, 100, SKILL_ADEPT)))
- failed_task = 1
- else
- genetics = seed.seed
- degradation = 0
+ active = TRUE
+ if(prob(user.skill_fail_chance(SKILL_BOTANY, 100, SKILL_ADEPT)))
+ failed_task = TRUE
+ else
+ genetics = seed.seed
+ degradation = 0
- qdel(seed)
- seed = null
+ QDEL_NULL(seed)
if(href_list["get_gene"])
-
if(!genetics || !loaded_disk)
- return
+ return TOPIC_REFRESH
var/decl/plant_gene/gene_master = locate(href_list["get_gene"])
if(ispath(gene_master))
gene_master = GET_DECL(gene_master)
if(!istype(gene_master))
- return
+ return TOPIC_HANDLED // Potential href hacking?
last_action = world.time
- active = 1
-
+ active = TRUE
loaded_disk.genes += new /datum/plantgene(gene_master, genetics)
-
loaded_disk.genesource = "[genetics.display_name]"
if(!genetics.roundstart)
loaded_disk.genesource += " (variety #[genetics.uid])"
-
loaded_disk.name += " ([gene_master.name], #[genetics.uid])"
loaded_disk.desc += " The label reads \'gene [gene_master.name], sampled from [genetics.display_name]\'."
- eject_disk = 1
-
+ eject_disk = TRUE
degradation += rand(20,60) + user.skill_fail_chance(SKILL_BOTANY, 100, SKILL_ADEPT)
var/expertise = max(0, user.get_skill_value(SKILL_BOTANY) - SKILL_ADEPT)
degradation = max(0, degradation - 10*expertise)
-
if(degradation >= 100)
- failed_task = 1
+ failed_task = TRUE
genetics = null
degradation = 0
@@ -296,30 +278,24 @@
ui.open()
ui.set_auto_update(1)
-/obj/machinery/botany/editor/Topic(href, href_list)
-
- if(..())
- return 1
+/obj/machinery/botany/editor/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["apply_gene"])
- if(!loaded_disk || !seed) return
-
- var/mob/user = usr
+ if(!loaded_disk || !seed) return TOPIC_REFRESH
last_action = world.time
- active = 1
+ active = TRUE
if(!isnull(SSplants.seeds[seed.seed.name]))
seed.seed = seed.seed.diverge(1)
seed.update_seed()
if(prob(seed.modified))
- failed_task = 1
+ failed_task = TRUE
seed.modified = 101
for(var/datum/plantgene/gene in loaded_disk.genes)
seed.seed.apply_gene(gene)
var/expertise = max(user.get_skill_value(SKILL_BOTANY) - SKILL_ADEPT)
seed.modified += rand(5,10) + min(-5, 30 * expertise)
-
- usr.set_machine(src)
- src.add_fingerprint(usr)
diff --git a/code/modules/hydroponics/seed_storage.dm b/code/modules/hydroponics/seed_storage.dm
index bee76cb91f76..6aa7d2372d15 100644
--- a/code/modules/hydroponics/seed_storage.dm
+++ b/code/modules/hydroponics/seed_storage.dm
@@ -286,8 +286,8 @@
show_browser(user, dat, "window=seedstorage;size=800x500")
onclose(user, "seedstorage")
-/obj/machinery/seed_storage/Topic(var/href, var/list/href_list)
- if (..())
+/obj/machinery/seed_storage/OnTopic(mob/user, href_list)
+ if((. = ..()))
return
var/task = href_list["task"]
var/id = text2num(href_list["id"])
@@ -304,13 +304,14 @@
qdel(our_pile)
flick("[initial(icon_state)]-vend", src)
O.dropInto(loc)
+ . = TOPIC_REFRESH
if ("purge")
QDEL_LIST(our_pile.seeds)
our_pile.seeds.Cut()
+ . = TOPIC_REFRESH
if(!length(our_pile.seeds))
piles -= our_pile
QDEL_NULL(our_pile)
- updateUsrDialog()
/obj/machinery/seed_storage/attackby(var/obj/item/O, var/mob/user)
diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm
index 5848a943ac70..1eaa5fba5651 100644
--- a/code/modules/hydroponics/spreading/spreading_response.dm
+++ b/code/modules/hydroponics/spreading/spreading_response.dm
@@ -78,8 +78,7 @@
if(H.species.species_flags & SPECIES_FLAG_NO_TANGLE)
return
- var/obj/item/clothing/shoes/magboots/magboots = H.get_equipped_item(slot_shoes_str)
- if(victim.loc != loc && istype(magboots) && (magboots.item_flags & ITEM_FLAG_NOSLIP) || H.species.check_no_slip(H))
+ if(victim.loc != loc && victim.can_slip())
visible_message("Tendrils lash to drag \the [victim] but \the [src] can't pull them across the ground!")
return
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/modules/implants/implant.dm
similarity index 100%
rename from code/game/objects/items/weapons/implants/implant.dm
rename to code/modules/implants/implant.dm
diff --git a/code/game/objects/items/weapons/implants/implants/adrenaline.dm b/code/modules/implants/implant_types/adrenaline.dm
similarity index 84%
rename from code/game/objects/items/weapons/implants/implants/adrenaline.dm
rename to code/modules/implants/implant_types/adrenaline.dm
index 7c3f0036fa7c..e93b99158db2 100644
--- a/code/game/objects/items/weapons/implants/implants/adrenaline.dm
+++ b/code/modules/implants/implant_types/adrenaline.dm
@@ -31,8 +31,8 @@
imp_in.set_status(STAT_PARA, 0)
/obj/item/implant/adrenalin/implanted(mob/source)
- source.StoreMemory("A implant can be activated by using the pale emote, say *pale to attempt to activate.", /decl/memory_options/system)
- to_chat(source, "The implanted freedom implant can be activated by using the pale emote, say *pale to attempt to activate.")
+ source.StoreMemory("\A [src] can be activated by using the pale emote, say *pale to attempt to activate.", /decl/memory_options/system)
+ to_chat(source, "\The [src] can be activated by using the pale emote, say *pale to attempt to activate.")
return TRUE
/obj/item/implanter/adrenalin
diff --git a/code/game/objects/items/weapons/implants/implants/chem.dm b/code/modules/implants/implant_types/chem.dm
similarity index 100%
rename from code/game/objects/items/weapons/implants/implants/chem.dm
rename to code/modules/implants/implant_types/chem.dm
diff --git a/code/game/objects/items/weapons/implants/implants/compressed.dm b/code/modules/implants/implant_types/compressed.dm
similarity index 88%
rename from code/game/objects/items/weapons/implants/implants/compressed.dm
rename to code/modules/implants/implant_types/compressed.dm
index e9872331439e..ad6dee6983b1 100644
--- a/code/game/objects/items/weapons/implants/implants/compressed.dm
+++ b/code/modules/implants/implant_types/compressed.dm
@@ -27,8 +27,8 @@
/obj/item/implant/compressed/implanted(mob/source)
src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_v", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
if (source.mind)
- source.StoreMemory("Compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", /decl/memory_options/system)
- to_chat(source, "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.")
+ source.StoreMemory("\A [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", /decl/memory_options/system)
+ to_chat(source, "\The [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.")
return TRUE
/obj/item/implanter/compressed
diff --git a/code/game/objects/items/weapons/implants/implants/death_alarm.dm b/code/modules/implants/implant_types/death_alarm.dm
similarity index 100%
rename from code/game/objects/items/weapons/implants/implants/death_alarm.dm
rename to code/modules/implants/implant_types/death_alarm.dm
diff --git a/code/game/objects/items/weapons/implants/implants/explosive.dm b/code/modules/implants/implant_types/explosive.dm
similarity index 100%
rename from code/game/objects/items/weapons/implants/implants/explosive.dm
rename to code/modules/implants/implant_types/explosive.dm
diff --git a/code/game/objects/items/weapons/implants/implants/freedom.dm b/code/modules/implants/implant_types/freedom.dm
similarity index 85%
rename from code/game/objects/items/weapons/implants/implants/freedom.dm
rename to code/modules/implants/implant_types/freedom.dm
index 720acd8685f4..2ec9c0890aed 100644
--- a/code/game/objects/items/weapons/implants/implants/freedom.dm
+++ b/code/modules/implants/implant_types/freedom.dm
@@ -50,8 +50,8 @@
/obj/item/implant/freedom/implanted(mob/living/source)
src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_v", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
- source.StoreMemory("Freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", /decl/memory_options/system)
- to_chat(source, "The implanted freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.")
+ source.StoreMemory("\A [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", /decl/memory_options/system)
+ to_chat(source, "\The [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.")
return TRUE
/obj/item/implanter/freedom
diff --git a/code/game/objects/items/weapons/implants/implants/imprinting.dm b/code/modules/implants/implant_types/imprinting.dm
similarity index 100%
rename from code/game/objects/items/weapons/implants/implants/imprinting.dm
rename to code/modules/implants/implant_types/imprinting.dm
diff --git a/code/game/objects/items/weapons/implants/implants/loyalty.dm b/code/modules/implants/implant_types/loyalty.dm
similarity index 100%
rename from code/game/objects/items/weapons/implants/implants/loyalty.dm
rename to code/modules/implants/implant_types/loyalty.dm
diff --git a/code/game/objects/items/weapons/implants/implants/tracking.dm b/code/modules/implants/implant_types/tracking.dm
similarity index 100%
rename from code/game/objects/items/weapons/implants/implants/tracking.dm
rename to code/modules/implants/implant_types/tracking.dm
diff --git a/code/game/objects/items/weapons/implants/implants/translator.dm b/code/modules/implants/implant_types/translator.dm
similarity index 93%
rename from code/game/objects/items/weapons/implants/implants/translator.dm
rename to code/modules/implants/implant_types/translator.dm
index 90220204ae8b..f4c540ddb7d4 100644
--- a/code/game/objects/items/weapons/implants/implants/translator.dm
+++ b/code/modules/implants/implant_types/translator.dm
@@ -41,7 +41,7 @@
/obj/item/implant/translator/natural
name = "lingophagic node"
- desc = "A chunk of what could be discolored crystalized brain matter. It seems to pulse occasionally."
+ desc = "A chunk of what could be discolored crystallized brain matter. It seems to pulse occasionally."
icon_state = "implant_melted"
origin_tech = @'{"biotech":5}'
learning_threshold = 10
diff --git a/code/game/objects/items/weapons/implants/implants/uplink.dm b/code/modules/implants/implant_types/uplink.dm
similarity index 77%
rename from code/game/objects/items/weapons/implants/implants/uplink.dm
rename to code/modules/implants/implant_types/uplink.dm
index fece5d1fc373..27e733c583aa 100644
--- a/code/game/objects/items/weapons/implants/implants/uplink.dm
+++ b/code/modules/implants/implant_types/uplink.dm
@@ -13,8 +13,8 @@
/obj/item/implant/uplink/implanted(mob/source)
var/emote_options = list("blink", "blink_r", "eyebrow", "chuckle", "twitch_v", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
activation_emote = source.client ? (input(source, "Choose activation emote:", "Uplink Implant Setup") in emote_options) : emote_options[1]
- source.StoreMemory("Uplink implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", /decl/memory_options/system)
- to_chat(source, "The implanted uplink implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.")
+ source.StoreMemory("\A [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", /decl/memory_options/system)
+ to_chat(source, "\The [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.")
hidden_uplink.uplink_owner = source.mind
return TRUE
diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/modules/implants/implantcase.dm
similarity index 100%
rename from code/game/objects/items/weapons/implants/implantcase.dm
rename to code/modules/implants/implantcase.dm
diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/modules/implants/implantchair.dm
similarity index 86%
rename from code/game/objects/items/weapons/implants/implantchair.dm
rename to code/modules/implants/implantchair.dm
index 7d2dfe25367c..6bfe7ff3b67c 100644
--- a/code/game/objects/items/weapons/implants/implantchair.dm
+++ b/code/modules/implants/implantchair.dm
@@ -9,13 +9,13 @@
opacity = FALSE
anchored = TRUE
- var/ready = 1
+ var/ready = TRUE
var/list/obj/item/implant/loyalty/implant_list = list()
var/max_implants = 5
var/injection_cooldown = 600
var/replenish_cooldown = 6000
var/mob/living/occupant = null
- var/injecting = 0
+ var/injecting = FALSE
/obj/machinery/implantchair/Initialize()
. = ..()
@@ -47,26 +47,24 @@
onclose(user, "implant")
-/obj/machinery/implantchair/Topic(href, href_list)
+/obj/machinery/implantchair/OnTopic(mob/user, href_list)
if((. = ..()))
return
- if((get_dist(src, usr) <= 1) || isAI(usr))
- if(href_list["implant"])
- if(src.occupant)
- injecting = 1
- go_out()
- ready = 0
- spawn(injection_cooldown)
- ready = 1
-
- if(href_list["replenish"])
- ready = 0
- spawn(replenish_cooldown)
- add_implants()
- ready = 1
-
- src.updateUsrDialog()
- src.add_fingerprint(usr)
+ if(!ready) // avoid topic hacking
+ return TOPIC_NOACTION
+ if(href_list["implant"] && occupant)
+ injecting = TRUE
+ go_out()
+ ready = FALSE
+ addtimer(CALLBACK(src, PROC_REF(make_ready)), injection_cooldown)
+
+ if(href_list["replenish"])
+ ready = 0
+ addtimer(CALLBACK(src, PROC_REF(add_implants)), replenish_cooldown)
+ addtimer(CALLBACK(src, PROC_REF(make_ready)), replenish_cooldown)
+
+/obj/machinery/implantchair/proc/make_ready()
+ ready = TRUE
/obj/machinery/implantchair/grab_attack(obj/item/grab/grab, mob/user)
var/mob/living/victim = grab.get_affecting_mob()
@@ -87,7 +85,7 @@
occupant.dropInto(loc)
if(injecting)
implant(src.occupant)
- injecting = 0
+ injecting = FALSE
src.occupant = null
icon_state = "implantchair"
return
diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/modules/implants/implanter.dm
similarity index 100%
rename from code/game/objects/items/weapons/implants/implanter.dm
rename to code/modules/implants/implanter.dm
diff --git a/code/game/objects/items/weapons/implants/implantpad.dm b/code/modules/implants/implantpad.dm
similarity index 97%
rename from code/game/objects/items/weapons/implants/implantpad.dm
rename to code/modules/implants/implantpad.dm
index 7f1226b1eaea..a2b1afb11fb4 100644
--- a/code/game/objects/items/weapons/implants/implantpad.dm
+++ b/code/modules/implants/implantpad.dm
@@ -1,6 +1,6 @@
/obj/item/implantpad
name = "implant pad"
- desc = "Used to reprogramm implants."
+ desc = "Used to reprogram implants."
icon = 'icons/obj/items/implant/implantpad.dmi'
icon_state = ICON_STATE_WORLD
w_class = ITEM_SIZE_SMALL
diff --git a/code/modules/integrated_electronics/subtypes/access.dm b/code/modules/integrated_electronics/subtypes/access.dm
index ef601575bd94..8d65f2c31da6 100644
--- a/code/modules/integrated_electronics/subtypes/access.dm
+++ b/code/modules/integrated_electronics/subtypes/access.dm
@@ -1,6 +1,6 @@
/obj/item/integrated_circuit/input/card_reader
name = "ID card reader" //To differentiate it from the data card reader
- desc = "A circuit that can read the registred name, assignment, and PassKey string from an ID card."
+ desc = "A circuit that can read the registered name, assignment, and PassKey string from an ID card."
icon_state = "card_reader"
complexity = 4
@@ -43,7 +43,7 @@
/obj/item/integrated_circuit/output/access_displayer
name = "access circuit"
- desc = "broadcasts access for your assembly via a passkey."
+ desc = "A circuit that broadcasts access for your assembly via a passkey."
extended_desc = "Useful for moving drones through airlocks."
complexity = 4
diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm
index 1d125d29c248..2b91f12b1ec4 100644
--- a/code/modules/integrated_electronics/subtypes/converters.dm
+++ b/code/modules/integrated_electronics/subtypes/converters.dm
@@ -109,6 +109,7 @@
/obj/item/integrated_circuit/converter/lowercase
name = "lowercase string converter"
+ // i'm not fixing the capitalization here to fit style guides because it's funny actually
desc = "this circuit will cause a string to come out in all lowercase."
icon_state = "lowercase"
inputs = list("input" = IC_PINTYPE_STRING)
@@ -128,6 +129,7 @@
/obj/item/integrated_circuit/converter/uppercase
name = "uppercase string converter"
+ // see capitalization note above
desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE."
icon_state = "uppercase"
inputs = list("input" = IC_PINTYPE_STRING)
@@ -392,7 +394,7 @@
/obj/item/integrated_circuit/converter/hsv2hex
name = "hsv to hexadecimal"
- desc = "This circuit can convert a HSV (Hue, Saturation, and Value) color to a Hexadecimal RGB color."
+ desc = "This circuit can convert an HSV (Hue, Saturation, and Value) color to a Hexadecimal RGB color."
extended_desc = "The first pin controls tint (0-359), the second pin controls how intense the tint is (0-255), and the third controls how bright the tint is (0 for black, 127 for normal, 255 for white)."
icon_state = "hsv-hex"
inputs = list(
@@ -418,7 +420,7 @@
/obj/item/integrated_circuit/converter/rgb2hex
name = "rgb to hexadecimal"
- desc = "This circuit can convert a RGB (Red, Green, Blue) color to a Hexadecimal RGB color."
+ desc = "This circuit can convert an RGB (Red, Green, Blue) color to a Hexadecimal RGB color."
extended_desc = "The first pin controls red amount, the second pin controls green amount, and the third controls blue amount. They all go from 0-255."
icon_state = "rgb-hex"
inputs = list(
diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm
index 0fd000025760..82449cc6ab6f 100644
--- a/code/modules/integrated_electronics/subtypes/manipulation.dm
+++ b/code/modules/integrated_electronics/subtypes/manipulation.dm
@@ -537,7 +537,7 @@
/obj/item/integrated_circuit/manipulation/wormhole
name = "wormhole generator"
desc = "This powerful circuit can open micro-length wormholes between two points in space."
- extended_desc = "If a valid teleporter console is supplied as input then its selected teleporter beacon will be used as destination point, \
+ extended_desc = "If a valid teleporter console is supplied as input then its selected teleporter beacon will be used as the destination point, \
and if not an undefined destination point is selected. \
Rift direction is a cardinal value determening in which direction the rift will be opened, relative the local north. \
A direction value of 0 will open the rift on top of the assembly, and any other non-cardinal values will open the rift in the assembly's current facing."
@@ -593,7 +593,7 @@
/obj/item/integrated_circuit/manipulation/ai
name = "integrated intelligence control circuit"
- desc = "Similar in structure to a intellicard, this circuit allows the AI to pulse four different activators for control of a circuit."
+ desc = "Similar in structure to a intelliCard, this circuit allows the AI to pulse four different activators for control of a circuit."
extended_desc = "Loading an AI is easy, all that is required is to insert the container into the device's slot. Unloading is a similar process, simply press\
down on the device in question and the device/card should pop out (if applicable)."
icon_state = "ai"
diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm
index 5255d8469c87..777bc82a7b46 100644
--- a/code/modules/integrated_electronics/subtypes/reagents.dm
+++ b/code/modules/integrated_electronics/subtypes/reagents.dm
@@ -343,7 +343,7 @@
/obj/item/integrated_circuit/reagent/storage/grinder
name = "reagent grinder"
- desc = "This is a reagent grinder. It accepts a ref to something, and refines it into reagents. It cannot grind materials. It can store up to 100u."
+ desc = "This is a reagent grinder. It accepts a ref to something and refines it into reagents. It cannot grind materials and can store up to 100u."
icon_state = "blender"
extended_desc = ""
inputs = list(
diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm
index f92af368dcd8..4f2781f5c11f 100644
--- a/code/modules/integrated_electronics/subtypes/smart.dm
+++ b/code/modules/integrated_electronics/subtypes/smart.dm
@@ -4,7 +4,7 @@
/obj/item/integrated_circuit/smart/basic_pathfinder
name = "basic pathfinder"
desc = "This complex circuit is able to determine what direction a given target is."
- extended_desc = "This circuit uses a miniturized integrated camera to determine where the target is. If the machine \
+ extended_desc = "This circuit uses a miniaturized integrated camera to determine where the target is. If the machine \
cannot see the target, it will not be able to calculate the correct direction."
icon_state = "numberpad"
complexity = 5
diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm
index 30d2a47b29b5..c7fae9674340 100644
--- a/code/modules/lighting/lighting_overlay.dm
+++ b/code/modules/lighting/lighting_overlay.dm
@@ -146,7 +146,7 @@
SHOULD_CALL_PARENT(FALSE)
return
-/atom/movable/lighting_overlay/can_fall()
+/atom/movable/lighting_overlay/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
return FALSE
// Override here to prevent things accidentally moving around overlays.
diff --git a/code/modules/locks/lock_construct.dm b/code/modules/locks/lock_construct.dm
index a1060c0063db..0a27464efde2 100644
--- a/code/modules/locks/lock_construct.dm
+++ b/code/modules/locks/lock_construct.dm
@@ -1,6 +1,6 @@
/obj/item/lock_construct
name = "lock"
- desc = "a simple tumbler lock and bolt, suitable for affixing to a door or closet."
+ desc = "A simple tumbler lock and bolt, suitable for affixing to a door or closet."
icon = 'icons/obj/items/doorlock.dmi'
icon_state = "lock_construct"
w_class = ITEM_SIZE_TINY
diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm
index 5b201f4509da..4ef94c9de02c 100644
--- a/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm
+++ b/code/modules/maps/template_types/random_exoplanet/planet_types/shrouded.dm
@@ -4,7 +4,7 @@
/obj/effect/overmap/visitable/sector/planetoid/exoplanet/shrouded
name = "shrouded exoplanet"
- desc = "An exoplanet shrouded in a perpetual storm of bizzare, light absorbing particles."
+ desc = "An exoplanet shrouded in a perpetual storm of bizarre, light-absorbing particles."
color = "#783ca4"
/obj/effect/overmap/visitable/sector/planetoid/exoplanet/shrouded/get_atmosphere_color()
diff --git a/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm b/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm
index 83421bfc4168..8947d15a5de3 100644
--- a/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm
+++ b/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm
@@ -132,7 +132,7 @@
//Always keep the overmap marker in sync if we have one set already
try_update_overmap_marker()
-// ** Bunch of overridables below **
+// ** Bunch of overrideables below **
///Sets the name of the planetoid, and causes updates to happen to anything linked to us.
/datum/planetoid_data/proc/SetName(var/newname)
diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm
index 6617c5c2a1e5..d5965e1caa12 100644
--- a/code/modules/materials/_materials.dm
+++ b/code/modules/materials/_materials.dm
@@ -193,6 +193,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
var/max_fluid_opacity = FLUID_MAX_ALPHA
/// Point at which the fluid will proc turf interaction logic. Workaround for mops being ruined forever by 1u of anything else being added.
var/turf_touch_threshold = FLUID_QDEL_POINT
+ /// Whether or not billets of this material will glow with heat.
+ var/glows_with_heat = FALSE
// Damage values.
var/hardness = MAT_VALUE_HARD // Used for edge damage in weapons.
@@ -303,7 +305,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
var/scent //refer to _scent.dm
var/scent_intensity = /decl/scent_intensity/normal
- var/scent_descriptor = SCENT_DESC_SMELL
+ var/scent_descriptor = "smell"
var/scent_range = 1
var/list/neutron_interactions // Associative List of potential neutron interactions for the material to undergo, corresponding to the ideal
@@ -366,11 +368,17 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
/// If an item has a null paint_verb, it automatically sets it based on material.
var/paint_verb = "painted"
+ /// What word is used to describe an item covered in/stained by this by default?
+ /// Can be overridden by get_coated_adjective().
+ var/coated_adjective = "stained"
+
/// Chance of a natural wall made of this material dropping a gemstone, if the gemstone_types list is populated.
var/gemstone_chance = 5
/// Assoc weighted list of gemstone material types to weighting.
var/list/gemstone_types
+ var/forgable = FALSE // Can this material be forged in bar/billet form?
+
// Placeholders for light tiles and rglass.
/decl/material/proc/reinforce(var/mob/user, var/obj/item/stack/material/used_stack, var/obj/item/stack/material/target_stack, var/use_sheets = 1)
if(!used_stack.can_use(use_sheets))
@@ -444,6 +452,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
burn_product = null
vapor_products = null
compost_value = 0
+ forgable = FALSE
else if(isnull(temperature_damage_threshold))
var/new_temperature_damage_threshold = max(melting_point, boiling_point, heating_point)
// Don't let the threshold be lower than the ignition point.
@@ -1215,3 +1224,28 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
/// If any value below 0 is returned, it doesn't start processing.
/decl/material/proc/get_time_to_dry_stain(obj/effect/decal/cleanable/blood/stain)
return initial(stain.time_to_dry)
+
+// TODO: Maybe make this use a strengths system like taste?
+/// Returns a string to describe an item coated with this reagent (and others).
+/// Receives the coating reagent holder as an argument, so coating.my_atom is accessible
+/// and it can also conditionally use a different string for primary/non-primary materials, or
+/// if another liquid is present, e.g. 'wet bloody muddy shoes'.
+/decl/material/proc/get_coated_adjective(datum/reagents/coating)
+ var/used_color = get_reagent_color(coating)
+ if(get_config_value(/decl/config/enum/colored_coating_names) == CONFIG_COATING_COLOR_COMPONENTS)
+ return FONT_COLORED(used_color, coated_adjective)
+ return coated_adjective
+
+/// Gets the name used to describe a coating with this material as its primary reagent.
+/// This is mostly for handling special cases like mud.
+/decl/material/proc/get_primary_coating_name(datum/reagents/coating)
+ // this should probably respect current phase/solution/etc better, but coating sure doesn't
+ return get_reagent_name(coating, phase_at_temperature())
+
+/// Builds a string to describe a coating made up of this reagent (and others).
+/// This reagent will never be the primary reagent, however; that's handled in get_primary_coating_name.
+/// Receives the coating as an argument like get_coated_adjective, but also receives the accumulator list
+/// for more complex behaviors like adding to the start. It can't reliably handle things like removing
+/// another entry because ordering is not guaranteed, so beware if you need something like that.
+/decl/material/proc/build_coated_name(datum/reagents/coating, list/accumulator)
+ accumulator |= get_coated_adjective(coating)
diff --git a/code/modules/materials/definitions/gasses/material_gas_mundane.dm b/code/modules/materials/definitions/gasses/material_gas_mundane.dm
index 394b1580c170..9ed5c8ded417 100644
--- a/code/modules/materials/definitions/gasses/material_gas_mundane.dm
+++ b/code/modules/materials/definitions/gasses/material_gas_mundane.dm
@@ -1,7 +1,7 @@
/decl/material/gas/oxygen
name = "oxygen"
uid = "gas_oxygen"
- lore_text = "An ubiquitous oxidizing agent."
+ lore_text = "A ubiquitous oxidizing agent."
flags = MAT_FLAG_FUSION_FUEL
gas_specific_heat = 20
molar_mass = 0.032
@@ -72,19 +72,15 @@
warning_prob = 15
M.take_damage(10, OXY,20)
if(istype(H))
- SET_HUD_ALERT(H, /decl/hud_element/condition/carbon_dioxide, 1)
+ SET_HUD_ALERT(H, HUD_OXY, 1)
else if(dosage >= 1.5)
warning_message = pick("dizzy","short of breath","faint","momentarily confused")
M.take_damage(3, OXY,5)
if(istype(H))
- SET_HUD_ALERT(H, /decl/hud_element/condition/carbon_dioxide, 1)
+ SET_HUD_ALERT(H, HUD_OXY, 1)
else if(dosage >= 0.25)
warning_message = pick("a little dizzy","short of breath")
warning_prob = 10
- if(istype(H))
- SET_HUD_ALERT(H, /decl/hud_element/condition/carbon_dioxide, 0)
- else if(istype(H))
- SET_HUD_ALERT(H, /decl/hud_element/condition/carbon_dioxide, 0)
if(istype(H) && dosage > 1 && H.ticks_since_last_successful_breath < 15)
H.ticks_since_last_successful_breath++
if(warning_message && prob(warning_prob))
@@ -153,7 +149,7 @@
/decl/material/gas/nitrogen
name = "nitrogen"
uid = "gas_nitrogen"
- lore_text = "An ubiquitous noble gas."
+ lore_text = "A ubiquitous noble gas."
gas_specific_heat = 20
molar_mass = 0.028
latent_heat = 199
diff --git a/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm b/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm
index bb527d7123d3..f7d289cc8693 100644
--- a/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm
+++ b/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm
@@ -1,7 +1,7 @@
/decl/material/liquid/surfactant // Foam precursor
name = "surfactant"
uid = "liquid_surfactant"
- lore_text = "A isocyanate liquid that forms a foam when mixed with water."
+ lore_text = "An isocyanate liquid that forms a foam when mixed with water."
taste_description = "metal"
color = "#9e6b38"
value = 0.1
@@ -10,7 +10,7 @@
/decl/material/liquid/foaming_agent // Metal foaming agent. This is lithium hydride. Add other recipes (e.g. LiH + H2O -> LiOH + H2) eventually.
name = "foaming agent"
uid = "liquid_foaming_agent"
- lore_text = "A agent that yields metallic foam when mixed with light metal and a strong acid."
+ lore_text = "An agent that yields metallic foam when mixed with light metal and a strong acid."
taste_description = "metal"
color = "#664b63"
value = 0.1
@@ -25,6 +25,7 @@
value = 0.1
slipperiness = 80
exoplanet_rarity_gas = MAT_RARITY_EXOTIC
+ coated_adjective = "oily"
// Prevent oil stains from drying.
/decl/material/liquid/lube/get_time_to_dry_stain(obj/effect/decal/cleanable/blood/stain)
diff --git a/code/modules/materials/definitions/liquids/materials_liquid_solvents.dm b/code/modules/materials/definitions/liquids/materials_liquid_solvents.dm
index ec78c02b460f..58d11660565d 100644
--- a/code/modules/materials/definitions/liquids/materials_liquid_solvents.dm
+++ b/code/modules/materials/definitions/liquids/materials_liquid_solvents.dm
@@ -31,7 +31,7 @@
/decl/material/liquid/acid/polyacid
name = "polytrinic acid"
uid = "liquid_polytrinic_acid"
- lore_text = "Polytrinic acid is a an extremely corrosive chemical substance."
+ lore_text = "Polytrinic acid is an extremely corrosive chemical substance."
taste_description = "acid"
color = "#8e18a9"
solvent_power = MAT_SOLVENT_STRONGEST
diff --git a/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm b/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm
index 3b42ee375e46..08eaa22b0c95 100644
--- a/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm
+++ b/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm
@@ -210,7 +210,9 @@
/decl/material/liquid/tar
name = "tar"
+ solid_name = "asphalt"
uid = "liquid_tar"
+ coated_adjective = "tarry"
lore_text = "A dark, viscous liquid."
taste_description = "petroleum"
color = "#140b30"
diff --git a/code/modules/materials/definitions/liquids/materials_liquid_water.dm b/code/modules/materials/definitions/liquids/materials_liquid_water.dm
index efb84cdf8e7f..099b762761fb 100644
--- a/code/modules/materials/definitions/liquids/materials_liquid_water.dm
+++ b/code/modules/materials/definitions/liquids/materials_liquid_water.dm
@@ -31,6 +31,28 @@
)
temperature_burn_milestone_material = /decl/material/liquid/water
can_boil_to_gas = TRUE
+ coated_adjective = "wet"
+
+/decl/material/liquid/water/build_coated_name(datum/reagents/coating, list/accumulator)
+ if(length(coating.reagent_volumes) > 1)
+ accumulator.Insert(1, "dilute") // dilute always comes first! also this is intentionally not colored in component color mode
+ return // don't insert 'wet'
+ ..()
+
+// make salty water named saltwater
+/decl/material/liquid/water/get_reagent_name(datum/reagents/holder, phase = MAT_PHASE_LIQUID)
+ if(phase == MAT_PHASE_LIQUID && holder?.get_primary_reagent_decl() == src)
+ if(REAGENT_VOLUME(holder, /decl/material/solid/sodiumchloride))
+ return "saltwater"
+ return ..() // just use the default handling
+
+// make pure water named fresh water
+/decl/material/liquid/water/get_reagent_name(datum/reagents/holder, phase = MAT_PHASE_LIQUID)
+ . = ..()
+ // length == 1 implies primary reagent, so checking both is redundant
+ if(phase == MAT_PHASE_LIQUID && length(holder?.reagent_volumes) == 1)
+ return "fresh [.]"
+ return
/decl/material/liquid/water/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder)
..()
diff --git a/code/modules/materials/definitions/solids/materials_solid_ice.dm b/code/modules/materials/definitions/solids/materials_solid_ice.dm
index b37ec038e84c..a86600f193db 100644
--- a/code/modules/materials/definitions/solids/materials_solid_ice.dm
+++ b/code/modules/materials/definitions/solids/materials_solid_ice.dm
@@ -35,6 +35,7 @@
solid_name = "snow"
gas_name = "steam"
adjective_name = "snow"
+ coated_adjective = "snowy"
color = COLOR_WHITE
codex_name = null
uid = "solid_snow"
diff --git a/code/modules/materials/definitions/solids/materials_solid_metal.dm b/code/modules/materials/definitions/solids/materials_solid_metal.dm
index 1b22aae712d7..51f1a2db4bfd 100644
--- a/code/modules/materials/definitions/solids/materials_solid_metal.dm
+++ b/code/modules/materials/definitions/solids/materials_solid_metal.dm
@@ -20,6 +20,8 @@
icon_reinf = 'icons/turf/walls/reinforced_metal.dmi'
exoplanet_rarity_gas = MAT_RARITY_NOWHERE
tensile_strength = 0.8 // metal wire is probably better than plastic?
+ forgable = TRUE
+ glows_with_heat = TRUE
/decl/material/solid/metal/uranium
name = "uranium"
diff --git a/code/modules/materials/definitions/solids/materials_solid_mineral.dm b/code/modules/materials/definitions/solids/materials_solid_mineral.dm
index bd0b1ca1ad4d..9b619de94902 100644
--- a/code/modules/materials/definitions/solids/materials_solid_mineral.dm
+++ b/code/modules/materials/definitions/solids/materials_solid_mineral.dm
@@ -279,6 +279,17 @@
/decl/flooring/mud,
/decl/flooring/dirt
)
+ solution_name = "mud"
+ coated_adjective = "muddy"
+
+// todo: make mud either its own material or a mix of dirt and water
+// or let dirt be in the liquid volumes list for mud?
+// would a ball of mud just be a ball of dirt coated with water?
+// or would water be part of its matter?
+// well anyway.
+// for now, at least, we assume dirt coatings are always mud.
+/decl/material/solid/soil/get_primary_coating_name(datum/reagents/coating)
+ return solution_name
/decl/material/solid/hematite
name = "hematite"
diff --git a/code/modules/materials/material_sheets_mapping.dm b/code/modules/materials/material_sheets_mapping.dm
index 1e17f9f3851f..49be21fa79f4 100644
--- a/code/modules/materials/material_sheets_mapping.dm
+++ b/code/modules/materials/material_sheets_mapping.dm
@@ -122,6 +122,9 @@ STACK_SUBTYPES(titanium, "titanium", solid/metal/tita
STACK_SUBTYPES(cotton, "cotton", solid/organic/cloth, thread, null)
STACK_SUBTYPES(dried_gut, "dried gut", solid/organic/leather/gut, thread, null)
+STACK_SUBTYPES(iron, "iron", solid/metal/iron, bar, null)
+STACK_SUBTYPES(copper, "copper", solid/metal/copper, bar, null)
+
STACK_SUBTYPES(chipboard_oak, "oak chipboard", solid/organic/wood/chipboard, sheet, null)
STACK_SUBTYPES(chipboard_maple, "maple chipboard", solid/organic/wood/chipboard/maple, sheet, null)
STACK_SUBTYPES(chipboard_mahogany, "mahogany chipboard", solid/organic/wood/chipboard/mahogany, sheet, null)
@@ -129,4 +132,5 @@ STACK_SUBTYPES(chipboard_ebony, "ebony chipboard", solid/organic/wood/chip
STACK_SUBTYPES(chipboard_walnut, "walnut chipboard", solid/organic/wood/chipboard/walnut, sheet, null)
STACK_SUBTYPES(chipboard_yew, "yew chipboard", solid/organic/wood/chipboard/yew, sheet, null)
+
#undef STACK_SUBTYPES
\ No newline at end of file
diff --git a/code/modules/mechs/components/armour.dm b/code/modules/mechs/components/armour.dm
index b86d67295dc3..a5c122dfadea 100644
--- a/code/modules/mechs/components/armour.dm
+++ b/code/modules/mechs/components/armour.dm
@@ -17,7 +17,7 @@
/obj/item/robot_parts/robot_component/armour/exosuit/radproof
name = "radiation-proof armour plating"
- desc = "A fully enclosed radiation hardened shell designed to protect the pilot from radiation"
+ desc = "A fully enclosed radiation hardened shell designed to protect the pilot from radiation."
armor = list(
ARMOR_MELEE = ARMOR_MELEE_RESISTANT,
ARMOR_BULLET = ARMOR_BALLISTIC_PISTOL,
@@ -32,7 +32,7 @@
/obj/item/robot_parts/robot_component/armour/exosuit/em
name = "EM-shielded armour plating"
- desc = "A shielded plating that sorrounds the eletronics and protects them from electromagnetic radiation"
+ desc = "A shielded plating that surrounds sensitive electronic components and protects them from electromagnetic radiation."
armor = list(
ARMOR_MELEE = ARMOR_MELEE_RESISTANT ,
ARMOR_BULLET = ARMOR_BALLISTIC_SMALL,
@@ -48,7 +48,7 @@
/obj/item/robot_parts/robot_component/armour/exosuit/combat
name = "heavy combat plating"
- desc = "Plating designed to deflect incoming attacks and explosions"
+ desc = "Plating designed to deflect incoming attacks and explosions."
armor = list(
ARMOR_MELEE = ARMOR_MELEE_MAJOR,
ARMOR_BULLET = ARMOR_BALLISTIC_RESISTANT,
diff --git a/code/modules/mechs/equipment/medical.dm b/code/modules/mechs/equipment/medical.dm
index 4aadea64370d..b9f6b5da59b6 100644
--- a/code/modules/mechs/equipment/medical.dm
+++ b/code/modules/mechs/equipment/medical.dm
@@ -1,6 +1,6 @@
/obj/item/mech_equipment/sleeper
name = "\improper exosuit sleeper"
- desc = "An exosuit-mounted sleeper designed to mantain patients stabilized on their way to medical facilities."
+ desc = "An exosuit-mounted sleeper designed to maintain patients stabilized on their way to medical facilities."
icon_state = "mech_sleeper"
restricted_hardpoints = list(HARDPOINT_BACK)
restricted_software = list(MECH_SOFTWARE_MEDICAL)
@@ -65,6 +65,9 @@
add_reagent_canister(null, new /obj/item/chems/chem_disp_cartridge/antitoxins())
add_reagent_canister(null, new /obj/item/chems/chem_disp_cartridge/oxy_meds())
+/obj/machinery/sleeper/mounted/DefaultTopicState()
+ return global.mech_topic_state
+
/obj/machinery/sleeper/mounted/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = global.mech_topic_state)
. = ..()
diff --git a/code/modules/mechs/equipment/utility.dm b/code/modules/mechs/equipment/utility.dm
index b5fb55b0461e..02bd1abf172a 100644
--- a/code/modules/mechs/equipment/utility.dm
+++ b/code/modules/mechs/equipment/utility.dm
@@ -572,7 +572,7 @@
/obj/item/gun/energy/plasmacutter/mounted/mech/auto
charge_cost = 13
name = "rotatory plasma cutter"
- desc = "A state of the art rotating, variable intensity, sequential-cascade plasma cutter. Resist the urge to aim this at your coworkers."
+ desc = "A state-of-the-art rotating, variable intensity, sequential-cascade plasma cutter. Resist the urge to aim this at your coworkers."
max_shots = 15
firemodes = list(
list(mode_name="single shot", autofire_enabled=0, burst=1, fire_delay=6, dispersion = list(0.0)),
@@ -604,17 +604,14 @@
QDEL_NULL(ion_trail)
return ..()
-/obj/item/mech_equipment/ionjets/proc/allowSpaceMove()
- if (!active)
+/obj/item/mech_equipment/ionjets/proc/provides_thrust()
+ if(!active)
return FALSE
-
- var/obj/item/cell/C = owner.get_cell()
- if (istype(C))
- if (C.checked_use(movement_power * CELLRATE))
+ var/obj/item/cell/cell = owner?.get_cell()
+ if(istype(cell))
+ if(cell.checked_use(movement_power * CELLRATE))
return TRUE
- else
- deactivate()
-
+ deactivate()
return FALSE
/obj/item/mech_equipment/ionjets/attack_self(mob/user)
diff --git a/code/modules/mechs/interface/_interface.dm b/code/modules/mechs/interface/_interface.dm
index 6395e7d10d82..e314bcf27a81 100644
--- a/code/modules/mechs/interface/_interface.dm
+++ b/code/modules/mechs/interface/_interface.dm
@@ -23,8 +23,7 @@
/obj/screen/zone_selector/exosuit
requires_ui_style = FALSE
-/mob/living/exosuit/InitializeHud()
- zone_sel = new /obj/screen/zone_selector/exosuit(null, src)
+/mob/living/exosuit/initialize_hud()
if(!LAZYLEN(hud_elements))
var/i = 1
for(var/hardpoint in hardpoints)
diff --git a/code/modules/mechs/mech.dm b/code/modules/mechs/mech.dm
index 809f205d2bdc..899c1d05203f 100644
--- a/code/modules/mechs/mech.dm
+++ b/code/modules/mechs/mech.dm
@@ -128,7 +128,7 @@
desc = "[desc] It has been built with [english_list(component_descriptions)]."
// Create HUD.
- InitializeHud()
+ initialize_hud()
// Build icon.
queue_icon_update()
diff --git a/code/modules/mechs/mech_interaction.dm b/code/modules/mechs/mech_interaction.dm
index 1a8c959d3ffd..f67589fa7a40 100644
--- a/code/modules/mechs/mech_interaction.dm
+++ b/code/modules/mechs/mech_interaction.dm
@@ -134,10 +134,8 @@
// User is not necessarily the exosuit, or the same person, so update intent.
if(user != src)
set_intent(user.get_intent())
- if(user.zone_sel)
- zone_sel.set_selected_zone(user.get_target_zone())
- else
- zone_sel.set_selected_zone(BP_CHEST)
+ set_target_zone(user.get_target_zone())
+
// You may attack the target with your exosuit FIST if you're malfunctioning.
var/atom/movable/AM = A
var/fail_prob = (user != src && istype(AM) && AM.loc != src) ? (user.skill_check(SKILL_MECH, HAS_PERK) ? 0: 15 ) : 0
diff --git a/code/modules/mechs/mech_movement.dm b/code/modules/mechs/mech_movement.dm
index 3fc3f1c25376..790bce7f715c 100644
--- a/code/modules/mechs/mech_movement.dm
+++ b/code/modules/mechs/mech_movement.dm
@@ -12,7 +12,7 @@
if(!isspaceturf(loc))
playsound(src.loc, mech_step_sound, 40, 1)
for(var/mob/pilot as anything in pilots)
- pilot.up_hint?.update_icon()
+ pilot.refresh_hud_element(HUD_UP_HINT)
//Inertia drift making us face direction makes exosuit flight a bit difficult, plus newtonian flight model yo
/mob/living/exosuit/set_dir(ndir)
@@ -20,9 +20,9 @@
return ..(dir)
return ..(ndir)
-/mob/living/exosuit/can_fall(var/anchor_bypass = FALSE, var/turf/location_override = src.loc)
+/mob/living/exosuit/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
//mechs are always anchored, so falling should always ignore it
- if(..(TRUE, location_override))
+ if((. = ..(TRUE, location_override)))
return !(can_overcome_gravity())
//For swimming
@@ -116,7 +116,7 @@
// Space movement
/datum/movement_handler/mob/space/exosuit/DoMove(direction, mob/mover, is_external)
- if(!mob.has_gravity() && (!allow_move || (allow_move == -1 && mob.handle_spaceslipping())))
+ if(!mob.has_gravity() && (last_space_move_result == SPACE_MOVE_FORBIDDEN || (last_space_move_result == SPACE_MOVE_SUPPORTED && mob.handle_spaceslipping())))
return MOVEMENT_HANDLED
mob.inertia_dir = 0
@@ -125,53 +125,46 @@
return MOVEMENT_PROCEED
if(!mob.has_gravity())
- allow_move = mob.Process_Spacemove(1)
- if(!allow_move)
+ last_space_move_result = mob.is_space_movement_permitted(allow_movement = TRUE)
+ if(last_space_move_result == SPACE_MOVE_FORBIDDEN)
return MOVEMENT_STOP
return MOVEMENT_PROCEED
-/mob/living/exosuit/Check_Shoegrip()//mechs are always magbooting
+/mob/living/exosuit/has_non_slip_footing()
return TRUE
-/mob/living/exosuit/Process_Spacemove(allow_movement)
- //Regardless of modules, emp prevents control
+/mob/living/exosuit/has_magnetised_footing()
+ return TRUE
- if(has_gravity() || throwing || !isturf(loc) || length(grabbed_by) || check_space_footing() || locate(/obj/structure/lattice) in range(1, get_turf(src)))
+/mob/living/exosuit/is_space_movement_permitted(allow_movement = FALSE)
+ . = SPACE_MOVE_FORBIDDEN
+ anchored = FALSE
+ //Regardless of modules, emp prevents control
+ if(has_gravity() || throwing || !isturf(loc) || length(grabbed_by) || !can_slip(magboots_only = TRUE) || locate(/obj/structure/lattice) in range(1, get_turf(src)))
+ . = SPACE_MOVE_PERMITTED
+ else
+ var/obj/item/mech_equipment/ionjets/J = hardpoints[HARDPOINT_BACK]
+ if(istype(J) && ((allow_movement || J.stabilizers) && J.provides_thrust()))
+ . = SPACE_MOVE_PERMITTED
+ if(. == SPACE_MOVE_PERMITTED)
anchored = TRUE
- return TRUE
- var/obj/item/mech_equipment/ionjets/J = hardpoints[HARDPOINT_BACK]
- if(istype(J) && ((allow_movement || J.stabilizers) && J.allowSpaceMove()))
- return TRUE
-
- anchored = FALSE
- return FALSE
-
-/mob/living/exosuit/check_space_footing() //mechs can't push off things to move around in space, they stick to hull or float away
- if(has_gravity())
- return TRUE
- for(var/thing in RANGE_TURFS(src, 1))
- var/turf/T = thing
- if(T.density || T.is_wall() || T.is_floor())
- return T
-
-/mob/living/exosuit/space_do_move(allow_move)
- if(allow_move == 1)
+/mob/living/exosuit/try_space_move(space_move_result, direction)
+ if(space_move_result == SPACE_MOVE_PERMITTED)
if(emp_damage >= EMP_MOVE_DISRUPT && prob(25))
var/obj/item/mech_equipment/ionjets/J = hardpoints[HARDPOINT_BACK]
- if(istype(J) && J.allowSpaceMove())
+ if(istype(J) && J.provides_thrust())
to_chat(src, SPAN_WARNING("\The [J] misfire, drifting \the [src] off course!"))
SetMoveCooldown(15) //2 seconds of random rando panic drifting
step(src, pick(global.alldirs))
- return 0
-
- . = ..()
+ return FALSE
+ return ..()
/mob/living/exosuit/overmap_can_discard()
for(var/atom/movable/AM in contents)
if(!AM.overmap_can_discard())
return FALSE
- return !pilots.len
+ return LAZYLEN(pilots) <= 0
/mob/living/exosuit/fall_damage()
return 175 //Exosuits are big and heavy
diff --git a/code/modules/mechs/mech_wreckage.dm b/code/modules/mechs/mech_wreckage.dm
index eb23590ea088..3f0c08020156 100644
--- a/code/modules/mechs/mech_wreckage.dm
+++ b/code/modules/mechs/mech_wreckage.dm
@@ -1,6 +1,6 @@
/obj/structure/mech_wreckage
name = "wreckage"
- desc = "It might have some salvagable parts."
+ desc = "It might have some salvageable parts."
density = TRUE
opacity = TRUE
anchored = TRUE
diff --git a/code/modules/mechs/premade/_premade.dm b/code/modules/mechs/premade/_premade.dm
index 77914bfc25d1..6498521605a7 100644
--- a/code/modules/mechs/premade/_premade.dm
+++ b/code/modules/mechs/premade/_premade.dm
@@ -40,7 +40,7 @@
/mob/living/exosuit/premade/random
name = "mismatched exosuit"
- desc = "It seems to have been roughly thrown together and then spraypainted a single colour."
+ desc = "It seems to have been roughly thrown together and then spray-painted a single colour."
/mob/living/exosuit/premade/random/Initialize(mapload, var/obj/structure/heavy_vehicle_frame/source_frame, var/super_random = FALSE, var/using_boring_colours = FALSE)
var/list/use_colours
diff --git a/code/modules/merchant/merchant_guns.dm b/code/modules/merchant/merchant_guns.dm
index e41d3d480e9d..939a570aab1f 100644
--- a/code/modules/merchant/merchant_guns.dm
+++ b/code/modules/merchant/merchant_guns.dm
@@ -12,5 +12,5 @@
return ..()
/obj/item/gun/projectile/automatic/smg/usi
- desc = "A cheap mass produced SMG. This one looks especially run-down. Uses pistol rounds."
+ desc = "A cheap mass-produced SMG. This one looks especially run-down. Uses pistol rounds."
jam_chance = 20
\ No newline at end of file
diff --git a/code/modules/mining/machinery/material_smelter.dm b/code/modules/mining/machinery/material_smelter.dm
index 263e0f797c75..3d54d262330b 100644
--- a/code/modules/mining/machinery/material_smelter.dm
+++ b/code/modules/mining/machinery/material_smelter.dm
@@ -96,8 +96,9 @@
SSmaterials.create_object(mtype, output_turf, samt)
remove_from_reagents(mtype, ramt)
-/obj/machinery/material_processing/smeltery/Topic(var/user, var/list/href_list)
- . = ..()
+/obj/machinery/material_processing/smeltery/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["toggle_alloying"])
if(atom_flags & ATOM_FLAG_NO_REACT)
diff --git a/code/modules/mining/machinery/material_stacker.dm b/code/modules/mining/machinery/material_stacker.dm
index 4db34e69b37f..593137e6e404 100644
--- a/code/modules/mining/machinery/material_stacker.dm
+++ b/code/modules/mining/machinery/material_stacker.dm
@@ -44,9 +44,11 @@
qdel(S)
if(emagged)
- for(var/mob/living/M in input_turf)
- visible_message(SPAN_DANGER("\The [src] squashes \the [src] with its stacking mechanism!"))
- M.take_overall_damage(rand(10, 20), 0)
+ for(var/mob/living/victim in input_turf)
+ if(!victim.simulated)
+ continue
+ visible_message(SPAN_DANGER("\The [src] squashes \the [victim] with its stacking mechanism!"))
+ victim.take_overall_damage(rand(10, 20), 0)
break
if(output_turf)
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index 7621e897fc81..5836b2ed9796 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -29,7 +29,7 @@
// Flags.
/obj/item/stack/flag
name = "beacon"
- desc = "Some deployable high-visibilty beacons."
+ desc = "Some deployable high-visibility beacons."
singular_name = "beacon"
icon_state = "folded"
amount = 10
diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm
index 2933c0b83fc4..574b2f558962 100644
--- a/code/modules/mob/animations.dm
+++ b/code/modules/mob/animations.dm
@@ -11,7 +11,7 @@
stop_floating()
return
- if(check_space_footing())
+ if(!can_slip(magboots_only = TRUE))
stop_floating()
return
diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm
index 4986952e1305..0ae0efae9437 100644
--- a/code/modules/mob/death.dm
+++ b/code/modules/mob/death.dm
@@ -102,15 +102,6 @@
SSstatistics.report_death(src)
- //TODO: Change death state to health_dead for all these icon files. This is a stop gap.
- if(healths)
- healths.overlays.Cut() // This is specific to humans but the relevant code is here; shouldn't mess with other mobs.
- if("health7" in icon_states(healths.icon))
- healths.icon_state = "health7"
- else
- healths.icon_state = "health6"
- log_debug("[src] ([src.type]) died but does not have a valid health7 icon_state (using health6 instead). report this error to Ccomp5950 or your nearest Developer")
-
timeofdeath = world.time
if(mind)
mind.StoreMemory("Time of death: [stationtime2text()]", /decl/memory_options/system)
diff --git a/code/modules/mob/grab/grab_object.dm b/code/modules/mob/grab/grab_object.dm
index 8efb2c19fb99..d5a9c3c8705c 100644
--- a/code/modules/mob/grab/grab_object.dm
+++ b/code/modules/mob/grab/grab_object.dm
@@ -55,8 +55,9 @@
update_icon()
events_repository.register(/decl/observ/moved, affecting, src, PROC_REF(on_affecting_move))
- if(assailant.zone_sel)
- events_repository.register(/decl/observ/zone_selected, assailant.zone_sel, src, PROC_REF(on_target_change))
+ var/obj/screen/zone_selector/zone_selector = assailant.get_hud_element(HUD_ZONE_SELECT)
+ if(zone_selector)
+ events_repository.register(/decl/observ/zone_selected, zone_selector, src, PROC_REF(on_target_change))
var/obj/item/organ/O = get_targeted_organ()
var/decl/pronouns/pronouns = assailant.get_pronouns()
@@ -138,8 +139,9 @@
affecting.reset_plane_and_layer()
affecting = null
if(assailant)
- if(assailant.zone_sel)
- events_repository.unregister(/decl/observ/zone_selected, assailant.zone_sel, src)
+ var/obj/screen/zone_selector/zone_selector = assailant.get_hud_element(HUD_ZONE_SELECT)
+ if(zone_selector)
+ events_repository.unregister(/decl/observ/zone_selected, zone_selector, src)
assailant = null
. = ..()
if(old_affecting)
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index f4482ab7e987..a1f9db81bd94 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -451,7 +451,7 @@
/mob/proc/item_should_have_screen_presence(obj/item/item, slot)
if(!slot || !istype(hud_used))
return FALSE
- if(hud_used.inventory_shown)
+ if(hud_used.is_inventory_shown())
return TRUE
var/datum/inventory_slot/inv_slot = get_inventory_slot_datum(slot)
return !(inv_slot?.can_be_hidden)
@@ -466,7 +466,8 @@
return
/mob/proc/select_held_item_slot(var/slot)
- return
+ SHOULD_CALL_PARENT(TRUE)
+ clear_available_intents()
/mob/proc/get_inventory_slots()
return
diff --git a/code/modules/mob/language/synthetic.dm b/code/modules/mob/language/synthetic.dm
index 99fc6d544994..6f8a751bcac5 100644
--- a/code/modules/mob/language/synthetic.dm
+++ b/code/modules/mob/language/synthetic.dm
@@ -1,7 +1,7 @@
/decl/language/machine
name = "Encoded Audio Language"
shorthand = "EAL"
- desc = "A efficient language of encoded tones used by synthetics."
+ desc = "An efficient language of encoded tones used by synthetics."
speech_verb = "whistles"
ask_verb = "chirps"
exclaim_verb = "whistles loudly"
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index 8a31af021dc1..3665f8d4c729 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -11,9 +11,11 @@
stop_aiming(no_message=1)
if(istype(ai))
ai.handle_death(gibbed)
+ handle_regular_hud_updates() // Update health icon etc.
var/decl/species/my_species = get_species()
if(my_species)
if(!gibbed && my_species.death_sound)
playsound(loc, my_species.death_sound, 80, 1, 1)
my_species.handle_death(src)
+
diff --git a/code/modules/mob/living/default_language.dm b/code/modules/mob/living/default_language.dm
index 6aba0abfb624..4a7384299ea2 100644
--- a/code/modules/mob/living/default_language.dm
+++ b/code/modules/mob/living/default_language.dm
@@ -25,10 +25,6 @@
to_chat(src, "You will now speak whatever your standard default language is if you do not specify one when speaking.")
default_language = language?.type
-// Silicons can't neccessarily speak everything in their languages list
-/mob/living/silicon/set_default_language(language)
- ..()
-
/mob/living/verb/check_default_language()
set name = "Check Default Language"
set category = "IC"
diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm
index 095c0b5067c8..7d6a018fa64b 100644
--- a/code/modules/mob/living/human/human.dm
+++ b/code/modules/mob/living/human/human.dm
@@ -37,7 +37,6 @@
LAZYCLEARLIST(smell_cooldown)
- QDEL_NULL(attack_selector)
QDEL_NULL(vessel)
QDEL_NULL(touching)
diff --git a/code/modules/mob/living/human/human_attackhand.dm b/code/modules/mob/living/human/human_attackhand.dm
index d32ec613162e..490e3d5f3dae 100644
--- a/code/modules/mob/living/human/human_attackhand.dm
+++ b/code/modules/mob/living/human/human_attackhand.dm
@@ -409,7 +409,7 @@
var/image/radial_button = new
radial_button.name = capitalize(u_attack.name)
LAZYSET(choices, u_attack, radial_button)
- var/decl/natural_attack/new_attack = show_radial_menu(src, (attack_selector || src), choices, radius = 42, use_labels = RADIAL_LABELS_OFFSET)
+ var/decl/natural_attack/new_attack = show_radial_menu(src, src, choices, radius = 42, use_labels = RADIAL_LABELS_OFFSET)
if(QDELETED(src) || !istype(new_attack) || !(new_attack in get_mob_natural_attacks()))
return
default_attack = new_attack
@@ -418,7 +418,7 @@
var/summary = default_attack.summarize()
if(summary)
to_chat(src, SPAN_NOTICE(summary))
- attack_selector?.update_icon()
+ refresh_hud_element(HUD_ATTACK)
/mob/living/human/UnarmedAttack(atom/A, proximity_flag)
// Hackfix for humans trying to attack someone without hands.
diff --git a/code/modules/mob/living/human/human_defines.dm b/code/modules/mob/living/human/human_defines.dm
index be736a3eb0d7..8108d6b8d3ee 100644
--- a/code/modules/mob/living/human/human_defines.dm
+++ b/code/modules/mob/living/human/human_defines.dm
@@ -14,7 +14,6 @@
var/damage_multiplier = 1
var/list/worn_underwear = list()
var/list/background_info = list()
- var/obj/screen/default_attack_selector/attack_selector
var/icon/stand_icon = null
/// Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life()
var/voice = ""
diff --git a/code/modules/mob/living/human/human_internals.dm b/code/modules/mob/living/human/human_internals.dm
index f77c5000586f..cbfe23386d37 100644
--- a/code/modules/mob/living/human/human_internals.dm
+++ b/code/modules/mob/living/human/human_internals.dm
@@ -4,5 +4,4 @@
/mob/living/human/set_internals(obj/item/tank/source, source_string)
..()
internal = source
- if(internals)
- internals.icon_state = "internal[!!internal]"
+ refresh_hud_element(HUD_INTERNALS)
diff --git a/code/modules/mob/living/human/human_movement.dm b/code/modules/mob/living/human/human_movement.dm
index 39f3c3a28416..a3af65028c19 100644
--- a/code/modules/mob/living/human/human_movement.dm
+++ b/code/modules/mob/living/human/human_movement.dm
@@ -65,41 +65,19 @@
. = ..()
. += species.strength
-/mob/living/human/space_do_move(var/allow_move, var/direction)
- if(allow_move == 1)
+/mob/living/human/try_space_move(space_move_result, direction)
+ if(space_move_result == SPACE_MOVE_PERMITTED)
var/obj/item/tank/jetpack/thrust = get_jetpack()
if(thrust && thrust.on && prob(skill_fail_chance(SKILL_EVA, 10, SKILL_ADEPT)))
- to_chat(src, "You fumble with [thrust] controls!")
+ to_chat(src, SPAN_WARNING("You fumble with the controls of \the [thrust]!"))
if(prob(50))
thrust.toggle()
if(prob(50))
thrust.stabilization_on = 0
SetMoveCooldown(15) //2 seconds of random rando panic drifting
step(src, pick(global.alldirs))
- return 0
-
- . = ..()
-
-/mob/living/human/slip_chance(var/prob_slip = 5)
- if(!..())
- return 0
- //Check hands and mod slip
- for(var/hand_slot in get_held_item_slots())
- var/datum/inventory_slot/inv_slot = get_inventory_slot_datum(hand_slot)
- var/obj/item/held = inv_slot?.get_equipped_item()
- if(!held)
- prob_slip -= 2
- else if(held.w_class <= ITEM_SIZE_SMALL)
- prob_slip -= 1
- return prob_slip
-
-/mob/living/human/Check_Shoegrip()
- if(species.check_no_slip(src))
- return 1
- var/obj/item/shoes = get_equipped_item(slot_shoes_str)
- if(shoes && (shoes.item_flags & ITEM_FLAG_NOSLIP) && istype(shoes, /obj/item/clothing/shoes/magboots)) //magboots + dense_object = no floating
- return 1
- return 0
+ return FALSE
+ return ..()
/mob/living/human/Move()
. = ..()
@@ -117,8 +95,6 @@
handle_leg_damage()
species.handle_post_move(src)
- if(client)
- up_hint.update_icon()
/mob/living/human/proc/handle_leg_damage()
if(!can_feel_pain())
diff --git a/code/modules/mob/living/human/human_species.dm b/code/modules/mob/living/human/human_species.dm
index c499bbb2da2e..90977e6035a7 100644
--- a/code/modules/mob/living/human/human_species.dm
+++ b/code/modules/mob/living/human/human_species.dm
@@ -56,7 +56,7 @@
/mob/living/human/dummy/mannequin/fully_replace_character_name(new_name, in_depth = TRUE)
..("[new_name] (mannequin)", FALSE)
-/mob/living/human/dummy/mannequin/InitializeHud()
+/mob/living/human/dummy/mannequin/initialize_hud()
return // Mannequins don't get HUDs
/mob/living/human/monkey
diff --git a/code/modules/mob/living/human/human_verbs.dm b/code/modules/mob/living/human/human_verbs.dm
index a43f889eb110..6eb933776124 100644
--- a/code/modules/mob/living/human/human_verbs.dm
+++ b/code/modules/mob/living/human/human_verbs.dm
@@ -270,7 +270,7 @@
usr.setClickCooldown(20)
if(usr.stat > 0)
- to_chat(usr, "You are unconcious and cannot do that!")
+ to_chat(usr, "You are unconscious and cannot do that!")
return
if(usr.restrained())
diff --git a/code/modules/mob/living/human/life.dm b/code/modules/mob/living/human/life.dm
index ebc47ef12025..b8de66f65755 100644
--- a/code/modules/mob/living/human/life.dm
+++ b/code/modules/mob/living/human/life.dm
@@ -49,8 +49,8 @@
add_stressor(/datum/stressor/fatigued, 5 MINUTES)
if(MOVING_QUICKLY(src))
set_moving_slowly()
- if(last_stamina != stamina && istype(hud_used))
- hud_used.update_stamina()
+ if(last_stamina != stamina)
+ refresh_hud_element(HUD_STAMINA)
/mob/living/human/proc/handle_stamina()
if((world.time - last_quick_move_time) > 5 SECONDS)
@@ -85,7 +85,7 @@
return pressure_adjustment_coefficient
-// Calculate how much of the enviroment pressure-difference affects the human.
+// Calculate how much of the environment pressure-difference affects the human.
/mob/living/human/calculate_affecting_pressure(var/pressure)
var/pressure_difference
@@ -181,7 +181,7 @@
var/loc_temp = environment.temperature
if(adjusted_pressure < species.get_warning_high_pressure(src) && adjusted_pressure > species.get_warning_low_pressure(src) && abs(loc_temp - bodytemperature) < 20 && bodytemperature < get_mob_temperature_threshold(HEAT_LEVEL_1) && bodytemperature > get_mob_temperature_threshold(COLD_LEVEL_1) && species.body_temperature)
- SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, 0)
+ SET_HUD_ALERT(src, HUD_PRESSURE, 0)
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
//Body temperature adjusts depending on surrounding atmosphere based on your thermal protection (convection)
@@ -210,10 +210,10 @@
else
burn_dam = HEAT_DAMAGE_LEVEL_3
take_overall_damage(burn=burn_dam, used_weapon = "High Body Temperature")
- SET_HUD_ALERT_MAX(src, /decl/hud_element/condition/fire, 2)
+ SET_HUD_ALERT_MAX(src, HUD_FIRE, 2)
else if(bodytemperature <= get_mob_temperature_threshold(COLD_LEVEL_1))
- SET_HUD_ALERT_MAX(src, /decl/hud_element/condition/fire, 1)
+ SET_HUD_ALERT_MAX(src, HUD_FIRE, 1)
if(status_flags & GODMODE) return 1 //godmode
var/burn_dam = 0
@@ -227,7 +227,7 @@
set_stasis(get_cryogenic_factor(bodytemperature), STASIS_COLD)
if(!has_chemical_effect(CE_CRYO, 1))
take_overall_damage(burn=burn_dam, used_weapon = "Low Body Temperature")
- SET_HUD_ALERT_MAX(src, /decl/hud_element/condition/fire, 1)
+ SET_HUD_ALERT_MAX(src, HUD_FIRE, 1)
// Account for massive pressure differences. Done by Polymorph
// Made it possible to actually have something that can protect against high pressure... Done by Errorage. Polymorph now has an axe sticking from his head for his previous hardcoded nonsense!
@@ -237,13 +237,13 @@
if(adjusted_pressure >= high_pressure)
var/pressure_damage = min( ( (adjusted_pressure / high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)
take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure")
- SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, 2)
+ SET_HUD_ALERT(src, HUD_PRESSURE, 2)
else if(adjusted_pressure >= species.get_warning_high_pressure(src))
- SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, 1)
+ SET_HUD_ALERT(src, HUD_PRESSURE, 1)
else if(adjusted_pressure >= species.get_warning_low_pressure(src))
- SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, 0)
+ SET_HUD_ALERT(src, HUD_PRESSURE, 0)
else if(adjusted_pressure >= species.get_hazard_low_pressure(src))
- SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, -1)
+ SET_HUD_ALERT(src, HUD_PRESSURE, -1)
else
var/list/obj/item/organ/external/parts = get_damageable_organs()
for(var/obj/item/organ/external/O in parts)
@@ -253,7 +253,7 @@
O.take_external_damage(brute = LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure")
if(getOxyLossPercent() < 55) // 11 OxyLoss per 4 ticks when wearing internals; unconsciousness in 16 ticks, roughly half a minute
take_damage(4) // 16 OxyLoss per 4 ticks when no internals present; unconsciousness in 13 ticks, OXY, roughly twenty seconds
- SET_HUD_ALERT(src, /decl/hud_element/condition/pressure, -2)
+ SET_HUD_ALERT(src, HUD_PRESSURE, -2)
return
@@ -464,130 +464,6 @@
else
clear_fullscreen("brute")
- if(healths)
-
- var/mutable_appearance/healths_ma = new(healths)
- healths_ma.icon_state = "blank"
- healths_ma.overlays = null
-
- if(has_chemical_effect(CE_PAINKILLER, 100))
- healths_ma.icon_state = "health_numb"
- else
- // Generate a by-limb health display.
- var/no_damage = 1
- var/trauma_val = 0 // Used in calculating softcrit/hardcrit indicators.
- if(can_feel_pain())
- trauma_val = max(shock_stage,get_shock())/(species.total_health-100)
- // Collect and apply the images all at once to avoid appearance churn.
- var/list/health_images = list()
- for(var/obj/item/organ/external/E in get_external_organs())
- if(no_damage && (E.brute_dam || E.burn_dam))
- no_damage = 0
- var/damage_image = E.get_damage_hud_image()
- if(damage_image)
- health_images += damage_image
-
-
- // Apply a fire overlay if we're burning.
- var/crit_markers = get_ui_icon(client?.prefs?.UI_style, UI_ICON_CRIT_MARKER)
- if(is_on_fire())
- health_images += image(crit_markers, "burning")
-
- // Show a general pain/crit indicator if needed.
- if(is_asystole())
- health_images += image(crit_markers, "hardcrit")
- else if(trauma_val)
- if(can_feel_pain())
- if(trauma_val > 0.7)
- health_images += image(crit_markers, "softcrit")
- if(trauma_val >= 1)
- health_images += image(crit_markers, "hardcrit")
- else if(no_damage)
- health_images += image(crit_markers, "fullhealth")
- healths_ma.overlays += health_images
- healths.appearance = healths_ma
-
- if(nutrition_icon)
- switch(nutrition)
- if(450 to INFINITY) nutrition_icon.icon_state = "nutrition0"
- if(350 to 450) nutrition_icon.icon_state = "nutrition1"
- if(250 to 350) nutrition_icon.icon_state = "nutrition2"
- if(150 to 250) nutrition_icon.icon_state = "nutrition3"
- else nutrition_icon.icon_state = "nutrition4"
-
- if(hydration_icon)
- switch(hydration)
- if(450 to INFINITY) hydration_icon.icon_state = "hydration0"
- if(350 to 450) hydration_icon.icon_state = "hydration1"
- if(250 to 350) hydration_icon.icon_state = "hydration2"
- if(150 to 250) hydration_icon.icon_state = "hydration3"
- else hydration_icon.icon_state = "hydration4"
-
- if(isSynthetic())
- var/obj/item/organ/internal/cell/C = get_organ(BP_CELL, /obj/item/organ/internal/cell)
- if(C)
- var/chargeNum = clamp(ceil(C.percent()/25), 0, 4) //0-100 maps to 0-4, but give it a paranoid clamp just in case.
- cells.icon_state = "charge[chargeNum]"
- else
- cells.icon_state = "charge-empty"
-
- if(pressure)
- pressure.icon_state = "pressure[GET_HUD_ALERT(src, /decl/hud_element/condition/pressure)]"
- if(toxin)
- toxin.icon_state = "tox[GET_HUD_ALERT(src, /decl/hud_element/condition/toxins)]"
- if(oxygen)
- oxygen.icon_state = "oxy[GET_HUD_ALERT(src, /decl/hud_element/condition/oxygen)]"
- if(fire)
- fire.icon_state = "fire[GET_HUD_ALERT(src, /decl/hud_element/condition/fire)]"
-
- if(bodytemp)
- if (!species)
- switch(bodytemperature) //310.055 optimal body temp
- if(370 to INFINITY) bodytemp.icon_state = "temp4"
- if(350 to 370) bodytemp.icon_state = "temp3"
- if(335 to 350) bodytemp.icon_state = "temp2"
- if(320 to 335) bodytemp.icon_state = "temp1"
- if(300 to 320) bodytemp.icon_state = "temp0"
- if(295 to 300) bodytemp.icon_state = "temp-1"
- if(280 to 295) bodytemp.icon_state = "temp-2"
- if(260 to 280) bodytemp.icon_state = "temp-3"
- else bodytemp.icon_state = "temp-4"
- else
- var/heat_1 = get_mob_temperature_threshold(HEAT_LEVEL_1)
- var/cold_1 = get_mob_temperature_threshold(COLD_LEVEL_1)
- //TODO: precalculate all of this stuff when the species datum is created
- var/base_temperature = species.body_temperature
- if(base_temperature == null) //some species don't have a set metabolic temperature
- base_temperature = (heat_1 + cold_1)/2
-
- var/temp_step
- if (bodytemperature >= base_temperature)
- temp_step = (heat_1 - base_temperature)/4
-
- if (bodytemperature >= heat_1)
- bodytemp.icon_state = "temp4"
- else if (bodytemperature >= base_temperature + temp_step*3)
- bodytemp.icon_state = "temp3"
- else if (bodytemperature >= base_temperature + temp_step*2)
- bodytemp.icon_state = "temp2"
- else if (bodytemperature >= base_temperature + temp_step*1)
- bodytemp.icon_state = "temp1"
- else
- bodytemp.icon_state = "temp0"
-
- else if (bodytemperature < base_temperature)
- temp_step = (base_temperature - cold_1)/4
-
- if (bodytemperature <= cold_1)
- bodytemp.icon_state = "temp-4"
- else if (bodytemperature <= base_temperature - temp_step*3)
- bodytemp.icon_state = "temp-3"
- else if (bodytemperature <= base_temperature - temp_step*2)
- bodytemp.icon_state = "temp-2"
- else if (bodytemperature <= base_temperature - temp_step*1)
- bodytemp.icon_state = "temp-1"
- else
- bodytemp.icon_state = "temp0"
return 1
/mob/living/human/handle_random_events()
diff --git a/code/modules/mob/living/human/update_icons.dm b/code/modules/mob/living/human/update_icons.dm
index eafc3556942a..ff824d2389b8 100644
--- a/code/modules/mob/living/human/update_icons.dm
+++ b/code/modules/mob/living/human/update_icons.dm
@@ -356,5 +356,5 @@ Please contact me on #coderbus IRC. ~Carn x
set_current_mob_overlay(HO_CONDITION_LAYER, condition_overlays, update_icons)
/mob/living/human/hud_reset(full_reset = FALSE)
- if((. = ..()) && internals && internal)
- internals.icon_state = "internal1"
+ if((. = ..()))
+ refresh_hud_element(HUD_INTERNALS)
diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm
index f0ab7bdc92eb..cbfd9853c9cc 100644
--- a/code/modules/mob/living/inventory.dm
+++ b/code/modules/mob/living/inventory.dm
@@ -58,12 +58,12 @@
queue_hand_rebuild()
/mob/living/select_held_item_slot(var/slot)
+ . = ..()
var/last_slot = get_active_held_item_slot()
if(slot != last_slot && (slot in get_held_item_slots()))
_held_item_slot_selected = slot
if(istype(hud_used))
- for(var/atom/hand as anything in hud_used.hand_hud_objects)
- hand.update_icon()
+ hud_used.update_hand_elements()
var/obj/item/I = get_active_held_item()
if(istype(I))
I.on_active_hand()
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 05d2002770b4..7c8dd1bf7c89 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -448,6 +448,10 @@
SHOULD_CALL_PARENT(TRUE)
if(!should_do_hud_updates())
return FALSE
+
+ if(istype(hud_used))
+ hud_used.handle_life_hud_update()
+
handle_hud_icons()
handle_vision()
handle_low_light_vision()
@@ -554,12 +558,9 @@
if(prob(current_size*5) && hand.w_class >= (11-current_size)/2 && try_unequip(hand))
to_chat(src, SPAN_WARNING("\The [S] pulls \the [hand] from your grip!"))
hand.singularity_pull(S, current_size)
- var/obj/item/shoes = get_equipped_item(slot_shoes_str)
- if(!current_posture.prone && !(shoes?.item_flags & ITEM_FLAG_NOSLIP))
- var/decl/species/my_species = get_species()
- if(!my_species?.check_no_slip(src) && prob(current_size*5))
- to_chat(src, SPAN_DANGER("A strong gravitational force slams you to the ground!"))
- SET_STATUS_MAX(src, STAT_WEAK, current_size)
+ if(prob(current_size*5) && can_slip())
+ to_chat(src, SPAN_DANGER("A strong gravitational force slams you to the ground!"))
+ SET_STATUS_MAX(src, STAT_WEAK, current_size)
apply_damage(current_size * 3, IRRADIATE, damage_flags = DAM_DISPERSED)
return ..()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index dcbc0d2917ea..44e8324fcc03 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -351,7 +351,7 @@ default behaviour is:
switch_from_dead_to_living_mob_list()
timeofdeath = 0
- // restore us to conciousness
+ // restore us to consciousness
set_stat(CONSCIOUS)
// make the icons look correct
@@ -521,6 +521,7 @@ default behaviour is:
var/turf/old_loc = loc
. = ..()
if(.)
+ refresh_hud_element(HUD_UP_HINT)
handle_grabs_after_move(old_loc, Dir)
if(active_storage && !active_storage.can_view(src))
active_storage.close(src)
@@ -646,7 +647,7 @@ default behaviour is:
set category = "IC"
// No posture, no adjustment.
- if(length(get_available_postures()) <= 1 || incapacitated(INCAPACITATION_KNOCKOUT) || !canClick())
+ if(length(get_available_postures()) <= 1 || incapacitated(INCAPACITATION_KNOCKDOWN) || !canClick())
return
var/list/selectable_postures = get_selectable_postures()
@@ -667,18 +668,18 @@ default behaviour is:
selected_posture = selectable_postures[1]
else
selected_posture = input(src, "Which posture do you wish to adopt?", "Change Posture", current_posture) as null|anything in selectable_postures
- if(!selected_posture || length(get_available_postures()) <= 1 || incapacitated(INCAPACITATION_KNOCKOUT) || !canClick())
+ if(!selected_posture || length(get_available_postures()) <= 1 || incapacitated(INCAPACITATION_KNOCKDOWN) || !canClick())
return
if(current_posture == selected_posture || !(selected_posture in get_selectable_postures()))
return
setClickCooldown(3)
- to_chat(src, SPAN_NOTICE("You are now [selected_posture.posture_change_message]."))
if(current_posture.prone && !selected_posture.prone)
- if(!do_after(src, 2 SECONDS, src, incapacitation_flags = ~INCAPACITATION_FORCELYING))
+ if(!do_after(src, 2 SECONDS, src, incapacitation_flags = INCAPACITATION_KNOCKDOWN))
return
if(current_posture == selected_posture || !(selected_posture in get_selectable_postures()))
return
+ to_chat(src, SPAN_NOTICE("You are now [selected_posture.posture_change_message]."))
set_posture(selected_posture)
//called when the mob receives a bright flash
@@ -699,27 +700,13 @@ default behaviour is:
. = ..() || is_floating
/mob/living/proc/slip(slipped_on, stun_duration = 8)
-
- if(immune_to_floor_hazards())
- return FALSE
-
- var/decl/species/my_species = get_species()
- if(my_species?.check_no_slip(src))
- return FALSE
-
- var/obj/item/shoes = get_equipped_item(slot_shoes_str)
- if(shoes && (shoes.item_flags & ITEM_FLAG_NOSLIP))
- return FALSE
-
- if(has_gravity() && !buckled && !current_posture?.prone)
+ if(can_slip())
to_chat(src, SPAN_DANGER("You slipped on [slipped_on]!"))
playsound(loc, 'sound/misc/slip.ogg', 50, 1, -3)
SET_STATUS_MAX(src, STAT_WEAK, stun_duration)
return TRUE
-
return FALSE
-
/mob/living/human/canUnEquip(obj/item/I)
. = ..() && !(I in get_organs())
@@ -1084,7 +1071,7 @@ default behaviour is:
if(user.mob_size >= exosuit.body.min_pilot_size && user.mob_size <= exosuit.body.max_pilot_size)
exosuit.enter(src)
else
- to_chat(user, SPAN_WARNING("You cannot pilot a exosuit of this size."))
+ to_chat(user, SPAN_WARNING("You cannot pilot an exosuit of this size."))
return TRUE
. = ..()
@@ -1134,20 +1121,21 @@ default behaviour is:
if(A.CheckRemoval(src))
A.Remove(src)
for(var/obj/item/I in src)
- if(I.action_button_name)
- if(!I.action)
- I.action = new I.default_action_type
- I.action.name = I.action_button_name
- I.action.desc = I.action_button_desc
- I.action.SetTarget(I)
- I.action.Grant(src)
+ if(QDELETED(I))
+ continue
+ if(!I.action_button_name)
+ continue
+ I.action ||= new I.default_action_type
+ I.action.name = I.action_button_name
+ I.action.desc = I.action_button_desc
+ I.action.SetTarget(I)
+ I.action.Grant(src)
return
/mob/living/update_action_buttons()
if(!istype(hud_used) || !client)
return
-
- if(hud_used.hud_shown != 1) //Hud toggled to minimal
+ if(!hud_used.is_hud_shown()) //Hud toggled to minimal
return
client.screen -= hud_used.hide_actions_toggle
@@ -1181,13 +1169,14 @@ default behaviour is:
client.screen += hud_used.hide_actions_toggle
/mob/living/handle_fall_effect(var/turf/landing)
- ..()
- if(istype(landing) && !landing.is_open())
- apply_fall_damage(landing)
- if(client)
- var/area/A = get_area(landing)
- if(A)
- A.alert_on_fall(src)
+ if(!(. = ..()) || !istype(landing))
+ return
+ apply_fall_damage(landing)
+ if(!client)
+ return
+ var/area/landing_area = get_area(landing)
+ if(landing_area)
+ landing_area.alert_on_fall(src)
/mob/living/proc/apply_fall_damage(var/turf/landing)
take_damage(rand(max(1, ceil(mob_size * 0.33)), max(1, ceil(mob_size * 0.66))) * get_fall_height())
@@ -2025,6 +2014,10 @@ default behaviour is:
update_equipment_overlay(slot_shoes_str)
return TRUE
+/mob/living/get_cell()
+ var/obj/item/organ/internal/cell/cell = get_organ(BP_CELL, /obj/item/organ/internal/cell)
+ return istype(cell) ? cell.cell : null
+
/mob/living/verb/pull_punches()
set name = "Switch Stance"
set desc = "Try not to hurt them."
@@ -2032,3 +2025,4 @@ default behaviour is:
if(!incapacitated())
pulling_punches = !pulling_punches
to_chat(src, SPAN_NOTICE("You are now [pulling_punches ? "pulling your punches" : "not pulling your punches"]."))
+
diff --git a/code/modules/mob/living/living_breath.dm b/code/modules/mob/living/living_breath.dm
index 01d9ecc93b4c..164a8503215e 100644
--- a/code/modules/mob/living/living_breath.dm
+++ b/code/modules/mob/living/living_breath.dm
@@ -106,8 +106,7 @@
else
check_for_airtight_internals()
var/obj/item/tank/new_internals = get_internals()
- if(internals && old_internals != new_internals)
- internals.icon_state = "internal[!!new_internals]"
+ refresh_hud_element(HUD_INTERNALS)
if(istype(new_internals))
return new_internals.remove_air_volume(volume_needed)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index fc07b274edcf..f6b7d220a18d 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -244,7 +244,7 @@
if(anchored || buckled)
return 0
. = (AM.get_mass()*TT.speed)/(get_mass()*min(AM.throw_speed,2))
- if(has_gravity() || check_space_footing())
+ if(!can_slip(magboots_only = TRUE))
. *= 0.5
/mob/living/proc/try_embed_in_mob(mob/living/user, obj/O, def_zone, embed_damage = 0, dtype = BRUTE, datum/wound/supplied_wound, obj/item/organ/external/affecting, direction)
diff --git a/code/modules/mob/living/living_maneuvers.dm b/code/modules/mob/living/living_maneuvers.dm
index 2afaa16ad4c0..8e925ee5cce8 100644
--- a/code/modules/mob/living/living_maneuvers.dm
+++ b/code/modules/mob/living/living_maneuvers.dm
@@ -25,13 +25,13 @@
forceMove(get_turf(origin))
prepared_maneuver.perform(src, check, get_acrobatics_multiplier(prepared_maneuver), reflexively = TRUE)
prepared_maneuver = null
- maneuver_icon?.update_icon()
+ refresh_hud_element(HUD_MANEUVER)
/mob/living/proc/try_maneuver(var/atom/target)
if(prepared_maneuver && (isturf(target) || isturf(target.loc))) // Avoid trying to jump at your backpack contents.
prepared_maneuver.perform(src, get_turf(target), get_acrobatics_multiplier(prepared_maneuver))
prepared_maneuver = null
- maneuver_icon?.update_icon()
+ refresh_hud_element(HUD_MANEUVER)
return TRUE
return FALSE
@@ -63,14 +63,14 @@
else
prepared_maneuver = null
to_chat(src, SPAN_NOTICE("You are no longer preparing to perform a maneuver."))
- maneuver_icon?.update_icon()
+ refresh_hud_element(HUD_MANEUVER)
/mob/living/proc/perform_maneuver(var/maneuver, var/atom/target)
var/decl/maneuver/performing_maneuver = ispath(maneuver) ? GET_DECL(maneuver) : maneuver
if(istype(performing_maneuver))
. = performing_maneuver.perform(src, target, get_acrobatics_multiplier(performing_maneuver))
prepared_maneuver = null
- maneuver_icon?.update_icon()
+ refresh_hud_element(HUD_MANEUVER)
/mob/living/proc/get_acrobatics_multiplier(var/decl/maneuver/attempting_maneuver)
return 1
diff --git a/code/modules/mob/living/living_throw.dm b/code/modules/mob/living/living_throw.dm
index b65ec9889e96..9fc36c7b2aa5 100644
--- a/code/modules/mob/living/living_throw.dm
+++ b/code/modules/mob/living/living_throw.dm
@@ -90,7 +90,7 @@
//actually throw it!
visible_message(SPAN_WARNING(message), range = min(itemsize*2,world.view))
lastarea = lastarea || get_area(loc)
- if(!check_space_footing() && prob((itemsize * itemsize * 10) * MOB_SIZE_MEDIUM/mob_size))
+ if(can_slip(magboots_only = TRUE) && prob((itemsize * itemsize * 10) * MOB_SIZE_MEDIUM/mob_size))
var/direction = get_dir(target, src)
step(src, direction)
space_drift(direction)
diff --git a/code/modules/mob/living/silicon/ai/ai_radio.dm b/code/modules/mob/living/silicon/ai/ai_radio.dm
index c9a32ee9cd33..7a195abc9bac 100644
--- a/code/modules/mob/living/silicon/ai/ai_radio.dm
+++ b/code/modules/mob/living/silicon/ai/ai_radio.dm
@@ -2,7 +2,7 @@
name = "\improper AI subspace transceiver"
desc = "Integrated AI radio transceiver."
encryption_keys = list(/obj/item/encryptionkey/heads/ai_integrated)
- var/disabledAi = 0 // Atlantis: Used to manually disable AI's integrated radio via inteliCard menu.
+ var/disabledAi = 0 // Atlantis: Used to manually disable AI's integrated radio via intelliCard menu.
/obj/item/radio/headset/heads/ai_integrated/get_accessible_channel_descriptions(mob/user)
. = ..()
diff --git a/code/modules/mob/living/silicon/ai/power.dm b/code/modules/mob/living/silicon/ai/power.dm
index 9d9206348df5..1785b37ecb5c 100644
--- a/code/modules/mob/living/silicon/ai/power.dm
+++ b/code/modules/mob/living/silicon/ai/power.dm
@@ -85,7 +85,7 @@
-// Handles all necessary power checks: Area power, inteliCard and Malf AI APU power and manual override.
+// Handles all necessary power checks: Area power, intelliCard and Malf AI APU power and manual override.
/mob/living/silicon/ai/proc/has_power(var/respect_override = 1)
if(psupply && !(psupply.stat & NOPOWER))
return 1
@@ -214,7 +214,7 @@
update_use_power(get_power_state())
/obj/machinery/ai_powersupply/proc/get_power_state()
- // Dead, powered by APU, admin power, or inside an item (inteliCard/IIS). No power usage.
+ // Dead, powered by APU, admin power, or inside an item (intelliCard/IIS). No power usage.
if(!powered_ai.stat == DEAD || powered_ai.admin_powered || istype(powered_ai.loc, /obj/item/))
return 0
// Normal power usage.
diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm
index 606dbce9d2b0..689e7211132a 100644
--- a/code/modules/mob/living/silicon/robot/analyzer.dm
+++ b/code/modules/mob/living/silicon/robot/analyzer.dm
@@ -57,7 +57,7 @@
user.show_message(text("\t []: [][] - [] - [] - []", \
capitalize(org.name), \
(org.installed == -1) ? "DESTROYED " :"",\
- (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \
+ (org.burn_damage > 0) ? "[org.burn_damage]" :0, \
(org.brute_damage > 0) ? "[org.brute_damage]" :0, \
(org.toggled) ? "Toggled ON" : "Toggled OFF",\
(org.powered) ? "Power ON" : "Power OFF"),1)
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index bab525146e14..137c8c9fd44d 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -1,21 +1,23 @@
// TODO: remove the robot.central_processor and robot.cell variables and completely rely on the robot component system
-
-/datum/robot_component/var/name
-/datum/robot_component/var/installed = 0
-/datum/robot_component/var/powered = 0
-/datum/robot_component/var/toggled = 1
-/datum/robot_component/var/brute_damage = 0
-/datum/robot_component/var/electronics_damage = 0
-/datum/robot_component/var/idle_usage = 0 // Amount of power used every MC tick. In joules.
-/datum/robot_component/var/active_usage = 0 // Amount of power used for every action. Actions are module-specific. Actuator for each tile moved, etc.
-/datum/robot_component/var/max_damage = 30 // HP of this component.
-/datum/robot_component/var/mob/living/silicon/robot/owner
-
-// The actual device object that has to be installed for this.
-/datum/robot_component/var/external_type = null
-
-// The wrapped device(e.g. radio), only set if external_type isn't null
-/datum/robot_component/var/obj/item/wrapped = null
+/datum/robot_component
+ var/name
+ /// Installation status; not a bool, may be -1, 0 or 1.
+ var/installed = 0
+ var/powered = FALSE
+ var/toggled = TRUE
+ var/brute_damage = 0
+ var/burn_damage = 0
+ /// Amount of power used every MC tick. In joules.
+ var/idle_usage = 0
+ /// Amount of power used for every action. Actions are module-specific. Actuator for each tile moved, etc.
+ var/active_usage = 0
+ /// HP of this component.
+ var/max_damage = 30
+ var/mob/living/silicon/robot/owner
+ /// The actual device object that has to be installed for this.
+ var/external_type
+ /// The wrapped device(e.g. radio), only set if external_type isn't null
+ var/obj/item/wrapped
/datum/robot_component/New(mob/living/silicon/robot/R)
src.owner = R
@@ -56,9 +58,9 @@
if(installed != 1) return
brute_damage += brute
- electronics_damage += electronics
+ burn_damage += electronics
- if(brute_damage + electronics_damage >= max_damage) destroy()
+ if(brute_damage + burn_damage >= max_damage) destroy()
/datum/robot_component/proc/heal_damage(brute, electronics)
if(installed != 1)
@@ -66,10 +68,10 @@
return 0
brute_damage = max(0, brute_damage - brute)
- electronics_damage = max(0, electronics_damage - electronics)
+ burn_damage = max(0, burn_damage - electronics)
/datum/robot_component/proc/is_powered()
- return (installed == 1) && (brute_damage + electronics_damage < max_damage) && (!idle_usage || powered)
+ return (installed == 1) && (brute_damage + burn_damage < max_damage) && (!idle_usage || powered)
/datum/robot_component/proc/update_power_state()
if(toggled == 0)
@@ -111,7 +113,7 @@
//A fixed and much cleaner implementation of /tg/'s special snowflake code.
/datum/robot_component/actuator/is_powered()
- return (installed == 1) && (brute_damage + electronics_damage < max_damage)
+ return (installed == 1) && (brute_damage + burn_damage < max_damage)
// POWER CELL
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index 90516b063816..e01e0ad52802 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -241,10 +241,6 @@
if(amount && should_be_dead() && stat == DEAD && !QDELETED(src))
gib()
-//DRONE MOVEMENT.
-/mob/living/silicon/robot/drone/slip_chance(var/prob_slip)
- return 0
-
//CONSOLE PROCS
/mob/living/silicon/robot/drone/proc/law_resync()
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm
index 41ef351a6119..7c6bfc00f010 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm
@@ -37,79 +37,71 @@
return
-/obj/machinery/computer/drone_control/Topic(href, href_list)
+/obj/machinery/computer/drone_control/OnTopic(mob/user, href_list)
if((. = ..()))
return
- if(!allowed(usr))
- to_chat(usr, "Access denied.")
- return
-
- if ((usr.contents.Find(src) || (in_range(src, usr) && isturf(src.loc))) || (issilicon(usr)))
- usr.set_machine(src)
+ if(!allowed(user))
+ to_chat(user, "Access denied.")
+ return TOPIC_HANDLED
if (href_list["setarea"])
-
//Probably should consider using another list, but this one will do.
var/t_area = input("Select the area to ping.", "Set Target Area", null) as null|anything in global.tagger_locations
-
if(!t_area)
- return
-
+ return TOPIC_HANDLED
drone_call_area = t_area
- to_chat(usr, "You set the area selector to [drone_call_area].")
+ to_chat(user, "You set the area selector to [drone_call_area].")
+ . = TOPIC_REFRESH
else if (href_list["ping"])
-
- to_chat(usr, "You issue a maintenance request for all active drones, highlighting [drone_call_area].")
+ to_chat(user, "You issue a maintenance request for all active drones, highlighting [drone_call_area].")
for(var/mob/living/silicon/robot/drone/D in global.silicon_mob_list)
if(D.client && D.stat == CONSCIOUS)
to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].")
+ . = TOPIC_REFRESH
else if (href_list["resync"])
-
var/mob/living/silicon/robot/drone/D = locate(href_list["resync"])
-
+ . = TOPIC_HANDLED
if(D.stat != DEAD)
- to_chat(usr, "You issue a law synchronization directive for the drone.")
+ to_chat(user, "You issue a law synchronization directive for the drone.")
D.law_resync()
+ . = TOPIC_REFRESH
else if (href_list["shutdown"])
-
var/mob/living/silicon/robot/drone/D = locate(href_list["shutdown"])
-
+ . = TOPIC_HANDLED
if(D.stat != DEAD)
- to_chat(usr, "You issue a kill command for the unfortunate drone.")
- message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
- log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.")
+ to_chat(user, "You issue a kill command for the unfortunate drone.")
+ message_admins("[key_name_admin(user)] issued kill order for drone [key_name_admin(D)] from control console.")
+ log_game("[key_name(user)] issued kill order for [key_name(src)] from control console.")
D.shut_down()
+ . = TOPIC_REFRESH
else if (href_list["search_fab"])
if(dronefab)
- return
+ return TOPIC_HANDLED
for(var/obj/machinery/drone_fabricator/fab in oview(3,src))
-
if(fab.stat & NOPOWER)
continue
-
dronefab = fab
- to_chat(usr, "Drone fabricator located.")
- return
+ to_chat(user, "Drone fabricator located.")
+ return TOPIC_REFRESH
- to_chat(usr, "Unable to locate drone fabricator.")
+ to_chat(user, "Unable to locate drone fabricator.")
+ . = TOPIC_HANDLED
else if (href_list["toggle_fab"])
-
if(!dronefab)
- return
+ return TOPIC_HANDLED
if(get_dist(src,dronefab) > 3)
dronefab = null
- to_chat(usr, "Unable to locate drone fabricator.")
- return
+ to_chat(user, "Unable to locate drone fabricator.")
+ return TOPIC_REFRESH
dronefab.produce_drones = !dronefab.produce_drones
- to_chat(usr, "You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.")
-
- src.updateUsrDialog()
+ to_chat(user, "You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.")
+ . = TOPIC_REFRESH
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_say.dm b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
index c547137d1250..e4d40ac20dfe 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_say.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
@@ -21,7 +21,7 @@
if(istype(L))
return L.broadcast(src,trim(copytext(message,2)))
- //Must be concious to speak
+ //Must be conscious to speak
if (stat)
return 0
diff --git a/code/modules/mob/living/silicon/robot/flying/flying.dm b/code/modules/mob/living/silicon/robot/flying/flying.dm
index 42d6b717d938..7733ed989851 100644
--- a/code/modules/mob/living/silicon/robot/flying/flying.dm
+++ b/code/modules/mob/living/silicon/robot/flying/flying.dm
@@ -1,5 +1,5 @@
/mob/living/silicon/robot/flying
- desc = "A utility robot with an anti-gravity hover unit and a lightweight frame."
+ desc = "A utility robot with an antigravity hover unit and a lightweight frame."
icon = 'icons/mob/robots/flying/flying.dmi'
module_category = ROBOT_MODULE_TYPE_FLYING
dismantle_type = /obj/item/robot_parts/robot_suit/flyer
@@ -43,11 +43,11 @@
if(. && !gibbed)
stop_flying()
-/mob/living/silicon/robot/flying/Process_Spacemove()
- return (pass_flags & PASS_FLAG_TABLE) || ..()
+/mob/living/silicon/robot/flying/is_space_movement_permitted(allow_movement = FALSE)
+ return (pass_flags & PASS_FLAG_TABLE) ? SPACE_MOVE_PERMITTED : ..()
-/mob/living/silicon/robot/flying/can_fall(var/anchor_bypass = FALSE, var/turf/location_override = loc)
- return !Process_Spacemove()
+/mob/living/silicon/robot/flying/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
+ return is_space_movement_permitted() == SPACE_MOVE_FORBIDDEN
/mob/living/silicon/robot/flying/can_overcome_gravity()
- return Process_Spacemove()
+ return is_space_movement_permitted() != SPACE_MOVE_FORBIDDEN
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index 4e2bc0fe3cf5..ea41b012d303 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -100,89 +100,6 @@
if (MED_HUD)
process_med_hud(src,0,network = get_computer_network())
- if(length(get_active_grabs()))
- ui_drop_grab.set_invisibility(INVISIBILITY_NONE)
- ui_drop_grab.alpha = 255
- else
- ui_drop_grab.set_invisibility(INVISIBILITY_ABSTRACT)
- ui_drop_grab.alpha = 0
-
- if (src.healths)
- if (src.stat != DEAD)
- if(isdrone(src))
- switch(current_health)
- if(35 to INFINITY)
- src.healths.icon_state = "health0"
- if(25 to 34)
- src.healths.icon_state = "health1"
- if(15 to 24)
- src.healths.icon_state = "health2"
- if(5 to 14)
- src.healths.icon_state = "health3"
- if(0 to 4)
- src.healths.icon_state = "health4"
- if(-35 to 0)
- src.healths.icon_state = "health5"
- else
- src.healths.icon_state = "health6"
- else
- switch(current_health)
- if(200 to INFINITY)
- src.healths.icon_state = "health0"
- if(150 to 200)
- src.healths.icon_state = "health1"
- if(100 to 150)
- src.healths.icon_state = "health2"
- if(50 to 100)
- src.healths.icon_state = "health3"
- if(0 to 50)
- src.healths.icon_state = "health4"
- else
- if(current_health > get_config_value(/decl/config/num/health_health_threshold_dead))
- src.healths.icon_state = "health5"
- else
- src.healths.icon_state = "health6"
- else
- src.healths.icon_state = "health7"
-
- if (src.cells)
- if (src.cell)
- var/chargeNum = clamp(ceil(cell.percent()/25), 0, 4) //0-100 maps to 0-4, but give it a paranoid clamp just in case.
- src.cells.icon_state = "charge[chargeNum]"
- else
- src.cells.icon_state = "charge-empty"
-
- if(bodytemp)
- switch(src.bodytemperature) //310.055 optimal body temp
- if(335 to INFINITY)
- src.bodytemp.icon_state = "temp2"
- if(320 to 335)
- src.bodytemp.icon_state = "temp1"
- if(300 to 320)
- src.bodytemp.icon_state = "temp0"
- if(260 to 300)
- src.bodytemp.icon_state = "temp-1"
- else
- src.bodytemp.icon_state = "temp-2"
-
- var/datum/gas_mixture/environment = loc?.return_air()
- if(fire && environment)
- switch(environment.temperature)
- if(-INFINITY to T100C)
- src.fire.icon_state = "fire0"
- else
- src.fire.icon_state = "fire1"
- if(oxygen && environment)
- var/decl/species/species = all_species[global.using_map.default_species]
- if(!species.breath_type || environment.gas[species.breath_type] >= species.breath_pressure)
- src.oxygen.icon_state = "oxy0"
- for(var/gas in species.poison_types)
- if(environment.gas[gas])
- src.oxygen.icon_state = "oxy1"
- break
- else
- src.oxygen.icon_state = "oxy1"
-
if(stat != DEAD)
if(is_blind())
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
diff --git a/code/modules/mob/living/silicon/robot/modules/_module.dm b/code/modules/mob/living/silicon/robot/modules/_module.dm
index ee0046ef2ae5..7bd571e00d42 100644
--- a/code/modules/mob/living/silicon/robot/modules/_module.dm
+++ b/code/modules/mob/living/silicon/robot/modules/_module.dm
@@ -16,7 +16,10 @@
)
var/list/module_sprites = list()
var/can_be_pushed = 1
- var/no_slip = 0
+ // Equivalent to shoes with ITEM_FLAG_NOSLIP
+ var/has_nonslip_feet = FALSE
+ // Equivalent to shoes with ITEM_FLAG_MAGNETIZED
+ var/has_magnetic_feet = FALSE
var/obj/item/borg/upgrade/jetpack = null
var/list/subsystems = list()
var/list/obj/item/borg/upgrade/supported_upgrades = list()
diff --git a/code/modules/mob/living/silicon/robot/modules/module_engineering.dm b/code/modules/mob/living/silicon/robot/modules/module_engineering.dm
index d0b1f9456e3d..fb3406b346d2 100644
--- a/code/modules/mob/living/silicon/robot/modules/module_engineering.dm
+++ b/code/modules/mob/living/silicon/robot/modules/module_engineering.dm
@@ -19,7 +19,8 @@
"Landmate" = 'icons/mob/robots/robot_engineer.dmi',
"Landmate - Treaded" = 'icons/mob/robots/robot_engineer_treaded.dmi'
)
- no_slip = 1
+ has_nonslip_feet = TRUE
+ has_magnetic_feet = TRUE
equipment = list(
/obj/item/flash,
/obj/item/borg/sight/meson,
diff --git a/code/modules/mob/living/silicon/robot/modules/module_illegal.dm b/code/modules/mob/living/silicon/robot/modules/module_illegal.dm
index 5ca5cfe98db7..e899ec1a2221 100644
--- a/code/modules/mob/living/silicon/robot/modules/module_illegal.dm
+++ b/code/modules/mob/living/silicon/robot/modules/module_illegal.dm
@@ -27,7 +27,7 @@
equipment += id
/obj/item/robot_module/syndicate/finalize_equipment(var/mob/living/silicon/robot/R)
- R.internals = locate(/obj/item/tank/jetpack/carbondioxide) in equipment
+ R.set_internals(locate(/obj/item/tank/jetpack/carbondioxide) in equipment)
. = ..()
/obj/item/robot_module/syndicate/Destroy()
diff --git a/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm b/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm
index b9456bc2050c..6d683809f001 100644
--- a/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm
+++ b/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm
@@ -1,8 +1,9 @@
/obj/item/robot_module/drone
name = "drone module"
- hide_on_manifest = 1
- no_slip = 1
- camera_channels = list(
+ hide_on_manifest = 1
+ has_nonslip_feet = TRUE
+ has_magnetic_feet = TRUE
+ camera_channels = list(
CAMERA_CAMERA_CHANNEL_ENGINEERING
)
languages = list(
@@ -60,7 +61,7 @@
/obj/item/robot_module/drone/finalize_equipment(var/mob/living/silicon/robot/R)
. = ..()
if(istype(R))
- R.internals = locate(/obj/item/tank/jetpack/carbondioxide) in equipment
+ R.set_internals(locate(/obj/item/tank/jetpack/carbondioxide) in equipment)
/obj/item/robot_module/drone/finalize_emag()
. = ..()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index e3572786bbaf..2a481872bb61 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -35,13 +35,13 @@
/// If icon selection has been completed yet
var/icon_selected = TRUE
/// Hud stuff
- var/obj/screen/robot_module/one/inv1
- var/obj/screen/robot_module/two/inv2
- var/obj/screen/robot_module/three/inv3
- var/obj/screen/robot_drop_grab/ui_drop_grab
+ var/obj/screen/robot/module/one/inv1
+ var/obj/screen/robot/module/two/inv2
+ var/obj/screen/robot/module/three/inv3
+
/// Used to determine whether they have the module menu shown or not
var/shown_robot_modules = 0
- var/obj/screen/robot_modules_background/robot_modules_background
+ var/obj/screen/robot/modules_background/robot_modules_background
/// 3 Modules can be activated at any one time.
var/obj/item/robot_module/module = null
var/obj/item/module_active
@@ -199,8 +199,7 @@
if(shown_robot_modules)
hud_used.toggle_show_robot_modules()
modtype = initial(modtype)
- if(hands)
- hands.icon_state = initial(hands.icon_state)
+ refresh_hud_element(HUD_ROBOT_MODULE)
// If the robot had a module and this wasn't an uncertified change, let the AI know.
if(module)
if (!suppress_alert)
@@ -236,9 +235,7 @@
return
new module_type(src)
-
- if(hands)
- hands.icon_state = lowertext(modtype)
+ refresh_hud_element(HUD_ROBOT_MODULE)
SSstatistics.add_field("cyborg_[lowertext(modtype)]",1)
updatename()
recalculate_synth_capacities()
@@ -314,7 +311,7 @@
var/dat = "[src.name] Self-Diagnosis Report\n"
for (var/V in components)
var/datum/robot_component/C = components[V]
- dat += "[C.name]
| Brute Damage: | [C.brute_damage] |
| Electronics Damage: | [C.electronics_damage] |
| Powered: | [(!C.idle_usage || C.is_powered()) ? "Yes" : "No"] |
| Toggled: | [ C.toggled ? "Yes" : "No"] |
"
+ dat += "[C.name]
| Brute Damage: | [C.brute_damage] |
| Electronics Damage: | [C.burn_damage] |
| Powered: | [(!C.idle_usage || C.is_powered()) ? "Yes" : "No"] |
| Toggled: | [ C.toggled ? "Yes" : "No"] |
"
return dat
@@ -446,7 +443,7 @@
var/obj/item/robot_parts/robot_component/WC = W
if(istype(WC))
C.brute_damage = WC.brute_damage
- C.electronics_damage = WC.burn_damage
+ C.burn_damage = WC.burn_damage
to_chat(user, "You install the [W.name].")
return TRUE
@@ -524,7 +521,7 @@
var/obj/item/robot_parts/robot_component/I = C.wrapped
if(istype(I))
I.set_bruteloss(C.brute_damage)
- I.set_burnloss(C.electronics_damage)
+ I.set_burnloss(C.burn_damage)
removed_item = I
if(C.installed == 1)
@@ -563,7 +560,7 @@
C.install()
// This means that removing and replacing a power cell will repair the mount.
C.brute_damage = 0
- C.electronics_damage = 0
+ C.burn_damage = 0
return TRUE
else if(IS_WIRECUTTER(W) || IS_MULTITOOL(W))
if (wiresexposed)
@@ -631,7 +628,6 @@
else if (H.wrapped == W)
H.wrapped = null
-
/mob/living/silicon/robot/try_awaken(mob/user)
return user?.attempt_hug(src)
@@ -808,16 +804,11 @@
/mob/living/silicon/robot/Move(a, b, flag)
. = ..()
- if(.)
-
- if(module && isturf(loc))
- var/obj/item/ore/orebag = locate() in list(module_state_1, module_state_2, module_state_3)
- if(orebag)
- loc.attackby(orebag, src)
- module.handle_turf(loc, src)
-
- if(client)
- up_hint.update_icon()
+ if(. && module && isturf(loc))
+ var/obj/item/ore/orebag = locate() in list(module_state_1, module_state_2, module_state_3)
+ if(orebag)
+ loc.attackby(orebag, src)
+ module.handle_turf(loc, src)
/mob/living/silicon/robot/proc/UnlinkSelf()
disconnect_from_ai()
diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm
index da95094c6766..6723fd88775f 100644
--- a/code/modules/mob/living/silicon/robot/robot_damage.dm
+++ b/code/modules/mob/living/silicon/robot/robot_damage.dm
@@ -9,7 +9,7 @@
var/amount = 0
for(var/V in components)
var/datum/robot_component/C = components[V]
- if(C.installed != 0) amount += C.electronics_damage
+ if(C.installed != 0) amount += C.burn_damage
return amount
/mob/living/silicon/robot/adjustBruteLoss(var/amount, var/do_update_health = TRUE)
@@ -30,7 +30,7 @@
for(var/V in components)
var/datum/robot_component/C = components[V]
if(C.installed == 1 || (C.installed == -1 && destroyed))
- if((brute && C.brute_damage) || (burn && C.electronics_damage) || (!C.toggled) || (!C.powered && C.toggled))
+ if((brute && C.brute_damage) || (burn && C.burn_damage) || (!C.toggled) || (!C.powered && C.toggled))
parts += C
return parts
@@ -93,12 +93,12 @@
var/datum/robot_component/picked = pick(parts)
var/brute_was = picked.brute_damage
- var/burn_was = picked.electronics_damage
+ var/burn_was = picked.burn_damage
picked.heal_damage(brute,burn)
brute -= (brute_was-picked.brute_damage)
- burn -= (burn_was-picked.electronics_damage)
+ burn -= (burn_was-picked.burn_damage)
parts -= picked
@@ -130,10 +130,10 @@
while(parts.len && (brute>0 || burn>0) )
var/datum/robot_component/picked = pick(parts)
var/brute_was = picked.brute_damage
- var/burn_was = picked.electronics_damage
+ var/burn_was = picked.burn_damage
picked.take_component_damage(brute,burn)
brute -= (picked.brute_damage - brute_was)
- burn -= (picked.electronics_damage - burn_was)
+ burn -= (picked.burn_damage - burn_was)
parts -= picked
update_health()
diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm
index 59ead6d32d8b..71c952c9dbde 100644
--- a/code/modules/mob/living/silicon/robot/robot_items.dm
+++ b/code/modules/mob/living/silicon/robot/robot_items.dm
@@ -87,7 +87,7 @@
//A harvest item for serviceborgs.
/obj/item/robot_harvester
name = "auto harvester"
- desc = "A hand-held harvest tool that resembles a sickle. It uses energy to cut plant matter very efficently."
+ desc = "A hand-held harvest tool that resembles a sickle. It uses energy to cut plant matter very efficiently."
icon = 'icons/obj/items/borg_module/autoharvester.dmi'
icon_state = "autoharvester"
max_health = ITEM_HEALTH_NO_DAMAGE
diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm
index 0ff911e5d0e5..55cfd8753368 100644
--- a/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -1,12 +1,8 @@
-/mob/living/silicon/robot/slip_chance(var/prob_slip)
- if(module && module.no_slip)
- return 0
- ..(prob_slip)
+/mob/living/silicon/robot/has_non_slip_footing(obj/item/shoes)
+ return module?.has_nonslip_feet
-/mob/living/silicon/robot/Check_Shoegrip()
- if(module && module.no_slip)
- return 1
- return 0
+/mob/living/silicon/robot/has_magnetised_footing(obj/item/shoes)
+ return module?.has_magnetic_feet
/mob/living/silicon/robot/get_jetpack()
return locate(/obj/item/tank/jetpack) in module?.equipment
@@ -20,4 +16,4 @@
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
tally-=3
- return tally+get_config_value(/decl/config/num/movement_robot)
\ No newline at end of file
+ return tally+get_config_value(/decl/config/num/movement_robot)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 81d21611390b..5fe858b67a56 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -457,3 +457,4 @@
/mob/living/silicon/handle_stance()
stance_damage = 0
return
+
diff --git a/code/modules/mob/living/simple_animal/_simple_animal.dm b/code/modules/mob/living/simple_animal/_simple_animal.dm
index 8d2d7af52642..0b7d78e11bf0 100644
--- a/code/modules/mob/living/simple_animal/_simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/_simple_animal.dm
@@ -12,11 +12,16 @@
icon_state = ICON_STATE_WORLD
buckle_pixel_shift = @"{'x':0,'y':0,'z':8}"
+ hud_used = /datum/hud/animal
+
move_intents = list(
/decl/move_intent/walk/animal,
/decl/move_intent/run/animal
)
+ // Set to TRUE to ignore slipping while EVA
+ var/skip_spacemove = FALSE
+
/// Added to the delay expected from movement decls.
var/base_movement_delay = 0
@@ -274,13 +279,13 @@ var/global/list/simplemob_icon_bitflag_cache = list()
bodytemperature += ((environment.temperature - bodytemperature) / 5)
if(bodytemperature < minbodytemp)
- SET_HUD_ALERT(src, /decl/hud_element/condition/fire, 2)
+ SET_HUD_ALERT(src, HUD_FIRE, 2)
take_damage(cold_damage_per_tick, BURN)
else if(bodytemperature > maxbodytemp)
- SET_HUD_ALERT(src, /decl/hud_element/condition/fire, 1)
+ SET_HUD_ALERT(src, HUD_FIRE, 1)
take_damage(heat_damage_per_tick, BURN)
else
- SET_HUD_ALERT(src, /decl/hud_element/condition/fire, 0)
+ SET_HUD_ALERT(src, HUD_FIRE, 0)
if(!atmos_suitable)
take_damage(unsuitable_atmos_damage)
@@ -590,3 +595,6 @@ var/global/list/simplemob_icon_bitflag_cache = list()
/mob/living/simple_animal/set_stat(var/new_stat)
if((. = ..()))
queue_icon_update()
+
+/mob/living/simple_animal/is_space_movement_permitted(allow_movement = FALSE)
+ return skip_spacemove ? SPACE_MOVE_PERMITTED : ..()
diff --git a/code/modules/mob/living/simple_animal/crow/crow.dm b/code/modules/mob/living/simple_animal/crow/crow.dm
index 66428209454e..1c780c3299aa 100644
--- a/code/modules/mob/living/simple_animal/crow/crow.dm
+++ b/code/modules/mob/living/simple_animal/crow/crow.dm
@@ -80,7 +80,7 @@
/mob/living/simple_animal/crow/cyber
name = "cybercrow"
- desc = "A large cybercrow. k4w k4w."
+ desc = "A large cybercrow. K4w k4w."
speak_emote = list("beeps")
/mob/living/simple_animal/crow/cyber/on_update_icon()
diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm
index 8eaa3d916813..9d63b3a9b810 100644
--- a/code/modules/mob/living/simple_animal/hostile/carp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/carp.dm
@@ -3,21 +3,22 @@
desc = "A ferocious, fang-bearing creature that resembles a fish."
icon = 'icons/mob/simple_animal/space_carp.dmi'
- max_health = 50
- harm_intent_damage = 8
- natural_weapon = /obj/item/natural_weapon/bite
+ max_health = 50
+ harm_intent_damage = 8
+ natural_weapon = /obj/item/natural_weapon/bite
base_movement_delay = 2
//Space carp aren't affected by atmos.
- min_gas = null
- max_gas = null
- minbodytemp = 0
- faction = "carp"
- bleed_colour = "#5d0d71"
- pass_flags = PASS_FLAG_TABLE
- butchery_data = /decl/butchery_data/animal/fish/space_carp
- ai = /datum/mob_controller/aggressive/carp
+ min_gas = null
+ max_gas = null
+ minbodytemp = 0
+ faction = "carp"
+ bleed_colour = "#5d0d71"
+ pass_flags = PASS_FLAG_TABLE
+ butchery_data = /decl/butchery_data/animal/fish/space_carp
+ ai = /datum/mob_controller/aggressive/carp
ability_handlers = list(/datum/ability_handler/predator)
+ skip_spacemove = TRUE
var/carp_color = COLOR_PURPLE
@@ -57,6 +58,3 @@
var/image/I = image(icon, "[icon_state]-eyes")
I.appearance_flags |= RESET_COLOR
add_overlay(I)
-
-/mob/living/simple_animal/hostile/carp/Process_Spacemove()
- return 1 //No drifting in space for space carp! //original comments do not steal
diff --git a/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm b/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm
index 1145b90b6e8b..330f1afffc4d 100644
--- a/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm
+++ b/code/modules/mob/living/simple_animal/hostile/commanded/nanomachines.dm
@@ -1,6 +1,6 @@
/mob/living/simple_animal/hostile/commanded/nanomachine
name = "swarm"
- desc = "a cloud of tiny, tiny robots."
+ desc = "A cloud of tiny, tiny robots."
icon = 'icons/mob/simple_animal/nanomachines.dmi'
natural_weapon = /obj/item/natural_weapon/nanomachine
max_health = 10
diff --git a/code/modules/mob/living/simple_animal/hostile/faithful_hound.dm b/code/modules/mob/living/simple_animal/hostile/faithful_hound.dm
index 345b7137994b..3e5bb0112dbf 100644
--- a/code/modules/mob/living/simple_animal/hostile/faithful_hound.dm
+++ b/code/modules/mob/living/simple_animal/hostile/faithful_hound.dm
@@ -65,9 +65,6 @@
new /obj/item/ectoplasm(get_turf(src))
qdel(src)
-/mob/living/simple_animal/faithful_hound/Destroy()
- return ..()
-
/mob/living/simple_animal/faithful_hound/hear_say(var/message, var/verb = "says", var/decl/language/language = null, var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
set waitfor = FALSE
if(!ai?.check_memory(speaker, message))
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
index c8de00b79d20..662a6058c3d5 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm
@@ -1,38 +1,39 @@
//malfunctioning combat drones
/mob/living/simple_animal/hostile/malf_drone
- name = "combat drone"
- desc = "An automated combat drone armed with state of the art weaponry and shielding."
- icon = 'icons/mob/simple_animal/drone_combat.dmi'
- burst_projectile = 0
- max_health = 300
- move_intents = list(
+ name = "combat drone"
+ desc = "An automated combat drone armed with state of the art weaponry and shielding."
+ icon = 'icons/mob/simple_animal/drone_combat.dmi'
+ burst_projectile = 0
+ max_health = 300
+ move_intents = list(
/decl/move_intent/walk/animal_slow,
/decl/move_intent/run/animal_slow
)
- projectiletype = /obj/item/projectile/beam/drone
- projectilesound = 'sound/weapons/laser3.ogg'
- gene_damage = -1
- butchery_data = /decl/butchery_data/synthetic
- bleed_colour = SYNTH_BLOOD_COLOR
+ projectiletype = /obj/item/projectile/beam/drone
+ projectilesound = 'sound/weapons/laser3.ogg'
+ gene_damage = -1
+ butchery_data = /decl/butchery_data/synthetic
+ bleed_colour = SYNTH_BLOOD_COLOR
+ ai = /datum/mob_controller/aggressive/malf_drone
base_movement_delay = 2
- ai = /datum/mob_controller/aggressive/malf_drone
//Drones aren't affected by atmos.
- min_gas = null
- max_gas = null
- minbodytemp = 0
- faction = "malf_drone"
+ min_gas = null
+ max_gas = null
+ minbodytemp = 0
+ faction = "malf_drone"
+ skip_spacemove = TRUE
- var/has_loot = 1
var/datum/effect/effect/system/trail/ion_trail
+ var/has_loot = 1
var/explode_chance = 1
- var/disabled = 0
- var/exploding = 0
+ var/disabled = 0
+ var/exploding = 0
var/static/list/debris = list(
- /decl/material/solid/glass = /obj/item/shard,
- /decl/material/solid/metal/steel = /obj/item/stack/material/rods,
+ /decl/material/solid/glass = /obj/item/shard,
+ /decl/material/solid/metal/steel = /obj/item/stack/material/rods,
/decl/material/solid/metal/plasteel = null
)
@@ -86,9 +87,6 @@
QDEL_NULL(ion_trail)
return ..()
-/mob/living/simple_animal/hostile/malf_drone/Process_Spacemove()
- return 1
-
/mob/living/simple_animal/hostile/malf_drone/proc/Haywire()
var/datum/mob_controller/aggressive/malf_drone/drone_ai = ai
if(prob(disabled ? 0 : 1) && istype(drone_ai) && drone_ai.malfunctioning)
@@ -202,10 +200,6 @@
if(. && !gibbed)
physically_destroyed()
-/mob/living/simple_animal/hostile/malf_drone/Destroy()
- QDEL_NULL(ion_trail)
- return ..()
-
/mob/living/simple_animal/hostile/malf_drone/physically_destroyed(skip_qdel)
//some random debris left behind
if(has_loot)
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm
index d8443751980f..17b7b6976f2d 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/exoplanet.dm
@@ -89,7 +89,7 @@
/mob/living/simple_animal/hostile/beast/shantak
name = "shantak"
- desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. Don't be fooled by its beauty though."
+ desc = "A piglike creature with a bright iridescent mane that sparkles as though lit by an inner light. Don't be fooled by its beauty though."
faction = "shantak"
icon = 'icons/mob/simple_animal/shantak.dmi'
move_intents = list(
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm
index faae358b3884..63f5255223b1 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm
@@ -27,30 +27,31 @@
//the king and his court
/mob/living/simple_animal/hostile/goat/king
- name = "king of goats"
- desc = "The oldest and wisest of goats; king of his race, peerless in dignity and power. His golden fleece radiates nobility."
- icon = 'icons/mob/simple_animal/goat_king.dmi'
- speak_emote = list("brays in a booming voice")
- ai = /datum/mob_controller/aggressive/goat/king
- response_harm = "assaults"
- max_health = 500
- mob_size = MOB_SIZE_LARGE
- mob_bump_flag = HEAVY
- move_intents = list(
+ name = "king of goats"
+ desc = "The oldest and wisest of goats; king of his race, peerless in dignity and power. His golden fleece radiates nobility."
+ icon = 'icons/mob/simple_animal/goat_king.dmi'
+ speak_emote = list("brays in a booming voice")
+ ai = /datum/mob_controller/aggressive/goat/king
+ response_harm = "assaults"
+ max_health = 500
+ mob_size = MOB_SIZE_LARGE
+ mob_bump_flag = HEAVY
+ move_intents = list(
/decl/move_intent/walk/animal,
/decl/move_intent/run/animal
)
- min_gas = null
- max_gas = null
- minbodytemp = 0
- flash_protection = FLASH_PROTECTION_MAJOR
- natural_weapon = /obj/item/natural_weapon/goatking
- var/current_damtype = BRUTE
+ min_gas = null
+ max_gas = null
+ minbodytemp = 0
+ flash_protection = FLASH_PROTECTION_MAJOR
+ natural_weapon = /obj/item/natural_weapon/goatking
+ skip_spacemove = TRUE
+ var/current_damtype = BRUTE
+ var/stun_chance = 5 //chance per attack to Weaken target
var/list/elemental_weapons = list(
BURN = /obj/item/natural_weapon/goatking/fire,
ELECTROCUTE = /obj/item/natural_weapon/goatking/lightning
)
- var/stun_chance = 5 //chance per attack to Weaken target
/mob/living/simple_animal/hostile/goat/king/proc/OnDeath()
visible_message(SPAN_CULT_ANNOUNCE("\The [src] lets loose a terrific wail as its wounds close shut with a flash of light, and its eyes glow even brighter than before!"))
@@ -69,9 +70,6 @@
ADJ_STATUS(target, STAT_CONFUSE, 1)
visible_message(SPAN_WARNING("\The [target] is bowled over by the impact of [src]'s attack!"))
-/mob/living/simple_animal/hostile/goat/king/Process_Spacemove()
- return 1
-
/mob/living/simple_animal/hostile/goat/king/get_natural_weapon()
if(!(current_damtype in elemental_weapons))
return ..()
@@ -148,7 +146,7 @@
boss_theme = play_looping_sound(src, sound_id, 'sound/music/Visager-Battle.ogg', volume = 10, range = 7, falloff = 4, prefer_mute = TRUE)
update_icon()
-/mob/living/simple_animal/hostile/retaliate/goat/guard
+/mob/living/simple_animal/hostile/goat/guard
name = "honour guard"
desc = "A very handsome and noble beast."
icon = 'icons/mob/simple_animal/goat_guard.dmi'
@@ -161,7 +159,7 @@
_base_attack_force = 15
sharp = TRUE
-/mob/living/simple_animal/hostile/retaliate/goat/guard/master
+/mob/living/simple_animal/hostile/goat/guard/master
name = "master of the guard"
desc = "A very handsome and noble beast - the most trusted of all the king's men."
icon = 'icons/mob/simple_animal/goat_master.dmi'
diff --git a/code/modules/mob/living/simple_animal/hostile/revenant.dm b/code/modules/mob/living/simple_animal/hostile/revenant.dm
index 0c5dddceaee1..ec429d2a63c8 100644
--- a/code/modules/mob/living/simple_animal/hostile/revenant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/revenant.dm
@@ -1,22 +1,20 @@
/mob/living/simple_animal/hostile/revenant
- name = "revenant"
- desc = "A flickering humanoid shadow that exudes a palpable sense of mance."
- icon = 'icons/mob/simple_animal/revenant.dmi'
- response_help_1p = "You wave your hand through $TARGET$."
- response_help_3p = "$USER$ waves $USER_THEIR$ hand through $TARGET$."
- max_health = 80
- gene_damage = -1
- ai = /datum/mob_controller/aggressive/revenant
-
+ name = "revenant"
+ desc = "A flickering humanoid shadow that exudes a palpable sense of mance."
+ icon = 'icons/mob/simple_animal/revenant.dmi'
+ response_help_1p = "You wave your hand through $TARGET$."
+ response_help_3p = "$USER$ waves $USER_THEIR$ hand through $TARGET$."
+ max_health = 80
+ gene_damage = -1
+ ai = /datum/mob_controller/aggressive/revenant
harm_intent_damage = 10
- natural_weapon = /obj/item/natural_weapon/revenant
-
- min_gas = null
- max_gas = null
- minbodytemp = 0
-
- faction = "revenants"
- supernatural = 1
+ natural_weapon = /obj/item/natural_weapon/revenant
+ min_gas = null
+ max_gas = null
+ minbodytemp = 0
+ skip_spacemove = TRUE
+ faction = "revenants"
+ supernatural = TRUE
/datum/mob_controller/aggressive/revenant
speak_chance = 0
@@ -34,9 +32,6 @@
atom_damage_type = BURN
_base_attack_force = 15
-/mob/living/simple_animal/hostile/revenant/Process_Spacemove()
- return 1
-
/mob/living/simple_animal/hostile/revenant/apply_attack_effects(mob/living/target)
. = ..()
if(prob(12))
diff --git a/code/modules/mob/living/simple_animal/hostile/shark.dm b/code/modules/mob/living/simple_animal/hostile/shark.dm
new file mode 100644
index 000000000000..b39c15e7a0c7
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/shark.dm
@@ -0,0 +1,58 @@
+/mob/living/simple_animal/hostile/carp/shark // generally stronger version of a carp that doesn't die from a mean look. Fance new sprites included, credits to F-Tang Steve
+ name = "cosmoshark"
+ desc = "Enormous creature that resembles a shark with magenta glowing lines along its body and set of long deep-purple teeth."
+ icon = 'maps/away/errant_pisces/icons/cosmoshark.dmi'
+ butchery_data = /decl/butchery_data/animal/fish/space_carp/shark
+ max_health = 100
+ natural_weapon = /obj/item/natural_weapon/bite/strong
+ faction = "shark"
+ ai = /datum/mob_controller/aggressive/carp/shark
+
+/datum/mob_controller/aggressive/carp/shark
+ break_stuff_probability = 35
+ turns_per_wander = 10
+
+/mob/living/simple_animal/hostile/carp/shark/carp_randomify()
+ return
+
+/mob/living/simple_animal/hostile/carp/shark/death(gibbed)
+ . = ..()
+ if(. && !gibbed)
+ var/datum/gas_mixture/environment = loc.return_air()
+ if (environment)
+ var/datum/gas_mixture/sharkmaw_chlorine = new
+ sharkmaw_chlorine.adjust_gas(/decl/material/gas/chlorine, 10)
+ environment.merge(sharkmaw_chlorine)
+ visible_message(SPAN_WARNING("\The [src]'s body releases some gas from the gills with a quiet fizz!"))
+
+/mob/living/simple_animal/hostile/carp/shark/apply_attack_effects(mob/living/target)
+ . =..()
+ var/mob/living/L = target
+ if(istype(L))
+ if(prob(25))//if one is unlucky enough, they get tackled few tiles away
+ L.visible_message("\The [src] tackles [L]!")
+ var/tackle_length = rand(3,5)
+ for (var/i = 1 to tackle_length)
+ var/turf/T = get_step(L.loc, dir)//on a first step of tackling standing mob would block movement so let's check if there's something behind it. Works for consequent moves too
+ if (T.density || LinkBlocked(L.loc, T) || TurfBlockedNonWindow(T) || DirBlocked(T, global.flip_dir[dir]))
+ break
+ sleep(2)
+ forceMove(T)//maybe there's better manner then just forceMove() them
+ L.forceMove(T)
+ visible_message("\The [src] releases [L].")
+
+/decl/butchery_data/animal/fish/space_carp/shark
+ meat_type = /obj/item/food/butchery/meat/fish/shark
+ must_use_hook = TRUE
+
+/obj/item/food/butchery/meat/fish/shark
+ desc = "A fillet of cosmoshark meat."
+ meat_name = "cosmoshark"
+ color = "#cecece"
+ center_of_mass = @'{"x":17,"y":13}'
+ bitesize = 8
+
+/obj/item/food/butchery/meat/fish/shark/populate_reagents()
+ . = ..()
+ add_to_reagents(/decl/material/liquid/psychoactives, 1)
+ add_to_reagents(/decl/material/gas/chlorine, 1)
diff --git a/code/modules/mob/living/simple_animal/hostile/vagrant.dm b/code/modules/mob/living/simple_animal/hostile/vagrant.dm
index 8fd2a41379c9..2724d98aede4 100644
--- a/code/modules/mob/living/simple_animal/hostile/vagrant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/vagrant.dm
@@ -1,39 +1,37 @@
/mob/living/simple_animal/hostile/vagrant
- name = "creature"
- desc = "You get the feeling you should run."
- icon = 'icons/mob/simple_animal/vagrant.dmi'
- max_health = 60
- move_intents = list(
+ name = "creature"
+ desc = "You get the feeling you should run."
+ icon = 'icons/mob/simple_animal/vagrant.dmi'
+ max_health = 60
+ move_intents = list(
/decl/move_intent/walk/animal_fast,
/decl/move_intent/run/animal_fast
)
- faction = "vagrant"
- harm_intent_damage = 3
- natural_weapon = /obj/item/natural_weapon/bite/weak
- light_color = "#8a0707"
- min_gas = null
- max_gas = null
- minbodytemp = 0
- gene_damage = -1
- pass_flags = PASS_FLAG_TABLE
- bleed_colour = "#aad9de"
- nutrition = 100
- ai = /datum/mob_controller/aggressive/vagrant
+ faction = "vagrant"
+ harm_intent_damage = 3
+ natural_weapon = /obj/item/natural_weapon/bite/weak
+ light_color = "#8a0707"
+ min_gas = null
+ max_gas = null
+ minbodytemp = 0
+ gene_damage = -1
+ pass_flags = PASS_FLAG_TABLE
+ bleed_colour = "#aad9de"
+ nutrition = 100
+ ai = /datum/mob_controller/aggressive/vagrant
base_movement_delay = 2
+ skip_spacemove = TRUE
- var/cloaked = 0
- var/mob/living/human/gripping = null
- var/blood_per_tick = 3
+ var/cloaked = 0
+ var/blood_per_tick = 3
var/health_per_tick = 0.8
+ var/mob/living/human/gripping
/datum/mob_controller/aggressive/vagrant
speak_chance = 0
turns_per_wander = 8
break_stuff_probability = 0
-/mob/living/simple_animal/hostile/vagrant/Process_Spacemove()
- return 1
-
/mob/living/simple_animal/hostile/vagrant/bullet_act(var/obj/item/projectile/Proj)
var/oldhealth = current_health
. = ..()
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index 3bd462aca867..a66a1b4f79a3 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -103,7 +103,7 @@
client.images = null //remove the images such as AIs being unable to see runes
client.screen = list() //remove hud items just in case
client.set_right_click_menu_mode(shift_to_open_context_menu)
- InitializeHud()
+ initialize_hud()
else
refresh_lighting_master()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index ad15792b151c..e10cf8f47e54 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -24,7 +24,6 @@
if(istype(ai))
QDEL_NULL(ai)
QDEL_NULL(lighting_master)
- remove_screen_obj_references()
if(client)
for(var/atom/movable/AM in client.screen)
var/obj/screen/screenobj = AM
@@ -37,26 +36,6 @@
ghostize()
return ..()
-/mob/proc/remove_screen_obj_references()
- QDEL_NULL_SCREEN(internals)
- QDEL_NULL_SCREEN(oxygen)
- QDEL_NULL_SCREEN(toxin)
- QDEL_NULL_SCREEN(fire)
- QDEL_NULL_SCREEN(bodytemp)
- QDEL_NULL_SCREEN(healths)
- QDEL_NULL_SCREEN(throw_icon)
- QDEL_NULL_SCREEN(maneuver_icon)
- QDEL_NULL_SCREEN(nutrition_icon)
- QDEL_NULL_SCREEN(hydration_icon)
- QDEL_NULL_SCREEN(pressure)
- QDEL_NULL_SCREEN(pain)
- QDEL_NULL_SCREEN(up_hint)
- QDEL_NULL_SCREEN(item_use_icon)
- QDEL_NULL_SCREEN(radio_use_icon)
- QDEL_NULL_SCREEN(gun_move_icon)
- QDEL_NULL_SCREEN(gun_setting_icon)
- QDEL_NULL_SCREEN(zone_sel)
-
/mob/Initialize()
if(ispath(skillset))
skillset = new skillset(src)
@@ -780,7 +759,7 @@
usr.setClickCooldown(20)
if(usr.stat == UNCONSCIOUS)
- to_chat(usr, "You are unconcious and cannot do that!")
+ to_chat(usr, "You are unconscious and cannot do that!")
return
if(usr.restrained())
@@ -890,7 +869,7 @@
/mob/proc/toggle_throw_mode(force_set)
in_throw_mode = isnull(force_set) ? !in_throw_mode : force_set
- throw_icon?.update_icon()
+ refresh_hud_element(HUD_THROW)
/mob/proc/toggle_antag_pool()
set name = "Toggle Add-Antag Candidacy"
@@ -908,12 +887,10 @@
to_chat(usr, "The game is not currently looking for antags.")
else
to_chat(usr, "You must be observing or in the lobby to join the antag pool.")
+
/mob/proc/is_invisible_to(var/mob/viewer)
return (!alpha || !mouse_opacity || viewer.see_invisible < invisibility)
-/client/proc/check_has_body_select()
- return mob && mob.hud_used && istype(mob.zone_sel, /obj/screen/zone_selector)
-
/client/verb/body_toggle_head()
set name = "body-toggle-head"
set hidden = 1
@@ -950,10 +927,7 @@
toggle_zone_sel(list(BP_L_LEG,BP_L_FOOT))
/client/proc/toggle_zone_sel(list/zones)
- if(!check_has_body_select())
- return
- var/obj/screen/zone_selector/selector = mob.zone_sel
- selector.set_selected_zone(next_in_list(mob.get_target_zone(), zones))
+ mob.set_target_zone(next_in_list(mob.get_target_zone(), zones))
/mob/proc/has_admin_rights()
return check_rights(R_ADMIN, 0, src)
@@ -968,7 +942,7 @@
return gender
/mob/try_fluid_push(volume, strength)
- if(..() && !buckled && (current_posture.prone || !Check_Shoegrip()) && (strength >= mob_size * (current_posture.prone ? 5 : 10)))
+ if(..() && can_slip() && (strength >= mob_size * (current_posture.prone ? 5 : 10)))
if(!current_posture.prone)
SET_STATUS_MAX(src, STAT_WEAK, 1)
if(current_posture.prone && prob(10))
@@ -1251,12 +1225,16 @@
return
/mob/proc/set_target_zone(new_zone)
- if(zone_sel)
- return zone_sel?.set_selected_zone(new_zone)
- return FALSE
+ if(new_zone == selected_zone)
+ return
+ var/old_zone = selected_zone
+ selected_zone = new_zone
+ var/obj/screen/zone_selector/selector = get_hud_element(HUD_ZONE_SELECT)
+ if(selector)
+ selector.set_selected_zone(new_zone, old_zone)
/mob/proc/get_target_zone()
- return zone_sel?.selecting || BP_CHEST
+ return selected_zone
/mob/proc/get_default_temperature_threshold(threshold)
switch(threshold)
@@ -1387,11 +1365,93 @@
/// THIS DOES NOT RELATE TO HELD ITEM SLOTS. It is very specifically a functional BP_L_HAND or BP_R_HAND organ, not necessarily a gripper.
/mob/proc/get_usable_hand_slot_organ()
- var/obj/item/organ/external/paw = GET_EXTERNAL_ORGAN(src, BP_L_HAND)
- if(!istype(paw) && !paw.is_usable())
- paw = GET_EXTERNAL_ORGAN(src, BP_R_HAND)
- if(istype(paw) && paw.is_usable())
- return paw
+ var/static/list/hand_slots = list(BP_L_HAND, BP_R_HAND)
+ for(var/slot in shuffle(hand_slots))
+ var/obj/item/organ/external/hand = GET_EXTERNAL_ORGAN(src, slot)
+ if(istype(hand) && hand.is_usable())
+ return hand
+
+/mob/proc/get_solid_footing()
+
+ if(!loc)
+ return src // this is a bit weird but we shouldn't slip in nullspace probably
+
+ // Check for dense turfs.
+ var/turf/my_turf = loc
+ if(!istype(my_turf))
+ return my_turf
+
+ if(my_turf.is_wall() || my_turf.is_floor())
+ return my_turf
+
+ // Check for catwalks and lattices.
+ var/atom/platform = my_turf.get_supporting_platform() || (locate(/obj/structure/lattice) in my_turf)
+ if(platform)
+ return platform
+
+ // Check for supportable nearby atoms.
+ for(var/turf/neighbor in RANGE_TURFS(my_turf, 1))
+ if(neighbor == my_turf)
+ continue
+ if(neighbor.contains_dense_objects(exceptions = src))
+ return neighbor
+ platform = neighbor.get_supporting_platform() || (locate(/obj/structure/lattice) in neighbor)
+ if(platform)
+ return platform
+
+ // Find something we are grabbing onto for support.
+ for(var/atom/movable/thing in range(1, my_turf))
+ if(thing == src || thing == inertia_ignore || !thing.simulated || thing == buckled)
+ continue
+ if(isturf(thing))
+ continue // We checked turfs when using magboots above.
+ else if(ismob(thing))
+ var/mob/victim = thing
+ if(victim.buckled)
+ continue
+ else if(thing.CanPass(src))
+ continue
+ if(thing.anchored)
+ return thing
+ var/is_being_grabbed = FALSE
+ for(var/obj/item/grab/grab in get_active_grabs())
+ if(thing == grab.affecting)
+ is_being_grabbed = TRUE
+ break
+ if(!is_being_grabbed)
+ . = thing
+
+/mob/proc/can_slip(magboots_only = FALSE)
+
+ // Are we immune to everything?
+ if(status_flags & GODMODE)
+ return FALSE
+
+ // Quick basic checks.
+ if(!simulated || !isturf(loc) || buckled || current_posture?.prone || throwing)
+ return FALSE
+
+ // Species flag/proc check.
+ if(get_species()?.check_no_slip(src, magboots_only))
+ return FALSE
+
+ // Check footwear.
+ if(!magboots_only && has_non_slip_footing())
+ return FALSE
+
+ if((has_gravity() || has_magnetised_footing()) && get_solid_footing())
+ return FALSE
+
+ // Slip!
+ return TRUE
+
+/mob/proc/has_non_slip_footing()
+ var/obj/item/shoes = get_equipped_item(slot_shoes_str)
+ return istype(shoes) && (shoes.item_flags & ITEM_FLAG_NOSLIP)
+
+/mob/proc/has_magnetised_footing()
+ var/obj/item/shoes = get_equipped_item(slot_shoes_str)
+ return istype(shoes) && (shoes.item_flags & ITEM_FLAG_MAGNETISED)
// Called when using the shredding behavior.
/mob/proc/can_shred(var/mob/living/human/H, var/ignore_intent, var/ignore_antag)
@@ -1413,3 +1473,4 @@
var/list/limb_unarmed_attacks = limb.get_natural_attacks()
if(istype(limb_unarmed_attacks, /decl/natural_attack) || (islist(limb_unarmed_attacks) && length(limb_unarmed_attacks)))
LAZYDISTINCTADD(., limb_unarmed_attacks)
+
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 88da01483aaf..a383f3b30fca 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -41,33 +41,12 @@
var/stat = CONSCIOUS //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
- var/obj/screen/robot_module/select/hands
- var/obj/screen/warning_cells/cells
- var/obj/screen/internals/internals
- var/obj/screen/oxygen/oxygen
- var/obj/screen/toxins/toxin
- var/obj/screen/fire_warning/fire
- var/obj/screen/bodytemp/bodytemp
- var/obj/screen/health_warning/healths
- var/obj/screen/throw_toggle/throw_icon
- var/obj/screen/maneuver/maneuver_icon
- var/obj/screen/food/nutrition_icon
- var/obj/screen/drink/hydration_icon
- var/obj/screen/pressure/pressure
- var/obj/screen/fullscreen/pain/pain
- var/obj/screen/up_hint/up_hint
- var/obj/screen/gun/item/item_use_icon
- var/obj/screen/gun/radio/radio_use_icon
- var/obj/screen/gun/move/gun_move_icon
- var/obj/screen/gun/mode/gun_setting_icon
-
/*A bunch of this stuff really needs to go under their own defines instead of being globally attached to mob.
A variable should only be globally attached to turfs/objects/whatever, when it is in fact needed as such.
The current method unnecessarily clusters up the variable list, especially for humans (although rearranging won't really clean it up a lot but the difference will be noticable for other mobs).
I'll make some notes on where certain variable defines should probably go.
Changing this around would probably require a good look-over the pre-existing code.
*/
- var/obj/screen/zone_selector/zone_sel = null
var/damageoverlaytemp = 0
var/obj/machinery/machine = null
@@ -157,5 +136,8 @@
var/offset_overhead_text_x = 0
var/offset_overhead_text_y = 0
+ /// What bodypart are we currently targetting?
+ var/selected_zone = BP_CHEST
+
/// Are you trying not to hurt your opponent?
var/pulling_punches
diff --git a/code/modules/mob/mob_intent.dm b/code/modules/mob/mob_intent.dm
index b55b2342ed84..37bf6fa6d50b 100644
--- a/code/modules/mob/mob_intent.dm
+++ b/code/modules/mob/mob_intent.dm
@@ -35,6 +35,10 @@
var/icon = 'icons/screen/intents.dmi'
/// State used to update intent selector.
var/icon_state
+ /// Whether or not this intent is available if you have an item in your hand.
+ var/requires_empty_hand
+ /// Intents to be removed from the available list if this intent is present.
+ var/list/blocks_other_intents
/decl/intent/validate()
. = ..()
@@ -83,20 +87,10 @@
icon_state = "intent_disarm"
sort_order = 2 // Corresponding to hotkey order.
-// Used by nymphs.
-/decl/intent/harm/binary
- icon = 'icons/screen/intents_wide.dmi'
- uid = "intent_harm_simple"
- intent_flags = (I_FLAG_HARM|I_FLAG_DISARM)
-
-/decl/intent/help/binary
- icon = 'icons/screen/intents_wide.dmi'
- uid = "intent_help_simple"
- intent_flags = (I_FLAG_HARM|I_FLAG_GRAB)
-
/mob
/// Decl for current 'intent' of mob; hurt, harm, etc. Initialized by get_intent().
- var/decl/intent/_a_intent
+ VAR_PRIVATE/decl/intent/_a_intent
+ VAR_PRIVATE/list/_available_intents
/mob/proc/check_intent(checking_intent)
var/decl/intent/intent = get_intent() // Ensures intent has been initalised.
@@ -112,21 +106,30 @@
if(!isnum(new_intent))
new_intent = resolve_intent(new_intent)
else // Retrieve intent decl based on flag.
- for(var/decl/intent/intent as anything in get_available_intents())
+ for(var/decl/intent/intent as anything in get_available_intents(skip_update = TRUE))
if(intent.intent_flags & new_intent)
new_intent = intent
break
if(istype(new_intent) && get_intent() != new_intent)
_a_intent = new_intent
- if(istype(hud_used) && hud_used.action_intent)
- hud_used.action_intent.update_icon()
+ if(istype(hud_used))
+ hud_used.refresh_element(HUD_INTENT)
return TRUE
return FALSE
/mob/proc/get_intent()
RETURN_TYPE(/decl/intent)
+ var/list/available_intents = get_available_intents()
+ if(length(available_intents) && (!_a_intent || !(_a_intent in available_intents)))
+ var/new_intent
+ if(_a_intent)
+ for(var/decl/intent/intent in available_intents)
+ if(_a_intent.intent_flags & intent.intent_flags)
+ new_intent = intent
+ break
+ _a_intent = new_intent || available_intents[1]
if(!_a_intent)
_a_intent = get_default_intent()
return _a_intent
@@ -134,25 +137,59 @@
/mob/proc/get_default_intent()
return GET_DECL(/decl/intent/help)
-/mob/proc/get_available_intents()
- var/static/list/available_intents
- if(!available_intents)
- available_intents = list(
+/mob/proc/get_default_intents()
+ var/static/list/default_intents
+ if(!default_intents)
+ default_intents = list(
GET_DECL(/decl/intent/help),
GET_DECL(/decl/intent/disarm),
GET_DECL(/decl/intent/grab),
GET_DECL(/decl/intent/harm)
)
- available_intents = sortTim(available_intents, /proc/cmp_decl_sort_value_asc)
- return available_intents
+ return default_intents
+
+/mob/proc/clear_available_intents(skip_update, skip_sleep)
+ set waitfor = FALSE
+ if(!skip_sleep)
+ sleep(0)
+ if(QDELETED(src))
+ return
+ _available_intents = null
+ if(!skip_update)
+ refresh_hud_element(HUD_INTENT)
+
+/mob/proc/get_available_intents(skip_update, force)
+ var/obj/item/held = get_active_held_item()
+ if(!held)
+ _available_intents = get_default_intents()
+ else if(force || !_available_intents)
+ // Grab all relevant intents.
+ _available_intents = list()
+ for(var/decl/intent/intent as anything in get_default_intents())
+ if(intent.requires_empty_hand)
+ continue
+ _available_intents += intent
+ // Add inhand intents.
+ var/list/held_intents = held.get_provided_intents(src)
+ if(length(held_intents))
+ _available_intents |= held_intents
+ // Trim blocked intents.
+ for(var/decl/intent/intent as anything in _available_intents)
+ _available_intents -= intent.blocks_other_intents
+ // Sort by hotkey order.
+ _available_intents = sortTim(_available_intents, /proc/cmp_decl_sort_value_asc)
+ // Update our HUD immediately.
+ if(!skip_update)
+ refresh_hud_element(HUD_INTENT)
+ return _available_intents
/mob/proc/cycle_intent(input)
set name = "a-intent"
set hidden = TRUE
switch(input)
if(INTENT_HOTKEY_RIGHT)
- return set_intent(next_in_list(get_intent(), get_available_intents()))
+ return set_intent(next_in_list(get_intent(), get_available_intents(skip_update = TRUE)))
if(INTENT_HOTKEY_LEFT)
- return set_intent(previous_in_list(get_intent(), get_available_intents()))
+ return set_intent(previous_in_list(get_intent(), get_available_intents(skip_update = TRUE)))
else // Fallback, should just use set_intent() directly
return set_intent(input)
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index a934d39d2e38..99f0b0fe161b 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -134,105 +134,71 @@
return mob.SelfMove(direction)
-/mob/Process_Spacemove(var/allow_movement)
- . = ..()
- if(.)
+/mob/is_space_movement_permitted(allow_movement = FALSE)
+ if((. = ..()))
return
+ var/atom/movable/footing = get_solid_footing()
+ if(footing)
+ if(istype(footing) && allow_movement)
+ return footing
+ return SPACE_MOVE_SUPPORTED
- var/atom/movable/backup = get_spacemove_backup()
- if(backup)
- if(istype(backup) && allow_movement)
- return backup
- return -1
-
-/mob/living/Process_Spacemove(allow_movement)
+/mob/living/is_space_movement_permitted(allow_movement = FALSE)
var/obj/item/tank/jetpack/thrust = get_jetpack()
if(thrust?.on && (allow_movement || thrust.stabilization_on) && thrust.allow_thrust(0.01, src))
- return TRUE
+ return SPACE_MOVE_PERMITTED
return ..()
-/mob/proc/space_do_move(var/allow_move, var/direction)
- if(ismovable(allow_move))//push off things in space
- handle_space_pushoff(allow_move, direction)
- allow_move = -1
-
- if(allow_move == -1 && handle_spaceslipping())
- return 0
-
- return 1
+// space_move_result can be:
+// - SPACE_MOVE_FORBIDDEN,
+// - SPACE_MOVE_PERMITTED,
+// - SPACE_MOVE_SUPPORTED (for non-movable atoms),
+// - or an /atom/movable that provides footing.
+/mob/proc/try_space_move(space_move_result, direction)
+ if(ismovable(space_move_result))//push off things in space
+ handle_space_pushoff(space_move_result, direction)
+ space_move_result = SPACE_MOVE_SUPPORTED
+ return space_move_result != SPACE_MOVE_SUPPORTED || !handle_spaceslipping()
/mob/proc/handle_space_pushoff(var/atom/movable/AM, var/direction)
if(AM.anchored)
return
-
if(ismob(AM))
var/mob/M = AM
- if(M.check_space_footing())
+ if(!M.can_slip(magboots_only = TRUE))
return
-
AM.inertia_ignore = src
if(step(AM, turn(direction, 180)))
- to_chat(src, "You push off of [AM] to propel yourself.")
+ to_chat(src, SPAN_INFO("You push off of \the [AM] to propel yourself."))
inertia_ignore = AM
-/mob/proc/get_spacemove_backup()//rename this
- var/shoegrip = Check_Shoegrip()
-
- for(var/thing in RANGE_TURFS(src, 1))//checks for walls or grav turf first
- var/turf/T = thing
- if(T.density || T.is_wall() || (T.is_floor() && (shoegrip || T.has_gravity())))
- return T
-
- var/obj/item/grab/grab = locate() in src
- for(var/A in range(1, get_turf(src)))
- if(istype(A,/atom/movable))
- var/atom/movable/AM = A
- if(AM == src || AM == inertia_ignore || !AM.simulated || !AM.mouse_opacity || AM == buckled) //mouse_opacity is hacky as hell, need better solution
- continue
- if(ismob(AM))
- var/mob/M = AM
- if(M.buckled)
- continue
- if(AM.density || !AM.CanPass(src))
- if(AM.anchored)
- return AM
- if(grab && AM == grab.affecting)
- continue
- . = AM
-
-/mob/proc/check_space_footing() //checks for gravity or maglockable turfs to prevent space related movement
- if(has_gravity() || anchored || buckled)
- return 1
-
- if(Check_Shoegrip())
- for(var/thing in RANGE_TURFS(src, 1)) //checks for turfs that one can maglock to
- var/turf/T = thing
- if(T.density || T.is_wall() || T.is_floor())
- return 1
-
- return 0
-
-/mob/proc/Check_Shoegrip()
- return 0
-
//return 1 if slipped, 0 otherwise
/mob/proc/handle_spaceslipping()
- if(prob(skill_fail_chance(SKILL_EVA, slip_chance(10), SKILL_EXPERT)))
- to_chat(src, "You slipped!")
+ if(prob(skill_fail_chance(SKILL_EVA, get_eva_slip_prob(), SKILL_EXPERT)))
+ to_chat(src, SPAN_DANGER("You slipped!"))
step(src,turn(last_move, pick(45,-45)))
- return 1
- return 0
-
-/mob/proc/slip_chance(var/prob_slip = 10)
- if(stat)
- return 0
- if(buckled)
- return 0
- if(Check_Shoegrip())
- return 0
- if(MOVING_DELIBERATELY(src))
- prob_slip *= 0.5
- return prob_slip
+ return TRUE
+ return FALSE
+
+/mob/proc/get_eva_slip_prob(var/prob_slip = 10)
+ // General slip check.
+ if((has_gravity() || has_magnetised_footing()) && get_solid_footing())
+ . = 0
+ else
+ //Check hands and mod slip
+ for(var/hand_slot in get_held_item_slots())
+ var/datum/inventory_slot/inv_slot = get_inventory_slot_datum(hand_slot)
+ var/obj/item/held = inv_slot?.get_equipped_item()
+ if(!held)
+ prob_slip -= 2
+ else if(held.w_class <= ITEM_SIZE_SMALL)
+ prob_slip -= 1
+ // If we're walking carefully, lower the chance.
+ if(MOVING_DELIBERATELY(src))
+ prob_slip *= 0.5
+ . = prob_slip
+ // Avoid negative probs.
+ . = max(0, .)
#define DO_MOVE(this_dir) var/final_dir = turn(this_dir, -dir2angle(dir)); Move(get_step(mob, final_dir), final_dir);
@@ -268,8 +234,7 @@
/mob/proc/set_move_intent(var/decl/move_intent/next_intent)
if(next_intent && move_intent != next_intent && next_intent.can_be_used_by(src))
move_intent = next_intent
- if(istype(hud_used) && hud_used.move_intent)
- hud_used.move_intent.update_icon()
+ refresh_hud_element(HUD_MOVEMENT)
return TRUE
return FALSE
diff --git a/code/modules/mob/observer/eye/freelook/chunk.dm b/code/modules/mob/observer/eye/freelook/chunk.dm
index 97c869dfc190..090b232c7390 100644
--- a/code/modules/mob/observer/eye/freelook/chunk.dm
+++ b/code/modules/mob/observer/eye/freelook/chunk.dm
@@ -128,7 +128,7 @@
if(seenby.len)
updating = TRUE
spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once
- if(updating) // Check if we're still updating, a forced update may have occured.
+ if(updating) // Check if we're still updating, a forced update may have occurred.
update()
else
dirty = TRUE // If this chunk is seen by noone, simply mark it as dirty and do nothing
diff --git a/code/modules/mob/observer/observer.dm b/code/modules/mob/observer/observer.dm
index 94db42cade22..e76f34229eb2 100644
--- a/code/modules/mob/observer/observer.dm
+++ b/code/modules/mob/observer/observer.dm
@@ -41,6 +41,9 @@ var/global/const/GHOST_IMAGE_ALL = ~GHOST_IMAGE_NONE
SSghost_images.queue_global_image_update()
. = ..()
+/mob/observer/can_slip(magboots_only = FALSE)
+ return FALSE
+
/mob/observer/get_movement_delay(travel_dir)
return 1
diff --git a/code/modules/mob/skills/skill.dm b/code/modules/mob/skills/skill.dm
index 87cad27fdb3d..9d75a5d591e3 100644
--- a/code/modules/mob/skills/skill.dm
+++ b/code/modules/mob/skills/skill.dm
@@ -331,7 +331,7 @@
category = /decl/skill_category/engineering
uid = "skill_electrical"
fallback_key = "/decl/hierarchy/skill/engineering/electrical"
- desc = "This skill describes your knowledge of electronics and the underlying physics. A low level of this skill implies you know how to lay out wiring and configure powernets, a high level of this skill is required for working complex electronic devices such as circuits or bots."
+ desc = "This skill describes your knowledge of electronics and the underlying physics. A low level of this skill implies you know how to lay out wiring and configure power networks, a high level of this skill is required for working complex electronic devices such as circuits or bots."
levels = list(
"Unskilled" = "You know that electrical wires are dangerous and getting shocked is bad; you can see and report electrical malfunctions such as broken wires or malfunctioning APCs. You can change a light bulb, and you know how to replace a battery or charge up the equipment you normally use.
- Every time you open the hacking panel, wires are randomized.
- Every time you pulse a wire, there is a chance you pulse a different one.
- Every time you cut a wire, there is a chance you cut/mend extra ones.
- You can misconnect remote signalling devices.",
"Basic" = "You can do basic wiring; you can lay cable for solars or the engine. You can repair broken wiring and build simple electrical equipment like light fixtures or APCs. You know the basics of circuits and understand how to protect yourself from electrical shock. You can probably hack a vending machine.
- Every time you open the hacking panel, some wires might be duplicated.",
diff --git a/code/modules/mob/skills/skill_verbs.dm b/code/modules/mob/skills/skill_verbs.dm
index 36be6e7adfec..fc051b139594 100644
--- a/code/modules/mob/skills/skill_verbs.dm
+++ b/code/modules/mob/skills/skill_verbs.dm
@@ -88,7 +88,7 @@ Robots and antags can instruct.
return
if(target.too_many_buffs(/datum/skill_buff/instruct))
var/decl/pronouns/pronouns = target.get_pronouns(ignore_coverings = TRUE)
- to_chat(src, SPAN_WARNING("\The [target] [pronouns.is] exhausted from all the training [pronouns.he] recieved."))
+ to_chat(src, SPAN_WARNING("\The [target] [pronouns.is] exhausted from all the training [pronouns.he] received."))
return
if(!get_options)
diff --git a/code/modules/mob_holder/_holder.dm b/code/modules/mob_holder/_holder.dm
index 002814c0c09a..18a1f358dd90 100644
--- a/code/modules/mob_holder/_holder.dm
+++ b/code/modules/mob_holder/_holder.dm
@@ -46,7 +46,8 @@
icon = initial(icon)
/obj/item/holder/Exited(atom/movable/am, atom/new_loc)
- am.vis_flags = initial(am.vis_flags)
+ if(!(locate(/mob) in contents))
+ am.vis_flags = initial(am.vis_flags)
. = ..()
/obj/item/holder/proc/destroy_all()
@@ -72,15 +73,15 @@
update_state()
/obj/item/holder/dropped()
- ..()
+ . = ..()
update_state(1)
/obj/item/holder/throw_impact(atom/hit_atom, datum/thrownthing/TT)
- ..()
+ . = ..()
update_state(1)
/obj/item/holder/proc/update_state(var/delay)
- set waitfor = 0
+ set waitfor = FALSE
for(var/mob/M in contents)
unregister_all_movement(last_holder, M)
@@ -97,11 +98,13 @@
mob_container.dropInto(loc)
M.reset_view()
qdel(src)
- else if(last_holder != loc)
+ return
+
+ if(last_holder != loc)
for(var/mob/M in contents)
register_all_movement(loc, M)
update_icon()
- last_holder = loc
+ last_holder = loc
/obj/item/holder/onDropInto(var/atom/movable/AM)
if(ismob(loc)) // Bypass our holding mob and drop directly to its loc
diff --git a/code/modules/modular_computers/computers/subtypes/dev_holo.dm b/code/modules/modular_computers/computers/subtypes/dev_holo.dm
index f2460d4efdf2..838bce869e9a 100644
--- a/code/modules/modular_computers/computers/subtypes/dev_holo.dm
+++ b/code/modules/modular_computers/computers/subtypes/dev_holo.dm
@@ -1,6 +1,6 @@
/obj/item/modular_computer/holotablet
name = "holotablet"
- desc = "An holoemitter-fitted device designed for writing reports and notes."
+ desc = "A holoemitter-fitted device designed for writing reports and notes."
icon = 'icons/obj/modular_computers/holo/basic.dmi'
icon_state = ICON_STATE_WORLD
diff --git a/code/modules/modular_computers/file_system/programs/generic/supply.dm b/code/modules/modular_computers/file_system/programs/generic/supply.dm
index 39f092d64a6a..b0f425734159 100644
--- a/code/modules/modular_computers/file_system/programs/generic/supply.dm
+++ b/code/modules/modular_computers/file_system/programs/generic/supply.dm
@@ -395,7 +395,7 @@
return
var/t = ""
- t += "[global.using_map.station_name] Supply Requisition Reciept
"
+ t += "[global.using_map.station_name] Supply Requisition Receipt
"
t += "INDEX: #[O.ordernum]
"
t += "REQUESTED BY: [O.orderedby]
"
t += "ASSIGNMENT: [O.orderedrank]
"
diff --git a/code/modules/modular_computers/file_system/programs/research/ai_restorer.dm b/code/modules/modular_computers/file_system/programs/research/ai_restorer.dm
index 8683438c0726..a1b613ac1ced 100644
--- a/code/modules/modular_computers/file_system/programs/research/ai_restorer.dm
+++ b/code/modules/modular_computers/file_system/programs/research/ai_restorer.dm
@@ -4,7 +4,7 @@
program_icon_state = "generic"
program_key_state = "mining_key"
program_menu_icon = "person"
- extended_desc = "This program is capable of reconstructing damaged AI systems. It can also be used to upload basic laws to the AI. Requires direct AI connection via inteliCard slot."
+ extended_desc = "This program is capable of reconstructing damaged AI systems. It can also be used to upload basic laws to the AI. Requires direct AI connection via intelliCard slot."
size = 12
read_access = list(access_bridge)
requires_access_to_run = 0
diff --git a/code/modules/modular_computers/file_system/reports/report.dm b/code/modules/modular_computers/file_system/reports/report.dm
index efb782c507fc..7d391fbb982c 100644
--- a/code/modules/modular_computers/file_system/reports/report.dm
+++ b/code/modules/modular_computers/file_system/reports/report.dm
@@ -143,7 +143,7 @@ no_html will strip any html, possibly killing useful formatting in the process.
if(no_html)
. = html2pencode(.)
-//recipient reports have a designated recipients field, for recieving submitted reports.
+//recipient reports have a designated recipients field, for receiving submitted reports.
/datum/computer_file/report/recipient
var/datum/report_field/people/list_from_manifest/recipients
diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm
index c25e0abb1d5b..72345bf49394 100644
--- a/code/modules/modular_computers/hardware/ai_slot.dm
+++ b/code/modules/modular_computers/hardware/ai_slot.dm
@@ -1,7 +1,7 @@
-// A wrapper that allows the computer to contain an inteliCard.
+// A wrapper that allows the computer to contain an intelliCard.
/obj/item/stock_parts/computer/ai_slot
- name = "inteliCard slot"
- desc = "An IIS interlink with connection uplinks that allow the device to interface with most common inteliCard models. Too large to fit into tablets. Uses a lot of power when active."
+ name = "intelliCard slot"
+ desc = "An IIS interlink with connection uplinks that allow the device to interface with most common intelliCard models. Too large to fit into tablets. Uses a lot of power when active."
icon_state = "aislot"
hardware_size = 1
critical = 0
@@ -58,7 +58,7 @@
device = locate() in src
if(!device.stored_card)
- to_chat(user, "There is no intellicard connected to \the [src].")
+ to_chat(user, "There is no intelliCard connected to \the [src].")
return
device.do_eject_ai(user)
diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm
index 7c47bf5a7ba4..52f0b478b337 100644
--- a/code/modules/modular_computers/hardware/battery_module.dm
+++ b/code/modules/modular_computers/hardware/battery_module.dm
@@ -2,7 +2,7 @@
// have tremendeous capacity in comparsion. Higher tier cells would provide your device with nearly infinite battery life, which is something i want to avoid.
/obj/item/stock_parts/computer/battery_module
name = "standard battery"
- desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops. It's rating is 75 Wh."
+ desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops. Its rating is 75 Wh."
icon_state = "battery_normal"
critical = 1
origin_tech = @'{"powerstorage":1,"engineering":1}'
@@ -35,7 +35,7 @@
/obj/item/stock_parts/computer/battery_module/advanced
name = "advanced battery"
- desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices. It's rating is 110 Wh."
+ desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices. Its rating is 110 Wh."
icon_state = "battery_advanced"
origin_tech = @'{"powerstorage":2,"engineering":2}'
hardware_size = 2
@@ -44,7 +44,7 @@
/obj/item/stock_parts/computer/battery_module/super
name = "super battery"
- desc = "A very advanced power cell, often used in high-end devices, or as uninterruptable power supply for important consoles or servers. It's rating is 150 Wh."
+ desc = "A very advanced power cell, often used in high-end devices, or as uninterruptible power supply for important consoles or servers. Its rating is 150 Wh."
icon_state = "battery_super"
origin_tech = @'{"powerstorage":3,"engineering":3}'
hardware_size = 2
@@ -53,7 +53,7 @@
/obj/item/stock_parts/computer/battery_module/ultra
name = "ultra battery"
- desc = "A very advanced large power cell. It's often used as uninterruptable power supply for critical consoles or servers. It's rating is 200 Wh."
+ desc = "A very advanced large power cell. It's often used as an uninterruptible power supply for critical consoles or servers. Its rating is 200 Wh."
icon_state = "battery_ultra"
origin_tech = @'{"powerstorage":5,"engineering":4}'
hardware_size = 3
@@ -62,7 +62,7 @@
/obj/item/stock_parts/computer/battery_module/micro
name = "micro battery"
- desc = "A small power cell, commonly seen in most portable microcomputers. It's rating is 50 Wh."
+ desc = "A small power cell, commonly seen in most portable microcomputers. Its rating is 50 Wh."
icon_state = "battery_micro"
origin_tech = @'{"powerstorage":2,"engineering":2}'
battery_rating = 50
@@ -70,7 +70,7 @@
/obj/item/stock_parts/computer/battery_module/nano
name = "nano battery"
- desc = "A tiny power cell, commonly seen in low-end portable microcomputers. It's rating is 30 Wh."
+ desc = "A tiny power cell, commonly seen in low-end portable microcomputers. Its rating is 30 Wh."
icon_state = "battery_nano"
battery_rating = 30
material = /decl/material/solid/metal/steel
diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm
index 562ea9a221aa..7915dc05bac3 100644
--- a/code/modules/modular_computers/hardware/network_card.dm
+++ b/code/modules/modular_computers/hardware/network_card.dm
@@ -31,7 +31,7 @@
/obj/item/stock_parts/computer/network_card/advanced
name = "advanced network card"
- desc = "An advanced network card for usage with standard network protocols. It's transmitter is strong enough to connect even when far away."
+ desc = "An advanced network card for usage with standard network protocols. Its transmitter is strong enough to connect even when far away."
long_range = 1
origin_tech = @'{"programming":4,"engineering":2}'
power_usage = 100 // Better range but higher power usage.
diff --git a/code/modules/modular_computers/hardware/processor_unit.dm b/code/modules/modular_computers/hardware/processor_unit.dm
index 95cf5d8525d1..9c803c2c2ad2 100644
--- a/code/modules/modular_computers/hardware/processor_unit.dm
+++ b/code/modules/modular_computers/hardware/processor_unit.dm
@@ -25,7 +25,7 @@
/obj/item/stock_parts/computer/processor_unit/photonic
name = "photonic processor"
- desc = "An advanced experimental CPU that uses photonic core instead of regular circuitry. It is more power efficient than its elecron analog."
+ desc = "An advanced experimental CPU that uses photonic core instead of regular circuitry. It is more power efficient than its electron analogue."
icon_state = "cpu_normal_photonic"
hardware_size = 2
power_usage = 50
@@ -36,7 +36,7 @@
/obj/item/stock_parts/computer/processor_unit/photonic/small
name = "photonic microprocessor"
- desc = "An advanced miniaturised CPU for use in portable devices. It uses photonic core instead of regular circuitry. It is more power efficient than its elecron analog."
+ desc = "An advanced miniaturised CPU for use in portable devices. It uses photonic core instead of regular circuitry. It is more power efficient than its electron analogue."
icon_state = "cpu_small_photonic"
hardware_size = 1
power_usage = 10
diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm
index f4de33b53613..00f823ff9fba 100644
--- a/code/modules/modular_computers/laptop_vendor.dm
+++ b/code/modules/modular_computers/laptop_vendor.dm
@@ -14,19 +14,40 @@
var/obj/item/modular_computer/tablet/fabricated_tablet = null
// Utility vars
- var/state = 0 // 0: Select device type, 1: Select loadout, 2: Payment, 3: Thankyou screen
- var/devtype = 0 // 0: None(unselected), 1: Laptop, 2: Tablet
- var/total_price = 0 // Price of currently vended device.
+ var/const/STATE_DEVICE_SEL = 0
+ var/const/STATE_LOADOUT_SEL = 1
+ var/const/STATE_PAYMENT = 2
+ var/const/STATE_THANK_YOU = 3
+ var/state = STATE_DEVICE_SEL
+ var/const/DEVICE_TYPE_NONE = 0
+ var/const/DEVICE_TYPE_LAPTOP = 1
+ var/const/DEVICE_TYPE_TABLET = 2
+ var/devtype = DEVICE_TYPE_NONE
+ /// The calculated price of the currently vended device.
+ var/total_price = 0
// Device loadout
- var/dev_cpu = 1 // 1: Default, 2: Upgraded
- var/dev_battery = 1 // 1: Default, 2: Upgraded, 3: Advanced
- var/dev_disk = 1 // 1: Default, 2: Upgraded, 3: Advanced
- var/dev_netcard = 0 // 0: None, 1: Basic, 2: Long-Range
- var/dev_tesla = 0 // 0: None, 1: Standard
- var/dev_nanoprint = 0 // 0: None, 1: Standard
- var/dev_card = 0 // 0: None, 1: Standard
- var/dev_aislot = 0 // 0: None, 1: Standard
+ var/const/COMPONENT_NONE = 0
+ var/const/COMPONENT_PRESENT = 1
+ var/const/COMPONENT_BASIC = 1
+ var/const/COMPONENT_UPGRADED = 2
+ var/const/COMPONENT_ADVANCED = 3
+ /// What kind of CPU are we adding? Valid states: COMPONENT_BASIC, COMPONENT_UPGRADED
+ var/dev_cpu = COMPONENT_BASIC
+ /// What kind of battery are we adding? Valid states: COMPONENT_BASIC, COMPONENT_UPGRADED, COMPONENT_ADVANCED
+ var/dev_battery = COMPONENT_BASIC
+ /// What kind of battery are we adding? Valid states: COMPONENT_BASIC, COMPONENT_UPGRADED, COMPONENT_ADVANCED
+ var/dev_disk = COMPONENT_BASIC
+ /// What kind of network card are we adding? Valid states: COMPONENT_NONE, COMPONENT_BASIC, COMPONENT_UPGRADED
+ var/dev_netcard = COMPONENT_NONE
+ /// Are we adding a tesla relay? Valid states: COMPONENT_NONE, COMPONENT_PRESENT
+ var/dev_tesla = COMPONENT_NONE
+ /// Are we adding a printer? Valid states: COMPONENT_NONE, COMPONENT_PRESENT
+ var/dev_nanoprint = COMPONENT_NONE
+ /// Are we adding a card reader? Valid states: COMPONENT_NONE, COMPONENT_PRESENT
+ var/dev_card = COMPONENT_NONE
+ /// Are we adding an AI slot? Valid states: COMPONENT_NONE, COMPONENT_PRESENT
+ var/dev_aislot = COMPONENT_NONE
/obj/machinery/lapvend/on_update_icon()
if(stat & BROKEN)
@@ -38,92 +59,91 @@
// Removes all traces of old order and allows you to begin configuration from scratch.
/obj/machinery/lapvend/proc/reset_order()
- state = 0
- devtype = 0
- if(fabricated_laptop)
- qdel(fabricated_laptop)
- fabricated_laptop = null
- if(fabricated_tablet)
- qdel(fabricated_tablet)
- fabricated_tablet = null
- dev_cpu = 1
- dev_battery = 1
- dev_disk = 1
- dev_netcard = 0
- dev_tesla = 0
- dev_nanoprint = 0
- dev_card = 0
- dev_aislot = 0
+ state = STATE_DEVICE_SEL
+ devtype = DEVICE_TYPE_NONE
+ QDEL_NULL(fabricated_laptop)
+ QDEL_NULL(fabricated_tablet)
+ dev_cpu = COMPONENT_BASIC
+ dev_battery = COMPONENT_BASIC
+ dev_disk = COMPONENT_BASIC
+ dev_netcard = COMPONENT_NONE
+ dev_tesla = COMPONENT_NONE
+ dev_nanoprint = COMPONENT_NONE
+ dev_card = COMPONENT_NONE
+ dev_aislot = COMPONENT_NONE
// Recalculates the price and optionally even fabricates the device.
-/obj/machinery/lapvend/proc/fabricate_and_recalc_price(var/fabricate = 0)
+/obj/machinery/lapvend/proc/fabricate_and_recalc_price(var/fabricate = FALSE)
total_price = 0
- if(devtype == 1) // Laptop, generally cheaper to make it accessible for most station roles
+ if(devtype == DEVICE_TYPE_LAPTOP) // Laptop, generally cheaper to make it accessible for most station roles
var/datum/extension/assembly/modular_computer/assembly
if(fabricate)
fabricated_laptop = new(src)
assembly = get_extension(fabricated_laptop, /datum/extension/assembly)
- total_price = 99
+ total_price = atom_info_repository.get_single_worth_for(/obj/item/modular_computer/laptop)
switch(dev_cpu)
- if(1)
+ if(COMPONENT_BASIC)
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/processor_unit/small)
if(fabricate)
assembly.add_replace_component(null, PART_CPU, new/obj/item/stock_parts/computer/processor_unit/small(fabricated_laptop))
- if(2)
+ if(COMPONENT_UPGRADED)
if(fabricate)
assembly.add_replace_component(null, PART_CPU, new/obj/item/stock_parts/computer/processor_unit(fabricated_laptop))
- total_price += 299
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/processor_unit)
switch(dev_battery)
- if(1) // Basic(750C)
+ if(COMPONENT_BASIC) // Basic(750C)
if(fabricate)
assembly.add_replace_component(null, PART_BATTERY, new/obj/item/stock_parts/computer/battery_module(fabricated_laptop))
- if(2) // Upgraded(1100C)
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/battery_module)
+ if(COMPONENT_UPGRADED) // Upgraded(1100C)
if(fabricate)
assembly.add_replace_component(null, PART_BATTERY, new/obj/item/stock_parts/computer/battery_module/advanced(fabricated_laptop))
- total_price += 199
- if(3) // Advanced(1500C)
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/battery_module/advanced)
+ if(COMPONENT_ADVANCED) // Advanced(1500C)
if(fabricate)
assembly.add_replace_component(null, PART_BATTERY, new/obj/item/stock_parts/computer/battery_module/super(fabricated_laptop))
- total_price += 499
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/battery_module/super)
switch(dev_disk)
- if(1) // Basic(128GQ)
+ if(COMPONENT_BASIC) // Basic(128GQ)
if(fabricate)
assembly.add_replace_component(null, PART_HDD, new/obj/item/stock_parts/computer/hard_drive(fabricated_laptop))
- if(2) // Upgraded(256GQ)
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/hard_drive)
+ if(COMPONENT_UPGRADED) // Upgraded(256GQ)
if(fabricate)
assembly.add_replace_component(null, PART_HDD, new/obj/item/stock_parts/computer/hard_drive/advanced(fabricated_laptop))
- total_price += 99
- if(3) // Advanced(512GQ)
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/hard_drive/advanced)
+ if(COMPONENT_ADVANCED) // Advanced(512GQ)
if(fabricate)
assembly.add_replace_component(null, PART_HDD, new/obj/item/stock_parts/computer/hard_drive/super(fabricated_laptop))
- total_price += 299
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/hard_drive/super)
switch(dev_netcard)
- if(1) // Basic(Short-Range)
+ if(COMPONENT_BASIC) // Basic(Short-Range)
if(fabricate)
assembly.add_replace_component(null, PART_NETWORK, new/obj/item/stock_parts/computer/network_card(fabricated_laptop))
- total_price += 99
- if(2) // Advanced (Long Range)
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/network_card)
+ if(COMPONENT_UPGRADED) // Advanced (Long Range)
if(fabricate)
assembly.add_replace_component(null, PART_NETWORK, new/obj/item/stock_parts/computer/network_card/advanced(fabricated_laptop))
- total_price += 299
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/network_card/advanced)
if(dev_tesla)
- total_price += 399
if(fabricate)
assembly.add_replace_component(null, PART_TESLA, new/obj/item/stock_parts/computer/tesla_link(fabricated_laptop))
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/tesla_link)
if(dev_nanoprint)
- total_price += 99
if(fabricate)
assembly.add_replace_component(null, PART_PRINTER, new/obj/item/stock_parts/computer/nano_printer(fabricated_laptop))
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/nano_printer)
if(dev_card)
- total_price += 199
if(fabricate)
assembly.add_replace_component(null, PART_CARD, new/obj/item/stock_parts/computer/card_slot(fabricated_laptop))
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/card_slot)
if(dev_aislot)
- total_price += 499
if(fabricate)
assembly.add_replace_component(null, PART_AI, new/obj/item/stock_parts/computer/ai_slot(fabricated_laptop))
+ total_price += atom_info_repository.get_single_worth_for(/obj/item/stock_parts/computer/ai_slot)
return total_price
- else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this.
+ else if(devtype == DEVICE_TYPE_TABLET) // Tablet, more expensive, not everyone could probably afford this.
var/datum/extension/assembly/modular_computer/assembly
if(fabricate)
fabricated_tablet = new(src)
@@ -131,35 +151,35 @@
assembly.add_replace_component(null, PART_CPU, new/obj/item/stock_parts/computer/processor_unit/small(fabricated_tablet))
total_price = 199
switch(dev_battery)
- if(1) // Basic(300C)
+ if(COMPONENT_BASIC) // Basic(300C)
if(fabricate)
assembly.add_replace_component(null, PART_BATTERY, new/obj/item/stock_parts/computer/battery_module/nano(fabricated_tablet))
- if(2) // Upgraded(500C)
+ if(COMPONENT_UPGRADED) // Upgraded(500C)
if(fabricate)
assembly.add_replace_component(null, PART_BATTERY, new/obj/item/stock_parts/computer/battery_module/micro(fabricated_tablet))
total_price += 199
- if(3) // Advanced(750C)
+ if(COMPONENT_ADVANCED) // Advanced(750C)
if(fabricate)
assembly.add_replace_component(null, PART_BATTERY, new/obj/item/stock_parts/computer/battery_module(fabricated_tablet))
total_price += 499
switch(dev_disk)
- if(1) // Basic(32GQ)
+ if(COMPONENT_BASIC) // Basic(32GQ)
if(fabricate)
assembly.add_replace_component(null, PART_HDD, new/obj/item/stock_parts/computer/hard_drive/micro(fabricated_tablet))
- if(2) // Upgraded(64GQ)
+ if(COMPONENT_UPGRADED) // Upgraded(64GQ)
if(fabricate)
assembly.add_replace_component(null, PART_HDD, new/obj/item/stock_parts/computer/hard_drive/small(fabricated_tablet))
total_price += 99
- if(3) // Advanced(128GQ)
+ if(COMPONENT_ADVANCED) // Advanced(128GQ)
if(fabricate)
assembly.add_replace_component(null, PART_HDD, new/obj/item/stock_parts/computer/hard_drive(fabricated_tablet))
total_price += 299
switch(dev_netcard)
- if(1) // Basic(Short-Range)
+ if(COMPONENT_BASIC) // Basic(Short-Range)
if(fabricate)
assembly.add_replace_component(null, PART_NETWORK, new/obj/item/stock_parts/computer/network_card(fabricated_tablet))
total_price += 99
- if(2) // Advanced (Long Range)
+ if(COMPONENT_UPGRADED) // Advanced (Long Range)
if(fabricate)
assembly.add_replace_component(null, PART_NETWORK, new/obj/item/stock_parts/computer/network_card/advanced(fabricated_tablet))
total_price += 299
@@ -182,76 +202,75 @@
return total_price
return 0
-
-
-
-
-/obj/machinery/lapvend/Topic(href, href_list)
- if(..())
- return 1
+/obj/machinery/lapvend/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["pick_device"])
if(state) // We've already picked a device type
- return 0
+ return TOPIC_REFRESH // Your UI must be out of date (or you're trying to href hack...)
devtype = text2num(href_list["pick_device"])
- state = 1
- fabricate_and_recalc_price(0)
- return 1
+ state = STATE_LOADOUT_SEL
+ fabricate_and_recalc_price(FALSE)
+ return TOPIC_REFRESH
if(href_list["clean_order"])
reset_order()
- return 1
- if((state != 1) && devtype) // Following IFs should only be usable when in the Select Loadout mode
- return 0
+ return TOPIC_REFRESH
+ // Following IFs should only be usable when in the Select Loadout mode.
+ if(state != STATE_LOADOUT_SEL)
+ return TOPIC_NOACTION
+ // Proceed to payment
if(href_list["confirm_order"])
- state = 2 // Wait for ID swipe for payment processing
- fabricate_and_recalc_price(0)
- return 1
+ state = STATE_PAYMENT // Wait for ID swipe for payment processing
+ fabricate_and_recalc_price(FALSE)
+ return TOPIC_REFRESH
+ // Hardware selection
if(href_list["hw_cpu"])
dev_cpu = text2num(href_list["hw_cpu"])
- fabricate_and_recalc_price(0)
- return 1
+ fabricate_and_recalc_price(FALSE)
+ return TOPIC_REFRESH
if(href_list["hw_battery"])
dev_battery = text2num(href_list["hw_battery"])
- fabricate_and_recalc_price(0)
- return 1
+ fabricate_and_recalc_price(FALSE)
+ return TOPIC_REFRESH
if(href_list["hw_disk"])
dev_disk = text2num(href_list["hw_disk"])
- fabricate_and_recalc_price(0)
- return 1
+ fabricate_and_recalc_price(FALSE)
+ return TOPIC_REFRESH
if(href_list["hw_netcard"])
dev_netcard = text2num(href_list["hw_netcard"])
- fabricate_and_recalc_price(0)
- return 1
+ fabricate_and_recalc_price(FALSE)
+ return TOPIC_REFRESH
if(href_list["hw_tesla"])
dev_tesla = text2num(href_list["hw_tesla"])
- fabricate_and_recalc_price(0)
- return 1
+ fabricate_and_recalc_price(FALSE)
+ return TOPIC_REFRESH
if(href_list["hw_nanoprint"])
dev_nanoprint = text2num(href_list["hw_nanoprint"])
- fabricate_and_recalc_price(0)
- return 1
+ fabricate_and_recalc_price(FALSE)
+ return TOPIC_REFRESH
if(href_list["hw_card"])
dev_card = text2num(href_list["hw_card"])
- fabricate_and_recalc_price(0)
- return 1
+ fabricate_and_recalc_price(FALSE)
+ return TOPIC_REFRESH
if(href_list["hw_aislot"])
dev_aislot = text2num(href_list["hw_aislot"])
- fabricate_and_recalc_price(0)
- return 1
- return 0
+ fabricate_and_recalc_price(FALSE)
+ return TOPIC_REFRESH
+ return TOPIC_NOACTION
/obj/machinery/lapvend/interface_interact(var/mob/user)
ui_interact(user)
return TRUE
/obj/machinery/lapvend/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
- if(stat & (BROKEN | NOPOWER | MAINT))
+ if(inoperable(MAINT))
if(ui)
ui.close()
- return 0
- var/list/data[0]
+ return
+ var/list/data = list()
data["state"] = state
- if(state == 1)
+ if(state == STATE_LOADOUT_SEL)
data["devtype"] = devtype
data["hw_battery"] = dev_battery
data["hw_disk"] = dev_disk
@@ -261,7 +280,7 @@
data["hw_card"] = dev_card
data["hw_cpu"] = dev_cpu
data["hw_aislot"] = dev_aislot
- if(state == 1 || state == 2)
+ if(state == STATE_LOADOUT_SEL || state == STATE_PAYMENT)
var/decl/currency/cur = GET_DECL(global.using_map.default_currency)
data["totalprice"] = cur.format_value(total_price)
@@ -273,29 +292,26 @@
ui.set_auto_update(1)
-/obj/machinery/lapvend/attackby(obj/item/W as obj, mob/user as mob)
- // Awaiting payment state
- if(state == 2)
- if(process_payment(W))
- fabricate_and_recalc_price(1)
- flick("world-vend", src)
- if((devtype == 1) && fabricated_laptop)
- fabricated_laptop.forceMove(src.loc)
- fabricated_laptop.update_icon()
- fabricated_laptop.update_verbs()
- fabricated_laptop = null
- else if((devtype == 2) && fabricated_tablet)
- fabricated_tablet.forceMove(src.loc)
- fabricated_tablet.update_verbs()
- fabricated_tablet = null
- ping("Enjoy your new product!")
- state = 3
- return 1
- return 0
+/obj/machinery/lapvend/attackby(obj/item/held_item as obj, mob/user as mob)
+ if(state == STATE_PAYMENT && process_payment(held_item))
+ fabricate_and_recalc_price(TRUE)
+ flick("world-vend", src)
+ if((devtype == DEVICE_TYPE_LAPTOP) && fabricated_laptop)
+ fabricated_laptop.forceMove(src.loc)
+ fabricated_laptop.update_icon()
+ fabricated_laptop.update_verbs()
+ fabricated_laptop = null
+ else if((devtype == DEVICE_TYPE_TABLET) && fabricated_tablet)
+ fabricated_tablet.forceMove(src.loc)
+ fabricated_tablet.update_verbs()
+ fabricated_tablet = null
+ ping("Enjoy your new product!")
+ state = STATE_THANK_YOU
+ return TRUE
return ..()
-// Simplified payment processing, returns 1 on success.
+// Simplified payment processing, returns TRUE on success.
/obj/machinery/lapvend/proc/process_payment(var/obj/item/charge_stick/I)
if(!istype(I))
ping("Invalid payment format.")
diff --git a/code/modules/modular_computers/terminal/terminal.dm b/code/modules/modular_computers/terminal/terminal.dm
index dec38ed92f15..02f13da48bc2 100644
--- a/code/modules/modular_computers/terminal/terminal.dm
+++ b/code/modules/modular_computers/terminal/terminal.dm
@@ -266,4 +266,4 @@
if(OS_NETWORK_ERROR)
return "Unable to connect to the network"
- return "An unspecified error occured."
\ No newline at end of file
+ return "An unspecified error occurred."
\ No newline at end of file
diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm
index 573c28223f17..802d6782d279 100644
--- a/code/modules/multiz/movement.dm
+++ b/code/modules/multiz/movement.dm
@@ -111,7 +111,7 @@
moving = FALSE
//For children to override
-/atom/movable/proc/can_fall(var/anchor_bypass = FALSE, var/turf/location_override = loc)
+/atom/movable/proc/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
if(immune_to_floor_hazards())
return FALSE
@@ -137,16 +137,16 @@
return TRUE
-/obj/can_fall(var/anchor_bypass = FALSE, var/turf/location_override = loc)
- return ..(anchor_fall)
+/obj/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
+ return ..(anchor_fall, location_override)
-/obj/effect/can_fall(var/anchor_bypass = FALSE, var/turf/location_override = loc)
+/obj/effect/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
return FALSE
-/obj/effect/decal/cleanable/can_fall(var/anchor_bypass = FALSE, var/turf/location_override = loc)
+/obj/effect/decal/cleanable/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
return TRUE
-/obj/item/pipe/can_fall(var/anchor_bypass = FALSE, var/turf/location_override = loc)
+/obj/item/pipe/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
var/turf/open/below = loc
below = below.below
@@ -158,18 +158,21 @@
if((locate(/obj/structure/disposalpipe/up) in below) || locate(/obj/machinery/atmospherics/pipe/zpipe/up) in below)
return FALSE
-/mob/living/can_fall(var/anchor_bypass = FALSE, var/turf/location_override = loc)
+/mob/living/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
if((. = ..()))
var/decl/species/my_species = get_species()
if(my_species)
return my_species.can_fall(src)
/atom/movable/proc/protected_from_fall_damage(var/turf/landing)
- if(!!(locate(/obj/structure/stairs) in landing))
- return TRUE
- var/turf/wall/natural/ramp = landing
- if(istype(ramp) && ramp.ramp_slope_direction) // walking down a ramp
- return TRUE
+ // Stairs and ramps will not save you from a high drop.
+ if(get_fall_height() <= 1)
+ if(!!(locate(/obj/structure/stairs) in landing))
+ return TRUE
+ var/turf/wall/natural/ramp = landing
+ if(istype(ramp) && ramp.ramp_slope_direction) // walking down a ramp
+ return TRUE
+ return FALSE
/mob/protected_from_fall_damage(var/turf/landing)
. = ..()
@@ -213,10 +216,16 @@
/atom/movable/proc/handle_fall_effect(var/turf/landing)
SHOULD_CALL_PARENT(TRUE)
- if(istype(landing) && landing.is_open())
- visible_message("\The [src] falls through \the [landing]!", "You hear a whoosh of displaced air.")
+ if(istype(landing) && can_fall() && landing.CanZPass(src, DOWN))
+ visible_message(
+ SPAN_NOTICE("\The [src] falls through \the [landing]!"),
+ "You hear a whoosh of displaced air."
+ )
else
- visible_message("\The [src] slams into \the [landing]!", "You hear something slam into the [global.using_map.ground_noun].")
+ visible_message(
+ SPAN_DANGER("\The [src] slams into [landing.is_open() ? "\the [landing]" : "an obstacle"]!"),
+ "You hear something slam into the [global.using_map.ground_noun]."
+ )
var/fall_damage = fall_damage() * get_fall_height()
if(fall_damage > 0)
for(var/mob/living/M in landing.contents)
@@ -421,7 +430,7 @@
owner = null
. = ..()
-/atom/movable/z_observer/can_fall()
+/atom/movable/z_observer/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
return FALSE
/atom/movable/z_observer/explosion_act()
diff --git a/code/modules/multiz/zmimic/mimic_movable.dm b/code/modules/multiz/zmimic/mimic_movable.dm
index 04644bcdde71..2cbf1c065f4e 100644
--- a/code/modules/multiz/zmimic/mimic_movable.dm
+++ b/code/modules/multiz/zmimic/mimic_movable.dm
@@ -49,7 +49,7 @@
mouse_opacity = FALSE
abstract_type = /atom/movable/openspace // unsure if this is valid, check with Lohi -- Yes, it's valid.
-/atom/movable/openspace/can_fall()
+/atom/movable/openspace/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
return FALSE
// No blowing up abstract objects.
diff --git a/code/modules/nano/interaction/default.dm b/code/modules/nano/interaction/default.dm
index 4e1f89bb2d45..51a7a6eca757 100644
--- a/code/modules/nano/interaction/default.dm
+++ b/code/modules/nano/interaction/default.dm
@@ -45,13 +45,13 @@ var/global/datum/topic_state/default/default_topic_state = new
if(src_object in view(client.view, src))
return STATUS_INTERACTIVE
- // If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view
+ // If we're installed in a chassi, rather than transfered to an intelliCard or other container, then check if we have camera view
if(is_in_chassis())
//stop AIs from leaving windows open and using then after they lose vision
if(cameranet && !cameranet.is_turf_visible(get_turf(src_object)))
return STATUS_CLOSE
return STATUS_INTERACTIVE
- else if(get_dist(src_object, src) <= get_effective_view(client)) // View does not return what one would expect while installed in an inteliCard
+ else if(get_dist(src_object, src) <= get_effective_view(client)) // View does not return what one would expect while installed in an intelliCard
return STATUS_INTERACTIVE
return STATUS_CLOSE
diff --git a/code/modules/nano/interaction/hands.dm b/code/modules/nano/interaction/hands.dm
index fe9a3df4c4fd..3122925e2cc0 100644
--- a/code/modules/nano/interaction/hands.dm
+++ b/code/modules/nano/interaction/hands.dm
@@ -1,6 +1,7 @@
-/*
- This state only checks if user is conscious.
-*/
+/**
+ This state checks if src_object is held in the user's hands (or a cyborg gripper),
+ as well as the default NanoUI interaction.
+**/
var/global/datum/topic_state/hands/hands_topic_state = new
/datum/topic_state/hands/can_use_topic(src_object, mob/user)
diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm
index e315b28c5809..f2125ae38e31 100644
--- a/code/modules/nano/nanoui.dm
+++ b/code/modules/nano/nanoui.dm
@@ -388,7 +388,7 @@ nanoui is used to open and update nano browser uis
diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm
index c65f7e18f4d9..a249ef857038 100644
--- a/code/modules/organs/external/_external.dm
+++ b/code/modules/organs/external/_external.dm
@@ -148,7 +148,7 @@
if(bodytype != old_bodytype && apply_to_internal_organs)
bodytype.rebuild_internal_organs(src, override_material)
if(.)
- update_icon(TRUE)
+ update_icon()
/obj/item/organ/external/copy_from_mob_snapshot(datum/mob_snapshot/supplied_appearance)
_icon_cache_key = null
diff --git a/code/modules/organs/external/_external_icons.dm b/code/modules/organs/external/_external_icons.dm
index 8f9b601a8c55..61ed76c361c8 100644
--- a/code/modules/organs/external/_external_icons.dm
+++ b/code/modules/organs/external/_external_icons.dm
@@ -43,7 +43,7 @@ var/global/list/limb_icon_cache = list()
if(eyes) eyes.update_colour()
/obj/item/organ/external/head/on_remove_effects(mob/living/last_owner)
- update_icon(1)
+ update_icon()
if(last_owner)
SetName("[last_owner.real_name]'s head")
addtimer(CALLBACK(last_owner, TYPE_PROC_REF(/mob, update_hair)), 1, TIMER_UNIQUE)
diff --git a/code/modules/organs/internal/brain_computer.dm b/code/modules/organs/internal/brain_computer.dm
index 78d419590260..919b10e056d7 100644
--- a/code/modules/organs/internal/brain_computer.dm
+++ b/code/modules/organs/internal/brain_computer.dm
@@ -1,7 +1,7 @@
// Robobrain.
/obj/item/organ/internal/brain/robotic
name = "computer intelligence core"
- desc = "The pinnacle of artifical intelligence technology, conveniently stored in a fist-sized cube."
+ desc = "The pinnacle of artificial intelligence technology, conveniently stored in a fist-sized cube."
icon = 'icons/obj/items/brain_interface_robotic.dmi'
origin_tech = @'{"engineering":4,"materials":4,"wormholes":2,"programming":4}'
material = /decl/material/solid/metal/steel
diff --git a/code/modules/organs/internal/lungs.dm b/code/modules/organs/internal/lungs.dm
index 7a9b0cb81803..2cfdb5d8fa1e 100644
--- a/code/modules/organs/internal/lungs.dm
+++ b/code/modules/organs/internal/lungs.dm
@@ -199,12 +199,12 @@
to_chat(owner, SPAN_NOTICE("It gets easier to breathe."))
breath_fail_ratio = clamp(0,breath_fail_ratio-0.05,1)
- SET_HUD_ALERT(owner, /decl/hud_element/condition/oxygen, (failed_inhale * 2))
+ SET_HUD_ALERT(owner, HUD_OXY, (failed_inhale * 2))
var/inhaled_gas_used = inhaling / 4
breath.adjust_gas(breath_type, -inhaled_gas_used, update = 0) //update afterwards
- SET_HUD_ALERT(owner, /decl/hud_element/condition/toxins, 0) // Reset our toxins alert for now.
+ SET_HUD_ALERT(owner, HUD_TOX, 0) // Reset our toxins alert for now.
if(!failed_inhale) // Enough gas to tell we're being poisoned via chemical burns or whatever.
var/poison_total = 0
if(poison_types)
@@ -212,7 +212,7 @@
if(poison_types[gname])
poison_total += breath.gas[gname]
if(((poison_total/breath.total_moles)*breath_pressure) > safe_toxins_max)
- SET_HUD_ALERT(owner, /decl/hud_element/condition/toxins, 1)
+ SET_HUD_ALERT(owner, HUD_TOX, 1)
// Pass reagents from the gas into our body.
// Presumably if you breathe it you have a specialized metabolism for it, so we drop/ignore breath_type. Also avoids
@@ -252,7 +252,7 @@
if(failed_breath)
handle_failed_breath()
else
- SET_HUD_ALERT(owner, /decl/hud_element/condition/oxygen, 0)
+ SET_HUD_ALERT(owner, HUD_OXY, 0)
return failed_breath
/obj/item/organ/internal/lungs/proc/handle_failed_breath()
@@ -266,7 +266,7 @@
if(damage || GET_CHEMICAL_EFFECT(owner, CE_BREATHLOSS) || world.time > last_successful_breath + 2 MINUTES)
owner.take_damage(HUMAN_MAX_OXYLOSS*breath_fail_ratio, OXY)
- SET_HUD_ALERT_MAX(owner, /decl/hud_element/condition/oxygen, 2)
+ SET_HUD_ALERT_MAX(owner, HUD_OXY, 2)
last_int_pressure = 0
/obj/item/organ/internal/lungs/proc/handle_temperature_effects(datum/gas_mixture/breath)
@@ -289,7 +289,7 @@
owner.apply_damage(damage, BURN, BP_HEAD, used_weapon = "Excessive Cold")
else
src.damage += damage
- SET_HUD_ALERT(owner, /decl/hud_element/condition/fire, 1)
+ SET_HUD_ALERT(owner, HUD_FIRE, 1)
else if(breath.temperature >= heat_1)
if(prob(20))
to_chat(owner, "You feel your face burning and a searing heat in your lungs!")
@@ -305,7 +305,7 @@
owner.apply_damage(damage, BURN, BP_HEAD, used_weapon = "Excessive Heat")
else
src.damage += damage
- SET_HUD_ALERT(owner, /decl/hud_element/condition/fire, 2)
+ SET_HUD_ALERT(owner, HUD_FIRE, 2)
//breathing in hot/cold air also heats/cools you a bit
var/temp_adj = breath.temperature - owner.bodytemperature
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 84d4cbc4155e..9fb1bec56819 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -57,7 +57,8 @@
return
/obj/item/organ/proc/refresh_action_button()
- return action
+ if(!QDELETED(src) && istype(action))
+ return action
/obj/item/organ/attack_self(var/mob/user)
return (owner && loc == owner && owner == user)
@@ -632,7 +633,7 @@ var/global/list/ailment_reference_cache = list()
STOP_PROCESSING(SSobj, src)
vital_to_owner = null
-//Since some types of organs completely ignore being detached, moved it to an overridable organ proc for external prosthetics
+//Since some types of organs completely ignore being detached, moved it to an overrideable organ proc for external prosthetics
/obj/item/organ/proc/set_detached(var/is_detached)
if(is_detached)
status |= ORGAN_CUT_AWAY
diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm
index 1f8f233fc7ce..141643e41cc5 100644
--- a/code/modules/organs/pain.dm
+++ b/code/modules/organs/pain.dm
@@ -1,3 +1,14 @@
+/mob
+ var/obj/screen/fullscreen/pain/pain
+
+/mob/Initialize()
+ pain = new(null, src)
+ . = ..()
+
+/mob/Destroy()
+ QDEL_NULL(pain)
+ . = ..()
+
/mob/proc/flash_pain(var/target)
if(pain)
var/matrix/M
diff --git a/code/modules/overmap/ftl_shunt/core.dm b/code/modules/overmap/ftl_shunt/core.dm
index 269e858851fb..c497e066fdab 100644
--- a/code/modules/overmap/ftl_shunt/core.dm
+++ b/code/modules/overmap/ftl_shunt/core.dm
@@ -374,7 +374,7 @@
A.overload_lighting(50)
/obj/machinery/ftl_shunt/core/proc/handle_spacefloat(var/mob/living/human/H)
- if(!H.check_space_footing())
+ if(H.can_slip(magboots_only = TRUE))
//Flip a coin ...
to_chat(H, SPAN_WARNING("Being untethered from a ship entering FTL is a bad idea, but you roll the dice..."))
if(prob(50))
diff --git a/code/modules/overmap/ships/computers/sensors.dm b/code/modules/overmap/ships/computers/sensors.dm
index cfbf0ad897dc..d1a572768517 100644
--- a/code/modules/overmap/ships/computers/sensors.dm
+++ b/code/modules/overmap/ships/computers/sensors.dm
@@ -257,4 +257,4 @@
/obj/machinery/shipsensors/weak
heat_reduction = 0.2
- desc = "Miniturized gravity scanner with various other sensors, used to detect irregularities in surrounding space. Can only run in vacuum to protect delicate quantum BS elements."
+ desc = "Miniaturized gravity scanner with various other sensors, used to detect irregularities in surrounding space. Can only run in vacuum to protect delicate quantum BS elements."
diff --git a/code/modules/overmap/ships/machines/fusion_thruster.dm b/code/modules/overmap/ships/machines/fusion_thruster.dm
index c8e10e58d04b..0f4b673554c1 100644
--- a/code/modules/overmap/ships/machines/fusion_thruster.dm
+++ b/code/modules/overmap/ships/machines/fusion_thruster.dm
@@ -1,6 +1,6 @@
/obj/machinery/atmospherics/unary/engine/fusion
name = "fusion nozzle"
- desc = "Simple rocket nozzle, expelling gas at hypersonic velocities to propell the ship."
+ desc = "Simple rocket nozzle, expelling gas at hypersonic velocities to propel the ship."
base_type = /obj/machinery/atmospherics/unary/engine/fusion
engine_extension = /datum/extension/ship_engine/gas/fusion
diff --git a/code/modules/overmap/ships/machines/gas_thruster.dm b/code/modules/overmap/ships/machines/gas_thruster.dm
index 7650eb31085d..4d744491d3a2 100644
--- a/code/modules/overmap/ships/machines/gas_thruster.dm
+++ b/code/modules/overmap/ships/machines/gas_thruster.dm
@@ -1,6 +1,6 @@
/obj/machinery/atmospherics/unary/engine
name = "rocket nozzle"
- desc = "Simple rocket nozzle, expelling gas at hypersonic velocities to propell the ship."
+ desc = "Simple rocket nozzle, expelling gas at hypersonic velocities to propel the ship."
icon = 'icons/obj/ship_engine.dmi'
icon_state = "nozzle"
layer = STRUCTURE_LAYER
diff --git a/code/modules/paperwork/adminpaper.dm b/code/modules/paperwork/adminpaper.dm
index a7d1cda991a9..d886c4defe19 100644
--- a/code/modules/paperwork/adminpaper.dm
+++ b/code/modules/paperwork/adminpaper.dm
@@ -57,7 +57,7 @@
text = "
"
text += "This transmission is intended only for the addressee and may contain confidential information. Any unauthorized disclosure is strictly prohibited.
"
- text += "If this transmission is recieved in error, please notify both the sender and the office of [global.using_map.boss_name] Internal Affairs immediately so that corrective action may be taken."
+ text += "If this transmission is received in error, please notify both the sender and the office of [global.using_map.boss_name] Internal Affairs immediately so that corrective action may be taken."
text += "Failure to comply is a breach of regulation and may be prosecuted to the fullest extent of the law, where applicable."
text += ""
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
index a5008f8e2256..a6a51a71675b 100644
--- a/code/modules/paperwork/folders.dm
+++ b/code/modules/paperwork/folders.dm
@@ -11,6 +11,8 @@
pickup_sound = 'sound/foley/paperpickup2.ogg'
material = /decl/material/solid/organic/cardboard
item_flags = ITEM_FLAG_CAN_TAPE
+ /// If true, add a cosmetic overlay when we have contents.
+ var/has_paper_overlay = TRUE
/obj/item/folder/blue
desc = "A blue folder."
@@ -28,9 +30,9 @@
desc = "A cyan folder."
icon_state = "folder_cyan"
-/obj/item/folder/on_update_icon(var/paper_overlay = TRUE)
+/obj/item/folder/on_update_icon()
. = ..()
- if(paper_overlay && length(contents))
+ if(has_paper_overlay && length(contents))
add_overlay("folder_paper")
/obj/item/folder/attackby(obj/item/W, mob/user)
@@ -88,10 +90,11 @@
name = "envelope"
desc = "A thick envelope. You can't see what's inside."
icon_state = "envelope_sealed"
+ has_paper_overlay = FALSE
var/sealed = 1
/obj/item/folder/envelope/on_update_icon()
- . = ..(paper_overlay = FALSE)
+ . = ..()
if(sealed)
icon_state = "envelope_sealed"
else
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index eb9bbb76a03b..6bd2a2524065 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -219,6 +219,10 @@
. = ..()
update_icon()
+/obj/item/camera/loaded/Initialize()
+ . = ..()
+ film = new /obj/item/camera_film(src)
+
/obj/item/camera/on_update_icon()
. = ..()
var/datum/extension/base_icon_state/bis = get_extension(src, /datum/extension/base_icon_state)
diff --git a/code/modules/paperwork/printer.dm b/code/modules/paperwork/printer.dm
index 0f91439ab58b..cfb02e78a147 100644
--- a/code/modules/paperwork/printer.dm
+++ b/code/modules/paperwork/printer.dm
@@ -5,7 +5,7 @@
////////////////////////////////////////////////////////////////////////////////////////
/obj/item/stock_parts/printer
name = "printer"
- desc = "A full fledged laser printer. This one is meant to be installed inside another machine. Comes with its own paper feeder and toner slot."
+ desc = "A full-fledged laser printer. This one is meant to be installed inside another machine. Comes with its own paper feeder and toner slot."
icon = 'icons/obj/items/stock_parts/modular_components.dmi'
icon_state = "printer"
randpixel = 5
diff --git a/code/game/objects/effects/decals/posters/_poster.dm b/code/modules/posters/_poster.dm
similarity index 100%
rename from code/game/objects/effects/decals/posters/_poster.dm
rename to code/modules/posters/_poster.dm
diff --git a/code/game/objects/effects/decals/posters/_poster_design.dm b/code/modules/posters/_poster_design.dm
similarity index 100%
rename from code/game/objects/effects/decals/posters/_poster_design.dm
rename to code/modules/posters/_poster_design.dm
diff --git a/code/game/objects/effects/decals/posters/bs12.dm b/code/modules/posters/bs12.dm
similarity index 100%
rename from code/game/objects/effects/decals/posters/bs12.dm
rename to code/modules/posters/bs12.dm
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 6e2b63b82fa9..11e314053cea 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -6,7 +6,7 @@ var/global/list/all_apcs = list()
// Requires a wire connection to a power network through a terminal
// Generates a terminal based on the direction of the APC on spawn
-// There are three different power channels, lighting, equipment, and enviroment
+// There are three different power channels, lighting, equipment, and environment
// Each may have one of the following states
// Power channels set to Auto change when power levels rise or drop below a threshold
diff --git a/code/modules/power/batteryrack.dm b/code/modules/power/batteryrack.dm
index ec8e3abac1c0..27524a6eb2c4 100644
--- a/code/modules/power/batteryrack.dm
+++ b/code/modules/power/batteryrack.dm
@@ -249,36 +249,34 @@
/obj/machinery/power/smes/batteryrack/outputting()
return
-/obj/machinery/power/smes/batteryrack/Topic(href, href_list)
+/obj/machinery/power/smes/batteryrack/OnTopic(mob/user, href_list)
// ..() would respond to those topic calls, but we don't want to use them at all.
// Calls to these shouldn't occur anyway, due to usage of different nanoUI, but
// it's here in case someone decides to try hrefhacking/modified templates.
if(href_list["input"] || href_list["output"])
- return 1
-
- if(..())
- return 1
+ return TOPIC_HANDLED
+ if((. = ..()))
+ return
if( href_list["disable"] )
update_io(0)
- return 1
+ return TOPIC_REFRESH
else if( href_list["enable"] )
update_io(clamp(text2num(href_list["enable"]), 1, 3))
- return 1
+ return TOPIC_REFRESH
else if( href_list["equaliseon"] )
equalise = 1
- return 1
+ return TOPIC_REFRESH
else if( href_list["equaliseoff"] )
equalise = 0
- return 1
+ return TOPIC_REFRESH
else if( href_list["ejectcell"] )
var/slot_number = text2num(href_list["ejectcell"])
if(slot_number != clamp(round(slot_number), 1, length(internal_cells)))
- return 1
+ return TOPIC_HANDLED
var/obj/item/cell/C = internal_cells[slot_number]
C.dropInto(loc)
internal_cells -= C
- update_icon()
RefreshParts()
update_maxcharge()
- return 1
\ No newline at end of file
+ return TOPIC_REFRESH
\ No newline at end of file
diff --git a/code/modules/power/breaker_box.dm b/code/modules/power/breaker_box.dm
index bf0c3c7fc75b..5cb140c727e3 100644
--- a/code/modules/power/breaker_box.dm
+++ b/code/modules/power/breaker_box.dm
@@ -8,7 +8,7 @@
name = "breaker box"
icon = 'icons/obj/power.dmi'
icon_state = "bbox_off"
- desc = "A large machine with heavy duty switching circuits used for advanced grid control."
+ desc = "A large machine with heavy-duty switching circuits used for advanced grid control."
//directwired = 0
var/icon_state_on = "bbox_on"
var/icon_state_off = "bbox_off"
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 655e27664973..0aa55c1c1e15 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -82,8 +82,20 @@ By design, d1 is the smallest direction and d2 is the highest
color = COLOR_SILVER
paint_color = COLOR_SILVER
+/obj/structure/cable/proc/canonize_cable_dirs()
+ // ensure d1 & d2 reflect the icon_state for entering and exiting cable
+ var/dir_components = splittext(icon_state, "-")
+ if(length(dir_components) < 2)
+ CRASH("Cable segment updating dirs with invalid icon_state: [d1], [d2]")
+ d1 = text2num(dir_components[1])
+ d2 = text2num(dir_components[2])
+ if(!(d1 in global.cabledirs) || !(d2 in global.cabledirs))
+ CRASH("Cable segment updating dirs with invalid values: [d1], [d2]")
+
/obj/structure/cable/Initialize(var/ml)
// ensure d1 & d2 reflect the icon_state for entering and exiting cable
+ if(isnull(d1) || isnull(d2))
+ canonize_cable_dirs()
. = ..(ml)
var/turf/T = src.loc // hide if turf is not intact
if(level == LEVEL_BELOW_PLATING && T)
@@ -129,18 +141,10 @@ By design, d1 is the smallest direction and d2 is the highest
/obj/structure/cable/on_update_icon()
..()
- // It is really gross to do this here but the order of icon updates to init seems
- // unreliable and I have now had to spend hours across two PRs chasing down
- // cable node weirdness due to the way this was handled previously. NO MORE.
+ // this should be less necessary now but it might still be just in case a subtype calls update_icon() in Initialize prior to its parent call
+ // which... don't do that, but better safe than sorry.
if(isnull(d1) || isnull(d2))
- var/dir_components = splittext(icon_state, "-")
- if(length(dir_components) < 2)
- CRASH("Cable segment updating dirs with invalid icon_state: [d1], [d2]")
- d1 = text2num(dir_components[1])
- d2 = text2num(dir_components[2])
- if(!(d1 in global.cabledirs) || !(d2 in global.cabledirs))
- CRASH("Cable segment updating dirs with invalid values: [d1], [d2]")
-
+ canonize_cable_dirs()
icon_state = "[d1]-[d2]"
alpha = invisibility ? 127 : 255
@@ -509,7 +513,7 @@ By design, d1 is the smallest direction and d2 is the highest
max_amount = MAXCOIL
color = COLOR_MAROON
paint_color = COLOR_MAROON
- desc = "A coil of wiring, suitable for both delicate electronics and heavy duty power supply."
+ desc = "A coil of wiring, suitable for both delicate electronics and heavy-duty power supply."
singular_name = "length"
w_class = ITEM_SIZE_NORMAL
throw_speed = 2
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index a60fab7f939a..f6dada5b25d4 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -1,7 +1,7 @@
// Power Cells
/obj/item/cell
name = "power cell"
- desc = "A rechargable electrochemical power cell."
+ desc = "A rechargeable electrochemical power cell."
icon = 'icons/obj/power.dmi'
icon_state = "cell"
item_state = "cell"
@@ -315,13 +315,13 @@
/obj/item/cell/potato
name = "potato battery"
- desc = "A rechargable starch based power cell."
+ desc = "A rechargeable starch based power cell."
origin_tech = @'{"powerstorage":1}'
icon = 'icons/obj/power.dmi'
icon_state = "potato_cell"
maxcharge = 20
-//Generic battery cell for guns with rechargable batteries.
+//Generic battery cell for guns with rechargeable batteries.
/obj/item/cell/gun
name = "weapon energy cell"
desc = "A military grade high-density battery, expected to deplete after tens of thousands of complete charge cycles."
diff --git a/code/modules/power/floorlamp.dm b/code/modules/power/floorlamp.dm
index 39ff3b57c3a4..62d4208e5905 100644
--- a/code/modules/power/floorlamp.dm
+++ b/code/modules/power/floorlamp.dm
@@ -23,12 +23,14 @@
if(istype(held_item, /obj/item/lampshade))
lampshade = held_item
user.drop_from_inventory(held_item, src)
- update_icon(0)
+ update_light_status(FALSE)
+ update_icon()
return TRUE
else if(held_item.do_tool_interaction(TOOL_SCREWDRIVER, user, src, 1 SECOND, "unscrewing", "unscrewing"))
lampshade.dropInto(loc)
lampshade = null
- update_icon(0)
+ update_light_status(FALSE)
+ update_icon()
return TRUE
return ..()
diff --git a/code/modules/power/fusion/core/_core.dm b/code/modules/power/fusion/core/_core.dm
index 3f667ebaa7d6..31a3fff21fa3 100644
--- a/code/modules/power/fusion/core/_core.dm
+++ b/code/modules/power/fusion/core/_core.dm
@@ -43,15 +43,16 @@
else
owned_field.handle_tick()
-/obj/machinery/fusion_core/Topic(href, href_list)
- if(..())
- return 1
+/obj/machinery/fusion_core/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if(href_list["str"])
var/dif = text2num(href_list["str"])
field_strength = min(max(field_strength + dif, MIN_FIELD_STR), MAX_FIELD_STR)
change_power_consumption(500 * field_strength, POWER_USE_ACTIVE)
if(owned_field)
owned_field.ChangeFieldStrength(field_strength)
+ return TOPIC_REFRESH
/obj/machinery/fusion_core/update_use_power(new_use_power)
. = ..()
diff --git a/code/modules/power/fusion/gyrotron/gyrotron.dm b/code/modules/power/fusion/gyrotron/gyrotron.dm
index db11e44f9b12..afb22c62b68d 100644
--- a/code/modules/power/fusion/gyrotron/gyrotron.dm
+++ b/code/modules/power/fusion/gyrotron/gyrotron.dm
@@ -3,7 +3,7 @@
/obj/machinery/emitter/gyrotron
name = "gyrotron"
icon = 'icons/obj/machines/power/fusion.dmi'
- desc = "It is a heavy duty industrial gyrotron suited for powering fusion reactors."
+ desc = "It is a heavy-duty industrial gyrotron suited for powering fusion reactors."
icon_state = "emitter-off"
initial_access = list(access_engine)
use_power = POWER_USE_IDLE
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index 4fbd6dea4679..fa8764e8dc6d 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -11,7 +11,7 @@
/obj/machinery/gravity_generator/
name = "Gravitational Generator"
- desc = "A device which produces a gravaton field when set up."
+ desc = "A device which produces a graviton field when set up."
icon = 'icons/obj/singularity.dmi'
icon_state = "TheSingGen"
anchored = TRUE
@@ -85,13 +85,12 @@
onclose(user, "gravgen")
-/obj/machinery/computer/gravity_control_computer/Topic(href, href_list)
- set background = 1
+/obj/machinery/computer/gravity_control_computer/OnTopic(user, href_list)
if((. = ..()))
- close_browser(usr, "window=air_alarm")
return
if(href_list["gentoggle"])
+ . = TOPIC_REFRESH
if(gravity_generator.on)
gravity_generator.on = 0
@@ -102,9 +101,9 @@
break
if(!G)
A.gravitychange(0)
+ CHECK_TICK
else
for(var/area/A in gravity_generator.localareas)
gravity_generator.on = 1
A.gravitychange(1)
-
- src.updateUsrDialog()
+ CHECK_TICK
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 624425a51215..76c85e46b822 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -43,6 +43,8 @@
var/flickering = 0
var/light_type = /obj/item/light/tube // the type of light item
var/accepts_light_type = /obj/item/light/tube
+ /// A debounce var to prevent lights from causing infinite loops due to machinery power updates.
+ var/currently_updating = FALSE
var/obj/item/light/lightbulb
@@ -54,7 +56,8 @@
/obj/machinery/light/set_color(color)
. = lightbulb?.set_color(color)
if(.)
- queue_icon_update()
+ update_light_status(TRUE)
+ update_icon()
// the smaller bulb light fixture
/obj/machinery/light/small
@@ -100,15 +103,43 @@
broken(1)
on = expected_to_be_on()
- queue_icon_update(0)
+ update_light_status(FALSE)
+ update_icon()
/obj/machinery/light/Destroy()
QDEL_NULL(lightbulb)
. = ..()
-/obj/machinery/light/on_update_icon(var/trigger = 1)
- atom_flags = atom_flags & ~ATOM_FLAG_CAN_BE_PAINTED
+/// Handles light updates that were formerly done in update_icon.
+/// * trigger (BOOL): if TRUE, this can trigger effects like burning out, rigged light explosions, etc.
+/obj/machinery/light/proc/update_light_status(trigger = TRUE)
+ if(currently_updating) // avoid infinite loops during power usage updates
+ return
+ currently_updating = TRUE
+ if(get_status() == LIGHT_OK) // we can't reuse this value later because update_use_power might change our status
+ atom_flags |= ATOM_FLAG_CAN_BE_PAINTED
+ else
+ atom_flags &= ~ATOM_FLAG_CAN_BE_PAINTED
+ on = FALSE
+ if(on)
+ update_use_power(POWER_USE_ACTIVE)
+ if(current_mode && (current_mode in lightbulb.lighting_modes))
+ set_light(arglist(lightbulb.lighting_modes[current_mode]))
+ else
+ set_light(lightbulb.b_range, lightbulb.b_power, lightbulb.b_color)
+ if(trigger && get_status() == LIGHT_OK)
+ switch_check()
+ else
+ update_use_power(POWER_USE_OFF)
+ set_light(0)
+ change_power_consumption((light_range * light_power) * LIGHTING_POWER_FACTOR, POWER_USE_ACTIVE)
+ currently_updating = FALSE
+
+/obj/machinery/light/update_use_power(new_use_power)
+ . = ..()
+ update_light_status(TRUE)
+/obj/machinery/light/on_update_icon()
// Update icon state
cut_overlays()
if(istype(construct_state))
@@ -127,15 +158,10 @@
switch(get_status()) // set icon_states
if(LIGHT_OK)
_state = "[base_state][on]"
- atom_flags |= ATOM_FLAG_CAN_BE_PAINTED
- if(LIGHT_EMPTY)
- on = 0
if(LIGHT_BURNED)
_state = "[base_state]_burned"
- on = 0
if(LIGHT_BROKEN)
_state = "[base_state]_broken"
- on = 0
if(istype(lightbulb, /obj/item/light))
var/image/I = image(icon, _state)
@@ -145,21 +171,6 @@
if(on)
compile_overlays() // force a compile so that we update prior to the light being set
- update_use_power(POWER_USE_ACTIVE)
-
- var/changed = 0
- if(current_mode && (current_mode in lightbulb.lighting_modes))
- changed = set_light(arglist(lightbulb.lighting_modes[current_mode]))
- else
- changed = set_light(lightbulb.b_range, lightbulb.b_power, lightbulb.b_color)
-
- if(trigger && changed && get_status() == LIGHT_OK)
- switch_check()
- else
- update_use_power(POWER_USE_OFF)
- set_light(0)
- change_power_consumption((light_range * light_power) * LIGHTING_POWER_FACTOR, POWER_USE_ACTIVE)
-
/obj/machinery/light/proc/get_status()
if(!lightbulb)
return LIGHT_EMPTY
@@ -174,7 +185,8 @@
/obj/machinery/light/proc/set_mode(var/new_mode)
if(current_mode != new_mode)
current_mode = new_mode
- update_icon(0)
+ update_light_status(FALSE)
+ update_icon()
/obj/machinery/light/proc/get_mode_color()
if (current_mode && (current_mode in lightbulb.lighting_modes))
@@ -199,7 +211,8 @@
// will not switch on if broken/burned/empty
/obj/machinery/light/proc/seton(var/state)
on = (state && get_status() == LIGHT_OK)
- queue_icon_update()
+ update_light_status(TRUE)
+ update_icon()
// examine verb
/obj/machinery/light/examine(mob/user)
@@ -226,6 +239,7 @@
lightbulb = L
on = expected_to_be_on()
+ update_light_status(TRUE)
update_icon()
/obj/machinery/light/proc/remove_bulb()
@@ -233,6 +247,7 @@
lightbulb.dropInto(loc)
lightbulb.update_icon()
lightbulb = null
+ update_light_status(TRUE)
update_icon()
/obj/machinery/light/cannot_transition_to(state_path, mob/user)
@@ -298,10 +313,11 @@
for(var/i = 0; i < amount; i++)
if(get_status() != LIGHT_OK) break
on = !on
- update_icon(0)
+ update_light_status(FALSE)
sleep(rand(5, 15))
on = (get_status() == LIGHT_OK)
- update_icon(0)
+ update_light_status(FALSE)
+ update_icon()
flickering = 0
// ai attack - make lights flicker, because why not
@@ -367,13 +383,15 @@
if(on)
spark_at(src, cardinal_only = TRUE)
lightbulb.status = LIGHT_BROKEN
+ update_light_status(TRUE)
update_icon()
/obj/machinery/light/proc/fix()
if(get_status() == LIGHT_OK || !lightbulb)
return
lightbulb.status = LIGHT_OK
- on = 1
+ on = TRUE
+ update_light_status(TRUE)
update_icon()
// explosion effect
diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm
index 4f5e0eb41cc8..d869748a7b40 100644
--- a/code/modules/power/port_gen.dm
+++ b/code/modules/power/port_gen.dm
@@ -377,33 +377,35 @@
ui.open()
ui.set_auto_update(1)
-/obj/machinery/port_gen/pacman/Topic(href, href_list)
- if(..())
+/obj/machinery/port_gen/pacman/OnTopic(mob/user, href_list)
+ if((. = ..()))
return
- src.add_fingerprint(usr)
if(href_list["action"])
if(href_list["action"] == "enable")
if(!active && HasFuel() && !IsBroken())
- active = 1
- update_icon()
+ active = TRUE
+ . = TOPIC_REFRESH
if(href_list["action"] == "disable")
if (active)
- active = 0
- update_icon()
+ active = FALSE
+ . = TOPIC_REFRESH
if(href_list["action"] == "eject")
if(!active)
DropFuel()
+ . = TOPIC_REFRESH
if(href_list["action"] == "lower_power")
if (power_output > 1)
power_output--
+ . = TOPIC_REFRESH
if (href_list["action"] == "higher_power")
if (power_output < max_power_output || (emagged && power_output < round(max_power_output*2.5)))
power_output++
+ . = TOPIC_REFRESH
/obj/machinery/port_gen/pacman/super
name = "portable fission generator"
- desc = "A power generator that utilizes uranium sheets as fuel. Can run for much longer than the standard portabke generators. Rated for 80 kW max safe output."
+ desc = "A power generator that utilizes uranium sheets as fuel. Can run for much longer than the standard portable generators. Rated for 80 kW max safe output."
icon_state = "portgen1"
sheet_path = /obj/item/stack/material/puck
sheet_material = /decl/material/solid/metal/uranium
diff --git a/code/modules/power/sensors/powernet_sensor.dm b/code/modules/power/sensors/powernet_sensor.dm
index 8a02779ed2a5..6a0134664cd3 100644
--- a/code/modules/power/sensors/powernet_sensor.dm
+++ b/code/modules/power/sensors/powernet_sensor.dm
@@ -9,7 +9,7 @@
/obj/machinery/power/sensor
name = "powernet sensor"
- desc = "Small machine which transmits data about specific powernet."
+ desc = "A sensor that records and transmits data about its connected power network."
anchored = TRUE
density = FALSE
level = LEVEL_BELOW_PLATING
diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm
index 4f3f45ee9313..c267422e0893 100644
--- a/code/modules/power/singularity/particle_accelerator/particle_control.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm
@@ -74,35 +74,35 @@
return
/obj/machinery/particle_accelerator/control_box/Topic(href, href_list)
- ..()
- //Ignore input if we are broken, !silicon guy cant touch us, or nonai controlling from super far away
- if(stat & (BROKEN|NOPOWER) || (get_dist(src, usr) > 1 && !issilicon(usr)) || (get_dist(src, usr) > 8 && !isAI(usr)))
- usr.unset_machine()
+ . = ..()
+ if(. == TOPIC_CLOSE)
close_browser(usr, "window=pacontrol")
- return
- if( href_list["close"] )
- close_browser(usr, "window=pacontrol")
- usr.unset_machine()
+/obj/machinery/particle_accelerator/control_box/OnTopic(href, href_list)
+ if((. = ..()))
return
-
+ if(inoperable())
+ return TOPIC_CLOSE
+ if(href_list["close"])
+ return TOPIC_CLOSE
if(href_list["togglep"])
- if(!wires.IsIndexCut(PARTICLE_TOGGLE_WIRE))
- src.toggle_power()
+ if(wires.IsIndexCut(PARTICLE_TOGGLE_WIRE))
+ return TOPIC_HANDLED
+ toggle_power()
+ return TOPIC_REFRESH
else if(href_list["scan"])
- src.part_scan()
-
+ part_scan()
+ return TOPIC_REFRESH
else if(href_list["strengthup"])
- if(!wires.IsIndexCut(PARTICLE_STRENGTH_WIRE))
- add_strength()
-
+ if(wires.IsIndexCut(PARTICLE_STRENGTH_WIRE))
+ return TOPIC_HANDLED
+ add_strength()
+ return TOPIC_REFRESH
else if(href_list["strengthdown"])
- if(!wires.IsIndexCut(PARTICLE_STRENGTH_WIRE))
- remove_strength()
-
- src.updateDialog()
- src.update_icon()
- return
+ if(wires.IsIndexCut(PARTICLE_STRENGTH_WIRE))
+ return TOPIC_HANDLED
+ remove_strength()
+ return TOPIC_REFRESH
/obj/machinery/particle_accelerator/control_box/proc/strength_change()
for(var/obj/structure/particle_accelerator/part in connected_parts)
diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm
index c1c8ea8295ec..97a0d08fa836 100644
--- a/code/modules/power/singularity/singularity.dm
+++ b/code/modules/power/singularity/singularity.dm
@@ -55,8 +55,8 @@ var/global/list/singularities = list()
STOP_PROCESSING(SSobj, src)
. = ..()
-/obj/effect/singularity/Process_Spacemove(allow_movement)
- return TRUE
+/obj/effect/singularity/is_space_movement_permitted(allow_movement = FALSE)
+ return SPACE_MOVE_PERMITTED
/obj/effect/singularity/proc/consume(atom/A)
energy += A.singularity_act(src, current_stage.stage_size)
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index 50c22d1479ea..2201e1fc430b 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -263,22 +263,19 @@
return 0
return round(100.0*charge/capacity, 0.1)
-/obj/machinery/power/smes/Topic(href, href_list)
- if(..())
- return 1
+/obj/machinery/power/smes/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
if( href_list["cmode"] )
inputting(!input_attempt)
- update_icon()
- return 1
+ . = TOPIC_REFRESH
else if( href_list["online"] )
outputting(!output_attempt)
- update_icon()
- return 1
+ . = TOPIC_REFRESH
else if( href_list["reboot"] )
failure_timer = 0
- update_icon()
- return 1
+ . = TOPIC_REFRESH
else if( href_list["input"] )
switch( href_list["input"] )
if("min")
@@ -288,7 +285,7 @@
if("set")
input_level = (input(usr, "Enter new input level (0-[input_level_max/1000] kW)", "SMES Input Power Control", input_level/1000) as num) * 1000
input_level = max(0, min(input_level_max, input_level)) // clamp to range
- return 1
+ . = TOPIC_REFRESH
else if( href_list["output"] )
switch( href_list["output"] )
if("min")
@@ -298,7 +295,7 @@
if("set")
output_level = (input(usr, "Enter new output level (0-[output_level_max/1000] kW)", "SMES Output Power Control", output_level/1000) as num) * 1000
output_level = max(0, min(output_level_max, output_level)) // clamp to range
- return 1
+ . = TOPIC_REFRESH
/obj/machinery/power/smes/proc/energy_fail(var/duration)
diff --git a/code/modules/power/smes_construction.dm b/code/modules/power/smes_construction.dm
index 59665f270cb1..cccc10631e3f 100644
--- a/code/modules/power/smes_construction.dm
+++ b/code/modules/power/smes_construction.dm
@@ -37,7 +37,7 @@
// 500% Charge Capacity, 40% I/O Capacity. Holds a lot of energy, but charges slowly if not combined with other coils. Ideal for backup storage.
/obj/item/stock_parts/smes_coil/super_capacity
name = "superconductive capacitance coil"
- desc = "Specialised version of standard superconductive magnetic coil. This one has significantly stronger containment field, allowing for significantly larger power storage. It's IO rating is much lower, however."
+ desc = "Specialised version of standard superconductive magnetic coil. This one has significantly stronger containment field, allowing for significantly larger power storage. Its IO rating is much lower, however."
icon_state = "smes_coil_capacitance"
ChargeCapacity = 250 KILOWATTS
IOCapacity = 100 KILOWATTS
@@ -76,7 +76,7 @@
maximum_component_parts = list(/obj/item/stock_parts/smes_coil = 6, /obj/item/stock_parts = 15)
interact_offline = TRUE
var/safeties_enabled = 1 // If 0 modifications can be done without discharging the SMES, at risk of critical failure.
- var/failing = 0 // If 1 critical failure has occured and SMES explosion is imminent.
+ var/failing = 0 // If 1 critical failure has occurred and SMES explosion is imminent.
var/grounding = 1 // Cut to quickly discharge, at cost of "minor" electrical issues in output powernet.
var/RCon = 1 // Cut to disable AI and remote control.
var/RCon_tag = "NO_TAG" // RCON tag, change to show it on SMES Remote control console.
diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm
index a941debb006a..23e5f846473c 100644
--- a/code/modules/power/solar.dm
+++ b/code/modules/power/solar.dm
@@ -107,7 +107,7 @@ var/global/list/solars_list = list()
set_dir(angle2dir(adir))
return
-//calculates the fraction of the sunlight that the panel recieves
+//calculates the fraction of the sunlight that the panel receives
/obj/machinery/power/solar/proc/update_solar_exposure()
var/datum/sun/sun = get_best_sun()
@@ -125,7 +125,7 @@ var/global/list/solars_list = list()
return
sunfrac = cos(p_angle) ** 2
- //isn't the power recieved from the incoming light proportionnal to cos(p_angle) (Lambert's cosine law) rather than cos(p_angle)^2 ?
+ //isn't the power received from the incoming light proportionnal to cos(p_angle) (Lambert's cosine law) rather than cos(p_angle)^2 ?
/obj/machinery/power/solar/Process()
if(stat & BROKEN)
@@ -427,14 +427,15 @@ var/global/list/solars_list = list()
updateDialog()
/obj/machinery/power/solar_control/Topic(href, href_list)
- if(..())
- close_browser(usr, "window=solcon")
- usr.unset_machine()
- return 0
- if(href_list["close"] )
+ . = ..()
+ if(. == TOPIC_CLOSE)
close_browser(usr, "window=solcon")
- usr.unset_machine()
- return 0
+
+/obj/machinery/power/solar_control/OnTopic(mob/user, href_list)
+ if((. = ..()))
+ return
+ if(href_list["close"])
+ return TOPIC_CLOSE
if(href_list["rate control"])
if(href_list["cdir"])
@@ -442,11 +443,11 @@ var/global/list/solars_list = list()
targetdir = cdir
if(track == 2) //manual update, so losing auto-tracking
track = 0
- spawn(1)
- set_panels(cdir)
+ addtimer(CALLBACK(src, PROC_REF(set_panels), cdir), 1)
if(href_list["tdir"])
trackrate = clamp(trackrate+text2num(href_list["tdir"]), -7200, 7200)
if(trackrate) nexttime = world.time + 36000/abs(trackrate)
+ return TOPIC_REFRESH
if(href_list["track"])
track = text2num(href_list["track"])
@@ -459,6 +460,7 @@ var/global/list/solars_list = list()
targetdir = cdir
if(trackrate) nexttime = world.time + 36000/abs(trackrate)
set_panels(targetdir)
+ return TOPIC_REFRESH
if(href_list["search_connected"])
search_for_connected()
@@ -466,9 +468,7 @@ var/global/list/solars_list = list()
if(connected_tracker && track == 2 && sun)
connected_tracker.set_angle(sun.angle)
set_panels(cdir)
-
- interact(usr)
- return 1
+ return TOPIC_REFRESH
//rotates the panel to the passed angle
/obj/machinery/power/solar_control/proc/set_panels(var/cdir)
diff --git a/code/modules/projectiles/ammunition/bullets.dm b/code/modules/projectiles/ammunition/bullets.dm
index 7966b8e04f9b..26090dff1d98 100644
--- a/code/modules/projectiles/ammunition/bullets.dm
+++ b/code/modules/projectiles/ammunition/bullets.dm
@@ -99,7 +99,7 @@
/obj/item/ammo_casing/shotgun/pellet
name = "shotgun shell"
- desc = "A shotshell."
+ desc = "A shotgun shell."
icon_state = "gshell"
spent_icon = "gshell-spent"
projectile_type = /obj/item/projectile/bullet/pellet/shotgun
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index d99abdef1e63..bb477976f9d3 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -418,12 +418,11 @@
for(var/obj/item/rig_module/stealth_field/S in rig.installed_modules)
S.deactivate()
- if(space_recoil)
- if(!user.check_space_footing())
- var/old_dir = user.dir
- user.inertia_ignore = projectile
- step(user,get_dir(target,user))
- user.set_dir(old_dir)
+ if(space_recoil && user.can_slip(magboots_only = TRUE))
+ var/old_dir = user.dir
+ user.inertia_ignore = projectile
+ step(user,get_dir(target,user))
+ user.set_dir(old_dir)
update_icon()
diff --git a/code/modules/projectiles/guns/energy/capacitor.dm b/code/modules/projectiles/guns/energy/capacitor.dm
index 1232ef3e8f39..f0ac3df942ae 100644
--- a/code/modules/projectiles/guns/energy/capacitor.dm
+++ b/code/modules/projectiles/guns/energy/capacitor.dm
@@ -147,9 +147,6 @@ var/global/list/laser_wavelengths
update_icon()
return TRUE
-/obj/item/gun/energy/capacitor/Process()
- . = ..()
-
/obj/item/gun/energy/capacitor/proc/charge(var/mob/user)
. = FALSE
if(!charging && istype(user))
@@ -259,7 +256,7 @@ var/global/list/laser_wavelengths
// Subtypes.
/obj/item/gun/energy/capacitor/rifle
name = "capacitor rifle"
- desc = "A heavy, unwieldly directed energy weapon that uses a linear capacitor array to charge a powerful beam."
+ desc = "A heavy, unwieldy directed energy weapon that uses a linear capacitor array to charge a powerful beam."
max_capacitors = 4
icon = 'icons/obj/guns/capacitor_rifle.dmi'
slot_flags = SLOT_BACK
diff --git a/code/modules/projectiles/guns/energy/secure.dm b/code/modules/projectiles/guns/energy/secure.dm
index 64d4cf57727a..c8df1f2ea053 100644
--- a/code/modules/projectiles/guns/energy/secure.dm
+++ b/code/modules/projectiles/guns/energy/secure.dm
@@ -34,7 +34,7 @@
/obj/item/gun/energy/laser/secure
name = "laser carbine"
- desc = "A G40E carbine, designed to kill with concentrated energy blasts. Fitted with an NT1019 chip to make sure killcount is tracked appropriately."
+ desc = "A G40E carbine, designed to kill with concentrated energy blasts. Fitted with an NT1019 chip to make sure kill count is tracked appropriately."
req_access = list(list(access_brig, access_bridge))
/obj/item/gun/energy/laser/secure/on_update_icon()
diff --git a/code/modules/projectiles/guns/energy/temperature.dm b/code/modules/projectiles/guns/energy/temperature.dm
index 933c6d2fff63..414aa4a3ccdb 100644
--- a/code/modules/projectiles/guns/energy/temperature.dm
+++ b/code/modules/projectiles/guns/energy/temperature.dm
@@ -48,8 +48,8 @@
show_browser(user, dat, "window=freezegun;size=450x300;can_resize=1;can_close=1;can_minimize=1")
onclose(user, "window=freezegun", src)
-/obj/item/gun/energy/temperature/Topic(user, href_list, state = global.inventory_topic_state)
- ..()
+/obj/item/gun/energy/temperature/DefaultTopicState()
+ return global.inventory_topic_state
/obj/item/gun/energy/temperature/OnTopic(user, href_list)
if(href_list["temp"])
diff --git a/code/modules/projectiles/guns/launcher/foam_gun.dm b/code/modules/projectiles/guns/launcher/foam_gun.dm
index 33eaae8345c6..8bdb703a1a1d 100644
--- a/code/modules/projectiles/guns/launcher/foam_gun.dm
+++ b/code/modules/projectiles/guns/launcher/foam_gun.dm
@@ -80,10 +80,24 @@
if(distance <= 1)
to_chat(user, "The hammer is a lot more resistant than you'd expect.")
+/obj/item/gun/launcher/foam/machine_gun
+ name = "foam machine gun"
+ desc = "The Jorf machine gun, hose the competition down and hate yourself while you spend forever reloading! It holds 30 darts."
+ icon = 'icons/obj/guns/foam/machine_gun.dmi'
+ w_class = ITEM_SIZE_NORMAL
+ fire_delay = 0
+ autofire_enabled = 1
+ one_hand_penalty = 3
+ max_darts = 30
+ burst_delay = 1
+ burst = 3
+ burst_accuracy = list(0,-1,-1)
+ dispersion = list(0.0, 0.6, 1.0)
+
//the projectile
/obj/item/foam_dart
name = "foam dart"
- desc = "An offical Jorf brand foam dart, for use only with offical Jorf brand foam dart launching products."
+ desc = "An official Jorf brand foam dart, for use only with official Jorf brand foam dart launching products."
icon = 'icons/obj/guns/foam/dart.dmi'
icon_state = "dart"
w_class = ITEM_SIZE_TINY
@@ -114,7 +128,7 @@
//boxes of the projectile
/obj/item/box/foam_darts
name = "box of foam darts"
- desc = "It's a box of offical Jorf brand foam darts, for use only with offical Jorf brand products."
+ desc = "It's a box of official Jorf brand foam darts, for use only with official Jorf brand products."
icon = 'icons/obj/guns/foam/boxes.dmi'
icon_state = "dart_box"
diff --git a/code/modules/projectiles/guns/launcher/syringe_gun.dm b/code/modules/projectiles/guns/launcher/syringe_gun.dm
index 69fa0078472d..2750cecee523 100644
--- a/code/modules/projectiles/guns/launcher/syringe_gun.dm
+++ b/code/modules/projectiles/guns/launcher/syringe_gun.dm
@@ -71,7 +71,7 @@
/obj/item/gun/launcher/syringe
name = "syringe gun"
- desc = "A spring loaded rifle designed to fit syringes, designed to incapacitate unruly patients from a distance."
+ desc = "A spring-loaded rifle designed to fit syringes, designed to incapacitate unruly patients from a distance."
icon = 'icons/obj/guns/launcher/syringe.dmi'
icon_state = ICON_STATE_WORLD
w_class = ITEM_SIZE_LARGE
@@ -152,7 +152,7 @@
/obj/item/gun/launcher/syringe/disguised
name = "deluxe electronic cigarette"
- desc = "A premium model eGavana MK3 electronic cigarette, shaped like a cigar."
+ desc = "A premium model eHavana MK3 electronic cigarette, shaped like a cigar."
icon = 'icons/clothing/mask/smokables/cigarette_electronic_deluxe.dmi'
icon_state = ICON_STATE_WORLD
w_class = ITEM_SIZE_SMALL
diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm
index 0021fc7522b5..217d232ba35b 100644
--- a/code/modules/projectiles/guns/projectile/shotgun.dm
+++ b/code/modules/projectiles/guns/projectile/shotgun.dm
@@ -1,6 +1,6 @@
/obj/item/gun/projectile/shotgun/pump
name = "shotgun"
- desc = "The mass-produced W-T Remmington 29x shotgun is a favourite of police and security forces on many worlds. Useful for sweeping alleys."
+ desc = "The mass-produced W-T Remington 29x shotgun is a favourite of police and security forces on many worlds. Useful for sweeping alleys."
icon = 'icons/obj/guns/shotgun/pump.dmi'
icon_state = ICON_STATE_WORLD
max_shells = 4
@@ -114,4 +114,20 @@
bulk = 2
/obj/item/gun/projectile/shotgun/doublebarrel/sawn/empty
- starts_loaded = FALSE
\ No newline at end of file
+ starts_loaded = FALSE
+
+/obj/item/gun/projectile/shotgun/doublebarrel/quad
+ name = "quad-barreled shotgun"
+ desc = "A true classic - but doubled. Firing it has a heck of a kick - knocks the air right out of you."
+ icon = 'icons/obj/guns/shotgun/quadbarrel.dmi'
+ max_shells = 4
+ w_class = ITEM_SIZE_HUGE
+ origin_tech = @'{"combat":6,"materials":3,"esoteric":9}'
+ firemodes = list(
+ list(mode_name="fire one barrel at a time", burst=1),
+ list(mode_name="fire two barrels at once", burst=2),
+ list(mode_name="fire all barrels at once", burst=4)
+ )
+
+/obj/item/gun/projectile/shotgun/doublebarrel/quad/empty
+ starts_loaded = FALSE
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 152cb7a6ab55..365338cf6cac 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -141,7 +141,7 @@
if(!AM.anchored && !AM.has_gravity())
if(ismob(AM))
var/mob/M = AM
- if(M.check_space_footing())
+ if(!M.can_slip(magboots_only = TRUE))
return
var/old_dir = AM.dir
step(AM,get_dir(firer,AM))
@@ -376,12 +376,12 @@
/obj/item/projectile/get_autopsy_descriptors()
return list(name)
-/obj/item/projectile/Process_Spacemove()
+/obj/item/projectile/is_space_movement_permitted(allow_movement = FALSE)
//Deletes projectiles that aren't supposed to be in vacuum if they leave pressurised areas
if (is_below_sound_pressure(get_turf(src)) && !vacuum_traversal)
qdel(src)
return
- return TRUE //Bullets don't drift in space
+ return SPACE_MOVE_PERMITTED //Bullets don't drift in space
/obj/item/projectile/proc/fire(angle, atom/direct_target)
//If no Angle needs to resolve it from xo/yo!
diff --git a/code/game/objects/effects/projectile/projectile_effects.dm b/code/modules/projectiles/projectile/effects/projectile_effects.dm
similarity index 100%
rename from code/game/objects/effects/projectile/projectile_effects.dm
rename to code/modules/projectiles/projectile/effects/projectile_effects.dm
diff --git a/code/game/objects/effects/projectile/projectile_impact.dm b/code/modules/projectiles/projectile/effects/projectile_impact.dm
similarity index 100%
rename from code/game/objects/effects/projectile/projectile_impact.dm
rename to code/modules/projectiles/projectile/effects/projectile_impact.dm
diff --git a/code/game/objects/effects/projectile/projectile_muzzle.dm b/code/modules/projectiles/projectile/effects/projectile_muzzle.dm
similarity index 100%
rename from code/game/objects/effects/projectile/projectile_muzzle.dm
rename to code/modules/projectiles/projectile/effects/projectile_muzzle.dm
diff --git a/code/game/objects/effects/projectile/projectile_tracer.dm b/code/modules/projectiles/projectile/effects/projectile_tracer.dm
similarity index 100%
rename from code/game/objects/effects/projectile/projectile_tracer.dm
rename to code/modules/projectiles/projectile/effects/projectile_tracer.dm
diff --git a/code/modules/projectiles/targeting/targeting_client.dm b/code/modules/projectiles/targeting/targeting_client.dm
deleted file mode 100644
index 082471448a5c..000000000000
--- a/code/modules/projectiles/targeting/targeting_client.dm
+++ /dev/null
@@ -1,11 +0,0 @@
-//These are called by the on-screen buttons, adjusting what the victim can and cannot do.
-/client/proc/add_gun_icons()
- if(!mob.item_use_icon) return 1 // This can runtime if someone manages to throw a gun out of their hand before the proc is called.
- screen |= mob.item_use_icon
- screen |= mob.gun_move_icon
- screen |= mob.radio_use_icon
-
-/client/proc/remove_gun_icons()
- screen -= mob.item_use_icon
- screen -= mob.gun_move_icon
- screen -= mob.radio_use_icon
diff --git a/code/modules/projectiles/targeting/targeting_overlay.dm b/code/modules/projectiles/targeting/targeting_overlay.dm
index 7210efedb4c4..c0bb7ce8a7bf 100644
--- a/code/modules/projectiles/targeting/targeting_overlay.dm
+++ b/code/modules/projectiles/targeting/targeting_overlay.dm
@@ -32,26 +32,8 @@
target_permissions |= perm
// Update HUD icons.
- if(owner.gun_move_icon)
- if(!(target_permissions & TARGET_CAN_MOVE))
- owner.gun_move_icon.SetName("Allow Movement")
- else
- owner.gun_move_icon.SetName("Disallow Movement")
- owner.gun_move_icon.update_icon()
-
- if(owner.item_use_icon)
- if(!(target_permissions & TARGET_CAN_CLICK))
- owner.item_use_icon.SetName("Allow Item Use")
- else
- owner.item_use_icon.SetName("Disallow Item Use")
- owner.item_use_icon.update_icon()
-
- if(owner.radio_use_icon)
- if(!(target_permissions & TARGET_CAN_RADIO))
- owner.radio_use_icon.SetName("Allow Radio Use")
- else
- owner.radio_use_icon.SetName("Disallow Radio Use")
- owner.radio_use_icon.update_icon()
+ if(istype(owner?.hud_used, /datum/hud))
+ owner.hud_used.update_gun_mode_icons(target_permissions)
var/message = "no longer permitted to "
var/use_span = "warning"
@@ -154,8 +136,9 @@
else
owner.visible_message(SPAN_DANGER("\The [owner] aims \the [thing] at \the [target]!"))
- if(owner.client)
- owner.client.add_gun_icons()
+ if(istype(owner.hud_used) && owner.client)
+ owner.hud_used.add_gun_icons()
+
var/decl/pronouns/pronouns = owner.get_pronouns()
to_chat(target, FONT_LARGE(SPAN_DANGER("\The [owner] [pronouns.is] menacing you with \a [thing]. No sudden moves!")))
aiming_with = thing
@@ -194,16 +177,15 @@
if(!active)
cancel_aiming(no_message)
- if(owner.client)
+ if(owner.client && istype(owner.hud_used))
if(active)
if(!no_message)
to_chat(owner, "You will now aim rather than fire.")
- owner.client.add_gun_icons()
+ owner.hud_used.add_gun_icons()
else
if(!no_message)
to_chat(owner, "You will no longer aim rather than fire.")
- owner.client.remove_gun_icons()
- owner.gun_setting_icon.update_icon()
+ owner.hud_used.remove_gun_icons()
/obj/aiming_overlay/proc/cancel_aiming(var/no_message = 0)
if(!aiming_with || !aiming_at)
diff --git a/code/modules/reagents/Chemistry-Grinder.dm b/code/modules/reagents/Chemistry-Grinder.dm
index 987f641fa246..b798bf9e4e6d 100644
--- a/code/modules/reagents/Chemistry-Grinder.dm
+++ b/code/modules/reagents/Chemistry-Grinder.dm
@@ -242,9 +242,9 @@
else
user.take_blood(beaker, dam)
SET_STATUS_MAX(user, STAT_STUN, 2)
- shake(user, 40)
+ shake_target(user, 4 SECONDS)
-/obj/machinery/reagentgrinder/proc/shake(mob/living/user, duration)
+/obj/machinery/reagentgrinder/proc/shake_target(mob/living/user, duration)
if(!user)
return
for(var/i = 1 to duration)
diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm
index 9b76b5dec22e..9c2063ed6cb3 100644
--- a/code/modules/reagents/Chemistry-Holder.dm
+++ b/code/modules/reagents/Chemistry-Holder.dm
@@ -186,7 +186,7 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new
if((check_flags & ATOM_FLAG_NO_REACT) && (check_flags & ATOM_FLAG_NO_PHASE_CHANGE) && (check_flags & ATOM_FLAG_NO_DISSOLVE))
return 0
- var/reaction_occured = FALSE
+ var/reaction_occurred = FALSE
var/list/eligible_reactions = list()
var/temperature = location?.temperature || T20C
@@ -228,7 +228,7 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new
clear_reagent(R.type)
for(var/product in replace_self_with)
add_reagent(product, replace_self_with[product] * replace_amount)
- reaction_occured = TRUE
+ reaction_occurred = TRUE
if(location)
if(replace_message)
@@ -245,7 +245,7 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new
for(var/decl/chemical_reaction/reaction in eligible_reactions)
if(reaction.can_happen(src))
active_reactions[reaction] = 1 // The number is going to be 1/(fraction of remaining reagents we are allowed to use), computed below
- reaction_occured = 1
+ reaction_occurred = 1
var/list/used_reagents = list()
// if two reactions share a reagent, each is allocated half of it, so we compute this here
@@ -273,10 +273,10 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new
update_total()
- if(reaction_occured)
+ if(reaction_occurred)
HANDLE_REACTIONS(src) // Check again in case the new reagents can react again
- return reaction_occured
+ return reaction_occurred
/* Holder-to-chemical */
/datum/reagents/proc/handle_update(var/safety)
@@ -925,14 +925,60 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new
return trans_to_holder(target.reagents, amount, multiplier, copy, defer_update = defer_update, transferred_phases = transferred_phases)
-/* Atom reagent creation - use it all the time */
-
/datum/reagents/proc/get_skimmable_reagents()
for(var/mat in reagent_volumes)
var/decl/material/reagent = GET_DECL(mat)
if(reagent.skimmable)
LAZYADD(., mat)
+/// Used to return strings like "dilute blood" for use in phrases like "It's covered in dilute oily slimy bloody mud!"
+/// This is explicitly inspired by Caves of Qud, by the way.
+/datum/reagents/proc/get_coated_name()
+ /// arbitrary number, number of words that will be included in the name. will always have primary in addition
+ var/const/MAX_COATING_NAMES = 4
+ if(!total_volume)
+ return null
+ // sort reagents from low to high, so largest reagent comes last (feels most impactful? idk, it's arbitrary)
+ var/list/volumes_temp = sortTim(reagent_volumes.Copy(), /proc/cmp_numeric_asc, associative = TRUE)
+ var/list/accumulator = list()
+ var/decl/material/primary_reagent_decl = get_primary_reagent_decl() // this also sets src.primary_reagent to the typepath
+ for(var/reagent_type in volumes_temp)
+ if(reagent_type == primary_reagent)
+ continue // added later
+ var/decl/material/reagent = GET_DECL(reagent_type)
+ reagent.build_coated_name(src, accumulator)
+ if(length(accumulator) >= MAX_COATING_NAMES)
+ break
+ var/primary_name = primary_reagent_decl.get_primary_coating_name(src)
+ if(get_config_value(/decl/config/enum/colored_coating_names) == CONFIG_COATING_COLOR_COMPONENTS)
+ var/primary_color = primary_reagent_decl.get_reagent_color(src)
+ primary_name = FONT_COLORED(primary_color, primary_name)
+ accumulator += primary_name // add primary to the end
+ . = jointext(accumulator, " ") // dilute oily slimy bloody mud
+ if(get_config_value(/decl/config/enum/colored_coating_names) == CONFIG_COATING_COLOR_MIXTURE)
+ . = FONT_COLORED(get_color(), .)
+
+/// Used to return strings like "inky bloody muddy snowy oily wet" for use in phrases like "You are wearing some inky bloody muddy snowy oily wet leather boots."
+/// This is explicitly inspired by Caves of Qud, by the way.
+/datum/reagents/proc/get_coated_adjectives()
+ var/const/MAX_COATING_ADJECTIVES = 5 // arbitrary number, limit how many reagents will show up in the name on examine
+ if(!total_volume)
+ return null
+ // sort reagents from low to high, so primary reagent comes last (feels most impactful? idk, it's arbitrary)
+ // todo: maybe at some point we could make staining have some kind of priority to sort by?
+ var/list/volumes_temp = sortTim(reagent_volumes.Copy(), /proc/cmp_numeric_asc, associative = TRUE)
+ var/list/accumulator = list()
+ for(var/reagent_type in volumes_temp)
+ var/decl/material/reagent = GET_DECL(reagent_type)
+ var/coated_name = reagent.get_coated_adjective(src)
+ accumulator |= coated_name
+ if(length(accumulator) >= MAX_COATING_ADJECTIVES)
+ break
+ . = jointext(accumulator, " ") // bloody muddy inky slimy wet
+ if(get_config_value(/decl/config/enum/colored_coating_names) == CONFIG_COATING_COLOR_MIXTURE)
+ . = FONT_COLORED(get_color(), .)
+
+/* Atom reagent creation - use it all the time */
/atom/proc/create_reagents(var/max_vol)
if(reagents)
log_debug("Attempted to create a new reagents holder when already referencing one: [log_info_line(src)]")
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index e304fbec91e0..d7c1f8cc4081 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -71,28 +71,56 @@
return ..()
-/obj/machinery/chem_master/Topic(href, href_list, state)
- if(..())
- return 1
- var/mob/user = usr
+/obj/machinery/chem_master/Topic(href, href_list)
+ . = ..()
+ if(. == TOPIC_CLOSE)
+ close_browser(usr, "window=chem_master")
+/obj/machinery/chem_master/OnTopic(mob/user, href_list, state)
+ if((. = ..()))
+ return
if (href_list["ejectp"])
if(loaded_pill_bottle)
loaded_pill_bottle.dropInto(loc)
loaded_pill_bottle = null
else if(href_list["close"])
- show_browser(user, null, "window=chem_master")
- user.unset_machine()
- return
+ return TOPIC_CLOSE
if(beaker)
+ // The custom ones modify our href_list.
+ if (href_list["addcustom"])
+ var/decl/material/their_reagent = locate(href_list["addcustom"])
+ if(their_reagent)
+ useramount = input("Select the amount to transfer.", 30, useramount) as null|num
+ if(useramount)
+ useramount = clamp(useramount, 0, 200)
+ href_list["amount"] = num2text(useramount)
+ href_list["add"] = href_list["addcustom"]
+ href_list -= "addcustom"
+ else
+ return TOPIC_HANDLED
+ else
+ return TOPIC_REFRESH // Tried to move a nonexistent reagent, maybe their UI is stale?
+ else if(href_list["removecustom"])
+ var/decl/material/my_reagents = locate(href_list["removecustom"])
+ if(my_reagents)
+ useramount = input("Select the amount to transfer.", 30, useramount) as null|num
+ if(useramount)
+ useramount = clamp(useramount, 0, 200)
+ href_list["amount"] = num2text(useramount)
+ href_list["remove"] = href_list["removecustom"]
+ href_list -= "removecustom"
+ else
+ return TOPIC_HANDLED
+
+ // DO NOT use else if here, we want these to run even if the custom ones do
var/datum/reagents/R = beaker.reagents
if (href_list["analyze"])
var/decl/material/reagent = locate(href_list["analyze"])
var/dat = get_chem_info(reagent)
if(dat && REAGENT_VOLUME(beaker.reagents, reagent.type))
show_browser(user, dat, "window=chem_master;size=575x400")
- return
+ return TOPIC_HANDLED
else if (href_list["add"])
if(href_list["amount"])
@@ -107,16 +135,7 @@
else
mult -= 0.4 * (SKILL_MAX - user.get_skill_value(core_skill))/(SKILL_MAX-SKILL_MIN) //10% loss per skill level down from max
R.trans_type_to(src, their_reagent.type, amount, mult)
-
-
-
- else if (href_list["addcustom"])
- var/decl/material/their_reagent = locate(href_list["addcustom"])
- if(their_reagent)
- useramount = input("Select the amount to transfer.", 30, useramount) as null|num
- if(useramount)
- useramount = clamp(useramount, 0, 200)
- src.Topic(href, list("amount" = "[useramount]", "add" = href_list["addcustom"]), state)
+ return TOPIC_REFRESH
else if (href_list["remove"])
if(href_list["amount"])
@@ -132,52 +151,44 @@
remove_from_reagents(my_reagents.type, amount)
for(var/decl/material/reagent in contaminants)
remove_from_reagents(reagent.type, round(rand()*amount, 0.1))
-
- else if (href_list["removecustom"])
- var/decl/material/my_reagents = locate(href_list["removecustom"])
- if(my_reagents)
- useramount = input("Select the amount to transfer.", 30, useramount) as null|num
- if(useramount)
- useramount = clamp(useramount, 0, 200)
- src.Topic(href, list("amount" = "[useramount]", "remove" = href_list["removecustom"]), state)
+ return TOPIC_REFRESH
else if (href_list["toggle"])
mode = !mode
+ return TOPIC_REFRESH
else if (href_list["toggle_sloppy"])
sloppy = !sloppy
+ return TOPIC_REFRESH
else if (href_list["main"])
- interact(user)
- return
+ return TOPIC_REFRESH
else if (href_list["eject"])
beaker.forceMove(loc)
beaker = null
reagents.clear_reagents()
icon_state = "mixer0"
+ return TOPIC_REFRESH
else if (href_list["createpill"] || href_list["createpill_multiple"])
var/count = 1
if(reagents.total_volume/count < 1) //Sanity checking.
- return
+ return TOPIC_HANDLED
if (href_list["createpill_multiple"])
count = input("Select the number of pills to make.", "Max [max_pill_count]", pillamount) as num
if(!CanInteract(user, state))
- return
+ return TOPIC_HANDLED
count = clamp(count, 1, max_pill_count)
- if(reagents.total_volume/count < 1) //Sanity checking.
- return
-
- var/amount_per_pill = reagents.total_volume/count
- if (amount_per_pill > 30) amount_per_pill = 30
+ var/amount_per_pill = min(reagents.total_volume/count, 30)
+ if(amount_per_pill < 1) // Sanity checking.
+ return TOPIC_HANDLED
var/name = sanitize_safe(input(usr,"Name:","Name your pill!","[reagents.get_primary_reagent_name()] ([amount_per_pill]u)"), MAX_NAME_LEN)
if(!CanInteract(user, state))
- return
-
+ return TOPIC_HANDLED
if(reagents.total_volume/count < 1) //Sanity checking.
- return
+ return TOPIC_HANDLED
while (count-- && count >= 0)
var/obj/item/chems/pill/dispensed/P = new(loc)
if(!name) name = reagents.get_primary_reagent_name()
@@ -187,9 +198,11 @@
P.update_icon()
if(loaded_pill_bottle && loaded_pill_bottle.storage && loaded_pill_bottle.contents.len < loaded_pill_bottle.storage.max_storage_space)
P.forceMove(loaded_pill_bottle)
+ return TOPIC_REFRESH
else if (href_list["createbottle"])
create_bottle(user)
+ return TOPIC_REFRESH
else if(href_list["change_pill"])
#define MAX_PILL_SPRITE 25 //max icon state of the pill sprites
var/dat = ""
@@ -197,15 +210,16 @@
dat += " |
"
dat += "
"
show_browser(user, dat, "window=chem_master")
- return
+ return TOPIC_HANDLED
else if(href_list["pill_sprite"])
pillsprite = href_list["pill_sprite"]
+ return TOPIC_REFRESH
else if(href_list["label_color"])
bottle_label_color = input(usr, "Pick new bottle label color", "Label color", bottle_label_color) as color
+ return TOPIC_REFRESH
else if(href_list["lid_color"])
bottle_lid_color = input(usr, "Pick new bottle lid color", "Lid color", bottle_lid_color) as color
-
- updateUsrDialog()
+ return TOPIC_REFRESH
/obj/machinery/chem_master/proc/fetch_contaminants(mob/user, datum/reagents/reagents, decl/material/main_reagent)
. = list()
diff --git a/code/modules/reagents/chems/chems_alcohol.dm b/code/modules/reagents/chems/chems_alcohol.dm
index 44384d64365f..505354b4d30f 100644
--- a/code/modules/reagents/chems/chems_alcohol.dm
+++ b/code/modules/reagents/chems/chems_alcohol.dm
@@ -121,7 +121,7 @@
/decl/material/liquid/alcohol/ale
name = "ale"
- lore_text = "A dark alchoholic beverage made by malted barley and yeast."
+ lore_text = "A dark alcoholic beverage made by malted barley and yeast."
taste_description = "hearty barley ale"
color = "#4c3100"
strength = 50
@@ -174,7 +174,7 @@
/decl/material/liquid/alcohol/cognac
name = "cognac"
- lore_text = "A sweet and strongly alchoholic drink, made after numerous distillations and years of maturing. Classy as fornication."
+ lore_text = "A sweet and strongly alcoholic drink, made after numerous distillations and years of maturing. Classy as fornication."
taste_description = "rich and smooth alcohol"
taste_mult = 1.1
color = "#ab3c05"
@@ -199,7 +199,7 @@
glass_name = "gin"
glass_desc = "A crystal clear glass of Griffeater gin."
-//Base type for alchoholic drinks containing coffee
+//Base type for alcoholic drinks containing coffee
/decl/material/liquid/alcohol/coffee
name = "coffee liqueur"
lore_text = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936!"
@@ -362,7 +362,7 @@
/decl/material/liquid/alcohol/wine
name = "red wine"
- lore_text = "An premium alchoholic beverage made from distilled grape juice."
+ lore_text = "An premium alcoholic beverage made from distilled grape juice."
taste_description = "bitter sweetness"
color = "#7e4043" // rgb: 126, 64, 67
strength = 15
@@ -375,7 +375,7 @@
/decl/material/liquid/alcohol/wine/premium
name = "white wine"
- lore_text = "An exceptionally expensive alchoholic beverage made from distilled white grapes."
+ lore_text = "An exceptionally expensive alcoholic beverage made from distilled white grapes."
taste_description = "white velvet"
color = "#ffddaa" // rgb: 255, 221, 170 - a light cream
strength = 20
diff --git a/code/modules/reagents/chems/chems_blood.dm b/code/modules/reagents/chems/chems_blood.dm
index ab5f8e6dd8ec..3af88ab10719 100644
--- a/code/modules/reagents/chems/chems_blood.dm
+++ b/code/modules/reagents/chems/chems_blood.dm
@@ -10,6 +10,7 @@
taste_mult = 1.3
glass_name = "tomato juice"
glass_desc = "Are you sure this is tomato juice?"
+ coated_adjective = "bloody"
value = 2.5
opacity = TRUE
min_fluid_opacity = FLUID_MAX_ALPHA
diff --git a/code/modules/reagents/chems/chems_cleaner.dm b/code/modules/reagents/chems/chems_cleaner.dm
index 6b9108b98ef4..d14189ec1813 100644
--- a/code/modules/reagents/chems/chems_cleaner.dm
+++ b/code/modules/reagents/chems/chems_cleaner.dm
@@ -19,7 +19,7 @@
touch_met = 5
toxicity = 5
scent = "clean linen"
- scent_descriptor = SCENT_DESC_FRAGRANCE
+ scent_descriptor = "fragrance"
value = 0.25
dirtiness = DIRTINESS_DECONTAMINATE
decontamination_dose = 5
diff --git a/code/modules/reagents/chems/chems_compounds.dm b/code/modules/reagents/chems/chems_compounds.dm
index 468300ba1720..45a828e3a60c 100644
--- a/code/modules/reagents/chems/chems_compounds.dm
+++ b/code/modules/reagents/chems/chems_compounds.dm
@@ -49,6 +49,14 @@
value = 0.1
uid = "chem_blackpepper"
+/decl/material/solid/cinnamon
+ name = "cinnamon"
+ lore_text = "A powder used to flavor food and drinks. Unpleasant to eat a full spoonful of."
+ taste_description = "cinnamon"
+ color = "#a34b0d"
+ value = 0.2
+ uid = "chem_cinnamon"
+
/decl/material/liquid/enzyme
name = "universal enzyme"
uid = "chem_enzyme"
@@ -315,7 +323,7 @@
color = "#684b3c"
scannable = 1
scent = "cigarette smoke"
- scent_descriptor = SCENT_DESC_ODOR
+ scent_descriptor = "odour"
scent_range = 4
hidden_from_codex = TRUE
uid = "chem_tobacco"
@@ -331,7 +339,7 @@
taste_description = "fine tobacco"
value = 1.5
scent = "fine tobacco smoke"
- scent_descriptor = SCENT_DESC_FRAGRANCE
+ scent_descriptor = "fragrance"
uid = "chem_tobacco_fine"
/decl/material/solid/tobacco/bad
@@ -340,7 +348,7 @@
value = 0.5
scent = "acrid tobacco smoke"
scent_intensity = /decl/scent_intensity/strong
- scent_descriptor = SCENT_DESC_ODOR
+ scent_descriptor = "odour"
uid = "chem_tobacco_terrible"
/decl/material/solid/tobacco/liquid
diff --git a/code/modules/reagents/chems/chems_drinks.dm b/code/modules/reagents/chems/chems_drinks.dm
index eca5276b785f..51539ecf078e 100644
--- a/code/modules/reagents/chems/chems_drinks.dm
+++ b/code/modules/reagents/chems/chems_drinks.dm
@@ -580,6 +580,11 @@
glass_special = list(DRINK_FIZZ)
allergen_flags = ALLERGEN_CAFFEINE | ALLERGEN_STIMULANT
+/decl/material/liquid/drink/cola/build_presentation_name_from_reagents(var/obj/item/prop, var/supplied)
+ if(prop.reagents.has_reagent(/decl/material/liquid/drink/milk))
+ . = "pilk"
+ . = ..(prop, .)
+
/decl/material/liquid/drink/citrussoda
name = "citrus soda"
lore_text = "Fizzy and tangy."
@@ -718,9 +723,9 @@
/decl/material/liquid/drink/tea/black/build_presentation_name_from_reagents(var/obj/item/prop, var/supplied)
if(prop.reagents.has_reagent(/decl/material/liquid/drink/juice/orange))
- if(prop.reagents.has_reagent(/decl/material/liquid/drink/milk))
+ if(prop.reagents.has_reagent(/decl/material/liquid/drink/milk) && prop.reagents.has_reagent(/decl/material/liquid/drink/syrup/vanilla)) //real london fogs need vanilla syrup
. = "London Fog"
- else if(prop.reagents.has_reagent(/decl/material/liquid/drink/milk/soymilk))
+ else if(prop.reagents.has_reagent(/decl/material/liquid/drink/milk/soymilk) && prop.reagents.has_reagent(/decl/material/liquid/drink/syrup/vanilla))
. = "soy London Fog"
else
. = "Baron Grey"
@@ -846,6 +851,19 @@
glass_name = "pumpkin spice syrup"
glass_desc = "Thick spiced pumpkin syrup used to flavor drinks."
+/decl/material/liquid/drink/syrup/lavender
+ name = "lavender syrup"
+ lore_text = "Thick lavender syrup used to flavor drinks."
+ taste_description = "lavender"
+ color = "#c38be7"
+ coffee_priority = 1
+ exoplanet_rarity_plant = MAT_RARITY_NOWHERE
+ exoplanet_rarity_gas = MAT_RARITY_NOWHERE
+ uid = "chem_drink_lavendersyrup"
+
+ glass_name = "lavender syrup"
+ glass_desc = "Thick lavender syrup used to flavor drinks."
+
/decl/material/liquid/drink/gingerbeer
name = "ginger beer"
lore_text = "A hearty, non-alcoholic beverage brewed from ginger."
@@ -903,3 +921,15 @@
glass_name = "Compote"
glass_desc = "Traditional dessert drink made from fruits or berries. Grandma would be proud."
allergen_flags = ALLERGEN_FRUIT
+
+/decl/material/liquid/drink/horchata
+ name = "horchata"
+ lore_text = "A traditional Mexican drink made from rice, milk, vanilla, and cinnamon."
+ taste_description = "refreshing vanilla and cinnamon"
+ color = "#d6c9be"
+ exoplanet_rarity_plant = MAT_RARITY_NOWHERE
+ exoplanet_rarity_gas = MAT_RARITY_NOWHERE
+ uid = "chem_drink_horchata"
+
+ glass_name = "Horchata"
+ glass_desc = "A traditional Mexican drink made from rice, milk, vanilla, and cinnamon."
diff --git a/code/modules/reagents/chems/chems_fuel.dm b/code/modules/reagents/chems/chems_fuel.dm
index 0c532bd6711e..7853f2f5579a 100644
--- a/code/modules/reagents/chems/chems_fuel.dm
+++ b/code/modules/reagents/chems/chems_fuel.dm
@@ -38,7 +38,7 @@
/decl/material/liquid/fuel/hydrazine
name = "hydrazine"
- lore_text = "A toxic, colorless, flammable liquid with a strong ammonia-like odor, in hydrate form."
+ lore_text = "A toxic, colorless, flammable liquid with a strong ammonia-like odour, in hydrate form."
taste_description = "sweet tasting metal"
color = "#808080"
metabolism = REM * 0.2
diff --git a/code/modules/reagents/chems/chems_nutriment.dm b/code/modules/reagents/chems/chems_nutriment.dm
index cc0774431ca6..efe6040294cd 100644
--- a/code/modules/reagents/chems/chems_nutriment.dm
+++ b/code/modules/reagents/chems/chems_nutriment.dm
@@ -32,7 +32,6 @@
lore_text = "Mollusc meat, or slug meat - something slimy, anyway."
scannable = 1
taste_description = "cold, bitter slime"
- overdose = 10
hydration_factor = 6
uid = "chem_nutriment_slime"
allergen_flags = ALLERGEN_MEAT | ALLERGEN_FISH
diff --git a/code/modules/reagents/chems/chems_oil.dm b/code/modules/reagents/chems/chems_oil.dm
index ad359dd61ca4..e540efb9844b 100644
--- a/code/modules/reagents/chems/chems_oil.dm
+++ b/code/modules/reagents/chems/chems_oil.dm
@@ -17,6 +17,7 @@
affect_blood_on_ingest = 0
affect_blood_on_inhale = 0
slipperiness = 8
+ coated_adjective = "oily"
/decl/material/liquid/oil/plant
name = "plant oil"
diff --git a/code/modules/reagents/cocktails.dm b/code/modules/reagents/cocktails.dm
index 166d689541b1..1815fa6e998b 100644
--- a/code/modules/reagents/cocktails.dm
+++ b/code/modules/reagents/cocktails.dm
@@ -236,7 +236,7 @@
/decl/cocktail/beepsky_smash
name = "Beepsky Smash"
- description = "A cocktail originating with stationside security forces. Rumoured to take the edge off being stunned with your own baton."
+ description = "A cocktail originating with station-side security forces. Rumoured to take the edge off being stunned with your own baton."
ratios = list(
/decl/material/liquid/alcohol/whiskey = 2,
/decl/material/liquid/drink/juice/lime = 1,
@@ -560,7 +560,7 @@
/decl/cocktail/rewriter
name = "Rewriter"
- description = "A sickly concotion that college students and academics swear by for getting you through an all-nighter or six."
+ description = "A sickly concoction that college students and academics swear by for getting you through an all-nighter or six."
ratios = list(
/decl/material/liquid/drink/coffee = 1,
/decl/material/liquid/drink/citrussoda = 1
diff --git a/code/modules/reagents/dispenser/cartridge_presets.dm b/code/modules/reagents/dispenser/cartridge_presets.dm
index fadf1e191872..79d763d1f945 100644
--- a/code/modules/reagents/dispenser/cartridge_presets.dm
+++ b/code/modules/reagents/dispenser/cartridge_presets.dm
@@ -73,6 +73,8 @@ DEFINE_CARTRIDGE_FOR_CHEM(syrup_chocolate, /decl/material/liquid/drink/syrup/cho
DEFINE_CARTRIDGE_FOR_CHEM(syrup_caramel, /decl/material/liquid/drink/syrup/caramel)
DEFINE_CARTRIDGE_FOR_CHEM(syrup_vanilla, /decl/material/liquid/drink/syrup/vanilla)
DEFINE_CARTRIDGE_FOR_CHEM(syrup_pumpkin, /decl/material/liquid/drink/syrup/pumpkin)
+DEFINE_CARTRIDGE_FOR_CHEM(syrup_lavender, /decl/material/liquid/drink/syrup/lavender)
+DEFINE_CARTRIDGE_FOR_CHEM(cinnamon, /decl/material/solid/cinnamon)
// Bar, coffee
DEFINE_CARTRIDGE_FOR_CHEM(coffee, /decl/material/liquid/drink/coffee)
diff --git a/code/modules/reagents/dispenser/dispenser_presets.dm b/code/modules/reagents/dispenser/dispenser_presets.dm
index a42e49a4ae41..0336edaecb5a 100644
--- a/code/modules/reagents/dispenser/dispenser_presets.dm
+++ b/code/modules/reagents/dispenser/dispenser_presets.dm
@@ -151,7 +151,9 @@
/obj/item/chems/chem_disp_cartridge/syrup_chocolate,
/obj/item/chems/chem_disp_cartridge/syrup_caramel,
/obj/item/chems/chem_disp_cartridge/syrup_vanilla,
- /obj/item/chems/chem_disp_cartridge/syrup_pumpkin
+ /obj/item/chems/chem_disp_cartridge/syrup_pumpkin,
+ /obj/item/chems/chem_disp_cartridge/syrup_lavender,
+ /obj/item/chems/chem_disp_cartridge/cinnamon
)
buildable = FALSE
\ No newline at end of file
diff --git a/code/modules/reagents/reactions/reaction_recipe.dm b/code/modules/reagents/reactions/reaction_recipe.dm
index a113d821cc58..f7cd8bb17a5e 100644
--- a/code/modules/reagents/reactions/reaction_recipe.dm
+++ b/code/modules/reagents/reactions/reaction_recipe.dm
@@ -119,3 +119,10 @@
result_amount = 6
mix_message = "The broth of the noodles takes on a hellish red gleam."
hidden_from_codex = TRUE
+
+/decl/chemical_reaction/recipe/horchata
+ name = "Horchata"
+ result = /decl/material/liquid/drink/horchata
+ required_reagents = list(/decl/material/liquid/nutriment/rice = 2, /decl/material/liquid/drink/milk = 2, /decl/material/liquid/drink/syrup/vanilla = 1, /decl/material/solid/cinnamon = 1)
+ result_amount = 6
+ mix_message = "The ingredients combine to create a refreshing white beverage."
diff --git a/code/modules/reagents/reagent_containers/beaker.dm b/code/modules/reagents/reagent_containers/beaker.dm
index ab42e686e931..3a769fdec137 100644
--- a/code/modules/reagents/reagent_containers/beaker.dm
+++ b/code/modules/reagents/reagent_containers/beaker.dm
@@ -164,7 +164,7 @@
material_alteration = MAT_FLAG_ALTERATION_NONE
lid_color = COLOR_GRAY40
-/obj/item/chems/glass/beaker/insulated/get_thermal_mass_coefficient()
+/obj/item/chems/glass/beaker/insulated/get_thermal_mass_coefficient(delta)
return 0.1
// Hack around reagent temp changes.
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index 658b68dddf7c..862b3d655059 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -117,7 +117,7 @@
/obj/item/chems/borghypo/service
name = "cyborg drink synthesizer"
- desc = "A portable drink dispencer."
+ desc = "A portable drink dispenser."
icon = 'icons/obj/drinks.dmi'
icon_state = "shaker"
charge_cost = 5
diff --git a/code/modules/reagents/reagent_containers/condiments/condiment_appearance.dm b/code/modules/reagents/reagent_containers/condiments/condiment_appearance.dm
index 4236c1867544..6192a77f4d6a 100644
--- a/code/modules/reagents/reagent_containers/condiments/condiment_appearance.dm
+++ b/code/modules/reagents/reagent_containers/condiments/condiment_appearance.dm
@@ -124,3 +124,9 @@
condiment_desc = "A small bottle of the essential oil of some kind of mint plant."
condiment_icon = 'icons/obj/food/condiments/coldsauce.dmi'
condiment_key = "small"
+
+/decl/condiment_appearance/cinnamon
+ condiment_type = /decl/material/solid/cinnamon
+ condiment_name = "cinnamon"
+ condiment_desc = "A small bottle of ground cinnamon."
+ condiment_icon = 'icons/obj/food/condiments/generic.dmi'
diff --git a/code/modules/reagents/reagent_containers/condiments/condiments.dm b/code/modules/reagents/reagent_containers/condiments/condiments.dm
index 3204fee220dc..c58d74df45ca 100644
--- a/code/modules/reagents/reagent_containers/condiments/condiments.dm
+++ b/code/modules/reagents/reagent_containers/condiments/condiments.dm
@@ -18,5 +18,6 @@ MAPPED_CONDIMENT_TYPE(frostoil, /decl/condiment_appearance/coldsauce)
MAPPED_CONDIMENT_TYPE(capsaicin, /decl/condiment_appearance/capsaicin)
MAPPED_CONDIMENT_TYPE(yeast, /decl/condiment_appearance/yeast)
MAPPED_CONDIMENT_TYPE(flour, /decl/condiment_appearance/flour)
+MAPPED_CONDIMENT_TYPE(cinnamon, /decl/condiment_appearance/cinnamon)
#undef MAPPED_CONDIMENT_TYPE
\ No newline at end of file
diff --git a/code/modules/reagents/reagent_containers/drinks/bottle.dm b/code/modules/reagents/reagent_containers/drinks/bottle.dm
index 56e5f6b47206..7797e94b0e32 100644
--- a/code/modules/reagents/reagent_containers/drinks/bottle.dm
+++ b/code/modules/reagents/reagent_containers/drinks/bottle.dm
@@ -13,7 +13,7 @@
abstract_type = /obj/item/chems/drinks/bottle
var/smash_duration = 5 //Directly relates to the 'weaken' duration. Lowered by armor (i.e. helmets)
- var/obj/item/chems/glass/rag/rag = null
+ var/obj/item/chems/rag/rag = null
var/rag_underlay = "rag"
var/stop_spin_bottle = FALSE //Gotta stop the rotation.
@@ -95,7 +95,7 @@
/obj/item/chems/drinks/bottle/attackby(obj/item/W, mob/user)
if(!rag)
- if(istype(W, /obj/item/chems/glass/rag))
+ if(istype(W, /obj/item/chems/rag))
insert_rag(W, user)
return TRUE
else if(W.isflamesource())
@@ -105,7 +105,7 @@
/obj/item/chems/drinks/bottle/attack_self(mob/user)
return rag ? remove_rag(user) : ..()
-/obj/item/chems/drinks/bottle/proc/insert_rag(obj/item/chems/glass/rag/R, mob/user)
+/obj/item/chems/drinks/bottle/proc/insert_rag(obj/item/chems/rag/R, mob/user)
if(material?.type != /decl/material/solid/glass)
to_chat(user, SPAN_WARNING("\The [src] isn't made of glass, you can't make a good Molotov with it."))
return TRUE
@@ -290,7 +290,7 @@
/obj/item/chems/drinks/bottle/patron
name = "Wrapp Artiste Patron"
- desc = "Silver laced tequila, served in space night clubs across the galaxy."
+ desc = "Silver laced tequila, served in space nightclubs across the galaxy."
icon_state = "patronbottle"
center_of_mass = @'{"x":16,"y":6}'
@@ -346,7 +346,7 @@
/obj/item/chems/drinks/bottle/cognac
name = "Chateau De Baton Premium Cognac"
- desc = "A sweet and strongly alchoholic drink, made after numerous distillations and years of maturing. You might as well not scream 'SHITCURITY' this time."
+ desc = "A sweet and strongly alcoholic drink, made after numerous distillations and years of maturing. You might as well not scream 'SHITCURITY' this time."
icon_state = "cognacbottle"
center_of_mass = @'{"x":16,"y":6}'
@@ -409,7 +409,7 @@
/obj/item/chems/drinks/bottle/cola
name = "\improper Space Cola"
- desc = "Cola. in space."
+ desc = "Cola... in space."
icon_state = "colabottle"
center_of_mass = @'{"x":16,"y":6}'
diff --git a/code/modules/reagents/reagent_containers/drinks/cans.dm b/code/modules/reagents/reagent_containers/drinks/cans.dm
index 7c2dbb14dd63..3b0974dd6e3a 100644
--- a/code/modules/reagents/reagent_containers/drinks/cans.dm
+++ b/code/modules/reagents/reagent_containers/drinks/cans.dm
@@ -12,7 +12,7 @@
/obj/item/chems/drinks/cans/cola
name = "\improper Space Cola"
- desc = "Cola. in space."
+ desc = "Cola... in space."
icon_state = "cola"
center_of_mass = @'{"x":16,"y":10}'
diff --git a/code/modules/reagents/reagent_containers/drinks/cocktailshaker.dm b/code/modules/reagents/reagent_containers/drinks/cocktailshaker.dm
index c2517e3b519d..f8416cf3a1f0 100644
--- a/code/modules/reagents/reagent_containers/drinks/cocktailshaker.dm
+++ b/code/modules/reagents/reagent_containers/drinks/cocktailshaker.dm
@@ -1,6 +1,6 @@
/obj/item/chems/drinks/shaker
name = "shaker"
- desc = "A three piece Cobbler-style shaker. Used to mix, cool, and strain drinks."
+ desc = "A three-piece Cobbler-style shaker. Used to mix, cool, and strain drinks."
icon_state = "shaker"
amount_per_transfer_from_this = 10
possible_transfer_amounts = @"[5,10,15,25,30,60]" //Professional bartender should be able to transfer as much as needed
diff --git a/code/modules/reagents/reagent_containers/food/canned/_canned.dm b/code/modules/reagents/reagent_containers/food/canned/_canned.dm
index 5e4c35d81297..63fa762a18d6 100644
--- a/code/modules/reagents/reagent_containers/food/canned/_canned.dm
+++ b/code/modules/reagents/reagent_containers/food/canned/_canned.dm
@@ -82,7 +82,7 @@
/obj/item/food/can/beans
name = "baked beans"
icon_state = "beans"
- desc = "Carefully synthethized from soy."
+ desc = "Carefully synthesized from soy."
trash = /obj/item/trash/beans
filling_color = "#ff6633"
nutriment_desc = list("beans" = 1)
diff --git a/code/modules/reagents/reagent_containers/food/dairy/cheeses.dm b/code/modules/reagents/reagent_containers/food/dairy/cheeses.dm
index 9b31f8e3c7c6..b6f7287382da 100644
--- a/code/modules/reagents/reagent_containers/food/dairy/cheeses.dm
+++ b/code/modules/reagents/reagent_containers/food/dairy/cheeses.dm
@@ -22,7 +22,7 @@
/obj/item/food/dairy/cheese/wheel
name = "wheel"
- desc = "A big wheel of delcious cheese."
+ desc = "A big wheel of delicious cheese."
icon = 'icons/obj/food/dairy/cheese_wheel.dmi'
slice_path = /obj/item/food/dairy/cheese/wedge/slice
slice_num = 5
diff --git a/code/modules/reagents/reagent_containers/food/eggs.dm b/code/modules/reagents/reagent_containers/food/eggs.dm
index ea7851b65edc..955ea9d8d10b 100644
--- a/code/modules/reagents/reagent_containers/food/eggs.dm
+++ b/code/modules/reagents/reagent_containers/food/eggs.dm
@@ -96,7 +96,7 @@
/obj/item/food/boiledegg
name = "boiled egg"
- desc = "A hard boiled egg."
+ desc = "A hard-boiled egg."
icon = 'icons/obj/food/eggs/egg.dmi'
icon_state = ICON_STATE_WORLD
filling_color = "#ffffff"
diff --git a/code/modules/reagents/reagent_containers/food/junkfood.dm b/code/modules/reagents/reagent_containers/food/junkfood.dm
index 7792578bcda1..70a2f267872b 100644
--- a/code/modules/reagents/reagent_containers/food/junkfood.dm
+++ b/code/modules/reagents/reagent_containers/food/junkfood.dm
@@ -91,7 +91,7 @@
/obj/item/food/junk/squid
name = "\improper Calamari Crisps"
icon_state = "squid"
- desc = "Space cepholapod tentacles, carefully removed from the squid then dried into strips of delicious rubbery goodness!"
+ desc = "Space cephalopod tentacles, carefully removed from the squid then dried into strips of delicious rubbery goodness!"
trash = /obj/item/trash/squid
filling_color = "#c0a9d7"
center_of_mass = @'{"x":15,"y":9}'
@@ -355,7 +355,7 @@
/obj/item/food/junk/oort
name = "\improper Cloud Rocks"
icon_state = "oort"
- desc = "Pop rocks. The new formula guarantees fewer shrapnel induced oral injuries."
+ desc = "Pop rocks. The new formula guarantees fewer shrapnel-induced oral injuries."
trash = /obj/item/trash/oort
filling_color = "#3f7dd2"
center_of_mass = @'{"x":15,"y":9}'
diff --git a/code/modules/reagents/reagent_containers/food/meat/cubes.dm b/code/modules/reagents/reagent_containers/food/meat/cubes.dm
index 76236a4910cf..ccad0f203228 100644
--- a/code/modules/reagents/reagent_containers/food/meat/cubes.dm
+++ b/code/modules/reagents/reagent_containers/food/meat/cubes.dm
@@ -36,7 +36,7 @@
add_to_reagents(/decl/material/solid/organic/meat, 10)
/obj/item/food/animal_cube/get_single_monetary_worth()
- . = (spawn_type ? round(atom_info_repository.get_combined_worth_for(spawn_type) * 1.25) : 5)
+ . = (spawn_type ? round(atom_info_repository.get_combined_worth_for((islist(spawn_type) ? spawn_type[1] : spawn_type)) * 1.25) : 5)
if(wrapper_type)
. += atom_info_repository.get_combined_worth_for(wrapper_type)
@@ -51,6 +51,8 @@
return
growing = TRUE
visible_message(SPAN_NOTICE("\The [src] expands!"))
+ if(islist(spawn_type))
+ spawn_type = pickweight(spawn_type)
var/mob/critter = new spawn_type
critter.dropInto(force_loc || loc)
qdel(src)
@@ -96,3 +98,19 @@
/obj/item/food/animal_cube/wrapped/monkey
name = "monkey cube"
spawn_type = /mob/living/human/monkey
+
+/obj/item/food/animal_cube/carp
+ name = "carp cube"
+ spawn_type = list(
+ /mob/living/simple_animal/hostile/carp = 10,
+ /mob/living/simple_animal/hostile/carp/pike = 3,
+ /mob/living/simple_animal/hostile/carp/shark = 1
+ )
+
+/obj/item/food/animal_cube/wrapped/carp
+ name = "carp cube"
+ spawn_type = list(
+ /mob/living/simple_animal/hostile/carp = 10,
+ /mob/living/simple_animal/hostile/carp/pike = 3,
+ /mob/living/simple_animal/hostile/carp/shark = 1
+ )
diff --git a/code/modules/reagents/reagent_containers/food/pasta.dm b/code/modules/reagents/reagent_containers/food/pasta.dm
index b62330fb2e96..94c12fc4feb7 100644
--- a/code/modules/reagents/reagent_containers/food/pasta.dm
+++ b/code/modules/reagents/reagent_containers/food/pasta.dm
@@ -54,7 +54,7 @@
/obj/item/food/meatballspagetti
name = "spaghetti & meatballs"
- desc = "Now thats a nice meatball!"
+ desc = "Now that's a nice meatball!"
icon = 'icons/obj/food/pasta/meatball_spaghetti.dmi'
plate = /obj/item/plate
filling_color = "#de4545"
diff --git a/code/modules/reagents/reagent_containers/food/rotten.dm b/code/modules/reagents/reagent_containers/food/rotten.dm
index 22e15e4dea1c..4115b5d05dee 100644
--- a/code/modules/reagents/reagent_containers/food/rotten.dm
+++ b/code/modules/reagents/reagent_containers/food/rotten.dm
@@ -1,8 +1,7 @@
//inedible old vendor food
-
+//filled with inedible and possibly dangerous chemicals
/obj/item/food/old
name = "master old-food"
- desc = "they're all inedible and potentially dangerous items"
center_of_mass = @'{"x":15,"y":12}'
nutriment_desc = list("rot" = 5, "mold" = 5)
nutriment_amt = 10
diff --git a/code/modules/reagents/reagent_containers/food/sliceable/cakes.dm b/code/modules/reagents/reagent_containers/food/sliceable/cakes.dm
index e5088980d8ef..2d7f45c72ee7 100644
--- a/code/modules/reagents/reagent_containers/food/sliceable/cakes.dm
+++ b/code/modules/reagents/reagent_containers/food/sliceable/cakes.dm
@@ -17,7 +17,7 @@
/obj/item/food/slice/carrotcake
name = "carrot cake slice"
- desc = "Carrotty slice of carrot cake, carrots are good for your eyes! It's true! Probably!"
+ desc = "Carrot-y slice of carrot cake, carrots are good for your eyes! It's true! Probably!"
icon = 'icons/obj/food/baked/cakes/slices/carrot.dmi'
plate = /obj/item/plate
filling_color = "#ffd675"
@@ -77,7 +77,7 @@
/obj/item/food/slice/cheesecake
name = "cheese cake slice"
- desc = "Slice of pure cheestisfaction."
+ desc = "Slice of pure cheesatisfaction."
icon = 'icons/obj/food/baked/cakes/slices/cheese.dmi'
plate = /obj/item/plate
filling_color = "#faf7af"
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index be5659ebba4e..70dc6661c2a2 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -22,7 +22,7 @@
)
// autoinjectors takes less time than a normal syringe (overriden for hypospray).
- // This delay is only applied when injecting concious mobs, and is not applied for self-injection
+ // This delay is only applied when injecting conscious mobs, and is not applied for self-injection
// The 1.9 factor scales it so it takes the following number of seconds:
// NONE 1.47
// BASIC 1.00
@@ -57,7 +57,7 @@
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(target)
- if(user != target && !target.incapacitated() && time) // you're injecting someone else who is concious, so apply the device's intrisic delay
+ if(user != target && !target.incapacitated() && time) // you're injecting someone else who is conscious, so apply the device's intrisic delay
to_chat(user, SPAN_WARNING("\The [user] is trying to inject \the [target] with \the [name]."))
if(!user.do_skilled(time, SKILL_MEDICAL, target))
return TRUE
@@ -83,7 +83,7 @@
////////////////////////////////////////////////////////////////////////////////
/obj/item/chems/hypospray/vial
name = "hypospray"
- desc = "A sterile, air-needle autoinjector for rapid administration of drugs to patients. Uses a replacable 30u vial."
+ desc = "A sterile, air-needle autoinjector for rapid administration of drugs to patients. Uses a replaceable 30u vial."
possible_transfer_amounts = @"[1,2,5,10,15,20,30]"
amount_per_transfer_from_this = 5
volume = 0
diff --git a/code/modules/reagents/reagent_containers/retort.dm b/code/modules/reagents/reagent_containers/retort.dm
index d19e473ee337..0b78d727e24e 100644
--- a/code/modules/reagents/reagent_containers/retort.dm
+++ b/code/modules/reagents/reagent_containers/retort.dm
@@ -1,7 +1,7 @@
/obj/item/chems/glass/retort
name = "retort"
base_name = "retort"
- desc = "A strangely-shaped vessel for seperating chemicals when heated."
+ desc = "A strangely-shaped vessel for separating chemicals when heated."
icon = 'icons/obj/items/retort.dmi'
icon_state = ICON_STATE_WORLD
volume = 120
diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm
index febab7b3c6b1..da96a75e031b 100644
--- a/code/modules/recycling/conveyor2.dm
+++ b/code/modules/recycling/conveyor2.dm
@@ -301,7 +301,7 @@ var/global/list/all_conveyor_switches = list()
/obj/item/conveyor_switch_construct/oneway
name = "one-way conveyor switch assembly"
- desc = "An one-way conveyor control switch assembly."
+ desc = "A one-way conveyor control switch assembly."
/obj/item/conveyor_switch_construct/oneway/afterattack(atom/A, mob/user, proximity)
if(!proximity || !istype(A, /turf/floor) || user.incapacitated())
diff --git a/code/modules/recycling/disposalpipe.dm b/code/modules/recycling/disposalpipe.dm
index 88e11fbbdc60..6727ee5fbfa8 100644
--- a/code/modules/recycling/disposalpipe.dm
+++ b/code/modules/recycling/disposalpipe.dm
@@ -236,6 +236,7 @@
// a straight or bent segment
/obj/structure/disposalpipe/segment
+ desc = "A linear segment of disposal piping that simply moves things from one end to the other."
icon_state = "pipe-s" // Sadly this var stores state. "pipe-c" is corner. Should be changed, but requires huge map diff.
turn = DISPOSAL_FLIP_FLIP
@@ -364,6 +365,7 @@
//a three-way junction with dir being the dominant direction
/obj/structure/disposalpipe/junction
+ desc = "A three-way segment of disposal piping that merges two incoming directions into a third outgoing one."
icon_state = "pipe-j1"
turn = DISPOSAL_FLIP_RIGHT|DISPOSAL_FLIP_FLIP
flipped_state = /obj/structure/disposalpipe/junction/mirrored
@@ -413,6 +415,7 @@
/obj/structure/disposalpipe/tagger
name = "package tagger"
+ desc = "A pipe that tags things passing through it with a sorting tag."
icon_state = "pipe-tagger"
var/sort_tag = ""
var/partial = 0
@@ -459,6 +462,7 @@
/obj/structure/disposalpipe/tagger/partial //needs two passes to tag
name = "partial package tagger"
+ desc = "A pipe that tags things passing through it with a sorting tag... but only the second time around."
icon_state = "pipe-tagger-partial"
partial = 1
turn = DISPOSAL_FLIP_FLIP
@@ -480,7 +484,7 @@
/obj/structure/disposalpipe/diversion_junction/proc/updatedesc()
desc = initial(desc)
if(sort_type)
- desc += "\nIt's currently [active ? "" : "un"]active!"
+ desc += "\nIt's currently [active ? "" : "in"]active!"
/obj/structure/disposalpipe/diversion_junction/proc/updatedir()
inactive_dir = dir
@@ -687,6 +691,7 @@
//a trunk joining to a disposal bin or outlet on the same turf
/obj/structure/disposalpipe/trunk
+ desc = "A section of pneumatic piping made to connect to a bin or outlet."
icon_state = "pipe-t"
var/obj/linked // the linked obj/machinery/disposal or obj/disposaloutlet
diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm
index 76e6c440ec3a..274c5aec2599 100644
--- a/code/modules/recycling/sortingmachinery.dm
+++ b/code/modules/recycling/sortingmachinery.dm
@@ -1,6 +1,6 @@
/obj/machinery/disposal/deliveryChute
name = "delivery chute"
- desc = "A chute for big and small packages alike!"
+ desc = "A chute to put things into a disposal network. Takes big and small packages alike!"
density = TRUE
icon = 'icons/obj/pipes/disposal_chute.dmi'
icon_state = "chute"
diff --git a/code/modules/research/research_fields.dm b/code/modules/research/research_fields.dm
index 31448ed7631b..d37be7dde722 100644
--- a/code/modules/research/research_fields.dm
+++ b/code/modules/research/research_fields.dm
@@ -49,7 +49,7 @@
/decl/research_field/programming
name = "Data Science"
- desc = "The study of computer science, data manipuation and artificial intelligence."
+ desc = "The study of computer science, data manipulation and artificial intelligence."
id = TECH_DATA
/decl/research_field/esoteria
diff --git a/code/game/objects/items/devices/scanners/_scanner.dm b/code/modules/scanners/_scanner.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/_scanner.dm
rename to code/modules/scanners/_scanner.dm
diff --git a/code/game/objects/items/devices/scanners/breath.dm b/code/modules/scanners/breath.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/breath.dm
rename to code/modules/scanners/breath.dm
diff --git a/code/game/objects/items/devices/scanners/gas.dm b/code/modules/scanners/gas.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/gas.dm
rename to code/modules/scanners/gas.dm
diff --git a/code/game/objects/items/devices/scanners/health.dm b/code/modules/scanners/health.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/health.dm
rename to code/modules/scanners/health.dm
diff --git a/code/game/objects/items/devices/scanners/mass_spectrometer.dm b/code/modules/scanners/mass_spectrometer.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/mass_spectrometer.dm
rename to code/modules/scanners/mass_spectrometer.dm
diff --git a/code/game/objects/items/devices/scanners/mining.dm b/code/modules/scanners/mining.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/mining.dm
rename to code/modules/scanners/mining.dm
diff --git a/code/game/objects/items/devices/scanners/network.dm b/code/modules/scanners/network.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/network.dm
rename to code/modules/scanners/network.dm
diff --git a/code/game/objects/items/devices/scanners/plant.dm b/code/modules/scanners/plant.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/plant.dm
rename to code/modules/scanners/plant.dm
diff --git a/code/game/objects/items/devices/scanners/price.dm b/code/modules/scanners/price.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/price.dm
rename to code/modules/scanners/price.dm
diff --git a/code/game/objects/items/devices/scanners/reagents.dm b/code/modules/scanners/reagents.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/reagents.dm
rename to code/modules/scanners/reagents.dm
diff --git a/code/game/objects/items/devices/scanners/xenobio.dm b/code/modules/scanners/xenobio.dm
similarity index 100%
rename from code/game/objects/items/devices/scanners/xenobio.dm
rename to code/modules/scanners/xenobio.dm
diff --git a/code/datums/extensions/scent/_scent.dm b/code/modules/scent/_scent.dm
similarity index 94%
rename from code/datums/extensions/scent/_scent.dm
rename to code/modules/scent/_scent.dm
index cdf60ec83e0f..2298b57494d2 100644
--- a/code/datums/extensions/scent/_scent.dm
+++ b/code/modules/scent/_scent.dm
@@ -1,6 +1,6 @@
-#define SCENT_DESC_ODOR "odour"
-#define SCENT_DESC_SMELL "smell"
-#define SCENT_DESC_FRAGRANCE "fragrance"
+var/global/const/SCENT_DESC_ODOR = "odour"
+var/global/const/SCENT_DESC_SMELL = "smell"
+var/global/const/SCENT_DESC_FRAGRANCE = "fragrance"
/*****
Scent intensity
@@ -43,7 +43,7 @@ Scent intensity
var/scent = "something"
var/decl/scent_intensity/intensity = /decl/scent_intensity
- var/descriptor = SCENT_DESC_SMELL //unambiguous descriptor of smell; food is generally good, sewage is generally bad. how 'nice' the scent is
+ var/descriptor = "smell" //unambiguous descriptor of smell; food is generally good, sewage is generally bad. how 'nice' the scent is
var/range = 1 //range in tiles
/datum/extension/scent/New()
diff --git a/code/datums/extensions/scent/scent_candle.dm b/code/modules/scent/scent_candle.dm
similarity index 95%
rename from code/datums/extensions/scent/scent_candle.dm
rename to code/modules/scent/scent_candle.dm
index b8821fbe4ef8..37830e311c08 100644
--- a/code/datums/extensions/scent/scent_candle.dm
+++ b/code/modules/scent/scent_candle.dm
@@ -1,6 +1,6 @@
/datum/extension/scent/candle
intensity = /decl/scent_intensity/normal
- descriptor = SCENT_DESC_FRAGRANCE
+ descriptor = "fragrance"
range = 4
/datum/extension/scent/candle/rose
diff --git a/code/datums/scents/scent_decls.dm b/code/modules/scent/scent_decls.dm
similarity index 100%
rename from code/datums/scents/scent_decls.dm
rename to code/modules/scent/scent_decls.dm
diff --git a/code/datums/extensions/scent/scent_misc.dm b/code/modules/scent/scent_misc.dm
similarity index 76%
rename from code/datums/extensions/scent/scent_misc.dm
rename to code/modules/scent/scent_misc.dm
index 5e79b5552e89..ecad58d68fc8 100644
--- a/code/datums/extensions/scent/scent_misc.dm
+++ b/code/modules/scent/scent_misc.dm
@@ -1,5 +1,5 @@
/datum/extension/scent/ashtray
scent = "an ashtray"
intensity = /decl/scent_intensity
- descriptor = SCENT_DESC_ODOR
+ descriptor = "odour"
range = 2
\ No newline at end of file
diff --git a/code/modules/sealant_gun/sealant_gun.dm b/code/modules/sealant_gun/sealant_gun.dm
index 70d644b721c9..6f0d91966447 100644
--- a/code/modules/sealant_gun/sealant_gun.dm
+++ b/code/modules/sealant_gun/sealant_gun.dm
@@ -1,6 +1,6 @@
/obj/item/gun/launcher/sealant
name = "sealant gun"
- desc = "A heavy, unwieldly device used to spray metal foam sealant onto hull breaches or damaged flooring."
+ desc = "A heavy, unwieldy device used to spray metal foam sealant onto hull breaches or damaged flooring."
icon = 'icons/obj/guns/sealant_gun.dmi'
icon_state = ICON_STATE_WORLD
autofire_enabled = TRUE
diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm
index d7cb76c4ead0..41df847379cf 100644
--- a/code/modules/security_levels/keycard_authentication.dm
+++ b/code/modules/security_levels/keycard_authentication.dm
@@ -194,7 +194,7 @@
if(nuke)
visible_message(SPAN_WARNING("\The [src] blinks and displays a message: The nuclear authorization code is [nuke.r_code]"), range=2)
else
- visible_message(SPAN_WARNING("\The [src] blinks and displays a message: No self destruct terminal found."), range=2)
+ visible_message(SPAN_WARNING("\The [src] blinks and displays a message: No self-destruct terminal found."), range=2)
SSstatistics.add_field("alert_keycard_auth_nukecode",1)
/obj/machinery/keycard_auth/proc/is_ert_blocked()
diff --git a/code/modules/shield_generators/shield.dm b/code/modules/shield_generators/shield.dm
index b39816fdce51..4a48e64409d5 100644
--- a/code/modules/shield_generators/shield.dm
+++ b/code/modules/shield_generators/shield.dm
@@ -13,12 +13,12 @@
var/disabled_for = 0
var/diffused_for = 0
-/obj/effect/shield/on_update_icon(update_neighbors = FALSE)
+/obj/effect/shield/on_update_icon()
if(gen && gen.check_flag(MODEFLAG_PHOTONIC) && !disabled_for && !diffused_for)
- set_opacity(1)
+ set_opacity(TRUE)
else
- set_opacity(0)
+ set_opacity(FALSE)
if(gen && gen.check_flag(MODEFLAG_OVERCHARGE))
color = COLOR_VIOLET
@@ -29,24 +29,32 @@
cut_overlays()
for(var/direction in global.cardinal)
- var/turf/T = get_step(src, direction)
- if(!T)
+ var/turf/resolved_turf = get_step_resolving_mimic(src, direction)
+ if(!resolved_turf)
continue
- var/found = locate(/obj/effect/shield) in T
+ var/found = locate(/obj/effect/shield) in resolved_turf
if(found)
- if(update_neighbors)
- for(var/obj/effect/shield/shield in T)
- shield.update_icon(FALSE)
add_overlay(image(icon = icon, icon_state = "[icon_state]edge", dir = direction))
+/obj/effect/shield/update_nearby_tiles(need_rebuild)
+ . = ..()
+ for(var/direction in global.cardinal)
+ var/turf/resolved_turf = get_step_resolving_mimic(src, direction)
+ if(!resolved_turf)
+ continue
+ for(var/obj/effect/shield/shield in resolved_turf)
+ if(!(shield.atom_flags & ATOM_FLAG_INITIALIZED)) // they'll update themselves later
+ continue
+ shield.update_icon()
+
// Prevents shuttles, singularities and pretty much everything else from moving the field segments away.
// The only thing that is allowed to move us is the Destroy() proc.
/obj/effect/shield/forceMove()
. = QDELING(src) && ..()
-/obj/effect/shield/Initialize()
+/obj/effect/shield/Initialize(mapload)
. = ..()
- update_icon(TRUE)
+ update_icon()
update_nearby_tiles()
/obj/effect/shield/Destroy()
@@ -96,7 +104,7 @@
set_density(1)
set_invisibility(INVISIBILITY_NONE)
update_nearby_tiles()
- update_icon(TRUE)
+ update_icon()
update_explosion_resistance()
gen.damaged_segments -= src
@@ -112,7 +120,7 @@
set_density(0)
set_invisibility(INVISIBILITY_MAXIMUM)
update_nearby_tiles()
- update_icon(TRUE)
+ update_icon()
update_explosion_resistance()
// Fails shield segments in specific range. Range of 1 affects the shielded turf only.
@@ -255,7 +263,7 @@
// Update airflow
update_nearby_tiles()
- update_icon(TRUE)
+ update_icon()
update_explosion_resistance()
/obj/effect/shield/proc/update_explosion_resistance()
diff --git a/code/modules/shuttles/escape_pods.dm b/code/modules/shuttles/escape_pods.dm
index bd13d30c417b..8d1ee2489bec 100644
--- a/code/modules/shuttles/escape_pods.dm
+++ b/code/modules/shuttles/escape_pods.dm
@@ -142,7 +142,7 @@ var/global/list/escape_pods_by_name = list()
/datum/computer/file/embedded_program/docking/simple/escape_pod_berth/receive_user_command(command)
if (!armed)
- return TRUE // Eat all commands.
+ return TOPIC_HANDLED // Eat all commands.
return ..(command)
/datum/computer/file/embedded_program/docking/simple/escape_pod_berth/process()
diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm
index 85ee565817b5..d11e0cb97a83 100644
--- a/code/modules/shuttles/shuttle.dm
+++ b/code/modules/shuttles/shuttle.dm
@@ -15,7 +15,7 @@
abstract_type = /datum/shuttle
var/multiz = 0 //how many multiz levels, starts at 0
- var/ceiling_type = /turf/unsimulated/floor/shuttle_ceiling
+ var/ceiling_type = /turf/floor/shuttle_ceiling
var/force_ceiling_on_init = TRUE // Whether or not to force ceilings turfs to be created above on initialization.
var/sound_takeoff = 'sound/effects/shuttle_takeoff.ogg'
@@ -116,7 +116,7 @@
if (moving_status == SHUTTLE_IDLE)
return //someone cancelled the launch
- if(!fuel_check()) //fuel error (probably out of fuel) occured, so cancel the launch
+ if(!fuel_check()) //fuel error (probably out of fuel) occurred, so cancel the launch
var/datum/shuttle/autodock/S = src
if(istype(S))
S.cancel_launch(null)
@@ -138,7 +138,7 @@
if(moving_status == SHUTTLE_IDLE)
return //someone cancelled the launch
- if(!fuel_check()) //fuel error (probably out of fuel) occured, so cancel the launch
+ if(!fuel_check()) //fuel error (probably out of fuel) occurred, so cancel the launch
var/datum/shuttle/autodock/S = src
if(istype(S))
S.cancel_launch(null)
diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm
index 422e33e3f0e1..774c5d4bdf09 100644
--- a/code/modules/shuttles/shuttle_console.dm
+++ b/code/modules/shuttles/shuttle_console.dm
@@ -37,7 +37,7 @@
shuttle_status = "Standing-by at [shuttle.get_location_name()]."
if(WAIT_LAUNCH, FORCE_LAUNCH)
- shuttle_status = "Shuttle has recieved command and will depart shortly."
+ shuttle_status = "Shuttle has received command and will depart shortly."
if(WAIT_ARRIVE)
shuttle_status = "Proceeding to \the [shuttle.get_destination_name()]."
if(WAIT_FINISH)
diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm
index f6efaa4a8645..f78010c50559 100644
--- a/code/modules/shuttles/shuttle_emergency.dm
+++ b/code/modules/shuttles/shuttle_emergency.dm
@@ -201,7 +201,7 @@
else
shuttle_status = "Standing-by at [global.using_map.dock_name]."
if(WAIT_LAUNCH, FORCE_LAUNCH)
- shuttle_status = "Shuttle has recieved command and will depart shortly."
+ shuttle_status = "Shuttle has received command and will depart shortly."
if(WAIT_ARRIVE)
shuttle_status = "Proceeding to destination."
if(WAIT_FINISH)
diff --git a/code/modules/shuttles/shuttle_ferry.dm b/code/modules/shuttles/shuttle_ferry.dm
index ebe0a7cf54f6..020d8c670c9c 100644
--- a/code/modules/shuttles/shuttle_ferry.dm
+++ b/code/modules/shuttles/shuttle_ferry.dm
@@ -63,4 +63,4 @@
if(initial(waypoint_offsite))
return "The offsite waypoint landmark (tag: [initial(waypoint_offsite)]) was not found."
else
- return "A offsite waypoint was not properly set."
\ No newline at end of file
+ return "An offsite waypoint was not properly set."
\ No newline at end of file
diff --git a/code/modules/shuttles/shuttle_log.dm b/code/modules/shuttles/shuttle_log.dm
index 03d6fe0f3070..b4cf0a2d7b57 100644
--- a/code/modules/shuttles/shuttle_log.dm
+++ b/code/modules/shuttles/shuttle_log.dm
@@ -6,7 +6,7 @@
var/list/datum/shuttle_mission/queued_missions = list() //Missions which are queued up, in order ([1] is the next one scheduled).
var/datum/shuttle_mission/current_mission //The current mission, planned or ongoing. Will also be in either missions or queued_missions, depending on stage.
var/home_base //The landmark tag from which missions originate.
- var/list/datum/nano_module/registered = list() //Nanomodules using logs should register to recieve updates.
+ var/list/datum/nano_module/registered = list() //Nanomodules using logs should register to receive updates.
var/last_spam = 0 //Helps with spam control from deck software.
/datum/shuttle_log/New(datum/shuttle/given_shuttle)
@@ -17,7 +17,7 @@
SSshuttle.shuttle_logs[given_shuttle] = src
/datum/shuttle_log/Destroy()
- update_registred()
+ update_registered()
registered = null
current_mission = null
QDEL_NULL_LIST(missions)
@@ -30,7 +30,7 @@
/datum/shuttle_log/proc/unregister(datum/nano_module/module)
registered -= module
-/datum/shuttle_log/proc/update_registred()
+/datum/shuttle_log/proc/update_registered()
for(var/datum/nano_module/module in registered)
SSnano.update_uis(module)
@@ -49,7 +49,7 @@
qdel(old_report)
new_report.mission.set_value(mission.name)
mission.other_reports += report
- update_registred()
+ update_registered()
return 1
/datum/shuttle_log/proc/process_queue()
@@ -64,7 +64,7 @@
if(!current_mission && length(queued_missions))
current_mission = queued_missions[1]
current_mission.stage = SHUTTLE_MISSION_PLANNED
- update_registred()
+ update_registered()
/datum/shuttle_log/proc/create_mission(name)
var/datum/shuttle_mission/mission = new()
@@ -85,7 +85,7 @@
mission.name = name
for(var/datum/computer_file/report/recipient/shuttle/report in mission.other_reports)
report.mission.set_value(name)
- update_registred()
+ update_registered()
//Only missions that haven't started can be deleted; returns 0 on failure.
/datum/shuttle_log/proc/delete_mission(datum/shuttle_mission/mission)
diff --git a/code/modules/species/outsider/random.dm b/code/modules/species/outsider/random.dm
deleted file mode 100644
index af9094b53cae..000000000000
--- a/code/modules/species/outsider/random.dm
+++ /dev/null
@@ -1,142 +0,0 @@
-/decl/bodytype/alium
- name = "humanoid"
- bodytype_category = BODYTYPE_HUMANOID
- icon_base = 'icons/mob/human_races/species/humanoid/body.dmi'
- bandages_icon = 'icons/mob/bandage.dmi'
- limb_blend = ICON_MULTIPLY
- appearance_flags = HAS_SKIN_COLOR
- body_flags = BODY_FLAG_NO_DNA | BODY_FLAG_NO_DEFIB | BODY_FLAG_NO_STASIS
- uid = "bodytype_alium"
-
-/decl/bodytype/alium/Initialize()
- if(prob(10))
- movement_slowdown += pick(-1,1)
- if(prob(5))
- body_flags |= BODY_FLAG_NO_PAIN
- base_color = RANDOM_RGB
- MULT_BY_RANDOM_COEF(eye_flash_mod, 0.5, 1.5)
- eye_darksight_range = rand(1,8)
- var/temp_comfort_shift = rand(-50,50)
- cold_level_1 += temp_comfort_shift
- cold_level_2 += temp_comfort_shift
- cold_level_3 += temp_comfort_shift
- heat_level_1 += temp_comfort_shift
- heat_level_2 += temp_comfort_shift
- heat_level_3 += temp_comfort_shift
- heat_discomfort_level += temp_comfort_shift
- cold_discomfort_level += temp_comfort_shift
- . = ..()
-
-/decl/species/alium
- name = SPECIES_ALIEN
- name_plural = "Humanoids"
- description = "Some alien humanoid species, unknown to humanity. How exciting."
- rarity_value = 5
- hidden_from_codex = TRUE
-
- spawn_flags = SPECIES_IS_RESTRICTED
-
- available_bodytypes = list(/decl/bodytype/alium)
-
- force_background_info = list(
- /decl/background_category/heritage = /decl/background_detail/heritage/hidden/alium
- )
-
- exertion_effect_chance = 10
- exertion_hydration_scale = 1
- exertion_reagent_scale = 1
- exertion_reagent_path = /decl/material/liquid/lactate
- exertion_emotes_biological = list(
- /decl/emote/exertion/biological,
- /decl/emote/exertion/biological/breath,
- /decl/emote/exertion/biological/pant
- )
- var/blood_color
-
-/decl/species/alium/Initialize()
-
- //Coloring
- blood_color = RANDOM_RGB
- flesh_color = RANDOM_RGB
-
- //Combat stats
- MULT_BY_RANDOM_COEF(total_health, 0.8, 1.2)
- MULT_BY_RANDOM_COEF(brute_mod, 0.5, 1.5)
- MULT_BY_RANDOM_COEF(burn_mod, 0.8, 1.2)
- MULT_BY_RANDOM_COEF(oxy_mod, 0.5, 1.5)
- MULT_BY_RANDOM_COEF(toxins_mod, 0, 2)
- MULT_BY_RANDOM_COEF(radiation_mod, 0, 2)
-
- if(brute_mod < 1 && prob(40))
- species_flags |= SPECIES_FLAG_NO_MINOR_CUT
- if(brute_mod < 0.9 && prob(40))
- species_flags |= SPECIES_FLAG_NO_EMBED
- if(toxins_mod < 0.1)
- species_flags |= SPECIES_FLAG_NO_POISON
-
- //Gastronomic traits
- taste_sensitivity = pick(TASTE_HYPERSENSITIVE, TASTE_SENSITIVE, TASTE_DULL, TASTE_NUMB)
- gluttonous = pick(0, GLUT_TINY, GLUT_SMALLER, GLUT_ANYTHING)
- stomach_capacity = 5 * stomach_capacity
- if(prob(20))
- gluttonous |= pick(GLUT_ITEM_TINY, GLUT_ITEM_NORMAL, GLUT_ITEM_ANYTHING, GLUT_PROJECTILE_VOMIT)
- if(gluttonous & GLUT_ITEM_ANYTHING)
- stomach_capacity += ITEM_SIZE_HUGE
-
- //Environment
- var/temp_comfort_shift = rand(-50,50)
- body_temperature += temp_comfort_shift
-
- var/pressure_comfort_shift = rand(-50,50)
- hazard_high_pressure += pressure_comfort_shift
- warning_high_pressure += pressure_comfort_shift
- warning_low_pressure += pressure_comfort_shift
- hazard_low_pressure += pressure_comfort_shift
-
- //Misc traits
- if(prob(40))
- available_pronouns = list(/decl/pronouns)
- if(prob(10))
- species_flags |= SPECIES_FLAG_NO_SLIP
- if(prob(10))
- species_flags |= SPECIES_FLAG_NO_TANGLE
-
- . = ..()
-
-/decl/species/alium/get_species_blood_color(mob/living/human/H)
- if(istype(H) && H.isSynthetic())
- return ..()
- return blood_color
-
-/obj/structure/aliumizer
- name = "alien monolith"
- desc = "Your true form is calling. Use this to become an alien humanoid."
- icon = 'icons/obj/xenoarchaeology.dmi'
- icon_state = "ano51"
- anchored = TRUE
-
-/obj/structure/aliumizer/attack_hand(mob/user)
- SHOULD_CALL_PARENT(FALSE)
- if(!ishuman(user))
- to_chat(user, SPAN_WARNING("You've got no business touching this."))
- return TRUE
- var/decl/species/species = user.get_species()
- if(!species)
- return TRUE
- if(species.name == SPECIES_ALIEN)
- to_chat(user, SPAN_WARNING("You're already a [SPECIES_ALIEN]."))
- return TRUE
- if(alert("Are you sure you want to be an alien?", "Mom Look I'm An Alien!", "Yes", "No") == "No")
- to_chat(user, SPAN_NOTICE("You are now a [SPECIES_ALIEN]!"))
- return TRUE
- if(species.name == SPECIES_ALIEN) //no spamming it to get free implants
- return TRUE
- to_chat(user, "You're now an alien humanoid of some undiscovered species. Make up what lore you want, no one knows a thing about your species! You can check info about your traits with Check Species Info verb in IC tab.")
- to_chat(user, "You can't speak any other languages by default. You can use translator implant that spawns on top of this monolith - it will give you knowledge of any language if you hear it enough times.")
- var/mob/living/human/H = user
- new /obj/item/implanter/translator(get_turf(src))
- H.change_species(SPECIES_ALIEN)
- var/decl/background_detail/background = H.get_background_datum_by_flag(BACKGROUND_FLAG_NAMING)
- H.fully_replace_character_name(background.get_random_name(H, H.gender))
- H.rename_self("Humanoid Alien", 1)
- return TRUE
diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm
index 6ef37bd2681e..82e201d287f5 100644
--- a/code/modules/species/species.dm
+++ b/code/modules/species/species.dm
@@ -176,7 +176,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200
var/list/base_auras
- var/job_skill_buffs = list() // A list containing jobs (/datum/job), with values the extra points that job recieves.
+ var/job_skill_buffs = list() // A list containing jobs (/datum/job), with values the extra points that job receives.
var/standing_jump_range = 2
var/list/maneuvers = list(/decl/maneuver/leap)
@@ -608,7 +608,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200
return
var/randn = rand(1, 100) - skill_mod + state_mod
- if(!(check_no_slip(target)) && randn <= 25)
+ if(!target.can_slip() && randn <= 25)
var/armor_check = 100 * target.get_blocked_ratio(affecting, BRUTE, damage = 20)
target.apply_effect(push_mod, WEAKEN, armor_check)
playsound(target.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
@@ -668,8 +668,8 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200
if(31 to 45) . = 4
else . = 8
-/decl/species/proc/check_no_slip(var/mob/living/human/H)
- if(can_overcome_gravity(H))
+/decl/species/proc/check_no_slip(mob/living/user, magboots_only)
+ if(can_overcome_gravity(user))
return TRUE
return (species_flags & SPECIES_FLAG_NO_SLIP)
diff --git a/code/modules/species/species_hud.dm b/code/modules/species/species_hud.dm
index 7add078db3ac..6c67caea5d24 100644
--- a/code/modules/species/species_hud.dm
+++ b/code/modules/species/species_hud.dm
@@ -1,25 +1,4 @@
/datum/hud_data
-
- /// Set to draw move intent box.
- var/has_m_intent = 1
- /// Set to draw environment warnings.
- var/has_warnings = 1
- /// Draw the pressure indicator.
- var/has_pressure = 1
- /// Draw the nutrition indicator.
- var/has_nutrition = 1
- /// Draw the bodytemp indicator.
- var/has_bodytemp = 1
- /// Set to draw drop button.
- var/has_drop = 1
- /// Set to draw throw button.
- var/has_throw = 1
- /// Set to draw resist button.
- var/has_resist = 1
- /// Set to draw the internals toggle button.
- var/has_internals = 1
- /// Set to draw the "look-up" hint icon
- var/has_up_hint = 1
/// Checked by mob_can_equip().
var/list/equip_slots = list()
/// Built in New(), used for unhidable inv updates
diff --git a/code/modules/surgery/crystal.dm b/code/modules/surgery/crystal.dm
index b607c915c263..39ec4770a456 100644
--- a/code/modules/surgery/crystal.dm
+++ b/code/modules/surgery/crystal.dm
@@ -1,6 +1,6 @@
/decl/surgery_step/generic/cut_open/crystal
name = "Drill keyhole incision"
- description = "This procedure drills a keyhold incision into crystalline limbs to allow for delicate internal work."
+ description = "This procedure drills a keyhole incision into crystalline limbs to allow for delicate internal work."
allowed_tools = list(TOOL_SURGICAL_DRILL = 100)
fail_string = "cracking"
access_string = "a neat hole"
diff --git a/code/modules/synthesized_instruments/real_instruments.dm b/code/modules/synthesized_instruments/real_instruments.dm
index 9324dc19c50f..b3cd8c900e2b 100644
--- a/code/modules/synthesized_instruments/real_instruments.dm
+++ b/code/modules/synthesized_instruments/real_instruments.dm
@@ -18,11 +18,11 @@
maximum_line_length = global.musical_config.max_line_length
instruments = istype(what) ? list(what) : what
-/datum/real_instrument/proc/Topic_call(href, href_list, usr)
+/datum/real_instrument/proc/OnTopic(mob/user, href_list)
var/target = href_list["target"]
var/value = text2num(href_list["value"])
if (href_list["value"] && !isnum(value))
- to_chat(usr, "Non-numeric value was given.")
+ to_chat(user, "Non-numeric value was given.")
return 0
@@ -31,20 +31,20 @@
if ("play")
src.player.song.playing = value
if (src.player.song.playing)
- src.player.song.play_song(usr)
+ src.player.song.play_song(user)
if ("newsong")
src.player.song.lines.Cut()
src.player.song.tempo = src.player.song.sanitize_tempo(5) // default 120 BPM
if ("import")
var/t = ""
do
- t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", owner.name), t) as message)
- if(!CanInteractWith(usr, owner, global.physical_topic_state))
+ t = html_encode(input(user, "Please paste the entire song, formatted:", text("[]", owner.name), t) as message)
+ if(!CanInteractWith(user, owner, global.physical_topic_state))
return
if(length(t) >= 2*src.maximum_lines*src.maximum_line_length)
- var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
- if(!CanInteractWith(usr, owner, global.physical_topic_state))
+ var/cont = input(user, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
+ if(!CanInteractWith(user, owner, global.physical_topic_state))
return
if(cont == "no")
break
@@ -60,24 +60,24 @@
else
src.player.song.tempo = src.player.song.sanitize_tempo(5) // default 120 BPM
if(src.player.song.lines.len > maximum_lines)
- to_chat(usr,"Too many lines!")
+ to_chat(user,"Too many lines!")
src.player.song.lines.Cut(maximum_lines+1)
var/linenum = 1
for(var/l in src.player.song.lines)
if(length(l) > maximum_line_length)
- to_chat(usr, "Line [linenum] too long!")
+ to_chat(user, "Line [linenum] too long!")
src.player.song.lines.Remove(l)
else
linenum++
if ("show_song_editor")
if (!src.song_editor)
src.song_editor = new (host = src.owner, song = src.player.song)
- src.song_editor.ui_interact(usr)
+ src.song_editor.ui_interact(user)
if ("show_usage")
if (!src.usage_info)
src.usage_info = new (owner, src.player)
- src.usage_info.ui_interact(usr)
+ src.usage_info.ui_interact(user)
if ("volume")
src.player.volume = min(max(min(player.volume+text2num(value), 100), 0), player.max_volume)
if ("transposition")
@@ -91,8 +91,8 @@
if ("sustain_timer")
src.player.song.sustain_timer = max(min(player.song.sustain_timer+value, global.musical_config.longest_sustain_timer), 1)
if ("soft_coeff")
- var/new_coeff = input(usr, "from [global.musical_config.gentlest_drop] to [global.musical_config.steepest_drop]") as num
- if(!CanInteractWith(usr, owner, global.physical_topic_state))
+ var/new_coeff = input(user, "from [global.musical_config.gentlest_drop] to [global.musical_config.steepest_drop]") as num
+ if(!CanInteractWith(user, owner, global.physical_topic_state))
return
new_coeff = round(min(max(new_coeff, global.musical_config.gentlest_drop), global.musical_config.steepest_drop), 0.001)
src.player.song.soft_coeff = new_coeff
@@ -102,8 +102,8 @@
var/datum/instrument/instrument = instruments[key]
categories |= instrument.category
- var/category = input(usr, "Choose a category") as null|anything in categories
- if(!CanInteractWith(usr, owner, global.physical_topic_state))
+ var/category = input(user, "Choose a category") as null|anything in categories
+ if(!CanInteractWith(user, owner, global.physical_topic_state))
return
var/list/instruments_available = list()
for (var/key in instruments)
@@ -111,8 +111,8 @@
if (instrument.category == category)
instruments_available += key
- var/new_instrument = input(usr, "Choose an instrument") as null|anything in instruments_available
- if(!CanInteractWith(usr, owner, global.physical_topic_state))
+ var/new_instrument = input(user, "Choose an instrument") as null|anything in instruments_available
+ if(!CanInteractWith(user, owner, global.physical_topic_state))
return
if (new_instrument)
src.player.song.instrument_data = instruments[new_instrument]
@@ -123,14 +123,14 @@
if (global.musical_config.env_settings_available)
if (!src.env_editor)
src.env_editor = new (src.player)
- src.env_editor.ui_interact(usr)
+ src.env_editor.ui_interact(user)
else
- to_chat(usr, "Virtual environment is disabled.")
+ to_chat(user, "Virtual environment is disabled.")
if ("show_echo_editor")
if (!src.echo_editor)
src.echo_editor = new (src.player)
- src.echo_editor.ui_interact(usr)
+ src.echo_editor.ui_interact(user)
if ("select_env")
if (value in -1 to 26)
@@ -239,11 +239,8 @@
return 0
-/obj/structure/synthesized_instrument/Topic(href, href_list)
- if (..())
- return 1
-
- return real_instrument.Topic_call(href, href_list, usr)
+/obj/structure/synthesized_instrument/OnTopic(mob/user, href_list)
+ return ..() || real_instrument.OnTopic(user, href_list)
////////////////////////
@@ -291,10 +288,7 @@
/obj/item/synthesized_instrument/proc/shouldStopPlaying(mob/user)
- return !(src && in_range(src, user))
-
-/obj/item/synthesized_instrument/Topic(href, href_list)
- if (..())
- return 1
+ return src && CanPhysicallyInteract(user)
- return real_instrument.Topic_call(href, href_list, usr)
\ No newline at end of file
+/obj/item/synthesized_instrument/OnTopic(mob/user, href_list)
+ return ..() || real_instrument.OnTopic(user, href_list)
\ No newline at end of file
diff --git a/code/modules/synthesized_instruments/real_instruments/Trumpet/trumpet.dm b/code/modules/synthesized_instruments/real_instruments/Trumpet/trumpet.dm
index ef2caaa8bb4d..6f275ac25217 100644
--- a/code/modules/synthesized_instruments/real_instruments/Trumpet/trumpet.dm
+++ b/code/modules/synthesized_instruments/real_instruments/Trumpet/trumpet.dm
@@ -1,6 +1,6 @@
/obj/item/synthesized_instrument/trumpet
name = "Omnitrumpet"
- desc = "The Omnitrumptet series 400 with more than 30 sound samples and fully customizable high fidelity output provides the ultimate means to toot your own horn"
+ desc = "The Omnitrumpet series 400 with more than 30 sound samples and fully customizable high fidelity output provides the ultimate means to toot your own horn"
icon_state = "trumpet"
sound_player = /datum/sound_player/synthesizer
path = /datum/instrument/brass
diff --git a/code/modules/tools/subtypes/hammers.dm b/code/modules/tools/subtypes/hammers.dm
index ff5d1ef19892..acd258ef5c08 100644
--- a/code/modules/tools/subtypes/hammers.dm
+++ b/code/modules/tools/subtypes/hammers.dm
@@ -84,6 +84,10 @@
icon = 'icons/obj/items/tool/hammers/forge.dmi'
w_class = ITEM_SIZE_NORMAL
+/obj/item/tool/hammer/forge/iron
+ material = /decl/material/solid/metal/iron
+ handle_material = /decl/material/solid/organic/wood/mahogany
+
// Forging hammers are not great at general hammer tasks (too heavy I guess),
// and also don't work as crowbars due to missing the nail ripper/flange,
// but will be more effective at forging when blacksmithy is merged.
diff --git a/code/modules/tools/subtypes/power_tools.dm b/code/modules/tools/subtypes/power_tools.dm
index a0b0867a3b74..84099987a3e4 100644
--- a/code/modules/tools/subtypes/power_tools.dm
+++ b/code/modules/tools/subtypes/power_tools.dm
@@ -1,6 +1,6 @@
/obj/item/tool/hydraulic_cutter
name = "hydraulic cutter"
- desc = "A universal, miniturized hydraulic tool with interchangable heads for either prying or cutting. But not both at the same time."
+ desc = "A universal, miniaturized hydraulic tool with interchangeable heads for either prying or cutting. But not both at the same time."
icon = 'icons/obj/items/tool/cutter.dmi'
icon_state = ICON_STATE_WORLD
slot_flags = SLOT_LOWER_BODY
diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm
index 62606d2626bc..4a61ea40daac 100644
--- a/code/modules/vehicles/cargo_train.dm
+++ b/code/modules/vehicles/cargo_train.dm
@@ -1,6 +1,6 @@
/obj/vehicle/train/cargo/engine
name = "cargo train tug"
- desc = "A ridable electric car designed for pulling cargo trolleys."
+ desc = "A rideable electric car designed for pulling cargo trolleys."
icon = 'icons/obj/vehicles.dmi'
icon_state = "cargo_engine"
on = 0
diff --git a/code/modules/xenoarcheaology/finds/strange_rock.dm b/code/modules/xenoarcheaology/finds/strange_rock.dm
index 7f0713988ff5..5e2c8770e9c6 100644
--- a/code/modules/xenoarcheaology/finds/strange_rock.dm
+++ b/code/modules/xenoarcheaology/finds/strange_rock.dm
@@ -1,7 +1,7 @@
/obj/item/strangerock
name = "strange rock"
- desc = "Seems to have some unusal strata evident throughout it."
+ desc = "Seems to have some unusual strata evident throughout it."
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "strange"
origin_tech = @'{"materials":5}'
diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm
index 2f03eb9da320..a131d1ee7bdc 100644
--- a/code/unit_tests/mob_tests.dm
+++ b/code/unit_tests/mob_tests.dm
@@ -65,7 +65,7 @@
test_result["msg"] = "Unable to find a location to create test mob"
return test_result
- var/mob/living/human/H = new mobtype(mobloc)
+ var/mob/living/human/H = new mobtype(mobloc, SPECIES_HUMAN) // force human for testing
H.mind_initialize("TestKey[rand(0,10000)]")
diff --git a/code/unit_tests/zas_tests.dm b/code/unit_tests/zas_tests.dm
index 7866c78bd62a..a3a236167d57 100644
--- a/code/unit_tests/zas_tests.dm
+++ b/code/unit_tests/zas_tests.dm
@@ -99,7 +99,7 @@
/// Here we move a shuttle then test it's area once the shuttle has arrived.
/datum/unit_test/zas_supply_shuttle_moved
name = "ZAS: Supply Shuttle (When Moved)"
- async = TRUE // We're moving the shuttle using built in procs.
+ async = TRUE // We're moving the shuttle using built-in procs.
///The shuttle datum of the supply shuttle
var/datum/shuttle/autodock/ferry/supply/shuttle = null
diff --git a/html/changelog.html b/html/changelog.html
index 23cae88f2087..2c838c27eee2 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -52,6 +52,12 @@
-->
+
29 January 2025
+
MistakeNot4892 updated:
+
+ - Various map changes to Bearcat, crashed pod, and several others. Please report issues!
+
+
22 January 2025
MistakeNot4892 updated: