diff --git a/code/_helpers/emissive.dm b/code/_helpers/emissive.dm
index 4ea0ca7e7cf3..98cde2aadb31 100644
--- a/code/_helpers/emissive.dm
+++ b/code/_helpers/emissive.dm
@@ -1,5 +1,6 @@
-/proc/emissive_overlay(var/icon, var/icon_state, var/loc, var/dir, var/color)
+/proc/emissive_overlay(icon, icon_state, loc, dir, color, flags)
var/image/I = image(icon, loc, icon_state, EMISSIVE_LAYER, dir)
I.plane = EMISSIVE_PLANE
I.color = color
+ I.appearance_flags |= flags
return I
diff --git a/code/_helpers/time.dm b/code/_helpers/time.dm
index a59873ee3308..f53718da51be 100644
--- a/code/_helpers/time.dm
+++ b/code/_helpers/time.dm
@@ -85,7 +85,7 @@ var/global/round_start_time = 0
out += "[seconds] second\s"
if(length(out))
return english_list(out)
- return null
+ return "less than a second"
/proc/roundduration2text()
if(!round_start_time)
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index 45dc05bd2c83..32eac707ce72 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -719,11 +719,8 @@ Turf and target are seperate in case you want to teleport some distance from a t
/obj/item/weldingtool/can_puncture()
return 1
-/obj/item/screwdriver/can_puncture()
- return 1
-
/obj/item/clothing/mask/smokable/cigarette/can_puncture()
- return src.lit
+ return ..() || lit // in case someone has a sharp cigarette for some reason
/*
Checks if that loc and dir has a item on the wall
diff --git a/code/_helpers/visual_filters.dm b/code/_helpers/visual_filters.dm
index ad1fc9104209..10e485e18543 100644
--- a/code/_helpers/visual_filters.dm
+++ b/code/_helpers/visual_filters.dm
@@ -52,8 +52,8 @@
LAZYREMOVE(filter_data, filter_name)
filters -= thing
update_filters()
- return FALSE
- return TRUE
+ return TRUE
+ return FALSE
/// Animate a given filter on this atom. All params after the first are passed to animate().
/atom/movable/proc/animate_filter(filter_name, list/params)
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 8c32d898a185..8fa2950b1b9e 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -116,11 +116,6 @@
var/sdepth = A.storage_depth(src)
if((!isturf(A) && A == loc) || (sdepth != -1 && sdepth <= 1))
if(holding)
-
- // AI driven mobs have a melee telegraph that needs to be handled here.
- if(check_intent(I_FLAG_HARM) && istype(A) && (!do_attack_windup_checking(A) || holding != get_active_held_item()))
- return TRUE
-
var/resolved = holding.resolve_attackby(A, src, params)
if(!resolved && A && holding)
holding.afterattack(A, src, 1, params) // 1 indicates adjacency
@@ -143,10 +138,6 @@
if(A.Adjacent(src)) // see adjacent.dm
if(holding)
- // AI driven mobs have a melee telegraph that needs to be handled here.
- if(check_intent(I_FLAG_HARM) && istype(A) && (!do_attack_windup_checking(A) || holding != get_active_held_item()))
- return TRUE
-
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
var/resolved = holding.resolve_attackby(A, src, params)
if(!resolved && A && holding)
@@ -217,18 +208,7 @@
if(istype(G) && G.Touch(A,1))
return TRUE
- // Pick up items.
- if(check_dexterity(DEXTERITY_HOLD_ITEM, silent = TRUE))
- return A.attack_hand(src)
-
- // TODO: some way to check if we SHOULD be doing an attack windup here;
- // corgis attacking a tree, for example, will do the windup animation despite
- // having no interaction or message shown at the end of it.
- // AI driven mobs have a melee telegraph that needs to be handled here.
- if(check_intent(I_FLAG_HARM) && istype(A) && !do_attack_windup_checking(A))
- return TRUE
-
- return FALSE
+ return A.attack_hand(src)
/*
Ranged unarmed attack:
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index 6debf2726ddb..de135d672c0d 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -8,9 +8,15 @@
/atom/proc/can_interact_with_storage(user, strict = FALSE)
return isliving(user)
+/atom/proc/get_required_interaction_dexterity()
+ return DEXTERITY_NONE
+
/atom/proc/attack_hand(mob/user)
SHOULD_CALL_PARENT(TRUE)
+ if(!user.check_dexterity(get_required_interaction_dexterity(), silent = TRUE))
+ return FALSE
+
if(can_interact_with_storage(user, strict = TRUE) && storage && user.check_dexterity((DEXTERITY_HOLD_ITEM|DEXTERITY_EQUIP_ITEM), TRUE))
add_fingerprint(user)
storage.open(user)
diff --git a/code/controllers/subsystems/ambience.dm b/code/controllers/subsystems/ambience.dm
index ad9d2a1c52b4..757f846c6402 100644
--- a/code/controllers/subsystems/ambience.dm
+++ b/code/controllers/subsystems/ambience.dm
@@ -63,10 +63,23 @@ SUBSYSTEM_DEF(ambience)
// Grab what we need to set ambient light from our level handler.
var/datum/level_data/level_data = SSmapping.levels_by_z[z]
+ var/daycycle_id = level_data.daycycle_id
+ // if we don't have a daycycle ourselves, and we're indoors because of a turf blocking us
+ // find the first daycycle above us to use
+ if(!outsideness && !daycycle_id && HasAbove(z))
+ var/turf/above = src
+ var/datum/level_data/above_level_data
+ while ((above = GetAbove(above)))
+ if((above.z_flags & ZM_TERMINATOR) || !HasAbove(above.z))
+ break
+ above_level_data = SSmapping.levels_by_z[above.z]
+ if(above_level_data.daycycle_id)
+ daycycle_id = above_level_data.daycycle_id
+ break
// Check for daycycle ambience.
- if(level_data.daycycle_id)
- var/datum/daycycle/daycycle = SSdaycycle.get_daycycle(level_data.daycycle_id)
+ if(daycycle_id)
+ var/datum/daycycle/daycycle = SSdaycycle.get_daycycle(daycycle_id)
var/new_power = daycycle?.current_period?.power
if(!isnull(new_power))
if(new_power > 0)
diff --git a/code/controllers/subsystems/initialization/modpacks.dm b/code/controllers/subsystems/initialization/modpacks.dm
index 5fad4ec549cb..f2f6c65a2e69 100644
--- a/code/controllers/subsystems/initialization/modpacks.dm
+++ b/code/controllers/subsystems/initialization/modpacks.dm
@@ -7,6 +7,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/modpack_nanoui_directories = list()
/datum/controller/subsystem/modpacks/Initialize()
var/list/all_modpacks = decls_repository.get_decls_of_subtype(/decl/modpack)
diff --git a/code/datums/ai/aggressive.dm b/code/datums/ai/aggressive.dm
index e50d4e124ae0..505017dbc0c9 100644
--- a/code/datums/ai/aggressive.dm
+++ b/code/datums/ai/aggressive.dm
@@ -90,10 +90,14 @@
return TRUE
/datum/mob_controller/aggressive/proc/attack_target()
+
+ set waitfor = FALSE
+
var/atom/target = get_target()
if(!istype(target))
lose_target()
return
+
if(isliving(target) && body.buckled_mob == target && (!body.faction || body.buckled_mob.faction != body.faction))
body.visible_message(SPAN_DANGER("\The [body] attempts to unseat \the [body.buckled_mob]!"))
body.set_dir(pick(global.cardinal))
@@ -105,11 +109,21 @@
var/mob/living/victim = target
SET_STATUS_MAX(victim, STAT_WEAK, 3)
return target
- if(body.Adjacent(target))
- body.set_intent(I_FLAG_HARM)
- body.ClickOn(target)
+
+ if(!body.Adjacent(target))
+ return target
+
+ // AI-driven mobs have a melee telegraph that needs to be handled here.
+ if(!body.do_attack_windup_checking(target))
return target
+ if(QDELETED(body) || body.incapacitated() || QDELETED(target))
+ return target
+
+ body.set_intent(I_FLAG_HARM)
+ body.ClickOn(target)
+ return target
+
/datum/mob_controller/aggressive/destroy_surroundings()
if(!body.can_act())
@@ -172,27 +186,25 @@
if(!(. = ..()))
return
- if(!only_attack_enemies)
- if(source)
- set_target(source)
- move_to_target(move_only = TRUE)
- return
-
- var/list/allies
- var/list/around = view(body, 7)
- for(var/atom/movable/A in around)
- if(A == body || !isliving(A))
- continue
- var/mob/living/M = A
- if(attack_same_faction || M.faction != body.faction)
- add_enemy(M)
- else if(istype(M.ai))
- LAZYADD(allies, M.ai)
-
- var/list/enemies = get_enemies()
- if(LAZYLEN(enemies) && LAZYLEN(allies))
- for(var/datum/mob_controller/ally as anything in allies)
- ally.add_enemies(enemies)
+ if(only_attack_enemies)
+ var/list/allies
+ var/list/around = view(body, 7)
+ for(var/atom/movable/A in around)
+ if(A == body || !isliving(A))
+ continue
+ var/mob/living/M = A
+ if(attack_same_faction || M.faction != body.faction)
+ add_enemy(M)
+ else if(istype(M.ai))
+ LAZYADD(allies, M.ai)
+ var/list/enemies = get_enemies()
+ if(LAZYLEN(enemies) && LAZYLEN(allies))
+ for(var/datum/mob_controller/ally as anything in allies)
+ ally.add_enemies(enemies)
+
+ if(source)
+ set_target(source)
+ move_to_target(move_only = TRUE)
/datum/mob_controller/aggressive/move_to_target(var/move_only = FALSE)
if(!body.can_act())
diff --git a/code/datums/communication/dsay.dm b/code/datums/communication/dsay.dm
index c21705a672eb..273f17a36b74 100644
--- a/code/datums/communication/dsay.dm
+++ b/code/datums/communication/dsay.dm
@@ -61,12 +61,8 @@
keyname = C.key
if(C.mob) //Most of the time this is the dead/observer mob; we can totally use him if there is no better name
- var/mindname
+ var/mindname = C.mob.mind?.name // the mind's "original name"
var/realname = C.mob.real_name
- if(C.mob.mind)
- mindname = C.mob.mind.name
- if(C.mob.mind.original && C.mob.mind.original.real_name)
- realname = C.mob.mind.original.real_name
if(mindname && mindname != realname)
name = "[realname] died as [mindname]"
else
diff --git a/code/datums/datum.dm b/code/datums/datum.dm
index 0fbfeaf0232b..a0aeed07808d 100644
--- a/code/datums/datum.dm
+++ b/code/datums/datum.dm
@@ -111,10 +111,3 @@
*/
/datum/proc/PopulateClone(var/datum/clone)
return clone
-
-/////////////////////////////////////////////////////////////
-//Common implementations
-/////////////////////////////////////////////////////////////
-
-/image/GetCloneArgs()
- return list(icon, loc, icon_state, layer, dir)
\ No newline at end of file
diff --git a/code/datums/extensions/abilities/abilities_predator.dm b/code/datums/extensions/abilities/abilities_predator.dm
index 025a1c0e05e3..066a3feac920 100644
--- a/code/datums/extensions/abilities/abilities_predator.dm
+++ b/code/datums/extensions/abilities/abilities_predator.dm
@@ -5,12 +5,26 @@
return istype(user) && !user.incapacitated() && isatom(target) && target.Adjacent(user)
/datum/ability_handler/predator/do_melee_invocation(mob/user, atom/target)
- // Nibbles
+
+ // Nibbles!
if(user.check_intent(I_FLAG_HARM))
if(isliving(target))
return handle_dismemberment(user, target)
if(istype(target, /obj/item/organ))
return handle_organ_destruction(user, target)
+
+ // Digging!
+ var/static/list/diggable_types = list(
+ /turf/floor,
+ /turf/wall,
+ /obj/structure/pit,
+ /obj/machinery/portable_atmospherics/hydroponics/soil
+ )
+ if(is_type_in_list(target, diggable_types))
+ var/obj/item/organ/external/paw = user.get_usable_hand_slot_organ()
+ if(paw)
+ return target.attackby(paw, user)
+
return FALSE
/datum/ability_handler/predator/proc/handle_organ_destruction(mob/user, obj/item/organ/chewtoy)
diff --git a/code/datums/extensions/milkable/milkable.dm b/code/datums/extensions/milkable/milkable.dm
index debc42f48536..523a37e3e533 100644
--- a/code/datums/extensions/milkable/milkable.dm
+++ b/code/datums/extensions/milkable/milkable.dm
@@ -8,6 +8,10 @@
var/milk_min = 5
var/milk_max = 10
+ var/cream_type = /decl/material/liquid/drink/milk/cream
+ var/cream_min = 2
+ var/cream_max = 5
+
var/impatience = 0
var/decl/skill/milking_skill = SKILL_BOTANY
var/milking_skill_req = SKILL_BASIC
@@ -42,9 +46,16 @@
create_milk()
/datum/extension/milkable/proc/create_milk()
- var/create_milk = min(rand(milk_min, milk_max), REAGENTS_FREE_SPACE(udder))
- if(create_milk > 0)
- udder.add_reagent(milk_type, create_milk, get_milk_data())
+
+ var/create_milk = min(rand(milk_min, milk_max), REAGENTS_FREE_SPACE(udder))
+ var/create_cream = min(rand(cream_min, cream_max), REAGENTS_FREE_SPACE(udder) - create_milk)
+
+ if(create_milk <= 0 && create_cream <= 0)
+ return
+
+ var/list/milk_data = get_milk_data()
+ udder.add_reagent(milk_type, create_milk, milk_data)
+ udder.add_reagent(cream_type, create_cream, milk_data)
/datum/extension/milkable/proc/get_milk_data()
var/static/list/milk_data = list(
@@ -113,7 +124,7 @@
SPAN_NOTICE("\The [user] milks \the [critter] into \the [container]."),
SPAN_NOTICE("You milk \the [critter] into \the [container].")
)
- udder.trans_type_to(container, milk_type, min(REAGENTS_FREE_SPACE(container.reagents), rand(15, 20)))
+ udder.trans_to(container, min(REAGENTS_FREE_SPACE(container.reagents), rand(15, 20)))
return TRUE
/datum/extension/milkable/proc/handle_milking_failure(mob/user, mob/living/critter)
diff --git a/code/datums/inventory_slots/_inventory_slot.dm b/code/datums/inventory_slots/_inventory_slot.dm
index 204284e6f2cc..6f23b1b51a10 100644
--- a/code/datums/inventory_slots/_inventory_slot.dm
+++ b/code/datums/inventory_slots/_inventory_slot.dm
@@ -19,6 +19,8 @@
var/requires_slot_flags
var/requires_organ_tag
var/quick_equip_priority = 0 // Higher priority means it will be checked first. If null, will not be considered for quick equip.
+ /// What depth of fluid is necessary for an item in this slot to be considered submerged?
+ var/fluid_height = FLUID_SHALLOW // we're treating FLUID_SHALLOW as waist level, basically
var/mob_overlay_layer
var/alt_mob_overlay_layer
diff --git a/code/datums/inventory_slots/inventory_gripper.dm b/code/datums/inventory_slots/inventory_gripper.dm
index c11a09eed720..334be51e15c7 100644
--- a/code/datums/inventory_slots/inventory_gripper.dm
+++ b/code/datums/inventory_slots/inventory_gripper.dm
@@ -5,6 +5,7 @@
/// If set, use this icon_state for the hand slot overlay; otherwise, use slot_id.
var/hand_overlay
quick_equip_priority = null // you quick-equip stuff by holding it in a gripper, so this ought to be skipped
+ fluid_height = (FLUID_SHALLOW + FLUID_OVER_MOB_HEAD) / 2 // halfway between waist and top of head, so roughly chest level, reasoning that you can just hold it up out of the water
// For reference, grippers do not use ui_loc, they have it set dynamically during /datum/hud/proc/rebuild_hands()
diff --git a/code/datums/inventory_slots/slots/slot_back.dm b/code/datums/inventory_slots/slots/slot_back.dm
index cc65742561b3..7c2496867edf 100644
--- a/code/datums/inventory_slots/slots/slot_back.dm
+++ b/code/datums/inventory_slots/slots/slot_back.dm
@@ -7,6 +7,7 @@
requires_slot_flags = SLOT_BACK
mob_overlay_layer = HO_BACK_LAYER
quick_equip_priority = 14
+ fluid_height = (FLUID_SHALLOW + FLUID_OVER_MOB_HEAD) / 2 // halfway between waist and top of head, so roughly chest level
/datum/inventory_slot/back/simple
requires_organ_tag = null
diff --git a/code/datums/inventory_slots/slots/slot_ears.dm b/code/datums/inventory_slots/slots/slot_ears.dm
index 295c24a5a89d..1e905433cfc3 100644
--- a/code/datums/inventory_slots/slots/slot_ears.dm
+++ b/code/datums/inventory_slots/slots/slot_ears.dm
@@ -10,6 +10,7 @@
requires_slot_flags = SLOT_EARS
mob_overlay_layer = HO_L_EAR_LAYER
quick_equip_priority = 7
+ fluid_height = (FLUID_SHALLOW * 0.25 + FLUID_OVER_MOB_HEAD * 0.75) // 3/4 of the way between waist-level and the top of your head
/datum/inventory_slot/ear/update_mob_equipment_overlay(var/mob/living/user, var/obj/item/prop, var/redraw_mob = TRUE)
for(var/slot in global.airtight_slots)
diff --git a/code/datums/inventory_slots/slots/slot_glasses.dm b/code/datums/inventory_slots/slots/slot_glasses.dm
index 0068fac4a1ed..d686ac93edb9 100644
--- a/code/datums/inventory_slots/slots/slot_glasses.dm
+++ b/code/datums/inventory_slots/slots/slot_glasses.dm
@@ -11,6 +11,7 @@
mob_overlay_layer = HO_GLASSES_LAYER
alt_mob_overlay_layer = HO_GOGGLES_LAYER
quick_equip_priority = 5
+ fluid_height = (FLUID_SHALLOW * 0.25 + FLUID_OVER_MOB_HEAD * 0.75) // 3/4 of the way between waist-level and the top of your head
/datum/inventory_slot/glasses/get_examined_string(mob/owner, mob/user, distance, hideflags, decl/pronouns/pronouns)
if(_holding && !(hideflags & HIDEEYES))
diff --git a/code/datums/inventory_slots/slots/slot_head.dm b/code/datums/inventory_slots/slots/slot_head.dm
index dce1c5e4ab64..6c31459f016e 100644
--- a/code/datums/inventory_slots/slots/slot_head.dm
+++ b/code/datums/inventory_slots/slots/slot_head.dm
@@ -9,6 +9,7 @@
requires_slot_flags = SLOT_HEAD
mob_overlay_layer = HO_HEAD_LAYER
quick_equip_priority = 9
+ fluid_height = FLUID_OVER_MOB_HEAD
/datum/inventory_slot/head/simple
requires_organ_tag = null
diff --git a/code/datums/inventory_slots/slots/slot_id.dm b/code/datums/inventory_slots/slots/slot_id.dm
index 35d80c2c5a47..67b759c682ca 100644
--- a/code/datums/inventory_slots/slots/slot_id.dm
+++ b/code/datums/inventory_slots/slots/slot_id.dm
@@ -6,6 +6,7 @@
requires_slot_flags = SLOT_ID
mob_overlay_layer = HO_ID_LAYER
quick_equip_priority = 13
+ fluid_height = (FLUID_SHALLOW + FLUID_OVER_MOB_HEAD) / 2 // halfway between waist and top of head, so roughly chest level
/datum/inventory_slot/id/update_mob_equipment_overlay(var/mob/living/user, var/obj/item/prop, var/redraw_mob = TRUE)
var/obj/item/clothing/clothes = user.get_equipped_item(slot_w_uniform_str)
diff --git a/code/datums/inventory_slots/slots/slot_mask.dm b/code/datums/inventory_slots/slots/slot_mask.dm
index 33f44fa90444..53fa82f64213 100644
--- a/code/datums/inventory_slots/slots/slot_mask.dm
+++ b/code/datums/inventory_slots/slots/slot_mask.dm
@@ -10,6 +10,7 @@
can_be_hidden = TRUE
mob_overlay_layer = HO_FACEMASK_LAYER
quick_equip_priority = 10
+ fluid_height = (FLUID_SHALLOW * 0.25 + FLUID_OVER_MOB_HEAD * 0.75) // 3/4 of the way between waist-level and the top of your head
/datum/inventory_slot/mask/update_mob_equipment_overlay(var/mob/living/user, var/obj/item/prop, var/redraw_mob = TRUE)
if(prop?.flags_inv & BLOCK_ALL_HAIR)
diff --git a/code/datums/inventory_slots/slots/slot_shoes.dm b/code/datums/inventory_slots/slots/slot_shoes.dm
index 02c47d26787c..6fc4889be0bd 100644
--- a/code/datums/inventory_slots/slots/slot_shoes.dm
+++ b/code/datums/inventory_slots/slots/slot_shoes.dm
@@ -10,6 +10,7 @@
)
requires_slot_flags = SLOT_FEET
quick_equip_priority = 3
+ fluid_height = 3
/datum/inventory_slot/shoes/update_mob_equipment_overlay(var/mob/living/user, var/obj/item/prop, var/redraw_mob = TRUE)
var/obj/item/suit = user.get_equipped_item(slot_wear_suit_str)
diff --git a/code/datums/inventory_slots/slots/slot_suit_storage.dm b/code/datums/inventory_slots/slots/slot_suit_storage.dm
index 91a03c4610d8..832a72563294 100644
--- a/code/datums/inventory_slots/slots/slot_suit_storage.dm
+++ b/code/datums/inventory_slots/slots/slot_suit_storage.dm
@@ -5,6 +5,7 @@
slot_id = slot_s_store_str
requires_organ_tag = BP_CHEST
mob_overlay_layer = HO_SUIT_STORE_LAYER
+ fluid_height = (FLUID_SHALLOW + FLUID_OVER_MOB_HEAD) / 2 // halfway between waist and top of head, so roughly chest level
/datum/inventory_slot/suit_storage/can_equip_to_slot(var/mob/user, var/obj/item/prop, var/disable_warning, var/ignore_equipped)
. = ..()
diff --git a/code/datums/mind/mind.dm b/code/datums/mind/mind.dm
index 34bad84cb65d..cb9ad6c9539e 100644
--- a/code/datums/mind/mind.dm
+++ b/code/datums/mind/mind.dm
@@ -33,7 +33,6 @@
var/key
var/name //replaces mob/var/original_name
var/mob/living/current
- var/mob/living/original //TODO: remove.not used in any meaningful way ~Carn. First I'll need to tweak the way silicon-mobs handle minds.
var/active = 0
var/gen_relations_info
@@ -71,18 +70,12 @@
if(current?.mind == src)
current.mind = null
current = null
- if(original?.mind == src)
- original.mind = null
- original = null
. = ..()
/datum/mind/proc/handle_mob_deletion(mob/living/deleted_mob)
if (current == deleted_mob)
current = null
- if (original == deleted_mob)
- original = null
-
/datum/mind/proc/transfer_to(mob/living/new_character)
if(!istype(new_character))
to_world_log("## DEBUG: transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn")
@@ -505,7 +498,6 @@
mind.key = key
else
mind = new /datum/mind(key)
- mind.original = src
SSticker.minds += mind
if(!mind.name) mind.name = real_name
mind.current = src
diff --git a/code/datums/music_tracks/europa.dm b/code/datums/music_tracks/europa.dm
index ccbc948eda00..b1b050118ba0 100644
--- a/code/datums/music_tracks/europa.dm
+++ b/code/datums/music_tracks/europa.dm
@@ -8,7 +8,7 @@
/decl/music_track/martiancowboy
artist = "Kevin MacLeod"
title = "Martian Cowboy"
- song = 'sound/music/europa/Martian Cowboy.ogg'
+ song = 'sound/music/europa/MartianCowboy.ogg'
license = /decl/license/cc_by_3_0
url = "https://incompetech.com/music/royalty-free/index.html?isrc=usuan1100349"
diff --git a/code/datums/security_state.dm b/code/datums/security_state.dm
deleted file mode 100644
index 1863d4ae8601..000000000000
--- a/code/datums/security_state.dm
+++ /dev/null
@@ -1,335 +0,0 @@
-/decl/security_state
- abstract_type = /decl/security_state
- // When defining any of these values type paths should be used, not instances. Instances will be acquired in /New()
-
- var/decl/security_level/severe_security_level // At which security level (and higher) the use of nuclear fission devices and other extreme measures are allowed. Defaults to the last entry in all_security_levels if unset.
- var/decl/security_level/high_security_level // At which security level (and higher) transfer votes are disabled, ERT may be requested, and other similar high alert implications. Defaults to the second to last entry in all_security_levels if unset.
- // All security levels within the above convention: Low, Guarded, Elevated, High, Severe
-
-
- // Under normal conditions the crew may not raise the current security level higher than the highest_standard_security_level
- // The crew may also not adjust the security level once it is above the highest_standard_security_level.
- // Defaults to the second to last entry in all_security_levels if unset/null.
- // Set to FALSE/0 if there should be no restrictions.
- var/decl/security_level/highest_standard_security_level
-
- var/decl/security_level/current_security_level // The current security level. Defaults to the first entry in all_security_levels if unset.
- var/decl/security_level/stored_security_level // The security level that we are escalating to high security from - we will return to this level once we choose to revert.
- var/list/all_security_levels // List of all available security levels
- var/list/standard_security_levels // List of all normally selectable security levels
- var/list/comm_console_security_levels // List of all selectable security levels for the command and communication console - basically standard_security_levels - 1
-
-/decl/security_state/Initialize()
-
- . = ..()
-
- // Setup the severe security level
- if(!(severe_security_level in all_security_levels))
- severe_security_level = all_security_levels[all_security_levels.len]
- severe_security_level = GET_DECL(severe_security_level)
-
- // Setup the high security level
- if(!(high_security_level in all_security_levels))
- high_security_level = all_security_levels[all_security_levels.len - 1]
- high_security_level = GET_DECL(high_security_level)
-
- // Setup the highest standard security level
- if(highest_standard_security_level || isnull(highest_standard_security_level))
- if(!(highest_standard_security_level in all_security_levels))
- highest_standard_security_level = all_security_levels[all_security_levels.len - 1]
- highest_standard_security_level = GET_DECL(highest_standard_security_level)
- else
- highest_standard_security_level = null
-
- // Setup the current security level
- if(current_security_level in all_security_levels)
- current_security_level = GET_DECL(current_security_level)
- else
- current_security_level = GET_DECL(all_security_levels[1])
-
- // Setup the full list of available security levels now that we no longer need to use "x in all_security_levels"
- var/list/security_level_instances = list()
- for(var/security_level_type in all_security_levels)
- security_level_instances += GET_DECL(security_level_type)
- all_security_levels = security_level_instances
-
- standard_security_levels = list()
- // Setup the list of normally selectable security levels
- for(var/security_level in all_security_levels)
- standard_security_levels += security_level
- if(security_level == highest_standard_security_level)
- break
-
- comm_console_security_levels = list()
- // Setup the list of selectable security levels available in the comm. console
- for(var/security_level in all_security_levels)
- if(security_level == highest_standard_security_level)
- break
- comm_console_security_levels += security_level
-
- // Now we ensure the high security level is not above the severe one (but we allow them to be equal)
- var/severe_index = all_security_levels.Find(severe_security_level)
- var/high_index = all_security_levels.Find(high_security_level)
- if(high_index > severe_index)
- high_security_level = severe_security_level
-
- // Finally switch up to the default starting security level.
- current_security_level.switching_up_to()
-
-/decl/security_state/proc/can_change_security_level()
- return current_security_level in standard_security_levels
-
-/decl/security_state/proc/can_switch_to(var/given_security_level)
- if(!can_change_security_level())
- return FALSE
- return given_security_level in standard_security_levels
-
-/decl/security_state/proc/current_security_level_is_lower_than(var/given_security_level)
- var/current_index = all_security_levels.Find(current_security_level)
- var/given_index = all_security_levels.Find(given_security_level)
-
- return given_index && current_index < given_index
-
-/decl/security_state/proc/current_security_level_is_same_or_higher_than(var/given_security_level)
- var/current_index = all_security_levels.Find(current_security_level)
- var/given_index = all_security_levels.Find(given_security_level)
-
- return given_index && current_index >= given_index
-
-/decl/security_state/proc/current_security_level_is_higher_than(var/given_security_level)
- var/current_index = all_security_levels.Find(current_security_level)
- var/given_index = all_security_levels.Find(given_security_level)
-
- return given_index && current_index > given_index
-
-/decl/security_state/proc/set_security_level(var/decl/security_level/new_security_level, var/force_change = FALSE)
- if(new_security_level == current_security_level)
- return FALSE
- if(!(new_security_level in all_security_levels))
- return FALSE
- if(!force_change && !can_switch_to(new_security_level))
- return FALSE
-
- var/decl/security_level/previous_security_level = current_security_level
- current_security_level = new_security_level
-
- var/previous_index = all_security_levels.Find(previous_security_level)
- var/new_index = all_security_levels.Find(new_security_level)
-
- if(new_index > previous_index)
- previous_security_level.switching_up_from()
- new_security_level.switching_up_to()
- else
- previous_security_level.switching_down_from()
- new_security_level.switching_down_to()
-
- log_and_message_admins("has changed the security level from [previous_security_level.name] to [new_security_level.name].")
- return TRUE
-
-// This proc decreases the current security level, if possible
-/decl/security_state/proc/decrease_security_level(var/force_change = FALSE)
- var/current_index = all_security_levels.Find(current_security_level)
- if(current_index == 1)
- return FALSE
- return set_security_level(all_security_levels[current_index - 1], force_change)
-
-/decl/security_level
- var/icon
- var/name
-
- // These values are primarily for station alarms and status displays, and which light colors and overlays to use
- var/light_range
- var/light_power
- var/light_color_alarm
- var/light_color_class
- var/light_color_status_display
-
- var/up_description
- var/down_description
-
- var/datum/alarm_appearance/alarm_appearance
-
- abstract_type = /decl/security_level
-
-/decl/security_level/Initialize()
- . = ..()
- if(ispath(alarm_appearance, /datum/alarm_appearance))
- alarm_appearance = new alarm_appearance
-
-/decl/security_level/validate()
- . = ..()
- var/initial_appearance = initial(alarm_appearance)
- if(!initial_appearance)
- . += "alarm_appearance was not set"
- else if(!ispath(initial_appearance))
- . += "alarm_appearance was not set to a /datum/alarm_appearance subpath"
- else if(!istype(alarm_appearance, /datum/alarm_appearance))
- . += "alarm_appearance creation failed (check runtimes?)"
-
-// Called when we're switching from a lower security level to this one.
-/decl/security_level/proc/switching_up_to()
- return
-
-// Called when we're switching from a higher security level to this one.
-/decl/security_level/proc/switching_down_to()
- return
-
-// Called when we're switching from this security level to a higher one.
-/decl/security_level/proc/switching_up_from()
- return
-
-// Called when we're switching from this security level to a lower one.
-/decl/security_level/proc/switching_down_from()
- return
-
-/*
-* The default security state and levels setup
-*/
-/decl/security_state/default
- all_security_levels = list(/decl/security_level/default/code_green, /decl/security_level/default/code_blue, /decl/security_level/default/code_red, /decl/security_level/default/code_delta)
-
-/decl/security_level/default
- abstract_type = /decl/security_level/default
- icon = 'icons/misc/security_state.dmi'
-
- var/static/datum/announcement/priority/security/security_announcement_up = new(do_log = 0, do_newscast = 1, new_sound = sound('sound/misc/notice1.ogg'))
- var/static/datum/announcement/priority/security/security_announcement_down = new(do_log = 0, do_newscast = 1, new_sound = sound('sound/misc/notice1.ogg'))
-
-/decl/security_level/default/switching_up_to()
- if(up_description)
- security_announcement_up.Announce(up_description, "Attention! Alert level elevated to [name]!")
- notify_station()
-
-/decl/security_level/default/switching_down_to()
- if(down_description)
- security_announcement_down.Announce(down_description, "Attention! Alert level changed to [name]!")
- notify_station()
-
-/decl/security_level/default/proc/notify_station()
- for(var/obj/machinery/firealarm/FA in SSmachines.machinery)
- if(isContactLevel(FA.z))
- FA.update_icon()
- post_status("alert")
-
-/decl/security_level/default/code_green
- name = "code green"
-
- light_range = 2
- light_power = 1
-
- light_color_alarm = COLOR_GREEN
- light_color_class = "font_green"
- light_color_status_display = COLOR_GREEN
-
-
- alarm_appearance = /datum/alarm_appearance/green
-
- down_description = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced."
-
-/decl/security_level/default/code_blue
- name = "code blue"
-
- light_range = 2
- light_power = 1
- light_color_alarm = COLOR_BLUE
- light_color_class = "font_blue"
- light_color_status_display = COLOR_BLUE
-
- alarm_appearance = /datum/alarm_appearance/blue
-
- up_description = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted."
- down_description = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed."
-
-/decl/security_level/default/code_red
- name = "code red"
-
- light_range = 4
- light_power = 2
- light_color_alarm = COLOR_RED
- light_color_class = "font_red"
- light_color_status_display = COLOR_RED
-
- alarm_appearance = /datum/alarm_appearance/red
-
- up_description = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised."
- down_description = "The self-destruct mechanism has been deactivated, there is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised."
-
-/decl/security_level/default/code_delta
- name = "code delta"
-
- light_range = 4
- light_power = 2
- light_color_alarm = COLOR_RED
- light_color_class = "font_red"
- light_color_status_display = COLOR_RED
-
- alarm_appearance = /datum/alarm_appearance/delta
-
-
- var/static/datum/announcement/priority/security/security_announcement_delta = new(do_log = 0, do_newscast = 1, new_sound = sound('sound/effects/siren.ogg'))
-
-/decl/security_level/default/code_delta/switching_up_to()
- security_announcement_delta.Announce("The self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.", "Attention! Delta security level reached!")
- notify_station()
-
-/datum/alarm_appearance
- var/display_icon //The icon_state for the displays. Normally only one is used, unless uses_twotone_displays is TRUE.
- var/display_icon_color //The color for the display icon.
-
- var/display_icon_twotone //Used for two-tone displays.
- var/display_icon_twotone_color //The color for the display icon.
-
- var/display_emblem //The icon_state for the emblem, i.e for delta, a radstorm, alerts.
- var/display_emblem_color //The color for the emblem.
-
- var/alarm_icon //The icon_state for the alarms
- var/alarm_icon_color //the color for the icon_state
-
- var/alarm_icon_twotone //Used for two-tone alarms (i.e delta).
- var/alarm_icon_twotone_color //The color for the secondary tone icon.
-
-/datum/alarm_appearance/green
- display_icon = "status_display_lines"
- display_icon_color = PIPE_COLOR_GREEN
-
- display_emblem = "status_display_alert"
- display_emblem_color = COLOR_WHITE
-
- alarm_icon = "alarm_normal"
- alarm_icon_color = PIPE_COLOR_GREEN
-
-/datum/alarm_appearance/blue
- display_icon = "status_display_lines"
- display_icon_color = COLOR_BLUE
-
- display_emblem = "status_display_alert"
- display_emblem_color = COLOR_WHITE
-
- alarm_icon = "alarm_normal"
- alarm_icon_color = COLOR_BLUE
-
-/datum/alarm_appearance/red
- display_icon = "status_display_lines"
- display_icon_color = COLOR_RED
-
- display_emblem = "status_display_alert"
- display_emblem_color = COLOR_WHITE
-
- alarm_icon = "alarm_blinking"
- alarm_icon_color = COLOR_RED
-
-/datum/alarm_appearance/delta
- display_icon = "status_display_twotone1"
- display_icon_color = COLOR_RED
-
- display_icon_twotone = "status_display_twotone2"
- display_icon_twotone_color = COLOR_YELLOW
-
- display_emblem = "delta"
- display_emblem_color = COLOR_WHITE
-
- alarm_icon = "alarm_blinking_twotone1"
- alarm_icon_color = COLOR_RED
-
- alarm_icon_twotone = "alarm_blinking_twotone2"
- alarm_icon_twotone_color = PIPE_COLOR_YELLOW
\ No newline at end of file
diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm
index 91b8006a1945..3c771acd1e42 100644
--- a/code/datums/supplypacks/engineering.dm
+++ b/code/datums/supplypacks/engineering.dm
@@ -155,13 +155,6 @@
containername = "shield generator construction kit crate"
access = access_engine
-/decl/hierarchy/supply_pack/engineering/inertial_damper
- name = "Equipment - inertial damper construction kit"
- contains = list(/obj/item/stock_parts/circuitboard/inertial_damper, /obj/item/stock_parts/capacitor, /obj/item/stock_parts/micro_laser, /obj/item/stock_parts/console_screen)
- containertype = /obj/structure/closet/crate/secure
- containername = "inertial damper construction kit crate"
- access = access_engine
-
/decl/hierarchy/supply_pack/engineering/smbig
name = "Power - Supermatter core"
contains = list(/obj/machinery/power/supermatter)
diff --git a/code/datums/supplypacks/galley.dm b/code/datums/supplypacks/galley.dm
index 5eb7cc9f071e..45c2c05ea161 100644
--- a/code/datums/supplypacks/galley.dm
+++ b/code/datums/supplypacks/galley.dm
@@ -72,6 +72,12 @@
containername = "pizza crate"
supply_method = /decl/supply_method/randomized
+/decl/hierarchy/supply_pack/galley/nuggets
+ name = "Emergency - Nugget crate"
+ contains = list(/obj/item/box/nuggets = 2)
+ containertype = /obj/structure/closet/crate/freezer
+ containername = "nugget crate"
+
/decl/hierarchy/supply_pack/galley/rations
num_contained = 6
name = "Emergency - MREs"
diff --git a/code/datums/uplink/devices and tools.dm b/code/datums/uplink/devices_and_tools.dm
similarity index 100%
rename from code/datums/uplink/devices and tools.dm
rename to code/datums/uplink/devices_and_tools.dm
diff --git a/code/game/antagonist/antagonist_update.dm b/code/game/antagonist/antagonist_update.dm
index be03efcadfd8..642141255657 100644
--- a/code/game/antagonist/antagonist_update.dm
+++ b/code/game/antagonist/antagonist_update.dm
@@ -13,7 +13,6 @@
player.current = new mob_path(get_turf(player.current))
player.transfer_to(player.current)
if(holder) qdel(holder)
- player.original = player.current
if(!preserve_appearance && (flags & ANTAG_SET_APPEARANCE))
spawn(3)
var/mob/living/human/H = player.current
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 01856eb77733..5dd985c6064c 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -994,3 +994,6 @@
/atom/proc/is_watertight()
return ATOM_IS_OPEN_CONTAINER(src)
+
+/atom/proc/can_drink_from(mob/user)
+ return ATOM_IS_OPEN_CONTAINER(src) && reagents?.total_volume && user.check_has_mouth()
diff --git a/code/game/atoms_fluids.dm b/code/game/atoms_fluids.dm
index e69ed3bbfc30..2984d5393f27 100644
--- a/code/game/atoms_fluids.dm
+++ b/code/game/atoms_fluids.dm
@@ -23,19 +23,64 @@
var/turf/T = get_turf(src)
return T?.is_flooded(lying_mob, absolute)
-/atom/proc/submerged(depth)
+/atom/proc/submerged(depth, above_turf)
+ var/turf/T = get_turf(src)
if(isnull(depth))
- var/turf/T = get_turf(src)
if(!istype(T))
return FALSE
depth = T.get_fluid_depth()
+ if(istype(T))
+ var/turf_height = T.get_physical_height()
+ // If we're not on the surface of the turf (floating, leaping, or other sources)
+ // then we add the turf height to the depth, so you can jump over a water-filled pit
+ // or throw something over it
+ if(turf_height < 0 && above_turf)
+ depth += turf_height
if(ismob(loc))
return depth >= FLUID_SHALLOW
if(isturf(loc))
+ if(locate(/obj/structure/table))
+ return depth >= FLUID_SHALLOW
return depth >= 3
return depth >= FLUID_OVER_MOB_HEAD
-/turf/submerged(depth)
+// This override exists purely because throwing is movable-level and not atom-level,
+// for obvious reasons (that being that non-movable atoms cannot move).
+/atom/movable/submerged(depth, above_turf)
+ above_turf ||= !!throwing
+ return ..()
+
+/obj/item/submerged(depth, above_turf)
+ var/datum/inventory_slot/slot = get_any_equipped_slot_datum()
+ // we're in a mob and have a slot, so we bail early
+ if(istype(slot))
+ var/mob/owner = loc // get_any_equipped_slot checks istype already
+ if(owner.current_posture.prone)
+ return ..() // treat us like an atom sitting on the ground (or table), really
+ if(isnull(depth)) // copied from base proc, since we aren't calling parent in this block
+ var/turf/T = get_turf(src)
+ if(!istype(T))
+ return FALSE
+ depth = T.get_fluid_depth()
+ return depth >= slot.fluid_height
+ return ..()
+
+/mob/submerged(depth, above_turf)
+ above_turf ||= is_floating || !!throwing // check throwing here because of the table check coming before parent call
+ var/obj/structure/table/standing_on = locate(/obj/structure/table) in loc
+ // can't stand on a table if we're floating
+ if(!above_turf && standing_on && standing_on.mob_offset > 0) // standing atop a table that is a meaningful amount above the ground (not a bench)
+ if(isnull(depth)) // duplicated from atom because we don't call parent in this block
+ var/turf/T = get_turf(src)
+ if(!istype(T))
+ return FALSE
+ depth = T.get_fluid_depth()
+ // assuming default tables are at waist height, this is a simple adjustment to scale it for taller/shorter ones
+ return depth >= floor(FLUID_SHALLOW * (standing_on.mob_offset / /obj/structure/table::mob_offset))
+ return ..()
+
+// above_turf is nonsensical for turfs but I don't want the linter to complain
+/turf/submerged(depth, above_turf)
if(isnull(depth))
depth = get_fluid_depth()
return depth >= FLUID_OVER_MOB_HEAD
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 477e9d25c5df..4b0049e92f2c 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -272,7 +272,7 @@
if(isturf(loc))
var/turf/T = loc
- if(T.reagents)
+ if(T.reagents?.total_volume && submerged())
fluid_act(T.reagents)
for(var/mob/viewer in storage?.storage_ui?.is_seeing)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 9bfdd9791429..be38f8871efc 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -550,7 +550,7 @@ var/global/list/additional_antag_types = list()
continue //Happy connected client
for(var/mob/observer/ghost/D in SSmobs.mob_list)
- if(D.mind && (D.mind.original == L || D.mind.current == L))
+ if(D.mind && D.mind.current == L)
if(L.stat == DEAD)
msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Dead)\n"
continue //Dead mob, ghost abandoned
diff --git a/code/game/machinery/_machines_base/machinery.dm b/code/game/machinery/_machines_base/machinery.dm
index 6736ad221bbe..d6fafc99f1e5 100644
--- a/code/game/machinery/_machines_base/machinery.dm
+++ b/code/game/machinery/_machines_base/machinery.dm
@@ -234,6 +234,8 @@ Class Procs:
/obj/machinery/CouldUseTopic(var/mob/user)
..()
user.set_machine(src)
+ if(clicksound && isliving(user))
+ playsound(src, clicksound, clickvol)
/obj/machinery/CouldNotUseTopic(var/mob/user)
user.unset_machine()
@@ -391,11 +393,6 @@ Class Procs:
/datum/proc/remove_visual(mob/M)
return
-/obj/machinery/CouldUseTopic(var/mob/user)
- ..()
- if(clicksound && isliving(user))
- playsound(src, clicksound, clickvol)
-
/obj/machinery/proc/display_parts(mob/user)
to_chat(user, "Following parts detected in the machine:")
for(var/obj/item/C in component_parts)
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index 16503b09fe95..0c145faa9de9 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -120,7 +120,7 @@
dat += "
[++i]. Set Custom Key
"
else
dat += "
Please authenticate with the server in order to show additional options."
- if((isAI(user) || isrobot(user)) && (user.mind.assigned_special_role && user.mind.original == user))
+ 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"
@@ -283,7 +283,7 @@
//Hack the Console to get the password
if (href_list["hack"])
- if((isAI(usr) || isrobot(usr)) && usr.mind.assigned_special_role && usr.mind.original == usr)
+ if((isAI(usr) || isrobot(usr)) && player_is_antag(usr.mind))
src.hacking = 1
src.screen = 2
update_icon()
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index 524f6a358899..4b1d38034e52 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -68,7 +68,7 @@
return TOPIC_HANDLED
// Antag AI checks
- if(!isAI(user) || !(user.mind.assigned_special_role && user.mind.original == user))
+ if(!isAI(user) || !player_is_antag(user.mind))
to_chat(user, "Access Denied")
return TOPIC_HANDLED
@@ -103,9 +103,9 @@
. = TOPIC_REFRESH
// Proc: get_cyborgs()
-// Parameters: 1 (operator - mob which is operating the console.)
+// Parameters: 1 (user - mob which is operating the console.)
// Description: Returns NanoUI-friendly list of accessible cyborgs.
-/obj/machinery/computer/robotics/proc/get_cyborgs(var/mob/operator)
+/obj/machinery/computer/robotics/proc/get_cyborgs(var/mob/user)
var/list/robots = list()
for(var/mob/living/silicon/robot/R in global.silicon_mob_list)
@@ -145,7 +145,7 @@
robot["master_ai"] = R.connected_ai ? R.connected_ai.name : "None"
robot["hackable"] = 0
// Antag AIs know whether linked cyborgs are hacked or not.
- if(operator && isAI(operator) && (R.connected_ai == operator) && (operator.mind.assigned_special_role && operator.mind.original == operator))
+ if(user && isAI(user) && (R.connected_ai == user) && player_is_antag(user.mind))
robot["hacked"] = R.emagged ? 1 : 0
robot["hackable"] = R.emagged? 0 : 1
robots.Add(list(robot))
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index c9149697a668..aa341461f1c8 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -141,9 +141,6 @@ About the new airlock wires panel:
return
..(user)
-/obj/machinery/door/airlock/bumpopen(mob/living/simple_animal/user)
- ..(user)
-
/obj/machinery/door/airlock/proc/isElectrified()
if(src.electrified_until != 0)
return 1
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 9d871d3e2b56..ce3c79b45d88 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -80,6 +80,9 @@ var/global/list/holopads = list()
/obj/machinery/hologram/holopad/Destroy()
global.listening_objects -= src
+ global.holopads -= src
+ for (var/mob/living/master in masters)
+ clear_holo(master)
return ..()
/obj/machinery/hologram/holopad/interface_interact(var/mob/living/human/user) //Carn: Hologram requests.
@@ -387,13 +390,6 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
idle_power_usage = 5
active_power_usage = 100
-//Destruction procs.
-/obj/machinery/hologram/holopad/Destroy()
- global.holopads -= src
- for (var/mob/living/master in masters)
- clear_holo(master)
- return ..()
-
/*
* Other Stuff: Is this even used?
*/
diff --git a/code/game/machinery/kitchen/icecream.dm b/code/game/machinery/kitchen/icecream.dm
index 2a893f6e61b4..cd751f4d64af 100644
--- a/code/game/machinery/kitchen/icecream.dm
+++ b/code/game/machinery/kitchen/icecream.dm
@@ -33,7 +33,7 @@
if(ICECREAM_STRAWBERRY)
return list(/decl/material/liquid/drink/milk, /decl/material/solid/ice, /decl/material/liquid/drink/juice/berry)
if(ICECREAM_BLUE)
- return list(/decl/material/liquid/drink/milk, /decl/material/solid/ice, /decl/material/liquid/ethanol/bluecuracao)
+ return list(/decl/material/liquid/drink/milk, /decl/material/solid/ice, /decl/material/liquid/alcohol/bluecuracao)
if(ICECREAM_CHERRY)
return list(/decl/material/liquid/drink/milk, /decl/material/solid/ice, /decl/material/liquid/nutriment/cherryjelly)
if(ICECREAM_BANANA)
diff --git a/code/game/machinery/vending/_vending.dm b/code/game/machinery/vending/_vending.dm
index 2bc56a9c1051..866062f2a54b 100644
--- a/code/game/machinery/vending/_vending.dm
+++ b/code/game/machinery/vending/_vending.dm
@@ -195,11 +195,6 @@
. = ..()
SSnano.update_uis(src)
-/obj/machinery/vending/receive_mouse_drop(atom/dropping, mob/user, params)
- . = ..()
- if(!. && dropping.loc == user && attempt_to_stock(dropping, user))
- return TRUE
-
/obj/machinery/vending/proc/attempt_to_stock(var/obj/item/I, var/mob/user)
for(var/datum/stored_items/vending_products/R in product_records)
if(I.type == R.item_path)
diff --git a/code/game/objects/objs.dm b/code/game/objects/__objs.dm
similarity index 95%
rename from code/game/objects/objs.dm
rename to code/game/objects/__objs.dm
index f1838fcfa065..8ab41e00a57f 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/__objs.dm
@@ -403,3 +403,16 @@
// Stub, used by /item and /structure
/obj/proc/refresh_color()
return
+
+// Slightly convoluted reagent logic to avoid fluid_act() putting reagents straight back into the destroyed /obj.
+/obj/physically_destroyed(skip_qdel)
+ var/dumped_reagents = FALSE
+ var/atom/last_loc = loc
+ if(last_loc && reagents?.total_volume)
+ reagents.trans_to(loc, reagents.total_volume, defer_update = TRUE)
+ dumped_reagents = TRUE
+ reagents.clear_reagents() // We are qdeling, don't bother with a more nuanced update.
+ . = ..()
+ if(dumped_reagents && last_loc && !QDELETED(last_loc) && last_loc.reagents?.total_volume)
+ last_loc.reagents.handle_update()
+ HANDLE_REACTIONS(last_loc.reagents)
diff --git a/code/game/objects/obj_edibility.dm b/code/game/objects/_obj_edibility.dm
similarity index 100%
rename from code/game/objects/obj_edibility.dm
rename to code/game/objects/_obj_edibility.dm
diff --git a/code/game/objects/objs_damage.dm b/code/game/objects/_objs_damage.dm
similarity index 100%
rename from code/game/objects/objs_damage.dm
rename to code/game/objects/_objs_damage.dm
diff --git a/code/game/objects/objs_interactions.dm b/code/game/objects/_objs_interactions.dm
similarity index 100%
rename from code/game/objects/objs_interactions.dm
rename to code/game/objects/_objs_interactions.dm
diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm
index 4abf329fd599..2a22a171886e 100644
--- a/code/game/objects/effects/decals/Cleanable/misc.dm
+++ b/code/game/objects/effects/decals/Cleanable/misc.dm
@@ -1,19 +1,20 @@
/obj/effect/decal/cleanable/generic
- name = "clutter"
- desc = "Someone should clean that up."
- gender = PLURAL
- icon = 'icons/obj/objects.dmi'
- icon_state = "shards"
- sweepable = TRUE
+ name = "clutter"
+ desc = "Someone should clean that up."
+ gender = PLURAL
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "shards"
+ sweepable = TRUE
/obj/effect/decal/cleanable/ash
- name = "ashes"
- desc = "Ashes to ashes, dust to dust, and into space."
- gender = PLURAL
- icon = 'icons/obj/objects.dmi'
- icon_state = "ash"
- weather_sensitive = FALSE
- sweepable = TRUE
+ name = "ashes"
+ desc = "Ashes to ashes, dust to dust, and into space."
+ gender = PLURAL
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "ash"
+ weather_sensitive = FALSE
+ sweepable = TRUE
+ burnable = FALSE
/obj/effect/decal/cleanable/ash/attackby(obj/item/I, mob/user)
if(ATOM_IS_OPEN_CONTAINER(I))
@@ -36,50 +37,50 @@
return TRUE
/obj/effect/decal/cleanable/flour
- name = "flour"
- desc = "It's still good. Four second rule!"
- gender = PLURAL
- icon = 'icons/effects/effects.dmi'
- icon_state = "flour"
- persistent = TRUE
- sweepable = TRUE
+ name = "flour"
+ desc = "It's still good. Four second rule!"
+ gender = PLURAL
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "flour"
+ persistent = TRUE
+ sweepable = TRUE
/obj/effect/decal/cleanable/cobweb
- name = "cobweb"
- desc = "Somebody should remove that."
- layer = ABOVE_HUMAN_LAYER
- icon = 'icons/effects/effects.dmi'
- icon_state = "cobweb1"
- weather_sensitive = FALSE
- sweepable = TRUE
+ name = "cobweb"
+ desc = "Somebody should remove that."
+ layer = ABOVE_HUMAN_LAYER
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "cobweb1"
+ weather_sensitive = FALSE
+ sweepable = TRUE
/obj/effect/decal/cleanable/molten_item
- name = "gooey grey mass"
- desc = "It looks like a melted... something."
- icon = 'icons/effects/molten_item.dmi'
- icon_state = "molten"
- persistent = TRUE
- generic_filth = TRUE
- weather_sensitive = FALSE
+ name = "gooey grey mass"
+ desc = "It looks like a melted... something."
+ icon = 'icons/effects/molten_item.dmi'
+ icon_state = "molten"
+ persistent = TRUE
+ generic_filth = TRUE
+ weather_sensitive = FALSE
/obj/effect/decal/cleanable/cobweb2
- name = "cobweb"
- desc = "Somebody should remove that."
- layer = ABOVE_HUMAN_LAYER
- icon = 'icons/effects/effects.dmi'
- icon_state = "cobweb2"
- weather_sensitive = FALSE
- sweepable = TRUE
+ name = "cobweb"
+ desc = "Somebody should remove that."
+ layer = ABOVE_HUMAN_LAYER
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "cobweb2"
+ weather_sensitive = FALSE
+ sweepable = TRUE
//Vomit (sorry)
/obj/effect/decal/cleanable/vomit
- name = "vomit"
- desc = "Gosh, how unpleasant."
- gender = PLURAL
- icon = 'icons/effects/vomit.dmi'
- icon_state = "vomit_1"
- persistent = TRUE
- generic_filth = TRUE
+ name = "vomit"
+ desc = "Gosh, how unpleasant."
+ gender = PLURAL
+ icon = 'icons/effects/vomit.dmi'
+ icon_state = "vomit_1"
+ persistent = TRUE
+ generic_filth = TRUE
/obj/effect/decal/cleanable/vomit/Initialize(ml, _age)
random_icon_states = icon_states(icon)
@@ -94,46 +95,46 @@
color = reagents.get_color()
/obj/effect/decal/cleanable/tomato_smudge
- name = "tomato smudge"
- desc = "It's red."
- icon = 'icons/effects/tomatodecal.dmi'
- icon_state = "tomato_floor1"
+ name = "tomato smudge"
+ desc = "It's red."
+ icon = 'icons/effects/tomatodecal.dmi'
+ icon_state = "tomato_floor1"
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
- persistent = TRUE
- generic_filth = TRUE
+ persistent = TRUE
+ generic_filth = TRUE
/obj/effect/decal/cleanable/egg_smudge
- name = "smashed egg"
- desc = "Seems like this one won't hatch."
- icon = 'icons/effects/tomatodecal.dmi'
- icon_state = "smashed_egg1"
+ name = "smashed egg"
+ desc = "Seems like this one won't hatch."
+ icon = 'icons/effects/tomatodecal.dmi'
+ icon_state = "smashed_egg1"
random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3")
- persistent = TRUE
- generic_filth = TRUE
+ persistent = TRUE
+ generic_filth = TRUE
/obj/effect/decal/cleanable/pie_smudge //honk
- name = "smashed pie"
- desc = "It's pie cream from a cream pie."
- icon = 'icons/effects/tomatodecal.dmi'
- icon_state = "smashed_pie"
+ name = "smashed pie"
+ desc = "It's pie cream from a cream pie."
+ icon = 'icons/effects/tomatodecal.dmi'
+ icon_state = "smashed_pie"
random_icon_states = list("smashed_pie")
- persistent = TRUE
- generic_filth = TRUE
+ persistent = TRUE
+ generic_filth = TRUE
/obj/effect/decal/cleanable/fruit_smudge
- name = "smudge"
- desc = "Some kind of fruit smear."
- icon = 'icons/effects/blood.dmi'
- icon_state = "mfloor1"
+ name = "smudge"
+ desc = "Some kind of fruit smear."
+ icon = 'icons/effects/blood.dmi'
+ icon_state = "mfloor1"
random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7")
- persistent = TRUE
- generic_filth = TRUE
+ persistent = TRUE
+ generic_filth = TRUE
/obj/effect/decal/cleanable/champagne
- name = "champagne"
- desc = "Someone got a bit too excited."
- gender = PLURAL
- icon = 'icons/effects/effects.dmi'
- icon_state = "fchampagne1"
- color = COLOR_BRASS
+ name = "champagne"
+ desc = "Someone got a bit too excited."
+ gender = PLURAL
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "fchampagne1"
+ color = COLOR_BRASS
random_icon_states = list("fchampagne1", "fchampagne2", "fchampagne3", "fchampagne4")
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 6c7d9ec89e07..66319d3ee89b 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -3,6 +3,7 @@
anchored = TRUE
abstract_type = /obj/effect/decal/cleanable
+ var/burnable = TRUE
var/sweepable = FALSE
var/weather_sensitive = TRUE
var/persistent = FALSE
@@ -46,6 +47,11 @@
SSpersistence.forget_value(src, /decl/persistence_handler/filth)
. = ..()
+/obj/effect/decal/cleanable/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ . = ..()
+ if(burnable && !QDELETED(src))
+ qdel(src)
+
/obj/effect/decal/cleanable/process_weather(obj/abstract/weather_system/weather, decl/state/weather/weather_state)
if(!weather_sensitive)
return PROCESS_KILL
diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm
index 5081ba6b45d8..b02237a6b2f3 100644
--- a/code/game/objects/items/__item.dm
+++ b/code/game/objects/items/__item.dm
@@ -99,7 +99,8 @@
var/paint_verb
/// What dexterity is required to attack with this item?
- var/needs_attack_dexterity = DEXTERITY_WIELD_ITEM
+ var/needs_attack_dexterity = DEXTERITY_WIELD_ITEM
+ var/needs_interaction_dexterity = DEXTERITY_HOLD_ITEM
/// Vars relating to wielding the item with two or more hands.
var/can_be_twohanded = FALSE
@@ -378,7 +379,7 @@
return ..(user, distance, "", jointext(desc_comp, "
"))
/obj/item/check_mousedrop_adjacency(var/atom/over, var/mob/user)
- . = (loc == user && istype(over, /obj/screen/inventory)) || ..()
+ . = (loc == user && istype(over, /obj/screen)) || ..()
/obj/item/handle_mouse_drop(atom/over, mob/user, params)
@@ -1115,9 +1116,6 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.
step_towards(src,S)
else ..()
-/obj/item/check_mousedrop_adjacency(var/atom/over, var/mob/user)
- . = (loc == user && istype(over, /obj/screen)) || ..()
-
// Supplied during loadout gear tweaking.
/obj/item/proc/set_custom_name(var/new_name)
base_name = new_name
@@ -1263,3 +1261,12 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.
continue
reagent_overlay.overlays += overlay_image(icon, modified_reagent_overlay, reagent.get_reagent_overlay_color(reagents), RESET_COLOR | RESET_ALPHA)
return reagent_overlay
+
+/obj/item/on_reagent_change()
+ . = ..()
+ // You can't put liquids in clay/sand/dirt vessels, sorry.
+ if(reagents?.total_liquid_volume > 0 && material && material.hardness <= MAT_VALUE_MALLEABLE && !QDELETED(src))
+ visible_message(SPAN_DANGER("\The [src] falls apart!"))
+ squash_item()
+ if(!QDELETED(src))
+ physically_destroyed()
diff --git a/code/game/objects/items/_item_interactions.dm b/code/game/objects/items/_item_interactions.dm
index e3e6a83045f3..b9efb6e61dc8 100644
--- a/code/game/objects/items/_item_interactions.dm
+++ b/code/game/objects/items/_item_interactions.dm
@@ -40,94 +40,3 @@
/decl/interaction_handler/storage_open/invoked(atom/target, mob/user, obj/item/prop)
target?.storage?.open(user)
-
-/decl/interaction_handler/wash_hands
- name = "Wash Hands"
- expected_target_type = /atom
- interaction_flags = INTERACTION_NEEDS_PHYSICAL_INTERACTION | INTERACTION_NEVER_AUTOMATIC
-
-/decl/interaction_handler/wash_hands/is_possible(atom/target, mob/user, obj/item/prop)
- . = ..() && target?.reagents?.has_reagent(/decl/material/liquid/water, 150)
- if(.)
- for(var/hand_slot in user.get_held_item_slots())
- var/obj/item/organ/external/organ = user.get_organ(hand_slot)
- if(istype(organ) && organ.is_washable)
- return TRUE
-
-/decl/interaction_handler/wash_hands/invoked(atom/target, mob/user, obj/item/prop)
-
- // Probably needs debounce and do_after() but showers and wading into water don't, so whatever.
- if(!target?.reagents?.has_reagent(/decl/material/liquid/water, 150)) // To avoid washing your hands in beakers.
- to_chat(user, SPAN_WARNING("\The [src] doesn't have enough water in it to wash your hands."))
- return
-
- var/found_hand = FALSE
- for(var/hand_slot in user.get_held_item_slots())
- var/obj/item/organ/external/organ = user.get_organ(hand_slot)
- if(istype(organ) && organ.is_washable)
- found_hand = TRUE
- break
-
- if(!found_hand)
- return
-
- var/decl/pronouns/pronouns = user.get_pronouns()
- if(isturf(target))
- var/turf/turf = target
- var/fluid = turf.get_fluid_name()
- user.visible_message(
- SPAN_NOTICE("\The [user] washes [pronouns.his] hands in \the [fluid]."),
- SPAN_NOTICE("You wash your hands in \the [fluid].")
- )
- else
- user.visible_message(
- SPAN_NOTICE("\The [user] washes [pronouns.his] hands in \the [target]."),
- SPAN_NOTICE("You wash your hands in \the [target].")
- )
-
- user.clean()
- playsound(user.loc, 'sound/effects/slosh.ogg', 25, 1)
- user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
-
-/decl/interaction_handler/drink
- name = "Drink"
- expected_target_type = /atom
- interaction_flags = INTERACTION_NEEDS_PHYSICAL_INTERACTION | INTERACTION_NEVER_AUTOMATIC
-
-/decl/interaction_handler/drink/is_possible(atom/target, mob/user, obj/item/prop)
- return ..() && ATOM_IS_OPEN_CONTAINER(target) && target?.reagents?.total_volume && user.check_has_mouth() && !istype(target, /obj/item)
-
-/decl/interaction_handler/drink/invoked(atom/target, mob/user, obj/item/prop)
-
- // Items can be picked up and drunk from, this interaction is for turfs and structures.
- if(istype(target, /obj/item))
- return
-
- if(!user.check_has_mouth())
- target.show_food_no_mouth_message(user, user)
- return
-
- if(!target?.reagents?.total_volume)
- target.show_food_empty_message(user, EATING_METHOD_DRINK)
- return
-
- if(!user.can_eat_food_currently(null, user, EATING_METHOD_DRINK))
- return
-
- var/blocked = user.check_mouth_coverage()
- if(blocked)
- to_chat(user, SPAN_NOTICE("\The [blocked] is in the way!"))
- return
-
- var/fluid_name = "\the [target]"
- if(isturf(target))
- var/turf/target_turf = target
- fluid_name = "\the [target_turf.get_fluid_name()]"
-
- user.visible_message(
- SPAN_NOTICE("\The [user] drinks from [fluid_name]."),
- SPAN_NOTICE("You drink from [fluid_name].")
- )
- target.reagents.trans_to_mob(user, 5, CHEM_INGEST)
- playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1)
- user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
diff --git a/code/game/objects/items/_item_materials.dm b/code/game/objects/items/_item_materials.dm
index 7aaf5d6bb267..261a8c5f5d0d 100644
--- a/code/game/objects/items/_item_materials.dm
+++ b/code/game/objects/items/_item_materials.dm
@@ -105,7 +105,7 @@
/obj/item/proc/update_name()
var/list/new_name = list(base_name || initial(name))
- if(material_alteration & MAT_FLAG_ALTERATION_NAME)
+ if(istype(material) && (material_alteration & MAT_FLAG_ALTERATION_NAME))
new_name.Insert(1, material.adjective_name)
if(name_prefix)
new_name.Insert(1, name_prefix)
diff --git a/code/game/objects/items/_item_melting.dm b/code/game/objects/items/_item_melting.dm
index d835d7d1c7de..318d8f288231 100644
--- a/code/game/objects/items/_item_melting.dm
+++ b/code/game/objects/items/_item_melting.dm
@@ -16,16 +16,22 @@
try_burn_wearer(holder, holder.get_equipped_slot_for_item(src))
// Temp gate until generalized temperature-based melting works properly.
- if(istype(loc, /obj/item/chems/crucible))
- // Check if this is meltable at all.
- var/list/meltable_materials
- for(var/mat in matter)
- var/decl/material/melt_material = GET_DECL(mat)
- if(!isnull(melt_material.melting_point) && temperature >= melt_material.melting_point)
- LAZYDISTINCTADD(meltable_materials, melt_material)
- if(length(meltable_materials))
- . = null // Don't return PROCESS_KILL here.
- handle_melting(meltable_materials)
+ var/static/list/_melting_containers = list(
+ /obj/item/chems/crucible,
+ /obj/item/organ/internal/stomach
+ )
+ if(!is_type_in_list(loc, _melting_containers))
+ return
+
+ // Check if this is meltable at all.
+ var/list/meltable_materials
+ for(var/mat in matter)
+ var/decl/material/melt_material = GET_DECL(mat)
+ if(!isnull(melt_material.melting_point) && temperature >= melt_material.melting_point)
+ LAZYDISTINCTADD(meltable_materials, melt_material)
+ if(length(meltable_materials))
+ . = null // Don't return PROCESS_KILL here.
+ handle_melting(meltable_materials)
/obj/item/place_melted_product(list/meltable_materials)
diff --git a/code/game/objects/items/_item_reagents.dm b/code/game/objects/items/_item_reagents.dm
index e34b7fd204ed..cf7a09c7a708 100644
--- a/code/game/objects/items/_item_reagents.dm
+++ b/code/game/objects/items/_item_reagents.dm
@@ -1,5 +1,5 @@
-/obj/item/proc/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) // This goes into afterattack
- if(!istype(target) || (target.atom_flags & ATOM_FLAG_OPEN_CONTAINER))
+/obj/item/proc/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target, skip_container_check = FALSE) // This goes into afterattack
+ if(!istype(target) || (!skip_container_check && (target.atom_flags & ATOM_FLAG_OPEN_CONTAINER)))
return FALSE
if(!target.reagents || !target.reagents.total_volume)
diff --git a/code/game/objects/items/devices/radio/headsets_shared.dm b/code/game/objects/items/devices/radio/headsets_shared.dm
index c591cb4a83ac..6c5551ea9839 100644
--- a/code/game/objects/items/devices/radio/headsets_shared.dm
+++ b/code/game/objects/items/devices/radio/headsets_shared.dm
@@ -221,6 +221,18 @@
encryption_keys = list(/obj/item/encryptionkey/raider)
analog_secured = list((access_raider) = TRUE)
+/obj/item/encryptionkey/hacked
+ can_decrypt = list(access_hacked)
+ origin_tech = @'{"esoteric":3}'
+
+/obj/item/encryptionkey/hacked/Initialize(ml, material_key)
+ . = ..()
+ can_decrypt |= get_all_station_access()
+
+/obj/item/radio/headset/hacked
+ origin_tech = @'{"esoteric":3}'
+ encryption_keys = list(/obj/item/encryptionkey/hacked)
+
// Bowman alts
/obj/item/radio/headset/headset_mining/bowman
name = "mining bowman radio headset"
diff --git a/code/game/objects/items/devices/tvcamera.dm b/code/game/objects/items/devices/tvcamera.dm
index bbcbc43e4889..272de8433723 100644
--- a/code/game/objects/items/devices/tvcamera.dm
+++ b/code/game/objects/items/devices/tvcamera.dm
@@ -96,6 +96,7 @@
update_held_icon()
/* Assembly by a roboticist */
+// TODO: Make this slapcrafting or remove tvcamera/tvassembly entirely
/obj/item/robot_parts/head/attackby(var/obj/item/assembly/S, mob/user)
if (!istype(S, /obj/item/assembly/infra))
return ..()
diff --git a/code/game/objects/items/flame/_flame.dm b/code/game/objects/items/flame/_flame.dm
index bee61f2c54c6..86fa054e41ab 100644
--- a/code/game/objects/items/flame/_flame.dm
+++ b/code/game/objects/items/flame/_flame.dm
@@ -125,6 +125,9 @@
update_attack_force()
update_icon()
+ if(ismob(loc)) // not very robust for things like accessories...
+ update_held_icon()
+ update_clothing_icon()
if(istype(loc, /obj/structure/wall_sconce))
loc.update_icon()
@@ -167,14 +170,7 @@
if(waterproof)
return
- var/check_depth = FLUID_PUDDLE
- if(ismob(loc))
- var/mob/holder = loc
- if(!holder.current_posture?.prone)
- check_depth = FLUID_OVER_MOB_HEAD
- else
- check_depth = FLUID_SHALLOW
- if(fluids.total_volume >= check_depth)
+ if(fluids.total_volume >= FLUID_PUDDLE)
snuff_out(no_message = TRUE)
/obj/item/flame/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
diff --git a/code/game/objects/items/flame/flame_torch.dm b/code/game/objects/items/flame/flame_torch.dm
index 26f616a4a47c..0e2f14c1022f 100644
--- a/code/game/objects/items/flame/flame_torch.dm
+++ b/code/game/objects/items/flame/flame_torch.dm
@@ -13,10 +13,6 @@
var/head_material = /decl/material/solid/organic/cloth
var/burnt = FALSE
-/obj/item/flame/torch/Initialize()
- . = ..()
- set_color(null) // clear our scent color
-
/obj/item/flame/torch/get_available_scents()
var/static/list/available_scents = list(
/decl/scent_type/woodsmoke
@@ -34,6 +30,7 @@
/obj/item/flame/torch/Initialize(var/ml, var/material_key, var/_head_material)
. = ..()
+ set_color(null) // clear our scent color. TODO: allow flame items to disable scent color setting in the first place
if(_head_material)
head_material = _head_material
@@ -76,11 +73,11 @@
if(head_material)
var/decl/material/head_mat = GET_DECL(head_material)
if(burnt)
- add_overlay(overlay_image(icon, "[icon_state]-burnt", head_mat.color, flags = RESET_COLOR))
+ add_overlay(overlay_image(icon, "[icon_state]-burnt", head_mat.color, flags = RESET_COLOR|KEEP_APART))
else
- add_overlay(overlay_image(icon, "[icon_state]-head", head_mat.color, flags = RESET_COLOR))
+ add_overlay(overlay_image(icon, "[icon_state]-head", head_mat.color, flags = RESET_COLOR|KEEP_APART))
if(lit)
- add_overlay(overlay_image(icon, "[icon_state]-lit", flags = RESET_COLOR))
+ add_overlay(overlay_image(icon, "[icon_state]-lit", flags = RESET_COLOR|KEEP_APART))
/obj/item/flame/torch/get_sconce_overlay()
. = list(overlay_image(icon, "[icon_state]-sconce", color = color, flags = RESET_COLOR))
diff --git a/code/game/objects/items/robot/robot_frame.dm b/code/game/objects/items/robot/robot_frame.dm
index bd8f71787b83..24f7474aa6e1 100644
--- a/code/game/objects/items/robot/robot_frame.dm
+++ b/code/game/objects/items/robot/robot_frame.dm
@@ -111,6 +111,7 @@
O.custom_name = created_name
O.updatename("Default")
+ clear_antag_roles(brainmob.mind, implanted = TRUE) // some antag roles persist
brainmob.mind.transfer_to(O)
if(O.mind && O.mind.assigned_role)
O.job = O.mind.assigned_role
diff --git a/code/game/objects/items/saddle.dm b/code/game/objects/items/saddle.dm
index cf7d51f0a3c5..2fb35ce01a44 100644
--- a/code/game/objects/items/saddle.dm
+++ b/code/game/objects/items/saddle.dm
@@ -9,7 +9,7 @@
material_alteration = MAT_FLAG_ALTERATION_ALL
/obj/item/saddle/mob_can_equip(mob/user, slot, disable_warning, force, ignore_equipped)
- if(!istype(user, /mob/living/simple_animal/passive/horse))
+ if(!istype(user) || !istype(user.get_bodytype(), /decl/bodytype/quadruped))
return FALSE
return ..()
diff --git a/code/game/objects/items/stacks/tiles/tile_types_wooden.dm b/code/game/objects/items/stacks/tiles/tile_types_wooden.dm
index fc9ec6517d76..a184391251f5 100644
--- a/code/game/objects/items/stacks/tiles/tile_types_wooden.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types_wooden.dm
@@ -28,6 +28,9 @@
/obj/item/stack/tile/wood/laminate
abstract_type = /obj/item/stack/tile/wood/laminate
+/obj/item/stack/tile/wood/rough
+ abstract_type = /obj/item/stack/tile/wood/rough
+
WOOD_TILE_SUBTYPE("oak", oak, oak)
WOOD_TILE_SUBTYPE("mahogany", mahogany, mahogany)
WOOD_TILE_SUBTYPE("maple", maple, maple)
@@ -35,6 +38,13 @@ WOOD_TILE_SUBTYPE("ebony", ebony, ebony)
WOOD_TILE_SUBTYPE("walnut", walnut, walnut)
WOOD_TILE_SUBTYPE("bamboo", bamboo, bamboo)
WOOD_TILE_SUBTYPE("yew", yew, yew)
+WOOD_TILE_SUBTYPE("rough oak", rough/oak, oak)
+WOOD_TILE_SUBTYPE("rough mahogany", rough/mahogany, mahogany)
+WOOD_TILE_SUBTYPE("rough maple", rough/maple, maple)
+WOOD_TILE_SUBTYPE("rough ebony", rough/ebony, ebony)
+WOOD_TILE_SUBTYPE("rough walnut", rough/walnut, walnut)
+WOOD_TILE_SUBTYPE("rough bamboo", rough/bamboo, bamboo)
+WOOD_TILE_SUBTYPE("rough yew", rough/yew, yew)
WOOD_TILE_SUBTYPE("oak laminate", laminate/oak, chipboard)
WOOD_TILE_SUBTYPE("mahogany laminate", laminate/mahogany, chipboard/mahogany)
WOOD_TILE_SUBTYPE("maple laminate", laminate/maple, chipboard/maple)
diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm
index bf4bfab6f1be..8c88b8edc0df 100644
--- a/code/game/objects/items/trash.dm
+++ b/code/game/objects/items/trash.dm
@@ -10,15 +10,12 @@
var/age = 0
/obj/item/trash/Initialize(mapload, var/_age)
+ if(!mapload)
+ SSpersistence.track_value(src, /decl/persistence_handler/filth/trash)
. = ..(mapload)
if(!isnull(_age))
age = _age
-/obj/item/trash/Initialize(var/ml)
- if(!ml)
- SSpersistence.track_value(src, /decl/persistence_handler/filth/trash)
- . = ..()
-
/obj/item/trash/Destroy()
SSpersistence.forget_value(src, /decl/persistence_handler/filth/trash)
. = ..()
diff --git a/code/game/objects/items/waterskin.dm b/code/game/objects/items/waterskin.dm
index 298388f36ecd..73852feaef06 100644
--- a/code/game/objects/items/waterskin.dm
+++ b/code/game/objects/items/waterskin.dm
@@ -1,4 +1,4 @@
-/obj/item/chems/waterskin
+/obj/item/chems/glass/waterskin
name = "waterskin"
desc = "A water-carrying vessel made from the dried stomach of some unfortunate animal."
icon = 'icons/obj/items/waterskin.dmi'
@@ -10,38 +10,40 @@
material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME
var/decl/material/stopper_material = /decl/material/solid/organic/cloth/hemp
-/obj/item/chems/waterskin/proc/get_stopper_message()
+/obj/item/chems/glass/waterskin/can_lid()
+ return FALSE // We handle it in attack_self().
+
+/obj/item/chems/glass/waterskin/proc/get_stopper_message()
var/decl/material/stopper_material_instance = GET_DECL(stopper_material)
return "You tie the neck of \the [src] closed with \a [stopper_material_instance.adjective_name] cord."
-/obj/item/chems/waterskin/proc/get_unstopper_message()
+/obj/item/chems/glass/waterskin/proc/get_unstopper_message()
var/decl/material/stopper_material_instance = GET_DECL(stopper_material)
return "You untie \the [stopper_material_instance.adjective_name] cord from around the neck of \the [src]."
-/obj/item/chems/waterskin/proc/get_stopper_overlay()
+/obj/item/chems/glass/waterskin/proc/get_stopper_overlay()
if(ATOM_IS_OPEN_CONTAINER(src))
return null
var/decl/material/stopper_material_instance = GET_DECL(stopper_material)
return overlay_image(icon, "[icon_state]-stopper", stopper_material_instance.color, RESET_COLOR | RESET_ALPHA)
-/obj/item/chems/waterskin/attack_self()
- . = ..()
- if(!.)
- if(ATOM_IS_OPEN_CONTAINER(src))
- to_chat(usr, SPAN_NOTICE(get_stopper_message()))
- atom_flags &= ~ATOM_FLAG_OPEN_CONTAINER
- else
- to_chat(usr, SPAN_NOTICE(get_unstopper_message()))
- atom_flags |= ATOM_FLAG_OPEN_CONTAINER
- update_icon()
+/obj/item/chems/glass/waterskin/attack_self()
+ if(ATOM_IS_OPEN_CONTAINER(src))
+ to_chat(usr, SPAN_NOTICE(get_stopper_message()))
+ atom_flags &= ~ATOM_FLAG_OPEN_CONTAINER
+ else
+ to_chat(usr, SPAN_NOTICE(get_unstopper_message()))
+ atom_flags |= ATOM_FLAG_OPEN_CONTAINER
+ update_icon()
+ return TRUE
-/obj/item/chems/waterskin/on_update_icon() // TODO: filled/empty sprites
+/obj/item/chems/glass/waterskin/on_update_icon() // TODO: filled/empty sprites
. = ..() // cuts overlays
var/image/stopper_overlay = get_stopper_overlay()
if(stopper_overlay)
add_overlay(stopper_overlay)
-/obj/item/chems/waterskin/crafted
+/obj/item/chems/glass/waterskin/crafted
desc = "A long and rather unwieldly water-carrying vessel."
icon = 'icons/obj/items/waterskin_crafted.dmi'
material = /decl/material/solid/organic/leather
@@ -49,17 +51,17 @@
material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC
stopper_material = /decl/material/solid/organic/wood/maple
-/obj/item/chems/waterskin/crafted/get_stopper_message()
+/obj/item/chems/glass/waterskin/crafted/get_stopper_message()
var/decl/material/stopper_material_instance = GET_DECL(stopper_material)
return "You insert \a [stopper_material_instance.adjective_name] stopper in the neck of \the [src]."
-/obj/item/chems/waterskin/crafted/get_unstopper_message()
+/obj/item/chems/glass/waterskin/crafted/get_unstopper_message()
var/decl/material/stopper_material_instance = GET_DECL(stopper_material)
return "You remove \the [stopper_material_instance.adjective_name] stopper from the neck of \the [src]."
-/obj/item/chems/waterskin/crafted/wine
+/obj/item/chems/glass/waterskin/crafted/wine
name = "wineskin"
-/obj/item/chems/waterskin/crafted/wine/populate_reagents()
+/obj/item/chems/glass/waterskin/crafted/wine/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/ethanol/wine, reagents?.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/wine, reagents?.maximum_volume)
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index 8e40d1f38f80..f48b28762d0e 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -32,6 +32,7 @@
var/decl/hierarchy/h = GET_DECL(/decl/hierarchy/rcd_mode)
work_modes = h.children
work_mode = work_modes[1]
+ update_icon() //Initializes the ammo counter
/obj/item/rcd/use_on_mob(mob/living/target, mob/living/user, animate = TRUE)
return FALSE
@@ -45,10 +46,6 @@
to_chat(user, "The current mode is '[work_mode]'.")
to_chat(user, "It currently holds [stored_matter]/[max_stored_matter] matter-units.")
-/obj/item/rcd/Initialize()
- . = ..()
- update_icon() //Initializes the ammo counter
-
/obj/item/rcd/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/rcd_ammo))
var/obj/item/rcd_ammo/cartridge = W
diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm
index dd248df7bb77..7ff92bf32ad2 100644
--- a/code/game/objects/items/weapons/material/shards.dm
+++ b/code/game/objects/items/weapons/material/shards.dm
@@ -53,6 +53,8 @@
. = ..()
// 1-(1-x)^2, so that glass shards with 0.3 opacity end up somewhat visible at 0.51 opacity
alpha = 255 * (material ? (1 - (1 - material.opacity)**2) : 1)
+ if(has_handle)
+ add_overlay(overlay_image(icon, "handle", has_handle, RESET_COLOR))
/obj/item/shard/attackby(obj/item/W, mob/user)
if(IS_WELDER(W) && material.shard_can_repair)
@@ -80,11 +82,6 @@
return TRUE
return ..()
-/obj/item/shard/on_update_icon()
- . = ..()
- if(has_handle)
- add_overlay(overlay_image(icon, "handle", has_handle, RESET_COLOR))
-
/obj/item/shard/Crossed(atom/movable/AM)
..()
if(!isliving(AM))
diff --git a/code/game/objects/items/weapons/melee/energy_sword.dm b/code/game/objects/items/weapons/melee/energy_sword.dm
index 3d20dd638d3e..045040acb762 100644
--- a/code/game/objects/items/weapons/melee/energy_sword.dm
+++ b/code/game/objects/items/weapons/melee/energy_sword.dm
@@ -20,9 +20,6 @@
if(!lighting_color)
lighting_color = blade_color
. = ..()
-
-/obj/item/energy_blade/sword/Initialize()
- . = ..()
set_extension(src, /datum/extension/demolisher/energy)
/obj/item/energy_blade/sword/is_special_cutting_tool(var/high_power)
diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm
index 0b2da5f210ae..37304ae49fcc 100644
--- a/code/game/objects/items/weapons/paint.dm
+++ b/code/game/objects/items/weapons/paint.dm
@@ -22,6 +22,12 @@
add_to_reagents(pigment, amt)
add_to_reagents(/decl/material/liquid/paint, amt)
+/obj/item/chems/glass/paint/get_edible_material_amount(mob/eater)
+ return 0
+
+/obj/item/chems/glass/paint/get_utensil_food_type()
+ return null
+
/obj/item/chems/glass/paint/on_update_icon()
. = ..()
if(reagents?.total_volume)
diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm
index 7800b0131cd6..81ae83daba05 100644
--- a/code/game/objects/items/weapons/policetape.dm
+++ b/code/game/objects/items/weapons/policetape.dm
@@ -250,7 +250,7 @@ var/global/list/image/hazard_overlays //Cached hazard floor overlays for the bar
/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(B && !QDELETED(B))
+ if(!QDELETED(B))
B.update_icon()
if(!QDELETED(src))
@@ -261,10 +261,11 @@ var/global/list/image/hazard_overlays //Cached hazard floor overlays for the bar
neighbors = 0
for (var/look_dir in global.cardinal)
var/turf/target_turf = get_step(src, look_dir)
- var/obj/structure/tape_barricade/B = locate(/obj/structure/tape_barricade, target_turf)
- //We connect to walls and other tape_barricades
- if((B && !QDELETED(B)) || (!B && target_turf?.is_wall()))
- neighbors |= 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()
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index 14a20b4125c1..fb4d2bb67566 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -17,17 +17,14 @@
/obj/item/backpack/can_contaminate()
return FALSE
-/obj/item/backpack/equipped()
- if(!has_extension(src, /datum/extension/appearance))
- set_extension(src, /datum/extension/appearance/cardborg)
- ..()
-
/obj/item/backpack/attackby(obj/item/W, mob/user)
if (storage?.use_sound)
playsound(src.loc, storage.use_sound, 50, 1, -5)
return ..()
/obj/item/backpack/equipped(var/mob/user, var/slot)
+ if(!has_extension(src, /datum/extension/appearance))
+ set_extension(src, /datum/extension/appearance/cardborg)
if (slot == slot_back_str && storage?.use_sound)
playsound(loc, storage.use_sound, 50, 1, -5)
return ..(user, slot)
diff --git a/code/game/objects/items/weapons/storage/nuggets.dm b/code/game/objects/items/weapons/storage/nuggets.dm
new file mode 100644
index 000000000000..3ecc72ce2270
--- /dev/null
+++ b/code/game/objects/items/weapons/storage/nuggets.dm
@@ -0,0 +1,63 @@
+/datum/storage/box/nuggets
+ can_hold = list(/obj/item/food/nugget)
+ var/expected_nugget_count = 10
+
+/datum/storage/box/nuggets/New()
+ max_storage_space = /obj/item/food/nugget::w_class * expected_nugget_count
+ ..()
+
+/datum/storage/box/nuggets/twenty
+ expected_nugget_count = 20
+
+/datum/storage/box/nuggets/forty
+ expected_nugget_count = 40
+
+/obj/item/box/nuggets
+ name = "10-piece nuggets box"
+ icon = 'icons/obj/items/storage/nugget_box.dmi'
+ icon_state = "nuggetbox_ten"
+ desc = "A share pack of golden chicken nuggets in various fun shapes. Rumours of the rare and deadly 'fifth nugget shape' remain unsubstantiated."
+ storage = /datum/storage/box/nuggets
+ center_of_mass = @'{"x":16,"y":9}'
+
+/obj/item/box/nuggets/Initialize(ml, material_key)
+ . = ..()
+ update_icon()
+
+/obj/item/box/nuggets/WillContain()
+ . = list()
+ if(istype(storage, /datum/storage/box/nuggets))
+ var/datum/storage/box/nuggets/nugget_box = storage
+ for(var/i = 1 to nugget_box.expected_nugget_count)
+ . += /obj/item/food/nugget
+
+/obj/item/box/nuggets/on_update_icon()
+ var/datum/storage/box/nuggets/nugget_box = storage
+ if(length(contents) == 0 || !istype(nugget_box))
+ icon_state = "[initial(icon_state)]_empty"
+ else if(length(contents) >= nugget_box.expected_nugget_count)
+ icon_state = "[initial(icon_state)]_full"
+ else
+ icon_state = initial(icon_state)
+
+// Subtypes below.
+/obj/item/box/nuggets/twenty
+ name = "20-piece nuggets box"
+ icon_state = "nuggetbox_twenty"
+ storage = /datum/storage/box/nuggets/twenty
+
+/obj/item/box/nuggets/twenty/WillContain()
+ . = list()
+ for(var/i = 1 to 20)
+ . += /obj/item/food/nugget
+
+/obj/item/box/nuggets/twenty/empty/WillContain()
+ return
+
+/obj/item/box/nuggets/forty
+ name = "40-piece nuggets box"
+ icon_state = "nuggetbox_forty"
+ storage = /datum/storage/box/nuggets/forty
+
+/obj/item/box/nuggets/forty/empty/WillContain()
+ return
diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm
index 3b9c293256e1..615c00682916 100644
--- a/code/game/objects/items/weapons/tools/weldingtool.dm
+++ b/code/game/objects/items/weapons/tools/weldingtool.dm
@@ -432,7 +432,7 @@
return TRUE
return ..()
-/obj/item/chems/welder_tank/standard_dispenser_refill(mob/user, obj/structure/reagent_dispensers/target)
+/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
diff --git a/code/game/objects/random/subtypes/clothing.dm b/code/game/objects/random/subtypes/clothing.dm
index f9bac2fd1c41..8524aff474c2 100644
--- a/code/game/objects/random/subtypes/clothing.dm
+++ b/code/game/objects/random/subtypes/clothing.dm
@@ -238,19 +238,3 @@
/obj/item/clothing/suit/space/void/medical/alt
)
return spawnable_choices
-
-/obj/random/hardsuit
- name = "Random Hardsuit"
- desc = "This is a random hardsuit control module."
- icon = 'icons/obj/rig_modules.dmi'
- 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/hacker,
- /obj/item/rig/light/stealth,
- /obj/item/rig/light
- )
- return spawnable_choices
diff --git a/code/game/objects/random/subtypes/maintenance.dm b/code/game/objects/random/subtypes/maintenance.dm
index 0df746fd50a8..b141867e7e15 100644
--- a/code/game/objects/random/subtypes/maintenance.dm
+++ b/code/game/objects/random/subtypes/maintenance.dm
@@ -209,14 +209,10 @@ something, make sure it's not in one of the other lists.*/
var/static/list/spawnable_choices = list(
/obj/random/maintenance/clean = 320,
/obj/item/clothing/head/soft/sec = 4,
- /obj/item/clothing/head/soft/sec/corp = 4,
/obj/item/backpack/security = 3,
/obj/item/backpack/satchel/sec = 3,
/obj/item/clothing/shoes/jackboots = 3,
/obj/item/clothing/suit/armor/vest = 3,
- /obj/item/clothing/head/beret/corp/sec = 3,
- /obj/item/clothing/head/beret/corp/sec/corporate/hos = 3,
- /obj/item/clothing/head/beret/corp/sec/navy/officer = 3,
/obj/item/flashlight/maglight = 2,
/obj/item/flash = 2,
/obj/item/clothing/mask/balaclava = 2,
@@ -226,7 +222,6 @@ something, make sure it's not in one of the other lists.*/
/obj/item/belt/security = 2,
/obj/item/clothing/glasses/hud/security = 2,
/obj/item/clothing/head/helmet = 2,
- /obj/item/clothing/suit/armor/vest/security = 2,
/obj/item/clothing/webbing/drop_pouches/black = 2,
/obj/item/clothing/head/earmuffs = 2,
/obj/item/handcuffs = 2,
diff --git a/code/game/objects/random/subtypes/misc.dm b/code/game/objects/random/subtypes/misc.dm
index b5206b950d30..4ccde91270d2 100644
--- a/code/game/objects/random/subtypes/misc.dm
+++ b/code/game/objects/random/subtypes/misc.dm
@@ -465,16 +465,6 @@
)
return spawnable_choices
-/obj/random/crayon
- name = "random crayon"
- desc = "This is a random crayon."
- icon = 'icons/obj/items/crayons.dmi'
- icon_state = "crayonred"
-
-/obj/random/crayon/spawn_choices()
- var/static/list/spawnable_choices = subtypesof(/obj/item/pen/crayon)
- return spawnable_choices
-
/obj/random/umbrella
name = "Random Umbrella"
desc = "This is a random umbrella."
diff --git a/code/game/objects/random/subtypes/paperwork.dm b/code/game/objects/random/subtypes/paperwork.dm
index 061b4944609a..a073a9d95067 100644
--- a/code/game/objects/random/subtypes/paperwork.dm
+++ b/code/game/objects/random/subtypes/paperwork.dm
@@ -12,7 +12,8 @@
icon_state = "crayonred"
/obj/random/crayon/spawn_choices()
- return subtypesof(/obj/item/pen/crayon)
+ var/static/list/spawnable_choices = subtypesof(/obj/item/pen/crayon)
+ return spawnable_choices
/obj/random/clipboard
name = "random clipboard"
diff --git a/code/game/objects/structures/__structure.dm b/code/game/objects/structures/__structure.dm
index 29c20b4b6d9a..f1fb8d4a2c11 100644
--- a/code/game/objects/structures/__structure.dm
+++ b/code/game/objects/structures/__structure.dm
@@ -88,19 +88,19 @@
if(tool_interaction_flags & TOOL_INTERACTION_ANCHOR)
if(anchored)
- to_chat(user, SPAN_SUBTLE("Can be unanchored with a wrench, and moved around."))
+ to_chat(user, SPAN_SUBTLE("Can be unanchored with a wrench or hammer, and moved around."))
else
- to_chat(user, SPAN_SUBTLE("Can be anchored in place with a wrench."))
+ to_chat(user, SPAN_SUBTLE("Can be anchored in place with a wrench or hammer."))
if(tool_interaction_flags & TOOL_INTERACTION_DECONSTRUCT)
- var/removed_with = "a crowbar"
+ var/removed_with = "a crowbar or hammer"
if(material && material.removed_by_welder)
removed_with = "a welding torch"
if(tool_interaction_flags & TOOL_INTERACTION_ANCHOR)
if(anchored)
to_chat(user, SPAN_SUBTLE("Can be deconstructed with [removed_with]."))
else
- to_chat(user, SPAN_SUBTLE("Can be deconstructed with [removed_with], if anchored down with a wrench first."))
+ to_chat(user, SPAN_SUBTLE("Can be deconstructed with [removed_with], if anchored down with a wrench or hammer first."))
else
to_chat(user, SPAN_SUBTLE("Can be deconstructed with [removed_with]."))
@@ -159,7 +159,7 @@
last_damage_message = 0.75
/obj/structure/physically_destroyed(var/skip_qdel)
- if(..(TRUE))
+ if((. = ..(TRUE)))
return dismantle_structure()
/obj/structure/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
diff --git a/code/game/objects/structures/_structure_construction.dm b/code/game/objects/structures/_structure_construction.dm
index 3e17a59ffe41..a069498e7d86 100644
--- a/code/game/objects/structures/_structure_construction.dm
+++ b/code/game/objects/structures/_structure_construction.dm
@@ -2,6 +2,43 @@
var/wired
var/tool_interaction_flags
+/obj/structure/proc/handle_default_hammer_attackby(var/mob/user, var/obj/item/hammer)
+
+ // Resolve ambiguous interactions.
+ var/can_deconstruct = (tool_interaction_flags & TOOL_INTERACTION_DECONSTRUCT) && can_dismantle(user)
+ var/can_unanchor = (tool_interaction_flags & TOOL_INTERACTION_ANCHOR) && can_unanchor(user)
+ if(can_deconstruct && can_unanchor)
+ var/choice = alert(user, "Do you wish to [anchored ? "unanchor" : "anchor"] or dismantle this structure?", "Tool Choice", (anchored ? "Unanchor" : "Anchor"), "Deconstruct", "Cancel")
+ if(!choice || choice == "Cancel" || QDELETED(src) || QDELETED(user) || QDELETED(hammer) || !CanPhysicallyInteract(user) || user.get_active_held_item() != hammer)
+ return TRUE
+ if(choice == "Deconstruct")
+ can_unanchor = FALSE
+ else
+ can_deconstruct = FALSE
+
+ if(can_unanchor)
+ playsound(src.loc, 'sound/items/Deconstruct.ogg', 100, 1)
+ visible_message(SPAN_NOTICE("\The [user] begins [anchored ? "unanchoring [src]" : "anchoring [src] in place"] with \the [hammer]."))
+ if(!do_after(user, 4 SECONDS, src) || QDELETED(src))
+ return TRUE
+ playsound(src.loc, 'sound/items/Deconstruct.ogg', 100, 1)
+ anchored = !anchored
+ visible_message(SPAN_NOTICE("\The [user] has [anchored ? "anchored" : "unanchored"] \the [src] with \the [hammer]."))
+ update_icon()
+ return TRUE
+
+ if(can_deconstruct)
+ playsound(loc, 'sound/items/Crowbar.ogg', 50, 1)
+ visible_message(SPAN_NOTICE("\The [user] starts knocking apart \the [src] with \the [hammer]."))
+ if(!do_after(user, 5 SECONDS, src) || QDELETED(src))
+ return TRUE
+ playsound(loc, 'sound/items/Crowbar.ogg', 50, 1)
+ visible_message(SPAN_NOTICE("\The [user] completely dismantles \the [src] with \the [hammer]."))
+ dismantle_structure(user)
+ return TRUE
+
+ return FALSE
+
/obj/structure/proc/handle_default_wrench_attackby(var/mob/user, var/obj/item/wrench)
if((tool_interaction_flags & TOOL_INTERACTION_ANCHOR) && can_unanchor(user))
playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
@@ -122,6 +159,8 @@
take_damage(force, used_item.atom_damage_type)
. = TRUE
+ else if(IS_HAMMER(used_item))
+ . = handle_default_hammer_attackby(user, used_item)
else if(IS_WRENCH(used_item))
. = handle_default_wrench_attackby(user, used_item)
else if(IS_SCREWDRIVER(used_item))
diff --git a/code/game/objects/structures/_structure_materials.dm b/code/game/objects/structures/_structure_materials.dm
index 3245a10faa26..f3c619b1f61b 100644
--- a/code/game/objects/structures/_structure_materials.dm
+++ b/code/game/objects/structures/_structure_materials.dm
@@ -65,19 +65,25 @@
if(parts_type && !ispath(parts_type, /obj/item/stack))
for(var/i = 1 to max(parts_amount, 1))
LAZYADD(., create_dismantled_part(T))
- else
- for(var/mat in matter)
- var/decl/material/M = GET_DECL(mat)
- var/placing
- if(isnull(parts_amount))
- placing = (matter[mat] / SHEET_MATERIAL_AMOUNT) * 0.75
- if(parts_type)
- placing *= atom_info_repository.get_matter_multiplier_for(parts_type, mat, placing)
- placing = floor(placing)
- else
- placing = parts_amount
- if(placing > 0)
+ return
+
+ for(var/mat in matter)
+
+ var/decl/material/M = GET_DECL(mat)
+ var/placing
+ if(isnull(parts_amount))
+ placing = (matter[mat] / SHEET_MATERIAL_AMOUNT) * 0.75
+ if(material == M && parts_type)
+ placing *= atom_info_repository.get_matter_multiplier_for(parts_type, mat, placing)
+ placing = floor(placing)
+ else
+ placing = parts_amount
+
+ if(placing > 0)
+ if(material == M)
LAZYADD(., M.place_dismantled_product(T, FALSE, placing, parts_type))
+ else
+ LAZYADD(., M.place_dismantled_product(T, FALSE, placing))
/obj/structure/proc/clear_materials()
matter = null
diff --git a/code/game/objects/structures/barrels/barrel.dm b/code/game/objects/structures/barrels/barrel.dm
index c0755926e96f..b28986d55923 100644
--- a/code/game/objects/structures/barrels/barrel.dm
+++ b/code/game/objects/structures/barrels/barrel.dm
@@ -16,6 +16,7 @@
volume = 7500
movable_flags = MOVABLE_FLAG_WHEELED
throwpass = TRUE
+ tool_interaction_flags = TOOL_INTERACTION_ANCHOR | TOOL_INTERACTION_DECONSTRUCT
// Should we draw our lid and liquid contents as overlays?
var/show_liquid_contents = TRUE
// Rivets, bands, etc. Currently just cosmetic.
@@ -30,12 +31,22 @@
if(. == INITIALIZE_HINT_NORMAL && storage)
return INITIALIZE_HINT_LATELOAD // we want to grab our turf contents.
-/obj/structure/reagent_dispensers/barrel/attackby(obj/item/W, mob/user)
+// Overrides due to wonky reagent_dispeners opencontainer flag handling.
+/obj/structure/reagent_dispensers/barrel/can_be_poured_from(mob/user, atom/target)
+ return (reagents?.maximum_volume > 0)
+/obj/structure/reagent_dispensers/barrel/can_be_poured_into(mob/user, atom/target)
+ return (reagents?.maximum_volume > 0)
+// Override to skip open container check.
+/obj/structure/reagent_dispensers/barrel/can_drink_from(mob/user)
+ return reagents?.total_volume && user.check_has_mouth()
+
+/obj/structure/reagent_dispensers/barrel/get_alt_interactions(mob/user)
. = ..()
- if(!. && user.check_intent(I_FLAG_HELP) && reagents?.total_volume > FLUID_PUDDLE)
- user.visible_message(SPAN_NOTICE("\The [user] dips \the [W] into \the [reagents.get_primary_reagent_name()]."))
- W.fluid_act(reagents)
- return TRUE
+ if(reagents?.total_volume >= FLUID_PUDDLE)
+ LAZYADD(., /decl/interaction_handler/dip_item)
+ LAZYADD(., /decl/interaction_handler/fill_from)
+ if(user?.get_active_held_item())
+ LAZYADD(., /decl/interaction_handler/empty_into)
/obj/structure/reagent_dispensers/barrel/LateInitialize(mapload, ...)
..()
@@ -47,7 +58,7 @@
storage.handle_item_insertion(null, thing)
/obj/structure/reagent_dispensers/barrel/on_reagent_change()
- if(!(. = ..()))
+ if(!(. = ..()) || QDELETED(src))
return
var/primary_mat = reagents?.get_primary_reagent_name()
if(primary_mat)
@@ -70,11 +81,11 @@
var/overlay_amount = NONUNIT_CEILING(reagents.total_liquid_volume / reagents.maximum_volume * 100, 10)
var/image/filling_overlay = overlay_image(icon, "[icon_state]-[overlay_amount]", reagents.get_color(), RESET_COLOR | RESET_ALPHA)
add_overlay(filling_overlay)
- add_overlay(overlay_image(icon, "[icon_state]-lidopen", material.color, RESET_COLOR))
+ add_overlay(overlay_image(icon, "[icon_state]-lidopen", material?.color, RESET_COLOR))
if(metal_material)
add_overlay(overlay_image(icon, "[icon_state]-lidopen-metal", metal_material.color, RESET_COLOR))
else
- add_overlay(overlay_image(icon, "[icon_state]-lidclosed", material.color, RESET_COLOR))
+ add_overlay(overlay_image(icon, "[icon_state]-lidclosed", material?.color, RESET_COLOR))
if(metal_material)
add_overlay(overlay_image(icon, "[icon_state]-lidclosed-metal", metal_material.color, RESET_COLOR))
@@ -91,12 +102,12 @@
/obj/structure/reagent_dispensers/barrel/ebony/beer/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/ethanol/beer, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/beer, reagents.maximum_volume)
/obj/structure/reagent_dispensers/barrel/ebony/wine/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/ethanol/wine, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/wine, reagents.maximum_volume)
/obj/structure/reagent_dispensers/barrel/ebony/oil/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/nutriment/plant_oil, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/oil, reagents.maximum_volume)
diff --git a/code/game/objects/structures/barrels/cask.dm b/code/game/objects/structures/barrels/cask.dm
index 04dbb4ca1ba3..d3755dfe55e6 100644
--- a/code/game/objects/structures/barrels/cask.dm
+++ b/code/game/objects/structures/barrels/cask.dm
@@ -31,12 +31,12 @@
/obj/structure/reagent_dispensers/barrel/cask/ebony/beer/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/ethanol/beer, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/beer, reagents.maximum_volume)
/obj/structure/reagent_dispensers/barrel/cask/ebony/wine/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/ethanol/wine, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/wine, reagents.maximum_volume)
/obj/structure/reagent_dispensers/barrel/cask/ebony/oil/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/nutriment/plant_oil, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/oil, reagents.maximum_volume)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
index 710f7d92d059..806048ba7a13 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
@@ -64,12 +64,14 @@
/obj/structure/closet/secure_closet/pilot
name = "pilot locker"
req_access = list(access_xenobiology)
+ /// The jumpsuit type spawned for this locker. Exists to be overridden by the corporate modpack, which adds pilot jumpsuits.
+ var/jumpsuit_type = /obj/item/clothing/jumpsuit/white
/obj/structure/closet/secure_closet/pilot/WillContain()
return list(
/obj/item/backpack/parachute,
/obj/item/knife/utility,
- /obj/item/clothing/jumpsuit/pilot,
+ jumpsuit_type,
/obj/item/clothing/suit/jacket/bomber,
/obj/item/clothing/mask/gas/half,
/obj/item/clothing/shoes/color/black,
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index f9a8de10bf38..6df0fd7eb1cb 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -324,6 +324,29 @@
material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC
material = /decl/material/solid/organic/wood/oak
color = /decl/material/solid/organic/wood/oak::color
+ var/icon/overlay_icon = 'icons/obj/closets/bases/chest.dmi'
+ // TODO: Rework chest crafting so that this can use reinf_material instead.
+ /// The material used for the opacity and color of the trim overlay.
+ var/decl/material/overlay_material = /decl/material/solid/metal/iron
+
+/obj/structure/closet/crate/chest/Initialize()
+ . = ..()
+ if(ispath(overlay_material))
+ overlay_material = GET_DECL(overlay_material)
+ // icon update is already queued in parent because of closet appearance
+
+/obj/structure/closet/crate/chest/update_material_desc(override_desc)
+ ..()
+ if(overlay_material)
+ desc = "[desc] It has a trim made of [overlay_material.solid_name]."
+
+/obj/structure/closet/crate/chest/on_update_icon()
+ . = ..()
+ if(istype(overlay_material))
+ var/overlay_state = opened ? "open-overlay" : "base-overlay"
+ var/image/trim = overlay_image(overlay_icon, overlay_state, overlay_material.color, RESET_COLOR|RESET_ALPHA)
+ trim.alpha = clamp((50 + overlay_material.opacity * 255), 0, 255)
+ add_overlay(trim)
/obj/structure/closet/crate/chest/ebony
material = /decl/material/solid/organic/wood/ebony
diff --git a/code/game/objects/structures/fires.dm b/code/game/objects/structures/fires.dm
index cdb416489e39..e0fe3055aa7f 100644
--- a/code/game/objects/structures/fires.dm
+++ b/code/game/objects/structures/fires.dm
@@ -244,9 +244,6 @@
/obj/structure/fire_source/isflamesource()
return (lit == FIRE_LIT)
-/obj/structure/fire_source/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- return ..() || (istype(mover) && mover.checkpass(PASS_FLAG_TABLE))
-
/obj/structure/fire_source/proc/burn_material(var/decl/material/mat, var/amount)
var/effective_burn_temperature = get_effective_burn_temperature()
. = mat.get_burn_products(amount, effective_burn_temperature)
@@ -441,7 +438,6 @@
removed.add_thermal_energy(heat_transfer)
environment.merge(removed)
-
queue_icon_update()
/obj/structure/fire_source/proc/has_fuel()
@@ -492,10 +488,10 @@
try_light(1000)
/obj/structure/fire_source/CanPass(atom/movable/mover, turf/target, height, air_group)
- . = ..()
+ . = ..() || mover?.checkpass(PASS_FLAG_TABLE)
if(. && lit && ismob(mover))
var/mob/M = mover
- if(!MOVING_QUICKLY(M))
+ if(M.client && !M.current_posture?.prone && !MOVING_QUICKLY(M))
to_chat(M, SPAN_WARNING("You refrain from stepping into \the [src]."))
return FALSE
return ..()
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index c508eb305f99..a82c4c7733da 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -19,13 +19,6 @@
set_extension(src, /datum/extension/penetration/simple, 100)
. = ..()
-/obj/structure/girder/can_unanchor(var/mob/user)
- . = ..()
- var/turf/T = loc
- if(!anchored && . && (!istype(T) || T.is_open()))
- to_chat(user, SPAN_WARNING("You can only secure \the [src] to solid ground."))
- return FALSE
-
/obj/structure/girder/handle_default_screwdriver_attackby(var/mob/user, var/obj/item/screwdriver)
if(reinf_material)
@@ -88,6 +81,10 @@
to_chat(user, SPAN_WARNING("You must remove the support rods before you can dislodge \the [src]."))
return FALSE
. = ..()
+ var/turf/T = loc
+ if(!anchored && . && (!istype(T) || T.is_open()))
+ to_chat(user, SPAN_WARNING("You can only secure \the [src] to solid ground."))
+ return FALSE
/obj/structure/girder/can_dismantle(var/mob/user)
if(reinf_material)
diff --git a/code/game/objects/structures/tables.dm b/code/game/objects/structures/tables.dm
index 999ab76ec864..e1fced7cee86 100644
--- a/code/game/objects/structures/tables.dm
+++ b/code/game/objects/structures/tables.dm
@@ -636,6 +636,9 @@
return TRUE
return FALSE
+/obj/structure/table/handle_default_hammer_attackby(var/mob/user, var/obj/item/hammer)
+ return !reinf_material && ..()
+
/obj/structure/table/handle_default_wrench_attackby(var/mob/user, var/obj/item/wrench)
return !reinf_material && ..()
diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm
index 0dc8afefce6a..38feb74fd25d 100644
--- a/code/game/objects/structures/target_stake.dm
+++ b/code/game/objects/structures/target_stake.dm
@@ -15,11 +15,6 @@
dummy = null
. = ..()
-/obj/structure/target_stake/attackby(obj/item/used_item, mob/user)
- if(dummy?.repair_target_dummy(used_item, user))
- return TRUE
- return ..()
-
/obj/structure/target_stake/take_damage(damage, damage_type, damage_flags, inflicter, armor_pen, silent, do_update_health)
if(dummy)
. = dummy.take_damage(damage, damage_type, damage_flags, inflicter, armor_pen, silent, do_update_health)
@@ -42,6 +37,8 @@
return ..()
/obj/structure/target_stake/attackby(obj/item/used_item, mob/user)
+ if(dummy?.repair_target_dummy(used_item, user))
+ return TRUE
if(istype(used_item, /obj/item/training_dummy) && can_hold_dummy(user, used_item))
if(dummy)
to_chat(user, SPAN_WARNING("\The [src] is already holding \the [dummy]."))
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 454e6e9b6b53..549d7d913abd 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -49,6 +49,23 @@ var/global/list/hygiene_props = list()
if(clogged <= 0)
unclog()
return TRUE
+ //toilet paper interaction for clogging toilets and other facilities
+ if (istype(thing, /obj/item/stack/tape_roll/barricade_tape/toilet))
+ if (clogged == -1)
+ to_chat(user, SPAN_WARNING("Try as you might, you can not clog \the [src] with \the [thing]."))
+ return TRUE
+ if (clogged)
+ to_chat(user, SPAN_WARNING("\The [src] is already clogged."))
+ return TRUE
+ if (!do_after(user, 3 SECONDS, src))
+ to_chat(user, SPAN_WARNING("You must stay still to clog \the [src]."))
+ return TRUE
+ if (clogged || QDELETED(thing) || !user.try_unequip(thing))
+ return TRUE
+ to_chat(user, SPAN_NOTICE("You unceremoniously jam \the [src] with \the [thing]. What a rebel."))
+ clog(1)
+ qdel(thing)
+ return TRUE
. = ..()
/obj/structure/hygiene/examine(mob/user)
@@ -474,27 +491,6 @@ var/global/list/hygiene_props = list()
. = ..()
icon_state = "puddle"
-//toilet paper interaction for clogging toilets and other facilities
-
-/obj/structure/hygiene/attackby(obj/item/I, mob/user)
- if (!istype(I, /obj/item/stack/tape_roll/barricade_tape/toilet))
- return ..()
- if (clogged == -1)
- to_chat(user, SPAN_WARNING("Try as you might, you can not clog \the [src] with \the [I]."))
- return TRUE
- if (clogged)
- to_chat(user, SPAN_WARNING("\The [src] is already clogged."))
- return TRUE
- if (!do_after(user, 3 SECONDS, src))
- to_chat(user, SPAN_WARNING("You must stay still to clog \the [src]."))
- return TRUE
- if (clogged || QDELETED(I) || !user.try_unequip(I))
- return TRUE
- to_chat(user, SPAN_NOTICE("You unceremoniously jam \the [src] with \the [I]. What a rebel."))
- clog(1)
- qdel(I)
- return TRUE
-
////////////////////////////////////////////////////
// Toilet Paper Roll
////////////////////////////////////////////////////
diff --git a/code/game/objects/structures/well.dm b/code/game/objects/structures/well.dm
index 10c34059fea6..639cc2b263a1 100644
--- a/code/game/objects/structures/well.dm
+++ b/code/game/objects/structures/well.dm
@@ -18,6 +18,23 @@
can_toggle_open = FALSE
var/auto_refill
+/obj/structure/reagent_dispensers/well/get_alt_interactions(mob/user)
+ . = ..()
+ if(reagents?.total_volume >= FLUID_PUDDLE)
+ LAZYADD(., /decl/interaction_handler/dip_item)
+ LAZYADD(., /decl/interaction_handler/fill_from)
+ if(user?.get_active_held_item())
+ LAZYADD(., /decl/interaction_handler/empty_into)
+
+// Overrides due to wonky reagent_dispeners opencontainer flag handling.
+/obj/structure/reagent_dispensers/well/can_be_poured_from(mob/user, atom/target)
+ return (reagents?.maximum_volume > 0)
+/obj/structure/reagent_dispensers/well/can_be_poured_into(mob/user, atom/target)
+ return (reagents?.maximum_volume > 0)
+// Override to skip open container check.
+/obj/structure/reagent_dispensers/well/can_drink_from(mob/user)
+ return reagents?.total_volume && user.check_has_mouth()
+
/obj/structure/reagent_dispensers/well/populate_reagents()
. = ..()
if(auto_refill)
@@ -32,6 +49,10 @@
. = ..()
if(reagents?.total_volume)
add_overlay(overlay_image(icon, "[icon_state]-fluid", reagents.get_color(), (RESET_COLOR | RESET_ALPHA)))
+ if(istype(reinf_material)) // reinf_material -> roof and posts, at this point in time
+ var/image/roof_image = overlay_image(icon, "[icon_state]-roof", reinf_material.color, RESET_COLOR | RESET_ALPHA | KEEP_APART)
+ roof_image.pixel_y = 16 // we have to use 32x32 sprites but want this to be, effectively, 48x32
+ add_overlay(roof_image)
/obj/structure/reagent_dispensers/well/on_reagent_change()
if(!(. = ..()))
@@ -64,6 +85,9 @@
/obj/structure/reagent_dispensers/well/mapped
auto_refill = /decl/material/liquid/water
+/obj/structure/reagent_dispensers/well/mapped/covered
+ reinf_material = /decl/material/solid/organic/wood/walnut
+
/obj/structure/reagent_dispensers/well/wall_fountain
name = "wall fountain"
desc = "An intricately-constructed fountain set into a wall."
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index f0fed052f813..bb4bf1781075 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -207,6 +207,9 @@
playsound(loc, crowbar.get_tool_sound(TOOL_CROWBAR) || 'sound/items/Crowbar.ogg', 75, 1)
return TRUE
+/obj/structure/window/handle_default_hammer_attackby(mob/user, obj/item/hammer)
+ return FALSE
+
/obj/structure/window/handle_default_wrench_attackby(mob/user, obj/item/wrench)
if(anchored || (reinf_material && construction_state > CONSTRUCTION_STATE_NO_FRAME))
return FALSE // ineligible, allow other interactions to proceed
diff --git a/code/game/turfs/flooring/_flooring.dm b/code/game/turfs/flooring/_flooring.dm
index 9d3ce2f33cfd..a02efe3cb841 100644
--- a/code/game/turfs/flooring/_flooring.dm
+++ b/code/game/turfs/flooring/_flooring.dm
@@ -78,7 +78,7 @@ var/global/list/flooring_cache = list()
var/render_trenches = TRUE
var/floor_layer = TURF_LAYER
var/holographic = FALSE
- var/dirt_color = "#7c5e42"
+ var/dirt_color = /decl/material/solid/soil::color
var/list/burned_states
var/list/broken_states
diff --git a/code/game/turfs/flooring/flooring_grass.dm b/code/game/turfs/flooring/flooring_grass.dm
index a9e70bbf7368..8ac33265fdb8 100644
--- a/code/game/turfs/flooring/flooring_grass.dm
+++ b/code/game/turfs/flooring/flooring_grass.dm
@@ -38,9 +38,10 @@
. = ..() || "mask_grass"
/decl/flooring/grass/wild/handle_item_interaction(turf/floor/floor, mob/user, obj/item/item)
- if(IS_KNIFE(item) && harvestable)
+ var/decl/material/floor_material = floor.get_material()
+ if(IS_KNIFE(item) && harvestable && istype(floor_material) && floor_material.dug_drop_type)
if(item.do_tool_interaction(TOOL_KNIFE, user, floor, 3 SECONDS, start_message = "harvesting", success_message = "harvesting") && !QDELETED(floor) && floor.get_topmost_flooring() == src)
- new /obj/item/stack/material/bundle/grass(floor, rand(2,5))
+ new floor_material.dug_drop_type(floor, rand(2,5))
floor.set_flooring(/decl/flooring/grass)
return TRUE
return ..()
diff --git a/code/game/turfs/flooring/flooring_mud.dm b/code/game/turfs/flooring/flooring_mud.dm
index 59be34fdfad7..fd4866144b90 100644
--- a/code/game/turfs/flooring/flooring_mud.dm
+++ b/code/game/turfs/flooring/flooring_mud.dm
@@ -3,6 +3,7 @@
desc = "A stretch of thick, waterlogged mud."
icon = 'icons/turf/flooring/mud.dmi'
icon_base = "mud"
+ color = null // autoset from material
icon_edge_layer = FLOOR_EDGE_MUD
footstep_type = /decl/footsteps/mud
turf_flags = TURF_FLAG_BACKGROUND | TURF_IS_HOLOMAP_PATH | TURF_FLAG_ABSORB_LIQUID
@@ -45,7 +46,7 @@
icon = 'icons/turf/flooring/dirt.dmi'
icon_base = "dirt"
icon_edge_layer = FLOOR_EDGE_DIRT
- color = "#41311b"
+ color = null // autoset from material
footstep_type = /decl/footsteps/asteroid
turf_flags = TURF_FLAG_BACKGROUND | TURF_IS_HOLOMAP_PATH | TURF_FLAG_ABSORB_LIQUID
force_material = /decl/material/solid/soil
diff --git a/code/game/turfs/flooring/flooring_wood.dm b/code/game/turfs/flooring/flooring_wood.dm
index 9b2b75b0ffd2..b5fc086d42f4 100644
--- a/code/game/turfs/flooring/flooring_wood.dm
+++ b/code/game/turfs/flooring/flooring_wood.dm
@@ -53,6 +53,47 @@
build_type = /obj/item/stack/tile/wood/yew
force_material = /decl/material/solid/organic/wood/yew
+// Rough-hewn floors.
+/decl/flooring/wood/rough
+
+ name = "rough wooden floor"
+ desc = "A stretch of loosely-fitted, rough-hewn wooden planks."
+ icon = 'icons/turf/flooring/wood_alt.dmi'
+ icon_base = "wood_peasant"
+ has_base_range = 3
+ build_type = /obj/item/stack/tile/wood/rough
+ broken_states = null
+
+/decl/flooring/wood/rough/mahogany
+ color = /decl/material/solid/organic/wood/mahogany::color
+ build_type = /obj/item/stack/tile/wood/rough/mahogany
+ force_material = /decl/material/solid/organic/wood/mahogany
+
+/decl/flooring/wood/rough/maple
+ color = /decl/material/solid/organic/wood/maple::color
+ build_type = /obj/item/stack/tile/wood/rough/maple
+ force_material = /decl/material/solid/organic/wood/maple
+
+/decl/flooring/wood/rough/ebony
+ color = /decl/material/solid/organic/wood/ebony::color
+ build_type = /obj/item/stack/tile/wood/rough/ebony
+ force_material = /decl/material/solid/organic/wood/ebony
+
+/decl/flooring/wood/rough/walnut
+ color = /decl/material/solid/organic/wood/walnut::color
+ build_type = /obj/item/stack/tile/wood/rough/walnut
+ force_material = /decl/material/solid/organic/wood/walnut
+
+/decl/flooring/wood/rough/bamboo
+ color = /decl/material/solid/organic/wood/bamboo::color
+ build_type = /obj/item/stack/tile/wood/rough/bamboo
+ force_material = /decl/material/solid/organic/wood/bamboo
+
+/decl/flooring/wood/rough/yew
+ color = /decl/material/solid/organic/wood/yew::color
+ build_type = /obj/item/stack/tile/wood/rough/yew
+ force_material = /decl/material/solid/organic/wood/yew
+
// Chipboard/wood laminate floors. Uses older icons.
/decl/flooring/laminate
name = "wooden laminate floor"
diff --git a/code/game/turfs/floors/subtypes/floor_natural.dm b/code/game/turfs/floors/subtypes/floor_natural.dm
index 901257fd1651..5851afd8ab9c 100644
--- a/code/game/turfs/floors/subtypes/floor_natural.dm
+++ b/code/game/turfs/floors/subtypes/floor_natural.dm
@@ -8,7 +8,7 @@
name = "dirt"
icon = 'icons/turf/flooring/dirt.dmi'
icon_state = "dirt"
- color = "#41311b"
+ color = /decl/material/solid/soil::color // preview color
_base_flooring = /decl/flooring/dirt
/turf/floor/chlorine_sand
@@ -72,6 +72,7 @@
name = "mud"
icon = 'icons/turf/flooring/mud.dmi'
icon_state = "mud"
+ color = /decl/material/solid/soil::color // preview color
_base_flooring = /decl/flooring/mud
/turf/floor/mud/water
diff --git a/code/game/turfs/floors/subtypes/floor_wood.dm b/code/game/turfs/floors/subtypes/floor_wood.dm
index d5fa771be77a..eff98a2a1176 100644
--- a/code/game/turfs/floors/subtypes/floor_wood.dm
+++ b/code/game/turfs/floors/subtypes/floor_wood.dm
@@ -5,6 +5,12 @@
color = /decl/material/solid/organic/wood/oak::color
_flooring = /decl/flooring/wood
+#define WOOD_FLOOR_SUBTYPE(BASE, WOOD) \
+/turf/floor/##BASE/##WOOD { \
+ color = /decl/material/solid/organic/wood/##WOOD::color; \
+ _flooring = /decl/flooring/##BASE/##WOOD; \
+}
+
/turf/floor/wood/broken
icon_state = "wood_broken0"
_floor_broken = TRUE
@@ -31,29 +37,27 @@
icon_state = "wood_broken4"
_floor_broken = "broken4"
-/turf/floor/wood/mahogany
- color = /decl/material/solid/organic/wood/mahogany::color
- _flooring = /decl/flooring/wood/mahogany
-
-/turf/floor/wood/maple
- color = /decl/material/solid/organic/wood/maple::color
- _flooring = /decl/flooring/wood/maple
-
-/turf/floor/wood/ebony
- color = /decl/material/solid/organic/wood/ebony::color
- _flooring = /decl/flooring/wood/ebony
-
-/turf/floor/wood/walnut
- color = /decl/material/solid/organic/wood/walnut::color
- _flooring = /decl/flooring/wood/walnut
-
-/turf/floor/wood/bamboo
- color = /decl/material/solid/organic/wood/bamboo::color
- _flooring = /decl/flooring/wood/bamboo
+WOOD_FLOOR_SUBTYPE(wood, mahogany)
+WOOD_FLOOR_SUBTYPE(wood, maple)
+WOOD_FLOOR_SUBTYPE(wood, ebony)
+WOOD_FLOOR_SUBTYPE(wood, walnut)
+WOOD_FLOOR_SUBTYPE(wood, bamboo)
+WOOD_FLOOR_SUBTYPE(wood, yew)
+
+// Rough wood floors; lower skill requirement, more wasteful to craft.
+/turf/floor/wood/rough
+ name = "rough-hewn wooden floor"
+ icon = 'icons/turf/flooring/wood_alt.dmi'
+ icon_state = "wood_peasant0"
+ color = /decl/material/solid/organic/wood/oak::color
+ _flooring = /decl/flooring/wood
-/turf/floor/wood/yew
- color = /decl/material/solid/organic/wood/yew::color
- _flooring = /decl/flooring/wood/yew
+WOOD_FLOOR_SUBTYPE(wood/rough, mahogany)
+WOOD_FLOOR_SUBTYPE(wood/rough, maple)
+WOOD_FLOOR_SUBTYPE(wood/rough, ebony)
+WOOD_FLOOR_SUBTYPE(wood/rough, walnut)
+WOOD_FLOOR_SUBTYPE(wood/rough, bamboo)
+WOOD_FLOOR_SUBTYPE(wood/rough, yew)
// Laminate floor; basically identical to wood, but uses older smoother icons.
/turf/floor/laminate
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 18bd63adae10..bdd356e53223 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -806,8 +806,12 @@
. = ..()
LAZYADD(., /decl/interaction_handler/show_turf_contents)
if(user)
- var/obj/item/held = user.get_active_held_item()
+ var/obj/item/held = user.get_active_held_item() || user.get_usable_hand_slot_organ()
if(istype(held))
+ if(reagents?.total_volume >= FLUID_PUDDLE)
+ LAZYADD(., /decl/interaction_handler/dip_item)
+ LAZYADD(., /decl/interaction_handler/fill_from)
+ LAZYADD(., /decl/interaction_handler/empty_into)
if(IS_SHOVEL(held))
if(can_dig_pit(held.material?.hardness))
LAZYDISTINCTADD(., /decl/interaction_handler/dig/pit)
@@ -836,6 +840,7 @@
name = "Dig Trench"
/decl/interaction_handler/dig/trench/invoked(atom/target, mob/user, obj/item/prop)
+ prop ||= user.get_usable_hand_slot_organ() // Allows drakes to dig.
var/turf/T = get_turf(target)
if(IS_SHOVEL(prop))
if(T.can_dig_trench(prop?.material?.hardness))
@@ -849,6 +854,7 @@
name = "Dig Pit"
/decl/interaction_handler/dig/pit/invoked(atom/target, mob/user, obj/item/prop)
+ prop ||= user.get_usable_hand_slot_organ() // Allows drakes to dig.
var/turf/T = get_turf(target)
if(T.can_dig_pit(prop?.material?.hardness))
T.try_dig_pit(user, prop)
@@ -857,6 +863,7 @@
name = "Dig Farm Plot"
/decl/interaction_handler/dig/farm/invoked(atom/target, mob/user, obj/item/prop)
+ prop ||= user.get_usable_hand_slot_organ() // Allows drakes to dig.
var/turf/T = get_turf(target)
if(T.can_dig_farm(prop?.material?.hardness))
T.try_dig_farm(user, prop)
diff --git a/code/game/turfs/turf_fluids.dm b/code/game/turfs/turf_fluids.dm
index e377ec4b32fa..0ea31b04c6f3 100644
--- a/code/game/turfs/turf_fluids.dm
+++ b/code/game/turfs/turf_fluids.dm
@@ -118,6 +118,8 @@
if(!QDELETED(src) && fluids?.total_volume)
fluids.touch_turf(src)
for(var/atom/movable/AM as anything in get_contained_external_atoms())
+ if(!AM.submerged())
+ continue
AM.fluid_act(fluids)
/turf/proc/remove_fluids(var/amount, var/defer_update)
diff --git a/code/modules/ZAS/Variable Settings.dm b/code/modules/ZAS/VariableSettings.dm
similarity index 100%
rename from code/modules/ZAS/Variable Settings.dm
rename to code/modules/ZAS/VariableSettings.dm
diff --git a/code/modules/admin/secrets/fun_secrets/waddle.dm b/code/modules/admin/secrets/fun_secrets/waddle.dm
index ea7bbd588895..90c663b5a82a 100644
--- a/code/modules/admin/secrets/fun_secrets/waddle.dm
+++ b/code/modules/admin/secrets/fun_secrets/waddle.dm
@@ -35,7 +35,7 @@
events_repository.register(/decl/observ/moved, holder, src, PROC_REF(waddle))
events_repository.register(/decl/observ/destroyed, holder, src, PROC_REF(qdel_self))
-/datum/extension/event_registration/Destroy()
+/datum/extension/waddle/Destroy()
events_repository.unregister(/decl/observ/destroyed, holder, src)
events_repository.unregister(/decl/observ/moved, holder, src)
return ..()
diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm
index e583f5664cec..a4cf742c410f 100644
--- a/code/modules/assembly/assembly.dm
+++ b/code/modules/assembly/assembly.dm
@@ -35,53 +35,49 @@
/// What the device does when turned on
/obj/item/assembly/proc/activate()
- return
-
-/// Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
-/obj/item/assembly/proc/pulsed(var/radio = 0)
- return
-
-/// Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct
-/obj/item/assembly/proc/pulse_device(var/radio = 0)
- return
+ if(!secured || (cooldown > 0)) return 0
+ cooldown = 2
+ spawn(10)
+ process_cooldown()
+ return 1
/// Code that has to happen when the assembly is un\secured goes here
/obj/item/assembly/proc/toggle_secure()
- return
+ secured = !secured
+ update_icon()
+ return secured
/// Called when an assembly is attacked by another
-/obj/item/assembly/proc/attach_assembly(var/obj/A, var/mob/user)
- return
-
-/// Called via spawn(10) to have it count down the cooldown var
-/obj/item/assembly/proc/process_cooldown()
- return
+/obj/item/assembly/proc/attach_assembly(var/obj/item/A, var/mob/user)
+ holder = new/obj/item/assembly_holder(get_turf(src))
+ if(holder.attach(A,src,user))
+ to_chat(user, "You attach \the [A] to \the [src]!")
+ return 1
+ return 0
/// Called when the holder is moved
/obj/item/assembly/proc/holder_movement()
return
-/// Called when attack_self is called
-/obj/item/assembly/interact(mob/user)
- return
-
-/obj/item/assembly/process_cooldown()
+/// Called via spawn(10) to have it count down the cooldown var
+/// This is really bad. Please just make it process...
+/obj/item/assembly/proc/process_cooldown()
cooldown--
if(cooldown <= 0) return 0
spawn(10)
process_cooldown()
return 1
-
-/obj/item/assembly/pulsed(var/radio = 0)
+/// Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
+/obj/item/assembly/proc/pulsed(var/radio = 0)
if(holder && (wires & WIRE_RECEIVE))
activate()
if(radio && (wires & WIRE_RADIO_RECEIVE))
activate()
return 1
-
-/obj/item/assembly/pulse_device(var/radio = 0)
+/// Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct
+/obj/item/assembly/proc/pulse_device(var/radio = 0)
if(holder && (wires & WIRE_PULSE))
holder.process_activation(src, 1, 0)
if(holder && (wires & WIRE_PULSE_SPECIAL))
@@ -90,29 +86,6 @@
//Not sure what goes here quite yet send signal?
return 1
-
-/obj/item/assembly/activate()
- if(!secured || (cooldown > 0)) return 0
- cooldown = 2
- spawn(10)
- process_cooldown()
- return 1
-
-
-/obj/item/assembly/toggle_secure()
- secured = !secured
- update_icon()
- return secured
-
-
-/obj/item/assembly/attach_assembly(var/obj/item/assembly/A, var/mob/user)
- holder = new/obj/item/assembly_holder(get_turf(src))
- if(holder.attach(A,src,user))
- to_chat(user, "You attach \the [A] to \the [src]!")
- return 1
- return 0
-
-
/obj/item/assembly/attackby(obj/item/component, mob/user)
if(!user_can_attack_with(user) || !component.user_can_attack_with(user))
return TRUE
@@ -152,6 +125,7 @@
interact(user)
return TRUE
+/// Called when attack_self is called
/obj/item/assembly/interact(mob/user)
return //HTML MENU FOR WIRES GOES HERE
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index c4ef0fcdbfa7..dba32a26eb25 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -36,20 +36,11 @@
special_assembly = null
return ..()
-/obj/item/assembly_holder/proc/attach(var/obj/item/left, var/obj/item/right, var/mob/user)
- return
-
-/obj/item/assembly_holder/proc/process_activation(var/atom/activator)
- return
-
-/obj/item/assembly_holder/proc/detached()
- return
-
-/obj/item/assembly_holder/attach(var/obj/item/assembly/left, var/obj/item/assembly/right, var/mob/user)
- if((!left)||(!right))
- return 0
- if((!istype(left))||(!istype(right)))
+/obj/item/assembly_holder/proc/attach(var/obj/item/left_item, var/obj/item/right_item, var/mob/user)
+ if(!istype(left_item) || !istype(right_item))
return 0
+ var/obj/item/assembly/left = left_item
+ var/obj/item/assembly/right = right_item
if((left.secured)||(right.secured))
return 0
if(user)
@@ -67,6 +58,24 @@
return 1
+/obj/item/assembly_holder/proc/process_activation(var/atom/activator, var/normal = 1, var/special = 1)
+ if(!activator) return 0
+ if(!secured)
+ visible_message("[html_icon(src)] *beep* *beep*", "*beep* *beep*")
+ if((normal) && (a_right) && (a_left))
+ if(a_right != activator)
+ a_right.pulsed(0)
+ if(a_left != activator)
+ a_left.pulsed(0)
+ if(master)
+ master.receive_signal()
+// if(special && special_assembly)
+// if(!special_assembly == activator)
+// special_assembly.dothings()
+ return 1
+
+/obj/item/assembly_holder/proc/detached()
+ return
/obj/item/assembly_holder/HasProximity(atom/movable/AM)
. = ..()
@@ -154,23 +163,6 @@
qdel(src)
return
-
-/obj/item/assembly_holder/process_activation(var/atom/activator, var/normal = 1, var/special = 1)
- if(!activator) return 0
- if(!secured)
- visible_message("[html_icon(src)] *beep* *beep*", "*beep* *beep*")
- if((normal) && (a_right) && (a_left))
- if(a_right != activator)
- a_right.pulsed(0)
- if(a_left != activator)
- a_left.pulsed(0)
- if(master)
- master.receive_signal()
-// if(special && special_assembly)
-// if(!special_assembly == activator)
-// special_assembly.dothings()
- return 1
-
/obj/item/assembly_holder/hear_talk(mob/living/M, msg, verb, decl/language/speaking)
if(a_right)
a_right.hear_talk(M,msg,verb,speaking)
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index aee7624c0f7a..a451bcffec1e 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -20,7 +20,23 @@
var/range = 2
/obj/item/assembly/prox_sensor/proc/toggle_scan()
+ if(!secured) return 0
+ scanning = !scanning
+ update_icon()
+ return
+
/obj/item/assembly/prox_sensor/proc/sense()
+ var/turf/mainloc = get_turf(src)
+// if(scanning && cooldown <= 0)
+// mainloc.visible_message("[html_icon(src)] *boop* *boop*", "*boop* *boop*")
+ if((!holder && !secured)||(!scanning)||(cooldown > 0)) return 0
+ pulse_device(0)
+ if(!holder)
+ mainloc.visible_message("[html_icon(src)] *beep* *beep*", "*beep* *beep*")
+ cooldown = 2
+ spawn(10)
+ process_cooldown()
+ return
/obj/item/assembly/prox_sensor/activate()
@@ -46,19 +62,6 @@
if(. && !istype(AM, /obj/effect/ir_beam) && AM.move_speed < 12)
sense()
-/obj/item/assembly/prox_sensor/sense()
- var/turf/mainloc = get_turf(src)
-// if(scanning && cooldown <= 0)
-// mainloc.visible_message("[html_icon(src)] *boop* *boop*", "*boop* *boop*")
- if((!holder && !secured)||(!scanning)||(cooldown > 0)) return 0
- pulse_device(0)
- if(!holder)
- mainloc.visible_message("[html_icon(src)] *beep* *beep*", "*beep* *beep*")
- cooldown = 2
- spawn(10)
- process_cooldown()
- return
-
/obj/item/assembly/prox_sensor/Process()
if(scanning)
@@ -80,12 +83,6 @@
. = ..()
addtimer(CALLBACK(src, PROC_REF(sense)), 0)
-/obj/item/assembly/prox_sensor/toggle_scan()
- if(!secured) return 0
- scanning = !scanning
- update_icon()
- return
-
/obj/item/assembly/prox_sensor/on_update_icon()
. = ..()
diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm
index aeb57facd843..bac9d7ec0796 100644
--- a/code/modules/assembly/timer.dm
+++ b/code/modules/assembly/timer.dm
@@ -16,9 +16,6 @@
var/timing = 0
var/time = 10
-/obj/item/assembly/timer/proc/timer_end()
-
-
/obj/item/assembly/timer/activate()
if(!..()) return 0//Cooldown check
@@ -39,7 +36,7 @@
return secured
-/obj/item/assembly/timer/timer_end()
+/obj/item/assembly/timer/proc/timer_end()
if(!secured) return 0
pulse_device(0)
if(!holder)
diff --git a/code/modules/augment/passive/boost/shooting.dm b/code/modules/augment/passive/boost/shooting.dm
index 59ca29796cb7..33306ef9f56b 100644
--- a/code/modules/augment/passive/boost/shooting.dm
+++ b/code/modules/augment/passive/boost/shooting.dm
@@ -6,16 +6,16 @@
material = /decl/material/solid/metal/steel
origin_tech = @'{"materials":4,"magnets":3,"biotech":3}'
-/obj/item/organ/internal/augment/boost/reflex/reset_matter()
+/obj/item/organ/internal/augment/boost/shooting/reset_matter()
matter = list(
/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT,
/decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE
)
-/obj/item/organ/internal/augment/boost/reflex/buff()
+/obj/item/organ/internal/augment/boost/shooting/buff()
if((. = ..()))
to_chat(owner, SPAN_NOTICE("Notice: AIM-4 finished reboot."))
-/obj/item/organ/internal/augment/boost/reflex/debuff()
+/obj/item/organ/internal/augment/boost/shooting/debuff()
if((. = ..()))
to_chat(owner, SPAN_WARNING("Catastrophic damage detected: AIM-4 shutting down."))
\ No newline at end of file
diff --git a/code/modules/bodytype/_bodytype.dm b/code/modules/bodytype/_bodytype.dm
index 64d2e2f21b08..af6100a8d0a6 100644
--- a/code/modules/bodytype/_bodytype.dm
+++ b/code/modules/bodytype/_bodytype.dm
@@ -365,6 +365,8 @@ var/global/list/bodytypes_by_category = list()
)
/// Set to FALSE if the mob will update prone icon based on state rather than transform.
var/rotate_on_prone = TRUE
+ /// Armour values used if naked.
+ var/list/natural_armour_values
/decl/bodytype/Initialize()
. = ..()
@@ -618,11 +620,15 @@ var/global/list/bodytypes_by_category = list()
return 220
/decl/bodytype/proc/apply_bodytype_organ_modifications(obj/item/organ/org)
- if(istype(org, /obj/item/organ/external))
- var/obj/item/organ/external/E = org
- E.arterial_bleed_severity *= arterial_bleed_multiplier
- if(islist(apply_encased))
- E.encased = apply_encased[E.organ_tag]
+ if(!istype(org, /obj/item/organ/external))
+ return
+ var/obj/item/organ/external/limb = org
+ limb.arterial_bleed_severity *= arterial_bleed_multiplier
+ if(islist(apply_encased))
+ limb.encased = apply_encased[limb.organ_tag]
+ if(LAZYLEN(natural_armour_values))
+ remove_extension(limb, /datum/extension/armor)
+ set_extension(limb, /datum/extension/armor, natural_armour_values)
//fully_replace: If true, all existing organs will be discarded. Useful when doing mob transformations, and not caring about the existing organs
/decl/bodytype/proc/create_missing_organs(mob/living/human/H, fully_replace = FALSE)
diff --git a/code/modules/bodytype/bodytype_prosthetic_models.dm b/code/modules/bodytype/bodytype_prosthetic_models.dm
index de7115f982b1..d7156bf6bdc2 100644
--- a/code/modules/bodytype/bodytype_prosthetic_models.dm
+++ b/code/modules/bodytype/bodytype_prosthetic_models.dm
@@ -10,7 +10,7 @@
icon_base = 'icons/mob/human_races/cyberlimbs/morgan/morgan_main.dmi'
modifier_string = "wooden"
hardiness = 0.75
- manual_dexterity = DEXTERITY_SIMPLE_MACHINES
+ manual_dexterity = DEXTERITY_SIMPLE_MACHINES | DEXTERITY_HOLD_ITEM | DEXTERITY_EQUIP_ITEM | DEXTERITY_KEYBOARDS | DEXTERITY_GRAPPLE
movement_slowdown = 1
is_robotic = FALSE
modular_limb_tier = MODULAR_BODYPART_ANYWHERE
diff --git a/code/modules/butchery/butchery_data_fish.dm b/code/modules/butchery/butchery_data_fish.dm
index 1facebe1a93a..f7f37c31878f 100644
--- a/code/modules/butchery/butchery_data_fish.dm
+++ b/code/modules/butchery/butchery_data_fish.dm
@@ -11,6 +11,9 @@
gut_type = /obj/item/food/butchery/offal/small
meat_flags = ALLERGEN_FISH
+/decl/butchery_data/animal/fish/oily
+ meat_type = /obj/item/food/butchery/meat/fish/oily
+
/decl/butchery_data/animal/fish/small
bone_amount = 1
skin_amount = 2
diff --git a/code/modules/butchery/butchery_products.dm b/code/modules/butchery/butchery_products.dm
index 23f9dc4858c9..d12b2980a3af 100644
--- a/code/modules/butchery/butchery_products.dm
+++ b/code/modules/butchery/butchery_products.dm
@@ -63,12 +63,6 @@
else
return ..()
-/obj/item/food/butchery/get_dried_product()
- . = ..()
- if(meat_name && istype(., /obj/item/food/jerky))
- var/obj/item/food/jerky/jerk = .
- jerk.set_meat_name(meat_name)
-
/obj/item/food/butchery/get_drying_state(var/obj/rack)
return "meat"
@@ -263,12 +257,12 @@
icon = 'icons/obj/food/butchery/ruminant_stomach.dmi'
material = /decl/material/solid/organic/meat/gut
nutriment_amt = 8
- dried_type = /obj/item/chems/waterskin
+ dried_type = /obj/item/chems/glass/waterskin
w_class = ITEM_SIZE_SMALL
var/stomach_reagent = /decl/material/liquid/acid/stomach
/obj/item/food/butchery/stomach/get_dried_product()
- var/obj/item/chems/waterskin/result = ..()
+ var/obj/item/chems/glass/waterskin/result = ..()
if(istype(result) && reagents?.total_volume)
reagents.trans_to_holder(result.reagents, reagents.total_volume)
return result
diff --git a/code/modules/butchery/butchery_products_meat_fish.dm b/code/modules/butchery/butchery_products_meat_fish.dm
index f1e06223d09a..90040989b1ff 100644
--- a/code/modules/butchery/butchery_products_meat_fish.dm
+++ b/code/modules/butchery/butchery_products_meat_fish.dm
@@ -16,6 +16,17 @@
slice_num = 3
butchery_data = /decl/butchery_data/animal/fish
allergen_flags = ALLERGEN_FISH
+ var/oil_type = /decl/material/liquid/oil/fish
+ var/oil_amount = 2
+
+/obj/item/food/butchery/meat/fish/oily
+ nutriment_amt = 4
+ oil_amount = 4
+
+/obj/item/food/butchery/meat/fish/populate_reagents()
+ . = ..()
+ if(oil_type && oil_amount > 0)
+ add_to_reagents(oil_type, oil_amount)
/obj/item/food/butchery/meat/fish/get_meat_icons()
var/static/list/meat_icons = list(
@@ -52,7 +63,7 @@
. = ..()
SetName("grilled [name]")
-/obj/item/food/butchery/meat/fish/get_meat_icons()
+/obj/item/food/butchery/meat/fish/grilled/get_meat_icons()
var/static/list/meat_icons = list(
'icons/obj/food/butchery/fish_grilled.dmi'
)
diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm
index 8e8c90860c46..d582783e0912 100644
--- a/code/modules/client/asset_cache.dm
+++ b/code/modules/client/asset_cache.dm
@@ -185,7 +185,7 @@ var/global/template_file_name = "all_templates.json"
if(fexists(path + filename))
register_asset(filename, fcopy_rsc(path + filename))
- merge_and_register_templates()
+ merge_and_register_all_templates()
var/list/mapnames = list()
for(var/z in SSmapping.map_levels)
@@ -199,13 +199,18 @@ var/global/template_file_name = "all_templates.json"
common[filename] = fcopy_rsc(file_path)
register_asset(filename, common[filename])
-/datum/asset/nanoui/proc/merge_and_register_templates()
- var/list/templates = flist(template_dir)
- for(var/filename in templates)
- if(copytext(filename, length(filename)) != "/")
- templates[filename] = replacetext(replacetext(file2text(template_dir + filename), "\n", ""), "\t", "")
- else
- templates -= filename
+/datum/asset/nanoui/proc/merge_and_register_all_templates()
+ . = merge_templates(template_dir)
+ . += merge_modpack_templates()
+ register_templates(.)
+
+/datum/asset/nanoui/proc/merge_modpack_templates()
+ PRIVATE_PROC(TRUE)
+ . = list()
+ for(var/mod_template_dir in SSmodpacks.modpack_nanoui_directories)
+ . += merge_templates(mod_template_dir)
+
+/datum/asset/nanoui/proc/register_templates(templates)
var/full_file_name = template_temp_dir + global.template_file_name
if(fexists(full_file_name))
fdel(file(full_file_name))
@@ -213,6 +218,17 @@ var/global/template_file_name = "all_templates.json"
to_file(template_file, json_encode(templates))
register_asset(global.template_file_name, fcopy_rsc(template_file))
+/// Handles adding a directory's templates to the compiled templates list.
+/datum/asset/nanoui/proc/merge_templates(use_dir)
+ PRIVATE_PROC(TRUE)
+ var/list/templates = flist(use_dir)
+ for(var/filename in templates)
+ if(copytext(filename, length(filename)) != "/")
+ templates[filename] = replacetext(replacetext(file2text(use_dir + filename), "\n", ""), "\t", "")
+ else
+ templates -= filename
+ return templates
+
/datum/asset/nanoui/send(client, uncommon)
if(!islist(uncommon))
uncommon = list(uncommon)
@@ -223,11 +239,12 @@ var/global/template_file_name = "all_templates.json"
// Note: this is intended for dev work, and is unsafe. Do not use outside of that.
/datum/asset/nanoui/proc/recompute_and_resend_templates()
- merge_and_register_templates()
+ merge_and_register_all_templates()
for(var/client/C in clients)
- if(C) // there are sleeps here, potentially
- send_asset(C, global.template_file_name, FALSE, FALSE)
- to_chat(C, SPAN_WARNING("Nanoui templates have been updated. Please close and reopen any browser windows."))
+ spawn() // there are sleeps here, potentially
+ if(C)
+ send_asset(C, global.template_file_name, FALSE, FALSE)
+ to_chat(C, SPAN_WARNING("Nanoui templates have been updated. Please close and reopen any browser windows."))
/client/proc/resend_nanoui_templates()
set category = "Debug"
diff --git a/code/modules/clothing/_clothing_accessories.dm b/code/modules/clothing/_clothing_accessories.dm
index 81e9d41a80aa..0469f605d014 100644
--- a/code/modules/clothing/_clothing_accessories.dm
+++ b/code/modules/clothing/_clothing_accessories.dm
@@ -216,7 +216,8 @@
accessory_visibility = clothes.accessory_visibility
accessory_slowdown = clothes.accessory_slowdown
mimicking_state_modifiers = TRUE
- clothing_state_modifiers = clothes.clothing_state_modifiers?.Copy()
+ clothing_state_modifiers = clothes.clothing_state_modifiers?.Copy()
+ bodytype_equip_flags = clothes.bodytype_equip_flags
else
accessory_hide_on_states = get_initial_accessory_hide_on_states()
accessory_slot = initial(accessory_slot)
@@ -225,5 +226,6 @@
accessory_slowdown = initial(accessory_slowdown)
mimicking_state_modifiers = FALSE
clothing_state_modifiers = null
+ bodytype_equip_flags = initial(bodytype_equip_flags)
update_clothing_state_toggles()
diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm
index 5132c8e2bc9f..4a85cb47cef1 100644
--- a/code/modules/clothing/chameleon.dm
+++ b/code/modules/clothing/chameleon.dm
@@ -22,17 +22,6 @@
flags_inv = copy.flags_inv
set_gender(copy.gender)
-/obj/item/clothing/OnDisguise(obj/item/copy, mob/user)
- . = ..()
- if(. && istype(copy, /obj/item/clothing))
- var/obj/item/clothing/clothing_copy = copy
- bodytype_equip_flags = clothing_copy.bodytype_equip_flags
- accessory_slot = clothing_copy.accessory_slot
- accessory_removable = clothing_copy.accessory_removable
- accessory_visibility = clothing_copy.accessory_visibility
- accessory_slowdown = clothing_copy.accessory_slowdown
- accessory_hide_on_states = clothing_copy.accessory_hide_on_states?.Copy()
-
/proc/generate_chameleon_choices(var/basetype)
. = list()
diff --git a/code/modules/clothing/masks/smokable.dm b/code/modules/clothing/masks/smokable.dm
index 9d5c9cf1a9f6..3612df6f7183 100644
--- a/code/modules/clothing/masks/smokable.dm
+++ b/code/modules/clothing/masks/smokable.dm
@@ -158,6 +158,19 @@
STOP_PROCESSING(SSobj, src)
set_light(0)
update_icon()
+ remove_extension(src, /datum/extension/scent)
+ if (type_butt)
+ var/obj/item/trash/cigbutt/butt = new type_butt(get_turf(src))
+ transfer_fingerprints_to(butt)
+ if(istype(butt) && butt.use_color)
+ butt.color = color
+ if(brand)
+ butt.desc += " This one is a [brand]."
+ if(ismob(loc))
+ var/mob/living/M = loc
+ if (!no_message)
+ to_chat(M, SPAN_NOTICE("Your [name] goes out."))
+ qdel(src)
/obj/item/clothing/mask/smokable/attackby(var/obj/item/W, var/mob/user)
if(W.isflamesource() || W.get_heat() >= T100C)
@@ -221,22 +234,6 @@
if(is_processing)
set_scent_by_reagents(src)
-/obj/item/clothing/mask/smokable/extinguish_fire(mob/user, no_message = FALSE)
- ..()
- remove_extension(src, /datum/extension/scent)
- if (type_butt)
- var/obj/item/trash/cigbutt/butt = new type_butt(get_turf(src))
- transfer_fingerprints_to(butt)
- if(istype(butt) && butt.use_color)
- butt.color = color
- if(brand)
- butt.desc += " This one is a [brand]."
- if(ismob(loc))
- var/mob/living/M = loc
- if (!no_message)
- to_chat(M, SPAN_NOTICE("Your [name] goes out."))
- qdel(src)
-
/obj/item/clothing/mask/smokable/cigarette/menthol
name = "menthol cigarette"
desc = "A cigarette with a little minty kick. Well, minty in theory."
@@ -530,22 +527,10 @@
set_scent_by_reagents(src)
update_icon()
-/obj/item/clothing/mask/smokable/pipe/extinguish_fire(mob/user, no_message)
- ..()
- new /obj/effect/decal/cleanable/ash(get_turf(src))
- if(ismob(loc))
- var/mob/living/M = loc
- if (!no_message)
- to_chat(M, SPAN_NOTICE("Your [name] goes out, and you empty the ash."))
- remove_extension(src, /datum/extension/scent)
-
/obj/item/clothing/mask/smokable/pipe/attack_self(var/mob/user)
- if(lit == 1)
+ if(lit)
user.visible_message(SPAN_NOTICE("[user] puts out [src]."), SPAN_NOTICE("You put out [src]."))
- lit = FALSE
- update_icon()
- STOP_PROCESSING(SSobj, src)
- remove_extension(src, /datum/extension/scent)
+ extinguish_fire(user, no_message = TRUE)
else if (smoketime)
var/turf/location = get_turf(user)
user.visible_message(SPAN_NOTICE("[user] empties out [src]."), SPAN_NOTICE("You empty out [src]."))
diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm
index 5f16eca89002..0386948c6020 100644
--- a/code/modules/clothing/spacesuits/rig/modules/combat.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm
@@ -215,10 +215,6 @@
var/obj/item/gun/gun
-/obj/item/rig_module/mounted/Destroy()
- QDEL_NULL(gun)
- . = ..()
-
/obj/item/rig_module/mounted/Initialize()
. = ..()
if(ispath(gun))
diff --git a/code/modules/clothing/suits/jackets/hoodies.dm b/code/modules/clothing/suits/jackets/hoodies.dm
index fcbd38712c8e..adfd915c60ac 100644
--- a/code/modules/clothing/suits/jackets/hoodies.dm
+++ b/code/modules/clothing/suits/jackets/hoodies.dm
@@ -18,13 +18,6 @@
desc = "A warm, black sweatshirt."
color = COLOR_DARK_GRAY
-/obj/item/clothing/suit/jacket/hoodie/get_assumed_clothing_state_modifiers()
- var/static/list/expected_state_modifiers = list(
- GET_DECL(/decl/clothing_state_modifier/buttons),
- GET_DECL(/decl/clothing_state_modifier/hood)
- )
- return expected_state_modifiers
-
/obj/item/clothing/head/hoodiehood
name = "hoodie hood"
desc = "A hood attached to a warm sweatshirt."
diff --git a/code/modules/codex/categories/category_recipes.dm b/code/modules/codex/categories/category_recipes.dm
index 292eca017613..caf8064f577f 100644
--- a/code/modules/codex/categories/category_recipes.dm
+++ b/code/modules/codex/categories/category_recipes.dm
@@ -40,7 +40,7 @@
if(!product)
continue
lore_text = initial(product.lore_text)
- if(ispath(food.result, /decl/material/liquid/drink) || ispath(food.result, /decl/material/liquid/ethanol))
+ if(ispath(food.result, /decl/material/liquid/drink) || ispath(food.result, /decl/material/liquid/alcohol))
category_name = "drink recipe"
mechanics_text = "This recipe produces [food.result_amount]u [product.name].
It should be performed in a glass or shaker, and requires the following ingredients:"
else
diff --git a/code/modules/crafting/handmade_items.dm b/code/modules/crafting/handmade_items.dm
index 5aa1ed2f1cae..0435e4adc633 100644
--- a/code/modules/crafting/handmade_items.dm
+++ b/code/modules/crafting/handmade_items.dm
@@ -5,6 +5,9 @@
material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME
presentation_flags = PRESENTATION_FLAG_NAME
+/obj/item/chems/glass/handmade/can_lid()
+ return FALSE
+
/obj/item/chems/glass/handmade/on_reagent_change()
if((. = ..()))
update_icon()
@@ -79,12 +82,12 @@
/obj/item/chems/glass/handmade/bottle/beer/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/ethanol/beer, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/beer, reagents.maximum_volume)
/obj/item/chems/glass/handmade/bottle/tall/wine/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/ethanol/wine, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/wine, reagents.maximum_volume)
/obj/item/chems/glass/handmade/bottle/wide/whiskey/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/ethanol/whiskey, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/whiskey, reagents.maximum_volume)
diff --git a/code/modules/crafting/metalwork/metalwork_items.dm b/code/modules/crafting/metalwork/metalwork_items.dm
index 5815340c135a..5278aaf343ec 100644
--- a/code/modules/crafting/metalwork/metalwork_items.dm
+++ b/code/modules/crafting/metalwork/metalwork_items.dm
@@ -19,37 +19,37 @@
obj_flags = OBJ_FLAG_NO_STORAGE
var/max_held = 10
-/obj/item/chems/crucible/attackby(obj/item/W, mob/user)
+/obj/item/chems/crucible/attackby(obj/item/used_item, mob/user)
// Fill a mould.
- if(istype(W, /obj/item/chems/mould))
- if(W.material?.hardness <= MAT_VALUE_MALLEABLE)
- to_chat(user, SPAN_WARNING("\The [W] is currently too soft to be used as a mould."))
+ if(istype(used_item, /obj/item/chems/mould))
+ if(used_item.material?.hardness <= MAT_VALUE_MALLEABLE)
+ to_chat(user, SPAN_WARNING("\The [used_item] is currently too soft to be used as a mould."))
return TRUE
- if(standard_pour_into(user, W))
+ if(standard_pour_into(user, used_item))
return TRUE
// Skim off any slag.
- if(istype(W, /obj/item/chems) && ATOM_IS_OPEN_CONTAINER(W) && W.reagents)
+ if(istype(used_item, /obj/item/chems) && ATOM_IS_OPEN_CONTAINER(used_item) && used_item.reagents)
// Pour contents into the crucible.
- if(W.reagents.total_volume)
- var/obj/item/chems/pouring = W
+ if(used_item.reagents.total_volume)
+ var/obj/item/chems/pouring = used_item
if(pouring.standard_pour_into(user, src))
return TRUE
// Attempting to skim off slag.
// TODO: check for appropriate vessel material? Check melting point against temperature of crucible?
if(reagents?.total_volume && length(reagents.reagent_volumes) > 1)
- var/removing = min(amount_per_transfer_from_this, REAGENTS_FREE_SPACE(W.reagents))
+ var/removing = min(amount_per_transfer_from_this, REAGENTS_FREE_SPACE(used_item.reagents))
if(removing < length(reagents.reagent_volumes)-1)
- to_chat(user, SPAN_WARNING("\The [W] is full."))
+ to_chat(user, SPAN_WARNING("\The [used_item] is full."))
return TRUE
// Remove a portion, excepting the primary reagent.
- var/old_amt = W.reagents.total_volume
+ var/old_amt = used_item.reagents.total_volume
var/decl/material/primary_mat = reagents.get_primary_reagent_decl()
- reagents.trans_to_holder(W.reagents, removing, skip_reagents = list(primary_mat.type))
- to_chat(user, SPAN_NOTICE("You skim [W.reagents.total_volume-old_amt] unit\s of slag from the top of \the [primary_mat]."))
+ reagents.trans_to_holder(used_item.reagents, removing, skip_reagents = list(primary_mat.type))
+ to_chat(user, SPAN_NOTICE("You skim [used_item.reagents.total_volume-old_amt] unit\s of slag from the top of \the [primary_mat]."))
return TRUE
return ..()
diff --git a/code/modules/crafting/stack_recipes/_recipe.dm b/code/modules/crafting/stack_recipes/_recipe.dm
index a73dbc0298f1..a5a28c6e6a55 100644
--- a/code/modules/crafting/stack_recipes/_recipe.dm
+++ b/code/modules/crafting/stack_recipes/_recipe.dm
@@ -61,7 +61,8 @@
/obj/item/stack/material/ore,
/obj/item/stack/material/log,
/obj/item/stack/material/lump,
- /obj/item/stack/material/slab
+ /obj/item/stack/material/slab,
+ /obj/item/stack/material/bundle
)
/// If set, will group recipes under a stack recipe list.
var/category
diff --git a/code/modules/crafting/stack_recipes/recipes_fodder.dm b/code/modules/crafting/stack_recipes/recipes_fodder.dm
index 86ec028b152d..a84f3c45cf67 100644
--- a/code/modules/crafting/stack_recipes/recipes_fodder.dm
+++ b/code/modules/crafting/stack_recipes/recipes_fodder.dm
@@ -1,14 +1,15 @@
/decl/stack_recipe/fodder
- result_type = /obj/structure/haystack
- required_material = /decl/material/solid/organic/plantmatter/grass/dry
- craft_stack_types = list(/obj/item/stack/material/bundle)
- one_per_turf = TRUE
- on_floor = TRUE
- difficulty = MAT_VALUE_EASY_DIY
- recipe_skill = SKILL_BOTANY
+ result_type = /obj/structure/haystack
+ required_material = /decl/material/solid/organic/plantmatter/grass/dry
+ craft_stack_types = list(/obj/item/stack/material/bundle)
+ forbidden_craft_stack_types = null
+ one_per_turf = TRUE
+ on_floor = TRUE
+ difficulty = MAT_VALUE_EASY_DIY
+ recipe_skill = SKILL_BOTANY
/decl/stack_recipe/fodder/get_required_stack_amount(obj/item/stack/stack)
return 30 // Arbitrary amount to make 20 food items.
/decl/stack_recipe/fodder/bale
- result_type = /obj/structure/haystack/bale
+ result_type = /obj/structure/haystack/bale
diff --git a/code/modules/crafting/stack_recipes/recipes_grass.dm b/code/modules/crafting/stack_recipes/recipes_grass.dm
index badba30d8a47..369270b898d4 100644
--- a/code/modules/crafting/stack_recipes/recipes_grass.dm
+++ b/code/modules/crafting/stack_recipes/recipes_grass.dm
@@ -1,7 +1,8 @@
/decl/stack_recipe/woven
- abstract_type = /decl/stack_recipe/woven
- craft_stack_types = /obj/item/stack/material/bundle
- category = "woven items"
+ abstract_type = /decl/stack_recipe/woven
+ craft_stack_types = /obj/item/stack/material/bundle
+ category = "woven items"
+ forbidden_craft_stack_types = null
/decl/stack_recipe/woven/can_be_made_from(stack_type, tool_type, decl/material/mat, decl/material/reinf_mat)
if((istype(mat) ? mat.type : mat) == /decl/material/solid/organic/plantmatter/grass)
diff --git a/code/modules/crafting/stack_recipes/recipes_soft.dm b/code/modules/crafting/stack_recipes/recipes_soft.dm
index 00a0e650a456..9672f23017e6 100644
--- a/code/modules/crafting/stack_recipes/recipes_soft.dm
+++ b/code/modules/crafting/stack_recipes/recipes_soft.dm
@@ -2,7 +2,11 @@
time = 1 SECOND
abstract_type = /decl/stack_recipe/soft
craft_stack_types = null
- forbidden_craft_stack_types = null
+ forbidden_craft_stack_types = list(
+ /obj/item/stack/material/bundle,
+ /obj/item/stack/material/thread,
+ /obj/item/stack/material/bolt
+ )
required_min_hardness = 0
required_max_hardness = MAT_VALUE_SOFT
crafting_extra_cost_factor = 1 // No wastage for just resculpting materials.
diff --git a/code/modules/crafting/stack_recipes/recipes_stacks.dm b/code/modules/crafting/stack_recipes/recipes_stacks.dm
index c78160e09fc0..06c19604fbfc 100644
--- a/code/modules/crafting/stack_recipes/recipes_stacks.dm
+++ b/code/modules/crafting/stack_recipes/recipes_stacks.dm
@@ -26,6 +26,26 @@
result_type = /obj/item/stack/tile/wood/walnut
required_material = /decl/material/solid/organic/wood/walnut
+/decl/stack_recipe/tile/wood/mahogany/rough
+ crafting_extra_cost_factor = 2 // wasteful but easy
+ difficulty = MAT_VALUE_EASY_DIY
+ result_type = /obj/item/stack/tile/wood/rough/mahogany
+
+/decl/stack_recipe/tile/wood/maple/rough
+ crafting_extra_cost_factor = 2
+ difficulty = MAT_VALUE_EASY_DIY
+ result_type = /obj/item/stack/tile/wood/rough/maple
+
+/decl/stack_recipe/tile/wood/ebony/rough
+ crafting_extra_cost_factor = 2
+ difficulty = MAT_VALUE_HARD_DIY
+ result_type = /obj/item/stack/tile/wood/rough/ebony
+
+/decl/stack_recipe/tile/wood/walnut/rough
+ crafting_extra_cost_factor = 2
+ difficulty = MAT_VALUE_EASY_DIY
+ result_type = /obj/item/stack/tile/wood/rough/walnut
+
/decl/stack_recipe/tile/wood/oak_laminate
result_type = /obj/item/stack/tile/wood/laminate/oak
required_material = /decl/material/solid/organic/wood/chipboard
diff --git a/code/modules/crafting/stack_recipes/recipes_textiles.dm b/code/modules/crafting/stack_recipes/recipes_textiles.dm
index 0097dc55b8c6..3f39d08385e6 100644
--- a/code/modules/crafting/stack_recipes/recipes_textiles.dm
+++ b/code/modules/crafting/stack_recipes/recipes_textiles.dm
@@ -99,7 +99,7 @@
result_type = /obj/item/backpack/crafted
/decl/stack_recipe/textiles/leather/waterskin
- result_type = /obj/item/chems/waterskin/crafted
+ result_type = /obj/item/chems/glass/waterskin/crafted
required_material = /decl/material/solid/organic/leather
category = null
diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm
index 3ed5186e6b89..b2af21d0e601 100644
--- a/code/modules/detectivework/tools/rag.dm
+++ b/code/modules/detectivework/tools/rag.dm
@@ -7,7 +7,6 @@
amount_per_transfer_from_this = 5
possible_transfer_amounts = @"[5]"
volume = 10
- can_be_placed_into = null
item_flags = ITEM_FLAG_NO_BLUDGEON
atom_flags = ATOM_FLAG_OPEN_CONTAINER
material = /decl/material/solid/organic/cloth
@@ -16,6 +15,15 @@
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)
+ 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()
. = ..()
update_name()
diff --git a/code/modules/detectivework/tools/storage.dm b/code/modules/detectivework/tools/storage.dm
index de56ab7d3dea..30e553fef614 100644
--- a/code/modules/detectivework/tools/storage.dm
+++ b/code/modules/detectivework/tools/storage.dm
@@ -3,7 +3,7 @@
desc = "Sterilized equipment within. Do not contaminate."
icon = 'icons/obj/forensics.dmi'
icon_state = "dnakit"
-
+
/obj/item/box/swabs/WillContain()
return list(/obj/item/forensics/sample/swab = DEFAULT_BOX_STORAGE)
@@ -11,7 +11,7 @@
name = "evidence bag box"
desc = "A box claiming to contain evidence bags."
-/obj/item/box/swabs/WillContain()
+/obj/item/box/evidence/WillContain()
return list(/obj/item/evidencebag = 7)
/obj/item/box/fingerprints
@@ -20,5 +20,5 @@
icon = 'icons/obj/forensics.dmi'
icon_state = "dnakit"
-/obj/item/box/swabs/WillContain()
+/obj/item/box/fingerprints/WillContain()
return list(/obj/item/forensics/sample/print = DEFAULT_BOX_STORAGE)
diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm
index 97dc8f97f3ff..2e0256a4706b 100644
--- a/code/modules/events/event_container.dm
+++ b/code/modules/events/event_container.dm
@@ -157,7 +157,6 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta/no_overmap(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 10, list(ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_JANITOR = 10)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravity Failure", /datum/event/gravity, 75, list(ASSIGNMENT_ENGINEER = 25)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_ENGINEER = 10)),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Inertial Damper Recalibration", /datum/event/inertial_damper, 75, list(ASSIGNMENT_ENGINEER = 25)),
new /datum/event_meta/no_overmap(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_COMPUTER = 50, ASSIGNMENT_ROBOT = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
new /datum/event_meta/no_overmap(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 20)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)),
diff --git a/code/modules/events/meteors.dm b/code/modules/events/meteors.dm
index f291cda35f54..b39f3c9da047 100644
--- a/code/modules/events/meteors.dm
+++ b/code/modules/events/meteors.dm
@@ -243,6 +243,8 @@ var/global/list/meteors_major = list(
. = ..()
z_original = z
global.meteor_list += src
+ if(!ismissile)
+ SpinAnimation()
/obj/effect/meteor/Move()
. = ..() //process movement...
@@ -259,11 +261,6 @@ var/global/list/meteors_major = list(
global.meteor_list -= src
. = ..()
-/obj/effect/meteor/Initialize()
- . = ..()
- if(!ismissile)
- SpinAnimation()
-
/obj/effect/meteor/Bump(atom/A)
..()
if(A && !QDELETED(src)) // Prevents explosions and other effects when we were deleted by whatever we Bumped() - currently used by shields.
diff --git a/code/modules/fabrication/designs/general/designs_general.dm b/code/modules/fabrication/designs/general/designs_general.dm
index 69b99bda0b9f..fda6ce15bad0 100644
--- a/code/modules/fabrication/designs/general/designs_general.dm
+++ b/code/modules/fabrication/designs/general/designs_general.dm
@@ -188,7 +188,7 @@
/datum/fabricator_recipe/fishing_line_high_quality
path = /obj/item/fishing_line/high_quality
-/datum/fabricator_recipe/chipboard
+/datum/fabricator_recipe/chipboard // base type is for oak
path = /obj/item/stack/material/sheet/mapped/chipboard_oak
category = "Textiles"
fabricator_types = list(
@@ -202,15 +202,6 @@
/decl/material/solid/organic/plastic = ceil((SHEET_MATERIAL_AMOUNT * FABRICATOR_EXTRA_COST_FACTOR)/2)
)
-/datum/fabricator_recipe/chipboard
- path = /obj/item/stack/material/sheet/mapped/chipboard_oak
-
-/datum/fabricator_recipe/chipboard/get_resources()
- resources = list(
- /decl/material/solid/organic/wood/oak = ceil((SHEET_MATERIAL_AMOUNT * FABRICATOR_EXTRA_COST_FACTOR)/2),
- /decl/material/solid/organic/plastic = ceil((SHEET_MATERIAL_AMOUNT * FABRICATOR_EXTRA_COST_FACTOR)/2)
- )
-
/datum/fabricator_recipe/chipboard/maple
path = /obj/item/stack/material/sheet/mapped/chipboard_maple
diff --git a/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm b/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm
index c817352197fe..44f481a550c0 100644
--- a/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm
+++ b/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm
@@ -467,9 +467,6 @@
/datum/fabricator_recipe/imprinter/circuit/long_range_relay
path = /obj/item/stock_parts/circuitboard/relay/long_range
-/datum/fabricator_recipe/imprinter/circuit/inertial_damper
- path = /obj/item/stock_parts/circuitboard/inertial_damper
-
/datum/fabricator_recipe/imprinter/circuit/docking_beacon
path = /obj/item/stock_parts/circuitboard/docking_beacon
diff --git a/code/modules/fluids/_fluid.dm b/code/modules/fluids/_fluid.dm
index ef00dac2cea6..ef3d0259a0d3 100644
--- a/code/modules/fluids/_fluid.dm
+++ b/code/modules/fluids/_fluid.dm
@@ -22,8 +22,7 @@
// Update layer.
var/new_layer
var/turf/T = get_turf(src)
- var/effective_depth = T?.get_physical_height() + reagent_volume
- if(effective_depth < 0)
+ if(T.pixel_z < 0)
new_layer = T.layer + 0.2
else if(reagent_volume > FLUID_DEEP)
new_layer = DEEP_FLUID_LAYER
diff --git a/code/modules/food/cooking/recipes/recipe_assembled.dm b/code/modules/food/cooking/recipes/recipe_assembled.dm
index db38ad62101d..863129f6f12f 100644
--- a/code/modules/food/cooking/recipes/recipe_assembled.dm
+++ b/code/modules/food/cooking/recipes/recipe_assembled.dm
@@ -30,7 +30,7 @@
result = /obj/item/food/superbiteburger
/decl/recipe/twobread
- reagents = list(/decl/material/liquid/ethanol/wine = 5)
+ reagents = list(/decl/material/liquid/alcohol/wine = 5)
items = list(
/obj/item/food/slice/bread = 2,
)
diff --git a/code/modules/food/cooking/recipes/recipe_baked.dm b/code/modules/food/cooking/recipes/recipe_baked.dm
index 90bb8ad590d9..a549e1b3f8a8 100644
--- a/code/modules/food/cooking/recipes/recipe_baked.dm
+++ b/code/modules/food/cooking/recipes/recipe_baked.dm
@@ -4,6 +4,9 @@
RECIPE_CATEGORY_MICROWAVE,
RECIPE_CATEGORY_BAKING_DISH
)
+ // some arbitrary value to make sure it doesn't cook in open air, but will when microwaved
+ // todo: rework futurecooking so that microwaves aren't the only appliance for everything (modern stove, oven, fryer, etc)
+ minimum_temperature = 80 CELSIUS
//cooking_heat_type = COOKING_HEAT_INDIRECT
/decl/recipe/baked/pizzamargherita
diff --git a/code/modules/food/cooking/recipes/recipe_boiled.dm b/code/modules/food/cooking/recipes/recipe_boiled.dm
index d1f8f74207fc..031bd5a164ab 100644
--- a/code/modules/food/cooking/recipes/recipe_boiled.dm
+++ b/code/modules/food/cooking/recipes/recipe_boiled.dm
@@ -1,6 +1,6 @@
/decl/recipe/boiled
abstract_type = /decl/recipe/boiled
- //minimum_temperature = T100C
+ minimum_temperature = 80 CELSIUS // increase to /decl/material/liquid/water::boiling_point once microwaves are reworked
//cooking_heat_type = COOKING_HEAT_INDIRECT
//cooking_medium_type = /decl/material/liquid/water
//cooking_medium_amount = 20
diff --git a/code/modules/food/cooking/recipes/recipe_fried.dm b/code/modules/food/cooking/recipes/recipe_fried.dm
index 784b619335ed..3d4af90fc98d 100644
--- a/code/modules/food/cooking/recipes/recipe_fried.dm
+++ b/code/modules/food/cooking/recipes/recipe_fried.dm
@@ -1,5 +1,8 @@
/decl/recipe/fried
abstract_type = /decl/recipe/fried
+ // some arbitrary value to make sure it doesn't cook in open air, but will when microwaved
+ // todo: rework futurecooking so that microwaves aren't the only appliance for everything (modern stove, oven, fryer, etc)
+ minimum_temperature = 80 CELSIUS
//cooking_heat_type = COOKING_HEAT_DIRECT
//cooking_medium_type = /decl/material/liquid/oil
container_categories = list(
diff --git a/code/modules/food/cooking/recipes/recipe_grilled.dm b/code/modules/food/cooking/recipes/recipe_grilled.dm
index d2e4e2340902..cf6896a827c3 100644
--- a/code/modules/food/cooking/recipes/recipe_grilled.dm
+++ b/code/modules/food/cooking/recipes/recipe_grilled.dm
@@ -5,6 +5,9 @@
RECIPE_CATEGORY_MICROWAVE,
RECIPE_CATEGORY_SKILLET
)
+ // some arbitrary value to make sure it doesn't cook in open air, but will when microwaved
+ // todo: rework futurecooking so that microwaves aren't the only appliance for everything (modern stove, oven, fryer, etc)
+ minimum_temperature = 80 CELSIUS
completion_message = "The meat sizzles as it is cooked through."
/decl/recipe/grilled/plainsteak
diff --git a/code/modules/food/cooking/recipes/recipe_steamed.dm b/code/modules/food/cooking/recipes/recipe_steamed.dm
index dacac34bed15..746439f6ac28 100644
--- a/code/modules/food/cooking/recipes/recipe_steamed.dm
+++ b/code/modules/food/cooking/recipes/recipe_steamed.dm
@@ -1,5 +1,8 @@
/decl/recipe/steamed
abstract_type = /decl/recipe/steamed
+ // some arbitrary value to make sure it doesn't cook in open air, but will when microwaved
+ // todo: rework futurecooking so that microwaves aren't the only appliance for everything (modern stove, oven, fryer, etc)
+ minimum_temperature = 80 CELSIUS
/decl/recipe/steamed/chawanmushi
fruit = list("mushroom" = 1)
diff --git a/code/modules/food/nuggets.dm b/code/modules/food/nuggets.dm
new file mode 100644
index 000000000000..c2171198fa13
--- /dev/null
+++ b/code/modules/food/nuggets.dm
@@ -0,0 +1,24 @@
+/obj/item/food/nugget
+ name = "chicken nugget"
+ icon = 'icons/obj/food/nuggets/nugget.dmi'
+ icon_state = ICON_STATE_WORLD
+ nutriment_desc = "mild battered chicken"
+ nutriment_amt = 6
+ nutriment_type = /decl/material/solid/organic/meat/chicken
+ material = /decl/material/solid/organic/meat/chicken
+ bitesize = 3
+ var/shape = null
+ var/static/list/nugget_icons = list(
+ "lump" = 'icons/obj/food/nuggets/nugget.dmi',
+ "star" = 'icons/obj/food/nuggets/nugget_star.dmi',
+ "lizard" = 'icons/obj/food/nuggets/nugget_lizard.dmi',
+ "corgi" = 'icons/obj/food/nuggets/nugget_corgi.dmi'
+ )
+
+/obj/item/food/nugget/Initialize()
+ . = ..()
+ if(isnull(shape))
+ shape = pick(nugget_icons)
+ set_icon(nugget_icons[shape])
+ desc = "A chicken nugget vaguely shaped like a [shape]."
+ add_allergen_flags(ALLERGEN_GLUTEN) // flour
diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm
index c4351b213e2b..8084a66d09df 100644
--- a/code/modules/games/cards.dm
+++ b/code/modules/games/cards.dm
@@ -27,6 +27,7 @@ var/global/list/card_decks = list()
/obj/item/deck/Initialize()
. = ..()
global.card_decks += src
+ generate_cards()
/obj/item/deck/Destroy()
. = ..()
@@ -70,10 +71,6 @@ var/global/list/card_decks = list()
desc = "A simple deck of playing cards."
icon_state = "deck"
-/obj/item/deck/Initialize()
- . = ..()
- generate_cards()
-
/obj/item/deck/proc/generate_cards()
return
diff --git a/code/modules/hydroponics/plant_types/seeds_misc.dm b/code/modules/hydroponics/plant_types/seeds_misc.dm
index e600ad4c3ab1..e98328e4b399 100644
--- a/code/modules/hydroponics/plant_types/seeds_misc.dm
+++ b/code/modules/hydroponics/plant_types/seeds_misc.dm
@@ -4,7 +4,7 @@
display_name = "cotton patch"
product_material = /decl/material/solid/organic/plantmatter/pith/husk
chems = list(
- /decl/material/liquid/nutriment/plant_oil = list(3,10),
+ /decl/material/liquid/oil/plant = list(3,10),
/decl/material/solid/organic/cloth = list(10,1)
)
slice_product = null
@@ -28,7 +28,7 @@
display_name = "flax patch"
// Do we want linseed oil at some point?
chems = list(
- /decl/material/liquid/nutriment/plant_oil = list(5,12),
+ /decl/material/liquid/oil/plant = list(5,12),
/decl/material/solid/organic/cloth/linen = list(8,1)
)
@@ -288,7 +288,7 @@
mutants = null
chems = list(
/decl/material/liquid/nutriment = list(1,20),
- /decl/material/liquid/ethanol/bluecuracao = list(10,5)
+ /decl/material/liquid/alcohol/bluecuracao = list(10,5)
)
/datum/seed/tomato/blue/teleport/New()
@@ -400,7 +400,7 @@
display_name = "hemp patch"
mutants = null
chems = list(
- /decl/material/liquid/nutriment/plant_oil = list(3,10),
+ /decl/material/liquid/oil/plant = list(3,10),
/decl/material/solid/organic/cloth/hemp = list(8,1),
/decl/material/liquid/nutriment = list(1)
)
@@ -725,7 +725,7 @@
product_name = "sunflower"
display_name = "sunflower patch"
chems = list(
- /decl/material/liquid/nutriment/plant_oil = list(10,10)
+ /decl/material/liquid/oil/plant = list(10,10)
)
/datum/seed/flower/sunflower/New()
@@ -800,7 +800,7 @@
display_name = "peanut vine"
chems = list(
/decl/material/liquid/nutriment = list(1,10),
- /decl/material/liquid/nutriment/plant_oil = list(1,10)
+ /decl/material/liquid/oil/plant = list(1,10)
)
slice_product = /obj/item/food/processed_grown/chopped
slice_amount = 3
@@ -890,7 +890,7 @@
name = "corn"
product_name = "corn"
display_name = "ears of corn"
- chems = list(/decl/material/liquid/nutriment = list(1,10), /decl/material/liquid/nutriment/cornoil = list(1,10))
+ chems = list(/decl/material/liquid/nutriment = list(1,10), /decl/material/liquid/oil/plant/corn = list(1,10))
grown_tag = "corn"
trash_type = /obj/item/corncob
backyard_grilling_product = /obj/item/food/popcorn
@@ -987,7 +987,7 @@
display_name = "soybean patch"
chems = list(
/decl/material/liquid/nutriment = list(1,20),
- /decl/material/liquid/nutriment/plant_oil = list(3,20),
+ /decl/material/liquid/oil/plant = list(3,20),
/decl/material/liquid/drink/milk/soymilk = list(7,20)
)
grown_tag = "soybeans"
diff --git a/code/modules/hydroponics/seed_packets.dm b/code/modules/hydroponics/seed_packets.dm
index aca1014088d5..21efe8deead6 100644
--- a/code/modules/hydroponics/seed_packets.dm
+++ b/code/modules/hydroponics/seed_packets.dm
@@ -26,7 +26,7 @@
/obj/item/seeds/populate_reagents()
. = ..()
- add_to_reagents(/decl/material/liquid/nutriment/plant_oil, 3)
+ add_to_reagents(/decl/material/liquid/oil/plant, 3)
/obj/item/seeds/get_single_monetary_worth()
. = seed ? seed.get_monetary_value() : ..()
diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm
index 3092b5c73e55..0456bff2302b 100644
--- a/code/modules/hydroponics/trays/tray.dm
+++ b/code/modules/hydroponics/trays/tray.dm
@@ -59,7 +59,7 @@
)
var/static/list/nutrient_reagents = list(
/decl/material/liquid/drink/milk = 0.1,
- /decl/material/liquid/ethanol/beer = 0.25,
+ /decl/material/liquid/alcohol/beer = 0.25,
/decl/material/solid/phosphorus = 0.1,
/decl/material/liquid/nutriment/sugar = 0.1,
/decl/material/liquid/drink/sodawater = 0.1,
@@ -89,7 +89,7 @@
/decl/material/liquid/water = 1,
/decl/material/liquid/adminordrazine = 1,
/decl/material/liquid/drink/milk = 0.9,
- /decl/material/liquid/ethanol/beer = 0.7,
+ /decl/material/liquid/alcohol/beer = 0.7,
/decl/material/liquid/fuel/hydrazine = -2,
/decl/material/solid/phosphorus = -0.5,
/decl/material/liquid/water = 1,
@@ -98,7 +98,7 @@
// Beneficial reagents also have values for modifying yield_mod and mut_mod (in that order).
var/static/list/beneficial_reagents = list(
- /decl/material/liquid/ethanol/beer = list( -0.05, 0, 0 ),
+ /decl/material/liquid/alcohol/beer = list( -0.05, 0, 0 ),
/decl/material/liquid/fuel/hydrazine = list( -2, 0, 0 ),
/decl/material/solid/phosphorus = list( -0.75, 0, 0 ),
/decl/material/liquid/drink/sodawater = list( 0.1, 0, 0 ),
diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm
index 8a5e9a6ccbea..69ae5bae034c 100644
--- a/code/modules/integrated_electronics/passive/power.dm
+++ b/code/modules/integrated_electronics/passive/power.dm
@@ -98,13 +98,13 @@
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
var/volume = 60
var/list/fuel = list(
- /decl/material/gas/hydrogen = 50000,
+ /decl/material/gas/hydrogen = 50000,
/decl/material/gas/hydrogen/deuterium = 50000,
- /decl/material/gas/hydrogen/tritium = 50000,
- /decl/material/liquid/fuel = 15000,
- /decl/material/solid/carbon = 10000,
- /decl/material/liquid/ethanol = 10000,
- /decl/material/liquid/nutriment = 8000
+ /decl/material/gas/hydrogen/tritium = 50000,
+ /decl/material/liquid/fuel = 15000,
+ /decl/material/solid/carbon = 10000,
+ /decl/material/liquid/alcohol/ethanol = 10000,
+ /decl/material/liquid/nutriment = 8000
)
var/multi = 1
diff --git a/code/modules/interactions/interactions_reagents.dm b/code/modules/interactions/interactions_reagents.dm
new file mode 100644
index 000000000000..c99ffad81ab7
--- /dev/null
+++ b/code/modules/interactions/interactions_reagents.dm
@@ -0,0 +1,138 @@
+/decl/interaction_handler/dip_item
+ name = "Dip Into"
+ interaction_flags = INTERACTION_NEEDS_PHYSICAL_INTERACTION | INTERACTION_NEVER_AUTOMATIC
+
+/decl/interaction_handler/dip_item/is_possible(atom/target, mob/user, obj/item/prop)
+ return ..() && target.reagents?.total_volume >= FLUID_PUDDLE && istype(prop) && target.can_be_poured_from(user, prop)
+
+/decl/interaction_handler/dip_item/invoked(atom/target, mob/user, obj/item/prop)
+ user.visible_message(SPAN_NOTICE("\The [user] dips \the [prop] into \the [target.reagents.get_primary_reagent_name()]."))
+ prop.fluid_act(target.reagents)
+ return TRUE
+
+/decl/interaction_handler/fill_from
+ name = "Fill From"
+ interaction_flags = INTERACTION_NEEDS_PHYSICAL_INTERACTION | INTERACTION_NEVER_AUTOMATIC
+
+/decl/interaction_handler/fill_from/is_possible(atom/target, mob/user, obj/item/prop)
+ if(!(. = ..()))
+ return
+ if(target.reagents?.total_volume < FLUID_PUDDLE)
+ return FALSE
+ if(!istype(prop) || (!isitem(target) && !istype(target, /obj/structure/reagent_dispensers)))
+ return FALSE
+ return target.can_be_poured_from(user, prop) && prop.can_be_poured_into(user, target)
+
+/decl/interaction_handler/fill_from/invoked(atom/target, mob/user, obj/item/prop)
+ if(isitem(target))
+ var/obj/item/vessel = target
+ return vessel.standard_pour_into(user, prop)
+ if(istype(target, /obj/structure/reagent_dispensers))
+ // Reagent dispensers have some wonky assumptions due to old UX around filling/emptying so we skip the atom flags check.
+ return prop.standard_dispenser_refill(user, target, skip_container_check = TRUE)
+ return FALSE
+
+/decl/interaction_handler/empty_into
+ name = "Pour Into"
+ interaction_flags = INTERACTION_NEEDS_PHYSICAL_INTERACTION | INTERACTION_NEVER_AUTOMATIC
+
+/decl/interaction_handler/empty_into/is_possible(atom/target, mob/user, obj/item/prop)
+ if(!(. = ..()))
+ return
+ if(!istype(prop) || prop.reagents?.total_volume <= 0)
+ return FALSE
+ return target.can_be_poured_into(user, prop) && prop.can_be_poured_from(user, target)
+
+/decl/interaction_handler/empty_into/invoked(atom/target, mob/user, obj/item/prop)
+ prop.standard_pour_into(user, target)
+ return TRUE
+
+/decl/interaction_handler/wash_hands
+ name = "Wash Hands"
+ expected_target_type = /atom
+ interaction_flags = INTERACTION_NEEDS_PHYSICAL_INTERACTION | INTERACTION_NEVER_AUTOMATIC
+
+/decl/interaction_handler/wash_hands/is_possible(atom/target, mob/user, obj/item/prop)
+ . = ..() && !istype(prop) && target?.reagents?.has_reagent(/decl/material/liquid/water, 150)
+ if(.)
+ for(var/hand_slot in user.get_held_item_slots())
+ var/obj/item/organ/external/organ = user.get_organ(hand_slot)
+ if(istype(organ) && organ.is_washable)
+ return TRUE
+
+/decl/interaction_handler/wash_hands/invoked(atom/target, mob/user, obj/item/prop)
+
+ // Probably needs debounce and do_after() but showers and wading into water don't, so whatever.
+ if(!target?.reagents?.has_reagent(/decl/material/liquid/water, 150)) // To avoid washing your hands in beakers.
+ to_chat(user, SPAN_WARNING("\The [src] doesn't have enough water in it to wash your hands."))
+ return
+
+ var/found_hand = FALSE
+ for(var/hand_slot in user.get_held_item_slots())
+ var/obj/item/organ/external/organ = user.get_organ(hand_slot)
+ if(istype(organ) && organ.is_washable)
+ found_hand = TRUE
+ break
+
+ if(!found_hand)
+ return FALSE
+
+ var/decl/pronouns/pronouns = user.get_pronouns()
+ if(isturf(target))
+ var/turf/turf = target
+ var/fluid = turf.get_fluid_name()
+ user.visible_message(
+ SPAN_NOTICE("\The [user] washes [pronouns.his] hands in \the [fluid]."),
+ SPAN_NOTICE("You wash your hands in \the [fluid].")
+ )
+ else
+ user.visible_message(
+ SPAN_NOTICE("\The [user] washes [pronouns.his] hands in \the [target]."),
+ SPAN_NOTICE("You wash your hands in \the [target].")
+ )
+
+ user.clean()
+ playsound(user.loc, 'sound/effects/slosh.ogg', 25, 1)
+ return TRUE
+
+/decl/interaction_handler/drink
+ name = "Drink"
+ expected_target_type = /atom
+ interaction_flags = INTERACTION_NEEDS_PHYSICAL_INTERACTION | INTERACTION_NEVER_AUTOMATIC
+
+/decl/interaction_handler/drink/is_possible(atom/target, mob/user, obj/item/prop)
+ return ..() && !istype(prop) && target.can_drink_from(user)
+
+/decl/interaction_handler/drink/invoked(atom/target, mob/user, obj/item/prop)
+
+ // Items can be picked up and drunk from, this interaction is for turfs and structures.
+ if(istype(target, /obj/item))
+ return
+
+ if(!user.check_has_mouth())
+ target.show_food_no_mouth_message(user, user)
+ return
+
+ if(!target?.reagents?.total_volume)
+ target.show_food_empty_message(user, EATING_METHOD_DRINK)
+ return
+
+ if(!user.can_eat_food_currently(null, user, EATING_METHOD_DRINK))
+ return
+
+ var/blocked = user.check_mouth_coverage()
+ if(blocked)
+ to_chat(user, SPAN_NOTICE("\The [blocked] is in the way!"))
+ return
+
+ var/fluid_name = "\the [target]"
+ if(isturf(target))
+ var/turf/target_turf = target
+ fluid_name = "\the [target_turf.get_fluid_name()]"
+
+ user.visible_message(
+ SPAN_NOTICE("\The [user] drinks from [fluid_name]."),
+ SPAN_NOTICE("You drink from [fluid_name].")
+ )
+ target.reagents.trans_to_mob(user, 5, CHEM_INGEST)
+ playsound(user.loc, 'sound/items/drink.ogg', rand(10, 50), 1)
diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm
index de8134d5e519..d4008f536a20 100644
--- a/code/modules/lighting/lighting_turf.dm
+++ b/code/modules/lighting/lighting_turf.dm
@@ -1,16 +1,22 @@
/turf
var/dynamic_lighting = TRUE
- var/ambient_light // If non-null, a hex RGB light color that should be applied to this turf.
- var/ambient_light_multiplier = 0.3 // The power of the above is multiplied by this. Setting too high may drown out normal lights on the same turf.
+ /// If non-null, a hex RGB light color that should be applied to this turf.
+ var/ambient_light
+ /// The power of the above is multiplied by this. Setting too high may drown out normal lights on the same turf.
+ var/ambient_light_multiplier = 0.3
luminosity = 1
var/tmp/lighting_corners_initialised = FALSE
- var/tmp/list/datum/light_source/affecting_lights // List of light sources affecting this turf.
- var/tmp/atom/movable/lighting_overlay/lighting_overlay // Our lighting overlay.
+ /// List of light sources affecting this turf.
+ var/tmp/list/datum/light_source/affecting_lights
+ /// Our lighting overlay, used to apply multiplicative lighting to the tile and its contents.
+ var/tmp/atom/movable/lighting_overlay/lighting_overlay
var/tmp/list/datum/lighting_corner/corners
- var/tmp/has_opaque_atom = FALSE // Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile.
- var/tmp/ambient_has_indirect = FALSE // If this is TRUE, an above turf's ambient light is affecting this turf.
+ /// Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile.
+ var/tmp/has_opaque_atom = FALSE
+ /// If this is TRUE, an above turf's ambient light is affecting this turf.
+ var/tmp/ambient_has_indirect = FALSE
// Record-keeping, do not touch -- that means you, admins.
var/tmp/ambient_light_old
@@ -92,14 +98,14 @@
ambient_light_old = ambient_light
-// Causes any affecting light sources to be queued for a visibility update, for example a door got opened.
+/// Causes any affecting light sources to be queued for a visibility update, for example a door got opened.
/turf/proc/reconsider_lights()
var/datum/light_source/L
for (var/thing in affecting_lights)
L = thing
L.vis_update()
-// Forces a lighting update. Reconsider lights is preferred when possible.
+/// Forces a lighting update. Reconsider lights is preferred when possible.
/turf/proc/force_update_lights()
var/datum/light_source/L
for (var/thing in affecting_lights)
@@ -137,7 +143,7 @@
C.active = TRUE
-// Returns the average color of this tile. Roughly corresponds to the color of a single old-style lighting overlay.
+/// Returns the average color of this tile. Roughly corresponds to the color of a single old-style lighting overlay.
/turf/proc/get_avg_color()
if (!lighting_overlay)
return null
@@ -159,7 +165,7 @@
#define SCALE(targ,min,max) (targ - min) / (max - min)
-// Used to get a scaled lumcount.
+/// Returns a lumcount (average intensity of color channels) scaled between minlum and maxlum.
/turf/proc/get_lumcount(minlum = 0, maxlum = 1)
if (!lighting_overlay)
return 0.5
@@ -176,7 +182,7 @@
#undef SCALE
-// Can't think of a good name, this proc will recalculate the has_opaque_atom variable.
+/// Can't think of a good name, this proc will recalculate the has_opaque_atom variable.
/turf/proc/recalc_atom_opacity()
#ifdef AO_USE_LIGHTING_OPACITY
var/old = has_opaque_atom
diff --git a/code/modules/maps/template_types/random_exoplanet/planet_themes/ruined_city.dm b/code/modules/maps/template_types/random_exoplanet/planet_themes/ruined_city.dm
index b8e70d839d6e..221ee935055c 100644
--- a/code/modules/maps/template_types/random_exoplanet/planet_themes/ruined_city.dm
+++ b/code/modules/maps/template_types/random_exoplanet/planet_themes/ruined_city.dm
@@ -15,7 +15,7 @@
'sound/ambience/ominous3.ogg'
)
-/datum/exoplanet_theme/robotic_guardians/modify_template_whitelist(whitelist_flags)
+/datum/exoplanet_theme/ruined_city/modify_template_whitelist(whitelist_flags)
return whitelist_flags | TEMPLATE_TAG_ALIEN
/datum/exoplanet_theme/ruined_city/get_map_generators(/datum/planetoid_data/E)
diff --git a/code/modules/materials/_material_stack.dm b/code/modules/materials/_material_stack.dm
index f5286e91141f..e8e684c7f240 100644
--- a/code/modules/materials/_material_stack.dm
+++ b/code/modules/materials/_material_stack.dm
@@ -223,4 +223,9 @@
/obj/item/stack/material/proc/matter_units_to_sheets(used)
if(!material || get_reinforced_material())
return 0
- return ceil(used / matter_per_piece[material.type])
\ No newline at end of file
+ return ceil(used / matter_per_piece[material.type])
+
+// Horrible solution to heat damage for atoms causing logs and
+// fuel to vanish. Replace this when the atom fire system exists.
+/obj/item/stack/material/should_take_heat_damage(datum/gas_mixture/air, exposed_temperature)
+ return istype(loc, /obj/structure/fire_source) ? FALSE : ..()
diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm
index f4a057dd4115..6ea17dcdf2df 100644
--- a/code/modules/materials/_materials.dm
+++ b/code/modules/materials/_materials.dm
@@ -141,6 +141,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
var/list/stack_origin_tech = @'{"materials":1}' // Research level for stacks.
// Attributes
+ /// Does this material float to the top of liquids, allowing it to be skimmed off? Specific to cream at time of writing.
+ var/skimmable = FALSE
/// How rare is this material in exoplanet xenoflora?
var/exoplanet_rarity_plant = MAT_RARITY_MUNDANE
/// How rare is this material in exoplanet atmospheres?
@@ -262,6 +264,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
var/cocktail_ingredient
var/defoliant
var/fruit_descriptor // String added to fruit desc if this chemical is present.
+ /// Does this reagent have an antibiotic effect (helping with infections)?
+ var/antibiotic_strength = 0
var/dirtiness = DIRTINESS_NEUTRAL // How dirty turfs are after being exposed to this material. Negative values cause a cleaning/sterilizing effect.
var/decontamination_dose = 0 // Amount required for a decontamination effect, if any.
@@ -287,13 +291,11 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
var/chilling_message = "crackles and freezes!"
var/chilling_sound = 'sound/effects/bubbles.ogg'
var/list/chilling_products
- var/bypass_chilling_products_for_root_type
var/heating_point
var/heating_message = "begins to boil!"
var/heating_sound = 'sound/effects/bubbles.ogg'
var/list/heating_products
- var/bypass_heating_products_for_root_type
var/accelerant_value = FUEL_VALUE_NONE
var/burn_temperature = 100 CELSIUS
var/burn_product
@@ -445,7 +447,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
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.
- if(!isnull(new_temperature_damage_threshold) && (isnull(ignition_point) || (new_temperature_damage_threshold > ignition_point)))
+ if(isnull(new_temperature_damage_threshold) && !isnull(ignition_point))
+ temperature_damage_threshold = ignition_point
+ else if(isnull(ignition_point) || (new_temperature_damage_threshold > ignition_point))
temperature_damage_threshold = new_temperature_damage_threshold
if(!shard_icon)
@@ -833,6 +837,14 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
if(M.status_flags & GODMODE)
return
+ if(antibiotic_strength)
+ M.adjust_immunity(-0.1 * antibiotic_strength)
+ M.add_chemical_effect(CE_ANTIBIOTIC, antibiotic_strength)
+ if(REAGENT_VOLUME(holder, type) > 10)
+ M.adjust_immunity(-0.3 * antibiotic_strength)
+ if(LAZYACCESS(M.chem_doses, type) > 15)
+ M.adjust_immunity(-0.25 * antibiotic_strength)
+
if(nutriment_factor || hydration_factor)
if(injectable_nutrition)
adjust_mob_nutrition(M, removed, holder, CHEM_INJECT)
diff --git a/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm b/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm
index 2b8f8eca63cd..6b76cad038a8 100644
--- a/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm
+++ b/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm
@@ -218,9 +218,9 @@
color = "#140b30"
toxicity = 4
heating_products = list(
- /decl/material/liquid/acetone = 0.4,
- /decl/material/solid/carbon = 0.4,
- /decl/material/liquid/ethanol = 0.2
+ /decl/material/liquid/acetone = 0.4,
+ /decl/material/solid/carbon = 0.4,
+ /decl/material/liquid/alcohol/ethanol = 0.2
)
heating_point = 145 CELSIUS
heating_message = "separates."
diff --git a/code/modules/materials/definitions/solids/materials_solid_ice.dm b/code/modules/materials/definitions/solids/materials_solid_ice.dm
index dd69df88531d..c90937ccd3be 100644
--- a/code/modules/materials/definitions/solids/materials_solid_ice.dm
+++ b/code/modules/materials/definitions/solids/materials_solid_ice.dm
@@ -117,9 +117,9 @@
liquid_name = null
gas_name = null
heating_products = list(
- /decl/material/gas/ammonia = 0.05,
- /decl/material/liquid/water = 0.55,
- /decl/material/liquid/ethanol = 0.4
+ /decl/material/gas/ammonia = 0.05,
+ /decl/material/liquid/water = 0.55,
+ /decl/material/liquid/alcohol/ethanol = 0.4
)
uid = "solid_ice_ediroite"
value = 0.2
diff --git a/code/modules/materials/definitions/solids/materials_solid_mineral.dm b/code/modules/materials/definitions/solids/materials_solid_mineral.dm
index 3dea5d14d81e..2d073b6fbb60 100644
--- a/code/modules/materials/definitions/solids/materials_solid_mineral.dm
+++ b/code/modules/materials/definitions/solids/materials_solid_mineral.dm
@@ -181,7 +181,7 @@
/decl/material/solid/potassium = 1
)
-/decl/material/solid/potassium/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder)
+/decl/material/solid/potash/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder)
. = ..()
var/volume = REAGENT_VOLUME(holder, type)
if(volume > 3)
diff --git a/code/modules/materials/definitions/solids/materials_solid_organic.dm b/code/modules/materials/definitions/solids/materials_solid_organic.dm
index b410f85be58f..26d720a8814d 100644
--- a/code/modules/materials/definitions/solids/materials_solid_organic.dm
+++ b/code/modules/materials/definitions/solids/materials_solid_organic.dm
@@ -3,6 +3,7 @@
ignition_point = T0C+500 // Based on loose ignition temperature of plastic
accelerant_value = 0.1
burn_product = /decl/material/gas/carbon_monoxide
+ boiling_point = null
melting_point = null
compost_value = 1
diff --git a/code/modules/materials/material_stack_misc.dm b/code/modules/materials/material_stack_misc.dm
index afabc40873b7..606d829b8e1e 100644
--- a/code/modules/materials/material_stack_misc.dm
+++ b/code/modules/materials/material_stack_misc.dm
@@ -147,9 +147,13 @@
/obj/item/stack/material/bundle/grass
material = /decl/material/solid/organic/plantmatter/grass
+ drying_wetness = 50
+ dried_type = /obj/item/stack/material/bundle/grass/dry
/obj/item/stack/material/bundle/grass/dry
material = /decl/material/solid/organic/plantmatter/grass/dry
+ drying_wetness = null
+ dried_type = null
/obj/item/stack/material/strut
name = "struts"
diff --git a/code/modules/mechs/components/body.dm b/code/modules/mechs/components/body.dm
index 4d8016e71384..e60ba0724037 100644
--- a/code/modules/mechs/components/body.dm
+++ b/code/modules/mechs/components/body.dm
@@ -50,6 +50,21 @@
"[WEST]" = list("x" = 8, "y" = 0)
)
)
+ if(pilot_coverage >= 100) //Open cockpits dont get to have air
+ cockpit = new
+ cockpit.volume = 200
+ if(loc)
+ var/datum/gas_mixture/air = loc.return_air()
+ if(air)
+ //Essentially at this point its like we created a vacuum, but realistically making a bottle doesnt actually increase volume of a room and neither should a mech
+ for(var/g in air.gas)
+ cockpit.gas[g] = (air.gas[g] / air.volume) * cockpit.volume
+
+ cockpit.temperature = air.temperature
+ cockpit.update_values()
+
+ air_supply = new /obj/machinery/portable_atmospherics/canister/air(src)
+ storage_compartment = new(src)
/obj/item/mech_component/chassis/Destroy()
QDEL_NULL(cell)
@@ -74,24 +89,6 @@
if(!m_armour)
to_chat(user, SPAN_WARNING("It is missing exosuit armour plating."))
-/obj/item/mech_component/chassis/Initialize()
- . = ..()
- if(pilot_coverage >= 100) //Open cockpits dont get to have air
- cockpit = new
- cockpit.volume = 200
- if(loc)
- var/datum/gas_mixture/air = loc.return_air()
- if(air)
- //Essentially at this point its like we created a vacuum, but realistically making a bottle doesnt actually increase volume of a room and neither should a mech
- for(var/g in air.gas)
- cockpit.gas[g] = (air.gas[g] / air.volume) * cockpit.volume
-
- cockpit.temperature = air.temperature
- cockpit.update_values()
-
- air_supply = new /obj/machinery/portable_atmospherics/canister/air(src)
- storage_compartment = new(src)
-
/obj/item/mech_component/chassis/proc/update_air(var/take_from_supply)
var/changed
diff --git a/code/modules/mechs/premade/heavy.dm b/code/modules/mechs/premade/heavy.dm
index a81ce89533f6..e1dfd62d77f5 100644
--- a/code/modules/mechs/premade/heavy.dm
+++ b/code/modules/mechs/premade/heavy.dm
@@ -90,10 +90,6 @@
"[WEST]" = list("x" = 12, "y" = 8)
)
)
-
- . = ..()
-
-/obj/item/mech_component/chassis/heavy/prebuild()
. = ..()
m_armour = new /obj/item/robot_parts/robot_component/armour/exosuit/combat(src)
diff --git a/code/modules/mechs/premade/misc.dm b/code/modules/mechs/premade/misc.dm
index 4d150377c327..dafb3bc44d58 100644
--- a/code/modules/mechs/premade/misc.dm
+++ b/code/modules/mechs/premade/misc.dm
@@ -53,7 +53,3 @@
)
)
. = ..()
-
-/obj/item/mech_component/chassis/pod/prebuild()
- . = ..()
- m_armour = new /obj/item/robot_parts/robot_component/armour/exosuit/radproof(src)
\ No newline at end of file
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 3dddd78acedb..62329f27692f 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -271,12 +271,49 @@
return 1 //already unequipped, so success
return I.mob_can_unequip(src, slot)
+/// Gets the inventory slot string ID for the mob whose contents we're in, if any.
+/// Checks both equipped and held item slots.
+/obj/item/proc/get_any_equipped_slot()
+ if(!ismob(loc))
+ return null
+ var/mob/mob = loc
+ return mob.get_any_equipped_slot_for_item(src)
+
+/// Gets the inventory slot string ID for an item that may be in our inventory.
+/// Checks both equipped and held item slots.
+/mob/proc/get_any_equipped_slot_for_item(obj/item/I)
+ var/list/slots = get_inventory_slots() + get_held_item_slots()
+ if(!length(slots))
+ return
+ for(var/slot_str in slots)
+ if(get_equipped_item(slot_str) == I) // slots[slot]._holding == I
+ return slot_str
+
+/// A counterpart to get_any_equipped_slot_for_item that returns the slot datum rather than the slot name.
+/// Checks both equipped and held item slots.
+/obj/item/proc/get_any_equipped_slot_datum()
+ if(!ismob(loc))
+ return null
+ var/mob/mob = loc
+ return mob.get_inventory_slot_datum(mob.get_any_equipped_slot_for_item(src))
+
+/// Gets the equipment (worn) slot string ID for the mob whose contents we're in, if any. Does not include held slots.
/obj/item/proc/get_equipped_slot()
if(!ismob(loc))
return null
var/mob/mob = loc
return mob.get_equipped_slot_for_item(src)
+/// A helper that returns the slot datum rather than the slot name.
+/// Does not include held slots.
+/// Saves unnecessary duplicate ismob checks and loc casts.
+/obj/item/proc/get_equipped_slot_datum()
+ if(!ismob(loc))
+ return null
+ var/mob/mob = loc
+ return mob.get_inventory_slot_datum(mob.get_equipped_slot_for_item(src))
+
+/// Gets the equipment (worn) slot string ID for an item we may be wearing. Does not include held slots.
/mob/proc/get_equipped_slot_for_item(obj/item/I)
var/list/slots = get_inventory_slots()
if(!length(slots))
@@ -285,6 +322,14 @@
if(get_equipped_item(slot_str) == I) // slots[slot]._holding == I
return slot_str
+/// Gets the held item slot string ID for the mob whose contents we're in, if any. Does not include worn slots.
+/obj/item/proc/get_held_slot()
+ if(!ismob(loc))
+ return null
+ var/mob/mob = loc
+ return mob.get_held_slot_for_item(src)
+
+/// Gets the held item slot string ID for an item we may be holding. Does not include worn slots.
/mob/proc/get_held_slot_for_item(obj/item/I)
var/list/slots = get_held_item_slots()
if(!length(slots))
diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm
index ff453a99da4f..9f3089994e6e 100644
--- a/code/modules/mob/living/bot/bot.dm
+++ b/code/modules/mob/living/bot/bot.dm
@@ -283,12 +283,12 @@
/mob/living/bot/proc/lookForTargets()
return
-/mob/living/bot/proc/confirmTarget(var/atom/A)
- if(A.invisibility >= INVISIBILITY_LEVEL_ONE)
+/mob/living/bot/proc/confirmTarget(atom/target)
+ if(target.invisibility >= INVISIBILITY_LEVEL_ONE)
return 0
- if(A in ignore_list)
+ if(target in ignore_list)
return 0
- if(!A.loc)
+ if(!target.loc)
return 0
return 1
diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm
index 0381d5de33f7..95fac4ce948e 100644
--- a/code/modules/mob/living/bot/cleanbot.dm
+++ b/code/modules/mob/living/bot/cleanbot.dm
@@ -1,5 +1,5 @@
/mob/living/bot/cleanbot
- name = "Cleanbot"
+ name = "cleanbot"
desc = "A little cleaning robot, he looks so excited!"
icon = 'icons/mob/bot/cleanbot.dmi'
icon_state = "cleanbot0"
@@ -35,47 +35,47 @@
ignore_list -= g
/mob/living/bot/cleanbot/lookForTargets()
- for(var/obj/effect/decal/cleanable/D in view(world.view + 1, src))
- if(confirmTarget(D))
- target = D
+ for(var/obj/effect/decal/cleanable/decal in view(world.view + 1, src))
+ if(confirmTarget(decal))
+ target = decal
playsound(src, 'sound/machines/boop1.ogg', 30)
return
-/mob/living/bot/cleanbot/confirmTarget(var/obj/effect/decal/cleanable/D)
- if(!..())
- return FALSE
- if(istype(D, /obj/effect/decal/cleanable/dirt))
- var/obj/effect/decal/cleanable/dirt/dirt = D
- return dirt.dirt_amount >= 25
- for(var/T in target_types)
- if(istype(D, T))
- return TRUE
- return FALSE
+/mob/living/bot/cleanbot/confirmTarget(atom/target)
+ . = ..()
+ if(.)
+ var/turf/decal_turf = get_turf(target)
+ if(!istype(decal_turf) || decal_turf.contains_dense_objects())
+ return FALSE // Stop trying to clean under full-tile windows.
+ if(istype(target, /obj/effect/decal/cleanable/dirt))
+ var/obj/effect/decal/cleanable/dirt/dirt = target
+ return dirt.dirt_amount >= 50 // Stop trying to clean invisible dirt.
+ return is_type_in_list(target, target_types)
/mob/living/bot/cleanbot/handleAdjacentTarget()
if(get_turf(target) == src.loc)
UnarmedAttack(target, TRUE)
-/mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/D, var/proximity)
+/mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/decal, var/proximity)
. = ..()
if(.)
return
- if(!istype(D))
+ if(!istype(decal))
return TRUE
- if(D.loc != loc)
+ if(decal.loc != loc)
return FALSE
busy = 1
- visible_message("\The [src] begins to clean up \the [D].")
+ visible_message("\The [src] begins to clean up \the [decal].")
update_icon()
- var/cleantime = istype(D, /obj/effect/decal/cleanable/dirt) ? 10 : 50
- if(do_after(src, cleantime, progress = 0) && !QDELETED(D))
- if(D == target)
+ var/cleantime = istype(decal, /obj/effect/decal/cleanable/dirt) ? 10 : 50
+ if(do_after(src, cleantime, progress = 0) && !QDELETED(decal))
+ if(decal == target)
target = null
- qdel(D)
+ qdel(decal)
playsound(src, 'sound/machines/boop2.ogg', 30)
busy = 0
update_icon()
diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm
index 0e027aa687ba..b706ce3450d5 100644
--- a/code/modules/mob/living/bot/farmbot.dm
+++ b/code/modules/mob/living/bot/farmbot.dm
@@ -222,21 +222,21 @@
if(prob(50))
new /obj/item/robot_parts/l_arm(my_turf)
-/mob/living/bot/farmbot/confirmTarget(var/atom/targ)
+/mob/living/bot/farmbot/confirmTarget(atom/target)
if(!..())
return 0
- if(emagged && ishuman(targ))
- if(targ in view(world.view, src))
+ if(emagged && ishuman(target))
+ if(target in view(world.view, src))
return 1
return 0
- if(istype(targ, /obj/structure/hygiene/sink))
+ if(istype(target, /obj/structure/hygiene/sink))
if(!tank || tank.reagents.total_volume >= tank.reagents.maximum_volume)
return 0
return 1
- var/obj/machinery/portable_atmospherics/hydroponics/tray = targ
+ var/obj/machinery/portable_atmospherics/hydroponics/tray = target
if(!istype(tray))
return 0
diff --git a/code/modules/mob/living/bot/floorbot.dm b/code/modules/mob/living/bot/floorbot.dm
index b772273fd66a..7f0e4f675410 100644
--- a/code/modules/mob/living/bot/floorbot.dm
+++ b/code/modules/mob/living/bot/floorbot.dm
@@ -109,28 +109,24 @@
target = S
return
-/mob/living/bot/floorbot/confirmTarget(var/atom/A) // The fact that we do some checks twice may seem confusing but remember that the bot's settings may be toggled while it's moving and we want them to stop in that case
+/mob/living/bot/floorbot/confirmTarget(atom/target) // The fact that we do some checks twice may seem confusing but remember that the bot's settings may be toggled while it's moving and we want them to stop in that case
anchored = FALSE
if(!..())
return 0
- if(istype(A, /obj/item/stack/tile/floor))
+ if(istype(target, /obj/item/stack/tile/floor))
return (amount < maxAmount && eattiles)
- if(istype(A, /obj/item/stack/material))
- var/obj/item/stack/material/S = A
+ if(istype(target, /obj/item/stack/material))
+ var/obj/item/stack/material/S = target
if(S.material?.type == /decl/material/solid/metal/steel)
return (amount < maxAmount && maketiles)
- if(A.loc.name == "Space")
- return 0
+ var/turf/floor/my_turf = target
+ if(!istype(my_turf) || (isturf(my_turf) && my_turf.is_open()))
+ return FALSE
- var/turf/floor/T = A
- if(istype(T))
- if(emagged)
- return 1
- else
- return (amount && (T.is_floor_damaged() || (improvefloors && !T.has_flooring())))
+ return emagged || (amount && (my_turf.is_floor_damaged() || (improvefloors && !my_turf.has_flooring())))
/mob/living/bot/floorbot/UnarmedAttack(var/atom/A, var/proximity)
diff --git a/code/modules/mob/living/bot/medibot.dm b/code/modules/mob/living/bot/medibot.dm
index 8084e5eaaebd..8ba09af58d39 100644
--- a/code/modules/mob/living/bot/medibot.dm
+++ b/code/modules/mob/living/bot/medibot.dm
@@ -78,35 +78,35 @@
/mob/living/bot/medbot/lookForTargets()
if(is_tipped) // Don't look for targets if we're incapacitated!
return
- for(var/mob/living/human/H in view(7, src)) // Time to find a patient!
- if(confirmTarget(H))
- target = H
+ for(var/mob/living/human/patient in view(7, src)) // Time to find a patient!
+ if(confirmTarget(patient))
+ target = patient
if(last_newpatient_speak + 300 < world.time && vocal)
if(vocal)
var/message_options = list(
- "Hey, [H.name]! Hold on, I'm coming." = 'sound/voice/medbot/mcoming.ogg',
- "Wait [H.name]! I want to help!" = 'sound/voice/medbot/mhelp.ogg',
- "[H.name], you appear to be injured!" = 'sound/voice/medbot/minjured.ogg'
+ "Hey, [patient.name]! Hold on, I'm coming." = 'sound/voice/medbot/mcoming.ogg',
+ "Wait [patient.name]! I want to help!" = 'sound/voice/medbot/mhelp.ogg',
+ "[patient.name], you appear to be injured!" = 'sound/voice/medbot/minjured.ogg'
)
var/message = pick(message_options)
say(message)
playsound(src, message_options[message], 50, 0)
- custom_emote(1, "points at [H.name].")
+ custom_emote(1, "points at [patient.name].")
last_newpatient_speak = world.time
break
-/mob/living/bot/medbot/UnarmedAttack(var/mob/living/human/H, var/proximity)
+/mob/living/bot/medbot/UnarmedAttack(var/mob/living/human/target, var/proximity)
. = ..()
if(.)
return
- if(!on || !istype(H))
+ if(!on || !istype(target))
return FALSE
if(busy)
return TRUE
- if(H.stat == DEAD)
+ if(target.stat == DEAD)
if(vocal)
var/static/death_messages = list(
"No! Stay with me!" = 'sound/voice/medbot/mno.ogg',
@@ -117,7 +117,7 @@
say(message)
playsound(src, death_messages[message], 50, 0)
- var/t = confirmTarget(H)
+ var/t = confirmTarget(target)
if(!t)
if(vocal)
var/static/possible_messages = list(
@@ -130,18 +130,18 @@
playsound(src, possible_messages[message], 50, 0)
icon_state = "medibots"
- visible_message("[src] is trying to inject [H]!")
+ visible_message("[src] is trying to inject [target]!")
if(declare_treatment)
var/area/location = get_area(src)
- broadcast_medical_hud_message("[src] is treating [H] in [location.proper_name]", src)
+ broadcast_medical_hud_message("[src] is treating [target] in [location.proper_name]", src)
busy = 1
update_icon()
- if(do_mob(src, H, 30))
+ if(do_mob(src, target, 30))
if(t == 1)
- reagent_glass.reagents.trans_to_mob(H, injection_amount, CHEM_INJECT)
+ reagent_glass.reagents.trans_to_mob(target, injection_amount, CHEM_INJECT)
else
- H.add_to_reagents(t, injection_amount)
- visible_message("[src] injects [H] with the syringe!")
+ target.add_to_reagents(t, injection_amount)
+ visible_message("[src] injects [target] with the syringe!")
busy = 0
update_icon()
return TRUE
@@ -297,33 +297,34 @@
reagent_glass.forceMove(my_turf)
reagent_glass = null
-/mob/living/bot/medbot/confirmTarget(var/mob/living/human/H)
- if(!..())
- return 0
+/mob/living/bot/medbot/confirmTarget(atom/target)
+ if(!(. = ..()))
+ return
- if(H.stat == DEAD) // He's dead, Jim
- return 0
+ var/mob/living/human/patient = target
+ if(!istype(patient) || patient.stat == DEAD) // He's dead, Jim
+ return FALSE
if(emagged)
return treatment_emag
// If they're injured, we're using a beaker, and they don't have on of the chems in the beaker
- if(reagent_glass && use_beaker && ((H.get_damage(BRUTE) >= heal_threshold) || (H.get_damage(TOX) >= heal_threshold) || (H.get_damage(TOX) >= heal_threshold) || (H.get_damage(OXY) >= (heal_threshold + 15))))
+ if(reagent_glass && use_beaker && ((patient.get_damage(BRUTE) >= heal_threshold) || (patient.get_damage(TOX) >= heal_threshold) || (patient.get_damage(TOX) >= heal_threshold) || (patient.get_damage(OXY) >= (heal_threshold + 15))))
for(var/R in reagent_glass.reagents.reagent_volumes)
- if(!H.reagents.has_reagent(R))
+ if(!patient.reagents.has_reagent(R))
return 1
continue
- if((H.get_damage(BRUTE) >= heal_threshold) && (!H.reagents.has_reagent(treatment_brute)))
+ if((patient.get_damage(BRUTE) >= heal_threshold) && (!patient.reagents.has_reagent(treatment_brute)))
return treatment_brute //If they're already medicated don't bother!
- if((H.get_damage(OXY) >= (15 + heal_threshold)) && (!H.reagents.has_reagent(treatment_oxy)))
+ if((patient.get_damage(OXY) >= (15 + heal_threshold)) && (!patient.reagents.has_reagent(treatment_oxy)))
return treatment_oxy
- if((H.get_damage(BURN) >= heal_threshold) && (!H.reagents.has_reagent(treatment_fire)))
+ if((patient.get_damage(BURN) >= heal_threshold) && (!patient.reagents.has_reagent(treatment_fire)))
return treatment_fire
- if((H.get_damage(TOX) >= heal_threshold) && (!H.reagents.has_reagent(treatment_tox)))
+ if((patient.get_damage(TOX) >= heal_threshold) && (!patient.reagents.has_reagent(treatment_tox)))
return treatment_tox
/mob/living/bot/medbot/proc/tip_over(mob/user)
diff --git a/code/modules/mob/living/bot/mulebot.dm b/code/modules/mob/living/bot/mulebot.dm
index 437ef6164511..078dee2a3827 100644
--- a/code/modules/mob/living/bot/mulebot.dm
+++ b/code/modules/mob/living/bot/mulebot.dm
@@ -178,7 +178,7 @@
target = home
targetName = "Home"
-/mob/living/bot/mulebot/confirmTarget()
+/mob/living/bot/mulebot/confirmTarget(atom/target)
return 1
/mob/living/bot/mulebot/calcTargetPath()
diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm
index 903677e4a811..faca3a286c20 100644
--- a/code/modules/mob/living/bot/secbot.dm
+++ b/code/modules/mob/living/bot/secbot.dm
@@ -157,10 +157,10 @@
return
..()
-/mob/living/bot/secbot/confirmTarget(var/atom/A)
+/mob/living/bot/secbot/confirmTarget(atom/target)
if(!..())
return 0
- return (check_threat(A) >= SECBOT_THREAT_ARREST)
+ return (check_threat(target) >= SECBOT_THREAT_ARREST)
/mob/living/bot/secbot/lookForTargets()
for(var/mob/living/M in view(src))
diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm
index 35b97e4880b8..b80dfb8f85db 100644
--- a/code/modules/mob/living/brain/brain.dm
+++ b/code/modules/mob/living/brain/brain.dm
@@ -26,11 +26,6 @@
)
return default_emotes
-/mob/living/brain/handle_regular_status_updates()
- . = ..()
- if(emp_damage || stat == DEAD || !is_in_interface())
- SET_STATUS_MAX(src, STAT_SILENCE, 2)
-
/mob/living/brain/is_deaf()
return emp_damage || stat == DEAD || !is_in_interface()
@@ -99,8 +94,10 @@
emp_damage += rand(0,10)
emp_damage = clamp(emp_damage, 0, max_emp_damage)
-/mob/living/brain/handle_regular_status_updates() // Status & health update, are we dead or alive etc.
+/mob/living/brain/handle_regular_status_updates() // Status & health update, are we dead or alive, can we communicate, etc.
. = ..()
+ if(emp_damage || stat == DEAD || !is_in_interface())
+ SET_STATUS_MAX(src, STAT_SILENCE, 2)
if(stat == DEAD || !isSynthetic())
emp_damage = 0
return
@@ -114,4 +111,4 @@
if(emp_damage <= 0)
last_emp_message = 0
emp_damage = 0
- to_chat(src, SPAN_NOTICE("All systems restored."))
+ to_chat(src, SPAN_NOTICE("All systems restored."))
\ No newline at end of file
diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm
index fb6b5abe17ba..88acdc74773b 100644
--- a/code/modules/mob/living/human/human.dm
+++ b/code/modules/mob/living/human/human.dm
@@ -511,9 +511,6 @@
if(species.holder_type)
holder_type = species.holder_type
set_max_health(species.total_health, skip_health_update = TRUE) // Health update is handled later.
- remove_extension(src, /datum/extension/armor)
- if(species.natural_armour_values)
- set_extension(src, /datum/extension/armor, species.natural_armour_values)
apply_species_appearance()
var/decl/pronouns/new_pronouns = get_pronouns_by_gender(get_gender())
diff --git a/code/modules/mob/living/human/human_attackhand.dm b/code/modules/mob/living/human/human_attackhand.dm
index 2c02b525e0aa..bf6a29c1bf3a 100644
--- a/code/modules/mob/living/human/human_attackhand.dm
+++ b/code/modules/mob/living/human/human_attackhand.dm
@@ -125,10 +125,6 @@
to_chat(user, SPAN_WARNING("You can't attack while incapacitated."))
return TRUE
- // AI driven mobs have a melee telegraph that needs to be handled here.
- if(user.check_intent(I_FLAG_HARM) && !user.do_attack_windup_checking(src))
- return TRUE
-
if(!ishuman(user))
attack_generic(user, rand(1,3), "punched")
return TRUE
diff --git a/code/modules/mob/living/human/human_species.dm b/code/modules/mob/living/human/human_species.dm
index 6988a940bed6..c499bbb2da2e 100644
--- a/code/modules/mob/living/human/human_species.dm
+++ b/code/modules/mob/living/human/human_species.dm
@@ -37,9 +37,6 @@
corpse.equip_corpse_outfit(src)
return INITIALIZE_HINT_LATELOAD
-/mob/living/human/corpse/get_death_message(gibbed)
- return SKIP_DEATH_MESSAGE
-
/mob/living/human/corpse/LateInitialize()
..()
var/current_max_health = get_max_health()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 6c5d31ae1084..fbb42a1db1a2 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -639,9 +639,9 @@ default behaviour is:
/mob/living/verb/rest_verb()
set name = "Rest"
set category = "IC"
- lay_down()
+ lay_down(block_posture = /decl/posture/sitting)
-/mob/living/verb/lay_down()
+/mob/living/verb/lay_down(block_posture as null)
set name = "Change Posture"
set category = "IC"
@@ -650,6 +650,15 @@ default behaviour is:
return
var/list/selectable_postures = get_selectable_postures()
+
+ if(block_posture)
+ for(var/decl/posture/selectable_posture in selectable_postures)
+ if(islist(block_posture))
+ if(is_type_in_list(selectable_posture, block_posture))
+ selectable_postures -= selectable_posture
+ else if(istype(selectable_posture, block_posture))
+ selectable_postures -= selectable_posture
+
if(!length(selectable_postures))
return
@@ -853,9 +862,14 @@ default behaviour is:
fluids.touch_mob(src)
if(QDELETED(src) || !fluids.total_volume)
return
+ var/on_turf = fluids.my_atom == get_turf(src)
for(var/atom/movable/A as anything in get_equipped_items(TRUE))
if(!A.simulated)
continue
+ // if we're being affected by reagent fluids, items check if they're submerged
+ // todo: i don't like how this works, it feels hacky. maybe separate coating and submersion somehow and make this only checked for submersion
+ if(on_turf && !A.submerged())
+ continue
A.fluid_act(fluids)
if(QDELETED(src) || !fluids.total_volume)
return
@@ -1519,6 +1533,13 @@ default behaviour is:
qdel(grab)
if(istype(ai))
ai.on_buckled(M)
+ reset_layer()
+ update_icon()
+
+/mob/living/unbuckle_mob()
+ . = ..()
+ reset_layer()
+ update_icon()
/mob/living/try_make_grab(mob/living/user, defer_hand = FALSE)
. = ..()
@@ -1886,16 +1907,6 @@ default behaviour is:
return TRUE
return FALSE
-/mob/living/buckle_mob(mob/living/M)
- . = ..()
- reset_layer()
- update_icon()
-
-/mob/living/unbuckle_mob()
- . = ..()
- reset_layer()
- update_icon()
-
/mob/living/proc/flee(atom/target, upset = FALSE)
var/static/datum/automove_metadata/_flee_automove_metadata = new(
_move_delay = null,
diff --git a/code/modules/mob/living/living_taste.dm b/code/modules/mob/living/living_taste.dm
index 03845380c3e3..9beeb47e2fbb 100644
--- a/code/modules/mob/living/living_taste.dm
+++ b/code/modules/mob/living/living_taste.dm
@@ -9,7 +9,7 @@
var/datum/reagents/temp = new(amount, global.temp_reagents_holder) //temporary holder used to analyse what gets transfered.
from.trans_to_holder(temp, amount, multiplier, 1)
var/text_output = temp.generate_taste_message(src, from)
- if(text_output != last_taste_text || last_taste_time + 1 MINUTE < world.time) //We dont want to spam the same message over and over again at the person. Give it a bit of a buffer.
+ if(text_output && (text_output != last_taste_text || last_taste_time + 1 MINUTE < world.time)) //We dont want to spam the same message over and over again at the person. Give it a bit of a buffer.
to_chat(src, SPAN_NOTICE("You can taste [text_output].")) //no taste means there are too many tastes and not enough flavor.
last_taste_time = world.time
last_taste_text = text_output
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index feec39924e9f..e9920873353f 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -659,7 +659,7 @@ var/global/list/custom_ai_icons_by_ckey_and_name = list()
set_light(1, 1, selected_sprite.alive_light)
// Pass lying down or getting up to our pet human, if we're in a rig.
-/mob/living/silicon/ai/lay_down()
+/mob/living/silicon/ai/lay_down(block_posture as null)
var/obj/item/rig/rig = src.get_rig()
if(rig)
rig.force_rest(src)
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 0f7102d1e156..5659569a4e94 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -251,7 +251,7 @@ var/global/list/possible_say_verbs = list(
if(istype(T))
T.visible_message("[src] neatly folds inwards, compacting down to a rectangular card.")
-/mob/living/silicon/pai/lay_down()
+/mob/living/silicon/pai/lay_down(block_posture as null)
// Pass lying down or getting up to our pet human, if we're in a rig.
if(istype(loc, /obj/item/paicard))
set_posture(/decl/posture/standing)
diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm
index 22ecbf50f91f..991631baa850 100644
--- a/code/modules/mob/living/silicon/robot/laws.dm
+++ b/code/modules/mob/living/silicon/robot/laws.dm
@@ -42,8 +42,11 @@
var/datum/ai_laws/master = connected_ai && lawupdate ? connected_ai.laws : null
if (master)
master.sync(src)
- ..()
- return
+ . = ..()
+ // if we aren't malfunctioning and we have a law 0, it's presumably shared
+ // if we are malfunctioning and we don't have a law 0, we don't need to worry about this
+ if(connected_ai && is_malfunctioning() && has_zeroth_law())
+ to_chat(src, SPAN_BOLD("Remember, your AI does NOT share or know about your law 0."))
/mob/living/silicon/robot/proc/robot_checklaws()
set category = "Silicon Commands"
diff --git a/code/modules/mob/living/silicon/robot/modules/module_clerical.dm b/code/modules/mob/living/silicon/robot/modules/module_clerical.dm
index d052194f847f..94f73f0d6370 100644
--- a/code/modules/mob/living/silicon/robot/modules/module_clerical.dm
+++ b/code/modules/mob/living/silicon/robot/modules/module_clerical.dm
@@ -65,7 +65,7 @@
var/datum/reagents/R = emag.create_reagents(50)
R.add_reagent(/decl/material/liquid/paralytics, 10)
R.add_reagent(/decl/material/liquid/sedatives, 15)
- R.add_reagent(/decl/material/liquid/ethanol/beer, 20)
+ R.add_reagent(/decl/material/liquid/alcohol/beer, 20)
R.add_reagent(/decl/material/solid/ice, 5)
emag.SetName("Mickey Finn's Special Brew")
@@ -75,7 +75,7 @@
E.add_to_reagents(/decl/material/liquid/enzyme, 2 * amount)
if(emag)
var/obj/item/chems/drinks/bottle/small/beer/B = emag
- B.add_to_reagents(/decl/material/liquid/ethanol/beer, amount * 0.4)
+ B.add_to_reagents(/decl/material/liquid/alcohol/beer, amount * 0.4)
B.add_to_reagents(/decl/material/solid/ice, amount * 0.1)
B.add_to_reagents(/decl/material/liquid/paralytics, amount * 0.2)
B.add_to_reagents(/decl/material/liquid/sedatives, amount * 0.3)
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 fe58498a36e8..b9456bc2050c 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
@@ -115,6 +115,8 @@
..()
var/obj/item/chems/spray/cleaner/drone/SC = locate() in equipment
SC.add_to_reagents(/decl/material/liquid/cleaner, 8 * amount)
+ var/obj/item/lightreplacer/LR = locate() in equipment
+ LR.Charge(R, amount)
/obj/item/robot_module/drone/construction
name = "construction drone module"
@@ -126,8 +128,3 @@
/obj/item/robot_module/drone/construction/Initialize()
equipment += /obj/item/rcd/borg
. = ..()
-
-/obj/item/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
- var/obj/item/lightreplacer/LR = locate() in equipment
- LR.Charge(R, amount)
- ..()
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 768dc1c0d513..52457ceb078c 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -68,9 +68,6 @@
QDEL_NULL_LIST(stock_parts)
return ..()
-/mob/living/silicon/get_dexterity(silent)
- return dexterity
-
/mob/living/silicon/fully_replace_character_name(new_name)
..()
create_or_update_account(new_name)
diff --git a/code/modules/mob/living/simple_animal/_simple_animal.dm b/code/modules/mob/living/simple_animal/_simple_animal.dm
index 2e1b6d8e3b46..77c479915f82 100644
--- a/code/modules/mob/living/simple_animal/_simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/_simple_animal.dm
@@ -164,16 +164,23 @@ var/global/list/simplemob_icon_bitflag_cache = list()
mob_icon_state_flags |= MOB_ICON_HAS_PARALYZED_STATE
global.simplemob_icon_bitflag_cache[type] = mob_icon_state_flags
+/mob/living/simple_animal/proc/add_additional_visible_overlays(list/accumulator)
+ return
+
/mob/living/simple_animal/refresh_visible_overlays()
+ var/list/add_overlays = list()
if(length(draw_visible_overlays))
- var/list/add_overlays = list()
for(var/overlay_state in draw_visible_overlays)
var/overlay_color = draw_visible_overlays[overlay_state]
if(overlay_state == "base")
add_overlays += overlay_image(icon, icon_state, overlay_color, RESET_COLOR)
else
add_overlays += overlay_image(icon, "[icon_state]-[overlay_state]", overlay_color, RESET_COLOR)
+
+ add_additional_visible_overlays(add_overlays)
+
+ if(length(add_overlays))
set_current_mob_overlay(HO_SKIN_LAYER, add_overlays)
else
set_current_mob_overlay(HO_SKIN_LAYER, null)
diff --git a/code/modules/mob/living/simple_animal/aquatic/aquatic_fish.dm b/code/modules/mob/living/simple_animal/aquatic/aquatic_fish.dm
index 7b8f5b5f1782..bbd6b916d820 100644
--- a/code/modules/mob/living/simple_animal/aquatic/aquatic_fish.dm
+++ b/code/modules/mob/living/simple_animal/aquatic/aquatic_fish.dm
@@ -22,6 +22,14 @@
butchery_data = /decl/butchery_data/animal/fish/medium
mob_size = MOB_SIZE_SMALL
+/mob/living/simple_animal/aquatic/fish/large/cave
+ name = "blind cave fish"
+ desc = "A pale, blobby fish that lives its entire life in the cold darkness of cave rivers, and hence has no need for eyes."
+ icon = 'icons/mob/simple_animal/fish_cave.dmi'
+
+/mob/living/simple_animal/aquatic/fish/large/cave/is_blind()
+ return TRUE
+
/mob/living/simple_animal/aquatic/fish/large/bass
name = "largemouth bass"
icon = 'icons/mob/simple_animal/fish_bass.dmi'
diff --git a/code/modules/mob/living/simple_animal/aquatic/aquatic_fish_lantern.dm b/code/modules/mob/living/simple_animal/aquatic/aquatic_fish_lantern.dm
new file mode 100644
index 000000000000..179605c12c9d
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/aquatic/aquatic_fish_lantern.dm
@@ -0,0 +1,26 @@
+/mob/living/simple_animal/aquatic/fish/large/lantern
+ name = "lantern fish"
+ desc = "An oily, glowing fish. They are sometimes caught in cave rivers, and are rumoured to have cousins in the deep ocean."
+ icon = 'icons/mob/simple_animal/fish_lantern.dmi'
+ butchery_data = /decl/butchery_data/animal/fish/oily
+ holder_type = /obj/item/holder/lanternfish
+ var/glow_color = COLOR_LIME
+ var/glow_power = 0.5
+ var/glow_range = 2
+
+/mob/living/simple_animal/aquatic/fish/large/lantern/Initialize()
+ . = ..()
+ set_light(glow_range, glow_power, glow_color)
+ refresh_visible_overlays()
+
+/mob/living/simple_animal/aquatic/fish/large/lantern/add_additional_visible_overlays(list/accumulator)
+ var/glow_state = "[icon_state]-glow"
+ if(check_state_in_icon(glow_state, icon))
+ accumulator += emissive_overlay(icon, glow_state, color = light_color, flags = RESET_COLOR)
+
+/obj/item/holder/lanternfish/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing)
+ if(overlay && (slot in global.all_hand_slots))
+ var/glow_state = "[overlay.icon_state]-glow"
+ if(check_state_in_icon(glow_state, overlay.icon))
+ overlay.overlays += emissive_overlay(overlay.icon, glow_state, color = light_color, flags = RESET_COLOR)
+ return ..()
diff --git a/code/modules/mob/living/simple_animal/friendly/possum.dm b/code/modules/mob/living/simple_animal/friendly/possum.dm
index 1aefcb1e0fd7..69f4f9973215 100644
--- a/code/modules/mob/living/simple_animal/friendly/possum.dm
+++ b/code/modules/mob/living/simple_animal/friendly/possum.dm
@@ -72,7 +72,7 @@
if(damage >= 3)
respond_to_damage()
-/mob/living/simple_animal/opossum/lay_down()
+/mob/living/simple_animal/opossum/lay_down(block_posture as null)
. = ..()
update_icon()
diff --git a/code/modules/mob/living/simple_animal/hostile/leech.dm b/code/modules/mob/living/simple_animal/hostile/leech.dm
index ea81aa10124a..c8f7259babca 100644
--- a/code/modules/mob/living/simple_animal/hostile/leech.dm
+++ b/code/modules/mob/living/simple_animal/hostile/leech.dm
@@ -17,7 +17,7 @@
/datum/mob_controller/aggressive/leech
break_stuff_probability = 5
-/mob/living/simple_animal/hostile/can_pry_door()
+/mob/living/simple_animal/hostile/leech/can_pry_door()
return FALSE
/mob/living/simple_animal/hostile/leech/exoplanet/Initialize()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 5ed9d75db534..449c6a76a2a3 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1297,11 +1297,6 @@
/mob/proc/get_blood_type()
return
-// Gets the ID card of a mob, but will not check types in the exceptions list
-/mob/GetIdCard(exceptions = null)
- RETURN_TYPE(/obj/item/card/id)
- return LAZYACCESS(GetIdCards(exceptions), 1)
-
/mob/get_overhead_text_x_offset()
return offset_overhead_text_x
@@ -1387,3 +1382,11 @@
/mob/proc/can_twohand_item(obj/item/item)
return FALSE
+
+/// 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
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 6751c0ad7f2e..67e363adcb0c 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -294,8 +294,6 @@ var/global/list/global/organ_rel_size = list(
var/datum/mind/M = O
if(M.current && M.current.client)
C = M.current.client
- else if(M.original && M.original.client)
- C = M.original.client
if(C)
if(C.get_preference_value(/datum/client_preference/anon_say) == PREF_YES)
diff --git a/code/modules/mob/new_player/login.dm b/code/modules/mob/new_player/login.dm
index 6951ec383e30..6c3a0d04adaf 100644
--- a/code/modules/mob/new_player/login.dm
+++ b/code/modules/mob/new_player/login.dm
@@ -36,12 +36,11 @@
show_lobby_menu(TRUE)
var/decl/security_state/security_state = GET_DECL(global.using_map.security_state)
- var/decl/security_level/SL = security_state.current_security_level
- var/alert_desc = ""
- if(SL.up_description)
- alert_desc = SL.up_description
-
- to_chat(src, SPAN_NOTICE("The alert level on the [station_name()] is currently: [SL.name]. [alert_desc]"))
+ if(security_state?.show_on_login)
+ var/decl/security_level/SL = security_state.current_security_level
+ // todo: allow maps to oevrride this string for things like the fantasy map being on high alert?
+ // eg "The alert level *in* Karzerfeste Keep is currently high alert." or "Karzerfeste Keep is currently on high alert."
+ to_chat(src, SPAN_NOTICE("The alert level on the [station_name()] is currently: [SL.name]. [SL?.up_description]"))
// bolds the changelog button on the interface so we know there are updates.
if(client.prefs?.lastchangelog != global.changelog_hash)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index caa16d854fb7..76e3dc995a59 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -2,6 +2,7 @@
universal_speak = TRUE
mob_sort_value = 10
invisibility = INVISIBILITY_ABSTRACT
+ is_spawnable_type = FALSE
simulated = FALSE
density = FALSE
stat = DEAD
@@ -392,7 +393,6 @@ INITIALIZE_IMMEDIATE(/mob/new_player)
if(mind)
mind.active = 0 //we wish to transfer the key manually
- mind.original = new_character
var/memory = client.prefs.records[PREF_MEM_RECORD]
if(memory)
mind.StoreMemory(memory)
diff --git a/code/modules/mob/skills/skill.dm b/code/modules/mob/skills/skill.dm
index 8a464067a3aa..cd0d2ec8927a 100644
--- a/code/modules/mob/skills/skill.dm
+++ b/code/modules/mob/skills/skill.dm
@@ -1,14 +1,24 @@
/decl/skill
-
- abstract_type = /decl/skill // Don't mess with this without changing how Initialize works.
- var/name = "None" // Name of the skill. This is what the player sees.
- var/decl/skill_category/category // Category this skill belongs to.
- var/desc = "Placeholder skill" // Generic description of this skill.
- var/difficulty = SKILL_AVERAGE //Used to compute how expensive the skill is
- var/default_max = SKILL_ADEPT //Makes the skill capped at this value in selection unless overriden at job level.
- var/default_value // The specific default value used for this skill. If null, uses the skillset's default.
- var/prerequisites // A list of skill prerequisites, if needed.
- var/fallback_key // If the skill UID is not found in the savefile, this is the fallback key to use for migrating old savefiles.
+ // UID is required for saving in prefs.
+ decl_flags = DECL_FLAG_MANDATORY_UID
+ /// Don't mess with this without changing how Initialize works.
+ abstract_type = /decl/skill
+ /// Name of the skill. This is what the player sees.
+ var/name = "None"
+ /// Generic description of this skill.
+ var/desc = "Placeholder skill"
+ /// Used to compute how expensive the skill is
+ var/difficulty = SKILL_AVERAGE
+ /// Makes the skill capped at this value in selection unless overriden at job level.
+ var/default_max = SKILL_ADEPT
+ /// The specific default value used for this skill. If null, uses the skillset's default.
+ var/default_value
+ /// A list of skill prerequisites, if needed.
+ var/prerequisites
+ /// If the skill UID is not found in the savefile, this is the fallback key to use for migrating old savefiles.
+ var/fallback_key
+ /// Category this skill belongs to.
+ var/decl/skill_category/category
// Names for different skill values, in order from 1 up.
var/list/levels = list(
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index e0c1d4468761..866c96a62c6e 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -70,7 +70,6 @@
O.aiRestorePowerRoutine = 0
if(mind)
mind.transfer_to(O)
- O.mind.original = O
else
O.key = key
@@ -128,7 +127,6 @@
mind.active = TRUE
mind.transfer_to(O)
if(O.mind && O.mind.assigned_role == ASSIGNMENT_ROBOT)
- O.mind.original = O
var/mmi_type = SSrobots.get_brain_type_by_title(O.mind.role_alt_title ? O.mind.role_alt_title : O.mind.assigned_role)
if(mmi_type)
O.central_processor = new mmi_type(O)
diff --git a/code/modules/mob_holder/_holder.dm b/code/modules/mob_holder/_holder.dm
index ec0dcd39482f..002814c0c09a 100644
--- a/code/modules/mob_holder/_holder.dm
+++ b/code/modules/mob_holder/_holder.dm
@@ -132,8 +132,15 @@
return ..()
/obj/item/holder/proc/sync(var/mob/living/M)
+
SetName(M.name)
desc = M.desc
+
+ if(QDELETED(src) || QDELETED(M) || !istype(M))
+ set_light(0)
+ else
+ set_light(M.light_range, M.light_power, M.light_color)
+
var/mob/living/human/H = loc
if(istype(H))
last_holder = H
diff --git a/code/modules/multiz/ladder.dm b/code/modules/multiz/ladder.dm
index dce4ccb57f63..2bdad6e2350f 100644
--- a/code/modules/multiz/ladder.dm
+++ b/code/modules/multiz/ladder.dm
@@ -23,6 +23,12 @@
var/static/list/radial_options = list("up" = radial_ladder_up, "down" = radial_ladder_down)
+/obj/structure/ladder/handle_default_hammer_attackby()
+ var/last_anchored = anchored
+ . = ..()
+ if(anchored != last_anchored)
+ find_connections()
+
/obj/structure/ladder/handle_default_wrench_attackby()
var/last_anchored = anchored
. = ..()
diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm
index 0a82703bd07d..7b6ef08b85bb 100644
--- a/code/modules/organs/external/_external.dm
+++ b/code/modules/organs/external/_external.dm
@@ -1591,14 +1591,13 @@ Note that amputating the affected organ does in fact remove the infection from t
butchery_decl.place_products(owner, butchery_decl.bone_material, 1, butchery_decl.bone_type)
return ..()
-// This likely seems excessive, but refer to organ explosion_act() to see how it should be handled before reaching this point.
/obj/item/organ/external/physically_destroyed(skip_qdel)
if(!owner)
return ..()
if(limb_flags & ORGAN_FLAG_CAN_AMPUTATE)
- dismember(FALSE, DISMEMBER_METHOD_BLUNT)
+ dismember(FALSE, DISMEMBER_METHOD_BLUNT) // This will also destroy the mob if it removes the last non-core limb.
else
- owner.gib()
+ owner.physically_destroyed() // Previously gib(), but that caused blood and guts to fly everywhere.
/obj/item/organ/external/is_vital_to_owner()
if(isnull(vital_to_owner))
diff --git a/code/modules/organs/external/diagnostics.dm b/code/modules/organs/external/diagnostics.dm
index 2bc96bfa3fc2..973c506b9fcd 100644
--- a/code/modules/organs/external/diagnostics.dm
+++ b/code/modules/organs/external/diagnostics.dm
@@ -110,6 +110,9 @@
for(var/obj/item/organ/internal/augment/aug in internal_organs)
if(istype(aug) && aug.known)
. += "[capitalize(aug.name)] implanted"
+ var/obj/item/organ/internal/lungs/L = locate() in src
+ if( L && L.is_bruised())
+ . += "Lung ruptured"
/obj/item/organ/external/proc/inspect(mob/user)
diff --git a/code/modules/organs/external/standard.dm b/code/modules/organs/external/standard.dm
index d3ec8d68e7f4..2beef64083b1 100644
--- a/code/modules/organs/external/standard.dm
+++ b/code/modules/organs/external/standard.dm
@@ -23,12 +23,6 @@
/obj/item/organ/external/chest/proc/get_current_skin()
return
-/obj/item/organ/external/get_scan_results()
- . = ..()
- var/obj/item/organ/internal/lungs/L = locate() in src
- if( L && L.is_bruised())
- . += "Lung ruptured"
-
/obj/item/organ/external/chest/die()
//Special handling for synthetics
if(BP_IS_PROSTHETIC(src) || BP_IS_CRYSTAL(src))
diff --git a/code/modules/organs/internal/_internal.dm b/code/modules/organs/internal/_internal.dm
index ac00fcf30e58..a3ac98d48e29 100644
--- a/code/modules/organs/internal/_internal.dm
+++ b/code/modules/organs/internal/_internal.dm
@@ -56,6 +56,12 @@
affected.cavity_max_w_class = max(affected.cavity_max_w_class, w_class)
affected.update_internal_organs_cost()
+ // This might need revisiting to stop people successfully implanting brains in groins and transferring minds.
+ if(transfer_brainmob_with_organ && istype(owner))
+ var/mob/living/brainmob = get_brainmob(create_if_missing = FALSE)
+ if(brainmob?.key)
+ transfer_key_from_mob_to_mob(brainmob, owner)
+
/obj/item/organ/internal/do_uninstall(in_place, detach, ignore_children, update_icon)
var/mob/living/victim = owner // cleared in parent proc
@@ -171,7 +177,7 @@
// We clamp/round here so that we don't accidentally heal past the threshold and
// cheat our way into a full second threshold of healing.
- damage = clamp(damage-get_organ_heal_amount(), min_heal_val, absolute_max_damage)
+ damage = clamp(damage - max(0, get_organ_heal_amount()), min_heal_val, absolute_max_damage)
// If we're within 1 damage of the nearest threshold (such as 0), round us down.
// This should be removed when float-aware modulo comes in in 515, but for now is needed
@@ -289,11 +295,3 @@
/obj/item/organ/internal/preserve_in_cryopod(var/obj/machinery/cryopod/pod)
var/mob/living/brainmob = get_brainmob()
return brainmob?.key
-
-// This might need revisiting to stop people successfully implanting brains in groins and transferring minds.
-/obj/item/organ/internal/do_install(mob/living/human/target, obj/item/organ/external/affected, in_place, update_icon, detached)
- . = ..()
- if(transfer_brainmob_with_organ && istype(owner))
- var/mob/living/brainmob = get_brainmob(create_if_missing = FALSE)
- if(brainmob?.key)
- transfer_key_from_mob_to_mob(brainmob, owner)
diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm
index 32a4b6e1c2de..c4980c3a3034 100644
--- a/code/modules/organs/internal/brain.dm
+++ b/code/modules/organs/internal/brain.dm
@@ -99,13 +99,15 @@
alert(owner, "You have taken massive brain damage! You will not be able to remember the events leading up to your injury.", "Brain Damaged")
/obj/item/organ/internal/brain/organ_can_heal()
- return (damage && owner && GET_CHEMICAL_EFFECT(owner, CE_BRAIN_REGEN)) || ..()
+ return (damage && owner && GET_CHEMICAL_EFFECT(owner, CE_BRAIN_REGEN) > 0) || ..()
/obj/item/organ/internal/brain/has_limited_healing()
- return (!owner || !GET_CHEMICAL_EFFECT(owner, CE_BRAIN_REGEN)) && ..()
+ return (!owner || GET_CHEMICAL_EFFECT(owner, CE_BRAIN_REGEN) <= 0) && ..()
/obj/item/organ/internal/brain/get_organ_heal_amount()
- return 1
+ if(!has_limited_healing())
+ . = 1 // We have full healing, so we always heal at least 1 unit of damage.
+ . += (owner ? GET_CHEMICAL_EFFECT(owner, CE_BRAIN_REGEN) : 0)
/obj/item/organ/internal/brain/Process()
if(owner)
diff --git a/code/modules/organs/internal/stomach.dm b/code/modules/organs/internal/stomach.dm
index cdc7df2fe4f8..cf870f3b64b0 100644
--- a/code/modules/organs/internal/stomach.dm
+++ b/code/modules/organs/internal/stomach.dm
@@ -115,7 +115,8 @@
next_cramp = world.time + rand(200,800)
owner.custom_pain("Your stomach cramps agonizingly!",1)
- var/alcohol_volume = REAGENT_VOLUME(ingested, /decl/material/liquid/ethanol)
+ // TODO: check if this even works - it won't be picking up alcohol subtypes.
+ var/alcohol_volume = REAGENT_VOLUME(ingested, /decl/material/liquid/alcohol/ethanol)
var/alcohol_threshold_met = alcohol_volume > STOMACH_VOLUME / 2
if(alcohol_threshold_met && owner.has_genetic_condition(GENE_COND_EPILEPSY) && prob(20))
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index c52321e2f2f1..c7bb11aa1f30 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -372,11 +372,11 @@
if (germ_level < INFECTION_LEVEL_ONE)
germ_level = 0 //cure instantly
else if (germ_level < INFECTION_LEVEL_TWO)
- germ_level -= 5 //at germ_level == 500, this should cure the infection in 5 minutes
+ germ_level -= round(5 * antibiotics) //at germ_level == 500, this should cure the infection in 5 minutes
else
- germ_level -= 3 //at germ_level == 1000, this will cure the infection in 10 minutes
+ germ_level -= round(3 * antibiotics) //at germ_level == 1000, this will cure the infection in 10 minutes
if(owner && owner.current_posture.prone)
- germ_level -= 2
+ germ_level -= round(2 * antibiotics)
germ_level = max(0, germ_level)
/obj/item/organ/proc/take_general_damage(var/amount, var/silent = FALSE)
diff --git a/code/modules/overmap/contacts/contact_sensors.dm b/code/modules/overmap/contacts/contact_sensors.dm
index f6dee900ce47..fcdd349fb077 100644
--- a/code/modules/overmap/contacts/contact_sensors.dm
+++ b/code/modules/overmap/contacts/contact_sensors.dm
@@ -16,6 +16,9 @@
var/obj/effect/overmap/overmap_location = loc
if(overmap_location.requires_contact)
new /datum/overmap_contact(src, overmap_location)
+ if(!contact_datums[linked])
+ var/datum/overmap_contact/record = new(src, linked)
+ record.marker.alpha = 255
/obj/machinery/computer/ship/sensors/Destroy()
objects_in_view.Cut()
@@ -23,12 +26,6 @@
trackers.Cut()
. = ..()
-/obj/machinery/computer/ship/sensors/attempt_hook_up(obj/effect/overmap/visitable/ship/sector)
- . = ..()
- if(. && linked && !contact_datums[linked])
- var/datum/overmap_contact/record = new(src, linked)
- record.marker.alpha = 255
-
/obj/machinery/computer/ship/sensors/proc/reveal_contacts(var/mob/user)
if(user && user.client)
for(var/key in contact_datums)
diff --git a/code/modules/overmap/ships/computers/engine_control.dm b/code/modules/overmap/ships/computers/engine_control.dm
index a62b7258705a..f7f37fcb3467 100644
--- a/code/modules/overmap/ships/computers/engine_control.dm
+++ b/code/modules/overmap/ships/computers/engine_control.dm
@@ -6,6 +6,21 @@
icon_screen = "engines"
var/display_state = "status"
+/// A stub used for modpacks to modify per-ship readout information.
+/// This mutates the UI data list, so it can be used to mask or remove features
+/// as well as to add entirely new ones.
+/// It does not return a value.
+/// While it can access per-engine data, it should be dispreferred for that compared to modify_engine_ui_data().
+/obj/machinery/computer/ship/engines/proc/modify_ship_ui_data(list/ui_data)
+ return
+
+/// A stub used for modpacks to modify per-engine readout information.
+/// This mutates the engine's data list, so it can be used to mask or remove features
+/// as well as to add entirely new ones.
+/// It does not return a value.
+/obj/machinery/computer/ship/engines/proc/modify_engine_ui_data(datum/extension/ship_engine/engine, list/engine_data)
+ return
+
/obj/machinery/computer/ship/engines/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(!linked)
display_reconnect_dialog(user, "ship control systems")
@@ -29,17 +44,13 @@
var/thrust = E.get_exhaust_velocity()
total_thrust += thrust
rdata["eng_thrust"] = "[thrust] m/s"
+ modify_engine_ui_data(E, rdata)
enginfo.Add(list(rdata))
data["engines_info"] = enginfo
data["total_thrust"] = "[total_thrust] m/s"
- var/damping_strength = 0
- for(var/datum/ship_inertial_damper/I in linked.inertial_dampers)
- var/obj/machinery/inertial_damper/ID = I.holder
- damping_strength += ID.get_damping_strength(FALSE)
- data["damping_strength"] = damping_strength
- data["needs_dampers"] = linked.needs_dampers
+ modify_ship_ui_data(data)
ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
diff --git a/code/modules/overmap/ships/landable.dm b/code/modules/overmap/ships/landable.dm
index e2d698ecdb7a..375e4253ec21 100644
--- a/code/modules/overmap/ships/landable.dm
+++ b/code/modules/overmap/ships/landable.dm
@@ -324,7 +324,7 @@
port_tag = new_port_tag
. = ..()
-/obj/abstract/local_dock/automatic/modify_mapped_vars(map_hash)
+/obj/abstract/local_dock/modify_mapped_vars(map_hash)
. = ..()
ADJUST_TAG_VAR(port_tag, map_hash)
ADJUST_TAG_VAR(dock_target, map_hash)
diff --git a/code/modules/overmap/ships/ship.dm b/code/modules/overmap/ships/ship.dm
index f4f1a734c884..133c506ffa63 100644
--- a/code/modules/overmap/ships/ship.dm
+++ b/code/modules/overmap/ships/ship.dm
@@ -19,9 +19,6 @@ var/global/const/OVERMAP_SPEED_CONSTANT = (1 SECOND)
var/skill_needed = SKILL_ADEPT //piloting skill needed to steer it without going in random dir
var/operator_skill
- var/needs_dampers = FALSE
- var/list/inertial_dampers = list()
- var/damping_strength = null
var/vessel_size = SHIP_SIZE_LARGE // arbitrary number, affects how likely are we to evade meteors
var/list/navigation_viewers // list of weakrefs to people viewing the overmap via this ship
@@ -85,15 +82,6 @@ var/global/const/OVERMAP_SPEED_CONSTANT = (1 SECOND)
/obj/effect/overmap/visitable/ship/adjust_speed(n_x, n_y)
. = ..()
- var/magnitude = norm(n_x, n_y)
- var/inertia_dir = magnitude >= 0 ? turn(fore_dir, 180) : fore_dir
- var/inertia_strength = magnitude * 1e3
- if(needs_dampers && damping_strength < inertia_strength)
- var/list/areas_by_name = area_repository.get_areas_by_z_level()
- for(var/area_name in areas_by_name)
- var/area/A = areas_by_name[area_name]
- if(area_belongs_to_zlevels(A, map_z))
- A.throw_unbuckled_occupants(inertia_strength+2, inertia_strength, inertia_dir)
for(var/zz in map_z)
if(is_still())
toggle_move_stars(zz)
@@ -119,10 +107,6 @@ var/global/const/OVERMAP_SPEED_CONSTANT = (1 SECOND)
return round(num_burns / burns_per_grid)
/obj/effect/overmap/visitable/ship/Process(wait, tick)
- damping_strength = 0
- for(var/datum/ship_inertial_damper/I in inertial_dampers)
- var/obj/machinery/inertial_damper/ID = I.holder
- damping_strength += ID.get_damping_strength(TRUE)
sensor_visibility = min(round(base_sensor_visibility + get_speed_sensor_increase(), 1), 100)
/obj/effect/overmap/visitable/ship/on_update_icon()
@@ -181,9 +165,6 @@ var/global/const/OVERMAP_SPEED_CONSTANT = (1 SECOND)
for(var/datum/extension/ship_engine/E in global.ship_engines)
if(check_ownership(E.holder))
engines |= E
- for(var/datum/ship_inertial_damper/I in global.ship_inertial_dampers)
- if(check_ownership(I.holder))
- inertial_dampers |= I
var/v_mass = recalculate_vessel_mass()
if(v_mass)
vessel_mass = v_mass
diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm
index e6014e8f4f70..077717829360 100644
--- a/code/modules/paperwork/filingcabinet.dm
+++ b/code/modules/paperwork/filingcabinet.dm
@@ -120,11 +120,11 @@
. += "Details: [record.get_medical_record()]"
return jointext(., "
")
-/obj/structure/filing_cabinet/records/medical
+/obj/structure/filing_cabinet/records/employment
name = "employment record archive"
archive_name = "employment record"
-/obj/structure/filing_cabinet/records/medical/collate_data(var/datum/computer_file/report/crew_record/record)
+/obj/structure/filing_cabinet/records/employment/collate_data(var/datum/computer_file/report/crew_record/record)
. = list()
. += "Name: [record.get_name()]"
. += "Gender: [record.get_gender()]"
diff --git a/code/modules/paperwork/pen/quill_and_ink.dm b/code/modules/paperwork/pen/quill_and_ink.dm
index c9cdf1af9270..4944165f4e5b 100644
--- a/code/modules/paperwork/pen/quill_and_ink.dm
+++ b/code/modules/paperwork/pen/quill_and_ink.dm
@@ -62,6 +62,12 @@
/// The maximum amount of ink in the inkwell when populating reagents.
var/starting_volume_high = 30
+/obj/item/chems/glass/inkwell/get_edible_material_amount(mob/eater)
+ return 0
+
+/obj/item/chems/glass/inkwell/get_utensil_food_type()
+ return null
+
/obj/item/chems/glass/inkwell/can_lid()
return FALSE
diff --git a/code/modules/persistence/persistence_datum.dm b/code/modules/persistence/persistence_datum.dm
index 0c9e0aedca6b..557ae252b88a 100644
--- a/code/modules/persistence/persistence_datum.dm
+++ b/code/modules/persistence/persistence_datum.dm
@@ -12,10 +12,6 @@
var/ignore_area_flags = FALSE // Set to TRUE to skip area flag checks such as nonpersistent areas.
var/ignore_invalid_loc = FALSE // Set to TRUE to skip checking for a non-null station turf for the entry.
-/decl/persistence_handler/Initialize()
- SetFilename()
- . = ..()
-
/decl/persistence_handler/proc/SetFilename()
if(name)
filename = "data/persistent/[ckey(global.using_map.name)]-[ckey(name)].json"
@@ -95,6 +91,8 @@
/decl/persistence_handler/Initialize()
+ SetFilename()
+
. = ..()
if(!fexists(filename))
diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm
index 431439981132..4f5e0eb41cc8 100644
--- a/code/modules/power/port_gen.dm
+++ b/code/modules/power/port_gen.dm
@@ -466,7 +466,7 @@
to_chat(user, "Auxilary tank shows [reagents.total_volume]u of liquid in it.")
/obj/machinery/port_gen/pacman/super/potato/UseFuel()
- if(reagents.has_reagent(/decl/material/liquid/ethanol/vodka))
+ if(reagents.has_reagent(/decl/material/liquid/alcohol/vodka))
rad_power = 4
temperature_gain = 60
remove_any_reagents(1)
@@ -486,9 +486,9 @@
/obj/machinery/port_gen/pacman/super/potato/attackby(var/obj/item/hit_with, var/mob/user)
if(istype(hit_with, /obj/item/chems))
var/obj/item/chems/chem_container = hit_with
- var/old_vodka_amount = REAGENT_VOLUME(reagents, /decl/material/liquid/ethanol/vodka)
+ var/old_vodka_amount = REAGENT_VOLUME(reagents, /decl/material/liquid/alcohol/vodka)
if(chem_container.standard_pour_into(src,user))
- if(REAGENT_VOLUME(reagents, /decl/material/liquid/ethanol/vodka) > old_vodka_amount) // yay, booze!
+ if(REAGENT_VOLUME(reagents, /decl/material/liquid/alcohol/vodka) > old_vodka_amount) // yay, booze!
audible_message(SPAN_NOTICE("[src] blips happily!"))
playsound(get_turf(src),'sound/machines/synth_yes.ogg', 50, FALSE)
else // you didn't add any more than we already had
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 83ee026551b2..4de22aa06166 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -259,7 +259,8 @@
/obj/item/gun/dropped(var/mob/living/user)
check_accidents(user)
update_icon()
- return ..()
+ . = ..()
+ clear_autofire()
/obj/item/gun/proc/Fire(atom/target, atom/movable/firer, clickparams, pointblank = FALSE, reflex = FALSE, set_click_cooldown = TRUE, target_zone = BP_CHEST)
if(!firer || !target)
@@ -708,10 +709,6 @@
afterattack(shoot_to,target)
return 1
-/obj/item/gun/dropped(mob/living/user)
- . = ..()
- clear_autofire()
-
/obj/item/gun/proc/can_autofire()
return (autofire_enabled && world.time >= next_fire_time)
diff --git a/code/modules/projectiles/guns/launcher/bows/sling.dm b/code/modules/projectiles/guns/launcher/bows/sling.dm
index 25a4b6e6d9c0..c3f3822d4d84 100644
--- a/code/modules/projectiles/guns/launcher/bows/sling.dm
+++ b/code/modules/projectiles/guns/launcher/bows/sling.dm
@@ -1,14 +1,15 @@
/obj/item/gun/launcher/bow/sling
- name = "sling"
- desc = "A simple strip of leather with a cup in the center, used to hurl stones with great speed."
- slot_flags = 0
- draw_time = 0.5 SECONDS
- icon = 'icons/obj/guns/launcher/sling.dmi'
- material = /decl/material/solid/organic/leather
- color = /decl/material/solid/organic/leather::color
- string = null
- max_tension = 1
- bow_ammo_type = null
+ name = "sling"
+ desc = "A simple strip of leather with a cup in the center, used to hurl stones with great speed."
+ slot_flags = 0
+ draw_time = 0.5 SECONDS
+ icon = 'icons/obj/guns/launcher/sling.dmi'
+ material = /decl/material/solid/organic/leather
+ color = /decl/material/solid/organic/leather::color
+ string = null
+ requires_string = FALSE
+ max_tension = 1
+ bow_ammo_type = null
/obj/item/gun/launcher/bow/sling/try_string(mob/user, obj/item/bowstring/new_string)
return FALSE
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index fbf7adf743f3..07ad3c6c6865 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -97,7 +97,7 @@
else animate_movement = NO_STEPS
. = ..()
-/obj/item/projectile/CanPass()
+/obj/item/projectile/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
return TRUE
/obj/item/projectile/damage_flags()
@@ -315,9 +315,6 @@
SHOULD_CALL_PARENT(FALSE)
return
-/obj/item/projectile/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- return 1
-
/obj/item/projectile/proc/before_move()
return
diff --git a/code/modules/random_map/drop/drop_types.dm b/code/modules/random_map/drop/drop_types.dm
index d517a2170175..a9f290a0aa65 100644
--- a/code/modules/random_map/drop/drop_types.dm
+++ b/code/modules/random_map/drop/drop_types.dm
@@ -51,18 +51,6 @@ var/global/list/datum/supply_drop_loot/supply_drop
/obj/item/gun/projectile/automatic/smg,
/obj/item/gun/projectile/automatic/assault_rifle)
-/datum/supply_drop_loot/ballistics
- name = "Ballistics"
- container = /obj/structure/largecrate
-/datum/supply_drop_loot/ballistics/New()
- ..()
- contents = list(
- /obj/item/gun/projectile/pistol,
- /obj/item/gun/projectile/shotgun/doublebarrel,
- /obj/item/gun/projectile/shotgun/pump,
- /obj/item/gun/projectile/automatic/smg,
- /obj/item/gun/projectile/automatic/assault_rifle)
-
/datum/supply_drop_loot/seeds
name = "Seeds"
container = /obj/structure/closet/crate
@@ -158,10 +146,10 @@ var/global/list/datum/supply_drop_loot/supply_drop
/obj/item/box/syringes,
/obj/item/box/autoinjectors)
-/datum/supply_drop_loot/power
- name = "Power"
+/datum/supply_drop_loot/materials
+ name = "Materials"
container = /obj/structure/largecrate
-/datum/supply_drop_loot/power/New()
+/datum/supply_drop_loot/materials/New()
..()
contents = list(
/obj/item/stack/material/sheet/mapped/steel,
diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm
index d35715d884ad..28b4f593c189 100644
--- a/code/modules/reagents/Chemistry-Holder.dm
+++ b/code/modules/reagents/Chemistry-Holder.dm
@@ -199,12 +199,12 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new
var/replace_sound
if(!(check_flags & ATOM_FLAG_NO_PHASE_CHANGE))
- if(!isnull(R.chilling_point) && R.type != R.bypass_chilling_products_for_root_type && LAZYLEN(R.chilling_products) && temperature <= R.chilling_point)
+ if(!isnull(R.chilling_point) && LAZYLEN(R.chilling_products) && temperature <= R.chilling_point)
replace_self_with = R.chilling_products
if(R.chilling_message)
replace_message = "\The [R.get_reagent_name(src)] [R.chilling_message]"
replace_sound = R.chilling_sound
- else if(!isnull(R.heating_point) && R.type != R.bypass_heating_products_for_root_type && LAZYLEN(R.heating_products) && temperature >= R.heating_point)
+ else if(!isnull(R.heating_point) && LAZYLEN(R.heating_products) && temperature >= R.heating_point)
replace_self_with = R.heating_products
if(R.heating_message)
replace_message = "\The [R.get_reagent_name(src)] [R.heating_message]"
@@ -579,6 +579,7 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new
if(transferred_phases & MAT_PHASE_LIQUID)
var/liquid_transferred = min(amount_to_transfer, CHEMS_QUANTIZE(LIQUID_VOLUME(src, rtype)))
target.add_reagent(rtype, liquid_transferred * multiplier, REAGENT_DATA(src, rtype), TRUE, TRUE, MAT_PHASE_LIQUID) // We don't react until everything is in place
+
. += liquid_transferred
amount_to_transfer -= liquid_transferred
@@ -885,6 +886,7 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new
if(!target.reagents)
target.create_reagents(FLUID_MAX_DEPTH)
+
trans_to_holder(target.reagents, amount, multiplier, copy, defer_update = defer_update, transferred_phases = transferred_phases)
// Deferred updates are presumably being done by SSfluids.
// Do an immediate fluid_act call rather than waiting for SSfluids to proc.
@@ -907,6 +909,12 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new
/* 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)
+
/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)]")
@@ -926,4 +934,4 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new
var/decl/material/newreagent = GET_DECL(reagent_type)
if(!istype(newreagent))
return FALSE
- return TRUE
\ No newline at end of file
+ return TRUE
diff --git a/code/modules/reagents/Chemistry-Taste.dm b/code/modules/reagents/Chemistry-Taste.dm
index 468897579942..73b25e51cd5c 100644
--- a/code/modules/reagents/Chemistry-Taste.dm
+++ b/code/modules/reagents/Chemistry-Taste.dm
@@ -72,4 +72,4 @@ calculate text size per text.
for(var/taste_desc in cocktail.tastes)
var/taste_power = cocktail.tastes[taste_desc] * cocktail_volume
tastes[taste_desc] += taste_power
- return tastes
\ No newline at end of file
+ return tastes
diff --git a/code/modules/reagents/chems/chems_ethanol.dm b/code/modules/reagents/chems/chems_alcohol.dm
similarity index 84%
rename from code/modules/reagents/chems/chems_ethanol.dm
rename to code/modules/reagents/chems/chems_alcohol.dm
index f7deadf14c9c..aa7ca92f847b 100644
--- a/code/modules/reagents/chems/chems_ethanol.dm
+++ b/code/modules/reagents/chems/chems_alcohol.dm
@@ -1,35 +1,30 @@
-/decl/material/liquid/ethanol
- name = "ethanol" //Parent class for all alcoholic reagents.
- lore_text = "A well-known alcohol with a variety of applications."
- taste_description = "pure alcohol"
+/decl/material/liquid/alcohol
+ abstract_type = /decl/material/liquid/alcohol
color = "#404030"
touch_met = 5
ignition_point = T0C+150
accelerant_value = FUEL_VALUE_ACCELERANT
solvent_power = MAT_SOLVENT_MODERATE
- uid = "chem_ethanol"
- boiling_point = T0C + 78.37
+ boiling_point = null // Pure ethanol boils, the rest has to separate first.
- heating_message = "boils away its ethanol content, leaving pure water."
+ heating_message = "boils away its water content, leaving pure alcohol."
heating_point = T0C + 78.37
heating_products = list(
- /decl/material/liquid/ethanol = 0.75,
- /decl/material/liquid/water = 0.25
+ /decl/material/liquid/alcohol/ethanol = 0.75,
+ /decl/material/liquid/water = 0.25
)
- bypass_heating_products_for_root_type = /decl/material/liquid/ethanol
- chilling_message = "separates as its water content freezes, leaving pure ethanol."
+ chilling_message = "separates as its water content freezes, leaving pure alcohol."
chilling_point = T0C
chilling_products = list(
- /decl/material/liquid/ethanol = 0.75,
- /decl/material/solid/ice = 0.25
+ /decl/material/liquid/alcohol/ethanol = 0.75,
+ /decl/material/solid/ice = 0.25
)
- bypass_chilling_products_for_root_type = /decl/material/liquid/ethanol
affect_blood_on_ingest = FALSE // prevents automatic toxins/inebriation as though injected
affect_blood_on_inhale = FALSE
- can_boil_to_gas = TRUE
- temperature_burn_milestone_material = /decl/material/liquid/ethanol
+
+ value = 1.2
var/strength = 10 // This is, essentially, units between stages - the lower, the stronger. Less fine tuning, more clarity.
var/alcohol_toxicity = 1
@@ -37,28 +32,18 @@
var/targ_temp = 310
var/halluci = 0
- glass_name = "ethanol"
- glass_desc = "A well-known alcohol with a variety of applications."
- value = 1.2
-
-/decl/material/liquid/ethanol/Initialize()
- . = ..()
- // Impure ethanol doesn't boil, it has to separate first.
- if(type != bypass_heating_products_for_root_type)
- boiling_point = null
-
-/decl/material/liquid/ethanol/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder)
+/decl/material/liquid/alcohol/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder)
..()
M.take_damage(removed * 2 * alcohol_toxicity, TOX)
M.add_chemical_effect(CE_ALCOHOL_TOXIC, alcohol_toxicity)
-/decl/material/liquid/ethanol/affect_inhale(mob/living/M, removed, datum/reagents/holder)
+/decl/material/liquid/alcohol/affect_inhale(mob/living/M, removed, datum/reagents/holder)
if(M.has_trait(/decl/trait/metabolically_inert))
return
..()
affect_ingest(M, removed, holder) // a bit of a hack, but it avoids code duplication
-/decl/material/liquid/ethanol/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
+/decl/material/liquid/alcohol/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
if(M.has_trait(/decl/trait/metabolically_inert))
return
@@ -99,7 +84,28 @@
if(halluci)
M.adjust_hallucination(halluci, halluci)
-/decl/material/liquid/ethanol/absinthe
+// Somewhat a dummy type for 'pure ethanol' to avoid having to set dirtiness/heating products/etc on literally everything else.
+/decl/material/liquid/alcohol/ethanol
+ name = "ethanol"
+ lore_text = "A well-known alcohol with a variety of applications."
+ taste_description = "pure alcohol"
+ glass_name = "ethanol"
+ glass_desc = "A well-known alcohol with a variety of applications."
+ dirtiness = DIRTINESS_STERILE
+ uid = "chem_ethanol"
+
+ // Uncomment when refining spirits is less annoying, specifically when we have more precise temperature control.
+ // boiling_point = T0C + 78.37
+ // can_boil_to_gas = TRUE
+ // temperature_burn_milestone_material = /decl/material/liquid/alcohol/ethanol
+
+ // Pure ethanol does not separate.
+ heating_point = null
+ heating_products = null
+ chilling_point = null
+ chilling_products = null
+
+/decl/material/liquid/alcohol/absinthe
name = "absinthe"
lore_text = "Watch out that the Green Fairy doesn't come for you!"
taste_description = "death and licorice"
@@ -113,7 +119,7 @@
glass_desc = "Wormwood, anise, oh my."
uid = "chem_ethanol_absinthe"
-/decl/material/liquid/ethanol/ale
+/decl/material/liquid/alcohol/ale
name = "ale"
lore_text = "A dark alchoholic beverage made by malted barley and yeast."
taste_description = "hearty barley ale"
@@ -126,7 +132,7 @@
glass_desc = "A freezing container of delicious ale"
uid = "chem_ethanol_ale"
-/decl/material/liquid/ethanol/beer
+/decl/material/liquid/alcohol/beer
name = "beer"
codex_name = "plain beer"
lore_text = "An alcoholic beverage made from malted grains, hops, yeast, and water."
@@ -141,18 +147,18 @@
glass_desc = "A freezing container of beer"
uid = "chem_ethanol_beer"
-/decl/material/liquid/ethanol/beer/good
+/decl/material/liquid/alcohol/beer/good
uid = "chem_ethanol_beer_good"
codex_name = "premium beer"
taste_description = "beer"
-/decl/material/liquid/ethanol/beer/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
+/decl/material/liquid/alcohol/beer/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
..()
if(M.has_trait(/decl/trait/metabolically_inert))
return
ADJ_STATUS(M, STAT_JITTER, -3)
-/decl/material/liquid/ethanol/bluecuracao
+/decl/material/liquid/alcohol/bluecuracao
name = "blue curacao"
lore_text = "Exotically blue, fruity drink, distilled from oranges."
taste_description = "oranges"
@@ -166,7 +172,7 @@
glass_name = "blue curacao"
glass_desc = "Exotically blue, fruity drink, distilled from oranges."
-/decl/material/liquid/ethanol/cognac
+/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."
taste_description = "rich and smooth alcohol"
@@ -180,7 +186,7 @@
glass_name = "cognac"
glass_desc = "Damn, you feel like some kind of French aristocrat just by holding this."
-/decl/material/liquid/ethanol/gin
+/decl/material/liquid/alcohol/gin
name = "gin"
lore_text = "It's gin. In space. I say, good sir."
taste_description = "an alcoholic christmas tree"
@@ -194,7 +200,7 @@
glass_desc = "A crystal clear glass of Griffeater gin."
//Base type for alchoholic drinks containing coffee
-/decl/material/liquid/ethanol/coffee
+/decl/material/liquid/alcohol/coffee
name = "coffee liqueur"
lore_text = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936!"
taste_description = "spiked coffee"
@@ -208,7 +214,7 @@
glass_desc = "Guaranteed to perk you up."
overdose = 45
-/decl/material/liquid/ethanol/coffee/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
+/decl/material/liquid/alcohol/coffee/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
..()
if(M.has_trait(/decl/trait/metabolically_inert))
@@ -220,10 +226,10 @@
if(M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
-/decl/material/liquid/ethanol/coffee/affect_overdose(mob/living/M, total_dose)
+/decl/material/liquid/alcohol/coffee/affect_overdose(mob/living/M, total_dose)
ADJ_STATUS(M, STAT_JITTER, 5)
-/decl/material/liquid/ethanol/melonliquor
+/decl/material/liquid/alcohol/melonliquor
name = "melon liqueur"
lore_text = "A relatively sweet and fruity 46 proof liqueur."
taste_description = "fruity alcohol"
@@ -236,7 +242,7 @@
glass_name = "melon liqueur"
glass_desc = "A relatively sweet and fruity 46 proof liquor."
-/decl/material/liquid/ethanol/rum
+/decl/material/liquid/alcohol/rum
name = "dark rum"
lore_text = "Yohoho and all that."
taste_description = "spiked butterscotch"
@@ -250,7 +256,7 @@
glass_name = "rum"
glass_desc = "Now you want to Pray for a pirate suit, don't you?"
-/decl/material/liquid/ethanol/sake
+/decl/material/liquid/alcohol/sake
name = "sake"
lore_text = "Anime's favorite drink."
taste_description = "dry alcohol"
@@ -263,7 +269,7 @@
glass_name = "sake"
glass_desc = "A glass of sake."
-/decl/material/liquid/ethanol/tequila
+/decl/material/liquid/alcohol/tequila
name = "tequila"
lore_text = "A strong and mildly flavoured, mexican produced spirit. Feeling thirsty hombre?"
taste_description = "paint stripper"
@@ -276,7 +282,7 @@
glass_name = "tequila"
glass_desc = "Now all that's missing is the weird colored shades!"
-/decl/material/liquid/ethanol/thirteenloko
+/decl/material/liquid/alcohol/thirteenloko
name = "Thirteen Loko"
lore_text = "A potent mixture of caffeine and alcohol."
taste_description = "jitters and death"
@@ -290,7 +296,7 @@
glass_name = "Thirteen Loko"
glass_desc = "This is a glass of Thirteen Loko, it appears to be of the highest quality. The drink, not the glass."
-/decl/material/liquid/ethanol/thirteenloko/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
+/decl/material/liquid/alcohol/thirteenloko/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
..()
if(M.has_trait(/decl/trait/metabolically_inert))
@@ -302,7 +308,7 @@
ADJ_STATUS(M, STAT_JITTER, 5)
M.add_chemical_effect(CE_PULSE, 2)
-/decl/material/liquid/ethanol/vermouth
+/decl/material/liquid/alcohol/vermouth
name = "vermouth"
lore_text = "You suddenly feel a craving for a martini..."
taste_description = "dry alcohol"
@@ -316,7 +322,7 @@
glass_name = "vermouth"
glass_desc = "You wonder why you're even drinking this straight."
-/decl/material/liquid/ethanol/vodka
+/decl/material/liquid/alcohol/vodka
name = "vodka"
codex_name = "plain vodka"
lore_text = "Number one drink AND fueling choice for Independents around the galaxy."
@@ -330,7 +336,7 @@
glass_name = "vodka"
glass_desc = "The glass contain wodka. Xynta."
-/decl/material/liquid/ethanol/vodka/premium
+/decl/material/liquid/alcohol/vodka/premium
name = "premium vodka"
codex_name = null
lore_text = "Premium distilled vodka imported directly from the Gilgamesh Colonial Confederation."
@@ -341,7 +347,7 @@
exoplanet_rarity_gas = MAT_RARITY_NOWHERE
uid = "chem_ethanol_premiumvodka"
-/decl/material/liquid/ethanol/whiskey
+/decl/material/liquid/alcohol/whiskey
name = "malt whiskey"
lore_text = "A superb and well-aged single-malt whiskey. Damn."
taste_description = "molasses"
@@ -354,7 +360,7 @@
glass_name = "whiskey"
glass_desc = "The silky, smokey whiskey goodness inside the glass makes the drink look very classy."
-/decl/material/liquid/ethanol/wine
+/decl/material/liquid/alcohol/wine
name = "red wine"
lore_text = "An premium alchoholic beverage made from distilled grape juice."
taste_description = "bitter sweetness"
@@ -367,7 +373,7 @@
glass_name = "red wine"
glass_desc = "A very classy looking drink."
-/decl/material/liquid/ethanol/wine/premium
+/decl/material/liquid/alcohol/wine/premium
name = "white wine"
lore_text = "An exceptionally expensive alchoholic beverage made from distilled white grapes."
taste_description = "white velvet"
@@ -377,7 +383,7 @@
exoplanet_rarity_gas = MAT_RARITY_NOWHERE
uid = "chem_ethanol_whitewine"
-/decl/material/liquid/ethanol/herbal
+/decl/material/liquid/alcohol/herbal
name = "herbal liquor"
lore_text = "A complex blend of herbs, spices and roots mingle in this old Earth classic."
taste_description = "a sweet summer garden"
@@ -390,7 +396,7 @@
glass_name = "herbal liquor"
glass_desc = "It's definitely green. Or is it yellow?"
-/decl/material/liquid/ethanol/hooch
+/decl/material/liquid/alcohol/hooch
name = "hooch"
lore_text = "Either someone's failure at cocktail making or attempt in alchohol production. In any case, do you really want to drink that?"
taste_description = "pure resignation"
@@ -404,7 +410,7 @@
glass_name = "Hooch"
glass_desc = "You've really hit rock bottom now... your liver packed its bags and left last night."
-/decl/material/liquid/ethanol/irish_cream
+/decl/material/liquid/alcohol/irish_cream
name = "Irish cream"
lore_text = "Whiskey-imbued cream."
taste_description = "creamy alcohol"
@@ -417,7 +423,7 @@
glass_name = "Irish cream"
glass_desc = "It's cream, mixed with whiskey."
-/decl/material/liquid/ethanol/mead
+/decl/material/liquid/alcohol/mead
name = "mead"
lore_text = "A Viking's drink, though a cheap one."
taste_description = "sweet, sweet alcohol"
@@ -431,7 +437,7 @@
glass_name = "mead"
glass_desc = "A Viking's beverage, though a cheap one."
-/decl/material/liquid/ethanol/moonshine
+/decl/material/liquid/alcohol/moonshine
name = "moonshine"
lore_text = "You've really hit rock bottom now... your liver packed its bags and left last night."
taste_description = "bitterness"
@@ -445,7 +451,7 @@
glass_name = "moonshine"
glass_desc = "You've really hit rock bottom now... your liver packed its bags and left last night."
-/decl/material/liquid/ethanol/pwine
+/decl/material/liquid/alcohol/pwine
name = "poison wine"
lore_text = "Is this even wine? Toxic! Hallucinogenic! Probably consumed in boatloads by your superiors!"
taste_description = "purified alcoholic death"
@@ -459,7 +465,7 @@
exoplanet_rarity_gas = MAT_RARITY_NOWHERE
uid = "chem_ethanol_poisonwine"
-/decl/material/liquid/ethanol/pwine/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
+/decl/material/liquid/alcohol/pwine/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
..()
if(M.has_trait(/decl/trait/metabolically_inert))
@@ -477,7 +483,7 @@
else
heart.take_internal_damage(100, 0)
-/decl/material/liquid/ethanol/aged_whiskey // I have no idea what this is and where it comes from. //It comes from Dinnlan now
+/decl/material/liquid/alcohol/aged_whiskey // I have no idea what this is and where it comes from. //It comes from Dinnlan now
name = "aged whiskey"
lore_text = "A well-aged whiskey of high quality. Probably imported. Just a sip'll do it, but that burn will leave you wanting more."
color = "#523600"
@@ -489,7 +495,7 @@
glass_name = "aged whiskey"
glass_desc = "A well-aged whiskey of high quality. Probably imported."
-/decl/material/liquid/ethanol/cider_apple
+/decl/material/liquid/alcohol/cider_apple
name = "apple cider"
lore_text = "A refreshing glass of apple cider."
taste_description = "cool apple cider"
@@ -502,7 +508,7 @@
glass_name = "apple cider"
glass_desc = "A refreshing glass of apple cider."
-/decl/material/liquid/ethanol/cider_pear
+/decl/material/liquid/alcohol/cider_pear
name = "pear cider"
lore_text = "A refreshing glass of pear cider."
taste_description = "cool pear cider"
@@ -515,7 +521,7 @@
glass_name = "pear cider"
glass_desc = "A refreshing glass of pear cider."
-/decl/material/liquid/ethanol/champagne
+/decl/material/liquid/alcohol/champagne
name = "champagne"
lore_text = "Smooth sparkling wine, produced in the same region of France as it has been for centuries."
taste_description = "bitterness and fizz"
@@ -529,7 +535,7 @@
glass_desc = "Sparkling white wine, produced in the same region of France as it has been for centuries."
glass_special = list(DRINK_FIZZ)
-/decl/material/liquid/ethanol/jagermeister
+/decl/material/liquid/alcohol/jagermeister
name = "Jagermeister"
lore_text = "A special blend of alcohol, herbs, and spices. It has remained a popular Earther drink."
taste_description = "herbs, spices, and alcohol"
@@ -542,7 +548,7 @@
glass_name = "jagermeister"
glass_desc = "A special blend of alcohol, herbs, and spices. It has remained a popular Earther drink."
-/decl/material/liquid/ethanol/kvass
+/decl/material/liquid/alcohol/kvass
name = "kvass"
lore_text = "An alcoholic drink commonly made from bread."
taste_description = "vkusnyy kvas, ypa!"
diff --git a/code/modules/reagents/chems/chems_drinks.dm b/code/modules/reagents/chems/chems_drinks.dm
index ba069e72a232..af54d84cd623 100644
--- a/code/modules/reagents/chems/chems_drinks.dm
+++ b/code/modules/reagents/chems/chems_drinks.dm
@@ -178,15 +178,16 @@
allergen_flags = ALLERGEN_VEGETABLE
/decl/material/liquid/drink/juice/garlic
- name = "garlic juice"
- lore_text = "Who would even drink this?"
+ name = "garlic oil"
+ lore_text = "A strong-smelling, pungent oil pressed from garlic cloves. It has some antibiotic properties, and can help with infections."
taste_description = "bad breath"
nutriment_factor = 1
color = "#eeddcc"
uid = "chem_drink_garlic"
+ antibiotic_strength = 0.65
- glass_name = "garlic juice"
- glass_desc = "Who would even drink juice from garlic?"
+ glass_name = "garlic oil"
+ glass_desc = "A potion of guaranteed bad breath."
allergen_flags = ALLERGEN_ALLIUM
/decl/material/liquid/drink/juice/onion
@@ -308,6 +309,7 @@
taste_description = "creamy milk"
color = "#dfd7af"
uid = "chem_drink_cream"
+ skimmable = TRUE
glass_name = "cream"
glass_desc = "Ewwww..."
diff --git a/code/modules/reagents/chems/chems_herbal.dm b/code/modules/reagents/chems/chems_herbal.dm
index f9f7d7bb4807..676142113fb2 100644
--- a/code/modules/reagents/chems/chems_herbal.dm
+++ b/code/modules/reagents/chems/chems_herbal.dm
@@ -15,10 +15,16 @@
/decl/material/liquid/antitoxins/ginseng
name = "powdered ginseng"
uid = "chem_antitoxins_herbal"
- lore_text = "Ginseng root has curative properties and encourages organ recovery after poisoning."
+ lore_text = "Ginseng root has curative properties and encourages organ recovery and restoration of blood volume after poisoning or blood loss."
taste_description = "bitter herbs"
antitoxin_strength = 0.35
+/decl/material/liquid/antitoxins/ginseng/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder)
+ . = ..()
+ if(M.has_trait(/decl/trait/metabolically_inert))
+ return
+ M.add_chemical_effect(CE_BLOODRESTORE, 8 * removed)
+
/decl/material/liquid/sedatives/valerian
name = "powdered valerian flower"
uid = "chem_sedatives_herbal"
diff --git a/code/modules/reagents/chems/chems_medicines.dm b/code/modules/reagents/chems/chems_medicines.dm
index 5724175fbce5..701d2f1d4763 100644
--- a/code/modules/reagents/chems/chems_medicines.dm
+++ b/code/modules/reagents/chems/chems_medicines.dm
@@ -236,19 +236,10 @@
overdose = REAGENTS_OVERDOSE/2
scannable = 1
value = 1.5
+ antibiotic_strength = 1
exoplanet_rarity_gas = MAT_RARITY_EXOTIC
uid = "chem_antibiotics"
-/decl/material/liquid/antibiotics/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder)
- var/volume = REAGENT_VOLUME(holder, type)
- . = ..()
- M.adjust_immunity(-0.1)
- M.add_chemical_effect(CE_ANTIBIOTIC, 1)
- if(volume > 10)
- M.adjust_immunity(-0.3)
- if(LAZYACCESS(M.chem_doses, type) > 15)
- M.adjust_immunity(-0.25)
-
/decl/material/liquid/antibiotics/affect_overdose(mob/living/M, total_dose)
..()
M.adjust_immunity(-0.5)
diff --git a/code/modules/reagents/chems/chems_nutriment.dm b/code/modules/reagents/chems/chems_nutriment.dm
index 3ac879172e79..d96d2b840d70 100644
--- a/code/modules/reagents/chems/chems_nutriment.dm
+++ b/code/modules/reagents/chems/chems_nutriment.dm
@@ -62,19 +62,6 @@
uid = "chem_nutriment_plant"
allergen_flags = ALLERGEN_VEGETABLE
-/decl/material/liquid/nutriment/plant_oil
- name = "plant oil"
- lore_text = "A thin yellow oil pressed from vegetables or nuts. Useful as fuel, or in cooking."
- uid = "chem_nutriment_plant_oil"
- melting_point = 273
- boiling_point = 373
- taste_description = "oily blandness"
- burn_product = /decl/material/gas/carbon_monoxide
- ignition_point = T0C+150
- accelerant_value = FUEL_VALUE_ACCELERANT
- gas_flags = XGM_GAS_FUEL
- allergen_flags = ALLERGEN_VEGETABLE
-
/decl/material/liquid/nutriment/honey
name = "honey"
lore_text = "A golden yellow syrup, loaded with sugary sweetness."
@@ -309,19 +296,6 @@
boiling_point = 373
allergen_flags = ALLERGEN_FRUIT
-/decl/material/liquid/nutriment/cornoil
- name = "corn oil"
- lore_text = "An oil derived from various types of corn."
- taste_description = "slime"
- taste_mult = 0.1
- nutriment_factor = 20
- color = "#302000"
- slipperiness = 8
- uid = "chem_nutriment_cornoil"
- melting_point = 273
- boiling_point = 373
- allergen_flags = ALLERGEN_VEGETABLE
-
/decl/material/liquid/nutriment/sprinkles
name = "sprinkles"
lore_text = "Multi-colored little bits of sugar, commonly found on donuts. Loved by cops."
diff --git a/code/modules/reagents/chems/chems_oil.dm b/code/modules/reagents/chems/chems_oil.dm
new file mode 100644
index 000000000000..ad359dd61ca4
--- /dev/null
+++ b/code/modules/reagents/chems/chems_oil.dm
@@ -0,0 +1,52 @@
+/decl/material/liquid/oil
+ name = "fuel oil" // paraffin etc
+ lore_text = "Clarified fuel oil, perfect for fuelling a lantern."
+ burn_product = /decl/material/gas/carbon_monoxide
+ ignition_point = T0C+150
+ accelerant_value = FUEL_VALUE_ACCELERANT
+ gas_flags = XGM_GAS_FUEL
+ melting_point = 273
+ boiling_point = 373
+ uid = "chem_oil_lamp"
+ color = "#664330"
+ value = 1.5
+ fishing_bait_value = 0
+ taste_mult = 4
+ metabolism = REM * 4
+ exoplanet_rarity_gas = MAT_RARITY_NOWHERE
+ affect_blood_on_ingest = 0
+ affect_blood_on_inhale = 0
+ slipperiness = 8
+
+/decl/material/liquid/oil/plant
+ name = "plant oil"
+ lore_text = "A thin yellow oil pressed from vegetables or nuts. Useful as fuel, or in cooking."
+ uid = "chem_oil_plant"
+ taste_description = "oily blandness"
+ allergen_flags = ALLERGEN_VEGETABLE
+ compost_value = 1
+ nutriment_factor = 8
+
+/decl/material/liquid/oil/plant/corn
+ name = "corn oil"
+ lore_text = "An oil derived from various types of corn."
+ taste_description = "slime"
+ nutriment_factor = 20
+ color = "#302000"
+ uid = "chem_oil_corn"
+ taste_mult = 0.1
+
+/decl/material/liquid/oil/fish
+ name = "fish oil"
+ lore_text = "A pungent yellow oil pressed from fish meat and fish skin. Useful as fuel, or in cooking, or for encouraging recovery after brain injuries."
+ uid = "chem_oil_fish"
+ taste_description = "pungent, oily fish"
+ allergen_flags = ALLERGEN_FISH
+ compost_value = 1
+ nutriment_factor = 6
+
+// Copied from neuroannealer; yes, it's silly, but we need a way to treat brain damage on the medieval map.
+// Should possibly be an ingredient rather than the be-all end-all medication.
+/decl/material/liquid/oil/fish/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder)
+ . = ..()
+ M.add_chemical_effect(CE_BRAIN_REGEN, 0.5) // Half as effective as neuroannealer, without the side-effects.
diff --git a/code/modules/reagents/chems/chems_painkillers.dm b/code/modules/reagents/chems/chems_painkillers.dm
index dc75c84c4ad4..6647c2afed2d 100644
--- a/code/modules/reagents/chems/chems_painkillers.dm
+++ b/code/modules/reagents/chems/chems_painkillers.dm
@@ -132,7 +132,7 @@
if(ingested)
var/list/pool = M.reagents.reagent_volumes | ingested.reagent_volumes
for(var/rtype in pool)
- var/decl/material/liquid/ethanol/booze = GET_DECL(rtype)
+ var/decl/material/liquid/alcohol/booze = GET_DECL(rtype)
if(!istype(booze) ||LAZYACCESS(M.chem_doses, rtype) < 2) //let them experience false security at first
continue
. = 1
diff --git a/code/modules/reagents/chems/random/chems_random.dm b/code/modules/reagents/chems/random/chems_random.dm
index 5327c213c049..2f67984c0097 100644
--- a/code/modules/reagents/chems/random/chems_random.dm
+++ b/code/modules/reagents/chems/random/chems_random.dm
@@ -6,7 +6,7 @@ var/global/list/random_chem_interaction_blacklist = list(
/decl/material/solid/tobacco,
/decl/material/liquid/drink,
/decl/material/liquid/random,
- /decl/material/liquid/ethanol // Includes alcoholic beverages
+ /decl/material/liquid/alcohol // Includes alcoholic beverages
)
#define FOR_ALL_EFFECTS \
diff --git a/code/modules/reagents/chems/random/random_effects.dm b/code/modules/reagents/chems/random/random_effects.dm
index af118872c971..0ef001eb16ad 100644
--- a/code/modules/reagents/chems/random/random_effects.dm
+++ b/code/modules/reagents/chems/random/random_effects.dm
@@ -227,7 +227,7 @@
mode = RANDOM_CHEM_EFFECT_INT
desc = "acute toxicity"
-/decl/random_chem_effect/random_properties/heal_brute/affect_blood(var/mob/living/M, var/removed, var/value)
+/decl/random_chem_effect/random_properties/tox_damage/affect_blood(var/mob/living/M, var/removed, var/value)
M.take_damage(value * removed, TOX)
/decl/random_chem_effect/random_properties/heal_brute
@@ -243,7 +243,7 @@
maximum = 10
desc = "burn repair"
-/decl/random_chem_effect/random_properties/heal_brute/affect_blood(var/mob/living/M, var/removed, var/value)
+/decl/random_chem_effect/random_properties/heal_burns/affect_blood(var/mob/living/M, var/removed, var/value)
M.heal_organ_damage(0, removed * value)
#undef RANDOM_CHEM_EFFECT_TRUE
diff --git a/code/modules/reagents/cocktails.dm b/code/modules/reagents/cocktails.dm
index 8bfe4705a959..166d689541b1 100644
--- a/code/modules/reagents/cocktails.dm
+++ b/code/modules/reagents/cocktails.dm
@@ -104,7 +104,7 @@
description = "Watered-down rum. Pirate approved!"
ratios = list(
/decl/material/liquid/water = 1,
- /decl/material/liquid/ethanol/rum = 1
+ /decl/material/liquid/alcohol/rum = 1
)
/decl/cocktail/screwdriver
@@ -112,7 +112,7 @@
description = "A classic mixture of vodka and orange juice. Just the thing for the tired engineer."
ratios = list(
/decl/material/liquid/drink/juice/orange = 4,
- /decl/material/liquid/ethanol/vodka = 1
+ /decl/material/liquid/alcohol/vodka = 1
)
/decl/cocktail/tequila_sunrise
@@ -120,39 +120,39 @@
description = "A simple cocktail of tequila and orange juice. Much like a screwdriver."
ratios = list(
/decl/material/liquid/drink/juice/orange = 4,
- /decl/material/liquid/ethanol/tequila = 1
+ /decl/material/liquid/alcohol/tequila = 1
)
/decl/cocktail/classic_martini
name = "gin martini"
description = "Vermouth with gin. The classiest of all cocktails."
ratios = list(
- /decl/material/liquid/ethanol/gin = 4,
- /decl/material/liquid/ethanol/vermouth = 1
+ /decl/material/liquid/alcohol/gin = 4,
+ /decl/material/liquid/alcohol/vermouth = 1
)
/decl/cocktail/vodka_martini
name = "vodka martini"
description = "A bastardisation of the classic martini. Still great."
ratios = list(
- /decl/material/liquid/ethanol/vodka = 4,
- /decl/material/liquid/ethanol/vermouth = 1
+ /decl/material/liquid/alcohol/vodka = 4,
+ /decl/material/liquid/alcohol/vermouth = 1
)
/decl/cocktail/allies_cocktail
name = "Allies Cocktail"
description = "A drink made from your allies, not as sweet as when made from your enemies."
ratios = list(
- /decl/material/liquid/ethanol/vermouth = 2,
- /decl/material/liquid/ethanol/vodka = 2,
- /decl/material/liquid/ethanol/gin = 2
+ /decl/material/liquid/alcohol/vermouth = 2,
+ /decl/material/liquid/alcohol/vodka = 2,
+ /decl/material/liquid/alcohol/gin = 2
)
/decl/cocktail/bilk
name = "bilk"
description = "A foul brew of milk and beer. For alcoholics who fear osteoporosis."
ratios = list(
- /decl/material/liquid/ethanol/beer = 1,
+ /decl/material/liquid/alcohol/beer = 1,
/decl/material/liquid/drink/milk = 1
)
@@ -161,7 +161,7 @@
description = "A mild cocktail, widely considered an all-time classic."
ratios = list(
/decl/material/liquid/drink/tonic = 4,
- /decl/material/liquid/ethanol/gin = 1
+ /decl/material/liquid/alcohol/gin = 1
)
/decl/cocktail/cuba_libre
@@ -169,24 +169,24 @@
description = "A classic mix of rum and cola."
ratios = list(
/decl/material/liquid/drink/cola = 4,
- /decl/material/liquid/ethanol/rum = 1
+ /decl/material/liquid/alcohol/rum = 1
)
/decl/cocktail/black_russian
name = "black Russian"
description = "Similar to a white Russian, but fit for the lactose-intolerant."
ratios = list(
- /decl/material/liquid/ethanol/vodka = 2,
- /decl/material/liquid/ethanol/coffee = 1
+ /decl/material/liquid/alcohol/vodka = 2,
+ /decl/material/liquid/alcohol/coffee = 1
)
/decl/cocktail/white_russian
name = "white Russian"
description = "A straightforward cocktail of coffee liqueur and vodka. Popular in a lot of places, but that's just, like, an opinion, man."
ratios = list(
- /decl/material/liquid/ethanol/coffee = 2,
+ /decl/material/liquid/alcohol/coffee = 2,
/decl/material/liquid/drink/milk/cream,
- /decl/material/liquid/ethanol/vodka = 1
+ /decl/material/liquid/alcohol/vodka = 1
)
/decl/cocktail/whiskey_cola
@@ -194,7 +194,7 @@
description = "Whiskey mixed with cola. Quite refreshing."
ratios = list(
/decl/material/liquid/drink/cola = 4,
- /decl/material/liquid/ethanol/whiskey = 1
+ /decl/material/liquid/alcohol/whiskey = 1
)
/decl/cocktail/bloody_mary
@@ -202,7 +202,7 @@
description = "A cocktail of vodka, tomato and lime juice. Celery stalk optional."
ratios = list(
/decl/material/liquid/drink/juice/tomato = 3,
- /decl/material/liquid/ethanol/vodka = 1,
+ /decl/material/liquid/alcohol/vodka = 1,
/decl/material/liquid/drink/juice/lime = 1
)
@@ -210,10 +210,10 @@
name = "The Livergeist"
description = "A cocktail pioneered by a small cabal with a vendetta against the liver. Drink very carefully."
ratios = list(
- /decl/material/liquid/ethanol/vodka = 1,
- /decl/material/liquid/ethanol/gin = 1,
- /decl/material/liquid/ethanol/aged_whiskey = 1,
- /decl/material/liquid/ethanol/cognac = 1,
+ /decl/material/liquid/alcohol/vodka = 1,
+ /decl/material/liquid/alcohol/gin = 1,
+ /decl/material/liquid/alcohol/aged_whiskey = 1,
+ /decl/material/liquid/alcohol/cognac = 1,
/decl/material/liquid/drink/juice/lime = 1
)
@@ -221,16 +221,16 @@
name = "Brave Bull"
description = "A strong cocktail of tequila and coffee liquor."
ratios = list(
- /decl/material/liquid/ethanol/tequila = 2,
- /decl/material/liquid/ethanol/coffee = 1
+ /decl/material/liquid/alcohol/tequila = 2,
+ /decl/material/liquid/alcohol/coffee = 1
)
/decl/cocktail/toxins_special
name = "H2 Special"
description = "Raise a glass to the bomb technicians of yesteryear, wherever their ashes now reside."
ratios = list(
- /decl/material/liquid/ethanol/rum = 1,
- /decl/material/liquid/ethanol/vermouth = 1,
+ /decl/material/liquid/alcohol/rum = 1,
+ /decl/material/liquid/alcohol/vermouth = 1,
/decl/material/solid/metallic_hydrogen
)
@@ -238,7 +238,7 @@
name = "Beepsky Smash"
description = "A cocktail originating with stationside security forces. Rumoured to take the edge off being stunned with your own baton."
ratios = list(
- /decl/material/liquid/ethanol/whiskey = 2,
+ /decl/material/liquid/alcohol/whiskey = 2,
/decl/material/liquid/drink/juice/lime = 1,
/decl/material/solid/metal/iron
)
@@ -258,8 +258,8 @@
name = "The Manly Dorf"
description = "A cocktail of old that claims to be for manly men, but is mostly for people who can't tell beer and ale apart."
ratios = list(
- /decl/material/liquid/ethanol/ale = 1,
- /decl/material/liquid/ethanol/beer = 1
+ /decl/material/liquid/alcohol/ale = 1,
+ /decl/material/liquid/alcohol/beer = 1
)
/decl/cocktail/irish_coffee
@@ -267,16 +267,16 @@
description = "A cocktail of coffee, whiskey and cream, just the thing to kick you awake while also dulling the pain of existence."
ratios = list(
/decl/material/liquid/drink/coffee = 4,
- /decl/material/liquid/ethanol/irish_cream = 1
+ /decl/material/liquid/alcohol/irish_cream = 1
)
/decl/cocktail/b52
name = "B-52"
description = "A semi-modern spin on an Irish coffee, featuring a dash of cognac. It will get you bombed."
ratios = list(
- /decl/material/liquid/ethanol/coffee = 1,
- /decl/material/liquid/ethanol/irish_cream = 1,
- /decl/material/liquid/ethanol/cognac = 1
+ /decl/material/liquid/alcohol/coffee = 1,
+ /decl/material/liquid/alcohol/irish_cream = 1,
+ /decl/material/liquid/alcohol/cognac = 1
)
order_specific = TRUE // layered cocktail
@@ -284,9 +284,9 @@
name = "Atomic Bomb"
description = "A radioactive take on a B-52, popularized by asteroid miners with prosthetic organs and something to prove."
ratios = list(
- /decl/material/liquid/ethanol/coffee = 1,
- /decl/material/liquid/ethanol/irish_cream = 1,
- /decl/material/liquid/ethanol/cognac = 1,
+ /decl/material/liquid/alcohol/coffee = 1,
+ /decl/material/liquid/alcohol/irish_cream = 1,
+ /decl/material/liquid/alcohol/cognac = 1,
/decl/material/solid/metal/uranium
)
order_specific = TRUE // layered cocktail
@@ -296,7 +296,7 @@
name = "margarita"
description = "A classic cocktail of antiquity."
ratios = list(
- /decl/material/liquid/ethanol/tequila = 3,
+ /decl/material/liquid/alcohol/tequila = 3,
/decl/material/liquid/drink/juice/lime = 1
)
@@ -305,10 +305,10 @@
description = "Most of the liquor cabinet, brought together in a delicious mix. Designed for middle-aged alcoholics."
ratios = list(
/decl/material/liquid/drink/cola = 2,
- /decl/material/liquid/ethanol/rum = 1,
- /decl/material/liquid/ethanol/vodka = 1,
- /decl/material/liquid/ethanol/gin = 1,
- /decl/material/liquid/ethanol/tequila = 1
+ /decl/material/liquid/alcohol/rum = 1,
+ /decl/material/liquid/alcohol/vodka = 1,
+ /decl/material/liquid/alcohol/gin = 1,
+ /decl/material/liquid/alcohol/tequila = 1
)
/decl/cocktail/threemileisland
@@ -316,10 +316,10 @@
description = "Much like the Atomic Bomb, this cocktail was adapted by asteroid miners who couldn't enjoy a drink without a dose of radiation poisoning."
ratios = list(
/decl/material/liquid/drink/cola = 2,
- /decl/material/liquid/ethanol/rum = 1,
- /decl/material/liquid/ethanol/vodka = 1,
- /decl/material/liquid/ethanol/gin = 1,
- /decl/material/liquid/ethanol/tequila = 1,
+ /decl/material/liquid/alcohol/rum = 1,
+ /decl/material/liquid/alcohol/vodka = 1,
+ /decl/material/liquid/alcohol/gin = 1,
+ /decl/material/liquid/alcohol/tequila = 1,
/decl/material/solid/metal/uranium
)
@@ -328,23 +328,23 @@
description = "A simple cocktail, considered to be cultured and refined."
ratios = list(
/decl/material/liquid/drink/sodawater = 4,
- /decl/material/liquid/ethanol/whiskey = 1
+ /decl/material/liquid/alcohol/whiskey = 1
)
/decl/cocktail/manhattan
name = "Manhattan"
description = "Another classic cocktail of antiquity. Popular with private investigators."
ratios = list(
- /decl/material/liquid/ethanol/whiskey = 2,
- /decl/material/liquid/ethanol/vermouth = 1
+ /decl/material/liquid/alcohol/whiskey = 2,
+ /decl/material/liquid/alcohol/vermouth = 1
)
/decl/cocktail/manhattan_proj
name = "Manhattan Project"
description = "A classic cocktail with a spicy twist, pioneered by a robot detective."
ratios = list(
- /decl/material/liquid/ethanol/whiskey = 2,
- /decl/material/liquid/ethanol/vermouth = 1,
+ /decl/material/liquid/alcohol/whiskey = 2,
+ /decl/material/liquid/alcohol/vermouth = 1,
/decl/material/solid/metal/uranium
)
@@ -353,14 +353,14 @@
description = "A simple, refreshing cocktail with a kick to it."
ratios = list(
/decl/material/liquid/drink/tonic = 4,
- /decl/material/liquid/ethanol/vodka = 1
+ /decl/material/liquid/alcohol/vodka = 1
)
/decl/cocktail/gin_fizz
name = "gin fizz"
description = "A dry, refreshing cocktail with a tang of lime."
ratios = list(
- /decl/material/liquid/ethanol/gin = 2,
+ /decl/material/liquid/alcohol/gin = 2,
/decl/material/liquid/drink/sodawater = 2,
/decl/material/liquid/drink/juice/lime = 1
)
@@ -369,7 +369,7 @@
name = "Bahama Mama"
description = "A sweet tropical cocktail that is deceptively strong."
ratios = list(
- /decl/material/liquid/ethanol/rum = 2,
+ /decl/material/liquid/alcohol/rum = 2,
/decl/material/liquid/drink/juice/orange = 2,
/decl/material/liquid/drink/juice/lime = 2,
/decl/material/liquid/drink/grenadine = 1
@@ -379,8 +379,8 @@
name = "Singulo"
description = "Traditionally thrown together from maintenance stills and used to treat singularity exposure in engineers who forgot their meson goggles."
ratios = list(
- /decl/material/liquid/ethanol/vodka = 1,
- /decl/material/liquid/ethanol/wine = 1,
+ /decl/material/liquid/alcohol/vodka = 1,
+ /decl/material/liquid/alcohol/wine = 1,
/decl/material/solid/metal/radium
)
@@ -388,7 +388,7 @@
name = "Demon's Blood"
description = "A ghoulish cocktail that originated as a practical joke in a fringe habitat."
ratios = list(
- /decl/material/liquid/ethanol/rum = 2,
+ /decl/material/liquid/alcohol/rum = 2,
/decl/material/liquid/drink/citrussoda = 2,
/decl/material/liquid/drink/cherrycola = 2,
/decl/material/liquid/blood = 1
@@ -399,7 +399,7 @@
description = "A thick and creamy cocktail."
ratios = list(
/decl/material/liquid/drink/milk/cream = 2,
- /decl/material/liquid/ethanol/rum = 2,
+ /decl/material/liquid/alcohol/rum = 2,
/decl/material/liquid/drink/juice/banana = 1,
/decl/material/liquid/drink/juice/watermelon = 1
)
@@ -408,7 +408,7 @@
name = "Anti-freeze"
description = "A chilled cocktail invented and popularized by corona miners."
ratios = list(
- /decl/material/liquid/ethanol/vodka = 3,
+ /decl/material/liquid/alcohol/vodka = 3,
/decl/material/liquid/drink/milk/cream = 2,
/decl/material/solid/ice = 2
)
@@ -417,7 +417,7 @@
name = "Barefoot"
description = "A smooth cocktail that will take your mind off the broken glass you stepped on."
ratios = list(
- /decl/material/liquid/ethanol/vermouth = 4,
+ /decl/material/liquid/alcohol/vermouth = 4,
/decl/material/liquid/drink/juice/berry = 2,
/decl/material/liquid/drink/milk/cream = 1
)
@@ -426,7 +426,7 @@
name = "sbiten"
description = "A form of spiced mead that will bring tears to the eyes of the most hardened drinker."
ratios = list(
- /decl/material/liquid/ethanol/mead = 9,
+ /decl/material/liquid/alcohol/mead = 9,
/decl/material/liquid/capsaicin = 1
)
@@ -434,7 +434,7 @@
name = "red mead"
description = "Supposedly a traditional drink amongst mercenary groups prior to dangerous missions."
ratios = list(
- /decl/material/liquid/ethanol/mead = 1,
+ /decl/material/liquid/alcohol/mead = 1,
/decl/material/liquid/blood = 1
)
@@ -442,7 +442,7 @@
name = "Acid Spit"
description = "A cocktail inspired by monsters of legend, popular with college students daring their friends to drink one."
ratios = list(
- /decl/material/liquid/ethanol/wine = 1,
+ /decl/material/liquid/alcohol/wine = 1,
/decl/material/liquid/acid
)
@@ -454,17 +454,17 @@
/decl/material/liquid/drink/juice/orange = 2,
/decl/material/liquid/drink/juice/lime = 1,
/decl/material/liquid/drink/juice/lemon = 1,
- /decl/material/liquid/ethanol/vodka = 1
+ /decl/material/liquid/alcohol/vodka = 1
)
/decl/cocktail/neurotoxin
name = "Neurotoxin"
description = "A cocktail primarily intended for people with a grudge against their own brain."
ratios = list(
- /decl/material/liquid/ethanol/vodka = 1,
- /decl/material/liquid/ethanol/gin = 1,
- /decl/material/liquid/ethanol/aged_whiskey = 1,
- /decl/material/liquid/ethanol/cognac = 1,
+ /decl/material/liquid/alcohol/vodka = 1,
+ /decl/material/liquid/alcohol/gin = 1,
+ /decl/material/liquid/alcohol/aged_whiskey = 1,
+ /decl/material/liquid/alcohol/cognac = 1,
/decl/material/liquid/drink/juice/lime = 1,
/decl/material/liquid/sedatives
)
@@ -474,16 +474,16 @@
description = "A tangy, fizzy twist on beer."
ratios = list(
/decl/material/liquid/drink/lemon_lime = 3,
- /decl/material/liquid/ethanol/beer = 1
+ /decl/material/liquid/alcohol/beer = 1
)
/decl/cocktail/irishslammer
name = "Irish Slammer"
description = "A rich cocktail of whiskey, stout and cream that was performed using a shot glass before glass-interleaving technology was lost."
ratios = list(
- /decl/material/liquid/ethanol/ale = 5,
- /decl/material/liquid/ethanol/whiskey = 1,
- /decl/material/liquid/ethanol/irish_cream = 1
+ /decl/material/liquid/alcohol/ale = 5,
+ /decl/material/liquid/alcohol/whiskey = 1,
+ /decl/material/liquid/alcohol/irish_cream = 1
)
// A whiskey cola with added beer.
@@ -491,8 +491,8 @@
name = "Syndicate Bomb"
description = "A murky cocktail reputed to have originated in criminal circles. It will definitely get you bombed."
ratios = list(
- /decl/material/liquid/ethanol/whiskey = 1,
- /decl/material/liquid/ethanol/beer = 1,
+ /decl/material/liquid/alcohol/whiskey = 1,
+ /decl/material/liquid/alcohol/beer = 1,
/decl/material/liquid/drink/cola = 4
)
@@ -500,19 +500,19 @@
name = "Devil's Kiss"
description = "A ghoulish cocktail popular in some of the weirder dive bars on the system fringe."
ratios = list(
- /decl/material/liquid/ethanol/rum = 4,
+ /decl/material/liquid/alcohol/rum = 4,
/decl/material/liquid/blood = 1,
- /decl/material/liquid/ethanol/coffee = 2
+ /decl/material/liquid/alcohol/coffee = 2
)
/decl/cocktail/hippiesdelight
name = "Hippy's Delight"
description = "A complex cocktail that just might open your third eye."
ratios = list(
- /decl/material/liquid/ethanol/vodka = 1,
- /decl/material/liquid/ethanol/gin = 1,
- /decl/material/liquid/ethanol/aged_whiskey = 1,
- /decl/material/liquid/ethanol/cognac = 1,
+ /decl/material/liquid/alcohol/vodka = 1,
+ /decl/material/liquid/alcohol/gin = 1,
+ /decl/material/liquid/alcohol/aged_whiskey = 1,
+ /decl/material/liquid/alcohol/cognac = 1,
/decl/material/liquid/drink/juice/lime = 1,
/decl/material/liquid/psychotropics = 2
)
@@ -531,7 +531,7 @@
description = "A smooth, steady cocktail supposedly ordered by sawbones and surgeons of legend."
ratios = list(
/decl/material/liquid/drink/cherrycola = 4,
- /decl/material/liquid/ethanol/rum = 2
+ /decl/material/liquid/alcohol/rum = 2
)
/decl/cocktail/vodkacola
@@ -539,14 +539,14 @@
description = "A simple mix of cola and vodka, combining sweetness, fizz and a kick in the teeth."
ratios = list(
/decl/material/liquid/drink/cola = 2,
- /decl/material/liquid/ethanol/vodka = 1
+ /decl/material/liquid/alcohol/vodka = 1
)
/decl/cocktail/sawbonesdismay
name = "Sawbones' Dismay"
description = "Legally, we are required to inform you that drinking this cocktail may invalidate your health insurance."
ratios = list(
- /decl/material/liquid/ethanol/jagermeister = 1,
+ /decl/material/liquid/alcohol/jagermeister = 1,
/decl/material/liquid/drink/beastenergy = 1
)
@@ -554,7 +554,7 @@
name = "Patron"
description = "Tequila mixed with flaked silver, for those with moderate expensive tastes."
ratios = list(
- /decl/material/liquid/ethanol/tequila = 1,
+ /decl/material/liquid/alcohol/tequila = 1,
/decl/material/solid/metal/silver
)
@@ -571,7 +571,7 @@
name = "Goldschlager"
description = "Schnapps mixed with flaked gold, for those with very expensive tastes."
ratios = list(
- /decl/material/liquid/ethanol/vodka = 1,
+ /decl/material/liquid/alcohol/vodka = 1,
/decl/material/solid/metal/gold
)
@@ -597,5 +597,5 @@
description = "Watered-down whiskey. Essentially grog, but without the pirates."
ratios = list(
/decl/material/liquid/water = 1,
- /decl/material/liquid/ethanol/whiskey = 1
+ /decl/material/liquid/alcohol/whiskey = 1
)
diff --git a/code/modules/reagents/dispenser/cartridge_presets.dm b/code/modules/reagents/dispenser/cartridge_presets.dm
index fc67bea1606c..fadf1e191872 100644
--- a/code/modules/reagents/dispenser/cartridge_presets.dm
+++ b/code/modules/reagents/dispenser/cartridge_presets.dm
@@ -32,24 +32,24 @@ DEFINE_CARTRIDGE_FOR_CHEM(iron, /decl/material/solid/metal/iron)
DEFINE_CARTRIDGE_FOR_CHEM(copper, /decl/material/solid/metal/copper)
DEFINE_CARTRIDGE_FOR_CHEM(mercury, /decl/material/liquid/mercury)
DEFINE_CARTRIDGE_FOR_CHEM(radium, /decl/material/solid/metal/radium)
-DEFINE_CARTRIDGE_FOR_CHEM(ethanol, /decl/material/liquid/ethanol)
+DEFINE_CARTRIDGE_FOR_CHEM(ethanol, /decl/material/liquid/alcohol/ethanol)
DEFINE_CARTRIDGE_FOR_CHEM(sacid, /decl/material/liquid/acid)
DEFINE_CARTRIDGE_FOR_CHEM(tungsten, /decl/material/solid/metal/tungsten)
// Bar, alcoholic
-DEFINE_CARTRIDGE_FOR_CHEM(beer, /decl/material/liquid/ethanol/beer)
-DEFINE_CARTRIDGE_FOR_CHEM(kahlua, /decl/material/liquid/ethanol/coffee)
-DEFINE_CARTRIDGE_FOR_CHEM(whiskey, /decl/material/liquid/ethanol/whiskey)
-DEFINE_CARTRIDGE_FOR_CHEM(wine, /decl/material/liquid/ethanol/wine)
-DEFINE_CARTRIDGE_FOR_CHEM(vodka, /decl/material/liquid/ethanol/vodka)
-DEFINE_CARTRIDGE_FOR_CHEM(gin, /decl/material/liquid/ethanol/gin)
-DEFINE_CARTRIDGE_FOR_CHEM(rum, /decl/material/liquid/ethanol/rum)
-DEFINE_CARTRIDGE_FOR_CHEM(tequila, /decl/material/liquid/ethanol/tequila)
-DEFINE_CARTRIDGE_FOR_CHEM(vermouth, /decl/material/liquid/ethanol/vermouth)
-DEFINE_CARTRIDGE_FOR_CHEM(cognac, /decl/material/liquid/ethanol/cognac)
-DEFINE_CARTRIDGE_FOR_CHEM(ale, /decl/material/liquid/ethanol/ale)
-DEFINE_CARTRIDGE_FOR_CHEM(mead, /decl/material/liquid/ethanol/mead)
+DEFINE_CARTRIDGE_FOR_CHEM(beer, /decl/material/liquid/alcohol/beer)
+DEFINE_CARTRIDGE_FOR_CHEM(kahlua, /decl/material/liquid/alcohol/coffee)
+DEFINE_CARTRIDGE_FOR_CHEM(whiskey, /decl/material/liquid/alcohol/whiskey)
+DEFINE_CARTRIDGE_FOR_CHEM(wine, /decl/material/liquid/alcohol/wine)
+DEFINE_CARTRIDGE_FOR_CHEM(vodka, /decl/material/liquid/alcohol/vodka)
+DEFINE_CARTRIDGE_FOR_CHEM(gin, /decl/material/liquid/alcohol/gin)
+DEFINE_CARTRIDGE_FOR_CHEM(rum, /decl/material/liquid/alcohol/rum)
+DEFINE_CARTRIDGE_FOR_CHEM(tequila, /decl/material/liquid/alcohol/tequila)
+DEFINE_CARTRIDGE_FOR_CHEM(vermouth, /decl/material/liquid/alcohol/vermouth)
+DEFINE_CARTRIDGE_FOR_CHEM(cognac, /decl/material/liquid/alcohol/cognac)
+DEFINE_CARTRIDGE_FOR_CHEM(ale, /decl/material/liquid/alcohol/ale)
+DEFINE_CARTRIDGE_FOR_CHEM(mead, /decl/material/liquid/alcohol/mead)
// Bar, soft
DEFINE_CARTRIDGE_FOR_CHEM(ice, /decl/material/solid/ice)
diff --git a/code/modules/reagents/reactions/reaction_alcohol.dm b/code/modules/reagents/reactions/reaction_alcohol.dm
index 87ac55aaceff..4d96bdb5d128 100644
--- a/code/modules/reagents/reactions/reaction_alcohol.dm
+++ b/code/modules/reagents/reactions/reaction_alcohol.dm
@@ -14,7 +14,7 @@
/decl/chemical_reaction/recipe/moonshine
name = "Moonshine"
- result = /decl/material/liquid/ethanol/moonshine
+ result = /decl/material/liquid/alcohol/moonshine
required_reagents = list(/decl/material/liquid/nutriment = 10)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 10
@@ -29,7 +29,7 @@
/decl/chemical_reaction/recipe/wine
name = "Red Wine"
- result = /decl/material/liquid/ethanol/wine
+ result = /decl/material/liquid/alcohol/wine
required_reagents = list(/decl/material/liquid/drink/juice/grape = 10)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 10
@@ -37,7 +37,7 @@
/decl/chemical_reaction/recipe/pwine
name = "Poison Wine"
- result = /decl/material/liquid/ethanol/pwine
+ result = /decl/material/liquid/alcohol/pwine
required_reagents = list(/decl/material/liquid/poisonberryjuice = 10)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 10
@@ -45,7 +45,7 @@
/decl/chemical_reaction/recipe/melonliquor
name = "Melon Liquor"
- result = /decl/material/liquid/ethanol/melonliquor
+ result = /decl/material/liquid/alcohol/melonliquor
required_reagents = list(/decl/material/liquid/drink/juice/watermelon = 10)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 10
@@ -53,7 +53,7 @@
/decl/chemical_reaction/recipe/bluecuracao
name = "Blue Curacao"
- result = /decl/material/liquid/ethanol/bluecuracao
+ result = /decl/material/liquid/alcohol/bluecuracao
required_reagents = list(/decl/material/liquid/drink/juice/orange = 10)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 10
@@ -61,15 +61,15 @@
/decl/chemical_reaction/recipe/beer
name = "Plain Beer"
- result = /decl/material/liquid/ethanol/beer
- required_reagents = list(/decl/material/liquid/nutriment/cornoil = 10)
+ result = /decl/material/liquid/alcohol/beer
+ required_reagents = list(/decl/material/liquid/oil/plant/corn = 10)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 10
mix_message = "The solution roils as it rapidly ferments into a foaming amber liquid."
/decl/chemical_reaction/recipe/vodka
name = "Potato Vodka"
- result = /decl/material/liquid/ethanol/vodka
+ result = /decl/material/liquid/alcohol/vodka
required_reagents = list(/decl/material/liquid/drink/juice/potato = 10)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 10
@@ -77,7 +77,7 @@
/decl/chemical_reaction/recipe/vodka2
name = "Turnip Vodka"
- result = /decl/material/liquid/ethanol/vodka
+ result = /decl/material/liquid/alcohol/vodka
required_reagents = list(/decl/material/liquid/drink/juice/turnip = 10)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 10
@@ -85,7 +85,7 @@
/decl/chemical_reaction/recipe/sake
name = "Sake"
- result = /decl/material/liquid/ethanol/sake
+ result = /decl/material/liquid/alcohol/sake
required_reagents = list(/decl/material/liquid/nutriment/rice = 10)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 10
@@ -93,7 +93,7 @@
/decl/chemical_reaction/recipe/kahlua
name = "Kahlua"
- result = /decl/material/liquid/ethanol/coffee
+ result = /decl/material/liquid/alcohol/coffee
required_reagents = list(/decl/material/liquid/drink/coffee = 5, /decl/material/liquid/nutriment/sugar = 5)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 5
@@ -101,28 +101,28 @@
/decl/chemical_reaction/recipe/irish_cream
name = "Irish Cream"
- result = /decl/material/liquid/ethanol/irish_cream
- required_reagents = list(/decl/material/liquid/ethanol/whiskey = 2, /decl/material/liquid/drink/milk/cream = 1)
+ result = /decl/material/liquid/alcohol/irish_cream
+ required_reagents = list(/decl/material/liquid/alcohol/whiskey = 2, /decl/material/liquid/drink/milk/cream = 1)
result_amount = 3
/decl/chemical_reaction/recipe/hooch
name = "Hooch"
- result = /decl/material/liquid/ethanol/hooch
- required_reagents = list (/decl/material/liquid/nutriment/sugar = 1, /decl/material/liquid/ethanol = 2, /decl/material/liquid/fuel = 1)
+ result = /decl/material/liquid/alcohol/hooch
+ required_reagents = list (/decl/material/liquid/nutriment/sugar = 1, /decl/material/liquid/alcohol/ethanol = 2, /decl/material/liquid/fuel = 1)
minimum_temperature = 30 CELSIUS
maximum_temperature = (30 CELSIUS) + 100
result_amount = 3
/decl/chemical_reaction/recipe/mead
name = "Mead"
- result = /decl/material/liquid/ethanol/mead
+ result = /decl/material/liquid/alcohol/mead
required_reagents = list(/decl/material/liquid/nutriment/honey = 1, /decl/material/liquid/water = 1)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 2
/decl/chemical_reaction/recipe/rum
name = "Dark Rum"
- result = /decl/material/liquid/ethanol/rum
+ result = /decl/material/liquid/alcohol/rum
required_reagents = list(/decl/material/liquid/nutriment/sugar = 1, /decl/material/liquid/water = 1)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 2
@@ -130,21 +130,21 @@
/decl/chemical_reaction/recipe/cider_apple
name = "Apple Cider"
- result = /decl/material/liquid/ethanol/cider_apple
+ result = /decl/material/liquid/alcohol/cider_apple
required_reagents = list(/decl/material/liquid/drink/juice/apple = 2, /decl/material/liquid/nutriment/sugar = 1)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 3
/decl/chemical_reaction/recipe/cider_pear
name = "Pear Cider"
- result = /decl/material/liquid/ethanol/cider_pear
+ result = /decl/material/liquid/alcohol/cider_pear
required_reagents = list(/decl/material/liquid/drink/juice/pear = 2, /decl/material/liquid/nutriment/sugar = 1)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 3
/decl/chemical_reaction/recipe/kvass
name = "Kvass"
- result = /decl/material/liquid/ethanol/kvass
- required_reagents = list(/decl/material/liquid/nutriment/sugar = 1, /decl/material/liquid/ethanol/beer = 1)
+ result = /decl/material/liquid/alcohol/kvass
+ required_reagents = list(/decl/material/liquid/nutriment/sugar = 1, /decl/material/liquid/alcohol/beer = 1)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 3
diff --git a/code/modules/reagents/reactions/reaction_compounds.dm b/code/modules/reagents/reactions/reaction_compounds.dm
index 528b85dbcbce..8e530dacaa58 100644
--- a/code/modules/reagents/reactions/reaction_compounds.dm
+++ b/code/modules/reagents/reactions/reaction_compounds.dm
@@ -48,7 +48,7 @@
name = "Methyl Bromide"
required_reagents = list(
/decl/material/liquid/bromide = 1,
- /decl/material/liquid/ethanol = 1,
+ /decl/material/liquid/alcohol/ethanol = 1,
/decl/material/liquid/fuel/hydrazine = 1
)
result_amount = 3
@@ -158,3 +158,27 @@
/decl/chemical_reaction/compound/condensed_capsaicin/on_reaction(datum/reagents/holder, created_volume, reaction_flags, list/reaction_data)
. = ..()
holder?.add_reagent(/decl/material/liquid/water, created_volume)
+
+// This is a bit silly, but we need a way to unify oil types until someone rewrites lanterns.
+/decl/chemical_reaction/compound/fuel_oil
+ name = "Plant Fuel Oil"
+ result = /decl/material/liquid/oil
+ result_amount = 3
+ required_reagents = list(
+ /decl/material/liquid/oil/plant = 2,
+ /decl/material/solid/graphite = 1
+ )
+
+/decl/chemical_reaction/compound/fuel_oil/corn
+ name = "Corn Fuel Oil"
+ required_reagents = list(
+ /decl/material/liquid/oil/plant/corn = 2,
+ /decl/material/solid/graphite = 1
+ )
+
+/decl/chemical_reaction/compound/fuel_oil/fish
+ name = "Fish Fuel Oil"
+ required_reagents = list(
+ /decl/material/liquid/oil/fish = 2,
+ /decl/material/solid/graphite = 1
+ )
diff --git a/code/modules/reagents/reactions/reaction_drugs.dm b/code/modules/reagents/reactions/reaction_drugs.dm
index 97cfaafade61..8f10b625a3c2 100644
--- a/code/modules/reagents/reactions/reaction_drugs.dm
+++ b/code/modules/reagents/reactions/reaction_drugs.dm
@@ -22,16 +22,16 @@
name = "Strong Painkillers"
result = /decl/material/liquid/painkillers/strong
required_reagents = list(
- /decl/material/liquid/stabilizer = 1,
- /decl/material/liquid/ethanol = 1,
- /decl/material/liquid/acetone = 1
+ /decl/material/liquid/stabilizer = 1,
+ /decl/material/liquid/alcohol/ethanol = 1,
+ /decl/material/liquid/acetone = 1
)
result_amount = 3
/decl/chemical_reaction/drug/antiseptic
name = "Antiseptic"
result = /decl/material/liquid/antiseptic
- required_reagents = list(/decl/material/liquid/ethanol = 1, /decl/material/liquid/antitoxins = 1, /decl/material/liquid/acid/hydrochloric = 1)
+ required_reagents = list(/decl/material/liquid/alcohol/ethanol = 1, /decl/material/liquid/antitoxins = 1, /decl/material/liquid/acid/hydrochloric = 1)
result_amount = 3
/decl/chemical_reaction/drug/mutagenics
@@ -136,7 +136,7 @@
/decl/chemical_reaction/drug/sedatives
name = "Sedatives"
result = /decl/material/liquid/sedatives
- required_reagents = list(/decl/material/liquid/ethanol = 1, /decl/material/liquid/nutriment/sugar = 4
+ required_reagents = list(/decl/material/liquid/alcohol/ethanol = 1, /decl/material/liquid/nutriment/sugar = 4
)
inhibitors = list(
/decl/material/solid/phosphorus
@@ -146,7 +146,7 @@
/decl/chemical_reaction/drug/paralytics
name = "Paralytics"
result = /decl/material/liquid/paralytics
- required_reagents = list(/decl/material/liquid/ethanol = 1, /decl/material/liquid/mercury = 2, /decl/material/liquid/fuel/hydrazine = 2)
+ required_reagents = list(/decl/material/liquid/alcohol/ethanol = 1, /decl/material/liquid/mercury = 2, /decl/material/liquid/fuel/hydrazine = 2)
result_amount = 1
/decl/chemical_reaction/drug/zombiepowder
diff --git a/code/modules/reagents/reactions/reaction_herbal.dm b/code/modules/reagents/reactions/reaction_herbal.dm
index f0f6bc441f42..b8a02ca07fec 100644
--- a/code/modules/reagents/reactions/reaction_herbal.dm
+++ b/code/modules/reagents/reactions/reaction_herbal.dm
@@ -44,7 +44,7 @@
/decl/chemical_reaction/drug/herbal/yarrow_tincture
name = "tincture of yarrow"
required_reagents = list(
- /decl/material/liquid/ethanol = 1,
+ /decl/material/liquid/alcohol/ethanol = 1,
/decl/material/liquid/brute_meds/yarrow = 3
)
result = /decl/material/liquid/brute_meds/yarrow/tincture
@@ -52,15 +52,15 @@
/decl/chemical_reaction/drug/herbal/aloe_tincture
name = "tincture of aloe"
required_reagents = list(
- /decl/material/liquid/ethanol = 1,
- /decl/material/liquid/burn_meds/aloe = 3
+ /decl/material/liquid/alcohol/ethanol = 1,
+ /decl/material/liquid/burn_meds/aloe = 3
)
result = /decl/material/liquid/burn_meds/aloe/tincture
/decl/chemical_reaction/drug/herbal/ginseng_tincture
name = "tincture of ginseng"
required_reagents = list(
- /decl/material/liquid/ethanol = 1,
+ /decl/material/liquid/alcohol/ethanol = 1,
/decl/material/liquid/antitoxins/ginseng = 3
)
result = /decl/material/liquid/antitoxins/ginseng/tincture
@@ -68,7 +68,7 @@
/decl/chemical_reaction/drug/herbal/valerian_tincture
name = "tincture of valerian"
required_reagents = list(
- /decl/material/liquid/ethanol = 1,
+ /decl/material/liquid/alcohol/ethanol = 1,
/decl/material/liquid/sedatives/valerian = 3
)
result = /decl/material/liquid/sedatives/valerian/tincture
diff --git a/code/modules/reagents/reactions/reaction_recipe.dm b/code/modules/reagents/reactions/reaction_recipe.dm
index f8a9797da156..a113d821cc58 100644
--- a/code/modules/reagents/reactions/reaction_recipe.dm
+++ b/code/modules/reagents/reactions/reaction_recipe.dm
@@ -37,7 +37,7 @@
/decl/chemical_reaction/recipe/garlicsauce
name = "Garlic Sauce"
result = /decl/material/liquid/nutriment/garlicsauce
- required_reagents = list(/decl/material/liquid/drink/juice/garlic = 1, /decl/material/liquid/nutriment/cornoil = 1)
+ required_reagents = list(/decl/material/liquid/drink/juice/garlic = 1, /decl/material/liquid/oil/plant/corn = 1)
result_amount = 2
mix_message = "The solution thickens into a creamy white oil."
@@ -79,7 +79,7 @@
/decl/chemical_reaction/recipe/vinegar2
name = "Clear Vinegar"
result = /decl/material/liquid/nutriment/vinegar
- required_reagents = list(/decl/material/liquid/ethanol = 10)
+ required_reagents = list(/decl/material/liquid/alcohol/ethanol = 10)
catalysts = list(/decl/material/liquid/enzyme = 5)
result_amount = 10
mix_message = "The solution roils as it rapidly ferments into a sharp-smelling liquid."
diff --git a/code/modules/reagents/reactions/reaction_recipe_food.dm b/code/modules/reagents/reactions/reaction_recipe_food.dm
index 29ba82a01db1..bc052960e913 100644
--- a/code/modules/reagents/reactions/reaction_recipe_food.dm
+++ b/code/modules/reagents/reactions/reaction_recipe_food.dm
@@ -58,7 +58,7 @@
name = "Enzyme Margarine"
required_reagents = list(
/decl/material/solid/sodiumchloride = 1,
- /decl/material/liquid/nutriment/plant_oil = 20
+ /decl/material/liquid/oil/plant = 20
)
catalysts = list(/decl/material/liquid/enzyme = 5)
mix_message = "The solution thickens and curdles into a pale yellow solid."
@@ -210,7 +210,7 @@
name = "Space Liberty Duff"
required_reagents = list(
/decl/material/liquid/water = 10,
- /decl/material/liquid/ethanol/vodka = 5,
+ /decl/material/liquid/alcohol/vodka = 5,
/decl/material/liquid/psychotropics = 5
)
obj_result = /obj/item/food/spacylibertyduff
@@ -219,7 +219,7 @@
name = "Amanita Jelly"
required_reagents = list(
/decl/material/liquid/water = 10,
- /decl/material/liquid/ethanol/vodka = 5,
+ /decl/material/liquid/alcohol/vodka = 5,
/decl/material/liquid/amatoxin = 5
)
obj_result = /obj/item/food/amanitajelly
diff --git a/code/modules/reagents/reactions/reaction_synthesis.dm b/code/modules/reagents/reactions/reaction_synthesis.dm
index c70444faff81..57192c726ae5 100644
--- a/code/modules/reagents/reactions/reaction_synthesis.dm
+++ b/code/modules/reagents/reactions/reaction_synthesis.dm
@@ -28,9 +28,6 @@
var/decl/material/mat = GET_DECL(/decl/material/solid/fiberglass)
mat.create_object(location, created_volume)
-/decl/chemical_reaction/synthesis/crystalization/can_happen(datum/reagents/holder)
- . = ..() && length(holder.reagent_volumes) > 1
-
/decl/chemical_reaction/synthesis/crystalization
name = "Crystalization"
required_reagents = list(/decl/material/liquid/crystal_agent = 1)
@@ -126,11 +123,11 @@
new /obj/item/stack/medical/resin/crafted(T, create_stacks)
/decl/chemical_reaction/synthesis/soap
- name = "Handmade Soap"
+ name = "Handmade Plant Soap"
required_reagents = list(
- /decl/material/solid/carbon/ashes = 5,
- /decl/material/liquid/water = 5,
- /decl/material/liquid/nutriment/plant_oil = 10
+ /decl/material/solid/carbon/ashes = 5,
+ /decl/material/liquid/water = 5,
+ /decl/material/liquid/oil/plant = 10
)
result_amount = 1
mix_message = "The solution thickens and solidifies."
@@ -147,6 +144,14 @@
for(var/i = 1 to create_soap)
new /obj/item/soap/crafted(T)
+/decl/chemical_reaction/synthesis/soap/corn
+ name = "Handmade Corn Soap"
+ required_reagents = list(
+ /decl/material/solid/carbon/ashes = 5,
+ /decl/material/liquid/water = 5,
+ /decl/material/liquid/oil/plant/corn = 10
+ )
+
// Making chipboard out of wood scraps/recycled wood.
/decl/chemical_reaction/synthesis/chipboard
name = "Oak Chipboard"
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index a39da55a863c..99ec47811aa7 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -30,6 +30,8 @@
var/image/contents_overlay = get_reagents_overlay(use_single_icon ? icon_state : null)
if(contents_overlay)
add_overlay(contents_overlay)
+ if(detail_state)
+ add_overlay(overlay_image(icon, "[initial(icon_state)][detail_state]", detail_color || COLOR_WHITE, RESET_COLOR))
/obj/item/chems/apply_additional_mob_overlays(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing)
var/image/reagents_overlay = get_reagents_overlay(overlay.icon_state)
@@ -50,11 +52,6 @@
return TRUE
return FALSE
-/obj/item/chems/on_update_icon()
- . = ..()
- if(detail_state)
- add_overlay(overlay_image(icon, "[initial(icon_state)][detail_state]", detail_color || COLOR_WHITE, RESET_COLOR))
-
/obj/item/chems/update_name()
. = ..() // handles material, etc
var/newname = name
@@ -100,6 +97,21 @@
return
/obj/item/chems/attackby(obj/item/used_item, mob/user)
+
+ // Skimming off cream, repurposed from crucibles.
+ // TODO: potentially make this an alt interaction and unify with slag skimming.
+ if(istype(used_item, /obj/item/chems) && ATOM_IS_OPEN_CONTAINER(used_item) && used_item.reagents?.maximum_volume && reagents?.total_volume && length(reagents.reagent_volumes) > 1)
+ var/list/skimmable_reagents = reagents.get_skimmable_reagents()
+ if(length(skimmable_reagents))
+ var/removing = min(amount_per_transfer_from_this, REAGENTS_FREE_SPACE(used_item.reagents))
+ if(removing <= 0)
+ to_chat(user, SPAN_WARNING("\The [used_item] is full."))
+ else
+ var/old_amt = used_item.reagents.total_volume
+ reagents.trans_to_holder(used_item.reagents, removing, skip_reagents = (reagents.reagent_volumes - skimmable_reagents))
+ to_chat(user, SPAN_NOTICE("You skim [used_item.reagents.total_volume-old_amt] unit\s of [used_item.reagents.get_primary_reagent_name()] from the top of \the [reagents.get_primary_reagent_name()]."))
+ return TRUE
+
if(used_item.user_can_attack_with(user, silent = TRUE))
if(IS_PEN(used_item))
var/tmp_label = sanitize_safe(input(user, "Enter a label for [name]", "Label", label_text), MAX_NAME_LEN)
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/_glass.dm
similarity index 57%
rename from code/modules/reagents/reagent_containers/glass.dm
rename to code/modules/reagents/reagent_containers/_glass.dm
index 64e7fb66199b..90981c545111 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/_glass.dm
@@ -19,7 +19,8 @@
pickup_sound = 'sound/foley/bottlepickup1.ogg'
watertight = FALSE // /glass uses the open container flag for this
- var/list/can_be_placed_into = list(
+/obj/item/chems/glass/proc/get_atoms_can_be_placed_into()
+ var/static/list/_can_be_placed_into = list(
/obj/machinery/chem_master/,
/obj/machinery/chemical_dispenser,
/obj/machinery/reagentgrinder,
@@ -40,6 +41,7 @@
/obj/machinery/radiocarbon_spectrometer,
/obj/machinery/material_processing/extractor
)
+ return _can_be_placed_into
/obj/item/chems/glass/examine(mob/user, distance)
. = ..()
@@ -77,7 +79,7 @@
return FALSE //If not, do nothing.
if(target?.storage)
return TRUE
- for(var/type in can_be_placed_into) //Is it something it can be placed into?
+ for(var/type in get_atoms_can_be_placed_into()) //Is it something it can be placed into?
if(istype(target, type))
return TRUE
if(standard_dispenser_refill(user, target)) //Are they clicking a water tank/some dispenser?
@@ -98,3 +100,59 @@
reagents.splash(target, min(reagents.total_volume, 5))
return TRUE
. = ..()
+
+// Drinking out of bowls.
+/obj/item/chems/glass/attack_self(mob/user)
+ if(is_edible(user) && handle_eaten_by_mob(user, user) != EATEN_INVALID)
+ return TRUE
+ return ..()
+
+/obj/item/chems/glass/get_food_default_transfer_amount(mob/eater)
+ return eater?.get_eaten_transfer_amount(amount_per_transfer_from_this)
+
+/obj/item/chems/glass/get_food_consumption_method(mob/eater)
+ return EATING_METHOD_DRINK
+
+/obj/item/chems/glass/get_edible_material_amount(mob/eater)
+ return reagents?.total_volume
+
+/obj/item/chems/glass/get_utensil_food_type()
+ return /obj/item/food/lump
+
+// Interaction code borrowed from /food.
+// Should we consider moving this down to /chems for any open container? Medicine from a bottle using a spoon, etc.
+/obj/item/chems/glass/attackby(obj/item/used_item, mob/living/user)
+
+ if(ATOM_IS_OPEN_CONTAINER(src))
+ if(istype(used_item, /obj/item/food))
+ if(!reagents?.total_volume)
+ to_chat(user, SPAN_WARNING("\The [src] is empty."))
+ return TRUE
+ var/transferring = min(get_food_default_transfer_amount(user), REAGENTS_FREE_SPACE(used_item.reagents))
+ if(!transferring)
+ to_chat(user, SPAN_WARNING("You cannot dip \the [used_item] in \the [src]."))
+ return TRUE
+ reagents.trans_to_holder(used_item.reagents, transferring)
+ user.visible_message(SPAN_NOTICE("\The [user] dunks \the [used_item] in \the [src]."))
+ return TRUE
+ var/obj/item/utensil/utensil = used_item
+ if(istype(utensil) && (utensil.utensil_flags & UTENSIL_FLAG_SCOOP))
+ if(utensil.loaded_food)
+ to_chat(user, SPAN_WARNING("You already have something on \the [utensil]."))
+ return TRUE
+ if(!reagents?.total_volume)
+ to_chat(user, SPAN_WARNING("\The [src] is empty."))
+ return TRUE
+ seperate_food_chunk(utensil, user)
+ if(utensil.loaded_food?.reagents?.total_volume)
+ to_chat(user, SPAN_NOTICE("You scoop up some of \the [utensil.loaded_food.reagents.get_primary_reagent_name()] with \the [utensil]."))
+ return TRUE
+ return ..()
+
+/obj/structure/glass/get_alt_interactions(mob/user)
+ . = ..()
+ if(reagents?.total_volume >= FLUID_PUDDLE)
+ LAZYADD(., /decl/interaction_handler/dip_item)
+ LAZYADD(., /decl/interaction_handler/fill_from)
+ if(user?.get_active_held_item())
+ LAZYADD(., /decl/interaction_handler/empty_into)
diff --git a/code/modules/reagents/reagent_containers/glass_edibility.dm b/code/modules/reagents/reagent_containers/_glass_edibility.dm
similarity index 100%
rename from code/modules/reagents/reagent_containers/glass_edibility.dm
rename to code/modules/reagents/reagent_containers/_glass_edibility.dm
diff --git a/code/modules/reagents/reagent_containers/beaker.dm b/code/modules/reagents/reagent_containers/beaker.dm
index b593c3f968f3..3b1ad5be0422 100644
--- a/code/modules/reagents/reagent_containers/beaker.dm
+++ b/code/modules/reagents/reagent_containers/beaker.dm
@@ -86,6 +86,9 @@
atom_flags = ATOM_FLAG_OPEN_CONTAINER
material = /decl/material/solid/metal/steel
+/obj/item/chems/glass/beaker/bowl/can_lid()
+ return FALSE
+
/obj/item/chems/glass/beaker/bowl/pottery
material = /decl/material/solid/stone/pottery
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index 06147c369b40..658b68dddf7c 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -37,9 +37,6 @@
reagent_volumes[T] = volume
var/decl/material/R = T
reagent_names += initial(R.name)
-
-/obj/item/chems/borghypo/Initialize()
- . = ..()
START_PROCESSING(SSobj, src)
/obj/item/chems/borghypo/Destroy()
@@ -128,18 +125,18 @@
volume = 60
possible_transfer_amounts = @"[5,10,20,30]"
reagent_ids = list(
- /decl/material/liquid/ethanol/beer,
- /decl/material/liquid/ethanol/coffee,
- /decl/material/liquid/ethanol/whiskey,
- /decl/material/liquid/ethanol/wine,
- /decl/material/liquid/ethanol/vodka,
- /decl/material/liquid/ethanol/gin,
- /decl/material/liquid/ethanol/rum,
- /decl/material/liquid/ethanol/tequila,
- /decl/material/liquid/ethanol/vermouth,
- /decl/material/liquid/ethanol/cognac,
- /decl/material/liquid/ethanol/ale,
- /decl/material/liquid/ethanol/mead,
+ /decl/material/liquid/alcohol/beer,
+ /decl/material/liquid/alcohol/coffee,
+ /decl/material/liquid/alcohol/whiskey,
+ /decl/material/liquid/alcohol/wine,
+ /decl/material/liquid/alcohol/vodka,
+ /decl/material/liquid/alcohol/gin,
+ /decl/material/liquid/alcohol/rum,
+ /decl/material/liquid/alcohol/tequila,
+ /decl/material/liquid/alcohol/vermouth,
+ /decl/material/liquid/alcohol/cognac,
+ /decl/material/liquid/alcohol/ale,
+ /decl/material/liquid/alcohol/mead,
/decl/material/liquid/water,
/decl/material/liquid/nutriment/sugar,
/decl/material/solid/ice,
@@ -158,8 +155,8 @@
/decl/material/liquid/drink/hot_coco,
/decl/material/liquid/drink/tea/green,
/decl/material/liquid/drink/citrussoda,
- /decl/material/liquid/ethanol/beer,
- /decl/material/liquid/ethanol/coffee
+ /decl/material/liquid/alcohol/beer,
+ /decl/material/liquid/alcohol/coffee
)
/obj/item/chems/borghypo/service/use_on_mob(mob/living/target, mob/living/user, animate = TRUE)
diff --git a/code/modules/reagents/reagent_containers/bowl.dm b/code/modules/reagents/reagent_containers/bowl.dm
index 62e34795c237..bc54aadbaa47 100644
--- a/code/modules/reagents/reagent_containers/bowl.dm
+++ b/code/modules/reagents/reagent_containers/bowl.dm
@@ -9,57 +9,9 @@
volume = 30
amount_per_transfer_from_this = 5
-// Drinking out of bowls.
-/obj/item/chems/glass/bowl/attack_self(mob/user)
- if(is_edible(user) && handle_eaten_by_mob(user, user) != EATEN_INVALID)
- return TRUE
- return ..()
-
/obj/item/chems/glass/bowl/can_lid()
return FALSE
-/obj/item/chems/glass/bowl/get_food_default_transfer_amount(mob/eater)
- return eater?.get_eaten_transfer_amount(amount_per_transfer_from_this)
-
-/obj/item/chems/glass/bowl/get_edible_material_amount(mob/eater)
- return reagents?.total_volume
-
-/obj/item/chems/glass/bowl/get_food_consumption_method(mob/eater)
- return EATING_METHOD_DRINK
-
-/obj/item/chems/glass/bowl/get_utensil_food_type()
- return /obj/item/food/lump
-
-// Interaction code borrowed from /food.
-/obj/item/chems/glass/bowl/attackby(obj/item/W, mob/living/user)
-
- if(istype(W, /obj/item/food))
- if(!reagents?.total_volume)
- to_chat(user, SPAN_WARNING("\The [src] is empty."))
- return TRUE
- var/transferring = min(get_food_default_transfer_amount(user), REAGENTS_FREE_SPACE(W.reagents))
- if(!transferring)
- to_chat(user, SPAN_WARNING("You cannot dip \the [W] in \the [src]."))
- return TRUE
- reagents.trans_to_holder(W.reagents, transferring)
- user.visible_message(SPAN_NOTICE("\The [user] dunks \the [W] in \the [src]."))
- return TRUE
-
- var/obj/item/utensil/utensil = W
- if(istype(utensil) && (utensil.utensil_flags & UTENSIL_FLAG_SCOOP))
- if(utensil.loaded_food)
- to_chat(user, SPAN_WARNING("You already have something on \the [utensil]."))
- return TRUE
- if(!reagents?.total_volume)
- to_chat(user, SPAN_WARNING("\The [src] is empty."))
- return TRUE
- seperate_food_chunk(utensil, user)
- if(utensil.loaded_food?.reagents?.total_volume)
- to_chat(user, SPAN_NOTICE("You scoop up some of \the [utensil.loaded_food.reagents.get_primary_reagent_name()] with \the [utensil]."))
- return TRUE
-
- return ..()
-
// Predefined soup types for mapping.
/obj/item/chems/glass/bowl/mapped
abstract_type = /obj/item/chems/glass/bowl/mapped
diff --git a/code/modules/reagents/reagent_containers/bucket.dm b/code/modules/reagents/reagent_containers/bucket.dm
index 3a8e13125733..e2e5c9f2e56d 100644
--- a/code/modules/reagents/reagent_containers/bucket.dm
+++ b/code/modules/reagents/reagent_containers/bucket.dm
@@ -15,6 +15,12 @@
drop_sound = 'sound/foley/donk1.ogg'
pickup_sound = 'sound/foley/pickup2.ogg'
+/obj/item/chems/glass/bucket/get_edible_material_amount(mob/eater)
+ return 0
+
+/obj/item/chems/glass/bucket/get_utensil_food_type()
+ return null
+
/obj/item/chems/glass/bucket/attackby(var/obj/D, mob/user)
if(istype(D, /obj/item/mop))
if(reagents.total_volume < 1)
diff --git a/code/modules/reagents/reagent_containers/condiments/condiment_appearance.dm b/code/modules/reagents/reagent_containers/condiments/condiment_appearance.dm
index b534f6bc812c..4236c1867544 100644
--- a/code/modules/reagents/reagent_containers/condiments/condiment_appearance.dm
+++ b/code/modules/reagents/reagent_containers/condiments/condiment_appearance.dm
@@ -75,7 +75,7 @@
condiment_center_of_mass = @'{"x":16,"y":8}'
/decl/condiment_appearance/cornoil
- condiment_type = /decl/material/liquid/nutriment/cornoil
+ condiment_type = /decl/material/liquid/oil/plant/corn
condiment_name = "corn oil"
condiment_desc = "A delicious oil used in cooking. Made from corn."
condiment_icon = 'icons/obj/food/condiments/cornoil.dmi'
diff --git a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm
index 1dc986fb81be..386ad49b09a5 100644
--- a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm
+++ b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm
@@ -39,23 +39,6 @@ var/global/const/DRINK_ICON_NOISY = "noise"
if(obj_flags & OBJ_FLAG_HOLLOW)
. /= HOLLOW_OBJECT_MATTER_MULTIPLIER
-/obj/item/chems/drinks/glass2/examine(mob/M)
- . = ..()
-
- for(var/I in extras)
- if(istype(I, /obj/item/glass_extra))
- to_chat(M, "There is \a [I] in \the [src].")
- else if(istype(I, /obj/item/food/processed_grown/slice))
- to_chat(M, "There is \a [I] on the rim.")
- else
- to_chat(M, "There is \a [I] somewhere on the glass. Somehow.")
-
- if(has_ice())
- to_chat(M, "There is some ice floating in the drink.")
-
- if(has_fizz())
- to_chat(M, "It is fizzing slightly.")
-
/obj/item/chems/drinks/glass2/proc/has_ice()
if(LAZYLEN(reagents.reagent_volumes))
var/decl/material/R = reagents.get_primary_reagent_decl()
@@ -113,7 +96,7 @@ var/global/const/DRINK_ICON_NOISY = "noise"
/obj/item/chems/drinks/glass2/examine(mob/user, distance)
. = ..()
- if(!istype(user) || distance > 1)
+ if(!istype(user))
return
var/list/extra_text
for(var/extra in extras)
@@ -122,8 +105,14 @@ var/global/const/DRINK_ICON_NOISY = "noise"
LAZYADD(extra_text, GE.glass_desc)
else if(istype(extra, /obj/item/food/processed_grown/slice))
LAZYADD(extra_text, "There is \a [extra] on the rim.")
+ else
+ to_chat(user, "There is \a [extra] somewhere on the glass. Somehow.")
if(length(extra_text))
to_chat(user, SPAN_NOTICE(jointext(extra_text," ")))
+ if(has_ice())
+ to_chat(user, "There is some ice floating in the drink.")
+ if(has_fizz())
+ to_chat(user, "It is fizzing slightly.")
/obj/item/chems/drinks/glass2/proc/get_filling_overlay(amount, overlay)
diff --git a/code/modules/reagents/reagent_containers/drinks.dm b/code/modules/reagents/reagent_containers/drinks.dm
index d1f01780b6ea..46c56514eee4 100644
--- a/code/modules/reagents/reagent_containers/drinks.dm
+++ b/code/modules/reagents/reagent_containers/drinks.dm
@@ -57,7 +57,7 @@
return
return ..()
-/obj/item/chems/drinks/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target)
+/obj/item/chems/drinks/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target, skip_container_check = FALSE)
return do_open_check(user) && ..()
/obj/item/chems/drinks/standard_pour_into(var/mob/user, var/atom/target)
diff --git a/code/modules/reagents/reagent_containers/drinks/bottle.dm b/code/modules/reagents/reagent_containers/drinks/bottle.dm
index 242cd0583bec..5d0776020c41 100644
--- a/code/modules/reagents/reagent_containers/drinks/bottle.dm
+++ b/code/modules/reagents/reagent_containers/drinks/bottle.dm
@@ -251,7 +251,7 @@
center_of_mass = @'{"x":16,"y":4}'
/obj/item/chems/drinks/bottle/gin/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/gin, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/gin, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/whiskey
name = "Uncle Git's Special Reserve"
@@ -260,7 +260,7 @@
center_of_mass = @'{"x":16,"y":3}'
/obj/item/chems/drinks/bottle/whiskey/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/whiskey, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/whiskey, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/agedwhiskey
name = "aged whiskey"
@@ -269,7 +269,7 @@
center_of_mass = @'{"x":16,"y":3}'
/obj/item/chems/drinks/bottle/agedwhiskey/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/aged_whiskey, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/aged_whiskey, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/vodka
name = "Tunguska Triple Distilled"
@@ -278,7 +278,7 @@
center_of_mass = @'{"x":17,"y":3}'
/obj/item/chems/drinks/bottle/vodka/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/vodka, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/vodka, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/tequila
name = "Caccavo Guaranteed Quality tequila"
@@ -287,7 +287,7 @@
center_of_mass = @'{"x":16,"y":3}'
/obj/item/chems/drinks/bottle/tequila/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/tequila, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/tequila, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/patron
name = "Wrapp Artiste Patron"
@@ -296,7 +296,7 @@
center_of_mass = @'{"x":16,"y":6}'
/obj/item/chems/drinks/bottle/patron/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/tequila, reagents.maximum_volume - 5)
+ add_to_reagents(/decl/material/liquid/alcohol/tequila, reagents.maximum_volume - 5)
add_to_reagents(/decl/material/solid/metal/silver, 5)
/obj/item/chems/drinks/bottle/rum
@@ -306,7 +306,7 @@
center_of_mass = @'{"x":16,"y":8}'
/obj/item/chems/drinks/bottle/rum/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/rum, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/rum, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/holywater
name = "Flask of Holy Water"
@@ -324,7 +324,7 @@
center_of_mass = @'{"x":17,"y":3}'
/obj/item/chems/drinks/bottle/vermouth/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/vermouth, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/vermouth, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/kahlua
name = "Robert Robust's Coffee Liqueur"
@@ -333,7 +333,7 @@
center_of_mass = @'{"x":17,"y":3}'
/obj/item/chems/drinks/bottle/kahlua/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/coffee, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/coffee, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/goldschlager
name = "College Girl Goldschlager"
@@ -342,7 +342,7 @@
center_of_mass = @'{"x":15,"y":3}'
/obj/item/chems/drinks/bottle/goldschlager/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/vodka, reagents.maximum_volume - 5)
+ add_to_reagents(/decl/material/liquid/alcohol/vodka, reagents.maximum_volume - 5)
add_to_reagents(/decl/material/solid/metal/gold, 5)
/obj/item/chems/drinks/bottle/cognac
@@ -352,7 +352,7 @@
center_of_mass = @'{"x":16,"y":6}'
/obj/item/chems/drinks/bottle/cognac/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/cognac, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/cognac, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/wine
name = "Doublebeard Bearded Special Wine"
@@ -361,7 +361,7 @@
center_of_mass = @'{"x":16,"y":4}'
/obj/item/chems/drinks/bottle/wine/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/wine, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/wine, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/absinthe
name = "Jailbreaker Verte"
@@ -370,7 +370,7 @@
center_of_mass = @'{"x":16,"y":6}'
/obj/item/chems/drinks/bottle/absinthe/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/absinthe, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/absinthe, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/melonliquor
name = "Emeraldine Melon Liquor"
@@ -379,7 +379,7 @@
center_of_mass = @'{"x":16,"y":6}'
/obj/item/chems/drinks/bottle/melonliquor/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/melonliquor, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/melonliquor, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/bluecuracao
name = "Miss Blue Curacao"
@@ -388,7 +388,7 @@
center_of_mass = @'{"x":16,"y":6}'
/obj/item/chems/drinks/bottle/bluecuracao/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/bluecuracao, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/bluecuracao, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/herbal
name = "Liqueur d'Herbe"
@@ -397,7 +397,7 @@
center_of_mass = @'{"x":16,"y":6}'
/obj/item/chems/drinks/bottle/herbal/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/herbal, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/herbal, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/grenadine
name = "Briar Rose Grenadine Syrup"
@@ -442,7 +442,7 @@
center_of_mass = @'{"x":16,"y":4}'
/obj/item/chems/drinks/bottle/pwine/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/pwine, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/pwine, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/sake
name = "Takeo Sadow's Combined Sake"
@@ -451,7 +451,7 @@
center_of_mass = @'{"x":16,"y":4}'
/obj/item/chems/drinks/bottle/sake/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/sake, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/sake, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/champagne
@@ -463,7 +463,7 @@
var/opening
/obj/item/chems/drinks/bottle/champagne/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/champagne, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/champagne, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/champagne/open(mob/user)
if(ATOM_IS_OPEN_CONTAINER(src))
@@ -498,7 +498,7 @@
center_of_mass = @'{"x":16,"y":6}'
/obj/item/chems/drinks/bottle/jagermeister/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/jagermeister, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/jagermeister, reagents.maximum_volume)
//////////////////////////PREMIUM ALCOHOL ///////////////////////
/obj/item/chems/drinks/bottle/premiumvodka
@@ -511,7 +511,7 @@
var/namepick = pick("Four Stripes","Gilgamesh","Novaya Zemlya","Indie","STS-35")
var/typepick = pick("Absolut","Gold","Quadruple Distilled","Platinum","Standard")
name = "[namepick] [typepick]"
- add_to_reagents(/decl/material/liquid/ethanol/vodka/premium, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/vodka/premium, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/premiumwine
name = "Uve De Blanc"
@@ -529,7 +529,7 @@
var/agedyear = rand(global.using_map.game_year - aged_max, global.using_map.game_year - aged_min)
set_custom_name(make_random_name())
desc += " This bottle is marked as [agedyear] Vintage."
- add_to_reagents(/decl/material/liquid/ethanol/wine/premium, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/wine/premium, reagents.maximum_volume)
//////////////////////////JUICES AND STUFF ///////////////////////
@@ -612,7 +612,7 @@
center_of_mass = @'{"x":16,"y":12}'
/obj/item/chems/drinks/bottle/small/beer/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/beer, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/beer, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/small/ale
name = "\improper Magm-Ale"
@@ -622,7 +622,7 @@
center_of_mass = @'{"x":16,"y":10}'
/obj/item/chems/drinks/bottle/small/ale/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/ale, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/ale, reagents.maximum_volume)
/obj/item/chems/drinks/bottle/small/gingerbeer
name = "Ginger Beer"
diff --git a/code/modules/reagents/reagent_containers/drinks/cans.dm b/code/modules/reagents/reagent_containers/drinks/cans.dm
index 4caf4c5fa412..7c2dbb14dd63 100644
--- a/code/modules/reagents/reagent_containers/drinks/cans.dm
+++ b/code/modules/reagents/reagent_containers/drinks/cans.dm
@@ -50,7 +50,7 @@
center_of_mass = @'{"x":16,"y":8}'
/obj/item/chems/drinks/cans/thirteenloko/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/thirteenloko, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/thirteenloko, reagents.maximum_volume)
/obj/item/chems/drinks/cans/dr_gibb
name = "\improper Dr. Gibb"
@@ -202,7 +202,7 @@
center_of_mass = @'{"x":16,"y":10}'
/obj/item/chems/drinks/cans/speer/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/beer/good, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/beer/good, reagents.maximum_volume)
/obj/item/chems/drinks/cans/ale
name = "\improper Magm-Ale"
@@ -211,4 +211,4 @@
center_of_mass = @'{"x":16,"y":10}'
/obj/item/chems/drinks/cans/ale/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/ale, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/ale, reagents.maximum_volume)
diff --git a/code/modules/reagents/reagent_containers/food/lunch.dm b/code/modules/reagents/reagent_containers/food/lunch.dm
index b027e451e05e..fc4f92672c18 100644
--- a/code/modules/reagents/reagent_containers/food/lunch.dm
+++ b/code/modules/reagents/reagent_containers/food/lunch.dm
@@ -69,10 +69,10 @@ var/global/list/lunchables_drink_reagents_ = list(
// This default list is a bit different, it contains items we don't want
var/global/list/lunchables_ethanol_reagents_ = list(
- /decl/material/liquid/ethanol/coffee,
- /decl/material/liquid/ethanol/hooch,
- /decl/material/liquid/ethanol/thirteenloko,
- /decl/material/liquid/ethanol/pwine
+ /decl/material/liquid/alcohol/coffee,
+ /decl/material/liquid/alcohol/hooch,
+ /decl/material/liquid/alcohol/thirteenloko,
+ /decl/material/liquid/alcohol/pwine
)
/proc/lunchables_lunches()
@@ -97,7 +97,7 @@ var/global/list/lunchables_ethanol_reagents_ = list(
/proc/lunchables_ethanol_reagents()
if(!(lunchables_ethanol_reagents_[lunchables_ethanol_reagents_[1]]))
- lunchables_ethanol_reagents_ = init_lunchable_reagent_list(lunchables_ethanol_reagents_, /decl/material/liquid/ethanol)
+ lunchables_ethanol_reagents_ = init_lunchable_reagent_list(lunchables_ethanol_reagents_, /decl/material/liquid/alcohol)
return lunchables_ethanol_reagents_
/proc/init_lunchable_list(var/list/lunches)
@@ -107,11 +107,11 @@ var/global/list/lunchables_ethanol_reagents_ = list(
.[initial(O.name)] = lunch
return sortTim(., /proc/cmp_text_asc)
-/proc/init_lunchable_reagent_list(var/list/banned_reagents, var/reagent_types)
+/proc/init_lunchable_reagent_list(var/list/banned_reagents, var/reagent_type)
. = list()
- for(var/reagent_type in subtypesof(reagent_types))
- if(reagent_type in banned_reagents)
+ for(var/reagent_subtype in decls_repository.get_decls_of_type(reagent_type))
+ if(reagent_subtype in banned_reagents)
continue
- var/decl/material/reagent = reagent_type
- .[initial(reagent.name)] = reagent_type
+ var/decl/material/reagent = reagent_subtype
+ .[initial(reagent.name)] = reagent_subtype
return sortTim(., /proc/cmp_text_asc)
diff --git a/code/modules/reagents/reagent_containers/food/meat/fish.dm b/code/modules/reagents/reagent_containers/food/meat/fish.dm
index 80b15eae9fbd..4036cb4efe70 100644
--- a/code/modules/reagents/reagent_containers/food/meat/fish.dm
+++ b/code/modules/reagents/reagent_containers/food/meat/fish.dm
@@ -29,7 +29,7 @@
/obj/item/food/fishandchips
name = "fish and chips"
desc = "Best enjoyed wrapped in a newspaper on a cold wet day."
- icon = 'icons/obj/food/fried/fishfingers.dmi'
+ icon = 'icons/obj/food/fried/fishandchips.dmi'
filling_color = "#e3d796"
center_of_mass = @'{"x":16,"y":16}'
nutriment_desc = list("salt" = 1, "chips" = 2, "fish" = 2)
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index af8367645f71..be5659ebba4e 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -185,6 +185,7 @@
. = ..()
if(label_text)
update_name()
+ update_icon()
/obj/item/chems/hypospray/autoinjector/populate_reagents()
SHOULD_CALL_PARENT(TRUE)
@@ -192,10 +193,6 @@
if(reagents?.total_volume > 0 && autolabel && !label_text) // don't override preset labels
label_text = "[reagents.get_primary_reagent_name()], [reagents.total_volume]u"
-/obj/item/chems/hypospray/autoinjector/Initialize()
- . = ..()
- update_icon()
-
/obj/item/chems/hypospray/autoinjector/use_on_mob(mob/living/target, mob/living/user, animate = TRUE)
. = ..()
if(.)
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index 711c448ebdd3..9cd81a4c4375 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -109,7 +109,7 @@
if(has_safety() && distance <= 1)
to_chat(user, "The safety is [safety ? "on" : "off"].")
-/obj/item/chems/get_alt_interactions(mob/user)
+/obj/item/chems/spray/get_alt_interactions(mob/user)
. = ..()
LAZYADD(., /decl/interaction_handler/empty/chems)
LAZYADD(., /decl/interaction_handler/next_spray_amount)
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index d6597858fa34..d8d5d4e5e06c 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -37,9 +37,9 @@
if(!(. = ..()))
return
if(reagents?.total_volume > 0)
- tool_interaction_flags = 0
+ tool_interaction_flags &= ~TOOL_INTERACTION_DECONSTRUCT
else
- tool_interaction_flags = TOOL_INTERACTION_DECONSTRUCT
+ tool_interaction_flags |= TOOL_INTERACTION_DECONSTRUCT
/obj/structure/reagent_dispensers/initialize_reagents(populate = TRUE)
if(!reagents)
@@ -118,11 +118,6 @@
if (N)
amount_dispensed = N
-/obj/structure/reagent_dispensers/physically_destroyed(var/skip_qdel)
- if(reagents?.total_volume)
- reagents.trans_to_turf(get_turf(src), reagents.total_volume)
- . = ..()
-
/obj/structure/reagent_dispensers/explosion_act(severity)
. = ..()
if(. && (severity == 1) || (severity == 2 && prob(50)) || (severity == 3 && prob(5)))
@@ -319,7 +314,7 @@
matter = list(/decl/material/solid/metal/stainlesssteel = MATTER_AMOUNT_TRACE)
/obj/structure/reagent_dispensers/beerkeg/populate_reagents()
- add_to_reagents(/decl/material/liquid/ethanol/beer, reagents.maximum_volume)
+ add_to_reagents(/decl/material/liquid/alcohol/beer, reagents.maximum_volume)
/obj/structure/reagent_dispensers/acid
name = "sulphuric acid dispenser"
diff --git a/code/modules/recycling/disposalpipe.dm b/code/modules/recycling/disposalpipe.dm
index 60401186373b..e035da8b8254 100644
--- a/code/modules/recycling/disposalpipe.dm
+++ b/code/modules/recycling/disposalpipe.dm
@@ -232,29 +232,6 @@
qdel(src)
-// pipe is deleted
-// ensure if holder is present, it is expelled
-/obj/structure/disposalpipe/Destroy()
- var/obj/structure/disposalholder/H = locate() in src
- if(H)
- // holder was present
- H.active = 0
- var/turf/T = src.loc
- if(T.density)
- // deleting pipe is inside a dense turf (wall)
- // this is unlikely, but just dump out everything into the turf in case
-
- for(var/atom/movable/AM in H)
- AM.forceMove(T)
- AM.pipe_eject(0)
- qdel(H)
- return ..()
-
- // otherwise, do normal expel from turf
- if(H)
- expel(H, T, 0)
- . = ..()
-
/obj/structure/disposalpipe/hides_under_flooring()
return 1
diff --git a/code/modules/security_levels/_security_level.dm b/code/modules/security_levels/_security_level.dm
new file mode 100644
index 000000000000..ca4ba811c82f
--- /dev/null
+++ b/code/modules/security_levels/_security_level.dm
@@ -0,0 +1,48 @@
+/decl/security_level
+ var/icon = 'icons/misc/security_state.dmi'
+ var/name
+
+ // These values are primarily for station alarms and status displays, and which light colors and overlays to use
+ var/light_range
+ var/light_power
+ var/light_color_alarm
+ var/light_color_class
+ var/light_color_status_display
+
+ var/up_description
+ var/down_description
+
+ var/datum/alarm_appearance/alarm_appearance
+
+ abstract_type = /decl/security_level
+
+/decl/security_level/Initialize()
+ . = ..()
+ if(ispath(alarm_appearance, /datum/alarm_appearance))
+ alarm_appearance = new alarm_appearance
+
+/decl/security_level/validate()
+ . = ..()
+ var/initial_appearance = initial(alarm_appearance)
+ if(!initial_appearance)
+ . += "alarm_appearance was not set"
+ else if(!ispath(initial_appearance))
+ . += "alarm_appearance was not set to a /datum/alarm_appearance subpath"
+ else if(!istype(alarm_appearance, /datum/alarm_appearance))
+ . += "alarm_appearance creation failed (check runtimes?)"
+
+// Called when we're switching from a lower security level to this one.
+/decl/security_level/proc/switching_up_to()
+ return
+
+// Called when we're switching from a higher security level to this one.
+/decl/security_level/proc/switching_down_to()
+ return
+
+// Called when we're switching from this security level to a higher one.
+/decl/security_level/proc/switching_up_from()
+ return
+
+// Called when we're switching from this security level to a lower one.
+/decl/security_level/proc/switching_down_from()
+ return
\ No newline at end of file
diff --git a/code/modules/security_levels/alarm_appearance.dm b/code/modules/security_levels/alarm_appearance.dm
new file mode 100644
index 000000000000..494158a60393
--- /dev/null
+++ b/code/modules/security_levels/alarm_appearance.dm
@@ -0,0 +1,61 @@
+/datum/alarm_appearance
+ var/display_icon //The icon_state for the displays. Normally only one is used, unless uses_twotone_displays is TRUE.
+ var/display_icon_color //The color for the display icon.
+
+ var/display_icon_twotone //Used for two-tone displays.
+ var/display_icon_twotone_color //The color for the display icon.
+
+ var/display_emblem //The icon_state for the emblem, i.e for delta, a radstorm, alerts.
+ var/display_emblem_color //The color for the emblem.
+
+ var/alarm_icon //The icon_state for the alarms
+ var/alarm_icon_color //the color for the icon_state
+
+ var/alarm_icon_twotone //Used for two-tone alarms (i.e delta).
+ var/alarm_icon_twotone_color //The color for the secondary tone icon.
+
+/datum/alarm_appearance/green
+ display_icon = "status_display_lines"
+ display_icon_color = PIPE_COLOR_GREEN
+
+ display_emblem = "status_display_alert"
+ display_emblem_color = COLOR_WHITE
+
+ alarm_icon = "alarm_normal"
+ alarm_icon_color = PIPE_COLOR_GREEN
+
+/datum/alarm_appearance/blue
+ display_icon = "status_display_lines"
+ display_icon_color = COLOR_BLUE
+
+ display_emblem = "status_display_alert"
+ display_emblem_color = COLOR_WHITE
+
+ alarm_icon = "alarm_normal"
+ alarm_icon_color = COLOR_BLUE
+
+/datum/alarm_appearance/red
+ display_icon = "status_display_lines"
+ display_icon_color = COLOR_RED
+
+ display_emblem = "status_display_alert"
+ display_emblem_color = COLOR_WHITE
+
+ alarm_icon = "alarm_blinking"
+ alarm_icon_color = COLOR_RED
+
+/datum/alarm_appearance/delta
+ display_icon = "status_display_twotone1"
+ display_icon_color = COLOR_RED
+
+ display_icon_twotone = "status_display_twotone2"
+ display_icon_twotone_color = COLOR_YELLOW
+
+ display_emblem = "delta"
+ display_emblem_color = COLOR_WHITE
+
+ alarm_icon = "alarm_blinking_twotone1"
+ alarm_icon_color = COLOR_RED
+
+ alarm_icon_twotone = "alarm_blinking_twotone2"
+ alarm_icon_twotone_color = PIPE_COLOR_YELLOW
\ No newline at end of file
diff --git a/code/modules/security levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm
similarity index 100%
rename from code/modules/security levels/keycard_authentication.dm
rename to code/modules/security_levels/keycard_authentication.dm
diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm
new file mode 100644
index 000000000000..186fd37fbbe7
--- /dev/null
+++ b/code/modules/security_levels/security_levels.dm
@@ -0,0 +1,105 @@
+/// The default security state used on most space maps.
+/decl/security_state/default
+ all_security_levels = list(
+ /decl/security_level/default/code_green,
+ /decl/security_level/default/code_blue,
+ /decl/security_level/default/code_red,
+ /decl/security_level/default/code_delta
+ )
+
+/// An abstract security level type that supports announcements on level change.
+/decl/security_level/default
+ abstract_type = /decl/security_level/default
+
+ var/static/datum/announcement/priority/security/security_announcement_up = new(do_log = 0, do_newscast = 1, new_sound = sound('sound/misc/notice1.ogg'))
+ var/static/datum/announcement/priority/security/security_announcement_down = new(do_log = 0, do_newscast = 1, new_sound = sound('sound/misc/notice1.ogg'))
+
+/decl/security_level/default/switching_up_to()
+ if(up_description)
+ security_announcement_up.Announce(up_description, "Attention! Alert level elevated to [name]!")
+ notify_station()
+
+/decl/security_level/default/switching_down_to()
+ if(down_description)
+ security_announcement_down.Announce(down_description, "Attention! Alert level changed to [name]!")
+ notify_station()
+
+/decl/security_level/default/proc/notify_station()
+ for(var/obj/machinery/firealarm/FA in SSmachines.machinery)
+ if(isContactLevel(FA.z))
+ FA.update_icon()
+ post_status("alert")
+
+/decl/security_level/default/code_green
+ name = "code green"
+
+ light_range = 2
+ light_power = 1
+
+ light_color_alarm = COLOR_GREEN
+ light_color_class = "font_green"
+ light_color_status_display = COLOR_GREEN
+
+
+ alarm_appearance = /datum/alarm_appearance/green
+
+ down_description = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced."
+
+/decl/security_level/default/code_blue
+ name = "code blue"
+
+ light_range = 2
+ light_power = 1
+ light_color_alarm = COLOR_BLUE
+ light_color_class = "font_blue"
+ light_color_status_display = COLOR_BLUE
+
+ alarm_appearance = /datum/alarm_appearance/blue
+
+ up_description = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted."
+ down_description = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed."
+
+/decl/security_level/default/code_red
+ name = "code red"
+
+ light_range = 4
+ light_power = 2
+ light_color_alarm = COLOR_RED
+ light_color_class = "font_red"
+ light_color_status_display = COLOR_RED
+
+ alarm_appearance = /datum/alarm_appearance/red
+
+ up_description = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised."
+ down_description = "The self-destruct mechanism has been deactivated, there is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised."
+
+/decl/security_level/default/code_delta
+ name = "code delta"
+
+ light_range = 4
+ light_power = 2
+ light_color_alarm = COLOR_RED
+ light_color_class = "font_red"
+ light_color_status_display = COLOR_RED
+
+ alarm_appearance = /datum/alarm_appearance/delta
+
+
+ var/static/datum/announcement/priority/security/security_announcement_delta = new(do_log = 0, do_newscast = 1, new_sound = sound('sound/effects/siren.ogg'))
+
+/decl/security_level/default/code_delta/switching_up_to()
+ security_announcement_delta.Announce("The self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.", "Attention! Delta security level reached!")
+ notify_station()
+
+// The following are dummy states and levels to soft-disable security levels on some maps.
+/// A security state used for maps that don't have security levels exposed to players.
+/decl/security_state/none
+ all_security_levels = list(
+ /decl/security_level/none
+ )
+
+/// A dummy security level with no effects.
+/decl/security_level/none
+ name = "none"
+ // Since currently we're required to have an alarm_appearance, we just use a blank one.
+ alarm_appearance = /datum/alarm_appearance
\ No newline at end of file
diff --git a/code/modules/security_levels/security_state.dm b/code/modules/security_levels/security_state.dm
new file mode 100644
index 000000000000..2e997845d411
--- /dev/null
+++ b/code/modules/security_levels/security_state.dm
@@ -0,0 +1,136 @@
+/decl/security_state
+ abstract_type = /decl/security_state
+ /// Whether or not security level information should be shown to new players on login.
+ var/show_on_login = TRUE
+ // When defining any of these values type paths should be used, not instances. Instances will be acquired in /New()
+
+ var/decl/security_level/severe_security_level // At which security level (and higher) the use of nuclear fission devices and other extreme measures are allowed. Defaults to the last entry in all_security_levels if unset.
+ var/decl/security_level/high_security_level // At which security level (and higher) transfer votes are disabled, ERT may be requested, and other similar high alert implications. Defaults to the second to last entry in all_security_levels if unset.
+ // All security levels within the above convention: Low, Guarded, Elevated, High, Severe
+
+
+ // Under normal conditions the crew may not raise the current security level higher than the highest_standard_security_level
+ // The crew may also not adjust the security level once it is above the highest_standard_security_level.
+ // Defaults to the second to last entry in all_security_levels if unset/null.
+ // Set to FALSE/0 if there should be no restrictions.
+ var/decl/security_level/highest_standard_security_level
+
+ var/decl/security_level/current_security_level // The current security level. Defaults to the first entry in all_security_levels if unset.
+ var/decl/security_level/stored_security_level // The security level that we are escalating to high security from - we will return to this level once we choose to revert.
+ var/list/all_security_levels // List of all available security levels
+ var/list/standard_security_levels // List of all normally selectable security levels
+ var/list/comm_console_security_levels // List of all selectable security levels for the command and communication console - basically standard_security_levels - 1
+
+/decl/security_state/Initialize()
+
+ . = ..()
+
+ // Setup the severe security level
+ if(!(severe_security_level in all_security_levels))
+ severe_security_level = all_security_levels[all_security_levels.len]
+ severe_security_level = GET_DECL(severe_security_level)
+
+ // Setup the high security level
+ if(!(high_security_level in all_security_levels))
+ high_security_level = all_security_levels[max(1, all_security_levels.len - 1)]
+ high_security_level = GET_DECL(high_security_level)
+
+ // Setup the highest standard security level
+ if(highest_standard_security_level || isnull(highest_standard_security_level))
+ if(!(highest_standard_security_level in all_security_levels))
+ highest_standard_security_level = all_security_levels[max(1, all_security_levels.len - 1)]
+ highest_standard_security_level = GET_DECL(highest_standard_security_level)
+ else
+ highest_standard_security_level = null
+
+ // Setup the current security level
+ if(current_security_level in all_security_levels)
+ current_security_level = GET_DECL(current_security_level)
+ else
+ current_security_level = GET_DECL(all_security_levels[1])
+
+ // Setup the full list of available security levels now that we no longer need to use "x in all_security_levels"
+ var/list/security_level_instances = list()
+ for(var/security_level_type in all_security_levels)
+ security_level_instances += GET_DECL(security_level_type)
+ all_security_levels = security_level_instances
+
+ standard_security_levels = list()
+ // Setup the list of normally selectable security levels
+ for(var/security_level in all_security_levels)
+ standard_security_levels += security_level
+ if(security_level == highest_standard_security_level)
+ break
+
+ comm_console_security_levels = list()
+ // Setup the list of selectable security levels available in the comm. console
+ for(var/security_level in all_security_levels)
+ if(security_level == highest_standard_security_level)
+ break
+ comm_console_security_levels += security_level
+
+ // Now we ensure the high security level is not above the severe one (but we allow them to be equal)
+ var/severe_index = all_security_levels.Find(severe_security_level)
+ var/high_index = all_security_levels.Find(high_security_level)
+ if(high_index > severe_index)
+ high_security_level = severe_security_level
+
+ // Finally switch up to the default starting security level.
+ current_security_level.switching_up_to()
+
+/decl/security_state/proc/can_change_security_level()
+ return current_security_level in standard_security_levels
+
+/decl/security_state/proc/can_switch_to(var/given_security_level)
+ if(!can_change_security_level())
+ return FALSE
+ return given_security_level in standard_security_levels
+
+/decl/security_state/proc/current_security_level_is_lower_than(var/given_security_level)
+ var/current_index = all_security_levels.Find(current_security_level)
+ var/given_index = all_security_levels.Find(given_security_level)
+
+ return given_index && current_index < given_index
+
+/decl/security_state/proc/current_security_level_is_same_or_higher_than(var/given_security_level)
+ var/current_index = all_security_levels.Find(current_security_level)
+ var/given_index = all_security_levels.Find(given_security_level)
+
+ return given_index && current_index >= given_index
+
+/decl/security_state/proc/current_security_level_is_higher_than(var/given_security_level)
+ var/current_index = all_security_levels.Find(current_security_level)
+ var/given_index = all_security_levels.Find(given_security_level)
+
+ return given_index && current_index > given_index
+
+/decl/security_state/proc/set_security_level(var/decl/security_level/new_security_level, var/force_change = FALSE)
+ if(new_security_level == current_security_level)
+ return FALSE
+ if(!(new_security_level in all_security_levels))
+ return FALSE
+ if(!force_change && !can_switch_to(new_security_level))
+ return FALSE
+
+ var/decl/security_level/previous_security_level = current_security_level
+ current_security_level = new_security_level
+
+ var/previous_index = all_security_levels.Find(previous_security_level)
+ var/new_index = all_security_levels.Find(new_security_level)
+
+ if(new_index > previous_index)
+ previous_security_level.switching_up_from()
+ new_security_level.switching_up_to()
+ else
+ previous_security_level.switching_down_from()
+ new_security_level.switching_down_to()
+
+ log_and_message_admins("has changed the security level from [previous_security_level.name] to [new_security_level.name].")
+ return TRUE
+
+// This proc decreases the current security level, if possible
+/decl/security_state/proc/decrease_security_level(var/force_change = FALSE)
+ var/current_index = all_security_levels.Find(current_security_level)
+ if(current_index == 1)
+ return FALSE
+ return set_security_level(all_security_levels[current_index - 1], force_change)
diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm
index 01ab98a5af68..5c615ad31b3d 100644
--- a/code/modules/species/species.dm
+++ b/code/modules/species/species.dm
@@ -87,7 +87,6 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200
/decl/natural_attack/bite
)
- var/list/natural_armour_values // Armour values used if naked.
var/brute_mod = 1 // Physical damage multiplier.
var/burn_mod = 1 // Burn damage multiplier.
var/toxins_mod = 1 // Toxloss modifier
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index 06fe754e5dea..ca8806692a16 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -181,7 +181,7 @@
/decl/surgery_step/sterilize/Initialize()
. = ..()
- for(var/decl/material/liquid/ethanol/booze in decls_repository.get_decls_of_type_unassociated(/decl/material/liquid/ethanol))
+ for(var/decl/material/liquid/alcohol/booze in decls_repository.get_decls_of_subtype_unassociated(/decl/material/liquid/alcohol))
if(booze.strength <= 40)
sterilizing_reagents |= booze.type
diff --git a/code/modules/synthesized_instruments/real_instruments/Violin/violin.dm b/code/modules/synthesized_instruments/real_instruments/Violin/violin.dm
index f3baab9aa07c..5eb4e3e773e3 100644
--- a/code/modules/synthesized_instruments/real_instruments/Violin/violin.dm
+++ b/code/modules/synthesized_instruments/real_instruments/Violin/violin.dm
@@ -10,6 +10,3 @@
path = /datum/instrument/obsolete/violin
material = /decl/material/solid/organic/wood/oak
matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_TRACE)
-
-/obj/structure/synthesized_instrument/synthesizer/shouldStopPlaying(mob/user)
- return !(src && in_range(src, user))
\ No newline at end of file
diff --git a/code/modules/tools/subtypes/hammers.dm b/code/modules/tools/subtypes/hammers.dm
index 20304b690e56..bb1c9ee58cd5 100644
--- a/code/modules/tools/subtypes/hammers.dm
+++ b/code/modules/tools/subtypes/hammers.dm
@@ -29,7 +29,10 @@
return tool_properties
/obj/item/tool/hammer/get_initial_tool_qualities()
- var/static/list/tool_qualities = list(TOOL_HAMMER = TOOL_QUALITY_DEFAULT)
+ var/static/list/tool_qualities = list(
+ TOOL_HAMMER = TOOL_QUALITY_DEFAULT,
+ TOOL_CROWBAR = TOOL_QUALITY_WORST
+ )
return tool_qualities
/obj/item/tool/hammer/sledge
diff --git a/code/modules/vehicles/engine.dm b/code/modules/vehicles/engine.dm
index 1b6682dfce4c..cffe87ade48a 100644
--- a/code/modules/vehicles/engine.dm
+++ b/code/modules/vehicles/engine.dm
@@ -110,8 +110,8 @@
for(var/rtype in temp_reagents_holder.reagents.reagent_volumes)
var/new_multiplier = 1
var/decl/material/R = GET_DECL(rtype)
- if(istype(R,/decl/material/liquid/ethanol))
- var/decl/material/liquid/ethanol/E = R
+ if(istype(R, /decl/material/liquid/alcohol))
+ var/decl/material/liquid/alcohol/E = R
new_multiplier = (10/E.strength)
actually_flameable = 1
else if(istype(R,/decl/material/liquid/fuel/hydrazine))
@@ -137,5 +137,5 @@
/obj/item/engine/thermal/rev_engine(var/atom/movable/M)
M.audible_message("\The [M] rumbles to life.")
-/obj/item/engine/electric/putter(var/atom/movable/M)
+/obj/item/engine/thermal/putter(var/atom/movable/M)
M.audible_message("\The [M] putters before turning off.")
\ No newline at end of file
diff --git a/code/modules/weather/weather_fsm_states.dm b/code/modules/weather/weather_fsm_states.dm
index e44f43efa8e9..029f500f16ff 100644
--- a/code/modules/weather/weather_fsm_states.dm
+++ b/code/modules/weather/weather_fsm_states.dm
@@ -163,7 +163,7 @@
/decl/state_transition/weather/snow_heavy
)
-/decl/state/weather/snow/heavy/adjust_temperature(initial_temperature)
+/decl/state/weather/snow/medium/adjust_temperature(initial_temperature)
return min(initial_temperature - 25, T0C)
/decl/state/weather/snow/heavy
diff --git a/code/modules/xenoarcheaology/finds/find_types/chem_containers.dm b/code/modules/xenoarcheaology/finds/find_types/chem_containers.dm
index 9cd5a4e78ae3..957c9204a4d0 100644
--- a/code/modules/xenoarcheaology/finds/find_types/chem_containers.dm
+++ b/code/modules/xenoarcheaology/finds/find_types/chem_containers.dm
@@ -29,16 +29,16 @@
/obj/item/chems/glass/replenishing/Initialize()
. = ..()
- spawning_id = pick(
- /decl/material/liquid/blood, \
- /decl/material/liquid/lube, \
- /decl/material/liquid/sedatives, \
- /decl/material/liquid/ethanol, \
- /decl/material/liquid/water, \
- /decl/material/solid/ice, \
- /decl/material/liquid/fuel, \
- /decl/material/liquid/cleaner \
- )
+ spawning_id = pick(list(
+ /decl/material/liquid/blood,
+ /decl/material/liquid/lube,
+ /decl/material/liquid/sedatives,
+ /decl/material/liquid/alcohol/ethanol,
+ /decl/material/liquid/water,
+ /decl/material/solid/ice,
+ /decl/material/liquid/fuel,
+ /decl/material/liquid/cleaner
+ ))
START_PROCESSING(SSobj, src)
/obj/item/chems/glass/replenishing/Process()
diff --git a/code/modules/xenoarcheaology/finds/find_types/weapons.dm b/code/modules/xenoarcheaology/finds/find_types/weapons.dm
index 73db85aeca5e..b593cece25d5 100644
--- a/code/modules/xenoarcheaology/finds/find_types/weapons.dm
+++ b/code/modules/xenoarcheaology/finds/find_types/weapons.dm
@@ -18,7 +18,7 @@
"It doesn't look safe.",
"It looks wickedly jagged.",
"There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains along the edges.")
-
+
/decl/archaeological_find/knife/new_icon()
return pick(knife_icons)
@@ -46,7 +46,7 @@
modification_flags = XENOFIND_APPLY_DECOR
possible_types = list(/obj/item/beartrap)
-/decl/archaeological_find/knife/generate_name()
+/decl/archaeological_find/trap/generate_name()
return "[pick("wicked","evil","byzantine","dangerous")] looking [pick("device","contraption","thing","trap")]"
/decl/archaeological_find/trap/get_additional_description()
diff --git a/code/modules/xenoarcheaology/tools/ano_device_battery.dm b/code/modules/xenoarcheaology/tools/ano_device_battery.dm
index 0ac71ec22783..86f037fd0f88 100644
--- a/code/modules/xenoarcheaology/tools/ano_device_battery.dm
+++ b/code/modules/xenoarcheaology/tools/ano_device_battery.dm
@@ -57,6 +57,7 @@
/obj/item/anodevice/Destroy()
inserted_battery = null
+ STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/anodevice/attackby(var/obj/I, var/mob/user)
@@ -188,10 +189,6 @@
else
icon_state = "anodev_empty"
-/obj/item/anodevice/Destroy()
- STOP_PROCESSING(SSobj, src)
- . = ..()
-
/obj/item/anodevice/use_on_mob(mob/living/target, mob/living/user, animate = TRUE)
if (!istype(target))
return ..()
diff --git a/html/changelog.html b/html/changelog.html
index d152fc178400..e3ca34984821 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -52,6 +52,20 @@
-->
+
03 January 2025
+
MistakeNot4892 updated:
+
+ - Raw plant oil no longer works as lantern fuel; it must be mixed with powdered graphite first.
+
+
+
23 December 2024
+
ophelia v0.8 updated:
+
+ - added new dirt and mud tile sprites
+ - added new wooden chest sprites, by Doe
+ - mud and soil plots are now properly greyscaled to soil material color
+
+
21 December 2024
Penelope Haze updated:
@@ -92,19 +106,6 @@ Neerti updated:
- Microlasers added to mining drills no longer multiply ore out of the ground, but make the drill mine faster, proportionally increasing the energy usage.
- Capacitors added to mining drills are less powerful.
-
-
01 November 2024
-
MistakeNot4892 updated:
-
- - Curries, soups and stews have been rewritten, please refer to the codex for recipes.
-
-
-
23 October 2024
-
MistakeNot4892 updated:
-
- - Dough now requires a 60C temperature and does not use egg.
- - Flatbread now uses unleavened dough, made without yeast, while pies use pie crust. Check the codex for updated recipes.
-